The validation package of Relativistic Algebra over Finite Ring Continuum: one script, algebra.py, 3 blocks, standard library only, one check per predicate of the paper's predicate ledger — 18 of 18 checks passing. The script is rendered below with an anchor per line; its markers (# 1:B2 (p01004): the predicate and its key) are the checks the ledger predicates cite, and the block index opens each block at its definition. The notebook frc-1-algebra.ipynb runs one cell per predicate on Google Colab (its generator make_notebook.py). Installed from this site as a named requirement: pip install frc-1-algebra --find-links https://finitering.space/pkg/ (the sdist frc-1-algebra-20261012.tar.gz).
Blocks: A (5) · B (4) · C (7) — the predicates each decides in parentheses.
1"""2algebra.py — the validation package of "Relativistic Algebra over Finite Ring Continuum" (Akhtman, Axioms 2025, 14, 636;3doi 10.3390/axioms14080636), the paper 1-algebra of the FRC corpus (finite-ring-space/src/1-algebra), added with the paper's4predicate ledger (Appendix A, 16 September 2026; one script since 24 September 2026, the three block scripts merged).5========================================================================================================================67One script, three blocks, eighteen checks, standard library only. Each check names the predicate(s) of the paper's ledger8it witnesses (LEDGER below; predicates cited as 1:XN) under a `# 1:XN (<key>)` marker, and the ledger's source column9links the marker in return (finitering.space/src/1-algebra/#<key>). The paper \\label(s) a check decides are10in the block banners. Eight master-ledger predicates of the corpus cite this paper (00:A8, B1, B8, B11, C9, C10, C25, D13); the11predicates of the paper ledger that the master carries are listed in the site generator.1213 python3 algebra.py every block, results.json written; exit 1 if a check fails (≈ 25 s)14 python3 algebra.py C one block (A, B or C); no results.json15 from frc_1_algebra import predicate; predicate("1:B2") one predicate: its block runs once per session1617Blocks: A the shell, its frame and the orbital complex EXACT (1:B2–B4, C2, C4)18 B the framed numbers, the charts and the horizon EXACT / CHART (1:D2, D4, D6, E2, Z1; B6 decides no predicate)19 C the conjecture of the conclusion, clause by clause EXACT / CHART (1:E3, D7, E4–E8)2021Everything the blocks share:22 * the shell datum: p = 4κ+1 prime, the primitive roots of F_p, the oriented quarter-turn i = −g^κ;23 * exact arithmetic in F_p (python int, reduced mod p) and in Q (fractions.Fraction);24 * the PASS/FAIL registry every block reports into (results.json).2526Kinds: EXACT checks are integer-pinned computations in F_p or exact rationals (a pass is a proof on the27tested instances); CHART checks decide a [chart] predicate — a statement about the reading of the shell against28Q or R — in exact rationals.29"""30import os, json, sys, math, random, itertools31from fractions import Fraction32from decimal import Decimal, getcontext3334SCRIPT = os.path.splitext(os.path.basename(__file__))[0] # "algebra": the one script, the name results.json and the site pages carry3536# The shells: p = 4κ+1 prime; the controls: p ≡ 3 (mod 4).37SHELLS = [5, 13, 17, 29, 37, 41, 173]38CONTROLS = [7, 11, 19, 23]3940# ----------------------------------------------------------------------------- registry41RESULTS = []4243# The paper's predicate ledger (Appendix A, predicates cited as 1:XN): the predicate(s) each check witnesses.44LEDGER = {45 "A1": "1:B2", "A2": "1:B3", "A3": "1:B4", "A4": "1:C2", "A5": "1:C4",46 "B1": "1:D2", "B2": "1:D4", "B3": "1:D6", "B4": "1:E2", "B5": "1:Z1", "B6": "", # B6 (the Euclidean step count) decides no predicate of the ledger47 "C1": "1:E3", "C2": "1:D7", "C3": "1:E4", "C4": "1:E5", "C5": "1:E6", "C6": "1:E7", "C7": "1:E8",48}4950BLOCK = {"A": "the shell, its frame and the orbital complex", # check-id prefix -> the block (the function block_<letter> below)51 "B": "the framed numbers, the charts and the horizon",52 "C": "the conjecture of the conclusion, clause by clause"}5354# the deciding check of each witnessed predicate: the one whose verdict decides the predicate's statement (the other checks that55# touch it are corroboration, listed by predicate() from the records)56PREDICATES = {57 "1:B2": "A1", "1:B3": "A2", "1:B4": "A3", "1:C2": "A4", "1:C4": "A5",58 "1:D2": "B1", "1:D4": "B2", "1:E2": "B4", "1:Z1": "B5", # D6: B3 witnesses it in LEDGER but carries no marker (as before the merge)59 "1:E3": "C1", "1:D7": "C2", "1:E4": "C3", "1:E5": "C4", "1:E6": "C5", "1:E7": "C6", "1:E8": "C7",60}61_RAN = set() # blocks already run in this session (predicate() runs each once)6263def check(pid, label, ok, detail="", kind="EXACT"):64 """Record one predicate check. pid = package check id; LEDGER[pid] = the paper statement(s) decided."""65 ok = bool(ok)66 rows = LEDGER.get(pid, "")67 RESULTS.append({"id": pid, "rows": rows, "block": pid[0], "script": SCRIPT, "label": label, "ok": ok, "detail": detail, "kind": kind})68 print(f" [{'PASS' if ok else 'FAIL'}] {pid:4s} {kind:6s} [{rows}] {label}" + (f" -- {detail}" if detail else ""))69 return ok7071def summary(write=True):72 n_ok = sum(r["ok"] for r in RESULTS)73 print(f"\nSUMMARY: {n_ok}/{len(RESULTS)} checks passed" + ("" if n_ok == len(RESULTS) else " <-- FAILURES"))74 if write:75 with open("results.json", "w") as f:76 json.dump(RESULTS, f, indent=1)77 return n_ok == len(RESULTS)7879def markers():80 """predicate label -> (script file, line) of its marker `# <paper>:<label> (<key>)`: the line of the check that decides it."""81 import re82 out = {}83 for i, line in enumerate(open(os.path.abspath(__file__), encoding="utf-8"), 1):84 m = re.match(r"\s*# ((?:\d+:[A-Z]+\d+[a-z]?(?: \(p\d{5}\))?)(?:, \d+:[A-Z]+\d+[a-z]?(?: \(p\d{5}\))?)*)\s*$", line)85 if m:86 for lab in re.findall(r"\d+:[A-Z]+\d+[a-z]?", m.group(1)): out.setdefault(lab, (SCRIPT + ".py", i))87 return out8889def _run_block(letter):90 if letter not in _RAN:91 globals()[f"block_{letter}"](); _RAN.add(letter)9293def predicate(label, lines=14):94 """Verify one ledger predicate: run the block of the check that decides it (once per session), print that check's source95 (from its marker) and every record that cites the predicate, and return True iff all pass."""96 pid = PREDICATES.get(label)97 if pid is None:98 print(f"{label}: no python witness (see the predicate's Lean witness or its source)"); return None99 citing = {i[0] for i, rows in LEDGER.items() if label in [t.strip() for t in rows.split(",")]}100 for b in sorted({pid[0]} | citing): _run_block(b) # the deciding block and every block whose checks cite the predicate101 mk = markers().get(label)102 if mk:103 src = open(os.path.abspath(__file__), encoding="utf-8").read().split("\n")104 print(f"— {mk[0]}:{mk[1]} (the check that decides {label}: {pid})")105 for j in range(mk[1] - 1, min(mk[1] - 1 + lines, len(src))): print(f"{j + 1:5d} {src[j]}")106 recs = [r for r in RESULTS if label in [t.strip() for t in r["rows"].split(",")]]107 ok = all(r["ok"] for r in recs)108 for r in recs:109 role = "(deciding)" if r["id"] == pid else "(corroborating)"110 print(f" [{'PASS' if r['ok'] else 'FAIL'}] {r['id']:4s} {role:16s} {r['detail'][:150]}")111 print(f"{label}: {'VERIFIED' if ok and recs else 'FAILED'} — {len(recs)} record(s)")112 return ok113114def verify_all():115 """Run every block (those already run in this session are not re-run) and print the summary; True iff every check passed."""116 for b in sorted(BLOCK): _run_block(b)117 return summary(write=False)118119# ----------------------------------------------------------------------------- the shell datum120def is_prime(n):121 if n < 2: return False122 d = 2123 while d * d <= n:124 if n % d == 0: return False125 d += 1126 return True127128def prime_factors(n):129 f, d = set(), 2130 while d * d <= n:131 while n % d == 0:132 f.add(d); n //= d133 d += 1134 if n > 1: f.add(n)135 return f136137def primitive_roots(p):138 n = p - 1139 fac = prime_factors(n)140 return [g for g in range(2, p) if all(pow(g, n // q, p) != 1 for q in fac)]141142def kappa(p):143 assert p % 4 == 1 and is_prime(p), p144 return (p - 1) // 4145146def quarter_turn(p, g):147 """i = −g^κ, the oriented quarter-turn of the frame (τ; 0, 1, g)."""148 return (-pow(g, kappa(p), p)) % p149150def sqrt_neg_one(p):151 return sorted(x for x in range(1, p) if (x * x) % p == p - 1)152153# ------------------------------------------------------------------------------------------------------------154# block A: the shell, its frame and the orbital complex (EXACT, integer-pinned)155# Paper statements decided (Sections 2–3; ledger predicates 1:B2–B4, 1:C2, 1:C4):156#157# A1 thm:symmetric-completeness the fourth roots of unity are Q4 = {1, i, −1, −i}; under the Klein four-group158# (1:B2) ⟨x ↦ −x, x ↦ x⁻¹⟩, Q4 is the union of the two size-2 orbits {±1}, {±i}, and159# F_p^× \ Q4 splits into exactly κ−1 orbits of size 4; for p ≡ 3 (mod 4) no i160# A2 (1:B3) i = −g^κ satisfies i² = −1 for every primitive root g; {−g^κ, g^κ} are the two161# square roots of −1; on F_13 with g = 2, i = 5162# A3 def:framed-field, φ_{a,b}(x) = a + bx is a ring isomorphism (F_p, +, ·) → (F_p, ⊕, ⊗) on every163# lem:affine-invariance (1:B4) frame (a, b), b ≠ 0; the unit of the relabelled field is a + b, and b is the164# unit only when a = 0165# A4 prop:frame-group (1:C2) ⟨T_a, S_m⟩ = Aff(F_p) of order p(p−1), simply transitive on the frames166# A5 def:orbit-sphere (1:C4) M_n(a) = M_{n+2κ}(−a), L_a(m) = L_{−a}(m+2κ); p−1 distinct meridian lists in167# 2κ great circles; 2κ latitude pairs; vertex count (p−1)²/2 + 1168#169# Shells: p ∈ {5, 13, 17, 29, 37, 41, 173} for A1–A2; p ∈ {13, 17} for A3–A5 (exhaustive over frames and pairs).170def klein_orbits(p):171 seen, orbits = set(), []172 for x in range(1, p):173 if x in seen: continue174 inv = pow(x, -1, p)175 orb = {x, (-x) % p, inv, (-inv) % p}176 seen |= orb; orbits.append(orb)177 return orbits178179def block_A():180 """Block A — the shell, its frame and the orbital complex (EXACT, integer-pinned): A1–A5."""181 print("block A — the shell, its frame and the orbital complex")182183 # A1 — symmetry completeness184 ok, det = True, []185 for p in SHELLS:186 k = kappa(p); orbits = klein_orbits(p)187 Q4 = {1, p - 1} | set(sqrt_neg_one(p))188 small = [o for o in orbits if len(o) < 4]189 big = [o for o in orbits if len(o) == 4]190 ok &= (len(Q4) == 4 and set().union(*small) == Q4 and sorted(len(o) for o in small) == [2, 2])191 ok &= (len(big) == k - 1 and len(big) + len(small) == k + 1)192 ok &= all(pow(x, 4, p) == 1 for x in Q4) and sum(1 for x in range(1, p) if pow(x, 4, p) == 1) == 4193 det.append(f"p={p}: Q4={sorted(Q4)}, {len(big)} orbits of size 4 = κ−1")194 for p in CONTROLS:195 orbits = klein_orbits(p)196 ok &= (sqrt_neg_one(p) == [] and sorted(len(o) for o in orbits) == [2] + [4] * ((p - 3) // 4))197 # 1:B2 (p01004)198 check("A1", "Q4 = {1,i,−1,−i} the unique order-4 subgroup, two Klein orbits of size 2, κ−1 orbits of size 4; no i for p ≡ 3 (mod 4)",199 ok, "; ".join(det) + f"; controls p ∈ {CONTROLS}")200201 # A2 — the oriented quarter-turn202 ok, det = True, []203 for p in SHELLS:204 k = kappa(p); roots = set(sqrt_neg_one(p)); n = 0205 for g in primitive_roots(p):206 i = quarter_turn(p, g)207 ok &= ((i * i) % p == p - 1) and ({i, pow(g, k, p)} == roots) and (pow(g, 2 * k, p) == p - 1); n += 1208 det.append(f"p={p}: {n} primitive roots")209 ok &= (quarter_turn(13, 2) == 5)210 # 1:B3 (p01005)211 check("A2", "i = −g^κ, i² = −1 for every primitive root; {−g^κ, g^κ} the two square roots of −1; g^{2κ} = −1; F_13, g = 2: i = 5",212 ok, "; ".join(det))213214 # A3 — the affine frame: ring isomorphism, the unit a + b215 ok, n = True, 0216 for p in [13, 17]:217 for a in range(p):218 for b in range(1, p):219 inv = lambda X: ((X - a) * pow(b, -1, p)) % p220 phi = lambda x: (a + b * x) % p221 oplus = lambda X, Y: (a + b * (inv(X) + inv(Y))) % p222 otimes = lambda X, Y: (a + b * (inv(X) * inv(Y))) % p223 ok &= all(phi((x + y) % p) == oplus(phi(x), phi(y)) and phi((x * y) % p) == otimes(phi(x), phi(y))224 for x in range(p) for y in range(p))225 ok &= (len({phi(x) for x in range(p)}) == p)226 ok &= all(otimes((a + b) % p, y) == y for y in range(p))227 ok &= ((a == 0) == all(otimes(b, y) == y for y in range(p)))228 n += 1229 # 1:B4 (p01006)230 check("A3", "φ_{a,b} = a + bx a ring isomorphism onto (F_p, ⊕, ⊗) on every frame; unit a + b; b the unit iff a = 0",231 ok, f"{n} frames on p ∈ {{13, 17}}, all pairs (x, y)")232233 # A4 — the frame group234 ok, det = True, []235 for p in [13, 17]:236 frames = [(a, b) for a in range(p) for b in range(1, p)]237 comp = lambda f, g: ((f[0] + f[1] * g[0]) % p, (f[1] * g[1]) % p) # f∘g as affine maps x ↦ a + b x238 ok &= (len(frames) == p * (p - 1))239 ok &= all(comp(f, g) in set(frames) for f in frames for g in frames) # closure240 # simple transitivity: for each (φ, φ') exactly one ψ with ψ∘φ = φ'241 cnt = 0242 for f in frames:243 for f2 in frames:244 sols = [psi for psi in frames if comp(psi, f) == f2]245 ok &= (len(sols) == 1); cnt += 1246 det.append(f"p={p}: |Aff| = {len(frames)} = p(p−1), {cnt} frame pairs, one carrier each")247 # 1:C2 (p01009)248 check("A4", "⟨T_a, S_m⟩ = Aff(F_p), order p(p−1), simply transitive on the frames (a, b)", ok, "; ".join(det))249250 # A5 — the orbital complex: involutions and counts251 ok, det = True, []252 for p in [13, 17]:253 k = kappa(p); g = primitive_roots(p)[0]; n2 = 2 * k254 M = lambda n, a: (a * pow(g, n, p)) % p255 L = lambda a, m: (a * pow(g, m, p)) % p256 ok &= all(M(n, a) == M(n + n2, (-a) % p) for n in range(p - 1) for a in range(p))257 ok &= all(L(a, m) == L((-a) % p, m + n2) for a in range(1, p) for m in range(p - 1))258 mer = {tuple(M(n, a) for a in range(p)) for n in range(p - 1)}259 circles = {frozenset({tuple(M(n, a) for a in range(p)), tuple(M(n + n2, a) for a in range(p))}) for n in range(p - 1)}260 latpairs = {frozenset({tuple(L(a, m) for m in range(p - 1)), tuple(L((-a) % p, m) for m in range(p - 1))}) for a in range(1, p)}261 ok &= (len(mer) == p - 1 and len(circles) == 2 * k and len(latpairs) == 2 * k)262 V = (p - 1) * (2 * k) + 1263 ok &= (V == (p - 1) ** 2 // 2 + 1)264 det.append(f"p={p}: {len(mer)} meridian lists, {len(circles)} great circles, {len(latpairs)} latitude pairs, |V| = {V}")265 # 1:C4 (p01011)266 check("A5", "M_n(a) = M_{n+2κ}(−a), L_a(m) = L_{−a}(m+2κ); p−1 meridian lists in 2κ circles; 2κ latitude pairs; |V| = (p−1)²/2 + 1",267 ok, "; ".join(det))268269# ------------------------------------------------------------------------------------------------------------270# block B: the framed numbers, the charts and the horizon (EXACT; B3 CHART in exact rationals)271# Paper statements decided (Sections 4–5; ledger predicates 1:D2, 1:D4, 1:D6, 1:E2, 1:Z1; B6 decides no predicate):272#273# B1 def:integers (1:D2) the window W_H = {|z| ≤ H}: z ↦ z mod p injective iff 2H < p; sums read back274# iff 4H < p; products read back whenever 2H² < p (sufficient; the product set is275# sparse, so the bound is not sharp) — swept over every H276# B2 thm:scale-periodicity (1:D4) the residue grids G_n = (x g^{−n})_x are (p−1)-periodic in n; the rational277# grids (x/g^n) with g lifted to Z are not278# B3 prop:r-rationals, thm:approx the chart of the grid [chart]: every r with |r| ≤ H g^{−n} lies within 1/(2gⁿ)279# (1:D6) of some x/gⁿ, x ∈ W_H (exact rationals); at (13, 2) no grid point of step ≤ 1/8280# lies within 1/16 of 33/10 — range and resolution trade off at fixed window281# B4 prop:Cp-field (1:E2) F_p[X]/(X²+1) has zero divisors on the shell ((u+X)(u−X) = 0, factors nonzero);282# X²+1 has no root, hence the quotient is a field, exactly for p ≡ 3 (mod 4)283# B5 thm:no-south-pole (1:Z1) 2s = 0 ⇒ s = 0 on every odd prime; 2·(2κ+1) = 1: the half-turn 2⁻¹ = 2κ+1284# B6 (no predicate) the Euclidean step count against the bound k ≤ ⌊log₂ p⌋+1 (lem:euclid-bound):285# p = 59 (55, 34) needs 7 > 6; p = 1009 (987, 610) needs 13 > 10; first excess at 59286def block_B():287 """Block B — the framed numbers, the charts and the horizon (EXACT; B3 CHART in exact rationals): B1–B6."""288 print("block B — the framed numbers, the charts and the horizon")289290 # B1 — the window law, the three thresholds as iff over every H291 ok, det = True, []292 for p in [13, 17, 29]:293 for H in range(1, p):294 W = range(-H, H + 1)295 inj = len({z % p for z in W}) == len(W)296 sums = len({(x + y) % p for x in W for y in W}) == len({x + y for x in W for y in W})297 prods = len({(x * y) % p for x in W for y in W}) == len({x * y for x in W for y in W})298 ok &= (inj == (2 * H < p)) and (sums == (4 * H < p)) and ((2 * H * H < p) <= prods) # products: sufficient, not necessary (the product set is sparse)299 det.append(f"p={p}: H = 1..{p-1} swept")300 # 1:D2 (p01013)301 check("B1", "z ↦ z mod p injective on W_H iff 2H < p; sums read back iff 4H < p; products read back whenever 2H² < p", ok, "; ".join(det))302303 # B2 — scale-periodicity: in the field yes, in Q no304 ok, det = True, []305 for p, g in [(13, 11), (13, 2), (17, 3), (29, 2)]:306 assert g in primitive_roots(p)307 grid = lambda n: tuple((x * pow(g, -n, p)) % p for x in range(p))308 ok &= all(grid(n) == grid(n + p - 1) for n in range(2 * (p - 1)))309 ok &= all(grid(n) != grid(n + d) for n in range(p - 1) for d in range(1, p - 1)) # exact period p−1310 qgrid = lambda n: tuple(Fraction(x, g ** n) for x in range(p))311 ok &= all(qgrid(n) != qgrid(n + p - 1) for n in range(3))312 det.append(f"({p},{g}): period {p-1} in F_p, none in Q")313 # 1:D4 (p01015)314 check("B2", "G_n = (x g^{−n})_x is (p−1)-periodic in the field, with exact period p−1; the rational grids x/gⁿ are not periodic",315 ok, "; ".join(det))316317 # B3 — the chart of the grid: the trade-off holds; its range at (13, 2)318 ok, det = True, []319 p, g, H = 13, 2, 12320 for n in range(0, 8):321 step = Fraction(1, g ** n)322 for num in range(-40, 41): # r = num/8 · H g^{−n}, a sample within the range323 r = Fraction(num, 40) * H * step324 x = round(r / step) # x = round(r gⁿ), |x| ≤ H325 ok &= (abs(x) <= H) and (abs(r - x * step) <= step / 2)326 r, tol = Fraction(33, 10), Fraction(1, 16)327 near = [(x, n) for n in range(3, 13) for x in range(p) if abs(Fraction(x, g ** n) - r) < tol]328 ok &= (near == []) and all(Fraction(x, g ** n) <= Fraction(3, 2) for n in range(3, 13) for x in range(p))329 best = min((abs(Fraction(x, g ** n) - r), x, n) for n in range(13) for x in range(p))330 ok &= (best[1:] == (7, 1) and best[0] == Fraction(1, 5))331 det.append(f"trade-off on {8*81} sampled reals at (13,2), H=12; range: no x/2^n (n ≥ 3, x < 13) within 1/16 of 33/10, best 7/2 at error 1/5")332 check("B3", "|r| ≤ H g^{−n} ⇒ some x/gⁿ, x ∈ W_H, within 1/(2gⁿ); at (13, 2) no point of step ≤ 1/8 within 1/16 of r = 33/10: range and resolution trade off at fixed window",333 ok, "; ".join(det), kind="CHART")334335 # B4 — the complex chart is not an extension: zero divisors iff −1 is a square336 ok, det = True, []337 for p in [5, 13, 17, 29, 37]:338 u = sqrt_neg_one(p)[0]339 # in F_p[X]/(X²+1): elements a + bX, product (a+bX)(c+dX) = (ac − bd) + (ad + bc)X340 mul = lambda A, B: ((A[0] * B[0] - A[1] * B[1]) % p, (A[0] * B[1] + A[1] * B[0]) % p)341 ok &= (mul((u, 1), ((-u) % p, 1)) == (0, 0)) and (u, 1) != (0, 0) and ((-u) % p, 1) != (0, 0)342 det.append(f"p={p}: (u+X)(u−X)=0 with u={u}")343 for p in CONTROLS:344 ok &= (sqrt_neg_one(p) == []) # X²+1 irreducible: the quotient is the field F_{p²}345 mul = lambda A, B: ((A[0] * B[0] - A[1] * B[1]) % p, (A[0] * B[1] + A[1] * B[0]) % p)346 elems = [(a, b) for a in range(p) for b in range(p) if (a, b) != (0, 0)]347 ok &= all(mul(A, B) != (0, 0) for A in elems for B in elems) # no zero divisors348 # 1:E2 (p01019)349 check("B4", "F_p[X]/(X²+1) has zero divisors on the shell (p ≡ 1 mod 4); it is a field exactly when p ≡ 3 (mod 4)",350 ok, "; ".join(det) + f"; fields at p ∈ {CONTROLS} (no zero divisors, exhaustive)")351352 # B5 — no element of additive order two; the half-turn353 ok, det = True, []354 for p in [q for q in range(3, 200) if is_prime(q)]:355 ok &= ([s for s in range(p) if (2 * s) % p == 0] == [0])356 if p % 4 == 1:357 k = kappa(p)358 ok &= ((2 * (2 * k + 1)) % p == 1) and (2 * k + 1 == (p + 1) // 2)359 # 1:Z1 (p01020)360 check("B5", "2s = 0 ⇒ s = 0 for every odd prime < 200; on the shell 2⁻¹ = 2κ+1 = (p+1)/2, the residue past the antipode", ok, "primes 3..199")361362 # B6 — the Euclidean step count against the bound ⌊log₂ p⌋+1 (recorded under V1)363 def steps(a, b):364 k = 0365 while b:366 a, b = b, a % b367 if b: k += 1368 return k369 fib = [1, 1]370 while fib[-1] < 2000: fib.append(fib[-1] + fib[-2])371 first = None372 for p in [q for q in range(5, 2000) if is_prime(q)]:373 worst = max(steps(fib[i + 1], fib[i]) for i in range(1, len(fib) - 1) if fib[i + 1] < p)374 if worst > p.bit_length():375 first = p; break376 ok = (steps(55, 34) == 7 and (59).bit_length() == 6 and steps(987, 610) == 13 and (1009).bit_length() == 10 and first == 59)377 ok &= (fib[3] == 3 and fib[3] < 2 ** 2) # F_4 = 3 < 2^{4−2}: the Fibonacci bound 2^{k−2} does not hold at k = 4378 check("B6", "the Euclidean step count against ⌊log₂p⌋+1: (55,34) needs 7 > ⌊log₂59⌋+1 = 6; (987,610) needs 13 > 10; first excess at p = 59; F_4 = 3 < 4",379 ok, "a ≥ b convention, consecutive Fibonacci pairs below p")380381# ------------------------------------------------------------------------------------------------------------382# block C: the conjecture of the conclusion, clause by clause (EXACT; C2–C4 CHART)383# The conclusion conjectures that the finite substrate supports polynomial equation solving, limit-like384# approximation and ε-approximation of continuous symmetries. Predicates 1:E3, D7 and E4–E8 decide it:385#386# C1 (1:E3) solving: f ∈ F_p[X] has a root in F_p iff gcd(f, X^p − X) ≠ 1, and deg gcd = the number of387# distinct roots — every monic polynomial of degree ≤ 3 over F_13 (2197) and F_17 (4913), by388# brute-force roots against the Euclidean gcd [exact]389# C2 (1:D7) limit-like approximation across shells: for r ∈ {π, e, √2, 33/10, 1/3} and ε = 10^−k390# (k = 2..8) the construction n = ⌈log₂(1/ε)⌉, x = round(r·2ⁿ), p = the first prime ≡ 1 (mod 4)391# beyond 2|x|+1 gives |r − x/2ⁿ| < ε with |x| ≤ 2κ [chart: r read as a rational to 60 digits]392# C3 (1:E4) the circle net: for N = p − 1 on every shell the rounding k(θ) = ⌊Nθ/2π + ½⌋ has angle error393# ≤ π/N, chord error |e^{2πik/N} − e^{iθ}| ≤ π/N, and group-law defect |k(θ₁)+k(θ₂)−k(θ₁+θ₂)| ≤ 1,394# on a grid of 4N angles plus 20000 random pairs [chart]395# C4 (1:E5) the SO(3) obstruction: the covering radii of the finite rotation groups in the rotation-angle396# metric — tetrahedral π/2, octahedral arccos((2√2−1)/4) ≈ 62.80°, icosahedral397# ε₀ = arccos((3√5−1)/8) ≈ 44.48° (the deep hole of the 600-cell, cos = φ²/2√2), cyclic and398# dihedral ≥ π/2 (they lie in an O(2)) — by exhaustive group closure and a sampled maximin;399# no finite subgroup of SO(3) is an ε-net for ε < ε₀ [chart; the list of groups is A3, Klein]400# C5 (1:E6) the window resolves SO(3): the framed quaternions W_H⁴ = {q ∈ Z⁴ : |q_i| ≤ H}, normalised, are an401# ε-net of SO(3) with ε ≤ 2·arcsin(1/H) (round H·s to the lattice: |Hs − q| ≤ 1, so the angle is402# ≤ arcsin(1/H)); measured ε(1) ≈ 60.8°, ε(2) ≈ 41.0°, ε(3) ≈ 30.0°; 2·arcsin(1/3) = 38.9° < ε₀, so on403# the shell p = 73 the window H = 3 out-resolves every finite subgroup; products of window quaternions404# have entries in W_{4H²} and read back exactly from the shell when 8H² < p (20000 random pairs on405# F_73, H = 3) [chart; the read-back is exact]406# C6 (1:E7) the Lie-algebra layer, one axis: every window rotation ρ_q, q = a + v, equals (aI − S_v)⁻¹(aI + S_v) — the407# Cayley step of ηS_v at α = η/(νa), computed in F_p[η] — and I + 2N(v)⁻¹S_v² at a = 0; on every axis the408# steps, the identity and the half-turn are the powers of one element of order p − (N(v)|p), every409# iterate stays among them, and at most 2H² + 2H are window rotations (p = 13, 17, 37, 73, 101) [exact]410# C7 (1:E8) two axes and range: ρ_(1+u)ρ_(1+w) = ρ_(1+u∘w), u∘w = (u + w + u×w)/(1 − u·w); the half-turn about411# u + w + u×w at u·w = 1; uw − wu = 2u×w (F_13, F_29, F_73, F_233); the entries of q^m are at most (2H)^m and412# q^m reads back from the shell iff 2‖q^m‖∞ < p (H ≤ 3, m ≤ 6; p = 13, 101, 1009) [exact]413414# ---------------------------------------------------------------- polynomial arithmetic over F_p (lists, low degree first)415def p_trim(a):416 while a and a[-1] == 0: a.pop()417 return a418def p_mod(a, b, p):419 a = a[:]; db = len(b) - 1; inv = pow(b[-1], -1, p)420 while len(a) - 1 >= db and a:421 c = (a[-1] * inv) % p; s = len(a) - 1 - db422 for i, bi in enumerate(b): a[s + i] = (a[s + i] - c * bi) % p423 p_trim(a)424 return a425def p_gcd(a, b, p):426 a, b = p_trim(a[:]), p_trim(b[:])427 while b: a, b = b, p_mod(a, b, p)428 if a: inv = pow(a[-1], -1, p); a = [(c * inv) % p for c in a]429 return a430def p_eval(a, x, p):431 r = 0432 for c in reversed(a): r = (r * x + c) % p433 return r434435def block_C():436 """Block C — the conjecture of the conclusion, clause by clause (EXACT; C2–C5 CHART): C1–C5."""437 print("block C — the conjecture of the conclusion, clause by clause")438439 # C1 — solving: roots exist iff gcd(f, X^p − X) ≠ 1; deg gcd counts the distinct roots440 ok, det = True, []441 for p, dmax in [(13, 3), (17, 3)]:442 xp_minus_x = [0] * (p + 1); xp_minus_x[p] = 1; xp_minus_x[1] = (xp_minus_x[1] - 1) % p443 n = 0444 for d in range(1, dmax + 1):445 for coeffs in itertools.product(range(p), repeat=d):446 f = list(coeffs) + [1] # monic of degree d447 roots = {x for x in range(p) if p_eval(f, x, p) == 0}448 g = p_gcd(f, xp_minus_x, p)449 ok &= ((len(g) - 1) == len(roots)) and ((len(roots) > 0) == (len(g) > 1)); n += 1450 det.append(f"p={p}: {n} monic polynomials of degree ≤ {dmax}")451 # 1:E3 (p01026)452 check("C1", "f has a root in F_p iff gcd(f, X^p − X) ≠ 1; deg gcd(f, X^p − X) = number of distinct roots (exhaustive, degree ≤ 3)",453 ok, "; ".join(det))454455 # C2 — limit-like approximation across the tower of shells456 getcontext().prec = 60457 reals = {"π": Fraction(Decimal("3.14159265358979323846264338327950288419716939937510582097494")),458 "e": Fraction(Decimal("2.71828182845904523536028747135266249775724709369995957496697")),459 "√2": Fraction(Decimal("1.41421356237309504880168872420969807856967187537694807317668")),460 "33/10": Fraction(33, 10), "1/3": Fraction(1, 3)}461 def next_shell(m): # the first prime ≡ 1 (mod 4) beyond m462 q = m + 1463 while not (q % 4 == 1 and is_prime(q)): q += 1464 return q465 ok, det = True, []466 for name, r in reals.items():467 for k in range(2, 9):468 eps = Fraction(1, 10 ** k); n = math.ceil(math.log2(10 ** k)); x = round(r * 2 ** n)469 p = next_shell(2 * abs(x) + 1); kap = (p - 1) // 4470 ok &= (abs(r - Fraction(x, 2 ** n)) < eps) and (abs(x) <= 2 * kap) and p % 4 == 1 and is_prime(p)471 det.append(f"{name}: ε=10⁻⁸ → n={n}, p={p}")472 # 1:D7 (p01027)473 check("C2", "for every r and ε some shell p = 4κ+1 carries x/2ⁿ, |x| ≤ 2κ, within ε of r (five reals, ε = 10⁻²..10⁻⁸)",474 ok, "; ".join(det), kind="CHART")475476 # C3 — the circle net and the group-law defect on every shell477 ok, det = True, []478 rnd = random.Random(1)479 for p in SHELLS:480 N = p - 1481 k = lambda th: math.floor(N * th / (2 * math.pi) + 0.5)482 worst_angle = worst_chord = 0.0; worst_defect = 0483 thetas = [2 * math.pi * j / (4 * N) for j in range(4 * N)] + [rnd.uniform(0, 2 * math.pi) for _ in range(2000)]484 for th in thetas:485 kk = k(th); worst_angle = max(worst_angle, abs(th - 2 * math.pi * kk / N))486 worst_chord = max(worst_chord, abs(complex(math.cos(2 * math.pi * kk / N), math.sin(2 * math.pi * kk / N)) - complex(math.cos(th), math.sin(th))))487 for _ in range(20000):488 a, b = rnd.uniform(0, 2 * math.pi), rnd.uniform(0, 2 * math.pi)489 worst_defect = max(worst_defect, abs(k(a) + k(b) - k(a + b)))490 ok &= (worst_angle <= math.pi / N + 1e-12) and (worst_chord <= math.pi / N + 1e-12) and (worst_defect <= 1)491 det.append(f"p={p}: angle {worst_angle:.4f} ≤ π/N={math.pi / N:.4f}, defect ≤ {worst_defect}")492 # 1:E4 (p01028)493 check("C3", "k(θ) = ⌊Nθ/2π + ½⌋, N = p−1: angle and chord error ≤ π/N, group-law defect ≤ 1, on every shell",494 ok, "; ".join(det), kind="CHART")495496 # C4 — the SO(3) obstruction: covering radii of the finite rotation groups497 def qmul(a, b):498 w1, x1, y1, z1 = a; w2, x2, y2, z2 = b499 return (w1*w2 - x1*x2 - y1*y2 - z1*z2, w1*x2 + x1*w2 + y1*z2 - z1*y2, w1*y2 - x1*z2 + y1*w2 + z1*x2, w1*z2 + x1*y2 - y1*x2 + z1*w2)500 def rot(axis, ang):501 n = math.sqrt(sum(c * c for c in axis)); s = math.sin(ang / 2) / n502 return (math.cos(ang / 2), s * axis[0], s * axis[1], s * axis[2])503 def closure(gens):504 G, frontier = [(1.0, 0.0, 0.0, 0.0)], [(1.0, 0.0, 0.0, 0.0)]505 while frontier:506 new = []507 for a in frontier:508 for g in gens:509 b = qmul(a, g)510 if not any(sum((u - v) ** 2 for u, v in zip(b, c)) < 1e-18 for c in G): G.append(b); new.append(b)511 frontier = new512 return G513 def dist(q, G): # rotation-angle distance from q to the group514 return 2 * math.acos(min(1.0, max(abs(sum(u * v for u, v in zip(q, g))) for g in G)))515 def covering_radius(G, samples=20000, refine=60):516 best = 0.0517 pts = []518 for _ in range(samples):519 v = [rnd.gauss(0, 1) for _ in range(4)]; n = math.sqrt(sum(c * c for c in v)); pts.append(tuple(c / n for c in v))520 pts.sort(key=lambda q: -dist(q, G))521 for q in pts[:12]:522 cur, step = dist(q, G), 0.05523 for _ in range(refine):524 cands = []525 for _ in range(48):526 v = [c + step * rnd.gauss(0, 1) for c in q]; n = math.sqrt(sum(c * c for c in v)); cands.append(tuple(c / n for c in v))527 c = max(cands, key=lambda q: dist(q, G)); dc = dist(c, G)528 if dc > cur: q, cur = c, dc529 else: step *= 0.7530 best = max(best, cur)531 return best532 phi = (1 + 5 ** 0.5) / 2533 groups = {"tetrahedral": closure([rot((0, 0, 1), math.pi), rot((1, 1, 1), 2 * math.pi / 3)]),534 "octahedral": closure([rot((0, 0, 1), math.pi / 2), rot((1, 1, 1), 2 * math.pi / 3)]),535 "icosahedral": closure([rot((0, 0, 1), math.pi), rot((1, 1, 1), 2 * math.pi / 3), rot((0, 1, phi), 2 * math.pi / 5)])}536 exact = {"tetrahedral": math.pi / 2, "octahedral": math.acos((2 * 2 ** 0.5 - 1) / 4), "icosahedral": math.acos((3 * 5 ** 0.5 - 1) / 8)}537 ok, det = True, []538 ok &= [len(G) for G in groups.values()] == [24, 48, 120] # the binary groups: 2 × 12, 24, 60539 for name, G in groups.items():540 r = covering_radius(G); ok &= abs(r - exact[name]) < 2e-3541 det.append(f"{name}: {math.degrees(r):.2f}° (exact {math.degrees(exact[name]):.2f}°)")542 # cyclic and dihedral groups lie in an O(2): rotations about an axis and half-turns about axes normal to it; the543 # rotation q = (w,x,y,z) with w²+z² = x²+y² = ½ is at distance 2·arccos(1/√2) = π/2 from every element of O(2)544 q = (0.5 ** 0.5 * math.cos(0.3), 0.5 ** 0.5 * math.cos(1.1), 0.5 ** 0.5 * math.sin(1.1), 0.5 ** 0.5 * math.sin(0.3))545 d_o2 = 2 * math.acos(max(math.hypot(q[0], q[3]), math.hypot(q[1], q[2])))546 ok &= abs(d_o2 - math.pi / 2) < 1e-12547 eps0 = min(exact.values()); ok &= abs(eps0 - exact["icosahedral"]) < 1e-15 and eps0 < math.pi / 2548 det.append(f"cyclic/dihedral (in O(2)): ≥ {math.degrees(d_o2):.2f}°; ε₀ = {math.degrees(eps0):.4f}° = {eps0:.6f} rad")549 # 1:E5 (p01029)550 check("C4", "covering radii in SO(3): tetrahedral π/2, octahedral arccos((2√2−1)/4), icosahedral arccos((3√5−1)/8) = ε₀ ≈ 44.48°, cyclic/dihedral ≥ π/2; no finite subgroup is an ε-net for ε < ε₀",551 ok, "; ".join(det), kind="CHART")552553 # C5 — the window resolves SO(3): the normalised framed quaternions are a 2·arcsin(1/H)-net, composing exactly on the shell554 ok, det = True, []555 for H in [1, 2, 3]:556 pts = [q for q in itertools.product(range(-H, H + 1), repeat=4) if any(q)]557 seen, W = set(), []558 for q in pts: # one representative per rotation (q and −q)559 n = math.sqrt(sum(c * c for c in q)); u = tuple(c / n for c in q)560 key = tuple(round(c, 9) for c in (u if next(c for c in u if abs(c) > 1e-12) > 0 else tuple(-c for c in u)))561 if key not in seen: seen.add(key); W.append(u)562 bound = 2 * math.asin(1 / H)563 samples = []564 for _ in range(3000):565 v = [rnd.gauss(0, 1) for _ in range(4)]; n = math.sqrt(sum(c * c for c in v)); samples.append(tuple(c / n for c in v))566 ds = [dist(q, W) for q in samples]567 ok &= max(ds) <= bound + 1e-12 # the elementary bound, on every sample568 # the rounding witness itself, on every sample: q = round(H s) is within arcsin(1/H)569 for s_ in samples:570 q = tuple(round(H * c) for c in s_)571 if any(q):572 n = math.sqrt(sum(c * c for c in q)); cosang = abs(sum(a * b for a, b in zip(s_, q))) / n573 ok &= 2 * math.acos(min(1.0, cosang)) <= bound + 1e-12574 measured = covering_radius(W, samples=4000, refine=40)575 ok &= measured <= bound + 1e-9576 det.append(f"H={H}: {len(W)} rotations, measured {math.degrees(measured):.1f}° ≤ bound {math.degrees(bound):.1f}°")577 ok &= 2 * math.asin(1 / 3) < math.acos((3 * 5 ** 0.5 - 1) / 8) # H = 3 beats every finite subgroup578 # exact composition on the shell p = 73 > 8·3² = 72: the product of two window quaternions reads back from F_73579 p, H = 73, 3580 def qmul_int(a, b):581 w1, x1, y1, z1 = a; w2, x2, y2, z2 = b582 return (w1*w2 - x1*x2 - y1*y2 - z1*z2, w1*x2 + x1*w2 + y1*z2 - z1*y2, w1*y2 - x1*z2 + y1*w2 + z1*x2, w1*z2 + x1*y2 - y1*x2 + z1*w2)583 read = lambda r: r - p if r > (p - 1) // 2 else r # the window reading of a residue584 n_pairs = 0585 for _ in range(20000):586 a = tuple(rnd.randint(-H, H) for _ in range(4)); b = tuple(rnd.randint(-H, H) for _ in range(4))587 exact = qmul_int(a, b); modp = qmul_int(tuple(c % p for c in a), tuple(c % p for c in b))588 ok &= all(read(c % p) == e for c, e in zip(modp, exact)) and all(abs(e) <= 4 * H * H for e in exact); n_pairs += 1589 det.append(f"2·arcsin(1/3) = {math.degrees(2 * math.asin(1/3)):.1f}° < ε₀; composition on F_{p}, H={H}: {n_pairs} pairs read back exactly")590 # 1:E6 (p01030)591 check("C5", "the normalised window quaternions W_H⁴ are a 2·arcsin(1/H)-net of SO(3) (H = 1, 2, 3), 38.9° < ε₀ at H = 3; their products read back exactly from the shell when 8H² < p",592 ok, "; ".join(det), kind="CHART")593594 # ---------------------------------------------------------------------------------------------------- the Lie-algebra layer595 # Quaternion rotations over F_p as 3×3 matrices: ρ_q(x) = q x q̄ / N(q) on pure x, S_v x = v × x, N(v) = v·v.596 def qm(x, y):597 a1, b1, c1, d1 = x; a2, b2, c2, d2 = y598 return (a1*a2 - b1*b2 - c1*c2 - d1*d2, a1*b2 + b1*a2 + c1*d2 - d1*c2, a1*c2 - b1*d2 + c1*a2 + d1*b2, a1*d2 + b1*c2 - c1*b2 + d1*a2)599 def mm(A, B, p): return tuple(tuple(sum(A[i][k] * B[k][j] for k in range(3)) % p for j in range(3)) for i in range(3))600 def minv(A, p):601 (a, b, c), (d, e, f), (g, h, i) = A602 det = (a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g)) % p603 if det == 0: return None604 di = pow(det, -1, p)605 adj = ((e*i - f*h, c*h - b*i, b*f - c*e), (f*g - d*i, a*i - c*g, c*d - a*f), (d*h - e*g, b*g - a*h, a*e - b*d))606 return tuple(tuple((x * di) % p for x in r) for r in adj)607 I3 = ((1, 0, 0), (0, 1, 0), (0, 0, 1))608 def rho(q, p):609 n = sum(c * c for c in q) % p; ni = pow(n, -1, p); cols = []610 for e in ((0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)):611 r = qm(qm(q, e), (q[0], -q[1], -q[2], -q[3])); cols.append([(c * ni) % p for c in r[1:]])612 return tuple(tuple(cols[j][i] for j in range(3)) for i in range(3))613 def Smat(v, p): x, y, z = v; return tuple(tuple(c % p for c in r) for r in ((0, -z, y), (z, 0, -x), (-y, x, 0)))614 def cayley(a, v, p):615 S = Smat(v, p); M = minv(tuple(tuple((a * I3[i][j] - S[i][j]) % p for j in range(3)) for i in range(3)), p)616 return None if M is None else mm(M, tuple(tuple((a * I3[i][j] + S[i][j]) % p for j in range(3)) for i in range(3)), p)617 def halfturn(v, p):618 S = Smat(v, p); S2 = mm(S, S, p); ni = pow(sum(c * c for c in v) % p, -1, p)619 return tuple(tuple((I3[i][j] + 2 * ni * S2[i][j]) % p for j in range(3)) for i in range(3))620 def legendre(n, p):621 n %= p622 return 0 if n == 0 else (1 if pow(n, (p - 1) // 2, p) == 1 else -1)623 def nonsquare(p): return next(x for x in range(2, p) if legendre(x, p) == -1)624 def eta_cayley_ok(a, v, p):625 # 8:C3 in F_p[η], η² = ν: α = η/(νa), H = ηS_v, so αH = (η²/(νa)) S_v; its η-part vanishes and its F_p-part is S_v/a626 nu = nonsquare(p); inv = lambda x: pow(x % p, -1, p)627 alpha = (0, inv(nu * a)) # 0 + (1/(νa)) η628 S = Smat(v, p)629 for i in range(3):630 for j in range(3):631 h = (0, S[i][j]) # η S_ij632 prod = ((alpha[0] * h[0] + nu * alpha[1] * h[1]) % p, (alpha[0] * h[1] + alpha[1] * h[0]) % p)633 if prod != ((S[i][j] * inv(a)) % p, 0): return False634 return True635 def primitive(v):636 g = 0637 for c in v: g = math.gcd(g, abs(c))638 v = tuple(c // g for c in v)639 for c in v: # sign: first nonzero coordinate positive640 if c: return v if c > 0 else tuple(-x for x in v)641 def group_order(M, p):642 k, X = 1, M643 while X != I3: X = mm(X, M, p); k += 1644 return k645646 ok, det = True, []647 n_rot = n_axes = 0648 for p, H in ((13, 1), (17, 1), (37, 2), (73, 3), (101, 3)):649 assert p > 8 * H * H650 window = [q for q in itertools.product(range(-H, H + 1), repeat=4) if any(q[1:])]651 axes = {}652 for q in window:653 a, v = q[0], q[1:]654 R = rho(q, p); n_rot += 1655 ok &= R == (cayley(a % p, v, p) if a % p else halfturn(v, p))656 if a % p: ok &= eta_cayley_ok(a % p, v, p)657 axes.setdefault(primitive(v), set()).add(R)658 for v0, rots in axes.items():659 n_axes += 1660 N = sum(c * c for c in v0) % p661 G = {I3, halfturn(v0, p)} | {C for C in (cayley(a, v0, p) for a in range(1, p)) if C is not None}662 order = p - legendre(N, p)663 ok &= len(G) == order # the order p − (N(v)|p)664 gen = next((M for M in G if group_order(M, p) == order), None) # cyclic: an element of full order665 powers, X = {I3}, gen666 while gen is not None and X != I3: powers.add(X); X = mm(X, gen, p)667 ok &= gen is not None and powers == G # whose powers are exactly the set668 for R in rots: # every iterate of a window rotation stays in it669 X = R670 for _ in range(order): ok &= X in G; X = mm(X, R, p)671 ok &= len(rots) <= 2 * H * H + 2 * H # at most 2H² + 2H window rotations672 det.append(f"{n_rot} window rotations on the shells 13, 17, 37, 73, 101 (8H² < p): ρ_q = (aI − S_v)⁻¹(aI + S_v) = the Cayley step of ηS_v at α = η/(νa), and I + 2N(v)⁻¹S_v² at a = 0")673 det.append(f"{n_axes} axes: the steps, the identity and the half-turn form a cyclic group of order p − (N(v)|p) holding every iterate; at most 2H² + 2H window rotations per axis")674 # 1:E7 (p01032)675 check("C6", "ρ_q = (aI − S_v)⁻¹(aI + S_v), the Cayley step of ηS_v at α = η/(νa), and the half-turn I + 2N(v)⁻¹S_v² at a = 0; with it the steps form a cyclic group of order p − (N(v)|p) holding every iterate; ≤ 2H² + 2H window rotations per axis",676 ok, "; ".join(det))677678 ok, det = True, []679 rnd = random.Random(20261004)680 def cross(u, w): return (u[1]*w[2] - u[2]*w[1], u[2]*w[0] - u[0]*w[2], u[0]*w[1] - u[1]*w[0])681 def dot(u, w): return sum(x * y for x, y in zip(u, w))682 n_comp = n_half = n_br = 0683 for p in (13, 29, 73, 233):684 inv = lambda x: pow(x % p, -1, p)685 tries = 0686 while n_comp < 4000 * (1 + (13, 29, 73, 233).index(p)) and tries < 100000:687 tries += 1688 u = tuple(rnd.randrange(p) for _ in range(3)); w = tuple(rnd.randrange(p) for _ in range(3))689 uw = dot(u, w) % p690 if (1 + dot(u, u)) % p == 0 or (1 + dot(w, w)) % p == 0: continue691 s = (1 - uw) % p692 m = tuple((u[i] + w[i] + cross(u, w)[i]) % p for i in range(3))693 lhs = mm(rho((1,) + u, p), rho((1,) + w, p), p)694 if s:695 c = tuple((x * inv(s)) % p for x in m)696 if (1 + dot(c, c)) % p == 0: continue697 ok &= lhs == rho((1,) + c, p); n_comp += 1698 elif any(m) and dot(m, m) % p:699 ok &= lhs == halfturn(m, p); n_half += 1700 br = tuple((x - y) % p for x, y in zip(qm((0,) + u, (0,) + w), qm((0,) + w, (0,) + u)))701 ok &= br == (0,) + tuple((2 * x) % p for x in cross(u, w)); n_br += 1702 # the half-turn case on purpose: w chosen with u·w = 1703 for _ in range(300):704 u = tuple(rnd.randrange(p) for _ in range(3))705 if not u[0] % p: continue706 w1, w2 = rnd.randrange(p), rnd.randrange(p)707 w = (((1 - u[1] * w1 - u[2] * w2) * inv(u[0])) % p, w1, w2)708 m = tuple((u[i] + w[i] + cross(u, w)[i]) % p for i in range(3))709 if (1 + dot(u, u)) % p == 0 or (1 + dot(w, w)) % p == 0 or not any(m) or dot(m, m) % p == 0: continue710 ok &= mm(rho((1,) + u, p), rho((1,) + w, p), p) == halfturn(m, p); n_half += 1711 det.append(f"composition ρ_(1+u)ρ_(1+w) = ρ_(1+u∘w): {n_comp} pairs; the half-turn at u·w = 1: {n_half}; [u,w] = 2u×w: {n_br} (F_13, F_29, F_73, F_233)")712 n_pow = n_rb = 0713 for H in (1, 2, 3):714 for q in itertools.product(range(-H, H + 1), repeat=4):715 if not any(q): continue716 r = (1, 0, 0, 0)717 for m_ in range(1, 7):718 r = qm(r, q); n_pow += 1719 ok &= max(map(abs, r)) <= (2 * H) ** m_720 for p in (13, 101, 1009):721 reads = all(((c % p) - p if (c % p) > (p - 1) // 2 else (c % p)) == c for c in r)722 ok &= reads == (2 * max(map(abs, r)) < p); n_rb += 1723 det.append(f"heights: {n_pow} powers q^m (H ≤ 3, m ≤ 6) with entries ≤ (2H)^m; read-back iff 2‖q^m‖∞ < p: {n_rb} cases on F_13, F_101, F_1009")724 # 1:E8 (p01033)725 check("C7", "ρ_(1+u)ρ_(1+w) = ρ_(1+u∘w), u∘w = (u+w+u×w)/(1−u·w); at u·w = 1 the half-turn about u+w+u×w; [u,w] = 2u×w; entries of q^m ≤ (2H)^m, read back iff 2‖q^m‖∞ < p",726 ok, "; ".join(det))727728if __name__ == "__main__":729 import time730 want = [a.upper() for a in sys.argv[1:]] or sorted(BLOCK)731 bad = [b for b in want if b not in BLOCK]732 if bad: sys.exit(f"no block {', '.join(bad)}: the blocks are {', '.join(sorted(BLOCK))}")733 t0 = time.time()734 for b in want:735 t = time.time(); _run_block(b); print(f" [block {b}: {time.time() - t:.1f} s]")736 ok = summary(write=(want == sorted(BLOCK)))737 kinds = {}738 for r in RESULTS: kinds[r["kind"]] = kinds.get(r["kind"], 0) + 1739 print("by kind: " + ", ".join(f"{k} {v}" for k, v in sorted(kinds.items())) + f"; {len(RESULTS)} checks in {time.time() - t0:.1f} s" + ("; results.json written" if want == sorted(BLOCK) else ""))740 sys.exit(0 if ok else 1)741