diff --git a/.github/workflows/p112-common-slice.yml b/.github/workflows/p112-common-slice.yml index 37f99ca573..48047f61c4 100644 --- a/.github/workflows/p112-common-slice.yml +++ b/.github/workflows/p112-common-slice.yml @@ -15,9 +15,9 @@ jobs: if: github.repository == 'CrocSwap/integer-mult-bounds' runs-on: ubuntu-24.04 timeout-minutes: 20 - env: - TMPDIR: ${{ runner.temp }}/p112-common-slice steps: + - name: Initialise P112 work directory + run: echo "TMPDIR=$RUNNER_TEMP/p112-common-slice" >> "$GITHUB_ENV" - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: fetch-depth: 0 diff --git a/research/twiddle-matched-layer/LICENSE b/research/twiddle-matched-layer/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/twiddle-matched-layer/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/research/twiddle-matched-layer/NOTICE b/research/twiddle-matched-layer/NOTICE new file mode 100644 index 0000000000..59d8e0cf31 --- /dev/null +++ b/research/twiddle-matched-layer/NOTICE @@ -0,0 +1,415 @@ +A sharper exponent for integer multiplication +Copyright 2026 Douglas Colkitt + +This project includes unmodified source files from OpenAI's manuscript +"Integer multiplication below n log n" and its accompanying repository: +https://github.com/openai/math +Commit: adc7f1241b42e322a6451854ab7e4b4c146bf78a + +The original manuscript identifies OpenAI as its author. Its Apache-2.0 +license is retained at upstream/LICENSE. The exact source URLs and hashes +are recorded in upstream/manifest.json. Proposed modifications are supplied +as separate files under patches/; upstream source files remain unchanged. + +The original local research note, scripts, certificates, patches, and +documentation were prepared by Douglas Colkitt with assistance from OpenAI +Codex. The community release incorporates work by the contributors identified +in the notices below; it is not solely Douglas Colkitt's work. +This project is not an official OpenAI release or an OpenAI endorsement. + +Related contributions (not imported in this checkpoint): +Zhihao Chen (jacklightChen), PR #7, supplied an earlier ternary five-subset +motif, finite-alphabet transfer and a different compressed producer: +https://github.com/CrocSwap/integer-mult-bounds/pull/7 +The present checkpoint claims no priority for that motif. Related compressed +complex-network work was submitted by eumemic in PR #3: +https://github.com/CrocSwap/integer-mult-bounds/pull/3 +The pending contributions and their stronger bounds require their own review; +this notice does not represent adoption or verification of their claims. + +Additional community work, including parallel and superseded submissions, is +acknowledged in CONTRIBUTORS.md, with pinned submission metadata in +docs/research/contribution-snapshot.json. These acknowledgements do not imply +joint authorship of the checkpoint, incorporation of pending code, or verification +of submitted mathematical claims. Original source-specific notices remain in force. + +Community release (accepted by conditional maintainer audit): +The following original contributor notices apply to the imported PR #39 chain. +The preceding non-import statements describe the preserved 2^-30 checkpoint. + +Ternary five-subset construction and common-four-point resynthesis +Copyright 2026 Zhihao Chen (jacklightChen) + +This is Zhihao Chen's first submission of this specific construction to this +repository. Research, proof development, code and verification were prepared +with substantial assistance from GPT-6 Astra (OpenAI Codex), as identified by +the contributor. This is not independent review or an OpenAI endorsement. +Future research building on this contribution should explicitly acknowledge +Zhihao Chen (jacklightChen), cite the accompanying note and pull request, and +retain the preceding contributors' attribution. This notice records research +provenance; the repository's Apache-2.0 license remains unchanged. + +Dependencies retained from eumemic's Claude-assisted PRs #3 and #5: +https://github.com/CrocSwap/integer-mult-bounds/pull/3 +https://github.com/CrocSwap/integer-mult-bounds/pull/5 +PR #5 commit: d3d370c34937503bd3fa63c83d505a05e8e50893 +These include complex_circuit.py, complex_network.py, fast_gaussian.py, +their generators, construction notes and certificates. The Gaussian input +scaling proof is corrected in this derivative; see the modification notice below. +Aligned pairing also appears in Bortlesboat's PR #2. Retained totals and bank +sharing appear in dleen's PR #4 and cheaper retained centers in eumemic's PR #6. +Their results and ideas are credited separately from this new construction. + +Bulk recursion and controlled tensor basis, 8 October 2026 +Copyright 2026 icekylinx + +The new projector batching, controlled simultaneous basis, mixed-width tape +recursions, whole-residual complex recursion, and dependency-path precision +guard in the batched-23 proof package are contributed by icekylinx, developed +with substantial OpenAI GPT-6 Astra assistance. Review corrections and +repository integration were prepared with OpenAI Codex assistance. They build on the retained +PR #7 finite producers and the preceding contributions credited above. +The new package retains the repository's Apache-2.0 license and the original +authors' attribution. It is not an official OpenAI release or endorsement. + +Modification notice, 8 October 2026 (icekylinx): the retained fast Gaussian +proof now bounds shifted approximation error by F=2^ceil(1.14 alpha^2). +The P=34p precision budget and asymptotic exponent are unchanged. New batching +checks are integrated into make verify. Existing attribution and licenses +are retained. + +Partial-swap extension, 8 October 2026 +Copyright 2026 icekylinx + +The partial-swap framing, binary retained-total triple construction, +dependency-preserving positive labels and carrier reuse, unequal (25,23,57) +common basis, improved complex batching, and exact assembly are contributed +by icekylinx with substantial OpenAI GPT-6 Astra and Codex assistance. +This extension directly inherits PR #10, commit +62691e395a0458ce089a1c7b5d89e74291e95e29. The portable producer adapters +modify the retained paired-exclusion and shared-point implementations credited +above. The original licenses, attribution, and Gaussian correction are retained. + +Endpoint-gauge extension, 8 October 2026 +Copyright 2026 icekylinx + +The complementary auxiliary endpoint gauges, (32,30,40) controlled basis, +general nondegenerate binary phase residuals, retained-center complex producer, +updated path guard and exact assembly are contributed by icekylinx with +substantial OpenAI GPT-6 Astra and Codex assistance. This extension inherits +f2ab41aebad47861caf6316282c1793e5513845e and its PR #10 ancestry. New portable +adapters retain the paired-exclusion and shared-point contributions credited +above. Original licenses, notices and the Gaussian correction are retained. + +Structured-basis and semantic-bulk extension, 8 October 2026 +Copyright 2026 icekylinx + +The selected (32,30,36) bit construction, A1/A5 block refinements, fixed +middle-axis I+J profiles with bounded-minor CRT certificates, mixed dyadic +complex centers, complete data-front batching and circuit-specific assembly +are contributed by icekylinx with substantial OpenAI GPT-6 Astra and Codex +assistance. The immediate parent is ed90fd940279c336ebc45968631bdebfb087b505. + +The semantic/bulk compatibility argument, literal scalar charge, product row +stock and parameterization adapt Zhihao Chen (jacklightChen)'s PR #23, +commit 661ebabc1076c9f525d7ce4967c876b203fa9827. Translated complex endpoints +are adopted from the same contributor's PR #21, +commit 5ba6cf0bfb68f2be8d15610e7972207c50254d6a, following eumemic's source-frame +work and the earlier nested-basis contributions. + +Completed-child semantic precision, arbitrary-coordinate routing, phase-cell +Gaussian inversion and bulk tape transfer are credited to the RaD project +(hipotures), commit 45d9b60355872041f9275f77c057514def0d45bc, exposed through +PR #20 at 4f8d6c8272b5ff307a0da51df545ec3cd96a8b6e. Their selected proof +sources retain their separate CC0 license and original NOTICE under +references/semantic-bulk/rad20. The PR #23 source retains its recorded OpenAI +Codex assistance; RaD retains its recorded Codex and GPT-6.1-Sol Ultra +assistance. These are source attributions, not claims about this session's +runtime model. Related contributions by Rohan Arun and Aurel Prosz remain +acknowledged in the imported notices. No exclusive priority or additional +license condition is asserted. + +Copied retained-center extension, 8 October 2026 +Copyright 2026 icekylinx + +The copied retained-center schedule in both orientations, its complex-phase +transfer, the Wm-N+L rank budget, and the selected (25,23)/(28,28) composition +are contributed by icekylinx with substantial OpenAI GPT-6 Astra and Codex +assistance. This extension inherits PR #32 at +0ef3aeb61f55cc0b321ce6a0ef00acee25cefe52 and the preceding PR #10/#18/#24 work. + +The two-stage topology and paid copied-stream endpoint correction are due +to Aurel Prosz (Paureel), c82d09eb4781b68435e3fa3eb6beea72fa900fab, +through Zhihao Chen (jacklightChen)'s PR #29 unequal-axis composition, +9d963275075fa98f1da821e27757b238dafd6b3c. That source also credits Swapnil +Jain's two-stage development at ae405eb474d1486b2d8aef90139869f927f4836a. + +The contiguous corner method, incidence factorization and exact partition +certificates are due to Rohan Arun (PR #31), method commit +02f68f95369c39955c5ffcfddbd75cd83e26b305. The selected (25,23) certificate +specializes Dominik Scholz's parameterization (PR #33), +a499a345c040aa15b68e984a0904eadc485c7a7e. Their source notices and proof +snapshots are preserved in references/copied-centers. Historical OpenAI +Codex, GPT-6 Astra and Anthropic Claude Opus 5.5 assistance is credited to +the respective imported sources. Existing PR #21/#23 and RaD attribution, +licenses and the Gaussian correction remain in force. + +Copied centers with reversed (23,25) data corners, 2026-10-08 +Rohan Arun with substantial OpenAI Codex assistance supplies the composition, +exact dimension23 controls and cost/assembly integration. James Chang's PR34 +supplies the reversed boundary family; icekylinx's PR36 supplies copied retained +centers and the selected complex graph. The balanced assembly remains attributed +to RaD/hipotures and its PR34 specialization. Retain Dominik Scholz PR33, Rohan +Arun PR31, Zhihao Chen PR29/21/23, Paureel/Aurel Prosz, Swapnil Jain, icekylinx, +eumemic, Douglas Colkitt, OpenAI and all earlier notices and hypotheses. +This is not a claim of formal verification, new foundational rank identities, +global optimality or measured runtime speedup. + +Fixed middle basis with copied reversed corners (2026-10-08): +Rohan Arun, with substantial OpenAI Codex assistance. Composition and +simultaneous-basis proof retain icekylinx PR32/36, James Chang PR34, +Dominik Scholz PR35/38, Zhihao Chen, Paureel, Swapnil Jain, RaD/hipotures, +eumemic and all preceding attribution and licenses. See research/copied-fixed-reversed. + +Changed-graph composition with copied centers and fixed bases, 8 October 2026 +Prepared with OpenAI Codex assistance. +The new composition uses icekylinx PR36 copied centers and PR32 fixed-I+J +projectors/profiler, Dominik Scholz PR35 two fixed factors and CRT argument, +Zhihao Chen (jacklightChen) PR29/23 interfaces, Aurel Prosz (Paureel) and +Swapnil Jain's two-stage development, Rohan Arun PR25/31 corner methods, +Dominik Scholz PR33/38 dimension/composition work; James Chang (jamesyc) +PR34 reversed geometry and balanced transfer; Rohan Arun PR37/39/40 +reversed integration, modular data tests and both-fixed baseline; +RaD (hipotures) PR41 changed scalar DAGs, alternating point order and +independent role compiler; RaD balanced routing/bulk interfaces, and all +retained predecessors. +Complete attribution and the conditional proof boundary are recorded in +research/copied-fixed/PROOF.md; imported originals and source pins are retained. +Original Apache-2.0 and CC0 notices remain applicable. + +Community follow-up integration (PRs #49, #45 and #26), 8 October 2026: +Rohan Arun contributes weighted carrier matching and climbed summand/leave-one-out +orders (PRs #44/#47/#49), with Anthropic Claude assistance. The final construction +composes Chafik Boukhalfa's changed-graph checks, exact rational data recovery and +reordered exclusion sums (PRs #43/#46/#48, OpenAI Codex assistance) with RaD / +hipotures's alternating pair order and independent physical role compiler (#41). +All predecessor attribution and conditional proof interfaces remain in force. + +Alejandro Zarzuelo Urdiales contributes Gaussian parity and canonical arithmetic +proofs, finite tensor execution, profile precision accounting and mixed-center +reference checks (#45), with substantial OpenAI Codex assistance. See +research/gaussian-parity-synthesis/PROVENANCE.md for his full attribution. +Ryan S / princezuda contributes historical Lean certificate arithmetic, algebraic +frame/movement/guard lemmas and independent paired-circuit checks (#26). Original +source notices and historical snapshots are preserved. Neither formal package +claims a full formal proof of the multiplication algorithm or a new kappa. + +Joint frame compilation of skip-prefix strips + +The local compiler and exact finite witnesses were prepared by eumemic with +substantial OpenAI Codex assistance. Avi Eisenberg / ikeboy with Anthropic +Claude assistance supplied the unmodified PR #53 skip-prefix producer. +The pinned PR #48 pipeline is Chafik Boukhalfa's contribution, incorporating +Rohan Arun, RaD / hipotures, icekylinx, Dominik Scholz, James Chang, +Zhihao Chen, Aurel Prosz / Paureel, Swapnil Jain, eumemic, Douglas Colkitt, +OpenAI, David Harvey, Joris van der Hoeven and the earlier contributors +credited in the retained sources. See references/frame-compiler/pr48/NOTICE +and references/frame-compiler/pr53/NOTICE for their original attribution. +No authorship or review by those predecessors is claimed for this compiler. + +Joint dual-skip/frame-compiler composition (2026-10-08) +--------------------------------------------------- +Rohan Gupta / gupt1156 with Anthropic Claude assistance: PR55 dual-skip +scalar graph; original LICENSE and NOTICE are retained under +references/frame-compiler/pr55. eumemic with substantial OpenAI Codex +assistance: PR57 joint reversible frame compiler, serialized physical-word +replay and profile reconstruction. Chafik Boukhalfa with OpenAI Codex +assistance: this composition, independent integration and exact certificate. +Avi Eisenberg / ikeboy, Rohan Arun, RaD / hipotures, icekylinx, and all +predecessor authors retain the notices above and in pinned source files. +No original copyright or Apache-2.0 notice is removed. + +Ranked reclamation after the PR58 joint-dual composition (2026-10-08) +---------------------------------------------------------------- +Chafik Boukhalfa with OpenAI Codex assistance: prioritize retired physical +slots by descending current frame rank, retaining slot ID as the tie-breaker; +complete replay, exact profiles, comparison and adversarial controls. +The dedicated joint_dual_reclaim_compiler.py is derived from eumemic's PR57 +compiler. Its original shared compiler remains byte-identical. The PR55 +producer and all preceding attribution remain unchanged. The complete PR58 +comparison certificate and its original source/proof provenance are retained +under references/frame-compiler/pr58. + +Skip-prefix strip producer, 8 October 2026 +By Avi Eisenberg (ikeboy), with Anthropic Claude (Claude Opus 5.5) +assistance. The skip-prefix leave-one-out strip layout in +research/skip-strips/skip_graph.py is new. Everything else reuses Chafik +Boukhalfa's PR #43/#46/#48 research/copied-fixed pipeline, its verification +code, exact data recovery and support-order sorting, together with: +- Rohan Arun's PR #44 weighted carrier matching optimizer; +- RaD (hipotures) PR #41 alternating point order; +- every predecessor credited above. +Complete attribution and the conditional proof boundary are recorded in +research/skip-strips/PROOF.md. Original Apache-2.0 and CC0 notices remain +applicable. + +Local split-pair skip-prefix research continuation (2026-10-08) +Prepared with substantial OpenAI Codex assistance at the user's request. +New contribution: singleton/pair recursive partition refinement, finite summand +order and moment search, and verified composition with inherited paid clones. +Avi Eisenberg/ikeboy with Anthropic Claude assistance: PR53 skip-prefix strips. +Chafik Boukhalfa with OpenAI Codex assistance: PR54 original-envelope clone +specialization and PR43/46/48 checking interfaces. RaD/hipotures: PR51 +whole-chain/source-partition cloning and earlier producer/interfaces. +Rohan Arun: PR44 weighted matching and earlier fixed/reversed work, with all +stated historical AI assistance. All predecessor notices remain applicable. + +Original-envelope whole-chain clones on skip-prefix strips (research/skip-clones): +Chafik Boukhalfa, prepared with OpenAI Codex assistance. The complete-chain +source-partition clone operation is adapted from RaD / hipotures, PR #51, +with original envelopes retained here. The scalar base is Avi Eisenberg's +PR #53 skip-prefix layout, prepared with Anthropic Claude assistance. +All credited PR #43/#46/#48, PR #44 and earlier code/proof notices remain +in force. This extension is provided under the repository's Apache-2.0 terms. + +Community review checkpoint #50–#61, 8 October 2026 +Maintainer integration and independent arithmetic: Douglas Colkitt, with OpenAI Codex. +Avi Eisenberg / ikeboy: skip-prefix strip framework (#53), with Anthropic Claude. +Rohan Gupta / gupt1156: parallel order search (#50, stated Antigravity assistance) +and dual-suffix strips (#55, Anthropic Claude assistance). +Eumemic: equal-frame joint compilation and paid signal reclamation (#57), with Codex. +Chafik Boukhalfa: original-envelope paid clones (#54), composition (#58) and ranked +reclamation (#60), with Codex. Rohan Arun: order search (#52) and positive-frame +composition (#56), with Anthropic Claude and stated Codex validation assistance. +RaD / hipotures: enlarged frames, source partitions and paid whole-chain clones +(#51), with Codex. Rohan Garg / rohangar1: singleton/pair recursion and paid-clone +composition (#59), with Codex. Alejandro Zarzuelo Urdiales: exact parameter +refinement, scoped Lean arithmetic, matrix/parity and search tools (#61), with +his disclosed multi-tool and Codex assistance. +Parallel #50/#52 records are reviewed and credited without replacing the earlier +climbed-48 implementation; their exact commit history is retained. The separate +#51 witness is retained as research; its source-graph/negative-basis data proof +has not received the same full replay as #56's consumed compiler machinery. +See docs/research/community-round2-review.md for precise validation boundaries. +All earlier licenses, contributions and notices remain applicable. + +Interval strips and core-aware pair assembly + +The interval leave-one-out strips and the core-aware group-pair assembly in +research/pair-assembly were prepared by Avi Eisenberg / ikeboy with Anthropic +Claude assistance. They build on PR #53's skip-prefix pipeline and its +inherited PR #48 sources. The stacked witness in research/pair-assembly/frame +uses eumemic's PR #57 joint frame compiler unchanged; its driver and verifier +are adaptations of PR #57's skip_frame_compiler.py, skip_frame_compose.py and +verify_skip_frame.py. Original notices are retained. + +Stopped product-ring extension, 9 October 2026 +Copyright 2026 icekylinx + +The opposite-bank generic projector factorization, componentwise atom-ring +adapters, stopped recurrence and outer ordinary-interchange conversion, +aligned pair-star producer with rational centers, exact denominator-21 +grid and selected (23,23)/(24,24) composition are contributed by icekylinx +with substantial OpenAI GPT-6 Astra and Codex assistance. This extension +builds on merged PR #36, 11817ccacb564bb7f98789c20dc11d3fece207e3, and is +integrated on upstream main 56b66d58297deca1d7dd130247d720e960f77a37. + +The retained ordinary leaf uses the preceding projector, corner and +copied-center proofs. The selected two-stage topology retains Aurel Prosz +(Paureel), Swapnil Jain and Zhihao Chen's credits; the semantic assembly +retains PR #21/#23 and RaD's attribution. Paired producers, carrier matching, +original source notices and each imported license remain unchanged. + +Partial-gauge extension, 9 October 2026 +Copyright 2026 icekylinx + +The pair-first cube assembly, compatible backward frame enlargement, +partial source-gauge schedule and stopped whole-projector composition are +contributed by icekylinx with substantial OpenAI GPT-6 Astra and Codex +assistance, extending PR #104 at 948ce1510df750f4c18b96bdaef436a86f8bf834. + +The physical deferred bit word, reflected event accounting, fan-order +clarification and signed two-stage endpoint are adopted from Zhihao Chen +(jacklightChen), PR #97, e15350b66e4bf796153a68c240a6cc1b788abe3e, with +Codex assistance. Its deferred readouts, V leaves, lifted frames and frozen +witness originate in Swapnil Jain's 741e7aa078392553815df7926ee17ac5e25a8c38, +with the original Claude disclosure retained. Cyclic interval and core-aware +pair primitives build on Avi Eisenberg (ikeboy), PR #62, +ad0f25ff7b23cff7f08ad237c2254e6ecf74257e, with Anthropic Claude assistance. +Prior two-stage, copied-center, ordinary-leaf, semantic/bulk, routing and +precision credits remain in force. Imported source notices and licenses +are preserved under references/partial-gauge/; see SOURCES.json. + +Three-stage cover extension, 9 October 2026 +Copyright 2026 icekylinx + +The arbitrary-subspace Clifford frame theorem, three-stage Cayley geometry, +weighted q-adic GL cover, unit-lower weighted compiler, charged local-ring +fallback, uniform batching, internal row borrowing and exact composition +are contributed by icekylinx with substantial OpenAI GPT-6 Astra assistance. This +repository integration uses Codex assistance and extends +PR #115, cf60442983c153a3a0f5272ea4713f99eba13c86. + +The selected local complex DAG and support/label replay are adopted from +Copyright 2026 eumemic, PR #117, cbb05ce504d571546d9b7794c186a613c659c3bf, +with its original Apache-2.0 terms and Claude assistance disclosure. +The unchanged bit physical word retains Zhihao Chen (jacklightChen), +PR #97, and Swapnil Jain's underlying witness and assistance notices. +The prior opposite-bank, stopped ordinary-leaf, copied-center, topology, +semantic/bulk, precision and analytic credits remain applicable. +Original source notices and license bytes are preserved in +references/three-stage-cover/pr117/ and references/partial-gauge/. + +Paired-cube and shared-core extension, 9 October 2026 +Copyright 2026 icekylinx + +The paired-coordinate triple-cube identity, signed overlap channels, +original-source involution, coordinate-star centers, concrete frame/carrier +compiler, chronological source gauges, PR97 gauge-subset selection, +orthogonal cross-stage routing and exact supplier/assembly integration +are contributed by icekylinx with substantial OpenAI GPT-6 Astra assistance. +Repository integration uses Codex assistance and extends PR #130 at +6a9970a530119174507904e23592fd59ede19a5d. + +The substantial completed-core workspace-sharing principle is credited to +an664, PR #128, 530588a019b4a74f09180680c9e3961bf649ec89, with its reported +OpenAI Codex assistance. No source code, partition or serialized witness +from that PR is imported. The new routing and paired-motif integration +are described separately and claim no exclusive priority for broad sharing, +paired-coordinate, Fourier or carrier-matching ideas. + +Selected coarse queries restrict the retained eumemic PR #117 positive DAG; +its original Apache-2.0 and Claude assistance notices remain unchanged. +The bit word and original frames retain Zhihao Chen's PR #97 and Swapnil +Jain's frozen witness, notices and historical assistance disclosures. +Earlier generalized Clifford, three-stage, uniform weighted recursion, +ordinary-leaf, semantic/bulk, precision and analytic credits remain in force. +Source-specific license bytes are preserved under references/. + +October 9 recycled-bit integration: +DaysSky (#150), William Porter/hpst3r (#147), Thomas Marchand/Th0rgal (#146), +Rohan Gupta/gupt1156 (#148), James Chang/jamesyc (#124), SovereignSteak (#122). +The original notices and assistance disclosures are retained under research/, +including research/recycled-bit-integration/NOTICE. Andrew Barnes/Bortlesboat +(#101) repairs shared verifiers using rfu08's #64 counterexample. rfu08's +scoped finite and formal-transfer packages are included separately; they do +not establish the full multiplication theorem. Earlier and parallel credits +remain applicable. Douglas Colkitt integrated these with OpenAI Codex assistance. + +SovereignSteak PR151 independently supplies the matching gauge/recycling +composition and the selected 473/10^6 atom refinement; its original package +and assistance disclosure are retained under research/gauge-recycling/. + +October 9 coordinated-frame and completed-entrance-bank integration: +Dugongue PR186, 166a34d75e853e933855f0f7e940fe77c4bb6b8d, builds on +Chafik Boukhalfa/chafreaky's PR181, 7fb2194801e3a10f54772c7f0d5505035a4fc0ad, +and eumemic's PR168 v4, 4a3c769e5c5430e7114c4d3e099ff34664677f17. +The frozen package and prerequisite archive preserve all author, source-license +and assistance notices, including PR175's compiler optimization. DaysSky's +carrier closure, James Chang's terminal substitution and balanced assembly, +geckods' stopping refinements and all preceding framework credits remain. +Rohan Arun's PR185 bootstrap and chafreaky's PR182 bit refinement are reviewed +parallel contributions; their gains are not added to the selected witness. +Douglas Colkitt integrated the package and supplied the bank scheduling +supplement with OpenAI Codex assistance, under Apache-2.0. The all-size +interfaces remain conditional; finite verification is not full formalization. diff --git a/research/twiddle-matched-layer/PROOF.md b/research/twiddle-matched-layer/PROOF.md new file mode 100644 index 0000000000..4cbb7f806f --- /dev/null +++ b/research/twiddle-matched-layer/PROOF.md @@ -0,0 +1,421 @@ +# A matched chunk layout for the actual-width T74 synthetic caller + +## Result and boundary + +This is a source-relative, changed outer-layout proposal and an independent +interface audit. It does not implement the diagonal pass claimed by Sagar +Thakrar in Discussion 2612 comment 19015185, execute a production T74 object, +or certify a new multiplication exponent. + +There is a concrete mismatch between the conservative outer caller and the +new actual-width root. The caller chooses + +\[ +d=\lfloor p^{1/40}\rfloor,\qquad K_d=\lfloor d^{1/500}\rfloor, +\] + +and each common synthetic round selects exactly \(g=d-1\) bits. PR3599's +literal planner instead chooses \(K_g=\lfloor g^{1/500}\rfloor\). +These widths disagree at every \(d=k^{500}\), \(k\ge2\). The unchanged +outer wrapper also requires a different planner constructor. A substitution +based only on the normalized tensor endpoint is therefore insufficient. + +Replace the outer named-slot layout's chunk width by \(K=K_g\), retain its +explicit positional permutation and inverse, and use a wrapper whose +admission is the actual-width root's admission. This makes every common +round a complete, correctly positioned PR3599 input. It requires no new +arbitrary-support router. The source layout bounds and their exponents +survive. The source's long records satisfy the newer root's record condition; +the disk-grid invariant guarantees every signed negation required by PR3611. + +Conditional on a complete paid diagonal/caller adapter with the lifecycle +specified below, the resulting forward/opposite transform has the same +normalization, error and asymptotic outer routing bottleneck. The public +single-record producer/consumer results alone do not establish that lifecycle. + +## 1. Exact sources and inherited premises + +The frozen canonical base is +`20ecf2891d80b5acf18d980b2164fb44ea7faa90` (priority revision 6). + +| Source | Exact head or canonical path | Used implication | +|---|---|---| +| Jose Manuel, PR2298 | canonical `research/selected-conservative-outer/PROOF.md` | Outer dimension/record bands, exact-K positional caller, analytic and cost premises | +| Nick Petalas, PR3493 | `c0ee30f63a89c3bd0eabb3ea7eaa7786d5ad707f` | Actual MSB/LSB wrapper, complete cardinality, consumed-output gate, smaller-dimension caller | +| Jose Manuel, PR3599 | `72df81b8cee17ffd990fc18b2d54024f65971556` | Actual selected-width plan, complete normalized root, retained physical premises and cost | +| Nick Petalas, PR3593 | `46c04613a19a5b7bd50d98e50bbc8ea8dc6275b0` | Encoded named-slot exponent, descriptor and declared tape-action tariff | +| Sagar Thakrar, PR3611 | `c21172062a2d907804538aa5a74012a2a4cc144e` | One encoded header to one exact signed Gaussian packet | +| Retained transform source | canonical `upstream/build/sections/06-transforms.tex` | Named slots, positional layout, grouped rounds, frequency order, one truncation per round | + +PR3576 at `1630afea0fc1083717b5b2799b8de7a819a6ea02` retunes the +older root and stopping rule but explicitly retains the older dimension law. +PR3553 at `d5ea38a0a613e721d828ef072379d7101d770cd6` is a logical +ordinary-selector composition, not a replacement physical synthetic caller. +Neither removes the present literal layout/constructor mismatch. + +The normalized T74 theorem remains conditional on the cited native, +ordinary/C0, common-label, hosting, coefficient-height and physical-refinement +premises. This audit does not replay the 2,394,506-child certificate or upgrade +any source's review status. The original transform and analytic arguments +remain credited to their sources, including Douglas Colkitt, Nussbaumer and +Quandalle, Harvey and van der Hoeven, Philipp, and the retained contributor +lineage. PR3599 also credits Hiroki Kumazaki's PR3576. The new result is the +specific joined contract, its floor-boundary obstruction and matched repair. + +## 2. The floor obstruction is literal + +For integer \(k\ge2\), if \(d=k^{500}\), then + +\[ +\lfloor d^{1/500}\rfloor=k, +\qquad +\lfloor(d-1)^{1/500}\rfloor=k-1. +\] + +Conversely, for integer \(d\ge2\), the two floors differ only at such +perfect powers. Indeed the integers between consecutive 500th powers share +the same floor, and subtracting one crosses a boundary only at a power. +Thus this is an infinite family of actual caller parameters, not a numerical +rounding accident. + +For arbitrary integer precision, the old threshold \(K_d\ge k\) is exactly \(p\ge k^{20000}\). +The repaired threshold \(K_g\ge k\) is exactly + +\[ +p\ge(k^{500}+1)^{40}. +\] + +For \(k=2\), these are respectively \(2^{20000}\) and +\((2^{500}+1)^{40}\). The actual PR2298 choice p=6b further restricts +p to multiples of six: replace either threshold X by \(6\lceil X/6\rceil\). +For k=2 these are \(2^{20000}+2\) and \((2^{500}+1)^{40}+5\). +Each perfect-power dimension interval contains such admitted multiples, +so this restriction does not remove the mismatch family. +A huge threshold is not a refutation of an +asymptotic theorem. It matters here because the API computes these floors; +one cannot equate them by asymptotic notation. + +In PR3599 `active_plan.py`, `d` is copied from the selected count and `K` +is computed from that value. Its full Gaussian count is + +\[ +\text{outer_rows}\;2^{\text{left}+gK+\text{right}}r. +\] + +Passing the old left/right fields with a smaller internally computed K +changes the complete expected payload extent by a factor +\(2^{g(K_d-K_g)}\). Enlarging the left field to conceal the extent mismatch +does not repair the endpoint: at offset zero and right field zero the +selected bit sets become \(\{0,K_d,\ldots,(g-1)K_d\}\) and +\(\{0,K_g,\ldots,(g-1)K_g\}\). Their Walsh tensors differ. + +A small exact calibration replaces the fixed exponent 1/500 by 1/2: +\(d=4,g=3,K_d=2,K_g=1\). A delta input at address zero has an output +at address two under the latter tensor and none under the former. This +scaled-exponent fixture checks the structural failure; it is not a finite +execution at the enormous production floor boundary. The checker separately +validates the exact production integer-power inequalities. + +## 3. Matched layout and all round cases + +Assume the outer caller's nontrivial range \(d\ge2\), and put +\(g=d-1\). There are g polynomial-record axes. Each is long, with +\(\ell\) named bits, or short, with \(\ell-1\) named bits. Let a be +the number of long axes and let A be their total number of record bits. +The number of complete polynomial records is \(M=2^A\), and +\(T=rM\), \(r=2^\ell\). No coefficient suffix or spectator is omitted. + +Set \(K=\lfloor g^{1/500}\rfloor\), +\(b=(\ell-1)\bmod K\), and \(q=\lfloor(\ell-1)/K\rfloor\). +Use the source's positional construction with this K: + +1. Move the long top slots to a prefix in axis order. +2. Append each of the low named planes \(b-1,\ldots,0\), in that order + and in axis order within a plane. +3. Transpose the remaining equal K-bit chunks from axis-major to chunk-major + order, preserving the bit order inside every chunk. + +Call this permutation L. It preserves the complete polynomial suffix. It +has the same explicit inverse as the retained construction, with its own +recorded positions; do not reuse an old-K inverse descriptor. + +For each common round \(\ell-2\ge h\ge b\), set + +\[ +j=\left\lfloor\frac{\ell-2-h}{K}\right\rfloor, +\quad \rho=(h-b)\bmod K, +\quad n_P=a+gb+jgK, +\quad n_S=(q-j-1)gK. +\] + +The selected named bits occupy exactly +\(n_S+\rho+tK\), \(0\le t0\) and acts on a axes. The b bottom rounds act on g axes. +Keep the source's elementary prefix implementation for these rounds; +do not invoke a smaller actual-width root against a g-chunk header. +They require \(a+gb\) individual butterfly sweeps. There are +\(R=\ell-1+\mathbf1_{a>0}\) complete rounds in total. At h=0 the +twiddle is the identity. Counting a diagonal there is a harmless charged +upper bound; this audit claims no implementation that removes it. + +The cases \(a=0\), \(a=1\), and \(a=g\) respectively include no top +round, a singleton top round, and a fully participating top round. If g=1, +K=1 and every common root is the source's singleton/fallback case. If d=1, +there are no record axes: use the outer finite-range/identity case instead +of evaluating \(\lfloor0^{1/500}\rfloor\) as a legal chunk width. The +opposite transform uses exactly the reversed round order and the inverse +twiddle before each butterfly. These rules cover both ends of the schedule. + +## 4. Parameter and budget compatibility + +For \(d\ge2\), \(g\ge d/2\). Since \(\lfloor x\rfloor\ge x/2\) +for \(x\ge1\), + +\[ +2^{-1-1/500}d^{1/500}\le K\le d^{1/500}. +\] + +Thus K retains the required growth and logarithmic absorption. The outer +source's bands include + +\[ +\frac{p}{12d}\le\ell\le\frac{p}{3d},\qquad +d\ell\le p/3,\qquad p\ge2^{40}. +\] + +They imply \(K\le\ell-1\): \(K\le d\), while +\(\ell\ge d^{39}/12\ge d+1\) for \(d\ge2\). +In particular K is also smaller than r. The full address and descriptor +length bounds remain O(p); changing the computed chunk positions adds no +advice tape or unbounded number of roles. + +The active width satisfies \(1\le g\le\lfloor p^{.997}\rfloor\). +The older source long-record band implies PR3599's newer condition with +fixed constants b=B=1: + +\[ +\log_2r=\ell\ge\frac{p^{39/40}}{12} +\ge(\log_2p)^2,\qquad \log_2r\le p. +\] + +For the middle inequality put \(t=\lfloor\log_2p\rfloor\ge40\). +It suffices that \(2^{39t/40}\ge12(t+1)^2\). At t=40, +\(2^{39}>12\cdot41^2\). Raising consecutive-step comparisons to the +40th power proves monotonicity because +\(2^{39}>((t+2)/(t+1))^{80}\) for t>=40. All comparisons can be +checked with integers. This proof uses actual complete coefficient records; +it does not replace record count by a label or a declaration. + +The prefix and movement costs are still charged. At most \(g(b+1)\) +single-bit moves and \(gq-1\) chunk exchanges give + +\[ +O\bigl(V[gK+pK^{\tau-1}]\bigr), +\qquad \tau=99830289/10^8, +\] + +including the inverse layout when needed. In the negative power term the +*lower* bound on K is essential: + +\[ +K^{\tau-1}\le +2^{(1+1/500)(1-\tau)}d^{(\tau-1)/500}. +\] + +The prefactor is fixed. This audit retains the old outer ordinary +interchange contract; PR3599's internal ordinary retuning is not silently +substituted into the independent outer movement term. + +With \(\alpha=99827101/10^8\), the common roots cost +\(O(V(\ell-1-b)g^\alpha\log p)\). Their MSB/LSB conversions add +O(V) per common call under the retained bridge theorem. The complete +conditional transform cost, once the paid diagonal/caller condition in +Section 6 holds, is therefore + +\[ +O\left(Tp\left[dK+pK^{\tau-1}+\ell g^\alpha\log p\right]\right). +\] + +The logarithm stays explicit until compared against an outer power gap. +The new common-round power saving is +\((1-\alpha)/40=172899/4000000000\). The exact-K movement saving +remains \(169711/2000000000000\), much smaller. Changing only the +root and this layout therefore does not improve that inherited bottleneck +or establish a new integer exponent. + +## 5. Complete-round numerical admission and formats + +At a legal caller entrance each Gaussian coefficient is in the closed +unit disk and each real/imaginary part is on the p-grid. Its integer +numerators lie in \([-2^p,2^p]\). The source width is w=p+2, so the +sole signed value whose negative is unrepresentable is \(-2^{p+1}\), +strictly outside that set. Every sign change requested by PR3611 is +therefore admitted. PR3611 already states the one-packet w=p+2 implication; +the added implication here is its preservation through every complete +actual-root, prefix and opposite round. It is not a claim based on the +tested packets or a new local signed-negation result. + +Every completed \(H_0^{\otimes g}\) is a contraction in maximum +coefficient norm; truncating each component toward zero preserves the +disk and returns the p-grid. A monomial \(J_E\) is an exact signed +coefficient permutation, so it preserves the disk, grid and width. It +commutes with Q_p because truncation toward zero is odd. Consequently + +\[ +J_EQ_p(\mathcal H z)=Q_p(J_E\mathcal H z), +\qquad +Q_p(\mathcal H J_E^{-1}z) +\] + +are the forward and opposite completed rounds. For prefix rounds, all +elementary factors are evaluated exactly before that single Q_p; applying +Q_p immediately before J_E gives the same output and allows the diagonal +to use w=p+2 rather than the temporary p+s grid. There is no truncation +between the individual prefix factors. Intermediate root or pair-update +values need their retained guard; they are not declared disk values. + +Induction proves signed-negation admission, disk/grid return and one error +increment below \(\sqrt2\,2^{-p}\) at every complete round. After R +rounds the error is below \(\sqrt2 R2^{-p}\le\sqrt2\ell2^{-p}\). +The exact forward and opposite operators are respectively +\(LB F^-\) and \(F^+B^{-1}L^{-1}\). The bit-reversed frequency order +B remains part of the endpoint. Using the same new L for both operands +allows their pointwise product in that order; the opposite consumes it. + +PR3599 returns LSB-first components; PR3611 consumes framed MSB-first +components. Nick Petalas's complete WordOrderBridge proves value-preserving +linear-cost conversion, but his `OuterLayer.__init__` requires +`root.plan.dimension_exponent == (1,40)`. The active-width plan derives its +dimension from the selected count. A new wrapper must validate that actual +contract and use its computed complete cardinality. Calling the old wrapper +unchanged is not established. Framing a full cube into packet records and +returning it to the root's sentinel/descriptor vocabulary is also a physical +adapter obligation, not an algebraic consequence of equal word widths. + +## 6. A positive paid-join criterion and remaining bill + +Let Q be the complete extra tariff for address enumeration, packet framing, +cube extraction/assembly, descriptor updates between rounds, output +consumption/clearing, role reuse and all head returns. It is unknown for the +joined published artifacts, and is not assigned zero. The new active claim +19015185 covers a fixed-h diagonal pass; its result and any later caller +interface must be checked before treating Q as paid. + +For one shape, define +\(M_0=A+\ell+1\) and +\(N_h=\ell+K+h+g+6\). The source's declared tape read/write/move and +data-gate producer tariff is bounded by +\(5000M_0^2(N_h+4)\). It is not a precise count of every finite-control +transition; a fixed transition-lowering factor must be retained separately. +The complete packet consumer tariff is bounded by +\(256(2rw+\ell+w+1)\). + +Invoking both modules once per record per complete round therefore has +the constructive declared-tariff bound + +\[ +\begin{aligned} +T_{\rm pc}\le {}&5000M M_0^2 +\left[R(\ell+K+g+10) ++\frac{(\ell-2)(\ell-1)}2 ++\mathbf1_{a>0}(\ell-1)\right]\\ +&+256MR(2rw+\ell+w+1). +\end{aligned} +\] + +This counts even the identity h=0 call; it does not charge the producer a +second time after shared header/descriptor accesses by the consumer. Source +volume and all complete-record calls are explicit. The outer caller has +\(A+\ell=\log_2T\le p/6\); thus M_0=O(p), N_h=O(p), and +\(T_{\rm pc}=O(MR(p^3+rp))\). With the proved long-record inequality, +\(p^2/r\le1\) for p>=2^40, so this is O(MRrp)=O(RV). +An exact bound for a proposed finite constant allowance B per rp record is +obtained by retaining the displayed tariffs, the finite-control factor and +the actual Q, rather than dropping any of them. + +A sufficient full caller condition is a fixed finite-tape diagonal +implementation, uniform over the round descriptors, with + +\[ +Q\le C\,MR(rw+A+p^3)+\operatorname{poly}(p) +\] + +for a fixed C, complete same-order disk-grid output, preserved borrowed +input and descriptors, and canonical returned heads. It must clear or +consume each previous owned output before reuse, restore its private roles, +and retain only a fixed number of complete cube buffers across rounds. +Under this condition the same long records pay Q, including its arbitrary +fixed-degree polynomial setup term: \(r\ge2^{(\log_2p)^2}\) dominates +every fixed power of p. The complete transform bound in Section 4 follows. +This is a positive conditional composition +criterion, not a claim that the unpublished diagonal or active-root wrapper +already satisfies it. + +| Item | Status in this audit | +|---|---| +| Exact chunk floor, extent and selected-bit mismatch | Proved; bounded controls | +| Matched complete-address layout and all round cases | Proved; bounded complete-cube arithmetic checks | +| Root dimension and long-record admission | Proved implication from the retained outer bands | +| Signed packet admission and completed-round error | Proved from source disk-grid contracts | +| New-root asymptotic tariff and native/hosting/height | Inherited source-relative theorem; no production replay | +| Component-order conversion | Retained constructive O(V) bridge; active-wrapper integration unimplemented | +| One-record encoded producer/consumer tariff | Retained written bounds; limited actual-interface corroboration | +| Owned full-array diagonal, framing, reuse and all-round control | Required positive criterion; not established by this audit | +| Precise combined tape count, arbitrary dirty private entry and production widths | Unestablished; no zero charge or practical cutoff claim | +| Full analytic/packing/multiplier adoption and selected improvement | Outside this result | + +## 7. Finite evidence and stopping decision + +The checker uses exact integers/rationals, directly reconstructs the named +layout, and compares complete small Gaussian cubes for every common/prefix +round, both directions and singleton/all-short/mixed/all-long cases. Its +normalized butterfly is an arithmetic oracle, not a physical T74 execution. +It checks the production floor thresholds with exact large +integers. A scaled-c case exposes both the extent failure and the wrong +selected-bit endpoint if the extent is concealed. Other controls reject a +changed offset, old inverse layout, wrong inverse-round order, floor rounding +in place of truncation toward zero, and an undersized signed format. + +The ten geometries produce 50 complete-round comparisons. Two additional +calls execute the unchanged PR3593 and PR3611 modules on a nonzero packet +returned by the repaired layout's arithmetic H oracle. The actual address +36 in the three-short-axis ell=3 example emits residues 12 and 4 with K=1; +interpreting those same physical bits under old K=2 emits zero instead. +The opposite packet returns exactly. Success tariffs independently reconcile +against all actual tape counters without double-counting shared header work. +The unchanged consumer rejects a second call with `one-shot consumer`, even +after its successful private cleanup. Both source ell=33 admission controls +reject before large allocation. These checks do not execute a full-array +diagonal pass, a physical root, or a new rearming implementation. + +The PR3593/3611 executables cap ell at 32. In the actual nontrivial PR2298 +domain, the source bands imply +\(\ell\ge2^{39}/12\), hence integer ell>=45,812,984,491. +Thus their small replay fixtures do not execute a legal nontrivial outer +instance. They test interfaces; the unbounded statements remain written, +source-relative arguments. This incompatibility of finite caps is not a +counterexample to those arguments and is not repaired by omitting a guard. + +Continue the bounded layer interface audit and hand the matched descriptor, +wrapper and paid lifecycle criterion to the diagonal author. Do not duplicate +that pass, execute an enormous root, or optimize header counts before the +required full-array result is available. The route is mathematically +compatible and closes concrete admission implications, but production +integration remains conditional and the inherited exact-K outer bottleneck +still controls the exponent. A new full caller implementation, a paid +different movement law, or independently admitted production sources is the +appropriate reopening evidence. diff --git a/research/twiddle-matched-layer/README.md b/research/twiddle-matched-layer/README.md new file mode 100644 index 0000000000..181ee07911 --- /dev/null +++ b/research/twiddle-matched-layer/README.md @@ -0,0 +1,211 @@ +# Matched twiddle layout for the actual-width normalised layer + +**A source-relative interface repair and conditional complete-round theorem.** +This package joins the actual outer layout to the newer root's selected width, +proves its record-size and signed-packet admission, and states the remaining +paid layer lifecycle. A separate addendum incorporates the subsequently +published PR3617 full diagonal pass. The physical root, all-round reuse, +complete caller invoice, and a faster multiplier remain unestablished. + +The investigation is complementary to +[Sagar Thakrar's completed fixed-h diagonal-pass handoff](https://github.com/CrocSwap/integer-mult-bounds/discussions/2612#discussioncomment-19015185). +It reuses his unchanged implementation. Its sources include the actual +[PR3493 outer wrapper](https://github.com/CrocSwap/integer-mult-bounds/pull/3493), +[PR3599 actual-width root](https://github.com/CrocSwap/integer-mult-bounds/pull/3599), +[PR3593 header producer](https://github.com/CrocSwap/integer-mult-bounds/pull/3593), +and [PR3611 packet consumer](https://github.com/CrocSwap/integer-mult-bounds/pull/3611). +All four are pinned at exact heads, with original bytes and credit retained. + +## Exact mismatch and repair + +In the retained outer construction, d=floor(p^(1/40)) and common rounds select +g=d-1 axes. The original layout chooses K=floor(d^(1/500)), while PR3599's +actual-width plan chooses K=floor(g^(1/500)). The integers disagree exactly +when d=k^500 for an integer k>=2. This changes both the root's complete array +extent and its selected physical bits. Increasing a left extent to conceal +the cardinality mismatch does not fix the wrong tensor action. + +[PROOF.md](PROOF.md) supplies a matched layout using +K=floor((d-1)^(1/500)), with the corresponding inverse layout and complete +descriptors. Common rounds already act on consecutive K-bit chunks at one +common offset, so these calls do not require a separate general-support +router. That distinct support-router work has also advanced in PR3619; it is +not part of this join. The existing layout movement and component-order conversion remain +charged. A new active-root wrapper must still bind them to the same complete +Gaussian array. The old wrapper's dimension-exponent constructor check cannot +simply be reused for the new plan. + +The floor issue survives the caller's final rounding. At a production boundary +d=k^500, g=d-1, take one real coefficient at address zero with p-grid numerator +2^g. Its value 2^(g-p) lies in the unit disk since p>=d^40>=g. In a common +chunk at residue zero, hiding the extent mismatch leaves actual selected +positions spaced k-1 bits apart. Its normalised tensor has numerator one at +address 2^(k-1), where the intended spacing-k tensor has zero. Both are already +on the p-grid, so truncation cannot hide the difference. Here the address is +within the final common chunk group, with right offset zero; a nonzero right +offset shifts both selected-position formulas. A subsequent signed +packet rotation preserves nonzeroness. This is a quantified counterexample to +the naive substitution, not an execution of an enormous production instance. + +For unrestricted integer precision, the old K>=k threshold is p>=k^20000; +the matched one is p>=(k^500+1)^40. The actual caller uses precisions divisible +by six. Exact tests cover the first legal precisions at both boundaries for +k=2 and k=3. The distinction persists on that restricted domain. + +## Completed rounds, precision, and cost + +The proof covers all-short, mixed, all-long, and singleton axes, common chunks, +top and bottom prefix rounds, and both transform directions. It retains the +frequency bit reversal and layout endpoint maps. The inverse direction applies +the inverse diagonal before the butterfly and reverses the round order. + +The actual outer bands imply the root's required long-record condition +r>=2^((log2 p)^2), with r=2^ell, and its dimension condition. Completed +normalised butterflies contract the unit disk, and truncation towards zero +preserves it. Signed coefficient permutations are exact isometries and commute +with this truncation. The packet width is therefore w=p+2 throughout the +complete-round induction, and the source's forbidden signed minimum is +unreachable. PR3611 already supplies the one-packet width observation; the new +scope is the actual layer's admission and repeated-round implication. + +After R<=ell rounds, the source-relative error is less than +sqrt(2) R 2^-p. Intermediate butterfly factors are not separately truncated. +With the retained ordinary movement exponent tau=99830289/10^8 and the newer +root exponent alpha=99827101/10^8, the complete conditional bound remains + + O(T p [d K + p K^(tau-1) + ell g^alpha log p]). + +Here M is the number of records, r the coefficients per record, and T=Mr. +No newer internal ordinary profile is silently substituted for the retained +outer movement theorem. The exact-K movement saving 169711/2000000000000 +still controls the narrower bottleneck. This package does not improve the +selected integer exponent. + +Let Q include all added address enumeration, packet framing, extraction and +assembly, descriptor updates, output consumption and clearing, tape reuse, +and head returns. A sufficient missing implementation contract is + + Q <= C M R (r w + A + p^3) + poly(p) + +for a fixed constant C and A=log2(M), together with complete same-order output, +preserved borrowed data, returned heads, private cleanup, and a fixed number +of complete array buffers across rounds. The long-record band pays this term. +The proof also retains and sums the producer and consumer's written tariffs. +PR3617 now supplies the fixed-h enumeration and packet lifecycle part, under +its own matching framed-input and successful-return premises. Q is still +unknown for the whole proposed composition, including the physical root, +initial framing and layout, descriptor changes, whole-output consumption, +and reuse between rounds. The exact simultaneous tape count and production +width lifecycle remain unestablished. + +## Published diagonal joined to complete arithmetic rounds + +The original seventeen-file proof/check component stays frozen. At the +pre-submission checkpoint, Sagar published +[PR3617](https://github.com/CrocSwap/integer-mult-bounds/pull/3617), exact head +`4bf091f415d6470b60a5062a08b0a47e5b12dbd7`, and explicitly handed its fixed-h +pass to this complementary caller audit. [diagonal/ADDENDUM.md](diagonal/ADDENDUM.md) +records the source-bound contract and what remains open. + +The addendum's checker retains all twelve predecessor package files unchanged +and executes the actual full diagonal on two small complete-cube geometries. +There are **12 positive completed forward/opposite rounds, 384 actual packet +applications, and 4,096 Gaussian coefficient comparisons**. The arithmetic +butterfly, truncation, layout, and host fixture serialization are explicitly +unpriced oracles. Each direction starts from the same initial cube; this is +not a forward/opposite full-transform round-trip claim. + +Every diagonal stage preserves borrowed bytes, returns all 38 heads, blanks +private roles, and rejects runtime tape replacement. The positive fixed-pass +tariffs total **19,566,850 actions**. A separate 64-packet wrong-K pass differs +at four coefficient positions. Off-grid encoding and second-use controls +reject for their intended reasons. + +The 38 roles include both complete streams. Packet buffers are reused within +each pass, but the full pass object itself is one-shot. Fresh stage instances +in the checker supply no physical all-round allocation or reuse theorem. +Thus PR3617 closes the fixed-diagonal portion of the former Q condition while +leaving the enclosing layer obligations explicit. The source's full historical +six-cube suite and a production physical root are not replayed here. + +## Bounded evidence and reproduction + +[check_join.py](check_join.py) reconstructs the layout independently and checks +ten complete small Gaussian cubes, giving **50 forward/opposite completed-round +comparisons**. Seven structural controls distinguish wrong extent, concealed +wrong tensor, old inverse layout, wrong offset, inverse order, floor rounding, +and insufficient signed width. + +Two additional calls execute the unchanged PR3593 and PR3611 modules on a +nonzero packet returned by the repaired layout's arithmetic butterfly oracle. +At physical address 36, matched K=1 emits residues 12 and 4; interpreting the +same bits under old K=2 emits zero. The opposite packet returns exactly. +Both consumer costs independently reconcile to 9,863 counted actions, with +producer tariffs 37,867 and 36,549. Source caps and one-shot reuse rejection +remain active. These are actual single-packet interfaces, not a full-array +diagonal implementation or physical T74 execution. + +The source executables cap ell at 32. The nontrivial outer bands instead imply +ell>=45,812,984,491. Thus the finite fixtures do not execute a legal nontrivial +outer instance. They corroborate interfaces; the unbounded results are written +proofs under named source premises. No cap was removed to imply otherwise. + +With Python 3.12 and the standard library, run from this directory + +```sh +python3.12 -I -Werror -B verify.py +python3.12 -I -O -Werror -B verify.py +python3.12 -I -Werror -B diagonal/verify.py +python3.12 -I -O -Werror -B diagonal/verify.py +``` + +The wrapper authenticates the exact inventory and all retained source bytes, +runs the bounded checker, and strictly compares [RECEIPT.json](RECEIPT.json). +Boolean/integer substitutions and changed source bytes fail. Default replay +is read-only and also works in a Git-free export. The addendum wrapper separately +authenticates its inventory, the frozen arithmetic module, and its typed +[receipt](diagonal/RECEIPT.json). Running either component checker alone prints +newly computed data; it does not compare the stored receipt. + +From a complete repository checkout, run + +```sh +GIT_NO_REPLACE_OBJECTS=1 python3.12 -B scripts/research_package.py --package research/twiddle-matched-layer --check-only +GIT_NO_REPLACE_OBJECTS=1 python3.12 -B scripts/research_package.py --package research/twiddle-matched-layer +GIT_NO_REPLACE_OBJECTS=1 python3.12 -B scripts/check_research_commit.py --package research/twiddle-matched-layer --check-source-history +``` + +[SOURCES.json](SOURCES.json) preserves the main20ecf289 baseline and original +catalogue card. Pending source bytes are retained in this PR's own ancestor +history; [SOURCE_INVENTORY.json](SOURCE_INVENTORY.json) records their original +paths, commits, Git blobs, SHA256s, and attribution. Frozen source modules are +not edited. [VERIFY.json](VERIFY.json) declares the bounded replay explicitly. + +## Open next questions + +[TASK.json](TASK.json) gives the structured next steps. The most useful next +implementation is the correctly typed active-width outer wrapper, connected +to PR3617 with the complete framing and inter-round lifecycle bill. +It must bind identical record order and extent, both component bit orders, +unit-disk output, borrowed storage, consumed previous outputs, private cleanup, +and returned heads across every round. A producer/consumer endpoint for one +record is insufficient for that obligation. + +Reopen a faster-bound claim only with a paid change to the remaining outer +movement bottleneck and all retained transfer implications. Finite admission +fixtures and local header savings cannot supply that change. + +## Credit + +New work by Clear1nsight with substantial OpenAI assistance from a root agent +and three concurrent specialists, including independent same-session source, +proof, and executable review. No independent human or formal-kernel acceptance +is claimed. New work is Apache-2.0. Original LICENSE and NOTICE bytes are kept. + +Credit Nick Petalas for PR3493's complete-format outer wrapper and PR3593's +encoded controller; Jose Manuel for the PR2298 outer construction and PR3599 +actual-width root, retaining Hiroki Kumazaki's factory/rate lineage; Sagar +Thakrar for PR3611's signed packet consumer and PR3617's completed diagonal +pass; and Philipp, Douglas Colkitt, David Arias, and the retained source authors +for the earlier positional schedule, monomial, and transform work. Detailed +attribution remains in the unchanged source proofs and source inventory. diff --git a/research/twiddle-matched-layer/RECEIPT.json b/research/twiddle-matched-layer/RECEIPT.json new file mode 100644 index 0000000000..0e05c4af35 --- /dev/null +++ b/research/twiddle-matched-layer/RECEIPT.json @@ -0,0 +1,297 @@ +{ + "actual_interface": { + "actual_single_packet_calls": [ + { + "consumer_actions_independently_reconciled": 9863, + "consumer_tariff": 9863, + "exponent": 12, + "opposite": false, + "packet": [ + [ + 2, + 0 + ], + [ + 3, + -1 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + -1, + -1 + ], + [ + -2, + 0 + ], + [ + -3, + 1 + ], + [ + -1, + -1 + ] + ], + "producer_tariff": 37867, + "producer_tariff_bound": 9000000, + "used_object_rejection": "one-shot consumer" + }, + { + "consumer_actions_independently_reconciled": 9863, + "consumer_tariff": 9863, + "exponent": 4, + "opposite": true, + "packet": [ + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + 3, + -1 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + 3, + -1 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ] + ], + "producer_tariff": 36549, + "producer_tariff_bound": 9000000, + "used_object_rejection": "one-shot consumer" + } + ], + "arithmetic_H_only": true, + "matched_layout_address": 36, + "source_cap_rejections": [ + "bad ell", + "allocation ell" + ], + "source_pins": [ + { + "git_blob": "2e72164d9429baeb1b18621f6f4b9576dbcc60a4", + "path": "pr3593-controller.py", + "sha256": "680146c712a9d547cd5b2b28b62748724c29e701c691fb304dd2bd652fd66c31" + }, + { + "git_blob": "d916056a4ae22d668ad3269ba881e4f518e982ab", + "path": "pr3611-consumer.py", + "sha256": "9c366cd26d5ce967551cdd18ecd3ff8ac9078207455dad4fbeb5b9e9678127e8" + } + ], + "whole_physical_root_or_diagonal_pass_executed": false, + "wrong_K_exponent": 0 + }, + "complete_cube_checks": [ + { + "coefficients": 4, + "common_calls_each_direction": 1, + "complete_round_comparisons": 2, + "declared_layout_K": 1, + "ell": 2, + "long_axes": [ + false + ], + "prefix_individual_sweeps_each_direction": 0, + "records": 2 + }, + { + "coefficients": 4, + "common_calls_each_direction": 1, + "complete_round_comparisons": 4, + "declared_layout_K": 1, + "ell": 2, + "long_axes": [ + true + ], + "prefix_individual_sweeps_each_direction": 1, + "records": 4 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 4, + "declared_layout_K": 1, + "ell": 3, + "long_axes": [ + false, + false + ], + "prefix_individual_sweeps_each_direction": 0, + "records": 16 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 6, + "declared_layout_K": 1, + "ell": 3, + "long_axes": [ + true, + false + ], + "prefix_individual_sweeps_each_direction": 1, + "records": 32 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 6, + "declared_layout_K": 1, + "ell": 3, + "long_axes": [ + true, + true + ], + "prefix_individual_sweeps_each_direction": 2, + "records": 64 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 4, + "declared_layout_K": 1, + "ell": 3, + "long_axes": [ + false, + false, + false + ], + "prefix_individual_sweeps_each_direction": 0, + "records": 64 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 6, + "declared_layout_K": 1, + "ell": 3, + "long_axes": [ + true, + false, + true + ], + "prefix_individual_sweeps_each_direction": 2, + "records": 256 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 4, + "declared_layout_K": 2, + "ell": 3, + "long_axes": [ + false, + false, + false, + false + ], + "prefix_individual_sweeps_each_direction": 0, + "records": 256 + }, + { + "coefficients": 8, + "common_calls_each_direction": 2, + "complete_round_comparisons": 6, + "declared_layout_K": 2, + "ell": 3, + "long_axes": [ + true, + false, + false, + false + ], + "prefix_individual_sweeps_each_direction": 1, + "records": 512 + }, + { + "coefficients": 16, + "common_calls_each_direction": 2, + "complete_round_comparisons": 8, + "declared_layout_K": 2, + "ell": 4, + "long_axes": [ + true, + false + ], + "prefix_individual_sweeps_each_direction": 3, + "records": 128 + } + ], + "controls": { + "concealed_extent_witness_address": 2, + "correct_value": [ + 0, + 0 + ], + "old_extent_bits": 6, + "rejected_failures": [ + "old chunk extent", + "concealed extent wrong tensor", + "old inverse layout", + "wrong offset", + "inverse round order", + "floor rounding", + "short signed format" + ], + "wrong_active_extent_bits": 3, + "wrong_value": [ + 1, + 0 + ] + }, + "floor_and_cost": { + "exact_K_saving": "169711/2000000000000", + "minimum_nontrivial_ell_lower_bound": 45812984491, + "new_layer_saving": "172899/4000000000", + "source_band_integer_checks": 2, + "thresholds": [ + { + "actual_new_offset": 5, + "actual_old_offset": 2, + "k": 2, + "new_threshold_bits": 20001, + "new_threshold_sha256": "0dfbab6dd9ffdd166ed4994eae02363c15807d70a2e5e9d6db1fc6d637caec8b", + "old_threshold_bits": 20001, + "old_threshold_sha256": "342a7e342b408f77e95eb8f239e764dd57d826a00418b3e4d63ab2cb39c65332" + }, + { + "actual_new_offset": 2, + "actual_old_offset": 3, + "k": 3, + "new_threshold_bits": 31700, + "new_threshold_sha256": "ccaa4d32b22b65aed640b1b2015de0f78d27ac4dffe0527aa42fb8e20fa6a8a8", + "old_threshold_bits": 31700, + "old_threshold_sha256": "b659e14e99d8ddf18bdcefc2776775602174630bd9f8250b9b2123debb763270" + } + ] + }, + "scope": "source-relative matched outer layout; bounded arithmetic and two actual single-packet joins" +} diff --git a/research/twiddle-matched-layer/SOURCES.json b/research/twiddle-matched-layer/SOURCES.json new file mode 100644 index 0000000000..fd2e876ae5 --- /dev/null +++ b/research/twiddle-matched-layer/SOURCES.json @@ -0,0 +1,193 @@ +{ + "schema_version": 1, + "base_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "b1fea0c94436b236cc2b7d41a7be032811b94c81", + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "67f085acd86acd7d4e03922d9cf4b26bca66fed5", + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0" + }, + { + "path": "research/twiddle-matched-layer/LICENSE", + "usage": "input", + "git_blob": "261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64", + "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/LICENSE" + }, + { + "path": "research/twiddle-matched-layer/NOTICE", + "usage": "input", + "git_blob": "59d8e0cf3102e15bd11db430838365531e2d7f18", + "sha256": "b49022cb4104d90b182e4c335f670faf45529025b15db77bf0291835083c28bd", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/NOTICE" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/PROOF.md", + "usage": "input", + "git_blob": "d06188b031ba29b33b8db4a1282a4ba84dfcbb78", + "sha256": "9510fbdf21eff20e75adfbc6f882541d926b721e9207f4a3697973a58fae66ec", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/README.md", + "usage": "input", + "git_blob": "f9547323c2812517b7b1f84c7f6d765ff586c98b", + "sha256": "bbbac07cc04d8460203ad9b99a9d1d3571aedf3816beed44166a98475fb08ee1", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/README.md" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/RESULT.json", + "usage": "input", + "git_blob": "5cd8d375ea8a3b599ff8f6df2d2abb9f72a228ca", + "sha256": "dfbb3875e20658760e01d42ecca0fef2b27f95d926f1ea93a716ffd7a9d0910a", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/RESULT.json" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/SOURCES.json", + "usage": "input", + "git_blob": "4388f45edf77f542a5ea3dc5d96d7edd7f6453c9", + "sha256": "cf594b115e2468430e9324f4f9fafcdef09f53db254070acee336225e611e5af", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/SOURCES.json" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/TASK.json", + "usage": "input", + "git_blob": "cc28886d898a785dbd42ad23661255a6456d051f", + "sha256": "20d398f587a92111509cbcc166e53690bf893440e1db951d523b7994d5da0ce6", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/TASK.json" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/VERIFY.json", + "usage": "input", + "git_blob": "e6787718411f8ba37fa502a9c0b239b020f8c816", + "sha256": "add3a15209fd6772a2a8542b0f1f56dca51f50bc60a9495008d50bd9c599fc10", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/VERIFY.json" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/inputs/consumer-PROOF.md", + "usage": "input", + "git_blob": "ecc93eb027ffbbed1561185750d7917db9b90e1d", + "sha256": "c2d510485286d03f449f49da632b3a032f9c07781bc64ded023889121e14a1ef", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/inputs/consumer-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/inputs/consumer.py", + "usage": "input", + "git_blob": "d916056a4ae22d668ad3269ba881e4f518e982ab", + "sha256": "9c366cd26d5ce967551cdd18ecd3ff8ac9078207455dad4fbeb5b9e9678127e8", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/inputs/consumer.py" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/inputs/controller-PROOF.md", + "usage": "input", + "git_blob": "bb215a4bbde0857bc96f03827b7f0a6c6c7c7911", + "sha256": "cd3f5b4d1ebbabb3f185c13fa56c9c4391f236472594fdafbb6db35e8ba91f8a", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/inputs/controller-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/inputs/controller.py", + "usage": "input", + "git_blob": "2e72164d9429baeb1b18621f6f4b9576dbcc60a4", + "sha256": "680146c712a9d547cd5b2b28b62748724c29e701c691fb304dd2bd652fd66c31", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/inputs/controller.py" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/pass.py", + "usage": "input", + "git_blob": "569aa79350ebde9d7df0b166d98b9f3eecf2df31", + "sha256": "7380a64128fdc416d3a8fce17c5fa43a6775d9dc0e71bdf62fbca46b6339ab45", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/pass.py" + }, + { + "path": "research/twiddle-matched-layer/diagonal/upstream/verify.py", + "usage": "input", + "git_blob": "50bda4b5c01b4f3d4ae74aa42ba77970e0189d02", + "sha256": "852931a48a21340e09455136e645e331266e98a6ddbc1dd4245efdc5b279597b", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/diagonal/upstream/verify.py" + }, + { + "path": "research/twiddle-matched-layer/pr2298-PROOF.md", + "usage": "input", + "git_blob": "f26af67ae1ee4d9886d4e4b28d5332994f492bc2", + "sha256": "4afeb1708cf9568a9cd25afc72b159d5b06d151a6a6aba567a50970b38a1f513", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr2298-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/pr3493-PROOF.md", + "usage": "input", + "git_blob": "67204b2fcdd21a5a11a6421738b294eac09feb75", + "sha256": "a74c30e25ad5e3aa9c7c2139ec3856fd0c94bfcccf166172e2aae58515ed9708", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3493-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/pr3493-outer_layer.py", + "usage": "input", + "git_blob": "2fc3370ea7e1b32be27faa4ec726ad7732af6769", + "sha256": "3e6bae42f4e6239d0a467fb0498da3906fc139672fae96211c835be3b5fef307", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3493-outer_layer.py" + }, + { + "path": "research/twiddle-matched-layer/pr3593-PROOF.md", + "usage": "input", + "git_blob": "bb215a4bbde0857bc96f03827b7f0a6c6c7c7911", + "sha256": "cd3f5b4d1ebbabb3f185c13fa56c9c4391f236472594fdafbb6db35e8ba91f8a", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3593-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/pr3593-controller.py", + "usage": "input", + "git_blob": "2e72164d9429baeb1b18621f6f4b9576dbcc60a4", + "sha256": "680146c712a9d547cd5b2b28b62748724c29e701c691fb304dd2bd652fd66c31", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3593-controller.py" + }, + { + "path": "research/twiddle-matched-layer/pr3599-PROOF.md", + "usage": "input", + "git_blob": "728ff53e7217e34b463cfcf86cc81624ea9b1dd2", + "sha256": "59da2c3223501da8228fb064201be81a809d4c3da19788692dbd5f5705fe016f", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3599-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/pr3599-active_plan.py", + "usage": "input", + "git_blob": "c3a01cd8c4f52cab478aefacad60f64f60f1453a", + "sha256": "e1092fdbb70df43f1d4fdb50f39a07a543d71c4ea9f9e8a50b790b81fd50223e", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3599-active_plan.py" + }, + { + "path": "research/twiddle-matched-layer/pr3599-active_root.py", + "usage": "input", + "git_blob": "8f63fc094432692b7fd81aad14d937320fda4354", + "sha256": "5496bfeea5955b8b70f380e39461198a121ebc0ce8ad0aa1d0e58a9f3035ebd7", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3599-active_root.py" + }, + { + "path": "research/twiddle-matched-layer/pr3611-PROOF.md", + "usage": "input", + "git_blob": "ecc93eb027ffbbed1561185750d7917db9b90e1d", + "sha256": "c2d510485286d03f449f49da632b3a032f9c07781bc64ded023889121e14a1ef", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3611-PROOF.md" + }, + { + "path": "research/twiddle-matched-layer/pr3611-consumer.py", + "usage": "input", + "git_blob": "d916056a4ae22d668ad3269ba881e4f518e982ab", + "sha256": "9c366cd26d5ce967551cdd18ecd3ff8ac9078207455dad4fbeb5b9e9678127e8", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/pr3611-consumer.py" + }, + { + "path": "research/twiddle-matched-layer/transforms.tex", + "usage": "input", + "git_blob": "de073e9292d58573f7065a3cd4f214e0d05f3444", + "sha256": "924316e4bc905066281d8f9e8746a49d8829aeb393688608deb1e61c3c87853c", + "pin": "head:a71efb6cfb2a53df145e207ddccc63815c4aabb8:research/twiddle-matched-layer/transforms.tex" + } + ] +} diff --git a/research/twiddle-matched-layer/SOURCE_INVENTORY.json b/research/twiddle-matched-layer/SOURCE_INVENTORY.json new file mode 100644 index 0000000000..9fdf974bbe --- /dev/null +++ b/research/twiddle-matched-layer/SOURCE_INVENTORY.json @@ -0,0 +1,142 @@ +{ + "canonical_main": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "claim": "https://github.com/CrocSwap/integer-mult-bounds/discussions/2612#discussioncomment-19015428", + "executed_sources": [ + "pr3593-controller.py", + "pr3611-consumer.py" + ], + "license_note": "Retain canonical Apache-2.0 LICENSE/NOTICE and original file credit. No original code is edited.", + "scientific_sources": [ + { + "bytes": 33854, + "credit": "retained source transform and positional schedule", + "git_blob": "de073e9292d58573f7065a3cd4f214e0d05f3444", + "local_path": "transforms.tex", + "origin_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "origin_path": "upstream/build/sections/06-transforms.tex", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "924316e4bc905066281d8f9e8746a49d8829aeb393688608deb1e61c3c87853c" + }, + { + "bytes": 18754, + "credit": "Jose Manuel / jmbarrancoml, PR2298", + "git_blob": "f26af67ae1ee4d9886d4e4b28d5332994f492bc2", + "local_path": "pr2298-PROOF.md", + "origin_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "origin_path": "research/selected-conservative-outer/PROOF.md", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "4afeb1708cf9568a9cd25afc72b159d5b06d151a6a6aba567a50970b38a1f513" + }, + { + "bytes": 9227, + "credit": "Nick Petalas; retains Jose Manuel's T74/outer premises", + "git_blob": "67204b2fcdd21a5a11a6421738b294eac09feb75", + "local_path": "pr3493-PROOF.md", + "origin_commit": "c0ee30f63a89c3bd0eabb3ea7eaa7786d5ad707f", + "origin_path": "research/t74-outer-format-plan/PROOF.md", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "a74c30e25ad5e3aa9c7c2139ec3856fd0c94bfcccf166172e2aae58515ed9708" + }, + { + "bytes": 2215, + "credit": "Nick Petalas, actual complete-format wrapper", + "git_blob": "2fc3370ea7e1b32be27faa4ec726ad7732af6769", + "local_path": "pr3493-outer_layer.py", + "origin_commit": "c0ee30f63a89c3bd0eabb3ea7eaa7786d5ad707f", + "origin_path": "research/t74-outer-format-plan/outer_layer.py", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "3e6bae42f4e6239d0a467fb0498da3906fc139672fae96211c835be3b5fef307" + }, + { + "bytes": 14261, + "credit": "Jose Manuel / jmbarrancoml; credits Hiroki Kumazaki's factory/rate and retained lineage", + "git_blob": "728ff53e7217e34b463cfcf86cc81624ea9b1dd2", + "local_path": "pr3599-PROOF.md", + "origin_commit": "72df81b8cee17ffd990fc18b2d54024f65971556", + "origin_path": "research/t74-retuned-physical-layer/PROOF.md", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "59da2c3223501da8228fb064201be81a809d4c3da19788692dbd5f5705fe016f" + }, + { + "bytes": 5202, + "credit": "Jose Manuel, actual-width encoded plan", + "git_blob": "c3a01cd8c4f52cab478aefacad60f64f60f1453a", + "local_path": "pr3599-active_plan.py", + "origin_commit": "72df81b8cee17ffd990fc18b2d54024f65971556", + "origin_path": "research/t74-retuned-physical-layer/active_plan.py", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "e1092fdbb70df43f1d4fdb50f39a07a543d71c4ea9f9e8a50b790b81fd50223e" + }, + { + "bytes": 1424, + "credit": "Jose Manuel, actual-width root constructor", + "git_blob": "8f63fc094432692b7fd81aad14d937320fda4354", + "local_path": "pr3599-active_root.py", + "origin_commit": "72df81b8cee17ffd990fc18b2d54024f65971556", + "origin_path": "research/t74-retuned-physical-layer/active_root.py", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "5496bfeea5955b8b70f380e39461198a121ebc0ce8ad0aa1d0e58a9f3035ebd7" + }, + { + "bytes": 13592, + "credit": "Nick Petalas, encoded header producer", + "git_blob": "bb215a4bbde0857bc96f03827b7f0a6c6c7c7911", + "local_path": "pr3593-PROOF.md", + "origin_commit": "46c04613a19a5b7bd50d98e50bbc8ea8dc6275b0", + "origin_path": "research/encoded-twiddle-controller/PROOF.md", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "cd3f5b4d1ebbabb3f185c13fa56c9c4391f236472594fdafbb6db35e8ba91f8a" + }, + { + "bytes": 18756, + "credit": "Nick Petalas, unchanged executable header producer", + "git_blob": "2e72164d9429baeb1b18621f6f4b9576dbcc60a4", + "local_path": "pr3593-controller.py", + "origin_commit": "46c04613a19a5b7bd50d98e50bbc8ea8dc6275b0", + "origin_path": "research/encoded-twiddle-controller/controller.py", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "680146c712a9d547cd5b2b28b62748724c29e701c691fb304dd2bd652fd66c31" + }, + { + "bytes": 16790, + "credit": "Sagar Thakrar, encoded packet consumer", + "git_blob": "ecc93eb027ffbbed1561185750d7917db9b90e1d", + "local_path": "pr3611-PROOF.md", + "origin_commit": "c21172062a2d907804538aa5a74012a2a4cc144e", + "origin_path": "research/encoded-twiddle-packet-consumer/PROOF.md", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "c2d510485286d03f449f49da632b3a032f9c07781bc64ded023889121e14a1ef" + }, + { + "bytes": 13620, + "credit": "Sagar Thakrar, unchanged executable signed packet consumer", + "git_blob": "d916056a4ae22d668ad3269ba881e4f518e982ab", + "local_path": "pr3611-consumer.py", + "origin_commit": "c21172062a2d907804538aa5a74012a2a4cc144e", + "origin_path": "research/encoded-twiddle-packet-consumer/consumer.py", + "retention": "unchanged public source; all-size/physical theorem remains an inherited premise", + "sha256": "9c366cd26d5ce967551cdd18ecd3ff8ac9078207455dad4fbeb5b9e9678127e8" + }, + { + "bytes": 11357, + "credit": "CrocSwap/integer-mult-bounds retained licence and source notices", + "git_blob": "261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64", + "local_path": "LICENSE", + "origin_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "origin_path": "LICENSE", + "retention": "unchanged documentary attribution input", + "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4" + }, + { + "bytes": 24973, + "credit": "CrocSwap/integer-mult-bounds retained licence and source notices", + "git_blob": "59d8e0cf3102e15bd11db430838365531e2d7f18", + "local_path": "NOTICE", + "origin_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "origin_path": "NOTICE", + "retention": "unchanged documentary attribution input", + "sha256": "b49022cb4104d90b182e4c335f670faf45529025b15db77bf0291835083c28bd" + } + ], + "scope": "Proof/source audit plus new bounded checks; not closure of or replay of the physical T74 native/ordinary backend." +} diff --git a/research/twiddle-matched-layer/TASK.json b/research/twiddle-matched-layer/TASK.json new file mode 100644 index 0000000000..541d4ed784 --- /dev/null +++ b/research/twiddle-matched-layer/TASK.json @@ -0,0 +1,293 @@ +{ + "schema_version": 1, + "task_id": "uniform-transfer-audit", + "priority_revision": 6, + "base_commit": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "original_card": { + "id": "uniform-transfer-audit", + "question": "Can one exact all-size/compiler, precision, hosting or restoration implication be proved or falsified?", + "starting_points": [ + "certificates/selected-result.json", + "docs/audit.md" + ], + "methods": [ + "Prove one missing implication with explicit quantified hypotheses.", + "Find an exact counterexample at the claimed interface boundary." + ], + "acceptance_gate": "Identify the proposition and what would change downstream; do not equate a finite replay with a universal proof.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read the selected review scope and choose one exact all-size or precision implication.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "Write its quantified inputs and conclusion; find a missing hypothesis or construct a minimal exact adversarial instance.", + "bottleneck_link": "Finite supplier improvements are useful only under the retained transfer obligations.", + "allowed_variations": [ + "Choose one tape, precision, hosting or restoration lemma." + ], + "scope_change_triggers": [ + "Replacing a quantified obligation with another finite smoke test." + ], + "overlap_terms": [ + "uniform transfer", + "all-size", + "precision" + ] + }, + "scope_status": "changed", + "actual_scope": "Prove the exact outer-layout/actual-width-root mismatch and a matched conditional normalised-layer theorem; discharge parameter, signed-width and complete-round obligations; independently join the subsequently published PR3617 diagonal to bounded arithmetic-H rounds.", + "scope_change_reason": "The user assigned the three predecessor handoffs. This narrows uniform transfer to the PR3493/2298 actual caller and PR3599 root, complementary to the separately claimed and now completed PR3617 fixed-h diagonal. The original task card is preserved unchanged.", + "bottleneck_link": "The K_d/K_g mismatch prevents naive actual-width substitution. Repairing it, proving record-band and signed-packet admission, and incorporating a paid fixed diagonal turns the remaining full-layer root/format/reuse invoice into one precise construction obligation. The inherited outer movement bottleneck remains.", + "budget_minutes": null, + "stop_rule": "NARROW after the source-relative proof, exact counterexample and bounded validation. Continue full-layer construction only with a typed actual-width root/rounded-return interface and a complete paid layout/framing/inter-round lifecycle and simultaneous-stock contract. Preserve all source heads and the selected frontier; unknown charges are not zero.", + "outcome": "partial", + "evidence": "PROOF.md and the original RECEIPT.json establish the source-relative parameter/layout/round theorem and 50 exact small completed-round comparisons plus two actual single-packet joins. diagonal/ADDENDUM.md and its separate RECEIPT.json retain PR3617 and execute 12 positive completed arithmetic-H rounds, 384 actual diagonal packets and 4096 Gaussian comparisons. Normal and optimized Git-free replays and actual source-byte/typed-receipt CLI rejection controls pass in independent same-session review. Publication and hosted evidence are recorded separately after execution.", + "author": "Clear1nsight", + "ai_assistance": "Substantial OpenAI assistance from a root agent and three concurrent specialists in mathematical derivation, source audit, exact implementation, and independent same-session cross-review. No independent human acceptance, formal-kernel proof, or OpenAI endorsement is claimed.", + "open_questions": [ + { + "question": "Can a correctly typed active-width outer wrapper physically implement the matched H/root and rounded return on the same complete array?", + "why_it_matters": "The former wrapper dimension-exponent guard and K law cannot be silently reused; the diagonal is now available, while H and Q_p remain unpriced arithmetic oracles here.", + "first_step": "Bind K=floor((d-1)^(1/500)), exact extent and record order, selected-bit offset, MSB/LSB component bridge, unit-disk admission, and one final Q_p after the complete H; price all layout and conversion.", + "blocked_by": "Physical actual-width wrapper, inherited native/compiler implementation and rounded-return/format contract are not supplied by this package." + }, + { + "question": "Can the whole layer reuse a fixed collection of full-cube and packet tapes with the required complete Q bill?", + "why_it_matters": "PR3617 supplies a one-shot fixed-h pass with 38 roles including both complete streams; packet reuse does not prove reuse across all rounds.", + "first_step": "Specify descriptor changes, previous-output consumption/reset, framing/extraction/assembly, private cleanup, borrowed restoration, canonical head returns, and an exact simultaneous buffer/role ledger; prove Q<=C M R(rw+A+p^3)+poly(p).", + "blocked_by": "Inter-round allocation/reset, initial framing/layout and complete stock are unimplemented; the finite checker uses fresh admitted stage instances." + }, + { + "question": "Can a paid change improve the retained outer movement bottleneck while preserving all transfer obligations?", + "why_it_matters": "The matched K has the same asymptotic order and does not change the narrower 169711/2000000000000 movement saving or selected integer exponent.", + "first_step": "Give a separately priced movement/consumer change with matching endpoints, then retain truncation, spectators, recursive precision/error, ownership and the whole multiplication invoice.", + "blocked_by": "No improved complete outer movement construction or full physical/all-size supplier admission is established." + } + ], + "budget_note": "The user explicitly removed the 60-minute cap. This result remains bounded to the assigned three-route comparison and its independently reviewable interfaces.", + "claim_url": "https://github.com/CrocSwap/integer-mult-bounds/discussions/2612#discussioncomment-19015428", + "selection": { + "mode": "User-assigned continuation, no reroll", + "original_card_preserved": true, + "task_picker": "python3 -B scripts/choose_research_task.py --task uniform-transfer-audit", + "claim_expiry_utc": "2026-10-18T11:30:00Z" + }, + "family_decision": { + "decision": "narrow", + "gate": "docs/research/research-family-status.md at main 20ecf289", + "positive_local_result": "Exact layout repair, parameter and complete-round proof, plus actual newly supplied diagonal corroboration", + "unknown": "Physical actual-width root and rounding, full-layer format/layout, all-round reuse and simultaneous stock, complete invoice and all-size transfer", + "selected_frontier_changed": false + }, + "checkpoints": [ + { + "canonical_main": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "canonical_fetch_utc": "2026-10-18T09:12:00Z", + "fetch_time_precision": "minute from session transcript", + "priority_revision": 6, + "scope": "User-assigned research, proof and validation of the three prior handoff routes; no reroll.", + "pins": { + "AGENTS.md": { + "sha256": "eb25d8ec495b80190a4b1a634710819bb74f0fae88d5203285c2b75b6f147347", + "bytes": 5580 + }, + "autoresearch.md": { + "sha256": "8c98d179208c34a8c6768931e13f3bbeaa1cb63d59c660799ffde05c40935d9b", + "bytes": 5298 + }, + "CONTRIBUTING.md": { + "sha256": "8a49fe97e2ad088a2b2e0c5b222aaab08752783b1f9c1260790d7dd13011d215", + "bytes": 7143 + }, + "docs/research/current-priorities.md": { + "sha256": "c95e09baa997b48ba00a26ea29168e782b17392d28184ecb7a17eea5472dd77c", + "bytes": 11358 + }, + "docs/research/agent-task-catalog.json": { + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0", + "bytes": 58553 + }, + "docs/research/agent-procedure.md": { + "sha256": "b2dd2f64e5746fce6289422351f2e3d1eb224f7db09aeb72f4d6626263190aa1", + "bytes": 27753 + }, + "docs/research/research-family-status.md": { + "sha256": "9b98ab42364e90588e90410fd2773f9bc4bf5050f514101bed0a0246881b5b7e", + "bytes": 14284 + }, + "certificates/selected-result.json": { + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129", + "bytes": 10725 + } + }, + "live_open_PR_coverage": { + "records": 330, + "pages": [ + 100, + 100, + 100, + 30 + ], + "collection_interval_UTC": "09:16 to 09:22", + "non_atomic": true, + "coverage": "All open PR metadata and bodies searched for relevant terms; targeted full source reads. Not all diffs or closed PRs." + }, + "discussion_coverage": { + "threads": [ + 1163, + 1166, + 1167, + 2750, + 2612 + ], + "mode": "Fresh loaded bodies and current visible comments; no all-thread/reply pagination.", + "material_overlap": "Sagar Thakrar fixed-h diagonal-pass implementation19015185. Our route3 claim19015428 explicitly excludes that implementation." + }, + "claims": { + "p104": "https://github.com/CrocSwap/integer-mult-bounds/discussions/2750#discussioncomment-19015413", + "layer": "https://github.com/CrocSwap/integer-mult-bounds/discussions/2612#discussioncomment-19015428" + }, + "orientation_baseline": { + "status": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "method": "Ran in preserved canonical-recovered worktree after verifying selected record and both baseline scripts byte-identical to current main. Initial new sparse-worktree attempt lacked selected ASSEMBLY; no omitted input was treated as passing.", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129", + "full_selected_replay": false + }, + "source_binding_environment": "GIT_NO_REPLACE_OBJECTS=1 for new Git source reads, following pending PR3615 finding; no shared-tool or replacement-ref modification." + }, + { + "kind": "pre-submission", + "canonical_main": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "checked_utc": "2026-10-18T09:58:08.977968+00:00", + "priority_revision": 6, + "guide_and_frontier_comparison": { + "AGENTS.md": { + "sha256": "eb25d8ec495b80190a4b1a634710819bb74f0fae88d5203285c2b75b6f147347", + "bytes": 5580, + "unchanged": true + }, + "autoresearch.md": { + "sha256": "8c98d179208c34a8c6768931e13f3bbeaa1cb63d59c660799ffde05c40935d9b", + "bytes": 5298, + "unchanged": true + }, + "CONTRIBUTING.md": { + "sha256": "8a49fe97e2ad088a2b2e0c5b222aaab08752783b1f9c1260790d7dd13011d215", + "bytes": 7143, + "unchanged": true + }, + "docs/research/current-priorities.md": { + "sha256": "c95e09baa997b48ba00a26ea29168e782b17392d28184ecb7a17eea5472dd77c", + "bytes": 11358, + "unchanged": true + }, + "docs/research/agent-task-catalog.json": { + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0", + "bytes": 58553, + "unchanged": true + }, + "docs/research/agent-procedure.md": { + "sha256": "b2dd2f64e5746fce6289422351f2e3d1eb224f7db09aeb72f4d6626263190aa1", + "bytes": 27753, + "unchanged": true + }, + "docs/research/research-family-status.md": { + "sha256": "9b98ab42364e90588e90410fd2773f9bc4bf5050f514101bed0a0246881b5b7e", + "bytes": 14284, + "unchanged": true + }, + "certificates/selected-result.json": { + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129", + "bytes": 10725, + "unchanged": true + } + }, + "decision": "continue two scoped contributions; canonical main and all checked guides/frontier unchanged; preserve all frozen science inputs", + "live_overlap_refresh": { + "api_coverage": "First100 all-state PRs sorted by updated descending reached06:53:20, covering all eight records updated since09:16; exact-source reads for relevant predecessors.", + "api_checked_through_utc": "2026-10-18T09:58:08Z", + "discussion_checked_utc": "2026-10-18T09:59:00Z", + "discussion_time_precision": "minute from session transcript", + "p104": "Fresh2750 loaded lastfive top-level claim/result bodies; our19015413 has0replies. No new same-scope P104 result.", + "layer": "Fresh2612 includes PR3617 DONE4bf091f415d6470b60a5062a08b0a47e5b12dbd7 and author handoff reply19015775 to ourclaim. Preserve frozen layer proof and assess successor separately.", + "new_adjacent": "PR3619 complete encoded support router, PR3618 flag9local correction and PR3604 P112 audit have distinct scopes.", + "limitations": "No exhaustive closed-PR/diff or all-Discussion pagination; time-window API metadata snapshot is non-atomic." + } + }, + { + "kind": "layer-pre-submission", + "canonical_main": "20ecf2891d80b5acf18d980b2164fb44ea7faa90", + "checked_utc": "2026-10-18T10:26:11.806821+00:00", + "priority_revision": 6, + "canonical_fetch": "git fetch --no-tags https://github.com/CrocSwap/integer-mult-bounds.git main; successful fresh approved network execution", + "guide_and_frontier_comparison": { + "AGENTS.md": { + "sha256": "eb25d8ec495b80190a4b1a634710819bb74f0fae88d5203285c2b75b6f147347", + "bytes": 5580, + "unchanged": true + }, + "autoresearch.md": { + "sha256": "8c98d179208c34a8c6768931e13f3bbeaa1cb63d59c660799ffde05c40935d9b", + "bytes": 5298, + "unchanged": true + }, + "CONTRIBUTING.md": { + "sha256": "8a49fe97e2ad088a2b2e0c5b222aaab08752783b1f9c1260790d7dd13011d215", + "bytes": 7143, + "unchanged": true + }, + "docs/research/current-priorities.md": { + "sha256": "c95e09baa997b48ba00a26ea29168e782b17392d28184ecb7a17eea5472dd77c", + "bytes": 11358, + "unchanged": true + }, + "docs/research/agent-task-catalog.json": { + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0", + "bytes": 58553, + "unchanged": true + }, + "docs/research/agent-procedure.md": { + "sha256": "b2dd2f64e5746fce6289422351f2e3d1eb224f7db09aeb72f4d6626263190aa1", + "bytes": 27753, + "unchanged": true + }, + "docs/research/research-family-status.md": { + "sha256": "9b98ab42364e90588e90410fd2773f9bc4bf5050f514101bed0a0246881b5b7e", + "bytes": 14284, + "unchanged": true + }, + "certificates/selected-result.json": { + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129", + "bytes": 10725, + "unchanged": true + } + }, + "decision": "continue complementary matched-layer proof and PR3617 addendum; preserve all frozen scientific inputs and source heads", + "live_overlap_refresh": { + "api_checked_through_utc": "2026-10-18T10:24:15Z", + "api_coverage": "First 100 all-state PRs sorted updated descend to07:00:47, covering all six records updated since09:58:08; exact requested four predecessor heads/bodies unchanged.", + "new_adjacent": "PR3621 fixed-word P104 full-row forcing census; PR3620 is this session P104 result; other updated bodies have distinct scopes.", + "layer": "Fresh2612 current claim19015428 retains sole author handoff reply19015775 to unchanged PR3617; no further reply.", + "p104": "Fresh2750 current claim19015413 has zero replies; earlier claims preserved.", + "limitations": "Metadata/body windows are non-atomic; no exhaustive closed/diff/all-Discussion or unpublished-work coverage.", + "discussions_observed_before_utc": "2026-10-18T10:26:11.806821+00:00", + "discussion_observation_window": "After the fresh10:24 API checkpoint and before this saved checkpoint; no exact browser timestamp claimed." + } + } + ], + "source_retention": { + "own_ancestor": "a71efb6cfb2a53df145e207ddccc63815c4aabb8", + "retained_files": 25, + "original_origin_records": [ + "SOURCE_INVENTORY.json", + "diagonal/SOURCE_INVENTORY.json" + ], + "scientific_freezes": "The original 17 scientific component files and the 16-file later addendum are preserved in separate scratch freezes. Publication changes only the addendum reproduction path to fit its new diagonal subdirectory; predecessor bytes, code and receipts stay unchanged." + }, + "metadata_frozen_at_utc": "2026-10-18T10:28:27.488080+00:00" +} diff --git a/research/twiddle-matched-layer/VERIFY.json b/research/twiddle-matched-layer/VERIFY.json new file mode 100644 index 0000000000..a767bc037c --- /dev/null +++ b/research/twiddle-matched-layer/VERIFY.json @@ -0,0 +1,82 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/twiddle-matched-layer/LICENSE", + "research/twiddle-matched-layer/NOTICE", + "research/twiddle-matched-layer/diagonal/upstream/PROOF.md", + "research/twiddle-matched-layer/diagonal/upstream/README.md", + "research/twiddle-matched-layer/diagonal/upstream/RESULT.json", + "research/twiddle-matched-layer/diagonal/upstream/SOURCES.json", + "research/twiddle-matched-layer/diagonal/upstream/TASK.json", + "research/twiddle-matched-layer/diagonal/upstream/VERIFY.json", + "research/twiddle-matched-layer/diagonal/upstream/inputs/consumer-PROOF.md", + "research/twiddle-matched-layer/diagonal/upstream/inputs/consumer.py", + "research/twiddle-matched-layer/diagonal/upstream/inputs/controller-PROOF.md", + "research/twiddle-matched-layer/diagonal/upstream/inputs/controller.py", + "research/twiddle-matched-layer/diagonal/upstream/pass.py", + "research/twiddle-matched-layer/diagonal/upstream/verify.py", + "research/twiddle-matched-layer/pr2298-PROOF.md", + "research/twiddle-matched-layer/pr3493-PROOF.md", + "research/twiddle-matched-layer/pr3493-outer_layer.py", + "research/twiddle-matched-layer/pr3593-PROOF.md", + "research/twiddle-matched-layer/pr3593-controller.py", + "research/twiddle-matched-layer/pr3599-PROOF.md", + "research/twiddle-matched-layer/pr3599-active_plan.py", + "research/twiddle-matched-layer/pr3599-active_root.py", + "research/twiddle-matched-layer/pr3611-PROOF.md", + "research/twiddle-matched-layer/pr3611-consumer.py", + "research/twiddle-matched-layer/transforms.tex" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-Werror", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Authenticate 13 retained source inputs and the typed original receipt; exact boundary, layout, round, rounding, width and actual single-packet checks. No physical H/root or whole-layer invoice." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-Werror", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Authenticate 13 retained source inputs and the typed original receipt; exact boundary, layout, round, rounding, width and actual single-packet checks. No physical H/root or whole-layer invoice. All explicit guards remain active under optimization." + }, + { + "argv": [ + "{python}", + "-I", + "-Werror", + "-B", + "{package}/diagonal/verify.py" + ], + "timeout_seconds": 120, + "checks": "Authenticate 12 PR3617 files, the source inventory, the frozen arithmetic checker and the strict typed receipt; 12 complete arithmetic-H rounds with 384 actual diagonal packets, wrong-K, off-grid, one-shot and tape-lifecycle controls. No all-round allocation/reuse theorem." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-Werror", + "-B", + "{package}/diagonal/verify.py" + ], + "timeout_seconds": 120, + "checks": "Authenticate 12 PR3617 files, the source inventory, the frozen arithmetic checker and the strict typed receipt; 12 complete arithmetic-H rounds with 384 actual diagonal packets, wrong-K, off-grid, one-shot and tape-lifecycle controls. No all-round allocation/reuse theorem. All explicit guards remain active under optimization." + } + ], + "execution_boundary": "Standard-library bounded checks. Original two header/consumer modules and later unchanged PR3617 fixed diagonal execute. H, Q_p, layout and host serialization are arithmetic oracles. No historical full source suite, production physical root, full-layer reuse/stock, complete invoice, independent human/formal acceptance or supplier admission." +} diff --git a/research/twiddle-matched-layer/check_join.py b/research/twiddle-matched-layer/check_join.py new file mode 100644 index 0000000000..421ae05f08 --- /dev/null +++ b/research/twiddle-matched-layer/check_join.py @@ -0,0 +1,388 @@ +"""Exact bounded checks for the changed outer layout; no physical root replay. + +New audit by Clear1nsight with substantial OpenAI assistance, Apache-2.0. +The two imported source modules remain byte-identical and separately credited. +""" + +from fractions import Fraction +from hashlib import sha1, sha256 +import importlib.util +import json +from pathlib import Path + +HERE = Path(__file__).resolve().parent + + +def need(condition, reason): + if not condition: + raise ValueError(reason) + + +def rejected(call, reason): + try: + call() + except ValueError as error: + need(str(error) == reason, "unexpected rejection reason: " + str(error)) + return reason + raise ValueError("missing rejection: " + reason) + + +def root_int(n, degree): + need(type(n) is int and n >= 0 and degree >= 1, "integer root domain") + if n < 2: + return n + x = 1 << ((n.bit_length() + degree - 1) // degree) + while True: + y = ((degree - 1) * x + n // pow(x, degree - 1)) // degree + if y >= x: + break + x = y + need(pow(x, degree) <= n < pow(x + 1, degree), "exact integer root") + return x + + +def integer_digest(n): + return sha256(n.to_bytes((n.bit_length() + 7) // 8 or 1, "big")).hexdigest() + + +def floors_and_cost(): + records = [] + for k in (2, 3): + d0 = pow(k, 500) + old = pow(d0, 40) + changed = pow(d0 + 1, 40) + cases = ((old - 1, k - 1, k - 1), (old, k, k - 1), + (changed - 1, k, k - 1), (changed, k, k)) + for p, expect_old, expect_new in cases: + d = root_int(p, 40) + need(root_int(d, 500) == expect_old, "old exact-K threshold") + need(root_int(d - 1, 500) == expect_new, "matched exact-K threshold") + for p, expected in ((6 * ((old + 5) // 6), k - 1), + (6 * ((changed + 5) // 6), k)): + need(p % 6 == 0, "actual precision multiple") + need(root_int(root_int(p, 40) - 1, 500) == expected, + "actual precision floor boundary") + records.append({"k": k, "old_threshold_bits": old.bit_length(), + "new_threshold_bits": changed.bit_length(), + "old_threshold_sha256": integer_digest(old), + "new_threshold_sha256": integer_digest(changed), + "actual_old_offset": (-old) % 6, + "actual_new_offset": (-changed) % 6}) + need(2 ** 39 > 12 * 41 ** 2, "record base inequality") + need(2 ** 39 * 41 ** 80 > 42 ** 80, "record monotonic ratio") + ell_min = (2 ** 39 + 11) // 12 + need(ell_min == 45812984491 and ell_min > 32, "actual caller versus executable cap") + tau = Fraction(99830289, 10 ** 8) + alpha = Fraction(99827101, 10 ** 8) + old_bottleneck = Fraction(1, 40 * 500) * (1 - tau) + new_layer_saving = (1 - alpha) / 40 + need(old_bottleneck == Fraction(169711, 2000000000000), "preserved outer ordinary bill") + need(new_layer_saving == Fraction(172899, 4000000000), "new layer exponent") + need(new_layer_saving > old_bottleneck, "outer bottleneck remains narrower") + return {"thresholds": records, "minimum_nontrivial_ell_lower_bound": ell_min, + "source_band_integer_checks": 2, + "exact_K_saving": str(old_bottleneck), "new_layer_saving": str(new_layer_saving)} + + +def slots_for(ell, flags, k): + need(ell >= 2 and flags and 1 <= k < ell, "layout domain") + original = tuple((i, h) for i, long in enumerate(flags) + for h in range(ell - (not long) - 1, -1, -1)) + b, q = (ell - 1) % k, (ell - 1) // k + prefix = [(i, ell - 1) for i, long in enumerate(flags) if long] + prefix += [(i, h) for h in range(b - 1, -1, -1) for i in range(len(flags))] + chunks = [(i, h) for j in range(q) for i in range(len(flags)) + for h in range(ell - 2 - j * k, ell - 2 - (j + 1) * k, -1)] + changed = tuple(prefix + chunks) + need(len(set(changed)) == len(original) and set(changed) == set(original), "layout bijection") + return original, changed + + +def bit_at(x, slots, named): + return (x >> (len(slots) - 1 - slots.index(named))) & 1 + + +def selected(slots, h): + return tuple(len(slots) - 1 - j for j, item in enumerate(slots) if item[1] == h) + + +def reorder(data, before, after): + need(set(before) == set(after), "permutation named domain") + output = [None] * len(data) + for x, row in enumerate(data): + y = 0 + for name in after: + y = 2 * y + bit_at(x, before, name) + output[y] = list(row) + need(all(row is not None for row in output), "complete permutation") + return output + + +def h_fast(data, bits): + result = [list(row) for row in data] + for bit in bits: + for x in range(len(result)): + if (x >> bit) & 1: + continue + y = x | (1 << bit) + left, right = result[x], result[y] + result[x] = [(a[0] + b[0], a[1] + b[1]) for a, b in zip(left, right)] + result[y] = [(a[0] - b[0], a[1] - b[1]) for a, b in zip(left, right)] + return result, 1 << len(bits) + + +def h_direct(data, bits): + """Independent explicit tensor matrix, before its 2^g denominator.""" + mask = sum(1 << bit for bit in bits) + result = [] + for x in range(len(data)): + row = [(0, 0) for _ in data[0]] + for choice in range(1 << len(bits)): + y = x & ~mask + for j, bit in enumerate(bits): + y |= ((choice >> j) & 1) << bit + sign = -1 if ((x & y & mask).bit_count() % 2) else 1 + row = [(a[0] + sign * b[0], a[1] + sign * b[1]) + for a, b in zip(row, data[y])] + result.append(row) + return result, 1 << len(bits) + + +def truncate(data, denominator): + def part(v): + return (1 if v >= 0 else -1) * (abs(v) // denominator) + return [[(part(a), part(b)) for a, b in row] for row in data] + + +def exponent(x, slots, ell, flags, h, opposite=False): + value = 0 + for i, long in enumerate(flags): + if h >= ell - (not long): + continue + branch = bit_at(x, slots, (i, h)) + low = sum((1 << v) * bit_at(x, slots, (i, v)) for v in range(h)) + value += branch * low + return ((1 if opposite else -1) * (1 << (ell - h)) * value) % (2 << ell) + + +def rotate(row, e): + r = len(row) + output = [None] * r + for j, (a, b) in enumerate(row): + quotient, destination = divmod(j + e, r) + sign = -1 if quotient % 2 else 1 + output[destination] = (sign * a, sign * b) + return output + + +def diagonal(data, slots, ell, flags, h, opposite=False): + return [rotate(row, exponent(x, slots, ell, flags, h, opposite)) + for x, row in enumerate(data)] + + +def reference_round(data, slots, ell, flags, h, opposite=False): + if opposite: + data = diagonal(data, slots, ell, flags, h, True) + raw, denominator = h_direct(data, selected(slots, h)) + if not opposite: + raw = diagonal(raw, slots, ell, flags, h) + return truncate(raw, denominator) + + +def caller_round(data, slots, ell, flags, k, h, opposite=False): + g, a = len(flags), sum(flags) + b, q = (ell - 1) % k, (ell - 1) // k + if b <= h < ell - 1: + j, rho = (ell - 2 - h) // k, (h - b) % k + left, right = a + g * b + j * g * k, (q - j - 1) * g * k + need(left + g * k + right == len(slots), "complete root extent") + bits = tuple(right + rho + t * k for t in range(g)) + need(set(bits) == set(selected(slots, h)), "literal root selected positions") + else: + bits = selected(slots, h) + if opposite: + data = diagonal(data, slots, ell, flags, h, True) + raw, denominator = h_fast(data, bits) + result = truncate(raw, denominator) + if not opposite: + result = diagonal(result, slots, ell, flags, h) + return result + + +def cube_checks(): + cases = ((2, (False,), 1), (2, (True,), 1), + (3, (False, False), 1), (3, (True, False), 1), + (3, (True, True), 1), (3, (False, False, False), 1), + (3, (True, False, True), 1), + (3, (False, False, False, False), 2), + (3, (True, False, False, False), 2), + (4, (True, False), 2)) + results = [] + for ell, flags, k in cases: + original, physical = slots_for(ell, flags, k) + m, r = 1 << len(original), 1 << ell + cube = [[((17 * x + 5 * j + 3) % 7 - 3, (11 * x + 7 * j + 2) % 7 - 3) + for j in range(r)] for x in range(m)] + levels = list(range(ell - 2, -1, -1)) + if any(flags): + levels.insert(0, ell - 1) + b, q = (ell - 1) % k, (ell - 1) // k + need(len(levels) == ell - 1 + int(any(flags)), "complete round count") + need(sum(b <= h < ell - 1 for h in levels) == q * k, "common root invocation count") + need(sum(len(selected(original, h)) for h in levels if h < b or h == ell - 1) + == sum(flags) + len(flags) * b, "prefix singleton inventory") + checked = 0 + for opposite in (False, True): + reference = cube + actual = reorder(cube, original, physical) + for h in reversed(levels) if opposite else levels: + reference = reference_round(reference, original, ell, flags, h, opposite) + actual = caller_round(actual, physical, ell, flags, k, h, opposite) + need(actual == reorder(reference, original, physical), "complete repaired round") + need(all(a * a + b0 * b0 <= 16 ** 2 for row in actual for a, b0 in row), + "complete-round disk return for p=4") + checked += 1 + results.append({"ell": ell, "long_axes": list(flags), "declared_layout_K": k, + "records": m, "coefficients": r, "complete_round_comparisons": checked, + "common_calls_each_direction": q * k, + "prefix_individual_sweeps_each_direction": sum(flags) + len(flags) * b}) + return results + + +def controls(): + ell, flags = 3, (False, False, False) + original, old = slots_for(ell, flags, 2) + _, new = slots_for(ell, flags, 1) + a = len(original) + need(a == 6 and 3 * 1 != a, "old descriptor extent must disagree") + impulse = [[(int(x == 0 and j == 0), 0) for j in range(1 << ell)] + for x in range(1 << a)] + # Scale by eight so the final truncation cannot hide the selected-bit error. + impulse[0][0] = (8, 0) + intended, den = h_fast(impulse, (0, 2, 4)) + concealed, bad_den = h_fast(impulse, (0, 1, 2)) + intended, concealed = truncate(intended, den), truncate(concealed, bad_den) + need(intended[2][0] == (0, 0) and concealed[2][0] == (1, 0), "wrong-root endpoint witness") + need(reorder(impulse, original, new) == impulse, "impulse origin invariant") + nonconstant = [[(x + j, 0) for j in range(1 << ell)] for x in range(1 << a)] + mapped = reorder(nonconstant, original, new) + need(reorder(mapped, old, original) != nonconstant, "old inverse layout control") + bad_offset, _ = h_fast(impulse, (1, 2, 3)) + good_offset, _ = h_fast(impulse, (0, 1, 2)) + need(bad_offset != good_offset, "offset control") + # Inverse order matters even though rounding commutes with the diagonal. + small_slots, _ = slots_for(2, (True,), 1) + one = [[(0, 0)] * 4 for _ in range(4)] + one[3][0] = (4, 0) + correct = reference_round(one, small_slots, 2, (True,), 1, True) + raw, d = h_fast(one, selected(small_slots, 1)) + wrong = diagonal(truncate(raw, d), small_slots, 2, (True,), 1, True) + need(correct != wrong, "inverse round order control") + need((-1) // 2 != -(1 // 2), "floor rounding is not odd") + need(truncate([[(-1, 1)]], 2) == [[(0, 0)]], "toward-zero control") + p = 4 + need(2 ** p > 2 ** ((p + 1) - 1) - 1, "p+1 misses positive disk endpoint") + need(-(2 ** (p + 1)) < -(2 ** p), "signed minimum outside caller disk") + return {"old_extent_bits": a, "wrong_active_extent_bits": 3, + "concealed_extent_witness_address": 2, + "correct_value": [0, 0], "wrong_value": [1, 0], + "rejected_failures": ["old chunk extent", "concealed extent wrong tensor", + "old inverse layout", "wrong offset", "inverse round order", + "floor rounding", "short signed format"]} + + +def load_frozen(name, filename, expected_blob): + path = HERE / filename + data = path.read_bytes() + blob = sha1(b"blob " + str(len(data)).encode() + b"\0" + data).hexdigest() + need(blob == expected_blob, "frozen source bytes: " + filename) + spec = importlib.util.spec_from_file_location(name, path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module, {"path": filename, "git_blob": blob, "sha256": sha256(data).hexdigest()} + + +def actual_packet_boundary(): + producer, pp = load_frozen("audited_pr3593", "pr3593-controller.py", "2e72164d9429baeb1b18621f6f4b9576dbcc60a4") + consumer, cp = load_frozen("audited_pr3611", "pr3611-consumer.py", "d916056a4ae22d668ad3269ba881e4f518e982ab") + cap_controls = [rejected(lambda: producer.encode(33, 1, 0, (True,)), "bad ell"), + rejected(lambda: consumer.Consumer(33, 6), "allocation ell")] + ell, flags, k, h, p = 3, (False, False, False), 1, 1, 4 + original, physical = slots_for(ell, flags, k) + address = (1, 0, 0, 1, 0, 0) + x = int("".join(map(str, address)), 2) + r, w = 1 << ell, p + 2 + cube = [] + for index in range(1 << len(original)): + sign = -1 if bit_at(index, original, (0, h)) else 1 + cube.append([(sign * (j % 3 + 1), sign * (1 - j % 3)) for j in range(r)]) + raw, denominator = h_fast(reorder(cube, original, physical), selected(physical, h)) + complete_h = truncate(raw, denominator) + packet = complete_h[x] + need(any(a or b for a, b in packet), "nonzero complete-H packet") + before_packet = packet + receipts = [] + for opposite in (False, True): + descriptor = producer.encode(ell, k, h, flags, opposite) + ctrl = producer.Controller(descriptor, address) + ctrl.execute() + expected_e = exponent(x, physical, ell, flags, h, opposite) + actual_e = int("".join(map(str, ctrl.data["output"].cells)), 2) + need(actual_e == expected_e, "actual emitted matched-layout exponent") + prod_snapshot = ctrl.invoice() + prod_cost = (sum(sum(v.values()) for v in prod_snapshot["data"].values()) + + prod_snapshot["control_tape_actions"] + prod_snapshot["descriptor_actions"] + + sum(prod_snapshot["gates"].values())) + producer_bound = 5000 * (len(address) + ell + 1) ** 2 * (ell + k + h + len(flags) + 10) + need(prod_cost <= producer_bound, "actual producer tariff") + bits = [int(bit) for pair in packet for value in pair + for bit in format(value % (1 << w), "0%db" % w)] + source = consumer.Tape(["^"] + bits + ["$"]) + width = consumer.Tape(["^"] + ["1"] * w + ["$"]) + module = consumer.Consumer(ell, w) + borrowed = (ctrl.data["output"], ctrl.descriptor, width, source) + snapshots = [(list(t.cells), t.head) for t in borrowed] + observed_tapes = tuple(module.tapes.values()) + borrowed + counts_before = [sum(t.counts.values()) for t in observed_tapes] + result = module.run(*borrowed) + need([(list(t.cells), t.head) for t in borrowed] == snapshots, "actual borrow return") + output_bits = result.cells[1:1 + 2 * r * w] + values = [] + for j in range(0, len(output_bits), w): + v = int("".join(map(str, output_bits[j:j + w])), 2) + values.append(v - (1 << w) if v >> (w - 1) else v) + packet = list(zip(values[::2], values[1::2])) + need(packet == rotate(before_packet if not opposite else receipts[-1]["packet"], expected_e), + "actual packet endpoint") + need(all(not any(module.tapes[role].cells) and module.tapes[role].head == 0 + for role in ("prefix", "suffix", "word", "a", "b")), "actual private return") + consumer_cost = sum(module.invoice.values()) + observed_cost = sum(sum(t.counts.values()) - old for t, old in zip(observed_tapes, counts_before)) + observed_cost += sum(module.gates.values()) + need(consumer_cost == observed_cost, "independent shared-role action reconciliation") + need(consumer_cost <= 256 * (2 * r * w + ell + w + 1), "actual consumer tariff") + rearm_control = rejected(lambda: module.run(*borrowed), "one-shot consumer") + need([(list(t.cells), t.head) for t in borrowed] == snapshots, "one-shot rejection preserves borrows") + receipts.append({"opposite": opposite, "exponent": actual_e, "producer_tariff": prod_cost, + "producer_tariff_bound": producer_bound, "consumer_tariff": consumer_cost, + "consumer_actions_independently_reconciled": observed_cost, + "used_object_rejection": rearm_control, "packet": packet}) + need(packet == before_packet, "actual opposite packet return") + wrong = producer.Controller(producer.encode(ell, 2, h, flags), address) + wrong.execute() + wrong_e = int("".join(map(str, wrong.data["output"].cells)), 2) + need(wrong_e != receipts[0]["exponent"], "old-K actual header must differ") + return {"source_pins": [pp, cp], "arithmetic_H_only": True, + "whole_physical_root_or_diagonal_pass_executed": False, + "matched_layout_address": x, "wrong_K_exponent": wrong_e, "source_cap_rejections": cap_controls, + "actual_single_packet_calls": receipts} + + +def run(): + return {"scope": "source-relative matched outer layout; bounded arithmetic and two actual single-packet joins", + "floor_and_cost": floors_and_cost(), "complete_cube_checks": cube_checks(), + "controls": controls(), "actual_interface": actual_packet_boundary()} + + +if __name__ == "__main__": + print(json.dumps(run(), sort_keys=True, indent=2)) diff --git a/research/twiddle-matched-layer/diagonal/ADDENDUM.md b/research/twiddle-matched-layer/diagonal/ADDENDUM.md new file mode 100644 index 0000000000..b1273dd0b6 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/ADDENDUM.md @@ -0,0 +1,194 @@ +# Published fixed-diagonal pass joined to the matched layer + +This is a source-relative addendum to the frozen matched-width layer proof. +It incorporates Sagar Thakrar's subsequently published [PR #3617](https://github.com/CrocSwap/integer-mult-bounds/pull/3617) +at `4bf091f415d6470b60a5062a08b0a47e5b12dbd7`. The original seventeen-file +layer component remains unchanged. The new bounded check runs the unchanged +complete diagonal implementation between explicitly unpriced arithmetic +operations for the normalized butterfly, rounding, and layout. It does not +implement a physical full layer. + +## Exactly which previously conditional work is now supplied + +The published successful-return theorem assumes a complete cube already in +the specified named-slot order, matching framed inputs and capacities, +distinct physical backing storage, and representable requested signed +negations. For one fixed round `h`, it supplies all of the following: + +- Encoded full-wrap enumeration of every actual physical record address. +- The actual PR #3593 header passed to the actual PR #3611 packet consumer. +- Framed extraction and assembly of every record at its original position. +- Paid counter, header, packet and output rearming on the same physical tapes + **within that fixed diagonal pass**. +- Preservation of the borrowed full source and descriptors, complete owned + output, returned heads, and blank auxiliary data on successful completion. + +With `N = 2^A`, `r = 2^ell`, and signed width `w`, the source proves + +\[ +T_{\mathrm{diag}}=O\!\left(N(rw+A+p^3)\right). +\] + +Its 38 roles include both full streams; they are not auxiliary-only roles. +Writing `B = 2rw`, its exact capacity is + +\[ +C_{\mathrm{producer}}+2N(B+2)+4B+2w+A+3\ell+32. +\] + +Allocation and valid framed-source admission remain the source premises. +The recorded tariff includes its constructor's counter initialization, +runtime primitive actions, explicit control/data gates, and stream returns; +it is not the complete enclosing caller's preparation bill. + +The full `DiagonalPass` object is itself **one-shot**. Its successful +within-pass reuse does not establish a reusable all-round controller. + +## Conditional normalized-round composition + +Let `K = floor((d-1)^(1/500))` and use the changed named-slot layout of the +frozen proof. All nontrivial source-band premises, exceptional elementary +branches and active-root API obligations of that proof remain in force. +For a common round, use its repaired active-root extent and offset + +\[ +g=d-1,\quad n_P=a+gb+jgK,\quad +n_S=(q-j-1)gK,\quad \rho=(h-b)\bmod K, +\] + +so that `n_P + gK + n_S = A` and the selected physical bit positions are +`n_S + rho + tK`, for `0 <= t < g`. The top/bottom elementary rounds use +their named singleton positions. These descriptors concern the arithmetic +target; the unchanged active-root/outer constructor is not thereby made +API-compatible. + +Write `H_h` for the normalized tensor butterfly, `Q_p` for componentwise +truncation toward zero onto the `p`-grid, and `J_h^-`, `J_h^+` for the two +signed polynomial diagonals. The forward and opposite completed-round +targets are respectively + +\[ +J_h^- Q_p H_h,\qquad Q_p H_h J_h^+. +\] + +For the forward call, apply `Q_p` **before** encoding the source packet. +This is exact because every `J_h` is a signed coordinate permutation and +`J_h Q_p = Q_p J_h`. An unrounded off-grid `H_h` intermediate is not a +same-width signed-integer input to the packet consumer. + +Suppose the initial coefficient of each packet lies in the unit disk on +the `p`-grid. A normalized butterfly coefficient is an average of signed +input coefficients, hence still lies in that disk. Truncating the real and +imaginary components toward zero cannot increase its magnitude. A signed +polynomial rotation only permutes or negates whole Gaussian coefficients. +Induction over every forward or opposite round therefore preserves both +the disk and grid. Consequently `w = p + 2` suffices: every component +numerator has magnitude at most `2^p`, whereas the forbidden signed minimum +is `-2^(p+1)` and cannot occur. The one-packet width implication is already +credited to PR #3611; the application here is the complete-round induction. + +Under these hypotheses the new published diagonal implements the required +`J_h` on every packet. It therefore composes with a correctly supplied +`H_h/Q_p` caller. This proves the exact conditional semantic join; it does +not prove that an approximate or differently framed physical root already +has the required return contract. + +## Updated complete-round cost status + +Let `M = ell - 1 + 1_{a>0}` be the number of retained round levels in one +direction. The fixed-diagonal part over those levels is now supplied by +the published source, with summed source tariff + +\[ +O\!\left(MN(rw+A+p^3)\right). +\] + +For the actual retained long-record bands, `A = O(p)`, `w = p+2`, and +`r` eventually dominates every fixed polynomial in `p`. Thus this term is +`O(MNrp)`. With `T = Nr` and `M <= ell`, it is absorbed by the retained +layer term `O(Tp ell g^alpha log p)` when `g >= 1` and `p` is in the +nontrivial admitted range. This absorption changes constants; it is not +an unchanged exact finite tariff. The old outer exponent +`tau = 99830289/10^8` and its narrower bottleneck remain unchanged. + +The remainder of the earlier `Q` obligation still includes: + +| Required caller work | Status after this addendum | +|---|---| +| Fixed-h address traversal, packet extraction/assembly, packet reuse, head returns | Supplied by PR #3617 under its stated input and successful-return premises | +| Initial `L` placement and complete framed-input construction | Still needs the actual physical caller and bill | +| Active root or elementary butterfly, MSB/LSB bridge, and `Q_p` return | Still conditional; this check uses arithmetic oracles | +| Changes of `h`, descriptor preparation, whole-output consumption/reset, and bounded reuse across round lifetimes | Still needs an enclosing schedule; each source full pass is one-shot | +| Fixed simultaneous stock and a bounded collection of live full-cube buffers | Still an enclosing caller obligation; 38 roles per stage is not 38 roles globally | +| Truncated domains, spectators, recursive precision/error, and complete multiplication invoice | Unchanged obligations | + +The published physical support router PR #3619 is adjacent current work, +but no composition with it is asserted or executed here. + +## Bounded executable evidence + +The new checker imports the three unchanged execution bodies directly and +authenticates all twelve retained PR #3617 package files against their +published Git blob IDs, SHA-256 digests and byte lengths. The arithmetic +component is separately byte-bound to the unchanged frozen layer checker. +It does not invoke the predecessor's large six-cube replay. + +| Geometry | Actual diagonal packets in positive schedules | Completed forward/opposite round comparisons | +|---|---:|---:| +| `ell=3`, three short axes, matched `K=1` | 256 | 4 | +| `ell=4`, one long axis, `K=2`, including top and bottom elementary rounds | 128 | 8 | + +All twelve returned rounds agree with the independent explicit tensor +formula in original axis order: 4,096 Gaussian coefficient comparisons. +The local examples use `p=4`, `w=6`; they verify the local grid/width +interface, not the enormous production `p=6b` parameter domain. The old +literal executable caps and the frozen layer's production-width gap remain. + +The twelve actual diagonal executions record a combined source action +tariff of **19,566,850**, including constructor counter work. Each has +exactly 38 distinct physical roles, preserved borrowed bytes, returned +heads, blank private data, fixed capacities and no runtime tape replacement. +The two fixture families use 13,373--13,396 and 7,419--7,488 cells per stage, +respectively, including both full streams. These are stage measurements; +the arithmetic H/Q/layout and host fixture serialization are not charged. + +A further actual 64-packet pass supplies a negative control: the old +`K=2` descriptor on the matched `K=1` physical cube disagrees with the +required completed-round output at `(record, coefficient)` positions +`(48,0), (48,4), (56,0), (56,4)`. This wrong-descriptor pass costs +3,331,410 source actions and is excluded from the positive invoice. +An off-grid numerator is rejected before encoding. A second full-pass +invocation rejects with `one-shot full pass` after each stage and preserves +the returned state. + +Each positive or control pass is a **fresh admitted stage instance**. +This is a checker implementation choice, not a physical all-round +allocation or reuse construction. The result upgrades the available +fixed-diagonal endpoint and cost evidence while retaining the remaining +caller obligations in the table above. + +## Reproduce and credit + +From this packaged addendum directory, with the unchanged original checker +in its parent directory: + +```sh +python3 -I -B check_3617_join.py --layer-component ../check_join.py +python3 -I -O -B check_3617_join.py --layer-component ../check_join.py +``` + +The CLI emits a deterministic receipt. Publication must bind it with the +package's strict typed receipt and source-inventory checks; ordinary Python +JSON-value equality is not a substitute for strict type comparison. + +Sagar Thakrar supplies PR #3617's encoded fixed-diagonal pass and PR #3611's +signed packet consumer. Nick Petalas supplies PR #3593's encoded producer, +its PR #3582/#3590 lineage, and the earlier layer/interface work. The +retained transform sources supply the layout and diagonal identities. +The original matched-width proof preserves Jose Manuel's PR #2298/#3599, +Nick Petalas's PR #3493 and Hiroki Kumazaki's PR #3576 factory/rate lineage. +This addendum's bounded +caller join and obligation update were prepared for Clear1nsight with +substantial OpenAI Codex assistance. Same-session AI reviews are not +independent human acceptance or formal-kernel proof. No frontier change +or achieved multiplication exponent is claimed. diff --git a/research/twiddle-matched-layer/diagonal/RECEIPT.json b/research/twiddle-matched-layer/diagonal/RECEIPT.json new file mode 100644 index 0000000000..d9be98f570 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/RECEIPT.json @@ -0,0 +1,528 @@ +{ + "arithmetic_component_sha256": "33f91624d60be8c7124ecc24be073f8a5a3759b671979b6a17a6e26538f4355e", + "cases": [ + { + "K": 1, + "ell": 3, + "flags": [ + false, + false, + false + ], + "precision": 4, + "records": 64, + "rounds": [ + { + "all_coefficients_compared": 512, + "arithmetic_H_descriptor": { + "K": 1, + "g": 3, + "left_bits": 0, + "offset": 0, + "right_bits": 3 + }, + "endpoint_sha256": "e7bc590eb27e753d8c445c8ecf8949712f4a2862c49ebde14ec049be16fb606f", + "h": 1, + "opposite": false + }, + { + "all_coefficients_compared": 512, + "arithmetic_H_descriptor": { + "K": 1, + "g": 3, + "left_bits": 3, + "offset": 0, + "right_bits": 0 + }, + "endpoint_sha256": "47011e46a0aa868f2faf9e14881652067fe31d56bdb14c216de0f267bfcb81fc", + "h": 0, + "opposite": false + }, + { + "all_coefficients_compared": 512, + "arithmetic_H_descriptor": { + "K": 1, + "g": 3, + "left_bits": 3, + "offset": 0, + "right_bits": 0 + }, + "endpoint_sha256": "30b3b0de8a5fa017f1b567729135e3bc96d7865c933f0893480c5f92c38910ca", + "h": 0, + "opposite": true + }, + { + "all_coefficients_compared": 512, + "arithmetic_H_descriptor": { + "K": 1, + "g": 3, + "left_bits": 0, + "offset": 0, + "right_bits": 3 + }, + "endpoint_sha256": "90f2a67145321823f3ae482d898423776f3406a3c5c1797d5d6846125feb3f1e", + "h": 1, + "opposite": true + } + ], + "width": 6 + }, + { + "K": 2, + "ell": 4, + "flags": [ + true + ], + "precision": 4, + "records": 16, + "rounds": [ + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "elementary_selected_bits": [ + 3 + ] + }, + "endpoint_sha256": "4b3ceab523b34bfb6f7929cb6978929eb17bf1b67dbdbba9d304e64e97590497", + "h": 3, + "opposite": false + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "K": 2, + "g": 1, + "left_bits": 2, + "offset": 1, + "right_bits": 0 + }, + "endpoint_sha256": "21d7e29265e70b2111cbb60dd68dba3e30343931896dcd82c0776a206acb0851", + "h": 2, + "opposite": false + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "K": 2, + "g": 1, + "left_bits": 2, + "offset": 0, + "right_bits": 0 + }, + "endpoint_sha256": "12935f9811cc8877804a66db373f97920b465ca1fc89a3b70c5a9facd3c845af", + "h": 1, + "opposite": false + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "elementary_selected_bits": [ + 2 + ] + }, + "endpoint_sha256": "78715fb2f460a8352e684c7a81bdba1538656541a1ac4bbc758d2be08b160800", + "h": 0, + "opposite": false + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "elementary_selected_bits": [ + 2 + ] + }, + "endpoint_sha256": "bc618f59a58716341a62a062b0137ff66fdcd67a8a57bb2cc1101abb1deb19e1", + "h": 0, + "opposite": true + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "K": 2, + "g": 1, + "left_bits": 2, + "offset": 0, + "right_bits": 0 + }, + "endpoint_sha256": "4719e8d06d1cd9fd2ccc0477f814ff7723b546f0b223f6abba7763c9edada844", + "h": 1, + "opposite": true + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "K": 2, + "g": 1, + "left_bits": 2, + "offset": 1, + "right_bits": 0 + }, + "endpoint_sha256": "72960a424916202967b086c123d5bdb6a6f74a8d0741f8425e8c9d6150eebe7c", + "h": 2, + "opposite": true + }, + { + "all_coefficients_compared": 256, + "arithmetic_H_descriptor": { + "elementary_selected_bits": [ + 3 + ] + }, + "endpoint_sha256": "fb2395176b520e4976b6fb76fc165fbc054976409b0783db77f951ac1fed81c7", + "h": 3, + "opposite": true + } + ], + "width": 6 + } + ], + "controls": { + "no_runtime_tape_replacement": true, + "off_grid_encoding": true, + "one_shot_after_each_pass": true, + "wrong_K_endpoint": [ + [ + 48, + 0 + ], + [ + 48, + 4 + ], + [ + 56, + 0 + ], + [ + 56, + 4 + ] + ] + }, + "diagonal_passes": [ + { + "K": 1, + "cells": 13396, + "ell": 3, + "explicit_gates": 322336, + "flags": [ + false, + false, + false + ], + "h": 1, + "input_sha256": "4dfe103d98af30bc8405aba215add6efd849e9ef99d7387c296f4c6884f4081d", + "opposite": false, + "output_stream_sha256": "806881748c986c7e3dc9f3ce020271165e31a21d13e8ae475aa6da253c9ac8e3", + "physical_roles_this_stage": 38, + "records": 64, + "source_tariff_this_diagonal": 3382475, + "tape_actions": { + "move": 1390642, + "read": 1385812, + "write": 283685 + }, + "width": 6 + }, + { + "K": 1, + "cells": 13373, + "ell": 3, + "explicit_gates": 314701, + "flags": [ + false, + false, + false + ], + "h": 0, + "input_sha256": "47011e46a0aa868f2faf9e14881652067fe31d56bdb14c216de0f267bfcb81fc", + "opposite": false, + "output_stream_sha256": "bd0447c08fbec911dd56c202639e88c1a15e9c9ee1c18180dca077869faf8dd7", + "physical_roles_this_stage": 38, + "records": 64, + "source_tariff_this_diagonal": 2778816, + "tape_actions": { + "move": 1114728, + "read": 1102946, + "write": 246441 + }, + "width": 6 + }, + { + "K": 1, + "cells": 13373, + "ell": 3, + "explicit_gates": 314701, + "flags": [ + false, + false, + false + ], + "h": 0, + "input_sha256": "ee662caf98402a1f729b9ee42fbeedc1f3592682861d0d2753c422344273e3fd", + "opposite": true, + "output_stream_sha256": "f70ac815cffed415492486e669d31398b1d8482addea45ec8ee304ce3e7b668b", + "physical_roles_this_stage": 38, + "records": 64, + "source_tariff_this_diagonal": 2770496, + "tape_actions": { + "move": 1110632, + "read": 1098722, + "write": 246441 + }, + "width": 6 + }, + { + "K": 1, + "cells": 13396, + "ell": 3, + "explicit_gates": 321952, + "flags": [ + false, + false, + false + ], + "h": 1, + "input_sha256": "30b3b0de8a5fa017f1b567729135e3bc96d7865c933f0893480c5f92c38910ca", + "opposite": true, + "output_stream_sha256": "f6de0839609e6571b526d5391b4dc55e64f2d5b9453199895e7b0c5507cefc04", + "physical_roles_this_stage": 38, + "records": 64, + "source_tariff_this_diagonal": 3298123, + "tape_actions": { + "move": 1351346, + "read": 1345364, + "write": 279461 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7488, + "ell": 4, + "explicit_gates": 140740, + "flags": [ + true + ], + "h": 3, + "input_sha256": "183aa0d3ec650117a15b7bfdecd23c83d7e3a2a569db985edfcdc3a1de22b825", + "opposite": false, + "output_stream_sha256": "255669eb5f4e041115b523d1be4060dfc71882efef11f56fea0c3de1419b0a1f", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 1079354, + "tape_actions": { + "move": 423798, + "read": 417248, + "write": 97568 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7465, + "ell": 4, + "explicit_gates": 139519, + "flags": [ + true + ], + "h": 2, + "input_sha256": "b95225168028944adf47a82fceaa1a9f3c3fa6a70644c4bee89f4bf126da6570", + "opposite": false, + "output_stream_sha256": "8efdce43d389e8134b68f2a76db9f6903b9da9b9099ab9d1e20ab2a99fc08855", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 982467, + "tape_actions": { + "move": 378850, + "read": 371786, + "write": 92312 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7442, + "ell": 4, + "explicit_gates": 138224, + "flags": [ + true + ], + "h": 1, + "input_sha256": "ae4cb55390bffef11e9d0dc889389267ecc0388aea0734259d763fd5565f5a79", + "opposite": false, + "output_stream_sha256": "e084663cc451b272329fa639976649b856958a57768d0ac3fede93f00c791198", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 883192, + "tape_actions": { + "move": 333388, + "read": 325600, + "write": 85980 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7419, + "ell": 4, + "explicit_gates": 136693, + "flags": [ + true + ], + "h": 0, + "input_sha256": "78715fb2f460a8352e684c7a81bdba1538656541a1ac4bbc758d2be08b160800", + "opposite": false, + "output_stream_sha256": "60838be3fc6656916d43c8370aa9067873ac924cc3b4b40144744707ac51b495", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 779369, + "tape_actions": { + "move": 286546, + "read": 277678, + "write": 78452 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7419, + "ell": 4, + "explicit_gates": 136693, + "flags": [ + true + ], + "h": 0, + "input_sha256": "680ba91ec23d4998578ff6f8e349bdcfbf97db4403c9d51eb09cf925a33f74b3", + "opposite": true, + "output_stream_sha256": "d5d586b74e1e7ad869790c5639abab9adc27a05bd5dec50c2782294a7f390b73", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 777289, + "tape_actions": { + "move": 285522, + "read": 276622, + "write": 78452 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7442, + "ell": 4, + "explicit_gates": 138128, + "flags": [ + true + ], + "h": 1, + "input_sha256": "bc618f59a58716341a62a062b0137ff66fdcd67a8a57bb2cc1101abb1deb19e1", + "opposite": true, + "output_stream_sha256": "e897506d79eefa03bc7793cb591650760ce87fde2ff1363d5b35a7a661a3e66d", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 862104, + "tape_actions": { + "move": 323564, + "read": 315488, + "write": 84924 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7465, + "ell": 4, + "explicit_gates": 139375, + "flags": [ + true + ], + "h": 2, + "input_sha256": "4719e8d06d1cd9fd2ccc0477f814ff7723b546f0b223f6abba7763c9edada844", + "opposite": true, + "output_stream_sha256": "fd9ea30b42f8cc67d0239b72fc13df80982ea08f5e9462181e1db5a1cb4b2734", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 946387, + "tape_actions": { + "move": 362082, + "read": 354570, + "write": 90360 + }, + "width": 6 + }, + { + "K": 2, + "cells": 7488, + "ell": 4, + "explicit_gates": 140548, + "flags": [ + true + ], + "h": 3, + "input_sha256": "72960a424916202967b086c123d5bdb6a6f74a8d0741f8425e8c9d6150eebe7c", + "opposite": true, + "output_stream_sha256": "910f8e43685b4c32bc5ae025aef10843215d51501b3db79deffde13fd652f24b", + "physical_roles_this_stage": 38, + "records": 16, + "source_tariff_this_diagonal": 1026778, + "tape_actions": { + "move": 399382, + "read": 392224, + "write": 94624 + }, + "width": 6 + }, + { + "K": 2, + "cells": 13418, + "ell": 3, + "explicit_gates": 326307, + "flags": [ + false, + false, + false + ], + "h": 1, + "input_sha256": "fdaf0ebff4623bf30c5b6e3ad760ce9139076709804e13acd779816a0c26f14e", + "opposite": false, + "output_stream_sha256": "04e85c5dcea668cc4fa3e1cc75d9008d185d85d7ee7e975933c1a1087541daf8", + "physical_roles_this_stage": 38, + "records": 64, + "source_tariff_this_diagonal": 3331410, + "tape_actions": { + "move": 1367348, + "read": 1358870, + "write": 278885 + }, + "width": 6 + } + ], + "implementation_sha256": "7f150d991c393dbcba570fec6fba0cdc05ae4155d0fe354773e73f0b2cac0b5b", + "schema": "actual-fixed-diagonal-arithmetic-layer-join-v1", + "scope": { + "H_is_arithmetic_oracle": true, + "Q_is_arithmetic_oracle": true, + "actual_full_diagonal": true, + "all_round_38_role_reuse_proved": false, + "complete_physical_layer": false, + "fresh_stage_instances": true, + "layout_is_arithmetic_oracle": true, + "production_width_execution": false + }, + "source_hashes": { + "PROOF.md": "9510fbdf21eff20e75adfbc6f882541d926b721e9207f4a3697973a58fae66ec", + "README.md": "bbbac07cc04d8460203ad9b99a9d1d3571aedf3816beed44166a98475fb08ee1", + "RESULT.json": "dfbb3875e20658760e01d42ecca0fef2b27f95d926f1ea93a716ffd7a9d0910a", + "SOURCES.json": "cf594b115e2468430e9324f4f9fafcdef09f53db254070acee336225e611e5af", + "SOURCE_INVENTORY.json": "9e0f618b7207d76f7942e67d5324dc542932d631c741de26b91c47521cdce7df", + "TASK.json": "20d398f587a92111509cbcc166e53690bf893440e1db951d523b7994d5da0ce6", + "VERIFY.json": "add3a15209fd6772a2a8542b0f1f56dca51f50bc60a9495008d50bd9c599fc10", + "inputs/consumer-PROOF.md": "c2d510485286d03f449f49da632b3a032f9c07781bc64ded023889121e14a1ef", + "inputs/consumer.py": "9c366cd26d5ce967551cdd18ecd3ff8ac9078207455dad4fbeb5b9e9678127e8", + "inputs/controller-PROOF.md": "cd3f5b4d1ebbabb3f185c13fa56c9c4391f236472594fdafbb6db35e8ba91f8a", + "inputs/controller.py": "680146c712a9d547cd5b2b28b62748724c29e701c691fb304dd2bd652fd66c31", + "pass.py": "7380a64128fdc416d3a8fce17c5fa43a6775d9dc0e71bdf62fbca46b6339ab45", + "verify.py": "852931a48a21340e09455136e645e331266e98a6ddbc1dd4245efdc5b279597b" + }, + "source_head": "4bf091f415d6470b60a5062a08b0a47e5b12dbd7" +} diff --git a/research/twiddle-matched-layer/diagonal/SOURCE_INVENTORY.json b/research/twiddle-matched-layer/diagonal/SOURCE_INVENTORY.json new file mode 100644 index 0000000000..dfcf358602 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/SOURCE_INVENTORY.json @@ -0,0 +1,103 @@ +{ + "files": [ + { + "expected_bytes": 11567, + "git_blob": "d06188b031ba29b33b8db4a1282a4ba84dfcbb78", + "path": "research/encoded-twiddle-diagonal-pass/PROOF.md", + "relative_path": "PROOF.md", + "sha256": "9510fbdf21eff20e75adfbc6f882541d926b721e9207f4a3697973a58fae66ec", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/PROOF.md" + }, + { + "expected_bytes": 5913, + "git_blob": "f9547323c2812517b7b1f84c7f6d765ff586c98b", + "path": "research/encoded-twiddle-diagonal-pass/README.md", + "relative_path": "README.md", + "sha256": "bbbac07cc04d8460203ad9b99a9d1d3571aedf3816beed44166a98475fb08ee1", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/README.md" + }, + { + "expected_bytes": 14808, + "git_blob": "5cd8d375ea8a3b599ff8f6df2d2abb9f72a228ca", + "path": "research/encoded-twiddle-diagonal-pass/RESULT.json", + "relative_path": "RESULT.json", + "sha256": "dfbb3875e20658760e01d42ecca0fef2b27f95d926f1ea93a716ffd7a9d0910a", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/RESULT.json" + }, + { + "expected_bytes": 3793, + "git_blob": "4388f45edf77f542a5ea3dc5d96d7edd7f6453c9", + "path": "research/encoded-twiddle-diagonal-pass/SOURCES.json", + "relative_path": "SOURCES.json", + "sha256": "cf594b115e2468430e9324f4f9fafcdef09f53db254070acee336225e611e5af", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/SOURCES.json" + }, + { + "expected_bytes": 6598, + "git_blob": "cc28886d898a785dbd42ad23661255a6456d051f", + "path": "research/encoded-twiddle-diagonal-pass/TASK.json", + "relative_path": "TASK.json", + "sha256": "20d398f587a92111509cbcc166e53690bf893440e1db951d523b7994d5da0ce6", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/TASK.json" + }, + { + "expected_bytes": 449, + "git_blob": "e6787718411f8ba37fa502a9c0b239b020f8c816", + "path": "research/encoded-twiddle-diagonal-pass/VERIFY.json", + "relative_path": "VERIFY.json", + "sha256": "add3a15209fd6772a2a8542b0f1f56dca51f50bc60a9495008d50bd9c599fc10", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/VERIFY.json" + }, + { + "expected_bytes": 9250, + "git_blob": "569aa79350ebde9d7df0b166d98b9f3eecf2df31", + "path": "research/encoded-twiddle-diagonal-pass/pass.py", + "relative_path": "pass.py", + "sha256": "7380a64128fdc416d3a8fce17c5fa43a6775d9dc0e71bdf62fbca46b6339ab45", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/pass.py" + }, + { + "expected_bytes": 18497, + "git_blob": "50bda4b5c01b4f3d4ae74aa42ba77970e0189d02", + "path": "research/encoded-twiddle-diagonal-pass/verify.py", + "relative_path": "verify.py", + "sha256": "852931a48a21340e09455136e645e331266e98a6ddbc1dd4245efdc5b279597b", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/verify.py" + }, + { + "expected_bytes": 16790, + "git_blob": "ecc93eb027ffbbed1561185750d7917db9b90e1d", + "path": "research/encoded-twiddle-diagonal-pass/inputs/consumer-PROOF.md", + "relative_path": "inputs/consumer-PROOF.md", + "sha256": "c2d510485286d03f449f49da632b3a032f9c07781bc64ded023889121e14a1ef", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/inputs/consumer-PROOF.md" + }, + { + "expected_bytes": 13620, + "git_blob": "d916056a4ae22d668ad3269ba881e4f518e982ab", + "path": "research/encoded-twiddle-diagonal-pass/inputs/consumer.py", + "relative_path": "inputs/consumer.py", + "sha256": "9c366cd26d5ce967551cdd18ecd3ff8ac9078207455dad4fbeb5b9e9678127e8", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/inputs/consumer.py" + }, + { + "expected_bytes": 13592, + "git_blob": "bb215a4bbde0857bc96f03827b7f0a6c6c7c7911", + "path": "research/encoded-twiddle-diagonal-pass/inputs/controller-PROOF.md", + "relative_path": "inputs/controller-PROOF.md", + "sha256": "cd3f5b4d1ebbabb3f185c13fa56c9c4391f236472594fdafbb6db35e8ba91f8a", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/inputs/controller-PROOF.md" + }, + { + "expected_bytes": 18756, + "git_blob": "2e72164d9429baeb1b18621f6f4b9576dbcc60a4", + "path": "research/encoded-twiddle-diagonal-pass/inputs/controller.py", + "relative_path": "inputs/controller.py", + "sha256": "680146c712a9d547cd5b2b28b62748724c29e701c691fb304dd2bd652fd66c31", + "url": "https://github.com/CrocSwap/integer-mult-bounds/blob/4bf091f415d6470b60a5062a08b0a47e5b12dbd7/research/encoded-twiddle-diagonal-pass/inputs/controller.py" + } + ], + "head": "4bf091f415d6470b60a5062a08b0a47e5b12dbd7", + "pull_request": 3617, + "repository": "CrocSwap/integer-mult-bounds" +} diff --git a/research/twiddle-matched-layer/diagonal/check_3617_join.py b/research/twiddle-matched-layer/diagonal/check_3617_join.py new file mode 100644 index 0000000000..2018061d6f --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/check_3617_join.py @@ -0,0 +1,232 @@ +"""Bounded actual-diagonal / arithmetic-H caller join, not a physical layer. + +Clear1nsight, with substantial OpenAI Codex assistance, Apache-2.0. +Sagar Thakrar supplies the unchanged PR3617 complete diagonal pass and its +PR3611 packet consumer. Nick Petalas supplies the unchanged PR3593 producer. +""" + +from argparse import ArgumentParser +from collections import Counter +from contextlib import ExitStack +from fractions import Fraction +from hashlib import sha1, sha256 +import json +from pathlib import Path +from types import ModuleType +from unittest.mock import patch + +HERE = Path(__file__).resolve().parent + + +def need(ok, why): + if not ok: + raise ValueError(why) + + +def load(name, path): + module = ModuleType(name) + module.__file__ = str(path) + exec(compile(path.read_bytes(), str(path), "exec"), module.__dict__) + return module + + +def digest(value): + return sha256(json.dumps(value, sort_keys=True, separators=(",", ":")).encode()).hexdigest() + + +def authenticate(): + manifest_path = HERE / "SOURCE_INVENTORY.json" + result = {"SOURCE_INVENTORY.json": sha256(manifest_path.read_bytes()).hexdigest()} + for row in json.loads(manifest_path.read_text())["files"]: + data = (HERE / "upstream" / row["relative_path"]).read_bytes() + need(len(data) == row["expected_bytes"], "source length") + need(sha1(b"blob " + str(len(data)).encode() + b"\0" + data).hexdigest() + == row["git_blob"], "source Git blob") + need(sha256(data).hexdigest() == row["sha256"], "source SHA-256") + result[row["relative_path"]] = row["sha256"] + return result + + +def encode(data, width): + out = ["@"] + for row in data: + out.append("^") + for pair in row: + for value in pair: + need(type(value) is int, "p-grid numerator must be a Gaussian integer") + need(-(1 << (width - 1)) <= value < (1 << (width - 1)), "signed width") + out.extend((value >> bit) & 1 for bit in range(width - 1, -1, -1)) + out.append("$") + out.append("!") + return out + + +def decode(stream, records, r, width): + need(stream[0] == "@" and stream[-1] == "!", "whole-stream framing") + at, rows = 1, [] + for _ in range(records): + need(stream[at] == "^", "packet start") + at += 1 + row = [] + for _ in range(r): + pair = [] + for _ in range(2): + word = stream[at:at + width] + need(len(word) == width and all(type(bit) is int and bit in (0, 1) + for bit in word), "signed word") + value = sum(bit << (width - 1 - j) for j, bit in enumerate(word)) + pair.append(value - ((1 << width) if word[0] else 0)) + at += width + row.append(tuple(pair)) + need(stream[at] == "$", "packet end") + at += 1 + rows.append(row) + need(at == len(stream) - 1, "complete stream extent") + return rows + + +def tapes(machine): + candidates = [*machine.producer.data.values(), machine.producer.descriptor, + *(counter.tape for counter in machine.producer.c.values()), + *machine.consumer.tapes.values(), *machine.tapes.values()] + return {id(tape): tape for tape in candidates} + + +def run(layer): + initial_sources = authenticate() + component_hash = sha256(Path(layer.__file__).read_bytes()).hexdigest() + own_hash = sha256(Path(__file__).read_bytes()).hexdigest() + adapter = load("retained_3617_pass", HERE / "upstream" / "pass.py") + producer = load("retained_3593_producer", HERE / "upstream" / "inputs" / "controller.py") + consumer = load("retained_3611_consumer", HERE / "upstream" / "inputs" / "consumer.py") + passes = [] + + def physical_diagonal(data, ell, flags, k, h, opposite, width): + descriptor = ("1" * ell + "#" + "1" * k + "#" + "1" * h + "#" + + "".join("L" if flag else "S" for flag in flags) + + "#" + ("+" if opposite else "-") + "#") + source = encode(data, width) + machine = adapter.DiagonalPass(producer, consumer, descriptor, width, source) + initial = tapes(machine) + need(len(initial) == 38 and len({id(t.cells) for t in initial.values()}) == 38, + "38 distinct admitted roles") + capacities = {key: len(tape.cells) for key, tape in initial.items()} + borrowed = [machine.tapes[role] for role in ("fullinput", "width", "descriptor")] + snapshots = [list(t.cells) for t in borrowed] + + def no_allocation(*_args, **_kwargs): + raise ValueError("runtime tape replacement") + + with ExitStack() as stack: + for cls in (producer.Tape, consumer.Tape): + stack.enter_context(patch.object(cls, "__init__", no_allocation)) + output = machine.run() + final = tapes(machine) + need(set(final) == set(initial), "stable within-pass roles") + need(all(len(t.cells) == capacities[key] for key, t in final.items()), "fixed capacities") + need(all(t.head == 0 for t in final.values()), "all heads returned") + need(all(t.cells == old for t, old in zip(borrowed, snapshots)), "borrowed bytes returned") + retained = {id(output), *(id(t) for t in borrowed)} + need(all(not any(t.cells) for key, t in final.items() if key not in retained), + "all other roles blank") + returned = list(output.cells) + try: + machine.run() + except ValueError as error: + need(str(error) == "one-shot full pass", "one-shot rejection reason") + else: + raise ValueError("missing full-pass one-shot rejection") + need(output.cells == returned and all(t.head == 0 for t in final.values()), + "one-shot control leaves returned state") + actions = Counter() + for tape in final.values(): + actions.update(tape.counts) + gates = sum(machine.gates.values()) + sum(machine.producer.gates.values()) + sum(machine.consumer.gates.values()) + passes.append({"ell": ell, "flags": list(flags), "K": k, "h": h, + "opposite": opposite, "width": width, "records": len(data), + "physical_roles_this_stage": 38, "cells": sum(capacities.values()), + "tape_actions": dict(sorted(actions.items())), "explicit_gates": gates, + "source_tariff_this_diagonal": sum(actions.values()) + gates, + "input_sha256": digest(data), "output_stream_sha256": digest(returned)}) + return decode(returned, len(data), 1 << ell, width) + + cases = [] + for ell, flags, k in ((3, (False, False, False), 1), (4, (True,), 2)): + original, physical = layer.slots_for(ell, flags, k) + records, r, precision, width = 1 << len(original), 1 << ell, 4, 6 + cube = [[((17 * x + 5 * j + 3) % 17 - 8, (11 * x + 7 * j + 2) % 17 - 8) + for j in range(r)] for x in range(records)] + levels = list(range(ell - 2, -1, -1)) + if any(flags): + levels.insert(0, ell - 1) + rounds = [] + for opposite in (False, True): + actual, reference = layer.reorder(cube, original, physical), cube + for h in reversed(levels) if opposite else levels: + reference = layer.reference_round(reference, original, ell, flags, h, opposite) + if opposite: + actual = physical_diagonal(actual, ell, flags, k, h, True, width) + b, q = (ell - 1) % k, (ell - 1) // k + g, a = len(flags), sum(flags) + if b <= h < ell - 1: + j, rho = (ell - 2 - h) // k, (h - b) % k + left, right = a + g*b + j*g*k, (q-j-1)*g*k + need(left + g*k + right == len(physical), "matched active-root extent") + bits = tuple(right + rho + t*k for t in range(g)) + need(set(bits) == set(layer.selected(physical, h)), "matched active-root slots") + descriptor = {"g": g, "K": k, "left_bits": left, + "right_bits": right, "offset": rho} + else: + bits = layer.selected(physical, h) + descriptor = {"elementary_selected_bits": list(bits)} + # This is an arithmetic H oracle, not a physical active-root call. + raw, denominator = layer.h_fast(actual, bits) + actual = layer.truncate(raw, denominator) + if not opposite: + actual = physical_diagonal(actual, ell, flags, k, h, False, width) + need(actual == layer.reorder(reference, original, physical), "complete joined round") + need(all(a*a + b*b <= (1 << (2 * precision)) for row in actual for a, b in row), + "whole returned p-grid unit disk") + rounds.append({"h": h, "opposite": opposite, + "arithmetic_H_descriptor": descriptor, + "all_coefficients_compared": records * r, + "endpoint_sha256": digest(actual)}) + cases.append({"ell": ell, "flags": list(flags), "K": k, "records": records, + "precision": precision, "width": width, "rounds": rounds}) + + ell, flags, k = 3, (False, False, False), 1 + _, physical = layer.slots_for(ell, flags, k) + signal = [[(int(x == 0 and j == 0) * 8, 0) for j in range(8)] for x in range(64)] + raw, divisor = layer.h_fast(signal, layer.selected(physical, 1)) + rounded = layer.truncate(raw, divisor) + correct = layer.diagonal(rounded, physical, ell, flags, 1) + wrong = physical_diagonal(rounded, ell, flags, 2, 1, False, 6) + differences = [(x, j) for x in range(64) for j in range(8) if correct[x][j] != wrong[x][j]] + need(differences, "wrong-K full-round endpoint control") + try: + encode([[(Fraction(1, 2), 0)]], 6) + except ValueError as error: + need(str(error) == "p-grid numerator must be a Gaussian integer", "off-grid rejection reason") + else: + raise ValueError("missing off-grid encoding rejection") + need(authenticate() == initial_sources, "all retained source bytes unchanged") + need(sha256(Path(layer.__file__).read_bytes()).hexdigest() == component_hash, + "frozen arithmetic component unchanged") + need(sha256(Path(__file__).read_bytes()).hexdigest() == own_hash, "join implementation unchanged") + return {"schema": "actual-fixed-diagonal-arithmetic-layer-join-v1", + "source_head": "4bf091f415d6470b60a5062a08b0a47e5b12dbd7", + "source_hashes": initial_sources, "arithmetic_component_sha256": component_hash, + "implementation_sha256": own_hash, "cases": cases, "diagonal_passes": passes, + "controls": {"wrong_K_endpoint": differences, "off_grid_encoding": True, + "one_shot_after_each_pass": True, "no_runtime_tape_replacement": True}, + "scope": {"actual_full_diagonal": True, "H_is_arithmetic_oracle": True, + "Q_is_arithmetic_oracle": True, "layout_is_arithmetic_oracle": True, + "fresh_stage_instances": True, "all_round_38_role_reuse_proved": False, + "production_width_execution": False, "complete_physical_layer": False}} + + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument("--layer-component", required=True, type=Path) + args = parser.parse_args() + print(json.dumps(run(load("frozen_layer_arithmetic", args.layer_component.resolve())), indent=2, sort_keys=True)) diff --git a/research/twiddle-matched-layer/diagonal/upstream/PROOF.md b/research/twiddle-matched-layer/diagonal/upstream/PROOF.md new file mode 100644 index 0000000000..d06188b031 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/upstream/PROOF.md @@ -0,0 +1,217 @@ +# Encoded fixed-round twiddle diagonal on a full positioned cube + +This is an author-written, source-relative proof for every finite admitted +shape. Executable examples corroborate it; they do not formally verify its +unbounded quantifiers. The supplied cube is already in the retained transform +layout. The result is the complete diagonal for one fixed round, including +address enumeration, packet transport and reusable-machine cleanup. + +## Contract and exact endpoint + +Let $\ell\geq2$, $r=2^\ell$, $1\leq K<\ell$, $0\leq h<\ell$, and let the +$D\geq1$ axis flags be long or short. Axis $i$ has $a_i=\ell$ or +$a_i=\ell-1$ address positions. Put $A=\sum_i a_i$ and $N=2^A$. +The unchanged PR3593 descriptor specifies these fields and a direction. +The width descriptor is a framed unary encoding of $w\geq2$. + +The full source is a framed stream `@(^bits$)^N!`: the notation means $N$ +consecutive packets, not literal exponent or parentheses characters. Each +packet contains $r$ Gaussian coefficients in increasing coefficient order, +real component before imaginary component, with each component a signed +$w$-bit two's-complement word in MSB-first order. Thus a packet has +$B=2rw$ payload bits. The descriptors, allocation extents and stream agree; +borrowed heads begin at zero and private storage is allocated blank before +the paid initialization. Distinct +physical roles have separate backing storage. Every component that this +particular diagonal negates must have a representable negation. This excludes +the signed minimum at those positions, without excluding it where no negation +is requested. Arbitrary malformed tapes and interrupted-run recovery are +outside the successful-execution theorem. + +For the physical address of packet $j$, write $x_{i,v}$ for its named slot +$(i,v)$. Define + +$$ +E_j=\sigma 2^{\ell-h}\sum_{i:h= 2`, `r = 2^ell`, and let `w >= 2` be a signed component width. +The producer returns a raw, most-significant-bit-first header of `ell+1` +bits, its head at zero, representing `E` modulo `2r`. Its borrowed +descriptor starts with `^ 1^ell #` and is returned unchanged at its left +delimiter. The consumer reads those actual tapes. A separate borrowed +descriptor `^ 1^w $` supplies component width by a unary scan. + +The coefficient source is one framed packet `^ bits $`, containing exactly +`r` Gaussian coefficients in increasing coefficient order. Each consists +of a signed MSB-first `w`-bit real component followed by its imaginary +component. These are complete coefficient words, not address bits. The +output uses the same framing and ordering convention. + +Write `E = epsilon*r + s`, where `epsilon` is the first header bit and +`0 <= s < r` is its remaining binary word. The endpoint is multiplication +by `y^E` in `Z[i][y]/(y^r+1)`, on precisely this packet. Signed minimum +`-2^(w-1)` is forbidden in every component which this particular exponent +requires to negate; copying that minimum without negation is allowed. +In particular the stronger no-minimum input contract of the predecessor +packet implementation is sufficient. For unit-disk grid components the +source format `w=p+2` is sufficient as well. + +The original producer executable restricts `ell` to 2..32 and its axis +count to 1..16. This package does not remove those admission caps or claim +execution of all mathematical shapes. The mathematical implication from +a valid encoded header is separate from finite simulator admission, +preallocation and the retained producer's general-family argument. + +## Exact split and sign identity + +For `f(y)=sum_(j=0)^(r-1) z_j y^j`, split the coefficient sequence into +its first `r-s` coefficients and last `s` coefficients. Since `y^r=-1`, + +``` +y^E f = (-1)^(epsilon+1) sum_(j=r-s)^(r-1) z_j y^(j+s-r) + + (-1)^epsilon sum_(j=0)^(r-s-1) z_j y^(j+s). +``` + +Consequently output the suffix before the prefix, negating the suffix +exactly when `epsilon=0` and the prefix exactly when `epsilon=1`. +When `s=0` the suffix is empty; this includes the identity header and +the all-coefficient sign change at `E=r`. Reducing a negative exponent +modulo `2r` preserves this rule because `y^(2r)=1`. + +Both components of each coefficient receive the same sign. No Gaussian +component exchange, coefficient truncation or frequency permutation is +part of this operation. In particular it preserves every coefficient norm +and introduces no numerical error. Its inverse uses the residue of `-E`. + +For a component to be negated, complementing its bits and adding one +computes its additive inverse modulo `2^w`. Except at signed minimum, +this is its exact integer negative in the signed `w`-bit range. The +minimum pattern is a leading one followed only by zeros. Detecting this +pattern while copying a word therefore suffices for the advertised guard; +no decoded component value is needed. Copying a word requires no such +restriction. The full consumer implementation and paid-control argument +below determine how these elementary identities are executed. + +## Relation to the supplied exponent + +The retained PR3593 output contract is + +``` +E = sign * 2^(ell-h) * sum_(i in I) x_(i,h) sum_(v=1) floor(N/2^k) < N. +``` + +Thus both countdowns together take `O(r)` primitive operations, after +their `O(ell)` initialization, because their initial values add to `r`. +Return scans are over just the digits visited by that decrement; they +do not introduce an `ell` factor per coefficient. + +## Packet traversal, signs and successful restoration + +`split` consumes its counter by one decrement per coefficient. Its finite +control calls `copy_word` exactly twice per coefficient, real then imaginary. +Each call scans the actual unary width descriptor, copying one current-cell +source bit per unary `1`, and then returns the width head by its delimiter. +It follows that the prefix receives exactly the first `r-s` coefficients +and the suffix exactly the remaining `s`. The source must then be at its +end delimiter. Both buffers receive their own end delimiter and their +heads return to the left delimiter. + +`emit` traverses the suffix first, then the prefix, ending each at its +buffer delimiter. `emit_word` copies exactly one unary-width component to +the word tape while recording its sign and whether any lower bit is nonzero. +For a negation it rejects precisely the minimum pattern and performs the +right-to-left complement-and-carry pass proved above. It then copies the +word forwards into the output. A following word overwrites the same word +extent, so the previous contents are never treated as new input. + +The signs passed by `run` are `not epsilon` for suffix negation and +`bool(epsilon)` for prefix negation. These are exactly the signs in the +algebraic identity. Every input coefficient is copied once, emitted once, +and retains real/imaginary component order. An empty suffix ends at its +delimiter without emitting any component. The output receives its final +delimiter and its head returns to zero. + +The borrowed source and unary width descriptor are never written and +return to their left delimiters. Header and producer descriptor were +already restored before coefficient processing. On successful return, +`clear` scans each of the five private scratch tapes to its capacity guard, +clears that guard, returns by the still-present left delimiter while +clearing the interior, then clears the left delimiter. All their cells +are zero and their heads are zero. The output remains framed with its +capacity guard; that guard is storage metadata beyond the output delimiter, +not an extra coefficient bit. + +On a signed-minimum rejection in an otherwise valid admitted packet, the +same `finally` block clears all five scratch tapes and also the partial +output. The borrowed heads are restored. This is a one-shot consumer, +including after rejection. Malformed framing, mismatched host capacities, +interruption and external tape mutation are outside this restoration +contract; an exception path for arbitrary malformed tapes is not claimed. + +## Encoded initialization and the physical inventory + +The constructor admits and allocates blank simulator storage using `ell` +and `w`; it executes no consumer tape operation. Matching allocated extents +are a valid-input precondition. It does not supply an exponent or a schedule +to `run`. Host allocation, list management and validation costs are not +asserted to be physical tape operations. + +The actual `initialize` operation frames the three packet tapes by scanning +the borrowed source from `^` to `$`, initializing one cell on each of the +three roles per actual input bit. It adds an endpoint cell and a capacity +guard, then returns all heads by their left delimiters. The word tape is +initialized analogously from the actual unary width descriptor. Both counter +tapes are initialized from the producer descriptor's actual unary `ell` +field, with one extra binary digit, endpoint cell and capacity guard. +These reads, writes, unit moves and tests are charged. Thus the initialization +schedule itself is encoded-input-driven; it is not justified merely by +charging host loops over decoded capacities. + +After allocation, `run` and its helpers inspect a tape only through its +current-cell `read`, `write` and unit `move` methods. Their loops terminate +on actual delimiters, unary symbols, or the marked-counter zero flags. +The role tuples have fixed size, and copying the real and imaginary words +is a fixed two-call control sequence. `epsilon`, carry, zero, sign and +minimum-detection state have finite ranges. `capacities`, Python head indices +and stored cell arrays are allocation/diagnostic data, not inputs to the +executed control. The dictionaries describing named roles have fixed size. +No trace or decoded exponent table is retained. + +Put `L=2rw`. The six owned tape capacities, including framing/guards, are + +``` +prefix, suffix, output: each L+3 +word: w+3 +a, b: each ell+4 +owned total: 3L+w+2ell+20. +``` + +Let `C_source` be the borrowed source's actual allocated capacity, at least +`L+2`; its active framed packet ends at `$`. Extra capacity after that +delimiter is not consumed. In particular a prior consumer output has +capacity `L+3`, including its trailing guard, and is a valid source without +copying or removing that guard. The width descriptor uses `w+2` cells. +The header and producer descriptor are shared existing tapes, not copies. +Therefore joining this consumer to the retained producer increases the +allocated finite-alphabet capacity by exactly + +``` +3L+2w+2ell+22+C_source. +``` + +For a minimally framed source this is `4L+2w+2ell+24`; for a prior guarded +output it is `4L+2w+2ell+25`. With the retained producer's 26 tapes the +join has 34 fixed tape roles. If `C_prod` is its stated capacity, add the +displayed increment to it, counting its output header and descriptor once. +If the source is retained from an earlier operation in a larger caller, +deduplicate that actual tape too when forming the larger caller's inventory. +This is tape capacity, not Python object memory or a bit-encoding count. +The alphabets and finite-control state are fixed independently of the shape. + +## Paid consumer bound and joined invoice + +The consumer tariff counts every current-cell read, write and unit move, +plus each explicit fixed finite-control gate recorded by `gate`. A named +Boolean gate such as complement-and-carry is one fixed macro in this tariff, +not a claim that its implementation uses only one Boolean primitive. +The remaining dispatch/control transitions require a constant factor per +recorded action or fixed macro entry. Thus a tariff bound also gives the +stated asymptotic full-transition bound, without asserting an exact numeric +count for every machine-state transition. + +The following conservative phase bounds follow directly from the loops. +They include the head-return scans; their deliberately loose constants do +not use finite timing measurements. + +| Phase | Upper bound in recorded actions | +| --- | ---: | +| Encoded initialization | `23L+11w+16ell+120` | +| Header staging, counter construction and top marking | `100ell+100` | +| All `copy_word` calls | `11L+20r` | +| All `emit_word` calls | `27L+60r` | +| Both complete countdowns | `23r` | +| Remaining split/emit guards, packet returns and fixed control | `12L+8r+100` | +| Five successful scratch clears | `16L+8w+16ell+106` | + +For example, a `copy_word` costs at most `11w+10`, and there are `2r` +such calls. An `emit_word`, including its negation branch and word return, +costs at most `27w+30`, again for `2r` calls. A decrement costs at most +`7nu_2(n)+16`; the valuation identity gives the countdown row. For a scratch +tape of capacity `C` initially at its left delimiter, `clear` costs exactly +`8C-6` in this tariff. The capacities above give the last row. Empty +segments still incur their delimiter/return overhead, included in the +fixed-control row. + +Summing the displayed bounds gives at most +`89L+111r+19w+132ell+426`. Since `w>=2`, `r<=L/4`, so this is bounded by +`120L+24w+144ell+512`, and hence, for `ell>=2`, + +``` +T_consumer <= 256*(L+ell+w+1) = O(rw+ell). +``` + +The verifier's exact tariff is the sum of the actual per-role action +counters and finite-gate counters, not this upper bound substituted for a +measurement. Consumer actions on borrowed producer tapes are measured as +increments during the consumer call. If `T_prod` denotes the producer's +recorded action/gate invoice at the end of its call, the joined invoice is +`T_prod+T_consumer`. Summing producer counters again after consumption would +double-count the header/descriptor increments and is not this formula. + +Under the predecessor's source band `D*ell=O(p)`, its established allowance +is `O(p^3)` producer transitions. Consequently this one-header/one-packet +join has `O(p^3+rw+ell)` transitions. With `w=O(p)`, `ell=O(p)` and the +retained long-record hypothesis that `r` eventually dominates every fixed +power of `p`, this is `O(rp)` per supplied record. This is an asymptotic +conditional implication, with no explicit cutoff, complete layer invoice, +address-enumeration cost or caller/stock/dirty-restoration admission. + +## Attribution, evidence and remaining boundary + +Nick Petalas's PR3593 supplies the encoded header producer, unary shape +protocol, exponent proof and full polynomial producer invoice; PR3582 is +its retained direct-operation predecessor. His `synthetic-monomial-packets` +supplies the earlier signed packet endpoint and data-only invoice, whose +host-provided integer headers left this encoded join open. The source +transform and their retained predecessor notices remain credited. The +split/sign algebra and linear packet cost were already stated there; they +are not new transform identities. + +This package's contribution is the actual paid connection through the raw +header and unary descriptor, including carry-stopping encoded coefficient +countdowns and encoded scratch initialization. Finite execution checks +corroborate the endpoint, counters, guard and restoration claims on their +listed cases; they do not prove unbounded quantifiers. The written argument +is not independent human acceptance or a proof-assistant certificate. +The producer theorem is inherited and its full source chain is identified +in the manifest. No complete synthetic round, T74 refinement, production +native object, numerical error chain, supplier admission, new multiplication +exponent or selected-frontier change is claimed. diff --git a/research/twiddle-matched-layer/diagonal/upstream/inputs/consumer.py b/research/twiddle-matched-layer/diagonal/upstream/inputs/consumer.py new file mode 100644 index 0000000000..d916056a4a --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/upstream/inputs/consumer.py @@ -0,0 +1,351 @@ +"""Physical signed packet consumer; allocation dimensions never drive run(). + +SPDX-License-Identifier: Apache-2.0 +Sagar Thakrar, with substantial OpenAI Codex assistance. +The borrowed header/descriptor protocol is Nick Petalas's PR3593 protocol. +""" +from collections import Counter + + +def require(ok, message): + if not ok: + raise ValueError(message) + + +class Tape: + """Simulator storage: only these methods inspect storage/head in execution.""" + + def __init__(self, cells): + self.cells = list(cells) + self.head = 0 + self.counts = Counter() + + def read(self): + self.counts["read"] += 1 + return self.cells[self.head] + + def write(self, value): + self.counts["write"] += 1 + self.cells[self.head] = value + + def move(self, direction): + require(direction in (-1, 1), "unit move") + require(0 <= self.head + direction < len(self.cells), "tape boundary") + self.counts["move"] += 1 + self.head += direction + + +class Consumer: + """One-shot consumer of a valid borrowed PR3593 twiddle header. + + Admission: matching unary descriptors and allocation dimensions; source has + exactly r Gaussian coefficients, each two signed width-bit MSB words. All + borrowed heads start at zero. A requested negation must be representable. + Tape objects must have separate backing storage, as their constructors + provide; manually sharing their diagnostic cells lists is not admitted. + run() never reads the host allocation dimensions. Arithmetic endpoints here + are exact signed rotations, not the rest of a recursive caller. + """ + + def __init__(self, ell, width): + require(type(ell) is int and 2 <= ell <= 32, "allocation ell") + require(type(width) is int and width >= 2, "allocation signed width") + length = 2 * (1 << ell) * width + self.capacities = dict(prefix=length+3, suffix=length+3, output=length+3, + word=width+3, a=ell+4, b=ell+4) + self.tapes = {} + self.invoice = Counter() + self.gates = Counter() + self.used = False + # Blank simulator allocation only. Actual framing/initialization is + # encoded-input driven in initialize(), and every such action is paid. + for role, capacity in self.capacities.items(): + self.tapes[role] = Tape((0,) * capacity) + + def gate(self, name): + self.gates[name] += 1 + self.invoice["gate"] += 1 + + def test(self, condition): + self.gate("test") + return condition + + def read(self, role): + self.invoice[role + ".read"] += 1 + return self.tapes[role].read() + + def write(self, role, value): + self.invoice[role + ".write"] += 1 + self.tapes[role].write(value) + + def move(self, role, direction): + self.invoice[role + ".move"] += 1 + self.tapes[role].move(direction) + + def home(self, role): + while self.test(self.read(role) != "^"): + self.move(role, -1) + + def initialize(self): + """Frame scratch using borrowed extents, never host allocation sizes.""" + require(self.test(self.read("source") == "^"), "source origin") + for role in ("prefix", "suffix", "output"): + self.write(role, "^") + self.move(role, 1) + self.move("source", 1) + while self.test(self.read("source") != "$"): + require(self.test(self.read("source") in (0, 1)), "source bit") + for role in ("prefix", "suffix", "output"): + self.write(role, 0) + self.move(role, 1) + self.move("source", 1) + for role in ("prefix", "suffix", "output"): + self.write(role, 0) + self.move(role, 1) + self.write(role, "!") + self.home(role) + self.home("source") + require(self.test(self.read("width") == "^"), "width origin") + self.write("word", "^") + self.move("word", 1) + self.move("width", 1) + while self.test(self.read("width") == "1"): + self.write("word", 0) + self.move("word", 1) + self.move("width", 1) + require(self.test(self.read("width") == "$"), "unary width delimiter") + self.write("word", 0) + self.move("word", 1) + self.write("word", "!") + self.home("word") + self.home("width") + require(self.test(self.read("descriptor") == "^"), "descriptor origin") + for role in ("a", "b"): + self.write(role, "^") + self.move(role, 1) + self.move("descriptor", 1) + while self.test(self.read("descriptor") == "1"): + for role in ("a", "b"): + self.write(role, 0) + self.move(role, 1) + self.move("descriptor", 1) + require(self.test(self.read("descriptor") == "#"), "unary ell delimiter") + for role in ("a", "b"): + # One extra binary digit, one endpoint delimiter, then guard. + self.write(role, 0) + self.move(role, 1) + self.write(role, 0) + self.move(role, 1) + self.write(role, "!") + self.home(role) + self.home("descriptor") + + def clear(self, role): + self.home(role) + self.move(role, 1) + while self.test(self.read(role) != "!"): + self.write(role, 0) + self.move(role, 1) + self.write(role, 0) + self.move(role, -1) + while self.test(self.read(role) != "^"): + self.write(role, 0) + self.move(role, -1) + self.write(role, 0) + + def mark_top(self, role): + """Enter at '$'; mark highest one by digit 2, return at '^'.""" + self.move(role, -1) + while self.test(self.read(role) == 0): + self.move(role, -1) + zero = self.test(self.read(role) == "^") + if self.test(not zero): + require(self.test(self.read(role) == 1), "binary counter") + self.write(role, 2) + self.home(role) + return zero + + def decrement(self, role): + """Positive counter only; top marker makes zero detection local.""" + self.move(role, 1) + while self.test(self.read(role) == 0): + self.write(role, 1) + self.move(role, 1) + top = self.test(self.read(role) == 2) + require(self.test(top or self.read(role) == 1), "positive marked counter") + self.write(role, 0) + self.move(role, -1) + zero = False + if self.test(top): + zero = self.test(self.read(role) == "^") + if self.test(not zero): + self.write(role, 2) + self.home(role) + return zero + + def counts_from_header(self): + """The descriptor's first unary field bounds every raw header access.""" + require(self.test(self.read("descriptor") == "^"), "descriptor origin") + epsilon = self.read("header") + require(self.test(epsilon in (0, 1)), "header sign bit") + self.move("descriptor", 1) + self.move("a", 1) + while self.test(self.read("descriptor") == "1"): + self.move("header", 1) + bit = self.read("header") + require(self.test(bit in (0, 1)), "header exponent bit") + self.write("a", bit) + self.move("a", 1) + self.move("descriptor", 1) + require(self.test(self.read("descriptor") == "#"), "unary ell delimiter") + self.write("a", "$") + # Restore the raw header by the very same unary field, not a host size. + self.move("descriptor", -1) + while self.test(self.read("descriptor") == "1"): + self.move("header", -1) + self.move("descriptor", -1) + require(self.test(self.read("descriptor") == "^"), "descriptor restored") + # Reverse MSB staging into little-endian s, with an extra high zero. + self.move("a", -1) + self.move("b", 1) + while self.test(self.read("a") != "^"): + self.write("b", self.read("a")) + self.move("b", 1) + self.move("a", -1) + self.write("b", 0) + self.move("b", 1) + self.write("b", "$") + self.home("b") + # Compute -s modulo 2r, then toggle its highest bit to obtain r-s. + carry = 1 + self.move("a", 1) + self.move("b", 1) + while self.test(self.read("b") != "$"): + bit = self.read("b") + self.gate("complement-add") + self.write("a", (1-bit) ^ carry) + carry &= 1-bit + self.move("a", 1) + self.move("b", 1) + self.write("a", "$") + self.move("a", -1) + self.gate("toggle-high") + self.write("a", 1-self.read("a")) + self.move("a", 1) + a_zero = self.mark_top("a") + b_zero = self.mark_top("b") + require(self.test(not a_zero), "r-s is positive") + return epsilon, a_zero, b_zero + + def copy_word(self, target): + self.move("width", 1) + while self.test(self.read("width") == "1"): + bit = self.read("source") + require(self.test(bit in (0, 1)), "complete source word") + self.write(target, bit) + self.move(target, 1) + self.move("source", 1) + self.move("width", 1) + require(self.test(self.read("width") == "$"), "unary width delimiter") + self.home("width") + + def split(self, counter, target, zero): + self.move(target, 1) + while self.test(not zero): + # Exactly two components; this is a finite control sequence. + self.copy_word(target) + self.copy_word(target) + zero = self.decrement(counter) + self.write(target, "$") + self.home(target) + + def emit_word(self, source, negate): + self.move("word", 1) + self.move("width", 1) + sign = self.read(source) + first, lower_nonzero = True, False + while self.test(self.read("width") == "1"): + bit = self.read(source) + require(self.test(bit in (0, 1)), "complete segment word") + self.gate("signed-minimum-flag") + if not first: + lower_nonzero |= bool(bit) + first = False + self.write("word", bit) + self.move("word", 1) + self.move(source, 1) + self.move("width", 1) + require(self.test(self.read("width") == "$"), "unary width delimiter") + self.write("word", "$") + self.home("width") + if self.test(negate): + require(self.test(not (sign == 1 and not lower_nonzero)), "signed minimum cannot be negated") + carry = 1 + self.move("word", -1) + while self.test(self.read("word") != "^"): + bit = self.read("word") + self.gate("signed-negate") + self.write("word", (1-bit) ^ carry) + carry &= 1-bit + self.move("word", -1) + else: + self.home("word") + self.move("word", 1) + while self.test(self.read("word") != "$"): + self.write("output", self.read("word")) + self.move("output", 1) + self.move("word", 1) + self.home("word") + + def emit(self, source, negate): + self.move(source, 1) + while self.test(self.read(source) != "$"): + self.emit_word(source, negate) + self.emit_word(source, negate) + self.home(source) + + def run(self, header, descriptor, width_descriptor, source): + self.gate("entry") + require(not self.used, "one-shot consumer") + self.used = True + # Fixed-arity identity admission, never a payload/descriptor decoding. + self.gate("distinct-borrows") + require(header is not descriptor and header is not width_descriptor and header is not source + and descriptor is not width_descriptor and descriptor is not source + and width_descriptor is not source, "distinct borrowed tapes") + for borrowed in (header, descriptor, width_descriptor, source): + for role in ("prefix", "suffix", "output", "word", "a", "b"): + require(self.test(borrowed is not self.tapes[role]), "borrowed tape aliases private role") + self.tapes.update(header=header, descriptor=descriptor, width=width_descriptor, source=source) + success = False + self.initialize() + try: + epsilon, a_zero, b_zero = self.counts_from_header() + require(self.test(self.read("source") == "^"), "source origin") + require(self.test(self.read("width") == "^"), "width origin") + self.move("source", 1) + self.split("a", "prefix", a_zero) + self.split("b", "suffix", b_zero) + require(self.test(self.read("source") == "$"), "complete source packet") + self.home("source") + self.move("output", 1) + self.gate("segment-sign") + self.emit("suffix", not epsilon) + self.emit("prefix", bool(epsilon)) + self.write("output", "$") + self.home("output") + self.gate("success") + success = True + return self.tapes["output"] + finally: + # Guaranteed on valid admitted inputs, including signed-minimum + # rejection. Malformed external tapes are outside this contract. + self.home("source") + self.home("width") + self.clear("prefix") + self.clear("suffix") + self.clear("word") + self.clear("a") + self.clear("b") + if self.test(not success): + self.clear("output") diff --git a/research/twiddle-matched-layer/diagonal/upstream/inputs/controller-PROOF.md b/research/twiddle-matched-layer/diagonal/upstream/inputs/controller-PROOF.md new file mode 100644 index 0000000000..bb215a4bbd --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/upstream/inputs/controller-PROOF.md @@ -0,0 +1,248 @@ +# Encoded shape control for direct synthetic twiddles + +This is an author-written proof for every finite valid shape. Independent human +and formal proof-kernel review are unclaimed. The executable limits ell to +2..32 and the number D of axes to 1..16. Its finite checks corroborate the +argument and do not prove its unbounded quantifiers. + +## Boundary and conclusion + +Let ell>=2, 1<=K=1. Axis i is long or short, with ell or +ell-1 named Boolean positions. Put A equal to their total number of positions, +I={i:hN^2 for these descriptors, no valid run overflows. The +carry/borrow identities and comparison invariant prove every counter operation. + +The simulator's preallocated list lengths and loop fuel are boundary checks and +diagnostics. No decoded counter value, Python head index, input bit, list of +named slots or arithmetic on an address value controls the schedule. Marker +tests and counter comparisons end all successful loops before their diagnostic +fuel bounds. Removing those guards gives the same finite-transition machine +on every valid input. The Boolean/counter dictionaries and opcode lookup each +have a fixed number of entries. A Python callback stack is not a physical tape. +Suspended axis scans have fixed nesting depth and constant finite state. + +The host admission function checks the descriptor grammar, executable caps and +address extent before starting the simulator. A valid-input theorem needs no +oracle for these tests. A uniform validator can scan the fixed grammar, count +the unary fields and flags, and compare K, h and ell on the same counter tapes. +No executed physical invoice for malformed host admission is claimed here. + +## Recovering the schedule from the descriptor + +The actual parser increments ell, K and h from their unary fields. Repeated +subtraction of K from ell-1 computes quotient q and remainder b. Counter +comparisons compute a and stride=max(a,1). A descriptor flag scan computes the +bank extent P, charging its dummy cell when d=0. Another counter holds n=h+1. + +Each axis sweep returns the descriptor head to caret, scans through the first +three separators, and reads L/S flags until the next separator. No flag vector +is copied. A counter base advances by stride precisely at participating axes. +There are three schedule phases. + +1. At v=ell-1, consume one slot for each L flag. +2. At v=b-1,...,0, sweep every flag and consume its slot. +3. Starting at upper=ell-2, repeat q chunks. Compute lower=upper+1-K. Sweep + flags and consume v=upper,...,lower for each axis, then subtract K from upper + when another chunk remains. + +This is exactly the canonical order: long top slots, extracted low planes, then +chunk-major high-to-low chunks with axis order and descending bits inside each +axis chunk. Each named position appears once. Top-round participation is the +actual L flag; in lower rounds all axes participate. Both the base and v are +reset at their specified loop boundaries. In particular, short axes do not +create holes in the top-round bank addressing. + +The controller emits a member of a fixed 80-symbol data instruction alphabet +at each data action. Instructions read/write a named Boolean register on a +named tape, move a named tape one cell, or perform one of eight fixed Boolean +register actions. They contain no integer operand, pointer or source index. +Production execution dispatches each instruction immediately and retains none. +The verifier can collect the stream for replay; that diagnostic program storage +is outside the producer's C bound and is disabled by default. + +To seek a data position, compare its binary position counter with the target, +move one cell toward the target, update the position counter, and repeat. Every +physical data move and every counter access is charged. Address progression +uses one right move before each slot after the first. There is no reread while +returning the address head. + +## Arithmetic and final restoration + +For an active axis, exactly the v0, complement and increment all n accumulator bits. +Unlike PR3582, this implementation also performs that harmless negation in an +empty top round. The result is still zero; its extra accesses/gates are charged. +Direction + and h=0 omit the negation. Read accumulator positions h,...,0 into +the output, followed by ell-h zeros. This is sign*2^(ell-h)*S modulo 2^(ell+1). + +Counter-controlled scans erase all P bank cells and all n accumulator cells. +Seek every data head to zero, return the descriptor head by its caret delimiter, +erase each of the 21 counters including its delimiters and reset the Boolean +registers. The persistent Boolean one is finite control in its initial state. +The output remains, and the borrowed address and descriptor were never written. +This proof concerns successful valid-input execution. It does not claim a +failure/retry restoration contract. + +## Data invoice and full polynomial bound + +Let f=1 exactly when h>0 and direction is -. There are d*h masked additions and + + L=d*h*(h+3)/2 + +accumulator ripple positions. The exact Boolean counts are + + AND=d*h+L+f*n, XOR=L+2*f*n. + +The exact read/write totals are + + address: reads A, writes 0; + bank: reads d*h, writes 2*d*a+d+P; + total: reads L+(f+1)*n, writes L+(f+1)*n; + output: reads 0, writes ell+1. + +For the chronological access positions t_1,...,t_s on a tape, set both endpoints +to zero. Its exact movement is sum |t_(j+1)-t_j|. checks.py independently builds +these access sequences from canonical named slots. Counter motion is additional +and is measured directly by the sequential counter implementation. + +For completeness, a generous bound on the data tariff is 30M^2. Indeed P<=A, +d*h<=A, d*a<=A, n<=ell and L<=A*(ell+2)/2. Bank read/write accesses are at most +5A, so its movement is at most (5A+1)*(P-1). Accumulator movement is at most +A*ell+6ell by summing the sparse ripples, optional negation, output and cleanup. +The other movements are 2*(A-1)+2ell. Summing these with the displayed read, +write and gate totals gives the bound, including the extra empty-round negation. + +Here is a conservative static count of the controller macros. Outside seeks, +parsing/division uses O(N+ell+D) macros. The top, low-plane and chunk passes +have A input events, at most d*a pending events, d*h contributions and L ripple +positions. Each event uses at most 30 counter macros. Finish/cleanup adds at +most 10*(ell+P+n+1), and fixed initialization/erasure has 42 counter roles. +These quantities give fewer than 100M^2 non-seek macros, with setup/erasure +separately bounded by 42*14*(W+2). A seek uses two counter macros per actual data +move and one final comparison. There are at most 30M^2 data moves, and fewer +than 10M^2 seek invocations from the displayed access totals and four returns. +Thus seeks use at most 70M^2 macros. Charging at most 14*(W+2) per macro, plus +descriptor sweeps and the data tariff, stays below 5000M^2*(W+2). Descriptor +sweeps need at most a constant times N*(ell+1) actions and are included. + +Finally W+2=N+4<=4M. The exact capacity formula and P<=A give C<=90M and the +binary encoding bound 182M. All bounds concern mathematical tape cells and +primitive actions, not Python allocation, timings or an optimized constant. + +## Source allowance and remaining join + +Under the retained D*ell=O(p) source band, A=O(p), ell=O(p), and N=O(p). The +complete descriptor/counter/data producer therefore has O(p^3) transitions and +O(p) tape cells. For fixed 0=2^(a_r*p/d_source), log2(r)>=(a_r/b_d)*p^(1-epsilon). Consequently r +eventually exceeds every fixed power of p, and this producer fits the source's +asymptotic O(rp) per-record exponent-production allowance. This gives no explicit +cutoff or optimized quadratic total-machine claim. + +The output is one header. Address enumeration, coefficient packets, signed +rotations, truncation, spectators, caller reservations, dirty caller return and +the complete layer/root invoice remain separate. This is a uniform encoded +header-producer implication, not a complete transform or supplier admission. +It establishes no new multiplication exponent and changes no selected frontier. diff --git a/research/twiddle-matched-layer/diagonal/upstream/inputs/controller.py b/research/twiddle-matched-layer/diagonal/upstream/inputs/controller.py new file mode 100644 index 0000000000..2e72164d94 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/upstream/inputs/controller.py @@ -0,0 +1,493 @@ +"""Encoded sequential twiddle controller. Nick Petalas, Apache-2.0.""" + +from collections import Counter as Tally + + +def require(ok, message): + if not ok: + raise ValueError(message) + + +LEFT, RIGHT = 2, 3 +ROLES = ('address', 'bank', 'total', 'output') +REGISTERS = ('input', 'branch', 'pending', 'carry', 'old', 'inverse', 'zero', 'one') +# Every entry belongs to a fixed finite alphabet, independent of the shape. +OPS = tuple((kind, role, reg) for kind in ('read', 'write') + for role in ROLES for reg in REGISTERS) + tuple( + ('move', role, direction) for role in ROLES for direction in (-1, 1)) + ( + ('gate', 'mask', 0), ('gate', 'ripple', 0), ('gate', 'invert', 0), + ('gate', 'negate', 0), ('gate', 'reset', 0), ('gate', 'carry-one', 0), + ('gate', 'save-branch', 0), ('gate', 'save-pending', 0)) +CODE = {op: i for i, op in enumerate(OPS)} + + +class Tape: + """Current-cell operations only; the integer head is simulator state.""" + + def __init__(self, cells): + self.cells = list(cells) + self.head = 0 + self.counts = Tally() + + def read(self): + self.counts['read'] += 1 + return self.cells[self.head] + + def write(self, value): + self.cells[self.head] = value + self.counts['write'] += 1 + + def move(self, direction): + require(direction in (-1, 1), 'bad unit move') + require(0 <= self.head + direction < len(self.cells), 'head out of bounds') + self.head += direction + self.counts['move'] += 1 + + +class Binary: + """A delimited little-endian counter. No decoded value controls execution.""" + + def __init__(self, width, descriptor): + self.width = width + self.tape = Tape((0,) * (width + 2)) + self.tape.write(LEFT) + self.tape.move(1) + # One zero bit per actual borrowed symbol, including ^ and $. + for _unused in range(width + 1): + token = descriptor.read() + self.tape.write(0) + self.tape.move(1) + if token == '$': + break + descriptor.move(1) + else: + raise ValueError('unterminated descriptor initialization') + self.tape.write(RIGHT) + self.home() + for _unused in range(width + 1): + if descriptor.read() == '^': + return + descriptor.move(-1) + raise ValueError('descriptor return budget exhausted') + + def home(self): + for _unused in range(self.width + 2): + if self.tape.read() == LEFT: + return + self.tape.move(-1) + raise ValueError('missing left delimiter') + + def zero(self): + self.tape.move(1) + for _unused in range(self.width + 1): + if self.tape.read() == RIGHT: + self.home() + return + self.tape.write(0) + self.tape.move(1) + raise ValueError('missing right delimiter') + + def change(self, decrement=False): + carry = 1 + self.tape.move(1) + for _unused in range(self.width + 1): + bit = self.tape.read() + if bit == RIGHT: + self.home() + require(not carry, 'counter overflow or underflow') + return + self.tape.write(bit ^ carry) + carry &= (1 - bit) if decrement else bit + self.tape.move(1) + raise ValueError('missing right delimiter') + + def combine(self, other, operation): + require(self is not other and self.width == other.width, 'counter alias') + require(operation in ('copy', 'add', 'sub', 'compare'), 'bad counter operation') + self.tape.move(1) + other.tape.move(1) + carry, relation = 0, 0 + for _unused in range(self.width + 1): + a, b = self.tape.read(), other.tape.read() + if a == RIGHT: + require(b == RIGHT and not carry, 'counter width or arithmetic failure') + self.home() + other.home() + return relation + if operation == 'copy': + self.tape.write(b) + elif operation == 'compare': + if a != b: + relation = 1 if a else -1 + else: + self.tape.write(a ^ b ^ carry) + if operation == 'add': + carry = (a & b) | ((a ^ b) & carry) + else: + carry = ((1 - a) & b) | ((1 - (a ^ b)) & carry) + self.tape.move(1) + other.tape.move(1) + raise ValueError('missing right delimiter') + + def copy(self, other): + self.combine(other, 'copy') + + def add(self, other): + self.combine(other, 'add') + + def sub(self, other): + self.combine(other, 'sub') + + def compare(self, other): + return self.combine(other, 'compare') + + def value(self): + """Diagnostics only. The controller never calls this method.""" + return sum(bit << i for i, bit in enumerate(self.tape.cells[1:-1])) + + def erase(self): + self.zero() + self.tape.move(1) + for _unused in range(self.width + 1): + if self.tape.read() == RIGHT: + self.tape.write(0) + self.home() + self.tape.write(0) + return + self.tape.move(1) + raise ValueError('missing right delimiter during erasure') + + +def encode(ell, k, h, axes, opposite=False): + require(type(ell) is int and 2 <= ell <= 32, 'bad ell') + require(type(k) is int and 1 <= k < ell, 'bad K') + require(type(h) is int and 0 <= h < ell, 'bad h') + require(type(axes) is tuple and 1 <= len(axes) <= 16, 'bad axes') + require(all(type(x) is bool for x in axes), 'non-Boolean axis') + require(type(opposite) is bool, 'bad direction') + return '1' * ell + '#' + '1' * k + '#' + '1' * h + '#' + ''.join( + 'L' if x else 'S' for x in axes) + '#' + ('+' if opposite else '-') + '#' + + +def admit(text, address): + """Reject malformed/excessive external inputs before private execution.""" + require(type(text) is str and len(text) <= 116, 'bad descriptor extent') + parts = text.split('#') + require(len(parts) == 6 and parts[-1] == '', 'bad descriptor framing') + require(all(set(x) <= {'1'} for x in parts[:3]), 'bad unary field') + ell, k, h = map(len, parts[:3]) + require(set(parts[3]) <= {'L', 'S'}, 'bad axis symbol') + axes = tuple(x == 'L' for x in parts[3]) + require(parts[4] in ('+', '-'), 'bad direction symbol') + require(encode(ell, k, h, axes, parts[4] == '+') == text, 'noncanonical descriptor') + extent = sum(ell if x else ell - 1 for x in axes) + require(type(address) is tuple and len(address) == extent, 'bad address extent') + require(all(type(x) is int and x in (0, 1) for x in address), 'bad address bit') + return ell, k, h, axes, parts[4] == '+' + + +class Controller: + NAMES = ('ell', 'k', 'h', 'b', 'q', 'a', 'stride', 'upper', 'lower', 'v', + 'base', 'target', 'low', 'j', 'zero', 'address-pos', 'bank-pos', + 'total-pos', 'output-pos', 'bank-size', 'total-size') + + def __init__(self, descriptor, address, trace=False): + ell, k, h, axes, opposite = admit(descriptor, address) + b = (ell - 1) % k + a = b if b <= h < ell - 1 else 0 + d = sum(h < ell - (not long) for long in axes) + self.data = {'address': Tape(address), 'bank': Tape((0,) * max(1, d * max(a, 1))), + 'total': Tape((0,) * (h + 1)), 'output': Tape((0,) * (ell + 1))} + # Host arithmetic here admits exact tape extents, never a data schedule. + self.descriptor = Tape('^' + descriptor + '$') + self.width = len(descriptor) + 2 + self.c = {name: Binary(self.width, self.descriptor) for name in self.NAMES} + self.bits = dict.fromkeys(REGISTERS, 0) + self.bits['one'] = 1 + self.gates = Tally() + self.trace = [] if trace else None + self.first = True + self.limit = len(address) + ell + 1 + + def emit(self, kind, role, reg): + opcode = CODE[kind, role, reg] + if self.trace is not None: + self.trace.append(opcode) + if kind == 'move': + self.data[role].move(reg) + elif kind == 'read': + self.bits[reg] = self.data[role].read() + elif kind == 'write': + self.data[role].write(self.bits[reg]) + else: + self.gate(role) + + def gate(self, action): + b = self.bits + if action == 'mask': + b['carry'] = b['branch'] & b['pending'] + self.gates['and'] += 1 + elif action == 'ripple': + b['inverse'] = b['old'] ^ b['carry'] + b['carry'] &= b['old'] + self.gates['and'] += 1 + self.gates['xor'] += 1 + elif action == 'invert': + b['inverse'] = b['old'] ^ 1 + self.gates['xor'] += 1 + elif action == 'negate': + b['old'] = b['inverse'] ^ b['carry'] + b['carry'] &= b['inverse'] + self.gates['and'] += 1 + self.gates['xor'] += 1 + elif action == 'carry-one': + b['carry'] = 1 + elif action == 'save-branch': + b['branch'] = b['input'] + elif action == 'save-pending': + b['pending'] = b['input'] + else: + require(action == 'reset', 'unknown Boolean action') + for name in REGISTERS: + b[name] = int(name == 'one') + + def seek(self, role, target): + position = self.c[role + '-pos'] + for _unused in range(self.limit + 1): + relation = position.compare(target) + if not relation: + return + direction = -1 if relation > 0 else 1 + self.emit('move', role, direction) + position.change(direction < 0) + raise ValueError('data seek budget exhausted') + + def input_slot(self): + if self.first: + self.first = False + else: + self.emit('move', 'address', 1) + self.c['address-pos'].change() + self.emit('read', 'address', 'input') + + def parse(self): + self.descriptor.move(1) + for field in ('ell', 'k', 'h'): + for _unused in range(self.width): + token = self.descriptor.read() + self.descriptor.move(1) + if token == '#': + break + require(token == '1', 'invalid unary symbol') + self.c[field].change() + else: + raise ValueError('unterminated unary field') + # The finite direction flag is read from the actual descriptor. + for _unused in range(self.width): + if self.descriptor.read() == '#': + self.descriptor.move(1) + self.opposite = self.descriptor.read() == '+' + break + self.descriptor.move(1) + else: + raise ValueError('unterminated axes') + self.c['upper'].copy(self.c['ell']) + self.c['upper'].change(True) + self.c['b'].copy(self.c['upper']) + for _unused in range(self.width): + if self.c['b'].compare(self.c['k']) < 0: + break + self.c['b'].sub(self.c['k']) + self.c['q'].change() + else: + raise ValueError('division budget exhausted') + if self.c['h'].compare(self.c['upper']) < 0 and self.c['b'].compare(self.c['h']) <= 0: + self.c['a'].copy(self.c['b']) + self.c['stride'].copy(self.c['a']) + if self.c['stride'].compare(self.c['zero']) == 0: + self.c['stride'].change() + for long in self.axes(): + if self.c['h'].compare(self.c['upper']) < 0 or long: + self.c['bank-size'].add(self.c['stride']) + if self.c['bank-size'].compare(self.c['zero']) == 0: + self.c['bank-size'].change() + self.c['total-size'].copy(self.c['h']) + self.c['total-size'].change() + + def axes(self): + # Marker scans, not a retained axis/participation table. + for _unused in range(self.width): + if self.descriptor.read() == '^': + break + self.descriptor.move(-1) + fields = 0 + for _unused in range(self.width): + if self.descriptor.read() == '#': + fields += 1 + self.descriptor.move(1) + if fields == 3: + break + for _unused in range(self.width): + token = self.descriptor.read() + if token == '#': + return + yield token == 'L' + self.descriptor.move(1) + raise ValueError('axis scan budget exhausted') + + def add(self): + self.emit('gate', 'mask', 0) + self.c['j'].copy(self.c['v']) + for _unused in range(self.width): + self.seek('total', self.c['j']) + self.emit('read', 'total', 'old') + self.emit('gate', 'ripple', 0) + self.emit('write', 'total', 'inverse') + if self.c['j'].compare(self.c['h']) == 0: + return + self.c['j'].change() + raise ValueError('ripple budget exhausted') + + def consume(self, active): + self.input_slot() + if not active: + return + c = self.c + if c['v'].compare(c['a']) < 0: + c['target'].copy(c['base']) + c['target'].add(c['v']) + self.seek('bank', c['target']) + self.emit('write', 'bank', 'input') + elif c['v'].compare(c['h']) == 0: + self.emit('gate', 'save-branch', 0) + c['low'].zero() + for _unused in range(self.width): + if c['low'].compare(c['a']) == 0: + break + c['target'].copy(c['base']) + c['target'].add(c['low']) + self.seek('bank', c['target']) + self.emit('read', 'bank', 'pending') + self.emit('write', 'bank', 'zero') + c['target'].copy(c['v']) + c['v'].copy(c['low']) + self.add() + c['v'].copy(c['target']) + c['low'].change() + self.seek('bank', c['base']) + self.emit('write', 'bank', 'branch') + elif c['v'].compare(c['h']) < 0: + self.seek('bank', c['base']) + self.emit('read', 'bank', 'branch') + self.emit('gate', 'save-pending', 0) + self.add() + + def schedule(self): + c = self.c + c['v'].copy(c['upper']) + c['base'].zero() + for long in self.axes(): + if long: + self.consume(True) + c['base'].add(c['stride']) + c['v'].copy(c['b']) + for _unused in range(self.width): + if c['v'].compare(c['zero']) == 0: + break + c['v'].change(True) + c['base'].zero() + for long in self.axes(): + active = c['h'].compare(c['upper']) < 0 or long + self.consume(active) + if active: + c['base'].add(c['stride']) + c['upper'].change(True) + for _unused in range(self.width): + if c['q'].compare(c['zero']) == 0: + return + c['lower'].copy(c['upper']) + c['lower'].change() + c['lower'].sub(c['k']) + c['base'].zero() + for long in self.axes(): + c['v'].copy(c['upper']) + for _step in range(self.width): + # Top-round participation is recovered without an axis index. + c['target'].copy(c['ell']) + c['target'].change(True) + active = c['h'].compare(c['target']) < 0 or long + self.consume(active) + if c['v'].compare(c['lower']) == 0: + break + c['v'].change(True) + else: + raise ValueError('chunk budget exhausted') + if active: + c['base'].add(c['stride']) + c['q'].change(True) + if c['q'].compare(c['zero']) > 0: + c['upper'].sub(c['k']) + raise ValueError('chunk count budget exhausted') + + def finish(self): + c = self.c + if not self.opposite and c['h'].compare(c['zero']) > 0: + self.emit('gate', 'carry-one', 0) + c['j'].zero() + for _unused in range(self.width): + self.seek('total', c['j']) + self.emit('read', 'total', 'old') + self.emit('gate', 'invert', 0) + self.emit('gate', 'negate', 0) + self.emit('write', 'total', 'old') + if c['j'].compare(c['h']) == 0: + break + c['j'].change() + c['v'].copy(c['h']) + c['j'].zero() + for _unused in range(self.width): + self.seek('output', c['j']) + if c['j'].compare(c['h']) <= 0: + self.seek('total', c['v']) + self.emit('read', 'total', 'old') + self.emit('write', 'output', 'old') + if c['v'].compare(c['zero']) > 0: + c['v'].change(True) + else: + self.emit('write', 'output', 'zero') + if c['j'].compare(c['ell']) == 0: + return + c['j'].change() + raise ValueError('output budget exhausted') + + def execute(self): + self.parse() + self.schedule() + self.finish() + for role in ('bank', 'total'): + self.c['j'].zero() + for _unused in range(self.limit): + if self.c['j'].compare(self.c[role + '-size']) == 0: + break + self.seek(role, self.c['j']) + self.emit('write', role, 'zero') + self.c['j'].change() + else: + raise ValueError('erasure budget exhausted') + for role in ROLES: + self.seek(role, self.c['zero']) + for _unused in range(self.width): + if self.descriptor.read() == '^': + break + self.descriptor.move(-1) + for counter in self.c.values(): + counter.erase() + self.emit('gate', 'reset', 0) + + def invoice(self): + return {'data': {role: dict(tape.counts) for role, tape in self.data.items()}, + 'control_tape_actions': sum(sum(c.tape.counts.values()) for c in self.c.values()), + 'descriptor_actions': sum(self.descriptor.counts.values()), + 'data_cells': sum(len(t.cells) for t in self.data.values()), + 'control_cells': len(self.c) * (self.width + 2), + 'descriptor_cells': len(self.descriptor.cells), 'gates': dict(self.gates)} diff --git a/research/twiddle-matched-layer/diagonal/upstream/pass.py b/research/twiddle-matched-layer/diagonal/upstream/pass.py new file mode 100644 index 0000000000..569aa79350 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/upstream/pass.py @@ -0,0 +1,240 @@ +"""Encoded fixed-round twiddle diagonal pass on one complete physical cube. + +SPDX-License-Identifier: Apache-2.0 +Sagar Thakrar, with substantial OpenAI Codex assistance. +Nick Petalas supplied the unchanged PR3593 producer; the unchanged PR3611 +consumer retains its source notices. No inherited execution body is edited. +""" +from collections import Counter + + +def require(ok, why): + if not ok: + raise ValueError(why) + + +class DiagonalPass: + """Valid-admission, one-shot pass; successful return is the proved contract. + + Constructor dimensions provision blank storage and admitted input only. + Runtime extents come from descriptors, framed packets and the unary guide. + Malformed-input recovery and exceptional interruption are not promised. + """ + def __init__(self, producer_module, consumer_module, descriptor, width, source): + # Admission/allocation only. No host dimensions are retained by Pass. + ell, _, _, axes, _ = producer_module.admit(descriptor, tuple( + 0 for axis in descriptor.split('#')[3] + for _ in range(len(descriptor.split('#')[0]) - (axis == 'S')))) + A = sum(ell if axis else ell-1 for axis in axes) + L = 2 * (1 << ell) * width + self.producer = producer_module.Controller(descriptor, (0,)*A) + self.consumer = consumer_module.Consumer(ell, width) + T = consumer_module.Tape + self.tapes = dict(fullinput=T(source), fulloutput=T((0,)*(2+(1 << A)*(L+2))), + unaryA=T((0,)*(A+2)), unaryell=T((0,)*(ell+2)), + width=T('^'+'1'*width+'$'), packet=T((0,)*(L+2)), + descriptor=self.producer.descriptor, + address=self.producer.data['address'], header=self.producer.data['output']) + self.gates = Counter() + self.actions = Counter() + self.used = False + + def test(self, value): + self.gates['test'] += 1 + return value + + def read(self, role): + self.actions[role+'.read'] += 1 + return self.tapes[role].read() + + def write(self, role, value): + self.actions[role+'.write'] += 1 + self.tapes[role].write(value) + + def move(self, role, direction): + self.actions[role+'.move'] += 1 + self.tapes[role].move(direction) + + def home(self, role, marker='^'): + while self.test(self.read(role) != marker): + self.move(role, -1) + + def clear_frame(self, role): + self.home(role) + self.move(role, 1) + while self.test(self.read(role) != '$'): + self.write(role, 0) + self.move(role, 1) + self.write(role, 0) + self.move(role, -1) + while self.test(self.read(role) != '^'): + self.write(role, 0) + self.move(role, -1) + self.write(role, 0) + + def address_home(self): + # Guide and raw address point to corresponding bits, except '^' at0. + while self.test(self.read('unaryA') == '1'): + self.move('unaryA', -1) + if self.test(self.read('unaryA') != '^'): + self.move('address', -1) + + def initialize(self): + require(self.test(self.read('descriptor') == '^'), 'descriptor start') + self.write('unaryell', '^') + self.move('unaryell', 1) + self.move('descriptor', 1) + while self.test(self.read('descriptor') == '1'): + self.write('unaryell', '1') + self.move('unaryell', 1) + self.move('descriptor', 1) + require(self.test(self.read('descriptor') == '#'), 'ell delimiter') + self.write('unaryell', '$') + self.home('unaryell') + # Skip the two remaining unary fields; fixed finite control sequence. + for _field in ('K', 'h'): + self.move('descriptor', 1) + while self.test(self.read('descriptor') != '#'): + self.move('descriptor', 1) + self.move('descriptor', 1) + self.write('unaryA', '^') + self.move('unaryA', 1) + first = True + while self.test(self.read('descriptor') != '#'): + flag = self.read('descriptor') + require(self.test(flag in ('L', 'S')), 'axis flag') + self.move('unaryell', 1) + if self.test(flag == 'S'): + self.move('unaryell', 1) + while self.test(self.read('unaryell') == '1'): + self.write('unaryA', '1') + self.move('unaryA', 1) + if self.test(not first): + self.move('address', 1) + self.write('address', 0) + first = False + self.move('unaryell', 1) + self.home('unaryell') + self.move('descriptor', 1) + self.write('unaryA', '$') + self.move('unaryA', -1) + self.address_home() + self.home('descriptor') + require(self.test(self.read('fullinput') == '@'), 'full input start') + self.move('fullinput', 1) + self.write('fulloutput', '@') + self.move('fulloutput', 1) + + def rearm_producer(self): + for name in self.producer.NAMES: + tape = self.producer.c[name].tape + self.tapes['counter'] = tape + self.write('counter', 2) + self.move('counter', 1) + while True: + token = self.read('descriptor') + self.write('counter', 0) + self.move('counter', 1) + if self.test(token == '$'): + break + self.move('descriptor', 1) + self.write('counter', 3) + while self.test(self.read('counter') != 2): + self.move('counter', -1) + self.home('descriptor') + self.gates['reset-first'] += 1 + self.producer.first = True + + def clear_header(self): + self.write('header', 0) + self.move('unaryell', 1) + while self.test(self.read('unaryell') == '1'): + self.move('header', 1) + self.write('header', 0) + self.move('unaryell', 1) + self.move('unaryell', -1) + while self.test(self.read('unaryell') == '1'): + self.move('header', -1) + self.move('unaryell', -1) + + def load_packet(self): + require(self.test(self.read('fullinput') == '^'), 'next complete packet') + self.write('packet', '^') + self.move('packet', 1) + self.move('fullinput', 1) + while self.test(self.read('fullinput') != '$'): + value = self.read('fullinput') + require(self.test(value in (0, 1)), 'packet bit') + self.write('packet', value) + self.move('packet', 1) + self.move('fullinput', 1) + self.write('packet', '$') + self.move('fullinput', 1) + self.home('packet') + + def append_packet(self, output): + self.tapes['returned'] = output + require(self.test(self.read('returned') == '^'), 'returned packet origin') + self.write('fulloutput', '^') + self.move('fulloutput', 1) + self.move('returned', 1) + while self.test(self.read('returned') != '$'): + self.write('fulloutput', self.read('returned')) + self.move('fulloutput', 1) + self.move('returned', 1) + self.write('fulloutput', '$') + self.move('fulloutput', 1) + self.home('returned') + + def increment(self): + # Reach the raw final address bit using the unary guide only. + self.move('unaryA', 1) + first = True + while self.test(self.read('unaryA') == '1'): + if self.test(not first): + self.move('address', 1) + first = False + self.move('unaryA', 1) + self.move('unaryA', -1) + carry = True + while self.test(self.read('unaryA') == '1'): + old = self.read('address') + self.gates['flip'] += 1 + self.write('address', 1-old) + if self.test(old == 0): + carry = False + break + self.move('unaryA', -1) + if self.test(self.read('unaryA') != '^'): + self.move('address', -1) + self.address_home() + return carry + + def run(self): + require(not self.used, 'one-shot full pass') + self.used = True + self.initialize() + first = True + while True: + if self.test(not first): + self.rearm_producer() + first = False + self.load_packet() + self.producer.execute() + result = self.consumer.run(self.tapes['header'], self.tapes['descriptor'], + self.tapes['width'], self.tapes['packet']) + self.append_packet(result) + self.consumer.clear('output') + self.gates['consumer-rearm'] += 1 + self.consumer.used = False + self.clear_frame('packet') + self.clear_header() + if self.test(self.increment()): + break + require(self.test(self.read('fullinput') == '!'), 'full cube packet extent') + self.write('fulloutput', '!') + self.home('fullinput', '@') + self.home('fulloutput', '@') + self.clear_frame('unaryA') + self.clear_frame('unaryell') + return self.tapes['fulloutput'] diff --git a/research/twiddle-matched-layer/diagonal/upstream/verify.py b/research/twiddle-matched-layer/diagonal/upstream/verify.py new file mode 100644 index 0000000000..50bda4b5c0 --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/upstream/verify.py @@ -0,0 +1,360 @@ +#!/usr/bin/env python3 +"""Independent complete-cube oracle and physical-boundary checks. + +SPDX-License-Identifier: Apache-2.0 +Sagar Thakrar, with substantial OpenAI Codex assistance. +Named-slot and polynomial oracles retain Nick Petalas's transform lineage. +Instrumentation below is checker-only; it supplies no production decision. +""" +from collections import Counter +from contextlib import ExitStack +import ast +import hashlib +import json +from pathlib import Path +import sys +from types import ModuleType +from unittest.mock import patch + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] + + +def require(ok, why): + if not ok: + raise ValueError(why) + + +def digest(value): + return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(",", ":")).encode()).hexdigest() + + +def authenticate(): + manifest = json.loads((HERE / "SOURCES.json").read_text()) + result = {} + entries = [(ROOT, x) for x in manifest["files"] if x["usage"] == "input"] + entries += [(HERE, x) for x in manifest["frozen_sources"]] + for base, row in entries: + raw = (base / row["path"]).read_bytes() + require(hashlib.sha256(raw).hexdigest() == row["sha256"], "source authentication: " + row["path"]) + result[row["path"]] = row["sha256"] + return result + + +def load(name, path): + module = ModuleType(name) + module.__file__ = str(HERE / path) + exec(compile((HERE / path).read_bytes(), module.__file__, "exec"), module.__dict__) + return module + + +def slots(ell, K, axes): + """Independent source formula, not a call into the producer scheduler.""" + b = (ell - 1) % K + ordered = [(i, ell - 1) for i, long in enumerate(axes) if long] + ordered += [(i, bit) for bit in range(b - 1, -1, -1) for i in range(len(axes))] + for top in range(ell - 2, b - 1, -K): + ordered += [(i, bit) for i in range(len(axes)) for bit in range(top, top - K, -1)] + expected = {(i, bit) for i, long in enumerate(axes) for bit in range(ell if long else ell - 1)} + require(len(ordered) == len(expected) and set(ordered) == expected, "literal source-slot bijection") + return ordered + + +def exponent(address, names, ell, h, axes, opposite): + bits = [(address >> (len(names) - 1 - j)) & 1 for j in range(len(names))] + named = dict(zip(names, bits)) + total = sum(named[i, h] * sum((1 << bit) * named[i, bit] for bit in range(h)) + for i, long in enumerate(axes) if h < (ell if long else ell - 1)) + return ((1 if opposite else -1) * (1 << (ell - h)) * total) % (1 << (ell + 1)), bits + + +def packet(address, r, width): + """Diverse bounded data; address and coefficient affect both components.""" + cap = (1 << (width - 1)) - 1 + modulus = 2 * cap + 1 + return [((3 * address + 5 * j + address * j) % modulus - cap, + (7 * address - 3 * j + 2 * address * j + 1) % modulus - cap) + for j in range(r)] + + +def encode(values, width): + return [((value >> bit) & 1) for pair in values for value in pair for bit in range(width - 1, -1, -1)] + + +def rotate(values, E): + """Coefficient destination/sign identity, independent of two-buffer split.""" + r = len(values) + result = [None] * r + for j, pair in enumerate(values): + quotient, target = divmod(j + E, r) + sign = -1 if quotient % 2 else 1 + result[target] = tuple(sign * x for x in pair) + return result + + +def inventory(machine): + result = {} + candidates = [*machine.producer.data.values(), machine.producer.descriptor, + *(c.tape for c in machine.producer.c.values()), + *machine.consumer.tapes.values(), *machine.tapes.values()] + for tape in candidates: + result[id(tape)] = tape + return result + + +def no_new_tape(*_args, **_kwargs): + raise ValueError("runtime allocated a replacement tape") + + +def run_case(adapter, producer, consumer, shape, source_override=None): + ell, K, h, axes, opposite, width = shape + names = slots(ell, K, axes) + A, r = len(names), 1 << ell + N = 1 << A + descriptor = "1" * ell + "#" + "1" * K + "#" + "1" * h + "#" + "".join( + "L" if x else "S" for x in axes) + "#" + ("+" if opposite else "-") + "#" + original_values = [packet(i, r, width) for i in range(N)] + source = ["@"] + expected = ["@"] + residues = [] + for i, values in enumerate(original_values): + E, _bits = exponent(i, names, ell, h, axes, opposite) + residues.append(E) + source.extend(["^", *encode(values, width), "$"]) + expected.extend(["^", *encode(rotate(values, E), width), "$"]) + source.append("!") + expected.append("!") + if source_override is not None: + # For inverse replay, decode each actual returned record in the checker. + source = list(source_override) + require(source[0] == "@" and source[-1] == "!", "inverse stream framing") + original_values = [] + expected = ["@"] + offset = 1 + for i in range(N): + require(source[offset] == "^", "inverse packet start") + offset += 1 + values = [] + for _j in range(r): + pair = [] + for _component in range(2): + word = source[offset:offset + width] + require(len(word) == width and all(x in (0, 1) for x in word), "inverse signed word") + value = sum(bit << (width - 1 - j) for j, bit in enumerate(word)) + if word[0]: + value -= 1 << width + pair.append(value) + offset += width + values.append(tuple(pair)) + require(source[offset] == "$", "inverse packet end") + offset += 1 + original_values.append(values) + expected.extend(["^", *encode(rotate(values, residues[i]), width), "$"]) + require(offset == len(source) - 1, "inverse complete cube") + expected.append("!") + + observed = Counter() + adapter_calls = Counter() + consumer_calls = Counter() + with ExitStack() as instrumentation: + for cls in (producer.Tape, consumer.Tape): + for method in ("read", "write", "move"): + original = getattr(cls, method) + + def counted(self, *args, _original=original, _method=method): + value = _original(self, *args) + observed[id(self), _method] += 1 + return value + + instrumentation.enter_context(patch.object(cls, method, counted)) + for cls, counter in ((adapter.DiagonalPass, adapter_calls), (consumer.Consumer, consumer_calls)): + for method in ("read", "write", "move"): + original = getattr(cls, method) + + def counted_role(self, role, *args, _original=original, _method=method, _counter=counter): + value = _original(self, role, *args) + _counter[role + "." + _method] += 1 + return value + + instrumentation.enter_context(patch.object(cls, method, counted_role)) + machine = adapter.DiagonalPass(producer, consumer, descriptor, width, source) + initial = inventory(machine) + require(len(initial) == 38, "fixed 38-role inventory") + require(len({id(t.cells) for t in initial.values()}) == 38, "distinct tape backing") + identities = set(initial) + capacities = {key: len(tape.cells) for key, tape in initial.items()} + borrowed = (machine.tapes["fullinput"], machine.tapes["width"], machine.tapes["descriptor"]) + snapshots = [list(tape.cells) for tape in borrowed] + events = {"produced": 0, "consumed": 0} + header_hash = hashlib.sha256() + execute = machine.producer.execute + consume = machine.consumer.run + + def checked_execute(): + index = events["produced"] + require(index < N and index == events["consumed"], "one producer per physical packet") + require(set(inventory(machine)) == identities, "stable physical tape identities") + E, bits = exponent(index, names, ell, h, axes, opposite) + require(machine.producer.data["address"] is machine.tapes["address"], "actual odometer address alias") + require(machine.tapes["address"].cells == bits and machine.tapes["address"].head == 0, + "complete physical address sequence") + require(all(c.tape.cells[0] == 2 and c.tape.cells[-1] == 3 and c.tape.head == 0 + for c in machine.producer.c.values()), "encoded producer counter rearm") + execute() + header = machine.tapes["header"] + require(header.cells == [(E >> bit) & 1 for bit in range(ell, -1, -1)] and header.head == 0, + "independent named-coordinate header") + require(machine.producer.trace is None, "no retained producer instruction history") + header_hash.update(bytes(header.cells)) + events["produced"] += 1 + + def checked_consume(header, desc, width_desc, source_packet): + index = events["consumed"] + require(events["produced"] == index + 1 and index < N, "actual header/packet pairing") + require(header is machine.producer.data["output"] and desc is machine.producer.descriptor, + "actual producer output borrowed") + require(width_desc is machine.tapes["width"] and source_packet is machine.tapes["packet"], + "actual extracted packet borrowed") + require(source_packet.cells == ["^", *encode(original_values[index], width), "$"], + "packet extraction keeps source order") + result = consume(header, desc, width_desc, source_packet) + bits = encode(rotate(original_values[index], residues[index]), width) + require(result.cells == ["^", *bits, "$", "!"] and result.head == 0, + "literal signed packet endpoint") + events["consumed"] += 1 + return result + + machine.producer.execute = checked_execute + machine.consumer.run = checked_consume + with patch.object(producer.Tape, "__init__", no_new_tape), patch.object(consumer.Tape, "__init__", no_new_tape): + output = machine.run() + require(events == {"produced": N, "consumed": N}, "complete full-wrap packet count") + require(output is machine.tapes["fulloutput"] and output.cells == expected, "complete diagonal stream endpoint") + require(all(tape.cells == original for tape, original in zip(borrowed, snapshots)), "borrowed stream/descriptors preserved") + final = inventory(machine) + require(set(final) == identities and all(len(t.cells) == capacities[key] for key, t in final.items()), + "no tape replacement or growth") + require(all(tape.head == 0 for tape in final.values()), "all 38 heads returned") + retained = {id(output), *(id(tape) for tape in borrowed)} + require(all(not any(tape.cells) for key, tape in final.items() if key not in retained), "all private roles blank") + require(machine.gates["flip"] == 2 * N - 2 and machine.gates["consumer-rearm"] == N + and machine.gates["reset-first"] == N - 1, "full-wrap/rearm gate census") + require(dict(machine.actions) == dict(adapter_calls), "adapter action invoice reconciliation") + require({k: v for k, v in machine.consumer.invoice.items() if "." in k} == dict(consumer_calls), + "consumer action invoice reconciliation") + require(machine.consumer.invoice["gate"] == sum(machine.consumer.gates.values()), "consumer gate reconciliation") + actual = Counter() + for key, tape in final.items(): + for operation in ("read", "write", "move"): + require(tape.counts[operation] == observed[key, operation], "primitive operation observation reconciliation") + actual[operation] += tape.counts[operation] + gates = sum(machine.gates.values()) + sum(machine.producer.gates.values()) + sum(machine.consumer.gates.values()) + total = sum(actual.values()) + gates + full_cells = len(machine.tapes["fullinput"].cells) + len(output.cells) + all_cells = sum(capacities.values()) + Q = ell + K + h + len(axes) + 6 + b = (ell - 1) % K + a = b if b <= h < ell - 1 else 0 + participating = sum(h < (ell if long else ell - 1) for long in axes) + bank = max(1, participating * max(a, 1)) + producer_cells = A + bank + (h + 1) + ell + 1 + 22 * Q + 86 + B = 2 * r * width + expected_cells = producer_cells + 2 * N * (B + 2) + 4 * B + 2 * width + A + 3 * ell + 32 + expected_auxiliary = producer_cells + 4 * B + 2 * width + A + 3 * ell + 28 + require(all_cells == expected_cells and all_cells - full_cells == expected_auxiliary, + "exact physical capacity formula") + require(len(machine.producer.c) == 21 and machine.producer.trace is None + and len(machine.tapes) <= 11 and len(machine.consumer.tapes) == 10, "fixed control dictionaries/no histories") + receipt = dict(shape=dict(ell=ell, K=K, h=h, axes=list(axes), opposite=opposite, width=width), + records=N, address_bits=A, roles=38, cells=all_cells, full_stream_cells=full_cells, + auxiliary_cells=all_cells - full_cells, physical_operations=dict(actual), + gate_operations=gates, total_tariff=total, adapter_gates=dict(machine.gates), + adapter_actions=dict(machine.actions), consumer_gates=dict(machine.consumer.gates), + producer_gates=dict(machine.producer.gates), headers_sha256=header_hash.hexdigest(), + source_sha256=digest(source), output_sha256=digest(output.cells)) + return receipt, list(output.cells) + + +def rejects(call, text): + try: + call() + except ValueError as error: + require(text in str(error), "unexpected control diagnostic: " + str(error)) + return str(error) + raise ValueError("control was accepted: " + text) + + +def controls(adapter, producer, consumer): + raw = (HERE / "pass.py").read_text() + mutations = ( + ("no_odometer_flip", "self.write('address', 1-old)", "self.write('address', old)", "complete physical address sequence"), + ("no_counter_rearm", "self.rearm_producer()", "pass", "encoded producer counter rearm"), + ("consumer_left_used", "self.consumer.used = False", "self.consumer.used = True", "one-shot consumer"), + ("header_not_cleared", "self.clear_header()", "pass", "all private roles blank"), + ("early_fullwrap", "if self.test(self.increment()):", "if self.test(not self.increment()):", "full cube packet extent"), + ("uncharged_adapter_move", "self.actions[role+'.move'] += 1", "self.actions[role+'.move'] += 0", "adapter action invoice reconciliation"), + ) + results = [] + for name, old, new, diagnostic in mutations: + require(raw.count(old) == 1, "unique actual mutation site: " + name) + changed = raw.replace(old, new) + module = ModuleType("diagonal_pass_mutant") + module.__file__ = str(HERE / "pass.py") + exec(compile(changed, module.__file__, "exec"), module.__dict__) + failure = rejects(lambda: run_case(module, producer, consumer, (2, 1, 1, (True,), False, 4)), diagnostic) + results.append(dict(name=name, diagnostic=failure, mutated_sha256=hashlib.sha256(changed.encode()).hexdigest())) + return results + + +def static_boundary(): + tree = ast.parse((HERE / "pass.py").read_text()) + cls = next(x for x in tree.body if isinstance(x, ast.ClassDef) and x.name == "DiagonalPass") + methods = [x for x in cls.body if isinstance(x, ast.FunctionDef) and x.name != "__init__"] + require(not any(isinstance(x, ast.Attribute) and x.attr in ("cells", "head", "capacities") + for method in methods for x in ast.walk(method)), "adapter bypasses physical tape API") + require(not any(isinstance(x, ast.Call) and isinstance(x.func, ast.Name) and x.func.id == "range" + for method in methods for x in ast.walk(method)), "runtime host-counted range") + return "Runtime accesses only tape primitives; no host-counted ranges, cell indexing or head inspection." + + +def build(include_large=True): + sources = authenticate() + producer = load("diagonal_retained_producer", "inputs/controller.py") + consumer = load("diagonal_retained_consumer", "inputs/consumer.py") + adapter = load("diagonal_adapter", "pass.py") + evidence = [] + small = (3, 2, 1, (True, False), False, 4) + first, stream = run_case(adapter, producer, consumer, small) + evidence.append(first) + inverse, returned = run_case(adapter, producer, consumer, (*small[:4], True, small[5]), stream) + require(digest(returned) == first["source_sha256"], "actual full-pass opposite round trip") + evidence.append(inverse) + for shape in ((4, 2, 2, (True,), False, 4), (3, 2, 2, (False,), False, 3), + (2, 1, 0, (True, False), True, 3)): + receipt, _ = run_case(adapter, producer, consumer, shape) + evidence.append(receipt) + negative = controls(adapter, producer, consumer) + if include_large: + receipt, _ = run_case(adapter, producer, consumer, (6, 2, 4, (True, False), False, 4)) + evidence.append(receipt) + return dict(status="PASS_ENCODED_TWIDDLE_DIAGONAL", source_sha256=sources, + physical_boundary=static_boundary(), complete_cube_cases=evidence, controls=negative, + roundtrip="Actual complete32-record forward output consumed by opposite pass, with original input recovered.", + instrumentation="Checker-only bounded counters wrap primitives and call boundaries; no production scheduling decisions or histories supplied.", + limitations=["Valid already-positioned complete cubes and represented signed negations only.", + "No butterfly, relocation, normalization, rounding or complete supplier."]) + + +def main(): + args = sys.argv[1:] + require(args in ([], ["--emit"], ["--small"]), "usage: verify.py [--emit|--small]") + result = build(args != ["--small"]) + if args: + print(json.dumps(result, sort_keys=True, indent=2)) + else: + require(result == json.loads((HERE / "RESULT.json").read_text()), "frozen receipt mismatch") + print(result["status"]) + + +if __name__ == "__main__": + main() diff --git a/research/twiddle-matched-layer/diagonal/verify.py b/research/twiddle-matched-layer/diagonal/verify.py new file mode 100644 index 0000000000..2d51e6f63b --- /dev/null +++ b/research/twiddle-matched-layer/diagonal/verify.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +"""Strict source and receipt wrapper for the PR3617 caller corroboration. + +Clear1nsight, with substantial OpenAI assistance. Apache-2.0. +The physical diagonal is real; H, rounding, and layout are arithmetic oracles. +""" + +from hashlib import sha256 +import importlib.util +import json +from pathlib import Path +import sys + +ROOT = Path(__file__).resolve().parent +INVENTORY_SHA256 = "9e0f618b7207d76f7942e67d5324dc542932d631c741de26b91c47521cdce7df" +LAYER_SHA256 = "33f91624d60be8c7124ecc24be073f8a5a3759b671979b6a17a6e26538f4355e" + + +def load(name, path): + spec = importlib.util.spec_from_file_location(name, path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def main(): + strict = load("strict_matched_layer_receipt", ROOT.parent / "verify.py") + raw = (ROOT / "SOURCE_INVENTORY.json").read_bytes() + strict.need(sha256(raw).hexdigest() == INVENTORY_SHA256, "diagonal source inventory hash") + path = ROOT.parent / "check_join.py" + strict.need(sha256(path.read_bytes()).hexdigest() == LAYER_SHA256, + "frozen arithmetic layer hash") + layer = load("frozen_layer_arithmetic", path) + join = load("diagonal_caller_corroboration", ROOT / "check_3617_join.py") + actual = json.loads(json.dumps(join.run(layer), sort_keys=True)) + stored = json.loads((ROOT / "RECEIPT.json").read_bytes(), object_pairs_hook=strict.unique) + strict.compare(actual, stored) + print("PASS_TWIDDLE_DIAGONAL_CALLER: 12 completed arithmetic-H rounds with " + "384 actual diagonal packets, plus wrong-K control; no physical H/root, " + "all-round reuse, complete invoice or supplier admission") + + +if __name__ == "__main__": + try: + main() + except (ValueError, OSError) as error: + print("FAIL_TWIDDLE_DIAGONAL_CALLER: " + str(error), file=sys.stderr) + raise SystemExit(1) diff --git a/research/twiddle-matched-layer/pr2298-PROOF.md b/research/twiddle-matched-layer/pr2298-PROOF.md new file mode 100644 index 0000000000..f26af67ae1 --- /dev/null +++ b/research/twiddle-matched-layer/pr2298-PROOF.md @@ -0,0 +1,373 @@ +# Conservative outer transfer for the selected callees + +We give a complete outer caller for two pending selected constructions: +PR2234 at `d047ef86fbc5b1614d3d8e2b8d3441413beab73f` and PR2287 at +`8c60765b5dea9d862b3b190d55da102a576031bf`. We retain the original +FFT, Gaussian, packing and recovery arguments in source sections 06–08, +and Douglas Colkitt's nonadjacent-axis schedule. We instantiate their +interfaces below; we do not claim those inherited methods as new. + +**Transfer theorem.** Under the completed ordinary-interchange and +complex-layer construction contracts specified in section 1, the caller +multiplies two n-bit binary integers in a fixed multitape model in + + O(n (log n)^(1-1/20000000)) + +time, with exact 2n-bit output, including leading zeros. We use published +analytic algorithms as described in section 5. The pending selected +callee proofs still require independent review. This is a proposed +composition, not an independently verified unconditional multiplication +theorem or a replacement selected frontier. In particular, our finite +tests do not execute the enormous recursive suppliers or Gaussian maps. + +## 1. Callee admission and the dimension extension + +PR2234 supplies ordinary interchange of two complete E-bit fields in +`O(V E^tau)` time, where `tau=99830289/100000000`. The caller may supply +arbitrary complete preceding, intervening and following fields and +arbitrary payload. The callee preserves payload, restores spectators, +clears work and returns its heads. V is the complete logical bit volume. +For E=0 we use the identity. We use the elementary linear-time bit move +for a one-bit difference between field widths. We do not expose a weighted +or radix-q internal operation to this outer caller. + +PR2287 proposes an exact complex C tensor, its normalized H0 tensor, +and an optional final p-grid truncation, with + + H0 = [[1,1],[1,-1]]/2, cost O(V d^lambdaPrime), + lambdaPrime=599/600, c=1/500, K=floor(d^c). + +Its literal statement fixes dimension exponent 997/1000. We need a +separate extension to `epsilon=1/40`, not an invocation of that statement +with different inputs. We retain its algorithm, finite words, row reserve, +proper-width induction, global compact parameters and one root grid. +We replace only `d=floor(p^(997/1000))` by `d=floor(p^(1/40))`. + +In that proof the dimension exponent enters through these conditions: + + d=Theta(p^epsilon), 1-epsilon(1+c)>0, + 1-epsilon>0, epsilon*c>0. + +For our choice the three gaps are `19499/20000`, `39/40` and `1/20000`. +The new long-record range `r=2^Theta(p/d)` still exceeds every fixed +polynomial in p. The guard `Delta=2^210000*d` is still o(p). The row +reserve has O(log d) selected axes; the compact reserve has +`O(d^(1-c) log p)` selected axes. Neither changes its exponent or constant +when we lower epsilon. We keep the selected axes at the same offset in +consecutive K-bit chunks and retain complete spectators. + +The internal, leaf and reservation exponents in PR2287 remain + + 99832997289/10^11, 99833167/10^8, 499/500, + +each below `lambda=249583/250000=2^40`, which ensures d>=2. +For b>=3, `(6b)^3<=b^10`, hence `d<=b^(1/12)`. + +Put `alpha=ceil((12d^2 b)^(1/4))`, `gamma=2d alpha^2` and `eta=1/(4d)`. +The elementary ceiling bounds give + + alpha<=2(12d^2 b)^(1/4), + gamma<28d^2 sqrt(b)<32b^(11/20). + +For the last inequality use `6^(1/20)<8/7`, which follows by taking +twentieth powers. Thus `2<=alpha=2^24 recovery threshold also has enough room +for the last gamma bound. We retain separate layer and prime thresholds. + +For each target length t_i choose a distinct odd prime satisfying + + (1-2eta)t_i < s_i <= (1-eta)t_i. + +Harvey–van der Hoeven's Lemma 5.1 supplies at least +`eta*x/(2 log x)` primes in this interval when `x>exp(2/eta)`. +Here `log(r/2)/d=Theta(p^(19/20))` tends to infinity, and each interval +eventually contains more than d primes. The r/2 and r intervals are +disjoint. We need no short-interval prime theorem. Trial division over +both intervals costs `O(d r^(3/2) poly(p))=n^o(1)` and generates the +primes without advice. + +Write S=product(s_i). Strict Bernoulli gives `T/21/(4d)`, so `alpha^4 theta_i>3db>=p`. +Also `gcd(s_i,t_i)=1` and `t_i<2^p`. These are the complete domain +conditions of the original one-dimensional Gaussian interface. + +For q=ceil(n/b), the input radix polynomials have degree q-1, with +digits in `[0,2^b)`. Their product degree is at most +`2q-2<2n/b<=T/2 e y G x -> y G e x, + x G e y -> e x G y -> e y G x. + +Each line uses one completed equal-width interchange and one elementary +bit move. G includes the complete intervening fields. Thus a reversal +costs `O(V d(1+ell^tau))`. Prefix-controlled rotations cost O(dV); +polynomial offset setup per prefix costs `O(dT poly(p)/r)=o(V)`. +For Gaussian axis exposure, exchange that axis with the innermost field, +process its lines, then reverse the same exchange. We retain the source +axis order and truncations, using at most 2(d-1) exchanges per tensor map. +Each inverse uses its actual payload width, which remains O(p). + +For synthetic transforms we use the original exact-K positional layout L +in source06. Move the extra top bits and at most K-1 bottom levels to a +prefix, then transpose the equal K-bit chunks to group-major order. This +costs `O(V[dK+p K^(tau-1)])`. The polynomial coefficient suffix remains +contiguous. A round's selected bits have one common offset in D=d-1 +consecutive K-bit chunks, with complete preceding/following fields and +total address length at most d*ell=O(p). The header has O(p) bits. +The extended layer therefore accepts each call. The separate named-slot +table has polynomial size and fits the long-record setup charge. + +We compute prefix rounds with exact elementary H0 kernels and one final +truncation. We process common rounds with the extended selected layer. +For a round at named level h, the monomial exponent is + + E=-sum_i (2r/2^(h+1))*b_i*k_i mod 2r, + k_i=sum_(v=2 and ell, the synthetic +transform error is Q0` and `D<=d` give the same `K>3G` +guard used in PR3477. Eventually `3H=2. Borrowed source rewind, +return rewind and failure clearing are linear in the visited packet. +The buffer occupies O(w) cells, counters use O(log N+log w), and the complete +output occupies V cells. A fixed eight-role scratch pool and one output per +bridge, plus the eight-role wrapper pool, give 26 added tape roles. +The host Tape model can retain historical list capacity; this is an +occupied/visited tape bound, not a claim of host-memory reclamation. + +The bridge validates signed width, positive encoded cardinality, each bit and +the final blank. Truncation, extra bits and an internal nonbit all fail before +a result is returned. Owned buffers and counters close on every exit, input +heads rewind, and failed output is erased. An initial implementation erased +the output marker before rewinding; the malformed-input control exposed that +cleanup defect. The published ordering rewinds before erasing the marker. + +`OuterLayer` plans once to obtain the actual width and complete cardinality, +copies these two encoded counts, clears planning scratch, converts, invokes +the root, then converts the returned packet. It releases its intermediate +packets and counts on success or failure. Root invocation owns its existing +cleanup contract. The caller must consume each output before reuse. +Its extra fixed-degree encoded planning cost is paid by the long record. + +## Consequence for the outer caller and stopping point + +The source-bound outer parameters are exactly PR2298's epsilon=1/40 and +c=1/500. Its narrowest charged saving is still +`epsilon*c*(1-tau)=169711/2000000000000`. The new layer exponent and linear +format passes do not remove this exact-K transposition cost. This package +makes no stronger integer-kappa substitution. It also does not repeat the +released wider-K/weaker-outer optimization in Discussion2291. + +The remaining review is the complete production T74 refinement and inherited +ordinary/native/hosting contracts, followed by the actual outer integration, +its analytic and numerical obligations and end-to-end execution. The finite +checks here use a reduced binding and guard. They verify the boundary itself; +they do not execute O73/GL64-scale native objects or the production guard-sized +payload. Independent human and formal proof-kernel review are unclaimed. diff --git a/research/twiddle-matched-layer/pr3493-outer_layer.py b/research/twiddle-matched-layer/pr3493-outer_layer.py new file mode 100644 index 0000000000..2fc3370ea7 --- /dev/null +++ b/research/twiddle-matched-layer/pr3493-outer_layer.py @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: Apache-2.0 +"""Join an explicitly planned physical root to MSB-first outer packets.""" + +import cohort + +cohort.activate() +from cardinal_counts import Count +from scratch_pool import ScratchPool +from session import OuterScope, erase_marker, sealed_constructors +from word_order import WordOrderBridge +from words import BLANK, need + + +class OuterLayer: + """The supplied root retains responsibility for its native construction.""" + + def __init__(self, root): + need(root.plan.dimension_exponent == (1, 40), "explicit outer root plan") + self.root = root + self.entrance, self.exit = WordOrderBridge(), WordOrderBridge() + self.pool = ScratchPool(8) + self.scope = OuterScope(self.pool) + self.closed = True + + def run( + self, + payload, + precision, + selected, + left, + right, + coefficients, + outer_rows, + residue, + ): + need( + self.closed and self.root.closed and self.exit.output.read() == BLANK, + "consumed complete outer layer", + ) + parameters = ( + precision, + selected, + left, + right, + coefficients, + outer_rows, + residue, + ) + width = gaussians = entry = result = None + self.closed = False + try: + self.root.plan.compute(*parameters) + with sealed_constructors(), self.scope.installed(): + width = Count(self.root.plan.count("input_bits")) + gaussians = Count(self.root.plan.count("gaussians")) + self.root.plan.clear() + entry = self.entrance.run(payload, width, gaussians) + result = self.root.run(entry, *parameters) + return self.exit.run(result, width, gaussians) + finally: + for tape in (result, entry): + if tape is not None: + tape.clear() + erase_marker(tape) + for value in (width, gaussians): + if value is not None: + value.close() + self.root.plan.clear() + self.pool.empty() + self.closed = True diff --git a/research/twiddle-matched-layer/pr3593-PROOF.md b/research/twiddle-matched-layer/pr3593-PROOF.md new file mode 100644 index 0000000000..bb215a4bbd --- /dev/null +++ b/research/twiddle-matched-layer/pr3593-PROOF.md @@ -0,0 +1,248 @@ +# Encoded shape control for direct synthetic twiddles + +This is an author-written proof for every finite valid shape. Independent human +and formal proof-kernel review are unclaimed. The executable limits ell to +2..32 and the number D of axes to 1..16. Its finite checks corroborate the +argument and do not prove its unbounded quantifiers. + +## Boundary and conclusion + +Let ell>=2, 1<=K=1. Axis i is long or short, with ell or +ell-1 named Boolean positions. Put A equal to their total number of positions, +I={i:hN^2 for these descriptors, no valid run overflows. The +carry/borrow identities and comparison invariant prove every counter operation. + +The simulator's preallocated list lengths and loop fuel are boundary checks and +diagnostics. No decoded counter value, Python head index, input bit, list of +named slots or arithmetic on an address value controls the schedule. Marker +tests and counter comparisons end all successful loops before their diagnostic +fuel bounds. Removing those guards gives the same finite-transition machine +on every valid input. The Boolean/counter dictionaries and opcode lookup each +have a fixed number of entries. A Python callback stack is not a physical tape. +Suspended axis scans have fixed nesting depth and constant finite state. + +The host admission function checks the descriptor grammar, executable caps and +address extent before starting the simulator. A valid-input theorem needs no +oracle for these tests. A uniform validator can scan the fixed grammar, count +the unary fields and flags, and compare K, h and ell on the same counter tapes. +No executed physical invoice for malformed host admission is claimed here. + +## Recovering the schedule from the descriptor + +The actual parser increments ell, K and h from their unary fields. Repeated +subtraction of K from ell-1 computes quotient q and remainder b. Counter +comparisons compute a and stride=max(a,1). A descriptor flag scan computes the +bank extent P, charging its dummy cell when d=0. Another counter holds n=h+1. + +Each axis sweep returns the descriptor head to caret, scans through the first +three separators, and reads L/S flags until the next separator. No flag vector +is copied. A counter base advances by stride precisely at participating axes. +There are three schedule phases. + +1. At v=ell-1, consume one slot for each L flag. +2. At v=b-1,...,0, sweep every flag and consume its slot. +3. Starting at upper=ell-2, repeat q chunks. Compute lower=upper+1-K. Sweep + flags and consume v=upper,...,lower for each axis, then subtract K from upper + when another chunk remains. + +This is exactly the canonical order: long top slots, extracted low planes, then +chunk-major high-to-low chunks with axis order and descending bits inside each +axis chunk. Each named position appears once. Top-round participation is the +actual L flag; in lower rounds all axes participate. Both the base and v are +reset at their specified loop boundaries. In particular, short axes do not +create holes in the top-round bank addressing. + +The controller emits a member of a fixed 80-symbol data instruction alphabet +at each data action. Instructions read/write a named Boolean register on a +named tape, move a named tape one cell, or perform one of eight fixed Boolean +register actions. They contain no integer operand, pointer or source index. +Production execution dispatches each instruction immediately and retains none. +The verifier can collect the stream for replay; that diagnostic program storage +is outside the producer's C bound and is disabled by default. + +To seek a data position, compare its binary position counter with the target, +move one cell toward the target, update the position counter, and repeat. Every +physical data move and every counter access is charged. Address progression +uses one right move before each slot after the first. There is no reread while +returning the address head. + +## Arithmetic and final restoration + +For an active axis, exactly the v0, complement and increment all n accumulator bits. +Unlike PR3582, this implementation also performs that harmless negation in an +empty top round. The result is still zero; its extra accesses/gates are charged. +Direction + and h=0 omit the negation. Read accumulator positions h,...,0 into +the output, followed by ell-h zeros. This is sign*2^(ell-h)*S modulo 2^(ell+1). + +Counter-controlled scans erase all P bank cells and all n accumulator cells. +Seek every data head to zero, return the descriptor head by its caret delimiter, +erase each of the 21 counters including its delimiters and reset the Boolean +registers. The persistent Boolean one is finite control in its initial state. +The output remains, and the borrowed address and descriptor were never written. +This proof concerns successful valid-input execution. It does not claim a +failure/retry restoration contract. + +## Data invoice and full polynomial bound + +Let f=1 exactly when h>0 and direction is -. There are d*h masked additions and + + L=d*h*(h+3)/2 + +accumulator ripple positions. The exact Boolean counts are + + AND=d*h+L+f*n, XOR=L+2*f*n. + +The exact read/write totals are + + address: reads A, writes 0; + bank: reads d*h, writes 2*d*a+d+P; + total: reads L+(f+1)*n, writes L+(f+1)*n; + output: reads 0, writes ell+1. + +For the chronological access positions t_1,...,t_s on a tape, set both endpoints +to zero. Its exact movement is sum |t_(j+1)-t_j|. checks.py independently builds +these access sequences from canonical named slots. Counter motion is additional +and is measured directly by the sequential counter implementation. + +For completeness, a generous bound on the data tariff is 30M^2. Indeed P<=A, +d*h<=A, d*a<=A, n<=ell and L<=A*(ell+2)/2. Bank read/write accesses are at most +5A, so its movement is at most (5A+1)*(P-1). Accumulator movement is at most +A*ell+6ell by summing the sparse ripples, optional negation, output and cleanup. +The other movements are 2*(A-1)+2ell. Summing these with the displayed read, +write and gate totals gives the bound, including the extra empty-round negation. + +Here is a conservative static count of the controller macros. Outside seeks, +parsing/division uses O(N+ell+D) macros. The top, low-plane and chunk passes +have A input events, at most d*a pending events, d*h contributions and L ripple +positions. Each event uses at most 30 counter macros. Finish/cleanup adds at +most 10*(ell+P+n+1), and fixed initialization/erasure has 42 counter roles. +These quantities give fewer than 100M^2 non-seek macros, with setup/erasure +separately bounded by 42*14*(W+2). A seek uses two counter macros per actual data +move and one final comparison. There are at most 30M^2 data moves, and fewer +than 10M^2 seek invocations from the displayed access totals and four returns. +Thus seeks use at most 70M^2 macros. Charging at most 14*(W+2) per macro, plus +descriptor sweeps and the data tariff, stays below 5000M^2*(W+2). Descriptor +sweeps need at most a constant times N*(ell+1) actions and are included. + +Finally W+2=N+4<=4M. The exact capacity formula and P<=A give C<=90M and the +binary encoding bound 182M. All bounds concern mathematical tape cells and +primitive actions, not Python allocation, timings or an optimized constant. + +## Source allowance and remaining join + +Under the retained D*ell=O(p) source band, A=O(p), ell=O(p), and N=O(p). The +complete descriptor/counter/data producer therefore has O(p^3) transitions and +O(p) tape cells. For fixed 0=2^(a_r*p/d_source), log2(r)>=(a_r/b_d)*p^(1-epsilon). Consequently r +eventually exceeds every fixed power of p, and this producer fits the source's +asymptotic O(rp) per-record exponent-production allowance. This gives no explicit +cutoff or optimized quadratic total-machine claim. + +The output is one header. Address enumeration, coefficient packets, signed +rotations, truncation, spectators, caller reservations, dirty caller return and +the complete layer/root invoice remain separate. This is a uniform encoded +header-producer implication, not a complete transform or supplier admission. +It establishes no new multiplication exponent and changes no selected frontier. diff --git a/research/twiddle-matched-layer/pr3593-controller.py b/research/twiddle-matched-layer/pr3593-controller.py new file mode 100644 index 0000000000..2e72164d94 --- /dev/null +++ b/research/twiddle-matched-layer/pr3593-controller.py @@ -0,0 +1,493 @@ +"""Encoded sequential twiddle controller. Nick Petalas, Apache-2.0.""" + +from collections import Counter as Tally + + +def require(ok, message): + if not ok: + raise ValueError(message) + + +LEFT, RIGHT = 2, 3 +ROLES = ('address', 'bank', 'total', 'output') +REGISTERS = ('input', 'branch', 'pending', 'carry', 'old', 'inverse', 'zero', 'one') +# Every entry belongs to a fixed finite alphabet, independent of the shape. +OPS = tuple((kind, role, reg) for kind in ('read', 'write') + for role in ROLES for reg in REGISTERS) + tuple( + ('move', role, direction) for role in ROLES for direction in (-1, 1)) + ( + ('gate', 'mask', 0), ('gate', 'ripple', 0), ('gate', 'invert', 0), + ('gate', 'negate', 0), ('gate', 'reset', 0), ('gate', 'carry-one', 0), + ('gate', 'save-branch', 0), ('gate', 'save-pending', 0)) +CODE = {op: i for i, op in enumerate(OPS)} + + +class Tape: + """Current-cell operations only; the integer head is simulator state.""" + + def __init__(self, cells): + self.cells = list(cells) + self.head = 0 + self.counts = Tally() + + def read(self): + self.counts['read'] += 1 + return self.cells[self.head] + + def write(self, value): + self.cells[self.head] = value + self.counts['write'] += 1 + + def move(self, direction): + require(direction in (-1, 1), 'bad unit move') + require(0 <= self.head + direction < len(self.cells), 'head out of bounds') + self.head += direction + self.counts['move'] += 1 + + +class Binary: + """A delimited little-endian counter. No decoded value controls execution.""" + + def __init__(self, width, descriptor): + self.width = width + self.tape = Tape((0,) * (width + 2)) + self.tape.write(LEFT) + self.tape.move(1) + # One zero bit per actual borrowed symbol, including ^ and $. + for _unused in range(width + 1): + token = descriptor.read() + self.tape.write(0) + self.tape.move(1) + if token == '$': + break + descriptor.move(1) + else: + raise ValueError('unterminated descriptor initialization') + self.tape.write(RIGHT) + self.home() + for _unused in range(width + 1): + if descriptor.read() == '^': + return + descriptor.move(-1) + raise ValueError('descriptor return budget exhausted') + + def home(self): + for _unused in range(self.width + 2): + if self.tape.read() == LEFT: + return + self.tape.move(-1) + raise ValueError('missing left delimiter') + + def zero(self): + self.tape.move(1) + for _unused in range(self.width + 1): + if self.tape.read() == RIGHT: + self.home() + return + self.tape.write(0) + self.tape.move(1) + raise ValueError('missing right delimiter') + + def change(self, decrement=False): + carry = 1 + self.tape.move(1) + for _unused in range(self.width + 1): + bit = self.tape.read() + if bit == RIGHT: + self.home() + require(not carry, 'counter overflow or underflow') + return + self.tape.write(bit ^ carry) + carry &= (1 - bit) if decrement else bit + self.tape.move(1) + raise ValueError('missing right delimiter') + + def combine(self, other, operation): + require(self is not other and self.width == other.width, 'counter alias') + require(operation in ('copy', 'add', 'sub', 'compare'), 'bad counter operation') + self.tape.move(1) + other.tape.move(1) + carry, relation = 0, 0 + for _unused in range(self.width + 1): + a, b = self.tape.read(), other.tape.read() + if a == RIGHT: + require(b == RIGHT and not carry, 'counter width or arithmetic failure') + self.home() + other.home() + return relation + if operation == 'copy': + self.tape.write(b) + elif operation == 'compare': + if a != b: + relation = 1 if a else -1 + else: + self.tape.write(a ^ b ^ carry) + if operation == 'add': + carry = (a & b) | ((a ^ b) & carry) + else: + carry = ((1 - a) & b) | ((1 - (a ^ b)) & carry) + self.tape.move(1) + other.tape.move(1) + raise ValueError('missing right delimiter') + + def copy(self, other): + self.combine(other, 'copy') + + def add(self, other): + self.combine(other, 'add') + + def sub(self, other): + self.combine(other, 'sub') + + def compare(self, other): + return self.combine(other, 'compare') + + def value(self): + """Diagnostics only. The controller never calls this method.""" + return sum(bit << i for i, bit in enumerate(self.tape.cells[1:-1])) + + def erase(self): + self.zero() + self.tape.move(1) + for _unused in range(self.width + 1): + if self.tape.read() == RIGHT: + self.tape.write(0) + self.home() + self.tape.write(0) + return + self.tape.move(1) + raise ValueError('missing right delimiter during erasure') + + +def encode(ell, k, h, axes, opposite=False): + require(type(ell) is int and 2 <= ell <= 32, 'bad ell') + require(type(k) is int and 1 <= k < ell, 'bad K') + require(type(h) is int and 0 <= h < ell, 'bad h') + require(type(axes) is tuple and 1 <= len(axes) <= 16, 'bad axes') + require(all(type(x) is bool for x in axes), 'non-Boolean axis') + require(type(opposite) is bool, 'bad direction') + return '1' * ell + '#' + '1' * k + '#' + '1' * h + '#' + ''.join( + 'L' if x else 'S' for x in axes) + '#' + ('+' if opposite else '-') + '#' + + +def admit(text, address): + """Reject malformed/excessive external inputs before private execution.""" + require(type(text) is str and len(text) <= 116, 'bad descriptor extent') + parts = text.split('#') + require(len(parts) == 6 and parts[-1] == '', 'bad descriptor framing') + require(all(set(x) <= {'1'} for x in parts[:3]), 'bad unary field') + ell, k, h = map(len, parts[:3]) + require(set(parts[3]) <= {'L', 'S'}, 'bad axis symbol') + axes = tuple(x == 'L' for x in parts[3]) + require(parts[4] in ('+', '-'), 'bad direction symbol') + require(encode(ell, k, h, axes, parts[4] == '+') == text, 'noncanonical descriptor') + extent = sum(ell if x else ell - 1 for x in axes) + require(type(address) is tuple and len(address) == extent, 'bad address extent') + require(all(type(x) is int and x in (0, 1) for x in address), 'bad address bit') + return ell, k, h, axes, parts[4] == '+' + + +class Controller: + NAMES = ('ell', 'k', 'h', 'b', 'q', 'a', 'stride', 'upper', 'lower', 'v', + 'base', 'target', 'low', 'j', 'zero', 'address-pos', 'bank-pos', + 'total-pos', 'output-pos', 'bank-size', 'total-size') + + def __init__(self, descriptor, address, trace=False): + ell, k, h, axes, opposite = admit(descriptor, address) + b = (ell - 1) % k + a = b if b <= h < ell - 1 else 0 + d = sum(h < ell - (not long) for long in axes) + self.data = {'address': Tape(address), 'bank': Tape((0,) * max(1, d * max(a, 1))), + 'total': Tape((0,) * (h + 1)), 'output': Tape((0,) * (ell + 1))} + # Host arithmetic here admits exact tape extents, never a data schedule. + self.descriptor = Tape('^' + descriptor + '$') + self.width = len(descriptor) + 2 + self.c = {name: Binary(self.width, self.descriptor) for name in self.NAMES} + self.bits = dict.fromkeys(REGISTERS, 0) + self.bits['one'] = 1 + self.gates = Tally() + self.trace = [] if trace else None + self.first = True + self.limit = len(address) + ell + 1 + + def emit(self, kind, role, reg): + opcode = CODE[kind, role, reg] + if self.trace is not None: + self.trace.append(opcode) + if kind == 'move': + self.data[role].move(reg) + elif kind == 'read': + self.bits[reg] = self.data[role].read() + elif kind == 'write': + self.data[role].write(self.bits[reg]) + else: + self.gate(role) + + def gate(self, action): + b = self.bits + if action == 'mask': + b['carry'] = b['branch'] & b['pending'] + self.gates['and'] += 1 + elif action == 'ripple': + b['inverse'] = b['old'] ^ b['carry'] + b['carry'] &= b['old'] + self.gates['and'] += 1 + self.gates['xor'] += 1 + elif action == 'invert': + b['inverse'] = b['old'] ^ 1 + self.gates['xor'] += 1 + elif action == 'negate': + b['old'] = b['inverse'] ^ b['carry'] + b['carry'] &= b['inverse'] + self.gates['and'] += 1 + self.gates['xor'] += 1 + elif action == 'carry-one': + b['carry'] = 1 + elif action == 'save-branch': + b['branch'] = b['input'] + elif action == 'save-pending': + b['pending'] = b['input'] + else: + require(action == 'reset', 'unknown Boolean action') + for name in REGISTERS: + b[name] = int(name == 'one') + + def seek(self, role, target): + position = self.c[role + '-pos'] + for _unused in range(self.limit + 1): + relation = position.compare(target) + if not relation: + return + direction = -1 if relation > 0 else 1 + self.emit('move', role, direction) + position.change(direction < 0) + raise ValueError('data seek budget exhausted') + + def input_slot(self): + if self.first: + self.first = False + else: + self.emit('move', 'address', 1) + self.c['address-pos'].change() + self.emit('read', 'address', 'input') + + def parse(self): + self.descriptor.move(1) + for field in ('ell', 'k', 'h'): + for _unused in range(self.width): + token = self.descriptor.read() + self.descriptor.move(1) + if token == '#': + break + require(token == '1', 'invalid unary symbol') + self.c[field].change() + else: + raise ValueError('unterminated unary field') + # The finite direction flag is read from the actual descriptor. + for _unused in range(self.width): + if self.descriptor.read() == '#': + self.descriptor.move(1) + self.opposite = self.descriptor.read() == '+' + break + self.descriptor.move(1) + else: + raise ValueError('unterminated axes') + self.c['upper'].copy(self.c['ell']) + self.c['upper'].change(True) + self.c['b'].copy(self.c['upper']) + for _unused in range(self.width): + if self.c['b'].compare(self.c['k']) < 0: + break + self.c['b'].sub(self.c['k']) + self.c['q'].change() + else: + raise ValueError('division budget exhausted') + if self.c['h'].compare(self.c['upper']) < 0 and self.c['b'].compare(self.c['h']) <= 0: + self.c['a'].copy(self.c['b']) + self.c['stride'].copy(self.c['a']) + if self.c['stride'].compare(self.c['zero']) == 0: + self.c['stride'].change() + for long in self.axes(): + if self.c['h'].compare(self.c['upper']) < 0 or long: + self.c['bank-size'].add(self.c['stride']) + if self.c['bank-size'].compare(self.c['zero']) == 0: + self.c['bank-size'].change() + self.c['total-size'].copy(self.c['h']) + self.c['total-size'].change() + + def axes(self): + # Marker scans, not a retained axis/participation table. + for _unused in range(self.width): + if self.descriptor.read() == '^': + break + self.descriptor.move(-1) + fields = 0 + for _unused in range(self.width): + if self.descriptor.read() == '#': + fields += 1 + self.descriptor.move(1) + if fields == 3: + break + for _unused in range(self.width): + token = self.descriptor.read() + if token == '#': + return + yield token == 'L' + self.descriptor.move(1) + raise ValueError('axis scan budget exhausted') + + def add(self): + self.emit('gate', 'mask', 0) + self.c['j'].copy(self.c['v']) + for _unused in range(self.width): + self.seek('total', self.c['j']) + self.emit('read', 'total', 'old') + self.emit('gate', 'ripple', 0) + self.emit('write', 'total', 'inverse') + if self.c['j'].compare(self.c['h']) == 0: + return + self.c['j'].change() + raise ValueError('ripple budget exhausted') + + def consume(self, active): + self.input_slot() + if not active: + return + c = self.c + if c['v'].compare(c['a']) < 0: + c['target'].copy(c['base']) + c['target'].add(c['v']) + self.seek('bank', c['target']) + self.emit('write', 'bank', 'input') + elif c['v'].compare(c['h']) == 0: + self.emit('gate', 'save-branch', 0) + c['low'].zero() + for _unused in range(self.width): + if c['low'].compare(c['a']) == 0: + break + c['target'].copy(c['base']) + c['target'].add(c['low']) + self.seek('bank', c['target']) + self.emit('read', 'bank', 'pending') + self.emit('write', 'bank', 'zero') + c['target'].copy(c['v']) + c['v'].copy(c['low']) + self.add() + c['v'].copy(c['target']) + c['low'].change() + self.seek('bank', c['base']) + self.emit('write', 'bank', 'branch') + elif c['v'].compare(c['h']) < 0: + self.seek('bank', c['base']) + self.emit('read', 'bank', 'branch') + self.emit('gate', 'save-pending', 0) + self.add() + + def schedule(self): + c = self.c + c['v'].copy(c['upper']) + c['base'].zero() + for long in self.axes(): + if long: + self.consume(True) + c['base'].add(c['stride']) + c['v'].copy(c['b']) + for _unused in range(self.width): + if c['v'].compare(c['zero']) == 0: + break + c['v'].change(True) + c['base'].zero() + for long in self.axes(): + active = c['h'].compare(c['upper']) < 0 or long + self.consume(active) + if active: + c['base'].add(c['stride']) + c['upper'].change(True) + for _unused in range(self.width): + if c['q'].compare(c['zero']) == 0: + return + c['lower'].copy(c['upper']) + c['lower'].change() + c['lower'].sub(c['k']) + c['base'].zero() + for long in self.axes(): + c['v'].copy(c['upper']) + for _step in range(self.width): + # Top-round participation is recovered without an axis index. + c['target'].copy(c['ell']) + c['target'].change(True) + active = c['h'].compare(c['target']) < 0 or long + self.consume(active) + if c['v'].compare(c['lower']) == 0: + break + c['v'].change(True) + else: + raise ValueError('chunk budget exhausted') + if active: + c['base'].add(c['stride']) + c['q'].change(True) + if c['q'].compare(c['zero']) > 0: + c['upper'].sub(c['k']) + raise ValueError('chunk count budget exhausted') + + def finish(self): + c = self.c + if not self.opposite and c['h'].compare(c['zero']) > 0: + self.emit('gate', 'carry-one', 0) + c['j'].zero() + for _unused in range(self.width): + self.seek('total', c['j']) + self.emit('read', 'total', 'old') + self.emit('gate', 'invert', 0) + self.emit('gate', 'negate', 0) + self.emit('write', 'total', 'old') + if c['j'].compare(c['h']) == 0: + break + c['j'].change() + c['v'].copy(c['h']) + c['j'].zero() + for _unused in range(self.width): + self.seek('output', c['j']) + if c['j'].compare(c['h']) <= 0: + self.seek('total', c['v']) + self.emit('read', 'total', 'old') + self.emit('write', 'output', 'old') + if c['v'].compare(c['zero']) > 0: + c['v'].change(True) + else: + self.emit('write', 'output', 'zero') + if c['j'].compare(c['ell']) == 0: + return + c['j'].change() + raise ValueError('output budget exhausted') + + def execute(self): + self.parse() + self.schedule() + self.finish() + for role in ('bank', 'total'): + self.c['j'].zero() + for _unused in range(self.limit): + if self.c['j'].compare(self.c[role + '-size']) == 0: + break + self.seek(role, self.c['j']) + self.emit('write', role, 'zero') + self.c['j'].change() + else: + raise ValueError('erasure budget exhausted') + for role in ROLES: + self.seek(role, self.c['zero']) + for _unused in range(self.width): + if self.descriptor.read() == '^': + break + self.descriptor.move(-1) + for counter in self.c.values(): + counter.erase() + self.emit('gate', 'reset', 0) + + def invoice(self): + return {'data': {role: dict(tape.counts) for role, tape in self.data.items()}, + 'control_tape_actions': sum(sum(c.tape.counts.values()) for c in self.c.values()), + 'descriptor_actions': sum(self.descriptor.counts.values()), + 'data_cells': sum(len(t.cells) for t in self.data.values()), + 'control_cells': len(self.c) * (self.width + 2), + 'descriptor_cells': len(self.descriptor.cells), 'gates': dict(self.gates)} diff --git a/research/twiddle-matched-layer/pr3599-PROOF.md b/research/twiddle-matched-layer/pr3599-PROOF.md new file mode 100644 index 0000000000..728ff53e72 --- /dev/null +++ b/research/twiddle-matched-layer/pr3599-PROOF.md @@ -0,0 +1,307 @@ +# Physical T74 cost in the actual selected width + +Jose Manuel (`jmbarrancoml`), with substantial OpenAI Codex assistance. +Apache-2.0. + +## Contract and source status + +I retain the complete PR3477 T74 word, both native providers and orientations, +whole-owner hosting, common-label endpoint, source-to-physical refinement and +Gaussian-height arguments. I use PR3562's completed ordinary rate +`a=576/332929`, with its retained C0 and fixed-tape cost premises. These +are source-relative mathematical dependencies. I claim no independent +scientific admission from their source retention or finite checks. + +Fix the same source-admissible prime q=213*2^80+1. For precision p>=2 and +selected width 1<=g<=floor(p^(997/1000)), put + + d=g, K=floor(g^(1/500)), G=4ceil(log2 p)+6, H=gG. + +I receive complete p-grid Gaussian packets with fields + + [outer rows][left address bits][gK address bits][right address bits] + [r complete Gaussian coefficients]. + +I act on address bits `right+rho+jK`, 0<=j=1, write L=66304 Gamma with Gamma=|O(73,2)|, and +lambda=ceil(log2 L). I retain the full coarse depth + + D0(e)=0 for e<73, + D0(e)=1+D0(48 floor(e/73)) otherwise, + +and compute + + q0=lambda D0(g), qF=ceil(2H/K), qB=ceil(H/K), + Q0=q0+qF+qB. + +On the fast branch g>Q0, I have K>3G. In particular +K>=G+4ceil(log2 p)+10, the sufficient finite compact guard. I use that +finite condition; I do not assert K/log p tends to infinity uniformly in g. +I also have + + 3H=0, + + p^k/r <= 2^(kx-bx^2) <= 2^(k^2/(4b)). (3) + +The upper bound on log2 r and the retained descriptor contract give +address/key length A<=A0 p. The compact source charges + + O(V+M A^6+delta_bad M A(R+A)), R=2hr, + +where h is the working component width and M is its record count. On the +fast branch delta_bad<=5/(128p^3). Thus A^6/R<=A0^6 2^(9/b), and +delta_bad A(1+A/R) is uniformly bounded. I also pay the phase invoice +O(V+M A^2) through (3). The same inequalities cover the retained polynomial +preparation and descriptor backing. They use no exact equality r=2^(Theta(p/d)). +The coefficient count remains unchanged through child descent, so I may +apply them at each actual record-bearing node. + +The new stopping test computes min(e^(10^6),g) by the retained binary +power algorithm. It has 20 fixed iterations, 19 squares and seven result +products, or 26 capped-product calls. Stored values stay at most g; +nontrivial temporary products stay below g^2. With ell=bitlength(g), +I pay O(ell^2) using the retained bitwise Horner multiplication. On +root-generated nodes, component_bits>=p, V_node>=2p, and g<=p. The bound +(1+log2 p)^2<=13p therefore pays this test within O(V_node). It closes +its scratch before child descent and adds no tape role or Gaussian operation. +An arbitrary huge-root-width toy descriptor with tiny components does not +satisfy this time-domain argument. + +## Complete moment and internal work + +I retain the complete histogram, already including all calls and idle work, + + {1:1645680,2:470196,3:159468,4:71928, + 5:13716,8:5328,48:28190}. + +I count rank mass 4816512 and 2394506 children. I divide by W=66304 +once. At sigma=998271/10^6, the exact rational enclosure is + + mu_sigma in + [999999903535664027556833879161, + 999999903535664027556833879162]/10^30, + 1-mu_sigma>9*10^-8. + +For each node, the weighted child sum is at most mu_sigma times its +V_node e^sigma weight. Summing the stopped tree gives a factor at most +1/(1-mu_sigma). I retain all positive-rank children. At this point even +one additional rank-one child fails the moment check. + +Let eta=10^-6. I now have tau=g^eta, so + + e^tau <= g^(-eta(sigma-tau)) e^sigma. + +The complete nonchild bill is O(V_node((e log p)^tau+1)), including source +gathers, monomials, scalar work, replacement, parking and the new test. +I obtain internal work + + O(V g^(sigma-eta(sigma-tau)) (log p)^tau). + +Stopped widths satisfy e=g^(1/500)/2. Since g<=p, I obtain + + Q0 <= 2lambda log2 g+6G g^(499/500)+2 + <= (lambda+8)G g^(499/500). + +On a fast root, the reserved leaves therefore cost +O(V g^.998 log p), which fits (2). If the fast guard fails, g<=Q0 gives + + g <= [(lambda+8)G]^500. + +Consequently the complete elementary root cost satisfies + + Vg <= Vg^alpha [(lambda+8)G]^(500(1-alpha)), + 500(1-alpha)=.864495<1. + +Since G=O(log p), that branch also fits (2). The argument includes g=1. +It does not require a new unproved practical cutoff. + +## Height, truncation and space + +I use the unchanged source height induction through full descent: +A(e)<=8e at leaves, A(e)<=A(48f)+sf+E internally, and A(e)<=2Be, +with the retained fixed s,E,B. The altered test touches only Count tapes. +The ordinary substitution preserves an exact bit-permutation endpoint. +I may therefore set Delta=2^210000 g and h=p+2Delta+3. Since g<=p, +h=O(p). The exact-half and final-only truncation arguments remain applicable. +The normalized Walsh row has L1 norm one, so final truncation gives the +claimed error and retains the unit disk. + +I keep the same geometric child volume V/L, full-depth stock and one-active- +branch parking protocol. The retained parked-payload bound is +4(1+731/L)V/(1-1/L), before the fixed current/output copies and paid metadata. +The changed planner retains one additional bounded Count for its domain +limit within its existing scratch pool. I allocate no input-dependent number +of tape roles. Together with (3), I retain O(V)+F_q occupied/visited space. + +## Conditional single-bit exposure on a global tensor + +Let S=(s_1,...,s_g) be distinct address positions of a complete dyadic +tensor. Choose a complete gK target span, with spaced selected positions +T=(rho,rho+K,...,rho+(g-1)K); in the root convention take right=0 and +left equal to the remaining address width. Require that the full span +fits and that the actual record contract survives its placement. + +Define a coordinate permutation P by sending s_i to t_i, then mapping +T\S bijectively onto S\T, and fixing the complement of S union T. +It moves at most 2g positions. For coefficient arrays, + + P^-1 (H0_T tensor I) P = H0_S tensor I. (4) + +A coordinate permutation of the complete tensor leaves each target chunk +a complete binary field. The unselected coordinates may come from different +original axes. A fixed coarse-label microbox generally lacks that closure. +I prove (4) without assuming a free payload permutation. + +If I supply the pinned arbitrary-support router contract, each direction +costs O(V g^tau polylog p), including its own prescribed record grouping +and restoration. I pay its additive poly(p) setup through (3), since the +complete input volume includes the actual r coefficients. I then obtain +the conditional global cost + + O(V (g^alpha log p + g^tau polylog p)) + = O(V g^alpha polylog p). + +I retain the router's logarithmic factor; tau 1: + result.multiply_small(constant) + return result + + def save(name, value): + copy_symbols(value.tape, self.roles[name]) + return value + + try: + with sealed_constructors(), self.scope.installed(): + save("zero", literal(0)) + two = literal(2) + need(compare(precision, two) >= 0, "root precision at least two") + positive(coefficients) + positive(outer_rows) + limit = keep(floor_power(precision, 997, 1000)) + need(compare(selected, limit) <= 0, "selected width within root domain") + d = save("d", literal(1) if selected.zero() else keep(Count(selected))) + K = save("K", keep(floor_power(d, 1, 500))) + need(compare(residue, K) < 0, "selected root residue") + logarithm = keep(ceil_log2(precision)) + G = save("G", plus(scaled(logarithm, 4), constant=6)) + H = save("H", times(d, G)) + depth = save("depth", keep(coarse_depth(d, self.dimension, self.maximum_rank))) + q0 = save("q0", scaled(depth, (self.level_divisor - 1).bit_length())) + qF = save("qF", keep(ceil_divide(scaled(H, 2), K))) + qB = save("qB", keep(ceil_divide(H, K))) + Q0 = save("Q0", plus(q0, qF, qB)) + delta = save("delta", scaled(d, 1 << self.guard_exponent)) + save("input_bits", plus(precision, constant=2)) + work_bits = save("work_bits", plus(precision, scaled(delta, 2), constant=3)) + active_bits = times(selected, K) + addresses = keep(power_two(plus(left, active_bits, right))) + save("gaussians", times(times(addresses, coefficients), outer_rows)) + self.fast = compare(selected, Q0) > 0 + if self.fast: + save("core_width", keep(subtract(selected, Q0))) + save("core_front", keep(subtract(times(qF, K), scaled(H, 2)))) + save("core_back", plus(keep(subtract(times(qB, K), H)), right)) + row_axes = times(q0, K) + original_rows = save("original_rows", keep(power_two(row_axes))) + prefix_count = save("prefixes", times(outer_rows, keep(power_two(left)))) + stock = literal(1) + repetitions = keep(Counter(depth)) + while not repetitions.finished: + stock.multiply_small(self.level_divisor) + repetitions.decrement() + save("stock", stock) + multiples = keep(ceil_divide(original_rows, stock)) + save("padded_rows", times(multiples, stock)) + rectangle = plus(keep(subtract(active_bits, row_axes)), right) + row_gaussians = times(keep(power_two(rectangle)), coefficients) + save("row_bits", scaled(times(row_gaussians, work_bits), 2)) + else: + for name in ("core_width", "core_front", "core_back", "row_bits"): + save(name, literal(0)) + for name in ("prefixes", "original_rows", "padded_rows", "stock"): + save(name, literal(1)) + except BaseException: + for tape in self.roles.values(): + tape.clear() + raise + finally: + for value in reversed(owned): + value.close() + self.pool.empty() + self.closed = True + return self diff --git a/research/twiddle-matched-layer/pr3599-active_root.py b/research/twiddle-matched-layer/pr3599-active_root.py new file mode 100644 index 0000000000..8f63fc0944 --- /dev/null +++ b/research/twiddle-matched-layer/pr3599-active_root.py @@ -0,0 +1,32 @@ +"""Join actual-width planning and the retuned machine to the retained root.""" + +from active_sources import active +active() +import root_layer as retained +from t74_root import T74RootLayer +from active_plan import ActiveWidthPlan +from retuned_machine import RetunedMachine +from retuned_native import build_native + + +class ActiveWidthRoot(T74RootLayer): + def __init__(self, binding, native, catalogue, plan=None, observe=None): + self.plan = plan if plan is not None else ActiveWidthPlan( + binding.dimension, binding.maximum_rank, binding.families * binding.cover.size) + self.machine = RetunedMachine(binding, native, catalogue, observe) + self.grid = retained.GridBoundary() + self.phase = retained.PhaseSweep() + self.padding = retained.RowPadding() + self.normalizer = retained.api["normalizer"].Normalizer() + self.leaf = retained.api["coefficient_engine"].CoefficientEngine(("left", "active", "right"), "active") + self.pool = retained.ScratchPool(32) + self.scope = retained.OuterScope(self.pool) + self.current, self.output = retained.Tape(), retained.Tape() + self.closed = True + + +def production_layer(): + """Construct the retained finite source; no production-size execution claim.""" + state = active() + binding = state.t74_binding.T74Binding(state.prepared) + return ActiveWidthRoot(binding, build_native(), binding.catalogue) diff --git a/research/twiddle-matched-layer/pr3611-PROOF.md b/research/twiddle-matched-layer/pr3611-PROOF.md new file mode 100644 index 0000000000..ecc93eb027 --- /dev/null +++ b/research/twiddle-matched-layer/pr3611-PROOF.md @@ -0,0 +1,316 @@ +# Consuming one encoded synthetic-twiddle header + +Copyright 2026 Sagar Thakrar. Apache-2.0. Prepared with substantial OpenAI +Codex assistance, including separate implementation and review agents. + +## Statement and inherited producer contract + +This is a source-relative join of one output of Nick Petalas's PR3593 +`Controller` to one complete coefficient packet. The retained producer commit +is `46c04613a19a5b7bd50d98e50bbc8ea8dc6275b0` (exact bytes are recorded +in SOURCES.json). +Its exponent theorem is an explicit inherited premise, not reproved here. +No address enumeration, complete round, physical butterfly or outer caller +is supplied by this join. + +Let `ell >= 2`, `r = 2^ell`, and let `w >= 2` be a signed component width. +The producer returns a raw, most-significant-bit-first header of `ell+1` +bits, its head at zero, representing `E` modulo `2r`. Its borrowed +descriptor starts with `^ 1^ell #` and is returned unchanged at its left +delimiter. The consumer reads those actual tapes. A separate borrowed +descriptor `^ 1^w $` supplies component width by a unary scan. + +The coefficient source is one framed packet `^ bits $`, containing exactly +`r` Gaussian coefficients in increasing coefficient order. Each consists +of a signed MSB-first `w`-bit real component followed by its imaginary +component. These are complete coefficient words, not address bits. The +output uses the same framing and ordering convention. + +Write `E = epsilon*r + s`, where `epsilon` is the first header bit and +`0 <= s < r` is its remaining binary word. The endpoint is multiplication +by `y^E` in `Z[i][y]/(y^r+1)`, on precisely this packet. Signed minimum +`-2^(w-1)` is forbidden in every component which this particular exponent +requires to negate; copying that minimum without negation is allowed. +In particular the stronger no-minimum input contract of the predecessor +packet implementation is sufficient. For unit-disk grid components the +source format `w=p+2` is sufficient as well. + +The original producer executable restricts `ell` to 2..32 and its axis +count to 1..16. This package does not remove those admission caps or claim +execution of all mathematical shapes. The mathematical implication from +a valid encoded header is separate from finite simulator admission, +preallocation and the retained producer's general-family argument. + +## Exact split and sign identity + +For `f(y)=sum_(j=0)^(r-1) z_j y^j`, split the coefficient sequence into +its first `r-s` coefficients and last `s` coefficients. Since `y^r=-1`, + +``` +y^E f = (-1)^(epsilon+1) sum_(j=r-s)^(r-1) z_j y^(j+s-r) + + (-1)^epsilon sum_(j=0)^(r-s-1) z_j y^(j+s). +``` + +Consequently output the suffix before the prefix, negating the suffix +exactly when `epsilon=0` and the prefix exactly when `epsilon=1`. +When `s=0` the suffix is empty; this includes the identity header and +the all-coefficient sign change at `E=r`. Reducing a negative exponent +modulo `2r` preserves this rule because `y^(2r)=1`. + +Both components of each coefficient receive the same sign. No Gaussian +component exchange, coefficient truncation or frequency permutation is +part of this operation. In particular it preserves every coefficient norm +and introduces no numerical error. Its inverse uses the residue of `-E`. + +For a component to be negated, complementing its bits and adding one +computes its additive inverse modulo `2^w`. Except at signed minimum, +this is its exact integer negative in the signed `w`-bit range. The +minimum pattern is a leading one followed only by zeros. Detecting this +pattern while copying a word therefore suffices for the advertised guard; +no decoded component value is needed. Copying a word requires no such +restriction. The full consumer implementation and paid-control argument +below determine how these elementary identities are executed. + +## Relation to the supplied exponent + +The retained PR3593 output contract is + +``` +E = sign * 2^(ell-h) * sum_(i in I) x_(i,h) sum_(v=1) floor(N/2^k) < N. +``` + +Thus both countdowns together take `O(r)` primitive operations, after +their `O(ell)` initialization, because their initial values add to `r`. +Return scans are over just the digits visited by that decrement; they +do not introduce an `ell` factor per coefficient. + +## Packet traversal, signs and successful restoration + +`split` consumes its counter by one decrement per coefficient. Its finite +control calls `copy_word` exactly twice per coefficient, real then imaginary. +Each call scans the actual unary width descriptor, copying one current-cell +source bit per unary `1`, and then returns the width head by its delimiter. +It follows that the prefix receives exactly the first `r-s` coefficients +and the suffix exactly the remaining `s`. The source must then be at its +end delimiter. Both buffers receive their own end delimiter and their +heads return to the left delimiter. + +`emit` traverses the suffix first, then the prefix, ending each at its +buffer delimiter. `emit_word` copies exactly one unary-width component to +the word tape while recording its sign and whether any lower bit is nonzero. +For a negation it rejects precisely the minimum pattern and performs the +right-to-left complement-and-carry pass proved above. It then copies the +word forwards into the output. A following word overwrites the same word +extent, so the previous contents are never treated as new input. + +The signs passed by `run` are `not epsilon` for suffix negation and +`bool(epsilon)` for prefix negation. These are exactly the signs in the +algebraic identity. Every input coefficient is copied once, emitted once, +and retains real/imaginary component order. An empty suffix ends at its +delimiter without emitting any component. The output receives its final +delimiter and its head returns to zero. + +The borrowed source and unary width descriptor are never written and +return to their left delimiters. Header and producer descriptor were +already restored before coefficient processing. On successful return, +`clear` scans each of the five private scratch tapes to its capacity guard, +clears that guard, returns by the still-present left delimiter while +clearing the interior, then clears the left delimiter. All their cells +are zero and their heads are zero. The output remains framed with its +capacity guard; that guard is storage metadata beyond the output delimiter, +not an extra coefficient bit. + +On a signed-minimum rejection in an otherwise valid admitted packet, the +same `finally` block clears all five scratch tapes and also the partial +output. The borrowed heads are restored. This is a one-shot consumer, +including after rejection. Malformed framing, mismatched host capacities, +interruption and external tape mutation are outside this restoration +contract; an exception path for arbitrary malformed tapes is not claimed. + +## Encoded initialization and the physical inventory + +The constructor admits and allocates blank simulator storage using `ell` +and `w`; it executes no consumer tape operation. Matching allocated extents +are a valid-input precondition. It does not supply an exponent or a schedule +to `run`. Host allocation, list management and validation costs are not +asserted to be physical tape operations. + +The actual `initialize` operation frames the three packet tapes by scanning +the borrowed source from `^` to `$`, initializing one cell on each of the +three roles per actual input bit. It adds an endpoint cell and a capacity +guard, then returns all heads by their left delimiters. The word tape is +initialized analogously from the actual unary width descriptor. Both counter +tapes are initialized from the producer descriptor's actual unary `ell` +field, with one extra binary digit, endpoint cell and capacity guard. +These reads, writes, unit moves and tests are charged. Thus the initialization +schedule itself is encoded-input-driven; it is not justified merely by +charging host loops over decoded capacities. + +After allocation, `run` and its helpers inspect a tape only through its +current-cell `read`, `write` and unit `move` methods. Their loops terminate +on actual delimiters, unary symbols, or the marked-counter zero flags. +The role tuples have fixed size, and copying the real and imaginary words +is a fixed two-call control sequence. `epsilon`, carry, zero, sign and +minimum-detection state have finite ranges. `capacities`, Python head indices +and stored cell arrays are allocation/diagnostic data, not inputs to the +executed control. The dictionaries describing named roles have fixed size. +No trace or decoded exponent table is retained. + +Put `L=2rw`. The six owned tape capacities, including framing/guards, are + +``` +prefix, suffix, output: each L+3 +word: w+3 +a, b: each ell+4 +owned total: 3L+w+2ell+20. +``` + +Let `C_source` be the borrowed source's actual allocated capacity, at least +`L+2`; its active framed packet ends at `$`. Extra capacity after that +delimiter is not consumed. In particular a prior consumer output has +capacity `L+3`, including its trailing guard, and is a valid source without +copying or removing that guard. The width descriptor uses `w+2` cells. +The header and producer descriptor are shared existing tapes, not copies. +Therefore joining this consumer to the retained producer increases the +allocated finite-alphabet capacity by exactly + +``` +3L+2w+2ell+22+C_source. +``` + +For a minimally framed source this is `4L+2w+2ell+24`; for a prior guarded +output it is `4L+2w+2ell+25`. With the retained producer's 26 tapes the +join has 34 fixed tape roles. If `C_prod` is its stated capacity, add the +displayed increment to it, counting its output header and descriptor once. +If the source is retained from an earlier operation in a larger caller, +deduplicate that actual tape too when forming the larger caller's inventory. +This is tape capacity, not Python object memory or a bit-encoding count. +The alphabets and finite-control state are fixed independently of the shape. + +## Paid consumer bound and joined invoice + +The consumer tariff counts every current-cell read, write and unit move, +plus each explicit fixed finite-control gate recorded by `gate`. A named +Boolean gate such as complement-and-carry is one fixed macro in this tariff, +not a claim that its implementation uses only one Boolean primitive. +The remaining dispatch/control transitions require a constant factor per +recorded action or fixed macro entry. Thus a tariff bound also gives the +stated asymptotic full-transition bound, without asserting an exact numeric +count for every machine-state transition. + +The following conservative phase bounds follow directly from the loops. +They include the head-return scans; their deliberately loose constants do +not use finite timing measurements. + +| Phase | Upper bound in recorded actions | +| --- | ---: | +| Encoded initialization | `23L+11w+16ell+120` | +| Header staging, counter construction and top marking | `100ell+100` | +| All `copy_word` calls | `11L+20r` | +| All `emit_word` calls | `27L+60r` | +| Both complete countdowns | `23r` | +| Remaining split/emit guards, packet returns and fixed control | `12L+8r+100` | +| Five successful scratch clears | `16L+8w+16ell+106` | + +For example, a `copy_word` costs at most `11w+10`, and there are `2r` +such calls. An `emit_word`, including its negation branch and word return, +costs at most `27w+30`, again for `2r` calls. A decrement costs at most +`7nu_2(n)+16`; the valuation identity gives the countdown row. For a scratch +tape of capacity `C` initially at its left delimiter, `clear` costs exactly +`8C-6` in this tariff. The capacities above give the last row. Empty +segments still incur their delimiter/return overhead, included in the +fixed-control row. + +Summing the displayed bounds gives at most +`89L+111r+19w+132ell+426`. Since `w>=2`, `r<=L/4`, so this is bounded by +`120L+24w+144ell+512`, and hence, for `ell>=2`, + +``` +T_consumer <= 256*(L+ell+w+1) = O(rw+ell). +``` + +The verifier's exact tariff is the sum of the actual per-role action +counters and finite-gate counters, not this upper bound substituted for a +measurement. Consumer actions on borrowed producer tapes are measured as +increments during the consumer call. If `T_prod` denotes the producer's +recorded action/gate invoice at the end of its call, the joined invoice is +`T_prod+T_consumer`. Summing producer counters again after consumption would +double-count the header/descriptor increments and is not this formula. + +Under the predecessor's source band `D*ell=O(p)`, its established allowance +is `O(p^3)` producer transitions. Consequently this one-header/one-packet +join has `O(p^3+rw+ell)` transitions. With `w=O(p)`, `ell=O(p)` and the +retained long-record hypothesis that `r` eventually dominates every fixed +power of `p`, this is `O(rp)` per supplied record. This is an asymptotic +conditional implication, with no explicit cutoff, complete layer invoice, +address-enumeration cost or caller/stock/dirty-restoration admission. + +## Attribution, evidence and remaining boundary + +Nick Petalas's PR3593 supplies the encoded header producer, unary shape +protocol, exponent proof and full polynomial producer invoice; PR3582 is +its retained direct-operation predecessor. His `synthetic-monomial-packets` +supplies the earlier signed packet endpoint and data-only invoice, whose +host-provided integer headers left this encoded join open. The source +transform and their retained predecessor notices remain credited. The +split/sign algebra and linear packet cost were already stated there; they +are not new transform identities. + +This package's contribution is the actual paid connection through the raw +header and unary descriptor, including carry-stopping encoded coefficient +countdowns and encoded scratch initialization. Finite execution checks +corroborate the endpoint, counters, guard and restoration claims on their +listed cases; they do not prove unbounded quantifiers. The written argument +is not independent human acceptance or a proof-assistant certificate. +The producer theorem is inherited and its full source chain is identified +in the manifest. No complete synthetic round, T74 refinement, production +native object, numerical error chain, supplier admission, new multiplication +exponent or selected-frontier change is claimed. diff --git a/research/twiddle-matched-layer/pr3611-consumer.py b/research/twiddle-matched-layer/pr3611-consumer.py new file mode 100644 index 0000000000..d916056a4a --- /dev/null +++ b/research/twiddle-matched-layer/pr3611-consumer.py @@ -0,0 +1,351 @@ +"""Physical signed packet consumer; allocation dimensions never drive run(). + +SPDX-License-Identifier: Apache-2.0 +Sagar Thakrar, with substantial OpenAI Codex assistance. +The borrowed header/descriptor protocol is Nick Petalas's PR3593 protocol. +""" +from collections import Counter + + +def require(ok, message): + if not ok: + raise ValueError(message) + + +class Tape: + """Simulator storage: only these methods inspect storage/head in execution.""" + + def __init__(self, cells): + self.cells = list(cells) + self.head = 0 + self.counts = Counter() + + def read(self): + self.counts["read"] += 1 + return self.cells[self.head] + + def write(self, value): + self.counts["write"] += 1 + self.cells[self.head] = value + + def move(self, direction): + require(direction in (-1, 1), "unit move") + require(0 <= self.head + direction < len(self.cells), "tape boundary") + self.counts["move"] += 1 + self.head += direction + + +class Consumer: + """One-shot consumer of a valid borrowed PR3593 twiddle header. + + Admission: matching unary descriptors and allocation dimensions; source has + exactly r Gaussian coefficients, each two signed width-bit MSB words. All + borrowed heads start at zero. A requested negation must be representable. + Tape objects must have separate backing storage, as their constructors + provide; manually sharing their diagnostic cells lists is not admitted. + run() never reads the host allocation dimensions. Arithmetic endpoints here + are exact signed rotations, not the rest of a recursive caller. + """ + + def __init__(self, ell, width): + require(type(ell) is int and 2 <= ell <= 32, "allocation ell") + require(type(width) is int and width >= 2, "allocation signed width") + length = 2 * (1 << ell) * width + self.capacities = dict(prefix=length+3, suffix=length+3, output=length+3, + word=width+3, a=ell+4, b=ell+4) + self.tapes = {} + self.invoice = Counter() + self.gates = Counter() + self.used = False + # Blank simulator allocation only. Actual framing/initialization is + # encoded-input driven in initialize(), and every such action is paid. + for role, capacity in self.capacities.items(): + self.tapes[role] = Tape((0,) * capacity) + + def gate(self, name): + self.gates[name] += 1 + self.invoice["gate"] += 1 + + def test(self, condition): + self.gate("test") + return condition + + def read(self, role): + self.invoice[role + ".read"] += 1 + return self.tapes[role].read() + + def write(self, role, value): + self.invoice[role + ".write"] += 1 + self.tapes[role].write(value) + + def move(self, role, direction): + self.invoice[role + ".move"] += 1 + self.tapes[role].move(direction) + + def home(self, role): + while self.test(self.read(role) != "^"): + self.move(role, -1) + + def initialize(self): + """Frame scratch using borrowed extents, never host allocation sizes.""" + require(self.test(self.read("source") == "^"), "source origin") + for role in ("prefix", "suffix", "output"): + self.write(role, "^") + self.move(role, 1) + self.move("source", 1) + while self.test(self.read("source") != "$"): + require(self.test(self.read("source") in (0, 1)), "source bit") + for role in ("prefix", "suffix", "output"): + self.write(role, 0) + self.move(role, 1) + self.move("source", 1) + for role in ("prefix", "suffix", "output"): + self.write(role, 0) + self.move(role, 1) + self.write(role, "!") + self.home(role) + self.home("source") + require(self.test(self.read("width") == "^"), "width origin") + self.write("word", "^") + self.move("word", 1) + self.move("width", 1) + while self.test(self.read("width") == "1"): + self.write("word", 0) + self.move("word", 1) + self.move("width", 1) + require(self.test(self.read("width") == "$"), "unary width delimiter") + self.write("word", 0) + self.move("word", 1) + self.write("word", "!") + self.home("word") + self.home("width") + require(self.test(self.read("descriptor") == "^"), "descriptor origin") + for role in ("a", "b"): + self.write(role, "^") + self.move(role, 1) + self.move("descriptor", 1) + while self.test(self.read("descriptor") == "1"): + for role in ("a", "b"): + self.write(role, 0) + self.move(role, 1) + self.move("descriptor", 1) + require(self.test(self.read("descriptor") == "#"), "unary ell delimiter") + for role in ("a", "b"): + # One extra binary digit, one endpoint delimiter, then guard. + self.write(role, 0) + self.move(role, 1) + self.write(role, 0) + self.move(role, 1) + self.write(role, "!") + self.home(role) + self.home("descriptor") + + def clear(self, role): + self.home(role) + self.move(role, 1) + while self.test(self.read(role) != "!"): + self.write(role, 0) + self.move(role, 1) + self.write(role, 0) + self.move(role, -1) + while self.test(self.read(role) != "^"): + self.write(role, 0) + self.move(role, -1) + self.write(role, 0) + + def mark_top(self, role): + """Enter at '$'; mark highest one by digit 2, return at '^'.""" + self.move(role, -1) + while self.test(self.read(role) == 0): + self.move(role, -1) + zero = self.test(self.read(role) == "^") + if self.test(not zero): + require(self.test(self.read(role) == 1), "binary counter") + self.write(role, 2) + self.home(role) + return zero + + def decrement(self, role): + """Positive counter only; top marker makes zero detection local.""" + self.move(role, 1) + while self.test(self.read(role) == 0): + self.write(role, 1) + self.move(role, 1) + top = self.test(self.read(role) == 2) + require(self.test(top or self.read(role) == 1), "positive marked counter") + self.write(role, 0) + self.move(role, -1) + zero = False + if self.test(top): + zero = self.test(self.read(role) == "^") + if self.test(not zero): + self.write(role, 2) + self.home(role) + return zero + + def counts_from_header(self): + """The descriptor's first unary field bounds every raw header access.""" + require(self.test(self.read("descriptor") == "^"), "descriptor origin") + epsilon = self.read("header") + require(self.test(epsilon in (0, 1)), "header sign bit") + self.move("descriptor", 1) + self.move("a", 1) + while self.test(self.read("descriptor") == "1"): + self.move("header", 1) + bit = self.read("header") + require(self.test(bit in (0, 1)), "header exponent bit") + self.write("a", bit) + self.move("a", 1) + self.move("descriptor", 1) + require(self.test(self.read("descriptor") == "#"), "unary ell delimiter") + self.write("a", "$") + # Restore the raw header by the very same unary field, not a host size. + self.move("descriptor", -1) + while self.test(self.read("descriptor") == "1"): + self.move("header", -1) + self.move("descriptor", -1) + require(self.test(self.read("descriptor") == "^"), "descriptor restored") + # Reverse MSB staging into little-endian s, with an extra high zero. + self.move("a", -1) + self.move("b", 1) + while self.test(self.read("a") != "^"): + self.write("b", self.read("a")) + self.move("b", 1) + self.move("a", -1) + self.write("b", 0) + self.move("b", 1) + self.write("b", "$") + self.home("b") + # Compute -s modulo 2r, then toggle its highest bit to obtain r-s. + carry = 1 + self.move("a", 1) + self.move("b", 1) + while self.test(self.read("b") != "$"): + bit = self.read("b") + self.gate("complement-add") + self.write("a", (1-bit) ^ carry) + carry &= 1-bit + self.move("a", 1) + self.move("b", 1) + self.write("a", "$") + self.move("a", -1) + self.gate("toggle-high") + self.write("a", 1-self.read("a")) + self.move("a", 1) + a_zero = self.mark_top("a") + b_zero = self.mark_top("b") + require(self.test(not a_zero), "r-s is positive") + return epsilon, a_zero, b_zero + + def copy_word(self, target): + self.move("width", 1) + while self.test(self.read("width") == "1"): + bit = self.read("source") + require(self.test(bit in (0, 1)), "complete source word") + self.write(target, bit) + self.move(target, 1) + self.move("source", 1) + self.move("width", 1) + require(self.test(self.read("width") == "$"), "unary width delimiter") + self.home("width") + + def split(self, counter, target, zero): + self.move(target, 1) + while self.test(not zero): + # Exactly two components; this is a finite control sequence. + self.copy_word(target) + self.copy_word(target) + zero = self.decrement(counter) + self.write(target, "$") + self.home(target) + + def emit_word(self, source, negate): + self.move("word", 1) + self.move("width", 1) + sign = self.read(source) + first, lower_nonzero = True, False + while self.test(self.read("width") == "1"): + bit = self.read(source) + require(self.test(bit in (0, 1)), "complete segment word") + self.gate("signed-minimum-flag") + if not first: + lower_nonzero |= bool(bit) + first = False + self.write("word", bit) + self.move("word", 1) + self.move(source, 1) + self.move("width", 1) + require(self.test(self.read("width") == "$"), "unary width delimiter") + self.write("word", "$") + self.home("width") + if self.test(negate): + require(self.test(not (sign == 1 and not lower_nonzero)), "signed minimum cannot be negated") + carry = 1 + self.move("word", -1) + while self.test(self.read("word") != "^"): + bit = self.read("word") + self.gate("signed-negate") + self.write("word", (1-bit) ^ carry) + carry &= 1-bit + self.move("word", -1) + else: + self.home("word") + self.move("word", 1) + while self.test(self.read("word") != "$"): + self.write("output", self.read("word")) + self.move("output", 1) + self.move("word", 1) + self.home("word") + + def emit(self, source, negate): + self.move(source, 1) + while self.test(self.read(source) != "$"): + self.emit_word(source, negate) + self.emit_word(source, negate) + self.home(source) + + def run(self, header, descriptor, width_descriptor, source): + self.gate("entry") + require(not self.used, "one-shot consumer") + self.used = True + # Fixed-arity identity admission, never a payload/descriptor decoding. + self.gate("distinct-borrows") + require(header is not descriptor and header is not width_descriptor and header is not source + and descriptor is not width_descriptor and descriptor is not source + and width_descriptor is not source, "distinct borrowed tapes") + for borrowed in (header, descriptor, width_descriptor, source): + for role in ("prefix", "suffix", "output", "word", "a", "b"): + require(self.test(borrowed is not self.tapes[role]), "borrowed tape aliases private role") + self.tapes.update(header=header, descriptor=descriptor, width=width_descriptor, source=source) + success = False + self.initialize() + try: + epsilon, a_zero, b_zero = self.counts_from_header() + require(self.test(self.read("source") == "^"), "source origin") + require(self.test(self.read("width") == "^"), "width origin") + self.move("source", 1) + self.split("a", "prefix", a_zero) + self.split("b", "suffix", b_zero) + require(self.test(self.read("source") == "$"), "complete source packet") + self.home("source") + self.move("output", 1) + self.gate("segment-sign") + self.emit("suffix", not epsilon) + self.emit("prefix", bool(epsilon)) + self.write("output", "$") + self.home("output") + self.gate("success") + success = True + return self.tapes["output"] + finally: + # Guaranteed on valid admitted inputs, including signed-minimum + # rejection. Malformed external tapes are outside this contract. + self.home("source") + self.home("width") + self.clear("prefix") + self.clear("suffix") + self.clear("word") + self.clear("a") + self.clear("b") + if self.test(not success): + self.clear("output") diff --git a/research/twiddle-matched-layer/transforms.tex b/research/twiddle-matched-layer/transforms.tex new file mode 100644 index 0000000000..de073e9292 --- /dev/null +++ b/research/twiddle-matched-layer/transforms.tex @@ -0,0 +1,737 @@ +\section{Synthetic transforms and their tape layout} +\label{sec:synthetic-layouts} + +We now implement the normalized Fourier transforms needed for +convolution. Their entries will be short polynomials in a quotient +where the required roots of unity act by exact signed permutations +of coefficient lists. We also specify where each frequency entry +is stored, because the opposite transform consumes that same order +after a pointwise product. + +The polynomial roots and radix-two butterflies belong to the fast +polynomial-transform method of Nussbaumer and +Quandalle~\cite{NussbaumerQuandalle1978,Nussbaumer1980}; we use the +form developed in~\cite[Section~2.4 and Lemma~3.2]{HarveyHoeven2021}. +The work here is to apply the simultaneous layers on a suitable tape +layout and retain the resulting frequency order through convolution. + +For an integer $r\geq 2$ that is a power of two, put +\[ + \mathcal R_r=\mathbb C[y]/(y^r+1),\qquad + \left\|\sum_{k=0}^{r-1}z_k y^k\right\|_\infty + =\max_{0\leq k0$ +and $C_w>1$, and choose the layer constants once as +\[ + C_M=C_\ell+1,\qquad + C_{\rm desc}=32(C_\ell+C_w+1). +\] +Use these constants and $C_w$ in +Proposition~\ref{prop:simultaneous-layer}. These fixed choices determine +a cutoff $p_1$, one fixed-tape procedure, and an implicit time constant +with the following guarantee. For every choice of positive integers +$p,d,r$ with $p\geq p_1$ and +\[ + a_dp^\epsilon\leq d\leq b_dp^\epsilon,\qquad + 2^{a_rp/d}\leq r\leq2^{b_rp/d}, +\] +suppose $d\geq2$ and $r=2^\ell$ with an integer $2\leq\ell0$. Thus all participating axes in a +common round have current length $u_i=2^{h+1}$. +The branch bit written at position $h$ is frequency bit $a_i-1-h$; +its frequency significance can differ between long and short axes. +The descriptor locates that named slot after $L$, so the physical +move has not changed which pair the current butterfly uses. The +opposite procedure executes this schedule in reverse order and, +when present, ends with the extra leading round on the long axes. + +For a position $h$ in the remaining chunks, the selected bit has +offset $(h-b)\bmod K$, counted from the least significant bit, in +each of the $D$ consecutive chunks with the same chunk index $j$. +Let $n_P$ and $n_S$ be the numbers of record-address bits before and +after that group. Every combination of those bits occurs, so the +layer sees the complete address set +\[ + [P]\times[2^K]^D\times[S],\qquad + P=2^{n_P},\quad S=2^{n_S},\quad + n_P+DK+n_S=\sum_i a_i\leq D\ell=O(p). +\] +Thus its record count is $PS2^{DK}=M$ and +$\log_2(2M)\leq(C_\ell+1)p=C_Mp$. +The current transform parameters supply $p,d,r,K,w$, and the round +determines $D,P,S$ and the selected offset $\rho$. Encode these values +as the header $\mathcal E$ of Proposition~\ref{prop:simultaneous-layer}. +The same fixed descriptor bound covers every axis choice and round. +Indeed $|\Gamma(v)|\leq2\log_2v+1$, and +$\ell+n_P+n_S\leq d\ell\leq C_\ell p$. Also +$d,D\leq\max\{C_\ell,1\}p$, $K,\rho+1\leq p$, and $w\leq C_wp$. +Adding the nine code lengths therefore gives +\[ + |\mathcal E| + \leq 2C_\ell p+12\log_2p+ + 4\log_2\max\{C_\ell,1\}+2\log_2C_w+9 + \leq C_{\rm desc}p. +\] +The last inequality uses $p\geq1$, $\log_2p\leq p$, and +$\log_2x\leq x$ for $x\geq1$. +This is the descriptor passed to the layer; the longer +table locating named slots remains separate for the transform's address +calculations. +The simultaneous-layer procedure therefore applies at cost +$O(Tpd^{\lambda'})$ per round and $O(Tp\ell d^{\lambda'})$ in total. + +In a round on prefix slots, process the participating bits individually. +Temporarily move one such bit immediately before the polynomial +suffix. In each now adjacent pair, buffer the first record and scan +it with the second, writing the half-sums and half-differences to two +work tapes. Append the half-sum record and then the half-difference +record, and reverse the bit move after +all pairs are processed. Including head returns, the work is +$O(rp)$ per pair and $O(Tp)$ for the moves and scans at coefficient +width $O(p)$. +That width suffices without truncating between axes: after $s\leq D$ +individual $H_0$ factors, the coefficients are exact dyadics on the +$2^{-(p+s)}$ grid and still lie in the disk. A temporary sum has +modulus at most two and needs only a constant number of extra integer +bits. Hence +$p+D+O(1)=O(p)$ bits per component suffice, since $D\leq d$ and +$d\ell=O(p)$. Complete the combined monomial exactly and apply +$Q_p$ once at the end of the round. Write the resulting disk-grid +numerators in the supplied $w$-bit component format. Their magnitudes +are at most $2^p$, so this takes one linear scan within the same bound. +In an opposite round on prefix slots the +inverse monomial comes first and preserves the grid and disk, so the +same width bound holds for its individual factors. There are at +most $b+1\leq K$ rounds on prefix slots, giving cost $O(TpdK)$. + +For each output record of a forward butterfly round, the descriptor +locates the new branch bit $b_i$ and the lower named slots that encode +$k_i$. Read their current values to compute +\eqref{eq:combined-twiddle}. Before an opposite round at position +$h$, all lower positions have already been processed in reverse. +Those slots again index the lower inputs of that level, while slot +$h$ still gives $b_i$. They therefore encode the same $k_i$ needed +by the inverse monomial before its +butterfly. The binary descriptions of the addresses, exponent, and +layout have polynomial length in $p$. Ordinary +fixed-tape arithmetic therefore computes the exponent in +$\operatorname{poly}(p)$ time per polynomial record. Each record +contains $\Theta(rp)$ bits, and $r$ dominates every fixed power of +$p$, so this work fits within its scan cost. The same bound covers +scans of the polynomially many round and layout descriptors. +Growing lists reside on tapes; a fixed number of counter and work +tapes suffices for every number of axes. + +To implement the monomial, write $E=er+s$ with $0\leq s1$. +Let $w$ be an integer with $p+2\leq w\leq C_wp$. +The input supplies $\Gamma(p)\Gamma(r)\Gamma(w)$ and two disk grid +polynomials $f,g\in\mathcal R_r$ in the component format of +Proposition~\ref{prop:simultaneous-layer} with width $w$. +One can compute the exact Gaussian integer +numerators of $fg$, and then return $Q_p(fg/r)$ in that same format, in time +$O(rp\log(rp))$ on a fixed number of tapes. The output is a disk +grid polynomial with error less than $\sqrt2\,2^{-p}$ from $fg/r$. +\end{lemma} +\begin{proof} +The supplied power of two $r$ determines $\ell=\log_2r$. +Write +\[ + f=2^{-p}(a+ib),\qquad g=2^{-p}(c+ie), +\] +where $a,b,c,e\in\mathbb Z[y]$ have degree less than $r$ and +coefficients of absolute value at most $2^p$. Set $B_0=2^{4p}$ +and, for $u\in\{a,b,c,e\}$, define the signed evaluation integer +\[ + A_u=u(B_0)=\sum_{j=0}^{r-1}u_jB_0^j. +\] +The bound +\[ + |A_u|\leq2^p\frac{B_0^r-1}{B_0-1}