From a3f2b8f53dd4d31912254d40e578df8f63ed7164 Mon Sep 17 00:00:00 2001 From: Nick Petalas Date: Tue, 27 Oct 2026 10:06:56 +0000 Subject: [PATCH] feat(research): extend one-column cyclotomic completion --- .../cyclotomic-column-completion/PROOF.md | 125 +++++++++ .../cyclotomic-column-completion/README.md | 143 ++++++++++ .../cyclotomic-column-completion/SOURCES.json | 30 ++ .../cyclotomic-column-completion/TASK.json | 131 +++++++++ .../cyclotomic-column-completion/VERIFY.json | 34 +++ .../cyclotomic-column-completion/verify.py | 259 ++++++++++++++++++ 6 files changed, 722 insertions(+) create mode 100644 research/cyclotomic-column-completion/PROOF.md create mode 100644 research/cyclotomic-column-completion/README.md create mode 100644 research/cyclotomic-column-completion/SOURCES.json create mode 100644 research/cyclotomic-column-completion/TASK.json create mode 100644 research/cyclotomic-column-completion/VERIFY.json create mode 100644 research/cyclotomic-column-completion/verify.py diff --git a/research/cyclotomic-column-completion/PROOF.md b/research/cyclotomic-column-completion/PROOF.md new file mode 100644 index 0000000000..5023cdde87 --- /dev/null +++ b/research/cyclotomic-column-completion/PROOF.md @@ -0,0 +1,125 @@ +# One-column cyclotomic completion + +This contribution was produced by Nick Petalas. Apache-2.0. + +## Statement + +Write mu_m for the mth roots of unity. Let m,n>=2 and let A be an +n-by-(n-1) matrix with entries in mu_m and A* A=nI. Then its unique +orthogonal flat completion whose new column starts with 1 is + +```text +w = (nI-AA*) e_1, H = [A w]. (1) +``` + +It satisfies H*H=nI and has entries in mu_lcm(2,m). Moreover: + +1. If m is even, every entry of w belongs to mu_m, for every n>=2. +2. If m is an odd prime power and n>=3, every entry of w belongs to mu_m. + +Thus composite even alphabets and odd prime-power alphabets retain their +original alphabet. Both the matrix order n and alphabet order m are arbitrary +under these hypotheses; they need not agree. This extends the prime-order +statement B097 of David Ganz's atlas, PR2849. That result and PR2855's +prime pilot application are cited rather than reverified here. + +The n>=3 condition in the second conclusion is necessary. For any odd m, +the valid two-row input A=(1,1)^T has normalized completion (1,-1)^T. +Even allowing a global phase cannot put both entries in mu_m, since their +ratio is -1. The doubled-alphabet conclusion is therefore sharp without +a restriction on n. No sharpness assertion is made for odd composite m +and n>=3. + +## The flat column and its integral entries + +Set C=nI-AA*. Since A*A=nI, C is Hermitian, C^2=nC, and rank C=1. +Every diagonal entry of AA* is n-1, so C has diagonal 1. A rank-one +Hermitian positive matrix with C_11=1 satisfies C=C e_1 e_1* C. +Consequently C=ww*, |w_i|=1 and w_1=1. Also A*C=0, so A*w=0. +The squared norm of w is n, proving H*H=nI. The orthogonal complement +of A's columns has dimension one, proving normalized uniqueness. + +For i>1 the formula is explicitly + +```text +w_i = -sum_(j=1)^(n-1) A_ij conjugate(A_1j). (2) +``` + +Hence w_i belongs to Z[zeta_m] and is an algebraic integer. No division by +n or a determinant denominator occurs. This is the useful integrality +property behind the alphabet extension. + +## The classical cyclotomic facts + +We use cyclotomic irreducibility and [Q(zeta_r):Q]=phi(r). Here are the +remaining arguments, to make their exact use explicit. + +If alpha in Z[zeta_m] satisfies |alpha|=1, then alpha conjugate(alpha)=1. +All automorphisms of Q(zeta_m) commute with complex conjugation, since this +Galois group is abelian. Applying an automorphism therefore shows that +every algebraic conjugate of alpha has modulus one. Kronecker's theorem +implies that alpha is a root of unity. + +For completeness, the needed Kronecker argument is finite. If alpha has +degree d, each power alpha^k is an algebraic integer of degree at most d, +and every conjugate still has modulus one. Coefficients of its monic +minimal polynomial are integer elementary symmetric sums, bounded in +absolute value by the corresponding binomial coefficients of degree at +most d. Only finitely many such polynomials exist, and each has finitely +many roots. Thus the sequence alpha,alpha^2,... has finitely many possible +values. Two powers agree; alpha!=0 then implies a positive power equals 1. + +Put M=lcm(2,m). The roots of unity in Q(zeta_m)=Q(zeta_M) are exactly +mu_M. Indeed, if a primitive tth root lies in this field, the compositum +with Q(zeta_M) is Q(zeta_l), l=lcm(M,t). Thus phi(l)=phi(M). +Because M is even and M divides l, the product formula for phi shows +that increasing any existing prime exponent or adjoining any new odd +prime strictly increases phi. It follows that l=M and t divides M. +The reverse inclusion is immediate, using zeta_2m=-zeta_m^((m+1)/2) +when m is odd. These are classical facts, not new number-theory claims. + +Applying them to every entry in (2) proves w_i in mu_M. For even m, +M=m, proving the first conclusion. + +## Removing the sign for odd prime powers + +Let m=p^a for an odd prime p and a>=1. Evaluation at zeta_m=1 followed +by reduction modulo p defines a ring map + +```text +rho: Z[zeta_m] -> F_p, rho(zeta_m)=1, +``` + +because Phi_(p^a)(1)=p. If n>=3, A has two distinct columns. Their +orthogonality is a sum of n elements of mu_m equal to zero. Applying +rho shows p divides n. Applying rho to (2) now gives + +```text +rho(w_i) = -(n-1) = 1 in F_p. +``` + +Every element of mu_2m is either zeta_m^k or -zeta_m^k. Their images +under rho are respectively 1 and -1, which differ because p is odd. +Therefore each w_i lies in mu_m. The first entry already equals 1. +This proves the second conclusion and completes the theorem. + +## Sources and scope + +David Ganz's atlas B082/B097 in PR2849 supplies the one-column and +prime-order setting and explicitly leaves the composite alphabet outside +its proof. The prime-phase pilot application in PR2855 supplies the exact +recovery context. Their original files and credit remain unchanged. +Kronecker's theorem, cyclotomic irreducibility, cyclotomic field degrees +and the prime-power reduction are classical. Richard Stanley's +[Algebraic Combinatorics, Theorem 12.14](https://math.mit.edu/~rstan/algcomb/algcomb.pdf) +and Eric Moorhouse's +[Cyclotomic Fields with Applications](https://ericmoorhouse.org/handouts/cyclotomic_fields.pdf) +are accessible mathematical precedents for the integrality argument. +The proof above supplies the actual implication used here. + +The contribution is the stated extension of this project's completion +interface and its exact finite corroboration. Global literature priority, +independent human and formal proof-kernel review are unclaimed. More than +one missing column, approximate data, physical preparation, paid consumption, +supplier admission and complete multiplication-theorem obligations remain +outside scope. No new kappa or selected-frontier change follows. diff --git a/research/cyclotomic-column-completion/README.md b/research/cyclotomic-column-completion/README.md new file mode 100644 index 0000000000..99793eff3a --- /dev/null +++ b/research/cyclotomic-column-completion/README.md @@ -0,0 +1,143 @@ +# One-column completion without enlarging cyclotomic alphabets + +This contribution was produced by Nick Petalas. Apache-2.0. + +Claim type: scoped algebraic proof with exact finite corroboration. Let A +be an n-by-(n-1) matrix over the mth roots of unity, with A* A=nI. +Its normalized missing column is explicitly + +```text +w = (nI-AA*) e_1, w_1=1. +``` + +The completed matrix [A w] has orthogonal columns and retains the original +alphabet whenever m is even, for every n>=2. It also retains the alphabet +when m is an odd prime power and n>=3. For arbitrary odd m it always uses +at most the 2mth roots. Matrix order and alphabet order need not agree. +This extends the prime-order case of David Ganz's +[atlas B097](../pure-math-atlas-400/volumes/02-geometry.md#b097), PR2849, +and the prime pilot interface in his PR2855. Neither predecessor is audited +or replayed here. + +[PROOF.md](PROOF.md) proves the universal statement. The missing entries +are integral sums of roots and have modulus one. Classical Kronecker and +cyclotomic field arguments put them in the original even alphabet. For +an odd prime-power alphabet p^a, orthogonality implies p divides n; +reduction at zeta=1 then excludes the extra minus sign. + +The n>=3 restriction for odd prime powers is necessary. For any odd m, +A=(1,1)^T has missing column (1,-1)^T, even up to global phase. Thus +alphabet doubling is unavoidable in the unrestricted odd-alphabet problem. +For odd composite m and n>=3, this package gives the doubled bound and +leaves original-alphabet completion open. + +## Exact finite evidence + +The standard-library verifier uses integer polynomial arithmetic modulo +cyclotomic polynomials. It imports no predecessor executable and uses no +floating-point comparisons. It reconstructs each missing column, checks +literal column and row Gram identities, checks input preservation and +checks same-alphabet membership where the theorem requires it. + +It checks all 314 dephased partial matrices in these ten domains: + +```text +shape alphabet orders m numbers of valid inputs, in that order +3x2 3, 6, 9, 15 2, 2, 2, 2 +4x3 2, 4, 6, 8, 10, 12 6, 24, 42, 60, 78, 96 +``` + +Dephased means first row and first column have phase zero. The census +enumerates 3,879 candidate nonconstant columns and 2,582 candidate input +matrices. It does not identify gauge/permutation equivalents with each +other. Each count above is directly enumerated. + +An additional 189 gauged tensor-Fourier erasures, at orders 4,6,8,9,12,15, +compare the recovered column with the independently retained erased column. +They include m=3,n=9 and m=9,n=9. Another 32 erasures of the 4-by-4 +one-parameter family over mu_8 test a changed non-Fourier phase. Four +odd-alphabet two-row examples check the necessary sign boundary. +In total the verifier completes 539 cases and recovers 3,325 entries; +488 cases fall under the same-alphabet theorem. The other cases test the +general doubled-alphabet conclusion without claiming a counterexample +at n>=3. Nine malformed inputs reject. Three changed output entries fail +the Gram check. These finite fixtures corroborate the proof rather than +prove its unbounded quantifiers. + +## Reproduction + +From the repository root, using CPython 3.12: + +```sh +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -I -W error -B research/cyclotomic-column-completion/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -I -W error -O -B research/cyclotomic-column-completion/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/research_package.py --package research/cyclotomic-column-completion +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/check_research_commit.py --package research/cyclotomic-column-completion --check-source-history +``` + +Another CPython 3.12 path may replace the local path. Both direct modes +write nothing and emit `PASS_CYCLOTOMIC_COLUMN_COMPLETION`, the enumerated +counts and a generated SHA256 receipt for the six package files. The +registered commands each have a 60-second timeout. Source history, +metadata and committed-byte checks are separate from mathematical review. + +The selected-baseline orientation passed with distinct complex, ordinary +BIT, admitted BIT and outer budgets. Its scope is source-binding metadata, +not a selected scientific replay. No selected cold replay was run. + +## Scope and credit + +This is an exact algebraic completion theorem and finite verifier. More +than one missing column, approximate observations, physical preparation, +paid consumption, dirty restoration, precision, tape costs and supplier +admission remain unproved. No new kappa or selected-frontier change is +claimed. Independent human and formal proof-kernel review, and global +literature priority, are unclaimed. Lean and Docker were not run. + +Credit David Ganz's PR2849 for B082/B097 and the explicit composite-alphabet +boundary, and his PR2855 for the exact pilot recovery application. Their +proofs, implementation and original attribution remain unchanged. +Kronecker's theorem, cyclotomic irreducibility and field degrees, prime-power +reduction, Fourier tensors and the four-dimensional one-parameter Hadamard +family are classical. The new contribution is the stated extension of +this project's completion interface. Exact repository provenance is in +[SOURCES.json](SOURCES.json); classical primary-source links are in the proof. + +The `formal-interface-lemma` card is explicitly changed to this algebraic +side result. It removes a prime-only alphabet restriction, without +constructing or pricing a multiplication supplier. The +[advance claim](https://github.com/CrocSwap/integer-mult-bounds/discussions/1166#discussioncomment-19214393) +and [TASK.json](TASK.json) record the exact scope and overlap limitations. + +## Open next questions + +1. For odd composite m and n>=3, must every such partial matrix complete + over mu_m? Start with m=15 and a dimension permitting mixed 3-cycle and + 5-cycle vanishing sums. The sign exclusion used for a single prime power + has no direct replacement. A counterexample must be a complete partial + matrix, not just a sum of n-1 roots with the right modulus. +2. Can this exact alphabet theorem support a robust completion method for + noisy composite-phase inputs? Start by bounding the perturbation of + (nI-AA*)e_1 and proving a separation radius for root rounding. Exact + orthogonality and integrality are used here, so no noise guarantee or + paid physical implementation follows. + +## Verifier bounds + +Only `verify.py` is executable. It has nonrecursive control flow and no +subprocess, network, generated code or dynamic imports. Functions are below +60 physical lines. Alphabets have order at most 15, cyclotomic conductors +at most 30, and matrices at most 16 rows. The largest census scans at most +12^3 candidate columns and at most 1,000^2 candidate pairs. Tensor fixtures +have at most four factors, three gauges and sixteen erasure positions. +All mathematical checks use explicit exceptions and remain active under -O. +Six package reads are each bounded by 1 MiB. Warning-strict execution and +syntax/function-size inspection are the available diagnostics; no external +static analyzer is installed or claimed. + +Power of Ten rules 3 and 9 need managed-runtime deviations. Python integer, +tuple, iterator and JSON operations allocate and use runtime dispatch. +The fixed capacities above bound live data and call targets; this command +has no steady service loop or external mutable resource. Both registered +modes exercise these limits and controls. Reassess storage and validation +before accepting external inputs or larger search domains. diff --git a/research/cyclotomic-column-completion/SOURCES.json b/research/cyclotomic-column-completion/SOURCES.json new file mode 100644 index 0000000000..4fdc938c07 --- /dev/null +++ b/research/cyclotomic-column-completion/SOURCES.json @@ -0,0 +1,30 @@ +{ + "schema_version": 1, + "base_commit": "de5ec2e7a6074068452f45b1a191b5c72832df4a", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "581f8d87008354eb5b869f7ed9de1317ad837ce8", + "sha256": "2a0220e866417774606e0f991e41b9c1d26b1f43b97857238cf478dbc7d330b5" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "3404fbdd5e7529a0674eef26114b5071e4586cec", + "sha256": "ead6cdc9d0af6d58e8a49744d8ec8c7c15e13d2ba93c276c434bcf9b51b93a81" + }, + { + "path": "research/pure-math-atlas-400/volumes/02-geometry.md", + "usage": "provenance", + "git_blob": "baef1e69c08c7cbd4dfd020862870fa5161afc86", + "sha256": "39fc97bdfa29337b79d1308e35df41e867ce2102d44755fd407aa09ff8352b39" + }, + { + "path": "research/atlas-frontier-applications/applications/phase-completion/README.md", + "usage": "provenance", + "git_blob": "54691ee126d4abbf80ebd9c98f03e7b258528b4b", + "sha256": "3f96a9614d06f437d75c10fb29c01a1c6ea612b14a62dcb1099274b09f4163b1" + } + ] +} diff --git a/research/cyclotomic-column-completion/TASK.json b/research/cyclotomic-column-completion/TASK.json new file mode 100644 index 0000000000..a1b0dff909 --- /dev/null +++ b/research/cyclotomic-column-completion/TASK.json @@ -0,0 +1,131 @@ +{ + "schema_version": 1, + "task_id": "formal-interface-lemma", + "priority_revision": 8, + "base_commit": "de5ec2e7a6074068452f45b1a191b5c72832df4a", + "original_card": { + "id": "formal-interface-lemma", + "question": "Can one uncovered interface implication be formalized with exact caller and certificate bindings?", + "starting_points": [ + "docs/research/research-family-status.md", + "certificates/selected-result.json", + "research/gate-operand-parity-lean/README.md", + "research/staged544-certified-endpoint/README.md", + "research/unconditional-batched-crt/README.md" + ], + "methods": [ + "Formalize a missing boundary lemma identified by the selected review.", + "Audit a formal theorem-to-certificate binding independently." + ], + "acceptance_gate": "State the exact formalized proposition and remaining assumptions; avoid duplicate arithmetic formalizations already present.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_selected_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Resolve the current selected review, separate complex/ordinary BIT/admitted BIT/outer budgets, and compare the card against live handoffs before starting. Historical ceilings require exact source/model equivalence.", + "scope": "Source-binding orientation only; not a scientific replay or all-size proof. Materialize selected inputs if this checkout is sparse." + }, + "first_experiment": "Write one missing statement with quantified hypotheses, actual caller and existing coverage. A compact-switch lemma is a candidate only after its mathematical contract is reviewed. Establish a bounded proof plan before a separately budgeted proof-assistant build; do not rerun large Lean jobs as orientation.", + "bottleneck_link": "A missing interface proof can reduce the conditional gap even if it does not change kappa.", + "allowed_variations": [ + "Narrow to one formal lemma or one theorem-to-certificate binding." + ], + "scope_change_triggers": [ + "Formalizing already-covered arithmetic and claiming the full multiplication theorem." + ], + "overlap_terms": [ + "hyperplane end", + "formal interface", + "Lean binding", + "3807", + "3857", + "4100", + "gate-operand-parity-lean", + "staged544-certified-endpoint", + "unconditional-batched-crt" + ], + "existing_checks": [ + { + "scope": "PR #3807: scoped gate-operand parity formalization.", + "evidence": "research/gate-operand-parity-lean/README.md", + "remaining": "Exact theorem-to-caller binding and genuinely uncovered interface lemmas.", + "status": "author-checked", + "source_commit": "4c3530f42a6abcc48e7a6bcffd6c901911dc8269", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "scope": "PR #3857: certified real-power moment/endpoint arithmetic.", + "evidence": "research/staged544-certified-endpoint/README.md", + "remaining": "Uniform algorithmic implications, not another endpoint digit.", + "status": "author-checked", + "source_commit": "ef4315b8caa605e47a2515004845eb2d2ed71a86", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "scope": "PR #4100: compact-switch formalization proposed as future validation.", + "evidence": "research/unconditional-batched-crt/README.md", + "remaining": "Audit the statement and assumptions before a formal proof campaign.", + "status": "author-checked", + "source_commit": "337d04939571a637aeab54a0f58f54fde811663a", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + } + ] + }, + "scope_status": "changed", + "actual_scope": "One-column flat completion retains every even root-of-unity alphabet for n>=2 and every odd prime-power alphabet for n>=3; arbitrary odd alphabets need at most doubling.", + "scope_change_reason": "The donation asks for an original result rather than another audit. This algebraic side result takes the explicit composite-alphabet boundary in David Ganz's atlas B097; it is not selected-caller formalization.", + "bottleneck_link": "Algebraic side result: removes a prime-only exact phase interface restriction. No supplier, physical cost or kappa gain is claimed.", + "budget_minutes": 60, + "stop_rule": "Stop at the first proved alphabet extension, with bounded exact corroboration; leave odd composite sign exclusion and noise robustness as open questions.", + "outcome": "completed", + "evidence": "PROOF.md and verify.py: 539 completions, 3325 recovered entries, 314 exhaustive dephased inputs across ten domains, 189 independent erased-column comparisons, 32 one-parameter erasures, four odd two-row boundaries, nine input rejections and three output mutation controls.", + "author": "Nick Petalas", + "ai_assistance": "Independent human and formal proof-kernel review are unclaimed.", + "open_questions": [ + { + "question": "Must original-alphabet completion hold for odd composite m and n>=3?", + "why_it_matters": "Would remove the remaining sign enlargement from this one-column interface.", + "first_step": "Construct or exclude a partial matrix for m=15 whose normalized missing column has mixed signs; begin with dimensions admitting both 3-cycle and 5-cycle vanishing sums.", + "blocked_by": "No prime-power residue map excludes the extra signs, and an isolated root sum is not a partial matrix." + }, + { + "question": "Can the exact composite-alphabet completion be made robust to noisy inputs?", + "why_it_matters": "Would turn exact phase recovery into a quantitative repair interface.", + "first_step": "Bound the perturbation of (nI-AA*)e_1 and derive a root-rounding separation radius.", + "blocked_by": "Current proof uses exact orthogonality and algebraic integrality; physical and noise costs are unknown." + } + ], + "claim_url": "https://github.com/CrocSwap/integer-mult-bounds/discussions/1166#discussioncomment-19214393", + "upstream_refresh": { + "commit": "de5ec2e7a6074068452f45b1a191b5c72832df4a", + "priority_revision": 8, + "checked_at_utc": "2026-10-27T09:59:50Z" + }, + "preserved_checkout": { + "state": "detached HEAD; no earlier branch name", + "head": "de5ec2e7a6074068452f45b1a191b5c72832df4a", + "earlier_commits": [ + "c297a40e7732bc9452bbf745f9aad43455b1e330", + "553d26d796fde9871ff2661a49ac7732e945410f", + "f9a3bc99b186b2e08a855e260f2f904ef33821c9", + "7c58c57143cc322eb0d578162e6df87ac0f4cd1f" + ], + "modified": false + }, + "overlap": { + "searched_at_utc": "2026-10-27T10:03:23Z", + "open_prs": 416, + "discussion_records": 5306, + "remote_pagination_complete": true, + "local_note_coverage": "Sparse: 181 materialized records, 7666 HEAD paths unsearched by the helper. All-main distinctive README searches and targeted merged-PR searches supplement this.", + "closest_predecessors": [ + "David Ganz PR2849, atlas B082/B097", + "David Ganz PR2855, prime-phase pilot recovery" + ], + "limits": "Bounded title/body and main README searches do not establish global literature priority or cover unpublished work. No relevant same-account PR from the preceding 24 hours was found." + }, + "claim_type": "scoped algebraic proof with exact finite corroboration" +} diff --git a/research/cyclotomic-column-completion/VERIFY.json b/research/cyclotomic-column-completion/VERIFY.json new file mode 100644 index 0000000000..e69bef41cc --- /dev/null +++ b/research/cyclotomic-column-completion/VERIFY.json @@ -0,0 +1,34 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-W", + "error", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 60, + "checks": "Exact cyclotomic completions, exhaustive dephased domains, retained erased-column oracles, input rejection and output mutation controls" + }, + { + "argv": [ + "{python}", + "-I", + "-W", + "error", + "-O", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 60, + "checks": "Exact cyclotomic completions, exhaustive dephased domains, retained erased-column oracles, input rejection and output mutation controls under optimized Python" + } + ] +} diff --git a/research/cyclotomic-column-completion/verify.py b/research/cyclotomic-column-completion/verify.py new file mode 100644 index 0000000000..611213a705 --- /dev/null +++ b/research/cyclotomic-column-completion/verify.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python3 +"""Exact finite corroboration of one-column cyclotomic completion. + +Produced by Nick Petalas. Apache-2.0. No predecessor code is imported. +""" + +import hashlib +import itertools +import json +from pathlib import Path + + +MAX_ORDER = 30 +MAX_ROWS = 16 +PACKAGE_FILES = ("README.md", "PROOF.md", "TASK.json", "SOURCES.json", + "VERIFY.json", "verify.py") + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def divide_exact(numerator, denominator): + """Monic integer polynomial division, coefficients in ascending order.""" + work = list(numerator) + degree = len(denominator) - 1 + quotient = [0] * max(1, len(work) - degree) + for top in range(len(work) - 1, degree - 1, -1): + coefficient = work[top] + quotient[top - degree] = coefficient + for j in range(degree + 1): + work[top - degree + j] -= coefficient * denominator[j] + require(not any(work), "inexact polynomial division") + return tuple(quotient) + + +def cyclotomics(limit): + require(2 <= limit <= MAX_ORDER, "cyclotomic order outside capacity") + polynomials = [()] * (limit + 1) + for order in range(1, limit + 1): + polynomial = (-1,) + (0,) * (order - 1) + (1,) + for divisor in range(1, order): + if order % divisor == 0: + polynomial = divide_exact(polynomial, polynomials[divisor]) + polynomials[order] = polynomial + return tuple(polynomials) + + +def roots(order): + polynomial = cyclotomics(order)[order] + degree = len(polynomial) - 1 + powers = [] + current = (1,) + (0,) * (degree - 1) + for _ in range(order): + powers.append(current) + work = [0] + list(current) + leading = work.pop() + current = tuple(work[j] - leading * polynomial[j] + for j in range(degree)) + require(current == powers[0], "root order did not close") + require(len(set(powers)) == order, "root order collapsed") + return tuple(powers) + + +def sum_phases(phases, powers): + degree = len(powers[0]) + total = [0] * degree + for phase in phases: + root = powers[phase % len(powers)] + for j in range(degree): + total[j] += root[j] + return tuple(total) + + +def valid_columns(matrix, powers): + rows = len(matrix) + cols = len(matrix[0]) + zero = (0,) * len(powers[0]) + for first in range(cols): + for second in range(first): + phases = (matrix[i][first] - matrix[i][second] + for i in range(rows)) + if sum_phases(phases, powers) != zero: + return False + return True + + +def complete(matrix, alphabet): + require(type(alphabet) is int and 2 <= alphabet <= 15, + "alphabet outside capacity") + require(2 <= len(matrix) <= MAX_ROWS, "row count outside capacity") + rows = len(matrix) + require(all(len(row) == rows - 1 for row in matrix), "wrong input shape") + require(all(type(x) is int and 0 <= x < alphabet + for row in matrix for x in row), "invalid phase code") + conductor = alphabet if alphabet % 2 == 0 else 2 * alphabet + powers = roots(conductor) + scale = conductor // alphabet + embedded = tuple(tuple(scale * x for x in row) for row in matrix) + require(valid_columns(embedded, powers), "nonorthogonal input") + recovered = [0] + for i in range(1, rows): + phases = (embedded[i][j] - embedded[0][j] for j in range(rows - 1)) + entry = tuple(-x for x in sum_phases(phases, powers)) + require(entry in powers, "missing entry escaped cyclotomic roots") + recovered.append(powers.index(entry)) + result = tuple(embedded[i] + (recovered[i],) for i in range(rows)) + require(valid_columns(result, powers), "completed Gram failed") + require(valid_columns(tuple(zip(*result)), powers), + "completed row Gram failed") + return result, conductor + + +def same_alphabet_required(alphabet, rows): + if alphabet % 2 == 0: + return True + for prime in (3, 5, 7, 11, 13): + for exponent in range(1, 4): + if alphabet == prime ** exponent: + return rows >= 3 + return False + + +def check_case(matrix, alphabet, counters): + completed, conductor = complete(matrix, alphabet) + scale = conductor // alphabet + require(all(completed[i][:-1] == tuple(scale * x for x in matrix[i]) + for i in range(len(matrix))), "input changed") + if same_alphabet_required(alphabet, len(matrix)): + require(all(row[-1] % scale == 0 for row in completed), + "same-alphabet theorem failed") + counters["same_alphabet_cases"] += 1 + counters["completed_cases"] += 1 + counters["recovered_entries"] += len(matrix) + return completed + + +def dephased_census(rows, alphabet, counters): + """All dephased 3x2 or 4x3 inputs, with no equivalence deduplication.""" + require(rows in (3, 4), "unsupported census shape") + powers = roots(alphabet if alphabet % 2 == 0 else 2 * alphabet) + scale = len(powers) // alphabet + zero = (0,) * len(powers[0]) + columns = [] + for tail in itertools.product(range(alphabet), repeat=rows - 1): + counters["candidate_columns"] += 1 + column = (0,) + tail + if sum_phases((scale * x for x in column), powers) == zero: + columns.append(column) + require(len(columns) <= 1000, "census column capacity exceeded") + count = 0 + choices = (((column,) for column in columns) if rows == 3 + else itertools.product(columns, repeat=2)) + for selected in choices: + counters["candidate_inputs"] += 1 + all_columns = ((0,) * rows,) + selected + matrix = tuple(tuple(column[i] for column in all_columns) + for i in range(rows)) + embedded = tuple(tuple(scale * x for x in row) for row in matrix) + if valid_columns(embedded, powers): + check_case(matrix, alphabet, counters) + count += 1 + return count + + +def fourier_tensor(factors, alphabet): + require(2 <= len(factors) <= 4, "tensor capacity exceeded") + indices = tuple(itertools.product(*(range(x) for x in factors))) + require(len(indices) <= MAX_ROWS, "tensor row capacity exceeded") + require(all(alphabet % x == 0 for x in factors), "incompatible tensor") + return tuple(tuple(sum(a * b * (alphabet // factor) + for a, b, factor in zip(row, col, factors)) % alphabet + for col in indices) for row in indices) + + +def fixtures(counters): + configurations = (((2, 2), 2), ((2, 3), 6), ((2, 2, 2), 4), + ((3, 3), 3), ((3, 3), 9), ((2, 2, 3), 6), + ((3, 5), 15)) + for factors, alphabet in configurations: + full = fourier_tensor(factors, alphabet) + for erased in range(len(full)): + for gauge in range(3): + row_order = tuple(reversed(range(len(full)))) + kept = tuple(j for j in range(len(full)) if j != erased) + matrix = tuple(tuple((full[i][j] + gauge * (i + 2 * j)) % alphabet + for j in reversed(kept)) for i in row_order) + completed = check_case(matrix, alphabet, counters) + scale = (alphabet if alphabet % 2 == 0 else 2 * alphabet) // alphabet + expected = tuple(scale * ((full[i][erased] + gauge * i + - full[row_order[0]][erased] - gauge * row_order[0]) % alphabet) + for i in row_order) + require(tuple(row[-1] for row in completed) == expected, + "independent erased-column oracle disagrees") + for phase in range(8): + full = ((0, 0, 0, 0), (0, 4, phase, (phase + 4) % 8), + (0, 0, 4, 4), (0, 4, (phase + 4) % 8, phase)) + for erased in range(4): + matrix = tuple(tuple(row[j] for j in range(4) if j != erased) + for row in full) + check_case(matrix, 8, counters) + + +def expect_rejection(matrix, alphabet): + try: + complete(matrix, alphabet) + except ValueError: + return + raise ValueError("invalid input was accepted") + + +def controls(counters): + invalid = (((), 4), (((0, 0), (0, 0)), 4), + (((0,), (4,)), 4), (((0,), (-1,)), 4), + (((0,), (True,)), 4), (((0,), (0,)), 1), + (((0,), (0,)), 16), (((0, 0),) * 3, 4), + (((0,) * 16,) * 17, 4)) + for matrix, alphabet in invalid: + expect_rejection(matrix, alphabet) + counters["rejection_controls"] += 1 + for alphabet in (3, 5, 9, 15): + completed = check_case(((0,), (0,)), alphabet, counters) + require(completed == ((0, 0), (0, alphabet)), "odd sign boundary lost") + counters["odd_two_row_boundaries"] += 1 + powers = roots(8) + matrix = ((0, 0, 0), (0, 4, 1), (0, 0, 4), (0, 4, 5)) + result, _ = complete(matrix, 8) + for row in range(1, 4): + mutant = tuple(r[:-1] + ((r[-1] + (1 if i == row else 0)) % 8,) + for i, r in enumerate(result)) + require(not valid_columns(mutant, powers), "mutant escaped Gram oracle") + counters["output_mutation_controls"] += 1 + + +def main(): + counters = dict.fromkeys(("completed_cases", "same_alphabet_cases", + "recovered_entries", "candidate_columns", "candidate_inputs", + "rejection_controls", "odd_two_row_boundaries", "output_mutation_controls"), 0) + census = {} + for rows, alphabet in ((3, 3), (3, 6), (3, 9), (3, 15), + (4, 2), (4, 4), (4, 6), (4, 8), (4, 10), (4, 12)): + census[f"{rows}x{rows-1}:mu{alphabet}"] = dephased_census(rows, alphabet, counters) + fixtures(counters) + controls(counters) + package = Path(__file__).resolve().parent + hashes = {} + for name in PACKAGE_FILES: + path = package / name + require(path.stat().st_size <= 1024 * 1024, "package file capacity exceeded") + data = path.read_bytes() + hashes[name] = hashlib.sha256(data).hexdigest() + print(json.dumps({"status": "PASS_CYCLOTOMIC_COLUMN_COMPLETION", + "counts": counters, "dephased_census": census, + "package_sha256": hashes}, sort_keys=True, indent=2)) + + +if __name__ == "__main__": + main()