# Edit this example, then press Run. Reset restores the published version.

def require(condition, message):
    if not condition:
        raise AssertionError(message)


def multiply(a, b):
    return tuple(tuple(sum(x*y for x, y in zip(row, column))
                       for column in zip(*b)) for row in a)


def apply(a, vector):
    return tuple(sum(x*y for x, y in zip(row, vector)) for row in a)


def recovery():
    r, f, h = ((1, 1),), ((1, 0),), ((2, 2),)
    u, v = (1, 0), (0, 1)
    summary = apply(r, u)[0]
    answers = (apply(f, u)[0], apply(f, v)[0])
    w = tuple(a-b for a, b in zip(u, v))
    rw, fw = apply(r, w)[0], apply(f, w)[0]
    require(summary == apply(r, v)[0] == 1, 'Collision is missing')
    require(answers == (1, 0) and rw == 0 and fw == 1, 'Witness failed')
    # The matrix identity proves the compatible linear rule for every vector.
    require(multiply(((2,),), r) == h, 'Compatible observation identity failed')
    return '\n'.join([
        f'Inputs: {u} and {v}', f'Same summary: {summary}',
        f'Requested first coordinates: {answers}', f'Kernel witness: {w}',
        f'R(w): {rw}', f'F(w): {fw}',
        f'Compatible observation coefficients: {h[0]}',
        'PASS: recovery',
    ])


print(recovery())
