diff --git a/research/shared-carrier-decoder/COST.md b/research/shared-carrier-decoder/COST.md new file mode 100644 index 0000000000..edb452a453 --- /dev/null +++ b/research/shared-carrier-decoder/COST.md @@ -0,0 +1,134 @@ +# Complete local invoice + +The baseline and candidate have the same 111 source streams, 111 target +streams, and 452 dirty helper streams. Each stream has `M` complex values. +The executed finite case has `M=512`. Every copy and adapter keeps the full +stream, including all control and spectator values. + +## Recursive children + +Every transition is lowered to one rank-r C child with two native monomial +adapters. No positive-rank transition is omitted. + +| Role or operation | Coordinate baseline | One replacement | +|---|---|---| +| 111 sources, line to FULL | 111 H8 | 111 H8 | +| Use helpers, zero to line to query to FULL | 444(2 H1+H7) | 441(2 H1+H7) | +| Eight centres, zero to query to FULL | 8(H8+H1) | 8(H8+H1) | +| COPY transforms | 8 H8 | 7 H8+H7 | +| Targets | 111 H8 | 56 H8+55(H1+H7) | +| Unused dirty helpers | 0 | **3 H9** | +| Total | 896 H1+444 H7+238 H8 | 945 H1+497 H7+182 H8+3 H9 | + +The difference is the sum of three paid changes: +`55(H1+H7-H8)` for target splits, `3(H9-2H1-H7)` for the inactive helpers, +and `H7-H8` for the changed COPY. It is therefore +`49 H1+53 H7-56 H8+3 H9`. Rank mass falls from 5908 to +5907, while the number of recursive children rises from 1578 to 1627. + +Under a common child price `r(m/r)^b`, the recursive difference is + +```text +(m/8)^b [49*8^b + 371*(8/7)^b - 448 + 27*(8/9)^b]. +``` + +For `0 <= b <= 1/256`, the exact integer checks + +```text +1009^256 > 8*1000^256, +7*1001^256 > 8*1000^256 +``` + +bound the square bracket above by + +```text +49*(1009/1000) + 371*(1001/1000) - 448 + 27 = -47/250. +``` + +This proves a strict recursive-moment improvement on the whole interval. It +includes the selected complex value +`416181814685169713943/250000000000000000000000` at the pinned base. The +formula is conditional on that child price. It does not construct an all-size +embedding or change the selected supplier. + +## Scalar, adapter, and temporary work + +| Scalar stage | Coordinate baseline | One replacement | +|---|---:|---:| +| Gather old helpers | 444 | 441 | +| Compensate old centre output | 444 | 507 | +| Remove old helper gather | 444 | 441 | +| Read sources | 444 | 441 | +| Gather updated helpers | 444 | 441 | +| Read transformed copies | 444 | 507 | +| Restore centres | 444 | 441 | +| Restore use helpers | 444 | 441 | +| AXPYs per address | 3552 | 3660 | + +Each AXPY charges one complex scalar addition. An AXPY coefficient of absolute +value 1/2 or 1/4 also charges one dyadic scalar multiplication. Their counts +are 888 and 1014. Negative signs are included in the scalar operations. +The candidate therefore pays **108 extra AXPYs and 126 extra dyadic scalar +multiplications per address**. + +Each native monomial adapter contains a permutation P, a quadratic phase D, +an XOR translation X, and a global phase. The emitted word retains identity +instances and charges them too. Each of these four types occurs 3156 times +in the baseline and 3254 times in the candidate. The increase is 98 scans +per type, or 392 adapter scans in total. The literal finite interpreter also +executes 5908 and 5907 coordinate C factors, respectively. + +In the forward orientation each word charges eight complete-stream copy +assignments, eight erasures, and all scatter reads in the AXPY table. In the +inverse transpose, replace those eight assignments with eight zero scans +and add eight centre-injection AXPYs. The recursive profile and all adapter +counts are the same. These orientation costs do not cancel from the invoice; +only their difference between the matched modules is zero. + +There are 674 original complex streams and one sequential temporary stream. +Thus there are at most `675 M` live complex values in the physical word. +The finite interpreter applies permutations by cycles and C and X gates by +pairs. Scalar arithmetic uses a fixed number of complex registers. Its fixed +permutation cycles and phase tables contain address data only. The checker +also stores proof data, exact integer numerators, and expected outputs; that +checker memory is not a claim about supplier workspace. + +## A finite route bound and the host boundary + +The invoice concerns the emitted complex-arithmetic word. It is not a count of +Python big-integer operations in the checker. Integer normalization and expected +output construction are verification work. + +The invoice counts all required arithmetic and address operations. It does +not treat an arbitrary address permutation as a free sequential tape scan. +At nine address bits, a direct P address circuit uses at most 256 Boolean +operations per value: its nine dot products need 81 ANDs and 72 XORs, with +space in the bound for packing the output bits. A D phase needs at most 144 +Boolean operations: 54 for the nine linear terms modulo four, 71 for the +quadratic parity, and one final XOR. X and a global unit phase use bounded address or scalar work. +These are fixed finite costs. A recursive child retains its full input volume. + +Here is a conservative route implementation for the finite word. Put the 675 +complex streams consecutively. A requested cell read or write can move the +head at most `2*675*M` complex-cell positions. An AXPY uses at most three cell +accesses per value. Each P, D, X, global-phase scan, or coordinate C factor +uses at most two per value. A copy assignment uses two, and an erasure uses +one. If `A` is the AXPY count, `B` is the sum of the four adapter scan counts, +and `R` is the rank mass, the forward access count is at most + +```text +M K, where K = 3A + 2B + 2R + 24. +``` + +The resulting route bound is `2*675*K*M^2` complex-cell moves. The inverse +transpose adds at most 16 accesses per address. For bit cells, multiply cell +width and charge the address counters. Exact integer arithmetic also has its +usual bit cost. No linear tape-time bound follows from this deliberately +simple route. + +A future host must supply and charge its complete-row routing interface, +external endpoint adapters, remaining side corrections, recursion storage, +precision control, and owner schedule. Those objects are not silently set to +zero here. They are outside the advertised finite decoder interface. +Consequently this result is a new exact local physical module with a smaller +paid recursive moment, not a measured speedup or an improved kappa. diff --git a/research/shared-carrier-decoder/EXPECTED.json b/research/shared-carrier-decoder/EXPECTED.json new file mode 100644 index 0000000000..1a9f273f72 --- /dev/null +++ b/research/shared-carrier-decoder/EXPECTED.json @@ -0,0 +1,523 @@ +{ + "base": "8bddbee377e2f3ce1f1247196c4b290d55767d20", + "geometry": { + "extra": 2, + "frame": [ + 0, + 1, + 26, + 27, + 44, + 45, + 54, + 55 + ], + "live": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119 + ], + "pivot": 0, + "ports": [ + 386, + 4, + 388, + 8, + 392, + 16, + 400, + 32, + 416, + 64, + 448, + 124, + 508, + 122, + 506, + 118, + 502, + 110, + 494, + 94, + 478, + 62, + 446, + 117, + 501, + 109, + 493, + 93, + 477, + 61, + 445, + 115, + 499, + 107, + 491, + 91, + 475, + 59, + 443, + 87, + 471, + 55, + 439, + 79, + 463, + 47, + 431, + 128, + 352, + 336, + 304, + 328, + 296, + 280, + 248, + 324, + 292, + 276, + 244, + 268, + 236, + 220, + 188, + 322, + 290, + 274, + 242, + 266, + 234, + 218, + 186, + 262, + 230, + 214, + 182, + 206, + 174, + 158, + 382, + 321, + 289, + 273, + 241, + 265, + 233, + 217, + 185, + 261, + 229, + 213, + 181, + 205, + 173, + 157, + 381, + 259, + 227, + 211, + 179, + 203, + 171, + 155, + 379, + 199, + 167, + 151, + 375, + 143, + 367, + 351, + 319 + ] + }, + "lowering_sha256": "fb17fa593ff638a03716c93e9218a2d2964e546d3851732c2806e489d1460d45", + "native_unique_frames": 234, + "native_unique_transitions": 913, + "rank_seven_dense_copy": { + "columns": 512, + "matrix_entries": 262144, + "rank": 7 + }, + "uniform_gain": { + "bracket_upper_bound": "-47/250", + "copied_rank": "64 -> 63", + "delta": { + "1": 49, + "7": 53, + "8": -56, + "9": 3 + }, + "interval": "0 <= b <= 1/256", + "rank_mass_saving": 1, + "selected_complex_b": "416181814685169713943/250000000000000000000000" + }, + "words": { + "coordinate": { + "conservative_finite_component_prefix": "473956352", + "frame": { + "coefficients": { + "-1": 1332, + "-1/4": 444, + "1": 1332, + "1/4": 444 + }, + "copy_profile": { + "8": 8 + }, + "move_profile": { + "1": 896, + "7": 444, + "8": 230 + }, + "profile": { + "1": 896, + "7": 444, + "8": 238 + }, + "rank_mass": 5908, + "source_reads": 444, + "source_restoration_reads": 444, + "unused_helper_tails": 0 + }, + "inverse_transpose_copy_ranks": [ + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8 + ], + "inverse_transpose_physical": { + "addresses_per_role": 512, + "exact_gaussian_values": 345088, + "inverse_transpose": true, + "operations": { + "C": 5908, + "D": 3156, + "P": 3156, + "X": 3156, + "axpy": 3552, + "center_injection": 8, + "copy_erase": 8, + "copy_zero": 8, + "phase": 3156 + }, + "original_roles": 674, + "scope": "One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof.", + "temporary_streams_peak": 1, + "trial": 0 + }, + "linear": { + "active_helper_streams": 452, + "address_bits": 9, + "axpy_scans": 3552, + "child_dispatches": 1578, + "clean_arithmetic_storage": "O(1) Gaussian dyadic registers per scalar or adapter loop, plus the one temporary stream.", + "copied_target_read_scans": 444, + "copy_assign_scans": 8, + "copy_erase_scans": 8, + "dirty_helper_streams": 452, + "dyadic_scalar_multiplications_per_address": 888, + "emitted_events": 5138, + "excluded": "No global owner map, outer assembly, rounding implementation, or selected-supplier invoice is supplied.", + "finite_child_native_scans": { + "coordinate_C_factors": 5908, + "diagonal_phase_scans": 3156, + "global_phase_scans": 3156, + "monomial_adapters": 3156, + "permutation_scans": 3156, + "positive_children": 1578, + "xor_translation_scans": 3156 + }, + "finite_complex_cell_accesses_per_address_bound": 47744, + "finite_tape_bound_volume_power": 2, + "finite_tape_complex_cell_move_coefficient": 64454400, + "fixed_address_metadata": "Input-independent permutation cycles and phase tables; these contain no complex data.", + "inverse_transpose_extra_cell_accesses_per_address_bound": 16, + "inverse_transpose_extra_center_injection_scans": 8, + "inverse_transpose_zero_scans_instead_of_copy_assign": 8, + "literal_finite_tape_bound": "With the 675 streams placed consecutively, each addressed read or write needs at most 2*675*M cell moves. Count these moves for every finite address access; no linear tape theorem is claimed.", + "maximum_live_complex_values_at_finite_size": 345600, + "original_streams": 674, + "permutation_bit_operations_per_value_bound": 256, + "positive_recursive_children": 1578, + "quadratic_phase_bit_operations_per_value_bound": 144, + "route_contract": "Every scan and child keeps the complete M-value stream. The full supplier must pay its retained row-routing interface.", + "scalar_additions_per_address": 3552, + "sequential_temporary_streams": 1, + "source_read_scans": 444, + "source_restoration_scans": 444, + "stream_volume": "M complex values, including every control and spectator value; M=512 in the finite replay." + }, + "physical": { + "addresses_per_role": 512, + "exact_gaussian_values": 345088, + "inverse_transpose": false, + "operations": { + "C": 5908, + "D": 3156, + "P": 3156, + "X": 3156, + "axpy": 3552, + "copy_assign": 8, + "copy_erase": 8, + "phase": 3156 + }, + "original_roles": 674, + "scope": "One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof.", + "temporary_streams_peak": 1, + "trial": 0 + }, + "scalar": { + "columns": 674, + "forward_peak_l1": "113", + "independent_integer_columns": 674, + "inverse_transpose_peak_l1": "32" + }, + "word_sha256": "af81c80bca251ebd615389a37cc07ace13167252eab36e10bf9c91a677534130" + }, + "one_replacement": { + "conservative_finite_component_prefix": "473956352", + "frame": { + "coefficients": { + "-1": 1323, + "-1/2": 91, + "-1/4": 416, + "1": 1323, + "1/2": 91, + "1/4": 416 + }, + "copy_profile": { + "7": 1, + "8": 7 + }, + "move_profile": { + "1": 945, + "7": 496, + "8": 175, + "9": 3 + }, + "profile": { + "1": 945, + "7": 497, + "8": 182, + "9": 3 + }, + "rank_mass": 5907, + "source_reads": 441, + "source_restoration_reads": 441, + "unused_helper_tails": 3 + }, + "inverse_transpose_copy_ranks": [ + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 7 + ], + "inverse_transpose_physical": { + "addresses_per_role": 512, + "exact_gaussian_values": 345088, + "inverse_transpose": true, + "operations": { + "C": 5907, + "D": 3254, + "P": 3254, + "X": 3254, + "axpy": 3660, + "center_injection": 8, + "copy_erase": 8, + "copy_zero": 8, + "phase": 3254 + }, + "original_roles": 674, + "scope": "One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof.", + "temporary_streams_peak": 1, + "trial": 0 + }, + "linear": { + "active_helper_streams": 449, + "address_bits": 9, + "axpy_scans": 3660, + "child_dispatches": 1627, + "clean_arithmetic_storage": "O(1) Gaussian dyadic registers per scalar or adapter loop, plus the one temporary stream.", + "copied_target_read_scans": 507, + "copy_assign_scans": 8, + "copy_erase_scans": 8, + "dirty_helper_streams": 452, + "dyadic_scalar_multiplications_per_address": 1014, + "emitted_events": 5295, + "excluded": "No global owner map, outer assembly, rounding implementation, or selected-supplier invoice is supplied.", + "finite_child_native_scans": { + "coordinate_C_factors": 5907, + "diagonal_phase_scans": 3254, + "global_phase_scans": 3254, + "monomial_adapters": 3254, + "permutation_scans": 3254, + "positive_children": 1627, + "xor_translation_scans": 3254 + }, + "finite_complex_cell_accesses_per_address_bound": 48850, + "finite_tape_bound_volume_power": 2, + "finite_tape_complex_cell_move_coefficient": 65947500, + "fixed_address_metadata": "Input-independent permutation cycles and phase tables; these contain no complex data.", + "inverse_transpose_extra_cell_accesses_per_address_bound": 16, + "inverse_transpose_extra_center_injection_scans": 8, + "inverse_transpose_zero_scans_instead_of_copy_assign": 8, + "literal_finite_tape_bound": "With the 675 streams placed consecutively, each addressed read or write needs at most 2*675*M cell moves. Count these moves for every finite address access; no linear tape theorem is claimed.", + "maximum_live_complex_values_at_finite_size": 345600, + "original_streams": 674, + "permutation_bit_operations_per_value_bound": 256, + "positive_recursive_children": 1627, + "quadratic_phase_bit_operations_per_value_bound": 144, + "route_contract": "Every scan and child keeps the complete M-value stream. The full supplier must pay its retained row-routing interface.", + "scalar_additions_per_address": 3660, + "sequential_temporary_streams": 1, + "source_read_scans": 441, + "source_restoration_scans": 441, + "stream_volume": "M complex values, including every control and spectator value; M=512 in the finite replay." + }, + "physical": { + "addresses_per_role": 512, + "exact_gaussian_values": 345088, + "inverse_transpose": false, + "operations": { + "C": 5907, + "D": 3254, + "P": 3254, + "X": 3254, + "axpy": 3660, + "copy_assign": 8, + "copy_erase": 8, + "phase": 3254 + }, + "original_roles": 674, + "scope": "One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof.", + "temporary_streams_peak": 1, + "trial": 0 + }, + "scalar": { + "columns": 674, + "forward_peak_l1": "113", + "independent_integer_columns": 674, + "inverse_transpose_peak_l1": "105/2" + }, + "word_sha256": "a1a5735d6004f4ffa1c544abed325fbfa483adaa69bc002a17c3c8156beb3d50" + } + } +} diff --git a/research/shared-carrier-decoder/LICENSE b/research/shared-carrier-decoder/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/shared-carrier-decoder/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/shared-carrier-decoder/NOTICE.md b/research/shared-carrier-decoder/NOTICE.md new file mode 100644 index 0000000000..bd709b0796 --- /dev/null +++ b/research/shared-carrier-decoder/NOTICE.md @@ -0,0 +1,65 @@ +# Source, credit, and scope + +New construction code, proofs, and documentation were prepared for Ali Romman +(@aliromman) with substantial OpenAI Codex assistance using GPT-6 Astra. +The new material is under the repository's Apache-2.0 license. No independent +human review or priority claim is made. + +The base is `8bddbee377e2f3ce1f1247196c4b290d55767d20`. SOURCES.json records +the source hashes and Git blobs. The only executable source copied from the +base is `vendor/clifford_exact.py`. It is retained byte for byte. It comes from +icekylinx's PR531 complex provider lineage, through PR552, PR558, and PR626. Credit +remains with those contributors and the earlier Clifford and physical compiler +work recorded in that lineage. The package uses the same exact canonical-frame +and Gaussian-dyadic phase convention. + +The mathematical and construction dependencies are: + +- [PR717](https://github.com/CrocSwap/integer-mult-bounds/pull/717), + DreamingOfClouds: the complex B14 decoder model and cost-63 P111 examples. +- [PR968](https://github.com/CrocSwap/integer-mult-bounds/pull/968), head + `6a99e7240b961ac5e115ae6aa0301ec7c4a45d77`, themilkman216, retained as + `research/complex-frame-pair-decoders`: the root-pair explanation and exact + eight-term puncture floor. Its proof leaves physical asymmetric-centre + construction open. The cost-63 number and its optimality are not new here. +- [PR620](https://github.com/CrocSwap/integer-mult-bounds/pull/620), + Joel Pulikkan / GamingPuzzled: the E8 decoder floor and coordinate decoder. + The related binary depth-one P111 value 63 is also prior work in + [PR757](https://github.com/CrocSwap/integer-mult-bounds/pull/757) and + [PR761](https://github.com/CrocSwap/integer-mult-bounds/pull/761). +- `notes/general-clifford-frames.tex`, credited there to icekylinx with OpenAI + assistance: exact frames for arbitrary binary subspaces, nested transitions, + and dirty tail conventions. +- `notes/copied-centers-lemma.tex` and its retained Paureel copy interface: + complete-stream copy, transform, read, and discard; one sequential temporary + stream; a paid recursive transform on the copy. +- The selected PR942/T37 construction and its recorded predecessors supply the + comparison exponent. No selected coefficient, profile, or supplier is changed. + +## Distinct scope at review + +[PR998](https://github.com/CrocSwap/integer-mult-bounds/pull/998), head +`66b777bf2b0160ed926572ff8714ac7b7bba0859`, extends the P112 single-lift floor +to complex coefficients. Its contract keeps eight coordinate readers and adds +one total. This package uses P111 and replaces one reader within eight terms. +It does not assert a counterexample to that floor. + +[PR1008](https://github.com/CrocSwap/integer-mult-bounds/pull/1008), head +`5d90de8d5b7077f4078e42c08ba4872682662e5b`, checks binary P111 tensor elementary +shears. It credits the earlier depth-one value and excludes a physical supplier +or delivery program. This package concerns an executed complex depth-one word. + +[PR1020](https://github.com/CrocSwap/integer-mult-bounds/pull/1020), head +`bf4ee95df4ee6e3101a88f5d015c8aa85b688b6d`, proves a cost-six root-pair +threshold at 26 punctures. It excludes a native supplier. This package keeps +the nine-line puncture and does not change that structural threshold. + +PR781 concerns a coded packet kernel; PR892 concerns complete fixed packing +for a helper endpoint change; PR920 concerns a restricted frame class for parity +kernels. Those scopes do not supply this complex changed-reader word. This is a +targeted overlap check, not a claim that all possible concurrent work was read. + +The first local candidate used eight nonzero COPY endpoints on P104. Their +common-target order was not resolved. That candidate was stopped. The retained +P111 construction has one nonzero endpoint and puts it last. No P104 physical +realization is claimed. diff --git a/research/shared-carrier-decoder/PROOF.md b/research/shared-carrier-decoder/PROOF.md new file mode 100644 index 0000000000..d5a5a91379 --- /dev/null +++ b/research/shared-carrier-decoder/PROOF.md @@ -0,0 +1,225 @@ +# Physical word and composition proof + +This proof concerns the finite module in `model.py`. The exact checks in +`verify.py` supply the finite identities used below. They are not a formal +proof of the integer-multiplication theorem. + +## 1. The decoder + +Let `r_i` be the 120 E8 root lines, with representatives of squared norm two. +The code stores `2 r_i` as integer vectors. Let + +```text +f0=e0+e1, f1=e0-e1, f2=e2+e3, f3=e2-e3, +f4=e4+e5, f5=e4-e5, f6=e6+e7, f7=e6-e7, +beta=e0+e2=(f0+f1+f2+f3)/2. +``` + +Remove the eight `f_k` and `beta`. The remaining set has 111 lines. The +constructor obtains labels `u_i` in the standard dot-product space +`V=F2^9` and checks all 14400 identities + +```text +u_i dot u_j = ( + 1) mod 2. +``` + +It constructs an orthonormal chart from the pairing matrix. No search result +or choice of a random seed is used. Every label has norm one. Put +`H_a = u_a^perp` and `E = span(u_f0)`. + +The direct gather and scatter matrices are + +```text +Q[k,i] = , D[t,k] = /4. +``` + +Since the `f_k` are orthogonal and have squared norm two, +`D Q = G`, where `G[t,i]=/2`. + +Replace the first gather row with `Q'[0,i]=`. Keep the other seven +rows. Thus `Q'[0]=(Q[0]+Q[1]+Q[2]+Q[3])/2`. Use + +```text +D'[t,0] = /2, +D'[t,j] = (-)/4 for j=1,2,3, +D'[t,j] = /4 for j=4,5,6,7. +``` + +Substitution gives `D' Q'=D Q=G`. The verifier checks every one of the +12321 entries with rational arithmetic. There are 444 nonzero direct gather +entries and 441 changed gather entries. The respective scatter counts are +444 and 507. + +For each gather row with root normal `a`, its support labels lie in `H_a`. +The line `a` is removed, so each nonzero inner product is `+1` or `-1`. +The label identity then gives `u_i dot u_a=0`. The constructor also checks +that each support spans all eight dimensions of `H_a`. + +## 2. The nonzero endpoint is last + +The seven unchanged terms copy from `H_fk` to zero. The changed term copies +from `H_beta` to `E`. The product `=1` gives `E subset H_beta`, so +this copy has rank `8-1=7`. Every direct copy has rank eight. + +A target needs the changed term exactly when `` is nonzero. The line +`f0` is removed, so this product is `+1` or `-1`. The label identity gives +`E subset H_t`. There are 55 such targets. + +Process all seven zero-endpoint copies first. Every target stays at zero +through those reads. For the last copy, move each of its 55 targets from zero +to `E`, read the copy, and then move it to its required sink `H_t`. The other +56 targets move directly from zero to `H_t`. These paths are nested. No +later operation needs a target back at zero. + +The old-value compensation occurs before any target moves. It is therefore +legal for all eight terms at zero. Cleanup uses only sources, use helpers, +and centres at FULL. It does not use a target. The order thus works for every +target and for every compensation and restoration operation. The negative +control that puts the nonzero-endpoint copy first fails the common-frame +check on a later target read. + +## 3. Scalar identity with arbitrary dirty helpers + +There is one dirty use helper `h_ki` for each nonzero gather coefficient, +and one dirty centre `c_k` per term. Give each helper an independent initial +value. Both modules have the same stock of 452 helpers. The changed module +uses 449 of them and sends the other three directly from zero to FULL. + +For each term, let `b_k=c_k+sum_i h_ki` denote its old combined value. The +literal chronological word has these eight stages: + +1. Add all use helpers to their centres at zero. +2. Subtract `sum_k D[t,k] b_k` from each target at zero. +3. Subtract the same use helpers from their centres. +4. Add `Q[k,i] X_i` to each use helper at its source line. +5. Add all updated use helpers to their centres at `H_a`. +6. Copy each centre to its stated endpoint and add the required scatter terms. +7. At FULL, subtract all updated use helpers from their centres. +8. At FULL, subtract `Q[k,i] X_i` from each use helper. + +Use `D',Q'` for the changed module. After stage five, centre `k` holds +`b_k+sum_i Q[k,i] X_i`. Stages two and six therefore add exactly `D Q X` +to the targets. Stage seven restores every centre to its independent initial +value. Stage eight restores every use helper. Sources never change their +logical value. The three inactive helpers never change their logical value. + +This argument applies component by component to arbitrary complex vectors. +The sparse rational replay checks all 674 logical input columns. A second +interpreter propagates one integer column at a time with denominator four; +it obtains the expected Gram map directly from the roots. It does not use +the sparse row result as its expected value. + +## 4. Exact native frames and the composition bridge + +For a binary subspace `U`, use the retained exact operator +`T_U = clifford_exact.canonical_frame(9,U)`. Its source bytes are pinned in +SOURCES.json. In particular, `T_0=I` and `T_FULL=F=C^tensor9`. The preimage +Lagrangian is + +```text +L_U = {(u,u+z): u in U, z in U^perp}. +``` + +The verifier applies each exact signed Pauli tableau to a basis of `L_U` and +checks that the image has zero X part. Both spaces have dimension nine. +The intersection formula gives + +```text +d(L_U,L_W) = dim(U)+dim(W)-2 dim(U intersect W). +``` + +Use the following invariant at every event: a role whose logical vector is +`v` and whose frame is `U` contains exactly `T_U v` as its physical array. +It holds at the advertised input endpoints. Each event preserves it: + +- **Move.** Apply the exact operator `A=T_W T_U^-1`. The array becomes + `T_W v`. `lower_child(A)` emits two monomial adapters around one contiguous + `C^tensorr` child, where `r=d(L_U,L_W)`. The verifier checks its rank, signed + Pauli tableau, and exact image of the zero basis vector. Equality of the + signed Pauli action gives equality up to a scalar; the zero-vector image + fixes that scalar. A ratio that commutes with all Z operators is diagonal; + commuting with all X operators makes its diagonal constant. Thus the check + proves the exact operator identity, + including phase, on every input vector. +- **Scalar add.** The two roles have the same exact `T_U`. A physical AXPY + gives `T_U v + q T_U w = T_U(v+q w)`. No equal-frame change is assumed free: + every role is constructed with the same canonical representative, and every + actual change has its own emitted native adapters. +- **COPY begin.** Allocate one complete temporary stream and copy `T_U c` + into it. Apply the paid child `T_W T_U^-1` to that copy. It now contains + exactly `T_W c`. This child is in the same rank and adapter invoice as every + original move. Its volume is the complete source volume, including control + and spectator values. +- **COPY reads and disposal.** Each target is at `W`, so its AXPY has the same + interpretation as above. The retained centre stays at `U` and is not changed + during the lifetime of the copy. The replay checks this fact. After the last + read, erase the temporary stream. Copies are sequential, so one temporary + stream suffices. Allocation, reads, and erasure have separate paid entries. + +Induction over the emitted word now connects the scalar identity to the +actual physical circuit. The result is not a scalar check followed by an +unrelated phase check: each scalar incidence and each COPY is bound to its +exact live frame and exact native transition by this invariant. + +Let `S` be the scalar map from section 3. Let `A_in` and `A_out` be the block +sums of the exact input and output frame operators. The whole physical map is + +```text +P = A_out S A_in^-1. +``` + +Both modules have identical `A_in` and `A_out`: sources enter at their lines +and leave at FULL; targets enter at zero and leave at `H_t`; every helper +enters at zero and leaves at FULL. A helper with initial physical vector `h` +therefore leaves with `F h`. The claim is logical restoration at FULL, +not physical identity on the helper array. External host charts or different +endpoint conventions would need their own charged adapters. This module does +not claim admission to the selected host. + +## 5. Inverse transpose and the temporary stream + +The package also executes `P^-T`. Use dual frames `R_U=T_U^-T`. Replace each +scalar shear `v_t += q v_s` by `v_s -= q v_t` in the same chronological order. +For a product of chronological shears, inverse transpose preserves this order. +The all-column replay checks the resulting map `X -= G^T Y`. + +A move uses `(T_W T_U^-1)^-T`, so it carries `R_U v` to `R_W v`. For a COPY +block, start a zero temporary stream at `R_W`. Accumulate `-D[t,k]` times each +target into it. At the end, apply `(T_W T_U^-1)^T` and add the result once to +the retained centre at `R_U`. The identity + +```text +(T_W T_U^-1)^T R_W = R_U +``` + +proves the required action. The copy transpose has the same Fourier rank. +Every target is constant during this dual copy block. The aggregate is thus +exactly the sum of the dual scalar shears. This orientation pays eight zero +scans and eight additional centre AXPYs in place of eight copy assignments. +It erases the same eight sequential temporary streams. + +The verifier lowers and phase-checks every executed dual move and COPY. The +separate Gaussian-integer interpreter executes both orientations for both +modules and compares all final physical arrays with their stated operators. +The rank-seven COPY is also checked on all 512 basis columns. + +## 6. Finite size and numerical scope + +The exact replay uses 512 addresses per original role. It has no floating +point arithmetic. The maximum logical row L1 norms are 113 in both forward +words, 32 in the direct inverse transpose, and 105/2 in the changed inverse +transpose. + +A C factor increases the maximum real or imaginary component by at most two. +An exact canonical frame and a lowered child each have at most nine C factors. +Converting an input source from its line frame costs a factor at most two. +A dual temporary sum can be bounded by the difference of two scalar prefixes, +which costs another factor two. A factor four covers scalar intermediates in +the pair formula. Thus `2^22 * 113 = 473956352` is a conservative finite +component prefix bound relative to the largest physical input component. +Permutations and unit phases do not increase that component norm. + +This bound is deliberately loose. It does not supply a fixed-precision +implementation, an all-size rounding argument, or a tape admission theorem. +The written argument and its finite checks have not had independent human +review. diff --git a/research/shared-carrier-decoder/README.md b/research/shared-carrier-decoder/README.md new file mode 100644 index 0000000000..fdaeab093a --- /dev/null +++ b/research/shared-carrier-decoder/README.md @@ -0,0 +1,98 @@ +# A physical complex P111 decoder with one nonzero COPY endpoint + +This package builds and executes two exact complex decoder modules on the same +111 data pairs and 452 dirty helper streams. The changed decoder has a smaller +complete recursive moment on `0 <= b <= 1/256`. It also uses **108 more scalar +AXPY scans**. No runtime gain, selected-supplier gain, or new kappa is claimed. + +The copied-rank value 63 is prior work. The new result is its explicit physical +word: source access, old-value compensation, exact Clifford phases, a nonzero +COPY endpoint, all helper tails, and arbitrary dirty-helper restoration. The +coordinate decoder is an executable baseline with the same physical endpoints +and helper stock. The changed word pays three unused rank-nine helper tails. + +| Paid quantity | Coordinate baseline | One replacement | Change | +|---|---:|---:|---:| +| Copied rank | 64 | 63 | -1 | +| All positive recursive children | 1578 | 1627 | +49 | +| Complete rank mass | 5908 | 5907 | -1 | +| Scalar AXPY scans | 3552 | 3660 | **+108** | +| Nonunit dyadic scalar multiplications per address | 888 | 1014 | +126 | +| Each of P, D, X, and global-phase adapter scans | 3156 | 3254 | +98 | +| Original streams | 674 | 674 | 0 | +| Peak temporary complex streams | 1 | 1 | 0 | + +Write `H_r` for one recursive child of rank `r`. The complete profiles are + +```text +baseline: 896 H_1 + 444 H_7 + 238 H_8 +candidate: 945 H_1 + 497 H_7 + 182 H_8 + 3 H_9. +``` + +For a child price `r(m/r)^b`, their difference is strictly negative throughout +`0 <= b <= 1/256`, including the selected complex exponent +`0.001664727258740678855772` at the pinned base. This is a statement about the +recursive part of the invoice. The extra scalar and adapter work stays in the +full recurrence. See [COST.md](COST.md). + +## Reproduce + +Base: `8bddbee377e2f3ce1f1247196c4b290d55767d20`. Use Python 3.10 or later and +its standard library. Run from the repository root: + +```sh +python3 -I -B research/shared-carrier-decoder/verify.py +python3 -I -B research/shared-carrier-decoder/test_controls.py +``` + +The first command checks the committed [EXPECTED.json](EXPECTED.json). Its last +line is: + +```text +PASS_SHARED_CARRIER_DECODER copies=64->63 columns=674 axpys=3552->3660 interval=[0,1/256] no_new_kappa +``` + +The second command rejects 11 broken constructions and three bad receipt cases. Its last line is: + +```text +PASS_SHARED_CARRIER_CONTROLS controls=14 +``` + +Use `--out /new/directory` with `verify.py` to write both complete words, all +native lowering records, and a certificate. The directory must not exist. +`EXPECTED.json` is required. Receipt comparison rejects Boolean or float values +in integer fields. `-O` is supported. The pinned compiler's assertions stay +enabled under `-O`. +The package also runs after it is copied outside the repository. +[VALIDATION.md](VALIDATION.md) records the completed checks and the separate +second-input review. + +## Evidence and scope + +- `model.py` constructs the E8 labels, the changed decoder, and both literal + words. It does not import an existing cost-63 witness. +- `verify.py` checks all 674 independent logical input columns, including every + dirty helper. A separate integer column interpreter checks the forward map. + It checks the full frame schedule and every native child, including its exact + phase. The certificate binds the emitted words and lowering records by hash. +- `physical.py` executes each whole physical word and its inverse transpose on + one dense Gaussian input across 674 streams of 512 values. It also checks all + 512 matrix columns of the rank-seven COPY. The whole-word dense input is a + finite execution check. The all-input conclusion uses the composition proof + in [PROOF.md](PROOF.md), together with the exact scalar and operator checks. +- The physical word uses in-place scalar loops, permutation cycles, phases, + translations, and C pairs. It needs one temporary complex stream. Address + tables contain fixed integers, not input-dependent complex data. +- Helpers recover their logical input at the advertised final FULL frame. + Their physical output is `F h`, not the same physical array `h`. + +This is a complete finite decoder module for the normalized Gram shear +`Y += G X`, where `G[t,i] = /2`. It is not a full supplier for +`Y += X`. It does not supply the remaining side corrections, a host owner map, +an all-size tape or rounding proof, or an outer bound assembly. The finite +routing bound in COST.md is explicit and quadratic; it is not a linear tape +admission. All selected files and `upstream/` stay unchanged. + +[NOTICE.md](NOTICE.md) gives the predecessor credit and overlap check. New +material was prepared for Ali Romman (@aliromman) with substantial OpenAI Codex +assistance. No independent human review is claimed. diff --git a/research/shared-carrier-decoder/REVIEW-SECOND-INPUT.json b/research/shared-carrier-decoder/REVIEW-SECOND-INPUT.json new file mode 100644 index 0000000000..08340c8318 --- /dev/null +++ b/research/shared-carrier-decoder/REVIEW-SECOND-INPUT.json @@ -0,0 +1,48 @@ +{ + "status": "PASS_PARENT_DECODER_DENSE_SECOND_INPUT", + "source_sha256": { + "model.py": "ece6a96ff45bee2c6926835d90a4a2c39dc07123aba35caab9dc823c8bc8e0d5", + "physical.py": "8f0193c2c3e4719321bb3ff18b6ad65034cd0a1eb48dc91751b4039a4f650048", + "verify.py": "cc562d4614df67a27ee76ca22a3ecd08e9fb5dfa1a718529aeadea7997d96326", + "test_controls.py": "9c5c76b711601c844c5f328c1d95d12f842d92a85ff961375fdf88fee9ae736b" + }, + "forward": { + "original_roles": 674, + "addresses_per_role": 512, + "exact_gaussian_values": 345088, + "trial": 1, + "inverse_transpose": false, + "operations": { + "C": 5907, + "D": 3254, + "P": 3254, + "X": 3254, + "axpy": 3660, + "copy_assign": 8, + "copy_erase": 8, + "phase": 3254 + }, + "temporary_streams_peak": 1, + "scope": "One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof." + }, + "inverse_transpose": { + "original_roles": 674, + "addresses_per_role": 512, + "exact_gaussian_values": 345088, + "trial": 1, + "inverse_transpose": true, + "operations": { + "C": 5907, + "D": 3254, + "P": 3254, + "X": 3254, + "axpy": 3660, + "center_injection": 8, + "copy_erase": 8, + "copy_zero": 8, + "phase": 3254 + }, + "temporary_streams_peak": 1, + "scope": "One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof." + } +} diff --git a/research/shared-carrier-decoder/SOURCES.json b/research/shared-carrier-decoder/SOURCES.json new file mode 100644 index 0000000000..61a31b8497 --- /dev/null +++ b/research/shared-carrier-decoder/SOURCES.json @@ -0,0 +1,32 @@ +{ + "base": "8bddbee377e2f3ce1f1247196c4b290d55767d20", + "clifford": { + "source": "research/complex-k492-owner-repair/vendor/multicold/vendor/pr558/vendor/pr552/complex-global/vendor531/vendor/clifford/clifford_exact.py", + "sha256": "2982ead07721e83358dc67c6f49c2b4c16a236a6bebdfd72f58221be1f5d0962", + "git_blob": "166841a037f069249f6f7f6dedb89248812f59e2", + "license": "Apache-2.0", + "attribution": "Exact Clifford compiler retained from the PR531 complex provider lineage, through PR552, PR558 and PR626. Original source is unchanged." + }, + "read_dependencies": { + "notes/general-clifford-frames.tex": { + "sha256": "c9bb9655b594583c6b4bab8cb485233f1d1e588f83858cf1e4c3530cee8fed54", + "git_blob": "0367eeb005298601f28a673861d6f71bf1d0ebbb" + }, + "notes/copied-centers-lemma.tex": { + "sha256": "d0ce6d3d504996aadb098227885224e48df46101daec8893523a0a8b7364d8fe", + "git_blob": "8933aaf508aa9d4c75ba1290913e02f6868d351d" + }, + "research/complex-frame-pair-decoders/PROOF.md": { + "sha256": "ba53c1d8a9bc2d935d546bde46ca7341bd65f8515013e07b073296b4db2a9a74", + "git_blob": "889f3a653ed1bdbb7df61ebe3af4f2103602a1f4" + }, + "research/complex-frame-pair-decoders/README.md": { + "sha256": "edd848b0177dc73a6e2646d4fd82f0b2ceae37e642bf19d6af602579a041a57e", + "git_blob": "be5bbbee8e30a4ee39fa513896e8fc7e0bb3721e" + }, + "research/community-frontier942-audit/ASSEMBLY.json": { + "sha256": "4b2894956e594e408e111d806c842f2ed2c32aefcadff93fad69ff0b46f1991a", + "git_blob": "9e71e9c1a1c1cbd1979f0c7bac87495322cbfad0" + } + } +} diff --git a/research/shared-carrier-decoder/VALIDATION.md b/research/shared-carrier-decoder/VALIDATION.md new file mode 100644 index 0000000000..af6d996837 --- /dev/null +++ b/research/shared-carrier-decoder/VALIDATION.md @@ -0,0 +1,77 @@ +# Validation record + +Validation used Python 3.14.7 on macOS 26.6.1, arm64. The final mathematical +sources, compiler pin, and expected receipt stayed fixed throughout each run. +Only documentation was completed afterward. The package uses the standard +library and one CPU. Peak child resident memory was 102875136 bytes, below +99 MiB. This is checker memory, not a supplier workspace bound. + +| Check | Result | Wall time | +|---|---|---:| +| `python3 -I -B research/shared-carrier-decoder/verify.py --out /new/directory` | exit 0; all final markers | 210.337 s | +| `python3 -I -B research/shared-carrier-decoder/test_controls.py` | exit 0; 14 controls | 2.068 s | +| Same package copied outside the repository to a path with spaces; `python3 -I -O -B verify.py --out /new/directory` | exit 0; all final markers | 170.133 s | +| Control suite in that relocated, optimized environment | exit 0; 14 controls | 1.936 s | +| Changed compiler source in the relocated package | exit 1; `Clifford source pin` | 0.091 s | +| `make selected-record-check` | exit 0; selected record intact | 0.492 s | + +The source-pin control restored the copied compiler before the successful +relocated run. Both generated CERTIFICATE.json files are byte-identical to +EXPECTED.json. The two word hashes and native lowering hash agree as well. +Timing is recorded for reproduction; it is not a performance comparison. + +## Coverage + +Each primary run checks both modules on all 674 independent logical columns. +The exact sparse row and separate integer column interpreters use different +state representations. The native audit checks 234 exact frame operators and +913 distinct ordered transitions. Each transition uses the retained compiler, +with its assertions enabled even under an optimized parent process. + +The separate physical interpreter executes both forward words and both inverse +transposes. Each execution checks 345088 complex output values, from 674 roles +and 512 addresses. All 512 matrix columns of the nonzero-endpoint rank-seven +COPY also pass. These execution checks support, but do not replace, the written +composition proof for arbitrary physical inputs. + +The coordinator, in a separate Codex review, ran all 14 controls and chose a +second dense input (`trial=1`) for the candidate's forward and inverse-transpose +physical executions. Both passed. [REVIEW-SECOND-INPUT.json](REVIEW-SECOND-INPUT.json) +binds that result to the four Python source hashes. This was a separate AI +replay with the same interpreter, not an independent human or formal review. + +## Failure controls and their contracts + +| Change | Contract that rejects it | +|---|---| +| Omit one old-value compensation, centre restoration, source restoration, or source read | Exact map on all independent dirty inputs | +| Change one scatter coefficient | Complete normalized Gram identity | +| Process the nonzero endpoint first | Common exact frame at every later COPY read | +| Copy to a line outside the query hyperplane | Legal source/endpoint inclusion | +| Omit one inactive helper tail | Every advertised physical output frame | +| Dispose of a copy before its first read | Temporary stream lifetime | +| Add a global phase to the compiled COPY | Exact complex operator, beyond its binary frame | +| Omit one C factor | Actual paid recursive operator | +| Replace integer 1 in the receipt with Boolean true or floating 1.0 | Canonical JSON value and type agreement | +| Remove EXPECTED.json from a copied package | Required receipt at the ordinary CLI boundary | + +The last three cases repair a review finding. The prior parsed-object equality +accepted `true == 1` and `1.0 == 1`. The verifier now compares canonical JSON +after it normalizes integer histogram keys. The missing-file control invokes +the real CLI on a copied package and fails before native work starts. + +The tests use the existing construction and verification entry points. They do +not add an alternate execution mode or alter a native primitive for testing. + +## Earlier failure and checks outside scope + +An earlier `/usr/bin/time -l` wrapper returned 1 because macOS denied its +`kern.clockrate` query after the verifier had completed. That wrapper result is +not counted as an exit-zero validation. The final runner records each Python +child's own return code and uses the permitted resource counter. + +The full repository `make verify`, historical supplier cold suites, hosted CI, +an all-size compiler, rounding code, and a linear tape implementation were not +run or built. This patch adds one isolated finite research package and changes +no selected construction or upstream source. The full theorem and runtime +claims stay outside its scope. diff --git a/research/shared-carrier-decoder/model.py b/research/shared-carrier-decoder/model.py new file mode 100644 index 0000000000..e0ecbe5e7f --- /dev/null +++ b/research/shared-carrier-decoder/model.py @@ -0,0 +1,235 @@ +# SPDX-License-Identifier: Apache-2.0 +"""Build the P111 decoder and its paid frame schedule.""" +from fractions import Fraction as Q +from itertools import combinations, product + +N = 9 +FULL = tuple(1 << j for j in range(N)) +ZERO = () + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def basis(rows): + pivots = {} + for value in rows: + while value: + bit = value.bit_length() - 1 + if bit in pivots: + value ^= pivots[bit] + else: + pivots[bit] = value + break + for bit in sorted(pivots): + for other in pivots: + if other > bit and (pivots[other] >> bit) & 1: + pivots[other] ^= pivots[bit] + return tuple(pivots[bit] for bit in sorted(pivots)) + + +def span(rows): + values = {0} + for row in rows: + values |= {x ^ row for x in values} + return values + + +def contained(left, right): + return len(basis(left + right)) == len(basis(right)) + + +def distance(left, right): + return 2 * len(basis(left + right)) - len(left) - len(right) + + +def parity(value): + return value.bit_count() & 1 + + +def perp(vector): + return basis([x for x in range(1, 1 << N) if parity(x & vector) == 0]) + + +def dot(x, y): + return sum(a * b for a, b in zip(x, y)) + + +def roots(): + values = [] + for a, b in combinations(range(8), 2): + for sign in (1, -1): + row = [0] * 8 + row[a], row[b] = 2, 2 * sign + values.append(tuple(row)) + for signs in product((1, -1), repeat=7): + row = (1,) + signs + if row.count(-1) % 2 == 0: + values.append(row) + require(len(values) == 120, "E8 line count") + return values + + +def labels_from_pairing(gram): + """Construct an orthonormal chart for the binary label form.""" + rows = [sum(((value + 1) & 1) << j for j, value in enumerate(row)) for row in gram] + anchors = [] + for index, row in enumerate(rows): + if len(basis([rows[j] for j in anchors] + [row])) > len(anchors): + anchors.append(index) + require(len(anchors) == N, "binary label rank") + form = [sum(((gram[a][b] + 1) & 1) << j for j, b in enumerate(anchors)) for a in anchors] + + def pairing(x, y): + return parity(sum(parity(row & y) << i for i, row in enumerate(form)) & x) + + chart = [] + for _ in range(N): + candidates = [x for x in range(1, 1 << N) + if all(pairing(x, y) == 0 for y in chart) and pairing(x, x)] + chosen = None + for x in candidates: + trial = chart + [x] + if len(trial) == N or any( + pairing(y, y) and all(pairing(y, z) == 0 for z in trial) + for y in range(1, 1 << N) + ): + chosen = x + break + require(chosen is not None, "orthonormal chart exists") + chart.append(chosen) + labels = [] + for row in gram: + evaluations = sum(((row[a] + 1) & 1) << i for i, a in enumerate(anchors)) + labels.append(sum(parity(evaluations & x) << i for i, x in enumerate(chart))) + require(all(parity(labels[i] & labels[j]) == ((gram[i][j] + 1) & 1) + for i in range(120) for j in range(120)), "label pairing identity") + return labels + + +def geometry(): + lines = roots() + gram = [[dot(a, b) // 4 for b in lines] for a in lines] + require(all(dot(a, b) % 4 == 0 for a in lines for b in lines), "integral E8 products") + frame = [] + for a in range(0, 8, 2): + for sign in (1, -1): + row = tuple(2 if j == a else 2 * sign if j == a + 1 else 0 for j in range(8)) + frame.append(lines.index(row)) + extra = next(j for j in range(120) if j not in frame) + pivot = next(k for k, a in enumerate(frame) if gram[extra][a]) + live = [i for i in range(120) if i not in frame and i != extra] + labels = labels_from_pairing(gram) + return dict(lines=lines, gram=gram, frame=frame, extra=extra, pivot=pivot, + live=live, labels=labels, ports=[labels[i] for i in live]) + + +def decoder(geo, replaced): + live, frame, gram = geo['live'], geo['frame'], geo['gram'] + gather = [[gram[i][a] for i in live] for a in frame] + scatter = [[Q(gram[i][a], 4) for a in frame] for i in live] + normals = list(frame) + endpoints = [ZERO for _ in frame] + if replaced: + k, beta = geo['pivot'], geo['extra'] + coefficients = [Q(gram[beta][a], 2) for a in frame] + require(coefficients[k] != 0, "replacement pivot") + gather[k] = [gram[beta][i] for i in live] + normals[k] = beta + endpoints[k] = (geo['labels'][frame[k]],) + for row in scatter: + old = row[k] + for j in range(8): + row[j] = old / coefficients[k] if j == k else row[j] - old * coefficients[j] / coefficients[k] + query_frames = [perp(geo['labels'][a]) for a in normals] + for k, row in enumerate(gather): + support = [geo['ports'][i] for i, value in enumerate(row) if value] + require(basis(support) == query_frames[k], "source query span") + require(contained(endpoints[k], query_frames[k]), "copy endpoint inside source span") + expected = [[Q(gram[t][i], 2) for i in live] for t in live] + require(all(sum(scatter[t][k] * gather[k][i] for k in range(8)) == expected[t][i] + for t in range(111) for i in range(111)), "exact decoder identity") + return dict(gather=gather, scatter=scatter, frames=query_frames, + endpoints=endpoints, expected=expected, normals=normals) + + +def build(replaced=True): + geo = geometry() + data = decoder(geo, replaced) + v = len(geo['live']) + # Both words use the same stock. The candidate pays the three unused tails. + direct = decoder(geo, False) + stock = sum(bool(q) for row in direct['gather'] for q in row) + 8 + n = 2 * v + stock + centers = list(range(2 * v, 2 * v + 8)) + uses = [] + for k, row in enumerate(data['gather']): + for i, q in enumerate(row): + if q: + uses.append(dict(center=k, source=i, q=q, role=2 * v + 8 + len(uses))) + require(2 * v + 8 + len(uses) <= n, "matched helper stock") + frames = [(p,) for p in geo['ports']] + [ZERO] * (n - v) + initial = list(frames) + events = [] + + def move(role, frame): + frame = basis(frame) + if frames[role] != frame: + require(contained(frames[role], frame), "constructor frame descent") + events.append(dict(op='move', role=role, before=list(frames[role]), after=list(frame))) + frames[role] = frame + + def add(target, source, q, frame, phase): + require(frames[target] == frames[source] == basis(frame), "constructor common frame") + events.append(dict(op='add', target=target, source=source, q=str(q), frame=list(frame), phase=phase)) + + # Compute and remove the complete response to arbitrary helper input. + for use in uses: + add(centers[use['center']], use['role'], 1, ZERO, 'old_gather') + for t, row in enumerate(data['scatter']): + for k, q in enumerate(row): + if q: + add(v + t, centers[k], -q, ZERO, 'compensate') + for use in reversed(uses): + add(centers[use['center']], use['role'], -1, ZERO, 'old_ungather') + # Read every source at its initial line. No source copy is free. + for use in uses: + i, h = use['source'], use['role'] + move(h, (geo['ports'][i],)) + add(h, i, use['q'], (geo['ports'][i],), 'source_read') + for k, center in enumerate(centers): + frame = data['frames'][k] + move(center, frame) + for use in uses: + if use['center'] == k: + move(use['role'], frame) + add(center, use['role'], 1, frame, 'new_gather') + order = [k for k in range(8) if not data['endpoints'][k]] + [k for k in range(8) if data['endpoints'][k]] + for k in order: + endpoint = data['endpoints'][k] + events.append(dict(op='copy_begin', source=centers[k], before=list(data['frames'][k]), after=list(endpoint), term=k)) + for t, row in enumerate(data['scatter']): + if row[k]: + move(v + t, endpoint) + events.append(dict(op='copy_add', target=v + t, q=str(row[k]), frame=list(endpoint), term=k)) + events.append(dict(op='copy_end', term=k)) + # The retained centers and all source-use helpers are restored at FULL. + for role in list(range(v)) + list(range(2 * v, n)): + move(role, FULL) + for use in reversed(uses): + add(centers[use['center']], use['role'], -1, FULL, 'restore_gather') + for use in reversed(uses): + add(use['role'], use['source'], -use['q'], FULL, 'restore_source') + for t, port in enumerate(geo['ports']): + move(v + t, perp(port)) + return dict(version=1, name='one_replacement' if replaced else 'coordinate', + n=n, v=v, helper_stock=stock, active_helpers=8 + len(uses), + initial_frames=[list(x) for x in initial], final_frames=[list(x) for x in frames], + events=events, centers=centers, unused=list(range(2 * v + 8 + len(uses), n)), + geometry=geo, decoder=data) + + +def serializable(word): + return {key: value for key, value in word.items() if key not in ('geometry', 'decoder')} diff --git a/research/shared-carrier-decoder/physical.py b/research/shared-carrier-decoder/physical.py new file mode 100644 index 0000000000..5cef032067 --- /dev/null +++ b/research/shared-carrier-decoder/physical.py @@ -0,0 +1,250 @@ +# SPDX-License-Identifier: Apache-2.0 +"""Execute the literal physical word with exact Gaussian dyadic arrays.""" +from collections import Counter +from fractions import Fraction as Q +from model import N, basis, distance, require + +SIZE = 1 << N + + +class Array: + def __init__(self, real, imag, denominator=0): + self.real = list(real) + self.imag = list(imag) + self.denominator = denominator + self.reduce() + + def copy(self): + return Array(self.real, self.imag, self.denominator) + + def reduce(self): + common = 0 + for part in (self.real, self.imag): + for value in part: + common |= value + if not common: + self.denominator = 0 + return + zeros = (abs(common) & -abs(common)).bit_length() - 1 + shift = min(zeros, self.denominator) + if shift: + for part in (self.real, self.imag): + for index, value in enumerate(part): + part[index] = value >> shift + self.denominator -= shift + + def add(self, source, coefficient): + power = coefficient.denominator.bit_length() - 1 + require(coefficient.denominator == 1 << power, 'physical dyadic scalar') + denominator = max(self.denominator, source.denominator + power) + left = denominator - self.denominator + right = denominator - source.denominator - power + num = coefficient.numerator + for target, values in ((self.real, source.real), (self.imag, source.imag)): + for index, value in enumerate(values): + target[index] = (target[index] << left) + num * (value << right) + self.denominator = denominator + self.reduce() + + def same(self, other): + return self.denominator == other.denominator and self.real == other.real and self.imag == other.imag + + +class Executor: + def __init__(self): + self.permutations = {} + self.phases = {} + self.counts = Counter() + + def apply(self, array, circuit): + for gate in circuit: + kind = gate[0] + self.counts[kind] += 1 + if kind == 'P': + rows = tuple(gate[1]) + if rows not in self.permutations: + indices = [sum(((row & x).bit_count() % 2) << bit for bit, row in enumerate(rows)) for x in range(SIZE)] + cycles, seen = [], set() + for start in range(SIZE): + if start in seen: + continue + cycle, current = [], start + while current not in seen: + seen.add(current) + cycle.append(current) + current = indices[current] + require(current == start, 'physical permutation cycle') + if len(cycle) > 1: + cycles.append(tuple(cycle)) + self.permutations[rows] = cycles + for cycle in self.permutations[rows]: + real, imag = array.real[cycle[-1]], array.imag[cycle[-1]] + for index in cycle: + array.real[index], real = real, array.real[index] + array.imag[index], imag = imag, array.imag[index] + elif kind == 'X': + offset = gate[1] + for x in range(SIZE): + y = x ^ offset + if x < y: + array.real[x], array.real[y] = array.real[y], array.real[x] + array.imag[x], array.imag[y] = array.imag[y], array.imag[x] + elif kind in ('D', 'phase'): + if kind == 'phase': + phases = [gate[1]] * SIZE + else: + quadratic, linear = tuple(gate[1]), tuple(gate[2]) + key = (quadratic, linear) + if key not in self.phases: + values = [] + for x in range(SIZE): + power = sum(linear[i] for i in range(N) if x & (1 << i)) + power += 2 * sum(1 for i in range(N) for j in range(i + 1, N) + if (x >> i) & (x >> j) & (quadratic[i] >> j) & 1) + values.append(power % 4) + self.phases[key] = values + phases = self.phases[key] + for x, power in enumerate(phases): + a, b = array.real[x], array.imag[x] + array.real[x], array.imag[x] = ((a, b), (-b, a), (-a, -b), (b, -a))[power % 4] + elif kind == 'C': + mask, sign = gate[1], gate[2] + require(mask > 0, 'physical C mask') + for x in range(SIZE): + y = x ^ mask + if x < y: + a, b, c, d = array.real[x], array.imag[x], array.real[y], array.imag[y] + array.real[x] = a + c + sign * (d - b) + array.imag[x] = b + d + sign * (a - c) + array.real[y] = a + c + sign * (b - d) + array.imag[y] = b + d + sign * (c - a) + array.denominator += 1 + array.reduce() + else: + raise ValueError('physical circuit primitive') + return array + + +def input_array(role, trial=0): + # This fixed input puts dense Gaussian values in every original role. + real = [((37 * role + 11 * x + 3 * role * x + trial * (x * x + role)) % 31) - 15 for x in range(SIZE)] + imag = [((19 * role + 7 * x + role * x * x + trial * (2 * x + role * role)) % 29) - 14 for x in range(SIZE)] + return Array(real, imag) + + +def expected_target(word, target, trial, inverse_transpose=False): + initial = input_array(target if inverse_transpose else word['v'] + target, trial) + real = [2 * x for x in initial.real] + imag = [2 * x for x in initial.imag] + root_t = word['geometry']['live'][target] + for source, root_i in enumerate(word['geometry']['live']): + weight = word['geometry']['gram'][root_t][root_i] + if weight: + values = input_array(word['v'] + source if inverse_transpose else source, trial) + if inverse_transpose: + weight = -weight + real = [a + weight * b for a, b in zip(real, values.real)] + imag = [a + weight * b for a, b in zip(imag, values.imag)] + return Array(real, imag, 1) + + +def whole_word(word, audit, trial=0, inverse_transpose=False): + from verify import transpose_operator + dual_frames = {} + dual_moves = {} + def frame_operator(frame): + original = audit.frame(frame) + if not inverse_transpose: + return original + if frame not in dual_frames: + dual_frames[frame] = transpose_operator(audit.cx, original.adjoint()) + return dual_frames[frame] + def move_operator(before, after, copy=False): + rank = distance(before, after) + _, original, compiled = audit.transition(before, after, rank) + if not inverse_transpose: + return compiled + key = (before, after, copy) + if key not in dual_moves: + dual = transpose_operator(audit.cx, original if copy else original.adjoint()) + receipt, lowered = audit.cx.lower_child(dual) + require(receipt['rank'] == rank, 'dual physical recursive rank') + require(lowered.tab == dual.tab and lowered.zero_state() == dual.zero_state(), 'dual physical exact phase') + dual_moves[key] = lowered + return dual_moves[key] + executor = Executor() + arrays = [input_array(role, trial) for role in range(word['n'])] + for role, frame in enumerate(word['initial_frames']): + executor.apply(arrays[role], frame_operator(basis(frame)).circuit) + executor.counts.clear() + temporary = None + copied = None + for event in word['events']: + op = event['op'] + if op in ('move', 'copy_begin'): + before, after = basis(event['before']), basis(event['after']) + compiled = move_operator(before, after, copy=(op == 'copy_begin')) + if op == 'move': + executor.apply(arrays[event['role']], compiled.circuit) + else: + require(temporary is None, 'physical temporary overlap') + copied = (event['source'], compiled) + if inverse_transpose: + temporary = Array([0] * SIZE, [0] * SIZE) + executor.counts['copy_zero'] += 1 + else: + temporary = arrays[event['source']].copy() + executor.apply(temporary, compiled.circuit) + executor.counts['copy_assign'] += 1 + elif op == 'add': + if inverse_transpose: + arrays[event['source']].add(arrays[event['target']], -Q(event['q'])) + else: + arrays[event['target']].add(arrays[event['source']], Q(event['q'])) + executor.counts['axpy'] += 1 + elif op == 'copy_add': + require(temporary is not None, 'physical missing copy') + if inverse_transpose: + temporary.add(arrays[event['target']], -Q(event['q'])) + else: + arrays[event['target']].add(temporary, Q(event['q'])) + executor.counts['axpy'] += 1 + elif op == 'copy_end': + require(temporary is not None, 'physical missing erase') + if inverse_transpose: + executor.apply(temporary, copied[1].circuit) + arrays[copied[0]].add(temporary, Q(1)) + executor.counts['center_injection'] += 1 + temporary = None + copied = None + executor.counts['copy_erase'] += 1 + else: + raise ValueError('physical word event') + require(temporary is None, 'physical final temporary') + word_counts = dict(sorted(executor.counts.items())) + for role, final in enumerate(word['final_frames']): + if inverse_transpose and role < word['v']: + logical = expected_target(word, role, trial, inverse_transpose=True) + elif not inverse_transpose and word['v'] <= role < 2 * word['v']: + logical = expected_target(word, role - word['v'], trial) + else: + logical = input_array(role, trial) + expected = executor.apply(logical, frame_operator(basis(final)).circuit) + require(arrays[role].same(expected), f'whole physical output role {role}') + return dict(original_roles=word['n'], addresses_per_role=SIZE, + exact_gaussian_values=word['n'] * SIZE, trial=trial, inverse_transpose=inverse_transpose, + operations=word_counts, temporary_streams_peak=1, + scope='One dense Gaussian input across every physical stream and address; all-input coverage comes from the symbolic composition proof.') + + +def copy_matrix(word, audit): + event = next(e for e in word['events'] if e['op'] == 'copy_begin' and distance(basis(e['before']), basis(e['after'])) == 7) + _, original, compiled = audit.transition(basis(event['before']), basis(event['after']), 7) + executor = Executor() + for column in range(SIZE): + values = [0] * SIZE + values[column] = 1 + left = executor.apply(Array(values, [0] * SIZE), original.circuit) + right = executor.apply(Array(values, [0] * SIZE), compiled.circuit) + require(left.same(right), f'full rank-seven copy matrix column {column}') + return dict(columns=SIZE, matrix_entries=SIZE * SIZE, rank=7) diff --git a/research/shared-carrier-decoder/test_controls.py b/research/shared-carrier-decoder/test_controls.py new file mode 100644 index 0000000000..a6fda311fc --- /dev/null +++ b/research/shared-carrier-decoder/test_controls.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +"""Reject changes that break the decoder or its physical contract.""" +from copy import deepcopy +from pathlib import Path +import json +import shutil +import subprocess +import sys +import tempfile + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE)) +from model import N, basis, build, distance, require +from physical import Array, Executor, SIZE +from verify import CliffordAudit, compare_receipt, frame_replay, symbolic_replay + + +def rejected(name, action, expected): + try: + action() + except ValueError as error: + require(expected in str(error), f'{name}: wrong rejection: {error}') + else: + raise ValueError(f'{name}: bad construction was accepted') + print('PASS_CONTROL_' + name, flush=True) + + +def omit(word, phase): + changed = deepcopy(word) + index = next(i for i, event in enumerate(changed['events']) if event.get('phase') == phase) + del changed['events'][index] + return changed + + +def main(): + expected = json.loads((HERE / 'EXPECTED.json').read_text()) + actual = deepcopy(expected) + for entry in actual['words'].values(): + for key in ('profile', 'copy_profile', 'move_profile'): + entry['frame'][key] = {int(rank): count for rank, count in entry['frame'][key].items()} + compare_receipt(actual, expected) + for name, value in (('BOOLEAN_RECEIPT', True), ('FLOAT_RECEIPT', 1.0)): + changed = deepcopy(expected) + changed['words']['coordinate']['physical']['temporary_streams_peak'] = value + rejected(name, lambda: compare_receipt(actual, changed), 'committed certificate agreement') + with tempfile.TemporaryDirectory(prefix='decoder missing receipt ') as directory: + copy = Path(directory) / 'decoder' + shutil.copytree(HERE, copy) + (copy / 'EXPECTED.json').unlink() + result = subprocess.run([sys.executable, '-I', '-B', str(copy / 'verify.py')], + cwd=directory, capture_output=True, text=True, check=False) + require(result.returncode != 0 and 'committed certificate missing' in result.stderr, + 'missing certificate must fail at the CLI boundary') + print('PASS_CONTROL_MISSING_CERTIFICATE', flush=True) + word = build(True) + for phase in ('compensate', 'restore_gather', 'restore_source', 'source_read'): + changed = omit(word, phase) + rejected('OMIT_' + phase.upper(), lambda: symbolic_replay(changed), 'forward arbitrary-input map') + + changed = deepcopy(word) + event = next(e for e in changed['events'] if e['op'] == 'copy_add' and e['term'] == word['geometry']['pivot']) + event['q'] = '1' + rejected('WRONG_DECODER_COEFFICIENT', lambda: symbolic_replay(changed), 'forward arbitrary-input map') + + changed = deepcopy(word) + starts = [i for i, e in enumerate(changed['events']) if e['op'] == 'copy_begin'] + ends = [i + 1 for i, e in enumerate(changed['events']) if e['op'] == 'copy_end'] + groups = [changed['events'][a:b] for a, b in zip(starts, ends)] + changed['events'] = changed['events'][:starts[0]] + groups[-1] + sum(groups[:-1], []) + changed['events'][ends[-1]:] + rejected('NONZERO_ENDPOINT_FIRST', lambda: frame_replay(changed), 'copy common frame') + + changed = deepcopy(word) + event = next(e for e in changed['events'] if e['op'] == 'copy_begin' and e['after']) + event['after'] = [word['geometry']['labels'][word['geometry']['extra']]] + rejected('ILLEGAL_COPY_ENDPOINT', lambda: frame_replay(changed), 'copy endpoint outside source span') + + changed = deepcopy(word) + idle = changed['unused'][0] + changed['events'] = [e for e in changed['events'] if not (e['op'] == 'move' and e['role'] == idle)] + rejected('UNPAID_IDLE_TAIL', lambda: frame_replay(changed), 'all physical sink frames') + + changed = deepcopy(word) + index = next(i for i, e in enumerate(changed['events']) if e['op'] == 'copy_add') + changed['events'].insert(index, dict(op='copy_end', term=changed['events'][index]['term'])) + rejected('EARLY_COPY_ERASURE', lambda: frame_replay(changed), 'copy term lifetime') + + audit = CliffordAudit() + event = next(e for e in word['events'] if e['op'] == 'copy_begin' and e['after']) + before, after = basis(event['before']), basis(event['after']) + _, original, compiled = audit.transition(before, after, distance(before, after)) + seed = [0] * SIZE + seed[0] = 1 + executor = Executor() + wanted = executor.apply(Array(seed, [0] * SIZE), original.circuit) + bad_phase = compiled.circuit + [('phase', 1)] + rejected('BINARY_FRAME_WITH_WRONG_GLOBAL_PHASE', + lambda: require(executor.apply(Array(seed, [0] * SIZE), bad_phase).same(wanted), 'exact physical copy phase'), + 'exact physical copy phase') + first_c = next(i for i, e in enumerate(compiled.circuit) if e[0] == 'C') + bad_child = compiled.circuit[:first_c] + compiled.circuit[first_c + 1:] + rejected('OMITTED_RECURSIVE_FACTOR', + lambda: require(executor.apply(Array(seed, [0] * SIZE), bad_child).same(wanted), 'exact physical copy operator'), + 'exact physical copy operator') + print('PASS_SHARED_CARRIER_CONTROLS controls=14') + + +if __name__ == '__main__': + main() diff --git a/research/shared-carrier-decoder/vendor/clifford_exact.py b/research/shared-carrier-decoder/vendor/clifford_exact.py new file mode 100644 index 0000000000..166841a037 --- /dev/null +++ b/research/shared-carrier-decoder/vendor/clifford_exact.py @@ -0,0 +1,149 @@ +"""Small exact Gaussian-dyadic Clifford compiler, independent of gx internals. +Paulis use i^p X^x Z^z. State vectors use integer Gaussian numerators / 2^d. +The tableau is supplemented by a literal circuit, so global phases are kept. +""" +from dataclasses import dataclass + +def parity(x):return x.bit_count()&1 +def rank(rows): + p={} + for x in rows: + while x: + b=x.bit_length()-1 + if b not in p:p[b]=x;break + x^=p[b] + return len(p) +def transpose(rows,n):return tuple(sum(((rows[j]>>i)&1)<>j&1);a[j],a[k]=a[k],a[j] + for i in range(n): + if i!=j and a[i]>>j&1:a[i]^=a[j] + assert [r&((1<>n for r in a) +def basis_extend(cols,n): + out=[] + for x in list(cols)+[1<len(out):out.append(x) + assert len(out)==n + return tuple(out) +def nullspace(rows,n): + a=list(rows);p=[];k=0 + for j in range(n): + t=next((i for i in range(k,len(a)) if a[i]>>j&1),None) + if t is None:continue + a[t],a[k]=a[k],a[t] + for i in range(len(a)): + if i!=k and a[i]>>j&1:a[i]^=a[k] + p.append(j);k+=1 + return tuple((1<>j)&1)<>i&1:out=pmul(out,T[i]) + for i in range(n): + if z>>i&1:out=pmul(out,T[n+i]) + return out +def compose(A,B):return tuple(apply(A,p) for p in B) +def inverse(T): + n=len(T)//2;cols=[x|(z<>n;u,v,p=apply(T,(x,z,0));assert (u,v)==identity(n)[j][:2];out.append((x,z,(-p)%4)) + return tuple(out) +def qvalue(Q,alpha,x,n): + return (sum(alpha[i] for i in range(n) if x>>i&1)+2*sum(parity((Q[i]>>(i+1))&(x>>(i+1))) for i in range(n) if x>>i&1))%4 +def mul_i(a,p): + x,y=a;p%=4 + return [(x,y),(-y,x),(-x,-y),(y,-x)][p] +@dataclass +class Op: + n:int + tab:tuple + circuit:list + def then(self,b): + assert self.n==b.n + return Op(self.n,compose(b.tab,self.tab),self.circuit+b.circuit) + def adjoint(self): + circ=[] + for e in reversed(self.circuit): + if e[0]=='P':circ.append(('P',inv(e[1],self.n))) + elif e[0]=='D':circ.append(('D',e[1],tuple((-x)%4 for x in e[2]))) + elif e[0]=='C':circ.append(('C',e[1],-e[2])) + elif e[0]=='phase':circ.append(('phase',(-e[1])%4)) + else:circ.append(e) + return Op(self.n,inverse(self.tab),circ) + def zero_state(self,basis=0): + N=1<>i)&1 for i in range(n)) + assert all(alpha[i]%2==(Q[i]>>i)&1 for i in range(n)) + return Op(n,tuple([(1<>i&1 else 0,1<>i&1 else 0) for i in range(n)]),[('C',q,sgn)]) +def xgate(n,b):return Op(n,tuple([(1<>i)&1)) for i in range(n)]),[('X',b)]) +def fourier(n,axes=None): + out=ident(n) + for i in range(n) if axes is None else axes:out=out.then(cgate(n,1<len(selected):picks.append(j);selected.append(x) + assert len(picks)==r and all(x>>r==0 for x in Bcols) + Br=transpose(selected,r);Bi=inv(Br,r);Dr=transpose([Dcols[j]&((1<= 2 * v and frame == (word['geometry']['ports'][source],), 'source read contract') + source_reads[source] += 1 + if event['phase'] == 'restore_source': + require(source < v and target >= 2 * v and frame == FULL, 'source restoration contract') + restoration[source] += 1 + elif op == 'copy_begin': + require(active is None, 'copy stream overlap') + source, before, after = event['source'], basis(event['before']), basis(event['after']) + require(frames[source] == before, 'copied source frame') + require(contained(after, before), 'copy endpoint outside source span') + r = distance(before, after) + require(r > 0, 'nontrivial copied child') + profile[r] += 1 + copies[r] += 1 + transitions.append((before, after, r)) + active = (event['term'], source, after) + elif op == 'copy_add': + require(active is not None and event['term'] == active[0], 'copy term lifetime') + target, q, frame = event['target'], Q(event['q']), basis(event['frame']) + require(v <= target < 2 * v and q != 0, 'copy target') + require(frames[target] == active[2] == frame, f'copy common frame at event {index}') + coefficients[str(q)] += 1 + elif op == 'copy_end': + require(active is not None and event['term'] == active[0], 'copy erasure term') + active = None + else: + raise ValueError('unknown event') + require(active is None and source_reads == restoration, 'complete source and stream lifecycle') + expected = [FULL] * v + [perp(p) for p in word['geometry']['ports']] + [FULL] * (n - 2 * v) + require(frames == expected == [basis(x) for x in word['final_frames']], 'all physical sink frames') + require(sum(copies.values()) == 8, 'all eight copied children') + idle_moves = [e for e in word['events'] if e['op'] == 'move' and e['role'] in word['unused']] + require(len(idle_moves) == len(word['unused']) and all(e['before'] == [] and basis(e['after']) == FULL for e in idle_moves), 'unused helper tails') + return dict(profile=dict(sorted(profile.items())), copy_profile=dict(sorted(copies.items())), + move_profile=dict(sorted(moves.items())), rank_mass=sum(r * z for r, z in profile.items()), + source_reads=sum(source_reads.values()), source_restoration_reads=sum(restoration.values()), + unused_helper_tails=len(idle_moves), coefficients=dict(sorted(coefficients.items()))), transitions + + +class CliffordAudit: + def __init__(self): + self.cx = load_clifford() + self.frames = {} + self.transitions = {} + + def frame(self, space): + if space not in self.frames: + operator = self.cx.canonical_frame(N, space) + lagrangian = [(u, u) for u in space] + [(0, z) for z in self.cx.nullspace(space, N)] + require(len(lagrangian) == N, 'Lagrangian dimension') + for x, z in lagrangian: + require(self.cx.apply(operator.tab, (x, z, 0))[0] == 0, 'exact frame preimage') + self.frames[space] = operator + return self.frames[space] + + def transition(self, before, after, expected_rank): + key = (before, after) + if key not in self.transitions: + original = self.frame(before).adjoint().then(self.frame(after)) + record, compiled = self.cx.lower_child(original) + require(record['rank'] == expected_rank, 'native Fourier rank') + require(compiled.tab == original.tab, 'native Pauli equality') + require(compiled.zero_state() == original.zero_state(), 'native exact global phase') + require(sum(gate[0] == 'C' for gate in compiled.circuit) == expected_rank, 'one rank-r coordinate child') + positions = [i for i, gate in enumerate(compiled.circuit) if gate[0] == 'C'] + require(positions == list(range(positions[0], positions[0] + expected_rank)), 'contiguous recursive child') + self.transitions[key] = (record, original, compiled) + require(self.transitions[key][0]['rank'] == expected_rank, 'cached rank contract') + return self.transitions[key] + + def invoice(self, transitions): + gates = Counter() + for before, after, rank in transitions: + _, _, compiled = self.transition(before, after, rank) + gates.update(gate[0] for gate in compiled.circuit) + return dict(positive_children=len(transitions), monomial_adapters=2 * len(transitions), + permutation_scans=gates['P'], diagonal_phase_scans=gates['D'], + xor_translation_scans=gates['X'], global_phase_scans=gates['phase'], + coordinate_C_factors=gates['C']) + + +def transpose_operator(cx, operator): + result = cx.ident(N) + for gate in reversed(operator.circuit): + if gate[0] == 'P': + part = cx.perm(N, cx.inv(gate[1], N)) + elif gate[0] == 'D': + part = cx.diag(N, gate[1], gate[2]) + elif gate[0] == 'C': + part = cx.cgate(N, gate[1], gate[2]) + elif gate[0] == 'X': + part = cx.xgate(N, gate[1]) + elif gate[0] == 'phase': + part = cx.Op(N, cx.identity(N), [gate]) + else: + raise ValueError('transpose primitive') + result = result.then(part) + return result + + +def transpose_copy_checks(audit, word): + records = [] + for event in word['events']: + if event['op'] != 'copy_begin': + continue + before, after = basis(event['before']), basis(event['after']) + record, original, _ = audit.transition(before, after, distance(before, after)) + transposed = transpose_operator(audit.cx, original) + lowered, compiled = audit.cx.lower_child(transposed) + require(lowered['rank'] == record['rank'], 'transpose copy rank') + require(compiled.tab == transposed.tab and compiled.zero_state() == transposed.zero_state(), 'transpose copy phase') + records.append(lowered['rank']) + return records + + +def integer_column_replay(word): + """Use scalar columns and fixed denominator four. Do not use row replay.""" + n, v = word['n'], word['v'] + for column in range(n): + values = [0] * n + values[column] = 4 + temporary = None + for event in word['events']: + op = event['op'] + if op == 'add': + q = Q(event['q']) + numerator = q.numerator * values[event['source']] + require(numerator % q.denominator == 0, 'integer column denominator') + values[event['target']] += numerator // q.denominator + elif op == 'copy_begin': + temporary = values[event['source']] + elif op == 'copy_add': + q = Q(event['q']) + numerator = q.numerator * temporary + require(numerator % q.denominator == 0, 'integer copied denominator') + values[event['target']] += numerator // q.denominator + elif op == 'copy_end': + temporary = None + expected = [0] * n + expected[column] = 4 + if column < v: + root_i = word['geometry']['live'][column] + for t, root_t in enumerate(word['geometry']['live']): + expected[v + t] += 2 * word['geometry']['gram'][root_t][root_i] + require(values == expected, f'independent logical column {column}') + return n + + +def uniform_gain(baseline, candidate): + ranks = set(baseline) | set(candidate) + delta = {r: candidate.get(r, 0) - baseline.get(r, 0) for r in sorted(ranks)} + require(delta == {1: 49, 7: 53, 8: -56, 9: 3}, 'complete profile difference') + require(1009 ** 256 > 8 * 1000 ** 256, 'first root upper bound') + require(7 * 1001 ** 256 > 8 * 1000 ** 256, 'second root upper bound') + margin = Q(421) - 49 * Q(1009, 1000) - 371 * Q(1001, 1000) + require(margin == Q(47, 250) > 0, 'uniform recursive moment margin') + selected_b = Q('0.001664727258740678855772') + require(0 < selected_b < Q(1, 256), 'selected complex exponent inside interval') + return dict(delta=delta, interval='0 <= b <= 1/256', bracket_upper_bound=str(-margin), + selected_complex_b=str(selected_b), copied_rank='64 -> 63', rank_mass_saving=1) + + +def linear_invoice(word, frame_receipt, native): + coefficients = Counter({Q(q): count for q, count in frame_receipt['coefficients'].items()}) + axpys = sum(coefficients.values()) + nonunit = sum(count for q, count in coefficients.items() if abs(q) != 1) + reads = sum(event['op'] == 'copy_add' for event in word['events']) + child_count = native['positive_children'] + adapter_scans = sum(native[key] for key in ('permutation_scans', 'diagonal_phase_scans', 'xor_translation_scans', 'global_phase_scans')) + access_factor = 3 * axpys + 2 * adapter_scans + 2 * native['coordinate_C_factors'] + 3 * 8 + # A scale by 1/2 or 1/4 is charged as one scalar multiplication. + return dict(original_streams=word['n'], dirty_helper_streams=word['helper_stock'], + active_helper_streams=word['active_helpers'], sequential_temporary_streams=1, + axpy_scans=axpys, scalar_additions_per_address=axpys, + dyadic_scalar_multiplications_per_address=nonunit, + source_read_scans=frame_receipt['source_reads'], + source_restoration_scans=frame_receipt['source_restoration_reads'], + copy_assign_scans=8, copy_erase_scans=8, copied_target_read_scans=reads, + positive_recursive_children=child_count, + inverse_transpose_zero_scans_instead_of_copy_assign=8, + inverse_transpose_extra_center_injection_scans=8, + emitted_events=len(word['events']), + child_dispatches=child_count, + maximum_live_complex_values_at_finite_size=675 * 512, + address_bits=9, + finite_complex_cell_accesses_per_address_bound=access_factor, + inverse_transpose_extra_cell_accesses_per_address_bound=16, + finite_tape_complex_cell_move_coefficient=2 * 675 * access_factor, + finite_tape_bound_volume_power=2, + fixed_address_metadata='Input-independent permutation cycles and phase tables; these contain no complex data.', + permutation_bit_operations_per_value_bound=256, + quadratic_phase_bit_operations_per_value_bound=144, + finite_child_native_scans=native, + route_contract='Every scan and child keeps the complete M-value stream. The full supplier must pay its retained row-routing interface.', + literal_finite_tape_bound='With the 675 streams placed consecutively, each addressed read or write needs at most 2*675*M cell moves. Count these moves for every finite address access; no linear tape theorem is claimed.', + stream_volume='M complex values, including every control and spectator value; M=512 in the finite replay.', + clean_arithmetic_storage='O(1) Gaussian dyadic registers per scalar or adapter loop, plus the one temporary stream.', + excluded='No global owner map, outer assembly, rounding implementation, or selected-supplier invoice is supplied.') + + +def compare_receipt(result, expected): + """Compare JSON values without numeric or Boolean type coercion.""" + normalized = json.loads(json.dumps(result, allow_nan=False)) + actual_text = json.dumps(normalized, sort_keys=True, separators=(',', ':'), allow_nan=False) + expected_text = json.dumps(expected, sort_keys=True, separators=(',', ':'), allow_nan=False) + require(actual_text == expected_text, 'committed certificate agreement') + + +def run(out=None): + audit = CliffordAudit() + result = dict(base='8bddbee377e2f3ce1f1247196c4b290d55767d20', words={}) + words = [] + for replaced in (False, True): + word = build(replaced) + frames, transitions = frame_replay(word) + scalar, _ = symbolic_replay(word) + scalar['independent_integer_columns'] = integer_column_replay(word) + native = audit.invoice(transitions) + from physical import whole_word + physical = whole_word(word, audit) + dual_physical = whole_word(word, audit, inverse_transpose=True) + for execution in (physical, dual_physical): + require(execution['operations']['axpy'] == sum(frames['coefficients'].values()), 'physical scalar invoice') + require(execution['operations']['C'] == frames['rank_mass'], 'physical recursive invoice') + for gate, field in (('P', 'permutation_scans'), ('D', 'diagonal_phase_scans'), ('X', 'xor_translation_scans'), ('phase', 'global_phase_scans')): + require(execution['operations'][gate] == native[field], 'physical adapter invoice') + require(execution['operations']['copy_erase'] == 8, 'physical erasure invoice') + require(physical['operations']['copy_assign'] == 8, 'physical allocation invoice') + require(dual_physical['operations']['copy_zero'] == dual_physical['operations']['center_injection'] == 8, 'dual physical allocation invoice') + transpose_ranks = transpose_copy_checks(audit, word) + scalar_peak = max(Q(scalar['forward_peak_l1']), Q(scalar['inverse_transpose_peak_l1'])) + prefix = (1 << 22) * scalar_peak + receipt = dict(frame=frames, scalar=scalar, physical=physical, inverse_transpose_physical=dual_physical, linear=linear_invoice(word, frames, native), + inverse_transpose_copy_ranks=transpose_ranks, + conservative_finite_component_prefix=str(prefix), + word_sha256=hashlib.sha256(json.dumps(serializable(word), sort_keys=True, separators=(',', ':')).encode()).hexdigest()) + result['words'][word['name']] = receipt + words.append(word) + print(f"PASS_{word['name'].upper()} columns={word['n']} profile={frames['profile']} axpys={receipt['linear']['axpy_scans']}", flush=True) + result['uniform_gain'] = uniform_gain(result['words']['coordinate']['frame']['profile'], result['words']['one_replacement']['frame']['profile']) + from physical import copy_matrix + result['rank_seven_dense_copy'] = copy_matrix(words[1], audit) + lowering_payload = [dict(before=before, after=after, native=record) + for (before, after), (record, _, _) in sorted(audit.transitions.items())] + result['lowering_sha256'] = hashlib.sha256(json.dumps(lowering_payload, sort_keys=True, separators=(',', ':')).encode()).hexdigest() + result['native_unique_frames'] = len(audit.frames) + result['native_unique_transitions'] = len(audit.transitions) + result['geometry'] = {k: words[1]['geometry'][k] for k in ('frame', 'extra', 'pivot', 'live', 'ports')} + if out is not None: + out.mkdir(parents=True, exist_ok=False) + (out / 'CERTIFICATE.json').write_text(json.dumps(result, indent=2, sort_keys=True) + '\n') + for word in words: + (out / (word['name'] + '-WORD.json')).write_text(json.dumps(serializable(word), indent=2, sort_keys=True) + '\n') + (out / 'LOWERING.json').write_text(json.dumps(lowering_payload, indent=2, sort_keys=True) + '\n') + return result, words, audit + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--out', type=Path) + args = parser.parse_args() + expected_path = HERE / 'EXPECTED.json' + require(expected_path.is_file(), 'committed certificate missing') + expected = json.loads(expected_path.read_text()) + result, _, _ = run(args.out) + compare_receipt(result, expected) + print('PASS_SHARED_CARRIER_DECODER copies=64->63 columns=674 axpys=3552->3660 interval=[0,1/256] no_new_kappa')