# -*- coding: utf-8 -*- """ verify_markoff_q35.py -- self-contained verifier for the note by David Niedbala Giraudin (ORCID 0009-0009-1526-1178), 31 October 2026, "Coincidences of q-analogues of Markoff numbers outside the known families: an answer to a question of Labbe, Lapointe and Steiner". Run as: python3 verify_markoff_q35.py (Python 3 only; no argument, no package; about one minute) Everything is exact (integers and polynomials with integer coefficients). Sections of the output follow the note: [1] calibration on values published in [LLS]; [2] the 50 pairs listed below and the pair of length 50: exact equalities; [3] none of these pairs is given by identities (4) and (7) of [LLS], even through chains of such identities; [4] the basic facts (F1)-(F4); [5] Theorem 2: polynomial identities for a generic 2x2 matrix G; [6] Theorem 3: polynomial identities for a generic matrix G = phi(G); [7] every one of the 50 classes contains an instance of Theorem 2 or 3; [8] the computational inputs of Theorem 4, and direct checks of it. """ import sys, time, random from itertools import product, combinations T0 = time.time() ok_all = True def report(label, ok): global ok_all ok_all &= bool(ok) print(f" {label:<70s} {'OK' if ok else 'FAILED'}", flush=True) # ============================================================== Z[q] arithmetic def qadd(a, b): n = max(len(a), len(b)); r = [0]*n for i, c in enumerate(a): r[i] += c for i, c in enumerate(b): r[i] += c while len(r) > 1 and r[-1] == 0: r.pop() return tuple(r) def qmul(a, b): r = [0]*(len(a)+len(b)-1) for i, x in enumerate(a): if x: for j, y in enumerate(b): r[i+j] += x*y while len(r) > 1 and r[-1] == 0: r.pop() return tuple(r) def qmm(A, B): return ((qadd(qmul(A[0][0], B[0][0]), qmul(A[0][1], B[1][0])), qadd(qmul(A[0][0], B[0][1]), qmul(A[0][1], B[1][1]))), (qadd(qmul(A[1][0], B[0][0]), qmul(A[1][1], B[1][0])), qadd(qmul(A[1][0], B[0][1]), qmul(A[1][1], B[1][1])))) Z0, Z1, ZQ = (0,), (1,), (0, 1) L_q = ((ZQ, Z0), (ZQ, Z1)); R_q = ((ZQ, Z1), (Z0, Z1)); I_q = ((Z1, Z0), (Z0, Z1)) MU = {'0': qmm(R_q, L_q), '1': qmm(qmm(R_q, R_q), qmm(L_q, L_q))} def mu12(w): M = I_q for c in w: M = qmm(M, MU[c]) return M[0][1] def Mq(z): M = I_q for c in z: M = qmm(M, L_q if c == '0' else R_q) return M def M12(z): return Mq(z)[0][1] def sigma(w): return ''.join('10' if c == '0' else '1100' for c in w) def bar(z): return ''.join('1' if c == '0' else '0' for c in reversed(z)) def tilde(w): return w[::-1] # ================================================== Z[a,b,c,d,q] arithmetic # a polynomial is a dict {(ea,eb,ec,ed,eq): coefficient} def padd(A, B): R = dict(A) for k, v in B.items(): n = R.get(k, 0) + v if n: R[k] = n else: R.pop(k, None) return R def pneg(A): return {k: -v for k, v in A.items()} def psub(A, B): return padd(A, pneg(B)) def pmul(A, B): R = {} for k1, v1 in A.items(): for k2, v2 in B.items(): k = (k1[0]+k2[0], k1[1]+k2[1], k1[2]+k2[2], k1[3]+k2[3], k1[4]+k2[4]) n = R.get(k, 0) + v1*v2 if n: R[k] = n else: R.pop(k, None) return R def mono(e, c=1): return {e: c} ONE = mono((0,0,0,0,0)); ZERO = {} A_, B_, C_, D_, Q_ = (mono((1,0,0,0,0)), mono((0,1,0,0,0)), mono((0,0,1,0,0)), mono((0,0,0,1,0)), mono((0,0,0,0,1))) def MM(X, Y): return ((padd(pmul(X[0][0], Y[0][0]), pmul(X[0][1], Y[1][0])), padd(pmul(X[0][0], Y[0][1]), pmul(X[0][1], Y[1][1]))), (padd(pmul(X[1][0], Y[0][0]), pmul(X[1][1], Y[1][0])), padd(pmul(X[1][0], Y[0][1]), pmul(X[1][1], Y[1][1])))) def MADD(X, Y): return tuple(tuple(padd(X[i][j], Y[i][j]) for j in range(2)) for i in range(2)) def MSUB(X, Y): return tuple(tuple(psub(X[i][j], Y[i][j]) for j in range(2)) for i in range(2)) def SMUL(s, X): return tuple(tuple(pmul(s, X[i][j]) for j in range(2)) for i in range(2)) def ISZERO(X): return all(not X[i][j] for i in range(2) for j in range(2)) LP = ((Q_, ZERO), (Q_, ONE)); RP = ((Q_, ONE), (ZERO, ONE)); IP = ((ONE, ZERO), (ZERO, ONE)) def MP(z): M = IP for c in z: M = MM(M, LP if c == '0' else RP) return M P4, N4 = MP('0110'), MP('1001') # the two windows JQ = ((ZERO, mono((0,0,0,0,0), -1)), (Q_, ZERO)) # J = S Q_q = [[0,-1],[q,0]] G = ((A_, B_), (C_, D_)) # q*phi(G) = q * transpose(Q G Q^{-1}) = [[q a, c], [q^2 b, q d]] (we work with # q*phi(G) to stay polynomial; each side of every identity below contains the same # number of factors phi(G), so the common power of q cancels) qPHI = ((pmul(Q_, A_), C_), (pmul(pmul(Q_, Q_), B_), pmul(Q_, D_))) def lin(M): # (q,1) M (1,1)^T return padd(pmul(Q_, padd(M[0][0], M[0][1])), padd(M[1][0], M[1][1])) def word_value(eps, wins, Gm, Hm): """(q,1) * X_0 a_1 X_1 a_2 ... a_k X_k * (1,1)^T with X_i = Gm if eps_i='+', Hm if '-'.""" M = Gm if eps[0] == '+' else Hm for i, w in enumerate(wins): M = MM(M, P4 if w == '+' else N4) M = MM(M, Gm if eps[i+1] == '+' else Hm) return lin(M) # ================================================================ [1] calibration print("[1] Calibration against [LLS]") report("mu_q(00101)_12 = 1+4q+10q^2+...+5q^10+q^11 (194 at q = 1)", mu12('00101') == (1,4,10,18,27,33,33,29,21,12,5,1)) report("mu_q(00011)_12 = mu_q(01001)_12", mu12('00011') == mu12('01001')) report("M_q(110000011)_12 = M_q(100010001)_12 = 1+2q+3q^2+4q^3+4q^4+4q^5+3q^6+2q^7+q^8", M12('110000011') == M12('100010001') == (1,2,3,4,4,4,3,2,1)) # ================================================================ the pairs PAIRS = """ 001011001011010011001011 001101001010110011010011 001011001011010101001011 001101001010110101010011 001011001101001010101101 001011010101001100101101 001011001101001011001011 001101001100101011010011 001011001101001101001011 001101001100101101010011 001011010011010011001011 001101010010110011010011 001011010011010101001011 001101010010110101010011 001011010101001011001011 001101010100101011010011 001011010101001101001011 001101010100101101010011 010010101011010011001011 010010110011010101001011 000101100010011010001100010011 000110100010010110001100100011 000101100010011010010100010011 000110100010010110010100100011 000101100011001000101001011001 000101100101001000110001011001 000101100011001000101100010011 000110100011000100101100100011 000101100011001000110100010011 000110100011000100110100100011 000101100100011010001100010011 000110100100010110001100100011 000101100100011010010100010011 000110100100010110010100100011 000101100101001000101100010011 000110100101000100101100100011 000101100101001000110100010011 000110100101000100110100100011 001010110010110101001100101011 001101010010101011001101010011 001010110010110101010100101011 001101010010101011010101010011 001010110011010100101010101101 001010110101010100110010101101 001010110011010100101100101011 001101010011001010101101010011 001010110011010100110100101011 001101010011001010110101010011 001010110100110101001100101011 001101010100101011001101010011 001010110100110101010100101011 001101010100101011010101010011 001010110101010100101100101011 001101010101001010101101010011 001010110101010100110100101011 001101010101001010110101010011 001011001011001101001011001011 001100101101001101010010110011 001011001011001101010011001011 001100101011001101010010110011 001011001011010011001010110011 001011001101010011010010110011 001011001011010011001011001011 001100101101010011010010110011 001011001011010011010011001011 001100101011010011010010110011 001011001101001101001011001011 001100101101001101001010110011 001011001101001101010011001011 001100101011001101001010110011 001011001101010011001011001011 001100101101010011001010110011 001011001101010011010011001011 001100101011010011001010110011 001100101011001101001011001011 001100101101001101010011001011 001101110010111011001110010111 001110110010110111001110100111 001101110010111011010110010111 001110110010110111010110100111 001101110011101001101011011101 001101110101101001110011011101 001101110011101001101110010111 001110110011100101101110100111 001101110011101001110110010111 001110110011100101110110100111 001101110100111011001110010111 001110110100110111001110100111 001101110100111011010110010111 001110110100110111010110100111 001101110101101001101110010111 001110110101100101101110100111 001101110101101001110110010111 001110110101100101110110100111 010001001010011010001100010011 010001001100011010010100010011 010010101010110101001100101011 010010101100110101010100101011 011001011010111011001110010111 011001011100111011010110010111 """.split() PAIRS = list(zip(PAIRS[0::2], PAIRS[1::2])) LONG = ("00010110001001101000100101100010011010001100010011", "00011010001001011000100110100010010110001100100011") # ================================================================ [2] equalities print("\n[2] Exact equalities") n24 = sum(1 for x, y in PAIRS if len(x) == 24); n30 = sum(1 for x, y in PAIRS if len(x) == 30) report(f"50 distinct pairs read ({n24} of length 24, {n30} of length 30)", len(set(PAIRS)) == 50 and n24 == 10 and n30 == 40) report("mu_q(A)_12 = mu_q(B)_12 for all 50 pairs", all(len(x) == len(y) and x != y and mu12(x) == mu12(y) for x, y in PAIRS)) p0 = mu12(PAIRS[0][0]) report(f"first pair: degree {len(p0)-1}, value {sum(p0)} at q = 1", len(p0)-1 == 69 and sum(p0) == 43633212873750) pl = mu12(LONG[0]) report(f"pair of length 50: mu_q(A)_12 = mu_q(B)_12, degree {len(pl)-1}", pl == mu12(LONG[1]) and len(pl)-1 == 137) WORDS = [w for p in PAIRS for w in p] report("the 100 words listed here are distinct, and no two are (4)-partners of each other", len(set(WORDS)) == 100 and not any(('0' + w[1:-1][::-1] + '1') in set(WORDS) - {w} for w in WORDS if w[0] == '0' and w[-1] == '1')) # ================================================================ [3] (4) and (7) def hat(v): return ''.join({'0':'1','1':'0','2':'2','3':'3'}[c] for c in reversed(v)) def psi(w, v): blk = {'0': w+'01'+tilde(w)+'01', '1': w+'10'+tilde(w)+'10', '2': w+'01'+tilde(w)+'10', '3': w+'10'+tilde(w)+'01'} return ''.join(blk[c] for c in v) def moves(x): """All y != x such that {x, y} is an instance of identity (4) or (7) of [LLS].""" out = set(); n = len(x) if n >= 2 and x[0] == '0' and x[-1] == '1': out.add('0' + tilde(x[1:-1]) + '1') # (4) core = x[1:-1] for lw in range(0, n-1): # (7) rest = len(core) - lw if rest <= 0 or rest % (2*lw+4): continue w = core[len(core)-lw:]; body = core[:len(core)-lw]; v = []; good = True for i in range(0, len(body), 2*lw+4): bl = body[i:i+2*lw+4] if bl[:lw] != w or bl[lw+2:2*lw+2] != tilde(w): good = False; break code = {('01','01'):'0', ('10','10'):'1', ('01','10'):'2', ('10','01'):'3'}.get((bl[lw:lw+2], bl[2*lw+2:])) if code is None: good = False; break v.append(code) if good and v: assert psi(w, ''.join(v)) + w == core out.add('0' + psi(w, hat(''.join(v))) + w + '1') out.discard(x) return out def part4(x): return '0' + x[1:-1][::-1] + '1' if x[0] == '0' and x[-1] == '1' else x def closure(x): seen, todo = {x}, [x] while todo: y = todo.pop() for z in moves(y): if z not in seen: seen.add(z); todo.append(z) return seen print("\n[3] Not given by (4) or (7), even through chains of them") sound = True; outside = True; exactAB = True for x, y in PAIRS + [LONG]: cx = closure(x); cy = closure(y); px = mu12(x) sound &= all(mu12(z) == px for z in cx | cy) outside &= y not in cx exactAB &= (cx == {x, part4(x)} and cy == {y, part4(y)} and part4(x) != x and part4(y) != y) report("all words reached from A or B by (4) and (7) have the same mu_q(.)_12", sound) report("for the 51 pairs, B is not reached from A by chains of (4) and (7)", outside) report("for the 51 pairs, the words reached are exactly {A, A'} and {B, B'}", exactAB) w, v = '01', '023'; x = '0' + psi(w, v) + w + '1'; y = '0' + psi(w, hat(v)) + w + '1' report("control: an instance of (7) is detected by the procedure and is an identity", y in moves(x) and mu12(x) == mu12(y) and x != y) # ================================================================ [4] basic facts print("\n[4] Basic facts") report("(F1) M_q(0110) - M_q(1001) = (q^3+1) J", ISZERO(MSUB(MSUB(P4, N4), SMUL(padd(mono((0,0,0,0,3)), ONE), JQ)))) detG = psub(pmul(A_, D_), pmul(B_, C_)) report("(F2) G J phi(G) = det(G) J for a generic G (checked as G J q.phi(G) = q.det(G) J)", ISZERO(MSUB(MM(MM(G, JQ), qPHI), SMUL(pmul(Q_, detG), JQ)))) def phi_q(M): # phi on matrices with entries in Z[q]; phi(X) = transpose(Q X Q^{-1}) (a, b), (c, d) = M # Q X Q^{-1} = [[a, q b],[c/q, d]] ; transpose -> [[a, c/q],[q b, d]] assert c[0] == 0 return ((a, tuple(c[1:]) or Z0), (qmul(ZQ, b), d)) report("(F3) phi(M_q(z)) = M_q(bar z) for all z of length <= 8", all(phi_q(Mq(z)) == Mq(bar(z)) for n in range(0, 9) for z in map(''.join, product('01', repeat=n)))) report("(F4) M_q(1 z 1)_12 = (q,1) M_q(z) (1,1)^T for all z of length <= 8", all(M12('1'+z+'1') == qadd(qmul(ZQ, qadd(Mq(z)[0][0], Mq(z)[0][1])), qadd(Mq(z)[1][0], Mq(z)[1][1])) for n in range(0, 9) for z in map(''.join, product('01', repeat=n)))) report("(F4b) mu_q(w)_12 = M_q(sigma(w))_12, and final letters 0 do not change it", all(mu12(w) == M12(sigma(w)) == M12(sigma(w).rstrip('0')) for n in range(1, 8) for w in map(''.join, product('01', repeat=n)))) # ================================================================ [5] Theorem 2 print("\n[5] Theorem 2 (k = 5): identities for a generic 2x2 matrix G") FLIP = {'+': '-', '-': '+'} def flipped(a, F): return ''.join(FLIP[c] if i+1 in F else c for i, c in enumerate(a)) THM2 = [('+-+--+', (1, 3, 5), lambda a: a[0] == a[4] != a[2]), ('+--+-+', (1, 3, 5), lambda a: a[0] == a[4] != a[2]), ('+--++-', (2, 4), lambda a: a[0] == a[4] != a[2] and a[1] == a[3])] for eps, F, cond in THM2: good = set(); bad = set() for a in map(''.join, product('+-', repeat=5)): same = not psub(word_value(eps, a, G, qPHI), word_value(eps, flipped(a, F), G, qPHI)) (good if same else bad).add(a) exact = good == {a for a in map(''.join, product('+-', repeat=5)) if cond(a)} report(f"pattern {eps}, flips {F}: identity holds exactly when the stated condition holds", exact) # ================================================================ [6] Theorem 3 print("\n[6] Theorem 3 (k = 14, T = bar T): identities for a generic G with phi(G) = G") GS = ((A_, B_), (pmul(Q_, B_), D_)) # phi(G) = G <=> c = q b THM3 = [ # (windows of the first word, flipped positions) ('+++-++---+-+++', (2,3,7,8,12,13)), ('+++-+---++-+++', (2,3,7,8,12,13)), ('+++--+-----+++', (2,3,7,8,12,13)), ('+++-----+--+++', (2,3,7,8,12,13)), ('+++-++-----+++', (1,4,11,14)), ('+++-+---+--+++', (1,4,11,14)), ('+++--+---+-+++', (1,4,11,14)), ('+++-----++-+++', (1,4,11,14)), ('+++-+---+++++-', (5,10)), ('++-++--+-+++-+', (5,10)), ('+-+++-+--++-++', (5,10)), ('-+++++---+-+++', (5,10)), ('++-++-+--++-++', (2,3,5,10,12,13)),('++-++--+-++-++', (2,3,5,10,12,13)), ('++-+--+---+-++', (2,3,5,10,12,13)),('++-+---+--+-++', (2,3,5,10,12,13)), ('++-++-+---+-++', (2,3,12,13)), ('++-++--+--+-++', (2,3,12,13)), ('++-+--+--++-++', (2,3,12,13)), ('++-+---+-++-++', (2,3,12,13))] ok3 = all(not psub(word_value('+'*15, a, GS, GS), word_value('+'*15, flipped(a, F), GS, GS)) for a, F in THM3) report("the 20 identities of Theorem 3 hold for a generic G with phi(G) = G", ok3) report("every flip set of Theorem 3 is symmetric under i -> 15 - i", all(set(F) == {15 - i for i in F} for a, F in THM3)) # ================================================================ [7] instances print("\n[7] Each of the 50 classes contains an instance of Theorem 2 or Theorem 3") def parses(z): out = []; n = len(z) if not (z[0] == '1' and z[-1] == '1'): return out for k in range(1, 40): num = n - 2 - 4*k if num < 0 or num % (k+1): continue t = num // (k+1); T = z[1:1+t]; Tb = bar(T); pos = 1; e = ''; a = ''; good = True for i in range(k+1): blk = z[pos:pos+t] if blk == T: e += '+' elif blk == Tb: e += '-' else: good = False; break pos += t if i < k: wdw = z[pos:pos+4] if wdw == '0110': a += '+' elif wdw == '1001': a += '-' else: good = False; break pos += 4 if good and pos == n-1: out.append((k, T, e, a)) return out def instance(x, y): zx, zy = sigma(x).rstrip('0'), sigma(y).rstrip('0') for (k, T, e, a) in parses(zx): for (k2, T2, e2, b) in parses(zy): if (k, T, e) != (k2, T2, e2) or a == b: continue F = tuple(i+1 for i in range(k) if a[i] != b[i]) if k == 5: for eps, FF, cond in THM2: if e == eps and F == FF and cond(a): return ('Th2', eps) if k == 14 and T == bar(T): if (a, F) in THM3 or (b, F) in THM3: return ('Th3', F) return None from collections import Counter tally = Counter(); allfound = True for x, y in PAIRS: hit = None for X in (x, part4(x)): for Y in (y, part4(y)): hit = hit or instance(X, Y) allfound &= hit is not None tally[hit] += 1 for key, c in sorted(tally.items(), key=str): print(f" {c:2d} classes : {key}") report("all 50 classes contain an instance (30 of Theorem 2, 20 of Theorem 3)", allfound and sum(c for k, c in tally.items() if k and k[0] == 'Th2') == 30 and sum(c for k, c in tally.items() if k and k[0] == 'Th3') == 20) # ================================================================ [8] Theorem 4 print("\n[8] Theorem 4 (k = 4m+1): computational inputs and direct checks") K = SMUL(pmul(padd(mono((0,0,0,0,3)), ONE), pmul(Q_, detG)), JQ) # q (q^3+1) det(G) J U = MM(MM(G, N4), qPHI) # q * G N phi(G) UK = MM(MM(G, P4), qPHI) # q * G P phi(G) V = MM(MM(qPHI, N4), G); VK = MM(MM(qPHI, P4), G) report("G P phi(G) = U + K and phi(G) P G = V + K (with the common factor q)", ISZERO(MSUB(UK, MADD(U, K))) and ISZERO(MSUB(VK, MADD(V, K)))) C = []; Cp = [] for X1 in (P4, N4): for X2 in (P4, N4): C.append(MM(MM(MM(UK, X1), U), X2)); Cp.append(MM(MM(MM(U, X1), UK), X2)) tr = lambda M: padd(M[0][0], M[1][1]) t1 = all(not psub(tr(C[i]), tr(Cp[i])) for i in range(4)) t2 = all(not psub(tr(MM(C[i], C[j])), tr(MM(Cp[i], Cp[j]))) for i in range(4) for j in range(i, 4)) report("traces: tr C_i = tr C'_i and tr C_i C_j = tr C'_i C'_j (i <= j)", t1 and t2) t3 = all(not psub(tr(MM(MM(C[i], C[j]), C[k])), tr(MM(MM(Cp[i], Cp[j]), Cp[k]))) for i, j, k in combinations(range(4), 3)) report("traces: tr C_i C_j C_k = tr C'_i C'_j C'_k (i < j < k)", t3) # C_1..C_4 span M_2: a nonzero value of the 4x4 determinant at one point suffices def ev(p, pt): s = 0 for (ea, eb, ec, ed, eq), co in p.items(): s += co * pt[0]**ea * pt[1]**eb * pt[2]**ec * pt[3]**ed * pt[4]**eq return s from fractions import Fraction def det4(M): M = [[Fraction(x) for x in r] for r in M]; n = 4; d = Fraction(1) for c in range(n): p = next((r for r in range(c, n) if M[r][c] != 0), None) if p is None: return 0 if p != c: M[c], M[p] = M[p], M[c]; d = -d d *= M[c][c] for r in range(c+1, n): f = M[r][c] / M[c][c] for j in range(c, n): M[r][j] -= f * M[c][j] return d pt = (2, 3, 5, 7, 11) report("C_1, ..., C_4 are linearly independent (4x4 determinant nonzero at a point)", det4([[ev(Ci[i][j], pt) for i in range(2) for j in range(2)] for Ci in C]) != 0) VKu = (padd(VK[0][0], VK[0][1]), padd(VK[1][0], VK[1][1])) report("(V+K)(1,1)^T is nonzero", bool(VKu[0]) or bool(VKu[1])) report("det C_i = det C'_i (the same factors in another order): checked symbolically", all(not psub(psub(pmul(C[i][0][0], C[i][1][1]), pmul(C[i][0][1], C[i][1][0])), psub(pmul(Cp[i][0][0], Cp[i][1][1]), pmul(Cp[i][0][1], Cp[i][1][0]))) for i in range(4))) # direct checks of the words of Theorem 4 over Z[q], random T def thm4_words(T, m, free): k = 4*m + 1; eps = '+-'*(2*m) + '-+' a = []; fi = 0 for i in range(k): if i % 2 == 0: a.append('0110' if (i//2) % 2 == 0 else '1001') else: a.append(free[fi]); fi += 1 b = [('1001' if x == '0110' else '0110') if i % 2 == 0 else x for i, x in enumerate(a)] Tb = bar(T) def build(ws): s = '1' + (T if eps[0] == '+' else Tb) for i, x in enumerate(ws): s += x + (T if eps[i+1] == '+' else Tb) return s + '1' return build(a), build(b) random.seed(20261031) okd = True; nchk = 0 for m in (1, 2, 3): for _ in range(12 if m < 3 else 4): T = ''.join(random.choice('01') for _ in range(random.randint(0, 6))) free = [random.choice(('0110', '1001')) for _ in range(2*m)] u, v = thm4_words(T, m, free); okd &= M12(u) == M12(v); nchk += 1 report(f"Theorem 4 checked directly on {nchk} random instances (m = 1, 2, 3)", okd) x50 = LONG[0] report("the pair of length 50 is an instance of Theorem 4 with m = 2", any(instance_pair == {sigma(LONG[0]).rstrip('0'), sigma(LONG[1]).rstrip('0')} for instance_pair in [set(thm4_words('0101011001', 2, f)) for f in product(('0110', '1001'), repeat=4)])) bad3 = 0 for T in ('0', '001', '0010110'): # T != bar T for fr in ('0110', '1001'): Tb = bar(T) u = '1' + T + '0110' + Tb + fr + Tb + '1001' + T + '1' # analogue with k = 3 v = '1' + T + '1001' + Tb + fr + Tb + '0110' + T + '1' bad3 += M12(u) != M12(v) report("control: the analogous statement with k = 3 is false (6 cases out of 6)", bad3 == 6) print(f"\nALL CHECKS {'PASSED' if ok_all else 'FAILED'} ({time.time()-T0:.0f} s)") sys.exit(0 if ok_all else 1)