""" jump_q.py -- the jump set as the class maxima at f > 1, where the bend's kernel splits each class. Question, derivation, predictions, kill and controls frozen before code; the engine and grid below. QUESTION. At odd p over the unramified base of degree f > 1, zeta_p in K (N(-ubar) = 1): is the jump set still the staircase of the class maxima H(m), proved at f = 1 (staircase.py, weld.py), now that each class Gamma_m = (s/p^m, m) splits into units off the kernel (landing e* exactly) and on it (tame_q.py)? Over 2 the wild readout is unread at f > 1: odd p only. DERIVATION (by hand; every use of f = 1 in the f = 1 proof). (F1) "zeta_p in K forces ubar = -1, so y^p - 1 sits past e* at every leading digit": FALSE at f > 1 (TRANSPLANT). Repair: off the kernel y lands at e* (excess 0); on it y^p - 1 sits past e*, and the f = 1 step runs verbatim (above the bend p-th powers map U_(s+j) onto U_(e*+j), j >= 1, the graded map x -> ubar x bijective on F_(p^f)), so a kernel landing is e* + v(zeta_p^(-a) y - 1) - s <= e* + G(m) - s. The witness y = h^(-1), v(zeta_p h - 1) = G(m) > s, has level s and residue that of zeta_p, which is on the kernel. So H(m) = G(m) + e at f > 1, attained on the kernel, no outside theorem. (F2) Pagano's presentation "U_1 = Lambda/Z_p V, one phi_i per weight": f = 1 only. His Theorem 1.5 (read in his text): U_1 = M^(f-1) (+) M*/Z_p v as filtered Z_p-modules, the direct sum filtered by the min (his 3.2.1). Torsion, so zeta_p, lies in the second summand; adding a p^m-th power with a nonzero first component cannot raise the weight, so G(m) is computed in M*/Z_p v, which is the f = 1 module: the Proposition 3.35 step and the staircase formula run unchanged. (F3) The bracket: the class's landings are {e*} (off the kernel, never empty at f > 1: q - 1 > p - 1) together with the kernel's, which lie in [min(H(m), e* + p^m), H(m)], both ends attained (the kernel's least landing is e* + min(l, p^m), tame_q). "Rigid" moves to the kernel: kernel-rigid iff l < p^m, the kernel then one value e* + l. (F4) No kernel-rigid class below N, so zeta_(p^N) in K forces l >= p^(N-1): f-free once (F3) holds. (F5) The rigid-seat closed form (i_2, beta_2) from dep = l = q e + r: f-free (pull-back through rho). The N = 1 bound H(M) - e* <= e: f-free (U_(e*+1) is all p-th powers at every f). (F6) The jump set reads M e digits of u: its proof's Hensel and O/pi^A steps are f-free; the Haar count (Pagano's 1.7/1.8 and Serre's mass) is f = 1 as written. OUT of this question. PREDICTIONS. (P1) H(m) by brute force over kernel units equals G(m) + e by search over U_1^(p^m), and units off the kernel land at e*, at every field and class. (P2) The staircase of H is a valid extended jump set (beta down, weights up, first point (c_0, M + 1) at e*, last beta = N), and equals the set rebuilt from the echelon's weights of zeta_p modulo p^n-th powers. (P3) Kernel landings inside the bracket, both ends met; l >= p^(N-1). (P4) The closed form at every kernel-rigid seat. DESIGN. tame_q.py's Ring at p = 3, f = 2, e = 2, 4, 6, 12, 18 and p = 5, f = 2, e = 4, 8: random digits with N(-ubar) = 1 and designed departures 1 .. s + 2, plus x^e - p T(dbar) twisted toward zeta_9 (Phi_9-type designs over Z_9) for N = 2. weld.py's Echelon generalized to f elements per level (F_p-linear algebra on F_(p^f) leading coefficients), giving U_1^(p^m) mod U_L and G(m) exactly; brute H(m) over kernel units z = 1 + T(a) pi^c + ... to the depth G sets (the brute arm and the grid as run: THE ENGINE AND GRID below). KILL (printed). Fields off (P1), off (P2), off (P3) or off (P4), summed over the grid: nonzero fires. Bar on the kernel arm (the arm a split would break); the off-kernel count printed beside it. CONTROLS. C1 f = 1: the generalized echelon reproduces weld.py's g and jump sets on its own population rows. C2 plant: the bracket's lower end read as the class's least landing (e*) instead of the kernel's at a kernel-rigid field: (P3)'s count nonzero. C3 the zeta_p found has order p and residue on the kernel. THE ENGINE AND GRID, set before the run. O_K mod p^N as int64 vectors over Z_p, multiplied through a structure tensor read off tame_q.py's Ring. The echelon files up to f elements per level, leading residues in echelon form over F_p, generators 1 + omega(beta_j) pi^i over the F_p-basis beta_j; zeta_p starts at a residue with a^(p-1) = -ubar and each correction solves x -> x lead((1 + pi^t)^p - 1) over F_q. The brute arm needs no G: every unit of the class (c, m), all a != 0, a prefix landing below the next digit's floor rho^(m+1)(c + k) landing there for every extension and only the rest extended, so the class's landings are read exhaustively, kernel and off. L = e* + (M + 1) e + 3. Grid widened before the run: p = 3, f = 2, e = 2, 4, 6, 12, 18 at the four ubar with N(-ubar) = 1, and p = 5, f = 2, e = 4, 8, 20 and p = 3, f = 3, e = 6, 12 at three ubar each (-1 first, then off F_p), l = 1 .. s + 2, none and one random tail per ubar. e = 2, 4 at p = 3 and 4, 8 at p = 5 have M = 0, so they read (P1)'s off-kernel arm and the first point alone. N = 2: cofactor.py's design B^6 Phi_9(A/B), B = 1 + 3 Omega - omega(a) x^i, A = B + omega(th) x^k over Z_9, k = 1, 2, 3, th = 1, g, g^2. FINDINGS (copied from the printed run). Controls: C1 30 fields of weld.py's population at (p, e) = (3, 6), (3, 12), (3, 18), 0 off; C3 and the echelon's closure 0 off at 311 fields (C3's level and residue hold by construction, its order is the reading); every designed departure read back; C2 the class's landings read for the kernel's break (P3) at 311 of 311 fields, and C2' the departure read as l + 1 at 105 of the 105 fields with a kernel-rigid class (117 classes). (P1) to (P4): 0 fields off of 311, 0 classes off on the kernel, 0 off-kernel landings off e*, at every grid point: (3, 2, 2) 20 fields, (3, 2, 4) 24, (3, 2, 6) 34 with 28 second points and 12 kernel-rigid seats, (3, 2, 12) 52, 40 and 12, (3, 2, 18) 70, 70 and 48, (5, 2, 4) 15, (5, 2, 8) 18, (5, 2, 20) 27, 27 and 15, (3, 3, 6) 21, 21 and 9, (3, 3, 12) 30, 30 and 9; 275 fields at N = 1 and 36 at N = 2, ubar off F_p at 168; the widest live branch count 6; 0 of 105 kernel-rigid seats off the closed form. At N = 2 every field reads l >= 3 = p^(N-1): l = 3 i at the designs with a != 0 (seats (1, 3), (4, 2) at l = 3 and (1, 3), (5, 2) at l = 6, every th), l = 9 and the second point (19, 2) at a = 0, k = 3; the 18 fields at k = 1, 2 have M = 1 = N - 1, every class holding a root, so they read the first point (c_0, 2) and the bracket's ends alone. KILL MISSES. VERDICT. On this grid (f = 2 and 3 at p = 3, f = 2 at p = 5, M <= 2, M = 2 only at (3, 2, 18); N = 2 only at p = 3, f = 2, from one design family) the derivation's predictions hold: the class maxima sit on the bend's kernel, H(m) = G(m) + e (F1), units off the kernel land at e*, the kernel's landings (not the class's: off-kernel units sit at e*, below it) lie in [min(H(m), e* + p^m), H(m)] with both ends attained (F3), l >= p^(N-1) (F4), and the rigid-seat closed form holds with "rigid" read on the kernel, l < p^m (F5's first half; its N = 1 bound H(M) - e* <= e is not read). The staircase is checked against G alone: given (P1) its equality with the set rebuilt from G is pullback arithmetic, and that G's staircase is Pagano's jump set at f > 1 rests on (F2), his Theorem 1.5 as read in his text, which nothing here computes. So the run is a toy instance of (F1), (F3), (F4) and the closed form of (F5), and the claim at every odd p and f is the derivation's. CHANGED AFTER THE FIRST RUN: the plant C2 now runs as frozen, the class's landings put through (P3)'s comparison where it reads the kernel's (the first run compared e* with the kernel's least landing outside it, which cannot fail), with C2', the departure read as l + 1, beside it; the kill counts fields as frozen, its bar on the kernel arm, classes and off-kernel landings printed beside; a pullback outside T* is counted against (P2) instead of raising, the H side and the G side apart; C1 prints its (p, e). Every later run reads as the first. RUN RECORD. First run 10/10, 100.9 s; second 10/10, 100.1 s; third 11/11, 100.5 s, peak commit 22.6 MB; on moving to code, 11/11, 99.5 s. """ import os os.environ.setdefault("OPENBLAS_NUM_THREADS", "1") import random import time import numpy as np # noqa: E402 from module_law import check, section, CHECKS # noqa: E402 from tame_q import (Ring, build, fq_all, norm_is_one, u_of, # noqa: E402 departure, designed_digits) from weld import rho, pullback, jump_set, weight # noqa: E402 import weld # noqa: E402 from staircase import staircase, second_closed, second_point # noqa: E402 INF = 10 ** 9 SEED = 1701 # ------------------------------------------------------------ the engine class Units: """U_1/U_L of O_K = Z_q[pi]/(F) mod p^N as int64 vectors of length e f (index i f + j for y^j pi^i), multiplied through a structure tensor built from the tuple Ring R.""" def __init__(self, R, L): p, f, e = R.p, R.f, R.e self.R, self.p, self.f, self.e, self.q = R, p, f, e, R.q self.N, self.P, self.L = R.N, R.P, L assert e * R.N > L n = self.n = e * f # y^m pi^k for k <= 2e - 2, m <= 2f - 2, by the Ring def mono(k, m): x = R.zero() x[min(k, e - 1)] = tuple(int(t == min(m, f - 1)) for t in range(f)) z = R.zero() z[k - min(k, e - 1)] = tuple(int(t == m - min(m, f - 1)) for t in range(f)) return self.vec(R.mul(x, z)) tab = {(k, m): mono(k, m) for k in range(2 * e - 1) for m in range(2 * f - 1)} T = np.zeros((n, n, n), dtype=np.int64) for i in range(e): for j in range(f): for i2 in range(e): for j2 in range(f): T[i * f + j, i2 * f + j2] = tab[(i + i2, j + j2)] self.T2 = T.reshape(n, n * n) self.one = np.zeros(n, dtype=np.int64) self.one[0] = 1 idx = np.arange(self.P) vp = np.zeros(self.P, dtype=np.int64) for k in range(1, R.N): vp[idx % p ** k == 0] = k vp[0] = INF self.vpt = vp self.pk = np.array([p ** k for k in range(R.N + 1)], dtype=np.int64) self.pis = [self.one] x = np.zeros(n, dtype=np.int64) x[f] = 1 self.piv = x def vec(self, z): return np.array([c for a in z for c in a], dtype=np.int64) % self.P def mul(self, x, y): M = ((x @ self.T2) % self.P).reshape(self.n, self.n) return (y @ M) % self.P def pw(self, x, k): r = self.one while k: if k & 1: r = self.mul(r, x) k >>= 1 if k: x = self.mul(x, x) return r def pi(self, i): while len(self.pis) <= i: self.pis.append(self.mul(self.pis[-1], self.piv)) return self.pis[i] def scal(self, c, x): """omega-free scalar: the Z_q tuple c times x.""" w = np.zeros(self.n, dtype=np.int64) w[:self.f] = c return self.mul(w, x) def gen(self, i, a): """1 + omega(a) pi^i.""" return (self.one + self.scal(self.R.omega(a), self.pi(i))) % self.P def lead(self, z): """(level, leading residue tuple) of z - 1; level L means z = 1.""" w = z.copy() w[0] = (w[0] - 1) % self.P w = w.reshape(self.e, self.f) v = self.vpt[w].min(axis=1) lev = self.e * v + np.arange(self.e) i = int(np.argmin(lev)) r = int(lev[i]) if r >= self.L: return self.L, None k = int(v[i]) return r, tuple(int(c) for c in (w[i] // self.pk[k]) % self.p) def inv(self, z): """z^(-1) for a principal unit: z^(p^k - 1) once U_1^(p^k) is past the precision.""" k, lv = 0, 1 while lv < self.e * self.N: lv = rho(self.p, self.e, lv) k += 1 return self.pw(z, self.p ** k - 1) class Echelon: """At each level the subgroup reaches, up to f filed elements whose leading residues are in echelon form over F_p (pivot coordinate 1, zero at every earlier pivot).""" def __init__(self, U): self.U, self.at = U, {} def reduce(self, z): """z times filed elements, to the first level where its leading residue leaves the filed span: (z, level, residue).""" U, p = self.U, self.U.p while True: r, c = U.lead(z) if r >= U.L: return z, U.L, None c = list(c) for (_, vec, piv, invs) in self.at.get(r, []): k = c[piv] if k: c = [(x - k * y) % p for x, y in zip(c, vec)] z = U.mul(z, invs[k]) if any(c): return z, r, tuple(c) def insert(self, z): U, p = self.U, self.U.p todo = [z] while todo: z, r, c = self.reduce(todo.pop()) if r >= U.L: continue piv = next(j for j, x in enumerate(c) if x) k = pow(c[piv], -1, p) if k != 1: z = U.pw(z, k) vec = tuple(k * x % p for x in c) assert U.lead(z) == (r, vec) assert len(self.at.get(r, [])) < U.f bi = U.inv(z) invs = [U.one] for _ in range(p - 1): invs.append(U.mul(invs[-1], bi)) self.at.setdefault(r, []).append((z, vec, piv, invs)) todo.append(U.pw(z, p)) def closed(self, rng, gens): U = self.U ok = all(self.reduce(U.pw(b, U.p))[1] >= U.L for ents in self.at.values() for b, _, _, _ in ents) for _ in range(4): z = U.one for g in gens: z = U.mul(z, U.pw(g, rng.randrange(U.p ** 2))) ok &= self.reduce(z)[1] >= U.L return ok def basis(p, f): return [tuple(int(t == j) for t in range(f)) for j in range(f)] def power_subgroup(U, n): """H_n = U_1^(p^n) mod U_L from the (1 + omega(beta_j) pi^i)^(p^n).""" gens = [] for i in range(1, U.L): lv = i for _ in range(n): lv = rho(U.p, U.e, lv) if lv >= U.L: continue for b in basis(U.p, U.f): gens.append(U.pw(U.gen(i, b), U.p ** n)) E = Echelon(U) for g in gens: E.insert(g) return E, gens def zeta_p(U, s, ubar): """A p-th root of unity of level s: residue a with a^(p-1) = -ubar, each correction solving the graded map over F_q at a level past s.""" R, p, e = U.R, U.p, U.e mu = tuple((-x) % p for x in ubar) a = next(a for a in fq_all(p, U.f)[1:] if R.fq_pow(a, p - 1) == mu) one = basis(p, U.f)[0] y = U.gen(s, a) while True: r, c = U.lead(U.pw(y, p)) if r >= U.L: return y, a t = r - e assert t > s, "the candidate's p-th power did not cancel at e*" _, cw = U.lead(U.pw(U.gen(t, one), p)) x = R.fq_mul(tuple((-v) % p for v in c), R.fq_inv(cw)) y = U.mul(y, U.gen(t, x)) assert U.lead(U.pw(y, p))[0] > r def on_kernel(R, a, m, ubar): mu = tuple((-x) % R.p for x in ubar) return R.fq_pow(R.fq_pow(a, R.p ** m), R.p - 1) == mu def floor_at(p, e, c, k, m, L): x = c + k for _ in range(m + 1): x = rho(p, e, x) return min(x, L) def brute_class(U, c, m, ubar): """Every landing v(z^(p^(m+1)) - 1) of the class (c, m), exhaustively: z = 1 + omega(a) pi^c + omega(t_1) pi^(c+1) + ..., a prefix whose landing sits below the next digit's floor rho^(m+1)(c + k) lands there for every extension, and only the rest is extended. Returns the off-kernel landings, the kernel landings (L for a branch still alive at the precision) and the largest live branch count.""" R, p, e, L = U.R, U.p, U.e, U.L F = fq_all(p, U.f) om = {x: R.omega(x) for x in F} P = p ** (m + 1) off, ker = [], [] live = [] for a in F[1:]: z = U.gen(c, a) live.append((z, on_kernel(R, a, m, ubar))) k, widest = 1, 0 while live: fl = floor_at(p, e, c, k, m, L) nxt = [] for z, onk in live: lv = U.lead(U.pw(z, P))[0] if lv < fl: (ker if onk else off).append(lv) elif fl >= L: (ker if onk else off).append(L) else: nxt.append((z, onk)) widest = max(widest, len(nxt)) if len(nxt) > 400: raise RuntimeError("brute: too many live branches") pc = U.pi(c + k) live = [((z + U.scal(om[t], pc)) % U.P, onk) for z, onk in nxt for t in F] k += 1 return off, ker, widest # ------------------------------------------------------------ a field def vp_int(n, p): k = 0 while n % p == 0: n //= p k += 1 return k def shape(p, e, s, M): es = p * s L = es + (M + 1) * e + 3 return L, (L + e) // e + 2 def read_field(R, rng): """G(0..M+2), N, the brute landings of every class, the controls.""" p, f, e = R.p, R.f, R.e s = e // (p - 1) M = vp_int(s, p) c0, es = s // p ** M, p * s L, _ = shape(p, e, s, M) u = u_of(R) ubar = tuple(a % p for a in u[0]) l = departure(R, u) U = Units(R, L + e) z, a = zeta_p(U, s, ubar) U.L = L ok_zeta = (U.lead(U.pw(z, p))[0] >= L and U.lead(z)[0] == s and on_kernel(R, a, 0, ubar)) G, closed = {0: L}, True for n in range(1, M + 3): E, gens = power_subgroup(U, n) closed &= E.closed(rng, gens[:6]) G[n] = E.reduce(z)[1] N = min(n for n in range(1, M + 3) if G[n] < L) br = {} for m in range(M + 1): off, ker, wide = brute_class(U, s // p ** m, m, ubar) br[m] = dict(off=off, ker=ker, hi=max(off + ker), wide=wide) return dict(s=s, M=M, c0=c0, es=es, L=L, l=l, ubar=ubar, G=G, N=N, br=br, ok_zeta=ok_zeta, closed=closed) def verdicts(p, e, rec, dl=0, whole=False): """Counts off (P1) .. (P4) for one field, and what each read. The plants C2: dl shifts the departure the predictions use; whole reads the class's landings, kernel and off, where (P3) reads the kernel's.""" s, M, es, L, N = (rec[k] for k in ("s", "M", "es", "L", "N")) l = rec["l"] + dl G, br = rec["G"], rec["br"] out = dict(p1=0, p1off=0, p2=0, p3=0, p4=0, seats=0, rigid=0, lN=0) H = {} for m in range(M + 1): want = G[m] + e if G[m] < L else L b = br[m] out["p1"] += b["hi"] != want out["p1off"] += sum(v != es for v in b["off"]) H[m] = b["hi"] if b["hi"] < L else INF ker = b["ker"] + (b["off"] if whole else []) lo = min(b["hi"], es + p ** m) ok = min(ker) == lo and max(ker) == b["hi"] ok &= min(ker) == es + min(l, p ** m) if l < p ** m and m >= N: out["rigid"] += 1 ok &= set(ker) == {es + l} out["p3"] += not ok if N >= 2: out["lN"] = l < p ** (N - 1) out["p3"] += out["lN"] try: pts = staircase(p, e, s, M, H) except TypeError: pts = None try: fromG = jump_set(p, e, G, M + 1) except TypeError: fromG = None by = sorted(pts or [(None, 0)], key=lambda t: -t[1]) ok = (pts is not None and by[0] == (rec["c0"], M + 1) and weight(p, e, *by[0]) == es and by[-1][1] == N and all(by[k][1] > by[k + 1][1] and weight(p, e, *by[k]) < weight(p, e, *by[k + 1]) for k in range(len(by) - 1)) and pts == fromG) out["p2"] = not ok if M >= N and l < p ** M: out["seats"] = 1 out["p4"] = not pts or len(pts) < 2 or second_point( pts) != second_closed( p, e, l) out["pts"] = pts return out # ------------------------------------------------------------ populations def ubars(p, f, R0, rng, k): """-1 first, then up to k - 1 others with N(-ubar) = 1, off F_p first.""" F = fq_all(p, f) good = [x for x in F[1:] if norm_is_one(R0, tuple((-a) % p for a in x))] m1 = (p - 1,) + (0,) * (f - 1) rest = [x for x in good if x != m1] rest.sort(key=lambda x: all(c == 0 for c in x[1:])) return [m1] + rest[:k - 1] GRID = [(3, 2, 2, 4), (3, 2, 4, 4), (3, 2, 6, 4), (3, 2, 12, 4), (3, 2, 18, 4), (5, 2, 4, 3), (5, 2, 8, 3), (5, 2, 20, 3), (3, 3, 6, 3), (3, 3, 12, 3)] def population(rng): """(label, Ring) over GRID: per ubar with N(-ubar) = 1, departures 1 .. s + 2 and none, and one random tail.""" out = [] for (p, f, e, k) in GRID: s = e // (p - 1) L, N = shape(p, e, s, vp_int(s, p)) F = fq_all(p, f) R0 = Ring(p, f, e, [None] * e, None, N) top = 2 * e + s for ub in ubars(p, f, R0, rng, k): dbar = R0.fq_inv(ub) for l in list(range(1, s + 3)) + [INF]: dg = (designed_digits(rng, F, l, top) if l < INF else [F[0]] * top) out.append((f"l={'inf' if l >= INF else l}", build(p, f, e, dbar, dg, N), l)) out.append(("random", build(p, f, e, dbar, [rng.choice(F) for _ in range(top)], N), None)) return out def cyclo9(R0, k, th, a, i, om): """B^6 Phi_9(A/B) over Z_q made monic, B = 1 + 3 Omega(x) - omega(a) x^i, A = B + omega(th) x^k (i < k, deg Omega < k): the (b, d) of an Eisenstein polynomial of degree 6k whose root pi has A/B = zeta_9, cofactor.py's design with Teichmuller residues th and a.""" p, f = R0.p, R0.f zero, one = (0,) * f, (1,) + (0,) * (f - 1) def pmul(x, y): out = [zero] * (len(x) + len(y) - 1) for i_, u in enumerate(x): for j, w in enumerate(y): out[i_ + j] = R0.zadd(out[i_ + j], R0.zmul(u, w)) return out def padd(x, y): n = max(len(x), len(y)) x = x + [zero] * (n - len(x)) y = y + [zero] * (n - len(y)) return [R0.zadd(u, w) for u, w in zip(x, y)] B = [zero] * k for j, c in enumerate(om): B[j] = R0.zmul((p,) + (0,) * (f - 1), c) B[0] = R0.zadd(B[0], one) if any(a): B[i] = R0.zadd(B[i], R0.zneg(R0.omega(a))) A = padd(B, [zero] * k + [R0.omega(th)]) A3 = pmul(pmul(A, A), A) B3 = pmul(pmul(B, B), B) tot = padd(padd(pmul(B3, B3), pmul(A3, B3)), pmul(A3, A3)) while not any(tot[-1]): tot.pop() lc = R0.omega(R0.fq_inv(R0.fq_pow(th, 6))) tot = [R0.zmul(lc, c) for c in tot] e = 6 * k assert tot[e] == one and len(tot) == e + 1 assert all(all(x % p == 0 for x in c) for c in tot[:e]) assert any(x % p ** 2 for x in tot[0]) b = [zero] + [tuple(x // p for x in c) for c in tot[1:e]] d = tuple((-x // p) % R0.P for x in tot[0]) return b, d def zeta9_population(rng): """Fields over W(F_9) holding zeta_9: k = 1, 2, 3 (e = 6, 12, 18), th = 1, a generator g and g^2; per th, Omega none or random, and at k >= 2 a random a at each i < k.""" p, f = 3, 2 out = [] F = fq_all(p, f) for k in (1, 2, 3): e = 6 * k s = e // 2 L, N = shape(p, e, s, vp_int(s, p)) R0 = Ring(p, f, e, [None] * e, None, N + 2) g = next(x for x in F[1:] if all( R0.fq_pow(x, j) != F[1] for j in range(1, 8))) designs = [(F[0], 0, 0), (F[0], 0, 1)] designs += [(rng.choice(F[1:]), i, t) for i in range(1, k) for t in (0, 1)] for th in (F[1], g, R0.fq_mul(g, g)): for a, i, t in designs: om = ([] if t == 0 else [tuple(rng.randrange(p ** 2) for _ in range(f)) for _ in range(k)]) b, d = cyclo9(R0, k, th, a, i, om) P = p ** N R = Ring(p, f, e, [tuple(x % P for x in c) for c in b], tuple(x % P for x in d), N) out.append((f"Phi_9 k={k} th={th} a={a} i={i} t={t}", R, None)) return out # ------------------------------------------------------------ sections def section_c1(rng): section("C1 f = 1: the engine against weld.py on its own population") bad = n = 0 seen = set() wrng = random.Random(weld.SEED) for label, p, e, b, d, dep in weld.population(wrng): if p == 2 or e > 18: continue seen.add((p, e)) rec = weld.read_field(p, e, b, d) s, M = rec["s"], rec["M"] L, N = shape(p, e, s, M) P = p ** N R = Ring(p, 1, e, [(x % P,) for x in b], (d % P,), N) U = Units(R, L + e) u = u_of(R) z, _ = zeta_p(U, s, tuple(a % p for a in u[0])) U.L = L Lw = rec["L"] mine = {n_: min(power_subgroup(U, n_)[0].reduce(z)[1], Lw) for n_ in range(1, M + 3)} theirs = {n_: rec["g"][n_] for n_ in range(1, M + 3)} mine[0] = theirs[0] = Lw n += 1 off = (mine != theirs or jump_set(p, e, mine, M + 2) != jump_set(p, e, theirs, M + 2)) bad += off if off: print(f" OFF p={p} e={e} {label}: mine {mine} weld {theirs}") check("C1 f = 1 echelon reproduces weld.py's g and jump sets", bad == 0, f"{n} fields at (p, e) in {sorted(seen)}, {bad} off") def section_fields(rng): section("P1-P4 THE JUMP SET AS THE CLASS MAXIMA AT f > 1") rows = population(rng) + zeta9_population(rng) tot = dict(p1=0, p1off=0, p2=0, p3=0, p4=0, seats=0, rigid=0, lN=0) foff = dict(p1=0, p2=0, p3=0, p4=0) plant = rigid_fields = plant_w = 0 bad_z = bad_c = 0 lmiss = 0 by = {} Ns = {} wide = 0 nonfp = 0 for label, R, dl in rows: p, f, e = R.p, R.f, R.e rec = read_field(R, rng) if dl is not None and rec["l"] != (dl if dl < INF else e * R.N): lmiss += 1 bad_z += not rec["ok_zeta"] bad_c += not rec["closed"] v = verdicts(p, e, rec) for k_ in tot: tot[k_] += v[k_] foff["p1"] += bool(v["p1"]) plant_w += verdicts(p, e, rec, whole=True)["p3"] > 0 for k_ in ("p2", "p3", "p4"): foff[k_] += bool(v[k_]) if v["rigid"]: rigid_fields += 1 plant += verdicts(p, e, rec, dl=1)["p3"] > 0 key = (p, f, e) by.setdefault(key, [0, 0, 0, 0]) by[key][0] += 1 by[key][1] += v["p1"] + v["p1off"] + v["p2"] + v["p3"] + v["p4"] by[key][2] += v["seats"] by[key][3] += len(v["pts"] or []) >= 2 Ns[rec["N"]] = Ns.get(rec["N"], 0) + 1 nonfp += any(rec["ubar"][1:]) wide = max(wide, max(b["wide"] for b in rec["br"].values())) if v["p1"] + v["p1off"] + v["p2"] + v["p3"] + v["p4"]: print(f" OFF {key} {label} N={rec['N']} l={rec['l']} " f"G={rec['G']} H={ {m: b['hi'] for m, b in rec['br'].items()} } " f"pts={v['pts']} {v}") if rec["N"] >= 2: print(f" N={rec['N']} {key} {label}: l={rec['l']} " f"ubar={rec['ubar']} G={rec['G']} pts={v['pts']}") for key, (n, off, seats, two) in by.items(): print(f" {key}: {n} fields, {two} with a second point, " f"{seats} kernel-rigid seats, off {off}") print(f" fields by N: {Ns}; ubar off F_p at {nonfp}; widest live " f"branch count {wide}; designed l missed {lmiss}") check("C3 zeta_p: order p, level s, residue on the kernel", bad_z == 0, f"{bad_z} off") check("Cb the echelon closed under p-th powers and random products", bad_c == 0, f"{bad_c} off") check("designed departures read back", lmiss == 0, f"{lmiss} missed") check("C2 plant: the class's landings read for the kernel's break P3 " "at every field", plant_w == len(rows), f"{plant_w} of {len(rows)} fields") check("C2' plant: the departure read as l + 1 breaks P3 at every field " "with a kernel-rigid class", plant == rigid_fields > 0, f"{plant} of {rigid_fields} fields ({tot['rigid']} kernel-rigid " f"classes)") check("P1 H(m) = G(m) + e on the kernel", tot["p1"] == 0, f"{tot['p1']} classes off; off the kernel {tot['p1off']} " f"landings off e*") check("P1' units off the kernel land at e*", tot["p1off"] == 0, f"{tot['p1off']} off") check("P2 the staircase of H is an extended jump set equal to G's", tot["p2"] == 0, f"{tot['p2']} fields off") check("P3 kernel landings lie in [min(H, e* + p^m), H], both ends " "attained, least e* + min(l, p^m); l >= p^(N-1)", tot["p3"] == 0, f"{tot['p3']} off ({tot['lN']} fields with l < p^(N-1))") check("P4 the closed form at every kernel-rigid seat", tot["p4"] == 0, f"{tot['p4']} of {tot['seats']} seats off") kill = sum(foff.values()) print(f"\nKILL: fields off (P1) {foff['p1']}, (P2) {foff['p2']}, " f"(P3) {foff['p3']}, (P4) {foff['p4']} of {len(rows)}; the " f"kernel arm's classes off (P1) {tot['p1']}, (P3) {tot['p3']}, " f"off-kernel landings off e* {tot['p1off']}: " f"{'FIRES' if kill else 'MISSES'}") def main(): t0 = time.time() rng = random.Random(SEED) section_c1(rng) if not all(CHECKS): print("\ncontrol failed: nothing below is read") raise SystemExit(1) section_fields(rng) print(f"\n{sum(CHECKS)}/{len(CHECKS)} checks PASS " f"[{time.time() - t0:.1f} s]") if not all(CHECKS): raise SystemExit(1) if __name__ == "__main__": main()