The validation package of Geometry and Constants in Finite Ring Continuum: one script, geometry.py, 4 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 (# 2:D1 (p02013): 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-2-geometry.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-2-geometry --find-links https://finitering.space/pkg/ (the sdist frc-2-geometry-20261012.tar.gz).
Blocks: A (9) · B (4) · C (3) · D (5) — the predicates each decides in parentheses.
1"""2geometry.py — the validation package of "Geometry and Constants in Finite Ring Continuum" (Akhtman, Symmetry 2026, 18, 751;3doi 10.3390/sym18050751), the paper 2-geometry of the FRC corpus (finite-ring-space/src/2-geometry), added with the paper's4predicate ledger (Appendix A, 17 September 2026, from the corpus script validation/verify_geometry.py; one script since524 September 2026, the four block scripts merged).6========================================================================================================================78One script, four blocks, eighteen checks, standard library only. Each check names the predicate(s) of the paper's ledger it9witnesses (LEDGER below; predicates cited as 2:XN) under a `# 2:XN (<key>)` marker, the key the predicate's accession key,, and the ledger's source column links the10marker of the check that decides each predicate (PREDICATES below; finitering.space/src/2-geometry/#<key>).11Where a predicate is proved in Lean (lean/FrcLedger/Geometry.lean on Mathlib, or lean/FrcCore with no axioms), the check here12is the instance the reader can run; the witnesses decide the same statements at different generality.1314 python3 geometry.py every block, results.json written; exit 1 if a check fails (≈ 2 s)15 python3 geometry.py C one block (A, B, C or D); no results.json16 from frc_2_geometry import predicate; predicate("2:D1") one predicate: its block runs once per session1718Blocks: A the Euclidean datum and the involutions EXACT (2:B3, D1–D8)19 B the orbital shell and its spherical completion EXACT (2:B4, C2–C4)20 C the external spherical comparison CHART / EXACT (2:E2–E4)21 D Fourier duality on the phase cycle EXACT / CHART (2:F1, F3–F6)2223Everything the blocks share:24 * the shell datum: p = 4κ+1 prime, the primitive generators of F_p, the oriented quarter-turn i = −g^κ,25 the half-period π = 2κ, the phase cycle of length n = p − 1;26 * exact arithmetic in F_p (python int, reduced mod p) and in Q (fractions.Fraction);27 * the PASS/FAIL registry every block reports into (results.json).2829Kinds: EXACT checks are integer-pinned computations in F_p or exact rationals (a pass is a proof on the tested30instances); CHART checks decide a [chart] predicate — the reading of the shell against R or C — in floats with the31closed forms checked.32"""33import os, json, sys, math, random34from collections import Counter, defaultdict35from fractions import Fraction3637SCRIPT = os.path.splitext(os.path.basename(__file__))[0] # "geometry": the one script, the name results.json and the site pages carry3839# The shells (p, κ): p = 4κ+1 prime.40SHELLS = [(5, 1), (13, 3), (17, 4), (29, 7), (37, 9), (41, 10)]4142# ----------------------------------------------------------------------------- registry43RESULTS = []4445# The paper's predicate ledger (Appendix A, predicates cited as 2:XN): the predicate(s) each check witnesses.46LEDGER = {47 "A1": "2:D1, 2:D2, 2:D3, 2:D4", "A2": "2:B3", "A3": "2:D5", "A4": "2:D6", "A5": "2:D7", "A6": "2:D8",48 "B1": "2:C2", "B2": "2:C3", "B3": "2:B4, 2:C4",49 "C1": "2:E2", "C2": "2:E3", "C2b": "2:E3", "C3": "2:E4",50 "D1": "2:F1", "D2": "2:F3", "D3": "2:F4", "D4": "2:F5", "D5": "2:F6",51}5253BLOCK = {"A": "the Euclidean datum and the involutions", # check-id prefix -> the block (the function block_<letter> below)54 "B": "the orbital shell and its spherical completion",55 "C": "the external spherical comparison",56 "D": "Fourier duality on the phase cycle"}5758# the deciding check of each witnessed predicate: the one whose verdict decides the predicate's statement (the other checks that59# touch it are corroboration, listed by predicate() from the records)60PREDICATES = {61 "2:B3": "A2", "2:B4": "B3",62 "2:C2": "B1", "2:C3": "B2", "2:C4": "B3",63 "2:D1": "A1", "2:D2": "A1", "2:D3": "A1", "2:D4": "A1", "2:D5": "A3", "2:D6": "A4", "2:D7": "A5", "2:D8": "A6",64 "2:E2": "C1", "2:E3": "C2", "2:E4": "C3",65 "2:F1": "D1", "2:F3": "D2", "2:F4": "D3", "2:F5": "D4", "2:F6": "D5",66}67_RAN = set() # blocks already run in this session (predicate() runs each once)6869def check(pid, label, ok, detail="", kind="EXACT"):70 """Record one predicate check. pid = package check id; LEDGER[pid] = the paper statement(s) decided."""71 ok = bool(ok)72 rows = LEDGER.get(pid, "")73 RESULTS.append({"id": pid, "rows": rows, "block": pid[0], "script": SCRIPT, "label": label, "ok": ok, "detail": detail, "kind": kind})74 print(f" [{'PASS' if ok else 'FAIL'}] {pid:4s} {kind:6s} [{rows}] {label}" + (f" -- {detail}" if detail else ""))75 return ok7677def summary(write=True):78 n_ok = sum(r["ok"] for r in RESULTS)79 print(f"\nSUMMARY: {n_ok}/{len(RESULTS)} checks passed" + ("" if n_ok == len(RESULTS) else " <-- FAILURES"))80 if write:81 with open("results.json", "w") as f:82 json.dump(RESULTS, f, indent=1)83 return n_ok == len(RESULTS)8485def markers():86 """predicate label -> (script file, line) of its marker `# <paper>:<label> (<key>)`: the line of the check that decides it."""87 import re88 out = {}89 for i, line in enumerate(open(os.path.abspath(__file__), encoding="utf-8"), 1):90 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)91 if m:92 for lab in re.findall(r"\d+:[A-Z]+\d+[a-z]?", m.group(1)): out.setdefault(lab, (SCRIPT + ".py", i))93 return out9495def _run_block(letter):96 if letter not in _RAN:97 globals()[f"block_{letter}"](); _RAN.add(letter)9899def predicate(label, lines=14):100 """Verify one ledger predicate: run the block of the check that decides it (once per session), print that check's source101 (from its marker) and every record that cites the predicate, and return True iff all pass."""102 pid = PREDICATES.get(label)103 if pid is None:104 print(f"{label}: no python witness (see the predicate's Lean witness or its source)"); return None105 citing = {i[0] for i, rows in LEDGER.items() if label in [t.strip() for t in rows.split(",")]}106 for b in sorted({pid[0]} | citing): _run_block(b) # the deciding block and every block whose checks cite the predicate107 mk = markers().get(label)108 if mk:109 src = open(os.path.abspath(__file__), encoding="utf-8").read().split("\n")110 print(f"— {mk[0]}:{mk[1]} (the check that decides {label}: {pid})")111 for j in range(mk[1] - 1, min(mk[1] - 1 + lines, len(src))): print(f"{j + 1:5d} {src[j]}")112 recs = [r for r in RESULTS if label in [t.strip() for t in r["rows"].split(",")]]113 ok = all(r["ok"] for r in recs)114 for r in recs:115 role = "(deciding)" if r["id"] == pid else "(corroborating)"116 print(f" [{'PASS' if r['ok'] else 'FAIL'}] {r['id']:4s} {role:16s} {r['detail'][:150]}")117 print(f"{label}: {'VERIFIED' if ok and recs else 'FAILED'} — {len(recs)} record(s)")118 return ok119120def verify_all():121 """Run every block (those already run in this session are not re-run) and print the summary; True iff every check passed."""122 for b in sorted(BLOCK): _run_block(b)123 return summary(write=False)124125# ----------------------------------------------------------------------------- the shell datum126def is_prime(n):127 return n > 1 and all(n % q for q in range(2, int(n ** .5) + 1))128129def order(x, p):130 """The multiplicative order of x in F_p^x."""131 k, y = 1, x % p132 while y != 1:133 y = y * x % p; k += 1134 return k135136def generators(p):137 """The primitive generators of F_p^x, in increasing order."""138 return [g for g in range(2, p) if order(g, p) == p - 1]139140def units(n):141 """The units of Z_n: u in [1, n) coprime to n."""142 return [u for u in range(1, n) if math.gcd(u, n) == 1]143144def kappa(p):145 assert is_prime(p) and p % 4 == 1, p146 return (p - 1) // 4147148def quarter_turn(p, g):149 """The oriented quarter-turn i = −g^κ (00:C7, 2:A2)."""150 return (-pow(g, kappa(p), p)) % p151152for _p, _k in SHELLS:153 assert is_prime(_p) and _p == 4 * _k + 1, (_p, _k)154155# ------------------------------------------------------------------------------------------------------------156# block A: the Euclidean datum and the involutions (2:B3, D1–D8)157# Section 2 (the frame) and Section 4 (symmetry axes and structural data) of the paper, on the shells158# p ∈ {5, 13, 17, 29, 37, 41} and every primitive generator. \label(s): prop:half-period,159# def:quarter-turn-subgroup, prop:quarter-turn, rem:observer-canonical-e, rem:exponential-unit (A1);160# prop:primitive-orbit, prop:no-canonical-e (A2); rem:frame-transport (A3); the Euler identity of 00:C14 (A4);161# prop:shell-negation, prop:k4-shell (A5); rem:euclidean-conjugation (A6).162def block_A():163 """Block A — the Euclidean datum and the involutions (EXACT): A1–A6."""164 # A1 half-period, quarter-turn of order four, i = −g^κ with i² = −1, 2π = −1, e = g^i (2:D1–D4)165 ok = True; det = []166 for p, k in SHELLS:167 pi = 2 * k168 for g in generators(p):169 i = quarter_turn(p, g)170 ok &= pow(g, pi, p) == p - 1 and (i * i) % p == p - 1 and pow(g, 4 * k, p) == 1 and order(pow(g, k, p), p) == 4171 ok &= (2 * pi) % p == p - 1172 Q = {x for x in range(1, p) if pow(x, 4, p) == 1}173 ok &= Q == {1, p - 1, i, (-i) % p}174 g = generators(p)[0]; i = quarter_turn(p, g)175 det.append(f"p={p}: g={g}, i={i}, e=g^i={pow(g, i, p)}, pi={pi}")176 # 2:D1 (p02013), 2:D2 (p02014), 2:D3 (p02015), 2:D4 (p02016)177 check("A1", "half-period g^pi = -1; i = -g^k of order 4 with i^2 = -1; Q_p = {±1, ±i}; 2pi = -1; e = g^i", ok, "; ".join(det[:3]))178179 # A2 the primitive generators form one orbit g^u, u a unit mod p−1 (2:B3)180 ok = True181 for p, k in SHELLS:182 gens = set(generators(p)); g = min(gens)183 orbit = {pow(g, u, p) for u in units(p - 1)}184 ok &= orbit == gens and len(gens) == len(units(p - 1))185 # 2:B3 (p02007)186 check("A2", "generators = {g^u : gcd(u, p-1) = 1}, one Aut(C_{p-1})-torsor", ok)187188 # A3 orientation classes: i' = i iff u ≡ 1 (mod 4), i' = −i iff u ≡ 3 (mod 4) (2:D5)189 ok = True; det = []190 for p, k in SHELLS:191 g = generators(p)[0]; i = quarter_turn(p, g)192 for u in units(p - 1):193 ip = quarter_turn(p, pow(g, u, p))194 ok &= (ip == i) == (u % 4 == 1) and (ip == (-i) % p) == (u % 4 == 3)195 same = sum(1 for u in units(p - 1) if u % 4 == 1)196 det.append(f"p={p}: {same} of {len(generators(p))} generators keep i")197 # 2:D5 (p02017)198 check("A3", "orientation classes of the quarter-turn under g -> g^u: kept for u = 1, flipped for u = 3 (mod 4)", ok, "; ".join(det))199200 # A4 the Euler identity e^{iπ} = g^{2κ i²} = (−1)^i, −1 iff the residue i is odd (2:D6, 00:C14)201 ok = True; det = []202 for p, k in SHELLS:203 for g in generators(p):204 i = quarter_turn(p, g); e = pow(g, i, p)205 ok &= pow(e, i * 2 * k, p) == (p - 1 if i % 2 else 1)206 odd = [g for g in generators(p) if quarter_turn(p, g) % 2 == 1]207 det.append(f"p={p}: i odd for g in {odd[:6]}{'...' if len(odd) > 6 else ''} ({len(odd)}/{len(generators(p))})")208 ok &= quarter_turn(13, 2) == 5 and quarter_turn(17, 3) == 4 and quarter_turn(17, 6) == 13209 # 2:D6 (p02018)210 check("A4", "Euler identity e^{i pi} = (-1)^i with i the residue representative; F13 g=2 odd, F17 g=3 even", ok, "; ".join(det[:3]))211212 # A5 negation/inversion orbits: F_p^x \ Q_p splits into κ−1 orbits of size four (2:D7, 1:B2)213 ok = True214 for p, k in SHELLS:215 Q = {x for x in range(1, p) if pow(x, 4, p) == 1}216 seen, orbits = set(), 0217 for x in range(1, p):218 if x in Q or x in seen: continue219 orb = {x, (-x) % p, pow(x, -1, p), (-pow(x, -1, p)) % p}220 ok &= len(orb) == 4; seen |= orb; orbits += 1221 ok &= len(Q) == 4 and orbits == k - 1222 R = lambda x: (-x) % p; I = lambda x: pow(x, -1, p)223 ok &= all(R(R(x)) == x and I(I(x)) == x and R(I(x)) == I(R(x)) for x in range(1, p))224 # 2:D7 (p02019)225 check("A5", "R, I commuting involutions; <R,I>-orbits off Q_p have four elements, k-1 of them", ok)226227 # A6 Euclidean conjugation: an involution of pairs; the pair map (a, b) -> a + b i is p-to-one (2:D8)228 ok = True229 for p, k in SHELLS:230 g = generators(p)[0]; i = quarter_turn(p, g)231 fibres = Counter((a + b * i) % p for a in range(p) for b in range(p))232 ok &= set(fibres.values()) == {p} and len(fibres) == p233 C = lambda a, b: (a, (-b) % p)234 ok &= all(C(*C(a, b)) == (a, b) for a in range(p) for b in range(p))235 a, b = 0, 1; a2, b2 = i, 0 # 0 + 1·i = i + 0·i, but the conjugates differ: not a map of the field236 ok &= (a + b * i) % p == (a2 + b2 * i) % p and (a - b * i) % p != (a2 - b2 * i) % p237 # 2:D8 (p02020)238 check("A6", "conjugation is an involution of the pairs, not of the field (the pair map is p-to-one)", ok)239240# ------------------------------------------------------------------------------------------------------------241# block B: the orbital shell and its spherical completion (2:B4, C2, C3, C4)242# Section 3 of the paper: the complex S_p of def:orbital-shell coded as vertices, edges and faces; the243# completion (the terminal latitude collapsed to S); the counts of rem:cell-counts (B1); closedness — every edge244# in two faces, every vertex link one cycle — of thm:combinatorial-sphere, exhaustive on p ∈ {5, 13, 17, 29} (B2);245# the cellular automorphisms: the reindexing ρ_u is cellular only for u = ±1, the dihedral maps are, the meridian246# reversal is a map of the completion only (prop:phase-frame-change, prop:shell-covariance; B3).247B_SHELLS = (5, 13, 17, 29) # the shells of block B (the package's SHELLS carry κ)248249def shell(p):250 """The orbital shell S_p of Def. 3.1: vertices, edges, faces; and its completion."""251 k = (p - 1) // 4; pi = 2 * k; n = p - 1252 V = ["N"] + [(a, m) for a in range(1, pi + 1) for m in range(n)]253 E = set()254 for m in range(n):255 E.add(frozenset(["N", (1, m)]))256 for a in range(1, pi): E.add(frozenset([(a, m), (a + 1, m)]))257 for a in range(1, pi + 1): E.add(frozenset([(a, m), (a, (m + 1) % n)]))258 F = []259 for m in range(n):260 F.append(("N", (1, m), (1, (m + 1) % n)))261 for a in range(1, pi): F.append(((a, m), (a + 1, m), (a + 1, (m + 1) % n), (a, (m + 1) % n)))262 col = lambda v: "S" if (v != "N" and v[0] == pi) else v # the completion: L_pi collapsed to S263 Vc = sorted({col(v) for v in V}, key=str)264 Ec = {frozenset(map(col, e)) for e in E if len({col(v) for v in e}) == 2}265 Fc = []266 for f in F:267 cf = []268 for v in map(col, f):269 if v not in cf: cf.append(v)270 Fc.append(tuple(cf))271 return V, E, F, Vc, Ec, Fc272273def closed_surface(V, E, F):274 """Every edge in exactly two faces; every vertex link a single cycle."""275 edge_faces = defaultdict(list)276 for fi, f in enumerate(F):277 for j in range(len(f)): edge_faces[frozenset([f[j], f[(j + 1) % len(f)]])].append(fi)278 if set(edge_faces) != set(E) or any(len(v) != 2 for v in edge_faces.values()): return False279 for v in V:280 around = [fi for fi, f in enumerate(F) if v in f]281 adj = defaultdict(set)282 for fi in around:283 f = F[fi]; j = f.index(v)284 for w in (f[(j - 1) % len(f)], f[(j + 1) % len(f)]):285 for fj in edge_faces[frozenset([v, w])]:286 if fj != fi: adj[fi].add(fj)287 if any(len(s) != 2 for s in adj.values()): return False288 seen, stack = set(), [around[0]]289 while stack:290 x = stack.pop()291 if x in seen: continue292 seen.add(x); stack.extend(adj[x])293 if seen != set(around): return False294 return True295296def block_B():297 """Block B — the orbital shell and its spherical completion (EXACT): B1–B3."""298 # B1 the counts and the Euler characteristics (2:C2)299 ok = True; det = []300 for p in B_SHELLS:301 k = (p - 1) // 4; pi = 2 * k; n = p - 1302 V, E, F, Vc, Ec, Fc = shell(p)303 ok &= (len(V), len(E), len(F)) == (pi * n + 1, 2 * pi * n, pi * n) and len(V) - len(E) + len(F) == 1304 ok &= (len(Vc), len(Ec), len(Fc)) == ((pi - 1) * n + 2, (2 * pi - 1) * n, pi * n) and len(Vc) - len(Ec) + len(Fc) == 2305 det.append(f"p={p}: |V|,|E|,|F| = {len(V)},{len(E)},{len(F)}, chi=1; completion {len(Vc)},{len(Ec)},{len(Fc)}, chi=2")306 # 2:C2 (p02010)307 check("B1", "cell counts of S_p and of its completion, chi = 1 and chi = 2 (Remark 3.4)", ok, "; ".join(det))308309 # B2 the completion is a closed surface (chi = 2, a sphere); S_p itself is not closed (2:C3)310 ok = True; det = []311 for p in B_SHELLS:312 V, E, F, Vc, Ec, Fc = shell(p)313 closed = closed_surface(Vc, Ec, Fc)314 ok &= closed and not closed_surface(V, E, F)315 det.append(f"p={p}: completion closed={closed}, S_p closed=False")316 # 2:C3 (p02011)317 check("B2", "the completion is a closed surface with chi = 2 (a sphere) by exhaustive incidence; S_p has a boundary", ok, "; ".join(det))318319 # B3 cellular automorphisms: rho_u iff u = ±1; the dihedral maps; meridian reversal on the completion only (2:B4, 2:C4)320 ok = True; det = []321 for p in B_SHELLS:322 k = (p - 1) // 4; pi = 2 * k; n = p - 1323 V, E, F, Vc, Ec, Fc = shell(p)324 faces = lambda FF, f: sorted(Counter(tuple(sorted(map(str, map(f, x)))) for x in FF).items())325 cellular = lambda f, EE, FF: {frozenset(map(f, e)) for e in EE} == EE and faces(FF, f) == faces(FF, lambda v: v)326 good = []327 for u in units(n):328 rho = lambda v: v if v in ("N", "S") else (v[0], v[1] * u % n)329 if cellular(rho, E, F): good.append(u)330 ok &= cellular(rho, E, F) == (u in (1, n - 1)) and cellular(rho, Ec, Fc) == (u in (1, n - 1))331 for c in range(n):332 for s_ in (1, -1):333 dih = lambda v: v if v in ("N", "S") else (v[0], (s_ * v[1] + c) % n)334 ok &= cellular(dih, E, F)335 sig = lambda v: "S" if v == "N" else "N" if v == "S" else (pi - v[0], v[1])336 ok &= cellular(sig, Ec, Fc)337 ok &= sum(1 for v in V if v == "N") == 1 and sum(1 for v in V if v != "N" and v[0] == pi) == n338 det.append(f"p={p}: rho_u cellular only for u in {good} of {len(units(n))} units")339 # 2:B4 (p02008), 2:C4 (p02012)340 check("B3", "rho_u (m -> um) is cellular iff u = ±1; the dihedral maps are; meridian reversal is a map of the completion only", ok, "; ".join(det))341342# ------------------------------------------------------------------------------------------------------------343# block C: the external spherical comparison (2:E2, E3, E4)344# Section 5 of the paper. C1 (CHART): the base-grid covering radius of the comparison map Xi_{13,g} against the345# bound sqrt2·pi/(p−1) of prop:grid-density. C2 (EXACT, rationals): the fixed-shell scale grid {x/g^n : |x| ≤ 2κ}346# has a covering radius in [0, 1] bounded below by ½ min(g^−m, 1 − 2κ g^−(m+1)) at every depth — the bounded347# precision of a fixed shell, prop:fixed-shell-density and thm:operational-precision (C2b: the covering radius348# exceeds ε = 1/20 on every tested shell). C3 (CHART): across the tower of shells the grids resolve every target (1:D7).349def fib_sphere(N):350 pts = []351 ga = math.pi * (3 - math.sqrt(5))352 for j in range(N):353 z = 1 - 2 * (j + .5) / N; r = math.sqrt(1 - z * z); t = ga * j354 pts.append((r * math.cos(t), r * math.sin(t), z))355 return pts356357def geod(u, v): return math.acos(max(-1., min(1., u[0] * v[0] + u[1] * v[1] + u[2] * v[2])))358359def fixed_shell_radius(p, g, N, H=None):360 """Covering radius in [0,1] of {x/g^n : 0 <= x <= H, n <= N}; H = 2κ (the balanced window) by default."""361 k = (p - 1) // 4; H = 2 * k if H is None else H362 pts = sorted({Fraction(x, g ** n) for n in range(N + 1) for x in range(0, H + 1) if x <= g ** n})363 return max(b - a for a, b in zip(pts, pts[1:])) / 2364365def lower_bound(p, g, H=None):366 """½ min(g^−m, 1 − H g^−(m+1)) with m = floor(log_g(H+1)): the cut of lean fixed_shell_bound."""367 k = (p - 1) // 4; H = 2 * k if H is None else H; m = 0368 while g ** (m + 1) <= H + 1: m += 1369 return min(Fraction(1, g ** m), 1 - Fraction(H, g ** (m + 1))) / 2370371def tower_best(t, shells, N=12):372 best = 1.373 for p, g in shells:374 k = (p - 1) // 4375 for n in range(N + 1):376 for x in range(0, 2 * k + 1):377 best = min(best, abs(t - x / g ** n))378 return best379380def block_C():381 """Block C — the external spherical comparison (C1, C3 CHART; C2 EXACT rationals): C1–C3."""382 # C1 the base-grid covering radius at p = 13 within sqrt2·pi/(p−1) (2:E2) — chart383 p = 13; pi = 6; n = 12384 grid = [(0., 0., 1.), (0., 0., -1.)]385 for a in range(1, pi + 1):386 th = math.pi * a / pi387 for m in range(n):388 ph = 2 * math.pi * m / n389 grid.append((math.sin(th) * math.cos(ph), math.sin(th) * math.sin(ph), math.cos(th)))390 cov = max(min(geod(x, y) for y in grid) for x in fib_sphere(60000))391 bound = math.sqrt(2) * math.pi / (p - 1)392 # 2:E2 (p02022)393 check("C1", "base-grid covering radius at p = 13 within the bound sqrt2 pi/(p-1)", cov <= bound,394 f"measured {cov:.4f} rad, bound {bound:.4f} rad", kind="CHART")395396 # C2 the fixed-shell refinement is bounded (2:E3) — exact rationals397 ok = True; det = []398 for p, g in [(13, 2), (13, 11), (13, 6), (17, 3), (29, 2), (173, 2)]:399 radii = [fixed_shell_radius(p, g, N) for N in (3, 6, 12, 24)]400 lb = lower_bound(p, g)401 radii_p = [fixed_shell_radius(p, g, N, p - 1) for N in (12, 24)]; lb_p = lower_bound(p, g, p - 1)402 ok &= all(r >= lb for r in radii) and radii[-1] == radii[-2] and all(r >= lb_p for r in radii_p) and radii_p[0] == radii_p[1]403 det.append(f"({p},{g}): radius {radii[-1]} >= {lb}")404 # 2:E3 (p02023)405 check("C2", "fixed-shell covering radius stabilises at >= 1/2 min(g^-m, 1 - H g^-(m+1)) for every depth (H = 2k and H = p-1)", ok, "; ".join(det[:4]))406 eps = Fraction(1, 20)407 viol = [(p, g) for p, g in [(13, 2), (13, 11), (17, 3), (29, 2)] if fixed_shell_radius(p, g, 40) > eps]408 check("C2b", "fixed-shell density at eps = 1/20: the covering radius exceeds 1/20 on every tested shell", viol == [(13, 2), (13, 11), (17, 3), (29, 2)],409 f"shells with covering radius > 1/20 at N = 40: {viol}")410411 # C3 the tower of shells resolves every target (2:E4, 1:D7) — chart412 targets = [0.9, 1 / 3, math.pi / 4, math.sqrt(2) - 1]413 tower = [(p, 2) for p in (13, 29, 173, 1013, 4093)]414 errs = [tower_best(t, tower) for t in targets]415 single = [tower_best(t, [(13, 2)]) for t in targets]416 # 2:E4 (p02024)417 check("C3", "the tower of shells (p = 13..4093, g = 2) brings every target within 1/2048; the single shell (13, 2) does not",418 all(e <= 1 / 2048 for e in errs) and max(single) > 1 / 16,419 "tower errors " + ", ".join(f"{e:.2e}" for e in errs) + "; single shell " + ", ".join(f"{e:.3f}" for e in single), kind="CHART")420421# ------------------------------------------------------------------------------------------------------------422# block D: Fourier duality on the phase cycle (2:F1, F3, F4, F5, F6)423# Section 6 of the paper, on (13, 2), (13, 11), (17, 3), (29, 2): the principal root (prop:principal-root, D1);424# the inversion W^−1 = −(g^−jk) (prop:ring-dft-inverse, D2); the polynomial reading F(v)_k = P_v(g^k)425# (prop:polynomial-form, D3); the covariance under g → g^u (prop:ring-dft-covariance, D4); and the external426# transport chi(g^m) = exp(−2 pi i m/n) with its step, half-period and quarter-turn identities427# (prop:datum-role-transport, D5; CHART).428FRAMES = [(13, 2), (13, 11), (17, 3), (29, 2)]429430def dft_checks(p, g):431 n = p - 1; k = (p - 1) // 4432 W = [[pow(g, j * kk, p) for j in range(n)] for kk in range(n)]433 Winv = [[(-pow(g, -j * kk, p)) % p for j in range(n)] for kk in range(n)]434 mul = lambda A, B: [[sum(A[r][t] * B[t][c] for t in range(n)) % p for c in range(n)] for r in range(n)]435 I = [[int(r == c) for c in range(n)] for r in range(n)]436 d1 = pow(g, n, p) == 1 and all(sum(pow(g, j * kk, p) for j in range(n)) % p == 0 for kk in range(1, n)) and (n * (p - 1)) % p == 1437 d2 = mul(W, Winv) == I and mul(Winv, W) == I438 rnd = random.Random(p)439 v = [rnd.randrange(p) for _ in range(n)]440 Fv = [sum(v[j] * pow(g, j * kk, p) for j in range(n)) % p for kk in range(n)]441 Pv = lambda x: sum(v[j] * pow(x, j, p) for j in range(n)) % p442 d3 = all(Fv[kk] == Pv(pow(g, kk, p)) for kk in range(n))443 d4 = True444 for u in units(n):445 gp = pow(g, u, p); vp = [v[u * j % n] for j in range(n)]446 Fvp = [sum(vp[j] * pow(gp, j * kk, p) for j in range(n)) % p for kk in range(n)]447 d4 &= Fvp == Fv448 chi = lambda m: complex(math.cos(-2 * math.pi * m / n), math.sin(-2 * math.pi * m / n))449 i = quarter_turn(p, g); li = next(m for m in range(n) if pow(g, m, p) == i)450 d5 = all(abs(chi(m + 1) - chi(1) * chi(m)) < 1e-12 and abs(chi(m + 2 * k) + chi(m)) < 1e-12451 and abs(chi(m + li) - 1j * chi(m)) < 1e-12 for m in range(n))452 d5 &= len({(round(chi(m).real, 9), round(chi(m).imag, 9)) for m in range(n)}) == n453 return d1, d2, d3, d4, d5454455def block_D():456 """Block D — Fourier duality on the phase cycle (EXACT; D5 CHART): D1–D5."""457 ok = [True] * 5458 for p, g in FRAMES:459 d = dft_checks(p, g); ok = [a and b for a, b in zip(ok, d)]460 # 2:F1 (p02025)461 check("D1", "g a principal root: g^n = 1, sum_j g^{jk} = 0 for 0 < k < n, n^-1 = -1", ok[0])462 # 2:F3 (p02027)463 check("D2", "inversion W^-1 = -(g^{-jk}) on (13, 2), (13, 11), (17, 3), (29, 2)", ok[1])464 # 2:F4 (p02028)465 check("D3", "polynomial reading F(v)_k = P_v(g^k)", ok[2])466 # 2:F5 (p02029)467 check("D4", "covariance F_{g^u}(v') = F_g(v) with v'_j = v_{uj}", ok[3])468 # 2:F6 (p02030)469 check("D5", "external transport chi(g^m) = exp(-2 pi i m/n), injective: step, half-period, quarter-turn", ok[4], kind="CHART")470471if __name__ == "__main__":472 import time473 want = [a.upper() for a in sys.argv[1:]] or sorted(BLOCK)474 bad = [b for b in want if b not in BLOCK]475 if bad: sys.exit(f"no block {', '.join(bad)}: the blocks are {', '.join(sorted(BLOCK))}")476 t0 = time.time()477 for b in want:478 t = time.time(); _run_block(b); print(f" [block {b}: {time.time() - t:.1f} s]")479 ok = summary(write=(want == sorted(BLOCK)))480 kinds = {}481 for r in RESULTS: kinds[r["kind"]] = kinds.get(r["kind"], 0) + 1482 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 ""))483 sys.exit(0 if ok else 1)484