diff --git a/research/negative-results-paradigm-search/README.md b/research/negative-results-paradigm-search/README.md new file mode 100644 index 0000000000..dc04f533bd --- /dev/null +++ b/research/negative-results-paradigm-search/README.md @@ -0,0 +1,380 @@ +# Negative results from a search for a new coding mechanism (no new κ) + +Scoping note, **no new κ**: one README, six standard-library checkers and one data file. No existing file changes. + +**Question.** Every witness on the frontier, 7.43e-4 (#285) at the time of writing, gets its saving from one +mechanism: the label (index-coding) decoder of the paired-cube line. Each data role saves one rank unit through a +free entrance label, and a centre-plus-producer decoder pays for it. The per-level coding gain is G ≈ 1.003 at +m ≈ 110–120, so the saving exponent a ≈ ln G / ln m is under 10⁻³. We looked for a different mechanism that could +multiply that exponent by 2 or more, on both the bit and the complex side. + +**Answer.** We found none. This note records what we tried, what is proved, what was computed, and what is still +open, so that others need not repeat the same routes. Section 1 covers a search run on 9–10 October 2026. Section 2 +lists earlier routes from 8–9 October that we discarded at the time. + +**Relation to other lists.** This complements Swapnil Jain's +[closed-ideas list](https://github.com/Swapnil-jain/integer-mult-kappa/blob/main/docs/CLOSED_IDEAS.md) and its +papers P1 ([doi:10.5281/zenodo.23265442](https://doi.org/10.5281/zenodo.23265442)) and P2 +([doi:10.5281/zenodo.23266393](https://doi.org/10.5281/zenodo.23266393)). Where a row overlaps theirs, we say so. We use +their status labels: **[proof]** a complete argument; **[cert]** an exact computer certificate; **[exp]** a decisive +experiment or a floating-point computation named as such; **[arg]** a short argument, not written as a full proof. +Every closure holds only in its stated model. Nothing here is a lower bound for integer multiplication. + +```sh +cd research/negative-results-paradigm-search/checks +python3 -B complex_m2_lambda2_certificate.py # < 1 s, section 1.1(a) +python3 -B multiplicative_index_maps.py # < 1 s, section 1.3(d) +python3 -B fourier_duality_f3.py # < 1 s, section 1.3(c) +python3 -B nonlinear_frames_m1.py # about 2 s, section 1.3(f) +python3 -B flag_model_cliques.py 2 # < 1 s, section 1.4(c) +python3 -B flag_model_cliques.py 3 # about 10 s +python3 -B bh_sign_gauges.py # < 1 s, section 1.4(d) +``` + +## 0. Model and the constraint that shapes everything + +The two recursive tape primitives are the address-field interchange (bit side, payload F₂, frames are rational +shears Φ_M:(H,D)→(H+MD,D) over Z/q^b with q an odd prime) and the simultaneous H₀ layer (complex side, frames are +exact Gaussian-dyadic Clifford operators acting as g^{⊗f} on f columns). A frame network splits rows into W role +streams; pointwise gates act at a common frame; a frame change of rank t costs one child of width t·f. The saving a +is the root of the moment Σ_e (t_e/m)^{1−a} = W. For small a, a ≈ D/E, where D = Wm − Σ t_e is the deficit and +E = Σ t_e ln(m/t_e) is the entropy. + +For lower bounds we use the general register (dilation) model, which contains every frame network and allows gates +between registers at different frames: + + ∏_i ( I + ([g_i] − 1) N_i ) = [T] · (permutation) over K[G]^{W×W}, + +with N_i rank-one idempotents over the payload field K, g_i the paid frame changes and T the target. Cost-zero +factors absorb the free maps. Correctness for all column counts f is exactly this identity in the group ring. + +Two facts govern any new mechanism: +- **Both sides must move.** κ ≤ min(a_b, a_c) up to the assembly factor. In particular κ ≤ a_c/(1+a_c), because the + complex primitive's binary basis changes call chunk interchanges. A gain on one side alone is worth at most the + gap to the other side, under 2% today. +- **Small m pays enormously.** a = ln G / ln m. Any saving at m ≤ 6 would be worth at least 50 times today's + exponent. That is why much of the search below concentrates on small m. + +## 1. The search of 9–10 October 2026 + +### 1.1 Complex primitive + +**(a) m = 2: no saving for any frames. [cert]** +Model: frames are any matrices in GL₄(C) generated by Hadamards on the two qubits and free maps. Free maps are all +monomial matrices (any invertible diagonal, any permutation of the four basis states). Gate coefficients are any +complex numbers, and gates may join registers at different frames. +Certificate: the FO lemma with ρ(g) = conjugation by Λ²(g) on End(Λ²C⁴). +- Λ²C⁴ = P₁ ⊕ P₂ ⊕ P₃, where P_a = span{e_x ∧ e_{x⊕a}}, one plane per perfect matching of F₂². +- Y₀ = span{Π₁, Π₂, Π₃}, the coordinate projectors onto the P_a. Every monomial matrix permutes the three planes, so + Y₀ is invariant under the free group. +- f(g) = dim(Y₀ + ρ(g)Y₀) − dim Y₀ is 0 on every monomial matrix, 1 for the Hadamard on each matching, and 2 for + H⊗H. Hence s ≥ 2W = Wm. + +This strengthens the earlier Clifford-only result. It covers Clifford+T, arbitrary phases, the exact "y-phase" +frames below and non-unitary diagonal scalings. The script is `checks/complex_m2_lambda2_certificate.py`. + +**(b) m = 3: the natural certificates cannot exist; the case is open.** +- [proof] No torus-invariant FO certificate exists in characteristic ≠ 2. Suppose Y₀ lies in the weight-0 part of a + representation, is AGL(3,2)-invariant, and gives a rank-linear bound. Then the fixed spaces of the coset block + groups would give an n-multilinear representation of the Fano matroid. That is impossible when 2 is invertible, + and gate coefficients contain 1/2. +- [exp] The best FO bound we found in the enlarged model is s ≥ 2W, from difference-class projectors in Λ², giving + G ≤ 1.5. Searches over sums of irreducible pieces of Λ¹–Λ⁴ and Sym²–Sym³ found nothing better. +- In the Clifford model the earlier bound is s ≥ 50W/21. It leaves only W = 2 with s = 5 and W = 3 with s = 8 at + small W. + +**(b′) m = 3, W = 2: settled in the dilation normal form, open in the full register model.** +- [proof] *Window lemmas*, valid for any frame group because they use only subadditive cost, target cost 3 and + cost ≥ 1 per paid move. Write t_j for the scalar mixing between moves j and j+1. + - In a three-move window whose outside moves cost at most 2 in total, the identity coefficient forces + t_j[1][1]·t_{j+1}[1][1] = 0, and the inverse network forces t_j[0][0]·t_{j+1}[0][0] = 0. + - Two-move windows force antidiagonal mixing. + - No single move can cost s − 2 or more. +- [cert] *Dilation normal form* (scalar idempotents, with free elements only inside paid moves): no W = 2 saving + for any cost profile with s ≤ 5. + - Five rank-one moves leave 169 zero patterns and 84 coefficient systems. Gröbner bases over Q decided each one, + so the verdict holds over every field of characteristic 0. + - The 6 consistent systems all force g₁ = 1 or g₅ = 1. + - The other profiles with s = 4 or 5 leave no survivor. + - A second, numerical code path agrees on all 84 systems. + - Only the cost properties above are used, so this covers Clifford frames and Clifford plus 2^k-th-root phases. +- [cert] *Full register model*: W = 2 needs s ≥ 5. With one free B-element inserted anywhere (6 placements, about + 109,000 exact systems) there is still no saving; any W = 2 solution would need at least two such insertions + between scalar mixings. +- [exp] *FO search*: nothing beats the Clifford bound 50W/21. 5,127 new functions from flag, isotropic-line and + stabilizer-state modules gave at best 7/3. FO is also blind to the window constraints. +- Open: the full register model at W = 2, s = 5 with two or more inserted free elements, and W = 3, s = 8. + +**(c) Non-Clifford frames and approximate arithmetic. [proof]/[arg]** +- [arg] Rounded arithmetic is legitimate in the cost model. Non-dyadic constants cost O(log p) per entry, which the + leaf terms absorb. Error growth is polynomial in d, so O(log d) guard bits suffice, and dirty roles are restored to + the same absolute error. But the network identity must still hold exactly in C[G]: a fixed per-level defect does + not shrink to 2^{−p}. +- [proof] In the synthetic layout, records lie in C[y]/(y^r+1). A diagonal frame y^{θ(x)} is a controlled signed + cyclic shift of the record, so it is free and exact. These frames reduce to the Clifford case: + - with bounded exponents, setting y → 1 gives a Clifford network of equal cost; + - with exponents k + l·r/2^s, one gets Clifford plus 2^{s+1}-th roots of unity, valid for every Galois conjugate; + - phases algebraically independent of the rest specialise to 1. +- We found no mechanism by which non-Clifford frames enlarge the one-dimensional entrance label at large m. + +### 1.2 Bit primitive: the abelian register model with per-role Levi targets + +Each role may end at its own target C_w, any invertible lower-triangular matrix, because free scalings X_w on the H +fields and Z_w on the D fields at entry and exit turn the shear by C_w = X_w Z_w^{-1} into the shear by I. A common +target C is equivalent to I. Mixed targets break the common-target hypothesis behind the trace lemma (P1, §5) and +behind the parity cut. + +**(a) Flag theorem. [proof]** +Setting: ∏_a (I + ([A_a] − 1) N_a) = diag([C_w]) over F[L], with every C_w invertible lower triangular (uniform or +not), any rational frames A_a and any payload field F. Call a frame *up* if its strictly upper part is nonzero. +Then + + W m − s ≤ Σ_{a up} ( m/2 − rank A_a ). + +In particular, **m = 2 never saves, for any assignment of Levi targets.** +Proof. +1. The strictly-upper part φ is a homomorphism from L to an abelian group. It kills every target and every low + frame, so the up factors satisfy a target-zero identity in F[φ(L)]. +2. At a generic character the up factors are proper pseudo-reflections with product I. In compact-WY form, + X_up T Y_upᵀ = 0 with T invertible, and Sylvester's inequality gives rank X_up + rank Y_up ≤ #up. +3. The character ζ^{A_ii} kills no target, because invertible lower-triangular C_w have nonzero diagonal. The span + condition (below) then gives span{x_a : (A_a)_ii ≠ 0} = F^W, so W ≤ rank X_up + #{low a : (A_a)_ii ≠ 0}. +4. Sum over i, using rank A ≥ #(nonzero diagonal entries) for lower-triangular A: + mW ≤ m·rank X_up + Σ_low rank A_a. The same holds for Y. Add the two and use step 2 to get + mW ≤ (m/2)·#up + Σ_low rank A_a. Subtract s. + +With a common target, conjugate first; the bound then holds for every complete flag, with "up" meaning frames that +do not preserve it. Every inequality of the proof was checked on 18,200 exactly verified solutions from unpruned +solvers, and on 11,760 more from a pruned one. + +**(b) Character and span conditions with Levi targets. [proof]** +For a character χ with kernel K, let t and u count the frames and targets in K, and let d = E − W. Then: +- |t − u| ≤ d; +- span{x_a : A_a ∉ K} ⊇ span{e_w : C_w ∉ K}, and the same for the y_a. + +Targets that are all multiples of one matrix, for example a mix of I and 2I, look like a common target to every +characteristic-2 character. So "some roles at I, some at 2I" gives nothing at m = 2, and in general no more than a +common target does. + +**(c) Small exact searches at m = 3, W = 3. [cert]/[exp]** (not packaged here) +Rank-one integer frames u vᵀ with u, v ∈ {0, ±1}³, and every lower-triangular subset-sum target, under the flag, +parabolic, character and span filters: +- E = 4: no candidate. +- E = 5: impossible by the flag theorem. +- E = 6: no candidate among 4.5·10⁹ leaves. +- E = 7, sparse pool: every candidate dies on a mod-3 kernel. +- E = 7, full pool: incomplete. +- E = 8 with Levi targets: not run. + +**(d) Non-abelian frames with mid-network Levi maps (G₀ = shears ⋊ Levi pairs).** +Free Levi maps applied in the middle of a network act on each register's shear parts by n ↦ X n Z^{-1}. A single +paid shear can then act on different terms of one input with different effective shears. With X = 2I every shear +is a commutator, so all character-based bounds fail: doubled import, counting, span and flag. Simple FO certificates +from permutation modules reach a ratio of only 1.33, where 2 is needed. (e) settles the case anyway. + +**(e) Theorem G₀: the flag theorem survives mid-network Levi maps. [proof]** +Setting: G₀ = N ⋊ L. +- N = M_m(Q) are the shears; L are the pairs (X, Z) of invertible lower-triangular matrices, acting by + (X,Z)·M = X M Z^{-1}. +- The state lies in M_W(F[G₀]). Free operations are GL_W(F₂) mixing and left multiplication of any register by + any l ∈ L, at any time. Paid operations are shears, at cost rank M. +- Targets are Π·diag([c_u l_u]), with c_u invertible lower triangular and l_u arbitrary. + +Then W m − s ≤ Σ_{up} (m/2 − rank M_j), as in (a). So **m = 2 never saves in G₀ either.** + +Why the earlier tools failed: with X = 2I every shear is a commutator, so every one-dimensional character is +trivial on shears. The proof uses a matrix rank function instead of characters. +1. Absorb the free operations into the idempotent vectors, which now have entries in F[L]. Projecting G₀ → L + kills every paid factor, so the identity becomes ∏_j (I + a_j([n_{M_j}] − 1)b_jᵀ) = Π·diag([n_{c_u}])·Π^{-1}. +2. On the group rings of the solvable quotients G₀/N′, where N′ is spanned by the matrix units over a down-set + (L-invariant, hence normal), use the Sylvester rank function. Its sources: + - congruence subgroups are torsion-free; + - torsion-free elementary amenable group rings are Ore domains (Kropholler–Linnell–Moody, Tamari); + - rank([g] − 1) = 1 for g of infinite order; + - matrices over F[L] have the same rank in every such quotient. +3. Two quotient families give the two halves of the flag argument: + - dividing out the lower-triangular shears gives rk A_up + rk B_up ≤ #up; + - projecting onto the rectangles {r ≤ i ≤ c} gives W ≤ rk A_up + #{low j : (M_j)_ii ≠ 0}. + +The same proof allows free zero-in/garbage-out temporaries. A separate adversarial review found the proof correct. +Exact checks covered valid W = 2 networks that are genuinely non-abelian, including one where a single paid shear +acts on 7 terms of one input with 6 different effective shears. + +Scope: G₀ omits the free lower-left updates D += K·H of the full machine, under which N is not normal. The full +non-abelian Borel model at m = 2 is therefore not covered by this theorem. + +**(f) Abelian m = 3: s ≥ 2W + 1. [proof]** +- Tight-frame lemma: let k be a rank-one frame with A₀₂ ≠ 0, and let P be the set of frames whose strictly-upper + parts are parallel to k's. Then 2W ≤ #up − |P| + 2·#{low frames with A₁₁ ≠ 0}. The proof uses a functional on the + {0,1} × {1,2} block, which kills P and no target. +- At s = 2W, the flag theorem forces 2W up frames of rank one. The lemma then forces A₀₂ = 0 for every frame, and the + coordinate kernels A₀₀, A₂₂ and {A₀₁ = A₀₂ = 0} contradict each other. +- So W = 3 needs s ≥ 7, and W = 4 needs s ≥ 9. The gain bound is still G < 3/2. +- [cert]/[exp] A type-level enumeration (the coordinate-character conditions depend only on support patterns) and + {0,±1} box searches leave no candidate in the following cases; every candidate found was killed by the first-order + mod-2 condition: + - W = 3, E = 8, sparse box: 1,035,664 candidates; + - W = 4, E = 8, full box: 7,176 candidates; + - W = 3, E = 7, sparse box. +- Still open: W = 3 with s = 7 or 8, and W = 4 with s = 9 to 11. + +### 1.3 Machine operations outside the frame model + +Each operation below is linear-time on a multitape machine by the 02-streams lemmas. + +| | Operation | Verdict | Status | +|---|---|---|---| +| (a) | Address-dependent (masked) gates, with stream compression | Freezing every mask at one logical address gives an unmasked network of the same cost. A compressed stream of density ε needs at least ε(rank − log_Q(1/ε)) interchanges. So this reduces to (b) up to O(1/b). | [proof] | +| (b) | Clean ancillas (extra zero-initialised volume, garbage erased) | The first-order p-integral bound and the cut bounds survive; apply them to the data–data block. In the moment equation an ancilla of total rank R adds R to Σt_e and nothing to Wm, so it must raise the deficit by more than R. Nested dirty auxiliaries are deficit-neutral and dominate ancillas by more than 10× today. | [proof]/[arg] | +| (c) | Fourier duality (an odd-characteristic payload such as F₃ makes the WHT exact and growth-free) | An XOR-shear H ⊕= D equals WHT_H · diag((−1)^{ξ·D}) · WHT_H, and an interchange is 6 H-layers plus 3 free sign passes (checked exactly). It does not retire the bit primitive: the complex primitive's basis changes call chunk interchanges at width eK > e, so the recursion is circular, and a contiguous-slot layer network needs about 10 extra children per role against a deficit of about 0.2. Inside a network it is covered by the non-CSS-label row of P1. | [cert]/[arg] | +| (d) | Multiplicative index maps (multiplying an index by a fixed unit mod N is O(V)) | Transposition is k ↦ 2^e·k mod (2^{2e}−1). The CRT turns it into a free negation, but the CRT step is itself the expensive shear. *Valuation lemma:* any factorisation into fixed units of size at most C has length at least e/log₂C. BFS over the generators {−1, 2, 3, 5, 7} gives exactly e for e ≤ 10, the naive count. | [proof]/[cert] | +| (e) | Carry-free digitwise maps (XOR, F_q-linear maps, F_{q^k} arithmetic on whole fields) | Not linear-time by any known method. Free updates are cyclic shifts with carries plus fixed units, so cheap linear frames live in characteristic 0, where the trace lemma and the p-integral theorem apply. An escape from characteristic 0 must therefore be non-abelian, not cross-characteristic. | [arg] | +| (f) | Nonlinear controlled-shift frames (the offset may be any polynomial-time function of earlier fields) | The target still costs m per register: a backward-information function is subadditive, at most 1 per interchange and equal to m on the target. A nonlinear shear x += g(y) costs 2 children, not 1. Frames that are smooth at a common fixed point linearise through the Jacobian. At m = 1, Q = 3 the generated group is all of S₉, and the exact cost census matches these lemmas. Non-smooth frames evade every linear obstruction; permutation-module FO gives only s ≳ 2W. | [proof]/[cert]; open | +| (g) | Unequal or digit-class streams, multi-rate heads | Reduce to virtual registers, compression or copying, and to the P1 rows on unequal widths and mixed motifs. | [arg] | +| (h) | Sparse convolution and prefix-sum gates | Augmentation kills translations, so the derivative bound survives; the cut bounds survive. No mechanism found. | [arg] | + +**Follow-up on (f), nonlinear frames at small size.** +- [arg] **Common-frame networks with s ≤ 8 never save, for any frames (nonlinear included) and any gates.** + - A common-frame network is a one-shot code on the undirected graph of distinct gate frames, with at most s edges. + - Coding equals routing for at most 6 coding nodes, for trees, for graphs whose terminals lie on one face + (Okamura–Seymour), and for theta graphs (Liu–Que–Li–Li, arXiv:2608.06070, Theorems 5 and 7, and the earlier + work cited there). So a saving needs at least 7 frames and cyclomatic number at least 3. + - That settles m = 2 with W = 3 or 4, and m = 3 with W = 3, without search. The smallest open common-frame + case is m = 2, W = 5, s = 9. + - This assumes the cited coding model covers time-ordered gate circuits. +- [proof]/[cert] **At m = 2, nonlinear frames have no local advantage over linear flags.** In the machine's free + group (controlled shifts by any polynomial-time offset, plus fixed units), the largest set of pairwise + session-compatible unit-cost directions is exactly q, as for linear flags. It is 3 at q = 3 for every b, checked + exhaustively and by SAT. Carry-free fibre maps would give 9 at N = 9, but they are not linear-time. +- [cert] **Register-model searches.** Exact F₂[Γ] arithmetic at N = 3, W = 2, m = 2, s = 3, over two structured + classes (6.6·10⁶ and 7.95·10⁷ distinct states), found no saving. +- [exp] **FO bounds.** Permutation-module FO certificates, including an LP over all free-group-stable sets of + point pairs, give only s ≥ 4W/3. +- **Open:** the register model beyond these classes (W = 2 with s = 3, W = 3 with s = 4 or 5). It has no useful + first-order identity: the group is generated by involutions, so every characteristic-2 character is trivial. + +### 1.4 Other primitive families, and embedding known coding-gap codes + +The reduction used throughout is this. With free temporaries, a frame network is a frameless bijective circuit plus +a map of its gates into the frame space. The gain is therefore at most the coding gap of the frame space for sessions +at the target's relative position. The undirected unicast gap codes that refuted the Li–Li conjecture this month +(Braverman–He, arXiv:2610.10108; Zhang–Li–Li, arXiv:2610.09367) are the natural seeds. + +**(a) Frame families.** +- Permutation and signed-permutation frames, finite subgroups of GL(Z), and lattice-preserving finite linear groups + never save. FO on Λ/pΛ applies whenever the H and D parts split the lattice mod p. [proof] +- Qudit Clifford frames over Z/N give the same rank geometry for prime N, and are slot-additive across primes for + composite N (coordinate isolation). [arg] +- Abelian or cyclic frame groups (units mod N, digit rotations, Z/N translations) have l₁-embeddable metrics, so + their gap is 1. [arg] +- Tensor-power primitives A^{⊗e} are slot-additive without free carry-free mixing. [arg] +- Primitives defined through multiplication are circular. [arg] + +**(b) Cayley-graph seeds. [proof]** If a finite frame group with cost-1 generators S is used directly, with +sessions along an involutive target z at distance D, the gap is at most D/|S|. A gain needs physical degree below +the session distance, which is the opposite of the Tanner seeds: Braverman–He has degree 10 at distance 5. + +**(c) Full GL_{2m} flag model (non-abelian, same interchange primitive). [cert]** At m = 2, among the cost-1 +neighbours of a flag, the largest pairwise session-compatible set has size 2 at q = 2 and 3 at q = 3. In the abelian +shear model it is m = 2. So the local "compatible directions ≤ m" obstruction, which rules out isometric Tanner-code +embeddings in the abelian model, is model-specific. On the bit side, m = 2 is closed for the abelian and G₀ models +(1.2(a), (e)), but not yet for the full non-abelian flag model. Script: `checks/flag_model_cliques.py`. + +**(d) Braverman–He's PG(2,9) code with per-session sign gauges. [cert]** +- With a common target I, an isometric frame embedding at m = 5 with rank-one edges is impossible: on a geodesic, + steps are orthogonal idempotents, and 731 edges are crossed in opposite directions by different sessions. +- With targets C_i = ±C₀, geodesic steps are C_i·P. Opposite traversals become consistent exactly when the two + sessions have opposite signs, which turns the obstruction into a sign system on the 157 sessions × 735 edges. +- No session uses an edge in both directions, but the system is unbalanced: 23,025 violated constraints in one + component. Sign gauges do not help. +- With general Levi targets the embedding is heavily overdetermined: about 11,760 rank-one conditions against 4,550 + unknowns. + +Script: `checks/bh_sign_gauges.py`. The data file holds the deleted-edge list R and the vertex order π transcribed +from the paper's appendix. + +### 1.5 Literature, 15 September – 10 October 2026 + +We scanned arXiv (cs.DS, cs.IT, cs.CC, cs.DM, cs.SC, math.CO) through the 9 October listing, ECCC, openai/math +(unchanged since 8 October) and GitHub. We found no new mechanism. Items: +- Zhang–Li–Li and Braverman–He have no follow-ups. +- J. A. Sussman's Lean WHT/DFT package (jacobalansussman/wht-power-saving-lean). Its scratch-copy note prices + copy-free centres at ×1.71 and shows that copies along coordinate directions gain at most ×1.11–1.25. +- A Lean certificate that the Li–Li conjecture fails with an unbounded gap (chris1234555/ncc-certificate). It goes + from a fast algorithm to a coding gap, not the reverse. +- Adler (FOCS 1996) on XOR coding for transposition-like I/O problems. Its gain comes from broadcast with side + information, which bounded fan-out reduces to the label mechanism. +- Alman et al. on Kronecker powers: constant factors only, or table lookups that a fixed-alphabet machine cannot do. + Catalytic register programs bound space, not time. + +## 2. Earlier routes we tried and discarded (8–9 October 2026) + +These rows summarise exploration notes. Their scripts and certificates are not packaged here, so treat the +[cert] labels in this section as reports, and ask if you need a reproduction. + +### 2.1 In-class routes on the paired-cube design + +| Approach | How it failed | +|---|---| +| **5-pair ports** (bigger cubes, less centre loss) | Each 32-port cube needs 171 decoder channels, so the cost per port is about 4× the triples', against a 1.2–1.4× budget. Even at p = 16 the complex saving would be about 0.4× the triples'. (Compare P2's weight-five row.) | +| **Register recycling** (#184-style reuse of retired registers) | The peak number of simultaneously live registers forces at least 4.9 per port (4.76 under fresh-rank liveness), against about 3.45 needed for 2×. Even with the recycling conditions relaxed, the gain is +3.7% (at most about +5.4%). | +| **Source-assisted words** (#193, original sources cancel values) | Even with every source available everywhere (not actually allowed), κ gains only +2.9%. The extra registers come from fan-out, not from the cancellable part. | +| **Nested-chain decoder modules** | They would need sources that targets cannot read inside side roots, or about 220 extra centres. Those centres cost more than the whole deficit. | +| **Better pair modules** (exact minimum register count) | The J0 module is within about 7% of the best found, worth about +0.5–1% κ. No construction gap. | +| **Smaller cover / cancelling modules** | The cover dimension is fixed because a three-shear rotation is minimal. Cancelling sums would put unreadable sources into a root's frame, which the checker rejects. | +| **Centre restructuring** (built from P, reordered, split) | −1% to −7%, because the centre sums are already co-optimised with P. | +| **Root-role permutations, merging 2-port roots, gauge parameter** | Exactly neutral. | +| **Non-uniform local circuits, parity-based cube totals** | No gain, or −1.3%. | +| **Five-stage "bridged" schedule** (#209's idea) | Our pricing at the time: about +6% on the complex side but only +1.9% on the bit side, which then sets κ, so about +1.9% overall. #234 later realised it with a five-stage bit supplier as well. | + +### 2.2 New-primitive routes + +| Route | Result | Status | +|---|---|---| +| Different-frame (DF) gates: Clifford operator-valued gate coefficients | No saving at m ≤ 2 for any W (exact rational certificate over Sp(4,2)). Gates without a (1+i) denominator never save, at any m. At m = 3 the best bound is s ≥ 50W/21; the only surviving W = 2 profile is five rank-1 children. DF cannot cut centre loss: summing the per-class decoder identities gives K + H + B = I as scalars. | [cert]/[proof] | +| Characteristic-0 Tanner codes on the dual polar graph DSp(2m,2) (small-instance reduction: free temporaries give a one-shot code over Q(i) with sessions between opposite Lagrangians) | Every m = 2 LP optimiser found has no code over any field (tight-cut propagation, corridor argument). Sp(2m,2)-invariant schemes cannot deliver opposite-pair sessions. Product Tanner codes have causal gap exactly 1. | [proof]/[cert] | +| Small instances | No saving at m = 1, W ≤ 2, ≤ 5 session labels, ≤ 6 coding labels, cyclomatic number ≤ 2, product label families, mW ≤ 9, m = 2 with W ≤ 5, m = 3 with W ≤ 3. | [cert] | +| Centre decoders | The paired-cube and bit star decoders sit at their invariant minimum rank, and the dense readable remainder is forced at rank about h. Overcomplete or coordinate-direction centres gain at most about 4–10%. | [cert] | +| More than one saved dimension per data role | k-dimensional source labels need degree ≥ 3 exact-match indicators, so the centre rank grows from about h to about h⁴. Two-sided labels split the readers of a centre copy into about 15 classes at p = 12, multiplying copy cost. Port-mixing shears break the Pauli structure. | [arg] | +| Cover and stage structure | Within one pair's three-transfer swap with common-frame scatter, the cover penalty (ln 3 per local rank unit) is intrinsic; padding loses (4h −11%, 5h −18%). #209's five-stage twins evade this by sharing helpers across pairs. | [arg] | +| Cross-level and recursive primitives | A self-similar k-level scheme flattens to one level at (W^k, m^k). Gauged or network-valued children gain at most ×1.03. Cross-level labels give at most ×1.11 before auxiliaries. | [proof]/[arg] | +| Gain mechanisms in the Clifford model | Fixed points of the output permutation never save. Swap partners that share a label save nothing. A dirty-role relay at best breaks even. Each saving role needs ≥ 3 coded transfers; #209 later showed 2 suffice with free gates between pairs. Aux swaps (×0.73) and k-cycles (×0.27) lose. | [proof]/[arg] | +| Breaking min(a_b, a_c) | The bit network appears in the complex recursion only as rank-zero adapters, which the a_c moment already counts, so κ ≤ a_c/(1+a_c). | [arg] | +| Assembly weighting | The cover assemblies pass m* = min(a_b, (1−β)a_c) into an unchanged structured assembly. A balanced prefix (margin 1 − ε) gives about +0.05%. | [cert] | + +## 3. What remains open + +None of these has a construction. They are listed in rough order of how directly a positive answer would bear on κ; +remember that both sides must move. + +1. **Complex primitive, m = 3.** + - The full register model with W = 2 and s = 5 needs two or more free elements inserted between scalar mixings. + - W = 3 with s = 8 is open: the Clifford bound is s ≥ 50W/21, and the enlarged model has only s ≥ 2W. + - Torus-invariant FO certificates cannot exist there (Fano obstruction), so a proof needs a different tool. +2. **Bit primitive, abelian, m = 3.** W = 3 with s = 7 or 8, and W = 4 with s = 9 to 11. Proven bounds allow + G < 3/2. +3. **Bit primitive, full non-abelian model at m = 2.** Theorem G₀ does not cover the free lower-left updates + D += K·H. With them the shears no longer form a normal subgroup. +4. **Non-smooth nonlinear frames, in the register (superposition) model.** W = 2 with s = 3, and W = 3 with s = 4 or + 5, beyond the searched classes. The first open common-frame case is m = 2, W = 5, s = 9. +5. **Large m.** No mechanism is known that saves more than one rank unit per data role at a decoder cost comparable + to today's. The flag theorem and the FO bounds still allow gains up to about m/2. So the obstruction is the lack + of a construction, not a proof. + +## 4. Credits and disclosure + +The obstruction tools we cite: +- The FO lemma, the p-integral (mixed-characteristic) theorem, the trace identity, the support lemma and character + counting come from our earlier exploration. P1 and P2 independently prove the overlapping statements; cite those. +- The doubled-import bound E + σ ≥ 2W is ours. It agrees with P1's "at least 2W children" row. + +Other credits: +- Paired cubes: icekylinx (#144). Source-assisted compression: icekylinx (#184). Pair donors: ikeboy (#193). +- Paired-cube design ceiling: DaysSky (#201). Structural barriers: huxint (#203). Lucas-parity obstruction: + GamingPuzzled (#231). +- Five-stage bridged schedule: J. A. Sussman (#209). Five-stage suppliers: hcg890 (#234). +- Closed-ideas list and papers P1/P2: Swapnil Jain. +- The PG(2,9) instance and gap: Braverman and He. Amplification framework: Zhang, Li and Li. + +Prepared by eumemic with substantial Anthropic Claude assistance (Claude Code agents ran the searches, proofs and +checks). Apache-2.0. diff --git a/research/negative-results-paradigm-search/checks/bh_sign_gauges.py b/research/negative-results-paradigm-search/checks/bh_sign_gauges.py new file mode 100644 index 0000000000..bcaa4b3f39 --- /dev/null +++ b/research/negative-results-paradigm-search/checks/bh_sign_gauges.py @@ -0,0 +1,139 @@ +"""Can per-session Levi sign gauges rescue a frame embedding of the Braverman-He PG(2,9) coding-gap instance? + +Instance: Braverman-He, arXiv:2610.10108 (Section 4, Appendix A). The incidence graph of PG(2,9) has 182 vertices +and 910 edges. The deleted set R (175 edges) and the vertex order pi are transcribed from the paper into +../data/bh_pg29_lists.json. R splits into 157 sessions B, 9 constant-zero edges C and 9 dropped edges J. The other +735 edges are physical, and every session has hop distance 5 in the physical graph. + +Frame model at m = 5 with rank-one edges (one child per physical edge). If session i has endpoint frame difference +C_i (an invertible lower-triangular Levi target) and hop distance 5 = m, then along every shortest path the five +edge differences are C_i P_j with P_j orthogonal rank-one idempotents (rank-one matrices C_i^-1 D_e summing to I). +With a common target C_i = I, an edge used by two sessions in opposite directions would be both P and -P'. +Sign gauges C_i = c_i C0 (c_i = +-1, both legal Levi targets) allow it, provided c_i * s_e = sigma(i, e) for +every session i whose geodesics use edge e in direction sigma (s_e = the edge's own sign). +This script checks that sign system. Standard library only.""" +import json +import os +from collections import defaultdict, deque + +HERE = os.path.dirname(os.path.abspath(__file__)) +lists = json.load(open(os.path.join(HERE, '..', 'data', 'bh_pg29_lists.json'))) + + +# F9 = F3[t]/(t^2 + 1), elements as pairs (a, b) = a + b t +def add(x, y): + return ((x[0] + y[0]) % 3, (x[1] + y[1]) % 3) + + +def mul(x, y): + a, b = x + c, d = y + return ((a * c - b * d) % 3, (a * d + b * c) % 3) + + +ZERO, ONE = (0, 0), (1, 0) + + +def eta(r): + return (r % 3, r // 3) + + +T = [(ZERO, ZERO, ONE)] + [(ZERO, ONE, eta(r)) for r in range(9)] + \ + [(ONE, eta(r), eta(s)) for r in range(9) for s in range(9)] +assert len(T) == 91 + + +def dot(p, l): + s = ZERO + for i in range(3): + s = add(s, mul(p[i], l[i])) + return s + + +nbr = {i: sorted(j for j in range(91) if dot(T[i], T[j]) == ZERO) for i in range(91)} +edges = [(i, 91 + nbr[i][r]) for i in range(91) for r in range(10)] # point i -- line j +assert len(edges) == 910 + +R = lists['R'] +if len(R) == 176 and R[-1] == 13: # trailing page number in the transcription + R = R[:-1] +pi = lists['pi'] +C = {102, 163, 164, 341, 386, 406, 476, 513, 862} +J = {103, 349, 470, 517, 603, 606, 674, 716, 861} +Rs = set(R) +assert len(R) == 175 and C <= Rs and J <= Rs +B = sorted(Rs - C - J) +assert len(B) == 157 +pos = {v: k for k, v in enumerate(pi)} +phys = [q for q in range(910) if q not in Rs] +assert len(phys) == 735 +sess = [] +for q in B: + u, v = edges[q] + if pos[u] > pos[v]: + u, v = v, u + sess.append((u, v)) + +adj = defaultdict(list) +for q in phys: + u, v = edges[q] + adj[u].append(v) + adj[v].append(u) + + +def bfs(s): + dist = {s: 0} + dq = deque([s]) + while dq: + x = dq.popleft() + for y in adj[x]: + if y not in dist: + dist[y] = dist[x] + 1 + dq.append(y) + return dist + + +inc = defaultdict(dict) # session -> {edge: sigma} +both = 0 +dists = defaultdict(int) +for i, (s, t) in enumerate(sess): + ds, dt = bfs(s), bfs(t) + L = ds[t] + dists[L] += 1 + for e in phys: + a, b = edges[e] + for (x, y, sg) in ((a, b, 1), (b, a, -1)): + if ds.get(x, 99) + 1 + dt.get(y, 99) == L: + if e in inc[i] and inc[i][e] != sg: + both += 1 + inc[i].setdefault(e, sg) +print('session hop distances:', dict(dists)) +print('session/edge pairs used in both directions:', both) + +# constraint c_i * s_e = sigma on the bipartite incidence graph; count violations of a BFS 2-colouring +nodes = defaultdict(list) +for i, m in inc.items(): + for e, sg in m.items(): + nodes[('s', i)].append((('e', e), sg)) + nodes[('e', e)].append((('s', i), sg)) +colour = {} +violations = 0 +components = 0 +for start in list(nodes): + if start in colour: + continue + components += 1 + colour[start] = 1 + dq = deque([start]) + while dq: + x = dq.popleft() + for y, sg in nodes[x]: + want = colour[x] * sg + if y not in colour: + colour[y] = want + dq.append(y) + elif colour[y] != want: + violations += 1 +print('edges on some session geodesic:', len({e for m in inc.values() for e in m}), 'of', len(phys)) +print('components:', components, ' violated sign constraints (each counted twice):', violations) +print('sign gauges consistent:', violations == 0) diff --git a/research/negative-results-paradigm-search/checks/complex_m2_lambda2_certificate.py b/research/negative-results-paradigm-search/checks/complex_m2_lambda2_certificate.py new file mode 100644 index 0000000000..fd4eaa9a0b --- /dev/null +++ b/research/negative-results-paradigm-search/checks/complex_m2_lambda2_certificate.py @@ -0,0 +1,125 @@ +r"""Exact FO certificate: the complex primitive has no coded saving at m = 2, for ANY frames in GL_4(C), +with ALL monomial matrices free (any invertible diagonal, any permutation of the 4 basis states), arbitrary +complex gate coefficients, and the register (different-frame) model. Standard library only. + +FO lemma (README section 2.2, different-frame gates): for a representation rho of the frame group and a subspace Y0 invariant +under the free group B, f(g) = dim(Y0 + rho(g) Y0) - dim Y0 is B-bi-invariant and subadditive, and every network +satisfies sum over paid children of f(child) >= W f(target). If f(child) <= cost(child), then s >= W f(target). + +Here rho(g) = conjugation by Lambda^2(g) on End(Lambda^2 C^4) (a rational representation of GL_4). +Lambda^2 C^4 = P_1 + P_2 + P_3 with P_a = span{e_x ^ e_{x xor a}} (one plane per perfect matching of F_2^2). +Y0 = span{Pi_1, Pi_2, Pi_3}, Pi_a the coordinate projector onto P_a. A diagonal matrix acts diagonally on +Lambda^2, so it fixes each Pi_a; a permutation of the four basis states permutes the three perfect matchings, so +it permutes the Pi_a. Hence Y0 is invariant under the whole monomial group. +Verified exactly below: f = 0 on generic diagonals and all 24 permutations; f = 1 for the Hadamard on each of the +three matchings (qubit 1, qubit 2, parity); f(H (x) H) = 2. So s >= 2W = Wm. +Scalars cancel under conjugation, so the integer matrix H = [[1,1],[1,-1]] is used.""" +import itertools +from fractions import Fraction as Fr + +N = 4 +pairs = [(x, y) for x in range(N) for y in range(N) if x < y] +pidx = {p: i for i, p in enumerate(pairs)} + + +def matmul(A, B): + return [[sum(A[i][k] * B[k][j] for k in range(len(B))) for j in range(len(B[0]))] for i in range(len(A))] + + +def inverse(M): + n = len(M) + A = [[Fr(v) for v in row] + [Fr(int(i == j)) for j in range(n)] for i, row in enumerate(M)] + for c in range(n): + p = next(i for i in range(c, n) if A[i][c] != 0) + A[c], A[p] = A[p], A[c] + piv = A[c][c] + A[c] = [v / piv for v in A[c]] + for i in range(n): + if i != c and A[i][c] != 0: + f = A[i][c] + A[i] = [a - f * b for a, b in zip(A[i], A[c])] + return [row[n:] for row in A] + + +def rank(vectors): + """rank over Q of a list of equal-length vectors""" + rows = [[Fr(v) for v in vec] for vec in vectors] + r = 0 + ncol = len(rows[0]) + for c in range(ncol): + p = next((i for i in range(r, len(rows)) if rows[i][c] != 0), None) + if p is None: + continue + rows[r], rows[p] = rows[p], rows[r] + for i in range(len(rows)): + if i != r and rows[i][c] != 0: + f = rows[i][c] / rows[r][c] + rows[i] = [a - f * b for a, b in zip(rows[i], rows[r])] + r += 1 + return r + + +def wedge2(g): + """matrix of Lambda^2 g in the basis e_x ^ e_y (x < y)""" + M = [[Fr(0)] * 6 for _ in range(6)] + for j, (x, y) in enumerate(pairs): + for i, (u, v) in enumerate(pairs): + M[i][j] = Fr(g[u][x]) * g[v][y] - Fr(g[u][y]) * g[v][x] + return M + + +Pi = {} +for a in (1, 2, 3): + D = [[Fr(0)] * 6 for _ in range(6)] + for (x, y) in pairs: + if x ^ y == a: + D[pidx[(x, y)]][pidx[(x, y)]] = Fr(1) + Pi[a] = D + + +def vec(M): + return [v for row in M for v in row] + + +Y0 = [vec(Pi[a]) for a in (1, 2, 3)] +assert rank(Y0) == 3 + + +def f(g): + L = wedge2(g) + Li = inverse(L) + gY = [vec(matmul(matmul(L, Pi[a]), Li)) for a in (1, 2, 3)] + return rank(Y0 + gY) - 3 + + +def perm_matrix(sig): + P = [[0] * 4 for _ in range(4)] + for x in range(4): + P[sig[x]][x] = 1 + return P + + +def kron(A, B): + return [[A[i // 2][j // 2] * B[i % 2][j % 2] for j in range(4)] for i in range(4)] + + +H2 = [[1, 1], [1, -1]] +I2 = [[1, 0], [0, 1]] +# index x = x1 + 2 x2; kron(A, B) puts A on bit 1 and B on bit 0 +H_q1 = kron(I2, H2) # matching a = 1 +H_q2 = kron(H2, I2) # matching a = 2 +CNOT = perm_matrix([0, 3, 2, 1]) # a permutation of F_2^2 mapping matching 1 to matching 3 +H_par = matmul(matmul(CNOT, H_q1), CNOT) # Hadamard on the parity matching a = 3 +T = kron(H2, H2) + +diags = [[[Fr(2), 0, 0, 0], [0, Fr(-3, 5), 0, 0], [0, 0, Fr(7, 3), 0], [0, 0, 0, Fr(11, 13)]], + [[Fr(5, 7), 0, 0, 0], [0, Fr(13), 0, 0], [0, 0, Fr(-1, 4), 0], [0, 0, 0, Fr(9, 2)]]] +ok_diag = all(f(d) == 0 for d in diags) +ok_perm = all(f(perm_matrix(s)) == 0 for s in itertools.permutations(range(4))) +print('f = 0 on generic diagonals:', ok_diag) +print('f = 0 on all 24 permutations:', ok_perm) +fq1, fq2, fpar, fT = f(H_q1), f(H_q2), f(H_par), f(T) +print('f(H on qubit 1) =', fq1, ' f(H on qubit 2) =', fq2, ' f(H on parity matching) =', fpar) +print('f(H (x) H) =', fT) +assert ok_diag and ok_perm and (fq1, fq2, fpar, fT) == (1, 1, 1, 2) +print('certificate holds: every network at m = 2 has s >= 2W = Wm (no saving)') diff --git a/research/negative-results-paradigm-search/checks/flag_model_cliques.py b/research/negative-results-paradigm-search/checks/flag_model_cliques.py new file mode 100644 index 0000000000..05927a1f75 --- /dev/null +++ b/research/negative-results-paradigm-search/checks/flag_model_cliques.py @@ -0,0 +1,157 @@ +"""Compatible-direction cliques in the GL_{2m}(F_q) flag model (lower Borel B, Bruhat-transposition cost). + +At m = 2 a 2-step session geodesic y -> x -> zy has x in the middle, so two cost-1 neighbours u, w of x are +compatible iff delta(u,w) = z (z = (1 3)(2 4), the interchange H <-> D). In the abelian shear model the largest +pairwise-compatible set is m = 2. This script computes it exactly in the full flag model. +Usage: python3 flag_model_cliques.py q (q = 2 or 3; standard library only) +""" +import itertools, sys + + +def max_clique(n_nodes, adj): + """Bron-Kerbosch with pivoting; adj: list of neighbour sets. Returns one maximum clique.""" + best = [] + + def bk(r, p, x): + nonlocal best + if not p and not x: + if len(r) > len(best): + best = list(r) + return + if len(r) + len(p) <= len(best): + return + u = max(p | x, key=lambda v: len(adj[v] & p)) + for v in list(p - adj[u]): + bk(r + [v], p & adj[v], x & adj[v]) + p = p - {v} + x = x | {v} + bk([], set(range(n_nodes)), set()) + return best + +q = int(sys.argv[1]); n = 4 + +def rank(M): + M = [list(r) for r in M]; r = 0; rows = len(M); cols = len(M[0]) if rows else 0 + for c in range(cols): + p = next((i for i in range(r, rows) if M[i][c] % q), None) + if p is None: continue + M[r], M[p] = M[p], M[r]; inv = pow(M[r][c], q - 2, q) + M[r] = [(v * inv) % q for v in M[r]] + for i in range(rows): + if i != r and M[i][c] % q: + f = M[i][c]; M[i] = [(a - f * b) % q for a, b in zip(M[i], M[r])] + r += 1 + return r + +def mat_inv(M): + A = [list(r) + [int(i == j) for j in range(n)] for i, r in enumerate(M)] + for c in range(n): + p = next(i for i in range(c, n) if A[i][c] % q) + A[c], A[p] = A[p], A[c]; inv = pow(A[c][c], q - 2, q) + A[c] = [(v * inv) % q for v in A[c]] + for i in range(n): + if i != c and A[i][c] % q: + f = A[i][c]; A[i] = [(a - f * b) % q for a, b in zip(A[i], A[c])] + return [r[n:] for r in A] + +def mul(A, B): + return [[sum(A[i][k] * B[k][j] for k in range(n)) % q for j in range(n)] for i in range(n)] + +def weyl(h): + """Permutation w with h in B w B, B lower triangular: invariants rank h[:i, j:].""" + r = lambda i, j: rank([row[j:] for row in h[:i]]) if i > 0 and j < n else 0 + w = {} + for i in range(1, n + 1): + for j in range(1, n + 1): + d = r(i, j - 1) - r(i - 1, j - 1) - r(i, j) + r(i - 1, j) + if d == 1: w[i - 1] = j - 1 + return tuple(w[i] for i in range(n)) + +def canon(g): + """Canonical form of the coset B g: the flag span(g_1) < span(g_1,g_2) < ... as reduced row echelon prefixes.""" + key = [] + for k in range(1, n + 1): + M = [list(r) for r in g[:k]] + # RREF + r = 0 + for c in range(n): + p = next((i for i in range(r, k) if M[i][c] % q), None) + if p is None: continue + M[r], M[p] = M[p], M[r]; inv = pow(M[r][c], q - 2, q) + M[r] = [(v * inv) % q for v in M[r]] + for i in range(k): + if i != r and M[i][c] % q: + f = M[i][c]; M[i] = [(a - f * b) % q for a, b in zip(M[i], M[r])] + r += 1 + key.append(tuple(map(tuple, M))) + return tuple(key) + +# Hecke transposition cost on S_4 (lower Borel has the same simple reflections and lengths). +def length(w): return sum(1 for i in range(n) for j in range(i + 1, n) if w[i] > w[j]) +def compose(a, b): return tuple(a[b[i]] for i in range(n)) # (a*b)(i) = a(b(i)) +simple = [tuple(list(range(i)) + [i + 1, i] + list(range(i + 2, n))) for i in range(n - 1)] +def times_s(x, s): + xs = compose(x, s) + return {xs} if length(xs) > length(x) else {xs, x} +def reduced_word(w): + word = []; w = tuple(w) + while length(w) > 0: + for i, s in enumerate(simple): + ws = compose(w, s) + if length(ws) < length(w): word.append(i); w = ws; break + return word[::-1] +transp = [] +for i, j in itertools.combinations(range(n), 2): + t = list(range(n)); t[i], t[j] = j, i; transp.append(tuple(t)) +def times_cell(X, t): + cur = set(X) + for i in reduced_word(t): + nxt = set() + for x in cur: nxt |= times_s(x, simple[i]) + cur = nxt + return cur +ident = tuple(range(n)); cost = {ident: 0}; frontier = {ident}; k = 0 +while len(cost) < 24: + k += 1; new = set() + for x in frontier: + for t in transp: + new |= times_cell({x}, t) + frontier = {w for w in new if w not in cost} + for w in frontier: cost[w] = k +z = (2, 3, 0, 1) +print("q =", q, " c(z) =", cost[z], " cost-1 cells:", sorted(w for w in cost if cost[w] == 1) == sorted(transp)) + +# Enumerate flags as cosets B g; neighbours of the base flag x = B. +flags = {} +gens = [] +for i in range(n): + for j in range(n): + if i != j: + e = [[int(a == b) for b in range(n)] for a in range(n)]; e[i][j] = 1; gens.append(e) +d = [[int(a == b) for b in range(n)] for a in range(n)]; d[0][0] = 2 % q or 1; gens.append(d) +stack = [[[int(a == b) for b in range(n)] for a in range(n)]] +while stack: + g0 = stack.pop() + for s in gens: + g = mul(g0, s); key = canon(g) + if key not in flags: flags[key] = g; stack.append(g) +for rows in []: + g = [list(r) for r in rows] + if rank(g) < n: continue + key = canon(g) + if key not in flags: flags[key] = g +print("flags:", len(flags)) +base = [[int(i == j) for j in range(n)] for i in range(n)] +nbrs = [g for g in flags.values() if cost[weyl(mul(g, mat_inv(base)))] == 1] +print("cost-1 neighbours of the base flag:", len(nbrs)) +adj = [set() for _ in nbrs] +inv = [mat_inv(g) for g in nbrs] +n_edges = 0 +for a in range(len(nbrs)): + for b in range(a + 1, len(nbrs)): + if weyl(mul(nbrs[b], inv[a])) == z or weyl(mul(nbrs[a], inv[b])) == z: + adj[a].add(b) + adj[b].add(a) + n_edges += 1 +cl = max_clique(len(nbrs), adj) +print("compatible pairs:", n_edges, " max pairwise-compatible set:", len(cl), " (abelian model: 2)") diff --git a/research/negative-results-paradigm-search/checks/fourier_duality_f3.py b/research/negative-results-paradigm-search/checks/fourier_duality_f3.py new file mode 100644 index 0000000000..d55b934106 --- /dev/null +++ b/research/negative-results-paradigm-search/checks/fourier_duality_f3.py @@ -0,0 +1,76 @@ +"""Fourier duality over an odd-characteristic payload (F_3); standard library only. + +Array f(H, D), H and D in F_2^e (e address bits each), payload F_3 (bits embed as 0/1, no growth). +Checks exactly, for e = 1..4 and both directions: + XOR-shear f(H, D) -> f(H xor D, D) == WHT_H^{-1} . diag((-1)^{xi.D}) . WHT_H (the sign pass is O(V)), + swap == 3 XOR-shears (H ^= D, D ^= H, H ^= D) == 6 WHT layers of e bits + 3 sign passes, output stays 0/1. +So the interchange can be bought with H-layers. The README explains why this does not retire the bit primitive: +the complex primitive's own basis changes call chunk interchanges at a larger width, so the recursion is circular.""" +import random + +P = 3 +rng = random.Random(1) + + +def popparity(x): + return bin(x).count('1') & 1 + + +def wht_axis(a, axis, e): + """Unnormalised Walsh-Hadamard transform over the e bits of one axis, mod P.""" + n = 1 << e + out = [row[:] for row in a] + if axis == 1: + out = [list(col) for col in zip(*out)] + for idx in range(n): # transform each line along the chosen axis + line = [out[k][idx] for k in range(n)] + h = 1 + while h < n: + for start in range(0, n, 2 * h): + for k in range(start, start + h): + u, v = line[k], line[k + h] + line[k], line[k + h] = (u + v) % P, (u - v) % P + h *= 2 + for k in range(n): + out[k][idx] = line[k] + if axis == 1: + out = [list(col) for col in zip(*out)] + return out + + +def xor_shear_direct(f, target_axis): + n = len(f) + g = [[0] * n for _ in range(n)] + for H in range(n): + for D in range(n): + if target_axis == 0: # (H, D) -> (H ^ D, D) + g[H ^ D][D] = f[H][D] + else: # (H, D) -> (H, D ^ H) + g[H][D ^ H] = f[H][D] + return g + + +def xor_shear_fourier(f, target_axis, e): + n = 1 << e + inv_n = pow(n, -1, P) + fh = wht_axis(f, target_axis, e) + for a in range(n): + for b in range(n): + xi, c = (a, b) if target_axis == 0 else (b, a) + if popparity(xi & c): # translation by c along the target axis -> sign (-1)^{xi.c} + fh[a][b] = (-fh[a][b]) % P + g = wht_axis(fh, target_axis, e) + return [[(v * inv_n) % P for v in row] for row in g] + + +if __name__ == '__main__': + for e in (1, 2, 3, 4): + n = 1 << e + f = [[rng.randrange(2) for _ in range(n)] for _ in range(n)] # bit data embedded in F_3 + for ax in (0, 1): + assert xor_shear_direct(f, ax) == xor_shear_fourier(f, ax, e), (e, ax) + g = xor_shear_fourier(xor_shear_fourier(xor_shear_fourier(f, 0, e), 1, e), 0, e) + assert g == [list(col) for col in zip(*f)], e + assert all(v in (0, 1) for row in g for v in row) + print('XOR-shear == WHT . (-1)^{xi.D} . WHT over F_3: exact for e = 1..4, both directions') + print('swap == 3 Fourier-conjugated XOR-shears == 6 WHT layers (e bits) + 3 sign passes: exact, output 0/1') diff --git a/research/negative-results-paradigm-search/checks/multiplicative_index_maps.py b/research/negative-results-paradigm-search/checks/multiplicative_index_maps.py new file mode 100644 index 0000000000..122aafbafb --- /dev/null +++ b/research/negative-results-paradigm-search/checks/multiplicative_index_maps.py @@ -0,0 +1,65 @@ +"""(f) multiplicative index maps. +1. Row-major 2^e x 2^e transposition == index map k -> 2^e k mod N, N = 2^{2e}-1 (k 2: + a, b = k % (n - 1), k % (n + 1) + at, bt = kt % (n - 1), kt % (n + 1) + assert at == a and bt == (-b) % (n + 1), (e, i, j) + return True + + +def bfs_len(e, gens): + n = 1 << e + N = n * n - 1 + target = n % N + gs = [] + for g in gens: + g %= N + if math.gcd(g, N) != 1: + continue + gs.append(g) + gs.append(pow(g, -1, N)) + gs = sorted(set(gs)) + dist = {1: 0} + dq = deque([1]) + while dq: + x = dq.popleft() + if x == target: + return dist[x], gs + for g in gs: + y = (x * g) % N + if y not in dist: + dist[y] = dist[x] + 1 + dq.append(y) + return None, gs + + +if __name__ == "__main__": + for e in range(1, 8): + check_identities(e) + print("identities: transposition == x2^e mod (2^{2e}-1), CRT negation of the (2^e+1)-residue: OK for e=1..7") + S = [-1, 2, 3, 5, 7] + C = 7 + print("generators S =", S, "(and inverses); valuation bound L >= e/log2(C) = e/%.3f" % math.log2(C)) + for e in range(2, 11): + L, gs = bfs_len(e, S) + print(f"e={e:2d} N=2^{2*e}-1 BFS length of 2^e = {L:3d} bound e/log2C = {e/math.log2(C):6.2f} naive = {e}") + S2 = [-1, 3, 5, 7, 11, 13] + print("generators without 2:", S2) + for e in range(2, 10): + L, gs = bfs_len(e, S2) + print(f"e={e:2d} BFS length of 2^e = {L} bound e/log2(13) = {e/math.log2(13):.2f}") diff --git a/research/negative-results-paradigm-search/checks/nonlinear_frames_m1.py b/research/negative-results-paradigm-search/checks/nonlinear_frames_m1.py new file mode 100644 index 0000000000..7d62d9d2c1 --- /dev/null +++ b/research/negative-results-paradigm-search/checks/nonlinear_frames_m1.py @@ -0,0 +1,95 @@ +"""(a) nonlinear (tame / Jonquieres) frames, smallest case m = 1, Q = 3. +Address set X = (Z/3)^2 = {(h, d)}, h before d in tape order. +Free group B: (h, d) -> (u h + a, v d + beta(h)), u, v units, beta ANY function (Lemma ordered-affine-streams). +Paid generator: the interchange tau: (h, d) -> (d, h). +Compute c(g) = min #tau over the whole group Gamma = by 0-1 BFS (left multiplication), +then check Lemma R (c >= r_1, r_1 = log_Q of the prefix-image count) and the costs of specific maps.""" +from collections import deque +import itertools +import math + +Q = 3 +PTS = [(h, d) for h in range(Q) for d in range(Q)] +IDX = {p: i for i, p in enumerate(PTS)} + + +def perm_from_map(fn): + return tuple(IDX[fn(h, d)] for (h, d) in PTS) + + +def compose(p, q): + """(p o q)(x) = p(q(x)); perms as tuples image-of-index.""" + return tuple(p[q[i]] for i in range(len(q))) + + +IDP = tuple(range(Q * Q)) +gens_B = [ + perm_from_map(lambda h, d: ((2 * h) % Q, d)), + perm_from_map(lambda h, d: ((h + 1) % Q, d)), + perm_from_map(lambda h, d: (h, (2 * d) % Q)), +] +for j in range(Q): + gens_B.append(perm_from_map(lambda h, d, j=j: (h, (d + (1 if h == j else 0)) % Q))) +tau = perm_from_map(lambda h, d: (d, h)) + +# enumerate B explicitly for a size check +Bset = {IDP} +frontier = [IDP] +while frontier: + nxt = [] + for x in frontier: + for g in gens_B: + y = compose(g, x) + if y not in Bset: + Bset.add(y) + nxt.append(y) + frontier = nxt +print("|B| =", len(Bset), "(expected", 2 * Q * 2 * Q ** Q, ")") + +# 0-1 BFS +INF = 10 ** 9 +dist = {IDP: 0} +dq = deque([IDP]) +while dq: + x = dq.popleft() + dx = dist[x] + for g in gens_B: + y = compose(g, x) + if dist.get(y, INF) > dx: + dist[y] = dx + dq.appendleft(y) + y = compose(tau, x) + if dist.get(y, INF) > dx + 1: + dist[y] = dx + 1 + dq.append(y) +print("|Gamma| =", len(dist), " (|S_9| = 362880, |A_9| = 181440)") +hist = {} +for v in dist.values(): + hist[v] = hist.get(v, 0) + 1 +print("cost histogram c(g):", dict(sorted(hist.items()))) + + +def r1_count(p): + best = 0 + for h in range(Q): + imgs = {PTS[p[IDX[(h, d)]]][0] for d in range(Q)} + best = max(best, len(imgs)) + return best + + +viol = 0 +for p, c in dist.items(): + if r1_count(p) > Q ** c: + viol += 1 +print("Lemma R violations (N_1 > Q^c):", viol) + +named = { + "linear shear (h+d, d)": lambda h, d: ((h + d) % Q, d), + "nonlinear shear (h+d^2, d)": lambda h, d: ((h + d * d) % Q, d), + "Feistel (d, h+d^2)": lambda h, d: (d, (h + d * d) % Q), + "swap (d, h)": lambda h, d: (d, h), + "(h + 2d^2 + d, d)": lambda h, d: ((h + 2 * d * d + d) % Q, d), +} +for name, fn in named.items(): + p = perm_from_map(fn) + print(f"c[{name}] = {dist.get(p)} N_1 = {r1_count(p)}") diff --git a/research/negative-results-paradigm-search/data/bh_pg29_lists.json b/research/negative-results-paradigm-search/data/bh_pg29_lists.json new file mode 100644 index 0000000000..056b3ccbb3 --- /dev/null +++ b/research/negative-results-paradigm-search/data/bh_pg29_lists.json @@ -0,0 +1 @@ +{"R": [7, 8, 9, 30, 31, 38, 39, 56, 57, 60, 68, 75, 79, 84, 88, 94, 102, 103, 117, 122, 127, 128, 141, 151, 154, 155, 157, 163, 164, 166, 167, 168, 176, 179, 183, 187, 203, 207, 208, 212, 215, 221, 224, 225, 231, 234, 236, 237, 238, 242, 243, 251, 253, 266, 282, 290, 300, 309, 318, 321, 324, 325, 330, 333, 338, 341, 349, 380, 386, 387, 389, 396, 398, 400, 401, 406, 407, 409, 411, 412, 418, 425, 426, 428, 439, 444, 454, 458, 464, 465, 468, 470, 476, 480, 481, 492, 502, 503, 504, 513, 517, 521, 522, 527, 539, 541, 544, 548, 552, 557, 559, 569, 579, 583, 585, 588, 592, 593, 598, 602, 603, 606, 607, 612, 619, 620, 632, 634, 643, 646, 670, 672, 673, 674, 682, 685, 688, 694, 695, 701, 702, 703, 709, 716, 718, 737, 746, 754, 757, 759, 773, 790, 821, 835, 837, 838, 839, 841, 842, 843, 846, 850, 853, 856, 857, 861, 862, 882, 884, 885, 887, 900, 901, 904, 907, 13], "pi": [93, 23, 16, 143, 107, 54, 88, 38, 157, 40, 171, 124, 123, 118, 90, 32, 15, 146, 114, 179, 181, 39, 128, 0, 119, 83, 21, 6, 132, 160, 17, 79, 22, 42, 41, 174, 5, 167, 26, 96, 8, 61, 168, 101, 75, 43, 102, 127, 99, 12, 30, 57, 147, 92, 138, 159, 113, 31, 172, 7, 116, 78, 28, 126, 19, 120, 89, 117, 9, 14, 122, 56, 72, 115, 153, 47, 65, 103, 74, 137, 97, 10, 110, 154, 135, 95, 4, 125, 86, 139, 34, 162, 80, 87, 129, 27, 134, 140, 36, 13, 148, 149, 82, 37, 176, 91, 73, 1, 51, 141, 105, 109, 35, 44, 130, 66, 11, 98, 121, 25, 76, 169, 49, 53, 150, 2, 104, 29, 158, 69, 180, 81, 52, 106, 112, 131, 164, 63, 71, 170, 155, 24, 64, 156, 62, 48, 46, 145, 163, 45, 77, 175, 33, 142, 18, 178, 166, 144, 152, 55, 67, 70, 177, 85, 111, 20, 136, 84, 100, 58, 151, 68, 50, 133, 165, 94, 60, 173, 3, 59, 161, 108]} \ No newline at end of file