diff --git a/.gitattributes b/.gitattributes index 6825630198..18d54d5a0d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -18,3 +18,7 @@ research/coordinated-frames-and-entrance-banks/** -text -whitespace # Frozen PR210 package and round-nine evidence retain their audited bytes. research/five-stage-source527-banks/** -text -whitespace research/community-round9-audit/** -text -whitespace + +research/e8-early-reset-reuse/** -text + +research/idle-axis-hosting/** -text -whitespace diff --git a/.github/workflows/e8-complex-gauge-kernel.yml b/.github/workflows/e8-complex-gauge-kernel.yml new file mode 100644 index 0000000000..8afe01752e --- /dev/null +++ b/.github/workflows/e8-complex-gauge-kernel.yml @@ -0,0 +1,41 @@ +name: Verify complex gauge-kernel supplier + +on: + push: + paths: + - 'research/e8-complex-gauge-kernel/**' + - 'research/idle-axis-hosting/**' + - 'research/split-centres-global/**' + - '.github/workflows/e8-complex-gauge-kernel.yml' + pull_request: + paths: + - 'research/e8-complex-gauge-kernel/**' + - 'research/idle-axis-hosting/**' + - 'research/split-centres-global/**' + - '.github/workflows/e8-complex-gauge-kernel.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + verify: + runs-on: ubuntu-24.04 + timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + python-version: ['3.11', '3.14'] + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 + with: + python-version: ${{ matrix.python-version }} + - name: Install numpy and scipy (Lemma G stage, --discover-check) + run: python3 -m pip install numpy scipy + - name: Replay PR442 parent, build the gauge-kernel words, check Lemma G, rediscover hosting, assemble + run: python3 -B research/e8-complex-gauge-kernel/verify.py "$RUNNER_TEMP/e8-complex-gauge-kernel" --all --discover-check + - name: Require committed files to remain unchanged + run: git diff --exit-code diff --git a/.github/workflows/early-reset-reuse.yml b/.github/workflows/early-reset-reuse.yml new file mode 100644 index 0000000000..ad7aeacfde --- /dev/null +++ b/.github/workflows/early-reset-reuse.yml @@ -0,0 +1,20 @@ +name: Verify early reset and kernel composition +on: [push, pull_request] +jobs: + verify: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python: ['3.11', '3.14'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + - run: python -B research/e8-early-reset-kernel/verify.py "$RUNNER_TEMP/early-reset-reuse" + - uses: actions/upload-artifact@v4 + if: always() + with: + name: early-reset-reuse-${{ matrix.python }} + path: ${{ runner.temp }}/early-reset-reuse diff --git a/.github/workflows/idle-axis-hosting.yml b/.github/workflows/idle-axis-hosting.yml new file mode 100644 index 0000000000..4f9bad7fea --- /dev/null +++ b/.github/workflows/idle-axis-hosting.yml @@ -0,0 +1,41 @@ +name: Verify idle-axis hosting composition + +on: + push: + paths: + - 'research/idle-axis-hosting/**' + - 'research/e8-early-reset-kernel/**' + - 'research/e8-early-reset-reuse/**' + - 'research/split-centres-global/**' + - '.github/workflows/idle-axis-hosting.yml' + pull_request: + paths: + - 'research/idle-axis-hosting/**' + - 'research/e8-early-reset-kernel/**' + - 'research/e8-early-reset-reuse/**' + - 'research/split-centres-global/**' + - '.github/workflows/idle-axis-hosting.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + verify: + runs-on: ubuntu-24.04 + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + python-version: ['3.11', '3.14'] + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 + with: + python-version: ${{ matrix.python-version }} + - name: Replay PR434 from scratch, host helper residuals on idle coordinates, audit and assemble + run: python3 -B research/idle-axis-hosting/verify.py "$RUNNER_TEMP/idle-axis-hosting" + - name: Require committed files to remain unchanged + run: git diff --exit-code diff --git a/.github/workflows/split-centres-global.yml b/.github/workflows/split-centres-global.yml new file mode 100644 index 0000000000..1adf7dc2ea --- /dev/null +++ b/.github/workflows/split-centres-global.yml @@ -0,0 +1,23 @@ +name: Split-centres global kappa +on: + pull_request: + paths: + - 'research/split-centres-global/**' + - '.github/workflows/split-centres-global.yml' + push: + paths: + - 'research/split-centres-global/**' + - '.github/workflows/split-centres-global.yml' + workflow_dispatch: +jobs: + verify: + runs-on: ubuntu-latest + strategy: + matrix: + python: ['3.11', '3.14'] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + - run: python -B research/split-centres-global/verify.py "$RUNNER_TEMP/split-centres-check" diff --git a/research/e8-complex-gauge-kernel/EXPECTED.json b/research/e8-complex-gauge-kernel/EXPECTED.json new file mode 100644 index 0000000000..bd3f095295 --- /dev/null +++ b/research/e8-complex-gauge-kernel/EXPECTED.json @@ -0,0 +1,732 @@ +{ + "baseline_442_complex": "1267453159029119/1000000000000000000", + "complex_cap_kappa_decimal": "0.001325031497415498", + "complex_decimal": "0.001326789535340266", + "complex_lower": "663394767670133/500000000000000000", + "hosting_audit_controls": [ + "hosted residual outside its window", + "remainder child understated", + "dropped bank", + "duplicated hosted residual", + "hosted width not the entrance width", + "overlapping hosted coordinates", + "hosted owner on the active pair", + "missing remainder child", + "two helpers on one physical family in one invocation (accepted by the #442 rule, rejected here)", + "a spectator coordinate that is a residual coordinate", + "spectator coordinates shifted", + "spectator record dropped", + "entering helper routed without a spectator record", + "rule flag removed from the template", + "two entering helpers on one bank family in one invocation, disjoint footprints, spectators in the pad (accepted by the #442 rule, rejected here)", + "a bank spectator that is a residual cell", + "bank spectator cells shifted", + "bank spectator count wrong", + "bank spectator record dropped", + "a banked entering helper on an active data family", + "a bank owner in the private namespace (centres)", + "a bank owner in the private namespace (reserved tableau)", + "windows of two idle children of one family group overlap (a bridge removed from the schedule)", + "private namespace left at the parent's ranges", + "private namespace overlapping the live stock", + "hosted helper on the data family of another replica", + "active owner on the family of another replica", + "a second owner on an active data family" + ], + "hosting_audit_controls_not_applicable": [], + "hosting_rule": true, + "lemma_G_independent_checks": { + "anchor": { + "calls": { + "n": 72, + "ok": true, + "orient": { + "backward": 32, + "forward": 40 + } + }, + "end_to_end": { + "columns": 512, + "dense": 8, + "failures": 0, + "kinds": { + "centre": 16, + "port": 240, + "random": 256 + }, + "seed": 2026, + "status": "PASS" + }, + "inputs": { + "CANONICAL-WORD.json": "be2d8d412b948bce50a0fc852ab4c01f57bff4c3c8272da80c09be5bcdf253bf", + "CLIFFORD-RECIPES.json": "242fe77af077973e1933524fe5c7ff3b68bef14b1f6938e024827de78d954492", + "LOCAL-PROGRAMS.json": "e1b483423ec93c47c80d21a01d92591f3856d1ec68da231372ec2bc29f7e8fd8" + }, + "labels": { + "backward": { + "compensation_gates": 0, + "entering": 0, + "entrance_rank": 0, + "events": 24857, + "kernel_updates": 0, + "local_mass": 7032, + "n_label_violations": 0, + "paid_profile": { + "1": 1912, + "2": 784, + "3": 168, + "4": 224, + "5": 392, + "8": 24 + }, + "scalar_violations": [], + "sha256": "b06539888be711e562ebcb4166583e970d16b9997b2142b3b4490c50781b3d22" + }, + "forward": { + "compensation_gates": 0, + "entering": 0, + "entrance_rank": 0, + "events": 24857, + "kernel_updates": 0, + "local_mass": 7032, + "n_label_violations": 0, + "paid_profile": { + "1": 1912, + "2": 784, + "3": 168, + "4": 224, + "5": 392, + "8": 24 + }, + "scalar_violations": [], + "sha256": "9f9f5034b82277de7ca6dc27a682c1732b28a4450eb057392487910928971cf8" + } + }, + "selftest_operators": 19, + "variant": "anchor" + }, + "gauge80": { + "calls": { + "n": 72, + "ok": true, + "orient": { + "backward": 32, + "forward": 40 + } + }, + "end_to_end": { + "columns": 722, + "dense": 8, + "failures": 0, + "kinds": { + "centre": 16, + "entering": 160, + "port": 240, + "random": 256, + "target_level": 50 + }, + "seed": 2026, + "status": "PASS" + }, + "inputs": { + "CANONICAL-WORD.json": "fd09083f9c356d324b967b68f8b4e967867a34642c2108c823bc4f3c8e632974", + "CLIFFORD-RECIPES.json": "c531b90b512a437e779c8068647ef8fc594ebe188cb00c0426c58f3cafa8b544", + "LOCAL-PROGRAMS.json": "8fc44dbb951b6a1af653070aaccd52a12b8f13ecb9cc5245a2d5a0a0112122d2", + "RESIDUAL-ADAPTERS.json": "00fa8dfc8cf72d34b87eeb199b8a5f5345533147c5cfb9b455a071e1d6f9c4ae" + }, + "instances": { + "I-centre": { + "centres": 16, + "chains": [ + [ + "1-0", + 8 + ], + [ + "8-0", + 1 + ], + [ + "8-1-0", + 1 + ], + [ + "8-2-1-0", + 2 + ], + [ + "8-4-2-1-0", + 4 + ] + ], + "failures": 0 + }, + "I-comp": { + "compensation_gates": 420, + "entering_helpers_compensating": 80, + "failures": 0, + "input_registers": 130, + "targets": 50 + }, + "I-helper": { + "entering_helpers": 80, + "failures": 0, + "widths": { + "5": 4, + "7": 14, + "8": 62 + } + }, + "I-tr": { + "failures": 0, + "transitions": 2933 + } + }, + "labels": { + "backward": { + "compensation_gates": 0, + "entering": 80, + "entrance_rank": 106, + "events": 25028, + "kernel_updates": 0, + "local_mass": 6926, + "n_label_violations": 0, + "paid_profile": { + "1": 2009, + "2": 838, + "3": 140, + "4": 274, + "5": 314, + "6": 2, + "7": 1, + "8": 17 + }, + "scalar_violations": [], + "sha256": "8c5d1072d3b262e5e10d1ec3e5116c253212931fe18cf7fad666bfd42c475bba" + }, + "forward": { + "compensation_gates": 420, + "entering": 80, + "entrance_rank": 106, + "events": 25028, + "kernel_updates": 0, + "local_mass": 6926, + "n_label_violations": 0, + "paid_profile": { + "1": 2009, + "2": 838, + "3": 140, + "4": 274, + "5": 314, + "6": 2, + "7": 1, + "8": 17 + }, + "scalar_violations": [], + "sha256": "d686835a2d6a817cb8780bffc0256f8cdc25e7cba1d271699c7fff911f44f7e6" + } + }, + "selftest_operators": 19, + "variant": "gauge80" + }, + "gauge80-kernel42": { + "calls": { + "n": 72, + "ok": true, + "orient": { + "backward": 32, + "forward": 40 + } + }, + "end_to_end": { + "columns": 806, + "dense": 8, + "failures": 0, + "kinds": { + "centre": 16, + "entering": 244, + "port": 240, + "random": 256, + "target_level": 50 + }, + "seed": 2026, + "status": "PASS" + }, + "inputs": { + "CANONICAL-WORD.json": "124051482e9e7f3358cae1eaf18e29c76e94f825dee1f39e3e80ac55a59f87e5", + "CLIFFORD-RECIPES.json": "626d06a0219fe20cf0dc6405b45fab0bb9e26d6307c92ff053eaec231559a420", + "LOCAL-PROGRAMS.json": "47f5ef86b36dbf5bafe7a20b96ca21984206b11502090924d91fd40c2d692190", + "RESIDUAL-ADAPTERS.json": "546196e37830b9ccbc544834cb6f37ba4ad841faf96f025fe5155f5ba3924e07" + }, + "instances": { + "I-centre": { + "centres": 16, + "chains": [ + [ + "1-0", + 8 + ], + [ + "8-0", + 1 + ], + [ + "8-1-0", + 1 + ], + [ + "8-2-1-0", + 2 + ], + [ + "8-4-2-1-0", + 4 + ] + ], + "failures": 0 + }, + "I-comp": { + "compensation_gates": 420, + "entering_helpers_compensating": 80, + "failures": 0, + "input_registers": 130, + "targets": 50 + }, + "I-helper": { + "entering_helpers": 122, + "failures": 0, + "widths": { + "5": 4, + "7": 14, + "8": 104 + } + }, + "I-tr": { + "failures": 0, + "transitions": 2945 + } + }, + "labels": { + "backward": { + "compensation_gates": 0, + "entering": 122, + "entrance_rank": 148, + "events": 25082, + "kernel_updates": 0, + "local_mass": 6884, + "n_label_violations": 0, + "paid_profile": { + "1": 2057, + "2": 928, + "3": 50, + "4": 274, + "5": 314, + "6": 2, + "7": 1, + "8": 17 + }, + "scalar_violations": [], + "sha256": "0305c019bd5b33e7662d9ea30e6e7d43571079cdbbc38914ed598386bb8eb968" + }, + "forward": { + "compensation_gates": 420, + "entering": 122, + "entrance_rank": 148, + "events": 25082, + "kernel_updates": 111, + "local_mass": 6884, + "n_label_violations": 0, + "paid_profile": { + "1": 2057, + "2": 928, + "3": 50, + "4": 274, + "5": 314, + "6": 2, + "7": 1, + "8": 17 + }, + "scalar_violations": [], + "sha256": "874e51c0a21696cfc9d73b4b6c4bf5f8070ae2d835d1749cf2752ec8a0e5bcd0" + } + }, + "necessity_mutants": [ + { + "checker_flags": [ + "ACC", + "G0" + ], + "mutant": "M1 compensation gate with the target still at label 0", + "physics": { + "backward": "FAIL (registers [374, 375])", + "forward": "FAIL (registers [186, 200])" + }, + "rejected": true + }, + { + "checker_flags": [ + "ACC", + "G1" + ], + "mutant": "M2 physical T_E on an entering helper (no virtual entrance)", + "physics": { + "backward": "FAIL (registers [374])", + "forward": "FAIL (registers [374])" + }, + "rejected": true + }, + { + "checker_flags": [ + "ACC", + "G2" + ], + "mutant": "M3 target visits its entrance levels out of nesting order (descends E2 -> E1)", + "physics": { + "backward": "PASS", + "forward": "PASS" + }, + "rejected": true + }, + { + "checker_flags": [ + "ACC", + "G2" + ], + "mutant": "M3b entering helper leaves the nested chain (E_j -> X -> F, X not containing E_j)", + "physics": { + "backward": "PASS", + "forward": "PASS" + }, + "rejected": true + }, + { + "checker_flags": [ + "G0" + ], + "mutant": "M4 scatter into a level-L1 target after the copy descended below L1", + "physics": { + "forward": "FAIL (registers [129, 194])" + }, + "rejected": true + }, + { + "checker_flags": [ + "ACC", + "G0" + ], + "mutant": "M5 last centre descent step skipped (level-0 targets scattered at L_last)", + "physics": { + "forward": "FAIL (registers [121, 122, 123, 127])" + }, + "rejected": true + }, + { + "checker_flags": [ + "G3" + ], + "mutant": "M6 centre copy taken at the wrong label (after the first descent)", + "physics": { + "forward": "FAIL (registers [121, 122, 123, 124])" + }, + "rejected": true + }, + { + "checker_flags": [ + "G3" + ], + "mutant": "M7 a child of another register runs while a centre copy is live", + "physics": { + "forward": "PASS" + }, + "rejected": true + }, + { + "checker_flags": [ + "ACC", + "G3" + ], + "mutant": "M8 centre chain leaves the centre frame (c_k -> X -> L1, X not inside c_k)", + "physics": { + "forward": "PASS" + }, + "rejected": true + }, + { + "checker_flags": [ + "S" + ], + "mutant": "M9 compensation coefficient doubled", + "physics": { + "backward": "FAIL (registers [374])", + "forward": "FAIL (registers [186, 200])" + }, + "rejected": true + }, + { + "checker_flags": [ + "G0" + ], + "mutant": "M10 compensation moved after the helper started climbing", + "physics": { + "backward": "FAIL (registers [374])", + "forward": "FAIL (registers [186, 200])" + }, + "rejected": true + }, + { + "checker_flags": [ + "ACC", + "G0" + ], + "mutant": "M11 kernel donor update with the donor still at label 0", + "physics": { + "backward": "FAIL (registers [396])", + "forward": "FAIL (registers [130, 188, 206, 221])" + }, + "rejected": true + }, + { + "checker_flags": [ + "G1" + ], + "mutant": "M12 R_E^-1 wrapper after the first gate on the helper", + "physics": { + "backward": "FAIL (registers [374])", + "forward": "FAIL (registers [186, 200])" + }, + "rejected": true + }, + { + "checker_flags": [ + "G1" + ], + "mutant": "M13 L_E^-1 wrapper dropped", + "physics": { + "backward": "FAIL (registers [374])", + "forward": "FAIL (registers [374])" + }, + "rejected": true + } + ], + "selftest_operators": 19, + "variant": "gauge80-kernel42" + }, + "kernel79": { + "calls": { + "n": 72, + "ok": true, + "orient": { + "backward": 32, + "forward": 40 + } + }, + "end_to_end": { + "columns": 670, + "dense": 8, + "failures": 0, + "kinds": { + "centre": 16, + "entering": 158, + "port": 240, + "random": 256 + }, + "seed": 2026, + "status": "PASS" + }, + "inputs": { + "CANONICAL-WORD.json": "1e643855b0a37636f6c4aa90c45c23c0f7abbb438028a91affab6df8b485a22d", + "CLIFFORD-RECIPES.json": "d7adae00b756bd3333a55195f2a98de39cca555ba30a9bccdebf94d5c8a789f4", + "LOCAL-PROGRAMS.json": "ecd8f4cadd13eef3445bfdaac3d28aa6c77de09231223da223fcfc55d03c1e3e", + "RESIDUAL-ADAPTERS.json": "5581b0f32e8d32a5a39692ce9559b21e46c41df357d72adcef138e6f148c23a3" + }, + "instances": { + "I-centre": { + "centres": 16, + "chains": [ + [ + "1-0", + 8 + ], + [ + "8-0", + 8 + ] + ], + "failures": 0 + }, + "I-comp": { + "compensation_gates": 0, + "entering_helpers_compensating": 0, + "failures": 0, + "input_registers": 0, + "targets": 0 + }, + "I-helper": { + "entering_helpers": 79, + "failures": 0, + "widths": { + "8": 79 + } + }, + "I-tr": { + "failures": 0, + "transitions": 2932 + } + }, + "labels": { + "backward": { + "compensation_gates": 0, + "entering": 79, + "entrance_rank": 79, + "events": 24990, + "kernel_updates": 0, + "local_mass": 6953, + "n_label_violations": 0, + "paid_profile": { + "1": 1981, + "2": 932, + "3": 20, + "4": 224, + "5": 392, + "8": 24 + }, + "scalar_violations": [], + "sha256": "273c5a33876fbfc744b623b0358101c7b03cd2e7337f61815c98c149dc368d49" + }, + "forward": { + "compensation_gates": 0, + "entering": 79, + "entrance_rank": 79, + "events": 24990, + "kernel_updates": 229, + "local_mass": 6953, + "n_label_violations": 0, + "paid_profile": { + "1": 1981, + "2": 932, + "3": 20, + "4": 224, + "5": 392, + "8": 24 + }, + "scalar_violations": [], + "sha256": "d1f34bbb4ab29de7d5c26ce27016b92224ddda74824b74290264b2e8e82880b6" + } + }, + "selftest_operators": 19, + "variant": "kernel79" + } + }, + "mutation_controls_certifying_pipeline": [ + "kernel: donor update omitted", + "kernel: donor update sign flipped", + "gauge: compensation gate omitted", + "gauge: compensation coefficient doubled", + "gauge: entrance outside the frame of its gates", + "helper with a frame-zero compensation given an entrance", + "helper-style entrance given to a data register", + "helper-style entrance given to a target register", + "target level forgotten", + "centre levels not a chain (word built without the builder's structural checks)" + ], + "mutation_controls_one_owner_rule": [ + "bank class: two entering helpers on one bank family", + "bank class: spectator is a residual cell of its own helper", + "bank class: an active data wire on a bank family", + "data class: two hosted helpers on one data family", + "data class: a hosted helper on an active data family", + "private namespace: a bank owner in the centres", + "private namespace: a bank owner in the reserved tableau", + "private namespace: a bank owner at the coefficient registers", + "hosting generator: eight entering helpers of one invocation on one bank family", + "parent template generator: eight entering helpers of one invocation on one bank family" + ], + "mutation_controls_selection": [ + "gauge: entrance outside the first frame", + "gauge: non-nested entrances at one target", + "kernel: pivot outside the donor span", + "kernel: entrance outside a donor first frame" + ], + "mutation_controls_word": [ + "kernel: donor update omitted", + "kernel: donor update sign flipped", + "gauge: compensation gate omitted", + "gauge: compensation coefficient doubled", + "gauge: entrance not inside the first frame of its gates", + "gauge: start_extra of a compensated helper without gauge or kernel", + "gauge: target level forgotten", + "gauge: target level different from the compensation frame" + ], + "replay_controls": [ + "wrong_scale", + "missing_center", + "wrong_common_frame", + "wrong_child_rank", + "missing_pre_wrapper", + "missing_post_wrapper", + "wrapper_with_wrong_frame", + "wrapper_in_wrong_phase", + "wrapper_on_a_data_register", + "wrapper_on_a_target_register", + "wrapper_on_a_centre_register", + "centre_step_not_nested", + "centre_descent_step_skipped", + "missing_padding", + "aliased_owner", + "missing_cover_phase", + "two_entering_helpers_on_one_bank_family", + "bank_spectator_is_a_residual_cell", + "bank_spectator_shifted", + "bank_spectator_record_dropped", + "bank_spectator_count_wrong", + "second_owner_on_an_active_data_family", + "helper_owner_on_an_active_data_family", + "active_wire_on_a_bank_family", + "owner_in_the_private_namespace_centres", + "owner_in_the_private_namespace_reserved_tableau", + "owner_in_the_private_namespace_coefficient", + "active_owner_on_the_family_of_another_replica" + ], + "status": "PASS_FULL_COMPLEX_GAUGE_KERNEL_COMPOSITION", + "suppliers": { + "#442 bit word (R747, nine stages)": { + "binding": "bit", + "kappa": "618775866623647/500000000000000000", + "kappa_decimal": "0.001237551733247294" + }, + "R724 mixed, eleven stages, whole-residual hosting": { + "binding": "bit", + "kappa": "51166847407811/40000000000000000", + "kappa_decimal": "0.001279171185195275" + } + }, + "words": { + "gauge80": { + "complex_lower": "261282591098137/200000000000000000", + "hosted_template_sha256": "04d04fe38af0425417e905cbcf730c1379b62fd52e3135f5d0ad26b9a4ef1c03", + "live": 7956 + }, + "gauge80-kernel42": { + "complex_lower": "663394767670133/500000000000000000", + "hosted_template_sha256": "18450983dd5a5dab0534e5ecf3e5a9e0d5c2e10500d26fe720482972ba8c7759", + "live": 7746 + }, + "kernel79": { + "complex_lower": "1305683989618791/1000000000000000000", + "hosted_template_sha256": "4cd63f26a279b8f91b0ffa4967c84822dd21f57bf0728fdfb559087922984fc8", + "live": 8005 + } + }, + "wrapper_check": { + "all_even_weight": true, + "all_totally_isotropic": false, + "frames": 16, + "wrappers_reject": [ + "wrong global phase", + "wrong translation", + "wrong quadratic form", + "sides swapped", + "wrong width" + ] + } +} diff --git a/research/e8-complex-gauge-kernel/MANIFEST.json b/research/e8-complex-gauge-kernel/MANIFEST.json new file mode 100644 index 0000000000..2b65846c37 --- /dev/null +++ b/research/e8-complex-gauge-kernel/MANIFEST.json @@ -0,0 +1,59 @@ +{ + "files": { + "EXPECTED.json": "de9e2ade14c2f390759230850377d48c28b16a28c955669fa89c535fcc228113", + "NOTICE.md": "7c7a022afe969a09ad5320935daf7db256b8f25ee56ecdcf9fc40eb0836e74ce", + "PR-BODY.md": "839708cb1f21d34f7ecf8d9edc5c9ec800b747d92c99e384e0bc246211bd01a1", + "PROOF.md": "a6bf0662abdd9bbe0649b52cada82c3341e61b49b966b93aa6f8f1ab30d2d949", + "README.md": "db9842231c944440c89cbe7ea9c5083d7380b443cd5c68f77a55232021764cab", + "SOURCE.json": "ee6dca44a773d457b9e0bbfc8d3d5f571673913686fa57187e63a84857ff505e", + "code/adapters_gk.py": "a8d6d9ccf20c261cb0b216baa9906f2f7689e1bb1dca070313a60b2cb6d3043c", + "code/assemble_gk.py": "e377ef9d9e90168290a4640250c0fb9c05015104bcc4827bc5ce63f6ca63763a", + "code/audit_gk.py": "cb79c6b788333a031e14c7f134823f5f6147d7f1dcc6e5e3b1420743c32f8ebc", + "code/audit_hosted_gk.py": "c46c69c1c6fdccce991bf5d5ec7def344d2749c53ad2db976a50ba3a6c37d657", + "code/controls_gk.py": "cf83aa95f03aa812c413905df9f75f13ac8f92f5db6a83cf9b1868aea2dd9de0", + "code/controls_hosting.py": "573966c7ad1deac24464414d3886171f594bb3ae3e7236a9ac2447cc40b20211", + "code/controls_pipeline.py": "cc6fb8bf4644cc3a1799f3bc90dc074adb5663d1889c92f7f73ec9f307acbd36", + "code/controls_sel.py": "d2777571d59736c3fe62b81506ae62c22a3816fbc3abf9303d914e6da6d64258", + "code/emit_gk.py": "4e415bff1d9f154496ed38e6889929b600aa0f3d583a375e8ca257ad8f51fa23", + "code/gk_common.py": "e68d190fd436b2f3955decb590adb53344d5d4ea0a19d62d86df1e4b55ecd198", + "code/gk_word.py": "f027a9273bcf4e0971258c160b7d3b3c196366b32a529cff6e6a0e666b03826b", + "code/hosted_gk.py": "8d2c29a5f79e6a1391f96baf44dd9fbe35203b6c11b02a7b2d238cf792ea163f", + "code/integrate_gk.py": "2e807893180a3716b36a81f1a7d933bd55f2299489b6f236ba5c644d87739209", + "code/lemmaG/check.py": "f572b7129a546e1b1193fdd5baee4f731a5b9b8a4e8dc7ac170bcad7758e5b9a", + "code/lemmaG/gd.py": "64cdb2cfefc9ec3ed80c277a18848778427c3d3dbda9b7be13f740522478e1de", + "code/lemmaG/lg_e2e.py": "8fe3719e8ec5ec49af480b40c15f07612a356f5071ea30e17ae2d8931b3f20ce", + "code/lemmaG/lg_instances.py": "47dcf2e9ae2d99699424d684abebc3d1d2d25b7aa6d440761e19835d140f5fbb", + "code/lemmaG/lg_lib.py": "e7db756ad091055b79e90e53d9cecda632a185a11ee3f095eed5d32757f87490", + "code/lemmaG/lg_mutants.py": "cf0d1f8e90a0780244b6de38d6aad08dd42f4c439397a6d5a61fccd23fe7e798", + "code/lemmaG/lg_phys.py": "0ca37829b596d83d0b94c5f0b6b278a100f22e626b2ab3b5210a38f9657c8a27", + "code/lemmaG/run_labels.py": "5f053e553b1c26e553a844e2891a73b6cc6b79404a7bb5d4722529f7db0d592c", + "code/make_meta.py": "06e44ae4fc4f3a88989828d6cbdf95524a2d9f65753045cbb3e6cfd7e042d96a", + "code/onehost_gk.py": "416b318c1b6b8c7b72e24713b1b18d8772ec368e042a321b4418c63a74711590", + "code/replay_gk.py": "2422b44fc2fb4742bb575572337158a15fb6831630f8746a1c7ee3133e0ee2e3", + "code/run_variant.py": "feecf7dff32860a02fbfb96da1049ba35d05b3baf74c4f741b878d4d91903903", + "data/SELECTION.json": "89b19daca7db07a7e09723b1b74b55682ae64af98072dbb3110d0376b7f052b2", + "data/bit-suppliers-pinned.json": "77121915641c8fef57ab10585fd5e8b13c817356bbbea21f4314d381cd029b83", + "data/selections/empty.json": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "data/selections/gauge80-kernel42.json": "436e4acadee227dbfcb66386c9ccaa38e68054e8ed4870bb174eeb41363375bb", + "data/selections/gauge80.json": "41e62cfd0d50f348eae3f81d9f62f7dab2667294554398d8bca43aadbb2c291b", + "data/selections/kernel79.json": "febded05174c364049632db3214dc9209426d1b81581cab728d79fa6594c9e47", + "provenance/README.md": "76f04346717183300ec2d3bf852d5bacc8a6c3dee458a17a1957613ddf033af0", + "provenance/cxcheck.py": "1df8db02ad02e8f1cf0bbaabd92d7d88341f8e10f0e76d7777d246eb52094ac8", + "provenance/cxlab.py": "46dd697395d69776eaefa7d5843ada050528d76832967c76afa2e80beb7d75ee", + "provenance/gauge.py": "a0fbf14085161f89d52343de80cddc8a11451bac635bc2677549ae7a26562491", + "provenance/gauge2.py": "3dda541e514944fc6486407a889ac6a0f3b1eeab08092799dec672a89cbcbcb8", + "provenance/gauge3.py": "fb74644f093f8a725af146b560380b360dc655edde61c7695d1a2d9b33fc58fc", + "provenance/gauge4.py": "e4e438034a3cd4c49adc744de86819dc574b130fb8bc8dc48b1d9955a3601a42", + "provenance/hostmodel.py": "1fe732f944166dca53363d63b0bc2a5c4ceaf0ffdb8973f554720be07bf07395", + "provenance/iso1.py": "1a7e3e08b0ecb9cdf19525ef23c5f790cf19427e238e71987a30c35aa54d9612", + "provenance/kcap.py": "96e4e067d850f1b3b5cdf241371956a99fe4f60229edd3fe43b3f7d14ae78bea", + "provenance/kern.py": "bdc708e887bda780b3145e2f536db9ace13cae165447c6057bb8b3476f8f1dc0", + "provenance/kern2.py": "62c02a73484f0b513c2d7bd4bdd9febf1c84bf42457506a36bab30b97b267efc", + "provenance/kern3.py": "e31d8b9728881d7921c404e55b875e6f8cea46a0c9fc6eea8263416cc6fba109", + "provenance/kern4.py": "0a21980027d427a6377a525d7082e460eed9e8577328831e2edde7eede1998dc", + "provenance/kern5.py": "bb0bbf4504f714d5d14c362d90c0d66c85c912e5b2f19c7401040e967c8a3c0c", + "provenance/kern6.py": "849c7e9404edb5bb2d2064339014d6bbfd7bcb0ab62a4ca09d7d2c658dcd14c6", + "provenance/sa_long.py": "e2270814c0ff0617b1104a007e4604ac713dbb1a033771d4a5357796198e646e", + "verify.py": "56a36950ed486a1b38334e8d75fd1efe75da7ba604fb4fafe7d8dc1e388349c5" + } +} diff --git a/research/e8-complex-gauge-kernel/NOTICE.md b/research/e8-complex-gauge-kernel/NOTICE.md new file mode 100644 index 0000000000..60c3bb3c7a --- /dev/null +++ b/research/e8-complex-gauge-kernel/NOTICE.md @@ -0,0 +1,6 @@ +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +`code/audit_gk.py`, `emit_gk.py`, `integrate_gk.py`, `replay_gk.py` are marked copies of PR #433's `complex_audit.py`, `complex_emit.py`, +`complex_integrate.py`, `complex_replay.py` (icekylinx with Codex assistance; adapted from PR #425 by jacklightChen / Zhihao Chen, OpenAI Codex); +`hosted_gk.py` of PR #442's `complex_hosted.py` and `audit_hosted_gk.py`, `assemble_gk.py` of its `audit.py`, `assemble.py` (DaysSky, with Claude +assistance). `assemble_gk.py` also follows the generalisation of `assemble.py` in the eleven-stage package of DreamingOfClouds. Every changed line +is marked `GK:`. PR #433's exact phase script `complex_phases_full.py` is run unchanged. diff --git a/research/e8-complex-gauge-kernel/PR-BODY.md b/research/e8-complex-gauge-kernel/PR-BODY.md new file mode 100644 index 0000000000..40d405a562 --- /dev/null +++ b/research/e8-complex-gauge-kernel/PR-BODY.md @@ -0,0 +1,45 @@ +Title: Complex supplier b ≈ 1.327·10⁻³ (+4.7%) on whole-residual hosting: shared-donor kernel and entrance gauges with paid residual wrappers (conditional on two lemmas) + + +> ⚠️ **Draft:** the heavy verification (full fresh-copy replays, CI) is still running. Build on this at your own risk. +## A stronger complex supplier: b = 1326789535340266/10¹⁸ ≈ 1.326790·10⁻³ (+4.68% over #442), whole-residual hosting, one owner per family + +This adds one self-contained package, `research/e8-complex-gauge-kernel/`. It is a **complex-side supplier**: #433's split-centre word (R = 560, m = 73), #442's idle-axis hosting with the one-helper-per-family rule of #458, and two tools of the bit side ported to it. **No new κ is claimed: the bit side binds** (κ = 1.237552·10⁻³ with #442's bit word, 1.279171·10⁻³ with our pinned R724 word). The current lemma-less κ frontier is #478 (Dugongue) at 1.295509·10⁻³, which sits at #458's complex cap; this supplier raises that cap; #458, #460 and #462 are bit-bound, not complex-bound. On the complex side b is +2.28% over #458 (1.297204·10⁻³) and +1.65% over #471 (1.305232·10⁻³; #471 admits our kernel79 through normalisation plus same-owner spectator borrowing, and is credited below). This raises the complex cap of this lineage to κ ≤ 1.325031·10⁻³ (the #448/#450 lineage used in #464 and #469 has complex roots of about 1.44·10⁻³). It is conditional on two lemmas, the review points: **Lemma A** (paid residual wrappers with explicit spectators; the entrances are isotropic, not coordinate entrances) and **Lemma G** (nonzero-frame compensation and the centre scatter). It supersedes the draft #449. + +| complex word | entering helpers | entrance rank | b (·10⁻³) | gain over #442 | +| --- | ---: | ---: | ---: | ---: | +| #442 | 0 | 0 | 1.267453 | | +| shared-donor kernel | 79 | 79 | 1.305684 | +3.02% | +| entrance gauges | 80 | 106 | 1.306413 | +3.07% | +| **both** | 122 | 148 | **1.326790** | **+4.68%** | + +### Relation to #458 and #471 +#458 (chafreaky) puts the 79-pivot kernel of #449 on an eleven-stage complex word and pays its entrance transforms as emitted, checked adapters, with at most one helper per host family per invocation. This package adopts that treatment on the nine-stage word and adds the entrance gauges; #449's hosting allowed several helpers on one family and left an entering helper's spectator coordinates unplaced, which #458 showed is not sufficient. #471 normalises the complete invocation and borrows spectators in the same owner array; this package applies the same borrowing to its banks (an entering helper is the only owner of its bank family in an invocation, its spectators are the first cells of the bank's pad) and extends the one-owner rule to every register class of an invocation, with a control for each. + +### Change +A helper's frame-zero compensation (the response of its arbitrary dirt) pins it to start frame {0}, so its residual has width 9. Two exact ways avoid it: +- **Shared-donor kernel** (#417/#435/#434/#439/#440): a pivot whose response column is a rational combination of donors' columns starts at an entrance E contained in every member's first frame; each donor receives `d += −q·pivot` at E before the main word (inverse after cleanup). +- **Entrance gauge** (#401/#408–#416): the compensation of a helper is executed at its entrance frame E instead of frame 0; targets climb through the nested entrance chain, and each centre copy descends from its frame through the levels it serves (mass-neutral, rank deficit 2,496). + +A helper that starts at E has the residual S_E = T_FULL·T_E⁻¹ = L_E (C_[w] ⊗ I) R_E, w = 9 − dim E, exactly (global phase included). The paid wrappers R_E⁻¹ before the whole invocation and L_E⁻¹ after its cleanup turn it into the coordinate factor and restore the e = 9 − w spectator coordinates; they are emitted, replayed, decoded and charged. Widths 8/16/32/48 of #442's idle children are tiled by width-8 residuals; the hosting is whole-residual with distinct stages in every copy and at most one helper per physical family per invocation, with the host chart (residual vectors, first unused basis vectors as spectators) in the route and audited. Residuals that are not hosted go to banks of their own, one entering helper per replica per bank family, with the spectators in the pad and the route and chart audited in the same way. + +### Result +Both rational moment engines certify b = 1326789535340266/10¹⁸ (next grid point rejected). Under the one-owner rule the word hosts 39,792 of 40,320 residuals whole; the other 528 (all of width 8) sit in 66 banks (live stock 7,746, maximum child 9, rank deficit 2,496). The finite invoices with the hosted stock and the wrapper charge, and the strict outer assembly (six bootstrap levels, 47 inequalities, next-grid, zero-η, zero-β and unit-β controls rejected), pass for #442's bit word (run here, κ = 1.237552·10⁻³ unchanged) and, as a pinned input from our own bit-side package that is not re-run here, for the eleven-stage R724 mixed word under whole-residual hosting (c = 1.280810·10⁻³): κ = 1.279171·10⁻³, bit-bound (no new κ). That pairing is informational; our R715 word is #463. + +### Checks (`python -B research/e8-complex-gauge-kernel/verify.py DIR [--all] [--discover-check]`) +- #442 runs unchanged (with #434 and #433 below it), then the **regression anchor**: with the empty selection the generalised scripts reproduce #433's canonical word, local programs, local checks, parent global template and independent replay, and #442's hosted template and `HOSTED.json`. +- Gauge + kernel word: exact arbitrary-dirt and inverse-transpose replay (800 columns); emitted program replay in both orientations with centre lifetimes and wrappers; independent read-back of the serialized stream; exact Gaussian recipes with global phase for every used frame transition (`complex_phases_full.py`, unmodified); exact decoding of the wrapper monomials (L⁻¹ S_E R⁻¹ = C_[w] ⊗ I on every entrance frame); independent hosting audit (windows, slots, owners, spectator chart on data and bank families, one owner per family on every register class, private namespace, remainders, wrong-width control); fresh finite invoices; certified b. +- **Independent Lemma G stage** (`code/lemmaG/`, imports no package script): the label / scalar / accounting checker on both orientations, the exact operator identities of every compensation, centre and helper instance on all 512 basis columns, the complete emitted program end to end against the transform computed from definitions, and 14 necessity mutants of the clauses. +- Mutation controls, all rejected, several through the certifying scripts themselves: kernel and gauge gates, entrances, target levels, centre chains, wrappers, centre descent steps, two helpers on one data or bank family (accepted by #442's rule, rejected here), spectator records, owners in the private namespace or on another replica's families, wrappers on non-helper registers, and selection-level conditions; the generators also refuse the eight-entering-helpers-per-bank tiling. +- `--discover-check` recomputes the frozen hosting selections with HiGHS and requires equality. Status: quick mode (`--discover-check`) passes from a fresh clone. The full `--all` replays (which also check the kernel79/gauge80 rows) are running after this draft; an earlier `--all` run failed only on a stale `EXPECTED.json` copy (complex-cap field from the pre-bank-fix word). + +### Principal review points (conditional) +- **Lemma A** (`PROOF.md` §3). Exact and checked: S_E = L_E (C_[w] ⊗ I) R_E and the wrapped product on every entrance frame. Assumed: #458's argument that wrappers around a whole invocation of a family on which nothing else acts leave the spectators identical, at nine stages, for hosted families and banks. +- **The entrances are not coordinate entrances.** Every entrance frame consists of even-weight vectors of F2⁹ (15 of 16 frames totally isotropic). The bit-style criterion of #440 (`validate_isometries`) is not met and cannot be met by any orthogonal map of O(9,2); restricted to entrances that meet it, the gain is 0. #442's complex audit asserted `w == 9` and #433's emit start frame 0 for compensated registers; the marked copies here generalise exactly these. +- **Lemma G** (`PROOF.md` §2): reduces to #425's conjugation lemma and #471's / #458's virtual entrance, plus a schedule lemma (hypotheses (a)-(d)) whose clauses are checked on the emitted streams by the independent stage above; new relative to #458 and #471, which do not use the gauge. +- All interfaces inherited from #370, #386, #425, #433 and #442 remain assumptions. This is a conditional finite witness, not a theorem. + +### Credits +Dugongue (#471), chafreaky (#458, #417, #439), DaysSky (#442), icekylinx (#433), jacklightChen / Zhihao Chen (#386, #425), rohanarun (#434, #435, #438), eumemic (#436, #437, #440, #441), #471 (normalisation of the complete invocation, same-owner spectator borrowing), the authors of #401 and #408–#416 (entrance gauges and prefixes), Dylan Crow (#370), Jacob Sussman (E8 unit); #451 for the cross-family obstruction. + +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Licensed Apache-2.0. diff --git a/research/e8-complex-gauge-kernel/PROOF.md b/research/e8-complex-gauge-kernel/PROOF.md new file mode 100644 index 0000000000..28eeab1e94 --- /dev/null +++ b/research/e8-complex-gauge-kernel/PROOF.md @@ -0,0 +1,358 @@ +# Entrance gauges and shared-donor kernel on the E8 complex word: what is claimed, what is new + +Everything here is conditional on the interfaces inherited by #442 (all-size compiler, correlated dirty banks, compressed windows, +restored work, tape/common grid, precision, analytic transfer) and, in addition, on **Lemma A** (paid residual wrappers with explicit +spectators) and **Lemma G** (nonzero-frame compensation and the centre scatter), which are the review points. No Lean proof and no +unconditional theorem is claimed. Hosting is #442's whole-residual hosting (no cross-family split) under the additional rule of #458, extended +here to banks: an entering helper is the only owner of its physical family (data or bank) in every invocation. + +## 0. Setting +Complex supplier of #433 (R = 560, h = 9, m = 73, nine stages, eight replicas) with #442's idle-axis hosting. Frames are subspaces of +F2^9; T_F = canonical_frame(9, F) (`clifford_exact.py`); a climb A → B applies T_B T_A^-1. A helper normally has start frame {0}, ends at FULL +and its residual has width 9. The frame-zero compensation `target += c·helper` (the response of the arbitrary helper dirt) is what normally +pins every helper to start frame {0}. A helper with start frame E of dimension e has residual width w = 9 − e. The construction of the paid +wrappers and the one-helper rule follow #458 (chafreaky), which did this for the kernel on an eleven-stage complex word; this package +applies them on the nine-stage word and adds entrance gauges. + +## 1. Lemma K (shared-donor kernel; port of #417/#435/#434/#439/#440, as frozen in #449 and used by #458) +Let col(x) ∈ Q^120 be the response of the target rows to the dirt of helper x. A class (E, D, P) has donors D with independent columns and +pivots P with col(p) = Σ_d q_{pd} col(d) exactly, E ⊆ the first frame of every member. Each pivot starts at E; before the main word every +donor receives `d += −q_{pd} p` at frame E (inverse after the full-frame cleanup, the inverse of the whole non-target subword). The donor +updates move the pivot's dirt into the donors, so the composite response of the pivot's dirt is col(p) − Σ_d q_{pd} col(d) = 0 and its +frame-zero compensation column vanishes. Exactness is the arbitrary-dirt replay of the explicit program (precondition + compensation + main + +cleanup) on every column, forward and inverse-transpose (`audit_gk.py`); frames are checked by the chain assertion; all coefficients have +power-of-two denominators (asserted by `emit_gk.py`). + +## 2. Lemma G (entrance gauge: nonzero-frame compensation and the centre scatter) +Scope: the entrance-gauge part of this package (nonzero-frame compensation and the centre scatter at the target levels), on the headline word gauge80 + kernel42, on the per-tool +words gauge80 and kernel79, with #433's word (the anchor) as the control. Lemma A (wrappers, spectators, one-owner rule, banks; §3) and Lemma K (§1) are not re-proved here; where +Lemma G uses them the interface is stated (2.2, item N). **Lemma G is not an assumption on top of #425 and #471: it reduces to #425's conjugation lemma and to #471/#458's virtual +entrance, plus a schedule lemma (2.4) whose clauses are checked exhaustively by code that imports no package script (2.5, `verify.py` stage).** The inputs are the emitted artefacts of +each variant (`CANONICAL-WORD`, `LOCAL-PROGRAMS`, `CLIFFORD-RECIPES`, `RESIDUAL-ADAPTERS`, and the 72 calls of the hosted template, which reference the program digests of 40 forward and 32 backward calls); +their sha256 values and the program digests are recorded by the check stage (`LEMMA-G-CHECK.json`, `EXPECTED.json`). The local word does not depend on the hosting or on the banks. + + +### 2.1 Setting + +* H = C^(2^9). Every operator below acts on the 2^9 local coordinates; on exterior slices it acts as the identity, which is omitted. +* A **frame** F is a subspace of F2^9, given by a row of the word's frame table. Each frame has a fixed invertible operator T_F on H. In the package, T_F = `canonical_frame(9, F)` (exact Gaussian-dyadic Clifford), T_0 = I and T_FULL = the Fourier gate on all nine axes. **Only the invertibility of T_F is used below.** +* A register is a pair (h, F): physical content h ∈ H and current label F. Its **logical value** is ℓ = T_F^-1 h. +* The events of an emitted local program are listed below. The physical effect is what the hardware does; the label effect is the bookkeeping. + +| event | physical effect | label | +| --- | --- | --- | +| `climb r A→B` | h_r ← T_B T_A^-1 h_r (the serialized child recipe) | A → B | +| `center k A→B` | the same on the private copy C_k | A → B | +| `add t ← s, q` at F | h_t ← h_t + q h_s | none | +| `scale t, q` | h_t ← q h_t | none | +| `copy C ← r` at F | h_C ← h_r | C := F | +| `clear C` at F | h_C ← 0 | C := F | +| adapters, wrappers | fixed endpoint operators (outside Lemma G) | none | + +--- + +### 2.2 What is inherited (admitted by #425, #433, #458, #471) + +**C. Common-frame conjugation lemma (#425, "Why the scalar argument lifts to exact complex labels").** +*Hypothesis:* in a stream of the events above, every `add` and `copy` has both operands at one current label, which equals the annotated frame (clause G0). +*Conclusion:* let λ⁰ and λ¹ be the initial and final labels, and let S be the rational matrix of the scalar events with the frames stripped. Then for **every** physical input, + + h_r(final) = Σ_s S_rs · T_{λ¹_r} · T_{λ⁰_s}^-1 · h_s. + +*Proof (four lines, included so that this file is self-contained).* The invariant is that h_r = T_{λ_r} ℓ_r at all times, where ℓ evolves under the scalar events alone. Start with ℓ_s := T_{λ⁰_s}^-1 h_s. +* A climb A → B: T_B T_A^-1 (T_A ℓ) = T_B ℓ, with the new label B. +* An add at a common F: T_F ℓ_t + q T_F ℓ_s = T_F(ℓ_t + q ℓ_s). +* A scale commutes with T_F. A copy at F gives T_F ℓ_r. A clear gives 0 = T_F·0. + +Only linearity and invertibility are used. ∎ + +**C′. #425's scalar interface.** +* Block form z′ = Uz, y′ = Vy + Jx + Ks. No target feeds a source or helper. Targets may be read, as in the 56 target butterflies at frame 0. +* The frame-zero preconditioner runs on label-0 registers. The cleanup U^-1 runs at the common FULL label. +* The second orientation is the inverse transpose: the dual of every scalar, in the same event order and with the **same frame chronology**. +* Private centre copies are taken, moved between nested frames by explicit paid children, scattered, and erased. #433 adds split centres: c_k has rank 8 or 1, and the copy goes c_k → 0. + +**N. Virtual entrance and full-invocation normalisation (#471 §1, #458 §1).** +* A helper may start at label E. Its logical input is T_E^-1 h, and no physical T_E is executed. +* Nonzero-frame helper←helper additions at the head of the word are admitted: the kernel donor updates at E, inverted at FULL in the cleanup. +* With the scalar identity, the cross blocks vanish, so the data endpoint is unaffected and the helper block is Φ_E = T_FULL T_E^-1. #471 states this as a property of the **complete invocation**, not of any one addition. +* Paid wrappers R_E^-1 (before) and L_E^-1 (after) turn Φ_E = L_E (C_[w] ⊗ I) R_E into C_[w] ⊗ I. Spectators are borrowed in the same owner array. That is Lemma A, which is not part of Lemma G. + +**Neither #458 nor #471 uses the gauge.** #458's README says "No … entrance-gauge construction from PR449 is used". #471's PR text says "Its separate gauge-80 change is not used". The steps below are therefore new. + +### 2.3 What is new relative to #458 and #471 + +* **N1. Labelled targets before the centre phase.** A target climbs 0 → E_(1) ⊊ … ⊊ L_t during a compensation segment and is read and written there. It sits at L_t through the centre phase and climbs from L_t into part B. In #425, #433, #458 and #471, targets are at label 0 until the scatter. +* **N2. Target-side nonzero-frame compensation.** The dirt column of an entering helper j is cancelled by gates `y_t += c_tj · x_j` at its entrance label E_j, instead of in the frame-zero preconditioner. In #471 the nonzero-frame adds are helper←helper, and a pivot's column vanishes by linear dependence. +* **N3. Centre scatter along a chain.** The copy descends c_k → λ_1 → … → λ_m = 0, scattering at every level. The backward orientation gathers while ascending. In #425 and #433 the copy makes one step, c_k → 0. + +All three are made of the event types already admitted in C, C′ and N. **No new operator-level fact is needed.** What is new is a *schedule lemma*: the emitted stream satisfies G0 and the accounting clauses. That lemma is proved below and checked exhaustively in 2.5. + +### 2.4 Lemma G: statement and proof + +Notation: +* W is #433's word. G is the set of gauge helpers, with entrances E_j; the kernel helpers (Lemma K) are disjoint from G. +* supp(j) is the set of targets in the support of j's dirt-response column. +* F_1(j) is the frame of the first gate on j in W. B_1(t) is the frame of the first gate on target t in part B of W. + +**Hypotheses on the selection:** +* **(a)** E_j ⊆ F_1(j). Since W's frames along a register are nested, E_j then lies inside every later frame of j. +* **(b)** For each target t, ℰ_t = {E_j : j ∈ G, t ∈ supp(j)} is a chain under inclusion. Write L_t := max ℰ_t, or 0 if ℰ_t is empty. +* **(c)** For each centre k, Λ_k = {L_t : t served by k} is a chain, max Λ_k ⊆ c_k, and 0 ∈ Λ_k. +* **(d)** L_t ⊆ B_1(t). The package's nested-climb assertions (`emit_gk`, `gk_word.profile`) enforce it, and it holds for all 50 levelled targets of the headline word. + +**Facts about W (checked):** +* **(W)** In part A of W no gate touches a target. With the gauge, the compensation gates are the only part-A gates on targets: 420 gates, 0 others. +* No entering helper is touched by the frame-zero preconditioner. In the headline word the preconditioner touches 112 targets and 438 helpers, none of them entering. +* At the cut, every centre register is at its centre label c_k, and no centre register is an entering helper. + +**Emission order:** +1. preconditioner +2. entry adapters and R^-1 wrappers +3. compensation segment: the gauge gates sorted by (dim E_j, j), each preceded by the climbs that bring its target to E_j +4. kernel updates +5. A +6. centre phase: copy at c_k; descend through Λ_k by decreasing dimension; scatter at each level; clear +7. B +8. final climbs +9. exit adapters +10. full-frame cleanup +11. L^-1 wrappers + +**Conclusions:** +* **(G-i) Schedule.** In both orientations the emitted stream satisfies: + * G0: common labels at every add and copy. + * G1: virtual entrances, with the wrappers outermost on each entering helper. + * G4: start labels as in W, except λ⁰_j = E_j; final labels as in W. + * ACC (accounting): + * every transition of a non-private register is an ascending nested climb charged |B| − |A|; + * every centre step is a strict nested descent (an ascent in the backward orientation) inside c_k; + * the centre steps sum to dim c_k; + * no child runs while a copy is live; + * the local rank mass per call equals mass(W) − Σ_j dim E_j. +* **(G-ii)** By C, h_r(final) = Σ_s S_rs T_{λ¹_r} T_{λ⁰_s}^-1 h_s for all inputs. +* **(G-iii)** The exact replay gives the scalar identity S: (x,s,y) ↦ (x,s,y+x) forward and (x−y,s,y) backward, all 800 columns, copies cleared. Therefore: + * the data block is **W's** data block (the source and target labels are unchanged at both ends); + * the cross blocks are 0; + * the block of entering helper j is Φ_{E_j} = T_FULL T_{E_j}^-1, which is exactly the input of #471's normalisation and Lemma A. + +**Proof of (G-i).** + +*Claim 1 (entering helpers).* +* j starts at E_j, and by (W) the preconditioner does not touch it. +* In the compensation segment, a gauge helper j occurs only as the source of its own gates, which are emitted at E_j, its label. A kernel pivot occurs only in donor updates at its class entrance, which is its start label (inherited, Lemma K / #471). +* The next event on j is the climb E_j → F_1(j), which is nested by (a) (by Lemma K's class condition for kernel helpers). The remaining climbs are W's, so they are nested and end at FULL. +* A nested chain telescopes, so j's climb mass is 9 − dim E_j. + +*Claim 2 (targets in the compensation segment).* +* Let j_1, …, j_p be t's gauge gates in emission order, so dim E_{j_1} ≤ … ≤ dim E_{j_p}. +* In a chain, dim E ≤ dim E′ implies E ⊆ E′, and equal dimension implies equality. By (b), therefore, 0 ⊆ E_{j_1} ⊆ … ⊆ E_{j_p} = L_t. +* The emitter climbs t only when the next gate's frame differs. So t's climbs are 0 → E_(1) ⊊ … ⊊ L_t, all ascending and nested. +* At each gate, t's label is E_j, which is j's label by Claim 1. So G0 holds at all 420 compensation gates. + +*Claim 3.* By (W) no other gate in the compensation segment, the kernel updates or A touches a target. So every target is at L_t when the centre phase starts. + +*Claim 4 (centre phase).* +* Forward: + * The copy is taken at c_k, the centre register's label, so the copy satisfies G0. + * Order Λ_k as λ_1 ⊋ … ⊋ λ_m. The order is strict because the λ_i are distinct elements of a chain, and λ_1 ⊆ c_k by (c). + * The steps c_k → λ_1 (omitted when they are equal) → … → λ_m are strict nested descents. + * At level λ_i the copy has label λ_i and scatters only into targets with L_t = λ_i, whose label is L_t by Claim 3. So G0 holds. + * By (c), λ_m = 0, so the step ranks telescope to dim c_k: the same mass as W's single c_k → 0 child. + * No climb is emitted inside the centre phase, so the lifetime clause holds. +* Backward: + * The copy is cleared at λ_m and gathers at λ_m. + * It then ascends λ_m → … → λ_1 → c_k, gathering at each level. + * Finally r += −C at c_k, followed by a clear. The label equalities are the same as in the forward orientation. + +*Claim 5 (targets in B).* t's first climb in B is L_t → B_1(t), nested by (d). The remaining climbs are W's and end at perp(P_t). The mass telescopes to 8, the same as in W. + +*Claim 6 (remaining events).* +* The preconditioner is at 0 on label-0 registers. +* The cleanup is the inverse of the non-target gates of the segment, the kernel updates, A and B. This includes the kernel updates, inverted at FULL, and excludes the gauge gates, whose destination is a target. Every source and helper is at FULL there. +* The backward orientation dualises each scalar but keeps its operand pair, so every label equality carries over. + +*Mass.* Sources contribute 8·120, targets 8·120, helpers Σ_j (9 − e_j) and centres Σ_k dim c_k. So mass = mass(W) − Σ_j e_j. ∎ + +**Which clauses are needed for what.** The necessity controls in 2.6 confirm this split. +* **Exactness (semantic):** + * G0 at the compensation gates (Claims 1 and 2), at the kernel updates (inherited) and at every scatter (Claims 3 and 4); + * G1, the virtual entrance with the wrappers outermost; + * the exact scalar identity S. +* **Paid profile, mass and lifetimes (accounting):** + * the nested monotone chains, which follow from (a), (b) and (d); + * the nested strict centre chain inside c_k with bottom 0, which follows from (c); + * the copy lifetimes. + + The operator identity survives a violation of any of these, but the charged children, the mass identity and therefore the moment (b) would be wrong. + +### 2.5 Independent exhaustive checks (`code/lemmaG/`, run by `verify.py`; no package script imported) + +Code in `code/lemmaG/` (driver `check.py`, one run per variant, stage of `verify.py`): +* `gd.py`: an exact Gaussian-dyadic applier for the Clifford primitives. It uses int64 with a 2^60 guard on every primitive; no run tripped it, so every equality is exact over Z[i][1/2]. It is cross-checked against the vendored state-vector routine on 19 operators. +* `lg_lib.py`: the label checker and exact rational scalar replay. +* `lg_phys.py`: the physical simulator. +* `lg_instances.py`, `lg_e2e.py`, `lg_mutants.py`: the drivers. + +The vendored `canonical_frame` and `cgate` are used only as **definitions** of T_F and C_q. Every executed transition, data adapter and wrapper is decoded from its serialized recipe. + +**Label, scalar and accounting checker** (`run_labels.py`). Both orientations, every event. + +| variant | label violations | scalar replay (800 columns) | compensation gates | kernel updates | entering helpers / entrance rank | local mass | calls → verified program | +| --- | --- | --- | --- | --- | --- | --- | --- | +| anchor | 0 | exact | 0 | 0 | 0 / 0 | 7032 | 72/72 | +| kernel79 | 0 | exact | 0 | 229 | 79 / 79 | 6953 = 7032 − 79 | 72/72 | +| gauge80 | 0 | exact | 420 | 0 | 80 / 106 | 6926 = 7032 − 106 | 72/72 | +| gauge80 + kernel42 | 0 | exact | 420 | 111 | 122 / 148 | 6884 = 7032 − 148 | 72/72 | + +In every variant the paid profile recount equals the word's `local_profile`, and every centre chain ends at 0 with lowering mass dim c_k (8×8 + 8×1 = 72). + +**Per-instance operator identities** (`lg_instances.py`). Each is exact and checked on **all 512 basis columns of every input**. + +| identity | headline instances | result | +| --- | --- | --- | +| I-tr: every used transition, recipe = T_b T_a^-1 | 2945 transitions (climbs and centre steps) | 0 failures | +| I-comp: the compensation segment acts as h_t ↦ T_{L_t}(h_t + Σ_j c_tj T_{E_j}^-1 h_j), h_j ↦ h_j | 420 gates; 130 input registers (50 targets, 80 gauge helpers) | 0 failures | +| I-centre: forward h_t += q_t T_{L_t} T_{c_k}^-1 h_r; backward h_r −= Σ q_t T_{c_k} T_{L_t}^-1 h_t | 16 centres × 2 orientations (every served target in the backward orientation) | 0 failures | +| I-helper: L_E^-1 · (recipes along the helper's emitted chain E → … → FULL) · R_E^-1 = C_[w] ⊗ I | 122 helpers (w = 8: 104; 7: 14; 5: 4) | 0 failures | + +The headline's centre chains are (dimensions along the path): +* 1→0 eight times; +* 8→0 once; +* 8→1→0 once; +* 8→2→1→0 twice; +* 8→4→2→1→0 four times. + +The target levels have dimension 1, 2 and 4. The same identities hold, with 0 failures, on gauge80 (I-tr 2933, I-comp 420 gates and 130 inputs, I-centre, I-helper 80) and on kernel79 (I-tr 2932, I-centre, I-helper 79; it has no compensation segment). + +**End-to-end identity of the complete emitted program** (`lg_e2e.py`). Both orientations, all events: preconditioner, data adapters, wrappers, every climb and centre step by its recipe, cleanup. The result is compared with the intended transform computed **from definitions**. Here F is the nine-axis Fourier gate, C_q is the port gate, x_i = C_{q_i}^-1 h_i, and the target paired with source i is v + i. + +* **Forward:** + * source i ↦ F x_i + * target v + i ↦ F C_{q_i}^-1 (h_{v+i} + x_i) + * non-entering helper ↦ F h (= C_[9]) + * entering helper ↦ C_[w] ⊗ I · h +* **Backward:** + * source i ↦ F (x_i − h_{v+i}) + * target ↦ F C_{q_i}^-1 h_{v+i} + * helpers as in the forward orientation + +Columns checked: + +| variant | basis columns | dense columns | result | +| --- | --- | --- | --- | +| gauge80 + kernel42 | 806 | 8 | PASS, exact | +| gauge80 | 722 | 8 | PASS, exact | +| kernel79 | 670 | 8 | PASS, exact | +| anchor | 512 | 8 | PASS, exact | + +* The headline's 806 basis columns are: + * 256 random (register, coordinate) columns; + * 244 columns at the entering helpers, two per helper; + * 50 columns at the levelled targets; + * 16 at the centre registers; + * 240 at the ports. +* In a dense column every one of the 800 registers holds random Gaussian integers at once. +* The anchor passing the same formula shows that the data-adapter interpretation is the admitted #433 one. + +The end-to-end result depends neither on the wording of Lemma G nor on Lemma C: it is a direct exact computation of the emitted program. + +### 2.6 Necessity controls (`code/lemmaG/lg_mutants.py`) + +Each mutant edits the emitted headline stream so that one clause is violated. "Physics" is the exact end-to-end check on targeted and random columns; a transition that has no recipe is executed as T_b T_a^-1. + +| mutant | clause violated | checker | physics | +| --- | --- | --- | --- | +| M1 compensation with the target still at label 0 | G0 at a nonzero-frame compensation | G0 | FAIL both | +| M2 physical T_E on the helper (start declared 0) | G1 virtual entrance | G1, ACC | FAIL both | +| M3 target visits its levels out of nesting order (E2 → E1) | G2 (via (b)) | G2, ACC | PASS → accounting | +| M3b helper detours E_j → X ⊉ E_j → F | G2 (via (a)) | G2, ACC | PASS → accounting | +| M4 scatter after the copy descended below the target's level | scatter at the level (G0 in the centre) | G0 | FAIL | +| M5 last centre step skipped | chain reaches every level, bottom 0 | G0, ACC | FAIL | +| M6 copy taken at the wrong label | copy at c_k | G3 | FAIL | +| M7 another child runs while a copy is live | copy lifetime | G3 | PASS → accounting | +| M8 centre chain leaves c_k (c_k → X → L1) | nested chain inside c_k (via (c)) | G3, ACC | PASS → accounting | +| M9 compensation coefficient doubled | scalar identity S | S | FAIL both | +| M10 compensation after the helper's first climb | G0 (the compensation reads the entrance value) | G0 | FAIL both | +| M11 kernel update with the donor at label 0 | G0 at a nonzero-frame kernel update (inherited) | G0, ACC | FAIL both | +| M12 R_E^-1 after the helper's first gate | G1, wrapper outermost | G1 | FAIL both | +| M13 L_E^-1 dropped | G1, wrapper outermost | G1 | FAIL both | + +The checker rejects all 14 mutants. The physics column confirms the classification: the semantic clauses are needed for exactness, and the accounting clauses for the charged profile. + +### 2.7 What Lemma G rests on +* #425's common-frame conjugation lemma C (proved in 2.2; it holds for any invertible label family), #425's scalar interface, and #471's / #458's virtual entrance and complete-invocation normalisation, with Lemma A (§3) closing the helper block. +* The new content is the schedule lemma (G-i), proved in 2.4 from (a)-(d) and the base-word facts (W). The common-label property is a CHECKED property of the emitted stream, not an assumption: the stage checks every event's labels, + the exact scalar identity on all 800 columns, the paid profile and mass identity, every transition recipe, the compensation segment, every centre phase and every entering helper's normalised chain on all 512 basis columns of each input, the 72 calls' program digests, and the complete program end to end. +* (b), (c) and nestedness are accounting conditions (charged profile, mass, D), not exactness conditions (2.4, 2.6). +* Lemma C and the virtual-entrance convention remain the admissions of #425 and #471/#458; Lemma G adds none. Lemma A (spectators, the one-owner rule, banks) and the global composition lie outside Lemma G; the check stage reads only the call digests of the hosted template. + + +## 3. Lemma A (paid residual wrappers with explicit spectators) — review point +Let E ⊆ F2^9, e = dim E, w = 9 − e. A helper that starts at E and ends at FULL has the physical residual S_E = T_FULL T_E^-1 (apply T_E^-1 +first). Its initial label is an interpretation of its arbitrary physical input h: the logical scalar value is T_E^-1 h. No T_E entrance transform is +executed, and none is charged as rank zero; the emitter has no entry adapter for entering helpers. +(i) **Exact (checked, `adapters_gk.py`):** S_E = L_E (C_[w] ⊗ I) R_E with R_E applied first, L_E, R_E Gaussian monomials (address permutation, +quadratic phase, translation, scalar power of i), for every entrance frame of the word, global phase included. The serialized monomials are +DECODED with the primitive constructors (not `lower_child`) and L_E^-1 S_E R_E^-1 has exactly the tableau and zero-state vector of C_[w] ⊗ I, i.e. +it is the Fourier factor on w coordinates and the identity on the other e. Wrong phase, translation, quadratic form, swapped sides and wrong width are rejected. +(ii) **Paid wrappers (emitted, replayed):** R_E^-1 is applied before every gate that touches the helper and L_E^-1 after the full-frame cleanup of the +whole local invocation (`residual_adapter` events; `replay_gk` demands exactly one of each per entering helper, with the right frame and phase). They are +charged: 144 elementary factors at each end of every entering helper in every invocation (a monomial on 9 bits has at most 81 + 45 + 9 = 135) in +`integrate_gk.py`. The wrapped residual is C_[w] ⊗ I on the nine local coordinates. +(iii) **Spectators and the one-helper rule (assumed, adopted from #458 §3):** the wrappers mix the w residual axes with e spectator axes of the host family +and surround the whole invocation, so the spectators must not be touched by anything else during the call. Hosting is therefore whole-residual with +at most one helper per physical data family per invocation, and an entering helper is also the only owner of its bank family (below); generated and audited (`onehost_gk.py`, `hosted_gk.py --one-helper-per-family`, +`audit_hosted_gk.py --one-helper-per-family`: all hosted families of a call are pairwise distinct and distinct from the active data families; the children of one +(pair, side) share their families and have pairwise disjoint windows, which is checked). The host chart is explicit and audited: for the host's port q the +parent's idle basis is B_q = U_q ⊕ I; the residual occupies the pending vectors b_off … b_(off+w−1); the spectators are the first e basis indices of B_q not +occupied by it, in increasing order; the route [4, child, offset, w, spectators] records them. The route is a permutation of an orthonormal basis (it is in +O(73,2)); the non-orthogonal address maps occur only inside the paid monomials. Under these conditions the complete effect of a call on the host is +P_g (C over the assigned pending vectors) P_g^-1 with identity on every spectator, and factors of different calls act on disjoint pending coordinates. +**Banked entering residuals (the same rule).** Entering residuals that are not hosted are tiled into banks of their own: bank j of a stage holds the j-th +entering helper of each of the eight replicas, packed from cell 0 (`gk_common.tile`), so a bank family has at most ONE entering owner per invocation (the generators place replicas by construction rather than asserting it; the eight replicas share each bank's spectator cell across invocations, never within one) and no +width-9 residual shares it. The bank chart is the analogue of the host chart: the bank is the standard basis of its 73 cells; the residual occupies cells +off … off+w−1; the e = 9 − w spectators are the first e cells beyond every residual cell of the bank (its pad), in increasing order; route +[2, off, w, spectators]. The pad is paid as before (rank 73 − Σ widths, i.e. 9 for eight width-8 residuals); the spectators are borrowed inside it and not +deducted, so D = 2496 is unchanged. Width-9 residuals keep #433's pure banks, [2, slot] with eight disjoint 9-cell slots, and carry no wrapper. A layout with eight +entering helpers of one invocation per bank family, each in a disjoint 9-cell footprint (eight residual cells and a spectator in the pad), has the same bank count, pad +and b; it is NOT used and the audit rejects it (control below), because the argument adopted here is #458's one-owner rule, not disjoint supports. +**Where the rule is asserted.** On every register class of an invocation, in the generators (`hosted_gk.one_helper_rule`, `integrate_gk.py`) and independently in +`audit_hosted_gk.py` (strict) and `replay_gk.py` (parent template): active data wires and hosted helpers (data families: one owner each, any width); banked helpers +(an entering helper is the sole owner of its bank family, spectators = the bank chart, the 9-cell footprints of a family are disjoint; width-9 helpers share a pure bank); +the private namespace (centres, reserved tableau, coefficient: never an owner; the hosted template's `private_namespace` record is re-based on the hosted stock, the +inherited record pointed beyond it, and is audited); copies (every owner of a replica's invocation lies on that replica's data families or on a bank; the children of +one (pair, side) share their families and have pairwise disjoint windows). Wrappers are emitted and replayed for helper registers only (data, target and centre +registers are rejected), and an entrance (`start_extra`) is accepted for helper registers only. +**What is not met:** the entrance frames consist of even-weight vectors of F2^9 (the dot product is alternating on E; 15 of the 16 frames of the headline +word are totally isotropic). The bit-style criterion of #440 (`validate_isometries`) is therefore **not** satisfied, and cannot be: no orthogonal map of O(9,2) +sends such an E to coordinate axes (restricted to entrances that satisfy it the gain is 0, `provenance/iso1.py`). That is why the wrappers are two-sided +paid monomials and not an orthogonal conjugation. + +## 4. Hosting, stock and invoices +Hosting is #442's integer programme with residual widths 9 − dim(E) and distinct stages in the pattern of every copy of an idle child +(`onehost_gk.py`); a hosted residual occupies w pending coordinates of one family; no piece lies on two families (`audit_hosted_gk.py`). Unhosted +residuals are tiled into banks (width-9 residuals by first fit, eight per bank with #433's [2, slot] routes; entering residuals in banks of their own, one per replica +per bank, route [2, offset, width, spectators]) and each bank pays a pad of rank 73 − Σ widths (split into commuting children of rank ≤ 51). The live stock is +64·120 + 9·banks; the finite invoices are #442's with the hosted stock +plus the wrapper factors above (`integrate_gk.py`, `assemble_gk.py`). + +## 5. Regression anchor and controls +With the empty selection the generalised scripts reproduce #433's CANONICAL-WORD, LOCAL-PROGRAMS, LOCAL-CHECKS, parent GLOBAL-TEMPLATE and +INDEPENDENT-REPLAY and #442's hosted template and HOSTED.json byte for byte (`verify.py` asserts it); the anchor keeps #442's hosting rule. +Mutation controls, all rejected: (a) through the certifying scripts (`controls_pipeline.py`, each runs `audit_gk` then `emit_gk` on a mutated word): +kernel donor update omitted / sign flipped; gauge gate omitted / coefficient doubled; entrance outside the frame of its gates; an entrance given to a helper +that keeps a frame-zero compensation; target level forgotten; centre levels not a chain (word built without the builder's checks); (b) in `replay_gk`: +the four local and three global controls of #433, missing / misplaced / wrong-frame wrappers, a centre step that is not nested, a skipped centre +descent step; (c) in `adapters_gk`: wrong phase, translation, quadratic form, swapped sides, wrong width; (d) in `audit_hosted_gk`: the eight controls of #442's +audit with a wrong-width control, two helpers on one physical family (accepted by #442's rule, rejected here), a spectator that is a residual coordinate, +shifted / dropped spectators, a missing spectator record, the rule flag removed, and, for the other register classes, two entering helpers on one bank family (the +nine-cell-footprint layout above: accepted by the #442 rule, rejected here), a bank spectator that is a residual cell / shifted / miscounted / dropped, a banked +entering helper or a second owner on an active data family, a bank owner in the centres or the reserved tableau of the private namespace, a private-namespace record left at the +parent's ranges or overlapping the live stock, a hosted or active owner on another replica's family, overlapping windows in one family group; +(d') in `controls_hosting.py`, through the generators (`hosted_gk.one_helper_rule`, `hosted_gk.py`, `integrate_gk.py`): one mutated owner array per register class (two entering +helpers on one bank family, a spectator inside the residual, an active wire on a bank, two hosted helpers on one data family, a helper on an active data family, an owner in the centres, +the reserved tableau or the coefficient registers), and the whole hosting and parent-template generators run with the eight-entering-helpers-per-bank tiling, which they must refuse; +in `replay_gk.py` the same rule is tested on mutated owner arrays of the parent template, plus wrappers naming a data, target or centre register; (d'') the independent Lemma G stage of `verify.py` (`code/lemmaG/`): the label / scalar / accounting checker, the exhaustive instance identities, the end-to-end identity and the 14 necessity mutants of 2.6 (all rejected); +(e) on the selection (`gk_word.build`): entrance outside a first frame, +non-nested entrances, pivot outside the donor span, entrance outside a donor's first frame. The strict outer assembly rejects the next grid point and zero/unit η, β. diff --git a/research/e8-complex-gauge-kernel/README.md b/research/e8-complex-gauge-kernel/README.md new file mode 100644 index 0000000000..1a8324e6aa --- /dev/null +++ b/research/e8-complex-gauge-kernel/README.md @@ -0,0 +1,75 @@ +# Complex supplier b ≈ 1.327·10⁻³ under whole-residual hosting: shared-donor kernel and entrance gauges with paid residual wrappers (conditional on two lemmas) + +**Certified complex saving b = 1326789535340266/10¹⁸ ≈ 1.326790·10⁻³, +4.68 % over #442's 1.267453·10⁻³,** on #442's whole-residual idle-axis hosting (no +cross-family split) with the rule of #458 extended to banks: an entering helper is the only owner of its physical family (data or bank) in every invocation. It rests on two lemmas that are the review points: +**Lemma A** (paid residual wrappers R_E⁻¹ / L_E⁻¹ with explicit spectators; the entrances are isotropic, not coordinate entrances) and **Lemma G** +(nonzero-frame compensation and the centre scatter); see [PROOF.md](PROOF.md). The bit side is not changed by this package. + +## What it does +On #433's split-centre complex word (R = 560, m = 73, nine stages) two tools of the bit side are ported: + +| complex word | entering helpers | entrance rank | b (·10⁻³) | gain over #442 | +| --- | ---: | ---: | ---: | ---: | +| #442 | 0 | 0 | 1.267453 | | +| shared-donor kernel (#417/#435/#434/#439/#440; 79 pivots, rank-1 entrances) | 79 | 79 | 1.305684 | +3.02 % | +| entrance gauges (#401/#408–#416; nested per target and per centre) | 80 | 106 | 1.306413 | +3.07 % | +| **both** | 122 | 148 | **1.326790** | **+4.68 %** | + +An entering helper's residual has width 9 − e (e = entrance rank), which tiles #442's idle children of ranks 8/16/32/48. Under the one-helper rule the word with both +tools hosts 39,792 of 40,320 residuals whole; the other 528 (all of width 8) sit in 66 banks of their own, one entering helper per replica per bank family and the spectators in the bank's pad (live stock 7,746, maximum child 9, rank deficit 2,496). + +## Relation to #458 and #449 +#458 (chafreaky) ships the 79-pivot kernel of the draft #449 on an eleven-stage complex word with paid, emitted residual adapters and the one-helper rule. This package +adopts exactly that treatment (wrappers, spectators, one helper per family) on the nine-stage word and adds the entrance gauges; it supersedes the draft #449, whose +hosting allowed several helpers on one family and left the spectator coordinates of an entering helper unplaced. +The one-owner rule is applied to bank families too (an entering helper owns its bank family alone in the invocation; its spectators are the first cells of the bank's pad, borrowed and not deducted, as #471 borrows spectators +in the same owner array). + +## Result of `verify.py` +- complex b (two exact moment engines, next grid point rejected): **1326789535340266/10¹⁸**; the complex-only κ cap of this lineage is 1.325031·10⁻³ (#442's complex word: 1.265849·10⁻³; the #448/#450 lineage used in #464 and #469 has complex roots of about 1.44·10⁻³). +- Strict outer assembly (six bootstrap levels, 47 inequalities, next grid point and zero-η, zero-β, unit-β controls rejected) for two bit suppliers: #442's own bit word (run here): + κ = 1.237552·10⁻³, bit-bound, unchanged; and the eleven-stage R724 mixed word under whole-residual hosting (bit c = 1.280810·10⁻³, a **pinned input** from our bit-side + package, not re-run here): κ = 1.279171·10⁻³, bit-bound. **No new κ is claimed: the bit side binds.** The current lemma-less κ frontier is #478 (Dugongue) at 1.295509·10⁻³, which sits at #458's complex cap; this supplier raises that cap; #458, #460 and #462 are bit-bound, not complex-bound. On the complex side b is + +2.28 % over #458's 1.297204·10⁻³ and +1.65 % over #471's 1.305232·10⁻³ (#471 admits our kernel79 through normalisation plus same-owner spectator borrowing; credited). The R724 pairing is informational; our related R715 word is #463. +- Regression anchor: with the empty selection the generalised scripts reproduce #433's CANONICAL-WORD, LOCAL-PROGRAMS, LOCAL-CHECKS, parent GLOBAL-TEMPLATE and + INDEPENDENT-REPLAY, and #442's hosted template and `HOSTED.json` (compared byte for byte within one run; the gzip container bytes depend on the zlib of the Python in use, so the `.gz` files of a Python 3.14 and a Python 3.12 run differ; `EXPECTED.json` therefore pins the Lemma G inputs `CANONICAL-WORD.json` and `LOCAL-PROGRAMS.json` by the sha256 of their decompressed JSON, never of the `.gz` bytes). +- Exact checks on the gauge + kernel word: arbitrary-dirt and inverse-transpose replay on 800 columns; emitted program replay in both orientations with centre lifetimes + and with the paid wrappers; an independent read-back of the serialized stream; exact Gaussian recipes (global phase included) for every used frame transition; exact decoding of + the serialized wrapper monomials (L⁻¹ S_E R⁻¹ = C_[w] ⊗ I on every entrance frame); independent hosting audit with the one-owner rule and the spectator chart on data and bank families; + an independent check stage for Lemma G (`code/lemmaG/`, imports no package script): label / scalar / accounting checker, exhaustive instance identities on all 512 basis columns, the complete program end to end, and 14 necessity mutants. +- Mutation controls, all rejected, several through the certifying scripts themselves (`audit_gk`, `emit_gk`, `replay_gk`, `audit_hosted_gk`): kernel and gauge gates, entrances, target levels, + centre chains, wrappers (missing, misplaced, wrong frame, wrong phase / translation / quadratic form / sides / width), centre descent steps, two helpers on one family + (accepted by #442's rule, rejected here), the same on bank families (the nine-cell-footprint layout), spectator records on data and bank families, owners in the private namespace, owners on another replica's families, wrappers on data / target / centre registers, + and four selection-level conditions; the generators `hosted_gk.py` and `integrate_gk.py` refuse the eight-entering-helpers-per-bank tiling (`code/controls_hosting.py`). + +## Plain statements about the scope +- **The entrances are not coordinate entrances.** Every entrance frame consists of even-weight vectors of F2⁹ (the dot product is alternating on E; 15 of the 16 frames of the headline word are + totally isotropic). The bit-style criterion of #440 (`validate_isometries`) is NOT met and cannot be: no orthogonal map of O(9,2) sends such an E to coordinate axes. With + entrances restricted to those that meet it the gain is 0 (`provenance/iso1.py`). Lemma A therefore uses two-sided paid monomials: part (i), L_E⁻¹ S_E R_E⁻¹ = C_[w] ⊗ I, is checked exactly; part (iii), + that the wrappers surround a whole invocation of a host or bank family on which nothing else acts, is #458's argument and is assumed. +- #442's shipped complex audit asserted `w == 9` and #433's emit asserted start frame 0 for compensated registers; the marked copies (`audit_gk.py`, `emit_gk.py`, `integrate_gk.py`, + `replay_gk.py`, `hosted_gk.py`, every change marked `GK:`) and the generated `audit_hosted_gk.py` generalise exactly these assumptions. +- **Lemma G** reduces to #425's conjugation lemma and to the virtual entrance of #471 / #458 plus a schedule lemma (PROOF.md §2, hypotheses (a)-(d)); the common-label property is checked on the emitted streams, not assumed. +- Hosting is whole-residual: one slot (child, port, offset) per residual, `offset + width ≤ rank`; no residual is split across families or children. +- All inherited interfaces of #370, #386, #425, #433, #442 remain assumptions. This is a conditional finite witness, not a theorem. + +## Run +This package lives in the tree of PR #442 and runs that package unchanged first (pinned by `SOURCE.json`). +```sh +python3 -B research/e8-complex-gauge-kernel/verify.py /absolute/new/output [--all] [--discover-check] +``` +Python 3.11+ and numpy (the Lemma G check stage); `--discover-check` also needs scipy and recomputes the frozen hosting selections (HiGHS), requiring equality. `--all` adds the kernel-only and +gauge-only words. About 25 minutes (PR #442's replay is 4 minutes of it; the exact phase recipes of each word take 2.5 minutes, the Lemma G stage about 10). The output directory must not exist. + +## Files +`PROOF.md` lemmas and scope · `verify.py` · `EXPECTED.json` · `SOURCE.json`, `MANIFEST.json` · `data/selections/*.json` frozen kernel classes and gauge entrances (helper indices), +`data/SELECTION.json` frozen hosting selections (patterns of distinct stages per idle-child copy), `data/bit-suppliers-pinned.json` · `code/` (`gk_word.py` applies a selection; +`audit_gk.py`, `emit_gk.py`, `integrate_gk.py`, `replay_gk.py`, `hosted_gk.py` are marked copies of #433's/#442's scripts; `onehost_gk.py`, `adapters_gk.py`, `audit_hosted_gk.py`, +`assemble_gk.py`, `controls_*.py`, `run_variant.py`; `lemmaG/` the independent Lemma G check stage run by `verify.py`) · `provenance/` the search scripts (not run by `verify.py`). + +## Credits +#458 (chafreaky: paid residual adapters, spectator chart and the one-helper rule), #442 (DaysSky: idle-axis hosting and the pipeline this extends), #433 (icekylinx: split centres), +#425 and #386 (jacklightChen / Zhihao Chen: mutable-basis packets, compressed windows), the shared-donor kernels and resets of the bit word: #417 and #439 (chafreaky), +#434, #435 and #438 (rohanarun), #436, #437, #440 and #441 (eumemic); the authors of #401 and #408–#416 (entrance gauges and prefixes); #370 (Dylan Crow); Jacob Sussman's E8 unit; and #451 for the +cross-family obstruction that makes whole-residual hosting the safe base; #471 (normalisation of the complete invocation and same-owner spectator borrowing, which admits the kernel79 word) and #472 (the current lemma-less κ frontier). +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Apache-2.0. diff --git a/research/e8-complex-gauge-kernel/SOURCE.json b/research/e8-complex-gauge-kernel/SOURCE.json new file mode 100644 index 0000000000..6ab7989bf9 --- /dev/null +++ b/research/e8-complex-gauge-kernel/SOURCE.json @@ -0,0 +1,137 @@ +{ + "note": "inventories of the packages of PR #442 and its parents that verify.py runs unchanged", + "packages": { + "e8-early-reset-kernel": { + "files": { + "EXPECTED.json": "6710a99055d7ee1d83d9f811822bb72db84f6ce95bd4e1e17f1df1659c7e958b", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "MANIFEST.json": "95a9570287b64d22de30e6ae3acf931d5f6daef1a163f0c99532e1a24639fbc2", + "NOTICE.md": "ff88b6031fe2fb5cbc483e8fcc08d228eaf2c982221adb3659da234dfa24cfeb", + "PROOF.md": "fb4e1c3a23e3a0be48b5254133e584dad6fb523042ca8ef70358684fb9185962", + "README.md": "4d7d736eda667533ab55bf3949e30832d4676d7ebeee00d9608307ecc5aacd4b", + "SELECTION.json": "b5f5d8c78d912820c8ed1a67c21062bec799714b9caa6724dfd515306ad42a2b", + "SOURCE.json": "a5e84250b687624b2158597831fb36a5f2b068983862c491f8e1020c9806cc65", + "VALIDATION.json": "77ad775cf69f5d913568b6276b0dfeb2eaef0306f57b71c0a467bff793807267", + "apply.py": "0d530e9703e1d1734c7af205bd393cba89ac41f75ed9781ea3dc5e46650f44f5", + "bit_audit.py": "203bb609952ad7b7ca761e9f9883ee9fa35a0a0474503b396d47a31169102e7d", + "bit_global.py": "79c7dc84e65dca10c35c842cf170e4719d45c38a25d03bf762332b24c700b6c9", + "bit_price.py": "36bf15803567a95b139a908461541bf19efe1f5b85fb31c270021833ab1393ee", + "combined.py": "4d514b6c70e969ec306d8c2bb38edec95b0cb7fa09f48dadbec8aa1eead69ce1", + "local-evidence/ASSEMBLY.json": "7c3cc4b503e4cf0fd3e050be46ad0da183c5b1c490f4901245df944fd9d6194e", + "local-evidence/AUDIT.json": "76a146a9123d8b653e6e46ff93f153653f9cefd0f5c3fdd264a59f1322110262", + "local-evidence/BIT-PRICE.json": "9a4a320cab1ce62b0c2329ac1bf3b81f73580fd603a406e4bfaae2962dfdad35", + "local-evidence/FULL-PYTHON311.json": "62b37525bf7b60c0d9101ed571681f3bf46ea75df065939864307e4986018332", + "local-evidence/FULL-PYTHON314.json": "85797531db037d06fb597a4c9b6ef6bd71e6a0ab4f220ae70b1b6bf3aeda205f", + "local-evidence/GLOBAL.json": "16c4e829eea1b2d12b70cec7e6a9c0e33ea0eae98a40894a3b779790fd2efbb3", + "local-evidence/SOURCE-SPANS.log": "bdf95dbce8337be57aab8a3d3b42a711ee276496c40cbb4c5356fc9cc9b2e811", + "source_span.py": "4772d177f37254c6f854af5ee3871aca193cfb24307a53c143c3bf517e56631e", + "vendor/kernel417/LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "vendor/kernel417/e8core.py": "3f4e25f700b7eb5821ab9cdfc65541f3f921baffeb8704beb21c6d7072052d29", + "vendor/kernel417/engines/base_two_moment.py": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098", + "vendor/kernel417/engines/moment.py": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482", + "vendor/kernel417/engines/outer.py": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c", + "vendor/kernel417/stages.py": "e73ab7836519510ed30dd7e3022dae557fa50fc513d723197929bff741859668", + "verify.py": "16c07414bc956744dc93b8e35b642267ea9819be922b0d3e081c543fdbf92a70" + } + }, + "e8-early-reset-reuse": { + "files": { + "EXPECTED.json": "5521c7e995fec77941243b28e090f95f2188f193d5f61275275cfa11215eecc0", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "MANIFEST.json": "4d23bafa43634a59e25f875333408b67cbecb1c912929824b5d45dea4de51da7", + "NOTICE.md": "c4085541471fe63d8f735beacd397d356446376ad3e56b2673940a2df3b8437e", + "PROOF.md": "09388e2f9e6b8fcc626a5172d55c45a957835075c51c68d1e86fd42ff4655ae8", + "README.md": "442bf686c0b24b9d7781b7b138f32fddea5d4efffeddc6e41d04719d2545e0cd", + "SELECTION.json": "9d47ade3fb69b3ef62a1a3ae75cebdddd57d144923977c5f2a07848ab596ea32", + "SOURCE.json": "c52287239c43aece2b3533ef48ee204d845d652066bca716c288b0c47e779521", + "VALIDATION.json": "bcb864a6b73d4ff4a24ab70ad51287653723c2115ce1c81db7817b81df2d9e92", + "bit_audit.py": "219eb4dd8e5380fb0432daa6a30c265755a78834616b2c5fc7aa161feb0231ee", + "bit_global.py": "9c2178df133dc663416aac13d8c8da80a9e4f5f7174bb36413180fcbad994ffb", + "bit_price.py": "36bf15803567a95b139a908461541bf19efe1f5b85fb31c270021833ab1393ee", + "combined.py": "dc621dce9ac1634a2701318311b30dffee7cce7e0c6be7ae808f44b27eb17f0f", + "local-evidence/ASSEMBLY.json": "c9ce28f59a5e460d39a888bbbc464e3fd6dd1c0b2c54ae86baeeea99febc8176", + "local-evidence/BIT-AUDIT.json": "2e458c3936e42539095610a50c730266dddd96e94d1ead171a99dd5f1fe9ef47", + "local-evidence/BIT-GLOBAL.json": "39f89d1e5bf51e9b1f1155e123dc3226627e465a246d37bb00f55d44d20bcaa0", + "local-evidence/BIT-PRICE.json": "96ec606146b5157871048e28f6649c31c1b6117d43be732e6a96bcc269c0e1b6", + "local-evidence/FAILED-INLINING.json": "95cbb0e6df953d25a888198c1072edf03db85b7c967a234680db3e095abd2dc7", + "local-evidence/FAILED-LATE-RESET.json": "f6ed36b59de745d50f37fcb4c80d129d9a2de0dfe1fe3de2d18e678135f7d9b6", + "local-evidence/FULL-PORTABLE-PYTHON311.json": "1dcca855b20cbac311a435f23f60001c342083edbef3194ba42a30e1f24c1982", + "local-evidence/FULL-PORTABLE-PYTHON314.json": "5687ed9209e11e64304d008a4a10678dc07cdc3522f5112c9a80557d45125c4a", + "local-evidence/FULL-PYTHON314-INITIAL.json": "0966528d4b30459d8b35296f31dbadfa34cdc7792419b34ab2505b7098923325", + "local-evidence/PARENT-FULL-REPLAY.json": "0ba447d6de6edd9fbe2371c36e3605dffa0c6526a874cfcb9bd19285c056bf1e", + "local-evidence/PYTHON311-GZIP-FAILURE.log": "ec1937c575536aeebe8f9c22d673fd66d1355ff870e2fdc80346205b29e42784", + "local-evidence/PYTHON311-INITIAL-FAILURE.json": "7902e8ca1e167b98d1c29170f8d57c9896b38ccab89065e4ed4e2c3feea79076", + "replay.py": "e0782ba05dda36323500390349d1180f6117a9c6112b09b9e21e29f67c4e5f5f", + "verify.py": "4e2082878acc1298f4354325b28f3cf047006170a9883148e7cf23002f6f02f1" + } + }, + "idle-axis-hosting": { + "files": { + "EXPECTED.json": "ed83c1bf1ca2d01eaab5149a34520806a07ef375dfa9e3ed69d123f4be4c9960", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "MANIFEST.json": "f68b82604363329618529313ac9c3796dc1e88b176eaee4a7b0dec9be428e987", + "NOTICE.md": "027a868628d0408602dbeae688b031ed9b4abfd6e5401f6e8106a3eb25ebc4ca", + "PROOF.md": "cfe34bf0b64259661312dae22c3a23adc5bf6f6326951eee5c1488ccfc347542", + "README.md": "1151f74cad54ac4937282b7a8b5d1108ed4ce35944ef9b7bb7d17abfce1fe4a0", + "SELECTION.json": "315d54be472842707cce879618be477d8b897050e873bc136d114eec6a232f97", + "assemble.py": "f9a2e6a42aadcf971702a5a867760a092566ed03356f4f34387d38f4093ad1a6", + "audit.py": "38594423a401110bd430b734037c6ecba422ee6a94d71709984e0afa9cd1edf8", + "bit_hosted.py": "6dfbf26213e8adf87563b3575cfb722bd07ecd65627f056b3293411dd3d89a61", + "complex_hosted.py": "829c5c4f4bdfccedadd31505f1f0a394f7a208d1446b7bbf9cc92d3aa1530c0c", + "hosting_core.py": "d8b90cd5d152df3c7c351230863d9e61816ad5e1f21d69bea1a86a5daad559a3", + "verify.py": "737a974d79fdd232b6c4b9e059c56835079971447342ed7ca3b82a614e30cb53" + } + }, + "split-centres-global": { + "files": { + ".gitattributes": "2f9541c7c27f084baad73b4cd50ddaeb264cc3aa8dbf13ec21df5ab3f673ca7e", + "CERTIFICATE.json": "f71580f22193726fb582eae604807ff70a7302265e001d9484a718e63bbe14c4", + "EXPECTED.json": "9b8e56eee3d5bdabd2e3e6e4ba0d9eba537525fba25a54126f9f0e41d2491a06", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "MANIFEST.json": "3129eb4321f706542470f8443f66a6b4351a12a9ceec85e7f76aa19db1e1e32f", + "NOTICE.md": "66101a9e74d0ba9c2da4c8802bcb1968534adfa7130b954628eb8bf515fc0389", + "PROOF.md": "6983e75f29af6eeaab20a30b08307ec6fab75ccb8b10291df8f9eb04d497f894", + "README.md": "b432292594adf2fcba2a8ddd87eda6167c76ff055e85aa5e3e2af7dd7e0f976e", + "SOURCES.json": "11aa666d678fed084b01d1e8e47239e1674eaedbc6fe0cee7edb2753477af9be", + "VALIDATION.json": "656d9bd7bd66058fdeb60cc90bd887e7ce75c0e0f9a100514e2bd84b95de89b6", + "code/bit_audit.py": "7fdbc077b7501a53662769ff2bf2ab44cc2e32dafc34478d7ef2c10e3144503a", + "code/bit_construct.py": "a461e6c983531beb5c8ac82ff593f39ce4e056387d1d6061f6e6b294dde4395f", + "code/bit_global.py": "3b2cb3ba21e5cf9b4deddb9e606322f33e9d8082020c0ee9092c21f4ebd9ad48", + "code/bit_price.py": "36bf15803567a95b139a908461541bf19efe1f5b85fb31c270021833ab1393ee", + "code/combined.py": "9c5bc70f2331b7342ceb252adcddb993581c45f80c37bcc58642dbad3b9775c2", + "code/complex_audit.py": "adeba5ea113652b60105db2e8719b18ffa292d3cc23730cca614b40272348330", + "code/complex_construct.py": "0f7f45b2333ec7daf4291e2bf675b49bc330b97fb5965dd27220ba353c291d6f", + "code/complex_emit.py": "f56d5f01f7c121741f175814138dca7190d769920f0a27e2d5b99c21aebed0f1", + "code/complex_integrate.py": "3792f41e409383e6989bda22801a4836a646a530f99e99bbd7244a8f3a1a8b4f", + "code/complex_phases.py": "13a959c52092776ae217df554b51c0298fa9eb3a350279acff6dece651c3f9cc", + "code/complex_phases_full.py": "0f2795aaffafe0c64d77f3748ef2109a3c42c58da867e4cf269a0a8cb6109466", + "code/complex_replay.py": "be2dccce2d1ad2c4f5c01a851c9c3896cc88236b5aeae706aad2ab16d6bfdad9", + "inputs/bit-geometry.json.gz": "5c980202227859e8bb9b863f94503930c2a59d460c0421356688e2b0d828b4a1", + "inputs/bit-r767.json.gz": "bd3b84244528767b85d8d7fe423b155630b5c659e21e51563674b1dcb6305ad7", + "inputs/complex-data-phases.json.gz": "c972b5b60649c2a52354f5160f69adc0f4a270fa09d32012beff9888774ab84f", + "inputs/complex-phase-receipt.json": "01763fee5017745de982f2ff5ee68004e815d6684097cc88011dfbfb1e789581", + "inputs/complex-phase-recipes.json.gz": "b5472bb1d3f9ff41b0819780a42886a7686b4caf3c0617bb1dc86158b3fb8671", + "inputs/complex-ports.json.gz": "77b0c0fa19ef3da1c7316010e13493aa5eea1a50c3506eddc08f7480e659878b", + "inputs/complex-template.json.gz": "1b84904a31a733aab9bfdda3f528c06719f590d2133a43687a8bded955dc991e", + "inputs/e8-r865.json.gz": "1fb726ea3818fe0837cceb0dd22a71a0814f064e5e781628104610d6468e0e55", + "notices/NOTICE-PR352.md": "967e6d7e76e216e4898cf543c75b527e8d397ec1ddba3800cb20701f24c89524", + "notices/NOTICE.md": "025773f32fb43667395e64c627a1752877bdc93afbfe01b106703eee438d21d3", + "notices/PR386.txt": "ae2241615a23063b18a04f1b7a88a52e62b3d7d42e333fbd21e3668567ab83d1", + "notices/PR426-SOURCE-PINS.json": "18ace817f2f9af22511bb303e99656ed114e534b87f3dd95a65ca4ca670baf2f", + "notices/PR426.md": "6a5593d0f284a2f0865037f5c5fa9e5f76f9e12cf50ec5284486d3b8137c89da", + "notices/SUSSMAN-NOTICE": "9419dd03a2f52cf8bdfc4d18216ce29f263ab583b27f01ced8e420985bcb7c81", + "proofs/INHERITED-COMPLEX-GEOMETRY.txt": "c1ff55536594222a8d2a30bc0e0956959774e1be2d5420b7838ad553ee556df2", + "proofs/PR386-BIT-GEOMETRY.txt": "c5f077b849e9add9957ab4ee36095dd47bc678dee7e09baa146dac4c0a0d66b2", + "proofs/PR425-COMPLEX.txt": "2cda27b9b9a1eb24127c38c2c7a6e085155a2472183e220189a3ea2c2b7720dc", + "proofs/PR426.md": "5787738ceb6faf14d3d96e8452592860a6c6a469733a9bcf196e8d1562ba1ffb", + "vendor/clifford_exact.py": "2982ead07721e83358dc67c6f49c2b4c16a236a6bebdfd72f58221be1f5d0962", + "vendor/engines/base_two_moment.py": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098", + "vendor/engines/moment.py": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482", + "vendor/engines/outer.py": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c", + "vendor/export_records.py": "8a5999601f917dbb492bb9ae9a344611f18cc7cedc53dc3c76496a369e530eb3", + "vendor/hamming_packets.py": "daa9301e2767a711cfe66c6bebaad68e1a3bdb97ec9e848c927527ab43b37ae5", + "verify.py": "12fcdb20a87f75812b09c4916fbfc86305982cb410247186a123b5c58d517b4c" + } + } + } +} diff --git a/research/e8-complex-gauge-kernel/code/adapters_gk.py b/research/e8-complex-gauge-kernel/code/adapters_gk.py new file mode 100644 index 0000000000..252ca9393d --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/adapters_gk.py @@ -0,0 +1,59 @@ +"""Paid residual wrappers for entering helpers (Lemma A): generation and independent decoding. Apache-2.0. +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. The wrapper construction follows PR #458 +(chafreaky): a helper that starts at frame E and ends at FULL has the physical residual S_E = T_FULL T_E^-1 (apply T_E^-1 first); +S_E = L_E (C_[w] x I) R_E with R_E applied first; the wrappers R_E^-1 before the whole local invocation and L_E^-1 after its +full-frame cleanup turn the residual into the coordinate factor C_[w] x I and restore the other 9 - w coordinates identically. +usage: adapters_gk.py CANONICAL-WORD.json.gz RESIDUAL-ADAPTERS.json OUT-LEMMA-A.json +Writes the recipes (generation uses clifford_exact.lower_child) and then DECODES the serialized monomials with the primitive +constructors of clifford_exact (not lower_child) and checks, for every entrance frame, that L_E^-1 S_E R_E^-1 has exactly the +tableau and zero-state vector (global phase included) of fourier(9, range(w)); mutated recipes (wrong phase, swapped sides, wrong +translation, wrong width) must be rejected.""" +import copy, gzip, json, sys +from pathlib import Path +R = Path(__file__).resolve().parent.parent.parent +sys.path.insert(0, str(R / 'split-centres-global/vendor')) +from clifford_exact import canonical_frame, lower_child, fourier, diag, perm, xgate, Op, identity +n = 9; FULL = tuple(1 << i for i in range(n)) +def monomial_op(rec): + """decode a serialized monomial (matrix rows, quadratic rows, Z4 linear part, translation, phase)""" + out = diag(n, tuple(rec['quadratic_rows']), tuple(rec['linear_Z4'])).then(perm(n, tuple(rec['matrix_rows']))).then(xgate(n, rec['offset'])) + return out.then(Op(n, identity(n), [('phase', rec['phase'])])) +def S_of(U): + return canonical_frame(n, tuple(U)).adjoint().then(canonical_frame(n, FULL)) +def wrapped_ok(U, rec): + """exactly: L^-1 S R^-1 = C_[w] x I (apply order: R^-1, S, L^-1)""" + w = n - len(U); S = S_of(U); Rm = monomial_op(rec['right']); Lm = monomial_op(rec['left']) + net = Rm.adjoint().then(S).then(Lm.adjoint()); target = fourier(n, range(w)) + return rec['rank'] == w and net.tab == target.tab and net.zero_state() == target.zero_state() +def main(): + c = json.load(gzip.open(sys.argv[1])); frames = c['frames']; v = c['v'] + starts = sorted({c['start'][r] for r in range(2 * v, len(c['start'])) if c['start'][r] != 0}) + recipes = {} + for f in starts: + U = frames[f]; rec, compiled = lower_child(S_of(U)) + recipes[str(f)] = dict(frame=f, vectors=list(U), entrance_rank=len(U), rank=rec['rank'], left=rec['left'], right=rec['right']) + Path(sys.argv[2]).write_text(json.dumps(dict(status='RESIDUAL_ADAPTER_RECIPES', recipes=recipes), sort_keys=True, separators=(',', ':')) + '\n') + # ---- independent decode of the serialized file + data = json.loads(Path(sys.argv[2]).read_text())['recipes'] + dot = lambda a, b: bin(a & b).count('1') & 1 + detail = [] + for f in starts: + rec = data[str(f)]; U = frames[f] + assert wrapped_ok(U, rec), ('wrapper product is not C_[w] x I', f) + detail.append(dict(frame=f, entrance_rank=len(U), residual_width=n - len(U), vectors=list(U), all_even_weight=all(bin(x).count('1') % 2 == 0 for x in U), + totally_isotropic=all(dot(a, b) == 0 for a in U for b in U))) + controls = [] + def reject(name, fn): + f = starts[0]; rec = copy.deepcopy(data[str(f)]); fn(rec) + if wrapped_ok(frames[f], rec): raise AssertionError('mutated wrapper accepted: ' + name) + controls.append(name) + reject('wrong global phase', lambda r: r['right'].__setitem__('phase', (r['right']['phase'] + 1) % 4)) + reject('wrong translation', lambda r: r['left'].__setitem__('offset', r['left']['offset'] ^ 1)) + reject('wrong quadratic form', lambda r: r['right'].__setitem__('quadratic_rows', [x ^ 2 if i == 0 else x for i, x in enumerate(r['right']['quadratic_rows'])]) if False else r['right']['linear_Z4'].__setitem__(0, (r['right']['linear_Z4'][0] + 2) % 4)) + reject('sides swapped', lambda r: (r.__setitem__('left', r['right']), r.__setitem__('right', r['left']))) + reject('wrong width', lambda r: r.__setitem__('rank', r['rank'] + 1)) + res = dict(status='PASS_RESIDUAL_WRAPPERS_ARE_EXACT', frames=len(detail), wrappers_reject=controls, all_even_weight=all(d['all_even_weight'] for d in detail), + all_totally_isotropic=all(d['totally_isotropic'] for d in detail), detail=detail) + Path(sys.argv[3]).write_text(json.dumps(res, indent=1) + '\n') + print('Lemma A (exact): L^-1 S_E R^-1 = C_[w] x I for', len(detail), 'entrance frames, global phase included;', len(controls), 'wrapper mutations rejected; all-even-weight:', res['all_even_weight']) +if __name__ == '__main__': main() diff --git a/research/e8-complex-gauge-kernel/code/assemble_gk.py b/research/e8-complex-gauge-kernel/code/assemble_gk.py new file mode 100644 index 0000000000..5973da7f80 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/assemble_gk.py @@ -0,0 +1,77 @@ +# Adapted from DaysSky PR442's assemble.py (complex half and strict outer assembly) and DreamingOfClouds' assemble_k.py by +# DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Apache-2.0. +"""Certified complex saving b for the gauge + kernel word under #442's whole-residual hosting: two exact moment engines, fresh +finite invoices with the hosted stock, then #434's strict outer assembly (six bootstrap levels, 47 inequalities, next-grid and +parameter controls) for each bit supplier listed in BITS.json (pinned inputs: c, charged two-level coefficient bits, row coefficient). +usage: assemble_gk.py PARENT_CHANGED PARENT_SC HOSTED_DIR AUDIT.json BITS.json OUT.json""" +import gzip, hashlib, importlib.util, json, math, sys +from fractions import Fraction as Q +from pathlib import Path +par, psc, cd, ap, bitsp, outp = map(Path, sys.argv[1:7]) +def load(name): + sp = importlib.util.spec_from_file_location('gk_' + name, par / 'work/pr361/code/engines' / (name + '.py')) + mod = importlib.util.module_from_spec(sp); sp.loader.exec_module(mod); return mod +M, Other, Outer = load('moment'), load('base_two_moment'), load('outer') +audit = json.loads(ap.read_text()); ch = json.loads((cd / 'HOSTED.json').read_text()) +assert audit['complex_template_sha256'] == ch['template_sha256'] +# ---------------- complex: two moments and the parent's invoice with the hosted stock +PC = {int(r): n for r, n in audit['complex_profile'].items()}; mc, WC = 73, audit['complex_live']; EC = sum(PC.values()) +massc = sum(r * z for r, z in PC.items()); assert mc * WC - massc == 2496 +rc = M.certify(PC, mc, WC, True); b = Q(int(Q(rc['lower']) * 10 ** 18), 10 ** 18) +fbc = 32 * mc * mc * EC +l3, h3 = Other.moment(mc, WC, list(PC.items()), b); b3, bh3 = Other.moment(mc, WC, [(1, fbc)], b); assert h3 + bh3 / 10 ** 16 < 1 +grid = Q(1, 10 ** 18) +l4, h4 = Other.moment(mc, WC, list(PC.items()), b + grid); b4, bh4 = Other.moment(mc, WC, [(1, fbc)], b + grid); assert l4 + b4 / 10 ** 16 > 1 # next grid point rejected +integ = json.loads((psc / 'INTEGRATION.json').read_text()); inv = integ['finite_invoice'] +physc = ch['physical']; v = 120 +compilerc = 64 * (mc + 1) ** 3 +pervertex = inv['pervertex'] - integ['physical'] * (64 + 1) + physc * (64 + 1) - integ['live'] + WC # stock-dependent terms re-based +r_ = mc // 2; group = 2 ** (r_ * r_) * math.prod(2 ** (2 * i) - 1 for i in range(1, r_ + 1)); stock = group * physc +smass = group * massc; logical = group * max(pervertex, inv['pervertex']) + 64; router = compilerc * (logical + 1) * (stock + 1) ** 2 +GG, EE, C0 = 1 << 30000, 1 << 100000, 1 << 210000; BB = smass + EE +literal = 2 * GG * stock ** 2 + 8 * smass + 4 * stock + 4 + 32 * mc +assert logical < 1 << 6050 and router < GG and literal < EE and BB < 1 << 100001 and 32 * mc * BB * BB < C0 and 2 * BB + 18 < C0 +depth = 2; assert mc ** depth > 2 * max(PC) ** depth +rowc = depth * stock.bit_length() + 9909 + 252; assert rowc < 20161 +# ---------------- outer assembly for each bit supplier, exactly as #434's combined.py +bits = json.loads(bitsp.read_text()); eta = beta = Q(1, 10 ** 18) +def ceil(x): return -((-x.numerator) // x.denominator) +def bootstrap(s_): + chn = [Q(384599, 10 ** 10)] + for j_ in range(6): chn.append((1 - s_) * s_ + s_ * chn[-1]) + q_ = chn[-1] * (1 - 2 * eta); mg = (1 - eta) * q_ / (1 + q_); tk = mg / grid + return chn, grid * ((tk.numerator - 1) // tk.denominator) +results = [] +for sup in bits: + c = Q(sup['c']); two_bits = int(sup['charged_two_level_coefficient_bits']); row = int(sup['row_coefficient']); ALLOW = max(20161, row, rowc) + s = min(c, (1 - beta) * b) - Q(1, 10 ** 24); assert 0 < s < c and s < (1 - beta) * b + chain = [Q(384599, 10 ** 10)]; cutoffs = [] + for j in range(6): + old = chain[-1]; a = (1 - s) * s + s * old + gap = min(s - a, 1 - a - s, 1 - a - s * (1 - old), 1 - s); assert old < a < s < 1 - a and gap > 0 + cutoff = max(ceil(36 / gap ** 2), ceil(2 * (4 + two_bits) / gap)); assert cutoff * gap ** 2 >= 36 and cutoff * gap >= 2 * (4 + two_bits) + cutoffs.append(dict(gap=str(gap), cutoff_log2=str(cutoff))); chain.append(a) + q = chain[-1] * (1 - 2 * eta); margin = (1 - eta) * q / (1 + q); ticks = margin / grid; k = grid * ((ticks.numerator - 1) // ticks.denominator) + bridge = {'semantic': {'C0': {'base': 2, 'exponent': 210000}, 'strict_literal_gap': 1}, 'rows': {'degree_gap': Q(10 ** 6) - Q(51 * ALLOW, 25)}} + a = Outer.assembly(chain[-1], b, bridge, k, eta=eta, beta=beta) + assert len(a['strict_constraints']) == 47 and all(x > 0 for x in a['strict_constraints'].values()) + controls = [] + for name, kk, ee, bb in [('next_grid', k + grid, eta, beta), ('zero_eta', k, Q(0), beta), ('zero_beta', k, eta, Q(0)), ('unit_beta', k, eta, Q(1))]: + try: Outer.assembly(chain[-1], b, bridge, kk, eta=ee, beta=bb) + except AssertionError: controls.append(name) + else: raise AssertionError(name) + results.append(dict(label=sup['label'], source=sup.get('source', ''), bit_lower=str(c), kappa=str(k), kappa_decimal=format(float(k), '.18f'), + binding_component='bit' if c < (1 - beta) * b else 'complex', external_row_allowance=ALLOW, + strict_outer_constraints={n: str(x) for n, x in a['strict_constraints'].items()}, outer_controls=controls, bootstrap=cutoffs)) +# kappa the complex supplier alone supports (a hypothetical bit supplier that does not bind) +c_hyp = b / (1 - beta) + Q(1, 10 ** 24); s_cx = min(c_hyp, (1 - beta) * b) - Q(1, 10 ** 24) +_, k_cx = bootstrap(s_cx) +res = dict(status='PASS_COMPLEX_GAUGE_KERNEL_CERTIFICATION', complex_lower=str(b), complex_decimal=format(float(b), '.18f'), + complex_cap_kappa=str(k_cx), complex_cap_kappa_decimal=format(float(k_cx), '.18f'), + complex=dict(live=WC, physical=physc, maxchild=max(PC), rank_mass=massc, hosted_residuals=audit['complex_hosted_residuals'], + physical_stock_bits=stock.bit_length(), router_bits=router.bit_length(), literal_bits=literal.bit_length(), row_coefficient=rowc, + pervertex_bits=pervertex.bit_length()), + suppliers=results, complex_template_sha256=ch['template_sha256'], widths=audit['widths']) +outp.write_text(json.dumps(res, indent=2) + '\n') +print(res['status'], 'b', res['complex_decimal'], 'complex-cap kappa', res['complex_cap_kappa_decimal']) +for r_ in results: print(' ', r_['label'], 'kappa', r_['kappa_decimal'], 'binding', r_['binding_component'], 'controls', r_['outer_controls']) diff --git a/research/e8-complex-gauge-kernel/code/audit_gk.py b/research/e8-complex-gauge-kernel/code/audit_gk.py new file mode 100644 index 0000000000..e80ca6b8b3 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/audit_gk.py @@ -0,0 +1,189 @@ +# GK: modified copy of PR #433's complex_audit.py (icekylinx with Codex; PR #425) by DreamingOfClouds with Claude Opus 5.5 +# (Anthropic), via Claude Code. Every change is marked "GK:"; with a word that has no start_extra / target_levels the +# behaviour and the written files are PR #433's. +# Modified from PR425 by icekylinx with Codex assistance. +"""Read-back audit, independent of the Hamming producer and its row state.""" +import copy,gzip,hashlib,importlib.util,json,math,time +from collections import Counter +from fractions import Fraction as Q +from pathlib import Path + +OUT=Path('split-centres');p=OUT/'FULL-WORD.json.gz' +word=json.load(gzip.open(p));v=120;n=240+word['report']['R'];start=time.monotonic() +def apply(e,rows): + if e[0]=='scale': + _,t,a,b,*_=e;q=Q(a,b);assert q + rows[t]={j:q*x for j,x in rows[t].items()} + else: + _,t,s,a,b,*_=e;q=Q(a,b);assert t!=s + for j,x in list(rows[s].items()): + z=rows[t].get(j,Q(0))+q*x + if z:rows[t][j]=z + else:rows[t].pop(j,None) +def ident():return [{r:Q(1)} for r in range(n)] +def inv(e): + e=copy.deepcopy(e) + if e[0]=='add':e[3]*=-1 + else:e[2],e[3]=e[3],e[2] + return e +def dual(e): + e=inv(e) + if e[0]=='add':e[1],e[2]=e[2],e[1] + return e + +main=word['A']+word['cut']+word['B'] +assert all(not 120<=e[2]<240 for e in word['A']+word['B'] if e[0]=='add' and not 120<=e[1]<240) +matrix=ident() +for e in main:apply(e,matrix) +print('full main columns',n,'replayed',flush=True) +# Compute -A_Y^-1 B_S using only rows of the explicit main operator. +dirty=[{} for r in range(n)] +for r in range(v,2*v):dirty[r]={j:x for j,x in matrix[r].items() if j>=2*v} +for e in word['precondition']:apply(e,dirty) +comp=[] +for r in range(v,2*v): + for j,q in sorted(dirty[r].items()):comp.append(['add',r,j,-q.numerator,q.denominator,[]]) + +cleanup=[inv(e) for e in reversed(word['A']+word['B']) if not v<=e[1]<2*v] +assert [e[:-1] for e in cleanup]==[e[:-1] for e in word['cleanup']] +program=word['precondition']+comp+main+cleanup +actual=ident() +for e in program:apply(e,actual) +expected=ident() +for t in range(v):expected[v+t][t]=Q(1) +assert actual==expected +print('PASS exact arbitrary dirt and restored sources/helpers',flush=True) +back=ident() +for e in program:apply(dual(e),back) +expected_back=ident() +for t in range(v):expected_back[t][v+t]=Q(-1) +assert back==expected_back +print('PASS exact inverse-transpose on every column',flush=True) +# Independent sparse vector controls avoid repeating a dense full replay. +def vector(es,x): + x=list(map(Q,x)) + for e in es: + if e[0]=='scale':x[e[1]]*=Q(e[2],e[3]) + else:x[e[1]]+=Q(e[3],e[4])*x[e[2]] + return x +sample=[((i*137+13)%101)-50 for i in range(n)] +want=vector(program,sample) +controls={ + 'missing_dirty_compensation':word['precondition']+main+cleanup, + 'missing_Y_inverse_basis':comp+main+cleanup, + 'missing_source_cleanup':word['precondition']+comp+main, + 'wrong_dual_event_order':[dual(e) for e in reversed(program)], +} +for name,es in controls.items(): + expected_sample=vector([dual(e) for e in program],sample) if name=='wrong_dual_event_order' else want + assert vector(es,sample)!=expected_sample,name + +# Orthogonal transvection and a port permutation bring the new geometry onto +# the already fixed 120-port routing family. Every incidence is transformed. +old=json.load(gzip.open('work/higher-stage-e8/verified/gcert1-e8-retimed.json.gz')) +def tau(x):return x^(43 if (x&43).bit_count()%2 else 0) +assert 43 .bit_count()%2==0 +assert set(map(tau,word['ports']))==set(old['ports']) +mapping={i:old['ports'].index(tau(q)) for i,q in enumerate(word['ports'])} +mapping.update({v+i:v+mapping[i] for i in range(v)}) +mapping.update({r:r for r in range(2*v,n)}) +def basis(vs): + b={} + for x in vs: + for k in sorted(b,reverse=True): + if x>>k&1:x^=b[k] + if x: + k=x.bit_length()-1 + for j in b: + if b[j]>>k&1:b[j]^=x + b[k]=x + return tuple(b[k] for k in sorted(b,reverse=True)) +def perp(x):return basis([z for z in range(1,512) if not (x&z).bit_count()%2]) +full=tuple(1<0 + edges.add((old,f));paid[delta]+=1;cur[r]=f +for part in ('A','B'): + if part=='B': + assert all(cur[r]==f for r,f in zip(can['centers'],can['center_frames'])) + assert all(cur[r]==tlev.get(r-v,0) for r in range(v,2*v)) # GK: targets sit at their level + for r_c,f in zip(can['centers'],can['center_frames']): + # GK: a centre copy descends cf -> served levels (descending chain) -> lowest served level; at the defaults the + # only served level is 0 and this is PR #433's single child of rank |cf| + served={tlev.get(e[1]-v,0) for e in can['cut'] if e[2]==r_c} + o=f + for Lv in sorted(served,key=lambda x:-len(frames[x])): + assert basis(frames[Lv]+frames[o])==tuple(frames[o]),('centre level outside the previous frame',r_c) + if Lv!=o: + paid[len(frames[o])-len(frames[Lv])]+=1 + if not(o==f and Lv==0):edges.add((o,Lv));edges.add((Lv,o)) # (cf,0),(0,cf) are added by the phase script + o=Lv + for e in can[part]: + rs=[e[1]]+([e[2]] if e[0]=='add' else []) + for r in rs:climb(r,e[-1]);incidences+=1 +for r,f in enumerate(can['final']):climb(r,f) +assert dict(paid)=={int(r):x for r,x in word['report']['local_profile'].items()} +# GK: entrances lower the helper climb by their rank; centre descents may stop above frame zero +if not word.get('start_extra') and not word.get('target_levels'):assert sum(r*x for r,x in paid.items())==9*can['R']+240*8+72 +else:assert sum(r*x for r,x in paid.items())==sum(int(r)*x for r,x in word['report']['local_profile'].items()) +can['local_profile']=dict(sorted(paid.items()));can['edges']=sorted(edges) +cp=OUT/'CANONICAL-WORD.json.gz';cp.write_bytes(gzip.compress(json.dumps(can,sort_keys=True,separators=(',',':')).encode(),mtime=0)) + +def engine(name): + p=Path('work/pr361/code/engines')/(name+'.py');s=importlib.util.spec_from_file_location('hamming_'+name,p) + m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m +M,M2=engine('moment'),engine('base_two_moment');m,W=73,word['report'].get('live',12720) # GK: unhosted stock of the word +HG={int(r):z for r,z in word['report']['global_profile'].items()} +root=M.certify(HG,m,W,True);b=Q(int(Q(root['lower'])*10**18),10**18);grid=Q(1,10**18) +assert M.moment(HG,m,W,b,True)[1]<1> i & 1)); a = q ^ (1 << z); order = list(range(L)); order[0], order[z] = order[z], order[0] + return [(1 << i) ^ (a if a >> i & 1 else 0) for i in order] + [1 << i for i in range(L, M)] + + +def audit_complex(t, parent_t, local_checks, widths, strict=False, charts=None): + """strict = PR #458's rule: at most one helper per physical family per invocation, spectators placed exactly. + charts = (ports, DATA-PHASES recipes) for the spectator chart.""" + R = len(widths) + assert t['local_programs'] == parent_t['local_programs'] and len(t['calls']) == 72 + prank = {} + for it in parent_t['idle_children']: prank.setdefault(it['child'], it['rank']) + stage_pair = {e['stage']: e['pair'] for e in t['recipe'] if e['kind'] == 'local'} + ev = []; side = {}; pairs = {} + for e in t['execution_schedule']: + if e['kind'] == 'local_cover_sweep': ev.append(('local', e['stage'], stage_pair[e['stage']])) + elif e['kind'] == 'bridge': ev.append(('bridge', e['dst'], e['src'])) + elif e['kind'] == 'idle_cover_sweep': + for sd, ch in enumerate(e['child_indices']): + if ch in prank: ev.append(('idle', ch, e['pair'])); side[ch] = sd; pairs[ch] = e['pair'] + W = wins(ev); hs = t['hosting'] + if strict: + assert hs.get('max_helpers_per_physical_family_per_call') == 1 + seen = {} # the children of one (pair, side) share their families: windows disjoint + for i in W: + for s_ in W[i]: + k = (pairs[i], side[i], s_); assert k not in seen, ('overlapping windows in one family group', k); seen[k] = i + used = defaultdict(set); hosted = {} + for i, port, off, w, s, h in hs['slots']: + assert w == widths[h] and s in W[i] and 0 <= off and off + w <= prank[i] and 0 <= port < V + cells = set(range(off, off + w)); assert not cells & used[i, port]; used[i, port] |= cells + assert (s, h) not in hosted; hosted[s, h] = (i, port, off, w) + rem = {} + for it in parent_t['idle_children']: rem[it['child'], it['port']] = it['rank'] - len(used[it['child'], it['port']]) + got = {(it['child'], it['port']): it['rank'] for it in t['idle_children']} + assert got == {k: r for k, r in rem.items() if r} and all(it['replicas'] == T for it in t['idle_children']) + LIVE = t['live']; occ = defaultdict(set); bw = {}; specs = []; foot = defaultdict(set) + for c in t['calls']: + s, rep, p = c['stage'], c['replica'], c['pair']; own = c['owners']; assert len(own) == 2 * V + R + if strict: # PR #458's rule on EVERY register class of the invocation (no register class is filtered out) + cnt = Counter(f for f, r in own) + for i_, (f, r) in enumerate(own): + assert f < LIVE, ('owner in the private namespace', f) # centres, reserved tableau and coefficient are never owners + if f < DATA: assert cnt[f] == 1, ('two helpers on one physical family in one invocation (data class)', s, rep) # active wires and hosted helpers of any width + elif i_ >= 2 * V and widths[i_ - 2 * V] < L: assert cnt[f] == 1, ('an entering helper shares its bank family in one invocation (bank class)', s, rep) + else: assert i_ >= 2 * V and r[0] == 2, ('bank class: helpers only', s, rep) # width-9 helpers share a pure bank as in #433 (no wrapper acts on them) + assert own[:2 * V] == next(q for q in parent_t['calls'] if (q['stage'], q['replica']) == (s, rep))['owners'][:2 * V] + for h, (f, r) in enumerate(own[2 * V:]): + w = widths[h] + if (s, h) in hosted: + i, port, off, w2 = hosted[s, h] + assert w2 == w and f == rep * 960 + (2 * pairs[i] + side[i]) * V + port and pairs[i] != p + if not strict: assert r[0] in (3, 4) and r[1:3] == [i, off] and (r[0] == 3 or w < L) # PR #442's rule: slot only (a spectator record, if any, is not read) + elif w == L: assert r == [3, i, off] + else: # exact host chart: residual vectors = pending[off:off+w] in B_q, spectators = the first unused indices + ports_, recipes = charts; B = idle_basis(ports_[port]); pend = [int(x) for x in recipes[port]['idle_children'][i]['orthogonal_axes']] + occ_ = [B.index(x) for x in pend[off:off + w]]; sp = [j for j in range(M) if j not in occ_][:L - w] + assert r == [4, i, off, w, sp] and len(set(occ_) | set(sp)) == L + else: + assert r[0] == 2 and DATA <= f < LIVE + if w == L: assert len(r) == 2; off = r[1] * L # [2, slot]: a width-9 residual of a pure width-9 bank (#433) + else: assert len(r) == 4 and r[2] == w and isinstance(r[3], list); off = r[1] # [2, offset, width, spectator cells]: a banked ENTERING residual + assert 0 <= off and off + w <= M + cells = set(range(off, off + w)); assert not cells & occ[f]; occ[f] |= cells; bw.setdefault(f, []).append((w, len(r) == 2)) + if w < L: specs.append((f, off, w, r[3])) + fp = cells | (set(r[3]) if w < L else set()) + if strict: assert len(fp) == L and not fp & foot[s, rep, f], ('footprints overlap on a bank family', s, rep, f); foot[s, rep, f] |= fp + banks = sorted(occ); assert banks == list(range(DATA, LIVE)) + if strict: # bank chart: the spectators of a banked entering helper are the first cells beyond every residual cell of the bank + for f, off, w, sp in specs: + n_ = len(occ[f]); assert occ[f] == set(range(n_)) and sp == list(range(n_, n_ + L - w)) and n_ + L - w <= M, ('bank spectators are not the first cells beyond the residuals', f) + pn = parent_t['private_namespace']; C_ = pn['centers'][1] - pn['centers'][0] # the private registers sit beyond the live stock and do not overlap it + assert t['physical'] == LIVE + C_ + R + 2 and t['private_namespace'] == {'centers': [LIVE, LIVE + C_], 'reserved_tableau': [LIVE + C_, LIVE + C_ + R], 'coefficient': [t['physical'] - 2, t['physical']]}, 'private namespace' + paid = Counter() + for c in t['calls']: + for r_, z in local_checks[c['orientation']]['paid_profile'].items(): paid[int(r_)] += z + for (ch, port), r_ in rem.items(): + if r_: paid[r_] += T + for f in banks: + pad = M - len(occ[f]); assert pad > 0 and occ[f] == set(range(len(occ[f]))) # packed from offset 0, rest is the pad + pure = all(w == L for w, _ in bw[f]); assert all(sh == (pure and w == L) for w, sh in bw[f]) and (pure or all(w < L for w, _ in bw[f])) # a bank holds only width-9 residuals (short route) or only entering ones + for part in split_pad(pad): paid[part] += 1 # a pad above 51 is paid as nested commuting children (73^2 > 2*child^2) + mass = sum(r * n for r, n in paid.items()); assert M * LIVE - mass == 2496 + assert M * M > 2 * max(paid) ** 2 + return paid, len(hosted) * T + + +def main(): + psc, cd, outp = map(Path, sys.argv[1:4]) + pct = json.loads(gzip.decompress((psc / 'GLOBAL-TEMPLATE.json.gz').read_bytes())) + can = json.loads(gzip.decompress((psc / 'CANONICAL-WORD.json.gz').read_bytes())) + widths = [L - len(can['frames'][can['start'][2 * V + i]]) for i in range(len(can['start']) - 2 * V)] + ct = json.loads(gzip.decompress((cd / 'GLOBAL-TEMPLATE.json.gz').read_bytes())) + ch = json.loads((cd / 'HOSTED.json').read_text()) + assert hashlib.sha256(gzip.decompress((cd / 'GLOBAL-TEMPLATE.json.gz').read_bytes())).hexdigest() == ch['template_sha256'] + lc = json.loads((psc / 'LOCAL-CHECKS.json').read_text()) + strict = '--one-helper-per-family' in sys.argv; sys.argv = [a for a in sys.argv if a != '--one-helper-per-family'] + charts = None + if strict: + ph = json.loads(Path('work/complex-nine-native/DATA-PHASES.json').read_text()); assert [p['q'] for p in ph['recipes']] == can['ports']; charts = (can['ports'], ph['recipes']) + cp, chh = audit_complex(ct, pct, lc, widths, strict, charts); assert cp == Counter({int(k): v for k, v in ch['global_profile'].items()}) + prank = {} + for it in pct['idle_children']: prank.setdefault(it['child'], it['rank']) + controls = []; skipped = [] + def reject(name, fn): + q = copy.deepcopy(ct); fn(q) + try: audit_complex(q, pct, lc, widths, strict, charts) + except (AssertionError, KeyError, IndexError, StopIteration): controls.append(name) + else: raise AssertionError('mutation accepted: ' + name) + sl0 = lambda q: q['hosting']['slots'][0] + reject('hosted residual outside its window', lambda q: sl0(q).__setitem__(4, next(s for s in range(9) if s not in q['hosting']['windows'][str(sl0(q)[0])][2]))) + reject('remainder child understated', lambda q: q['idle_children'][0].__setitem__('rank', q['idle_children'][0]['rank'] - 1)) + reject('dropped bank', lambda q: q.__setitem__('live', q['live'] - 1)) + reject('duplicated hosted residual', lambda q: q['hosting']['slots'].append(list(sl0(q)))) + reject('hosted width not the entrance width', lambda q: sl0(q).__setitem__(3, sl0(q)[3] + 1)) + def overlap(q): # two different residuals of one (child, port) forced onto the same coordinates + seen = {} + for sl in q['hosting']['slots']: + k = (sl[0], sl[1]) + if k in seen: sl[2] = seen[k][2]; return + seen[k] = sl + raise RuntimeError('no (child, port) with two residuals: control not applicable') + reject('overlapping hosted coordinates', overlap) + reject('hosted owner on the active pair', lambda q: q['calls'][0]['owners'].__setitem__(240 + next(h for h in range(len(widths)) if q['calls'][0]['owners'][240 + h][1][0] == 3), [0, [3, 0, 0]])) + reject('missing remainder child', lambda q: q['idle_children'].pop()) + if strict: + def share_family(q): # move a stage-s helper onto the family of another stage-s helper of the same child, at free coordinates + used_ = defaultdict(set); by = defaultdict(list) + for sl in q['hosting']['slots']: + used_[sl[0], sl[1]] |= set(range(sl[2], sl[2] + sl[3])); by[sl[0], sl[4]].append(sl) + for (i, s_), sls in by.items(): + for a in sls: + for sl in sls: + if sl is a or sl[1] == a[1]: continue + w = sl[3]; free = [o for o in range(0, prank[i] - w + 1) if not (set(range(o, o + w)) & used_[i, a[1]])] + if not free: continue + old_port = sl[1]; sl[1] = a[1]; sl[2] = free[0] + for c in q['calls']: + if c['stage'] == s_: + f0, r0 = c['owners'][2 * V + sl[5]] + c['owners'][2 * V + sl[5]] = [f0 + (a[1] - old_port), [3, i, sl[2]] if w == L else [4, i, sl[2], w, None]] + return a, sl + raise RuntimeError('control not applicable') + def refresh_remainders(q): # keep the remainder children consistent with the (mutated) slots + used_ = defaultdict(int) + for sl in q['hosting']['slots']: used_[sl[0], sl[1]] += sl[3] + q['idle_children'] = [dict(child=it['child'], port=it['port'], rank=it['rank'] - used_[it['child'], it['port']], hosted=used_[it['child'], it['port']], replicas=T) + for it in pct['idle_children'] if it['rank'] - used_[it['child'], it['port']] > 0] + q = copy.deepcopy(ct) + try: a, sl = share_family(q); refresh_remainders(q) + except RuntimeError: a = sl = None # no free coordinates in this word's hosting: control not applicable (recorded below) + if sl is not None: + if sl[3] < L: # complete the spectator record so that only the family rule is violated + ports_, recipes = charts + for c in q['calls']: + if c['stage'] == sl[4]: + f0, r0 = c['owners'][2 * V + sl[5]]; B = idle_basis(ports_[sl[1]]); pend = [int(x) for x in recipes[sl[1]]['idle_children'][sl[0]]['orthogonal_axes']] + occ_ = [B.index(x) for x in pend[sl[2]:sl[2] + sl[3]]]; r0[4] = [j for j in range(M) if j not in occ_][:L - sl[3]] + audit_complex(q, pct, lc, widths, False, charts) # the PR #442 rule accepts this template ... + try: audit_complex(q, pct, lc, widths, True, charts) + except AssertionError: controls.append('two helpers on one physical family in one invocation (accepted by the #442 rule, rejected here)') + else: raise AssertionError('mutation accepted: two helpers on one family') + else: skipped.append('two helpers on one physical family: no free coordinates to build the violation in this word') + def entering_owner(q): # (owner record of the first hosted entering helper in call 0) + return next(o for o in q['calls'][0]['owners'][2 * V:] if o[1][0] == 4) + def spectator_is_residual(q): + o = entering_owner(q); f = o[0]; i, off, w = o[1][1], o[1][2], o[1][3]; port = (f % 960) % V # family = rep*960 + (2*pair+side)*V + port + B = idle_basis(charts[0][port]); pend = [int(x) for x in charts[1][port]['idle_children'][i]['orthogonal_axes']] + o[1][4] = [B.index(pend[off])] + o[1][4][1:] + reject('a spectator coordinate that is a residual coordinate', spectator_is_residual) + reject('spectator coordinates shifted', lambda q: entering_owner(q)[1].__setitem__(4, [x + 1 for x in entering_owner(q)[1][4]])) + reject('spectator record dropped', lambda q: entering_owner(q)[1].__setitem__(slice(4, None), [])) + reject('entering helper routed without a spectator record', lambda q: entering_owner(q).__setitem__(1, [3, entering_owner(q)[1][1], entering_owner(q)[1][2]])) + reject('rule flag removed from the template', lambda q: q['hosting'].pop('max_helpers_per_physical_family_per_call')) + # ---- the rule on the other register classes: banks, the private namespace (centres, tableau, coefficient), copies (replicas), data wires + def reject_with(name, fn, must): + q = copy.deepcopy(ct); fn(q) + try: audit_complex(q, pct, lc, widths, strict, charts) + except (AssertionError, KeyError, IndexError, StopIteration) as e: + assert any(m_ in str(e) for m_ in must), (name, str(e)); controls.append(name) + else: raise AssertionError('mutation accepted: ' + name) + def banked_pos(q): # (call, index) of the first banked ENTERING owner + return next((c, i) for c in q['calls'] for i, o in enumerate(c['owners']) if i >= 2 * V and o[1][0] == 2 and len(o[1]) == 4) + def pack_banks_by_call(q): + """re-lay every entering bank of a stage so that eight entering helpers (their footprints are nine cells each) share a bank family, whatever their + replica: residuals packed from cell 0, the spectators of the bank's helpers in its pad (cells after the residuals), disjoint. The layout of + 'nine-cell bank slots': cell-level everything is valid (residuals packed from 0, pad recomputed, disjoint footprints); only the one-owner rule is + violated. RuntimeError when the stage cannot be re-laid on its own bank families.""" + for s_ in sorted({c['stage'] for c in q['calls']}): + items = [(c, i) for c in sorted((c for c in q['calls'] if c['stage'] == s_), key=lambda c: c['replica']) for i, o in enumerate(c['owners']) + if i >= 2 * V and o[1][0] == 2 and len(o[1]) == 4] + if not items: continue + fams = sorted({c['owners'][i][0] for c, i in items}); groups = [items[k:k + M // L] for k in range(0, len(items), M // L)] + if len(groups) != len(fams): raise RuntimeError('control not applicable') + for f0, grp in zip(fams, groups): + cells = sum(c['owners'][i][1][2] for c, i in grp); off = 0; spec = cells + for c, i in grp: + w = c['owners'][i][1][2]; c['owners'][i] = [f0, [2, off, w, list(range(spec, spec + L - w))]]; off += w; spec += L - w + if any(o[1][0] == 2 and len(o[1]) == 4 for c in ct['calls'] for o in c['owners'][2 * V:]): + q = copy.deepcopy(ct) + try: pack_banks_by_call(q) + except RuntimeError: q = None; skipped.append('two entering helpers on one bank family: the entering banks of this word cannot be re-laid eight per family') + if q is not None: + audit_complex(q, pct, lc, widths, False, charts) # the PR #442 rule accepts this layout (cells disjoint, spectators not read) ... + try: audit_complex(q, pct, lc, widths, True, charts) + except AssertionError as e: + assert 'bank class' in str(e), str(e); controls.append('two entering helpers on one bank family in one invocation, disjoint footprints, spectators in the pad (accepted by the #442 rule, rejected here)') + else: raise AssertionError('mutation accepted: two entering helpers on one bank family') + reject_with('a bank spectator that is a residual cell', lambda q: (lambda r: r.__setitem__(3, [r[1]]))(banked_pos(q)[0]['owners'][banked_pos(q)[1]][1]), ('footprints overlap', 'bank spectators')) + reject_with('bank spectator cells shifted', lambda q: (lambda r: r.__setitem__(3, [x + 1 for x in r[3]]))(banked_pos(q)[0]['owners'][banked_pos(q)[1]][1]), ('bank spectators',)) + reject_with('bank spectator count wrong', lambda q: (lambda r: r.__setitem__(3, r[3] * 2))(banked_pos(q)[0]['owners'][banked_pos(q)[1]][1]), ('bank spectators',)) + reject_with('bank spectator record dropped', lambda q: (lambda o: o.__setitem__(1, o[1][:3]))(banked_pos(q)[0]['owners'][banked_pos(q)[1]]), ('',)) + reject_with('a banked entering helper on an active data family', lambda q: (lambda c, i: c['owners'][i].__setitem__(0, c['owners'][0][0]))(*banked_pos(q)), ('data class',)) + reject_with('a bank owner in the private namespace (centres)', lambda q: (lambda c, i: c['owners'][i].__setitem__(0, q['live'] + 1))(*banked_pos(q)), ('private namespace', '')) + reject_with('a bank owner in the private namespace (reserved tableau)', lambda q: (lambda c, i: c['owners'][i].__setitem__(0, q['live'] + 16 + 5))(*banked_pos(q)), ('private namespace', '')) + else: skipped.append('bank controls: this word has no banked entering helper') + for bi in [i for i, e in enumerate(ct['execution_schedule']) if e['kind'] == 'bridge']: # copies: the children of one (pair, side) share their families + q = copy.deepcopy(ct); q['execution_schedule'].pop(bi) + try: audit_complex(q, pct, lc, widths, True, charts) + except AssertionError as e: + if 'overlapping windows' in str(e): controls.append('windows of two idle children of one family group overlap (a bridge removed from the schedule)'); break + else: skipped.append('windows of two idle children of one family group: no schedule mutation creates an overlap in this word') + reject_with('private namespace left at the parent\'s ranges', lambda q: q.__setitem__('private_namespace', pct['private_namespace']), ('private namespace',)) + reject_with('private namespace overlapping the live stock', lambda q: q['private_namespace'].__setitem__('centers', [q['live'] - 1, q['live'] + 15]), ('private namespace',)) + reject_with('hosted helper on the data family of another replica', lambda q: next(o for o in q['calls'][0]['owners'][2 * V:] if o[1][0] in (3, 4)).__setitem__(0, next(o for o in q['calls'][0]['owners'][2 * V:] if o[1][0] in (3, 4))[0] + 960), ('',)) + reject_with('active owner on the family of another replica', lambda q: q['calls'][0]['owners'][0].__setitem__(0, q['calls'][0]['owners'][0][0] + 960), ('',)) + reject_with('a second owner on an active data family', lambda q: q['calls'][0]['owners'].__setitem__(1, [q['calls'][0]['owners'][0][0], q['calls'][0]['owners'][1][1]]), ('data class',)) + res = dict(status='PASS_INDEPENDENT_HOSTING_AUDIT_WITH_ENTRANCE_WIDTHS', one_helper_per_family=strict, complex_template_sha256=ch['template_sha256'], + complex_profile={str(k): v for k, v in sorted(cp.items())}, complex_live=ct['live'], complex_hosted_residuals=chh, + complex_maxchild=max(cp), widths=dict(sorted(Counter(widths).items())), mutations_rejected=controls, controls_not_applicable=skipped) + outp.write_text(json.dumps(res, indent=2) + '\n'); print(json.dumps({k: v for k, v in res.items() if 'profile' not in k})) + + +if __name__ == '__main__': main() diff --git a/research/e8-complex-gauge-kernel/code/controls_gk.py b/research/e8-complex-gauge-kernel/code/controls_gk.py new file mode 100644 index 0000000000..135c1c3e24 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/controls_gk.py @@ -0,0 +1,127 @@ +"""Mutation controls for the kernel and gauge gates, with an independent in-memory checker. Apache-2.0. +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +usage: controls_gk.py GK_FULL-WORD.json.gz OUT.json +The checker (exact_ok) replays the explicit program precondition + compensation + main + cleanup on every column with arbitrary +helper dirt, forward and inverse-transpose, as audit_gk.py does, but shares no code with it or with gk_word.py except +`profile` (frame chains). Every control must be REJECTED; the unmutated word must be accepted.""" +import copy, gzip, json, sys +from fractions import Fraction as Q +from pathlib import Path +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from gk_common import V, FULL, basis +import gk_word as GW + + +def ap(e, rows): + if e[0] == 'scale': + q = Q(e[2], e[3]); rows[e[1]] = {j: q * x for j, x in rows[e[1]].items()} + else: + q = Q(e[3], e[4]); t, s = e[1], e[2] + for j, x in list(rows[s].items()): + z = rows[t].get(j, Q(0)) + q * x + if z: rows[t][j] = z + else: rows[t].pop(j, None) + + +def inv(e): + e = copy.deepcopy(e) + if e[0] == 'add': e[3] *= -1 + else: e[2], e[3] = e[3], e[2] + return e + + +def dual(e): + e = inv(e) + if e[0] == 'add': e[1], e[2] = e[2], e[1] + return e + + +def exact_ok(w): + """raises AssertionError unless the word is an exact arbitrary-dirt, inverse-transpose program with frame-legal compensation""" + R = w['report']['R']; n = 2 * V + R + ident = lambda: [{r: Q(1)} for r in range(n)] + A, B, cut, prec = w['A'], w['B'], w['cut'], w['precondition'] + main = A + cut + B + M = ident() + for e in main: ap(e, M) + dirty = [{} for _ in range(n)] + for r in range(V, 2 * V): dirty[r] = {j: x for j, x in M[r].items() if j >= 2 * V} + for e in prec: ap(e, dirty) + comp = [['add', r, j, -x.numerator, x.denominator, []] for r in range(V, 2 * V) for j, x in sorted(dirty[r].items())] + start = {int(r) for r in w.get('start_extra', {})} + assert not any(e[2] in start for e in comp), 'a helper with a frame-zero compensation must start at frame zero' + cleanup = [inv(e) for e in reversed(A + B) if not V <= e[1] < 2 * V] + program = list(prec) + comp + main + cleanup + actual = ident() + for e in program: ap(e, actual) + expected = ident() + for t in range(V): expected[V + t][t] = Q(1) + assert actual == expected, 'arbitrary-dirt exactness' + back = ident() + for e in program: ap(dual(e), back) + eb = ident() + for t in range(V): eb[t][V + t] = Q(-1) + assert back == eb, 'inverse-transpose exactness' + GW.profile(w) # frame chains, entrance containment, centre chains and levels + + +def controls(w): + out = [] + exact_ok(w) + def expect_reject(name, fn): + q = copy.deepcopy(w); fn(q) + try: exact_ok(q) + except (AssertionError, KeyError, StopIteration): out.append(name) + else: raise AssertionError('mutation accepted: ' + name) + kern = [i for i, e in enumerate(w['A']) if e[0] == 'add' and e[1] >= 2 * V and e[2] >= 2 * V and e[5] and e[-1] and str(e[2]) in w['start_extra']] + gaug = [i for i, e in enumerate(w['A']) if e[0] == 'add' and V <= e[1] < 2 * V and str(e[2]) in w['start_extra']] + assert kern and gaug, 'word has neither kernel nor gauge gates' + expect_reject('kernel: donor update omitted', lambda q: q['A'].pop(kern[0])) + expect_reject('kernel: donor update sign flipped', lambda q: q['A'][kern[0]].__setitem__(3, -q['A'][kern[0]][3])) + expect_reject('gauge: compensation gate omitted', lambda q: q['A'].pop(gaug[0])) + expect_reject('gauge: compensation coefficient doubled', lambda q: q['A'][gaug[0]].__setitem__(3, 2 * q['A'][gaug[0]][3])) + def bad_entrance(q): # entrance outside the helper's first frame (the gate frames are unchanged) + e = q['A'][gaug[0]]; h = str(e[2]); E = e[-1] + q['start_extra'][h] = [next(x for x in range(1, 512) if basis(E + [x]) != basis(E))] + expect_reject('gauge: entrance not inside the first frame of its gates', bad_entrance) + expect_reject('gauge: start_extra of a compensated helper without gauge or kernel', lambda q: q['start_extra'].__setitem__(str(2 * V + next(h for h in range(q['report']['R']) if str(2 * V + h) not in q['start_extra'])), [1])) + expect_reject('gauge: target level forgotten', lambda q: q['target_levels'].pop(next(iter(q['target_levels'])))) + def wrong_level(q): # a target level that its compensation gates do not produce + t = next(iter(q['target_levels'])); E = q['target_levels'][t] + q['target_levels'][t] = [next(x for x in range(1, 512) if basis(E + [x]) != basis(E))] + expect_reject('gauge: target level different from the compensation frame', wrong_level) + return out + + +def selection_controls(base, sel): + """structural controls on the selection itself (gk_word.build must refuse)""" + out = [] + GW.build(base, sel) + def refuse(name, fn): + q = copy.deepcopy(sel); fn(q) + try: GW.build(base, q) + except (AssertionError, KeyError, StopIteration): out.append(name) + else: raise AssertionError('selection accepted: ' + name) + h0 = next(iter(sel['gauge'])) + first = GW.first_frames(base) + refuse('gauge: entrance outside the first frame', lambda q: q['gauge'].__setitem__(h0, list(first[int(h0)]) + [next(x for x in range(1, 512) if basis(list(first[int(h0)]) + [x]) != basis(list(first[int(h0)])))])) + col = GW.responses(base) + def incomparable(q): # two entering helpers sharing a target with incomparable entrances + hs = [int(h) for h in q['gauge']] + for a in hs: + for b in hs: + if a < b and set(col[a]) & set(col[b]): + ea = basis(q['gauge'][str(a)]) + other = [x for x in GW.span(first[b]) if x and x not in GW.span(ea) and len(basis(ea)) == 1 and basis([x]) != ea] + if other: q['gauge'][str(b)] = [other[0]]; return + raise RuntimeError('control not applicable') + refuse('gauge: non-nested entrances at one target', incomparable) + c0 = sel['kernel'][0] + refuse('kernel: pivot outside the donor span', lambda q: q['kernel'][0].__setitem__('donors', q['kernel'][0]['donors'][:-1]) if len(c0['donors']) > 1 and GW.solve_relation(col, c0['donors'][:-1], c0['pivots'][0]) is None else (_ for _ in ()).throw(RuntimeError('control not applicable'))) + refuse('kernel: entrance outside a donor first frame', lambda q: q['kernel'][0].__setitem__('E', [next(x for x in range(1, 512) if x not in GW.span(first[c0['donors'][0]]))])) + return out + + +if __name__ == '__main__': + w = json.load(gzip.open(sys.argv[1])); res = controls(w) + Path(sys.argv[2]).write_text(json.dumps(dict(status='PASS_GAUGE_KERNEL_MUTATION_CONTROLS', rejected=res), indent=2) + '\n'); print(len(res), 'controls rejected') diff --git a/research/e8-complex-gauge-kernel/code/controls_hosting.py b/research/e8-complex-gauge-kernel/code/controls_hosting.py new file mode 100644 index 0000000000..8907924d6c --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/controls_hosting.py @@ -0,0 +1,84 @@ +"""Mutation controls of the one-owner rule on EVERY register class, run through the generating scripts (hosted_gk.py, integrate_gk.py). Apache-2.0. +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +usage: controls_hosting.py VARIANT_WORKDIR SELECTION.json KEY OUT.json (cwd = VARIANT_WORKDIR, as the inherited scripts expect) +Register classes of one invocation: active data wires, hosted helpers (data families), banked helpers (bank families), the private namespace +(centres, reserved tableau, coefficient), copies (replicas). The rule: an entering helper is the only owner of its physical family in the invocation; +a family of the data class has one owner; nothing is owned in the private namespace. +(a) the generator's rule function `hosted_gk.one_helper_rule` is run on mutated owner arrays of a real invocation, one mutation per class; +(b) the whole hosting generator is run with a bank tiling that puts eight entering helpers of ONE invocation on one bank family, each with a disjoint + 9-cell footprint (8 residual cells and a spectator in the pad): hosted_gk.py must refuse it, while the unmutated tiling must be accepted; +(c) the parent-template generator integrate_gk.py is run on the same mutated tiling and must refuse it. +(The independent audit has its own controls for the same layout in audit_hosted_gk.py, and replay_gk.py for the parent template.)""" +import copy, gzip, json, os, runpy, shutil, sys, tempfile +from collections import Counter +from pathlib import Path +CODE = Path(__file__).resolve().parent; sys.path.insert(0, str(CODE)) +import gk_common as GC +import hosted_gk as HG +work = Path(sys.argv[1]).resolve(); selp = Path(sys.argv[2]).resolve(); key = sys.argv[3]; outp = Path(sys.argv[4]).resolve() +os.chdir(work) +V, L, M, DATA = GC.V, GC.L, GC.M, GC.DATA +can = json.load(gzip.open('split-centres/CANONICAL-WORD.json.gz')); R = can['R'] +widths = [L - len(can['frames'][can['start'][2 * V + i]]) for i in range(R)] +hosted = json.loads(gzip.decompress((work / 'hosted/GLOBAL-TEMPLATE.json.gz').read_bytes())); W = hosted['live'] +call = next(c for c in hosted['calls'] if any(o[1][0] == 2 and len(o[1]) == 4 for o in c['owners'][2 * V:])) # an invocation with banked entering helpers +good = call['owners']; HG.one_helper_rule(good, widths, W) +out = [] +def refused(name, fn, must): + o = copy.deepcopy(good); fn(o) + try: HG.one_helper_rule(o, widths, W) + except AssertionError as e: + assert must in str(e), (name, str(e)); out.append(dict(control=name, rejected_by='hosted_gk.one_helper_rule', message=str(e)[:100])) + else: raise AssertionError('accepted by the generator rule: ' + name) +ent = [i for i in range(2 * V, 2 * V + R) if good[i][1][0] == 2 and len(good[i][1]) == 4]; a, b = ent[0], ent[1] +host_ = [i for i in range(2 * V, 2 * V + R) if good[i][1][0] in (3, 4)] +def join(o): # bank class: b joins a's bank family at the next free cells with a spectator of its own + fa = o[a][0]; free = 64; o[b] = [fa, [2, free, widths[b - 2 * V], [free + widths[b - 2 * V]]]] +refused('bank class: two entering helpers on one bank family', join, 'shares its bank family') +refused('bank class: spectator is a residual cell of its own helper', lambda o: o[a][1].__setitem__(3, [o[a][1][1]]), 'footprints overlap') +refused('bank class: an active data wire on a bank family', lambda o: o.__setitem__(3, [DATA, [1, 0, 3]]), 'bank family owned by a non-helper') +refused('data class: two hosted helpers on one data family', lambda o: o.__setitem__(host_[1], [o[host_[0]][0], o[host_[1]][1]]), 'two owners on one data family') +refused('data class: a hosted helper on an active data family', lambda o: o.__setitem__(host_[0], [o[0][0], o[host_[0]][1]]), 'two owners on one data family') +refused('private namespace: a bank owner in the centres', lambda o: o.__setitem__(a, [W + 3, o[a][1]]), 'private namespace') +refused('private namespace: a bank owner in the reserved tableau', lambda o: o.__setitem__(a, [W + len(can['centers']) + 5, o[a][1]]), 'private namespace') +refused('private namespace: a bank owner at the coefficient registers', lambda o: o.__setitem__(a, [hosted['physical'] - 1, o[a][1]]), 'private namespace') +# ---- (b), (c): a tiling with eight entering helpers of one invocation per bank family +def packed_tile(items): + """the layout of 'nine-cell bank slots': entering helpers in replica order, as many per bank family as fit with a disjoint spectator cell each + (eight residuals of width 8 and eight spectators in the pad of 9), whatever their replica""" + wide = [x for x in items if x[2] == L]; ent_ = [x for x in items if x[2] < L] + assign, nb, pads = saved(wide) if wide else ({}, 0, Counter()) + if not ent_: return assign, nb, pads + pads = Counter(pads); banks = [] + for x in ent_: # every footprint is nine cells (w residual + 9 - w spectators), so a bank takes M // 9 = 8 of them + if not banks or len(banks[-1]) == M // L: banks.append([]) + banks[-1].append(x) + for bk, mem in enumerate(banks): + cells = sum(y[2] for y in mem); off = 0; spec = cells + for rep, h, w in mem: + assign[(rep, h)] = (nb + bk, off, w, False, tuple(range(spec, spec + L - w))); off += w; spec += L - w + assert spec <= M + for part in GC.split_pad(M - cells): pads[part] += 1 + return assign, nb + len(banks), pads +saved = GC.tile +tmpd = Path(tempfile.mkdtemp(prefix='gkhost-', dir=work)) +try: + HG.ONEPER = True; HG.SELECTION = str(selp); HG.KEY = key; HG.DISCOVER = False; HG.DISCOVER_TO = None + HG.tile = saved; HG.main(Path('split-centres'), tmpd / 'ok') # the real tiling is accepted + HG.tile = packed_tile + try: HG.main(Path('split-centres'), tmpd / 'packed') + except AssertionError as e: + assert 'shares its bank family' in str(e), str(e); out.append(dict(control='hosting generator: eight entering helpers of one invocation on one bank family', rejected_by='hosted_gk.py', message=str(e)[:100])) + else: raise AssertionError('hosted_gk.py accepted the packed bank tiling') +finally: HG.tile = saved +# parent template generator, in a throw-away copy of the variant directory +t2 = tmpd / 'parent'; t2.mkdir(); os.symlink(work / 'work', t2 / 'work'); shutil.copytree(work / 'split-centres', t2 / 'split-centres'); shutil.copy(work / 'BIT-PRICE.json', t2 / 'BIT-PRICE.json') +GC.tile = packed_tile; os.chdir(t2) +try: + try: runpy.run_path(str(CODE / 'integrate_gk.py'), run_name='__main__') + except AssertionError as e: + assert 'shares its bank family' in str(e), str(e); out.append(dict(control='parent template generator: eight entering helpers of one invocation on one bank family', rejected_by='integrate_gk.py', message=str(e)[:100])) + else: raise AssertionError('integrate_gk.py accepted the packed bank tiling') +finally: GC.tile = saved; os.chdir(work) +shutil.rmtree(tmpd, ignore_errors=True) +outp.write_text(json.dumps(dict(status='PASS_ONE_OWNER_RULE_CONTROLS_ON_EVERY_REGISTER_CLASS', controls=out), indent=1) + '\n'); print(len(out), 'generator controls rejected') diff --git a/research/e8-complex-gauge-kernel/code/controls_pipeline.py b/research/e8-complex-gauge-kernel/code/controls_pipeline.py new file mode 100644 index 0000000000..02ecc1326c --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/controls_pipeline.py @@ -0,0 +1,71 @@ +"""Mutation controls that run through the CERTIFYING scripts (audit_gk.py, emit_gk.py). Apache-2.0. +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +usage: controls_pipeline.py VARIANT_WORKDIR SELECTION.json OUT.json +Every control writes a mutated FULL-WORD.json.gz into a fresh copy of the variant's split-centres directory and runs audit_gk.py then +emit_gk.py there; the pair must FAIL (nonzero exit). The unmutated word must pass. The selection-level words are built with +gk_word.build(check=False), so the structural assertions of the builder are NOT what rejects them.""" +import copy, gzip, json, os, shutil, subprocess, sys, tempfile +from pathlib import Path +CODE = Path(__file__).resolve().parent; sys.path.insert(0, str(CODE)) +import gk_word as GW +from gk_common import V, basis +work = Path(sys.argv[1]).resolve(); sel = json.loads(Path(sys.argv[2]).read_text()) +base = json.load(gzip.open(work / 'sc_base/FULL-WORD.json.gz')) +good = json.load(gzip.open(work / 'split-centres/FULL-WORD.json.gz')) +env = dict(os.environ, PYTHONDONTWRITEBYTECODE='1'); env.pop('PYTHONOPTIMIZE', None) +def run_pair(word): + tmp = Path(tempfile.mkdtemp(prefix='gkctl-', dir=work)) + try: + os.symlink(work / 'work', tmp / 'work'); shutil.copytree(work / 'sc_base', tmp / 'split-centres') + (tmp / 'split-centres/FULL-WORD.json.gz').write_bytes(GW.dump(word)) + for script in ('audit_gk.py', 'emit_gk.py'): + q = subprocess.run([sys.executable, '-B', str(CODE / script)], cwd=tmp, env=env, capture_output=True, text=True) + if q.returncode: return script, (q.stderr.strip().splitlines() or ['?'])[-1][:160] + return None, '' + finally: shutil.rmtree(tmp, ignore_errors=True) +assert run_pair(good) == (None, ''), 'the unmutated word must pass the certifying scripts' +out = [] +def expect_fail(name, word, must=None): + script, msg = run_pair(word) + assert script is not None, ('mutation accepted by the certifying scripts: ' + name) + if must: assert must in msg, (name, msg) + out.append(dict(control=name, rejected_by=script, message=msg)) +def mut(fn): + w = copy.deepcopy(good); fn(w); return w +kern = next(i for i, e in enumerate(good['A']) if e[0] == 'add' and e[1] >= 2 * V and e[2] >= 2 * V and str(e[2]) in good['start_extra']) +gaug = next(i for i, e in enumerate(good['A']) if e[0] == 'add' and V <= e[1] < 2 * V and str(e[2]) in good['start_extra']) +expect_fail('kernel: donor update omitted', mut(lambda w: w['A'].pop(kern))) +expect_fail('kernel: donor update sign flipped', mut(lambda w: w['A'][kern].__setitem__(3, -w['A'][kern][3]))) +expect_fail('gauge: compensation gate omitted', mut(lambda w: w['A'].pop(gaug))) +expect_fail('gauge: compensation coefficient doubled', mut(lambda w: w['A'][gaug].__setitem__(3, 2 * w['A'][gaug][3]))) +def bad_entrance(w): + e = w['A'][gaug]; E = e[-1]; w['start_extra'][str(e[2])] = [next(x for x in range(1, 512) if basis(E + [x]) != basis(E))] +expect_fail('gauge: entrance outside the frame of its gates', mut(bad_entrance)) +expect_fail('helper with a frame-zero compensation given an entrance', mut(lambda w: w['start_extra'].__setitem__(str(2 * V + next(h for h in range(w['report']['R']) if str(2 * V + h) not in w['start_extra'])), [1]))) +# ---- register classes other than helpers: a data or target register has #433's own start frame and adapter; a helper-style entrance (start_extra: residual wrapper, +# spectators, bank footprint) is defined for helper registers only +expect_fail('helper-style entrance given to a data register', mut(lambda w: w['start_extra'].__setitem__('3', [1, 2][:1]))) +expect_fail('helper-style entrance given to a target register', mut(lambda w: w['start_extra'].__setitem__(str(V + 3), [1]))) +expect_fail('target level forgotten', mut(lambda w: w['target_levels'].pop(next(iter(w['target_levels']))))) +# ---- centre chain broken: two entering helpers a, b whose targets share a centre, b's entrance replaced by an incomparable line that is +# otherwise legal (inside b's frames); the word is built without the builder's structural checks, and `profile` (a second checker) +# is used only to find the case: the certifying script must reject it by its own centre-chain assertion. +col = GW.responses(base); first = GW.first_frames(base) +gh = sorted(int(h) for h in sel['gauge']); done = False +for b in gh: + if done: break + for x in sorted(GW.span(first[b])): + if not x or done: continue + E0 = basis(sel['gauge'][str(b)]) + if basis([x]) == E0 or len(E0) != 1: continue + for a in gh: + if a == b or set(col[a]) & set(col[b]): continue + sel2 = {'gauge': {str(a): sel['gauge'][str(a)], str(b): [x]}} + w = GW.build(base, sel2, check=False) + try: GW.profile(w) + except AssertionError as e: + if 'served levels must descend' not in str(e): continue + else: continue + expect_fail('centre levels not a chain (word built without the builder\'s structural checks)', w, 'centre level outside the previous frame'); done = True; break +assert done, 'no centre-chain control available' +Path(sys.argv[3]).write_text(json.dumps(dict(status='PASS_CERTIFYING_PIPELINE_MUTATION_CONTROLS', controls=out), indent=1) + '\n'); print(len(out), 'controls rejected by the certifying scripts') diff --git a/research/e8-complex-gauge-kernel/code/controls_sel.py b/research/e8-complex-gauge-kernel/code/controls_sel.py new file mode 100644 index 0000000000..183a72ab12 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/controls_sel.py @@ -0,0 +1,8 @@ +"""Selection-level mutation controls. usage: controls_sel.py BASE_FULL-WORD.json.gz SELECTION.json OUT.json (Apache-2.0)""" +import gzip, json, sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).resolve().parent)) +import controls_gk as C +base = json.load(gzip.open(sys.argv[1])); sel = json.loads(Path(sys.argv[2]).read_text()) +res = C.selection_controls(base, sel) +Path(sys.argv[3]).write_text(json.dumps(dict(status='PASS_SELECTION_MUTATION_CONTROLS', refused=res), indent=2) + '\n'); print(len(res), 'selection controls refused') diff --git a/research/e8-complex-gauge-kernel/code/emit_gk.py b/research/e8-complex-gauge-kernel/code/emit_gk.py new file mode 100644 index 0000000000..0dd1853bb5 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/emit_gk.py @@ -0,0 +1,156 @@ +# GK: modified copy of PR #433's complex_emit.py (icekylinx with Codex assistance; PR #425) by DreamingOfClouds with Claude Opus 5.5 +# (Anthropic), via Claude Code. Every change is marked "GK:". On a word without start_extra / target_levels the behaviour +# and every written file equal PR #433's (regression anchor in verify.py). +import sys as _sys, os as _os; _sys.path.insert(0, _os.path.dirname(_os.path.abspath(__file__))) +# Adapted from PR425 by icekylinx with Codex assistance. +"""Emit both local programs, integrate the fixed nine-stage geometry, and bill. + +The expanded scalar interface is justified in PROOF.txt. This script does not +claim a Lean proof or discharge the inherited all-size/analytic interfaces. +""" +import copy,gzip,hashlib,importlib.util,json,math +from collections import Counter +from fractions import Fraction as Q +from pathlib import Path + +OUT=Path('split-centres');cp=OUT/'CANONICAL-WORD.json.gz' +c=json.load(gzip.open(cp)) +frames=c['frames'];v,R,h=c['v'],c['R'],c['h'];n=2*v+R +def digest(x):return hashlib.sha256(json.dumps(x,sort_keys=True,separators=(',',':')).encode()).hexdigest() +def basis(vs): + b={} + for x in vs: + for p in sorted(b,reverse=True): + if x>>p&1:x^=b[p] + if x: + p=x.bit_length()-1 + for q in b: + if b[q]>>p&1:b[q]^=x + b[p]=x + return tuple(b[p] for p in sorted(b,reverse=True)) +def dual(e): + e=list(e) + if e[0]=='add':e[1],e[2]=e[2],e[1];e[3]*=-1 + else:e[2],e[3]=e[3],e[2] + return e +def scalar(e,back): + e=dual(e) if back else list(e) + if e[0]=='add':return ['add',['L',e[1]],['L',e[2]],e[3],e[4]] + return ['scale',['L',e[1]],e[2],e[3]] +def primitive_bound(e): + if e[0] in ('clear','copy'):return 1 + q=Q(e[3],e[4]) if e[0]=='add' else Q(e[2],e[3]) + a,b=abs(q.numerator),q.denominator + assert b&(b-1)==0 + if e[0]=='scale': + assert a&(a-1)==0 + return abs(a.bit_length()-b.bit_length())+int(q<0) + # Exact binary Horner multiplication on a cleared private stream, repeated + # halving, signed accumulation into the target, then clear the private stream. + return 3+(a.bit_length()-1)+a.bit_count()+(b.bit_length()-1) + +def emit(back): + out=[];cur=c['start'].copy() + def event(e):out.append(e) + def scal(e,f):event(['scalar',e,f]) + event(['phase','zero_frame_precondition']) + for e in c['precondition']+c['compensation']: + regs=[e[1]]+([e[2]] if e[0]=='add' else []) + assert all(c['start'][r]==0 for r in regs) + scal(scalar(e,back),0) + event(['phase','entry_adapters']) + # GK: a helper that starts at a nonzero entrance frame has NO entry adapter; its paid wrapper R_E^-1 (Lemma A) precedes every gate + # that touches it and L_E^-1 follows the full-frame cleanup. Words without entrances emit PR #433's events. + entering=[r for r,f in enumerate(c['start']) if r>=2*v and f!=0] + for r,f in enumerate(c['start']): + if r in entering:event(['residual_adapter','pre',r,f]) + else:event(['adapter','old_to_new',r,f]) + def climb(r,f,part): + old=cur[r] + if old==f:return + assert basis(frames[old]+frames[f])==tuple(frames[f]) + rank=len(frames[f])-len(frames[old]);assert rank>0 + event(['climb',part,r,old,f,rank]);cur[r]=f + for part in ('A','centers','B','final'): + event(['phase',part]) + if part in ('A','B'): + for e in c[part]: + regs=[e[1]]+([e[2]] if e[0]=='add' else []) + for r in regs:climb(r,e[-1],part) + scal(scalar(e,back),e[-1]) + elif part=='centers': + # GK: targets sit at their nonzero-frame-compensation level (0 at the defaults); a centre copy descends + # cf -> served levels (descending chain) -> lowest served level and scatters into each target at its level + lv=lambda r:c.get('target_levels',{}).get(str(r-v),0) + assert all(cur[r]==lv(r) for r in range(v,2*v)) + for k,r in enumerate(c['centers']): + cf=c['center_frames'][k];assert cur[r]==cf + terms=[e for e in c['cut'] if e[2]==r] + path=[cf]+sorted({lv(e[1]) for e in terms}-{cf},key=lambda x:-len(frames[x])) + C=['C',k] + if not back: + scal(['clear',C],cf);scal(['copy',C,['L',r]],cf) + for a in range(len(path)): + if a>0:event(['center',k,path[a-1],path[a],len(frames[path[a-1]])-len(frames[path[a]])]) + for e in terms: + if lv(e[1])==path[a]:scal(['add',['L',e[1]],C,e[3],e[4]],path[a]) + scal(['clear',C],path[-1]) + else: + scal(['clear',C],path[-1]) + for a in range(len(path)-1,-1,-1): + for e in terms: + if lv(e[1])==path[a]:scal(['add',C,['L',e[1]],e[3],e[4]],path[a]) + if a>0:event(['center',k,path[a],path[a-1],len(frames[path[a-1]])-len(frames[path[a]])]) + scal(['add',['L',r],C,-1,1],cf);scal(['clear',C],cf) + else: + for r,f in enumerate(c['final']):climb(r,f,part) + event(['phase','exit_adapters']) + for r,f in enumerate(c['final']):event(['adapter','new_to_old',r,f]) + event(['phase','full_frame_cleanup']) + for e in c['cleanup']: + regs=[e[1]]+([e[2]] if e[0]=='add' else []) + assert all(c['final'][r]==1 for r in regs) + scal(scalar(e,back),1) + for r in entering:event(['residual_adapter','post',r,c['start'][r]]) # GK: L_E^-1 after the full-frame cleanup + event(['phase','done']) + return out + +def check_local(events,back): + # Literal scalar replay of the emitted stream, including center lifetimes. + state={('L',r):{r:Q(1)} for r in range(n)};live=[];paid=Counter();prims=0;macros=0 + for e in events: + if e[0]=='climb':assert not live;paid[e[5]]+=1 + elif e[0]=='center':assert live==[e[1]];paid[e[4]]+=1 + elif e[0]=='scalar': + op=e[1];tag=op[0];t=tuple(op[1]);macros+=1;prims+=2*primitive_bound(op) + if tag=='clear': + state[t]={} + if t[0]=='C' and t[1] in live:live.remove(t[1]) + elif tag=='copy':state[t]=dict(state.get(tuple(op[2]),{}));live.append(t[1]) + elif tag=='scale':state[t]={j:Q(op[2],op[3])*x for j,x in state[t].items()} + else: + s=tuple(op[2]);q=Q(op[3],op[4]);row=state.setdefault(t,{}) + if t[0]=='C' and t[1] not in live:live.append(t[1]) + for j,x in list(state.get(s,{}).items()): + z=row.get(j,Q(0))+q*x + if z:row[j]=z + else:row.pop(j,None) + assert not live and all(not row for r,row in state.items() if r[0]=='C') + for r in range(n): + expected={r:Q(1)} + if back and r> p & 1: x ^= b[p] + if x: + p = x.bit_length() - 1 + for q in b: + if b[q] >> p & 1: b[q] ^= x + b[p] = x + return tuple(b[p] for p in sorted(b, reverse=True)) + + +def widths_of(word): + """residual width of every helper: 9 - dim(entrance frame); 9 when the word has no extension""" + R = word['report']['R'] if 'R' not in word else word['R'] + w = [L] * R + for r, E in word.get('start_extra', {}).items(): + assert 2 * V <= int(r) < 2 * V + R + w[int(r) - 2 * V] = L - len(basis(E)) + return w + + +def split_pad(p): + """a pad of rank p is paid as nested commuting children of rank <= 51 (so that 73^2 > 2*child^2); rank 1 stays 1""" + if p == 0: return [] + n = -(-p // 51); return [p // n + (1 if i < p % n else 0) for i in range(n)] + + +def tile(items): + """Bank tiling of unhosted residuals. items: list of (rep, helper, width); a bank has M = 73 cells. + * width-9 residuals (no wrapper acts on them): first fit in the given order, packed from offset 0, eight per bank, pad rank 1 + (PR #433/#442's tiling and routes [2, slot]); + * ENTERING residuals (width w < 9, paid wrappers, e = 9 - w spectators): banks of their own in which every entering helper is the ONLY + owner of its bank family in its invocation (the one-helper rule of PR #458 extended to banks): bank j holds the j-th entering + helper of each replica, residuals packed from offset 0 in replica order (at most one helper per replica, hence per invocation). + The spectators of an entering helper are the first e cells of the bank beyond every residual cell of the bank (the pad, which no call + uses for a residual, is paid as before: rank 73 - sum of widths; the spectators are borrowed inside it and not deducted). + Returns (assign, banks, pads): assign[(rep, helper)] = (bank, offset, width, pure, spectators) with pure = the bank holds only width-9 + residuals and spectators = () for width 9; pads = Counter of pad ranks (split into children of rank <= 51).""" + assign = {}; pads = Counter(); fill = [] + for z, (rep, h, w) in enumerate(items): # width 9: first fit, as PR #433 (all widths 9 reproduces it exactly) + if w != L: continue + for b, f in enumerate(fill): + if f + w <= M: break + else: + b = len(fill); fill.append(0) + assign[(rep, h)] = (b, fill[b], w, True, ()); fill[b] += w + nwide = len(fill); byrep = {} + for rep, h, w in items: + if w < L: byrep.setdefault(rep, []).append((h, w)) + cells = [0] * max((len(v) for v in byrep.values()), default=0); emax = [0] * len(cells); place = {} + for rep in sorted(byrep): # the j-th entering helper of every replica goes to entering bank j + for j, (h, w) in enumerate(byrep[rep]): + place[(rep, h)] = (nwide + j, cells[j], w); cells[j] += w; emax[j] = max(emax[j], L - w) + for j in range(len(cells)): assert cells[j] + emax[j] <= M, ('entering bank without room for its spectators', j) + for (rep, h), (b, off, w) in place.items(): + assign[(rep, h)] = (b, off, w, False, tuple(range(cells[b - nwide], cells[b - nwide] + L - w))) + fill += cells + for f in fill: + for part in split_pad(M - f): pads[part] += 1 + return assign, len(fill), pads + + +def route(off, w, pure, sp=()): + """owner route of a banked helper residual: PR #433's [2, slot] for width 9 (pure width-9 bank); an entering helper (w < 9) is + [2, offset, width, [spectator cells]] with e = 9 - w spectators""" + if w == L: assert pure and not sp; return [2, off // L] + assert not pure and len(sp) == L - w; return [2, off, w, list(sp)] + + +def unhosted_stock(widths): + """live stock and padding histogram of the unhosted (parent) template, per stage x nine""" + R = len(widths) + _, nb, pads = tile([(rep, h, widths[h]) for rep in range(T) for h in range(R)]) + return DATA + L * nb, Counter({r: z * L for r, z in pads.items()}) diff --git a/research/e8-complex-gauge-kernel/code/gk_word.py b/research/e8-complex-gauge-kernel/code/gk_word.py new file mode 100644 index 0000000000..15782ba625 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/gk_word.py @@ -0,0 +1,194 @@ +"""Apply a frozen selection (shared-donor kernel + entrance gauges) to PR #433's complex word. Apache-2.0. +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +usage: gk_word.py BASE_FULL-WORD.json.gz SELECTION.json OUT_FULL-WORD.json.gz +An empty selection ({}) copies the input byte for byte (regression anchor). + +selection = {"kernel": [{"E": [x], "donors": [h..], "pivots": [h..]}..], "gauge": {"h": [x..]}} (h = helper index 0..R-1) +Kernel (PR #417/#435/#434/#440): a pivot starts at E; every donor receives donor += -q * pivot at frame E before the main +word, where col(pivot) = sum q_d col(d) are the exact dirty-response columns; the pivot's frame-zero compensation vanishes. +Gauge (#401/#408-#416): the compensation target += -C[t,h] * helper of helper h is executed at frame E_h as the first gates +of the main word; h starts at E_h and its targets climb to the level L_t = largest E over their entering helpers. +The exact verification is the arbitrary-dirt replay of audit_gk.py; this module also checks the structural conditions.""" +import copy, gzip, hashlib, json, sys +from collections import Counter, defaultdict +from fractions import Fraction as Q +from pathlib import Path +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from gk_common import * + + +def apply_op(e, rows): + if e[0] == 'scale': + _, t, a, b, *_ = e; q = Q(a, b); rows[t] = {j: q * x for j, x in rows[t].items()} + else: + _, t, s, a, b, *_ = e; q = Q(a, b) + for j, x in list(rows[s].items()): + z = rows[t].get(j, Q(0)) + q * x + if z: rows[t][j] = z + else: rows[t].pop(j, None) + + +def inverse(e, F): + e = copy.deepcopy(e) + if e[0] == 'add': e[3] *= -1 + else: e[2], e[3] = e[3], e[2] + e[-1] = list(F); return e + + +def responses(word): + """dirty-response columns col[h] = {target: coefficient} of the unmodified word (after the frame-zero preconditioner)""" + R = word['report']['R']; n = 2 * V + R + rows = [{r: Q(1)} for r in range(n)] + for e in word['A'] + word['cut'] + word['B']: apply_op(e, rows) + dirty = [{} for _ in range(n)] + for r in range(V, 2 * V): dirty[r] = {j: x for j, x in rows[r].items() if j >= 2 * V} + for e in word['precondition']: apply_op(e, dirty) + col = [{} for _ in range(R)] + for r in range(V, 2 * V): + for j, x in dirty[r].items(): col[j - 2 * V][r - V] = x + return col + + +def first_frames(word): + first = {} + for seq in (word['A'], word['B']): + for e in seq: + F = basis(e[-1]) + for r in [e[1]] + ([e[2]] if e[0] == 'add' else []): + if r >= 2 * V: first.setdefault(r - 2 * V, F) + return first + + +def solve_relation(col, donors, p): + """exact rational c with col[p] = sum_d c_d col[d]; None if p is not in the span""" + ts = sorted({t for d in donors for t in col[d]} | set(col[p])) + idx = {t: i for i, t in enumerate(ts)} + Mx = [[Q(0)] * (len(donors) + 1) for _ in ts] + for ci, d in enumerate(donors): + for t, x in col[d].items(): Mx[idx[t]][ci] = x + for t, x in col[p].items(): Mx[idx[t]][-1] = x + piv = []; r = 0 + for c in range(len(donors)): + pr = next((i for i in range(r, len(Mx)) if Mx[i][c]), None) + if pr is None: continue + Mx[r], Mx[pr] = Mx[pr], Mx[r]; q = Mx[r][c]; Mx[r] = [x / q for x in Mx[r]] + for i in range(len(Mx)): + if i != r and Mx[i][c]: + f = Mx[i][c]; Mx[i] = [a - f * b for a, b in zip(Mx[i], Mx[r])] + piv.append(c); r += 1 + if any(Mx[i][-1] for i in range(r, len(Mx))): return None + assert r == len(donors), 'donors must have independent response columns' + return {donors[c]: Mx[i][-1] for i, c in enumerate(piv) if Mx[i][-1]} + + +def span(U): + s = {0} + for b in U: s |= {x ^ b for x in s} + return s + + +def perp(x): return basis([z for z in range(1, 512) if not (x & z).bit_count() % 2]) + + +def profile(word): + """local paid profile of a gk word by direct simulation of the frame chains (second implementation: audit_gk.py)""" + R = word['report']['R']; n = 2 * V + R; P = word['ports'] + cur = {} + for r in range(n): + cur[r] = (P[r],) if r < V else ((basis(word['start_extra'][str(r)]) if str(r) in word.get('start_extra', {}) else ()) if r >= 2 * V else ()) + paid = Counter() + def climb(r, F): + F = basis(F); o = cur[r] + assert basis(list(o) + list(F)) == F, ('frame violation', r, o, F) + if o != F: paid[len(F) - len(o)] += 1; cur[r] = F + lev = {int(t): basis(E) for t, E in word.get('target_levels', {}).items()} + for seq, part in ((word['A'], 'A'), (word['B'], 'B')): + if part == 'B': + for r, f in zip(word['centers'], word['center_frames']): + assert cur[r] == basis(f), 'centre frame' + served = sorted({lev.get(e[1] - V, ()) for e in word['cut'] if e[2] == r}, key=lambda E: -len(E)) + o = basis(f) + for Lv in served: + assert span(Lv) <= span(o), 'served levels must descend inside the centre frame' + if Lv != o: paid[len(o) - len(Lv)] += 1; o = Lv + for t in range(V): assert cur[V + t] == lev.get(t, ()), 'target level at the centre scatter' + for e in seq: + for r in [e[1]] + ([e[2]] if e[0] == 'add' else []): climb(r, e[-1]) + for r in range(n): climb(r, FULL if (r < V or r >= 2 * V) else perp(P[r - V])) + return paid + + +def global_profile(local, widths): + """unhosted nine-stage profile: local x (stages*replicas) + the 240*8 idle children per rank + bank pads""" + live, pads = unhosted_stock(widths) + g = Counter({r: z * L * T for r, z in local.items()}) + for r in (16, 8, 32, 8, 48, 8, 48, 32, 16): g[r] += 240 * T + g.update(pads) + return live, g + + +def build(word, sel, check=True): # check=False only for the mutation controls that must be caught by the certifying scripts + if not sel: return word + w = copy.deepcopy(word); R = w['report']['R'] + col = responses(word); first = first_frames(word) + gauge = {int(h): basis(E) for h, E in sel.get('gauge', {}).items()} + classes = sel.get('kernel', []) + pivots = {p for c in classes for p in c['pivots']}; donors = {d for c in classes for d in c['donors']} + assert not (pivots & donors) and not (pivots | donors) & set(gauge) and len(pivots) == sum(len(c['pivots']) for c in classes) + # --- structural conditions ------------------------------------------------------------------------------------- + for h, E in gauge.items(): + assert not check or span(E) <= span(first[h]), ('gauge entrance outside the first frame', h) + levels = defaultdict(list) + for h, E in gauge.items(): + for t in col[h]: levels[t].append(E) + for t, Es in levels.items(): # pairwise nested comps per target + for a in Es: + for b in Es: assert not check or span(a) <= span(b) or span(b) <= span(a), ('non-nested gauges at target', t) + lev = {t: max(Es, key=len) for t, Es in levels.items()} + for k, r in enumerate(w['centers']): # chain per centre, inside the centre frame + served = {lev.get(e[1] - V, ()) for e in w['cut'] if e[2] == r} + for a in served: + for b in served: assert not check or span(a) <= span(b) or span(b) <= span(a), ('centre chain', k) + top = max(served, key=len) + assert not check or span(top) <= span(basis(w['center_frames'][k])), ('level outside centre frame', k) + # --- gates ---------------------------------------------------------------------------------------------------------- + gates = [] + for h, E in sorted(gauge.items(), key=lambda kv: (len(kv[1]), kv[0])): + for t, x in sorted(col[h].items()): + c = -x; gates.append(['add', V + t, 2 * V + h, c.numerator, c.denominator, list(E)]) + pre = [] + start = {2 * V + h: list(E) for h, E in gauge.items()} + for cl in sorted(classes, key=lambda c: (len(c['E']), c['E'])): + E = basis(cl['E']) + for x in [*cl['donors'], *cl['pivots']]: assert span(E) <= span(first[x]), ('kernel entrance outside the first frame', x) + for p in cl['pivots']: + rel = solve_relation(col, cl['donors'], p) + assert rel is not None, ('pivot response not in the donor span', p) + start[2 * V + p] = list(E) + for d, c in rel.items(): + q = -c; pre.append(['add', 2 * V + d, 2 * V + p, q.numerator, q.denominator, list(E)]) + w['A'] = gates + pre + w['A'] + w['cleanup'] = [inverse(e, FULL) for e in reversed(w['A'] + w['B']) if not V <= e[1] < 2 * V] + w['start_extra'] = {str(r): list(E) for r, E in sorted(start.items())} + w['target_levels'] = {str(t): list(E) for t, E in sorted(lev.items()) if E} + if not check: return w + prof = profile(w); widths = widths_of(w) + live, g = global_profile(prof, widths) + w['report']['local_profile'] = {str(k): z for k, z in sorted(prof.items())} + w['report']['global_profile'] = {str(k): z for k, z in sorted(g.items())} + w['report']['live'] = live + w['report']['entrance_rank'] = sum(L - x for x in widths); w['report']['entering_helpers'] = sum(1 for x in widths if x < L) + w['report']['selection_sha256'] = hashlib.sha256(json.dumps(sel, sort_keys=True).encode()).hexdigest() + return w + + +def dump(w): return gzip.compress(json.dumps(w, sort_keys=True, separators=(',', ':')).encode(), mtime=0) + + +if __name__ == '__main__': + src, selp, out = map(Path, sys.argv[1:4]) + sel = json.loads(selp.read_text()) + if not sel: out.write_bytes(src.read_bytes()); print('empty selection: copied byte for byte'); sys.exit(0) + word = json.load(gzip.open(src)); w = build(word, sel); out.write_bytes(dump(w)) + print('gk word: entering helpers', w['report']['entering_helpers'], 'entrance rank', w['report']['entrance_rank'], + 'local profile', w['report']['local_profile'], 'unhosted live', w['report']['live']) diff --git a/research/e8-complex-gauge-kernel/code/hosted_gk.py b/research/e8-complex-gauge-kernel/code/hosted_gk.py new file mode 100644 index 0000000000..ae62c773b3 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/hosted_gk.py @@ -0,0 +1,150 @@ +# GK: modified copy of PR #442's complex_hosted.py (DaysSky) by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +# Every change is marked "GK:". At the defaults (no --selection / --key, all residual widths 9) the written files equal PR #442's. +"""Idle-axis hosting for #433's compressed nine-stage complex template (m=73, R=560, whole rank-nine residuals). +Local programs, data routes and the cover correction are unchanged; bank slots of hosted residuals move onto pending +idle-child coordinates of untouched data families; unhosted width-9 residuals are re-tiled eight per bank with one paid pad +(a final partial bank pays the larger pad); unhosted ENTERING residuals (GK) go to banks of their own, at most one per replica (hence per invocation) in a bank, with spectators in the pad. usage: complex_hosted.py SPLIT_CENTRES_DIR OUT""" +import gzip, hashlib, json, math, sys, time +from collections import Counter, defaultdict +from pathlib import Path +HERE = Path(__file__).resolve().parent +PKG442 = HERE.parent.parent / 'idle-axis-hosting' # GK: PR #442's package supplies hosting_core and the default SELECTION.json +sys.path.insert(0, str(PKG442)); sys.path.insert(0, str(HERE)) +import hosting_core as HC +from gk_common import tile, widths_of, basis, route +import onehost_gk as OH +V, K, T, L, M, R = 120, 4, 8, 9, 73, 560 +DATA = 2 * K * V * T +DISCOVER = False; SELECTION = None; KEY = 'complex'; DISCOVER_TO = None; ONEPER = False +def one_helper_rule(own, widths, W): + """GK: PR #458's rule on every register class of one invocation (own = the 2V active data owners followed by the R helper owners). + data families (f < DATA): the active families and every hosted helper (any width) are pairwise distinct; + bank families (DATA <= f < W): an ENTERING helper (width < 9) is the only owner of its family; width-9 helpers share a pure bank as in + PR #433 (no wrapper acts on them) and their eight 9-cell slots are disjoint; + every other family (the private namespace, f >= W) is owned by nobody; the active owners carry route [1, ...] and are never helpers.""" + fam = Counter(f for f, r in own) + for i, (f, r) in enumerate(own): + helper = i >= 2 * V; w = widths[i - 2 * V] if helper else None + if f < DATA: assert fam[f] == 1, ('two owners on one data family in one invocation', f) + elif f < W: + assert helper and r[0] == 2, ('a bank family owned by a non-helper', f) + if w < L: assert fam[f] == 1, ('an entering helper shares its bank family in one invocation', f) + else: raise AssertionError(('owner in the private namespace', f)) + assert (r[0] == 1) == (not helper) + cells = defaultdict(set) # disjoint footprints (residual cells and spectators) of the helpers of one bank family + for i, (f, r) in enumerate(own): + if i >= 2 * V and f >= DATA: + w = widths[i - 2 * V]; foot = set(range(r[1] * L, r[1] * L + L)) if len(r) == 2 else set(range(r[1], r[1] + w)) | set(r[3]) + assert len(foot) == L and not foot & cells[f], ('footprints overlap on a bank family', f); cells[f] |= foot +def main(src, out): + t0 = time.monotonic(); out.mkdir(parents=True, exist_ok=False) + blob = gzip.decompress((src / 'GLOBAL-TEMPLATE.json.gz').read_bytes()); t = json.loads(blob) + integ = json.loads((src / 'INTEGRATION.json').read_text()); checks = json.loads((src / 'LOCAL-CHECKS.json').read_text()) + assert hashlib.sha256(blob).hexdigest() == integ['global_template_sha256'] and t['live'] == integ['live'] + rank = {} + for it in t['idle_children']: + assert it['replicas'] == T; rank.setdefault(it['child'], it['rank']); assert rank[it['child']] == it['rank'] + pair_of_stage = {e['stage']: e['pair'] for e in t['recipe'] if e['kind'] == 'local'} + sched = []; side_of = {}; pair_of = {} + for e in t['execution_schedule']: + if e['kind'] == 'local_cover_sweep': sched.append(dict(kind='local', stage=e['stage'], pair=pair_of_stage[e['stage']])) + elif e['kind'] == 'bridge': sched.append(dict(kind='bridge', dst=e['dst'], src=e['src'])) + elif e['kind'] == 'idle_cover_sweep': + for sd, ch in enumerate(e['child_indices']): + if ch in rank: + sched.append(dict(kind='idle', pair=e['pair'], rank=rank[ch], idx=ch)); side_of[ch] = sd; pair_of[ch] = e['pair'] + # GK: residual widths from the word's entrance frames (all 9 at the defaults) + canon = json.loads(gzip.decompress((src / 'CANONICAL-WORD.json.gz').read_bytes())) + widths = [L - len(canon['frames'][canon['start'][2 * V + i]]) for i in range(R)] + win = {k: x for k, x in HC.windows(sched).items() if x[1] >= min(widths) and x[2]} + avail = {} + for w_ in widths: avail[(0, w_)] = avail.get((0, w_), 0) + 1 + avail = {(s, w_): z for s in range(L) for (_, w_), z in avail.items()} + sel = Path(SELECTION) if SELECTION else PKG442 / 'SELECTION.json'; key = KEY + if ONEPER: # GK: whole residuals, at most one helper per physical family per invocation (PR #458's rule) + OH.check_disjoint_groups(win, pair_of, side_of) + if DISCOVER: + psel, val = OH.solve(win, V, avail, M, HC.cost(1, M) / 8); OH.save(DISCOVER_TO or sel, key, psel, val); sel = DISCOVER_TO or sel + psel, val = OH.load(sel, key) + slots, rem = OH.expand(win, psel, widths, V) + ph = json.loads(Path('work/complex-nine-native/DATA-PHASES.json').read_text()) + assert [p['q'] for p in ph['recipes']] == canon['ports'] and len(ph['recipes']) == V + else: + if DISCOVER: + ys, zs, val = HC.solve(win, V, avail, M, pad_value=HC.cost(1, M) / 8); HC.save_selection(DISCOVER_TO or sel, key, ys, zs, val) + sel = DISCOVER_TO or sel + ys, zs, val = HC.load_selection(sel, key) + helpers = {s: [(h, widths[h]) for h in sorted(range(R), key=lambda h: (-widths[h], h))] for s in range(L)} # GK: widest first + slots, rem = HC.expand(win, ys, zs, helpers, V) + hosted = {(s, h): (i, port, off) for i, port, off, w, s, h in slots} + # re-tile unhosted residuals: per stage, z = rank among (replica, helper) unhosted pairs; eight per bank + base = [DATA]; tl = {}; partial = Counter() + for s in range(L): # GK: width-9 residuals: eight per bank and one pad, as in PR #442; entering residuals: one per replica per bank (gk_common.tile) + left = [(rep, h, widths[h]) for rep in range(T) for h in range(R) if (s, h) not in hosted] + asg, nb, pads = tile(left) + for (rep, h), x_ in asg.items(): tl[s, rep, h] = x_ + base.append(base[-1] + nb); partial.update(pads) + W = base[-1] + for c in t['calls']: + s, rep, p = c['stage'], c['replica'], c['pair']; own = c['owners'][:2 * V] + for h in range(R): + if (s, h) in hosted: + i, port, off = hosted[s, h]; w_ = widths[h] + if ONEPER and w_ < L: # GK: explicit spectator chart (PR #458's route record); width 9 has no spectator and keeps [3, i, off] + rt = [4, i, off, w_, OH.spectators(canon['ports'][port], [int(x) for x in ph['recipes'][port]['idle_children'][i]['orthogonal_axes']], off, w_)] + else: rt = [3, i, off] + own.append([rep * 960 + (2 * pair_of[i] + side_of[i]) * V + port, rt]) + else: + b, off_, w_, pure_, sp_ = tl[s, rep, h]; own.append([base[s] + b, route(off_, w_, pure_, sp_)]) + assert len({(f, json.dumps(r)) for f, r in own}) == 2 * V + R and all(f < W for f, r in own) # every owner lies in the live stock: none in the private namespace + if ONEPER: one_helper_rule(own, widths, W) # GK: the rule on EVERY register class, not only the data families + c['owners'] = own + if ONEPER: # GK: bank chart across all invocations: residual cells packed from 0, the spectators of an entering helper are the first cells beyond them + occ = defaultdict(set) + for c in t['calls']: + for h, (f, r) in enumerate(c['owners'][2 * V:]): + if f >= DATA: occ[f] |= set(range(r[1] * L, r[1] * L + L)) if len(r) == 2 else set(range(r[1], r[1] + widths[h])) + for c in t['calls']: + for h, (f, r) in enumerate(c['owners'][2 * V:]): + if f >= DATA and widths[h] < L: + assert occ[f] == set(range(len(occ[f]))) and r[2] == widths[h] and r[3] == list(range(len(occ[f]), len(occ[f]) + L - widths[h])) and len(occ[f]) + L - widths[h] <= M, ('bank spectator chart', f, r) + paid = Counter() + for c in t['calls']: + for r_, z in checks[c['orientation']]['paid_profile'].items(): paid[int(r_)] += z + newidle = [] + for it in t['idle_children']: + ch, port = it['child'], it['port']; rr = rem.get((ch, port), it['rank']) if ch in win else it['rank'] + if rr: newidle.append(dict(child=ch, port=port, rank=rr, hosted=it['rank'] - rr, replicas=T)); paid[rr] += T + for r_, n in partial.items(): paid[r_] += L * n if False else n * 1 + # padding: one pad child per bank per stage (already per-stage counted above), the template replays all stages + mass = sum(r * n for r, n in paid.items()); D = M * W - mass + assert D == 2496, D + t.update(version='hamming-mutable-basis-nine-v1+idle-axis-hosting', live=W, idle_children=newidle, + physical=W + R + (integ['physical'] - integ['live'] - R), + hosting=dict(windows={str(i): [w[0], w[1], sorted(w[2])] for i, w in win.items()}, sides=side_of, pairs=pair_of, + slots=[list(x) for x in slots], banks=[base[s + 1] - base[s] for s in range(L)])) + if ONEPER: # GK + C_ = len(canon['centers']); t['private_namespace'] = {'centers': [W, W + C_], 'reserved_tableau': [W + C_, W + C_ + R], 'coefficient': [t['physical'] - 2, t['physical']]} # re-based on the hosted stock (the parent's ranges lie beyond the hosted physical stock) + t['hosting']['max_helpers_per_physical_family_per_call'] = 1 + t['route_semantics']['helper'] += '; entering helpers: paid wrappers R_E^-1 before and L_E^-1 after the invocation, route [4, child, offset, width, spectator indices]; an entering helper is the only owner of its physical family in the invocation (data or bank); a banked entering helper is [2, offset, width, spectator cells] with the spectators the first cells of the bank beyond every residual cell' + t['bank_padding']['families'] = list(range(DATA, W)); t['cover_final_correction']['families'] = [0, W] + t['cover_final_correction']['charged_calls_per_cover'] = W + for e in t['execution_schedule']: + if e['kind'] == 'bank_padding_cover_sweep': e['families'] = [DATA, W] + elif e['kind'] == 'translate_every_live_family': e.update(t['cover_final_correction']) + tb = json.dumps(t, sort_keys=True, separators=(',', ':')).encode(); (out / 'GLOBAL-TEMPLATE.json.gz').write_bytes(gzip.compress(tb, mtime=0)) + res = dict(status='PASS_IDLE_AXIS_HOSTED_COMPLEX_TEMPLATE', parent_template_sha256=integ['global_template_sha256'], + template_sha256=hashlib.sha256(tb).hexdigest(), live=W, physical=t['physical'], global_profile=dict(sorted(paid.items())), + rank_mass=mass, deficit=D, maxchild=max(paid), hosted_residuals=len(slots) * T, banks_per_stage=t['hosting']['banks'], + saved_cost_proxy=val, seconds=time.monotonic() - t0) + (out / 'HOSTED.json').write_text(json.dumps(res, indent=2) + '\n') + print(json.dumps({k: res[k] for k in ('live', 'maxchild', 'hosted_residuals', 'banks_per_stage', 'deficit')})) +if __name__ == '__main__': + # GK: --selection FILE --key NAME choose a frozen selection of this package; --discover-to FILE recomputes it with scipy + argv = sys.argv[1:]; opts = {} + for o in ('--selection', '--key', '--discover-to'): + if o in argv: i = argv.index(o); opts[o] = argv[i + 1]; del argv[i:i + 2] + SELECTION = opts.get('--selection'); KEY = opts.get('--key', 'complex'); DISCOVER_TO = Path(opts['--discover-to']) if '--discover-to' in opts else None + ONEPER = '--one-helper-per-family' in argv + DISCOVER = '--discover' in argv or DISCOVER_TO is not None; args = [a for a in argv if a not in ('--discover', '--one-helper-per-family')] + main(Path(args[0]), Path(args[1])) diff --git a/research/e8-complex-gauge-kernel/code/integrate_gk.py b/research/e8-complex-gauge-kernel/code/integrate_gk.py new file mode 100644 index 0000000000..df261063e1 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/integrate_gk.py @@ -0,0 +1,123 @@ +# GK: modified copy of PR #433's complex_integrate.py (icekylinx with Codex assistance; PR #425) by DreamingOfClouds with Claude Opus 5.5 +# (Anthropic), via Claude Code. Every change is marked "GK:". On a word without start_extra / target_levels the behaviour +# and every written file equal PR #433's (regression anchor in verify.py). +import sys as _sys, os as _os; _sys.path.insert(0, _os.path.dirname(_os.path.abspath(__file__))) +# Adapted from PR425 for heterogeneous centres by icekylinx, with Codex assistance. +import copy,gzip,hashlib,importlib.util,json,math +from collections import Counter +from fractions import Fraction as Q +from pathlib import Path +OUT=Path('split-centres');cp=OUT/'CANONICAL-WORD.json.gz' +c=json.load(gzip.open(cp));audit=json.loads((OUT/'SCALAR-FRAME-AUDIT.json').read_text()) +phase=json.loads((OUT/'CLIFFORD-REVIEW.json').read_text());sha=lambda p:hashlib.sha256(Path(p).read_bytes()).hexdigest() +assert phase['canonical_word_sha256']==audit['canonical_word_sha256']==sha(cp) +assert phase['all_child_equalities_include_global_phase'] +programs=json.load(gzip.open(OUT/'LOCAL-PROGRAMS.json.gz'));checks=json.loads((OUT/'LOCAL-CHECKS.json').read_text()) +frames=c['frames'];v,R,h=c['v'],c['R'],c['h'];n=2*v+R;private_centres=len(c['centers']) +for z in checks.values():z['paid_profile']={int(r):n for r,n in z['paid_profile'].items()} +old=Path('work/complex-nine-native');template=json.load(gzip.open(old/'GLOBAL-TEMPLATE.json.gz')) +data_phase=json.loads((old/'DATA-PHASES.json').read_text()) +assert template['exact_data_phase_recipe_sha256']==sha(old/'DATA-PHASES.json') +assert data_phase['status']=='PASS_EXACT_Z4_DATA_ROUTE_IDLE_AND_TERMINAL_PHASES' +m,T,L,k=73,8,9,4 +# GK: residual widths 9 - dim(start frame); banks tile per width class (all 9: PR #433's eight residuals + one pad) +from gk_common import tile,route +widths=[h-len(frames[c['start'][2*v+i]]) for i in range(R)] +assign,nb,pads=tile([(rep,i,widths[i]) for rep in range(T) for i in range(R)]);entering0=any(w_2*maxchild**depth +assert local_bound<1<<48 and logical<1<<6050 and router0 + bound=max(math.ceil(36/gap**2),math.ceil(2*(4+512)/gap)) + assert bound*gap**2>=36 and bound*gap>=2*(4+512) + cutoffs.append(str(bound));chain.append(z) +bridge={'semantic':{'C0':{'base':2,'exponent':210000},'strict_literal_gap':1}, + 'rows':{'degree_gap':Q(10**6)-Q(51*20161,25)}} +q=chain[-1]*(1-2*eta);ticks=(1-eta)*q/(1+q)/grid;kap=Q((ticks.numerator-1)//ticks.denominator,10**18) +assembly=Outer.assembly(chain[-1],b,bridge,kap,eta=eta,beta=beta) +try:Outer.assembly(chain[-1],b,bridge,kap+grid,eta=eta,beta=beta) +except AssertionError:pass +else:raise AssertionError('next kappa grid accepted') +result={'status':'PASS_NEW_STRUCTURAL_PROGRAM_AND_FINITE_ASSEMBLY_PENDING_REPLAY', + 'canonical_word_sha256':sha(cp),'scalar_audit_sha256':sha(OUT/'SCALAR-FRAME-AUDIT.json'), + 'exact_phase_receipt_sha256':sha(OUT/'CLIFFORD-REVIEW.json'),'global_template_sha256':hashlib.sha256(blob).hexdigest(), + 'local_program_checks':checks,'R':R,'m':m,'live':W,'physical':physical, + 'bank_assignments':len(assignments),'rank_mass':mass,'deficit':2496, + 'global_profile':dict(sorted(paid.items())),'emitted_local_events_all_calls':event_count, + 'finite_invoice':{'local_primitive_bound':local_bound,'local_adapters':adapters, + 'pervertex':pervertex,'physical_stock_bits':stock.bit_length(), + 'router_bits':router.bit_length(),'literal_bits':literal.bit_length(), + 'physical_row_coefficient':row,'retained_row_coefficient':20161, + 'compiler':compiler,'G_exponent':30000,'E_exponent':100000,'C0_exponent':210000, + 'required_C0_bits':(32*m*BB*BB).bit_length(),'halving_degree':depth, + 'halving_integer_inequality':[m**depth,2*maxchild**depth]}, + 'complex_b':str(b),'bit_c':str(bit),'prospective_kappa':str(kap),'kappa_float':float(kap), + 'log2_kappa':math.log2(float(kap)), + 'kappa_gain_percent':float(100*(kap/Q(998390813251625,10**18)-1)), + 'strict_outer_constraints':{name:str(z) for name,z in assembly['strict_constraints'].items()}, + 'next_kappa_grid_rejected':True,'bootstrap_cutoffs_log2':cutoffs, + 'scope':'New finite scalar interface with a written conjugation proof, conditional on inherited all-size compiler, precision/tape and analytic transfer. Independent emitted-program replay and fresh package replay still required before final promotion.'} +(OUT/'INTEGRATION.json').write_text(json.dumps(result,indent=2)+'\n') +print('PASS prospective kappa',float(kap),'gain',result['kappa_gain_percent'],'percent',flush=True) diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/check.py b/research/e8-complex-gauge-kernel/code/lemmaG/check.py new file mode 100644 index 0000000000..2c3ec7067e --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/check.py @@ -0,0 +1,49 @@ +"""Independent check stage for Lemma G (PROOF.md §2) on the emitted artefacts of one variant. Apache-2.0. +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +usage: check.py BASE VARIANT OUTDIR [--mutants] +BASE/VARIANT/{split-centres,hosted} is a run_variant.py work directory (BASE = the output directory of verify.py). The scripts of this directory import no +script of the package and none of PR #433/#442 except the vendored `clifford_exact`, which is used only as the DEFINITION of the label operators T_F and of the port +gate C_q (every executed transition, data adapter and wrapper is decoded from its serialized recipe). + gd.selftest the exact Gaussian-dyadic applier agrees with the vendored state-vector routine on 19 operators + run_labels.py label / scalar / accounting checker on both orientations (clauses G0-G4, S, ACC), the 72 calls' program digests + lg_instances.py I-tr, I-comp, I-centre, I-helper: exact operator identities of every Lemma G instance on all 512 basis columns (not for the anchor) + lg_e2e.py the complete emitted program end to end, both orientations, against the transform computed from definitions + lg_mutants.py the 14 necessity controls (--mutants; headline word only) +Writes LEMMA-G-CHECK.json (deterministic content only) into OUTDIR; any failure raises.""" +import json, os, subprocess, sys +from collections import Counter +from pathlib import Path +HERE = Path(__file__).resolve().parent +base, name, outd = Path(sys.argv[1]).resolve(), sys.argv[2], Path(sys.argv[3]).resolve(); mut = '--mutants' in sys.argv[4:] +outd.mkdir(parents=True, exist_ok=True) +env = dict(os.environ, LG_BASE=str(base), PYTHONDONTWRITEBYTECODE='1', PYTHONINTMAXSTRDIGITS='0'); env.pop('PYTHONOPTIMIZE', None) +def run(script, *args): + log = outd / (Path(script).stem + '-' + name + '.log') + with log.open('w') as f: q = subprocess.run([sys.executable, '-B', str(HERE / script), *args], cwd=outd, env=env, stdout=f, stderr=subprocess.STDOUT) + if q.returncode: raise RuntimeError((script, name, log.read_text()[-2000:])) +sys.path.insert(0, str(HERE)); import lg_phys as P; from gd import selftest +S = dict(variant=name, selftest_operators=selftest(P.ce)) +run('run_labels.py', name) +L = json.loads((outd / ('LABELS-' + name + '.json')).read_text())[name] +keys = ('n_label_violations', 'scalar_violations', 'events', 'sha256', 'compensation_gates', 'kernel_updates', 'entering', 'entrance_rank', 'local_mass', 'paid_profile') +S['labels'] = {o: {k: L[o][k] for k in keys} for o in ('forward', 'backward')}; S['calls'] = {k: L['calls'][k] for k in ('n', 'ok', 'orient')}; S['inputs'] = L['inputs'] +assert all(S['labels'][o]['n_label_violations'] == 0 and S['labels'][o]['scalar_violations'] == [] for o in S['labels']) and S['calls']['ok'], 'label / scalar checker' +if name != 'anchor': + run('lg_instances.py', name) + I = json.loads((outd / ('INSTANCES-' + name + '.json')).read_text()) + S['instances'] = {'I-tr': dict(transitions=I['I-tr']['transitions'], failures=len(I['I-tr']['failures'])), + 'I-comp': dict(compensation_gates=I['I-comp']['compensation_gates'], targets=I['I-comp']['targets'], entering_helpers_compensating=I['I-comp']['entering_helpers_compensating'], + input_registers=I['I-comp']['input_registers'], failures=len(I['I-comp']['failures'])), + 'I-centre': dict(centres=I['I-centre']['centres'], chains=sorted(Counter('-'.join(map(str, d['path_dims'])) for d in I['I-centre']['detail']).items()), failures=len(I['I-centre']['failures'])), + 'I-helper': dict(entering_helpers=I['I-helper']['entering_helpers'], widths=dict(sorted(I['I-helper']['widths'].items())), failures=len(I['I-helper']['failures']))} + assert all(x['failures'] == 0 for x in S['instances'].values()), 'instance identities' +run('lg_e2e.py', name) +E = json.loads((outd / ('E2E-' + name + '.json')).read_text()) +S['end_to_end'] = dict(status=E['status'], columns=E['columns'], kinds=dict(sorted(E['kinds'].items())), dense=E['dense'], seed=E['seed'], failures=len(E['failures'])) +assert E['status'] == 'PASS' and not E['failures'], 'end-to-end identity' +if mut: + run('lg_mutants.py') + M = json.loads((outd / 'MUTANTS.json').read_text()) + S['necessity_mutants'] = [dict(mutant=m['mutant'], rejected=m['rejected'], checker_flags=m['checker_flags'], physics=m['physics']) for m in M] + assert len(M) == 14 and all(m['rejected'] for m in M), 'necessity controls' +(outd / 'LEMMA-G-CHECK.json').write_text(json.dumps(S, indent=1, sort_keys=True) + '\n'); print(name, 'PASS Lemma G independent checks', flush=True) diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/gd.py b/research/e8-complex-gauge-kernel/code/lemmaG/gd.py new file mode 100644 index 0000000000..e6a5d77381 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/gd.py @@ -0,0 +1,170 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +"""Exact Gaussian-dyadic batch vectors on C^(2^9) and an independent applier for Clifford circuit primitives. + +A register value is (re + i*im) / 2^d with re, im int64 arrays of shape (512, k) (k simultaneous input columns). +Every operation asserts |numerator| < 2^60 afterwards, so int64 never wraps: a result is exact or the run aborts. + +Primitive semantics (written here from the documented conventions of the vendored compiler, not imported): + ('P', G) v'[G x] = v[x] (G given by its 9 rows over F2) + ('X', b) v'[x] = v[x ^ b] + ('D', Q, alpha) v'[x] = i^(sum_i alpha_i x_i + 2 sum_{i G^-1, D -> conjugate phases, X -> X, phase -> -p, C(q,s) -> C(q,-s). +`selftest()` compares this applier with the vendored compiler's own state-vector routine on basis vectors.""" +import numpy as np + +N = 512; n = 9 +XS = np.arange(N, dtype=np.int64) +LIM = 1 << 60 + + +def par(x): return bin(x).count('1') & 1 + + +def mv(rows, x): return sum(par(r & x) << i for i, r in enumerate(rows)) + + +_pcache = {} +def pidx(G): + G = tuple(G) + if G not in _pcache: _pcache[G] = np.array([mv(G, x) for x in range(N)], dtype=np.int64) + return _pcache[G] + + +_dcache = {} +def qarr(Q, alpha): + key = (tuple(Q), tuple(alpha)) + if key not in _dcache: + out = np.zeros(N, dtype=np.int64) + for x in range(N): + s = sum(alpha[i] for i in range(n) if x >> i & 1) + s += 2 * sum(1 for i in range(n) for j in range(i + 1, n) if x >> i & 1 and x >> j & 1 and Q[i] >> j & 1) + out[x] = s % 4 + _dcache[key] = out + return _dcache[key] + + +class GD: + __slots__ = ('re', 'im', 'd') + def __init__(self, re, im, d=0): self.re, self.im, self.d = re, im, d + @staticmethod + def zeros(k): return GD(np.zeros((N, k), np.int64), np.zeros((N, k), np.int64), 0) + def copy(self): return GD(self.re.copy(), self.im.copy(), self.d) + def k(self): return self.re.shape[1] + def guard(self): + if self.re.size and (np.abs(self.re).max() >= LIM or np.abs(self.im).max() >= LIM): raise OverflowError('int64 guard') + def norm(self): + while self.d > 0 and not np.any((self.re | self.im) & 1): + self.re >>= 1; self.im >>= 1; self.d -= 1 + return self + def is_zero(self): return not np.any(self.re) and not np.any(self.im) + def equals(self, o): + a = self.copy().norm(); b = o.copy().norm() + if a.is_zero() and b.is_zero(): return True + return a.d == b.d and np.array_equal(a.re, b.re) and np.array_equal(a.im, b.im) + def mul_ipow(self, q): # q: scalar or (512,) array of exponents mod 4 + q = np.asarray(q) % 4 + if q.ndim: q = q[:, None] + re, im = self.re, self.im + nre = np.where(q == 0, re, np.where(q == 1, -im, np.where(q == 2, -re, im))) + nim = np.where(q == 0, im, np.where(q == 1, re, np.where(q == 2, -im, -re))) + self.re, self.im = nre, nim + return self + def apply_prim(self, p, inverse=False): + t = p[0] + if t == 'P': + idx = pidx(p[1]) + if inverse: self.re, self.im = self.re[idx], self.im[idx] + else: + r = np.empty_like(self.re); i = np.empty_like(self.im); r[idx] = self.re; i[idx] = self.im; self.re, self.im = r, i + elif t == 'X': + idx = XS ^ p[1]; self.re, self.im = self.re[idx], self.im[idx] + elif t == 'D': + q = qarr(p[1], p[2]); self.mul_ipow(-q if inverse else q) + elif t == 'phase': + self.mul_ipow(-p[1] if inverse else p[1]) + elif t == 'C': + q, s = p[1], p[2] + if inverse: s = -s + idx = XS ^ q; wr, wi = self.re[idx], self.im[idx] + re, im = self.re, self.im + self.re = re - s * im + wr + s * wi + self.im = im + s * re + wi - s * wr + self.d += 1 + else: raise ValueError(p) + self.guard() + return self + def apply_circ(self, circ, inverse=False): + for p in (reversed(circ) if inverse else circ): self.apply_prim(p, inverse) + return self.norm() + def add_scaled(self, src, num, den): + """self += (num/den) * src, den a power of two""" + assert den > 0 and den & (den - 1) == 0 + e = den.bit_length() - 1 + D = max(self.d, src.d + e) + a = self.re << (D - self.d); b = self.im << (D - self.d) + sh = D - src.d - e + a = a + num * (src.re << sh); b = b + num * (src.im << sh) + self.re, self.im, self.d = a, b, D + self.guard(); return self.norm() + def scale(self, num, den): + assert den > 0 and den & (den - 1) == 0 + self.re = self.re * num; self.im = self.im * num; self.d += den.bit_length() - 1 + self.guard(); return self.norm() + + +def circ_of(op): + """primitive list of a vendored Op (used only to read the DEFINITION of canonical frames / gates)""" + return [tuple(e) for e in op.circuit] + + +def monomial_circ(rec): + """decode a serialized Gaussian monomial: diag(Q, alpha), then perm(G), then translation, then global phase""" + return [('D', tuple(rec['quadratic_rows']), tuple(rec['linear_Z4'])), ('P', tuple(rec['matrix_rows'])), ('X', rec['offset']), ('phase', rec['phase'])] + + +def fourier_circ(axes): return [('C', 1 << i, 1) for i in axes] + + +def recipe_circ(rec): + """serialized child recipe: right monomial, Fourier on the first `rank` axes, left monomial (rank 0: the monomial in `left`)""" + if rec['rank'] == 0: return monomial_circ(rec['left']) + return monomial_circ(rec['right']) + fourier_circ(range(rec['rank'])) + monomial_circ(rec['left']) + + +def basis_batch(cols): + """GD with column c = basis vector e_{cols[c]}""" + g = GD.zeros(len(cols)) + for c, b in enumerate(cols): g.re[b, c] = 1 + return g + + +def identity_batch(): return basis_batch(list(range(N))) + + +def selftest(vendor): + import random + ce = vendor + rng = random.Random(1) + FULL = tuple(1 << i for i in range(n)) + ops = [ce.canonical_frame(n, ()), ce.canonical_frame(n, FULL), ce.canonical_frame(n, (510,)), ce.canonical_frame(n, (408, 102)), + ce.cgate(n, 7), ce.cgate(n, 13).adjoint(), ce.fourier(n, range(5))] + for _ in range(6): + U = [] + while len(U) < rng.randint(1, 8): + x = rng.randrange(1, N) + if ce.rank(U + [x]) > len(U): U.append(x) + ops.append(ce.canonical_frame(n, tuple(U))) + ops.append(ce.canonical_frame(n, tuple(U)).adjoint().then(ce.canonical_frame(n, FULL))) + for op in ops: + cols = rng.sample(range(N), 12) + g = basis_batch(cols).apply_circ(circ_of(op)) + for c, b in enumerate(cols): + vec, den = op.zero_state(b) + ref = GD(np.array([[a] for a, _ in vec], np.int64), np.array([[bb] for _, bb in vec], np.int64), den) + col = GD(g.re[:, c:c + 1].copy(), g.im[:, c:c + 1].copy(), g.d) + assert col.equals(ref), 'applier disagrees with vendored state vector' + h = g.copy().apply_circ(circ_of(op), inverse=True) + assert h.equals(basis_batch(cols)), 'inverse applier' + return len(ops) diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/lg_e2e.py b/research/e8-complex-gauge-kernel/code/lemmaG/lg_e2e.py new file mode 100644 index 0000000000..5c13bb0ff3 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/lg_e2e.py @@ -0,0 +1,41 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +"""End-to-end exact identity of the full emitted local program (both orientations) on >= 256 random basis columns, structured +columns (every entering helper twice, every target with a nonzero level, every centre register, every source/target port) and +dense columns (every register dirty with random Gaussian integers simultaneously). Transitions, data adapters and wrappers are +executed from their serialized recipes; the expected transform is computed from definitions (lg_phys.expected). +usage: lg_e2e.py VARIANT [n_random] [seed]""" +import sys, json, time, random +import numpy as np +from lg_lib import load +from lg_phys import Model, run, expected, compare +from gd import GD +import os +SP = os.environ['LG_BASE'] # the output directory of verify.py: //{split-centres,hosted} +name = sys.argv[1]; nr = int(sys.argv[2]) if len(sys.argv) > 2 else 256; seed = int(sys.argv[3]) if len(sys.argv) > 3 else 2026 +d = load(f'{SP}/{name}'); m = Model(d); c = d['c']; v = c['v']; rng = random.Random(seed) +cols = [('random', rng.randrange(m.n), rng.randrange(512)) for _ in range(nr)] +ent = [r for r in range(2 * v, m.n) if c['start'][r] != 0] +cols += [('entering', r, b) for r in ent for b in (0, rng.randrange(1, 512))] +cols += [('target_level', v + int(t), rng.randrange(512)) for t in c.get('target_levels', {})] +cols += [('centre', r, rng.randrange(512)) for r in c['centers']] +cols += [('port', r, rng.randrange(512)) for r in range(2 * v)] +B = 32; rep = {'variant': name, 'seed': seed, 'columns': len(cols), 'kinds': {}, 'batches': 0, 'failures': [], 'dense': 0} +for k in set(x[0] for x in cols): rep['kinds'][k] = sum(1 for x in cols if x[0] == k) +t0 = time.time() +def check(init, label): + for o in ('forward', 'backward'): + got = run(m, d['progs'][o], init); exp = expected(m, init, o == 'backward') + bad, left = compare(m, got, exp) + if bad or left: rep['failures'].append((label, o, bad[:10], [str(x) for x in left])) +for i in range(0, len(cols), B): + chunk = cols[i:i + B]; init = {} + for ci, (_, r, b) in enumerate(chunk): init.setdefault(('L', r), GD.zeros(len(chunk))).re[b, ci] = 1 + check(init, f'batch{i // B}'); rep['batches'] += 1 + print(name, 'batch', i // B, 'failures so far', len(rep['failures']), round(time.time() - t0), flush=True) +nprng = np.random.default_rng(seed) +for j in range(2): # dense: every register dirty at once, 4 independent columns per run + k = 4; init = {('L', r): GD(nprng.integers(-1000, 1001, (512, k)).astype(np.int64), nprng.integers(-1000, 1001, (512, k)).astype(np.int64), 0) for r in range(m.n)} + check(init, f'dense{j}'); rep['dense'] += k + print(name, 'dense', j, 'failures so far', len(rep['failures']), round(time.time() - t0), flush=True) +rep['seconds'] = round(time.time() - t0, 1); rep['status'] = 'PASS' if not rep['failures'] else 'FAIL' +json.dump(rep, open(f'E2E-{name}.json', 'w'), indent=1); print(name, rep['status'], rep['columns'], 'basis columns +', rep['dense'], 'dense', rep['seconds'], 's') diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/lg_instances.py b/research/e8-complex-gauge-kernel/code/lemmaG/lg_instances.py new file mode 100644 index 0000000000..023880988e --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/lg_instances.py @@ -0,0 +1,125 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +"""Exhaustive exact operator identities for every Lemma G instance of one variant (all 512 basis columns of every input). + I-tr every transition used by the program (climbs and centre steps): serialized recipe == T_b T_a^-1 (definition) + I-comp the nonzero-frame compensation segment (head of A): for every input register (target or entering helper) the segment + acts as h_t -> T_{lam_t} (h_t + sum_j c_tj T_{E_j}^-1 h_j), h_j -> h_j (labels lam from the stream) + I-centre every centre phase, both orientations: forward h_t += q_t T_{L_t} T_{c_k}^-1 h_r ; backward h_r -= sum_t q_t T_{c_k} T_{L_t}^-1 h_t + I-helper every entering helper: L_E^-1 . (product of the recipes of ITS emitted climb chain E -> ... -> FULL) . R_E^-1 == C_[w] (x) I +usage: lg_instances.py VARIANT [skip_tr]""" +import sys, json, time +from collections import defaultdict +from lg_lib import load, check_labels +from lg_phys import Model, run +from gd import GD, identity_batch, fourier_circ +import os +SP = os.environ['LG_BASE'] # the output directory of verify.py: //{split-centres,hosted} + + +def main(name, skip_tr=False): + d = load(f'{SP}/{name}'); m = Model(d); c = d['c']; v = c['v']; start = c['start'] + I = identity_batch(); rep = {'variant': name}; t0 = time.time() + fw, bw = d['progs']['forward'], d['progs']['backward'] + # ---- I-tr ------------------------------------------------------------------------------------------------- + used = sorted({(e[3], e[4]) for e in fw + bw if e[0] == 'climb'} | {(e[2], e[3]) for e in fw + bw if e[0] == 'center'}) + if not skip_tr: + badtr = [ab for ab in used if not m.rec_transition(I.copy(), *ab).equals(m.def_transition(I.copy(), *ab))] + rep['I-tr'] = dict(transitions=len(used), columns_each=512, failures=badtr) + print(name, 'I-tr', len(used), 'failures', len(badtr), round(time.time() - t0), flush=True) + # ---- labels along the forward stream ---------------------------------------------------------------------- + lam = {r: start[r] for r in range(2 * v + c['R'])} + iA = fw.index(['phase', 'A']); seg_end = None; comp = [] + for idx in range(iA + 1, len(fw)): + e = fw[idx] + if e[0] == 'climb': lam[e[2]] = e[4]; continue + if e[0] == 'scalar' and e[1][0] == 'add': + t, s = e[1][1][1], e[1][2][1] + if v <= t < 2 * v and start[s] != 0 and e[2] == start[s]: comp.append((t, s, e[1][3], e[1][4])); continue + seg_end = idx; break + seg = fw[iA + 1:seg_end] + # labels at the end of the segment + lam_end = {r: start[r] for r in range(2 * v + c['R'])} + for e in fw[:seg_end]: + if e[0] == 'climb': lam_end[e[2]] = e[4] + tg = sorted({t for t, s, a, b in comp}); hs = sorted({s for t, s, a, b in comp}) + regs = tg + hs; badc = [] + for r in regs: + got = run(m, seg, {('L', r): I}) + exp = {} + if r in tg: exp[r] = m.def_transition(I.copy(), 0, lam_end[r]) + else: + exp[r] = I.copy() + for t, s, a, b in comp: + if s != r: continue + x = m.def_transition(I.copy(), start[r], lam_end[t]); x.scale(a, b) if b > 0 else x.scale(-a, -b) + if t in exp: exp[t].add_scaled(x, 1, 1) + else: exp[t] = x + keys = set(exp) | {k[1] for k in got if k[0] == 'L'} + for k in keys: + a_ = got.get(('L', k)); b_ = exp.get(k) + if a_ is None: a_ = GD.zeros(512) + if b_ is None: b_ = GD.zeros(512) + if not a_.equals(b_): badc.append((r, k)) + rep['I-comp'] = dict(compensation_gates=len(comp), targets=len(tg), entering_helpers_compensating=len(hs), + input_registers=len(regs), columns_each=512, target_levels_after_segment=sorted({lam_end[t] for t in tg}), failures=badc) + print(name, 'I-comp gates', len(comp), 'inputs', len(regs), 'failures', len(badc), round(time.time() - t0), flush=True) + # ---- I-centre ----------------------------------------------------------------------------------------------- + badk = []; cinfo = [] + for orient, ev in (('forward', fw), ('backward', bw)): + lamc = {r: start[r] for r in range(2 * v + c['R'])} + i0 = ev.index(['phase', 'centers']); i1 = ev.index(['phase', 'B']) + for e in ev[:i0]: + if e[0] == 'climb': lamc[e[2]] = e[4] + cent = ev[i0 + 1:i1] + groups = defaultdict(list); cur = None + for e in cent: + if e[0] == 'scalar': + op = e[1]; ks = [x[1] for x in op[1:] if isinstance(x, list) and x[0] == 'C'] + if ks: cur = ks[0] + elif e[0] == 'center': cur = e[1] + groups[cur].append(e) + for k, evs in sorted(groups.items()): + r = c['centers'][k]; cf = c['center_frames'][k]; assert lamc[r] == cf + terms = [(op[1][1], op[3], op[4]) for _, op, f in [e for e in evs if e[0] == 'scalar'] if op[0] == 'add' and op[1][0] == 'L' and op[2][0] == 'C'] if orient == 'forward' else \ + [(op[2][1], op[3], op[4]) for _, op, f in [e for e in evs if e[0] == 'scalar'] if op[0] == 'add' and op[1][0] == 'C' and op[2][0] == 'L'] + path = [cf] + [e[3] for e in evs if e[0] == 'center'] if orient == 'forward' else None + if orient == 'forward': + got = run(m, evs, {('L', r): I}) + exp = {r: I.copy()} + for t, a, b in terms: + x = m.def_transition(I.copy(), cf, lamc[t]); x.scale(a, b) + if t in exp: exp[t].add_scaled(x, 1, 1) + else: exp[t] = x + for kk in set(exp) | {q[1] for q in got if q[0] == 'L'}: + a_, b_ = got.get(('L', kk)), exp.get(kk) + if not (a_ or GD.zeros(512)).equals(b_ or GD.zeros(512)): badk.append((orient, k, kk)) + if any(q[0] == 'C' and not y.is_zero() for q, y in got.items()): badk.append((orient, k, 'copy not cleared')) + cinfo.append(dict(centre=k, register=r, frame=cf, path_dims=[len(m.frames[f]) for f in path], targets=len(terms))) + else: + for t, a, b in terms: + got = run(m, evs, {('L', t): I}) + x = m.def_transition(I.copy(), lamc[t], cf); x.scale(-a, b) + exp = {t: I.copy(), r: x} + for kk in set(exp) | {q[1] for q in got if q[0] == 'L'}: + a_, b_ = got.get(('L', kk)), exp.get(kk) + if not (a_ or GD.zeros(512)).equals(b_ or GD.zeros(512)): badk.append((orient, k, t, kk)) + if any(q[0] == 'C' and not y.is_zero() for q, y in got.items()): badk.append((orient, k, t, 'copy not cleared')) + rep['I-centre'] = dict(centres=len(c['centers']), detail=cinfo, failures=badk) + print(name, 'I-centre failures', len(badk), round(time.time() - t0), flush=True) + # ---- I-helper ----------------------------------------------------------------------------------------------- + badh = []; widths = defaultdict(int) + for r in range(2 * v, 2 * v + c['R']): + if start[r] == 0: continue + chain = [(e[3], e[4]) for e in fw if e[0] == 'climb' and e[2] == r] + assert chain[0][0] == start[r] and chain[-1][1] == 1 + Rc, Lc, w = m.wraps[start[r]]; widths[w] += 1 + g = I.copy().apply_circ(Rc, inverse=True) + for a, b in chain: m.rec_transition(g, a, b) + g.apply_circ(Lc, inverse=True) + if not g.equals(I.copy().apply_circ(fourier_circ(range(w)))): badh.append(r) + rep['I-helper'] = dict(entering_helpers=sum(widths.values()), widths=dict(widths), columns_each=512, failures=badh) + print(name, 'I-helper', sum(widths.values()), 'failures', len(badh), round(time.time() - t0), flush=True) + rep['seconds'] = round(time.time() - t0, 1) + json.dump(rep, open(f'INSTANCES-{name}.json', 'w'), indent=1) + + +if __name__ == '__main__': main(sys.argv[1], len(sys.argv) > 2) diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/lg_lib.py b/research/e8-complex-gauge-kernel/code/lemmaG/lg_lib.py new file mode 100644 index 0000000000..86146353b8 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/lg_lib.py @@ -0,0 +1,217 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +"""Independent Lemma G checker: labels, scalar replay, accounting. Reads only the EMITTED artefacts of one variant +(CANONICAL-WORD.json.gz, LOCAL-PROGRAMS.json.gz or the hosted GLOBAL-TEMPLATE's local_programs). No package script is imported. + +Semantics checked (see LEMMA-G.md): + every register r carries a label lam(r) in the frame table; private centre copies ('C',k) too. + G0 every scalar add / copy has both operands at ONE current label equal to the annotated frame; scale is annotated at the + operand's label; a clear (re)declares the clean private copy at the annotated frame. + G1 virtual entrance: an entering helper (start frame E != 0) starts at label E, receives exactly one R_E^-1 wrapper before any + other event that touches it, and exactly one L_E^-1 wrapper after its last touch; no physical T_E (no adapter on it). + G2 every transition of a non-private register is an ascending nested climb A < B charged |B|-|A| (no live copy meanwhile). + G3 centre phase: copy at the centre's current label; every step of a copy is nested and strictly monotone (down in the forward + orientation, up in the backward one), charged |A|-|B|; every scatter/gather meets the target at the copy's label; the copy is + cleared; no non-private transition while a copy is live. + G4 endpoint labels: start = word's start (sources: port lines, targets: 0, helpers: 0 or E), final = word's final. + S the scalar matrix of the stream (frames stripped) is exactly (x,s,y)->(x,s,y+x) forward and (x-y,s,y) backward, all columns, + private copies cleared. + ACC paid profile recount; per-register climb mass telescopes to dim(final)-dim(start); centre steps sum to dim(c_k) (bottom 0). +""" +import gzip, hashlib, json +from collections import Counter, defaultdict +from fractions import Fraction as Q +from pathlib import Path + +PHASES = ['zero_frame_precondition', 'entry_adapters', 'A', 'centers', 'B', 'final', 'exit_adapters', 'full_frame_cleanup', 'done'] + + +def rank2(vs): + p = {} + for x in vs: + while x: + b = x.bit_length() - 1 + if b not in p: p[b] = x; break + x ^= p[b] + return len(p) + + +class Frames: + def __init__(self, frames): + self.F = [tuple(f) for f in frames]; self.dim = [rank2(f) for f in self.F] + assert all(self.dim[i] == len(f) for i, f in enumerate(self.F)), 'frame rows not independent' + self._sub = {} + def sub(self, a, b): # frame a contained in frame b + k = (a, b) + if k not in self._sub: self._sub[k] = rank2(list(self.F[a]) + list(self.F[b])) == self.dim[b] + return self._sub[k] + + +def digest(x): return hashlib.sha256(json.dumps(x, sort_keys=True, separators=(',', ':')).encode()).hexdigest() + + +def load(vdir, programs_from='template'): + vdir = Path(vdir); sc = vdir / 'split-centres' + c = json.loads(gzip.decompress((sc / 'CANONICAL-WORD.json.gz').read_bytes())) + lp = json.loads(gzip.decompress((sc / 'LOCAL-PROGRAMS.json.gz').read_bytes())) + tpl = None + for p in (vdir / 'hosted' / 'GLOBAL-TEMPLATE.json.gz', sc / 'GLOBAL-TEMPLATE.json.gz'): + if p.exists(): tpl = json.loads(gzip.decompress(p.read_bytes())); break + progs = tpl['local_programs'] if (programs_from == 'template' and tpl) else lp + for o in ('forward', 'backward'): assert progs[o] == lp[o], 'template programs differ from LOCAL-PROGRAMS' + rec = json.loads((sc / 'CLIFFORD-RECIPES.json').read_text()) + ra = sc / 'RESIDUAL-ADAPTERS.json' + wraps = json.loads(ra.read_text())['recipes'] if ra.exists() else {} + # the .gz inputs are pinned by the sha256 of their DECOMPRESSED json (key without '.gz'): the gzip container bytes depend on the zlib of the Python in use + shas = {(p.name[:-3] if p.name.endswith('.gz') else p.name): hashlib.sha256(gzip.decompress(p.read_bytes()) if p.name.endswith('.gz') else p.read_bytes()).hexdigest() + for p in sorted(sc.glob('*')) if p.name in ('CANONICAL-WORD.json.gz', 'LOCAL-PROGRAMS.json.gz', 'CLIFFORD-RECIPES.json', 'RESIDUAL-ADAPTERS.json')} + return dict(c=c, progs=progs, tpl=tpl, rec=rec, wraps=wraps, shas=shas, vdir=str(vdir)) + + +def check_labels(c, events, back): + """Returns (violations, info). violations: list of (clause, message).""" + v, R = c['v'], c['R']; n = 2 * v + R; Fr = Frames(c['frames']); start, final = c['start'], c['final'] + viol = []; bad = lambda cl, msg: viol.append((cl, msg)) if len(viol) < 200 else None + lam = {('L', r): start[r] for r in range(n)} + entering = {r for r in range(2 * v, n) if start[r] != 0} + # G4 start labels + P = c['ports'] + for i in range(v): + if Fr.F[start[i]] and rank2(list(Fr.F[start[i]]) + [P[i]]) != 1 or Fr.dim[start[i]] != 1: bad('G4', f'source {i} start not its port line') + if start[v + i] != 0: bad('G4', f'target {i} does not start at 0') + phase = -1; live = set(); touched_after_post = set(); pre = {}; post = {}; first_touch = {} + paid = Counter(); climb_mass = Counter(); centre_steps = defaultdict(list); centre_copy_frame = {} + gates_at_nonzero = [] # (event index, kind, dst, src, frame) + nontrivial_wrapper_frames = {} + def touch(r, idx): + if r in post: touched_after_post.add(r) + first_touch.setdefault(r, idx) + for idx, e in enumerate(events): + tag = e[0] + if tag == 'phase': + k = PHASES.index(e[1]) if e[1] in PHASES else None + if k is None or k != phase + 1: bad('ORDER', f'phase order at {idx}: {e[1]}') + phase = k if k is not None else phase + continue + ph = PHASES[phase] if phase >= 0 else None + if tag == 'scalar': + op, f = e[1], e[2]; t = tuple(op[1]); kind = op[0] + if kind == 'add': + s = tuple(op[2]) + for x in (t, s): + if x[0] == 'L': touch(x[1], idx) + lt, ls = lam.get(t), lam.get(s) + if not (lt == ls == f): bad('G0', f'add at {idx} {t}<-{s} frame {f} but labels {lt},{ls} ({ph})') + if f != 0 and t[0] == 'L' and s[0] == 'L': gates_at_nonzero.append((idx, ph, t[1], s[1], f)) + if t[0] == 'C' and back and ph == 'centers': live.add(t[1]) + elif kind == 'copy': + s = tuple(op[2]); touch(s[1], idx) + if lam.get(s) != f: bad('G3', f'copy at {idx} from {s} at label {lam.get(s)} but frame {f}') + if t in lam and lam[t] != f: bad('G3', f'copy into {t} declared at {lam[t]} but frame {f}') + lam[t] = f; live.add(t[1]); centre_copy_frame[t[1]] = f + elif kind == 'scale': + if t[0] == 'L': touch(t[1], idx) + if lam.get(t) != f: bad('G0', f'scale at {idx} {t} label {lam.get(t)} frame {f}') + elif kind == 'clear': + if t[0] != 'C': bad('G3', f'clear of a non-private register at {idx}') + lam[t] = f; live.discard(t[1]) + else: bad('G0', f'unknown scalar {kind}') + elif tag == 'climb': + _, part, r, a, b, rk = e; touch(r, idx) + if part != ph: bad('ORDER', f'climb at {idx} tagged {part} in phase {ph}') + if live: bad('G3', f'climb at {idx} of {r} while centre copy {sorted(live)} live') + if lam[('L', r)] != a: bad('G2', f'climb at {idx} of {r} from {a} but label {lam[("L", r)]}') + if not (Fr.sub(a, b) and Fr.dim[b] > Fr.dim[a]): bad('G2', f'climb at {idx} of {r} {a}->{b} not ascending nested') + if rk != Fr.dim[b] - Fr.dim[a]: bad('ACC', f'climb at {idx} charged {rk} != {Fr.dim[b] - Fr.dim[a]}') + lam[('L', r)] = b; paid[rk] += 1; climb_mass[r] += rk + elif tag == 'center': + _, k, a, b, rk = e; C = ('C', k) + if ph != 'centers': bad('ORDER', f'centre step at {idx} outside centre phase') + if lam.get(C) != a: bad('G3', f'centre step at {idx}: copy {k} at {lam.get(C)} not {a}') + if not back: + if not (Fr.sub(b, a) and Fr.dim[a] > Fr.dim[b]): bad('G3', f'centre step at {idx} {a}->{b} not a strict nested descent') + else: + if not (Fr.sub(a, b) and Fr.dim[b] > Fr.dim[a]): bad('G3', f'centre step at {idx} {a}->{b} not a strict nested ascent') + if rk != abs(Fr.dim[a] - Fr.dim[b]): bad('ACC', f'centre step at {idx} charged {rk}') + if k not in live: bad('G3', f'centre step at {idx} on a dead copy {k}') + lam[C] = b; paid[rk] += 1; centre_steps[k].append((a, b)) + elif tag == 'adapter': + _, way, r, f = e; touch(r, idx) + if way == 'old_to_new' and r in entering: bad('G1', f'entry adapter on entering helper {r} at {idx} (a physical T_E)') + if way == 'new_to_old' and r in entering and final[r] != 1: bad('G1', f'exit adapter of entering helper {r} not at FULL') + if way == 'old_to_new': + if ph != 'entry_adapters' or f != start[r] or lam[('L', r)] != f: bad('G4', f'entry adapter {r} frame {f}') + elif way == 'new_to_old': + if ph != 'exit_adapters' or f != final[r] or lam[('L', r)] != f: bad('G4', f'exit adapter {r} frame {f}') + else: bad('G4', f'unknown adapter {way}') + elif tag == 'residual_adapter': + _, side, r, f = e + if r not in entering: bad('G1', f'wrapper on non-entering register {r}') + if f != start[r]: bad('G1', f'wrapper {side} of {r} at frame {f} but start {start[r]}') + if side == 'pre': + if r in pre or r in first_touch: bad('G1', f'pre wrapper of {r} not the first event touching it') + if ph != 'entry_adapters': bad('G1', f'pre wrapper of {r} outside entry adapters') + pre[r] = idx; first_touch.setdefault(r, idx) + elif side == 'post': + if r in post: bad('G1', f'second post wrapper on {r}') + if ph != 'full_frame_cleanup' or lam[('L', r)] != final[r]: bad('G1', f'post wrapper of {r} not after the full-frame cleanup') + post[r] = idx + else: bad('G1', f'unknown wrapper side {side}') + else: bad('ORDER', f'unknown event {tag}') + if phase != len(PHASES) - 1: bad('ORDER', 'stream does not end with done') + for r in entering: + if r not in pre: bad('G1', f'entering helper {r} without pre wrapper') + if r not in post: bad('G1', f'entering helper {r} without post wrapper') + if touched_after_post: bad('G1', f'registers touched after their post wrapper: {sorted(touched_after_post)[:5]}') + for r in range(n): + if lam[('L', r)] != final[r]: bad('G4', f'register {r} ends at {lam[("L", r)]} not {final[r]}') + if climb_mass[r] != Fr.dim[final[r]] - Fr.dim[start[r]]: bad('ACC', f'climb mass of {r} does not telescope') + if live: bad('G3', f'copies live at the end {sorted(live)}') + cmass = {} + for k, cf in enumerate(c['center_frames']): + st = centre_steps.get(k, []) + cmass[k] = sum(abs(Fr.dim[a] - Fr.dim[b]) for a, b in st) + bottom = (st[-1][1] if st else cf) if not back else (st[0][0] if st else cf) + if Fr.dim[bottom] != 0: bad('ACC', f'centre {k} bottom level {bottom} is not 0 (lowering mass {cmass[k]} < dim c_k)') + if cmass[k] != Fr.dim[cf]: bad('ACC', f'centre {k} lowering mass {cmass[k]} != dim c_k {Fr.dim[cf]}') + if dict(paid) != {int(r): z for r, z in c['local_profile'].items()}: bad('ACC', f'paid profile {dict(paid)} != word {c["local_profile"]}') + info = dict(entering=len(entering), entrance_rank=sum(Fr.dim[start[r]] for r in entering), paid_profile=dict(sorted(paid.items())), + local_mass=sum(k * z for k, z in paid.items()), nonzero_frame_gates=len(gates_at_nonzero), + centre_paths={k: [s for s in st] for k, st in centre_steps.items()}) + return viol, info, gates_at_nonzero + + +def scalar_replay(c, events, back): + """exact rational replay of the stream with frames stripped; returns list of violations ('S', msg)""" + v, R = c['v'], c['R']; n = 2 * v + R + st = {('L', r): {r: Q(1)} for r in range(n)} + for e in events: + if e[0] != 'scalar': continue + op = e[1]; t = tuple(op[1]); k = op[0] + if k == 'clear': st[t] = {} + elif k == 'copy': st[t] = dict(st.get(tuple(op[2]), {})) + elif k == 'scale': + q = Q(op[2], op[3]); st[t] = {j: q * x for j, x in st[t].items()} + else: + s = tuple(op[2]); q = Q(op[3], op[4]); row = st.setdefault(t, {}) + for j, x in list(st.get(s, {}).items()): + z = row.get(j, Q(0)) + q * x + if z: row[j] = z + else: row.pop(j, None) + viol = [] + for r in range(n): + exp = {r: Q(1)} + if back and r < v: exp[v + r] = Q(-1) + if not back and v <= r < 2 * v: exp[r - v] = Q(1) + if st[('L', r)] != exp: viol.append(('S', f'column mismatch at register {r}')) + if len(viol) > 20: break + for t, row in st.items(): + if t[0] == 'C' and row: viol.append(('S', f'private copy {t} not cleared')) + return viol + + +def classify(c, gates): + """lemma instances among the nonzero-frame gates: gauge compensations (target <- entering helper) and kernel updates (helper <- helper)""" + v = c['v']; start = c['start'] + comp = [g for g in gates if g[1] == 'A' and v <= g[2] < 2 * v and start[g[3]] != 0 and g[4] == start[g[3]]] + kern = [g for g in gates if g[1] == 'A' and g[2] >= 2 * v and g[3] >= 2 * v and start[g[3]] != 0 and g[4] == start[g[3]]] + return comp, kern diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/lg_mutants.py b/research/e8-complex-gauge-kernel/code/lemmaG/lg_mutants.py new file mode 100644 index 0000000000..839319cbf6 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/lg_mutants.py @@ -0,0 +1,185 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +"""Necessity controls for Lemma G on the headline word: each mutant edits the EMITTED stream (and, where stated, the start label) so +that exactly one clause is violated. For each mutant we report + checker : the clauses lg_lib flags (label checker + exact scalar replay) -- must be non-empty (mutant rejected) + physics : whether the exact physical identity still holds (targeted + random columns; transitions without a recipe are executed + as T_b T_a^-1). FAIL => the clause is needed for the operator identity; PASS => the clause is an accounting clause + (paid children / rank mass / lifetimes), needed for the cost certificate, not for exactness.""" +import copy, json, random, sys, time +from lg_lib import load, check_labels, scalar_replay, Frames, rank2 +from lg_phys import Model, run, expected, compare +from gd import GD +import os +SP = os.environ['LG_BASE'] # the output directory of verify.py: //{split-centres,hosted} +d = load(f'{SP}/gauge80-kernel42'); c0 = d['c']; m = Model(d); v = c0['v']; start = c0['start']; Fr = Frames(c0['frames']) +FW, BW = d['progs']['forward'], d['progs']['backward'] +iA = FW.index(['phase', 'A']); iC = FW.index(['phase', 'centers']); iB = FW.index(['phase', 'B']) + + +def comp_gates(ev): + out = [] + for i in range(iA + 1, iC): + e = ev[i] + if e[0] == 'scalar' and e[1][0] == 'add': + t, s = e[1][1][1], e[1][2][1] + if v <= t < 2 * v and start[s] != 0 and e[2] == start[s]: out.append(i) + return out + + +def climbs_of(ev, r, lo=0, hi=None): + return [i for i in range(lo, hi or len(ev)) if ev[i][0] == 'climb' and ev[i][2] == r] + + +def both(fn): + """apply an index-based edit to forward and backward alike (outside the centre phase the streams are aligned)""" + return fn(copy.deepcopy(FW), 'forward'), fn(copy.deepcopy(BW), 'backward') + + +def physics(fw, bw, regs, orients=('forward', 'backward')): + rng = random.Random(7); cols = [(r, b) for r in regs for b in (0, rng.randrange(1, 512))] + [(rng.randrange(m.n), rng.randrange(512)) for _ in range(8)] + init = {} + for ci, (r, b) in enumerate(cols): init.setdefault(('L', r), GD.zeros(len(cols))).re[b, ci] = 1 + res = {} + for o, ev in (('forward', fw), ('backward', bw)): + if o not in orients or ev is None: continue + try: + got = run(m, ev, init, mode='fallback'); bad, left = compare(m, got, expected(m, init, o == 'backward')) + res[o] = 'PASS' if not bad and not left else f'FAIL (registers {bad[:4]})' + except Exception as ex: res[o] = f'FAIL ({type(ex).__name__}: {ex})' + return res + + +def checker(fw, bw, c=None): + c = c or c0; out = set(); msgs = [] + for o, ev in (('forward', fw), ('backward', bw)): + if ev is None: continue + viol, info, _ = check_labels(c, ev, o == 'backward'); sv = scalar_replay(c, ev, o == 'backward') + out |= {x[0] for x in viol + sv}; msgs += [f'{o}: {x[0]} {x[1]}' for x in (viol + sv)[:2]] + return sorted(out), msgs[:3] + + +R = [] +def record(name, clause, fw, bw, regs, c=None, orients=('forward', 'backward')): + t = time.time(); flags, msgs = checker(fw, bw, c); ph = physics(fw, bw, regs, orients) + R.append(dict(mutant=name, violates=clause, checker_flags=flags, rejected=bool(flags), first_messages=msgs, physics=ph, seconds=round(time.time() - t, 1))) + print(json.dumps(R[-1]), flush=True) + + +# ---------- choose instances --------------------------------------------------------------------------------------- +CG = comp_gates(FW) +# a target whose comps span two levels E1 < E2 with the climb E1 -> E2 in between +tgt2 = None +for i in CG: + t = FW[i][1][1][1]; cl = climbs_of(FW, t, iA, iC) + if len(cl) == 2: tgt2 = t; break +g0 = CG[0]; t0_, s0_ = FW[g0][1][1][1], FW[g0][1][2][1]; E0 = FW[g0][2] + +# M1 G0 at a compensation gate: the target is NOT at E_j (its climb 0->E removed; next climb starts at 0) +def m1(ev, o): + cl = climbs_of(ev, t0_, iA, None); a = cl[0]; assert ev[a][3] == 0 and ev[a][4] == E0 and a < g0 + nxt = cl[1]; ev[nxt] = ['climb', ev[nxt][1], t0_, 0, ev[nxt][4], Fr.dim[ev[nxt][4]]]; del ev[a]; return ev +fw, bw = both(m1); record('M1 compensation gate with the target still at label 0', 'G0 (common label at a nonzero-frame compensation)', fw, bw, [t0_, s0_]) + +# M2 G1 virtual entrance violated: a physical T_E (climb 0 -> E) is executed on the helper; its start is declared 0 +def m2(ev, o): + i = ev.index(['phase', 'A']); ev.insert(i + 1, ['climb', 'A', s0_, 0, start[s0_], Fr.dim[start[s0_]]]); return ev +c2 = copy.deepcopy(c0); c2['start'][s0_] = 0 +fw, bw = both(m2); record('M2 physical T_E on an entering helper (no virtual entrance)', 'G1 (virtual entrance)', fw, bw, [s0_], c=c2) + +# M3 G2 (target chain monotone; the (b) condition): the target visits its levels out of nesting order (E2 first, descends to E1) +def m3(ev, o): + t = tgt2; cl = climbs_of(ev, t, iA, iC); a, b = cl[0], cl[1] # 0->E1 at a, E1->E2 at b + E1, E2 = ev[a][4], ev[b][4]; assert Fr.sub(E1, E2) + g1 = [i for i in range(a + 1, b) if ev[i][0] == 'scalar' and ev[i][1][0] == 'add' and t in (ev[i][1][1][1], ev[i][1][2][1])] + E1g = [ev[i] for i in g1] + for i in reversed(g1): del ev[i] + b -= len(g1); ev[a] = ['climb', 'A', t, 0, E2, Fr.dim[E2]]; del ev[b] + iCm = ev.index(['phase', 'centers']) + last = max(i for i in range(a, iCm) if ev[i][0] == 'scalar' and ev[i][1][0] == 'add' and t in (ev[i][1][1][1], ev[i][1][2][1])) + ins = [['climb', 'A', t, E2, E1, Fr.dim[E1] - Fr.dim[E2]]] + E1g + [['climb', 'A', t, E1, E2, Fr.dim[E2] - Fr.dim[E1]]] + ev[last + 1:last + 1] = ins; return ev +fw, bw = both(m3); record('M3 target visits its entrance levels out of nesting order (descends E2 -> E1)', 'G2 (monotone nested chain; selection condition (b))', fw, bw, [tgt2]) + +# M3b G2 for a helper (selection condition (a)): the entering helper's first climb detours through a frame that does not contain E_j +def m3b(ev, o): + cl = climbs_of(ev, s0_); i = cl[0]; a, b = ev[i][3], ev[i][4] + X = next(f for f in range(len(Fr.F)) if Fr.dim[f] == Fr.dim[a] and not Fr.sub(a, f) and Fr.sub(f, b)) + ev[i:i + 1] = [['climb', ev[i][1], s0_, a, X, 0], ['climb', ev[i][1], s0_, X, b, Fr.dim[b] - Fr.dim[X]]]; return ev +fw, bw = both(m3b); record('M3b entering helper leaves the nested chain (E_j -> X -> F, X not containing E_j)', 'G2 (monotone nested chain; selection condition (a))', fw, bw, [s0_]) + +# centre mutants (forward stream; the centre phase is orientation specific) +cents = {} +for i in range(iC + 1, iB): + e = FW[i] + if e[0] == 'center': cents.setdefault(e[1], []).append(i) +kdeep = next(k for k, L in cents.items() if len(L) >= 3) # a centre with a chain c_k -> L1 -> L2 -> ... -> 0 +st = cents[kdeep]; rk = c0['centers'][kdeep] +scat_after = lambda i: [j for j in range(i + 1, iB) if FW[j][0] == 'scalar' and FW[j][1][0] == 'add' and FW[j][1][2] == ['C', kdeep] and all(FW[q][0] != 'center' for q in range(i + 1, j))] +lev1 = scat_after(st[0]) # scatters at the first served level L1 != 0 +tl = FW[lev1[0]][1][1][1] + +def m4(ev, o): # scatter into a level-L1 target after the copy has descended further + e = ev[lev1[0]]; del ev[lev1[0]]; j = st[1] # st[1] index shifts by one + ev.insert(j, e); return ev +record('M4 scatter into a level-L1 target after the copy descended below L1', 'G3 (scatter meets the target at its level)', m4(copy.deepcopy(FW), 'f'), None, [rk, tl], orients=('forward',)) + +def m5(ev, o): # the last descent L_last -> 0 skipped; level-0 targets scattered at L_last + j = st[-1]; del ev[j]; return ev +r5 = [FW[j][1][1][1] for j in scat_after(st[-1])][:2] +record('M5 last centre descent step skipped (level-0 targets scattered at L_last)', 'G3 (chain reaches every served level; bottom 0)', m5(copy.deepcopy(FW), 'f'), None, [rk] + r5, orients=('forward',)) + +def m6(ev, o): # copy made after the first descent: the copy is declared at L1 while the centre register is at c_k + cp = next(j for j in range(iC, st[0]) if ev[j][0] == 'scalar' and ev[j][1][0] == 'copy' and ev[j][1][1] == ['C', kdeep]) + e = ev[cp]; del ev[cp]; ev.insert(st[0], ['scalar', e[1], FW[st[0]][3]]); return ev +record('M6 centre copy taken at the wrong label (after the first descent)', 'G3 (copy at the centre label c_k)', m6(copy.deepcopy(FW), 'f'), None, [rk, tl], orients=('forward',)) + +def m7(ev, o): # a climb of an unrelated register moved inside a live centre phase + touched = {x[1] for e in ev[iC:iB] if e[0] == 'scalar' for x in e[1][1:] if isinstance(x, list) and x[0] == 'L'} + def free(i): # no event touches the register between the centre phase and this climb + r = ev[i][2] + for q in range(iC, i): + e = ev[q] + if e[0] in ('climb',) and e[2] == r: return False + if e[0] == 'scalar' and any(isinstance(x, list) and x == ['L', r] for x in e[1][1:]): return False + return True + j = next(i for i in range(iB, len(ev)) if ev[i][0] == 'climb' and ev[i][2] not in touched and free(i)); e = ev[j]; del ev[j] + ev.insert(st[0] + 1, ['climb', 'centers', e[2], e[3], e[4], e[5]]); return ev +fw7 = m7(copy.deepcopy(FW), 'f'); r7 = fw7[st[0] + 1][2] +record('M7 a child of another register runs while a centre copy is live', 'G3 (copy lifetime)', fw7, None, [r7, rk], orients=('forward',)) + +def m8(ev, o): # a centre step detours through a frame outside the centre frame (chain not inside c_k) + j = st[0]; a, b = ev[j][2], ev[j][3] + X = next(f for f in range(len(Fr.F)) if Fr.dim[f] == Fr.dim[b] + 1 and Fr.sub(b, f) and not Fr.sub(f, a)) + ev[j:j + 1] = [['center', kdeep, a, X, Fr.dim[a] - Fr.dim[X]], ['center', kdeep, X, b, 1]]; return ev +record('M8 centre chain leaves the centre frame (c_k -> X -> L1, X not inside c_k)', 'G3 (nested chain inside c_k; selection condition (c))', m8(copy.deepcopy(FW), 'f'), None, [rk, tl], orients=('forward',)) + +# M9 coefficient of one compensation doubled (labels intact) +def m9(ev, o): + e = ev[g0]; e[1][3] *= 2; return ev +fw, bw = both(m9); record('M9 compensation coefficient doubled', 'S (scalar identity)', fw, bw, [t0_, s0_]) + +# M10 compensation executed after the helper's first climb (not as the first gate on j) +def m10(ev, o): + e = ev[g0]; j = climbs_of(ev, s0_)[0]; del ev[g0]; ev.insert(j, e); return ev +fw, bw = both(m10); record('M10 compensation moved after the helper started climbing', 'G0 + S (compensation reads the entrance value)', fw, bw, [t0_, s0_]) + +# M11 kernel update with the donor still at label 0 +kg = next(i for i in range(iA + 1, iC) if FW[i][0] == 'scalar' and FW[i][1][0] == 'add' and FW[i][1][1][1] >= 2 * v and start[FW[i][1][2][1]] != 0 and FW[i][2] != 0) +dn = FW[kg][1][1][1] +def m11(ev, o): + cl = climbs_of(ev, dn); a = cl[0]; assert ev[a][3] == 0 and a < kg + ev[cl[1]] = ['climb', ev[cl[1]][1], dn, 0, ev[cl[1]][4], Fr.dim[ev[cl[1]][4]]]; del ev[a]; return ev +fw, bw = both(m11); record('M11 kernel donor update with the donor still at label 0', 'G0 (common label at a nonzero-frame kernel update; inherited #471)', fw, bw, [dn, FW[kg][1][2][1]]) + +# M12 pre wrapper after the helper's first gate +def m12(ev, o): + p = ev.index(['residual_adapter', 'pre', s0_, start[s0_]]); e = ev[p]; del ev[p]; ev.insert(g0, e); return ev +fw, bw = both(m12); record('M12 R_E^-1 wrapper after the first gate on the helper', 'G1 (wrapper surrounds the whole invocation)', fw, bw, [s0_, t0_]) + +# M13 post wrapper dropped +def m13(ev, o): + ev.remove(['residual_adapter', 'post', s0_, start[s0_]]); return ev +fw, bw = both(m13); record('M13 L_E^-1 wrapper dropped', 'G1 (wrapper surrounds the whole invocation)', fw, bw, [s0_]) + +json.dump(R, open('MUTANTS.json', 'w'), indent=1) +print('rejected by the checker:', sum(r['rejected'] for r in R), '/', len(R)) diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/lg_phys.py b/research/e8-complex-gauge-kernel/code/lemmaG/lg_phys.py new file mode 100644 index 0000000000..4b92387237 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/lg_phys.py @@ -0,0 +1,137 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +"""Exact physical simulation of an emitted local program on C^(2^9) registers (Gaussian-dyadic, int64 with overflow guard). + +Transitions are executed with the SERIALIZED child recipes (CLIFFORD-RECIPES.json, decoded here), data adapters with the serialized +endpoint monomials, entering-helper wrappers with the serialized RESIDUAL-ADAPTERS monomials. Expected values are computed from +DEFINITIONS only (canonical frames, the port gate C_q, the Fourier gate), never from recipes. +""" +import sys +import numpy as np +from gd import GD, circ_of, monomial_circ, recipe_circ, fourier_circ, basis_batch, N +from pathlib import Path +VENDOR = str(Path(__file__).resolve().parents[3] / 'split-centres-global/vendor') # the vendored clifford_exact of PR #433/#442 (definitions of T_F and C_q only) +sys.path.insert(0, VENDOR) +import clifford_exact as ce # used ONLY for the definitions canonical_frame / cgate (label family and port gate) + +n9 = 9 + + +class Model: + def __init__(self, d): + self.c = c = d['c']; self.v = c['v']; self.R = c['R']; self.n = 2 * c['v'] + c['R'] + self.frames = [tuple(f) for f in c['frames']] + self.children = {(r['old'], r['new']): recipe_circ(r) for r in d['rec']['children']} + self.src_ad = {}; self.tgt_ad = {} + for a in d['rec']['endpoint_adapters']: + (self.src_ad if a['role'] == 'source' else self.tgt_ad)[a['port']] = (a['frame'], monomial_circ(a['left']) if a['rank'] == 0 else None) + self.wraps = {int(f): (monomial_circ(w['right']), monomial_circ(w['left']), w['rank']) for f, w in d['wraps'].items()} + self._T = {} + # ---- definitions --------------------------------------------------------------------------------------------- + def T(self, f): + if f not in self._T: self._T[f] = circ_of(ce.canonical_frame(n9, self.frames[f])) + return self._T[f] + def def_transition(self, g, a, b): # T_b T_a^-1 + return g.apply_circ(self.T(a), inverse=True).apply_circ(self.T(b)) + def Cq(self, i): return circ_of(ce.cgate(n9, self.c['ports'][i])) + # ---- serialized operators ------------------------------------------------------------------------------------ + def rec_transition(self, g, a, b): + return g.apply_circ(self.children[(a, b)]) + + +def run(model, events, init, mode='recipe', regs=None, stop=None): + """apply `events` physically to state `init` (dict reg -> GD, missing = 0). regs: optional set of registers to simulate + (events touching other registers are an error unless their operands are all zero). Returns the state.""" + st = {x: y.copy() for x, y in init.items()}; k = next(iter(st.values())).k() + if mode == 'recipe': trans = model.rec_transition + elif mode == 'def': trans = model.def_transition + else: # mutants only: a transition without a serialized recipe is executed as T_b T_a^-1 + trans = lambda g, a, b: model.rec_transition(g, a, b) if (a, b) in model.children else model.def_transition(g, a, b) + def get(x): return st.get(x) + for idx, e in enumerate(events): + if stop is not None and idx >= stop: break + tag = e[0] + if tag == 'phase': continue + if tag == 'scalar': + op = e[1]; t = tuple(op[1]); kind = op[0] + if kind == 'clear': st.pop(t, None) + elif kind == 'copy': + s = get(tuple(op[2])); st.pop(t, None) + if s is not None: st[t] = s.copy() + elif kind == 'scale': + if t in st: st[t].scale(op[2], op[3]) if op[3] > 0 else st[t].scale(-op[2], -op[3]) + else: + s = get(tuple(op[2])) + if s is None: continue + num, den = op[3], op[4] + if den < 0: num, den = -num, -den + if t not in st: st[t] = GD.zeros(k) + st[t].add_scaled(s, num, den) + elif tag == 'climb': + _, part, r, a, b, rk = e + if ('L', r) in st: trans(st[('L', r)], a, b) + elif tag == 'center': + _, kk, a, b, rk = e + if ('C', kk) in st: trans(st[('C', kk)], a, b) + elif tag == 'adapter': + _, way, r, f = e; x = st.get(('L', r)) + if way == 'old_to_new': + if r < model.v: + fr, circ = model.src_ad[r]; assert fr == f + if x is not None: x.apply_circ(circ) + else: assert f == 0, ('unexpected non-identity entry adapter', r, f) + else: + if model.v <= r < 2 * model.v: + fr, circ = model.tgt_ad[r - model.v]; assert fr == f + if x is not None: x.apply_circ(circ, inverse=True) + else: assert f == 1, ('unexpected non-identity exit adapter', r, f) + elif tag == 'residual_adapter': + _, side, r, f = e; x = st.get(('L', r)) + Rc, Lc, w = model.wraps[f] + if x is not None: x.apply_circ(Rc if side == 'pre' else Lc, inverse=True) + else: raise ValueError(e) + return st + + +def expected(model, init, back): + """intended transform from DEFINITIONS: data shear in the old representation, helpers C_[w] (x) I""" + v, n, c = model.v, model.n, model.c + F = fourier_circ(range(9)); k = next(iter(init.values())).k() + out = {} + def g(r): return init.get(('L', r)) + def add(r, x): + if x is None: return + if r in out: out[r].add_scaled(x, 1, 1) + else: out[r] = x + for i in range(v): + Cq = model.Cq(i); hs, ht = g(i), g(v + i) + xs = hs.copy().apply_circ(Cq, inverse=True) if hs is not None else None # logical source C_q^-1 h_s + if not back: + add(i, xs.copy().apply_circ(F) if xs is not None else None) + yt = ht.copy() if ht is not None else None + if xs is not None: + yt = yt if yt is not None else GD.zeros(k); yt.add_scaled(xs, 1, 1) + if yt is not None: add(v + i, yt.apply_circ(Cq, inverse=True).apply_circ(F)) + else: + z = xs.copy() if xs is not None else None + if ht is not None: + z = z if z is not None else GD.zeros(k); z.add_scaled(ht, -1, 1) + if z is not None: add(i, z.apply_circ(F)) + if ht is not None: add(v + i, ht.copy().apply_circ(Cq, inverse=True).apply_circ(F)) + for r in range(2 * v, n): + h = g(r) + if h is None: continue + w = 9 - len(model.frames[c['start'][r]]) + add(r, h.copy().apply_circ(fourier_circ(range(w)))) + return out + + +def compare(model, got, exp): + bad = [] + for r in range(model.n): + a = got.get(('L', r)); b = exp.get(r) + if a is None and b is None: continue + if a is None: a = GD.zeros(b.k()) + if b is None: b = GD.zeros(a.k()) + if not a.equals(b): bad.append(r) + leftovers = [x for x, y in got.items() if x[0] == 'C' and not y.is_zero()] + return bad, leftovers diff --git a/research/e8-complex-gauge-kernel/code/lemmaG/run_labels.py b/research/e8-complex-gauge-kernel/code/lemmaG/run_labels.py new file mode 100644 index 0000000000..5d10da278a --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/lemmaG/run_labels.py @@ -0,0 +1,23 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. Independent Lemma G checker: imports no package script. +import sys, time, json +from lg_lib import * +import os +SP=os.environ['LG_BASE'] # the output directory of verify.py: //{split-centres,hosted} +out={} +for name in sys.argv[1:]: + t=time.time(); d=load(f'{SP}/{name}') + c=d['c']; res={'inputs':d['shas']} + for o in ('forward','backward'): + ev=d['progs'][o]; back=o=='backward' + viol,info,gates=check_labels(c,ev,back); sv=scalar_replay(c,ev,back) + comp,kern=classify(c,gates) + res[o]=dict(label_violations=viol[:10],n_label_violations=len(viol),scalar_violations=sv[:5],events=len(ev),sha256=digest(ev), + compensation_gates=len(comp),kernel_updates=len(kern),**{k:v for k,v in info.items() if k!='centre_paths'}) + calls=d['tpl']['calls'] if d['tpl'] else [] + res['calls']=dict(n=len(calls),ok=all(cl['local_program_sha256']==res[cl['orientation']]['sha256'] for cl in calls), + orient=dict(__import__('collections').Counter(cl['orientation'] for cl in calls))) + res['seconds']=round(time.time()-t,1); out[name]=res + print(name, json.dumps({o:{k:res[o][k] for k in ('n_label_violations','scalar_violations','compensation_gates','kernel_updates','entering','entrance_rank','local_mass','paid_profile')} for o in ('forward','backward')}), res['calls'], res['seconds'],flush=True) + for o in ('forward','backward'): + for x in res[o]['label_violations'][:5]: print(' ',o,x) +json.dump(out,open('LABELS-'+'-'.join(sys.argv[1:])+'.json','w'),indent=1) diff --git a/research/e8-complex-gauge-kernel/code/make_meta.py b/research/e8-complex-gauge-kernel/code/make_meta.py new file mode 100644 index 0000000000..af22530f71 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/make_meta.py @@ -0,0 +1,12 @@ +"""Write SOURCE.json (inventories of the upstream packages this package runs) and MANIFEST.json (this package's files). Apache-2.0. +usage: python -B research/e8-complex-gauge-kernel/code/make_meta.py""" +import hashlib, json +from pathlib import Path +ROOT = Path(__file__).resolve().parent.parent; R = ROOT.parent +sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest() +def inventory(p): return {f.relative_to(p).as_posix(): sha(f) for f in sorted(Path(p).rglob('*')) if f.is_file() and '__pycache__' not in f.parts} +packages = ['idle-axis-hosting', 'split-centres-global', 'e8-early-reset-kernel', 'e8-early-reset-reuse'] +(ROOT / 'SOURCE.json').write_text(json.dumps(dict(note='inventories of the packages of PR #442 and its parents that verify.py runs unchanged', packages={p: dict(files=inventory(R / p)) for p in packages}), indent=1, sort_keys=True) + '\n') +inv = inventory(ROOT); inv.pop('MANIFEST.json', None) +(ROOT / 'MANIFEST.json').write_text(json.dumps(dict(files=inv), indent=1, sort_keys=True) + '\n') +print('SOURCE.json and MANIFEST.json written;', len(inv), 'files') diff --git a/research/e8-complex-gauge-kernel/code/onehost_gk.py b/research/e8-complex-gauge-kernel/code/onehost_gk.py new file mode 100644 index 0000000000..220cc7a2f5 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/onehost_gk.py @@ -0,0 +1,111 @@ +"""Whole-residual idle-axis hosting with at most ONE helper per physical family per invocation (the rule of PR #458), plus the exact +host chart with explicit spectator coordinates. Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +A copy (port) of an idle child hosts a PATTERN: residuals of pairwise distinct stages inside the child's window, offsets 0, w1, w1+w2, ... +(a residual is whole: one slot in one family). The children of one (pair, side) have pairwise disjoint windows (checked), so the +families they share never host two helpers of one invocation, and the integer programme needs only the distinct-stage condition. +Chart: for the host's port q the parent's idle basis is B_q = U_q (+) I (PR #433 geometry; the construction is that of PR #458). A hosted +residual of width w occupies the pending vectors b_off..b_(off+w-1) of its child; the other e = 9 - w coordinates of the local nine are +SPECTATORS: the first e basis indices of B_q not occupied by the residual, in increasing order. The paid wrappers (adapters_gk.py) act on +these nine coordinates and restore the spectators identically.""" +import math +from collections import Counter + +H, M = 9, 73 + + +def cost(r, m): return r * math.log(m / r) if r else 0.0 + + +def patterns(rank, stages, widths): + out = [()] + ws = sorted(widths, reverse=True) + def rec(i, cur, tot): + for j in range(i, len(stages)): + for w in ws: + if tot + w <= rank: + c = cur + [(stages[j], w)]; out.append(tuple(c)); rec(j + 1, c, tot + w) + rec(0, [], 0) + return out + + +def solve(win, copies, avail, m, pad_value, time_limit=600): + """win {idx: (pair, rank, stages)}, avail {(stage, width): helpers per replica}. Maximise saved idle cost (+ pad_value per hosted residual).""" + import numpy as np + from scipy.optimize import milp, LinearConstraint, Bounds + widths = sorted({w for (_, w) in avail}); var = [] + for idx, (p, r, st) in sorted(win.items()): + for pat in patterns(r, sorted(st), widths): var.append((idx, pat)) + n = len(var); c = np.zeros(n) + for j, (idx, pat) in enumerate(var): + r = win[idx][1]; c[j] = -(cost(r, m) - cost(r - sum(w for _, w in pat), m) + pad_value * len(pat)) + rows, lo, hi = [], [], [] + by = {} + for j, (idx, pat) in enumerate(var): by.setdefault(idx, []).append(j) + for idx, js in by.items(): + row = np.zeros(n); row[js] = 1; rows.append(row); lo.append(copies); hi.append(copies) + for (s, w), a in sorted(avail.items()): + row = np.zeros(n) + for j, (idx, pat) in enumerate(var): row[j] = sum(1 for sw in pat if sw == (s, w)) + rows.append(row); lo.append(0); hi.append(a) + res = milp(c, constraints=LinearConstraint(np.array(rows), lo, hi), integrality=np.ones(n), bounds=Bounds(np.zeros(n), np.full(n, np.inf)), + options=dict(time_limit=time_limit, disp=False)) + assert res.x is not None, res.message + x = [int(round(t)) for t in res.x] + return [[idx, [list(sw) for sw in pat], x[j]] for j, (idx, pat) in enumerate(var) if x[j]], -res.fun + + +def save(path, key, sel, val): + import json + from pathlib import Path + p = Path(path); d = json.loads(p.read_text()) if p.exists() else {} + d[key] = dict(rule='one-helper-per-family', patterns=sorted(sel), proxy_saving=val) + p.write_text(json.dumps(d, indent=1, sort_keys=True) + '\n') + + +def load(path, key): + import json + from pathlib import Path + d = json.loads(Path(path).read_text())[key]; assert d['rule'] == 'one-helper-per-family' + return d['patterns'], d['proxy_saving'] + + +def check_disjoint_groups(win, pair_of, side_of): + """children of one (pair, side) share their physical families; their windows must be disjoint""" + seen = {} + for idx, (p, r, st) in win.items(): + for s in st: + k = (pair_of[idx], side_of[idx], s); assert k not in seen, ('windows of two children of one family group overlap', idx, seen[k], k); seen[k] = idx + + +def expand(win, sel, widths, V): + """-> slots [idx, port, off, w, s, h] (one replica), rem {(idx, port): remaining pending rank}""" + R = len(widths); pool = {} + for h in sorted(range(R)): pool.setdefault(widths[h], []).append(h) + pool = {(s, w): list(hs) for s in range(9) for w, hs in pool.items()} + slots = []; rem = {}; used = Counter() + for idx, pat, copies in sorted(sel, key=lambda e: (e[0], e[1])): + r = win[idx][1] + for _ in range(copies): + cp = used[idx]; used[idx] += 1; assert cp < V; off = 0 + assert len({s for s, w in pat}) == len(pat) + for s, w in pat: + assert s in win[idx][2] and off + w <= r + slots.append([idx, cp, off, w, s, pool[s, w].pop(0)]); off += w + rem[idx, cp] = r - off + assert all(n == V for n in used.values()) and len(used) == len(win) + return slots, rem + + +def idle_basis(q): + """PR #433 / #458: the parent's orthonormal idle basis U_q (+) I for port q (H = 9 local coordinates, M = 73)""" + z = next(i for i in range(H) if not (q >> i & 1)); a = q ^ (1 << z); order = list(range(H)); order[0], order[z] = order[z], order[0] + return [(1 << i) ^ (a if a >> i & 1 else 0) for i in order] + [1 << i for i in range(H, M)] + + +def spectators(q, pending, off, w): + """indices (into B_q) of the e = 9 - w spectator coordinates of a residual at pending[off:off+w]""" + B = idle_basis(q); occ = [B.index(x) for x in pending[off:off + w]] + assert len(set(occ)) == w + sp = [j for j in range(M) if j not in occ][:H - w] + assert len(sp) == H - w + return sp diff --git a/research/e8-complex-gauge-kernel/code/replay_gk.py b/research/e8-complex-gauge-kernel/code/replay_gk.py new file mode 100644 index 0000000000..b2e08a30c9 --- /dev/null +++ b/research/e8-complex-gauge-kernel/code/replay_gk.py @@ -0,0 +1,271 @@ +# GK: modified copy of PR #433's complex_replay.py (icekylinx with Codex assistance; PR #425) by DreamingOfClouds with Claude Opus 5.5 +# (Anthropic), via Claude Code. Every change is marked "GK:". On a word without start_extra / target_levels the behaviour +# and every written file equal PR #433's (regression anchor in verify.py). +import sys as _sys, os as _os; _sys.path.insert(0, _os.path.dirname(_os.path.abspath(__file__))) +# Adapted for heterogeneous centres by icekylinx with Codex assistance. +"""Independent read-back of the serialized local/global instruction stream.""" +import copy,gzip,hashlib,importlib.util,json,math +from collections import Counter +from fractions import Fraction as Q +from pathlib import Path + +OUT=Path('split-centres');P=OUT/'GLOBAL-TEMPLATE.json.gz' +ir=json.load(gzip.open(P));c=json.load(gzip.open(OUT/'CANONICAL-WORD.json.gz')) +integration=json.loads((OUT/'INTEGRATION.json').read_text()) +assert hashlib.sha256(gzip.decompress(P.read_bytes())).hexdigest()==integration['global_template_sha256'] +assert c['ports']==json.load(gzip.open('work/higher-stage-e8/verified/gcert1-e8-retimed.json.gz'))['ports'] +v,R,h=c['v'],c['R'],c['h'];n=2*v+R;frames=c['frames'] +from gk_common import tile # GK +widths=[h-len(frames[c['start'][2*v+i]]) for i in range(R)] +assign,nb,pads=tile([(rep,i,widths[i]) for rep in range(8) for i in range(R)]);W=7680+9*nb +levels={int(t):f for t,f in c.get('target_levels',{}).items()} +entering=[r for r,f in enumerate(c['start']) if r>=2*v and f!=0];plain={r for r in range(n) if r not in set(entering)} # GK +def contains(a,b): + for x in a: + for y in b: + if x>>(y.bit_length()-1)&1:x^=y + if x:return False + return True +def local(events,back): + rows={('L',r):{r:Q(1)} for r in range(n)} + norm={('L',r):Q(1) for r in range(n)};prefix=Q(1);cur=c['start'].copy();private={} + hist=Counter();phases=[];entry=[];exit=[];centers=[];matrix_hash=hashlib.sha256();chain={};wrappers=[] + allowed=['zero_frame_precondition','entry_adapters','A','centers','B','final','exit_adapters','full_frame_cleanup','done'] + for event in events: + tag=event[0] + if tag=='phase': + phases.append(event[1]);assert phases==allowed[:len(phases)] + if event[1]=='A':assert entry==[(r,f) for r,f in enumerate(c['start']) if r in plain] and sorted(r for k_,r,f_ in wrappers if k_=='pre')==entering # GK + if event[1]=='centers':assert all(cur[r]==levels.get(r-v,0) for r in range(v,2*v)) # GK + if event[1]=='full_frame_cleanup':assert cur==c['final'] and exit==list(enumerate(c['final'])) + assert not private + elif tag=='residual_adapter': # GK: paid wrappers of entering helpers: R_E^-1 before the invocation, L_E^-1 after the full-frame cleanup + _,kind,r,f=event;assert r in entering and f==c['start'][r] and kind in ('pre','post') + assert (kind=='pre' and phases[-1]=='entry_adapters') or (kind=='post' and phases[-1]=='full_frame_cleanup') + assert (kind,r) not in {(k,x) for k,x,_ in wrappers};wrappers.append((kind,r,f)) + elif tag=='adapter': + assert event[3]==(c['start'] if event[1]=='old_to_new' else c['final'])[event[2]] + (entry if event[1]=='old_to_new' else exit).append((event[2],event[3])) + elif tag=='climb': + _,part,r,a,b,rank=event + assert not private and phases[-1]==part and cur[r]==a + assert contains(frames[a],frames[b]) and rank==len(frames[b])-len(frames[a])>0 + hist[rank]+=1;cur[r]=b + elif tag=='center': + _,k,a,b,rank=event + assert phases[-1]=='centers' and private=={('C',k):a} + cf=c['center_frames'][k];cr=len(frames[cf]) + # GK: stepwise descent cf -> served levels -> lowest (forward), reversed ascent (backward); each step is a nested child + assert contains(frames[a],frames[b]) if back else contains(frames[b],frames[a]) + assert rank==abs(len(frames[a])-len(frames[b]))>0 + chain.setdefault(k,[]).append((a,b)) + private['C',k]=b;hist[rank]+=1;centers.append(k) + elif tag=='scalar': + _,e,f=event;op=e[0];target=tuple(e[1]);source=tuple(e[2]) if op in ('copy','add') else None + if target[0]=='C' and op=='clear': + assert private.get(target,f)==f + private.pop(target,None) + else: + for r in (target,source): + if r is None:continue + if r[0]=='L':assert cur[r[1]]==f,('common frame',r,cur[r[1]],f) + else: + if r==target and r not in private:private[r]=f + assert private[r]==f + if op=='clear':rows[target]={};norm[target]=Q(0) + elif op=='copy':rows[target]=dict(rows[source]);norm[target]=norm[source] + elif op=='scale': + q=Q(e[2],e[3]);a,b=abs(q.numerator),q.denominator + assert a&(a-1)==0 and b&(b-1)==0 + rows[target]={j:q*x for j,x in rows[target].items()};norm[target]*=abs(q) + else: + q=Q(e[3],e[4]);a,b=abs(q.numerator),q.denominator + assert source!=target and b&(b-1)==0 + # Independent symbolic replay of the cleared coefficient work. + w=0 + for bit in bin(a)[2:]:w=2*w+int(bit) + assert Q(w,b)*(1 if q>0 else -1)==q + prefix=max(prefix,Q(a)*norm[source]) + norm[target]=norm.get(target,Q(0))+abs(q)*norm[source] + row=rows.setdefault(target,{}) + for j,x in list(rows[source].items()): + z=row.get(j,Q(0))+q*x + if z:row[j]=z + else:row.pop(j,None) + prefix=max(prefix,norm[target]) + else:raise AssertionError(tag) + assert phases==allowed and set(centers)==set(range(len(c['centers']))) and not private + assert sorted(r for k,r,_ in wrappers if k=='pre')==entering and sorted(r for k,r,_ in wrappers if k=='post')==entering # GK + for k,st in chain.items(): # GK: the steps of each centre chain link up and end at the centre frame + cf=c['center_frames'][k] + if back:assert st[-1][1]==cf and all(st[i][1]==st[i+1][0] for i in range(len(st)-1)) + else:assert st[0][0]==cf and all(st[i][1]==st[i+1][0] for i in range(len(st)-1)) + assert all(not row for reg,row in rows.items() if reg[0]=='C') + for r in range(n): + expected={r:Q(1)} + if back and r= W). sole=False skips only the + sole-owner assertion (used by a control to show that the footprints themselves are fine).""" + fam=Counter(f for f,_ in owners);foot={} + for i,(f,route) in enumerate(owners): + assert f=240 and route[0]==2,('bank class: helpers only',i,f);w=widths[i-240] + if w==9: assert len(route)==2,('width-9 helper in a pure bank',i) + else: + if sole: assert fam[f]==1,('entering helper shares its bank family in one invocation',i,f) + assert len(route)==4 and route[2]==w and len(set(route[3]))==9-w==len(route[3]),('entering helper without a spectator record',i) + assert route[3]==list(range(len(occ[f]),len(occ[f])+9-w)) and len(occ[f])+9-w<=73,('spectators are not the first cells beyond the residuals',i,f) + cells=residual_cells(route)|(set(route[3]) if len(route)==4 else set()) + assert len(cells)==9 and not cells&foot.setdefault(f,set()),('footprints overlap on a bank family',i,f);foot[f]|=cells +def global_check(t): + assert t['live']==W and t['physical']==W+R+len(c['centers'])+2 # GK + occ={} + for call in t['calls']: + for fam,route in call['owners'][240:]:occ.setdefault(fam,set()).update(residual_cells(route)) + assert all(cs==set(range(len(cs))) for cs in occ.values()),'bank residuals are packed from cell 0' + # Eight data-wire scalar columns, independently recomposed. + matrix=[[int(i==j) for j in range(8)] for i in range(8)] + for e in t['recipe']: + if e['kind']=='local': + a=2*e['pair'];b=a+1;dst,src,q=(a,b,-1) if e['reverse'] else (b,a,1) + matrix[dst]=[x+q*y for x,y in zip(matrix[dst],matrix[src])] + elif e['kind']=='bridge': + i,j,q=e['dst'],e['src'],e['coefficient'] + matrix[2*i]=[x+q*y for x,y in zip(matrix[2*i],matrix[2*j])] + matrix[2*j+1]=[x-q*y for x,y in zip(matrix[2*j+1],matrix[2*i+1])] + else: + assert e['kind']=='terminal';old=copy.deepcopy(matrix) + for i in range(4):matrix[2*i]=old[2*i+1];matrix[2*i+1]=[-x for x in old[2*i]] + assert matrix==[[int(i==j) for j in range(8)] for i in range(8)] + seen=set();hist=Counter();pairs={e['stage']:e for e in t['recipe'] if e['kind']=='local'} + for call in t['calls']: + stage,rep,pair=call['stage'],call['replica'],call['pair'] + assert (stage,rep) not in seen;seen.add((stage,rep)) + assert pair==pairs[stage]['pair'] + assert call['orientation']==('backward' if pairs[stage]['reverse'] else 'forward') + assert len(call['owners'])==800 + for r,(fam,route) in enumerate(call['owners']): + if r<240:assert fam==rep*960+(2*pair+r//120)*120+r%120 and route==[1,stage,r%120] + else: + bk,off_,w_,pure_,sp_=assign[rep,r-240];assert fam==7680+stage*nb+bk and route==([2,off_//9] if (w_==9 and pure_) else [2,off_,w_,list(sp_)]) # GK + assert len(set((f,json.dumps(r)) for f,r in call['owners']))==800 + bank_rule(call['owners'],occ) # GK: the rule on every register class, stated independently of tile() + for r,z in profiles[call['orientation']].items():hist[r]+=z + assert seen=={(s,r) for s in range(9) for r in range(8)} + for child in t['idle_children']:hist[child['rank']]+=child['replicas'] + assert t['bank_padding']=={'families':list(range(7680,W)),'axis':72,'child_rank':1} + for r_,z_ in pads.items():hist[r_]+=z_*9 # GK + assert t['cover_final_correction']['families']==[0,W] + assert t['cover_final_correction']['charged_calls_per_cover']==W + assert t['execution_schedule'][-1]=={'kind':'translate_every_live_family',**{k:v for k,v in t['cover_final_correction'].items() if k!='kind'}} + assert 73*W-sum(r*z for r,z in hist.items())==2496 + return hist +H=global_check(ir) +for name,mut in [('missing_padding',lambda t:t['bank_padding']['families'].pop()), + ('aliased_owner',lambda t:t['calls'][0]['owners'][241].__setitem__(1,[2,0])), + ('missing_cover_phase',lambda t:t['cover_final_correction'].__setitem__('charged_calls_per_cover',0))]: + t=copy.deepcopy(ir);mut(t) + try:global_check(t) + except (AssertionError,KeyError):controls.append(name) + else:raise AssertionError('global mutation accepted: '+name) +# GK: controls of the rule itself, one per register class, run on bank_rule (not on the equality with tile()); only for words with entering +# helpers (the anchor's INDEPENDENT-REPLAY.json must stay byte-identical to PR #433's) +occ_all={} +for call in ir['calls']: + for fam_,route_ in call['owners'][240:]:occ_all.setdefault(fam_,set()).update(residual_cells(route_)) +def rule_control(name,mut,must): + o=copy.deepcopy(ir['calls'][0]['owners']);mut(o) + try:bank_rule(o,occ_all) + except AssertionError as e: + assert must in str(e),(name,str(e));controls.append(name) + else:raise AssertionError('rule mutation accepted: '+name) +bank_rule(ir['calls'][0]['owners'],occ_all) +ent=[r for r in range(240,800) if widths[r-240]<9] +if entering: + a_,b_=ent[0],ent[1] + def to_one_bank(o): # bank class: b joins a's bank family at the next free cells, with a spectator of its own + fa=o[a_][0];free=len(occ_all[fa]);o[b_]=[fa,[2,free,widths[b_-240],[free+widths[b_-240]]]] + rule_control('two_entering_helpers_on_one_bank_family',to_one_bank,'shares its bank family') + rule_control('bank_spectator_is_a_residual_cell',lambda o:o[a_][1].__setitem__(3,[o[a_][1][1]]+o[a_][1][3][1:]),'first cells beyond') + rule_control('bank_spectator_shifted',lambda o:o[a_][1].__setitem__(3,[x+1 for x in o[a_][1][3]]),'first cells beyond') + rule_control('bank_spectator_record_dropped',lambda o:o[a_].__setitem__(1,o[a_][1][:3]),'without a spectator record') + rule_control('bank_spectator_count_wrong',lambda o:o[a_][1].__setitem__(3,o[a_][1][3]*2),'without a spectator record') + rule_control('second_owner_on_an_active_data_family',lambda o:o.__setitem__(241,[o[0][0],[1,0,0]]),'data class') + rule_control('helper_owner_on_an_active_data_family',lambda o:o.__setitem__(250,[o[3][0],[2,0]]),'data class') + rule_control('active_wire_on_a_bank_family',lambda o:o.__setitem__(5,[7680,[1,0,5]]),'bank class') + C_=len(c['centers']) + rule_control('owner_in_the_private_namespace_centres',lambda o:o.__setitem__(300,[W+3,[2,0]]),'private namespace') + rule_control('owner_in_the_private_namespace_reserved_tableau',lambda o:o.__setitem__(300,[W+C_+5,[2,0]]),'private namespace') + rule_control('owner_in_the_private_namespace_coefficient',lambda o:o.__setitem__(300,[W+C_+R+1,[2,0]]),'private namespace') + t=copy.deepcopy(ir);t['calls'][0]['owners'][0][0]+=960 # copies: an active owner of replica 0's invocation on a family of replica 1 + try:global_check(t) + except (AssertionError,KeyError):controls.append('active_owner_on_the_family_of_another_replica') + else:raise AssertionError('global mutation accepted: active_owner_on_the_family_of_another_replica') +assert dict(H)=={int(r):z for r,z in integration['global_profile'].items()} + +def load(name): + sp=importlib.util.spec_from_file_location('replay_hamming_'+name,Path('work/pr361/code/engines')/(name+'.py')) + m=importlib.util.module_from_spec(sp);sp.loader.exec_module(m);return m +M,B=load('moment'),load('base_two_moment');b=Q(integration['complex_b']);grid=Q(1,10**18) +assert M.moment(H,73,W,b,True)[1]<1 audit_gk (exact arbitrary-dirt + inverse-transpose + frame chains) -> emit_gk (emitted program replay, both orientations) + -> exact Gaussian phase recipes (PR #433's complex_phases_full.py, unmodified, for every used transition) -> integrate_gk (parent template) + -> replay_gk (independent read-back) -> hosted_gk (whole-residual idle-axis hosting; frozen selection) -> audit_hosted_gk +At --anchor (empty selection) the unmodified inputs must reproduce PR #433's and #442's files byte for byte.""" +import gzip, hashlib, json, os, shutil, subprocess, sys, time +from pathlib import Path +ROOT = Path(__file__).resolve().parent.parent; CODE = ROOT / 'code'; R = ROOT.parent +name, selp, key, changed, work = sys.argv[1], Path(sys.argv[2]), sys.argv[3], Path(sys.argv[4]), Path(sys.argv[5]) +flags = set(a for a in sys.argv[6:]) +assert not work.exists(); work.mkdir(parents=True) +env = dict(os.environ, PYTHONDONTWRITEBYTECODE='1', PYTHONINTMAXSTRDIGITS='0'); env.pop('PYTHONOPTIMIZE', None) +sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest() +log = open(work / 'run.log', 'w'); steps = [] +def run(step, script, *args, cwd=None): + t = time.monotonic() + q = subprocess.run([sys.executable, '-B', str(script), *map(str, args)], cwd=cwd or work, env=env, stdout=log, stderr=subprocess.STDOUT, text=True) + if q.returncode: raise RuntimeError((name, step, 'see ' + str(work / 'run.log'))) + steps.append(dict(step=step, seconds=round(time.monotonic() - t, 1))); print(name, 'PASS', step, flush=True) +shutil.copytree(changed / 'work', work / 'work', symlinks=False) +shutil.copy(changed / 'BIT-PRICE.json', work / 'BIT-PRICE.json') +base = work / 'sc_base'; shutil.copytree(changed / 'split-centres', base, symlinks=False) +sc = work / 'split-centres'; shutil.copytree(base, sc) +run('gk_word', CODE / 'gk_word.py', base / 'FULL-WORD.json.gz', selp, sc / 'GK-WORD.json.gz') +os.replace(sc / 'GK-WORD.json.gz', sc / 'FULL-WORD.json.gz') +if '--controls' in flags: + run('mutation controls (word)', CODE / 'controls_gk.py', sc / 'FULL-WORD.json.gz', work / 'CONTROLS-WORD.json') + run('mutation controls (selection)', CODE / 'controls_sel.py', base / 'FULL-WORD.json.gz', selp, work / 'CONTROLS-SELECTION.json') + run('mutation controls (through the certifying scripts)', CODE / 'controls_pipeline.py', work, selp, work / 'CONTROLS-PIPELINE.json') +run('audit_gk', CODE / 'audit_gk.py'); run('emit_gk', CODE / 'emit_gk.py') +if '--anchor' in flags: + for f in ('CANONICAL-WORD.json.gz', 'LOCAL-PROGRAMS.json.gz', 'LOCAL-CHECKS.json'): + assert (sc / f).read_bytes() == (base / f).read_bytes(), ('anchor: ' + f + ' differs from PR #433') + print(name, 'ANCHOR canonical word, local programs and local checks identical to PR #433', flush=True) + # canonical word identical => PR #433's phase recipes apply unchanged (they are bound to the canonical hash) +else: + run('phases (exact Gaussian recipes, all used transitions)', R / 'split-centres-global/code/complex_phases_full.py') + run('adapters_gk (paid residual wrappers: L^-1 S_E R^-1 = C_[w] x I, exactly)', CODE / 'adapters_gk.py', sc / 'CANONICAL-WORD.json.gz', sc / 'RESIDUAL-ADAPTERS.json', work / 'LEMMA-A.json') +run('integrate_gk', CODE / 'integrate_gk.py'); run('replay_gk', CODE / 'replay_gk.py') +if '--anchor' in flags: + for f in ('GLOBAL-TEMPLATE.json.gz', 'INDEPENDENT-REPLAY.json'): + assert (sc / f).read_bytes() == (base / f).read_bytes(), ('anchor: ' + f + ' differs from PR #433') + print(name, 'ANCHOR parent global template and independent replay identical to PR #433', flush=True) +host = work / 'hosted' +ONE = [] if '--anchor' in flags else ['--one-helper-per-family'] # the anchor uses PR #442's rule; every other word PR #458's +if '--anchor' in flags: sel_args = [] +elif '--discover' in flags: sel_args = [*ONE, '--key', key, '--discover-to', work / 'SELECTION-new.json'] # development only: freeze a new selection +else: sel_args = [*ONE, '--selection', ROOT / 'data/SELECTION.json', '--key', key] +run('hosted_gk', CODE / 'hosted_gk.py', sc, host, *sel_args) +if '--discover-check' in flags and '--anchor' not in flags: + run('hosted_gk --discover (selection recomputed with HiGHS)', CODE / 'hosted_gk.py', sc, work / 'hosted-rediscovered', *ONE, '--key', key, '--discover-to', work / 'SELECTION-rediscovered.json') + a = json.loads((ROOT / 'data/SELECTION.json').read_text())[key]; b = json.loads((work / 'SELECTION-rediscovered.json').read_text())[key] + assert a['patterns'] == b['patterns'], 'rediscovered selection differs' + assert (host / 'GLOBAL-TEMPLATE.json.gz').read_bytes() == (work / 'hosted-rediscovered' / 'GLOBAL-TEMPLATE.json.gz').read_bytes() +run('audit_hosted_gk', CODE / 'audit_hosted_gk.py', sc, host, work / 'HOSTING-AUDIT.json', *ONE) +if '--controls' in flags and '--anchor' not in flags: + run('mutation controls (one-owner rule on every register class, through the generators)', CODE / 'controls_hosting.py', work, ROOT / 'data/SELECTION.json', key, work / 'CONTROLS-HOSTING.json') +(work / 'STEPS.json').write_text(json.dumps(dict(name=name, steps=steps, canonical_word_sha256=sha(sc / 'CANONICAL-WORD.json.gz'), + hosted_template_sha256=json.loads((host / 'HOSTED.json').read_text())['template_sha256']), indent=1) + '\n') +print(name, 'DONE', flush=True) diff --git a/research/e8-complex-gauge-kernel/data/SELECTION.json b/research/e8-complex-gauge-kernel/data/SELECTION.json new file mode 100644 index 0000000000..d85790080a --- /dev/null +++ b/research/e8-complex-gauge-kernel/data/SELECTION.json @@ -0,0 +1,1948 @@ +{ + "complex-gauge80": { + "patterns": [ + [ + 0, + [ + [ + 1, + 9 + ] + ], + 120 + ], + [ + 1, + [], + 58 + ], + [ + 1, + [ + [ + 2, + 8 + ] + ], + 62 + ], + [ + 2, + [ + [ + 0, + 7 + ], + [ + 1, + 9 + ] + ], + 14 + ], + [ + 2, + [ + [ + 0, + 8 + ], + [ + 1, + 8 + ] + ], + 62 + ], + [ + 2, + [ + [ + 0, + 9 + ] + ], + 30 + ], + [ + 2, + [ + [ + 0, + 9 + ], + [ + 1, + 7 + ] + ], + 14 + ], + [ + 3, + [], + 120 + ], + [ + 4, + [ + [ + 0, + 5 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 4 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 5 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 4 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 5 + ], + [ + 3, + 9 + ] + ], + 4 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 5 + ] + ], + 4 + ], + [ + 4, + [ + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 104 + ], + [ + 5, + [], + 44 + ], + [ + 5, + [ + [ + 4, + 7 + ] + ], + 14 + ], + [ + 5, + [ + [ + 4, + 8 + ] + ], + 62 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 7 + ], + [ + 3, + 7 + ] + ], + 14 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 106 + ], + [ + 7, + [], + 120 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 8 + ], + [ + 4, + 5 + ], + [ + 5, + 8 + ] + ], + 4 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 36 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 56 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 24 + ], + [ + 9, + [], + 58 + ], + [ + 9, + [ + [ + 6, + 8 + ] + ], + 62 + ], + [ + 10, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ], + [ + 4, + 9 + ] + ], + 120 + ], + [ + 11, + [], + 120 + ], + [ + 12, + [ + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 120 + ], + [ + 13, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ] + ], + 58 + ], + [ + 13, + [ + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 62 + ], + [ + 14, + [ + [ + 5, + 7 + ], + [ + 6, + 7 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 14 + ], + [ + 14, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 5 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 14, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ] + ], + 4 + ], + [ + 14, + [ + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 98 + ], + [ + 15, + [ + [ + 5, + 5 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 15, + [ + [ + 5, + 9 + ], + [ + 6, + 5 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 15, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 5 + ] + ], + 4 + ], + [ + 15, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 8, + 9 + ] + ], + 108 + ], + [ + 16, + [ + [ + 7, + 9 + ] + ], + 68 + ], + [ + 16, + [ + [ + 8, + 9 + ] + ], + 52 + ], + [ + 17, + [ + [ + 7, + 7 + ], + [ + 8, + 9 + ] + ], + 14 + ], + [ + 17, + [ + [ + 7, + 8 + ], + [ + 8, + 8 + ] + ], + 62 + ], + [ + 17, + [ + [ + 7, + 9 + ] + ], + 30 + ], + [ + 17, + [ + [ + 7, + 9 + ], + [ + 8, + 7 + ] + ], + 14 + ] + ], + "proxy_saving": 24905.589249734894, + "rule": "one-helper-per-family" + }, + "complex-gauge80-kernel42": { + "patterns": [ + [ + 0, + [ + [ + 0, + 8 + ], + [ + 1, + 8 + ] + ], + 104 + ], + [ + 0, + [ + [ + 0, + 9 + ] + ], + 2 + ], + [ + 0, + [ + [ + 0, + 9 + ], + [ + 1, + 7 + ] + ], + 14 + ], + [ + 1, + [], + 120 + ], + [ + 2, + [ + [ + 0, + 7 + ], + [ + 1, + 9 + ] + ], + 14 + ], + [ + 2, + [ + [ + 0, + 9 + ] + ], + 66 + ], + [ + 2, + [ + [ + 1, + 9 + ] + ], + 40 + ], + [ + 3, + [], + 16 + ], + [ + 3, + [ + [ + 2, + 8 + ] + ], + 104 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 5 + ], + [ + 3, + 9 + ] + ], + 4 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 7 + ], + [ + 3, + 7 + ] + ], + 14 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ] + ], + 78 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 3, + 8 + ] + ], + 24 + ], + [ + 5, + [], + 16 + ], + [ + 5, + [ + [ + 4, + 8 + ] + ], + 104 + ], + [ + 6, + [ + [ + 0, + 5 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 4 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 1, + 5 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 4 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ] + ], + 16 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 5 + ] + ], + 4 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 8 + ] + ], + 16 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 76 + ], + [ + 7, + [], + 106 + ], + [ + 7, + [ + [ + 4, + 7 + ] + ], + 14 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ], + [ + 4, + 9 + ] + ], + 52 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 68 + ], + [ + 9, + [], + 16 + ], + [ + 9, + [ + [ + 6, + 8 + ] + ], + 104 + ], + [ + 10, + [ + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 120 + ], + [ + 11, + [], + 120 + ], + [ + 12, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 24 + ], + [ + 12, + [ + [ + 3, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 38 + ], + [ + 12, + [ + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 58 + ], + [ + 13, + [ + [ + 3, + 8 + ], + [ + 4, + 5 + ], + [ + 5, + 8 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 13, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ] + ], + 2 + ], + [ + 13, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 114 + ], + [ + 14, + [ + [ + 5, + 5 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 14, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ] + ], + 116 + ], + [ + 15, + [ + [ + 5, + 7 + ], + [ + 6, + 7 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 14 + ], + [ + 15, + [ + [ + 5, + 8 + ], + [ + 6, + 9 + ], + [ + 8, + 9 + ] + ], + 94 + ], + [ + 15, + [ + [ + 5, + 9 + ], + [ + 6, + 5 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 15, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 5 + ], + [ + 8, + 9 + ] + ], + 4 + ], + [ + 15, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 5 + ] + ], + 4 + ], + [ + 16, + [ + [ + 7, + 8 + ], + [ + 8, + 8 + ] + ], + 40 + ], + [ + 16, + [ + [ + 7, + 9 + ], + [ + 8, + 7 + ] + ], + 14 + ], + [ + 16, + [ + [ + 8, + 9 + ] + ], + 66 + ], + [ + 17, + [ + [ + 7, + 7 + ], + [ + 8, + 9 + ] + ], + 14 + ], + [ + 17, + [ + [ + 7, + 8 + ], + [ + 8, + 8 + ] + ], + 64 + ], + [ + 17, + [ + [ + 7, + 9 + ] + ], + 42 + ] + ], + "proxy_saving": 28412.8444832947, + "rule": "one-helper-per-family" + }, + "complex-kernel79": { + "patterns": [ + [ + 0, + [ + [ + 1, + 9 + ] + ], + 120 + ], + [ + 1, + [], + 41 + ], + [ + 1, + [ + [ + 2, + 8 + ] + ], + 79 + ], + [ + 2, + [ + [ + 0, + 8 + ], + [ + 1, + 8 + ] + ], + 79 + ], + [ + 2, + [ + [ + 1, + 9 + ] + ], + 41 + ], + [ + 3, + [], + 120 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ] + ], + 80 + ], + [ + 4, + [ + [ + 0, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 40 + ], + [ + 5, + [], + 41 + ], + [ + 5, + [ + [ + 4, + 8 + ] + ], + 79 + ], + [ + 6, + [ + [ + 0, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ] + ], + 120 + ], + [ + 7, + [], + 120 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 3, + 9 + ], + [ + 5, + 9 + ] + ], + 81 + ], + [ + 8, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 39 + ], + [ + 9, + [], + 41 + ], + [ + 9, + [ + [ + 6, + 8 + ] + ], + 79 + ], + [ + 10, + [ + [ + 0, + 9 + ], + [ + 1, + 9 + ], + [ + 2, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ] + ], + 120 + ], + [ + 11, + [], + 120 + ], + [ + 12, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 119 + ], + [ + 12, + [ + [ + 3, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 1 + ], + [ + 13, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ] + ], + 80 + ], + [ + 13, + [ + [ + 3, + 9 + ], + [ + 4, + 9 + ], + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 8, + 9 + ] + ], + 40 + ], + [ + 14, + [ + [ + 5, + 9 + ], + [ + 6, + 9 + ], + [ + 7, + 9 + ] + ], + 120 + ], + [ + 15, + [ + [ + 6, + 9 + ], + [ + 7, + 9 + ], + [ + 8, + 9 + ] + ], + 120 + ], + [ + 16, + [ + [ + 7, + 8 + ], + [ + 8, + 8 + ] + ], + 79 + ], + [ + 16, + [ + [ + 7, + 9 + ] + ], + 41 + ], + [ + 17, + [ + [ + 8, + 9 + ] + ], + 120 + ] + ], + "proxy_saving": 24390.168700650247, + "rule": "one-helper-per-family" + } +} diff --git a/research/e8-complex-gauge-kernel/data/bit-suppliers-pinned.json b/research/e8-complex-gauge-kernel/data/bit-suppliers-pinned.json new file mode 100644 index 0000000000..7ff0d30d85 --- /dev/null +++ b/research/e8-complex-gauge-kernel/data/bit-suppliers-pinned.json @@ -0,0 +1,9 @@ +[ + { + "label": "R724 mixed, eleven stages, whole-residual hosting", + "c": "1280809559877993762253/1000000000000000000000000", + "charged_two_level_coefficient_bits": 576, + "row_coefficient": 28416, + "source": "DreamingOfClouds nesttax w_fpm RESULT.json (s11pkg code, depth-3 halving); input pinned here, verified by its own package, not re-run" + } +] \ No newline at end of file diff --git a/research/e8-complex-gauge-kernel/data/selections/empty.json b/research/e8-complex-gauge-kernel/data/selections/empty.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/research/e8-complex-gauge-kernel/data/selections/empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/research/e8-complex-gauge-kernel/data/selections/gauge80-kernel42.json b/research/e8-complex-gauge-kernel/data/selections/gauge80-kernel42.json new file mode 100644 index 0000000000..cf624433f0 --- /dev/null +++ b/research/e8-complex-gauge-kernel/data/selections/gauge80-kernel42.json @@ -0,0 +1,470 @@ +{ + "gauge": { + "134": [ + 510 + ], + "135": [ + 510 + ], + "136": [ + 510 + ], + "137": [ + 510 + ], + "138": [ + 510 + ], + "139": [ + 510 + ], + "164": [ + 510 + ], + "165": [ + 510 + ], + "166": [ + 510 + ], + "167": [ + 510 + ], + "190": [ + 408, + 102 + ], + "191": [ + 408, + 102 + ], + "192": [ + 510 + ], + "193": [ + 510 + ], + "194": [ + 510 + ], + "195": [ + 510 + ], + "220": [ + 510 + ], + "221": [ + 510 + ], + "222": [ + 510 + ], + "223": [ + 510 + ], + "246": [ + 408, + 102 + ], + "247": [ + 408, + 102 + ], + "248": [ + 510 + ], + "249": [ + 510 + ], + "250": [ + 510 + ], + "251": [ + 510 + ], + "274": [ + 408, + 102 + ], + "275": [ + 408, + 102 + ], + "276": [ + 510 + ], + "277": [ + 510 + ], + "278": [ + 510 + ], + "279": [ + 510 + ], + "304": [ + 510 + ], + "305": [ + 510 + ], + "306": [ + 510 + ], + "307": [ + 510 + ], + "326": [ + 408 + ], + "327": [ + 408 + ], + "330": [ + 408 + ], + "331": [ + 408 + ], + "408": [ + 408 + ], + "409": [ + 408 + ], + "414": [ + 408 + ], + "415": [ + 408 + ], + "464": [ + 408 + ], + "465": [ + 408 + ], + "470": [ + 408 + ], + "471": [ + 408 + ], + "492": [ + 408 + ], + "493": [ + 408 + ], + "494": [ + 408 + ], + "495": [ + 408 + ], + "532": [ + 510 + ], + "533": [ + 510 + ], + "534": [ + 510 + ], + "535": [ + 510 + ], + "536": [ + 408, + 102 + ], + "537": [ + 408, + 102 + ], + "538": [ + 408, + 102 + ], + "539": [ + 408, + 102 + ], + "540": [ + 291, + 163, + 102, + 24 + ], + "541": [ + 291, + 163, + 102, + 24 + ], + "542": [ + 291, + 163, + 102, + 24 + ], + "543": [ + 291, + 163, + 102, + 24 + ], + "544": [ + 510 + ], + "545": [ + 510 + ], + "546": [ + 510 + ], + "547": [ + 510 + ], + "548": [ + 408, + 102 + ], + "549": [ + 408, + 102 + ], + "550": [ + 408, + 102 + ], + "551": [ + 408, + 102 + ], + "552": [ + 510 + ], + "553": [ + 510 + ], + "554": [ + 510 + ], + "555": [ + 510 + ], + "556": [ + 510 + ], + "557": [ + 510 + ], + "558": [ + 510 + ], + "559": [ + 510 + ] + }, + "kernel": [ + { + "E": [ + 504 + ], + "donors": [ + 334, + 335, + 362, + 363 + ], + "pivots": [ + 390, + 391, + 418, + 419 + ] + }, + { + "E": [ + 390 + ], + "donors": [ + 324, + 325, + 328, + 329, + 380, + 384, + 440, + 444 + ], + "pivots": [ + 381, + 385, + 441, + 445, + 498, + 499, + 500, + 501 + ] + }, + { + "E": [ + 6 + ], + "donors": [ + 128, + 129 + ], + "pivots": [ + 156, + 157 + ] + }, + { + "E": [ + 414 + ], + "donors": [ + 218, + 219, + 302, + 303 + ], + "pivots": [ + 358, + 359, + 386, + 387 + ] + }, + { + "E": [ + 384 + ], + "donors": [ + 162, + 163, + 240, + 241, + 300, + 352, + 353, + 356, + 360, + 361, + 412, + 416, + 417, + 438, + 442 + ], + "pivots": [ + 301, + 357, + 413, + 436, + 437, + 439, + 443, + 496, + 497, + 502, + 503 + ] + }, + { + "E": [ + 126 + ], + "donors": [ + 160, + 161 + ], + "pivots": [ + 242, + 243 + ] + }, + { + "E": [ + 102 + ], + "donors": [ + 188, + 189 + ], + "pivots": [ + 244, + 245 + ] + }, + { + "E": [ + 30 + ], + "donors": [ + 132, + 133 + ], + "pivots": [ + 268, + 269 + ] + }, + { + "E": [ + 96 + ], + "donors": [ + 186, + 187 + ], + "pivots": [ + 216, + 217 + ] + }, + { + "E": [ + 120 + ], + "donors": [ + 158, + 159 + ], + "pivots": [ + 214, + 215 + ] + }, + { + "E": [ + 480 + ], + "donors": [ + 272, + 273, + 298 + ], + "pivots": [ + 299 + ] + }, + { + "E": [ + 24 + ], + "donors": [ + 130, + 131 + ], + "pivots": [ + 212, + 213 + ] + } + ] +} \ No newline at end of file diff --git a/research/e8-complex-gauge-kernel/data/selections/gauge80.json b/research/e8-complex-gauge-kernel/data/selections/gauge80.json new file mode 100644 index 0000000000..24f90c3889 --- /dev/null +++ b/research/e8-complex-gauge-kernel/data/selections/gauge80.json @@ -0,0 +1,270 @@ +{ + "gauge": { + "134": [ + 510 + ], + "135": [ + 510 + ], + "136": [ + 510 + ], + "137": [ + 510 + ], + "138": [ + 510 + ], + "139": [ + 510 + ], + "164": [ + 510 + ], + "165": [ + 510 + ], + "166": [ + 510 + ], + "167": [ + 510 + ], + "190": [ + 408, + 102 + ], + "191": [ + 408, + 102 + ], + "192": [ + 510 + ], + "193": [ + 510 + ], + "194": [ + 510 + ], + "195": [ + 510 + ], + "220": [ + 510 + ], + "221": [ + 510 + ], + "222": [ + 510 + ], + "223": [ + 510 + ], + "246": [ + 408, + 102 + ], + "247": [ + 408, + 102 + ], + "248": [ + 510 + ], + "249": [ + 510 + ], + "250": [ + 510 + ], + "251": [ + 510 + ], + "274": [ + 408, + 102 + ], + "275": [ + 408, + 102 + ], + "276": [ + 510 + ], + "277": [ + 510 + ], + "278": [ + 510 + ], + "279": [ + 510 + ], + "304": [ + 510 + ], + "305": [ + 510 + ], + "306": [ + 510 + ], + "307": [ + 510 + ], + "326": [ + 408 + ], + "327": [ + 408 + ], + "330": [ + 408 + ], + "331": [ + 408 + ], + "408": [ + 408 + ], + "409": [ + 408 + ], + "414": [ + 408 + ], + "415": [ + 408 + ], + "464": [ + 408 + ], + "465": [ + 408 + ], + "470": [ + 408 + ], + "471": [ + 408 + ], + "492": [ + 408 + ], + "493": [ + 408 + ], + "494": [ + 408 + ], + "495": [ + 408 + ], + "532": [ + 510 + ], + "533": [ + 510 + ], + "534": [ + 510 + ], + "535": [ + 510 + ], + "536": [ + 408, + 102 + ], + "537": [ + 408, + 102 + ], + "538": [ + 408, + 102 + ], + "539": [ + 408, + 102 + ], + "540": [ + 291, + 163, + 102, + 24 + ], + "541": [ + 291, + 163, + 102, + 24 + ], + "542": [ + 291, + 163, + 102, + 24 + ], + "543": [ + 291, + 163, + 102, + 24 + ], + "544": [ + 510 + ], + "545": [ + 510 + ], + "546": [ + 510 + ], + "547": [ + 510 + ], + "548": [ + 408, + 102 + ], + "549": [ + 408, + 102 + ], + "550": [ + 408, + 102 + ], + "551": [ + 408, + 102 + ], + "552": [ + 510 + ], + "553": [ + 510 + ], + "554": [ + 510 + ], + "555": [ + 510 + ], + "556": [ + 510 + ], + "557": [ + 510 + ], + "558": [ + 510 + ], + "559": [ + 510 + ] + } +} \ No newline at end of file diff --git a/research/e8-complex-gauge-kernel/data/selections/kernel79.json b/research/e8-complex-gauge-kernel/data/selections/kernel79.json new file mode 100644 index 0000000000..60ef2c4b1c --- /dev/null +++ b/research/e8-complex-gauge-kernel/data/selections/kernel79.json @@ -0,0 +1,338 @@ +{ + "kernel": [ + { + "E": [ + 480 + ], + "donors": [ + 134, + 135, + 270, + 271, + 272, + 273, + 298, + 300, + 384, + 390, + 410, + 519, + 536, + 558 + ], + "pivots": [ + 299, + 301, + 385, + 411, + 440, + 441, + 466, + 467 + ] + }, + { + "E": [ + 510 + ], + "donors": [ + 166, + 167, + 194, + 195, + 532, + 539, + 541, + 543 + ], + "pivots": [ + 222, + 223, + 250, + 251, + 278, + 279, + 306, + 307 + ] + }, + { + "E": [ + 408 + ], + "donors": [ + 184, + 190, + 191, + 240, + 246, + 247, + 274, + 275, + 324, + 326, + 408, + 507, + 540 + ], + "pivots": [ + 327, + 330, + 331, + 414, + 415, + 464, + 465, + 470, + 471, + 492, + 493, + 494 + ] + }, + { + "E": [ + 384 + ], + "donors": [ + 162, + 163, + 248, + 249, + 297, + 304, + 305, + 356, + 409, + 412, + 413, + 439, + 514, + 525, + 534, + 542 + ], + "pivots": [ + 357, + 360, + 361, + 416, + 417, + 436, + 437, + 442, + 443, + 495, + 502 + ] + }, + { + "E": [ + 126 + ], + "donors": [ + 160, + 161, + 533, + 535, + 552 + ], + "pivots": [ + 242, + 243 + ] + }, + { + "E": [ + 414 + ], + "donors": [ + 185, + 192, + 193, + 218, + 219, + 302, + 303, + 352, + 353, + 380, + 382, + 468, + 505, + 510, + 511, + 521, + 547, + 548 + ], + "pivots": [ + 358, + 359, + 381, + 383, + 386, + 387, + 469, + 472, + 473, + 496, + 497 + ] + }, + { + "E": [ + 390 + ], + "donors": [ + 164, + 165, + 220, + 221, + 276, + 277, + 325, + 328, + 506, + 512, + 515, + 529 + ], + "pivots": [ + 329, + 332, + 333, + 388, + 389, + 500, + 501, + 503 + ] + }, + { + "E": [ + 102 + ], + "donors": [ + 188, + 189, + 537, + 538 + ], + "pivots": [ + 244, + 245 + ] + }, + { + "E": [ + 486 + ], + "donors": [ + 136, + 137, + 334, + 335, + 354, + 362, + 363, + 509, + 526, + 531 + ], + "pivots": [ + 355, + 444, + 445, + 446, + 447, + 474, + 475 + ] + }, + { + "E": [ + 96 + ], + "donors": [ + 186, + 187, + 438, + 517, + 549 + ], + "pivots": [ + 216, + 217 + ] + }, + { + "E": [ + 30 + ], + "donors": [ + 132, + 133, + 296, + 498, + 499, + 528 + ], + "pivots": [ + 268, + 269 + ] + }, + { + "E": [ + 120 + ], + "donors": [ + 158, + 159, + 527, + 546, + 553 + ], + "pivots": [ + 214, + 215 + ] + }, + { + "E": [ + 6 + ], + "donors": [ + 128, + 129, + 138, + 139, + 508, + 513, + 554, + 555 + ], + "pivots": [ + 156, + 157 + ] + }, + { + "E": [ + 24 + ], + "donors": [ + 130, + 131, + 241, + 419, + 557 + ], + "pivots": [ + 212, + 213 + ] + } + ] +} \ No newline at end of file diff --git a/research/e8-complex-gauge-kernel/provenance/README.md b/research/e8-complex-gauge-kernel/provenance/README.md new file mode 100644 index 0000000000..55f3dffdcd --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/README.md @@ -0,0 +1,8 @@ +Development scripts that found the frozen selections (`../data/selections/*.json`). They are NOT run by +`verify.py`; the selections are verified by the package, not by the search. They need numpy (and scipy for `hostmodel.py`) and +`CXG_BASE` = the output directory of `python -B research/idle-axis-hosting/verify.py $CXG_BASE`, `CXG_REPO` = this repository. +- `kern*.py`: shared-donor kernel classes (rank-1 entrances; simulated annealing over the helper → class partition). +- `gauge*.py`: entrance gauges (per-target nesting, per-centre chains, greedy with refill). +- `iso1.py`: with entrances restricted to the bit-style criterion (orthonormal basis, 1 ∉ E) the kernel potential and the number of + gauge-eligible helpers are 0. +- `hostmodel.py`, `kcap.py`: the fast hosted-b model used to rank candidates (the package's certified numbers come from `assemble_gk.py`; the model's bank tiling predates the banked spectators and reads about 0.05 % high). diff --git a/research/e8-complex-gauge-kernel/provenance/cxcheck.py b/research/e8-complex-gauge-kernel/provenance/cxcheck.py new file mode 100644 index 0000000000..c0eee7f6d0 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/cxcheck.py @@ -0,0 +1,79 @@ +"""Generalised exact checker for variants of the #433 complex word (arbitrary dirt, inverse-transpose, frame chain, paid profile). +A variant = dict(A,B,cut,precondition,pre,start,ports,...). pre = list of ['add',donor,pivot,num,den,E] ops placed first in main. +start = {register: frame(list of masks)} for pivots (default () for helpers, (P[s],) for sources, () for targets). +cleanup is rebuilt: inverse of all non-target ops of pre+A+B at FULL, reversed.""" +from cxlab import * +import time +FULL=tuple(1<=2*v} + for e in prec:apply(e,dirty) + comp=[] + for r in range(v,2*v): + for j,x in sorted(dirty[r].items()):comp.append(['add',r,j,-x.numerator,x.denominator,[]]) + ncomp_cols=len({e[2] for e in comp}) + cleanup=[] + for e in reversed(list(pre)+A+B): + if not v<=e[1]<2*v: + c=inv(e);c[-1]=list(FULL);cleanup.append(c) + program=list(prec)+comp+main+cleanup + rep=dict(R=R,comp_adds=len(comp),comp_cols=ncomp_cols) + if full: + actual=ident(n) + for e in program:apply(e,actual) + expected=ident(n) + for t in range(v):expected[v+t][t]=Q(1) + assert actual==expected,'arbitrary-dirt exactness FAILED' + back=ident(n) + for e in program:apply(dual(e),back) + eb=ident(n) + for t in range(v):eb[t][v+t]=Q(-1) + assert back==eb,'inverse-transpose FAILED' + rep['exact_arbitrary_dirt']=True;rep['exact_inverse_transpose']=True + # frame chain + paid profile (mirrors complex_audit canonical climb check) + cur={} + for r in range(n): + if r=2*v) else perp(P[r-v])) + rep['local_profile']=dict(sorted(paid.items()));rep['edges']=len(edges) + rep['mass']=sum(r*z for r,z in paid.items()) + rep['widths']=[9-startrank[r] for r in range(2*v,n)] + rep['seconds']=time.time()-t0 + rep['_program']=program + return rep,edges +if __name__=='__main__': + w=load();rep,_=check(w) + print({k:v for k,v in rep.items() if k not in('_program','widths')},sum(rep['widths'])) diff --git a/research/e8-complex-gauge-kernel/provenance/cxlab.py b/research/e8-complex-gauge-kernel/provenance/cxlab.py new file mode 100644 index 0000000000..caed7a48d6 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/cxlab.py @@ -0,0 +1,38 @@ +"""cx lab helpers. Paths come from the environment: CXG_BASE = output directory of +`python -B research/idle-axis-hosting/verify.py $CXG_BASE` (PR #442 replay, which contains parent/changed/split-centres).""" +import gzip,json,copy,os,sys +from fractions import Fraction as Q +from collections import Counter,defaultdict +CX=os.environ.get('CXG_BASE','') +CH=CX+'/parent/changed/split-centres/' +v=120 +def load(path=None): + return json.load(gzip.open(path or (CH+'FULL-WORD.json.gz'))) +def apply(e,rows): + if e[0]=='scale': + _,t,a,b,*_=e;q=Q(a,b) + rows[t]={j:q*x for j,x in rows[t].items()} + else: + _,t,s,a,b,*_=e;q=Q(a,b) + for j,x in list(rows[s].items()): + z=rows[t].get(j,Q(0))+q*x + if z:rows[t][j]=z + else:rows[t].pop(j,None) +def inv(e): + e=copy.deepcopy(e) + if e[0]=='add':e[3]*=-1 + else:e[2],e[3]=e[3],e[2] + return e +def basis(vs): + b={} + for x in vs: + for k in sorted(b,reverse=True): + if x>>k&1:x^=b[k] + if x: + k=x.bit_length()-1 + for j in b: + if b[j]>>k&1:b[j]^=x + b[k]=x + return tuple(b[k] for k in sorted(b,reverse=True)) +def inside(a,b):return basis(list(a)+list(b))==tuple(b) if basis(b)==tuple(b) else basis(list(a)+list(b))==basis(b) +def ident(n):return [{r:Q(1)} for r in range(n)] diff --git a/research/e8-complex-gauge-kernel/provenance/gauge.py b/research/e8-complex-gauge-kernel/provenance/gauge.py new file mode 100644 index 0000000000..45ddbacdd6 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/gauge.py @@ -0,0 +1,51 @@ +from kern import * +import random +def span(F): + s={0} + for b in F:s|={x^b for x in s} + return frozenset(s) +def perp(x):return basis([z for z in range(1,512) if not (x&z).bit_count()%2]) +def prep(w): + col,first=setup(w);R=len(col);P=w['ports'] + A,B=w['A'],w['B'];FB={} + for seq in (A,B): + for e in seq: + for r in ([e[1]]+([e[2]] if e[0]=='add' else [])): + if v<=r<2*v and e[-1] is not None:FB.setdefault(r-v,basis(e[-1])) + cap={t:span(FB[t]) if t in FB else span(perp(P[t])) for t in range(v)} + cands={} + for h in range(R): + S=list(col[h]);inter=set(span(first[h])) + for t in S:inter&=cap[t] + # candidate subspaces of first[h] inside inter + cs=[] + for E in subspaces(first[h]): + if span(E)<=inter:cs.append(E) + cands[h]=sorted(cs,key=lambda E:-len(E)) + return col,first,cap,cands,P +def nested(sa,sb):return sa<=sb or sb<=sa +def greedy(col,cands,seed=0,order=None): + R=len(col);rnd=random.Random(seed) + chain={t:[] for t in range(v)} # list of span-sets + E_of={} + hs=list(range(R)) + if order is None: + hs.sort(key=lambda h:(len(col[h]),rnd.random())) + else:hs=order + eps=0 + for h in hs: + for E in cands[h]: + sE=span(E) + if all(all(nested(sE,c) for c in chain[t]) for t in col[h]): + E_of[h]=E;eps+=len(E) + for t in col[h]:chain[t].append(sE) + break + return E_of,eps +if __name__=='__main__': + w=load();col,first,cap,cands,P=prep(w) + print('cands sizes',Counter(len(c) for c in cands.values()).most_common(6)) + print('upper (sum of max cand rank)',sum(len(c[0]) if c else 0 for c in cands.values())) + best=0 + for seed in range(30): + E_of,eps=greedy(col,cands,seed) + if eps>best:best=eps;print(seed,eps,len(E_of),Counter(len(E) for E in E_of.values())) diff --git a/research/e8-complex-gauge-kernel/provenance/gauge2.py b/research/e8-complex-gauge-kernel/provenance/gauge2.py new file mode 100644 index 0000000000..84c9c839e6 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/gauge2.py @@ -0,0 +1,72 @@ +"""Gauge variant (entrance comps at nonzero frames on a global flag; centre copies climb the flag). Profile model on top of the exact word.""" +from cxcheck import * +from gauge import prep,span,perp +import pickle +import hostmodel as HM +def gauge_profile(w,pre,start_kernel,gauge,flag): + """gauge: {helper h: E basis tuple (member of flag)}; start_kernel: {reg: E} kernel pivots (registers absolute ids); returns profile dict + widths""" + rep,edges=check(w,pre=pre,start=start_kernel,full=False) # kernel/baseline chain profile (comps ignored) + paid=Counter(rep['local_profile']) + # remove climbs saved for gauge helpers: recompute their chains with start E + A,B=w['A'],w['B'];P=w['ports'];R=w['report']['R'];n=240+R + # recompute full chain simulation with gauge starts and target levels + col,first=__import__('kern').setup(w) + supp={h:set(col[h]) for h in range(R)} + lev={t:() for t in range(v)} + for h,E in gauge.items(): + for t in supp[h]: + if len(E)>len(lev[t]): + assert span(lev[t])<=span(E) + lev[t]=E + st={} + for h,E in start_kernel.items():st[h]=E + cur={} + for r in range(n): + if r top served level -> ... -> lowest served level (mass-neutral descent) + for r,f in zip(ce,cf): + f=basis(list(f)) + tl={lev[e[1]-v] for e in w['cut'] if e[2]==r} + path=sorted(tl,key=lambda L:-len(L)) + o=f + for L in path: + assert basis(list(L)+list(o))==o,('centre frame does not contain served level',r,L,o) + if L!=o:paid[len(o)-len(L)]+=1;o=L + for e in seq: + for r in ([e[1]]+([e[2]] if e[0]=='add' else [])):climb(r,e[-1]) + for r in range(n):climb(r,FULL if (r=2*v) else perp(P[r-v])) + widths=[9-len(gauge.get(h,st.get(2*v+h,()))) for h in range(R)] + return dict(sorted(paid.items())),widths +if __name__=='__main__': + w=load();w['R']=w['report']['R'] + sc,flag,per=pickle.load(open('flag_best.pkl','rb')) + col,first,cap,cands,P=prep(w);R=len(col) + gauge={} + for h,k in per.items(): + if k>0: + E=[F for F in flag if len(F)==k][0];gauge[h]=E + prof,widths=gauge_profile(w,(),{},gauge,flag) + print('gauge helpers',len(gauge),'eps',sum(len(E) for E in gauge.values()),'profile',prof) + r0=HM.evaluate({1:1912,2:784,3:168,4:224,5:392,8:24},[9]*560) + r=HM.evaluate(prof,widths) + print('b',r['b'],'%+.3f%%'%(100*(r['b']/r0['b']-1)),r['W'],r['banks']) diff --git a/research/e8-complex-gauge-kernel/provenance/gauge3.py b/research/e8-complex-gauge-kernel/provenance/gauge3.py new file mode 100644 index 0000000000..5b17140c0c --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/gauge3.py @@ -0,0 +1,53 @@ +"""per-target nested + per-centre chain gauge assignment (greedy / SA-lite)""" +from gauge import * +import random,pickle +def setup_g(w): + col,first,cap,cands,P=prep(w);R=len(col) + served={} + for i,r in enumerate(w['centers']): + served[i]=sorted({e[1]-v for e in w['cut'] if e[2]==r}) + cf=[span(f) for f in w['center_frames']] + tcent=defaultdict(list) + for i,ts in served.items(): + for t in ts:tcent[t].append(i) + return col,first,cap,cands,P,served,cf,tcent +def greedy_g(col,cands,served,cf,tcent,order,minrank=1): + R=len(col) + L={t:frozenset({0}) for t in range(v)} # span sets of current level + Lall={t:[] for t in range(v)} + Lb={t:() for t in range(v)} + E_of={};eps=0 + for h in order: + for E in cands[h]: + sE=span(E) + ok=True;newL={} + for t in col[h]: + cur=L[t] + if not all(sE<=c or c<=sE for c in Lall[t]):ok=False;break + newL[t]=sE if len(sE)>len(cur) else cur + if not ok:continue + # centre chains + containment in cf + cs={i for t in newL for i in tcent[t]} + for i in cs: + levels=[newL.get(u,L[u]) for u in served[i]] + top=max(levels,key=len) + if not all(a<=b or b<=a for a in set(levels) for b in set(levels)):ok=False;break + if not top<=cf[i]:ok=False;break + if not ok:continue + E_of[h]=E;eps+=len(E) + for t,s in newL.items(): + L[t]=s;Lb[t]=E if len(s)>len(span(Lb[t])) else Lb[t] + for t in col[h]:Lall[t].append(sE) + break + return E_of,eps +if __name__=='__main__': + w=load();w['R']=w['report']['R'] + col,first,cap,cands,P,served,cf,tcent=setup_g(w);R=len(col) + print('centres served sizes',[len(served[i]) for i in served]) + best=(0,None) + for seed in range(300): + rnd=random.Random(seed);order=list(range(R));rnd.shuffle(order) + if seed%3==0:order.sort(key=lambda h:len(col[h])) + E_of,eps=greedy_g(col,cands,served,cf,tcent,order) + if eps>best[0]:best=(eps,E_of);print(seed,eps,len(E_of),Counter(len(E) for E in E_of.values()),flush=True) + pickle.dump(best,open('gauge3_best.pkl','wb')) diff --git a/research/e8-complex-gauge-kernel/provenance/gauge4.py b/research/e8-complex-gauge-kernel/provenance/gauge4.py new file mode 100644 index 0000000000..f1be84aba6 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/gauge4.py @@ -0,0 +1,53 @@ +from gauge3 import * +import time +def state_from(E_of,col,tcent,served,cf): + pass +def refill(col,cands,served,cf,tcent,E_of,drop,rnd): + keep={h:E for h,E in E_of.items() if h not in drop} + R=len(col) + # rebuild L from keep + L={t:frozenset({0}) for t in range(v)} + Lall={t:[] for t in range(v)} + for h,E in keep.items(): + sE=span(E) + for t in col[h]: + Lall[t].append(sE) + if len(sE)>len(L[t]):L[t]=sE + cur=dict(keep);eps=sum(len(E) for E in keep.values()) + order=[h for h in range(R) if h not in keep];rnd.shuffle(order) + for h in order: + for E in cands[h]: + sE=span(E);ok=True;newL={} + for t in col[h]: + c=L[t] + if not all(sE<=x or x<=sE for x in Lall[t]):ok=False;break + newL[t]=sE if len(sE)>len(c) else c + if not ok:continue + cs={i for t in newL for i in tcent[t]} + for i in cs: + levels=[newL.get(u,L[u]) for u in served[i]] + top=max(levels,key=len) + if not all(a<=b or b<=a for a in set(levels) for b in set(levels)) or not top<=cf[i]:ok=False;break + if not ok:continue + cur[h]=E;eps+=len(E) + for t,s in newL.items():L[t]=s + for t in col[h]:Lall[t].append(sE) + break + return cur,eps +if __name__=='__main__': + import sys + seed=int(sys.argv[1]);iters=int(sys.argv[2]) + w=load();w['R']=w['report']['R'] + col,first,cap,cands,P,served,cf,tcent=setup_g(w);R=len(col) + eps0,E_of=pickle.load(open('gauge3_best.pkl','rb')) + rnd=random.Random(seed);best=(eps0,E_of);t0=time.time() + cands_h=[h for h in range(R) if cands[h]] + for it in range(iters): + cur=best[1] + drop=set(rnd.sample(list(cur),max(1,int(len(cur)*rnd.choice([0.05,0.1,0.2,0.4]))))) + n,e=refill(col,cands,served,cf,tcent,cur,drop,rnd) + if e>=best[0]: + if e>best[0]:print(it,e,len(n),Counter(len(E) for E in n.values()),round(time.time()-t0),flush=True) + best=(e,n) + pickle.dump(best,open('gauge4_best_%d.pkl'%seed,'wb')) + print('final',best[0]) diff --git a/research/e8-complex-gauge-kernel/provenance/hostmodel.py b/research/e8-complex-gauge-kernel/provenance/hostmodel.py new file mode 100644 index 0000000000..6d7723269d --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/hostmodel.py @@ -0,0 +1,88 @@ +"""Hosted complex model: replicates idle-axis-hosting/complex_hosted.py profile arithmetic for arbitrary local paid profile +and per-helper residual widths (same for every stage/replica). Needs scipy (venv python).""" +import gzip,json,sys,math,importlib.util,time +from collections import Counter +from pathlib import Path +from fractions import Fraction as Q +import os +CX=os.environ['CXG_BASE'];REPO=os.environ.get('CXG_REPO','.') +sys.path.insert(0,REPO+'/research/idle-axis-hosting') +import hosting_core as HC +V,K,T,L,M=120,4,8,9,73 +DATA=2*K*V*T +PAR=Path(CX+'/parent/changed') +_t=json.loads(gzip.decompress((PAR/'split-centres/GLOBAL-TEMPLATE.json.gz').read_bytes())) +def _eng(name): + sp=importlib.util.spec_from_file_location('h_'+name,PAR/'work/pr361/code/engines'/(name+'.py'));mod=importlib.util.module_from_spec(sp);sp.loader.exec_module(mod);return mod +ENG=_eng('moment') +rank={};pair_of_stage={e['stage']:e['pair'] for e in _t['recipe'] if e['kind']=='local'} +sched=[];side_of={};pair_of={} +for it in _t['idle_children']:rank.setdefault(it['child'],it['rank']) +for e in _t['execution_schedule']: + if e['kind']=='local_cover_sweep':sched.append(dict(kind='local',stage=e['stage'],pair=pair_of_stage[e['stage']])) + elif e['kind']=='bridge':sched.append(dict(kind='bridge',dst=e['dst'],src=e['src'])) + elif e['kind']=='idle_cover_sweep': + for sd,ch in enumerate(e['child_indices']): + if ch in rank:sched.append(dict(kind='idle',pair=e['pair'],rank=rank[ch],idx=ch));side_of[ch]=sd;pair_of[ch]=e['pair'] +WINALL=HC.windows(sched) +IDLE=_t['idle_children'] +def evaluate(local_profile,widths,discover=True,sel=None,verbose=False,pad_val=None,exact=False): + """local_profile: {rank:count per call}; widths: list of residual widths (len R) -> dict(b,W,profile)""" + R=len(widths);wmin=min(widths) + win={k:x for k,x in WINALL.items() if x[1]>=wmin and x[2]} + cnt=Counter(widths) + avail={(s,w):c for s in range(L) for w,c in cnt.items()} + # identify helper ids per width + hl={}; + ids=sorted(range(R),key=lambda h:(-widths[h],h)) + helpers={s:[(h,widths[h]) for h in ids] for s in range(L)} + if discover: + ys,zs,val=HC.solve(win,V,avail,M,pad_value=(HC.cost(1,M)/8 if pad_val is None else pad_val)) + else:ys,zs,val=sel + slots,rem=HC.expand(win,ys,zs,helpers,V) + hosted={(s,h) for i,port,off,w,s,h in slots} # per replica? slots are per (idx,copy) -> one replica set + hosted_cnt=Counter((s,h) for i,c,o,w,s,h in slots) + # each slot hosts replicas T times (same for all replicas) + base=DATA;partial=Counter();banks=[] + paid=Counter() + W=DATA + for s in range(L): + left=[(rep,h) for rep in range(T) for h in range(R) if (s,h) not in {(s2,h2) for (_,_,_,_,s2,h2) in []}] + # build hosted set + hset={(s,h) for (_,_,_,_,s,h) in slots} + for s in range(L): + items=sorted([widths[h] for rep in range(T) for h in range(R) if (s,h) not in hset],reverse=True) + bins=[] + for w in items: + for i,b in enumerate(bins): + if b+w<=M:bins[i]+=w;break + else:bins.append(w) + W+=len(bins);banks.append(len(bins)) + for b in bins: + if M-b:paid[M-b]+=1 + for r_,z in local_profile.items():paid[int(r_)]+=int(z)*L*T + nid=0 + for it in IDLE: + ch,port=it['child'],it['port'];rr=rem.get((ch,port),it['rank']) if ch in win else it['rank'] + if rr:paid[rr]+=T + mass=sum(r*z for r,z in paid.items());D=M*W-mass + out=dict(W=W,D=D,profile=dict(sorted(paid.items())),hosted=len(slots)*T,banks=banks,val=val,sel=(ys,zs,val)) + if exact: + rc=ENG.certify({int(r):n for r,n in paid.items()},M,W,True);out['b']=float(Q(int(Q(rc['lower'])*10**18),10**18)) + else:out['b']=float(bfloat(paid,W)) + return out +def bfloat(paid,W,m=M): + lo,hi=0.,.01 + for _ in range(80): + q=(lo+hi)/2 + mom=sum(r*z/(m*W)*(m/r)**q for r,z in paid.items())+32*m*sum(paid.values())/(10**16*W)*m**q + if mom<1:lo=q + else:hi=q + return (lo+hi)/2 +if __name__=='__main__': + t0=time.time() + loc={1:1912,2:784,3:168,4:224,5:392,8:24} + r=evaluate(loc,[9]*560,discover=False,sel=HC.load_selection(REPO+'/research/idle-axis-hosting/SELECTION.json','complex'),exact=True) + print('frozen sel:',r['W'],r['D'],r['b'],r['banks'],r['hosted'],time.time()-t0) + r=evaluate(loc,[9]*560,discover=True,exact=True) + print('discover:',r['W'],r['D'],r['b'],r['banks'],r['hosted'],time.time()-t0) diff --git a/research/e8-complex-gauge-kernel/provenance/iso1.py b/research/e8-complex-gauge-kernel/provenance/iso1.py new file mode 100644 index 0000000000..715255d443 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/iso1.py @@ -0,0 +1,53 @@ +from kern import * +import numpy as np +def gram(E): + return [[bin(a&b).count('1')&1 for b in E] for a in E] +def det2(G): + n=len(G);M=[r[:] for r in G] + for c in range(n): + p=next((i for i in range(c,n) if M[i][c]),None) + if p is None:return 0 + M[c],M[p]=M[p],M[c] + for i in range(n): + if i!=c and M[i][c]:M[i]=[x^y for x,y in zip(M[i],M[c])] + return 1 +def spanvecs(E): + s={0} + for b in E:s|={x^b for x in s} + return s +ONE=511 +def isometric(E): + """E has orthonormal basis and E^perp (in F2^9) too""" + if not E:return True + if not det2(gram(E)):return False + S=spanvecs(E) + if ONE in S:return False # complement alternating + if all(bin(x).count('1')%2==0 for x in S):return False # E alternating + # E^perp contains ONE? ONE in E^perp iff all vectors of E even-weight -> excluded above + return True +if __name__=='__main__': + w=load();col,first=setup(w);R=len(col) + # which first-frame subspaces are isometric + cand={} + for h,F in first.items(): + for E in subspaces(F):cand.setdefault(E,[]).append(h) + iso={E:G for E,G in cand.items() if isometric(E)} + print('first-frame subspaces',len(cand),'isometric',len(iso),Counter(len(E) for E in iso)) + C=np.zeros((v,R)) + for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) + pot=[] + for E,G in iso.items(): + if len(G)>=2: + rk=np.linalg.matrix_rank(C[:,G]); + if len(G)-rk>0:pot.append((len(E)*(len(G)-rk),E,len(G),rk)) + print('kernel potentials with isometric E',sorted(pot,reverse=True)[:10]) + # gauge: eligible helpers per isometric E + from gauge import prep,span + col2,first2,cap,cands,P=prep(w) + best=[] + for E in iso: + sE=span(E) + el=[h for h in range(R) if sE<=span(first2[h]) and all(sE<=cap[t] for t in col2[h])] + best.append((len(E)*len(el),len(el),E)) + best.sort(reverse=True);print('gauge best isometric E (eps,n,E)',best[:8]) diff --git a/research/e8-complex-gauge-kernel/provenance/kcap.py b/research/e8-complex-gauge-kernel/provenance/kcap.py new file mode 100644 index 0000000000..37e9724fcc --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kcap.py @@ -0,0 +1,13 @@ +from fractions import Fraction as Q +def kappa_of(s_in,eta=Q(1,10**18),beta=Q(1,10**18)): + s=Q(s_in)-Q(1,10**24) + a=Q(384599,10**10) + for _ in range(6):a=(1-s)*s+s*a + q=a*(1-2*eta);margin=(1-eta)*q/(1+q);grid=Q(1,10**18);ticks=margin/grid + return grid*((ticks.numerator-1)//ticks.denominator) +def cap_from_b(b):return float(kappa_of((1-Q(1,10**18))*Q(b))) +if __name__=='__main__': + c=Q('1239085165241180038597')/Q(10**24) + print('check kappa(c bit)',float(kappa_of(c)),'expected 0.001237551733247294') + for name,b in (('baseline cx hosted',1.267453159029119e-3),('kernel77',1.309121737234019e-3),('gauge70+kernel44 (model)',1.329163e-3)): + print(name,'b',b,'kappa cap',cap_from_b(Q(b).limit_denominator(10**18))) diff --git a/research/e8-complex-gauge-kernel/provenance/kern.py b/research/e8-complex-gauge-kernel/provenance/kern.py new file mode 100644 index 0000000000..3ca9dfeb0d --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kern.py @@ -0,0 +1,53 @@ +from cxlab import * +import numpy as np, itertools, sys +def subspaces(F): + """all nonzero subspaces of span(F) as canonical bases, any rank""" + F=list(F);k=len(F);out=set() + vecs=[] + for mask in range(1,1<>i&1:x^=F[i] + vecs.append(x) + # enumerate subspaces by generating from subsets of vectors up to rank k + seen=set() + def rec(cur,start): + for i in range(start,len(vecs)): + b=basis(list(cur)+[vecs[i]]) + if len(b)==len(cur)+1 and b not in seen: + seen.add(b);rec(b,i+1) + rec((),0) + return seen +def setup(w): + A,B=w['A'],w['B'];n=240+w['report']['R'];R=w['report']['R'] + M=ident(n) + for e in A+w['cut']+B:apply(e,M) + dirty=[{} for r in range(n)] + for r in range(v,2*v):dirty[r]={j:x for j,x in M[r].items() if j>=2*v} + for e in w['precondition']:apply(e,dirty) + col=[dict() for _ in range(R)] + for r in range(v,2*v): + for j,x in dirty[r].items():col[j-2*v][r-v]=x + first={} + for seq in (A,B): + for e in seq: + F=basis(e[-1]) + for r in ([e[1]]+([e[2]] if e[0]=='add' else [])): + if r>=2*v:first.setdefault(r-2*v,F) + return col,first +if __name__=='__main__': + w=load();col,first=setup(w);R=len(col) + cand={} + for h,F in first.items(): + for E in subspaces(F):cand.setdefault(E,[]).append(h) + print('first-frame subspaces',len(cand),Counter(len(E) for E in cand)) + C=np.zeros((v,R)) + for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) + pot=[] + for E,G in cand.items(): + if len(G)<2:continue + rk=np.linalg.matrix_rank(C[:,G]);pot.append((len(E)*(len(G)-rk),E,len(G),rk)) + pot.sort(reverse=True) + print('E with positive potential',sum(1 for p in pot if p[0]>0),Counter((len(p[1]),p[2]-p[3]) for p in pot if p[0]>0)) + print(pot[:5]) diff --git a/research/e8-complex-gauge-kernel/provenance/kern2.py b/research/e8-complex-gauge-kernel/provenance/kern2.py new file mode 100644 index 0000000000..23ac0ea211 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kern2.py @@ -0,0 +1,43 @@ +from kern import * +from cxcheck import check +import hostmodel as HM +def span(F): + s={0} + for b in F:s|={x^b for x in s} + return s +def dup_pairs(col): + key=defaultdict(list) + for h,c in enumerate(col): + if not c:continue + ts=sorted(c);f=c[ts[0]] + key[tuple((t,c[t]/f) for t in ts)].append(h) + out=[] + for g in key.values(): + if len(g)==2:out.append(tuple(g)) + return out +def build_pre(col,plan,first): + """plan: list of (pivot, donor, E_basis_tuple) with proportional columns. returns pre ops (register ids absolute) and start dict""" + pre=[];start={} + for p,d,E in sorted(plan,key=lambda x:len(x[2])): + cp,cd=col[p],col[d] + t0=sorted(cd)[0];c=cp[t0]/cd[t0] + assert all(cp.get(t,0)==c*cd.get(t,0) for t in set(cp)|set(cd)) + q=-c + pre.append(['add',2*v+d,2*v+p,q.numerator,q.denominator,list(E)]) + start[2*v+p]=list(E) + return pre,start +if __name__=='__main__': + w=load();w['R']=w['report']['R'];col,first=setup(w) + base,_=check(w);print('base profile',base['local_profile']) + pairs=dup_pairs(col);print(len(pairs)) + plan=[] + for a,b in pairs: + I=span(first[a])&span(first[b]);x=[y for y in I if y] + assert len(x)==1 + plan.append((a,b,(x[0],))) + pre,start=build_pre(col,plan,first) + rep,edges=check(w,pre=pre,start=start) + print('exact ok',rep.get('exact_arbitrary_dirt'),rep['exact_inverse_transpose'],'comp cols',rep['comp_cols'],'profile',rep['local_profile'],'sumwidth',sum(rep['widths'])) + r0=HM.evaluate({1:1912,2:784,3:168,4:224,5:392,8:24},[9]*560) + r=HM.evaluate(rep['local_profile'],rep['widths']) + print('b base',r0['b'],'b kernel56',r['b'],'%+.3f%%'%(100*(r['b']/r0['b']-1)),'W',r['W'],r['banks']) diff --git a/research/e8-complex-gauge-kernel/provenance/kern3.py b/research/e8-complex-gauge-kernel/provenance/kern3.py new file mode 100644 index 0000000000..eaf0ff7d28 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kern3.py @@ -0,0 +1,73 @@ +"""General exact kernel (shared-donor) for the complex word: partition helpers by rank-1 entrance E; donors independent, pivots dependent.""" +from kern2 import * +import itertools,random +def solve_rel(col,donors,p): + """exact rational coefficients c_d with col[p]=sum c_d col[d] (or None)""" + cols=sorted({t for d in donors for t in col[d]}|set(col[p])) + if not cols:return {} + idx={t:i for i,t in enumerate(cols)} + M=[[Q(0)]*(len(donors)+1) for _ in cols] + for ci,d in enumerate(donors): + for t,x in col[d].items():M[idx[t]][ci]=x + for t,x in col[p].items():M[idx[t]][-1]=x + piv=[];r=0 + for c in range(len(donors)): + pr=next((i for i in range(r,len(M)) if M[i][c]),None) + if pr is None:continue + M[r],M[pr]=M[pr],M[r];q=M[r][c];M[r]=[x/q for x in M[r]] + for i in range(len(M)): + if i!=r and M[i][c]: + f=M[i][c];M[i]=[a-f*b for a,b in zip(M[i],M[r])] + piv.append(c);r+=1 + for i in range(r,len(M)): + if M[i][-1]:return None + return {donors[c]:M[i][-1] for i,c in enumerate(piv) if M[i][-1]} +def plan_greedy(col,first,seed=0,minE=1): + R=len(col) + cand={} + for h,F in first.items(): + for E in subspaces(F):cand.setdefault(E,[]).append(h) + C=np.zeros((v,R)) + for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) + Es=[E for E,G in cand.items() if len(G)>=2 and len(G)-np.linalg.matrix_rank(C[:,G])>0] + free=set(range(R));groups=[] + while True: + best=None + for E in Es: + G=[h for h in cand[E] if h in free] + if len(G)<2:continue + rk=np.linalg.matrix_rank(C[:,G]);pv=len(G)-rk + val=pv*len(E) + if best is None or val>best[0]:best=(val,E,G) + if not best or best[0]<=0:break + val,E,G=best + # donors: greedy independent in order of G; pivots rest + donors=[];rows=np.zeros((v,0)) + for h in sorted(G): + c=C[:,h:h+1] + if np.linalg.matrix_rank(np.hstack([rows,c]))>rows.shape[1]:rows=np.hstack([rows,c]);donors.append(h) + pivots=[h for h in G if h not in donors] + groups.append((E,donors,pivots));free-=set(G) + return groups +def groups_to_pre(col,groups): + pre=[];start={};eps=0 + for E,donors,pivots in sorted(groups,key=lambda g:len(g[0])): + for p in pivots: + rel=solve_rel(col,donors,p) + assert rel is not None,(E,p) + start[2*v+p]=list(E);eps+=len(E) + for d,c in rel.items(): + q=-c;pre.append(['add',2*v+d,2*v+p,q.numerator,q.denominator,list(E)]) + return pre,start,eps +if __name__=='__main__': + w=load();w['R']=w['report']['R'];col,first=setup(w) + groups=plan_greedy(col,first) + print([(E,len(d),len(p)) for E,d,p in groups]) + pre,start,eps=groups_to_pre(col,groups) + print('pre ops',len(pre),'eps',eps) + rep,edges=check(w,pre=pre,start=start) + print('exact',rep['exact_arbitrary_dirt'],rep['exact_inverse_transpose'],rep['local_profile'],'sumwidth',sum(rep['widths']),'newedges',len(edges)) + r=HM.evaluate(rep['local_profile'],rep['widths']) + r0=HM.evaluate({1:1912,2:784,3:168,4:224,5:392,8:24},[9]*560) + print('b',r['b'],'%+.3f%%'%(100*(r['b']/r0['b']-1)),'W',r['W'],r['banks']) diff --git a/research/e8-complex-gauge-kernel/provenance/kern4.py b/research/e8-complex-gauge-kernel/provenance/kern4.py new file mode 100644 index 0000000000..04d7cec6e3 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kern4.py @@ -0,0 +1,46 @@ +from kern3 import * +def rand_plan(col,first,C,cand,Es,rnd): + R=len(col);free=set(range(R));groups=[] + Eorder=Es[:] + while True: + opts=[] + for E in Eorder: + G=[h for h in cand[E] if h in free] + if len(G)<2:continue + rk=np.linalg.matrix_rank(C[:,G]);pv=len(G)-rk + if pv>0:opts.append((pv,E,G)) + if not opts:break + # pick randomly weighted by pivots + tot=sum(o[0] for o in opts);x=rnd.random()*tot;acc=0 + for o in opts: + acc+=o[0] + if acc>=x:pick=o;break + pv,E,G=pick + donors=[];rows=np.zeros((v,0));Gs=G[:];rnd.shuffle(Gs) + for h in Gs: + c=C[:,h:h+1] + if np.linalg.matrix_rank(np.hstack([rows,c]))>rows.shape[1]:rows=np.hstack([rows,c]);donors.append(h) + pivots=[h for h in G if h not in donors] + groups.append((E,donors,pivots));free-=set(G) + # completion: free helpers that can pivot onto existing classes + for h in sorted(free): + for gi,(E,donors,pivots) in enumerate(groups): + if not span(E)<=span(first[h]):continue + M=np.hstack([C[:,donors],C[:,h:h+1]]) + if np.linalg.matrix_rank(M)==len(donors):pivots.append(h);free.discard(h);break + return groups +if __name__=='__main__': + w=load();w['R']=w['report']['R'];col,first=setup(w);R=len(col) + cand={} + for h,F in first.items(): + for E in subspaces(F):cand.setdefault(E,[]).append(h) + C=np.zeros((v,R)) + for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) + Es=[E for E,G in cand.items() if len(G)>=2 and len(G)-np.linalg.matrix_rank(C[:,G])>0] + best=0;bg=None + for seed in range(300): + rnd=random.Random(seed);g=rand_plan(col,first,C,cand,Es,rnd) + tot=sum(len(p)*len(E) for E,d,p in g) + if tot>best:best=tot;bg=g;print(seed,tot,[(E[0],len(d),len(p)) for E,d,p in g],flush=True) + import pickle;pickle.dump(bg,open('kern4_best.pkl','wb')) diff --git a/research/e8-complex-gauge-kernel/provenance/kern5.py b/research/e8-complex-gauge-kernel/provenance/kern5.py new file mode 100644 index 0000000000..5064b882cc --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kern5.py @@ -0,0 +1,50 @@ +from kern4 import * +import math,pickle,time +def nullity(C,S): + return len(S)-(np.linalg.matrix_rank(C[:,sorted(S)],tol=1e-8) if S else 0) +def sa(col,first,C,cand,Es,iters=30000,seed=0,init=None,T0=0.6): + rnd=random.Random(seed);big=sorted({h for E in Es for h in cand[E]}) + allowed={h:[E for E in Es if h in set(cand[E])] for h in big} + cls={E:set() for E in Es};asg={} + if init: + for E,d,p in init: + for h in d+p: + if E in cls:cls[E].add(h);asg[h]=E + val={E:nullity(C,cls[E]) for E in Es} + cur=sum(val.values());best=cur;bestasg=dict(asg);t0=time.time() + for it in range(iters): + T=T0*(1-it/iters)+0.02 + h=rnd.choice(big);old=asg.get(h) + choices=allowed[h]+[None] + new=rnd.choice(choices) + if new==old:continue + dv=0;newvals={} + if old is not None: + S=cls[old]-{h};nv=nullity(C,S);newvals[old]=nv;dv+=nv-val[old] + if new is not None: + S=cls[new]|{h};nv=nullity(C,S);newvals[new]=nv;dv+=nv-val[new] + if dv>=0 or rnd.random()best:best=cur;bestasg=dict(asg) + return best,bestasg +if __name__=='__main__': + w=load();w['R']=w['report']['R'];col,first=setup(w);R=len(col) + cand={} + for h,F in first.items(): + for E in subspaces(F):cand.setdefault(E,[]).append(h) + C=np.zeros((v,R)) + for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) + Es=[E for E,G in cand.items() if len(G)>=2 and len(G)-np.linalg.matrix_rank(C[:,G])>0] + init=pickle.load(open('kern4_best.pkl','rb')) + print('init',sum(len(p) for E,d,p in init)) + b0=None + for seed in range(4): + best,asg=sa(col,first,C,cand,Es,iters=40000,seed=seed,init=init) + print('seed',seed,'best nullity sum',best,flush=True) + if b0 is None or best>b0[0]:b0=(best,asg) + pickle.dump(b0,open('kern5_best.pkl','wb')) diff --git a/research/e8-complex-gauge-kernel/provenance/kern6.py b/research/e8-complex-gauge-kernel/provenance/kern6.py new file mode 100644 index 0000000000..e2699ebaff --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/kern6.py @@ -0,0 +1,29 @@ +from kern5 import * +def asg_to_groups(C,asg): + cls={} + for h,E in asg.items():cls.setdefault(E,[]).append(h) + groups=[] + for E,G in cls.items(): + G=sorted(G);donors=[];rows=np.zeros((v,0)) + for h in G: + c=C[:,h:h+1] + if np.linalg.matrix_rank(np.hstack([rows,c]),tol=1e-8)>rows.shape[1]:rows=np.hstack([rows,c]);donors.append(h) + pivots=[h for h in G if h not in donors] + if pivots:groups.append((E,donors,pivots)) + return groups +if __name__=='__main__': + w=load();w['R']=w['report']['R'];col,first=setup(w);R=len(col) + C=np.zeros((v,R)) + for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) + best,asg=pickle.load(open('kern5_best.pkl','rb')) + groups=asg_to_groups(C,asg) + print([(E[0],len(d),len(p)) for E,d,p in groups]) + pre,start,eps=groups_to_pre(col,groups) + print('pre ops',len(pre),'eps',eps) + rep,edges=check(w,pre=pre,start=start) + print('exact',rep['exact_arbitrary_dirt'],rep['exact_inverse_transpose'],rep['local_profile'],'sumwidth',sum(rep['widths']),'newedges',len(edges)) + r=HM.evaluate(rep['local_profile'],rep['widths'],exact=True) + r0=HM.evaluate({1:1912,2:784,3:168,4:224,5:392,8:24},[9]*560,exact=True) + print('b',r['b'],'%+.3f%%'%(100*(r['b']/r0['b']-1)),'W',r['W'],r['banks'],'hosted',r['hosted']) + pickle.dump((pre,start),open('kern6_word.pkl','wb')) diff --git a/research/e8-complex-gauge-kernel/provenance/sa_long.py b/research/e8-complex-gauge-kernel/provenance/sa_long.py new file mode 100644 index 0000000000..302d7d24e1 --- /dev/null +++ b/research/e8-complex-gauge-kernel/provenance/sa_long.py @@ -0,0 +1,15 @@ +import sys +from kern5 import * +seed=int(sys.argv[1]);iters=int(sys.argv[2]) +w=load();w['R']=w['report']['R'];col,first=setup(w);R=len(col) +cand={} +for h,F in first.items(): + for E in subspaces(F):cand.setdefault(E,[]).append(h) +C=np.zeros((v,R)) +for h in range(R): + for t,x in col[h].items():C[t,h]=float(x) +Es=[E for E,G in cand.items() if len(G)>=2 and len(G)-np.linalg.matrix_rank(C[:,G])>0] +init=pickle.load(open('kern4_best.pkl','rb')) +best,asg=sa(col,first,C,cand,Es,iters=iters,seed=seed,init=init,T0=0.5) +print('seed',seed,'best',best,flush=True) +pickle.dump((best,asg),open('sa_long_%d.pkl'%seed,'wb')) diff --git a/research/e8-complex-gauge-kernel/verify.py b/research/e8-complex-gauge-kernel/verify.py new file mode 100644 index 0000000000..8cecfbd4b8 --- /dev/null +++ b/research/e8-complex-gauge-kernel/verify.py @@ -0,0 +1,99 @@ +"""Fresh replay: PR #442 in full, regression anchor, the gauge + kernel complex word through the extended pipeline, mutation controls, +independent hosting audit, certified complex saving b and the strict outer assembly for the listed bit suppliers. +usage: python -B research/e8-complex-gauge-kernel/verify.py /absolute/new/output [--all] [--discover-check] + --all also run the kernel-only and gauge-only words (per-tool numbers) + (always) the independent Lemma G check stage (code/lemmaG) runs on the headline word and the anchor, and with --all on the per-tool words + --discover-check recompute the frozen hosting selections with scipy/HiGHS and require byte equality (needs numpy, scipy) +needs: Python 3.11+ (standard library; numpy for the Lemma G check stage, numpy and scipy for --discover-check); the repository tree of PR #442 (this package lives in it). +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code.""" +from pathlib import Path +import hashlib, json, os, subprocess, sys, time +assert __debug__ +ROOT = Path(__file__).resolve().parent; R = ROOT.parent; CODE = ROOT / 'code' +args = [a for a in sys.argv[1:] if not a.startswith('--')]; flags = {a for a in sys.argv[1:] if a.startswith('--')} +assert len(args) == 1 and flags <= {'--all', '--discover-check', '--write-expected'}, __doc__ +out = Path(args[0]).resolve(); assert not out.exists() and not out.is_relative_to(R) +read = lambda p: json.loads(Path(p).read_text()); sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest() +def inventory(p): return {f.relative_to(p).as_posix(): sha(f) for f in sorted(Path(p).rglob('*')) if f.is_file() and '__pycache__' not in f.parts} +def integrity(): + actual = inventory(ROOT); actual.pop('MANIFEST.json'); assert actual == read(ROOT / 'MANIFEST.json')['files'], 'package manifest differs' + for name, exp in read(ROOT / 'SOURCE.json')['packages'].items(): assert inventory(R / name) == exp['files'], ('upstream package differs', name) +integrity(); out.mkdir(parents=True) +env = dict(os.environ, PYTHONDONTWRITEBYTECODE='1', PYTHONINTMAXSTRDIGITS='0'); env.pop('PYTHONOPTIMIZE', None) +PY = sys.executable; steps = [] +def run(name, cmd, cwd=None): + t = time.monotonic(); log = out / (name.replace(' ', '_') + '.log'); print('RUN', name, flush=True) + with log.open('w') as f: q = subprocess.run([PY, '-B', *map(str, cmd)], cwd=cwd, env=env, stdout=f, stderr=subprocess.STDOUT) + if q.returncode: raise RuntimeError((name, q.returncode, log.read_text()[-3000:])) + steps.append(dict(name=name, seconds=round(time.monotonic() - t, 1), log_sha256=sha(log))); print('PASS', name, flush=True) +try: + p442 = out / 'p442' + run('parent-442-full', [R / 'idle-axis-hosting/verify.py', p442]) + assert read(p442 / 'RECEIPT.json')['status'] == 'PASS_FULL_IDLE_AXIS_HOSTING_COMPOSITION' + changed = p442 / 'parent/changed' + # ---- regression anchor: empty selection reproduces PR #433/#442 byte for byte + run('anchor', [CODE / 'run_variant.py', 'anchor', ROOT / 'data/selections/empty.json', 'complex', changed, out / 'anchor', '--anchor']) + a, b = out / 'anchor/hosted', p442 / 'complex' + assert (a / 'GLOBAL-TEMPLATE.json.gz').read_bytes() == (b / 'GLOBAL-TEMPLATE.json.gz').read_bytes(), 'anchor: hosted template differs from PR #442' + ha, hb = read(a / 'HOSTED.json'), read(b / 'HOSTED.json'); ha.pop('seconds'); hb.pop('seconds'); assert ha == hb + # ---- the words + words = [('gauge80-kernel42', 'complex-gauge80-kernel42')] + ([('kernel79', 'complex-kernel79'), ('gauge80', 'complex-gauge80')] if '--all' in flags else []) + procs = [] + for i, (w, key) in enumerate(words): + extra = (['--controls'] if w == 'gauge80-kernel42' else []) + (['--discover-check'] if '--discover-check' in flags else []) + t = time.monotonic(); log = (out / ('variant-' + w + '.log')).open('w'); print('RUN variant', w, flush=True) + procs.append((w, t, log, subprocess.Popen([PY, '-B', str(CODE / 'run_variant.py'), w, str(ROOT / 'data/selections' / (w + '.json')), key, str(changed), str(out / w), *extra], + cwd=out, env=env, stdout=log, stderr=subprocess.STDOUT))) + for w, t, log, p in procs: + rc = p.wait(); log.close() + if rc: raise RuntimeError((w, rc, (out / ('variant-' + w + '.log')).read_text()[-3000:])) + steps.append(dict(name='variant ' + w, seconds=round(time.monotonic() - t, 1), log_sha256=sha(out / ('variant-' + w + '.log')))); print('PASS variant', w, flush=True) + # ---- independent check stage for Lemma G (code/lemmaG: imports no package script): labels, exhaustive instance identities, end-to-end identity, necessity mutants + lgw = [(w, ['--mutants'] if w == 'gauge80-kernel42' else []) for w, key in words] + [('anchor', [])] + procs = [] + for w, extra in lgw: + t = time.monotonic(); log = (out / ('lemmaG-' + w + '.log')).open('w'); print('RUN lemma G checks', w, flush=True) + procs.append((w, t, log, subprocess.Popen([PY, '-B', str(CODE / 'lemmaG/check.py'), str(out), w, str(out / 'lemmaG' / w), *extra], cwd=out, env=env, stdout=log, stderr=subprocess.STDOUT))) + for w, t, log, p in procs: + rc = p.wait(); log.close() + if rc: raise RuntimeError(('lemma G checks', w, rc, (out / ('lemmaG-' + w + '.log')).read_text()[-3000:])) + steps.append(dict(name='lemma G checks ' + w, seconds=round(time.monotonic() - t, 1), log_sha256=sha(out / ('lemmaG-' + w + '.log')))); print('PASS lemma G checks', w, flush=True) + lemmaG = {w: read(out / 'lemmaG' / w / 'LEMMA-G-CHECK.json') for w, extra in lgw} + # ---- certification and outer assembly + r442 = read(p442 / 'RESULT.json') + bits = [dict(label='#442 bit word (R747, nine stages)', c=r442['bit_lower'], charged_two_level_coefficient_bits=r442['bit']['charged_two_level_coefficient_bits'], + row_coefficient=r442['bit']['row_coefficient'], source='run by this package inside the PR #442 replay')] + read(ROOT / 'data/bit-suppliers-pinned.json') + (out / 'BITS.json').write_text(json.dumps(bits, indent=1) + '\n') + results = {} + for w, key in words: + wd = out / w + run('assemble ' + w, [CODE / 'assemble_gk.py', changed, wd / 'split-centres', wd / 'hosted', wd / 'HOSTING-AUDIT.json', out / 'BITS.json', out / ('RESULT-' + w + '.json')]) + results[w] = read(out / ('RESULT-' + w + '.json')) + assert results[w]['complex_template_sha256'] == read(wd / 'hosted/HOSTED.json')['template_sha256'] + head = results['gauge80-kernel42'] + summary = dict(status='PASS_FULL_COMPLEX_GAUGE_KERNEL_COMPOSITION', complex_lower=head['complex_lower'], complex_decimal=head['complex_decimal'], + complex_cap_kappa_decimal=head['complex_cap_kappa_decimal'], baseline_442_complex=str(read(p442 / 'RESULT.json')['complex_lower']), + suppliers={r['label']: dict(kappa=r['kappa'], kappa_decimal=r['kappa_decimal'], binding=r['binding_component']) for r in head['suppliers']}, + words={w: dict(complex_lower=r['complex_lower'], hosted_template_sha256=r['complex_template_sha256'], live=r['complex']['live']) for w, r in results.items()}, + mutation_controls_word=read(out / 'gauge80-kernel42/CONTROLS-WORD.json')['rejected'], mutation_controls_selection=read(out / 'gauge80-kernel42/CONTROLS-SELECTION.json')['refused'], + mutation_controls_certifying_pipeline=[c['control'] for c in read(out / 'gauge80-kernel42/CONTROLS-PIPELINE.json')['controls']], + mutation_controls_one_owner_rule=[c['control'] for c in read(out / 'gauge80-kernel42/CONTROLS-HOSTING.json')['controls']], + replay_controls=read(out / 'gauge80-kernel42/split-centres/INDEPENDENT-REPLAY.json')['mutation_controls_rejected'], + wrapper_check={k: read(out / 'gauge80-kernel42/LEMMA-A.json')[k] for k in ('frames', 'wrappers_reject', 'all_even_weight', 'all_totally_isotropic')}, + hosting_audit_controls=read(out / 'gauge80-kernel42/HOSTING-AUDIT.json')['mutations_rejected'], + hosting_audit_controls_not_applicable=read(out / 'gauge80-kernel42/HOSTING-AUDIT.json')['controls_not_applicable'], + hosting_rule=read(out / 'gauge80-kernel42/HOSTING-AUDIT.json')['one_helper_per_family'], lemma_G_independent_checks=lemmaG) + if '--write-expected' in flags: (out / 'EXPECTED.candidate.json').write_text(json.dumps(summary, indent=1, sort_keys=True) + '\n') # development: review, then copy to EXPECTED.json + exp = read(ROOT / 'EXPECTED.json') if (ROOT / 'EXPECTED.json').exists() else None + if exp is not None and '--all' in flags: + for k, v in exp.items(): assert summary[k] == v, (k, summary[k], v) + elif exp is not None: + for k in ('complex_lower', 'complex_decimal', 'complex_cap_kappa_decimal', 'baseline_442_complex', 'suppliers', 'mutation_controls_word', 'mutation_controls_selection', 'mutation_controls_certifying_pipeline', 'mutation_controls_one_owner_rule', 'replay_controls', 'wrapper_check', 'hosting_audit_controls', 'hosting_audit_controls_not_applicable', 'hosting_rule'): + assert summary[k] == exp[k], (k, summary[k], exp[k]) + assert summary['words']['gauge80-kernel42'] == exp['words']['gauge80-kernel42'] + for w_, v_ in summary['lemma_G_independent_checks'].items(): assert v_ == exp['lemma_G_independent_checks'][w_], ('lemma G checks', w_) + assert inventory(ROOT).get('MANIFEST.json') is not None and (lambda a: (a.pop('MANIFEST.json'), a)[1] == read(ROOT / 'MANIFEST.json')['files'])(inventory(ROOT)), 'package modified during verification' + receipt = dict(summary, steps=steps, python=sys.version.split()[0], manifest_sha256=sha(ROOT / 'MANIFEST.json')) + (out / 'RECEIPT.json').write_text(json.dumps(receipt, indent=2) + '\n'); print(json.dumps({k: v for k, v in summary.items() if not k.startswith('mutation_controls') and k not in ('hosting_audit_controls', 'replay_controls')}, indent=1)) +except BaseException as e: + (out / 'FAILURE.json').write_text(json.dumps(dict(error=repr(e), completed=steps), indent=2) + '\n'); raise diff --git a/research/e8-early-reset-kernel/EXPECTED.json b/research/e8-early-reset-kernel/EXPECTED.json new file mode 100644 index 0000000000..e286628f86 --- /dev/null +++ b/research/e8-early-reset-kernel/EXPECTED.json @@ -0,0 +1,10 @@ +{ + "status": "PASS_CONDITIONAL_EARLY_RESET_KERNEL_ASSEMBLY", + "kappa": "566550276142217/500000000000000000", + "kappa_decimal": "0.001133100552284434", + "bit_lower": "1134385925603239057397/1000000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "bit_template_sha256": "f9ce9ac945d9e8ea737dc5e456e366a7e2a21d8b989d24b742d7f124d26fb32f", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f" +} diff --git a/research/e8-early-reset-kernel/LICENSE b/research/e8-early-reset-kernel/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/e8-early-reset-kernel/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/e8-early-reset-kernel/MANIFEST.json b/research/e8-early-reset-kernel/MANIFEST.json new file mode 100644 index 0000000000..c96c75aa92 --- /dev/null +++ b/research/e8-early-reset-kernel/MANIFEST.json @@ -0,0 +1,32 @@ +{ + "files": { + "EXPECTED.json": "6710a99055d7ee1d83d9f811822bb72db84f6ce95bd4e1e17f1df1659c7e958b", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "NOTICE.md": "ff88b6031fe2fb5cbc483e8fcc08d228eaf2c982221adb3659da234dfa24cfeb", + "PROOF.md": "fb4e1c3a23e3a0be48b5254133e584dad6fb523042ca8ef70358684fb9185962", + "README.md": "4d7d736eda667533ab55bf3949e30832d4676d7ebeee00d9608307ecc5aacd4b", + "SELECTION.json": "b5f5d8c78d912820c8ed1a67c21062bec799714b9caa6724dfd515306ad42a2b", + "SOURCE.json": "a5e84250b687624b2158597831fb36a5f2b068983862c491f8e1020c9806cc65", + "VALIDATION.json": "77ad775cf69f5d913568b6276b0dfeb2eaef0306f57b71c0a467bff793807267", + "apply.py": "0d530e9703e1d1734c7af205bd393cba89ac41f75ed9781ea3dc5e46650f44f5", + "bit_audit.py": "203bb609952ad7b7ca761e9f9883ee9fa35a0a0474503b396d47a31169102e7d", + "bit_global.py": "79c7dc84e65dca10c35c842cf170e4719d45c38a25d03bf762332b24c700b6c9", + "bit_price.py": "36bf15803567a95b139a908461541bf19efe1f5b85fb31c270021833ab1393ee", + "combined.py": "4d514b6c70e969ec306d8c2bb38edec95b0cb7fa09f48dadbec8aa1eead69ce1", + "local-evidence/ASSEMBLY.json": "7c3cc4b503e4cf0fd3e050be46ad0da183c5b1c490f4901245df944fd9d6194e", + "local-evidence/AUDIT.json": "76a146a9123d8b653e6e46ff93f153653f9cefd0f5c3fdd264a59f1322110262", + "local-evidence/BIT-PRICE.json": "9a4a320cab1ce62b0c2329ac1bf3b81f73580fd603a406e4bfaae2962dfdad35", + "local-evidence/FULL-PYTHON311.json": "62b37525bf7b60c0d9101ed571681f3bf46ea75df065939864307e4986018332", + "local-evidence/FULL-PYTHON314.json": "85797531db037d06fb597a4c9b6ef6bd71e6a0ab4f220ae70b1b6bf3aeda205f", + "local-evidence/GLOBAL.json": "16c4e829eea1b2d12b70cec7e6a9c0e33ea0eae98a40894a3b779790fd2efbb3", + "local-evidence/SOURCE-SPANS.log": "bdf95dbce8337be57aab8a3d3b42a711ee276496c40cbb4c5356fc9cc9b2e811", + "source_span.py": "4772d177f37254c6f854af5ee3871aca193cfb24307a53c143c3bf517e56631e", + "vendor/kernel417/LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "vendor/kernel417/e8core.py": "3f4e25f700b7eb5821ab9cdfc65541f3f921baffeb8704beb21c6d7072052d29", + "vendor/kernel417/engines/base_two_moment.py": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098", + "vendor/kernel417/engines/moment.py": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482", + "vendor/kernel417/engines/outer.py": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c", + "vendor/kernel417/stages.py": "e73ab7836519510ed30dd7e3022dae557fa50fc513d723197929bff741859668", + "verify.py": "16c07414bc956744dc93b8e35b642267ea9819be922b0d3e081c543fdbf92a70" + } +} diff --git a/research/e8-early-reset-kernel/NOTICE.md b/research/e8-early-reset-kernel/NOTICE.md new file mode 100644 index 0000000000..0673347680 --- /dev/null +++ b/research/e8-early-reset-kernel/NOTICE.md @@ -0,0 +1,3 @@ +Rohan Arun with substantial OpenAI Codex assistance. Apache-2.0. + +New contribution: composition of eleven early bit resets with 110 remapped surviving response-kernel relations. Chafik Boukhalfa/chafreaky #417 supplied the kernel principle and independent replay; #435 supplied the source selection and mixed-width bank implementation. icekylinx #433 supplied split centres and source-basis reuse; ai-nanachi #426 supplied clean-reset reuse; Zhihao Chen #425/#386, Dylan Crow #370 and Jacob Sussman supplied the inherited construction. All vendored notices and parent sources remain preserved. diff --git a/research/e8-early-reset-kernel/PROOF.md b/research/e8-early-reset-kernel/PROOF.md new file mode 100644 index 0000000000..25cfa0e865 --- /dev/null +++ b/research/e8-early-reset-kernel/PROOF.md @@ -0,0 +1,9 @@ +# Composed response cancellation after early helper reuse + +First reconstruct the eleven early clean resets using the pinned earlier-reset package, including fresh compensation and cleanup. Its exact all-column target response determines which remapped kernel relations remain valid. Retain a pivot p with entrance E and donors D only if response(p) equals the XOR of donor responses, E lies inside each participant's first frame, pivots and donors are disjoint, and each shared donor serves a single entrance. Omit entries invalidated by physical aliases, changed responses, or changed first frames. Choose total entrance rank divisible by eight for exact bank packing. + +Remove pivot columns from the initial zero-frame target compensation. Start each pivot at E, emit donor += pivot at E before the main word, and emit the inverse at the full frame after cleanup. The exact response relation cancels the omitted compensation. The entire composed program is replayed on all independent columns; the PR417/435 auditor additionally checks integer source-span legality. All unchanged rational frames and every nested/reflected transition are independently checked by the emitted-template audit. + +Residual helper width is 8 minus its entrance rank. With eight replicas, width-seven slots are packed eight at a time with one width-eight slot; width-four slots pack sixteen at a time; remaining width-eight slots pack eight at a time. Every bank is full, every owner disjoint, every helper slot is accounted for, and all 72 emitted local invocations are checked. The emitted histogram, physical stock, coefficient growth, finite cost invoice, two exact moment engines, six bootstrap levels and 47 outer inequalities are recomputed after both transformations. + +No separately reported numerical gains are added. The complex supplier is unchanged and all its phases are freshly replayed by the full wrapper. All-size compiler, dirty-bank, compressed-window, restored-work, tape/common-grid, precision and analytic interfaces remain conditional assumptions. No new Lean theorem or unconditional multiplication bound is claimed. diff --git a/research/e8-early-reset-kernel/README.md b/research/e8-early-reset-kernel/README.md new file mode 100644 index 0000000000..dc413e500b --- /dev/null +++ b/research/e8-early-reset-kernel/README.md @@ -0,0 +1,9 @@ +# Early reset and response-kernel composition + +Conditional kappa = 0.001133100552284434, above PR436's 0.001128983115440183. Eleven earlier resets give R747. After remapping the PR435/417 kernel selection and rejecting changed/invalid response relations, 110 entries survive with entrance rank 128 and 97 donor slots. There are 731 width-64 helper banks per stage, 14,259 live and 14,268 physical families. + +Run `python -B research/e8-early-reset-kernel/verify.py /absolute/new/output` using the Python standard library. The wrapper freshly replays the full earlier-reset package and its parent phases, then applies and checks the kernel composition. + +At draft update, exact changed scalar/frames/source-span checks, global banks, independent audit, two moments and full finite assembly passed. Both Python versions passed the earlier-reset parent wrapper. The new combined wrapper and GitHub CI remain pending. These are conditional bounds, retaining every stated all-size interface. + +The full uninterrupted wrapper now passes locally on Python 3.11 and Python 3.14 against 98b2d164fe0d51253faa05b8fb14cd82e57ef841. Both regenerate every parent phase and every changed program; receipts are in local-evidence/FULL-PYTHON*.json. GitHub CI remains pending. diff --git a/research/e8-early-reset-kernel/SELECTION.json b/research/e8-early-reset-kernel/SELECTION.json new file mode 100644 index 0000000000..fff02ebc1e --- /dev/null +++ b/research/e8-early-reset-kernel/SELECTION.json @@ -0,0 +1,1696 @@ +{ + "status": "PASS_LOCAL_RESPONSE_KERNEL_AND_FIRST_MOMENT", + "input_sha256": "98ffef9246c8bf6c537ab5e134321abea05cf0b7830c9e3fd92cbe4e88d8c308", + "output_sha256": "da4aa797d6dad909fd1faaa90abea749b026299ac8cad3ad0a4a248e16bdb5f5", + "entries": [ + [ + [ + 2 + ], + 738, + [ + 257, + 736 + ] + ], + [ + [ + 2 + ], + 739, + [ + 256, + 737 + ] + ], + [ + [ + 1 + ], + 741, + [ + 250, + 740 + ] + ], + [ + [ + 1 + ], + 743, + [ + 248, + 742 + ] + ], + [ + [ + 0 + ], + 745, + [ + 244, + 744 + ] + ], + [ + [ + 0 + ], + 747, + [ + 242, + 746 + ] + ], + [ + [ + 4 + ], + 751, + [ + 779, + 835 + ] + ], + [ + [ + 4 + ], + 752, + [ + 268, + 750 + ] + ], + [ + [ + 4 + ], + 753, + [ + 269, + 779, + 835 + ] + ], + [ + [ + 5 + ], + 754, + [ + 820, + 900 + ] + ], + [ + [ + 5 + ], + 755, + [ + 272, + 820, + 900 + ] + ], + [ + [ + 1 + ], + 757, + [ + 248, + 756 + ] + ], + [ + [ + 0 + ], + 761, + [ + 242, + 760 + ] + ], + [ + [ + 7 + ], + 767, + [ + 287, + 765 + ] + ], + [ + [ + 1 + ], + 769, + [ + 248, + 768 + ] + ], + [ + [ + 1 + ], + 771, + [ + 249, + 770 + ] + ], + [ + [ + 0 + ], + 773, + [ + 242, + 772 + ] + ], + [ + [ + 0 + ], + 777, + [ + 762, + 763, + 776 + ] + ], + [ + [ + 4 + ], + 781, + [ + 269, + 779 + ] + ], + [ + [ + 2 + ], + 783, + [ + 257, + 782 + ] + ], + [ + [ + 4 + ], + 784, + [ + 750, + 868 + ] + ], + [ + [ + 4 + ], + 785, + [ + 268, + 750, + 868 + ] + ], + [ + [ + 0 + ], + 787, + [ + 241, + 786 + ] + ], + [ + [ + 0 + ], + 789, + [ + 748, + 749, + 788 + ] + ], + [ + [ + 0 + ], + 791, + [ + 762, + 763, + 790 + ] + ], + [ + [ + 5 + ], + 795, + [ + 275, + 793 + ] + ], + [ + [ + 2 + ], + 797, + [ + 257, + 796 + ] + ], + [ + [ + 2 + ], + 799, + [ + 256, + 798 + ] + ], + [ + [ + 0 + ], + 801, + [ + 748, + 749, + 800 + ] + ], + [ + [ + 0 + ], + 803, + [ + 241, + 802 + ] + ], + [ + [ + 0 + ], + 804, + [ + 762, + 776, + 790 + ] + ], + [ + [ + 0 + ], + 805, + [ + 763, + 776, + 790 + ] + ], + [ + [ + 7 + ], + 808, + [ + 284, + 806 + ] + ], + [ + [ + 4 + ], + 809, + [ + 269, + 807 + ] + ], + [ + [ + 7 + ], + 811, + [ + 764, + 766, + 810 + ] + ], + [ + [ + 4 + ], + 813, + [ + 268, + 812 + ] + ], + [ + [ + 0 + ], + 814, + [ + 776, + 790 + ] + ], + [ + [ + 0 + ], + 815, + [ + 762, + 763, + 776, + 790 + ] + ], + [ + [ + 0 + ], + 817, + [ + 241, + 816 + ] + ], + [ + [ + 0 + ], + 818, + [ + 748, + 800 + ] + ], + [ + [ + 0 + ], + 819, + [ + 749, + 800 + ] + ], + [ + [ + 5 + ], + 822, + [ + 272, + 820 + ] + ], + [ + [ + 5 + ], + 823, + [ + 275, + 821 + ] + ], + [ + [ + 3 + ], + 825, + [ + 263, + 824 + ] + ], + [ + [ + 5 + ], + 827, + [ + 274, + 826 + ] + ], + [ + [ + 0 + ], + 828, + [ + 762, + 790 + ] + ], + [ + [ + 0 + ], + 829, + [ + 763, + 790 + ] + ], + [ + [ + 0 + ], + 830, + [ + 748, + 788 + ] + ], + [ + [ + 0 + ], + 831, + [ + 749, + 788 + ] + ], + [ + [ + 0 + ], + 832, + [ + 786, + 802, + 816 + ] + ], + [ + [ + 0 + ], + 833, + [ + 241, + 786, + 802, + 816 + ] + ], + [ + [ + 7 + ], + 836, + [ + 283, + 834 + ] + ], + [ + [ + 4 + ], + 837, + [ + 269, + 835 + ] + ], + [ + [ + 2 + ], + 838, + [ + 736, + 782 + ] + ], + [ + [ + 2 + ], + 839, + [ + 257, + 736, + 782 + ] + ], + [ + [ + 4 + ], + 840, + [ + 750, + 812 + ] + ], + [ + [ + 4 + ], + 841, + [ + 268, + 750, + 812 + ] + ], + [ + [ + 1 + ], + 845, + [ + 250, + 844 + ] + ], + [ + [ + 1 + ], + 847, + [ + 249, + 846 + ] + ], + [ + [ + 5 + ], + 851, + [ + 275, + 849 + ] + ], + [ + [ + 2 + ], + 852, + [ + 736, + 796 + ] + ], + [ + [ + 2 + ], + 853, + [ + 257, + 736, + 796 + ] + ], + [ + [ + 2 + ], + 855, + [ + 256, + 854 + ] + ], + [ + [ + 5 + ], + 856, + [ + 896, + 924 + ] + ], + [ + [ + 5 + ], + 857, + [ + 792, + 794, + 896, + 924 + ] + ], + [ + [ + 1 + ], + 859, + [ + 250, + 858 + ] + ], + [ + [ + 1 + ], + 860, + [ + 756, + 768 + ] + ], + [ + [ + 1 + ], + 861, + [ + 248, + 756, + 768 + ] + ], + [ + [ + 4 + ], + 863, + [ + 779, + 807, + 835 + ] + ], + [ + [ + 4 + ], + 865, + [ + 269, + 779, + 807, + 835 + ] + ], + [ + [ + 3 + ], + 867, + [ + 263, + 866 + ] + ], + [ + [ + 4 + ], + 869, + [ + 268, + 868 + ] + ], + [ + [ + 1 + ], + 873, + [ + 249, + 872 + ] + ], + [ + [ + 1 + ], + 874, + [ + 742, + 768 + ] + ], + [ + [ + 1 + ], + 875, + [ + 248, + 742, + 768 + ] + ], + [ + [ + 5 + ], + 877, + [ + 793, + 821, + 849 + ] + ], + [ + [ + 5 + ], + 879, + [ + 275, + 793, + 821, + 849 + ] + ], + [ + [ + 7 + ], + 881, + [ + 764, + 766, + 880 + ] + ], + [ + [ + 5 + ], + 883, + [ + 274, + 882 + ] + ], + [ + [ + 1 + ], + 884, + [ + 844, + 858 + ] + ], + [ + [ + 1 + ], + 885, + [ + 250, + 844, + 858 + ] + ], + [ + [ + 5 + ], + 886, + [ + 900, + 928 + ] + ], + [ + [ + 5 + ], + 887, + [ + 272, + 900, + 928 + ] + ], + [ + [ + 1 + ], + 888, + [ + 742, + 756 + ] + ], + [ + [ + 1 + ], + 889, + [ + 248, + 742, + 756 + ] + ], + [ + [ + 4 + ], + 891, + [ + 779, + 807 + ] + ], + [ + [ + 4 + ], + 893, + [ + 269, + 779, + 807 + ] + ], + [ + [ + 2 + ], + 894, + [ + 782, + 796 + ] + ], + [ + [ + 2 + ], + 895, + [ + 257, + 782, + 796 + ] + ], + [ + [ + 5 + ], + 897, + [ + 792, + 794, + 896 + ] + ], + [ + [ + 4 + ], + 899, + [ + 267, + 898 + ] + ], + [ + [ + 5 + ], + 901, + [ + 272, + 900 + ] + ], + [ + [ + 2 + ], + 903, + [ + 254, + 902 + ] + ], + [ + [ + 2 + ], + 908, + [ + 737, + 798, + 854 + ] + ], + [ + [ + 2 + ], + 909, + [ + 256, + 737, + 798, + 854 + ] + ], + [ + [ + 3 + ], + 913, + [ + 260, + 912 + ] + ], + [ + [ + 2 + ], + 917, + [ + 254, + 916 + ] + ], + [ + [ + 7 + ], + 919, + [ + 286, + 766, + 810, + 880 + ] + ], + [ + [ + 7 + ], + 921, + [ + 286, + 764, + 810, + 880 + ] + ], + [ + [ + 4 + ], + 922, + [ + 750, + 812, + 868 + ] + ], + [ + [ + 4 + ], + 923, + [ + 268, + 750, + 812, + 868 + ] + ], + [ + [ + 5 + ], + 925, + [ + 792, + 794, + 924 + ] + ], + [ + [ + 5 + ], + 929, + [ + 272, + 928 + ] + ], + [ + [ + 7 + ], + 931, + [ + 284, + 930 + ] + ], + [ + [ + 0, + 3, + 5, + 6, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119 + ], + 938, + [ + 932, + 933, + 937 + ] + ], + [ + [ + 0, + 1, + 2, + 3, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71 + ], + 949, + [ + 941 + ] + ], + [ + [ + 0, + 2, + 5, + 7, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47 + ], + 953, + [ + 942, + 944, + 951 + ] + ], + [ + [ + 0, + 1, + 6, + 7, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ], + 958, + [ + 943, + 945, + 956 + ] + ], + [ + [ + 2, + 3, + 6, + 7, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95 + ], + 961, + [ + 936 + ] + ], + [ + [ + 4, + 5, + 6, + 7, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63 + ], + 978, + [ + 959, + 960, + 977 + ] + ] + ], + "total_entrance_rank": 128, + "donor_slots": 97, + "new_frames": 0, + "local_profile": { + "1": 2480, + "4": 324, + "2": 1031, + "3": 309, + "5": 133, + "8": 9, + "7": 14 + }, + "global_profile": { + "1": 178560, + "4": 23328, + "2": 74232, + "3": 22248, + "5": 9576, + "8": 648, + "7": 6768, + "14": 3840, + "28": 3840, + "42": 3840 + }, + "live": 14259, + "banks_per_stage": 731, + "bit_price": { + "lower": "0.001134385925603239057397", + "upper": "0.001134385925603239057398", + "lower_endpoint_residual_upper": "-1.208815110554072546890868962118806453466727141708111658528148771609217E-24", + "upper_endpoint_residual_lower": "1.206647999073094385830833942650340983281407775833257592984711501729879E-24", + "strict_rational_signs": true, + "moment_minus_one_at_current_k_required_rate": [ + "-0.001059935772403113935979679141367753634160753707351085784521072950941911", + "-0.001059935772403113935979679141367753634160753707351085784521072950867727" + ], + "nominal_k_ceiling_interval": [ + "0.001133100552284434337978314624649498572528216136568917723800228264595422", + "0.001133100552284434337979312359732310865246830293765932499225360045604731" + ] + }, + "rejected": [ + { + "entry": [ + [ + 0, + 3, + 4, + 7, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79 + ], + 947, + [ + 937 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 0, + 3, + 4, + 7, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79 + ], + 948, + [ + 937, + 940, + 941 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 0, + 1, + 2, + 3, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71 + ], + 961, + [ + 950 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 0, + 1, + 4, + 5, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39 + ], + 965, + [ + 957, + 959, + 963 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 0, + 2, + 4, + 6, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ], + 966, + [ + 936 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 0, + 2, + 4, + 6, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23 + ], + 968, + [ + 936, + 956, + 958 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 2, + 3, + 6, + 7, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95 + ], + 973, + [ + 942 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 3, + 5, + 7, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111 + ], + 976, + [ + 932 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 2, + 3, + 6, + 7, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95 + ], + 981, + [ + 942, + 943, + 980 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 2, + 3, + 4, + 5, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103 + ], + 982, + [ + 944 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 2, + 3, + 4, + 5, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103 + ], + 983, + [ + 944, + 974, + 975 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 3, + 5, + 7, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111 + ], + 985, + [ + 932, + 977, + 984 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 3, + 4, + 6, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87 + ], + 986, + [ + 934 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 3, + 4, + 6, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87 + ], + 987, + [ + 934, + 978, + 979 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 2, + 5, + 6, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55 + ], + 990, + [ + 935 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 2, + 5, + 6, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55 + ], + 995, + [ + 935, + 991, + 994 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 2, + 4, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + 996, + [ + 933 + ] + ], + "reason": "changed response" + }, + { + "entry": [ + [ + 1, + 2, + 4, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + 997, + [ + 933, + 992, + 993 + ] + ], + "reason": "changed response" + } + ] +} diff --git a/research/e8-early-reset-kernel/SOURCE.json b/research/e8-early-reset-kernel/SOURCE.json new file mode 100644 index 0000000000..78e840b5ad --- /dev/null +++ b/research/e8-early-reset-kernel/SOURCE.json @@ -0,0 +1,68 @@ +{ + "parent_pr": 434, + "parent_code_head": "50585107b561a170ccd2c6be09dbe90041ea7f6f", + "parent_manifest_sha256": "4d23bafa43634a59e25f875333408b67cbecb1c912929824b5d45dea4de51da7", + "kernel_source_pr": 435, + "kernel_source_head": "2c9c833ac8709402c37fc88a6a23393fb0d397fb", + "kernel_provenance": { + "head": "2c9c833ac8709402c37fc88a6a23393fb0d397fb", + "files": [ + { + "path": "research/split-centres-kernel/code/bit_audit.py", + "git_blob": "ce13906fe7473999b0ffc721f60fbf853645e371", + "sha256": "c94a1dd1c078deddbde088dc6291190977266009073c4cb4108f9e2faf898381" + }, + { + "path": "research/split-centres-kernel/code/bit_global.py", + "git_blob": "c8f37eb96eb13847fa157c574d7ab445edaae61c", + "sha256": "6d0eea0aaafbe90f1cdb43d7719ceb7b472fbbb6e6a7cb58bcfe82c31ac801c0" + }, + { + "path": "research/split-centres-kernel/code/bit_kernel.py", + "git_blob": "c0b7445f769713d0cd647c1e01f8befc39fffbd1", + "sha256": "14f164fcc0674f73163808a9d9762eb439ea130895f593cb78a6cafaed2dfb11" + }, + { + "path": "research/split-centres-kernel/code/combined.py", + "git_blob": "cead756a2c8fb52d6ba4cc7fe27200950d9a6b2c", + "sha256": "4f1f280b050e9aca659f10ad8996164e47f4e42fe4fd8631c822227413c427ae" + }, + { + "path": "research/split-centres-kernel/stages/kernel-selection.json", + "git_blob": "6426b40cde286df8894a4c7740e8cd5b520130d1", + "sha256": "87994a173608a930c83bfb35a05994f9681031f1b79df148cc2e2579fec9ef1f" + }, + { + "path": "research/split-centres-kernel/vendor/kernel417/LICENSE", + "git_blob": "261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64", + "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4" + }, + { + "path": "research/split-centres-kernel/vendor/kernel417/e8core.py", + "git_blob": "f2874bae8ef044240211fd892afb457d13759c74", + "sha256": "3f4e25f700b7eb5821ab9cdfc65541f3f921baffeb8704beb21c6d7072052d29" + }, + { + "path": "research/split-centres-kernel/vendor/kernel417/engines/base_two_moment.py", + "git_blob": "14a90fa0e788217856f070382c9e61bd7c603c61", + "sha256": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098" + }, + { + "path": "research/split-centres-kernel/vendor/kernel417/engines/moment.py", + "git_blob": "7d697cb45203fe72d97037403d6da41f71f3b7fd", + "sha256": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482" + }, + { + "path": "research/split-centres-kernel/vendor/kernel417/engines/outer.py", + "git_blob": "43007488ad2c43187c77cc6798beff8b1cd76ad2", + "sha256": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c" + }, + { + "path": "research/split-centres-kernel/vendor/kernel417/stages.py", + "git_blob": "9ef95d52f4b2ba0389bb2edb15228da698dd75f4", + "sha256": "e73ab7836519510ed30dd7e3022dae557fa50fc513d723197929bff741859668" + } + ] + }, + "scope": "Filter and remap PR435/417 response relations after eleven early resets, then freshly reprice the combined emitted word." +} diff --git a/research/e8-early-reset-kernel/VALIDATION.json b/research/e8-early-reset-kernel/VALIDATION.json new file mode 100644 index 0000000000..d57a499ef8 --- /dev/null +++ b/research/e8-early-reset-kernel/VALIDATION.json @@ -0,0 +1,9 @@ +{ + "status": "PASS_FULL_PYTHON311_AND_314", + "validated_code_head": "98b2d164fe0d51253faa05b8fb14cd82e57ef841", + "kappa": "0.001133100552284434", + "scope": "Fresh parent construction, all phase pairs, reset reconstruction, both emitted bit compositions, independent source spans and banks, two moments, complete finite invoices and outer constraints.", + "pending": [ + "GitHub CI" + ] +} diff --git a/research/e8-early-reset-kernel/apply.py b/research/e8-early-reset-kernel/apply.py new file mode 100644 index 0000000000..f87dfda4b5 --- /dev/null +++ b/research/e8-early-reset-kernel/apply.py @@ -0,0 +1,43 @@ +"""Apply a source-bound subset of PR435/417 response relations after PR434 resets.""" +from pathlib import Path +import copy,hashlib,json,sys +from collections import defaultdict,Counter +ROOT=Path(__file__).resolve().parent + +def reconstruct(raw,s): + assert hashlib.sha256(raw).hexdigest()==s['input_sha256'];c=json.loads(raw);w=copy.deepcopy(c);v=c['v'];n=2*v+c['R'];frames=[sum(1<=2*v and f:first.setdefault(x,frames[f]) + pivots={};donors={};by=defaultdict(list) + for lines,p,ds in s['entries']: + E=sum(1<=0 + cur[x]=newf + if f: hist[f]+=1 + events.append([0,x,oldf,newf,f,int(reverse)]) + elif op==1: + assert cur[x]==cur[y]==f and x!=y and x0 + cutoff=max(ceil(36/gap**2),ceil(2*(4+charged_two)/gap)) + assert cutoff*gap**2>=36 and cutoff*gap>=2*(4+charged_two) + cutoffs.append(dict(gap=str(gap),cutoff_log2=str(cutoff)));chain.append(a) +q=chain[-1]*(1-2*eta);margin=(1-eta)*q/(1+q);ticks=margin/grid;k=grid*((ticks.numerator-1)//ticks.denominator) +bridge={'semantic':{'C0':{'base':2,'exponent':210000},'strict_literal_gap':1},'rows':{'degree_gap':Q(10**6)-Q(51*20161,25)}} +a=Outer.assembly(chain[-1],b,bridge,k,eta=eta,beta=beta) +assert len(a['strict_constraints'])==47 and all(x>0 for x in a['strict_constraints'].values()) +controls=[] +for name,kk,ee,bb in [('next_grid',k+grid,eta,beta),('zero_eta',k,Q(0),beta),('zero_beta',k,eta,Q(0)),('unit_beta',k,eta,Q(1))]: + try:Outer.assembly(chain[-1],b,bridge,kk,eta=ee,beta=bb) + except AssertionError:controls.append(name) + else:raise AssertionError(name) +result=dict(status='PASS_CONDITIONAL_EARLY_RESET_KERNEL_ASSEMBLY',kappa=str(k),kappa_decimal=format(float(k),'.18f'),bit_lower=str(c),complex_lower=str(b),binding_component='bit',gain_over_pr425_percent=float(100*(k/Q(1048005508028206,10**18)-1)),bit_invoice=dict(prefix_bits=prefix.bit_length(),charged_prefix_bits=charged_prefix,coefficient_bits=coefficient.bit_length(),two_level_coefficient_bits=two.bit_length(),charged_two_level_coefficient_bits=charged_two,row_coefficient=row,live=W,physical=physical),strict_outer_constraints={n:str(x) for n,x in a['strict_constraints'].items()},outer_controls=controls,bootstrap=cutoffs,bit_template_sha256=g['template_sha256'],complex_template_sha256=cx['global_template_sha256'],scope='Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim.') +(ROOT/'RESULT.json').write_text(json.dumps(result,indent=2)+'\n') +print(result['status'],result['kappa_decimal'],result['gain_over_pr425_percent'],result['bit_invoice']) diff --git a/research/e8-early-reset-kernel/local-evidence/ASSEMBLY.json b/research/e8-early-reset-kernel/local-evidence/ASSEMBLY.json new file mode 100644 index 0000000000..2d9275b4b3 --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/ASSEMBLY.json @@ -0,0 +1,103 @@ +{ + "status": "PASS_CONDITIONAL_EARLY_RESET_KERNEL_ASSEMBLY", + "kappa": "566550276142217/500000000000000000", + "kappa_decimal": "0.001133100552284434", + "bit_lower": "1134385925603239057397/1000000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "gain_over_pr425_percent": 8.119713456118378, + "bit_invoice": { + "prefix_bits": 226, + "charged_prefix_bits": 256, + "coefficient_bits": 226, + "two_level_coefficient_bits": 488, + "charged_two_level_coefficient_bits": 512, + "row_coefficient": 18355, + "live": 14259, + "physical": 14268 + }, + "strict_outer_constraints": { + "bit_positive": "69237422216994571231731016394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_above_bit": "3027381811712032772175233605721028340518668567140762933350575870332865191369601146608087238821236792462091890206796168535162002266114342356390411552406563352949/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_below_one_over32": "30066013450793671/1000000000000000000", + "beta_positive": "1/1000000000000000000", + "beta_below_one": "999999999999999999/1000000000000000000", + "leaf_saving_above_bit": "3027381811712032699910429577014424336612418567140762933350575870332865191369601146608087238821236792462091890206796168535162002266114342356390411552406563352949/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_positive": "34618711108497285546628085980144914598009649322150646873843380631974330337665775297028821571958982750377041293717838708194510889073738997356966796489911060679915911552406563352949/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_internal": "69237422216994571231731016394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_leaf": "1513690905856016419192637005501783400037225677849353126156619368025669662334224702971178428041017249622958706282161291805489110926261002643033203510088939320084088447593436647051/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_positive": "34618711108497293176022617230144914598009649322150646873843380631974330337665775297028821571958982750377041293717838708194510889073738997356966796489911060679915911552406563352949/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_below_one": "30482959413891502706823977382769855085401990350677849353126156619368025669662334224702971178428041017249622958706282161291805489110926261002643033203510088939320084088447593436647051/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_reservations": "1/4000000000000000000", + "lambda_above_tau": "69237422216994571231731016394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_sigma": "3027381811712032841412655822715599572249684961419734592831907303192102258019025276275222047451635645854004651385559376073070112059318173821228409286292220996558588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_internal": "69237422216994571231731016394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_prime_above_lambda": "69237422216994571231731016394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_leaf": "1513690905856016419192637005501783400037225677849353126156619368025669662334224702971178428041017249622958706282161291805489110926261002643033203510088939320084088447593436647051/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_reservations": "1/4000000000000000000", + "lambda_prime_below_one": "34618711108497285546628085980144914598009649322150646873843380631974330337665775297028821571958982750377041293717838708194510889073738997356966796489911060679915911552406563352949/30517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "epsilon_positive": "824799408783783782958984375000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/825735049624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377", + "epsilon_below_one": "935640840770197731465032729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377/825735049624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377", + "guard_width": "935640840770197731465032729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377/825735049624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377", + "K_geometry": "619535197428608034950703313979193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377/825735049624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377000000000000000000", + "K_dominates_log": "30181962605490229417091461309195833846544927717528973213455737846402513917892235976507838913943511293241691126206500399143391103187358578171278036108258119723582489156491283934640879204527843633/26636614504017870344853206700941713090320845378659242063534301116505644577452193352482152416366136863775394107492343364174537498595530722752708776631638980872432359120795472156367000000000000000000", + "record_suffix": "935640840770197731465032729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377/825735049624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377", + "phase_local": "7485126726161581025985212208990865709120246178298925956560470154963351238580616803898817357783948289351013750750911538248082319428974953261114148185014851029252986376468687733612867255340363152623/6605880396996431845523595261833544846399569653907492031756506676893399855208143951415573799258801942216297738658101154315285299651691619242671776604646467256363225061957277094779016000000000000000000", + "phase_boundary": "1497025345232315544609002742154988589464523052305300551355128640243467072065455671439777950742394516312822824269988086019842598075679559123692864467841045938672936810647011910400067255340363152623/1321176079399286369104719052366708969279913930781498406351301335378679971041628790283114759851760388443259547731620230863057059930338323848534355320929293451272645012391455418955803200000000000000000", + "gamma_sublinear": "1/2000000000000000000", + "cell_above_band": "1649598817567567565092233700375446019309550592270806894200053793261563496030436665388325018098982006073053275092649757222962782667737355710589337543538547594666027924419191592954596867255340363152623/3302940198498215922761797630916772423199784826953746015878253338446699927604071975707786899629400971108148869329050577157642649825845809621335888302323233628181612530978638547389508000000000000000000", + "prime_interval_packing": "935640840770197731465032729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377/825735049624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377", + "alpha_positive": "1871281681540394637195015833832230909443005747679902139180462484913459832472653242218467913682491627127709757175045801784107580660260521257281694700164408756834189908510866649350867255340363152623/1651470099249107961380898815458386211599892413476873007939126669223349963802035987853893449814700485554074434664525288578821324912922904810667944151161616814090806265489319273694754000000000000000000", + "alpha_below_one": "1649598817567567566743703799624553980690449407729193105799946206738436503969563334611674981901017993926946724907350242777037217332262644289410662456461452405333972075580808407045403132744659636847377/1651470099249107961380898815458386211599892413476873007939126669223349963802035987853893449814700485554074434664525288578821324912922904810667944151161616814090806265489319273694754000000000000000000", + "alpha_below_one_fourth": "410996243130736595708029688030764321990530097621538349845601204820924031118036343721254894539992629761390898908956276342921223647570465681409704343090239794765867376463818951774337632744659636847377/1651470099249107961380898815458386211599892413476873007939126669223349963802035987853893449814700485554074434664525288578821324912922904810667944151161616814090806265489319273694754000000000000000000", + "delta_positive": "1/8000000000000000000", + "delta_below_one_eighth": "999999999999999999/8000000000000000000", + "short_record_fallback": "50284589023755639450550561947992852913465435982210087302859165385722658942883811531989641634516383968749221857814449882621435887501656295301706001999427642810130314654325274095462490292340911783154748095539039217711968081469021320817854289360191881492365590119398439280952169129815427826165501507629212226183536366779259610196729558300895864773/50398867774936156048001062483471258898922497969875274900486043372294615594544555293392744440145888841371900471939858660242350003446133569661497319066211450625329781051309792288047912597656250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "small_field_exposure": "1/1000000000000000000", + "artificial_boundary": "46248647905701184502994092243542020713267905454447515571451892035362508353573841615159615339773469519511222083986859962853394049210320886809606200206556095266907716722400641979368337398233978910542131/6605880396996431845523595261833544846399569653907492031756506676893399855208143951415573799258801942216297738658101154315285299651691619242671776604646467256363225061957277094779016000000000000000000", + "literal_scalar_guard": "1", + "row_product_gap": "23971789/25", + "balanced_prefix_above_kappa": "550042988388611688369205823989077886773965515878728726747932211633432067386799257451668462594712434857941333397055768012640812633662078222152713997053717290771577011531200424585191/412867524812276990345224703864596552899973103369218251984781667305837490950508996963473362453675121388518608666131322144705331228230726202666986037790404203522701566372329818423688500000000000000000", + "coordinate_movement_above_kappa": "78452961352847598918516394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_phase_layer_above_kappa": "54870185430533879209592448049792533549596965003804189905260217731037830574516104195278040056414925387769089892369778347174192562172540807794291183705325234899550178063548242464601/165147009924910796138089881545838621159989241347687300793912666922334996380203598785389344981470048555407443466452528857882132491292290481066794415116161681409080626548931927369475400000000000000000", + "bulk_exposure_above_kappa": "78452961352847598918516394278971659481331432859237066649424129667134808630398853391912761178763207537908109793203831464837997733885657643609588447593436647051/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gaussian_arithmetic_above_kappa": "4672012566095017110455046145179280659383717220367477108119098713076538168683698149591961776978647743841875247691579066755199689856285989527773563574955434617118216520775908609126171/6605880396996431845523595261833544846399569653907492031756506676893399855208143951415573799258801942216297738658101154315285299651691619242671776604646467256363225061957277094779016000000000000000000", + "scalar_work_above_kappa": "7974952764593233033216843776096053082583502047321223123997352051523238096287770125299748676608048714950024117020629643912842339682131799149109451877278668245299829051754547156515679/6605880396996431845523595261833544846399569653907492031756506676893399855208143951415573799258801942216297738658101154315285299651691619242671776604646467256363225061957277094779016000000000000000000", + "dimension_above_kappa": "411931883971506793163802659524015135469232720619859634789183848572891235797423214669958704933124136063149853928581112713236002168825041809973826595871674018630012430681387472347888511531200424585191/412867524812276990345224703864596552899973103369218251984781667305837490950508996963473362453675121388518608666131322144705331228230726202666986037790404203522701566372329818423688500000000000000000" + }, + "outer_controls": [ + "next_grid", + "zero_eta", + "zero_beta", + "unit_beta" + ], + "bootstrap": [ + { + "gap": "77700191184163087736308252660500911393801/62500000000000000000000000000000000000000000000", + "cutoff_log2": "23292621022833" + }, + { + "gap": "22035500823998869930507930842150868768654091410330107949400549/15625000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "18100755477578231773" + }, + { + "gap": "6249190499590723752847946110114538620601182257691815838869237387367034660501227601/3906250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "14066143459678166113736944" + }, + { + "gap": "1772248437287297768063758813231463857764748822643053531819635241254009676979099435670084333982024596749/976562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "10930836123019037656056314603016" + }, + { + "gap": "502603420982761311539041506293808216479242223973462530201407562553643345749374692386480249099696279705752331693888441501401/244140625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "8494380758365423758936869721476641843" + }, + { + "gap": "142536561730721028340518668567140762933350575870332865191369601146608087238821236792462091890206796168535162002266114342356390411552406563352949/61035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "6601005051767263055251893981415233874399241" + } + ], + "bit_template_sha256": "f9ce9ac945d9e8ea737dc5e456e366a7e2a21d8b989d24b742d7f124d26fb32f", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f", + "scope": "Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim." +} diff --git a/research/e8-early-reset-kernel/local-evidence/AUDIT.json b/research/e8-early-reset-kernel/local-evidence/AUDIT.json new file mode 100644 index 0000000000..643c814b0b --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/AUDIT.json @@ -0,0 +1,34 @@ +{ + "status": "PASS_INDEPENDENT_COMPRESSED_BIT_TEMPLATE_AUDIT", + "template_sha256": "f9ce9ac945d9e8ea737dc5e456e366a7e2a21d8b989d24b742d7f124d26fb32f", + "source_frames": 944, + "exact_nested_frame_pairs": 3357, + "exact_reflected_pairs": 3357, + "orthogonal_lift_argument": "Adding the same orthogonal E_s leaves P_V-P_U unchanged; each audited projector is therefore the literal child projector in every one of the nine windows.", + "exact_bank_families": 6579, + "mixed_width_slots": true, + "entrance_rank_total": 128, + "mutations_rejected": [ + "omit an idle child", + "omit a bridge", + "omit terminal exchange", + "remove a local invocation", + "re-use a helper bank slot", + "understate live stock", + "omit a local paid move", + "wrong reflected copy charge" + ], + "profile": { + "1": 178560, + "2": 74232, + "3": 22248, + "4": 23328, + "5": 9576, + "7": 6768, + "8": 648, + "14": 3840, + "28": 3840, + "42": 3840 + }, + "seconds": 1.8856884160777554 +} diff --git a/research/e8-early-reset-kernel/local-evidence/BIT-PRICE.json b/research/e8-early-reset-kernel/local-evidence/BIT-PRICE.json new file mode 100644 index 0000000000..0339fa04e3 --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/BIT-PRICE.json @@ -0,0 +1,17 @@ +{ + "lower": "0.001134385925603239057397", + "upper": "0.001134385925603239057398", + "lower_endpoint_residual_upper": "-1.208815110554072546890868962118806453466727141708111658528148771609217E-24", + "upper_endpoint_residual_lower": "1.206647999073094385830833942650340983281407775833257592984711501729879E-24", + "strict_rational_signs": true, + "moment_minus_one_at_current_k_required_rate": [ + "-0.001059935772403113935979679141367753634160753707351085784521072950941911", + "-0.001059935772403113935979679141367753634160753707351085784521072950867727" + ], + "nominal_k_ceiling_interval": [ + "0.001133100552284434337978314624649498572528216136568917723800228264595422", + "0.001133100552284434337979312359732310865246830293765932499225360045604731" + ], + "source_template_sha256": "f9ce9ac945d9e8ea737dc5e456e366a7e2a21d8b989d24b742d7f124d26fb32f", + "two_exact_engines": true +} diff --git a/research/e8-early-reset-kernel/local-evidence/FULL-PYTHON311.json b/research/e8-early-reset-kernel/local-evidence/FULL-PYTHON311.json new file mode 100644 index 0000000000..e78af127aa --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/FULL-PYTHON311.json @@ -0,0 +1,49 @@ +{ + "status": "PASS_FULL_EARLY_RESET_KERNEL_COMPOSITION", + "kappa": "566550276142217/500000000000000000", + "kappa_decimal": "0.001133100552284434", + "source_manifest_sha256": "fcc4de6a0a0bc14011be74ce43402c20490c0441a8688534be23f0f86aa5bfea", + "checks": [ + { + "name": "full-early-reuse434", + "seconds": 120.78334466693923, + "log_sha256": "c0edbb5dd9975ae1879cf20f98ed89b925ff3f9b695f027aca13f4930a6f81a6" + }, + { + "name": "kernel-reconstruction", + "seconds": 0.07485416706185788, + "log_sha256": "3f693dcbe49585d9ce689315e42a81cc7e4a4e45f0990c938217fb43c5150f28" + }, + { + "name": "export", + "seconds": 0.5898666669381782, + "log_sha256": "6c647e3d28cf94ce9f8b9fdcfc5c10797c18d488d74fe09b8de8671dfd7ae107" + }, + { + "name": "integer-source-spans", + "seconds": 0.06577295798342675, + "log_sha256": "bdf95dbce8337be57aab8a3d3b42a711ee276496c40cbb4c5356fc9cc9b2e811" + }, + { + "name": "global-program", + "seconds": 2.7857714579440653, + "log_sha256": "7e97172f5d1a084d7e5b043f4cb772d5d42389a151211c114e5a4632638cc826" + }, + { + "name": "independent-audit", + "seconds": 3.3599830419989303, + "log_sha256": "4ea14031d43b401b0349f6ec33ff189f633e00cc89d1e10017b1df4438e17cf4" + }, + { + "name": "two-moments", + "seconds": 0.13630245893727988, + "log_sha256": "59229b1eb12d77f6e25381ed1715fb134898e731fb30ba564789d62a44253478" + }, + { + "name": "finite-assembly", + "seconds": 0.15192366705741733, + "log_sha256": "e9af1d9589b520a86e59f494ff0a0f18609be39722dc55dc28ed91951b7b2134" + } + ], + "parent_phase_mode": "full replay" +} diff --git a/research/e8-early-reset-kernel/local-evidence/FULL-PYTHON314.json b/research/e8-early-reset-kernel/local-evidence/FULL-PYTHON314.json new file mode 100644 index 0000000000..37155858c0 --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/FULL-PYTHON314.json @@ -0,0 +1,49 @@ +{ + "status": "PASS_FULL_EARLY_RESET_KERNEL_COMPOSITION", + "kappa": "566550276142217/500000000000000000", + "kappa_decimal": "0.001133100552284434", + "source_manifest_sha256": "fcc4de6a0a0bc14011be74ce43402c20490c0441a8688534be23f0f86aa5bfea", + "checks": [ + { + "name": "full-early-reuse434", + "seconds": 111.79458600003272, + "log_sha256": "c0edbb5dd9975ae1879cf20f98ed89b925ff3f9b695f027aca13f4930a6f81a6" + }, + { + "name": "kernel-reconstruction", + "seconds": 0.06413062498904765, + "log_sha256": "3f693dcbe49585d9ce689315e42a81cc7e4a4e45f0990c938217fb43c5150f28" + }, + { + "name": "export", + "seconds": 0.37764429196249694, + "log_sha256": "6c647e3d28cf94ce9f8b9fdcfc5c10797c18d488d74fe09b8de8671dfd7ae107" + }, + { + "name": "integer-source-spans", + "seconds": 0.08005450002383441, + "log_sha256": "bdf95dbce8337be57aab8a3d3b42a711ee276496c40cbb4c5356fc9cc9b2e811" + }, + { + "name": "global-program", + "seconds": 2.7084261670242995, + "log_sha256": "8dd0f6c14d141094a7f0432bd7c2e065c7af228d161121e5355b7f6009a4f117" + }, + { + "name": "independent-audit", + "seconds": 1.9340536249801517, + "log_sha256": "e37173420f400387484e79ce9fa0309ea399ef891e44cbe28731b86c603f37a0" + }, + { + "name": "two-moments", + "seconds": 0.14735429198481143, + "log_sha256": "59229b1eb12d77f6e25381ed1715fb134898e731fb30ba564789d62a44253478" + }, + { + "name": "finite-assembly", + "seconds": 0.16268512490205467, + "log_sha256": "e9af1d9589b520a86e59f494ff0a0f18609be39722dc55dc28ed91951b7b2134" + } + ], + "parent_phase_mode": "full replay" +} diff --git a/research/e8-early-reset-kernel/local-evidence/GLOBAL.json b/research/e8-early-reset-kernel/local-evidence/GLOBAL.json new file mode 100644 index 0000000000..9d69b480fb --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/GLOBAL.json @@ -0,0 +1,165 @@ +{ + "status": "PASS_SOURCE_BOUND_NINE_STAGE_BIT_TEMPLATE", + "h": 8, + "m": 64, + "v": 120, + "R": 747, + "replicas": 8, + "live": 14259, + "physical": 14268, + "word_sha256": "da4aa797d6dad909fd1faaa90abea749b026299ac8cad3ad0a4a248e16bdb5f5", + "source_records_sha256": "99cb283793818ad03f8f16f95a8eb23d0b18769d0657d58043fb7a427471c35d", + "local_checks": { + "forward": { + "copies": 9, + "adds": 14693, + "records": 19002, + "all_columns": 987, + "cancellation_free_row_l1": 4749881, + "profile": { + "1": 2480, + "2": 1031, + "3": 309, + "4": 324, + "5": 133, + "7": 14, + "8": 9 + }, + "sha256": "4ed9ed1f7756ea6ff2c299b61ed1dc3fe0fa5bbbb91b5170133596b452c8085e" + }, + "reverse": { + "copies": 9, + "adds": 14693, + "records": 19002, + "all_columns": 987, + "cancellation_free_row_l1": 18976518, + "profile": { + "1": 2480, + "2": 1031, + "3": 309, + "4": 324, + "5": 133, + "7": 14, + "8": 9 + }, + "sha256": "ceedc55929da7f5279c330cd9714e78a7c4e294f0cb8e446ace5707369440bd8" + } + }, + "scalar_stages": [ + { + "stage": 0, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 1, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 2, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 3, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 4, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 5, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 6, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 7, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 8, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + } + ], + "independent_unbanked_scalar_columns": 7683, + "all_scalar_columns_restored": true, + "geometry_sha256": "fc7b29b16ee754ca9717973b745d6322bbf8351a5e35e3fc9e0fbf7a88dc0317", + "template_sha256": "f9ce9ac945d9e8ea737dc5e456e366a7e2a21d8b989d24b742d7f124d26fb32f", + "emitted_program_sha256": "3c56fb306442103076c77a04ed28c2786c456ce3266808b1eeacf36b78a48475", + "emitted_events": 1368144, + "local_invocations": 72, + "bank_assignments": 53784, + "banks_per_stage": 731, + "entrance_rank_total": 128, + "mixed_width_slots": true, + "padding_calls": 0, + "profile": { + "1": 178560, + "2": 74232, + "3": 22248, + "4": 23328, + "5": 9576, + "7": 6768, + "8": 648, + "14": 3840, + "28": 3840, + "42": 3840 + }, + "paid_calls": 326880, + "rank_mass": 910080, + "deficit": 2496, + "maxchild": 42, + "halving_depth": 2, + "halving_integer_inequality": [ + 4096, + 3528 + ], + "local_additions": 14693, + "bridge_additions": 17280, + "copy_erase_episodes": 648, + "global_prefix_bound": "82190131489578773587585573345852919919075549029526266900008239366144", + "global_prefix_bits": 226, + "charged_prefix_bits": 256, + "omitted_bridge_shears_rejected": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17 + ], + "scope": "Complete source-bound finite cover template. Local and unbanked global F2 columns are replayed; arbitrary physical bank dirt follows by injective owner routes and the all-column local theorem. Astronomical cover enumeration and all-size compiler interfaces remain explicit inherited assumptions.", + "seconds": 2.6007981669390574 +} diff --git a/research/e8-early-reset-kernel/local-evidence/SOURCE-SPANS.log b/research/e8-early-reset-kernel/local-evidence/SOURCE-SPANS.log new file mode 100644 index 0000000000..d612f8c813 --- /dev/null +++ b/research/e8-early-reset-kernel/local-evidence/SOURCE-SPANS.log @@ -0,0 +1 @@ +{"status": "PASS_INDEPENDENT_F2_AND_INTEGER_SOURCE_SPANS", "columns": 987, "profile": {"1": 2480, "4": 324, "2": 1031, "3": 309, "5": 133, "8": 9, "7": 14}, "word_sha256": "da4aa797d6dad909fd1faaa90abea749b026299ac8cad3ad0a4a248e16bdb5f5"} diff --git a/research/e8-early-reset-kernel/source_span.py b/research/e8-early-reset-kernel/source_span.py new file mode 100644 index 0000000000..a8722a7e4f --- /dev/null +++ b/research/e8-early-reset-kernel/source_span.py @@ -0,0 +1,10 @@ +"""PR417/435 independent all-column replay, including integer source-span legality.""" +from pathlib import Path +import sys,json,hashlib +ROOT=Path(__file__).resolve().parent;sys.path.insert(0,str(ROOT/'vendor/kernel417')) +from e8core import Lat,replay +w=json.loads(Path(sys.argv[1]).read_text());frames=json.loads(Path(sys.argv[2]).read_text())['frames'];L=Lat(w['lines']);masks=[sum(1</2) for orthogonality + self.ip = [[sum(a * b for a, b in zip(x, y)) // 2 for y in self.lines] for x in self.lines] + + def close(self, mask): + """mask of all root lines in span(roots of mask)""" + if mask in self._close: return self._close[mask] + idx = [i for i in range(self.v) if mask >> i & 1] + basis = [] + for i in idx: + if rank([self.lines[j] for j in basis] + [self.lines[i]]) > len(basis): basis.append(i) + d = len(basis); out = 0 + if d == 8: out = (1 << self.v) - 1 + elif d: + B = [self.lines[j] for j in basis] + for i in range(self.v): + if rank(B + [self.lines[i]]) == d: out |= 1 << i + self._close[mask] = out; self._close[out] = out; self._dim[out] = d + return out + + def dim(self, mask): + if mask not in self._dim: self.close(mask) + return self._dim[mask] + + def basis(self, mask): + b = [] + for i in range(self.v): + if mask >> i & 1 and rank([self.lines[j] for j in b] + [self.lines[i]]) > len(b): b.append(i) + return b + + def perp(self, t): + return self.close(sum(1 << j for j in range(self.v) if self.ip[t][j] == 0)) + + +def to_masks(c, L): + return [L.close(sum(1 << i for i in fr)) for fr in c['frames']] + + +PHASES = ('D', 'A', 'B', 'C') + + +def replay(c, L=None, masks=None, check_f2=True, span=True, span_mode='z'): + """Exact legality + F2 replay + histogram of a bitE8/1 word. Returns dict(H_local, steps, ...). + Legality: each register's frames nested (mask inclusion = exact Q-subspace inclusion for root-spanned frames) and + strictly increasing at each move; every gate at one common frame; D compensation at frame 0; y at frame 0 at the + scatter; COPY of retained totals; final frames (x, helpers FULL; y_t at its cap t-perp). + Source-span: every non-target operand's x-support lies in the gate frame.""" + L = L or Lat(c['lines']); masks = masks or to_masks(c, L) + v, R, h = c['v'], c['R'], c['h']; n = 2 * v + R; FULL = (1 << v) - 1 + cur = [masks[f] for f in c['start']] + for r in range(v): assert cur[r] == L.close(1 << r), 'x start' + for r in range(v, 2 * v): assert cur[r] == 0, 'y start at 0' + sig = [L.dim(cur[r]) for r in range(n)] + H = Counter(); steps = 0; viol = [] + val = [1 << i for i in range(n)] + zsupp = [{i: 1} if i < v else {} for i in range(n)] # integer support of each register over the x columns (all ADDs are +1) + def climb(r, m): + nonlocal steps + if cur[r] == m: return + assert cur[r] & ~m == 0 and cur[r] != m, ('not nested', r) + H[L.dim(m) - L.dim(cur[r])] += 1; steps += 1; cur[r] = m + def run(gates, ph): + for k, (f, d, srcs) in enumerate(gates): + m = masks[f] + assert d not in srcs and len(set(srcs)) == len(srcs), (ph, k) # rohanarun: source destinations allowed (#433 source-basis gates); spans checked below + for x in [d] + srcs: climb(x, m) + for s in srcs: + val[d] ^= val[s] + if span: + if s < v or s >= 2 * v: + ms = sum(1 << i for i in zsupp[s]) + if ms & ~m: viol.append((ph, k, s)) + zd = zsupp[d] + for i, a in zsupp[s].items(): + w = zd.get(i, 0) + a + if w: zd[i] = w + else: zd.pop(i, None) + if span_mode == 'f2': + zsupp[d] = {i: 1 for i in range(v) if val[d] >> i & 1} + if span and (d >= 2 * v or d < v): + md = sum(1 << i for i in zsupp[d]) + if md & ~m: viol.append((ph, k, d)) + run(c['D'], 'D') + for r in range(v, n): assert cur[r] == masks[c['start'][r]], 'D compensation at frame 0 (helpers untouched otherwise)' + run(c['A'], 'A') + for t in range(v): assert cur[v + t] == 0, 'y at frame 0 at the scatter' + copies = [val[q] for q in c['ret']] + for q in c['ret']: + assert q >= 2 * v or q < v; H[L.dim(cur[q])] += 1 # rohanarun: #433 retains totals in source rows + for t, row in enumerate(c['scatter']): + for k in row: val[v + t] ^= copies[k] + run(c['B'], 'B'); run(c['C'], 'C') + for r in range(n): climb(r, masks[c['final'][r]]) + for r in range(v): assert cur[r] == FULL + for r in range(2 * v, n): assert cur[r] == FULL + for t in range(v): assert cur[v + t] == L.perp(t), 'y final at cap' + if check_f2: + for s in range(v): assert val[s] == 1 << s + for t in range(v): assert val[v + t] == (1 << (v + t)) | (1 << t), ('target', t) + for r in range(2 * v, n): assert val[r] == 1 << r, ('helper', r) + return dict(sig=sig, viol=viol, H=H, steps=steps, n=n, v=v, R=R, h=h, L=L, masks=masks, ncopy=len(c['ret'])) + + +def profile(H_local, v, h=8): + prof = Counter({j: 5 * c for j, c in H_local.items()}) + for j in (2 * h - 2, h - 1, 2 * h + 2, 4): prof[j] += 2 * v + return prof + + +def coarse(H, m, W): + grid = Q(1, 10**18) + root = moment.certify(dict(H), m, W, True); c = Q(int(Q(root['lower']) * 10**18), 10**18) + assert moment.moment(H, m, W, c, True)[1] < 1 < moment.moment(H, m, W, c + grid, True)[0] + fb = 32 * m * m * sum(H.values()) + _, up = other.moment(m, W, list(H.items()), c); _, bad = other.moment(m, W, [(1, fb)], c) + lo, _ = other.moment(m, W, list(H.items()), c + grid); blo, _ = other.moment(m, W, [(1, fb)], c + grid) + assert up + Q(1, 10**16) * bad < 1 < lo + Q(1, 10**16) * blo + return c + + +def kappa(c, b): + grid = Q(1, 10**18); eta = Q(1, 10**12); beta = Q(1, 10**9); cap = (1 - beta) * b + sv = min(c, Q(((cap - grid) * 10**18).__floor__(), 10**18)); binding = 'bit' if sv == c else 'complex' + chain = [Q(384599, 10**10)] + for _ in range(3): + a = (1 - sv) * sv + sv * chain[-1]; assert chain[-1] < a < sv < 1 - a; chain.append(a) + bit = chain[-1] + bridge = dict(proof='PROOF.md', representation='Exact powers with source-bound finite overcharges', + semantic=dict(G=dict(base=2, exponent=30000), E=dict(base=2, exponent=100000), B_upper=dict(base=2, exponent=100001), + C0=dict(base=2, exponent=210000), C1=1, strict_literal_gap=1, induction_gap_lower=1), + rows=dict(coefficient=20161, degree=10**6, suffix_slope=4 * 10**6, degree_gap=Q(10**6) - Q(51 * 20161, 25))) + q = bit * (1 - 2 * eta); mn = (1 - eta) * q / (1 + q); t = mn * 10**18; k = Q((t.numerator - 1) // t.denominator, 10**18) + asm = outer.assembly(bit, b, bridge, k, eta=eta, beta=beta) + assert len(asm['strict_constraints']) == 47 and min(asm['strict_constraints'].values()) > 0 + try: + outer.assembly(bit, b, bridge, k + grid, eta=eta, beta=beta); raise SystemExit('ADJACENT ADMITTED') + except AssertionError: pass + return k, binding + + +def price_word(c, **kw): + r = replay(c, **kw) + v, h, R = r['v'], r['h'], r['R']; m = 5 * h + resid = sum(h - r['sig'][x] for x in range(2 * v, 2 * v + R)) + T = 1 if resid % h == 0 else h + W = (4 * v * h + resid) * T // h; assert (4 * v * h + resid) * T % h == 0 + prof = Counter({j: T * k for j, k in profile(r['H'], v, h).items()}); mass = sum(a * b for a, b in prof.items()) + L_copy = h * r['ncopy'] + assert m * W - mass == T * (4 * v - 5 * L_copy), ('deficit', m * W - mass) + assert 2 * max(prof) < m + cc = coarse(prof, m, W) + return dict(c=cc, H=r['H'], prof=prof, W=W, T=T, resid=resid, m=m, deficit=m * W - mass, replay=r) + + +def phi_fn(m, W, a): + """linearized moment term per child of rank r (float), for search scoring""" + import math + return lambda r: r / (m * W) * math.exp(a * math.log(m / r)) diff --git a/research/e8-early-reset-kernel/vendor/kernel417/engines/base_two_moment.py b/research/e8-early-reset-kernel/vendor/kernel417/engines/base_two_moment.py new file mode 100644 index 0000000000..14a90fa0e7 --- /dev/null +++ b/research/e8-early-reset-kernel/vendor/kernel417/engines/base_two_moment.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +"""Maintainer arithmetic cross-check of the pinned PR39 certificate. + +Uses no producer/checker imports. Counts are inputs, not proved by this script. +80-term rational logarithms and 12-term exponentials independently enclose +the two moments. The accompanying written review addresses their realization. +""" +import argparse +from fractions import Fraction as Q +from hashlib import sha256 +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +GRID = 10**30 + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def log_unit(x): + require(1 <= x <= 2, "logarithm range") + z = (x-1)/(x+1) + lo = 2*sum((z**(2*j+1)/(2*j+1) for j in range(80)), Q(0)) + return lo, lo+2*z**161/(161*(1-z*z)) + + +def log_bounds(x): + k = 0 + while x > 2: + x /= 2 + k += 1 + lo, hi = log_unit(x) + l2, u2 = log_unit(Q(2)) + lo, hi = lo+k*l2, hi+k*u2 + # Outward rational rounding keeps later certificates compact. + return Q((lo*GRID).__floor__(), GRID), Q((hi*GRID).__ceil__(), GRID) + + +def exp_bounds(x): + require(0 <= x < 1, "exponential range") + term = total = Q(1) + for j in range(1, 13): + term *= x/j + total += term + tail = term*x/13/(1-x/14) + return total, total+tail + + +def moment(m, W, entries, saving): + lo = hi = Q(0) + for t, count in entries: + t, count = int(t), int(count) + require(0 < t < m and count > 0, "improper child") + l, u = log_bounds(Q(m, t)) + lower = exp_bounds(saving*l)[0] + upper = exp_bounds(saving*u)[1] + lo += Q(t*count, m*W)*lower + hi += Q(t*count, m*W)*upper + return Q((lo*GRID).__floor__(), GRID), Q((hi*GRID).__ceil__(), GRID) + diff --git a/research/e8-early-reset-kernel/vendor/kernel417/engines/moment.py b/research/e8-early-reset-kernel/vendor/kernel417/engines/moment.py new file mode 100644 index 0000000000..7d697cb452 --- /dev/null +++ b/research/e8-early-reset-kernel/vendor/kernel417/engines/moment.py @@ -0,0 +1,113 @@ +"""Independent prospective ordinary five-stage cost, never supplier admission. + +Consumes a raw one-invocation ledger made from the actual source/internal/target +paths. No packed profile is used as an input. Missing physical/finite/compiler +obligations must remain explicit in the accompanying report. +""" +from collections import Counter +from decimal import Decimal, localcontext, ROUND_FLOOR +from fractions import Fraction as F +from functools import lru_cache +from math import factorial +import hashlib, json, sys +from pathlib import Path + +DYAD = 1 << 224 + +def floor(x): return F(x.numerator*DYAD//x.denominator, DYAD) +def ceil(x): return -floor(-x) + +@lru_cache(None) +def logarithm(x): + """Mercator bounds after binary reduction; ln(2) via two Mercator sums. + + For 1 <= y < 2, log(y) is an alternating series in z=y-1. + We instead reduce to 1 <= y < 3/2, and bound log(3/2) and + log(2) by the same alternating series at z=1/2 and z=1/3, + using log(2)=log(3/2)+log(4/3). All sums are exact rationals. + """ + assert x >= 1 + k = 0 + while x >= 2: x /= 2; k += 1 + j = int(x >= F(3, 2)) + if j: x /= F(3, 2) + def mercator(y): + z=y-1 + assert 0 <= z <= F(1,2) + # An even partial sum is below log; the next term bounds its tail. + t=z; s=F(0) + for n in range(1, 225): + s += (t if n & 1 else -t)/n + t *= z + return s, s+t/225 + a,b=mercator(x); c,d=mercator(F(3,2)); e,f=mercator(F(4,3)) + return floor(a+(k+j)*c+k*e), ceil(b+(k+j)*d+k*f) + +def exponential(l,u): + assert 0 <= l <= u < F(1,10) + def poly(x): + s=t=F(1) + for j in range(1,25): t=t*x/j; s+=t + return s,t + lo,_=poly(l);hi,last=poly(u) + return floor(lo),ceil(hi+last*u/25/(1-u/26)) + +def moment(H,m,W,a,bad=False): + lo=hi=F(0) + for r,n in H.items(): + assert 0 < r < m and n > 0 + l,u=logarithm(F(m,r)); e,f=exponential(a*l,a*u) + p=F(r*n,m*W);lo+=p*e;hi+=p*f + if bad: + # Existing envelope shape, only conditionally portable to the new cover. + l,u=logarithm(F(m));e,f=exponential(a*l,a*u) + p=F(32*m*sum(H.values()),10**16*W) + lo+=p*e;hi+=p*f + return floor(lo),ceil(hi) + +def decimal(x): + with localcontext() as c: + c.prec=70 + return str(Decimal(x.numerator)/Decimal(x.denominator)) + +def certify(H,m,W,bad=False): + with localcontext() as c: + c.prec=70 + terms=[(Decimal(r*n)/Decimal(m*W),(Decimal(m)/Decimal(r)).ln()) for r,n in H.items()] + fallback=Decimal(32*m*sum(H.values()))/Decimal(10**16*W) if bad else Decimal(0) + lm=Decimal(m).ln();lo=Decimal(0);hi=Decimal('.003') + for _ in range(210): + a=(lo+hi)/2 + if sum(p*(a*l).exp() for p,l in terms)+fallback*(a*lm).exp()<1:lo=a + else:hi=a + q=int(((lo+hi)/2*10**24).to_integral_value(rounding=ROUND_FLOOR)) + lo=F(q,10**24);hi=lo+F(1,10**24) + lv=moment(H,m,W,lo,bad);hv=moment(H,m,W,hi,bad) + assert lv[1]<10 for v in slacks.values()),{k:str(v) for k,v in slacks.items() if v<=0} + assert min(margins.values())==minimum + assert margins['balanced_prefix']-minimum==eta and 1-eps-r==eta/2 + assert 1-eps*(1+c)==eta-eps*eta/4 + return dict(parameters=dict(a_bit=a,a_complex=b,tau=tau,sigma=sigma, + eta=eta,beta=beta,q=q,c=c,epsilon=eps,lambda_=lam, + lambda_prime=lp,alpha_squared_power=r,delta=delta, + C0=bridge['semantic']['C0'],C1=1,kappa=kappa), + strict_constraints=slacks,margins=margins,minimum_margin=minimum, + absorption_gap=minimum-kappa, + recurrence=dict(internal=internal,leaf=leaf,reservations=1-c)) diff --git a/research/e8-early-reset-kernel/vendor/kernel417/stages.py b/research/e8-early-reset-kernel/vendor/kernel417/stages.py new file mode 100644 index 0000000000..9ef95d52f4 --- /dev/null +++ b/research/e8-early-reset-kernel/vendor/kernel417/stages.py @@ -0,0 +1,143 @@ +"""Transcript stages on the E8 bit word (bitE8/1), applied from frozen selections, each bound to the exact input word. + +retime (our #329 descent2 / #287 concave retiming, ported to E8 frames): every selected gate g gets a new frame F with + close(LB_g + prev frames of its participants) <= F <= rootspan(AND of their next frames), where LB_g is the + x-support of the non-target operands (source-span rule); pinned: D gates (frame 0), y at frame 0 at the scatter, + retained totals at FULL at COPY, start and final frames. Checked on the joint retimed configuration. +kernel (our #320/#329 shared-donor response kernel; #272/#299/#319 lineage): entry = pivot p, entrance E, donors D with + resp(p) = XOR resp(D) over F2, where resp(h) = the targets whose frame-0 completion (D) gates read h; E inside the + first frame of p and of every donor. p starts at E and leaves the D gates; each donor climbs to E at the start of + A and pays d += (its pivots) at E; after C it pays d += (its pivots) again at FULL (F2: d -= p). + Exclusivity: pivots are never donors, a donor serves one entrance. Total entrance rank = 0 mod 8 (integral + B_4 width W; the residuals then tile width-72 banks with 9 replicas, checked separately). + +usage: stages.py retime|kernel IN.json.gz OUT.json.gz SELECTION.json +After applying, the full exact replay of e8core (legality, F2 on all columns, source spans) must pass and the output +must equal the frozen output content hash. (This package uses the kernel stage only: on PR #376's word our retiming +descent finds no move, before or after the kernel.) +Chafik Boukhalfa (chafreaky) with Anthropic Claude assistance; Apache-2.0.""" +import sys, os, json, hashlib +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from e8core import * + + +def content_sha(c): + return hashlib.sha256(json.dumps(c, sort_keys=True, separators=(',', ':')).encode()).hexdigest() + + +class Framer: + def __init__(self, c): + self.fl = c['frames']; self.key = {}; self.v = c['v'] + for k, fr in enumerate(self.fl): self.key.setdefault(sum(1 << i for i in fr), k) + def fid(self, m): + if m not in self.key: self.key[m] = len(self.fl); self.fl.append([i for i in range(self.v) if m >> i & 1]) + return self.key[m] + + +def mask_of(lines): return sum(1 << i for i in lines) + + +def occurrences(c, masks): + """per register: list of (kind, ref) with pins ('p', mask) and gates ('g', (phase, k)) in time order""" + v = c['v']; n = 2 * v + c['R']; FULL = (1 << v) - 1 + occ = [[('p', masks[c['start'][r]])] for r in range(n)] + for ph in ('D', 'A'): + for k, (f, d, s) in enumerate(c[ph]): + for x in [d] + s: occ[x].append(('g', (ph, k))) + for t in range(v): occ[v + t].append(('p', 0)) + for q in c['ret']: occ[q].append(('p', FULL)) + for ph in ('B', 'C'): + for k, (f, d, s) in enumerate(c[ph]): + for x in [d] + s: occ[x].append(('g', (ph, k))) + for r in range(n): occ[r].append(('p', masks[c['final'][r]])) + return occ + + +def lower_bounds(c, L): + v = c['v']; n = 2 * v + c['R']; sup = [1 << i if i < v else 0 for i in range(n)]; lb = {} + for ph in ('D', 'A', 'B', 'C'): + for k, (f, d, srcs) in enumerate(c[ph]): + need = 0 + for s in srcs: + sup[d] |= sup[s] + if s < v or s >= 2 * v: need |= sup[s] + if d >= 2 * v: need |= sup[d] + lb[(ph, k)] = L.close(need) if need else 0 + return lb + + +def retime(c, sel): + L = Lat(c['lines']); masks = to_masks(c, L); occ = occurrences(c, masks); lb = lower_bounds(c, L) + gm = {(ph, k): masks[g[0]] for ph in ('D', 'A', 'B', 'C') for k, g in enumerate(c[ph])} + pos = {} + for r, o in enumerate(occ): + for i, (kind, x) in enumerate(o): + if kind == 'g': pos.setdefault(x, []).append((r, i)) + def fr(r, i): + kind, x = occ[r][i]; return x if kind == 'p' else gm[x] + seen = set() + for ph, k, old_lines, new_lines in sel: + g = (ph, k); assert ph != 'D' and g not in seen; seen.add(g) + assert gm[g] == L.close(mask_of(old_lines)), ('selection not bound to this word', g) + F = L.close(mask_of(new_lines)); assert F == mask_of(new_lines), 'frame given as all its root lines' + gm[g] = F + for g in seen: # the joint retimed configuration: every moved gate inside its feasible interval + F = gm[g]; lo = lb[g]; hi = (1 << c['v']) - 1 + for r, i in pos[g]: lo |= fr(r, i - 1); hi &= fr(r, i + 1) + assert lo & ~F == 0 and F & ~hi == 0, ('outside the feasible interval', g) + out = json.loads(json.dumps(c)); fm = Framer(out) + for ph in ('D', 'A', 'B', 'C'): + out[ph] = [[fm.fid(gm[(ph, k)]), d, list(s)] for k, (f, d, s) in enumerate(c[ph])] + return out + + +def kernel(c, sel): + L = Lat(c['lines']); masks = to_masks(c, L); v = c['v']; n = 2 * v + c['R']; FULL = (1 << v) - 1 + occ = occurrences(c, masks) + gm = {(ph, k): masks[g[0]] for ph in ('D', 'A', 'B', 'C') for k, g in enumerate(c[ph])} + first = {} + for h in range(2 * v, n): + assert masks[c['start'][h]] == 0 + first[h] = next(x if kind == 'p' else gm[x] for kind, x in occ[h][1:] if (x if kind == 'p' else gm[x]) != 0) + resp = {} + for f, t, srcs in c['D']: + assert masks[f] == 0 + for s in srcs: resp[s] = resp.get(s, 0) ^ (1 << (t - v)) + ret = set(c['ret']); pivots = {}; donor_at = {}; tot = 0 + for E_lines, p, D in sel: + E = L.close(mask_of(E_lines)); assert E == mask_of(E_lines) and E != 0 + assert p not in ret and p not in pivots and p not in donor_at and 2 * v <= p < n + x = resp.get(p, 0) + for d in D: + assert d not in ret and d not in pivots and 2 * v <= d < n + assert donor_at.setdefault(d, E) == E, 'donor serves one entrance' + x ^= resp.get(d, 0) + assert x == 0, ('response relation fails', p) + for h in [p] + D: assert E & ~first[h] == 0, ('entrance not inside first frame', h) + pivots[p] = E; tot += L.dim(E) + assert not set(pivots) & set(donor_at) + assert tot % 8 == 0, 'total entrance rank 0 mod 8' + out = json.loads(json.dumps(c)); fm = Framer(out) + for p, E in pivots.items(): out['start'][p] = fm.fid(E) + out['D'] = [[f, t, [s for s in srcs if s not in pivots]] for f, t, srcs in c['D']] + byd = {} + for E_lines, p, D in sel: + for d in D: byd.setdefault((d, mask_of(E_lines)), []).append(p) + out['A'] = [[fm.fid(E), d, sorted(ps)] for (d, E), ps in sorted(byd.items())] + out['A'] + out['C'] = out['C'] + [[fm.fid(FULL), d, sorted(ps)] for (d, E), ps in sorted(byd.items())] + return out, len(sel), tot, len(byd) + + +if __name__ == '__main__': + st, inp, outp, selp = sys.argv[1:5] + c = load_word(inp); sel = json.load(open(selp)) + assert sel['input_sha256'] == content_sha(c), 'selection bound to a different input word' + if st == 'retime': + w = retime(c, sel['gates']); info = '%d gates retimed' % len(sel['gates']) + else: + w, ne, tot, nd = kernel(c, sel['entries']); info = '%d entries, total entrance rank %d, %d donor slots' % (ne, tot, nd) + r = replay(w, span_mode='z'); assert not r['viol'], r['viol'][:5] + assert content_sha(w) == sel['output_sha256'], 'output differs from the frozen stage output' + save_word(w, outp) + print(' stage %s: %s | exact replay PASS (legality, F2 on %d columns, source spans) | local histogram %s | output sha %s' + % (st, info, r['n'], dict(sorted(r['H'].items())), sel['output_sha256'][:16])) diff --git a/research/e8-early-reset-kernel/verify.py b/research/e8-early-reset-kernel/verify.py new file mode 100644 index 0000000000..2cb303ae52 --- /dev/null +++ b/research/e8-early-reset-kernel/verify.py @@ -0,0 +1,32 @@ +"""Fresh parent replay, chronological reset reconstruction, banks and exact assembly.""" +from pathlib import Path +import hashlib,json,os,subprocess,sys,time +assert __debug__ +ROOT=Path(__file__).resolve().parent;PARENT=ROOT.parent/'e8-early-reset-reuse';UPSTREAM=ROOT.parent/'split-centres-global';out=Path(sys.argv[1]).resolve();assert not out.exists() and not out.is_relative_to(ROOT.parent) +read=lambda p:json.loads(p.read_text());sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +def integrity(): + assert {p.relative_to(ROOT).as_posix():sha(p) for p in ROOT.rglob('*') if p.is_file() and p.name!='MANIFEST.json'}==read(ROOT/'MANIFEST.json')['files'] + assert sha(PARENT/'MANIFEST.json')==read(ROOT/'SOURCE.json')['parent_manifest_sha256'] +integrity();out.mkdir(parents=True);env=dict(os.environ,PYTHONDONTWRITEBYTECODE='1',PYTHONINTMAXSTRDIGITS='0');env.pop('PYTHONOPTIMIZE',None);steps=[] +def run(name,file,*args,cwd=None): + t=time.monotonic();log=out/(name+'.log');print('RUN',name,flush=True) + with log.open('w') as f:q=subprocess.run([sys.executable,'-B',str(file),*map(str,args)],cwd=cwd,env=env,stdout=f,stderr=subprocess.STDOUT) + if q.returncode:raise RuntimeError((name,q.returncode,log.read_text()[-2000:])) + steps.append(dict(name=name,seconds=time.monotonic()-t,log_sha256=sha(log)));print('PASS',name,flush=True) +try: + base=out/'baseline';run('full-early-reuse434',PARENT/'verify.py',base) + changed=out/'changed';changed.mkdir() + for name in ('work','inherited','split-centres'):(changed/name).symlink_to(base/'baseline'/name,target_is_directory=True) + bit=changed/'bit426-source-centres';bit.mkdir() + run('kernel-reconstruction',ROOT/'apply.py',base/'changed/bit426-source-centres/bit-source-centres.json',bit/'bit-source-centres.json') + run('export',UPSTREAM/'vendor/export_records.py',bit/'bit-source-centres.json',bit/'records') + run('integer-source-spans',ROOT/'source_span.py',bit/'bit-source-centres.json',bit/'records/frames.json') + run('global-program',ROOT/'bit_global.py','--source',bit,'--local-check',bit,'--out',bit/'global',cwd=changed) + run('independent-audit',ROOT/'bit_audit.py','--local-check',bit,'--out',bit/'global',cwd=changed) + run('two-moments',ROOT/'bit_price.py',cwd=changed) + env['E8_OUTPUT']=str(changed);run('finite-assembly',ROOT/'combined.py',cwd=changed) + actual=read(changed/'RESULT.json');expected=read(ROOT/'EXPECTED.json') + for k,v in expected.items():assert actual[k]==v,(k,actual[k],v) + integrity();result=dict(status='PASS_FULL_EARLY_RESET_KERNEL_COMPOSITION',kappa=actual['kappa'],kappa_decimal=actual['kappa_decimal'],source_manifest_sha256=sha(ROOT/'MANIFEST.json'),checks=steps,parent_phase_mode=read(base/'RESULT.json')['parent_phase_mode']);(out/'RESULT.json').write_text(json.dumps(result,indent=2)+'\n') +except BaseException as e: + (out/'FAILURE.json').write_text(json.dumps(dict(error=repr(e),completed=steps),indent=2)+'\n');raise diff --git a/research/e8-early-reset-reuse/EXPECTED.json b/research/e8-early-reset-reuse/EXPECTED.json new file mode 100644 index 0000000000..5cb40a0157 --- /dev/null +++ b/research/e8-early-reset-reuse/EXPECTED.json @@ -0,0 +1,10 @@ +{ + "status": "PASS_CONDITIONAL_EARLY_RESET_REUSE_ASSEMBLY", + "kappa": "1128250848293019/1000000000000000000", + "kappa_decimal": "0.001128250848293019", + "bit_lower": "1129525236098815991751/1000000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "bit_template_sha256": "10dfc644197ef152062bf69960ecdc2405c847ce47147b520c3172c51cd82bd9", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f" +} diff --git a/research/e8-early-reset-reuse/LICENSE b/research/e8-early-reset-reuse/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/e8-early-reset-reuse/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/e8-early-reset-reuse/MANIFEST.json b/research/e8-early-reset-reuse/MANIFEST.json new file mode 100644 index 0000000000..1980f550b0 --- /dev/null +++ b/research/e8-early-reset-reuse/MANIFEST.json @@ -0,0 +1,30 @@ +{ + "files": { + "EXPECTED.json": "5521c7e995fec77941243b28e090f95f2188f193d5f61275275cfa11215eecc0", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "NOTICE.md": "c4085541471fe63d8f735beacd397d356446376ad3e56b2673940a2df3b8437e", + "PROOF.md": "09388e2f9e6b8fcc626a5172d55c45a957835075c51c68d1e86fd42ff4655ae8", + "README.md": "442bf686c0b24b9d7781b7b138f32fddea5d4efffeddc6e41d04719d2545e0cd", + "SELECTION.json": "9d47ade3fb69b3ef62a1a3ae75cebdddd57d144923977c5f2a07848ab596ea32", + "SOURCE.json": "c52287239c43aece2b3533ef48ee204d845d652066bca716c288b0c47e779521", + "VALIDATION.json": "bcb864a6b73d4ff4a24ab70ad51287653723c2115ce1c81db7817b81df2d9e92", + "bit_audit.py": "219eb4dd8e5380fb0432daa6a30c265755a78834616b2c5fc7aa161feb0231ee", + "bit_global.py": "9c2178df133dc663416aac13d8c8da80a9e4f5f7174bb36413180fcbad994ffb", + "bit_price.py": "36bf15803567a95b139a908461541bf19efe1f5b85fb31c270021833ab1393ee", + "combined.py": "dc621dce9ac1634a2701318311b30dffee7cce7e0c6be7ae808f44b27eb17f0f", + "local-evidence/ASSEMBLY.json": "c9ce28f59a5e460d39a888bbbc464e3fd6dd1c0b2c54ae86baeeea99febc8176", + "local-evidence/BIT-AUDIT.json": "2e458c3936e42539095610a50c730266dddd96e94d1ead171a99dd5f1fe9ef47", + "local-evidence/BIT-GLOBAL.json": "39f89d1e5bf51e9b1f1155e123dc3226627e465a246d37bb00f55d44d20bcaa0", + "local-evidence/BIT-PRICE.json": "96ec606146b5157871048e28f6649c31c1b6117d43be732e6a96bcc269c0e1b6", + "local-evidence/FAILED-INLINING.json": "95cbb0e6df953d25a888198c1072edf03db85b7c967a234680db3e095abd2dc7", + "local-evidence/FAILED-LATE-RESET.json": "f6ed36b59de745d50f37fcb4c80d129d9a2de0dfe1fe3de2d18e678135f7d9b6", + "local-evidence/FULL-PORTABLE-PYTHON311.json": "1dcca855b20cbac311a435f23f60001c342083edbef3194ba42a30e1f24c1982", + "local-evidence/FULL-PORTABLE-PYTHON314.json": "5687ed9209e11e64304d008a4a10678dc07cdc3522f5112c9a80557d45125c4a", + "local-evidence/FULL-PYTHON314-INITIAL.json": "0966528d4b30459d8b35296f31dbadfa34cdc7792419b34ab2505b7098923325", + "local-evidence/PARENT-FULL-REPLAY.json": "0ba447d6de6edd9fbe2371c36e3605dffa0c6526a874cfcb9bd19285c056bf1e", + "local-evidence/PYTHON311-GZIP-FAILURE.log": "ec1937c575536aeebe8f9c22d673fd66d1355ff870e2fdc80346205b29e42784", + "local-evidence/PYTHON311-INITIAL-FAILURE.json": "7902e8ca1e167b98d1c29170f8d57c9896b38ccab89065e4ed4e2c3feea79076", + "replay.py": "e0782ba05dda36323500390349d1180f6117a9c6112b09b9e21e29f67c4e5f5f", + "verify.py": "4e2082878acc1298f4354325b28f3cf047006170a9883148e7cf23002f6f02f1" + } +} diff --git a/research/e8-early-reset-reuse/NOTICE.md b/research/e8-early-reset-reuse/NOTICE.md new file mode 100644 index 0000000000..ba47405801 --- /dev/null +++ b/research/e8-early-reset-reuse/NOTICE.md @@ -0,0 +1,3 @@ +Rohan Arun, with substantial OpenAI Codex assistance. Apache-2.0. + +New contribution: eleven earlier clean resets selected and composed on PR433's R758 bit word. The clean-reset reuse principle and base bit lineage are from ai-nanachi #426; the split-centre complex and mutable-source bit composition are from icekylinx #433. Zhihao Chen supplied #425/#386; Dylan Crow supplied #370; Jacob Sussman supplied E8 and compiler interfaces. All parent notices remain in the pinned sibling package. Adapted bit_global.py, bit_audit.py, bit_price.py and combined.py retain original author notices. diff --git a/research/e8-early-reset-reuse/PROOF.md b/research/e8-early-reset-reuse/PROOF.md new file mode 100644 index 0000000000..933ba6ab83 --- /dev/null +++ b/research/e8-early-reset-reuse/PROOF.md @@ -0,0 +1,9 @@ +# Earlier clean reset and physical slot reuse + +Select a helper whose last main read has completed and which is not read by the subsequent target decoder. Immediately after that last read, cancel its clean source content using the recorded three or four available parent rows. Parent frames must admit the reset before their next use. The slot may retain arbitrary helper dirt. A later logical helper whose first use has not occurred is assigned that physical slot. The selected intervals and eleven physical pairs are disjoint. + +The reconstruction checks each actual reset on source columns with the earlier physical aliases already applied. It emits every reset addition, including its frame transitions. The main helper word is inverted at the full frame after restoring the source basis. The initial target compensation is regenerated from the entire changed raw operator on every independent physical column; no old dirty response is reused. The full emitted forward and reflected words independently verify the target shear, restored sources, restored helpers, and erased private copy row. + +The global nine-stage dimension-64 geometry and data routes are inherited. New ownership is generated for R747: 6,723 complete rank-eight helper banks, 53,784 assignments, 14,403 live and 14,412 physical rows. All 72 invocations and reflected streams are emitted and independently decoded. The two exact moment engines use the reconstructed profile and positive fallback allowance. The changed prefix has 226 bits, charged at 256; the two-level coefficient has 488 bits, charged at 512. Six finite bootstrap levels and 47 strict outer inequalities give the selected conditional bound. + +The parent complex supplier is unchanged and fully replayed, including all Gaussian phase pairs, by verify.py. Parent all-size compiler, dirty-bank, compressed-window, restored-work, tape/common-grid, precision and analytic interfaces remain assumptions. This is not an unconditional multiplication theorem or new Lean proof. diff --git a/research/e8-early-reset-reuse/README.md b/research/e8-early-reset-reuse/README.md new file mode 100644 index 0000000000..5c976801cd --- /dev/null +++ b/research/e8-early-reset-reuse/README.md @@ -0,0 +1,11 @@ +# Earlier clean resets on PR433 + +Conditional kappa = 0.001128250848293019, approximately 0.659% above PR433. Eleven helpers removed, R758 to R747. The exact bit saving is 0.001129525236098815991751; the unchanged complex saving is 0.001183986549206329. + +Run `python -B research/e8-early-reset-reuse/verify.py /absolute/new/output` with Python 3.11 or 3.14. Standard library only. The wrapper freshly verifies the pinned parent with all phases before reconstructing and checking the changed bit program. + +At draft submission the changed emitted bit, independent bank audit, two rational moments and exact finite assembly passed locally against the previously fully replayed parent. The new uninterrupted wrapper and GitHub CI are pending. Local receipts distinguish that scope. + +The initial full Python3.14 wrapper passed. Python3.11 exposed the parent compressed-file metadata mismatch; the package now imports PR433's upstream decoded-witness hash fix at 6d9244518175caf9e0089f92486959bc2c317273. Fresh both-version replays are pending. The original failure and pass receipts are preserved. + +Both fresh portable full replays now passed locally on Python 3.11 and 3.14 against e48f24fd2393500c804a0cbab542e20de8ddee6e. See VALIDATION.json and local-evidence/FULL-PORTABLE-PYTHON*.json. diff --git a/research/e8-early-reset-reuse/SELECTION.json b/research/e8-early-reset-reuse/SELECTION.json new file mode 100644 index 0000000000..9df36fb9ef --- /dev/null +++ b/research/e8-early-reset-reuse/SELECTION.json @@ -0,0 +1,141 @@ +{ + "source_sha256": "015811014644ed62acba1da590d9cf6ebdfe834d89867f8ce2b68722609072ea", + "word_sha256": "98ffef9246c8bf6c537ab5e134321abea05cf0b7830c9e3fd92cbe4e88d8c308", + "R": 747, + "local_profile": { + "1": 2398, + "2": 865, + "3": 475, + "5": 153, + "4": 310, + "8": 9, + "7": 14 + }, + "global_profile": { + "1": 172656, + "2": 62280, + "3": 34200, + "5": 11016, + "4": 22320, + "8": 648, + "7": 6768, + "14": 3840, + "28": 3840, + "42": 3840 + }, + "live": 14403, + "entries": [ + { + "position": 1032, + "new_helper": 949, + "retired_helper": 406, + "parents": [ + 411, + 518 + ], + "frame": 458 + }, + { + "position": 1036, + "new_helper": 950, + "retired_helper": 252, + "parents": [ + 0, + 1, + 512, + 523 + ], + "frame": 458 + }, + { + "position": 1038, + "new_helper": 957, + "retired_helper": 532, + "parents": [ + 533, + 534 + ], + "frame": 459 + }, + { + "position": 1053, + "new_helper": 936, + "retired_helper": 310, + "parents": [ + 315, + 566 + ], + "frame": 461 + }, + { + "position": 1069, + "new_helper": 937, + "retired_helper": 422, + "parents": [ + 427, + 598 + ], + "frame": 463 + }, + { + "position": 1085, + "new_helper": 933, + "retired_helper": 294, + "parents": [ + 299, + 630 + ], + "frame": 465 + }, + { + "position": 1094, + "new_helper": 935, + "retired_helper": 374, + "parents": [ + 379, + 646 + ], + "frame": 466 + }, + { + "position": 1103, + "new_helper": 934, + "retired_helper": 444, + "parents": [ + 439, + 662 + ], + "frame": 467 + }, + { + "position": 1112, + "new_helper": 932, + "retired_helper": 492, + "parents": [ + 487, + 678 + ], + "frame": 468 + }, + { + "position": 1121, + "new_helper": 944, + "retired_helper": 476, + "parents": [ + 471, + 694 + ], + "frame": 469 + }, + { + "position": 1128, + "new_helper": 942, + "retired_helper": 710, + "parents": [ + 455, + 460 + ], + "frame": 470 + } + ] +} diff --git a/research/e8-early-reset-reuse/SOURCE.json b/research/e8-early-reset-reuse/SOURCE.json new file mode 100644 index 0000000000..d9ed13ac34 --- /dev/null +++ b/research/e8-early-reset-reuse/SOURCE.json @@ -0,0 +1,7 @@ +{ + "parent_pr": 433, + "parent_commit": "6d9244518175caf9e0089f92486959bc2c317273", + "parent_manifest_sha256": "3129eb4321f706542470f8443f66a6b4351a12a9ceec85e7f76aa19db1e1e32f", + "attribution": "Rohan Arun with substantial OpenAI Codex assistance. icekylinx PR433 split centres and source reuse; ai-nanachi PR426 clean reset principle and base bit word; Zhihao Chen PR425/386; Dylan Crow PR370; Jacob Sussman E8 and inherited framework.", + "parent_update": "Upstream PR433 gzip portability repair: bind decoded canonical witness rather than platform-dependent gzip header. No construction or price changes." +} diff --git a/research/e8-early-reset-reuse/VALIDATION.json b/research/e8-early-reset-reuse/VALIDATION.json new file mode 100644 index 0000000000..2cfd52731f --- /dev/null +++ b/research/e8-early-reset-reuse/VALIDATION.json @@ -0,0 +1,9 @@ +{ + "status": "PASS_BOTH_FULL_LOCAL_REPLAYS", + "validated_code_head": "e48f24fd2393500c804a0cbab542e20de8ddee6e", + "python": [ + "3.11", + "3.14" + ], + "scope": "Fresh full parent phases and changed bit program, independent audit, finite invoice and exact assembly; GitHub CI pending." +} diff --git a/research/e8-early-reset-reuse/bit_audit.py b/research/e8-early-reset-reuse/bit_audit.py new file mode 100644 index 0000000000..155faf40b0 --- /dev/null +++ b/research/e8-early-reset-reuse/bit_audit.py @@ -0,0 +1,126 @@ +# Adapted with exact rational span checks by icekylinx; Codex assistance. +"""Independent audit of the emitted bit template, including mutation controls. +Prepared by Zhihao Chen with OpenAI Codex assistance; Apache-2.0. +""" +import argparse, copy, gzip, hashlib, json, struct, time +from collections import Counter, defaultdict +from pathlib import Path +from fractions import Fraction as Q + +def sha(p): return hashlib.sha256(p.read_bytes()).hexdigest() + +def main(): + ap=argparse.ArgumentParser(); ap.add_argument('--local-check',type=Path,required=True); ap.add_argument('--out',type=Path,required=True) + a=ap.parse_args(); start=time.monotonic(); out=a.out + blob=gzip.decompress((out/'GLOBAL-TEMPLATE.json.gz').read_bytes()); t=json.loads(blob) + g=json.loads((out/'GLOBAL.json').read_text()); geo=json.loads((out/'GEOMETRY.json').read_text()) + assert hashlib.sha256(blob).hexdigest()==g['template_sha256'] + assert t['geometry_sha256']==sha(out/'GEOMETRY.json') and t['source_record_sha256']==sha(a.local_check/'records/249-records.bin') + fs=json.loads((a.local_check/'records/frames.json').read_text())['frames'] + records=list(struct.iter_unpack('<6i',(a.local_check/'records/249-records.bin').read_bytes())) + word=json.loads((a.local_check/'bit-source-centres.json').read_text()) + assert g['word_sha256']==sha(a.local_check/'bit-source-centres.json') + def rank(rows): + piv={} + for rr in rows: + row=list(map(Q,rr)) + for k,b in sorted(piv.items()): + q=row[k] + if q:row=[x-q*y for x,y in zip(row,b)] + k=next((j for j,x in enumerate(row) if x),None) + if k is not None: + q=row[k];piv[k]=[x/q for x in row] + return len(piv) + dimensions={};proj={} + for key,f in fs.items(): + k=int(key);B=f['B'];roots=[word['lines'][j] for j in word['frames'][k]] + assert rank(B)==f['dim']==rank(B+roots)==rank(roots) + dimensions[k]=f['dim'];proj[k]=B + sets=[set(f) for f in word['frames']];pairs={} + for op,x,y,c,r,z in records: + if op==0: + assert sets[y]<=sets[c] and dimensions[c]-dimensions[y]==r + pairs[y,c]=r + # Positive definite rational form: exact inclusion implies commuting + # orthogonal projectors and rank(P_V-P_U)=dim(V)-dim(U), also in reflection. + assert len(proj)==944 + expected={} + for rev in (False,True): + es=[] + for op,x,y,c,f,z in (reversed(records) if rev else records): + if op==0: es.append([0,x,c if rev else y,y if rev else c,f,int(rev)]) + elif op==1: es.append([1,x,y,-c if rev else c,f,int(rev)]) + elif op==(3 if rev else 2): es.append([2,x,y,c,f,abs(dimensions[c]-dimensions[f]),int(rev)]) + else: es.append([3,x,y,c,f,z,int(rev)]) + expected['reverse' if rev else 'forward']=es + assert t['local_programs']==expected + + def validate(q,check_profile=True): + assert (q['m'],q['live'],q['replicas'],q['stages'])==(64,14403,8,9) + assert q['bank_padding'] is None and q['local_programs']==expected + hist=Counter(); occupation=defaultdict(set); calls=set() + for c in q['calls']: + st,rep,p=c['stage'],c['replica'],c['pair']; rev=c['orientation']=='reverse' + assert 0<=st<9 and 0<=rep<8 and p==max(0,(st-1)//2) + assert rev==(st in (1,3,5,7)) and (st,rep) not in calls; calls.add((st,rep)) + own=c['owners']; assert len(own)==987 + assert len({(f,tuple(r)) for f,r in own})==987 + for i,(family,route) in enumerate(own): + assert 0<=family<14403 + if i<240: + side=i//120; side=1-side if rev else side + assert family==rep*960+(2*p+side)*120+i%120 and route==['data',st,i%120] + else: + j=i-240; bank,slot=divmod(rep*747+j,8) + assert family==7680+st*747+bank and route==['bank',slot] + assert slot not in occupation[family]; occupation[family].add(slot) + for e in q['local_programs'][c['orientation']]: + if e[0]==0 and e[4]: hist[e[4]]+=1 + if e[0]==2: hist[e[5]]+=1 + assert calls=={(s,r) for s in range(9) for r in range(8)} + assert set(occupation)==set(range(7680,14403)) and all(s==set(range(8)) for s in occupation.values()) + levels=[-1]*4; scalar=[1<=0 + cur[x]=newf + if f: hist[f]+=1 + events.append([0,x,oldf,newf,f,int(reverse)]) + elif op==1: + assert cur[x]==cur[y]==f and x!=y and x0 + cutoff=max(ceil(36/gap**2),ceil(2*(4+charged_two)/gap)) + assert cutoff*gap**2>=36 and cutoff*gap>=2*(4+charged_two) + cutoffs.append(dict(gap=str(gap),cutoff_log2=str(cutoff)));chain.append(a) +q=chain[-1]*(1-2*eta);margin=(1-eta)*q/(1+q);ticks=margin/grid;k=grid*((ticks.numerator-1)//ticks.denominator) +bridge={'semantic':{'C0':{'base':2,'exponent':210000},'strict_literal_gap':1},'rows':{'degree_gap':Q(10**6)-Q(51*20161,25)}} +a=Outer.assembly(chain[-1],b,bridge,k,eta=eta,beta=beta) +assert len(a['strict_constraints'])==47 and all(x>0 for x in a['strict_constraints'].values()) +controls=[] +for name,kk,ee,bb in [('next_grid',k+grid,eta,beta),('zero_eta',k,Q(0),beta),('zero_beta',k,eta,Q(0)),('unit_beta',k,eta,Q(1))]: + try:Outer.assembly(chain[-1],b,bridge,kk,eta=ee,beta=bb) + except AssertionError:controls.append(name) + else:raise AssertionError(name) +result=dict(status='PASS_CONDITIONAL_EARLY_RESET_REUSE_ASSEMBLY',kappa=str(k),kappa_decimal=format(float(k),'.18f'),bit_lower=str(c),complex_lower=str(b),binding_component='bit',gain_over_pr425_percent=float(100*(k/Q(1048005508028206,10**18)-1)),bit_invoice=dict(prefix_bits=prefix.bit_length(),charged_prefix_bits=charged_prefix,coefficient_bits=coefficient.bit_length(),two_level_coefficient_bits=two.bit_length(),charged_two_level_coefficient_bits=charged_two,row_coefficient=row,live=W,physical=physical),strict_outer_constraints={n:str(x) for n,x in a['strict_constraints'].items()},outer_controls=controls,bootstrap=cutoffs,bit_template_sha256=g['template_sha256'],complex_template_sha256=cx['global_template_sha256'],scope='Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim.') +(ROOT/'RESULT.json').write_text(json.dumps(result,indent=2)+'\n') +print(result['status'],result['kappa_decimal'],result['gain_over_pr425_percent'],result['bit_invoice']) diff --git a/research/e8-early-reset-reuse/local-evidence/ASSEMBLY.json b/research/e8-early-reset-reuse/local-evidence/ASSEMBLY.json new file mode 100644 index 0000000000..7899c12d17 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/ASSEMBLY.json @@ -0,0 +1,103 @@ +{ + "status": "PASS_CONDITIONAL_EARLY_RESET_REUSE_ASSEMBLY", + "kappa": "1128250848293019/1000000000000000000", + "kappa_decimal": "0.001128250848293019", + "bit_lower": "1129525236098815991751/1000000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "gain_over_pr425_percent": 7.656957873799007, + "bit_invoice": { + "prefix_bits": 226, + "charged_prefix_bits": 256, + "coefficient_bits": 226, + "two_level_coefficient_bits": 488, + "charged_two_level_coefficient_bits": 512, + "row_coefficient": 18355, + "live": 14403, + "physical": 14412 + }, + "strict_outer_constraints": { + "bit_positive": "18506141468243001171708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_above_bit": "892294153953493164291278909495839246640718806729067679326283799449521771430341633720462386272040419854572728671718333403296175864465736075385269023/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_below_one_over32": "30066013450793671/1000000000000000000", + "beta_positive": "1/1000000000000000000", + "beta_below_one": "999999999999999999/1000000000000000000", + "leaf_saving_above_bit": "892294153953493144892843287299344910640718806729067679326283799449521771430341633720462386272040419854572728671718333403296175864465736075385269023/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_positive": "9253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_internal": "18506141468243001171708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_leaf": "446147076976746590952563111892673627029080493868694593022423092995693206388887017410709421705678576206823978063818746847075359260514534634396458647034263924614730977/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_positive": "9253070734121502615348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_below_one": "8182746929265878497384651780922990920795029080493868694593022423092995693206388887017410709421705678576206823978063818746847075359260514534634396458647034263924614730977/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_reservations": "1/4000000000000000000", + "lambda_above_tau": "18506141468243001171708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_sigma": "892294153953493182797420377738840418349439897233228432685564992720454092104057834270940614841698786134110342399677913548723447192747402672089093158534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_internal": "18506141468243001171708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_prime_above_lambda": "18506141468243001171708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_leaf": "446147076976746590952563111892673627029080493868694593022423092995693206388887017410709421705678576206823978063818746847075359260514534634396458647034263924614730977/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_reservations": "1/4000000000000000000", + "lambda_prime_below_one": "9253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8192000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "epsilon_positive": "8191999999999999991808000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023", + "epsilon_below_one": "9253070734121508759348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023", + "guard_width": "9253070734121508759348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023", + "K_geometry": "6153253070734121502615348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023000000000000000000", + "K_dominates_log": "298486152713596858261133817512502470632990336423297619419569593576548431826888260502741412409135756167867272375543865463217697380751748781054158084305815184186507344194653674987571967/264556550668842629050559619970226099329192610306649396948612179900225945380439068160728686792848203916896554065223747782359771762604499531140825920688805346325012428033000000000000000000", + "record_suffix": "9253070734121508759348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023", + "phase_local": "74024565872972061873532681881951133072419136972041364050849695749903148941911326953710017832743458407756117597195128601430221103979702469771903690084240423237478610831034263924614730977/65610024565872972004538785752616072633639767356049050443255820615256034454348888903860714324626354571390345408175489450025223397125915883722924828330823725888603082152184000000000000000000", + "phase_boundary": "14804913174594405813704079789093026160605252132801009446193203545075585462800203865138558131659801295479791056803568581251503403246995491432041025425259712355012889083834263924614730977/13122004913174594400907757150523214526727953471209810088651164123051206890869777780772142864925270914278069081635097890005044679425183176744584965666164745177720616430436800000000000000000", + "gamma_sublinear": "1/2000000000000000000", + "cell_above_band": "16383999999999999975414746929265878499432651780922990920795029080493868694593022423092995693206388887017410709421705678576206823978063818746847075359260514534634396458647034263924614730977/32805012282936486002269392876308036316819883678024525221627910307628017227174444451930357162313177285695172704087744725012611698562957941861462414165411862944301541076092000000000000000000", + "prime_interval_packing": "9253070734121508759348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023", + "alpha_positive": "18506141468243009317443367419896657842593619935253531608984234307877308180244649058174274362977529864997061465578041082512673259542789677578282441966446006785166996693034263924614730977/16402506141468243001134696438154018158409941839012262610813955153814008613587222225965178581156588642847586352043872362506305849281478970930731207082705931472150770538046000000000000000000", + "alpha_below_one": "16383999999999999991817253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023/16402506141468243001134696438154018158409941839012262610813955153814008613587222225965178581156588642847586352043872362506305849281478970930731207082705931472150770538046000000000000000000", + "alpha_below_one_fourth": "4082120393898817740966230742118607881759891839817812121094504554145624845216560907433120370926169630846899526545390049544063789060826953055104519328710036861252525637818465736075385269023/16402506141468243001134696438154018158409941839012262610813955153814008613587222225965178581156588642847586352043872362506305849281478970930731207082705931472150770538046000000000000000000", + "delta_positive": "1/8000000000000000000", + "delta_below_one_eighth": "999999999999999999/8000000000000000000", + "short_record_fallback": "134065954450456131888572404073222057587195605953853045459726979682067836030854839827324250112657359613753045411329984324417514991266327925496392926819076909098625880785159609317507266039991394147465325581857236255532115555519907868899367780890770924744091711832220085615353750878175230822142166392507469830641670083374529/134369330310907846665295433221357716753694243545188455307787920620044358562506524475106742936834774162207427395943402393651657517313875729864550048421526990619859112247672832000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "small_field_exposure": "1/1000000000000000000", + "artificial_boundary": "459344196526983776126450045233130945570820183505623430783661477680566669551012043961606727517391669910070531137138798564473166705073135613542857400568808263504921467841530897208226155807069/65610024565872972004538785752616072633639767356049050443255820615256034454348888903860714324626354571390345408175489450025223397125915883722924828330823725888603082152184000000000000000000", + "literal_scalar_guard": "1", + "row_product_gap": "23971789/25", + "balanced_prefix_above_kappa": "9220264634419749410126248485777003611646590040381762946804723855588412103267248597113917235579943540037407401432945273428716916281235826485632259566734279018802352149563/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023000000000000000000", + "coordinate_movement_above_kappa": "20879569810177875708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_phase_layer_above_kappa": "50950578184281395477945013334999726622080956043781582069887313934070389823681874206566397250082460930680711270550454608778199582024817051013332801269065664136348344027/410062653536706075028367410953850453960248545975306565270348878845350215339680555649129464528914716071189658801096809062657646232036974273268280177067648286803769263451150000000000000000", + "bulk_exposure_above_kappa": "20879569810177875708721090504160753359281193270932320673716200550478228569658366279537613727959580145427271328281666596703824135534263924614730977/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gaussian_arithmetic_above_kappa": "32755851721687387778173246790830983497147865725523447047402902960172275292169933211998391431748076713180293331353881281163970707046189184558230058827109403470041890851389/65610024565872972004538785752616072633639767356049050443255820615256034454348888903860714324626354571390345408175489450025223397125915883722924828330823725888603082152184000000000000000000", + "scalar_work_above_kappa": "65560864004623873780442639667139019813967749403547972269030813267800292519344377663928748594061253998875466035441626006176582405609147126419692472992521266414343431927481/65610024565872972004538785752616072633639767356049050443255820615256034454348888903860714324626354571390345408175489450025223397125915883722924828330823725888603082152184000000000000000000", + "dimension_above_kappa": "8182746929265878492268916415342740330921277566270872306239612463474758640011112742605822812688954275690124059558007358784254476792205787963351312739882860749556874297711279018802352149563/8201253070734121500567348219077009079204970919506131305406977576907004306793611112982589290578294321423793176021936181253152924640739485465365603541352965736075385269023000000000000000000" + }, + "outer_controls": [ + "next_grid", + "zero_eta", + "zero_beta", + "unit_beta" + ], + "bootstrap": [ + { + "gap": "19718173301699986490442310099608577089/16000000000000000000000000000000000000000000", + "cutoff_log2": "23703316064509" + }, + { + "gap": "89088697416160189168478072742640881250923123343423452063/64000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "18578781647433489479" + }, + { + "gap": "402511727930897263492893481780029509017558469228965731102330904495255713921/256000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "14562145083988389157871807" + }, + { + "gap": "1818588618094756475300249931559443478956904117509927455038979846382951280845356947587831584607/1024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "11413884584645035881423129400187" + }, + { + "gap": "8216566952880397264033353325540771278429496754443877107508740488500708481207792267348207305960479962067658955969/4096000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "8946261732747165430949576222298741146" + }, + { + "gap": "37123278909495839246640718806729067679326283799449521771430341633720462386272040419854572728671718333403296175864465736075385269023/16384000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "7012126186950169517647508261689402518966285" + } + ], + "bit_template_sha256": "10dfc644197ef152062bf69960ecdc2405c847ce47147b520c3172c51cd82bd9", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f", + "scope": "Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim." +} diff --git a/research/e8-early-reset-reuse/local-evidence/BIT-AUDIT.json b/research/e8-early-reset-reuse/local-evidence/BIT-AUDIT.json new file mode 100644 index 0000000000..5acb750852 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/BIT-AUDIT.json @@ -0,0 +1,33 @@ +{ + "status": "PASS_INDEPENDENT_COMPRESSED_BIT_TEMPLATE_AUDIT", + "template_sha256": "10dfc644197ef152062bf69960ecdc2405c847ce47147b520c3172c51cd82bd9", + "source_frames": 944, + "exact_nested_frame_pairs": 3341, + "exact_reflected_pairs": 3341, + "orthogonal_lift_argument": "Adding the same orthogonal E_s leaves P_V-P_U unchanged; each audited projector is therefore the literal child projector in every one of the nine windows.", + "exact_bank_families": 6723, + "slots_per_bank": 8, + "mutations_rejected": [ + "omit an idle child", + "omit a bridge", + "omit terminal exchange", + "remove a local invocation", + "re-use a helper bank slot", + "understate live stock", + "omit a local paid move", + "wrong reflected copy charge" + ], + "profile": { + "1": 172656, + "2": 62280, + "3": 34200, + "4": 22320, + "5": 11016, + "7": 6768, + "8": 648, + "14": 3840, + "28": 3840, + "42": 3840 + }, + "seconds": 1.6600992910098284 +} diff --git a/research/e8-early-reset-reuse/local-evidence/BIT-GLOBAL.json b/research/e8-early-reset-reuse/local-evidence/BIT-GLOBAL.json new file mode 100644 index 0000000000..fd3faa8602 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/BIT-GLOBAL.json @@ -0,0 +1,164 @@ +{ + "status": "PASS_SOURCE_BOUND_NINE_STAGE_BIT_TEMPLATE", + "h": 8, + "m": 64, + "v": 120, + "R": 747, + "replicas": 8, + "live": 14403, + "physical": 14412, + "word_sha256": "98ffef9246c8bf6c537ab5e134321abea05cf0b7830c9e3fd92cbe4e88d8c308", + "source_records_sha256": "bd805894638e578daf4f057f61bf6c6810d4460ac98b6238619549a0b5af1b68", + "local_checks": { + "forward": { + "copies": 9, + "adds": 14586, + "records": 18819, + "all_columns": 987, + "cancellation_free_row_l1": 4749825, + "profile": { + "1": 2398, + "2": 865, + "3": 475, + "4": 310, + "5": 153, + "7": 14, + "8": 9 + }, + "sha256": "67a94cf0035c06591019042d3bbc1d62e435cd6e839a0c08afe98609607b0522" + }, + "reverse": { + "copies": 9, + "adds": 14586, + "records": 18819, + "all_columns": 987, + "cancellation_free_row_l1": 18975950, + "profile": { + "1": 2398, + "2": 865, + "3": 475, + "4": 310, + "5": 153, + "7": 14, + "8": 9 + }, + "sha256": "bcd0366700ed4a0f4717c54e5f330015d8f174636c6f0f5a9c42ff553396e931" + } + }, + "scalar_stages": [ + { + "stage": 0, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 1, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 2, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 3, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 4, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 5, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 6, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + }, + { + "stage": 7, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": true + }, + { + "stage": 8, + "all_columns": 7683, + "helper_columns": 6723, + "reverse": false + } + ], + "independent_unbanked_scalar_columns": 7683, + "all_scalar_columns_restored": true, + "geometry_sha256": "ec1742de8de83751f6c633e54d855a920645bcca40ce2a2d2e2a8349576a00db", + "template_sha256": "10dfc644197ef152062bf69960ecdc2405c847ce47147b520c3172c51cd82bd9", + "emitted_program_sha256": "ced149086bd620d31aa8b5f6a68999d3194a7e32fb2c47c0b9f8332dd961abf4", + "emitted_events": 1354968, + "local_invocations": 72, + "bank_assignments": 53784, + "banks_per_stage": 747, + "whole_rank8_slots_per_bank": 8, + "padding_calls": 0, + "profile": { + "1": 172656, + "2": 62280, + "3": 34200, + "4": 22320, + "5": 11016, + "7": 6768, + "8": 648, + "14": 3840, + "28": 3840, + "42": 3840 + }, + "paid_calls": 321408, + "rank_mass": 919296, + "deficit": 2496, + "maxchild": 42, + "halving_depth": 2, + "halving_integer_inequality": [ + 4096, + 3528 + ], + "local_additions": 14586, + "bridge_additions": 17280, + "copy_erase_episodes": 648, + "global_prefix_bound": "82175447241247327050912217435296917941221100975248000000000000000000", + "global_prefix_bits": 226, + "charged_prefix_bits": 256, + "omitted_bridge_shears_rejected": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17 + ], + "scope": "Complete source-bound finite cover template. Local and unbanked global F2 columns are replayed; arbitrary physical bank dirt follows by injective owner routes and the all-column local theorem. Astronomical cover enumeration and all-size compiler interfaces remain explicit inherited assumptions.", + "seconds": 2.408216124982573 +} diff --git a/research/e8-early-reset-reuse/local-evidence/BIT-PRICE.json b/research/e8-early-reset-reuse/local-evidence/BIT-PRICE.json new file mode 100644 index 0000000000..0ee06a110f --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/BIT-PRICE.json @@ -0,0 +1,17 @@ +{ + "lower": "0.001129525236098815991751", + "upper": "0.001129525236098815991752", + "lower_endpoint_residual_upper": "-1.251774999433093430381353664521278818665250762780616345195836520018292E-25", + "upper_endpoint_residual_lower": "2.276366164350301667566734024087898004226996967249013754753469273066967E-24", + "strict_rational_signs": true, + "moment_minus_one_at_current_k_required_rate": [ + "-0.001042177813821591887548119068554528501744007073182525639912744635909457", + "-0.001042177813821591887548119068554528501744007073182525639912744635835273" + ], + "nominal_k_ceiling_interval": [ + "0.001128250848293019129894635265715588124139286669678372820580212187821160", + "0.001128250848293019129895633010486841514774944147064771313407964226126090" + ], + "source_template_sha256": "10dfc644197ef152062bf69960ecdc2405c847ce47147b520c3172c51cd82bd9", + "two_exact_engines": true +} diff --git a/research/e8-early-reset-reuse/local-evidence/FAILED-INLINING.json b/research/e8-early-reset-reuse/local-evidence/FAILED-INLINING.json new file mode 100644 index 0000000000..927c934e27 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/FAILED-INLINING.json @@ -0,0 +1,571 @@ +{ + "source_sha256": "015811014644ed62acba1da590d9cf6ebdfe834d89867f8ce2b68722609072ea", + "tested": 140, + "statuses": { + "frame": 106, + "source_identity": 34 + }, + "positive": [], + "results": [ + { + "helper": 246, + "status": "frame" + }, + { + "helper": 247, + "status": "frame" + }, + { + "helper": 252, + "status": "frame" + }, + { + "helper": 253, + "status": "frame" + }, + { + "helper": 254, + "status": "frame" + }, + { + "helper": 255, + "status": "frame" + }, + { + "helper": 258, + "status": "frame" + }, + { + "helper": 259, + "status": "frame" + }, + { + "helper": 260, + "status": "frame" + }, + { + "helper": 261, + "status": "frame" + }, + { + "helper": 262, + "status": "frame" + }, + { + "helper": 263, + "status": "frame" + }, + { + "helper": 264, + "status": "frame" + }, + { + "helper": 265, + "status": "frame" + }, + { + "helper": 267, + "status": "frame" + }, + { + "helper": 268, + "status": "frame" + }, + { + "helper": 270, + "status": "frame" + }, + { + "helper": 271, + "status": "frame" + }, + { + "helper": 272, + "status": "frame" + }, + { + "helper": 273, + "status": "frame" + }, + { + "helper": 274, + "status": "frame" + }, + { + "helper": 275, + "status": "frame" + }, + { + "helper": 276, + "status": "frame" + }, + { + "helper": 277, + "status": "frame" + }, + { + "helper": 278, + "status": "frame" + }, + { + "helper": 279, + "status": "frame" + }, + { + "helper": 280, + "status": "frame" + }, + { + "helper": 281, + "status": "frame" + }, + { + "helper": 282, + "status": "frame" + }, + { + "helper": 283, + "status": "frame" + }, + { + "helper": 284, + "status": "frame" + }, + { + "helper": 285, + "status": "frame" + }, + { + "helper": 286, + "status": "frame" + }, + { + "helper": 287, + "status": "frame" + }, + { + "helper": 517, + "status": "source_identity" + }, + { + "helper": 533, + "status": "source_identity" + }, + { + "helper": 549, + "status": "source_identity" + }, + { + "helper": 565, + "status": "source_identity" + }, + { + "helper": 581, + "status": "source_identity" + }, + { + "helper": 597, + "status": "source_identity" + }, + { + "helper": 613, + "status": "source_identity" + }, + { + "helper": 629, + "status": "source_identity" + }, + { + "helper": 645, + "status": "source_identity" + }, + { + "helper": 661, + "status": "source_identity" + }, + { + "helper": 677, + "status": "source_identity" + }, + { + "helper": 693, + "status": "source_identity" + }, + { + "helper": 714, + "status": "source_identity" + }, + { + "helper": 725, + "status": "source_identity" + }, + { + "helper": 750, + "status": "source_identity" + }, + { + "helper": 752, + "status": "frame" + }, + { + "helper": 764, + "status": "source_identity" + }, + { + "helper": 765, + "status": "source_identity" + }, + { + "helper": 766, + "status": "frame" + }, + { + "helper": 767, + "status": "frame" + }, + { + "helper": 778, + "status": "source_identity" + }, + { + "helper": 780, + "status": "frame" + }, + { + "helper": 792, + "status": "source_identity" + }, + { + "helper": 793, + "status": "source_identity" + }, + { + "helper": 794, + "status": "frame" + }, + { + "helper": 795, + "status": "frame" + }, + { + "helper": 806, + "status": "source_identity" + }, + { + "helper": 808, + "status": "frame" + }, + { + "helper": 810, + "status": "frame" + }, + { + "helper": 811, + "status": "frame" + }, + { + "helper": 812, + "status": "frame" + }, + { + "helper": 813, + "status": "frame" + }, + { + "helper": 820, + "status": "source_identity" + }, + { + "helper": 821, + "status": "source_identity" + }, + { + "helper": 822, + "status": "frame" + }, + { + "helper": 823, + "status": "frame" + }, + { + "helper": 824, + "status": "frame" + }, + { + "helper": 825, + "status": "frame" + }, + { + "helper": 826, + "status": "frame" + }, + { + "helper": 827, + "status": "frame" + }, + { + "helper": 834, + "status": "source_identity" + }, + { + "helper": 836, + "status": "frame" + }, + { + "helper": 848, + "status": "source_identity" + }, + { + "helper": 849, + "status": "source_identity" + }, + { + "helper": 850, + "status": "frame" + }, + { + "helper": 851, + "status": "frame" + }, + { + "helper": 862, + "status": "source_identity" + }, + { + "helper": 864, + "status": "frame" + }, + { + "helper": 866, + "status": "frame" + }, + { + "helper": 867, + "status": "frame" + }, + { + "helper": 868, + "status": "frame" + }, + { + "helper": 869, + "status": "frame" + }, + { + "helper": 876, + "status": "source_identity" + }, + { + "helper": 877, + "status": "source_identity" + }, + { + "helper": 878, + "status": "frame" + }, + { + "helper": 879, + "status": "frame" + }, + { + "helper": 880, + "status": "frame" + }, + { + "helper": 881, + "status": "frame" + }, + { + "helper": 882, + "status": "frame" + }, + { + "helper": 883, + "status": "frame" + }, + { + "helper": 890, + "status": "source_identity" + }, + { + "helper": 892, + "status": "frame" + }, + { + "helper": 896, + "status": "frame" + }, + { + "helper": 897, + "status": "frame" + }, + { + "helper": 898, + "status": "frame" + }, + { + "helper": 899, + "status": "frame" + }, + { + "helper": 900, + "status": "frame" + }, + { + "helper": 901, + "status": "frame" + }, + { + "helper": 902, + "status": "frame" + }, + { + "helper": 903, + "status": "frame" + }, + { + "helper": 904, + "status": "source_identity" + }, + { + "helper": 905, + "status": "source_identity" + }, + { + "helper": 906, + "status": "frame" + }, + { + "helper": 910, + "status": "frame" + }, + { + "helper": 911, + "status": "frame" + }, + { + "helper": 912, + "status": "frame" + }, + { + "helper": 913, + "status": "frame" + }, + { + "helper": 914, + "status": "frame" + }, + { + "helper": 915, + "status": "frame" + }, + { + "helper": 916, + "status": "frame" + }, + { + "helper": 917, + "status": "frame" + }, + { + "helper": 918, + "status": "source_identity" + }, + { + "helper": 919, + "status": "source_identity" + }, + { + "helper": 920, + "status": "frame" + }, + { + "helper": 921, + "status": "frame" + }, + { + "helper": 922, + "status": "frame" + }, + { + "helper": 923, + "status": "frame" + }, + { + "helper": 924, + "status": "frame" + }, + { + "helper": 925, + "status": "frame" + }, + { + "helper": 926, + "status": "frame" + }, + { + "helper": 927, + "status": "frame" + }, + { + "helper": 928, + "status": "frame" + }, + { + "helper": 929, + "status": "frame" + }, + { + "helper": 930, + "status": "frame" + }, + { + "helper": 931, + "status": "frame" + }, + { + "helper": 932, + "status": "frame" + }, + { + "helper": 933, + "status": "frame" + }, + { + "helper": 934, + "status": "frame" + }, + { + "helper": 935, + "status": "frame" + }, + { + "helper": 936, + "status": "frame" + }, + { + "helper": 937, + "status": "frame" + }, + { + "helper": 942, + "status": "frame" + }, + { + "helper": 943, + "status": "frame" + }, + { + "helper": 944, + "status": "frame" + }, + { + "helper": 950, + "status": "frame" + }, + { + "helper": 951, + "status": "frame" + } + ] +} diff --git a/research/e8-early-reset-reuse/local-evidence/FAILED-LATE-RESET.json b/research/e8-early-reset-reuse/local-evidence/FAILED-LATE-RESET.json new file mode 100644 index 0000000000..f01e4f53a2 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/FAILED-LATE-RESET.json @@ -0,0 +1,8 @@ +{ + "source_sha256": "015811014644ed62acba1da590d9cf6ebdfe834d89867f8ce2b68722609072ea", + "tested_retired_birth_pairs": 484, + "witnesses": 0, + "positive": [], + "rejections": {}, + "results": [] +} diff --git a/research/e8-early-reset-reuse/local-evidence/FULL-PORTABLE-PYTHON311.json b/research/e8-early-reset-reuse/local-evidence/FULL-PORTABLE-PYTHON311.json new file mode 100644 index 0000000000..b91e7cc182 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/FULL-PORTABLE-PYTHON311.json @@ -0,0 +1,44 @@ +{ + "status": "PASS_FULL_PARENT_AND_EARLY_RESET_REUSE", + "kappa": "1128250848293019/1000000000000000000", + "kappa_decimal": "0.001128250848293019", + "source_manifest_sha256": "06c5bd1afe07ebede7aaa13ae694ab7b345beab0a9d149c27fc992c92f3727f6", + "checks": [ + { + "name": "full-parent433", + "seconds": 114.39691066707019, + "log_sha256": "028a6067de8c3a61dfbf81c5d9c8d3629949b70cc118b64264f25df4b84a64ac" + }, + { + "name": "reconstruct", + "seconds": 0.05611987505108118, + "log_sha256": "ceeb567022f0746ceb350487a568b94cdfeacf3fb55cdc4088fecfab389caefa" + }, + { + "name": "export", + "seconds": 0.5730349159566686, + "log_sha256": "4be929eee47c06938fe228adcef2dff245a38d32c9bdcc44808376735c175f1b" + }, + { + "name": "global-program", + "seconds": 2.582935667014681, + "log_sha256": "c9ed76d601e121721dd1e540a5db45701b8a6b3d37920b72d3a300126e1624fd" + }, + { + "name": "independent-audit", + "seconds": 3.009822624968365, + "log_sha256": "e089d3fa06b37a96a4a998d27c28f3b62c5b88a7d4fe5e77e0ff6e2a9ca6ef76" + }, + { + "name": "two-moments", + "seconds": 0.13729891693219543, + "log_sha256": "6d556f02612ff9a8df2239e44b949bc8bf81e03102b54ca762966a7dbd7a598e" + }, + { + "name": "finite-assembly", + "seconds": 0.15405583300162107, + "log_sha256": "cd2459472bd6f540e6610b019907b7fc36b1058cc69b1b608e6254e33a8de603" + } + ], + "parent_phase_mode": "full replay" +} diff --git a/research/e8-early-reset-reuse/local-evidence/FULL-PORTABLE-PYTHON314.json b/research/e8-early-reset-reuse/local-evidence/FULL-PORTABLE-PYTHON314.json new file mode 100644 index 0000000000..773987c837 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/FULL-PORTABLE-PYTHON314.json @@ -0,0 +1,44 @@ +{ + "status": "PASS_FULL_PARENT_AND_EARLY_RESET_REUSE", + "kappa": "1128250848293019/1000000000000000000", + "kappa_decimal": "0.001128250848293019", + "source_manifest_sha256": "06c5bd1afe07ebede7aaa13ae694ab7b345beab0a9d149c27fc992c92f3727f6", + "checks": [ + { + "name": "full-parent433", + "seconds": 106.79119999997783, + "log_sha256": "028a6067de8c3a61dfbf81c5d9c8d3629949b70cc118b64264f25df4b84a64ac" + }, + { + "name": "reconstruct", + "seconds": 0.05519566696602851, + "log_sha256": "ceeb567022f0746ceb350487a568b94cdfeacf3fb55cdc4088fecfab389caefa" + }, + { + "name": "export", + "seconds": 0.3756797920214012, + "log_sha256": "4be929eee47c06938fe228adcef2dff245a38d32c9bdcc44808376735c175f1b" + }, + { + "name": "global-program", + "seconds": 2.8925695409998298, + "log_sha256": "e0c19f3d4a91706a47e43f67bcbed72bdbb4e46534476bfad7c6e069dccabefb" + }, + { + "name": "independent-audit", + "seconds": 1.761562458006665, + "log_sha256": "1c95eb8403c1b9bd0c405247001c8fdfc03ea58c1f991cae2497ee7cb3221538" + }, + { + "name": "two-moments", + "seconds": 0.15180487500037998, + "log_sha256": "6d556f02612ff9a8df2239e44b949bc8bf81e03102b54ca762966a7dbd7a598e" + }, + { + "name": "finite-assembly", + "seconds": 0.17741812497843057, + "log_sha256": "cd2459472bd6f540e6610b019907b7fc36b1058cc69b1b608e6254e33a8de603" + } + ], + "parent_phase_mode": "full replay" +} diff --git a/research/e8-early-reset-reuse/local-evidence/FULL-PYTHON314-INITIAL.json b/research/e8-early-reset-reuse/local-evidence/FULL-PYTHON314-INITIAL.json new file mode 100644 index 0000000000..39fe0d80ac --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/FULL-PYTHON314-INITIAL.json @@ -0,0 +1,44 @@ +{ + "status": "PASS_FULL_PARENT_AND_EARLY_RESET_REUSE", + "kappa": "1128250848293019/1000000000000000000", + "kappa_decimal": "0.001128250848293019", + "source_manifest_sha256": "493f586b3c35dc0c2dacca23e58d81a8deff4f1187df2d2f6b18842ccb9568de", + "checks": [ + { + "name": "full-parent433", + "seconds": 103.98563337500673, + "log_sha256": "028a6067de8c3a61dfbf81c5d9c8d3629949b70cc118b64264f25df4b84a64ac" + }, + { + "name": "reconstruct", + "seconds": 0.050218041986227036, + "log_sha256": "ceeb567022f0746ceb350487a568b94cdfeacf3fb55cdc4088fecfab389caefa" + }, + { + "name": "export", + "seconds": 0.3637806250480935, + "log_sha256": "4be929eee47c06938fe228adcef2dff245a38d32c9bdcc44808376735c175f1b" + }, + { + "name": "global-program", + "seconds": 2.4805483330274, + "log_sha256": "20c0d8b5ce235496b9149639369284883c7ad245addabd6c364a115644b73913" + }, + { + "name": "independent-audit", + "seconds": 1.7047545410459861, + "log_sha256": "9e17c2b34dffc8eb7d63b6ed4d43bce0b872d6d9adfa0b1a64ec46379bbbda49" + }, + { + "name": "two-moments", + "seconds": 0.15184016700368375, + "log_sha256": "6d556f02612ff9a8df2239e44b949bc8bf81e03102b54ca762966a7dbd7a598e" + }, + { + "name": "finite-assembly", + "seconds": 0.15915608289651573, + "log_sha256": "cd2459472bd6f540e6610b019907b7fc36b1058cc69b1b608e6254e33a8de603" + } + ], + "parent_phase_mode": "full replay" +} diff --git a/research/e8-early-reset-reuse/local-evidence/PARENT-FULL-REPLAY.json b/research/e8-early-reset-reuse/local-evidence/PARENT-FULL-REPLAY.json new file mode 100644 index 0000000000..59ced26676 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/PARENT-FULL-REPLAY.json @@ -0,0 +1,120 @@ +{ + "status": "PASS_CONDITIONAL_SPLIT_CENTRE_ASSEMBLY", + "kappa": "560432476129139/500000000000000000", + "kappa_decimal": "0.001120864952258278", + "bit_lower": "561061350132569610283/500000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "gain_over_pr425_percent": 6.9522005058117555, + "bit_invoice": { + "prefix_bits": 223, + "charged_prefix_bits": 256, + "coefficient_bits": 223, + "two_level_coefficient_bits": 483, + "charged_two_level_coefficient_bits": 512, + "row_coefficient": 18355, + "live": 14502, + "physical": 14511 + }, + "strict_outer_constraints": { + "bit_positive": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_above_bit": "791857266447229204459483569705102945201339627252022591017013352985113602942786795000164759817249951996149235225861576966507630300630689893816878766552471016817/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_below_one_over32": "30066013450793671/1000000000000000000", + "beta_positive": "1/1000000000000000000", + "beta_below_one": "999999999999999999/1000000000000000000", + "leaf_saving_above_bit": "791857266447229189304455739864091745201339627252022591017013352985113602942786795000164759817249951996149235225861576966507630300630689893816878766552471016817/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_positive": "7181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_internal": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_leaf": "395928633223614609015398433325827868141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_positive": "7181585281696892583407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_below_one": "6392818414718303107416592912348246333468141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_reservations": "1/4000000000000000000", + "lambda_above_tau": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_sigma": "791857266447229218822654133098884940741856057546919645815673725733091011925773442015051156874463156995984475408611624970358395074769112927309248465921781123000121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_internal": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_prime_above_lambda": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_leaf": "395928633223614609015398433325827868141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_reservations": "1/4000000000000000000", + "lambda_prime_below_one": "7181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "epsilon_positive": "6399999999999999993600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "epsilon_below_one": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "guard_width": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "K_geometry": "4807181585281696892583407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817000000000000000000", + "K_dominates_log": "231664041345061050845983947421186256401668584010497584446258683699366907737186677571792433338340060113453513521617978855187267028104098984087218414251878140832554446748323117142213588175726741393/206683276944570867451077647988766247307479316572776744891925575256476111799662761934047904233001101994161357746522719973016545013550824072000632231965075950141464786411824273258607000000000000000000", + "record_suffix": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "phase_local": "57452682253575172660075115932332441271463422396879066665683849849996634666672126693120783994727674596531689914600391489101073218400050692643898107263289403063667839215065313749127621233447528983183/51257452682253575127867256701214029332254870510048632733197542663606075726316364959643880249784273294552016721137634553308103163360604369856156793527338835635083267030132419768134536000000000000000000", + "phase_boundary": "11490536450715029406269754961108975467567014357972880107649718965136053613580158978016584167309038954918313004492748842618542529916554807718463285392220894997054215109129499241498821233447528983183/10251490536450715025573451340242805866450974102009726546639508532721215145263272991928776049956854658910403344227526910661620632672120873971231358705467767127016653406026483953626907200000000000000000", + "gamma_sublinear": "1/2000000000000000000", + "cell_above_band": "12799999999999999980792818414718303109016592912348246333468141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/25628726341126787563933628350607014666127435255024316366598771331803037863158182479821940124892136647276008360568817276654051581680302184928078396763669417817541633515066209884067268000000000000000000", + "prime_interval_packing": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "alpha_positive": "14363170563393788359632590021810442080310539860404516767526852145439839929398406960210596656522703682519149061374476508023700697946773300526302961759162676751217566615750487648225621233447528983183/12814363170563393781966814175303507333063717627512158183299385665901518931579091239910970062446068323638004180284408638327025790840151092464039198381834708908770816757533104942033634000000000000000000", + "alpha_below_one": "12799999999999999993607181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/12814363170563393781966814175303507333063717627512158183299385665901518931579091239910970062446068323638004180284408638327025790840151092464039198381834708908770816757533104942033634000000000000000000", + "alpha_below_one_fourth": "3189227622077454657132070953804066391185618867017635029057319564329939892965374403017531918954994377226981896009727683073732747012090999815483496633699514550441486622767525747860182878766552471016817/12814363170563393781966814175303507333063717627512158183299385665901518931579091239910970062446068323638004180284408638327025790840151092464039198381834708908770816757533104942033634000000000000000000", + "delta_positive": "1/8000000000000000000", + "delta_below_one_eighth": "999999999999999999/8000000000000000000", + "short_record_fallback": "81827972558059963142482295831039750365059753405165839859500887157900070163784215146039541956047009515286378723945407637791323146319740145866082020356197908534083134290654194352838948148633280800174595114507063924980758679362172726895650066012032777455278212210736064133662717611940569491044304210260992667579958374711353997952140066809896811489/82011924291605720204587610721942446931607792816077812373116068261769721162106183935430208399654837271283226753820215285292965061376966991769850869643742137016133227248211871629015257600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "small_field_exposure": "1/1000000000000000000", + "artificial_boundary": "358859621458028601093359598365557325330989185343344322865175917750116843085479998176003320395642823216282588862770178911921831577311447916339793034478937323776724933813811421508232513136299657413050451/51257452682253575127867256701214029332254870510048632733197542663606075726316364959643880249784273294552016721137634553308103163360604369856156793527338835635083267030132419768134536000000000000000000", + "literal_scalar_guard": "1", + "row_product_gap": "23971789/25", + "balanced_prefix_above_kappa": "5122866517862023505724960619093421545844111701898553134698525509504383311993872387184513125657251444712150871805627114225726283245038727038504547469670408073428467093191496467269437/3203590792640848445491703543825876833265929406878039545824846416475379732894772809977742515611517080909501045071102159581756447710037773116009799595458677227192704189383276235508408500000000000000000", + "coordinate_movement_above_kappa": "16099174487823595540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_phase_layer_above_kappa": "3838551450442350120466514150535089425156364590041027177747358186058007158198199154413541220091468727605299653469049909287939671070001907844989495748423461692471525807616440463522057/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817000000000000000000", + "bulk_exposure_above_kappa": "16099174487823595540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gaussian_arithmetic_above_kappa": "49929956359383891636682334467235976400846493161596454696927943987316335662954230095174784854400852306299403498179012231794056054820241901455974763560139756902928431597231181121226907/51257452682253575127867256701214029332254870510048632733197542663606075726316364959643880249784273294552016721137634553308103163360604369856156793527338835635083267030132419768134536000000000000000000", + "scalar_work_above_kappa": "3022347308020427168024638512713719642678957136664830842541068612764774941044496502999868999171719558143016474349913180337924305460021763455362126412952366988818802604491895640211767/2050298107290143005114690268048561173290194820401945309327901706544243029052654598385755209991370931782080668845505382132324126534424174794246271741093553425403330681205296790725381440000000000000000", + "dimension_above_kappa": "3196409207359151553231162974036146672459031212215382000019265285423173401803752699526640796382355306275012080586149285130394424095589341109716483649580049811311843280287131837920058593191496467269437/3203590792640848445491703543825876833265929406878039545824846416475379732894772809977742515611517080909501045071102159581756447710037773116009799595458677227192704189383276235508408500000000000000000" + }, + "outer_controls": [ + "next_grid", + "zero_eta", + "zero_beta", + "unit_beta" + ], + "bootstrap": [ + { + "gap": "48640105104416009930955104551272628756769/40000000000000000000000000000000000000000000000", + "cutoff_log2": "24346328299693" + }, + { + "gap": "10916033216189494908506938862091413300675156484737667525550897/8000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "19335382939135799529" + }, + { + "gap": "2449825733746901655394438404809502019511708753179325050819248403056515410563319361/1600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "15355787073969246541017124" + }, + { + "gap": "549801013506219857550281901936704203615404924098069138182437287931091972275689180385852832590942771793/320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "12195269025875323655994833423982" + }, + { + "gap": "123388839576821941106964776874551364767558290306753584545234931806617408234472738882773008179061080923160999418343337504609/64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "9685246734476302780854842486398253310" + }, + { + "gap": "27691483569705102945201339627252022591017013352985113602942786795000164759817249951996149235225861576966507630300630689893816878766552471016817/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "7691835588756193183914168151850588989363719" + } + ], + "bit_template_sha256": "c40f89a2ae3c2c5635ddf8f18d74f24567ddf67fc8c8e93a1fc7a1a8098e857e", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f", + "scope": "Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim.", + "verification_steps": [ + "hamming_packets", + "complex_construct", + "complex_audit", + "complex_emit", + "complex_phases", + "bit_construct", + "bit_export", + "bit_global", + "bit_audit", + "bit_price", + "complex_integrate", + "complex_replay", + "combined" + ], + "phase_mode": "full replay", + "manifest_sha256": "c903e548e42d04a243a034d320b15e6cb26b878c30f935181336ea6ea679a004" +} diff --git a/research/e8-early-reset-reuse/local-evidence/PYTHON311-GZIP-FAILURE.log b/research/e8-early-reset-reuse/local-evidence/PYTHON311-GZIP-FAILURE.log new file mode 100644 index 0000000000..20a1987364 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/PYTHON311-GZIP-FAILURE.log @@ -0,0 +1,5 @@ +Traceback (most recent call last): + File "/Volumes/SP AI 01_16/CodexWorkspaces/imb-retime2/frontier390/source433-review/research/split-centres-global/code/complex_phases.py", line 9, in + assert sha(O/'CANONICAL-WORD.json.gz')==r['canonical_word_sha256'] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +AssertionError diff --git a/research/e8-early-reset-reuse/local-evidence/PYTHON311-INITIAL-FAILURE.json b/research/e8-early-reset-reuse/local-evidence/PYTHON311-INITIAL-FAILURE.json new file mode 100644 index 0000000000..d82c79a260 --- /dev/null +++ b/research/e8-early-reset-reuse/local-evidence/PYTHON311-INITIAL-FAILURE.json @@ -0,0 +1,4 @@ +{ + "error": "RuntimeError(('full-parent433', 1, 'PASS hamming_packets\\nPASS complex_construct\\nPASS complex_audit\\nPASS complex_emit\\nTraceback (most recent call last):\\n File \"/Volumes/SP AI 01_16/CodexWorkspaces/imb-retime2/frontier390/early-reuse-publication/research/split-centres-global/verify.py\", line 39, in \\n for name in (\\'complex_construct\\',\\'complex_audit\\',\\'complex_emit\\',\\'complex_phases\\',\\'bit_construct\\'):run(name,\\'code/\\'+name+\\'.py\\')\\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n File \"/Volumes/SP AI 01_16/CodexWorkspaces/imb-retime2/frontier390/early-reuse-publication/research/split-centres-global/verify.py\", line 36, in run\\n assert r.returncode==0,(name,str(out/(name+\\'.log\\')))\\n ^^^^^^^^^^^^^^^\\nAssertionError: (\\'complex_phases\\', \\'/Volumes/SP AI 01_16/CodexWorkspaces/imb-retime2/frontier390/early-reuse-full311/baseline/complex_phases.log\\')\\n'))", + "completed": [] +} diff --git a/research/e8-early-reset-reuse/replay.py b/research/e8-early-reset-reuse/replay.py new file mode 100644 index 0000000000..84d4875764 --- /dev/null +++ b/research/e8-early-reset-reuse/replay.py @@ -0,0 +1,71 @@ +"""Reconstruct eleven chronological clean resets; regenerate arbitrary-dirt compensation. +Rohan Arun with OpenAI Codex assistance, using icekylinx's PR433 and ai-nanachi's PR426. +""" +import copy,hashlib,json,sys +from pathlib import Path +from collections import defaultdict +ROOT=Path(__file__).resolve().parent + +def reconstruct(raw,selection): + assert hashlib.sha256(raw).hexdigest()==selection['source_sha256'] + w=json.loads(raw);v=w['v'];n=2*v+w['R'];entries=selection['entries'];cut=len(w['A'])-w['source_basis_gates'];assert all(d>=2*v for f,d,ss in w['A'][:cut]) + removed={z['new_helper'] for z in entries};retired={z['retired_helper'] for z in entries} + assert len(removed)==len(retired)==len(entries) and not removed&retired + assert all(2*v<=x>i&1] + if ss:D.append([0,v+t,ss]) + c['D']=D;raw=json.dumps(c,sort_keys=True,separators=(',',':')).encode();assert hashlib.sha256(raw).hexdigest()==selection['word_sha256'];return raw + +def controls(raw,sel): + rejected=[] + cases=[] + for label in ('missing reset parent','wrong insertion time','duplicate physical reuse'): + s=copy.deepcopy(sel) + if label=='missing reset parent':s['entries'][0]['parents'].pop() + elif label=='wrong insertion time':s['entries'][0]['position']=0 + else:s['entries'][1]['new_helper']=s['entries'][0]['new_helper'] + cases.append((label,s)) + for label,s in cases: + try:reconstruct(raw,s) + except AssertionError:rejected.append(label) + else:raise AssertionError(label) + return rejected +if __name__=='__main__': + raw=Path(sys.argv[1]).read_bytes();s=json.loads((ROOT/'SELECTION.json').read_text());out=Path(sys.argv[2]);data=reconstruct(raw,s);out.write_bytes(data);print(json.dumps(dict(status='PASS_EXACT_CHRONOLOGICAL_RECONSTRUCTION',helpers_removed=len(s['entries']),R=s['R'],sha256=hashlib.sha256(data).hexdigest(),controls=controls(raw,s)))) diff --git a/research/e8-early-reset-reuse/verify.py b/research/e8-early-reset-reuse/verify.py new file mode 100644 index 0000000000..6fae5fc80e --- /dev/null +++ b/research/e8-early-reset-reuse/verify.py @@ -0,0 +1,31 @@ +"""Fresh parent replay, chronological reset reconstruction, banks and exact assembly.""" +from pathlib import Path +import hashlib,json,os,subprocess,sys,time +assert __debug__ +ROOT=Path(__file__).resolve().parent;PARENT=ROOT.parent/'split-centres-global';out=Path(sys.argv[1]).resolve();assert not out.exists() and not out.is_relative_to(ROOT.parent) +read=lambda p:json.loads(p.read_text());sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest() +def integrity(): + assert {p.relative_to(ROOT).as_posix():sha(p) for p in ROOT.rglob('*') if p.is_file() and p.name!='MANIFEST.json'}==read(ROOT/'MANIFEST.json')['files'] + assert sha(PARENT/'MANIFEST.json')==read(ROOT/'SOURCE.json')['parent_manifest_sha256'] +integrity();out.mkdir(parents=True);env=dict(os.environ,PYTHONDONTWRITEBYTECODE='1',PYTHONINTMAXSTRDIGITS='0');env.pop('PYTHONOPTIMIZE',None);steps=[] +def run(name,file,*args,cwd=None): + t=time.monotonic();log=out/(name+'.log');print('RUN',name,flush=True) + with log.open('w') as f:q=subprocess.run([sys.executable,'-B',str(file),*map(str,args)],cwd=cwd,env=env,stdout=f,stderr=subprocess.STDOUT) + if q.returncode:raise RuntimeError((name,q.returncode,log.read_text()[-2000:])) + steps.append(dict(name=name,seconds=time.monotonic()-t,log_sha256=sha(log)));print('PASS',name,flush=True) +try: + base=out/'baseline';run('full-parent433',PARENT/'verify.py',base,'--replay-phases') + changed=out/'changed';changed.mkdir() + for name in ('work','inherited','split-centres'):(changed/name).symlink_to(base/name,target_is_directory=True) + bit=changed/'bit426-source-centres';bit.mkdir() + run('reconstruct',ROOT/'replay.py',base/'bit426-source-centres/bit-source-centres.json',bit/'bit-source-centres.json') + run('export',PARENT/'vendor/export_records.py',bit/'bit-source-centres.json',bit/'records') + run('global-program',ROOT/'bit_global.py','--source',bit,'--local-check',bit,'--out',bit/'global',cwd=changed) + run('independent-audit',ROOT/'bit_audit.py','--local-check',bit,'--out',bit/'global',cwd=changed) + run('two-moments',ROOT/'bit_price.py',cwd=changed) + env['E8_OUTPUT']=str(changed);run('finite-assembly',ROOT/'combined.py',cwd=changed) + actual=read(changed/'RESULT.json');expected=read(ROOT/'EXPECTED.json') + for k,v in expected.items():assert actual[k]==v,(k,actual[k],v) + integrity();result=dict(status='PASS_FULL_PARENT_AND_EARLY_RESET_REUSE',kappa=actual['kappa'],kappa_decimal=actual['kappa_decimal'],source_manifest_sha256=sha(ROOT/'MANIFEST.json'),checks=steps,parent_phase_mode=read(base/'RESULT.json')['phase_mode']);(out/'RESULT.json').write_text(json.dumps(result,indent=2)+'\n') +except BaseException as e: + (out/'FAILURE.json').write_text(json.dumps(dict(error=repr(e),completed=steps),indent=2)+'\n');raise diff --git a/research/e8-lemma-a-lean/.gitignore b/research/e8-lemma-a-lean/.gitignore new file mode 100644 index 0000000000..2b00952692 --- /dev/null +++ b/research/e8-lemma-a-lean/.gitignore @@ -0,0 +1 @@ +.lake diff --git a/research/e8-lemma-a-lean/LICENSE b/research/e8-lemma-a-lean/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/e8-lemma-a-lean/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/e8-lemma-a-lean/LemmaA.lean b/research/e8-lemma-a-lean/LemmaA.lean new file mode 100644 index 0000000000..2cc601bdb5 --- /dev/null +++ b/research/e8-lemma-a-lean/LemmaA.lean @@ -0,0 +1,4 @@ +import LemmaA.Realize +import LemmaA.Schedule +import LemmaA.Tensor +import LemmaA.Streams diff --git a/research/e8-lemma-a-lean/LemmaA/Realize.lean b/research/e8-lemma-a-lean/LemmaA/Realize.lean new file mode 100644 index 0000000000..8917c5b7f7 --- /dev/null +++ b/research/e8-lemma-a-lean/LemmaA/Realize.lean @@ -0,0 +1,163 @@ +/- +Lemma A, realization: a local invocation executed on physical families through charts. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. + +Each register `i` of an invocation is hosted on the physical family `own i` through a linear +chart `chart i : W ≃ₗ[K] M` (route and batch). Executing an event physically reads the +operands through their charts and writes the destination's family back. + +* `realize_run` one owner (injective `own`) ⇒ the physical run, read through the charts, + is the local run; families that host no register are untouched. +* `one_owner_needed` two registers on one family: already a one-event stream breaks it. +* `family_endpoint` with Lemma G's unit row, the helper's family ends as + `chart⁻¹ ∘ T_{λ¹} T_{λ⁰}⁻¹ ∘ chart` of its own initial value. +* `endpoint_indep` with a zero column, no other family reads the helper's family. +-/ +import LemmaG.Stream + +namespace LemmaA + +open LemmaG LemmaG.Stream + +variable {ι Φ Λ K : Type*} [DecidableEq ι] [DecidableEq Φ] [Semiring K] +variable {W M : Type*} [AddCommMonoid W] [Module K W] [AddCommMonoid M] [Module K M] + +/-- The register an event writes. -/ +def dst : Event ι Λ K → ι + | .relabel r _ _ => r + | .add t _ _ => t + | .scale t _ => t + | .copy c _ _ => c + | .clear c _ => c + +omit [DecidableEq Φ] in +theorem phys_ne (rec : Λ → Λ → M → M) (e : Event ι Λ K) (h : ι → M) (i : ι) (hi : i ≠ dst e) : + e.phys rec h i = h i := by + cases e <;> simp [Event.phys, dst, Function.update_of_ne hi] at hi ⊢ <;> + exact Function.update_of_ne hi _ _ + +/-- A hosting: owner family and chart of every register of one invocation. -/ +structure Hosting (ι Φ K W M : Type*) [Semiring K] [AddCommMonoid W] [Module K W] + [AddCommMonoid M] [Module K M] where + own : ι → Φ + chart : ι → W ≃ₗ[K] M + +/-- The registers as seen through their charts. -/ +def view (σ : Hosting ι Φ K W M) (y : Φ → W) : ι → M := fun i => σ.chart i (y (σ.own i)) + +/-- One event executed on the physical families. -/ +def realize (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) (e : Event ι Λ K) (y : Φ → W) : Φ → W := + Function.update y (σ.own (dst e)) ((σ.chart (dst e)).symm (e.phys rec (view σ y) (dst e))) + +/-- A stream executed on the physical families. -/ +def realizeRun (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) : + List (Event ι Λ K) → (Φ → W) → (Φ → W) + | [], y => y + | e :: es, y => realizeRun σ rec es (realize σ rec e y) + +theorem view_realize (σ : Hosting ι Φ K W M) (hinj : Function.Injective σ.own) + (rec : Λ → Λ → M → M) (e : Event ι Λ K) (y : Φ → W) : + view σ (realize σ rec e y) = e.phys rec (view σ y) := by + funext i + by_cases hi : i = dst e + · subst hi; simp [view, realize] + · have hf : σ.own i ≠ σ.own (dst e) := hinj.ne hi + simp only [view, realize, Function.update_of_ne hf] + rw [phys_ne rec e _ i hi]; rfl + +/-- **Realization under the one-owner rule.** The physical run, read through the charts, is the +local run of the same stream. -/ +theorem realize_run (σ : Hosting ι Φ K W M) (hinj : Function.Injective σ.own) + (rec : Λ → Λ → M → M) : + ∀ (es : List (Event ι Λ K)) (y : Φ → W), + view σ (realizeRun σ rec es y) = physRun rec es (view σ y) + | [], _ => rfl + | e :: es, y => by + simp only [realizeRun, physRun] + rw [realize_run σ hinj rec es, view_realize σ hinj] + +omit [DecidableEq ι] [DecidableEq Φ] in +/-- The value of a family that hosts register `i` is the chart preimage of the view. -/ +theorem family_eq (σ : Hosting ι Φ K W M) (y : Φ → W) (i : ι) : + y (σ.own i) = (σ.chart i).symm (view σ y i) := by simp [view] + +/-- Families that host no register of the invocation are untouched. -/ +theorem realize_untouched (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) : + ∀ (es : List (Event ι Λ K)) (y : Φ → W) (f : Φ), (∀ i, σ.own i ≠ f) → + realizeRun σ rec es y f = y f + | [], _, _, _ => rfl + | e :: es, y, f, hf => by + simp only [realizeRun] + rw [realize_untouched σ rec es _ f hf, realize, Function.update_of_ne (Ne.symm (hf _))] + +/-- **The one-owner rule is needed.** If two registers share a family, the one-event stream +`scale i 0` already changes what register `j` sees, although the local run leaves `j` alone. -/ +theorem one_owner_needed (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) (i j : ι) (hij : i ≠ j) + (hown : σ.own i = σ.own j) (y : Φ → W) (hy : view σ y j ≠ 0) : + view σ (realizeRun σ rec [Event.scale i (0 : K)] y) j ≠ + physRun rec [Event.scale i (0 : K)] (view σ y) j := by + have h1 : view σ (realizeRun σ rec [Event.scale i (0 : K)] y) j = 0 := by + simp only [realizeRun, realize, view, dst] + rw [hown, Function.update_self] + simp [Event.phys] + have h2 : physRun rec [Event.scale i (0 : K)] (view σ y) j = view σ y j := by + simp [physRun, Event.phys, Function.update_of_ne (Ne.symm hij)] + rw [h1, h2] + exact fun h => hy h.symm + +section Endpoint + +variable [Fintype ι] + +/-- **The helper's family at the end of a complete invocation.** One owner, exact recipes, +well labelled, and a unit row of the scalar shadow (Lemma G, H3): the family ends as the chart +conjugate of `T_{λ¹ j} T_{λ⁰ j}⁻¹` applied to its own initial value. -/ +theorem family_endpoint (T : Λ → M ≃ₗ[K] M) (σ : Hosting ι Φ K W M) + (hinj : Function.Injective σ.own) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (y : Φ → W) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (j : ι) + (hS : ∀ s, S es j s = if s = j then 1 else 0) : + realizeRun σ rec es y (σ.own j) = + (σ.chart j).symm (T (labRun es l j) ((T (l j)).symm (σ.chart j (y (σ.own j))))) := by + rw [family_eq σ (realizeRun σ rec es y) j, realize_run σ hinj rec es y, + row_unit T rec es l (view σ y) hrec hw j hS] + rfl + +/-- A zero column: changing input `j` does not change output `r ≠ j`. -/ +theorem physRun_indep (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (h : ι → M) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (j r : ι) + (hcol : S es r j = 0) (v : M) : + physRun rec es (Function.update h j v) r = physRun rec es h r := by + rw [conj_matrix T rec es l _ hrec hw r, conj_matrix T rec es l h hrec hw r] + congr 1 + refine Finset.sum_congr rfl (fun s _ => ?_) + by_cases hs : s = j + · subst hs; simp [hcol] + · rw [Function.update_of_ne hs] + +/-- **No other family reads the helper's family.** If column `j` of the scalar shadow vanishes +off the diagonal (Lemma G, H3), every other family's end value is independent of the helper +family's initial value. -/ +theorem endpoint_indep (T : Λ → M ≃ₗ[K] M) (σ : Hosting ι Φ K W M) + (hinj : Function.Injective σ.own) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (y : Φ → W) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (j : ι) + (hcol : ∀ r, r ≠ j → S es r j = 0) (w : W) (f : Φ) (hf : f ≠ σ.own j) : + realizeRun σ rec es (Function.update y (σ.own j) w) f = realizeRun σ rec es y f := by + by_cases hfo : ∃ r, σ.own r = f + · obtain ⟨r, rfl⟩ := hfo + have hrj : r ≠ j := fun h => hf (h ▸ rfl) + rw [family_eq σ (realizeRun σ rec es (Function.update y (σ.own j) w)) r, + family_eq σ (realizeRun σ rec es y) r, realize_run σ hinj, realize_run σ hinj] + have hv : view σ (Function.update y (σ.own j) w) = + Function.update (view σ y) j (σ.chart j w) := by + funext i + by_cases hi : i = j + · subst hi; simp [view] + · simp [view, Function.update_of_ne hi, Function.update_of_ne (hinj.ne hi)] + rw [hv, physRun_indep T rec es l _ hrec hw j r (hcol r hrj)] + · push_neg at hfo + rw [realize_untouched σ rec es _ f hfo, realize_untouched σ rec es _ f hfo, + Function.update_of_ne hf] + +end Endpoint + +end LemmaA diff --git a/research/e8-lemma-a-lean/LemmaA/Schedule.lean b/research/e8-lemma-a-lean/LemmaA/Schedule.lean new file mode 100644 index 0000000000..0bdd775a0f --- /dev/null +++ b/research/e8-lemma-a-lean/LemmaA/Schedule.lean @@ -0,0 +1,218 @@ +/- +Lemma A, scheduling: whole invocations, no other actor, and borrowed pending blocks. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. + +A global state is `y : Φ → W` (one value per physical family). An action is a map on global +states; `Supported A S` says that `A` changes only families in `S` and reads only families in +`S`. Words of actions are applied left to right (`evalW`). + +* `commute_of_disjoint` actions with disjoint supports commute. +* `shuffle_eval` an interleaving of two pairwise commuting words is their concatenation. +* `whole_invocation` the realized events of an invocation, interleaved with actions that + touch none of its families, act as the complete invocation followed by + those actions ("no other actor"). +* `split_off` an endpoint that acts on family `f` alone, and that no other family + reads, splits into a piece supported on `{f}` and a rest that does not + touch `f`. +* `defer`, `async_window` a piece on `f` moves past every action that commutes with it, in + particular every action not touching `f`; the pieces of one pending + child, gathered before its deadline, give the child (#505). +-/ +import LemmaA.Realize +import Mathlib.Data.Set.Disjoint + +namespace LemmaA + +variable {Φ W : Type*} + +/-- `A` changes only families in `S`, and its values on `S` depend only on the input on `S`. -/ +def Supported (A : (Φ → W) → (Φ → W)) (S : Set Φ) : Prop := + (∀ y f, f ∉ S → A y f = y f) ∧ (∀ y y', (∀ f ∈ S, y f = y' f) → ∀ f ∈ S, A y f = A y' f) + +theorem Supported.mono {A : (Φ → W) → (Φ → W)} {S T : Set Φ} (h : Supported A S) (hST : S ⊆ T) : + Supported A T := by + refine ⟨fun y f hf => h.1 y f (fun hs => hf (hST hs)), fun y y' hyy f hf => ?_⟩ + by_cases hfS : f ∈ S + · exact h.2 y y' (fun g hg => hyy g (hST hg)) f hfS + · rw [h.1 y f hfS, h.1 y' f hfS]; exact hyy f hf + +/-- **Disjoint supports commute.** -/ +theorem commute_of_disjoint {A B : (Φ → W) → (Φ → W)} {S T : Set Φ} (hA : Supported A S) + (hB : Supported B T) (h : Disjoint S T) : A ∘ B = B ∘ A := by + funext y f + simp only [Function.comp] + by_cases hfS : f ∈ S + · have hfT : f ∉ T := Set.disjoint_left.1 h hfS + rw [hB.1 (A y) f hfT] + exact hA.2 (B y) y (fun g hg => hB.1 y g (Set.disjoint_left.1 h hg)) f hfS + · rw [hA.1 (B y) f hfS] + by_cases hfT : f ∈ T + · exact hB.2 y (A y) (fun g hg => (hA.1 y g (Set.disjoint_right.1 h hg)).symm) f hfT + · rw [hB.1 y f hfT, hB.1 (A y) f hfT, hA.1 y f hfS] + +/-- Apply a word of actions, first element first. -/ +def evalW : List ((Φ → W) → (Φ → W)) → (Φ → W) → (Φ → W) + | [] => id + | a :: as => evalW as ∘ a + +theorem evalW_append : ∀ (as bs : List ((Φ → W) → (Φ → W))), + evalW (as ++ bs) = evalW bs ∘ evalW as + | [], _ => rfl + | a :: as, bs => by simp only [List.cons_append, evalW, evalW_append as bs]; rfl + +/-- An action that commutes with every element of a word commutes with the word. -/ +theorem evalW_comm (U : (Φ → W) → (Φ → W)) : ∀ (as : List ((Φ → W) → (Φ → W))), + (∀ a ∈ as, a ∘ U = U ∘ a) → evalW as ∘ U = U ∘ evalW as + | [], _ => rfl + | a :: as, h => by + simp only [evalW] + rw [Function.comp_assoc, h a List.mem_cons_self, ← Function.comp_assoc, + evalW_comm U as (fun b hb => h b (List.mem_cons_of_mem _ hb)), Function.comp_assoc] + +/-- **Deferral.** A piece moves to the right past every action that commutes with it. -/ +theorem defer (U : (Φ → W) → (Φ → W)) (xs ys zs : List ((Φ → W) → (Φ → W))) + (h : ∀ a ∈ ys, a ∘ U = U ∘ a) : + evalW (xs ++ U :: ys ++ zs) = evalW (xs ++ ys ++ U :: zs) := by + simp only [evalW_append, List.append_assoc, List.cons_append, evalW] + funext y + exact congrArg (evalW zs) (congrFun (evalW_comm U ys h) (evalW xs y)) + +/-- `us` interleaves `as` and `bs`, keeping the order within each. -/ +inductive Interleave {α : Type*} : List α → List α → List α → Prop + | nil : Interleave [] [] [] + | left {a as bs us} : Interleave as bs us → Interleave (a :: as) bs (a :: us) + | right {b as bs us} : Interleave as bs us → Interleave as (b :: bs) (b :: us) + +/-- **Shuffles of commuting words.** If every action of `as` commutes with every action of +`bs`, any interleaving evaluates to `as` followed by `bs`. -/ +theorem shuffle_eval {as bs us : List ((Φ → W) → (Φ → W))} + (hc : ∀ a ∈ as, ∀ b ∈ bs, a ∘ b = b ∘ a) (h : Interleave as bs us) : + evalW us = evalW (as ++ bs) := by + induction h with + | nil => rfl + | @left a as bs us _ ih => + simp only [evalW, List.cons_append] + rw [ih (fun x hx y hy => hc x (List.mem_cons_of_mem _ hx) y hy)] + | @right b as bs us _ ih => + have ih' := ih (fun x hx y hy => hc x hx y (List.mem_cons_of_mem _ hy)) + have hb := evalW_comm b as (fun x hx => hc x hx b List.mem_cons_self) + funext y + show evalW us (b y) = evalW (as ++ b :: bs) y + rw [ih', evalW_append, evalW_append] + show evalW bs (evalW as (b y)) = evalW bs (b (evalW as y)) + exact congrArg (evalW bs) (congrFun hb y) + +/-! ### Whole invocation, no other actor -/ + +section Whole + +open LemmaG + +variable {ι Λ K M : Type*} [DecidableEq ι] [DecidableEq Φ] [Semiring K] +variable [AddCommMonoid W] [Module K W] [AddCommMonoid M] [Module K M] + +/-- A realized event touches only families that host registers of the invocation. -/ +theorem realize_supported (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) (e : Event ι Λ K) : + Supported (realize σ rec e) (Set.range σ.own) := by + refine ⟨fun y f hf => ?_, fun y y' hyy f _ => ?_⟩ + · exact Function.update_of_ne (fun h => hf ⟨_, h.symm⟩) _ _ + · have hv : view σ y = view σ y' := funext fun i => by simp [view, hyy (σ.own i) ⟨i, rfl⟩] + by_cases hf : f = σ.own (dst e) + · subst hf; simp [realize, hv] + · simp [realize, Function.update_of_ne hf, hyy f ‹_›] + +theorem realizeRun_eq_evalW (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) : + ∀ es : List (Event ι Λ K), realizeRun σ rec es = evalW (es.map (realize σ rec)) + | [] => rfl + | e :: es => by + funext y + simp only [realizeRun, List.map_cons, evalW, Function.comp, realizeRun_eq_evalW σ rec es] + +/-- **Whole invocation, no other actor.** Interleave the realized events of an invocation with +foreign actions, each supported on a set that contains no family of the invocation. The result +is the complete invocation followed by the foreign actions; with one owner, the invocation part +is the local run read through the charts (`realize_run`). -/ +theorem whole_invocation (σ : Hosting ι Φ K W M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (foreign us : List ((Φ → W) → (Φ → W))) + (hfor : ∀ b ∈ foreign, ∃ T : Set Φ, Supported b T ∧ Disjoint (Set.range σ.own) T) + (hint : Interleave (es.map (realize σ rec)) foreign us) : + evalW us = evalW foreign ∘ realizeRun σ rec es := by + rw [shuffle_eval _ hint, evalW_append, realizeRun_eq_evalW] + intro a ha b hb + obtain ⟨e, -, rfl⟩ := List.mem_map.1 ha + obtain ⟨T, hbT, hdis⟩ := hfor b hb + exact commute_of_disjoint (realize_supported σ rec e) hbT hdis + +end Whole + +/-! ### Borrowed pending blocks (#505) -/ + +section Async + +variable [DecidableEq Φ] + +/-- **Split off a single-family piece.** If an endpoint `E` acts on family `f` as the piece `P` +(supported on `{f}`) and no other family's value depends on `f`, then `E` is "the rest, then +`P`", where the rest leaves `f` alone and does not read it. -/ +theorem split_off (E P : (Φ → W) → (Φ → W)) (f : Φ) (hP : Supported P {f}) + (hEf : ∀ y, E y f = P y f) + (hread : ∀ y w g, g ≠ f → E (Function.update y f w) g = E y g) : + E = P ∘ (fun y => Function.update (E y) f (y f)) ∧ + Supported (fun y => Function.update (E y) f (y f)) {f}ᶜ := by + refine ⟨?_, ?_, ?_⟩ + · funext y g + simp only [Function.comp] + by_cases hg : g = f + · subst hg + rw [hEf] + exact hP.2 y _ (fun h hh => by rw [Set.mem_singleton_iff.1 hh]; simp) g rfl + · rw [hP.1 _ g (by simpa using hg), Function.update_of_ne hg] + · intro y g hg + simp only [Set.mem_compl_iff, Set.mem_singleton_iff, not_not] at hg + subst hg; simp + · intro y y' hyy g hg + simp only [Set.mem_compl_iff, Set.mem_singleton_iff] at hg + have hy' : y' = Function.update y f (y' f) := by + funext h + by_cases hh : h = f + · subst hh; simp + · rw [Function.update_of_ne hh]; exact (hyy h hh).symm + show Function.update (E y) f (y f) g = Function.update (E y') f (y' f) g + rw [Function.update_of_ne hg, Function.update_of_ne hg, hy', hread y (y' f) g hg] + +omit [DecidableEq Φ] in +/-- A piece on `{f}` commutes with every action that does not touch `f`. -/ +theorem commute_of_not_mem {P A : (Φ → W) → (Φ → W)} {f : Φ} {S : Set Φ} + (hP : Supported P {f}) (hA : Supported A S) (hf : f ∉ S) : A ∘ P = P ∘ A := + (commute_of_disjoint hP hA (Set.disjoint_singleton_left.2 hf)).symm + +/-- **Borrowed pending block, asynchronous window (#505).** An invocation endpoint `E` acts on +the owner family `f` as the piece `P` and nothing else reads `f`. If every action between the +invocation and the pending child's deadline commutes with `P` (it does not touch `f`, or it is +another piece of the same child on a disjoint block), the schedule equals the one in which the +rest of the invocation runs in place and `P` runs just before the deadline. -/ +theorem async_window (E P : (Φ → W) → (Φ → W)) (f : Φ) (hP : Supported P {f}) + (hEf : ∀ y, E y f = P y f) + (hread : ∀ y w g, g ≠ f → E (Function.update y f w) g = E y g) + (xs ys zs : List ((Φ → W) → (Φ → W))) (hys : ∀ a ∈ ys, a ∘ P = P ∘ a) : + evalW (xs ++ E :: ys ++ zs) = + evalW (xs ++ (fun y => Function.update (E y) f (y f)) :: ys ++ P :: zs) := by + obtain ⟨hsplit, -⟩ := split_off E P f hP hEf hread + have h1 : evalW (xs ++ E :: ys ++ zs) = + evalW ((xs ++ [fun y => Function.update (E y) f (y f)]) ++ P :: ys ++ zs) := by + simp only [evalW_append, List.append_assoc, List.cons_append, List.singleton_append, evalW] + conv_lhs => rw [hsplit] + rfl + rw [h1, defer P _ ys zs hys] + simp + +omit [DecidableEq Φ] in +/-- **Gathering.** Pieces whose product is the pending child can be replaced by the child. -/ +theorem gather (ps : List ((Φ → W) → (Φ → W))) (C : (Φ → W) → (Φ → W)) (h : evalW ps = C) + (xs zs : List ((Φ → W) → (Φ → W))) : evalW (xs ++ ps ++ zs) = evalW (xs ++ C :: zs) := by + simp only [evalW_append, List.cons_append, evalW, h] + rfl + +end Async + +end LemmaA diff --git a/research/e8-lemma-a-lean/LemmaA/Streams.lean b/research/e8-lemma-a-lean/LemmaA/Streams.lean new file mode 100644 index 0000000000..d3ad32fc95 --- /dev/null +++ b/research/e8-lemma-a-lean/LemmaA/Streams.lean @@ -0,0 +1,76 @@ +/- +Lemma A, stream units: owners are physical streams (family, cover class), as in the cover model +of #442/#458. An invocation at cover class `d` realizes register `r` on the stream +`(fam r, d · σ_r⁻¹)`, where `σ_r` is its route (slot permutation, host chart). Several registers of +one invocation may share a family; they own distinct streams as soon as their routes differ, in +particular when their footprints on the family are disjoint. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +-/ +import LemmaA.Tensor + +namespace LemmaA + +open TensorProduct LemmaG LemmaG.Stream + +section Owner + +variable {ι Fam G : Type*} [Group G] + +/-- The stream that register `r` owns in the invocation at cover class `d`. -/ +def streamOwner (fam : ι → Fam) (σ : ι → G) (d : G) (r : ι) : Fam × G := (fam r, d * (σ r)⁻¹) + +/-- Distinct (family, route) pairs give distinct streams, at every cover class. -/ +theorem streamOwner_injective (fam : ι → Fam) (σ : ι → G) (d : G) + (h : Function.Injective fun r => (fam r, σ r)) : Function.Injective (streamOwner fam σ d) := by + intro r r' hrr + simp only [streamOwner, Prod.mk.injEq, mul_right_inj, inv_inj] at hrr + exact h (Prod.ext hrr.1 hrr.2) + +/-- **Disjoint footprints give one owner per stream.** If registers on the same family have +pairwise disjoint, nonempty footprints (`fp σ` is the set of family coordinates that route `σ` +places the register on), the stream owner map is injective at every cover class. -/ +theorem streamOwner_injective_of_disjoint {C : Type*} (fam : ι → Fam) (σ : ι → G) (d : G) + (fp : G → Set C) (hne : ∀ r, (fp (σ r)).Nonempty) + (hdis : ∀ r r', r ≠ r' → fam r = fam r' → Disjoint (fp (σ r)) (fp (σ r'))) : + Function.Injective (streamOwner fam σ d) := by + refine streamOwner_injective fam σ d (fun r r' h => ?_) + by_contra hne' + simp only [Prod.mk.injEq] at h + obtain ⟨x, hx⟩ := hne r + have := hdis r r' hne' h.1 + rw [h.2] at this hx + exact Set.disjoint_left.1 this hx hx + +/-- **The cover sweep visits each stream once per route.** For a fixed route `σ`, exactly one cover +class `d` realizes a register with route `σ` on the stream `(f, g)`, namely `d = g σ`. -/ +theorem sweep_unique (σ g : G) : ∃! d : G, d * σ⁻¹ = g := + ⟨g * σ, by simp, fun d h => by rw [← h]; simp⟩ + +end Owner + +section Lemma + +variable {K : Type*} [CommSemiring K] +variable {A B : Type*} [AddCommMonoid A] [Module K A] [AddCommMonoid B] [Module K B] +variable {ι Λ Fam G C W : Type*} [DecidableEq ι] [Fintype ι] [DecidableEq Fam] [Group G] [DecidableEq G] +variable [AddCommMonoid W] [Module K W] + +/-- **Lemma A on streams.** Registers of one invocation may share a family if their footprints on +it are pairwise disjoint (#433 pure-bank slots, #442 hosted slots, #471/#500 footprints). Realized +on the streams `(fam r, d · σ_r⁻¹)`, the complete invocation leaves the helper's stream holding +`chart⁻¹ (C ⊗ id) chart` of its own initial value: the spectators are untouched. -/ +theorem lemmaA_streams (T : Λ → (A ⊗[K] B) ≃ₗ[K] (A ⊗[K] B)) (fam : ι → Fam) (σ : ι → G) (d : G) + (fp : G → Set C) (hne : ∀ r, (fp (σ r)).Nonempty) + (hdis : ∀ r r', r ≠ r' → fam r = fam r' → Disjoint (fp (σ r)) (fp (σ r'))) + (chart : ι → W ≃ₗ[K] (A ⊗[K] B)) (rec : Λ → Λ → A ⊗[K] B → A ⊗[K] B) + (es : List (Event ι Λ K)) (l : ι → Λ) (y : Fam × G → W) (hrec : RecipesExact T rec es) + (hw : WellLabelled es l) (j : ι) (hS : ∀ s, S es j s = if s = j then 1 else 0) + (Cj : A →ₗ[K] A) (hfac : ∀ v, T (labRun es l j) ((T (l j)).symm v) = Cj.rTensor B v) : + realizeRun ⟨streamOwner fam σ d, chart⟩ rec es y (streamOwner fam σ d j) = + (chart j).symm (Cj.rTensor B (chart j (y (streamOwner fam σ d j)))) := + lemmaA_family T ⟨streamOwner fam σ d, chart⟩ + (streamOwner_injective_of_disjoint fam σ d fp hne hdis) rec es l y hrec hw j hS Cj hfac + +end Lemma + +end LemmaA diff --git a/research/e8-lemma-a-lean/LemmaA/Tensor.lean b/research/e8-lemma-a-lean/LemmaA/Tensor.lean new file mode 100644 index 0000000000..cd33a52ab5 --- /dev/null +++ b/research/e8-lemma-a-lean/LemmaA/Tensor.lean @@ -0,0 +1,149 @@ +/- +Lemma A, spectators: the wrapped helper block is `C ⊗ id`, so the spectator factor is untouched, +and pieces on complementary tensor factors of one family commute and multiply to `C ⊗ D`. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +-/ +import LemmaA.Schedule +import Mathlib.LinearAlgebra.TensorProduct.Basic + +namespace LemmaA + +open TensorProduct LemmaG LemmaG.Stream + +variable {K : Type*} [CommSemiring K] +variable {A B : Type*} [AddCommMonoid A] [Module K A] [AddCommMonoid B] [Module K B] + +/-- **Spectators are untouched.** If the wrapped helper block is `C ⊗ id` (Lemma A, exact part: +`L_E⁻¹ S_E R_E⁻¹ = C_[w] ⊗ I`), each pure tensor keeps its spectator factor. -/ +theorem spectators_fixed (G : A ⊗[K] B →ₗ[K] A ⊗[K] B) (C : A →ₗ[K] A) + (h : G = C.rTensor B) (a : A) (b : B) : G (a ⊗ₜ b) = C a ⊗ₜ b := by + rw [h]; rfl + +/-- Residuals on complementary tensor factors commute. -/ +theorem residuals_commute (C : A →ₗ[K] A) (D : B →ₗ[K] B) : + C.rTensor B ∘ₗ D.lTensor A = D.lTensor A ∘ₗ C.rTensor B := by + rw [LinearMap.rTensor_comp_lTensor, LinearMap.lTensor_comp_rTensor] + +section Helper + +variable {ι Λ : Type*} [DecidableEq ι] [Fintype ι] + +/-- **The helper block of a complete invocation fixes the spectators.** Lemma G's unit row gives +the block `T_{λ¹ j} T_{λ⁰ j}⁻¹`; with the exact factorization of that block as `C ⊗ id` (checked +numerically), register `j` ends as `(C ⊗ id) h_j`. -/ +theorem helper_block (T : Λ → (A ⊗[K] B) ≃ₗ[K] (A ⊗[K] B)) (rec : Λ → Λ → A ⊗[K] B → A ⊗[K] B) + (es : List (Event ι Λ K)) (l : ι → Λ) (h : ι → A ⊗[K] B) (hrec : RecipesExact T rec es) + (hw : WellLabelled es l) (j : ι) (hS : ∀ s, S es j s = if s = j then 1 else 0) + (C : A →ₗ[K] A) (hfac : ∀ v, T (labRun es l j) ((T (l j)).symm v) = C.rTensor B v) : + physRun rec es h j = C.rTensor B (h j) := by + rw [row_unit T rec es l h hrec hw j hS, hfac] + +/-- **Lemma A, realized helper family.** One owner per invocation, exact recipes, well labelled, +a unit row (Lemma G, H3) and the exact factorization `T_{λ¹}T_{λ⁰}⁻¹ = C ⊗ id`: at the end of the +complete invocation the helper's family holds `χ⁻¹ (C ⊗ id) χ` of its own initial value. With +`endpoint_indep` no other family reads it, and with `whole_invocation` no other actor may run on +it meanwhile. -/ +theorem lemmaA_family {Φ W : Type*} [DecidableEq Φ] [AddCommMonoid W] [Module K W] + (T : Λ → (A ⊗[K] B) ≃ₗ[K] (A ⊗[K] B)) (σ : Hosting ι Φ K W (A ⊗[K] B)) + (hinj : Function.Injective σ.own) (rec : Λ → Λ → A ⊗[K] B → A ⊗[K] B) + (es : List (Event ι Λ K)) (l : ι → Λ) (y : Φ → W) (hrec : RecipesExact T rec es) + (hw : WellLabelled es l) (j : ι) (hS : ∀ s, S es j s = if s = j then 1 else 0) + (C : A →ₗ[K] A) (hfac : ∀ v, T (labRun es l j) ((T (l j)).symm v) = C.rTensor B v) : + realizeRun σ rec es y (σ.own j) = (σ.chart j).symm (C.rTensor B (σ.chart j (y (σ.own j)))) := by + rw [family_endpoint T σ hinj rec es l y hrec hw j hS, hfac] + +end Helper + +section Family + +variable {Φ W : Type*} [DecidableEq Φ] [AddCommMonoid W] [Module K W] + +/-- Apply `U` to family `f` and leave every other family alone. -/ +def famAct (f : Φ) (U : W → W) : (Φ → W) → (Φ → W) := + fun y => Function.update y f (U (y f)) + +omit [AddCommMonoid W] in +theorem famAct_supported (f : Φ) (U : W → W) : Supported (famAct f U) {f} := by + refine ⟨fun y g hg => Function.update_of_ne (by simpa using hg) _ _, fun y y' hyy g hg => ?_⟩ + rw [Set.mem_singleton_iff.1 hg] + simp [famAct, hyy f rfl] + +omit [AddCommMonoid W] in +theorem famAct_comp (f : Φ) (U V : W → W) : famAct f U ∘ famAct f V = famAct f (U ∘ V) := by + funext y g + by_cases hg : g = f + · subst hg; simp [famAct] + · simp [famAct, Function.update_of_ne hg] + +/-- **Pieces on disjoint blocks of one family commute.** In a common chart `χ : W ≃ A ⊗ B`, one +piece acts as `C ⊗ id` and the other as `id ⊗ D`. -/ +theorem pieces_commute (χ : W ≃ₗ[K] A ⊗[K] B) (f : Φ) (C : A →ₗ[K] A) (D : B →ₗ[K] B) : + famAct f (χ.symm ∘ C.rTensor B ∘ χ) ∘ famAct f (χ.symm ∘ D.lTensor A ∘ χ) = + famAct f (χ.symm ∘ D.lTensor A ∘ χ) ∘ famAct f (χ.symm ∘ C.rTensor B ∘ χ) := by + have key : (χ.symm ∘ C.rTensor B ∘ χ) ∘ (χ.symm ∘ D.lTensor A ∘ χ) = + (χ.symm ∘ D.lTensor A ∘ χ) ∘ (χ.symm ∘ C.rTensor B ∘ χ) := by + funext v + have := LinearMap.congr_fun (residuals_commute C D) (χ v) + simp only [LinearMap.comp_apply] at this + simp [this] + rw [famAct_comp, famAct_comp, key] + +/-- **Pieces gather into the child.** The two pieces together act as `χ⁻¹ (C ⊗ D) χ`. -/ +theorem pieces_product (χ : W ≃ₗ[K] A ⊗[K] B) (f : Φ) (C : A →ₗ[K] A) (D : B →ₗ[K] B) : + evalW [famAct f (χ.symm ∘ C.rTensor B ∘ χ), famAct f (χ.symm ∘ D.lTensor A ∘ χ)] = + famAct f (χ.symm ∘ TensorProduct.map C D ∘ χ) := by + have key : (χ.symm ∘ D.lTensor A ∘ χ) ∘ (χ.symm ∘ C.rTensor B ∘ χ) = + χ.symm ∘ TensorProduct.map C D ∘ χ := by + funext v + have := LinearMap.congr_fun (LinearMap.lTensor_comp_rTensor (f := C) (g := D)) (χ v) + simp only [LinearMap.comp_apply] at this + simp [this] + simp only [evalW] + rw [Function.id_comp, famAct_comp, key] + +end Family + +section Piece + +variable {ι Λ : Type*} [DecidableEq ι] [Fintype ι] +variable {Φ W : Type*} [DecidableEq Φ] [AddCommMonoid W] [Module K W] + +/-- **The realized invocation as a single-family piece.** Under the hypotheses of +`lemmaA_family`, plus a zero helper column (Lemma G, H3), the complete realized invocation acts on +the helper's family `own j` as the piece `famAct (own j) (chart⁻¹ ∘ (C ⊗ id) ∘ chart)`, and no other +family reads `own j`: these are the hypotheses `hEf`, `hread` of `split_off` and `async_window`. -/ +theorem lemmaA_piece (T : Λ → (A ⊗[K] B) ≃ₗ[K] (A ⊗[K] B)) (σ : Hosting ι Φ K W (A ⊗[K] B)) + (hinj : Function.Injective σ.own) (rec : Λ → Λ → A ⊗[K] B → A ⊗[K] B) + (es : List (Event ι Λ K)) (l : ι → Λ) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) + (j : ι) (hS : ∀ s, S es j s = if s = j then 1 else 0) (hcol : ∀ r, r ≠ j → S es r j = 0) + (C : A →ₗ[K] A) (hfac : ∀ v, T (labRun es l j) ((T (l j)).symm v) = C.rTensor B v) : + (∀ y, realizeRun σ rec es y (σ.own j) = + famAct (σ.own j) ((σ.chart j).symm ∘ C.rTensor B ∘ σ.chart j) y (σ.own j)) ∧ + (∀ y w g, g ≠ σ.own j → + realizeRun σ rec es (Function.update y (σ.own j) w) g = realizeRun σ rec es y g) := + ⟨fun y => by + rw [lemmaA_family T σ hinj rec es l y hrec hw j hS C hfac] + simp [famAct], + fun y w g hg => endpoint_indep T σ hinj rec es l y hrec hw j hcol w g hg⟩ + +/-- **Lemma A with asynchronous borrowing (#505).** A complete realized invocation whose helper +`j` borrows the pending block of family `own j` can be split: the rest of the invocation runs in +place, and its piece on `own j` runs just before the pending child's deadline, provided every +action in between commutes with that piece. -/ +theorem lemmaA_async (T : Λ → (A ⊗[K] B) ≃ₗ[K] (A ⊗[K] B)) (σ : Hosting ι Φ K W (A ⊗[K] B)) + (hinj : Function.Injective σ.own) (rec : Λ → Λ → A ⊗[K] B → A ⊗[K] B) + (es : List (Event ι Λ K)) (l : ι → Λ) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) + (j : ι) (hS : ∀ s, S es j s = if s = j then 1 else 0) (hcol : ∀ r, r ≠ j → S es r j = 0) + (C : A →ₗ[K] A) (hfac : ∀ v, T (labRun es l j) ((T (l j)).symm v) = C.rTensor B v) + (xs ys zs : List ((Φ → W) → (Φ → W))) + (hys : ∀ a ∈ ys, a ∘ famAct (σ.own j) ((σ.chart j).symm ∘ C.rTensor B ∘ σ.chart j) = + famAct (σ.own j) ((σ.chart j).symm ∘ C.rTensor B ∘ σ.chart j) ∘ a) : + evalW (xs ++ realizeRun σ rec es :: ys ++ zs) = + evalW (xs ++ (fun y => Function.update (realizeRun σ rec es y) (σ.own j) (y (σ.own j))) :: ys ++ + famAct (σ.own j) ((σ.chart j).symm ∘ C.rTensor B ∘ σ.chart j) :: zs) := by + obtain ⟨hEf, hread⟩ := lemmaA_piece T σ hinj rec es l hrec hw j hS hcol C hfac + exact async_window _ _ (σ.own j) (famAct_supported _ _) hEf hread xs ys zs hys + +end Piece + +end LemmaA diff --git a/research/e8-lemma-a-lean/MANIFEST.json b/research/e8-lemma-a-lean/MANIFEST.json new file mode 100644 index 0000000000..50c27df241 --- /dev/null +++ b/research/e8-lemma-a-lean/MANIFEST.json @@ -0,0 +1,62 @@ +{ + "format": "e8-lemma-a-lean-v1", + "lean_toolchain": "leanprover/lean4:v4.21.0", + "mathlib": { + "inputRev": "v4.21.0", + "rev": "308445d7985027f538e281e18df29ca16ede2ba3" + }, + "library": "LemmaA", + "depends_on": "LemmaG (path ../e8-lemma-g-lean)", + "modules": [ + "LemmaA.Realize", + "LemmaA.Schedule", + "LemmaA.Tensor", + "LemmaA.Streams" + ], + "main_theorem": "LemmaA.lemmaA_streams", + "unit_model": "physical streams (family, cover class); one owner per stream, implied by disjoint footprints", + "axiom_probe": "PrintAxioms.lean", + "allowed_axioms": [ + "Classical.choice", + "Quot.sound", + "propext" + ], + "instance_checks": [ + "code/check_owners.py", + "code/check_windows.py", + "../e8-lemma-g-lean/code/check_extended_labels.py" + ], + "instance_input": "the output directory of PR #484 verify.py", + "external_files": { + "../e8-lemma-g-lean/LemmaG/BitEntrance.lean": "49872d04ec0cb0035a741075e3d593563a55ba8b5642cd225a8d06c166e890c8", + "../e8-lemma-g-lean/LemmaG/Frames.lean": "64e9bf83af211fd75ac2c7877b98604b11e2ba90b8e918435b92d0dcea0ccef7", + "../e8-lemma-g-lean/LemmaG/Schedule.lean": "df2c5feb64185810038b5095abc41c5455de3499b584acfea53c607233703ebb", + "../e8-lemma-g-lean/LemmaG/Stream.lean": "7138f4b859d0574a803e99401f05ef5e0ec9eeac0eb480775cd9b86595c365f8", + "../e8-lemma-g-lean/LemmaG.lean": "ac5ab476d9c8e29de95b92844bdb3d9a59f108dfffb89c31ea65e413d0f4c09b", + "../e8-lemma-g-lean/lakefile.toml": "0d6ef7ebfd0c900dde7c8b5075ec4b7b47942e801dc5effb4288e078c17e203b", + "../e8-lemma-g-lean/lean-toolchain": "d24fed434d3b13adfaab57724a0a7f270ea8bf1c818b5ae5cf25cbce24dd685c", + "../e8-lemma-g-lean/lake-manifest.json": "a6082ec3e086d463f5eb3ba1befdbec45e868e2b328c6b066e25fcc82d1353f8", + "../e8-lemma-g-lean/code/check_extended_labels.py": "9e072754d350e79e5657196bee30cd18ed0a0677628aa66d16a15ce2aab1d2ea", + "../e8-complex-gauge-kernel/EXPECTED.json": "de9e2ade14c2f390759230850377d48c28b16a28c955669fa89c535fcc228113", + "../e8-complex-gauge-kernel/code/lemmaG/lg_lib.py": "e7db756ad091055b79e90e53d9cecda632a185a11ee3f095eed5d32757f87490" + }, + "files": { + ".gitignore": "d4e3917adcfaaa8d53ccc3eb2c9c3423307b0de18d8efbb32e3a92aa53ffb0f9", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "LemmaA.lean": "dcb29f406b352c608a89837ec95071ac01e9bcbe4671e01927c416e754e4c53d", + "LemmaA/Realize.lean": "3aa9afd36035afd94296ef410c647d5a8c6fb282f64062542c7070bb1d99a14f", + "LemmaA/Schedule.lean": "2b1c8a1a0370e47bc0c4b353a03605b9ad7e385ba30b4ac3bec7ecf76f656a5f", + "LemmaA/Streams.lean": "345b264eae4ed037e632461fd7a55dd27c6b21e828167e3b441482d063cf547e", + "LemmaA/Tensor.lean": "dcaba494eee73b8066d65326d9a8c3aea260f3b736eb1c5fbf7dfb7fe0c66baf", + "NOTICE.md": "1a7c2ee7de81ea8475e0a11c2d5b8ceebc9c9524bdbb26f15cd875356069daf2", + "PROOF.md": "fb2e59bb8cce222c75f0d0cf882f87d25df12e29375fa9032644b94221e540b9", + "PrintAxioms.lean": "bdcaf408e43c39ed77eb8736ca8ab02802b16ef5cf77474b96ea9b5458274e7d", + "README.md": "87a242f674783d6c553c450b7c5951f667f0f480316a557146449c5003c1d298", + "code/check_owners.py": "d04ea7a6e7cdd0b041f55b22e16e307472f001566311ba8724a446ac49881a3a", + "code/check_windows.py": "82a6af1bde10af6bba37ef6c8cf9773c299af762ced90704cd7c42de8b599448", + "lake-manifest.json": "2680a53c2bf2d8765e52871b7dcaaadf4e28eae878f5259ebdb94c399b9511b6", + "lakefile.toml": "3597e7d50913f50ba45cd66875686ec793a78ded39a04fa90fb75911c5d3c6e7", + "lean-toolchain": "d24fed434d3b13adfaab57724a0a7f270ea8bf1c818b5ae5cf25cbce24dd685c", + "verify.py": "32a20a1a3c979079483f149124b8b6be07812e5e1c046ed5300162fd2a21c7db" + } +} diff --git a/research/e8-lemma-a-lean/NOTICE.md b/research/e8-lemma-a-lean/NOTICE.md new file mode 100644 index 0000000000..a682089527 --- /dev/null +++ b/research/e8-lemma-a-lean/NOTICE.md @@ -0,0 +1,10 @@ +Apache-2.0 (see `LICENSE`). Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. + +The Lean sources are new. They formalise the realization part of Lemma A of PR #484 (DreamingOfClouds), which PR #484 +adopted from PR #458 §3 (chafreaky: one helper per physical family per call, paid wrappers, restored spectators), with +PR #471's same-owner spectator borrowing (Dugongue), the footprint rule of PR #471/#500 (Dugongue, rohanarun) and, as a proved variant, PR #505's asynchronous whole-owner borrowing +(Dugongue). The event semantics are those of PR #425's conjugation lemma (jacklightChen / Zhihao Chen), reused from the +Lemma G package `../e8-lemma-g-lean` (a Lake path dependency, same Lean and Mathlib pin as `formal/lean` on main). +`code/check_owners.py` reads PR #484's emitted hosted template and its `EXPECTED.json` (read-only). The stream +model (family, cover class) is that of PR #442's idle-axis hosting (DaysSky) and PR #458; the pure banks are PR #433's +(icekylinx). `code/check_windows.py` is written independently of PR #484's audit_hosted_gk.py and PR #505's audit_async.py. diff --git a/research/e8-lemma-a-lean/PROOF.md b/research/e8-lemma-a-lean/PROOF.md new file mode 100644 index 0000000000..f5bb219244 --- /dev/null +++ b/research/e8-lemma-a-lean/PROOF.md @@ -0,0 +1,211 @@ +# Lemma A: clean statement and proof + +Lemma A of PR #484 (`research/e8-complex-gauge-kernel/PROOF.md` §3) has two parts. + +* **Exact part.** For every entrance frame, `S_E = L_E (C_[w] ⊗ I) R_E`, where `L_E` and `R_E` are Gaussian + monomials. The wrapped product of every entering helper's emitted chain is `C_[w] ⊗ I`. #484 checks this + numerically. +* **Realization part.** The wrappers surround a whole invocation, and nothing else acts on the helper's stream + during it. Then the host keeps its assigned residual and identical spectators. #484 assumed this from #458 §3, for + hosted families and banks, at nine stages. + +This package proves the realization part as an abstract theorem in Lean. +* It holds for every chart, every number of stages, and every layout in which the registers of one invocation own + distinct streams. +* It includes several registers on one family, provided their footprints are disjoint. +* Each hypothesis is checked on the emitted words. + +Lean names are in brackets. The objects `Event`, `physRun`, `S`, `WellLabelled` and `RecipesExact` are reused from +the Lemma G package `../e8-lemma-g-lean`. + +## 1. Setting: stream units + +**Units are physical streams `(F, g)`.** `F` is a family and `g ∈ O(73,2)` is a cover class. This is the model of the +cover construction that #484 inherits: +* the template's `cover` field: "all matrices d in O(73,2)"; +* its `loop_order`: "every cover class d; each local invocation completes before the next"; +* its `route_semantics`: helper at "physical cover class d*Pi(slot)^(-1)"; +* #442's idle-axis hosting (`research/idle-axis-hosting/PROOF.md` §1–2): "on every physical data stream (F, g)", "owned + by stream (F, d·σ⁻¹)", "eight sequential residuals and a pad tile a bank stream", and the source for distinct streams + per slot: "Distinct slots of one invocation have distinct σ, so distinct physical classes for every d … They are + sequential, exactly as the parent's banks are co-owned sequentially by different cover classes"; +* #458 §3, only for the convention `g = dσ⁻¹` of the owner cover class. + +In this model the pieces fit together as follows. +* **Global state.** A global state is `y : streams → W`, where `W` is the space of functions on a family's address + cells. +* **Realization.** A local cover sweep runs the invocation once for every class `d`. At class `d`, register `r` is + realized on the stream `(fam r, d·σ_r⁻¹)` [`streamOwner`]. Here `σ_r` is the register's route: an element of + `O(73,2)` whose first nine columns are its footprint (its local coordinates on the family). Examples are the slot + permutation `Π(slot)` of a bank, a host chart, and a data phase `ρ`. +* **Distinct routes, distinct streams.** Two registers of one invocation with different routes own different + streams, even on one family [`streamOwner_injective`]. Disjoint nonempty footprints give different routes + [`streamOwner_injective_of_disjoint`]. +* **One visit per route.** Over the sweep, a fixed stream `(F, g)` is realized through a fixed route `σ` by exactly + one class, `d = gσ` [`sweep_unique`; #458 §3: "for a fixed family, d → g is a bijection"]. So a stream receives the blocks of different routes sequentially, from + different invocations. Those blocks are disjoint (§4), so they commute and tile the stream [`pieces_*`, `gather`]. + +Lemma A is proved in #442's stream model. That the model describes the machine is inherited from #442, like the +compiler. + +**An invocation.** It is a local stream `es` on registers `ι`, as in Lemma G. `ι` includes the private centre copies. +A **hosting** `σ` gives each register an owner unit and a linear chart `chart i : W ≃ M`, made of the route and the +batch of remaining coordinates. In this section `σ` is the hosting; elsewhere `σ_r` is a route. + +**Physical execution** [`realize`, `realizeRun`]. Each event reads its operands through their charts. It writes the +destination register's unit back. + +**Actions and words** [`Supported`, `evalW`, `Interleave`]. An action is *supported on* `S` if: +* it changes only units in `S`; +* its values on `S` depend only on the input on `S`. + +A physical schedule is a word of actions, applied left to right. + +## 2. Statement + +**Lemma A (realization).** Let `σ` host the invocation `es`, and let `j` be an entering helper. Assume the following. + +* **(O) One owner per stream.** The owner map is injective on the registers of the invocation. In the stream model, + (O) follows from **(O′)**: every data wire is alone on its family, and registers that share a family have pairwise + disjoint, nonempty footprints. +* **(W) Whole invocation, no other actor.** The physical word interleaves the realized events of `es` only with + actions supported away from the invocation's units. +* **(E) Exact endpoint (Lemma G).** `es` is well labelled with exact recipes. Row `j` of its scalar shadow is `e_j`, + and column `j` vanishes off the diagonal. +* **(F) Exact factorization.** + * The labels are **Lemma G's extended labels**: `λ⁰_j = (prew, j)` and `λ¹_j = (done, j)`. The wrappers are relabel + events in `es`, so `T_{λ¹_j}T_{λ⁰_j}⁻¹ = L_E⁻¹ S_E R_E⁻¹`. Lemma G's `check_extended_labels.py` checks this + reading, and `verify.py` runs it. + * The split `M ≅ A ⊗ B` (residual ⊗ spectators and batch) is chosen per helper. + * The hypothesis is then `T_{λ¹_j}T_{λ⁰_j}⁻¹ = C ⊗ id`. #484's I-helper check gives it. + +Then the following hold. + +1. **The whole invocation.** The word equals the complete invocation followed by the other actions + [`whole_invocation`]. Read through the charts, the invocation is the local run [`realize_run`]. Units that host + no register are untouched [`realize_untouched`]. +2. **The helper's unit.** It ends as `chart_j⁻¹ (C ⊗ id) chart_j` applied to its own initial value [`lemmaA_family`; + on streams with (O′): `lemmaA_streams`]. On a pure tensor this is `a ⊗ b ↦ C a ⊗ b`: **the spectators are + untouched** [`spectators_fixed`, `helper_block`]. +3. **No other reader.** No other unit's final value depends on the helper's unit [`endpoint_indep`]. The complete + invocation acts on it as a single-unit piece [`lemmaA_piece`] and splits off [`split_off`]. +4. **Pending blocks.** Pieces on disjoint blocks of one pending child commute [`pieces_commute`]. They multiply to + `C ⊗ D` [`pieces_product`]; for `k` blocks, iterate. Together with the paid remainder they give back the child, + which is `⊗_b C_b` over its pending axes (#458: "the original idle operator is recovered"). + +**(O) cannot be dropped within the model** [`one_owner_needed`]. If two registers share a unit, the one-event stream +`scale i 0` changes what register `j` sees, while the local run leaves `j` alone. + +**(W) cannot be dropped.** An action that reads the helper's unit between `R_E⁻¹` and `L_E⁻¹` sees `R_E⁻¹h`, not `h`. + +**Variant A′ (asynchronous borrowing)** [`lemmaA_async`, `async_window`, `defer`, `gather`]. Suppose every action +between the invocation and the pending child's deadline commutes with the piece of item 3. This holds in either case: +* the action does not touch the piece's unit [`commute_of_not_mem`]; +* the action is another piece of the same child on a disjoint block [`pieces_commute`]. + +Then the schedule equals the one in which the rest of the invocation runs in place and the piece runs just before the +deadline. Gathering the child's pieces gives back the child [`gather`]. The variant's hypotheses are #505's scheduling +conditions. Under them, the owner's history is the original one: +* **window:** each block is used strictly inside its pending child's open window, after the owner's previous data or + bridge touch and before the child's deadline; +* **blocks:** the blocks of one child are pairwise disjoint; +* **whole invocations:** each invocation is indivisible, with distinct owners. + +## 3. Proofs + +* **`realize_run`.** Induct over the stream. Realizing an event writes the destination's unit and nothing else. + Under (O), every other register sits on another unit, so its view is unchanged. The destination's view is its new + local value. +* **`family_endpoint`, `lemmaA_family`.** A unit's value is `chart⁻¹(view)`, and the view is the local run. Lemma G's + `row_unit` gives `T_{λ¹}T_{λ⁰}⁻¹` applied to the initial view, and (F) rewrites it. +* **`lemmaA_streams`.** Apply `lemmaA_family` to the hosting `r ↦ (fam r, d·σ_r⁻¹)`. +* **`streamOwner_injective`.** `d·σ⁻¹ = d·σ'⁻¹` forces `σ = σ'` in a group. +* **`streamOwner_injective_of_disjoint`.** Equal routes on one family would give a footprint disjoint from itself, yet + nonempty. +* **`sweep_unique`.** `d = gσ` is the unique solution of `d·σ⁻¹ = g`. +* **`endpoint_indep`.** Changing the helper's unit changes the view only at `j`. By `conj_matrix`, output `r` is + `T(Σ_s S_rs T⁻¹h_s)`, and `S_rj = 0`. +* **`commute_of_disjoint`, `shuffle_eval`, `whole_invocation`, `split_off`, `defer`, `async_window`.** Check unit by + unit, and induct over interleavings and words. +* **`pieces_commute`, `pieces_product`.** Mathlib's `rTensor_comp_lTensor` and `lTensor_comp_rTensor`. + +The scheduling and stream results hold over any semiring; `streamOwner_injective` holds over any group. The tensor +results (`lemmaA_family`, `lemmaA_streams`, `lemmaA_piece`, `lemmaA_async`, `helper_block`, `spectators_fixed`, +`pieces_*`) need a commutative semiring. + +## 4. Instance hypotheses + +| | hypothesis | check | result | +| --- | --- | --- | --- | +| (F) | `L_E⁻¹ S_E R_E⁻¹ = C_[w] ⊗ I` in Lemma G's extended labels | #484 `adapters_gk.py` (`LEMMA-A.json`); #484 I-helper (all 512 columns); Lemma G `check_extended_labels.py` (run by `verify.py`) | headline: 16 frames and 122/122 helpers; gauge80: 80/80; kernel79: 79/79; 0 tag violations | +| (E) | well labelled, exact recipes, unit helper rows, zero helper columns | Lemma G package H1–H3 (#484 G0/G2/G3, I-tr, scalar replay) | 0 violations | +| (O′) | data wires alone; registers sharing a family have disjoint footprints; centre copies in distinct private slots | **new** `code/check_owners.py` (3 mutants rejected) | 0 violations on all four words | +| (W) | calls run to completion; every hosted block strictly inside its pending child's open window | completion: `check_owners.py` tests the template's declared `loop_order` (a declaration, not a structural replay; for #505's asynchronous order the structural check is #505's own audit, replayed here but not re-implemented); windows: **new** `code/check_windows.py` (independent, 2 mutants rejected); #484 `audit_hosted_gk.py` | 0 violations on all four words | +| blocks | the hosted blocks of one pending child are pairwise disjoint; the remainder is the rest | `check_windows.py`; #484 `audit_hosted_gk.py` (remainder ranks) | 0 violations | +| charts | route = permutation of an orthonormal basis, residual first, then spectators | #484 `audit_hosted_gk.py` | PASS | + +Data wires and centre copies have a nonempty footprint by construction: their route's first nine columns. So the +Lean hypothesis `hne` holds for them, although `check_owners.py` tests nonemptiness only on shared families. + +**Coverage on #484's words** (`check_owners.py`, from the emitted hosted templates): + +| word | calls with one register per family | calls sharing a family with disjoint footprints | hosted blocks in their windows | +| --- | --- | --- | --- | +| headline gauge80 + kernel42 | 72/72 | 0 | 39,792 | +| gauge80 | 40/72 | 32 (1,280 registers, #433 pure-bank slots) | 38,112 | +| kernel79 | 56/72 | 16 (1,308 registers, #433 pure-bank slots) | 37,720 | +| anchor | 0/72 | 72 (36,480 registers, #442 hosted slots) | 34,560 | + +Every call of every word satisfies (O′). Lemma A therefore covers all calls of all four words, including the +slot-sharing calls of gauge80 and kernel79. + +The anchor is not pinned to `EXPECTED.json` and has no wrappers. Its (O′) and windows rest on this package's two +checkers alone. #484's anchor hosting audit is non-strict and is not read. + +## 5. Scope + +* **#458 and #484.** #458 §3 states the one-helper rule as required, and rejects same-call packing into disjoint slots. + This package follows #442 §2 instead: distinct routes give distinct physical classes, and streams are co-owned + sequentially across cover classes. That needs atomic invocations (`loop_order`). + * The single-owner calls are #458's case: headline 72/72, gauge80 40, kernel79 56, and #505 72/72. + * The sharing calls rest on #442's model. +* **#433 pure banks and #442 hosted slots.** These are instances through (O′): the slots are disjoint footprints. +* **#471 and #500 (footprint rule).** Several helpers of one invocation on one family, with pairwise disjoint + nine-coordinate footprints, is exactly (O′). Given their footprint disjointness and windows, these layouts are + instances. Their words are not checked here. `check_owners.py` and `check_windows.py` read hosted templates in the same + format and layout: 960 families per replica, 120 ports, and 16 centres for `--async`. +* **#505 (asynchronous whole owners).** + * Each invocation is whole. Per #505, "all 800 families per invocation are distinct", so (O) holds literally. + * The cross-replica borrowing is Variant A′. + * **Replayed here.** #505's own `verify.py` (offline, Python 3.14) passes every stage, including its independent + asynchronous audit. + * Two discrepancies remain. Its final comparison of the emitted template's sha256 with #505's `EXPECTED.json` + fails, although the audit's sigma-stream digest, owner, profile and κ records equal #505's shipped evidence. + Separately, #505's tree lacks a `.gitattributes` that its MANIFEST lists; that entry was dropped from a scratch + copy. + * On the emitted template, `check_owners.py` finds one register per family in 72/72 calls. + * `check_windows.py` finds all 40,320 hosted blocks strictly inside their owner child's open window, with blocks + pairwise disjoint and family-group windows disjoint. + + So Variant A′'s owner and window hypotheses hold on the template emitted by replaying #505 (4ee769c) here. That + template does not hash-match #505's `EXPECTED.json` (template_sha256 aa741871… vs 276b69e3…). The sigma-stream + digest, owner, profile and κ records equal #505's shipped evidence. + * Not re-checked here: per-replica order (#505's audit checks it), the prefix bound and its invoice. (E) and (F) are + not re-checked on #505's word. +* **#512.** It reports 800 distinct physical owners per invocation, and it builds on #505's asynchronous machinery + and #507's factory. On its own report its invocations meet (O). Its borrowing is Variant A′ under the same + scheduling conditions. #512's word is not checked here. + +## 6. Changes relative to #484 §3 + +1. **The realization part is proved, not assumed.** It holds for every chart, given one owner per stream. +2. **The unit model is stated.** A unit is a stream `(F, g)`, as in #442 §2. #458 §3 states the one-helper rule as + required and rejects same-call packing into disjoint slots. This package follows #442 §2 instead: one owner per + stream, which disjoint footprints imply, with streams co-owned sequentially across cover classes. That needs atomic + invocations. +3. **"Nothing else acts" is exactly** that the interleaved actions avoid the invocation's units (`whole_invocation`), + together with the window condition for borrowed blocks. +4. **The spectator claim follows from two facts:** Lemma G's block structure and the exact factorization in the + extended labels. +5. **(O′), the windows and the block disjointness are now checked independently** on all four words. + `check_owners.py` and `check_windows.py` can also run on asynchronous templates. diff --git a/research/e8-lemma-a-lean/PrintAxioms.lean b/research/e8-lemma-a-lean/PrintAxioms.lean new file mode 100644 index 0000000000..9ab97a5e89 --- /dev/null +++ b/research/e8-lemma-a-lean/PrintAxioms.lean @@ -0,0 +1,25 @@ +import LemmaA +#print axioms LemmaA.realize_run +#print axioms LemmaA.realize_untouched +#print axioms LemmaA.one_owner_needed +#print axioms LemmaA.family_endpoint +#print axioms LemmaA.endpoint_indep +#print axioms LemmaA.commute_of_disjoint +#print axioms LemmaA.commute_of_not_mem +#print axioms LemmaA.shuffle_eval +#print axioms LemmaA.whole_invocation +#print axioms LemmaA.split_off +#print axioms LemmaA.defer +#print axioms LemmaA.async_window +#print axioms LemmaA.gather +#print axioms LemmaA.spectators_fixed +#print axioms LemmaA.helper_block +#print axioms LemmaA.lemmaA_family +#print axioms LemmaA.lemmaA_piece +#print axioms LemmaA.lemmaA_async +#print axioms LemmaA.pieces_commute +#print axioms LemmaA.pieces_product +#print axioms LemmaA.streamOwner_injective +#print axioms LemmaA.streamOwner_injective_of_disjoint +#print axioms LemmaA.sweep_unique +#print axioms LemmaA.lemmaA_streams diff --git a/research/e8-lemma-a-lean/README.md b/research/e8-lemma-a-lean/README.md new file mode 100644 index 0000000000..42355bfe90 --- /dev/null +++ b/research/e8-lemma-a-lean/README.md @@ -0,0 +1,119 @@ +# Lemma A (paid wrappers, spectators, one owner) of PR #484: clean proof and Lean 4 formalisation + +Lemma A of #484 (§3) has two parts: +* **exact part:** `S_E = L_E (C_[w] ⊗ I) R_E` on every entrance frame. #484 checks this numerically. +* **realization part:** paid wrappers around a whole invocation, with nothing else acting meanwhile, leave the host with its residual and its spectators untouched. #484 assumed this from #458 §3. + +This package proves the realization part in Lean 4 and checks every hypothesis on the emitted words. `PROOF.md` holds the clean statement and proof. The package is stacked on the Lemma G package `../e8-lemma-g-lean`, whose event semantics it reuses through a Lake path dependency. + +**Model.** Units are physical streams `(family F, cover class g ∈ O(73,2))`, as in #442 §2. At cover class `d`, register `r` lives on the stream `(F_r, d·σ_r⁻¹)`, where `σ_r` is its route. #442 §2: "Distinct slots of one invocation have distinct σ, so distinct physical classes for every d … sequential, exactly as the parent's banks are co-owned sequentially by different cover classes". One owner per stream follows when registers that share a family have pairwise disjoint footprints. + +**Lemma A is proved in #442's stream model. That the model describes the machine is inherited from #442.** #458 §3 states the one-helper rule as required, and rejects same-call packing into disjoint slots. Its case is the single-owner calls. The sharing calls rest on #442's model, which needs atomic invocations. + +So the theorem covers: +* one helper per family (#458's case, #484); +* #433's pure-bank slots and #442's hosted slots; +* #471's and #500's footprint rule. + +**Coverage on #484's words.** Every call of all four words satisfies the hypotheses: +* the headline: 72/72 calls with one register per family; +* gauge80: 40 such calls, plus 32 slot-sharing calls; +* kernel79: 56 such calls, plus 16 slot-sharing calls; +* the anchor: 72 hosted-slot calls, all sharing a family. The anchor is not pinned to EXPECTED and has no wrappers; its (O′) and windows are checked by this package's checkers alone. + +## Proved in Lean (`LemmaA/`, Lean 4.21.0 + Mathlib v4.21.0, the pin of `formal/lean` on main) + +**Main theorem, on streams.** It holds over any commutative semiring, for any modules, charts and number of stages. + +```lean +theorem LemmaA.lemmaA_streams (T : Λ → (A ⊗[K] B) ≃ₗ[K] (A ⊗[K] B)) (fam : ι → Fam) (σ : ι → G) (d : G) + (fp : G → Set C) (hne : ∀ r, (fp (σ r)).Nonempty) + (hdis : ∀ r r', r ≠ r' → fam r = fam r' → Disjoint (fp (σ r)) (fp (σ r'))) + (chart : ι → W ≃ₗ[K] (A ⊗[K] B)) (rec : Λ → Λ → A ⊗[K] B → A ⊗[K] B) + (es : List (Event ι Λ K)) (l : ι → Λ) (y : Fam × G → W) (hrec : RecipesExact T rec es) + (hw : WellLabelled es l) (j : ι) (hS : ∀ s, S es j s = if s = j then 1 else 0) + (Cj : A →ₗ[K] A) (hfac : ∀ v, T (labRun es l j) ((T (l j)).symm v) = Cj.rTensor B v) : + realizeRun ⟨streamOwner fam σ d, chart⟩ rec es y (streamOwner fam σ d j) = + (chart j).symm (Cj.rTensor B (chart j (y (streamOwner fam σ d j)))) +``` + +In words, the theorem assumes: +* registers that share a family have pairwise disjoint footprints; +* the invocation is well labelled with exact recipes; +* the helper has a unit row (Lemma G); +* its block factors as `C ⊗ id`, in Lemma G's extended labels (where `T_{λ¹}T_{λ⁰}⁻¹ = L_E⁻¹ S_E R_E⁻¹`). + +Then after the complete invocation, the helper's stream holds `chart⁻¹ (C ⊗ id) chart` of its own initial value. The spectators are untouched. + +| theorem | content | +| --- | --- | +| `streamOwner_injective(_of_disjoint)`, `sweep_unique` | distinct routes, or disjoint footprints, give distinct streams; the cover sweep visits each stream once per route | +| `realize_run`, `realize_untouched`, `one_owner_needed` | with one owner per unit, the physical execution read through the charts is the local run; within the model, sharing a unit breaks this | +| `family_endpoint`, `endpoint_indep`, `lemmaA_family`, `lemmaA_piece` | the helper's unit ends as a function of itself, no other unit reads it, and the invocation acts on it as a single-unit piece | +| `spectators_fixed`, `helper_block` | the wrapped block `C ⊗ id` keeps every spectator factor | +| `commute_of_disjoint`, `shuffle_eval`, `whole_invocation` | no other actor: interleaving with actions that avoid the invocation's units is harmless | +| `split_off`, `pieces_commute`, `pieces_product` | pieces on disjoint blocks of one pending child commute and multiply to `C ⊗ D` | +| `lemmaA_async`, `async_window`, `defer`, `gather` | Variant A′ (#505): a borrowed piece moves to its child's deadline past every commuting action, and the gathered pieces give the child | + +There is no instance enumeration and no `decide`/`native_decide`. `#print axioms` gives a subset of `[propext, Classical.choice, Quot.sound]` for all 24 named results (`PrintAxioms.lean`). + +## Checked on the words (PROOF.md §4) + +| hypothesis | check | headline / gauge80 / kernel79 / anchor | +| --- | --- | --- | +| (F) in extended labels | #484 `adapters_gk.py` and I-helper; Lemma G `check_extended_labels.py` | 16 frames, 122 / 80 / 79 helpers; anchor has no wrappers; 0 tag violations | +| (E) | Lemma G package H1–H3 | 0 violations | +| (O′) one owner per stream, centre copies | **new** `code/check_owners.py` (3 mutants) | 0 violations on all four words | +| (W), windows, disjoint blocks | **new** `code/check_windows.py` (independent; 2 mutants); `loop_order`; #484 hosting audit | 39,792 / 38,112 / 37,720 / 34,560 blocks; 0 violations | + +## #505 and #512 + +**#505.** Its invocations are whole. Per #505's own text, "all 800 families per invocation are distinct", so (O) holds literally. Its cross-replica borrowing is Variant A′. Variant A′ needs three conditions: +* windows; +* disjoint blocks; +* whole invocations with distinct owners. + +`verify.py --async T.json.gz` runs `check_owners.py` and `check_windows.py` on an asynchronous template. Results on the template that #505's own `verify.py` emits: +* #505's `verify.py` (4ee769c) passes every stage here, including its independent audit. +* `check_owners.py`: one register per family in 72/72 calls. +* `check_windows.py`: all 40,320 hosted blocks lie inside their owner child's open window, with blocks disjoint and family-group windows disjoint. +* So Variant A′'s owner and window hypotheses hold on the template emitted by replaying #505 (4ee769c) here. +* That template does not hash-match #505's `EXPECTED.json` (template_sha256 aa741871… vs 276b69e3…). The sigma-stream digest, owner, profile and κ records equal #505's shipped evidence. + +#505's other conditions are not re-checked here: per-replica order, the prefix bound and its invoice. (E) and (F) are not re-checked on #505's word. + +**#512.** It reports 800 distinct physical owners per invocation and builds on #505's asynchronous machinery. #512's word is not checked here; its coverage rests on #512's own report. + +## Trust base + +* The Lean kernel (4.21.0), Mathlib v4.21.0 (rev `308445d`), and the axioms `propext`, `Classical.choice`, `Quot.sound`. +* The Lemma G package, built here from source. +* #484's numerical checks of (F), and its hosting audit. +* This package's instance checks: `code/check_owners.py`, `code/check_windows.py`, and Lemma G's `check_extended_labels.py`. +* Inherited interfaces: + * #442's stream model (§2), in which streams `(F, g)` are the physical units; + * #442's compiler, under which the local program acts identically on the batch coordinates. + +## Run + +```sh +python3 research/e8-lemma-a-lean/verify.py # Lean: manifest, source scan, cache get, build, axioms +python3 research/e8-lemma-a-lean/verify.py --instances /abs/out/of/484/verify # plus #484's results, extended labels, owners, windows +python3 research/e8-lemma-a-lean/verify.py --no-cache --async T.json.gz # owners and windows on an asynchronous template +``` + +* `lake build` also builds `../e8-lemma-g-lean`. +* `--instances` needs the output directory of #484's `verify.py`; run it with `--all` to include gauge80 and kernel79. +* The checkers assume #484's layout: 960 families per replica and 120 ports; `--async` assumes 16 centres. + +## Credits + +* #458 (chafreaky): the one-helper rule, paid wrappers, spectator routing, cover-class owners, and the family-unit case of the realization argument formalised here. +* #471 (Dugongue): complete-invocation normalisation, same-owner spectator borrowing, and the footprint rule. +* #500 (rohanarun): footprint hosting with paid wrappers. +* #505 (Dugongue): asynchronous whole-owner replicas. +* #433 (icekylinx): the complex supplier and its pure banks. +* #442 (DaysSky): whole-residual and idle-axis hosting, and the stream model. +* #425 (Zhihao Chen): the conjugation lemma. +* #484 (DreamingOfClouds): the gauge/kernel word and Lemma A. +* Lean conventions: the `formal/lean` pin on main; #487/#488 (jamesyc). diff --git a/research/e8-lemma-a-lean/code/check_owners.py b/research/e8-lemma-a-lean/code/check_owners.py new file mode 100644 index 0000000000..4acfcda6cf --- /dev/null +++ b/research/e8-lemma-a-lean/code/check_owners.py @@ -0,0 +1,117 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +"""Instance check (O) (PROOF.md §4): one owner per stream in every invocation. + +Units are physical streams (family, cover class) (PROOF.md §1; #442 idle-axis hosting, #458 §3, the template's +`route_semantics`). An invocation at cover class d realizes register r on the stream (fam r, d * sigma_r^-1); by +`LemmaA.streamOwner_injective_of_disjoint` the owner map is injective once registers that share a family have pairwise +disjoint, nonempty footprints on it. This script reads the emitted hosted template and checks, in every call: + * data wires (route kind 1) are alone on their family; + * registers sharing a family have pairwise disjoint nonempty footprints, computed in the family's own coordinates: + [2, slot] pure-bank width-9 slot: cells 9*slot .. 9*slot+8 + [2, off, w, spectators] banked entering helper: cells off .. off+w-1 and its spectator cells + [3, child, off] hosted width-9: pending positions off .. off+8 of that idle child + [4, child, off, w, sp] hosted entering helper: pending positions off .. off+w-1, spectators as basis indices + a shared family whose footprints live in different coordinate systems cannot be checked and counts as a violation; + * no owner lies in the private namespace, and the private centre copies sit in one private slot per centre + (template `private_namespace`), disjoint from the reserved tableau and coefficient slots; + * the template runs each local invocation to completion before the next (`loop_order`): no other actor in a call. +It reports the calls with one register per family and the calls that share a family (covered through stream units), and +checks the template against #484's EXPECTED.json where it is pinned. + +usage: check_owners.py BASE VARIANT [VARIANT ...] [--mutants] reads BASE//hosted/GLOBAL-TEMPLATE.json.gz and + BASE//split-centres/CANONICAL-WORD.json.gz; or check_owners.py --template T.json.gz NCENTRES [--mutants] +Standard library only.""" +import gzip, hashlib, json, sys +from collections import Counter, defaultdict +from pathlib import Path + +HERE = Path(__file__).resolve().parent +EXPECTED = json.loads((HERE.parents[1] / 'e8-complex-gauge-kernel' / 'EXPECTED.json').read_text()) + + +def kind(r): + return str(r[0]) if r[0] != 2 else ('2-slot' if len(r) == 2 else '2-entering') + + +def footprint(r): + k = kind(r) + if k == '2-slot': return 'cell', {9 * r[1] + x for x in range(9)} + if k == '2-entering': return 'cell', set(range(r[1], r[1] + r[2])) | set(r[3]) + if k == '3': return ('pend', r[1]), set(range(r[2], r[2] + 9)) + if k == '4': return ('pend+B', r[1]), {('p', x) for x in range(r[2], r[2] + r[3])} | {('B', x) for x in r[4]} + return 'data', set() + + +def check_template(t, ncent): + live = t['live']; bad = []; kinds = Counter(); calls = 0; single = 0; shared_calls = 0; shared_regs = 0 + if 'each local invocation completes before the next' not in t['loop_order'].lower(): bad.append('loop_order: invocations not atomic') + for c in t['calls']: + own = c['owners']; calls += 1; tag = f"call stage {c['stage']} replica {c['replica']}" + kinds.update(kind(r) for _, r in own) + if any(f >= live for f, _ in own): bad.append(f'{tag}: owner in the private namespace') + groups = defaultdict(list) + for f, r in own: groups[f].append(r) + shared = {f: rs for f, rs in groups.items() if len(rs) > 1} + if not shared: single += 1; continue + shared_calls += 1 + for f, rs in shared.items(): + shared_regs += len(rs) + fps = [footprint(r) for r in rs] + if any(sys_ == 'data' for sys_, _ in fps): bad.append(f'{tag}: a data wire shares family {f}'); continue + if len({sys_ for sys_, _ in fps}) != 1 or fps[0][0][0] == 'pend+B': bad.append(f'{tag}: family {f} footprints in mixed coordinates'); continue + seen = set() + for _, fp in fps: + if not fp or fp & seen: bad.append(f'{tag}: footprints overlap on family {f}'); break + seen |= fp + pn = t['private_namespace']; a, b = pn['centers'] + others = [tuple(pn[k]) for k in pn if k != 'centers'] + if b - a != ncent or a < live or any(not (b <= x0 or x1 <= a) for x0, x1 in others): + bad.append(f'centre copies: private slots {pn["centers"]} for {ncent} centres, live {live}, others {others}') + return dict(calls=calls, one_register_per_family=single, sharing_calls=shared_calls, sharing_registers=shared_regs, + kinds=dict(sorted(kinds.items()))), bad + + +def main(): + args = [a for a in sys.argv[1:] if a != '--mutants']; ok = True + if args[0] == '--template': + raw = Path(args[1]).read_bytes(); jobs = [(args[1], raw, int(args[2]), None)] + else: + base = Path(args[0]); jobs = [] + for name in args[1:]: + raw = (base / name / 'hosted' / 'GLOBAL-TEMPLATE.json.gz').read_bytes() + ncent = len(json.loads(gzip.decompress((base / name / 'split-centres' / 'CANONICAL-WORD.json.gz').read_bytes()))['center_frames']) + jobs.append((name, raw, ncent, EXPECTED['words'].get(name, {}).get('hosted_template_sha256'))) + for name, raw, ncent, exp in jobs: + t = json.loads(gzip.decompress(raw)) + info, bad = check_template(t, ncent) + if exp is not None and exp not in (hashlib.sha256(raw).hexdigest(), hashlib.sha256(gzip.decompress(raw)).hexdigest()): + bad.append('hosted template differs from #484 EXPECTED.json') + ok &= not bad + print(f"{name}: calls {info['calls']}; one register per family {info['one_register_per_family']}/{info['calls']}; " + f"sharing a family with disjoint footprints (stream units) {info['sharing_calls']}/{info['calls']} " + f"({info['sharing_registers']} registers); centre copies {ncent} in private slots; " + f"{'pinned to EXPECTED' if exp else 'no EXPECTED pin'}; route kinds {info['kinds']}; violations {len(bad)} {bad[:3]}", flush=True) + if '--mutants' in sys.argv: + import copy + mu = {} + m = copy.deepcopy(t) # a helper moved onto an active data wire's family + c = m['calls'][0]; c['owners'][-1][0] = c['owners'][0][0]; mu['helper on a data wire family'] = len(check_template(m, ncent)[1]) + m = copy.deepcopy(t); hit = False # two registers on one family with overlapping footprints + for c in m['calls']: + fams = defaultdict(list) + for o in c['owners']: fams[o[0]].append(o) + for f, os_ in fams.items(): + if len(os_) > 1 and not hit: os_[1][1] = list(os_[0][1]); hit = True + if not hit: + hs = [o for o in c['owners'] if o[1][0] in (2, 3, 4)] + if len(hs) > 1: hs[1][0] = hs[0][0]; hs[1][1] = list(hs[0][1]); hit = True + mu['two registers with the same footprint on one family'] = len(check_template(m, ncent)[1]) + m = copy.deepcopy(t); m['private_namespace']['centers'] = [m['private_namespace']['centers'][0], m['private_namespace']['centers'][1] - 1] + mu['a centre copy without its private slot'] = len(check_template(m, ncent)[1]) + ok &= all(v > 0 for v in mu.values()); print(' mutants (violations each):', mu, flush=True) + print('PASS one owner per stream' if ok else 'FAIL owner check') + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/research/e8-lemma-a-lean/code/check_windows.py b/research/e8-lemma-a-lean/code/check_windows.py new file mode 100644 index 0000000000..9586d33d96 --- /dev/null +++ b/research/e8-lemma-a-lean/code/check_windows.py @@ -0,0 +1,113 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +"""Instance check (W)/(A') (PROOF.md §4-5): every hosted block lies inside its pending child's open window, and the +hosted blocks of one pending child are pairwise disjoint. + +These are the hypotheses of Variant A' (`LemmaA.lemmaA_async`, `async_window`, `gather`) that a schedule must meet, and, +for the lockstep words, the window part of (W). Written independently of #484's audit_hosted_gk.py and #505's +audit_async.py; it reads only the emitted hosted template: + * positions are indices into the template's `execution_schedule`; a local cover sweep of stage s touches the pair that + stage s acts on (`recipe`), for each of its replicas; a bridge touches its src and dst pairs; an idle cover sweep of a + pair runs that pair's pending children (`child_indices`, one per side); + * the open window of (owner replica, child i) is (last touch of the child's pair by that replica before the idle + sweep, the idle sweep): after the owner's previous data or bridge touch, before the child's deadline; + * the windows of the children of one family group (replica, pair, side) are pairwise disjoint, so inside a window no + idle sweep and no data or bridge touch acts on the family; only hosted blocks do; + * a hosted route [3, i, off] (width 9) or [4, i, off, w, spectators] on family f is owned by replica f // 960 on pair + side (f % 960) // 120 and port f % 120; the side must match child i, the call must lie strictly inside the window, + and its block off .. off+w-1 must be disjoint from every other block on (owner replica, child i, port). +Lockstep (#484: events carry `replicas`) and asynchronous (#505: events carry one `replica`) templates are both read. + +usage: check_windows.py T.json.gz [T2.json.gz ...] [--mutants] Standard library only.""" +import gzip, json, sys +from collections import defaultdict +from pathlib import Path + + +def reps(e, allreps): + if 'replicas' in e: return list(e['replicas']) + if 'replica' in e: return [e['replica']] + return list(allreps) + + +def check(t): + allreps = sorted({c['replica'] for c in t['calls']}) + stagepair = {e['stage']: e['pair'] for e in t['recipe'] if e.get('kind') == 'local'} + last, windows, child, group = {}, {}, {}, {}; callpos = {}; bad = [] + for pos, e in enumerate(t['execution_schedule']): + k = e.get('kind') + if k == 'local_cover_sweep': + for r in reps(e, allreps): callpos[e['stage'], r] = pos; last[r, stagepair[e['stage']]] = pos + elif k == 'bridge': + for r in reps(e, allreps): last[r, e['src']] = last[r, e['dst']] = pos + elif k == 'idle_cover_sweep': + for side, i in enumerate(e['child_indices']): + for r in reps(e, allreps): + if (r, i) in windows: bad.append(f'child {i} of replica {r} run twice') + windows[r, i] = (last.get((r, e['pair']), -1), pos); group[r, i] = (r, e['pair'], side) + child[i] = (e['pair'], side) + by = defaultdict(list) # children of one family group: pairwise disjoint windows + for key, w in windows.items(): by[group[key]].append(w) + for g, ws in by.items(): + ws.sort() + if any(a[1] > b[0] for a, b in zip(ws, ws[1:])): bad.append(f'overlapping child windows in family group {g}') + used = defaultdict(set); n = 0 + for c in t['calls']: + pos = callpos.get((c['stage'], c['replica'])) + if pos is None: bad.append(f"call stage {c['stage']} replica {c['replica']} has no cover sweep"); continue + for f, r in c['owners']: + if r[0] not in (3, 4): continue + i, off = r[1], r[2]; w = 9 if r[0] == 3 else r[3]; n += 1 + orep, ps, port = f // 960, (f % 960) // 120, f % 120 + if i not in child or ps != 2 * child[i][0] + child[i][1]: bad.append(f'call {c["stage"]},{c["replica"]}: family {f} is not on child {i}'); continue + lo, hi = windows.get((orep, i), (None, None)) + if lo is None or not lo < pos < hi: bad.append(f'call {c["stage"]},{c["replica"]}: block on replica {orep} child {i} outside its window {lo},{hi} at {pos}') + cells = set(range(off, off + w)) + if cells & used[orep, i, port]: bad.append(f'call {c["stage"]},{c["replica"]}: block overlaps on replica {orep} child {i} port {port}') + used[orep, i, port] |= cells + return n, len(windows), bad + + +def mutants(t): + """necessity controls: each edit must be rejected""" + import copy + res = {} + stagepair = {e['stage']: e['pair'] for e in t['recipe'] if e.get('kind') == 'local'} + children = {} + for e in t['execution_schedule']: + if e.get('kind') == 'idle_cover_sweep': + for side, i in enumerate(e['child_indices']): children[i] = (e['pair'], side) + m = copy.deepcopy(t) # a block moved onto another child of the same family group + done = False + for c in m['calls']: + for f, r in c['owners']: + if r[0] in (3, 4) and not done: + alt = [j for j, ps in children.items() if ps == children[r[1]] and j != r[1]] + if alt: r[1] = alt[0]; done = True + res['block moved to another child (outside its window)'] = len(check(m)[2]) + m = copy.deepcopy(t) # two blocks of one child made to overlap + seen = {} + for c in m['calls']: + for f, r in c['owners']: + if r[0] in (3, 4): + key = (f, r[1]) + if key in seen and 'done' not in seen: r[2] = seen[key]; seen['done'] = 1 + seen.setdefault(key, r[2]) + res['two blocks of one child overlap'] = len(check(m)[2]) + return res + + +def main(): + ok = True + for p in [a for a in sys.argv[1:] if not a.startswith('--')]: + t = json.loads(gzip.decompress(Path(p).read_bytes())) + n, nw, bad = check(t) + ok &= not bad + print(f'{p}: hosted blocks {n}; pending windows {nw}; violations {len(bad)} {bad[:3]}', flush=True) + if '--mutants' in sys.argv: + mu = mutants(t); ok &= all(v > 0 for v in mu.values()); print(' mutants (violations each):', mu, flush=True) + print('PASS windows and blocks' if ok else 'FAIL windows and blocks') + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/research/e8-lemma-a-lean/lake-manifest.json b/research/e8-lemma-a-lean/lake-manifest.json new file mode 100644 index 0000000000..7acfc87a86 --- /dev/null +++ b/research/e8-lemma-a-lean/lake-manifest.json @@ -0,0 +1,125 @@ +{ + "version": "1.1.0", + "packagesDir": ".lake/packages", + "packages": [ + { + "type": "path", + "scope": "", + "name": "LemmaG", + "manifestFile": "lake-manifest.json", + "inherited": false, + "dir": "./../e8-lemma-g-lean", + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover-community/mathlib4", + "type": "git", + "subDir": null, + "scope": "", + "rev": "308445d7985027f538e281e18df29ca16ede2ba3", + "name": "mathlib", + "manifestFile": "lake-manifest.json", + "inputRev": "v4.21.0", + "inherited": false, + "configFile": "lakefile.lean" + }, + { + "url": "https://github.com/leanprover-community/plausible", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "c4aa78186d388e50a436e8362b947bae125a2933", + "name": "plausible", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover-community/LeanSearchClient", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "6c62474116f525d2814f0157bb468bf3a4f9f120", + "name": "LeanSearchClient", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover-community/import-graph", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "d07bd64f1910f1cc5e4cc87b6b9c590080e7a457", + "name": "importGraph", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover-community/ProofWidgets4", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "6980f6ca164de593cb77cd03d8eac549cc444156", + "name": "proofwidgets", + "manifestFile": "lake-manifest.json", + "inputRev": "v0.0.62", + "inherited": true, + "configFile": "lakefile.lean" + }, + { + "url": "https://github.com/leanprover-community/aesop", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "8ff27701d003456fd59f13a9212431239d902aef", + "name": "aesop", + "manifestFile": "lake-manifest.json", + "inputRev": "master", + "inherited": true, + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover-community/quote4", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "e9c65db4823976353cd0bb03199a172719efbeb7", + "name": "Qq", + "manifestFile": "lake-manifest.json", + "inputRev": "master", + "inherited": true, + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover-community/batteries", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "8d2067bf518731a70a255d4a61b5c103922c772e", + "name": "batteries", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml" + }, + { + "url": "https://github.com/leanprover/lean4-cli", + "type": "git", + "subDir": null, + "scope": "leanprover", + "rev": "7c6aef5f75a43ebbba763b44d535175a1b04c9e0", + "name": "Cli", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml" + } + ], + "name": "LemmaA", + "lakeDir": ".lake" +} diff --git a/research/e8-lemma-a-lean/lakefile.toml b/research/e8-lemma-a-lean/lakefile.toml new file mode 100644 index 0000000000..e3ffb61b29 --- /dev/null +++ b/research/e8-lemma-a-lean/lakefile.toml @@ -0,0 +1,14 @@ +name = "LemmaA" +defaultTargets = ["LemmaA"] + +[[require]] +name = "mathlib" +git = "https://github.com/leanprover-community/mathlib4" +rev = "v4.21.0" + +[[require]] +name = "LemmaG" +path = "../e8-lemma-g-lean" + +[[lean_lib]] +name = "LemmaA" diff --git a/research/e8-lemma-a-lean/lean-toolchain b/research/e8-lemma-a-lean/lean-toolchain new file mode 100644 index 0000000000..980709bbba --- /dev/null +++ b/research/e8-lemma-a-lean/lean-toolchain @@ -0,0 +1 @@ +leanprover/lean4:v4.21.0 diff --git a/research/e8-lemma-a-lean/verify.py b/research/e8-lemma-a-lean/verify.py new file mode 100644 index 0000000000..4ef44ec8b6 --- /dev/null +++ b/research/e8-lemma-a-lean/verify.py @@ -0,0 +1,125 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +"""Verify the Lean formalisation of Lemma A. + +usage: python3 verify.py [--no-cache] [--instances BASE] [--async T.json.gz] + 1. every file listed in MANIFEST.json has its recorded sha256 and no unlisted file sits in LemmaA/ or code/; the files of + the Lemma G package (path dependency) and of PR #484 that are used have their recorded sha256 ("external_files"); + 2. the Lean sources contain no `sorry`, `admit`, `axiom`, `native_decide`, `implemented_by`, `extern`, `unsafe`, `opaque` + and no `set_option` other than the heartbeat limits (Lemma G's sources are scanned too); + 3. `lake exe cache get` (Mathlib's pinned build, skipped with --no-cache) and `lake build` (builds LemmaG as well); + 4. `lake env lean PrintAxioms.lean`: each main theorem depends only on propext, Classical.choice, Quot.sound; + 5. with --instances BASE (BASE = the output directory of PR #484's verify.py; --all there adds gauge80 and kernel79), on + every word present (the headline is required; the anchor is checked where present): + a. #484's own results on inputs equal to EXPECTED.json: LEMMA-A.json (required for every wrapped word), + HOSTING-AUDIT.json (strict one-helper audit, where present), LEMMA-G-CHECK.json (I-helper count = EXPECTED, + scalar replay); + b. the Lemma G package's code/check_extended_labels.py --mutants: (F) is read in Lemma G's extended labels; + c. code/check_owners.py --mutants: one owner per stream (disjoint footprints on shared families), centre copies; + d. code/check_windows.py --mutants: every hosted block inside its pending child's open window, blocks disjoint; + 6. with --async T.json.gz (an asynchronous hosted template, e.g. the one PR #505's verify.py emits): c. and d. on it. +Python 3.9+, standard library only; `lake` from elan on PATH (the toolchain is pinned by lean-toolchain).""" +import hashlib, json, os, re, subprocess, sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +ALLOWED = {'propext', 'Classical.choice', 'Quot.sound'} +FORBIDDEN = re.compile(r'\b(sorry|admit|axiom|native_decide|implemented_by|extern|unsafe|opaque)\b|set_option\s+(?!maxHeartbeats|maxRecDepth)') + + +def fail(msg): + print('FAIL', msg, flush=True); sys.exit(1) + + +def run(cmd, timeout): + print('$', ' '.join(cmd), flush=True) + p = subprocess.run(cmd, cwd=HERE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=timeout) + if p.returncode: + print(p.stdout[-4000:]); fail(f'{cmd[0]} {cmd[1]} exited {p.returncode}') + return p.stdout + + +def strip_comments(src): + src = re.sub(r'/-.*?-/', ' ', src, flags=re.S) # block and doc comments (not nested in these sources) + return re.sub(r'--[^\n]*', ' ', src) + + +def main(): + args = sys.argv[1:] + man = json.loads((HERE / 'MANIFEST.json').read_text()) + for rel, sha in man['files'].items(): + got = hashlib.sha256((HERE / rel).read_bytes()).hexdigest() + if got != sha: fail(f'sha256 of {rel}') + for d in ('LemmaA', 'code'): + for p in (HERE / d).rglob('*'): + if p.is_file() and '__pycache__' not in p.parts and str(p.relative_to(HERE)) not in man['files']: + fail(f'unlisted file {p.relative_to(HERE)}') + for rel, sha in man['external_files'].items(): + if hashlib.sha256((HERE / rel).read_bytes()).hexdigest() != sha: fail(f'sha256 of {rel}') + print('manifest: %d files and %d external files (Lemma G package, #484) OK' % (len(man['files']), len(man['external_files'])), flush=True) + + G = HERE.parent / 'e8-lemma-g-lean' + lean_files = (sorted(HERE.glob('LemmaA/*.lean')) + [HERE / 'LemmaA.lean', HERE / 'PrintAxioms.lean'] + + sorted(G.glob('LemmaG/*.lean')) + [G / 'LemmaG.lean']) + for p in lean_files: + m = FORBIDDEN.search(strip_comments(p.read_text())) + if m: fail(f'forbidden token {m.group(0)!r} in {p.name}') + print('sources: no sorry / admit / axiom / native_decide / unsafe / opaque / extern in %d files' % len(lean_files), flush=True) + + if '--no-cache' not in args: + run(['lake', 'exe', 'cache', 'get'], 3600) + out = run(['lake', 'build'], 3600) + print('\n'.join(l for l in out.splitlines() if 'warning' in l or 'error' in l or 'Build completed' in l), flush=True) + + out = run(['lake', 'env', 'lean', 'PrintAxioms.lean'], 1200) + wanted = [l.split()[2] for l in (HERE / 'PrintAxioms.lean').read_text().splitlines() if l.startswith('#print axioms')] + seen = {} + for m in re.finditer(r"'([\w.']+)' depends on axioms: \[([^\]]*)\]", out): + seen[m.group(1)] = [a.strip() for a in m.group(2).split(',') if a.strip()] + for m in re.finditer(r"'([\w.']+)' does not depend on any axioms", out): + seen[m.group(1)] = [] + print(out.strip(), flush=True) + for name in wanted: + if name not in seen: fail(f'no axiom report for {name}') + if not set(seen[name]) <= ALLOWED: fail(f'{name} depends on {seen[name]}') + print('axioms: %d theorems, only %s' % (len(wanted), sorted(ALLOWED)), flush=True) + + if '--instances' in args: + base = Path(args[args.index('--instances') + 1]) + words = [w for w in ('gauge80-kernel42', 'gauge80', 'kernel79', 'anchor') if (base / w / 'hosted').is_dir()] + if 'gauge80-kernel42' not in words: fail(f'{base} lacks the headline word') + E = json.loads((HERE.parent / 'e8-complex-gauge-kernel' / 'EXPECTED.json').read_text()) + for w in words: + L = json.loads((base / 'lemmaG' / w / 'LEMMA-G-CHECK.json').read_text()) + if L['inputs'] != E['lemma_G_independent_checks'][w]['inputs']: fail(f'{w}: emitted inputs differ from #484 EXPECTED.json') + if any(L['labels'][o]['n_label_violations'] or L['labels'][o]['scalar_violations'] for o in ('forward', 'backward')): + fail(f'{w}: #484 label/scalar check') + if w == 'anchor': + print('instances: anchor: #484 label and scalar checks PASS (no wrappers)', flush=True); continue + la = base / w / 'LEMMA-A.json' + if not la.exists(): fail(f'{w}: #484 LEMMA-A.json missing') + A = json.loads(la.read_text()) + if A['status'] != 'PASS_RESIDUAL_WRAPPERS_ARE_EXACT': fail(f'{w}: #484 LEMMA-A.json') + if w == 'gauge80-kernel42' and A['frames'] != E['wrapper_check']['frames']: fail('headline: #484 LEMMA-A frames') + ha = base / w / 'HOSTING-AUDIT.json' + if ha.exists(): + H = json.loads(ha.read_text()) + if not (H['status'].startswith('PASS') and H['one_helper_per_family']): fail(f'{w}: #484 hosting audit') + if L['instances']['I-helper']['failures']: fail(f'{w}: #484 I-helper') + if L['instances']['I-helper']['entering_helpers'] != E['lemma_G_independent_checks'][w]['instances']['I-helper']['entering_helpers']: + fail(f'{w}: I-helper count differs from EXPECTED.json') + print('instances: %s: #484 Lemma A exact part (%d frames), %shosting audit, I-helper %d helpers, scalar replay: PASS' + % (w, A['frames'], 'strict ' if ha.exists() else 'no ', L['instances']['I-helper']['entering_helpers']), flush=True) + out = run([sys.executable, '-B', str(HERE.parent / 'e8-lemma-g-lean' / 'code' / 'check_extended_labels.py'), str(base), *words, '--mutants'], 3600) + print('\n'.join(l for l in out.splitlines() if re.match(r'^\S+ (forward|backward) violations', l) or 'mutants (' in l + or 'extended labels' in l), flush=True) + print(run([sys.executable, '-B', 'code/check_owners.py', str(base), *words, '--mutants'], 3600).strip(), flush=True) + print(run([sys.executable, '-B', 'code/check_windows.py', *[str(base / w / 'hosted' / 'GLOBAL-TEMPLATE.json.gz') for w in words], '--mutants'], 3600).strip(), flush=True) + if '--async' in args: + tpl = args[args.index('--async') + 1] + print(run([sys.executable, '-B', 'code/check_owners.py', '--template', tpl, '16', '--mutants'], 3600).strip(), flush=True) + print(run([sys.executable, '-B', 'code/check_windows.py', tpl, '--mutants'], 3600).strip(), flush=True) + print('PASS Lemma A Lean verification', flush=True) + + +if __name__ == '__main__': + main() diff --git a/research/e8-lemma-g-lean/.gitignore b/research/e8-lemma-g-lean/.gitignore new file mode 100644 index 0000000000..2b00952692 --- /dev/null +++ b/research/e8-lemma-g-lean/.gitignore @@ -0,0 +1 @@ +.lake diff --git a/research/e8-lemma-g-lean/LICENSE b/research/e8-lemma-g-lean/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/e8-lemma-g-lean/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/e8-lemma-g-lean/LemmaG.lean b/research/e8-lemma-g-lean/LemmaG.lean new file mode 100644 index 0000000000..ce3c72d19b --- /dev/null +++ b/research/e8-lemma-g-lean/LemmaG.lean @@ -0,0 +1,4 @@ +import LemmaG.Stream +import LemmaG.Schedule +import LemmaG.Frames +import LemmaG.BitEntrance diff --git a/research/e8-lemma-g-lean/LemmaG/BitEntrance.lean b/research/e8-lemma-g-lean/LemmaG/BitEntrance.lean new file mode 100644 index 0000000000..edff353bc4 --- /dev/null +++ b/research/e8-lemma-g-lean/LemmaG/BitEntrance.lean @@ -0,0 +1,31 @@ +/- +Bit-side transfer of the entrance step: for the doubled-address frame operator +`D_P = [[1 - P, P], [P, 1 - P]]`, `D_1 · D_P = D_{1-P}` (the entrance `D_I D_E = D_{E⊥}`), and +`D_{gᵀ P g} = diag(g, g)ᵀ · D_P · diag(g, g)` for every `g` with `gᵀ g = 1`. Both hold for every +square matrix `P` over every commutative ring; nothing about roots or the field is used. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +-/ +import Mathlib.Data.Matrix.Block + +namespace LemmaG + +open Matrix + +variable {n R : Type*} [Fintype n] [DecidableEq n] [CommRing R] + +/-- The bit-side frame operator on the doubled address space. -/ +def Dbit (P : Matrix n n R) : Matrix (n ⊕ n) (n ⊕ n) R := fromBlocks (1 - P) P P (1 - P) + +/-- `D_I · D_E = D_{E⊥}` with `P_{E⊥} = 1 - P_E`. -/ +theorem Dbit_one_mul (P : Matrix n n R) : Dbit 1 * Dbit P = Dbit (1 - P) := by + simp [Dbit, fromBlocks_multiply] + +/-- Conjugation by `diag(g, g)` for `gᵀ g = 1`. -/ +theorem Dbit_conj (g P : Matrix n n R) (hg : gᵀ * g = 1) : + (fromBlocks g 0 0 g)ᵀ * Dbit P * fromBlocks g 0 0 g = Dbit (gᵀ * P * g) := by + simp only [Dbit, fromBlocks_transpose, transpose_zero, fromBlocks_multiply, Matrix.mul_zero, + Matrix.zero_mul, add_zero, zero_add, Matrix.mul_sub, Matrix.sub_mul, Matrix.mul_one, + Matrix.mul_assoc, hg] + simp only [← Matrix.mul_assoc, hg, sub_self, add_zero, zero_add] + +end LemmaG diff --git a/research/e8-lemma-g-lean/LemmaG/Frames.lean b/research/e8-lemma-g-lean/LemmaG/Frames.lean new file mode 100644 index 0000000000..33db0a3236 --- /dev/null +++ b/research/e8-lemma-g-lean/LemmaG/Frames.lean @@ -0,0 +1,47 @@ +/- +Lemma G, the frame instance: subspaces of F₂⁹ under inclusion, ranked by dimension, satisfy +the order hypotheses of `LemmaG.Schedule`. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +-/ +import LemmaG.Schedule +import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas +import Mathlib.Algebra.Field.ZMod + +namespace LemmaG + +/-- Over any division ring, dimension is strictly monotone on the subspaces of a +finite-dimensional space. -/ +theorem rank_strictMono {K V : Type*} [DivisionRing K] [AddCommGroup V] [Module K V] + [FiniteDimensional K V] : StrictMono (fun E : Submodule K V => Module.finrank K E) := + Submodule.finrank_strictMono + +instance fact_prime_two' : Fact (Nat.Prime 2) := ⟨Nat.prime_two⟩ + +/-- A frame of the word: a subspace of `F₂⁹`. -/ +abbrev Frame := Submodule (ZMod 2) (Fin 9 → ZMod 2) + +/-- The rank of a frame is its dimension. -/ +noncomputable def frameRank (E : Frame) : ℕ := Module.finrank (ZMod 2) E + +/-- Dimension is strictly monotone for inclusion. -/ +theorem frameRank_strictMono : StrictMono frameRank := + rank_strictMono (K := ZMod 2) (V := Fin 9 → ZMod 2) + +/-- The compensation segment on the frames of the word (`comp_segment` with `Λ = Frame`, +`rk = dim`). Targets start at the zero frame `⊥`, which lies below every entrance. -/ +theorem comp_segment_frames {ι K : Type*} [DecidableEq ι] [DecidableEq Frame] + (its : List (Item ι Frame K)) (l : ι → Frame) + (hdisj : ∀ a ∈ its, ∀ b ∈ its, b.mv ≠ a.pt) + (hentr : ∀ a ∈ its, l a.pt = a.F) + (hzero : ∀ a ∈ its, l a.mv = ⊥) + (hchain : ∀ a ∈ its, ∀ b ∈ its, a.mv = b.mv → a.F ≤ b.F ∨ b.F ≤ a.F) + (hsorted : its.Pairwise (fun a b => frameRank a.F ≤ frameRank b.F)) : + Stream.WellLabelled (emit l its) l ∧ + (∀ r A B, Event.relabel r A B ∈ emit l its → A < B) ∧ + (∀ a ∈ its, a.F ≤ Stream.labRun (emit l its) l a.mv ∧ + ∃ b ∈ its, b.mv = a.mv ∧ Stream.labRun (emit l its) l a.mv = b.F) ∧ + (∀ m, (∀ a ∈ its, a.mv ≠ m) → Stream.labRun (emit l its) l m = l m) := + comp_segment frameRank frameRank_strictMono its l hdisj hentr + (fun a ha => by rw [hzero a ha]; exact bot_le) hchain hsorted + +end LemmaG diff --git a/research/e8-lemma-g-lean/LemmaG/Schedule.lean b/research/e8-lemma-g-lean/LemmaG/Schedule.lean new file mode 100644 index 0000000000..d765e1ed74 --- /dev/null +++ b/research/e8-lemma-g-lean/LemmaG/Schedule.lean @@ -0,0 +1,331 @@ +/- +Lemma G, schedule part: the compensation segment and the centre scatter are well labelled, +their moves are strict nested monotone chains, and the paid ranks telescope. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. + +Frames are elements of an arbitrary partial order `Λ` with a strictly monotone rank +`rk : Λ → ℕ` (for subspaces of `F₂⁹`: inclusion and dimension, see `LemmaG.Frames`). +-/ +import LemmaG.Stream + +namespace LemmaG + +open Stream Event + +/-! ### Chains ordered by rank -/ + +section Rank + +variable {Λ : Type*} [PartialOrder Λ] {rk : Λ → ℕ} + +/-- In a chain, a rank comparison is an inclusion (PROOF.md, Claim 2). -/ +theorem le_of_rk_le (hrk : StrictMono rk) {a b : Λ} (hc : a ≤ b ∨ b ≤ a) (h : rk a ≤ rk b) : + a ≤ b := by + rcases hc with hab | hba + · exact hab + · rcases hba.lt_or_eq with hlt | heq + · exact absurd (hrk hlt) (not_lt.2 h) + · exact heq ▸ le_rfl + +/-- In a chain, equal rank is equality. -/ +theorem eq_of_rk_eq (hrk : StrictMono rk) {a b : Λ} (hc : a ≤ b ∨ b ≤ a) (h : rk a = rk b) : + a = b := + le_antisymm (le_of_rk_le hrk hc h.le) (le_of_rk_le hrk hc.symm h.ge) + +end Rank + +/-! ### The mover emitter + +A schedule is a list of gates. Each gate names a *mover* (the register that changes frame: +a target in the compensation segment, the private copy in the centre phase), a static +*partner* (the entering helper, resp. the served target or the centre register), the gate's +frame, a coefficient and a direction. The emitter moves the mover to the gate's frame when +it is not already there and then emits the gate (PROOF.md §2.4, emission steps 3 and 6). -/ + +/-- One gate of a schedule. -/ +structure Item (ι Λ K : Type*) where + mv : ι + pt : ι + F : Λ + q : K + into : Bool + +variable {ι Λ K : Type*} [DecidableEq ι] [DecidableEq Λ] + +/-- The gate: `mv += q·pt` when `into`, otherwise `pt += q·mv`. -/ +def Item.gate (it : Item ι Λ K) : Event ι Λ K := + if it.into then .add it.mv it.pt it.q else .add it.pt it.mv it.q + +/-- The move before a gate: nothing if the mover is already at the gate's frame. -/ +def Item.move (l : ι → Λ) (it : Item ι Λ K) : List (Event ι Λ K) := + if l it.mv = it.F then [] else [Event.relabel it.mv (l it.mv) it.F] + +/-- The emitted events. -/ +def emit : (ι → Λ) → List (Item ι Λ K) → List (Event ι Λ K) + | _, [] => [] + | l, it :: its => it.move l ++ (it.gate :: emit (Function.update l it.mv it.F) its) + +/-- The labels after the schedule. -/ +def moveLab : (ι → Λ) → List (Item ι Λ K) → (ι → Λ) + | l, [] => l + | l, it :: its => moveLab (Function.update l it.mv it.F) its + +omit [DecidableEq Λ] in +theorem moveLab_untouched : ∀ (its : List (Item ι Λ K)) (l : ι → Λ) (m : ι), + (∀ a ∈ its, a.mv ≠ m) → moveLab l its m = l m + | [], _, _, _ => rfl + | it :: its, l, m, h => by + simp only [moveLab] + rw [moveLab_untouched its _ m (fun a ha => h a (List.mem_cons_of_mem _ ha))] + exact Function.update_of_ne (Ne.symm (h it List.mem_cons_self)) _ _ + +omit [DecidableEq Λ] in +/-- A mover ends at the frame of one of its gates. -/ +theorem moveLab_mem : ∀ (its : List (Item ι Λ K)) (l : ι → Λ) (m : ι), + (∃ a ∈ its, a.mv = m) → ∃ a ∈ its, a.mv = m ∧ moveLab l its m = a.F + | [], _, _, ⟨_, ha, _⟩ => absurd ha List.not_mem_nil + | it :: its, l, m, _ => by + simp only [moveLab] + by_cases hlater : ∃ a ∈ its, a.mv = m + · obtain ⟨a, ha, ham, hfin⟩ := moveLab_mem its _ m hlater + exact ⟨a, List.mem_cons_of_mem _ ha, ham, hfin⟩ + · push_neg at hlater + rw [moveLab_untouched its _ m hlater] + by_cases him : it.mv = m + · subst him; exact ⟨it, List.mem_cons_self, rfl, by simp⟩ + · obtain ⟨a, ha, ham⟩ := ‹∃ a ∈ it :: its, a.mv = m› + rcases List.mem_cons.1 ha with rfl | ha' + · exact absurd ham him + · exact absurd ham (hlater a ha') + +omit [DecidableEq Λ] in +/-- If the frames of each mover are `R`-sorted (`R` transitive and reflexive), the mover ends +`R`-above every frame of its gates: with `R = (≤)` the target ends at `L_t = max ℰ_t`. -/ +theorem moveLab_top (R : Λ → Λ → Prop) (hrefl : ∀ a, R a a) + (htrans : ∀ a b c, R a b → R b c → R a c) : + ∀ (its : List (Item ι Λ K)) (l : ι → Λ), + its.Pairwise (fun a b => a.mv = b.mv → R a.F b.F) → + ∀ a ∈ its, R a.F (moveLab l its a.mv) + | [], _, _, a, ha => absurd ha List.not_mem_nil + | it :: its, l, hs, a, ha => by + simp only [moveLab] + rw [List.pairwise_cons] at hs + by_cases hlater : ∃ b ∈ its, b.mv = a.mv + · obtain ⟨b, hb, hbm⟩ := hlater + have hb' := moveLab_top R hrefl htrans its (Function.update l it.mv it.F) hs.2 b hb + rw [hbm] at hb' + rcases List.mem_cons.1 ha with rfl | ha' + · exact htrans _ _ _ (hs.1 b hb hbm.symm) hb' + · exact moveLab_top R hrefl htrans its _ hs.2 a ha' + · push_neg at hlater + rw [moveLab_untouched its _ a.mv hlater] + rcases List.mem_cons.1 ha with rfl | ha' + · simp [hrefl] + · exact absurd rfl (hlater a ha') + +/-- **Emitter lemma.** Hypotheses: partners never move; each partner sits at its gate's frame; +each mover starts `R`-below each of its frames; along the list, the frames of each mover are +`R`-sorted. Conclusions: the emitted stream is well labelled, its labels end at `moveLab`, and +every relabel it emits is a proper `R`-step. -/ +theorem emit_spec (R : Λ → Λ → Prop) : ∀ (its : List (Item ι Λ K)) (l : ι → Λ), + (∀ a ∈ its, ∀ b ∈ its, b.mv ≠ a.pt) → + (∀ a ∈ its, l a.pt = a.F) → + (∀ a ∈ its, R (l a.mv) a.F) → + its.Pairwise (fun a b => a.mv = b.mv → R a.F b.F) → + WellLabelled (emit l its) l ∧ labRun (emit l its) l = moveLab l its ∧ + (∀ r A B, Event.relabel r A B ∈ emit l its → R A B ∧ A ≠ B) + | [], _, _, _, _, _ => ⟨trivial, rfl, fun _ _ _ h => absurd h List.not_mem_nil⟩ + | it :: its, l, hpt, hptl, hinit, hsort => by + rw [List.pairwise_cons] at hsort + set l1 := Function.update l it.mv it.F with hl1 + have hne : it.mv ≠ it.pt := hpt it List.mem_cons_self it List.mem_cons_self + -- the move (possibly empty) brings the mover to the gate's frame + have hpre : labRun (it.move l) l = l1 := by + unfold Item.move; split_ifs with h + · rw [hl1]; show l = _; rw [← h]; exact (Function.update_eq_self _ _).symm + · rfl + have hwpre : WellLabelled (it.move l) l := by + unfold Item.move; split_ifs + · trivial + · exact ⟨rfl, trivial⟩ + -- the gate is admissible: both operands at the gate's frame + have hgate : it.gate.Admissible l1 := by + have h1 : l1 it.mv = it.F := by simp [hl1] + have h2 : l1 it.pt = it.F := by + rw [hl1, Function.update_of_ne (Ne.symm hne)]; exact hptl it List.mem_cons_self + unfold Item.gate; split_ifs <;> simp [Admissible, h1, h2] + have hglab : it.gate.lab l1 = l1 := by unfold Item.gate; split_ifs <;> rfl + -- the induction hypothesis for the remaining gates + have ih := emit_spec R its l1 + (fun a ha b hb => hpt a (List.mem_cons_of_mem _ ha) b (List.mem_cons_of_mem _ hb)) + (fun a ha => by + have : a.pt ≠ it.mv := fun h => + hpt a (List.mem_cons_of_mem _ ha) it List.mem_cons_self h.symm + rw [hl1, Function.update_of_ne this]; exact hptl a (List.mem_cons_of_mem _ ha)) + (fun a ha => by + by_cases ham : a.mv = it.mv + · rw [ham, hl1, Function.update_self]; exact hsort.1 a ha ham.symm + · rw [hl1, Function.update_of_ne ham]; exact hinit a (List.mem_cons_of_mem _ ha)) + hsort.2 + refine ⟨?_, ?_, ?_⟩ + · simp only [emit] + rw [wellLabelled_append, hpre] + exact ⟨hwpre, hgate, by rw [hglab]; exact ih.1⟩ + · simp only [emit, moveLab] + rw [labRun_append, hpre] + show labRun (emit l1 its) (it.gate.lab l1) = moveLab l1 its + rw [hglab]; exact ih.2.1 + · intro r A B hmem + simp only [emit, List.mem_append, List.mem_cons] at hmem + rcases hmem with hm | hm | hm + · unfold Item.move at hm + split_ifs at hm with h + · exact absurd hm List.not_mem_nil + · rw [List.mem_singleton] at hm + cases hm + exact ⟨hinit it List.mem_cons_self, h⟩ + · unfold Item.gate at hm; split_ifs at hm + · exact ih.2.2 r A B hm + +/-- **Exactness needs no order condition.** The emitted stream is well labelled as soon as the +partners never move and each partner sits at its gate's frame: (a)–(d) are not used. -/ +theorem emit_wellLabelled (its : List (Item ι Λ K)) (l : ι → Λ) + (hpt : ∀ a ∈ its, ∀ b ∈ its, b.mv ≠ a.pt) (hptl : ∀ a ∈ its, l a.pt = a.F) : + WellLabelled (emit l its) l := + (emit_spec (fun _ _ => True) its l hpt hptl (fun _ _ => trivial) + (List.pairwise_of_forall (fun _ _ _ => trivial))).1 + +/-! ### Clause (b): the compensation segment (Claims 1 and 2) -/ + +/-- **Compensation segment.** The gates `y_t += c·x_j` (mover = target `t`, partner = gauge +helper `j`, frame `E_j`), emitted in order of rank. Hypotheses: helpers are not targets; +each helper is at its entrance label (virtual entrance, untouched before); each target starts +below each of its entrances (at `0`); (b) the entrances of each target form a chain. Then the +segment is well labelled, every climb it emits is a strict nested ascent, and each target ends +at the largest of its entrances `L_t` (above all, and attained). -/ +theorem comp_segment [PartialOrder Λ] (rk : Λ → ℕ) (hrk : StrictMono rk) + (its : List (Item ι Λ K)) (l : ι → Λ) + (hdisj : ∀ a ∈ its, ∀ b ∈ its, b.mv ≠ a.pt) + (hentr : ∀ a ∈ its, l a.pt = a.F) + (hbot : ∀ a ∈ its, l a.mv ≤ a.F) + (hchain : ∀ a ∈ its, ∀ b ∈ its, a.mv = b.mv → a.F ≤ b.F ∨ b.F ≤ a.F) + (hsorted : its.Pairwise (fun a b => rk a.F ≤ rk b.F)) : + WellLabelled (emit l its) l ∧ + (∀ r A B, Event.relabel r A B ∈ emit l its → A < B) ∧ + (∀ a ∈ its, a.F ≤ labRun (emit l its) l a.mv ∧ + ∃ b ∈ its, b.mv = a.mv ∧ labRun (emit l its) l a.mv = b.F) ∧ + (∀ m, (∀ a ∈ its, a.mv ≠ m) → labRun (emit l its) l m = l m) := by + have hle : its.Pairwise (fun a b => a.mv = b.mv → a.F ≤ b.F) := + hsorted.imp_of_mem (fun ha hb hr hm => le_of_rk_le hrk (hchain _ ha _ hb hm) hr) + obtain ⟨hw, hlab, hrel⟩ := emit_spec (· ≤ ·) its l hdisj hentr hbot hle + refine ⟨hw, fun r A B h => lt_of_le_of_ne (hrel r A B h).1 (hrel r A B h).2, ?_, ?_⟩ + · intro a ha + rw [hlab] + exact ⟨moveLab_top (· ≤ ·) (fun _ => le_rfl) (fun _ _ _ => le_trans) its l hle a ha, + moveLab_mem its l a.mv ⟨a, ha, rfl⟩⟩ + · intro m hm; rw [hlab]; exact moveLab_untouched its l m hm + +/-! ### Clause (c): the centre phase (Claim 4) -/ + +/-- **Centre phase, forward orientation.** Copy the centre register `r` (label `c`) into the +private register `C`, then descend through the levels of the served targets in order of +decreasing rank, scattering `y_t += q·C` at each level, then clear `C`. Hypotheses: the copy +register is neither the centre register nor a served target; the centre register is at `c`; +each served target is at its level; (c) the levels form a chain inside `c`. Then the phase is +well labelled and every centre step is a strict nested descent. -/ +theorem centre_forward [PartialOrder Λ] (rk : Λ → ℕ) (hrk : StrictMono rk) + (C r : ι) (c : Λ) (its : List (Item ι Λ K)) (l : ι → Λ) (Fend : Λ) + (hmv : ∀ a ∈ its, a.mv = C) (hCpt : ∀ a ∈ its, a.pt ≠ C) + (hr : l r = c) (hlev : ∀ a ∈ its, l a.pt = a.F) + (hin : ∀ a ∈ its, a.F ≤ c) + (hchain : ∀ a ∈ its, ∀ b ∈ its, a.F ≤ b.F ∨ b.F ≤ a.F) + (hsorted : its.Pairwise (fun a b => rk b.F ≤ rk a.F)) : + WellLabelled ([Event.copy C r c] ++ emit (Function.update l C c) its ++ [Event.clear C Fend]) l ∧ + (∀ r' A B, Event.relabel r' A B ∈ emit (Function.update l C c) its → B < A) := by + have hge : its.Pairwise (fun a b => a.mv = b.mv → b.F ≤ a.F) := + hsorted.imp_of_mem (fun ha hb hr' _ => le_of_rk_le hrk (hchain _ hb _ ha) hr') + have hspec := emit_spec (fun a b => b ≤ a) its (Function.update l C c) + (fun a _ b hb => by rw [hmv b hb]; exact (hCpt a ‹_›).symm) + (fun a ha => by rw [Function.update_of_ne (hCpt a ha)]; exact hlev a ha) + (fun a ha => by rw [hmv a ha, Function.update_self]; exact hin a ha) + hge + refine ⟨?_, fun r' A B h => lt_of_le_of_ne (hspec.2.2 r' A B h).1 (Ne.symm (hspec.2.2 r' A B h).2)⟩ + rw [wellLabelled_append, wellLabelled_append] + refine ⟨⟨⟨hr, trivial⟩, ?_⟩, ?_⟩ + · exact hspec.1 + · exact ⟨trivial, trivial⟩ + +/-- **Centre phase, backward orientation.** Clear `C` at the bottom level, ascend through the +levels in order of increasing rank gathering `C += q·y_t`, finally `r += -C` at `c` (the last +gate, partner `r` at frame `c`). Hypotheses as in the forward orientation, with the gates now +sorted by increasing rank and the final gate at `c`. Then the phase is well labelled and every +centre step is a strict nested ascent. -/ +theorem centre_backward [PartialOrder Λ] (rk : Λ → ℕ) (hrk : StrictMono rk) + (C : ι) (bottom : Λ) (its : List (Item ι Λ K)) (l : ι → Λ) + (hmv : ∀ a ∈ its, a.mv = C) (hCpt : ∀ a ∈ its, a.pt ≠ C) + (hlev : ∀ a ∈ its, l a.pt = a.F) + (hbot : ∀ a ∈ its, bottom ≤ a.F) + (hchain : ∀ a ∈ its, ∀ b ∈ its, a.F ≤ b.F ∨ b.F ≤ a.F) + (hsorted : its.Pairwise (fun a b => rk a.F ≤ rk b.F)) : + WellLabelled ([Event.clear C bottom] ++ emit (Function.update l C bottom) its) l ∧ + (∀ r' A B, Event.relabel r' A B ∈ emit (Function.update l C bottom) its → A < B) := by + have hle : its.Pairwise (fun a b => a.mv = b.mv → a.F ≤ b.F) := + hsorted.imp_of_mem (fun ha hb hr' _ => le_of_rk_le hrk (hchain _ ha _ hb) hr') + have hspec := emit_spec (· ≤ ·) its (Function.update l C bottom) + (fun a _ b hb => by rw [hmv b hb]; exact (hCpt a ‹_›).symm) + (fun a ha => by rw [Function.update_of_ne (hCpt a ha)]; exact hlev a ha) + (fun a ha => by rw [hmv a ha, Function.update_self]; exact hbot a ha) + hle + refine ⟨?_, fun r' A B h => lt_of_le_of_ne (hspec.2.2 r' A B h).1 (hspec.2.2 r' A B h).2⟩ + rw [wellLabelled_append] + exact ⟨⟨trivial, trivial⟩, hspec.1⟩ + +/-! ### Accounting: paid ranks telescope -/ + +/-- The paid rank of the relabels of register `m` in a stream: `|rk B - rk A|` per relabel. -/ +def paid (rk : Λ → ℕ) (m : ι) : List (Event ι Λ K) → ℕ + | [] => 0 + | Event.relabel r A B :: es => (if r = m then ((rk B : ℤ) - rk A).natAbs else 0) + paid rk m es + | _ :: es => paid rk m es + +omit [DecidableEq Λ] in +/-- **Telescoping.** If every relabel of `m` in a well-labelled stream is rank-ascending and +nothing copies into or clears `m`, the paid rank of `m` is `rk λ¹(m) - rk λ⁰(m)`. Nested +ascents (clause G2) are rank-ascending. -/ +theorem paid_telescopes (rk : Λ → ℕ) (m : ι) : + ∀ (es : List (Event ι Λ K)) (l : ι → Λ), WellLabelled es l → + (∀ A B, Event.relabel m A B ∈ es → rk A ≤ rk B) → + (∀ e ∈ es, ∀ F, (∀ r, e ≠ Event.copy m r F) ∧ e ≠ Event.clear m F) → + (paid rk m es : ℤ) = rk (labRun es l m) - rk (l m) + | [], _, _, _, _ => by simp [paid, labRun] + | e :: es, l, hw, hasc, hcc => by + have ih := paid_telescopes rk m es (e.lab l) hw.2 + (fun A B h => hasc A B (List.mem_cons_of_mem _ h)) + (fun e' he' => hcc e' (List.mem_cons_of_mem _ he')) + have hcc0 := hcc e List.mem_cons_self + simp only [labRun] + cases e with + | relabel r A B => + have hA : l r = A := hw.1 + simp only [paid, Nat.cast_add, ih] + by_cases hrm : r = m + · subst hrm + have hab := hasc A B List.mem_cons_self + simp only [Event.lab, Function.update_self, if_true] + rw [Int.natAbs_of_nonneg (by omega), hA] + omega + · have h1 : (Event.relabel r A B : Event ι Λ K).lab l m = l m := + Function.update_of_ne (Ne.symm hrm) _ _ + rw [h1]; simp [hrm] + | add t s q => simpa [paid, Event.lab] using ih + | scale t q => simpa [paid, Event.lab] using ih + | copy c r F => + have hc : c ≠ m := fun h => (hcc0 F).1 r (by rw [h]) + simp only [paid] + rw [ih]; simp [Event.lab, Function.update_of_ne (Ne.symm hc)] + | clear c F => + have hc : c ≠ m := fun h => (hcc0 F).2 (by rw [h]) + simp only [paid] + rw [ih]; simp [Event.lab, Function.update_of_ne (Ne.symm hc)] + +end LemmaG diff --git a/research/e8-lemma-g-lean/LemmaG/Stream.lean b/research/e8-lemma-g-lean/LemmaG/Stream.lean new file mode 100644 index 0000000000..e898971903 --- /dev/null +++ b/research/e8-lemma-g-lean/LemmaG/Stream.lean @@ -0,0 +1,356 @@ +/- +Lemma G, semantic part: the common-frame conjugation lemma for labelled event streams. +Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. + +A register file is a function `ι → M`. Every register also carries a label in `Λ` +(a frame, possibly tagged by its conversion phase; see PROOF.md §1). A family +`T : Λ → M ≃ₗ[K] M` of linear automorphisms gives each label its operator. The +physical program executes the events below; the label program tracks the labels; the +scalar shadow is the same program with every relabel deleted. + +Main results: +* `Stream.conj` physical run = D(λ¹) ∘ scalar shadow ∘ D(λ⁰)⁻¹ (operator form); +* `Stream.conj_matrix` the same with the scalar shadow written as its matrix `S`; +* `Stream.row_unit`, `Stream.row_pair` the two row shapes used by the word. +Nothing about the field, the frames or the operators is used beyond: `K` is a semiring, +`M` a `K`-module, every `T F` is a `K`-linear bijection. +-/ +import Mathlib.Algebra.Module.Equiv.Defs +import Mathlib.Algebra.Module.Pi +import Mathlib.Algebra.BigOperators.Pi +import Mathlib.Algebra.Module.LinearMap.Basic +import Mathlib.LinearAlgebra.Span.Basic + +namespace LemmaG + +/-- The events of an emitted local program (PROOF.md §1.1). `relabel r A B` covers climbs, +centre steps, data adapters and residual wrappers: the register `r` moves from label `A` +to label `B` and the hardware executes a fixed recipe. -/ +inductive Event (ι Λ K : Type*) where + | relabel (r : ι) (A B : Λ) + | add (t s : ι) (q : K) + | scale (t : ι) (q : K) + | copy (c r : ι) (F : Λ) + | clear (c : ι) (F : Λ) + +namespace Event + +variable {ι Λ K : Type*} [DecidableEq ι] + +section Semantics + +variable [Semiring K] {M : Type*} [AddCommMonoid M] [Module K M] + +/-- Physical effect. `rec A B` is the operator the hardware executes for `relabel _ A B` +(the serialized recipe). -/ +def phys (rec : Λ → Λ → M → M) : Event ι Λ K → (ι → M) → (ι → M) + | relabel r A B, h => Function.update h r (rec A B (h r)) + | add t s q, h => Function.update h t (h t + q • h s) + | scale t q, h => Function.update h t (q • h t) + | copy c r _, h => Function.update h c (h r) + | clear c _, h => Function.update h c 0 + +/-- Scalar shadow: the same event with the frames stripped (a relabel does nothing). -/ +def scal (e : Event ι Λ K) : (ι → M) → (ι → M) := e.phys (fun _ _ v => v) + +end Semantics + +/-- Label effect. -/ +def lab : Event ι Λ K → (ι → Λ) → (ι → Λ) + | relabel r _ B, l => Function.update l r B + | copy c _ F, l => Function.update l c F + | clear c F, l => Function.update l c F + | add .., l => l + | scale .., l => l + +/-- The label condition of one event (clause G0 together with the source label of a +relabel). This is the whole hypothesis on the labels. -/ +def Admissible : Event ι Λ K → (ι → Λ) → Prop + | relabel r A _, l => l r = A + | add t s _, l => l t = l s + | copy _ r F, l => l r = F + | scale .., _ => True + | clear .., _ => True + +/-- The registers an event can relabel. -/ +def moves : Event ι Λ K → ι → Prop + | relabel r _ _, i => i = r + | copy c _ _, i => i = c + | clear c _, i => i = c + | add .., _ => False + | scale .., _ => False + +end Event + +namespace Stream + +open Event + +variable {ι Λ K : Type*} [DecidableEq ι] [Semiring K] +variable {M : Type*} [AddCommMonoid M] [Module K M] + +/-- Run a list of events physically (left to right). -/ +def physRun (rec : Λ → Λ → M → M) : List (Event ι Λ K) → (ι → M) → (ι → M) + | [], h => h + | e :: es, h => physRun rec es (e.phys rec h) + +/-- The scalar shadow of a stream. -/ +def scalRun (es : List (Event ι Λ K)) : (ι → M) → (ι → M) := physRun (fun _ _ v => v) es + +/-- The labels after a stream. -/ +def labRun : List (Event ι Λ K) → (ι → Λ) → (ι → Λ) + | [], l => l + | e :: es, l => labRun es (e.lab l) + +/-- Every event is admissible at the labels current when it runs. -/ +def WellLabelled : List (Event ι Λ K) → (ι → Λ) → Prop + | [], _ => True + | e :: es, l => e.Admissible l ∧ WellLabelled es (e.lab l) + +/-- Every relabel of the stream executes exactly `T B ∘ (T A)⁻¹`. -/ +def RecipesExact (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) : Prop := + ∀ r A B, Event.relabel r A B ∈ es → ∀ v, rec A B v = T B ((T A).symm v) + +/-- Register-wise label operator `D(λ)`. -/ +def D (T : Λ → M ≃ₗ[K] M) (l : ι → Λ) (x : ι → M) : ι → M := fun r => T (l r) (x r) + +/-- Its inverse `D(λ)⁻¹`. -/ +def Dinv (T : Λ → M ≃ₗ[K] M) (l : ι → Λ) (h : ι → M) : ι → M := fun r => (T (l r)).symm (h r) + +omit [DecidableEq ι] in +theorem D_Dinv (T : Λ → M ≃ₗ[K] M) (l : ι → Λ) (h : ι → M) : D T l (Dinv T l h) = h := by + funext r; simp [D, Dinv] + +/-- One step of the invariant `h = D(λ) ℓ`. -/ +theorem step (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (e : Event ι Λ K) (l : ι → Λ) + (x : ι → M) (hrec : ∀ r A B, e = Event.relabel r A B → ∀ v, rec A B v = T B ((T A).symm v)) + (ha : e.Admissible l) : + e.phys rec (D T l x) = D T (e.lab l) (e.scal x) := by + cases e with + | relabel r A B => + have hr := hrec r A B rfl + simp only [Admissible] at ha + funext i + by_cases hi : i = r + · subst hi; simp [phys, scal, lab, D, hr, ha] + · simp [phys, scal, lab, D, Function.update_of_ne hi] + | add t s q => + simp only [Admissible] at ha + funext i + by_cases hi : i = t + · subst hi; simp [phys, scal, lab, D, ha] + · simp [phys, scal, lab, D, Function.update_of_ne hi] + | scale t q => + funext i + by_cases hi : i = t + · subst hi; simp [phys, scal, lab, D] + · simp [phys, scal, lab, D, Function.update_of_ne hi] + | copy c r F => + simp only [Admissible] at ha + funext i + by_cases hi : i = c + · subst hi; simp [phys, scal, lab, D, ha] + · simp [phys, scal, lab, D, Function.update_of_ne hi] + | clear c F => + funext i + by_cases hi : i = c + · subst hi; simp [phys, scal, lab, D] + · simp [phys, scal, lab, D, Function.update_of_ne hi] + +/-- **Conjugation lemma (operator form).** For a well-labelled stream whose relabels execute +`T B ∘ (T A)⁻¹`, the physical program equals `D(λ¹) ∘ (scalar shadow) ∘ D(λ⁰)⁻¹`. -/ +theorem conj (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) : + ∀ (es : List (Event ι Λ K)) (l : ι → Λ) (x : ι → M), + RecipesExact T rec es → WellLabelled es l → + physRun rec es (D T l x) = D T (labRun es l) (scalRun es x) + | [], _, _, _, _ => rfl + | e :: es, l, x, hrec, hw => by + have h1 := step T rec e l x + (fun r A B he v => hrec r A B (he ▸ List.mem_cons_self ..) v) hw.1 + have h2 := conj T rec es (e.lab l) (e.scal x) + (fun r A B hm v => hrec r A B (List.mem_cons_of_mem _ hm) v) hw.2 + simp only [physRun, scalRun, labRun] at h2 ⊢ + rw [h1, h2] + rfl + +theorem conj' (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (h : ι → M) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) : + physRun rec es h = D T (labRun es l) (scalRun es (Dinv T l h)) := by + rw [← conj T rec es l _ hrec hw, D_Dinv] + +/-! ### The scalar shadow is a matrix -/ + +section Matrix + +variable {N : Type*} [AddCommMonoid N] [Module K N] + +theorem scal_map (φ : M →ₗ[K] N) (e : Event ι Λ K) (x : ι → M) : + e.scal (fun i => φ (x i)) = fun i => φ (e.scal x i) := by + funext i + cases e with + | relabel r A B => by_cases hi : i = r <;> simp [scal, phys, Function.update_apply, hi] + | add t s q => by_cases hi : i = t <;> simp [scal, phys, Function.update_apply, hi] + | scale t q => by_cases hi : i = t <;> simp [scal, phys, Function.update_apply, hi] + | copy c r F => by_cases hi : i = c <;> simp [scal, phys, Function.update_apply, hi] + | clear c F => by_cases hi : i = c <;> simp [scal, phys, Function.update_apply, hi] + +theorem scalRun_map (φ : M →ₗ[K] N) : + ∀ (es : List (Event ι Λ K)) (x : ι → M), + scalRun es (fun i => φ (x i)) = fun i => φ (scalRun es x i) + | [], _ => rfl + | e :: es, x => by + show scalRun es (e.scal (fun i => φ (x i))) = fun i => φ (scalRun es (e.scal x) i) + rw [scal_map φ e x] + exact scalRun_map φ es (e.scal x) + +theorem scal_add (e : Event ι Λ K) (x y : ι → M) : e.scal (x + y) = e.scal x + e.scal y := by + funext i + cases e with + | relabel r A B => by_cases hi : i = r <;> simp [scal, phys, Function.update_apply, hi] + | add t s q => + by_cases hi : i = t <;> simp [scal, phys, Function.update_apply, hi, smul_add, add_add_add_comm] + | scale t q => by_cases hi : i = t <;> simp [scal, phys, Function.update_apply, hi, smul_add] + | copy c r F => by_cases hi : i = c <;> simp [scal, phys, Function.update_apply, hi] + | clear c F => by_cases hi : i = c <;> simp [scal, phys, Function.update_apply, hi] + +theorem scal_zero (e : Event ι Λ K) : e.scal (0 : ι → M) = 0 := by + funext i + cases e with + | relabel r A B => by_cases hi : i = r <;> simp [scal, phys, Function.update_apply, hi] + | add t s q => by_cases hi : i = t <;> simp [scal, phys, Function.update_apply, hi] + | scale t q => by_cases hi : i = t <;> simp [scal, phys, Function.update_apply, hi] + | copy c r F => by_cases hi : i = c <;> simp [scal, phys, Function.update_apply, hi] + | clear c F => by_cases hi : i = c <;> simp [scal, phys, Function.update_apply, hi] + +theorem scalRun_add : ∀ (es : List (Event ι Λ K)) (x y : ι → M), + scalRun es (x + y) = scalRun es x + scalRun es y + | [], _, _ => rfl + | e :: es, x, y => by + show scalRun es (e.scal (x + y)) = scalRun es (e.scal x) + scalRun es (e.scal y) + rw [scal_add e x y] + exact scalRun_add es _ _ + +theorem scalRun_zero : ∀ (es : List (Event ι Λ K)), scalRun es (0 : ι → M) = 0 + | [] => rfl + | e :: es => by + show scalRun es (e.scal (0 : ι → M)) = 0 + rw [scal_zero e] + exact scalRun_zero es + +/-- The scalar shadow as an additive map. -/ +def scalHom (es : List (Event ι Λ K)) : (ι → M) →+ (ι → M) where + toFun := scalRun es + map_zero' := scalRun_zero es + map_add' := scalRun_add es + +/-- The matrix of the scalar shadow: `S r s` is the coefficient of the input of register `s` +in the output of register `r` (replay over `K` on the basis column `s`). -/ +def S (es : List (Event ι Λ K)) (r s : ι) : K := scalRun es (Pi.single s (1 : K)) r + +/-- The same matrix, read row-wise from one symbolic replay in which register `i` holds the +basis vector `eᵢ` (this is how the checker `lg_lib.scalar_replay` computes it). -/ +theorem S_rowform (es : List (Event ι Λ K)) (r s : ι) : + scalRun es (fun i => (Pi.single i (1 : K) : ι → K)) r s = S es r s := by + let ev : (ι → K) →ₗ[K] K := + { toFun := fun v => v s + map_add' := fun _ _ => rfl + map_smul' := fun _ _ => rfl } + have h := congrFun (scalRun_map (M := ι → K) (N := K) ev es + (fun i => (Pi.single i (1 : K) : ι → K))) r + simp only [ev, LinearMap.coe_mk, AddHom.coe_mk] at h + rw [← h, S] + congr 1 + funext i + by_cases hi : i = s + · subst hi; simp + · simp [Pi.single_apply, hi, Ne.symm hi] + +variable [Fintype ι] + +/-- **The scalar shadow acts on any module through its matrix.** -/ +theorem scalRun_eq_sum (es : List (Event ι Λ K)) (x : ι → M) (r : ι) : + scalRun es x r = ∑ s, S es r s • x s := by + have hx : x = ∑ s, Pi.single s (x s) := (Finset.univ_sum_single x).symm + have hcol : ∀ s, scalRun es (Pi.single s (x s)) r = S es r s • x s := by + intro s + let φ : K →ₗ[K] M := + { toFun := fun k => k • x s + map_add' := fun a b => add_smul a b (x s) + map_smul' := fun a b => by simp [mul_smul] } + have e1 : (Pi.single s (x s) : ι → M) = fun i => φ ((Pi.single s (1 : K) : ι → K) i) := by + funext i + by_cases hi : i = s + · subst hi; simp [φ] + · simp [φ, Pi.single_apply, hi] + rw [e1, scalRun_map φ es] + simp [S, φ] + calc scalRun es x r = scalHom es x r := rfl + _ = scalHom es (∑ s, Pi.single s (x s)) r := by rw [← hx] + _ = ∑ s, scalHom es (Pi.single s (x s)) r := by rw [map_sum, Finset.sum_apply] + _ = ∑ s, S es r s • x s := Finset.sum_congr rfl (fun s _ => hcol s) + +/-- **Conjugation lemma, matrix form (Lemma G (G-ii)).** For every input `h`, +`h_r(final) = T_{λ¹ r} (∑ₛ S r s • T_{λ⁰ s}⁻¹ hₛ)`. -/ +theorem conj_matrix (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (h : ι → M) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (r : ι) : + physRun rec es h r = T (labRun es l r) (∑ s, S es r s • (T (l s)).symm (h s)) := by + rw [conj' T rec es l h hrec hw] + simp only [D] + rw [scalRun_eq_sum] + rfl + +/-- A unit row (`S r = eᵣ`): register `r` ends as `T_{λ¹ r} T_{λ⁰ r}⁻¹ hᵣ` and no other input +reaches it. Sources (forward), targets (backward) and all helpers; for an entering helper +`λ⁰ = E_j`, which is the virtual entrance. -/ +theorem row_unit (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (h : ι → M) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (r : ι) + (hS : ∀ s, S es r s = if s = r then 1 else 0) : + physRun rec es h r = T (labRun es l r) ((T (l r)).symm (h r)) := by + rw [conj_matrix T rec es l h hrec hw r] + congr 1 + simp [hS, ite_smul] + +/-- A paired row (`S r = eᵣ + a·e_{s₀}`): targets (forward, `a = 1`) and sources +(backward, `a = -1`). -/ +theorem row_pair (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (h : ι → M) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (r s₀ : ι) + (a : K) (hS : ∀ s, S es r s = (if s = r then 1 else 0) + (if s = s₀ then a else 0)) : + physRun rec es h r = + T (labRun es l r) ((T (l r)).symm (h r) + a • (T (l s₀)).symm (h s₀)) := by + rw [conj_matrix T rec es l h hrec hw r] + congr 1 + simp [hS, add_smul, ite_smul, Finset.sum_add_distrib] + +end Matrix + +/-! ### Composition facts used by the schedule lemma -/ + +omit [Semiring K] in +theorem labRun_append : ∀ (a b : List (Event ι Λ K)) (l : ι → Λ), + labRun (a ++ b) l = labRun b (labRun a l) + | [], _, _ => rfl + | _ :: a, b, _ => labRun_append a b _ + +omit [Semiring K] in +theorem wellLabelled_append : ∀ (a b : List (Event ι Λ K)) (l : ι → Λ), + WellLabelled (a ++ b) l ↔ WellLabelled a l ∧ WellLabelled b (labRun a l) + | [], _, _ => by simp [WellLabelled, labRun] + | e :: a, b, l => by + simp only [List.cons_append, WellLabelled, labRun] + rw [wellLabelled_append a b] + tauto + +omit [Semiring K] in +/-- A stream that never relabels register `i` leaves its label unchanged (Claim 3). -/ +theorem labRun_untouched : ∀ (es : List (Event ι Λ K)) (l : ι → Λ) (i : ι), + (∀ e ∈ es, ¬ e.moves i) → labRun es l i = l i + | [], _, _, _ => rfl + | e :: es, l, i, h => by + simp only [labRun] + rw [labRun_untouched es _ i (fun e' he' => h e' (List.mem_cons_of_mem _ he'))] + have hi := h e List.mem_cons_self + cases e <;> simp_all [Event.lab, Event.moves, Function.update_of_ne] + +end Stream + +end LemmaG diff --git a/research/e8-lemma-g-lean/MANIFEST.json b/research/e8-lemma-g-lean/MANIFEST.json new file mode 100644 index 0000000000..21c920953e --- /dev/null +++ b/research/e8-lemma-g-lean/MANIFEST.json @@ -0,0 +1,53 @@ +{ + "format": "e8-lemma-g-lean-v1", + "lean_toolchain": "leanprover/lean4:v4.21.0", + "mathlib": { + "inputRev": "v4.21.0", + "rev": "308445d7985027f538e281e18df29ca16ede2ba3" + }, + "library": "LemmaG", + "modules": [ + "LemmaG.Stream", + "LemmaG.Schedule", + "LemmaG.Frames", + "LemmaG.BitEntrance" + ], + "main_theorem": "LemmaG.Stream.conj_matrix", + "axiom_probe": "PrintAxioms.lean", + "allowed_axioms": [ + "Classical.choice", + "Quot.sound", + "propext" + ], + "instance_checks": [ + "code/check_extended_labels.py", + "code/check_adapters.py" + ], + "instance_input": "the output directory of PR #484 verify.py", + "external_files": { + "../e8-complex-gauge-kernel/EXPECTED.json": "de9e2ade14c2f390759230850377d48c28b16a28c955669fa89c535fcc228113", + "../e8-complex-gauge-kernel/code/lemmaG/lg_lib.py": "e7db756ad091055b79e90e53d9cecda632a185a11ee3f095eed5d32757f87490", + "../e8-complex-gauge-kernel/code/lemmaG/lg_phys.py": "0ca37829b596d83d0b94c5f0b6b278a100f22e626b2ab3b5210a38f9657c8a27", + "../e8-complex-gauge-kernel/code/lemmaG/gd.py": "64cdb2cfefc9ec3ed80c277a18848778427c3d3dbda9b7be13f740522478e1de", + "../split-centres-global/vendor/clifford_exact.py": "2982ead07721e83358dc67c6f49c2b4c16a236a6bebdfd72f58221be1f5d0962" + }, + "files": { + ".gitignore": "d4e3917adcfaaa8d53ccc3eb2c9c3423307b0de18d8efbb32e3a92aa53ffb0f9", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "LemmaG.lean": "ac5ab476d9c8e29de95b92844bdb3d9a59f108dfffb89c31ea65e413d0f4c09b", + "LemmaG/BitEntrance.lean": "49872d04ec0cb0035a741075e3d593563a55ba8b5642cd225a8d06c166e890c8", + "LemmaG/Frames.lean": "64e9bf83af211fd75ac2c7877b98604b11e2ba90b8e918435b92d0dcea0ccef7", + "LemmaG/Schedule.lean": "df2c5feb64185810038b5095abc41c5455de3499b584acfea53c607233703ebb", + "LemmaG/Stream.lean": "7138f4b859d0574a803e99401f05ef5e0ec9eeac0eb480775cd9b86595c365f8", + "NOTICE.md": "41b01b1317c56c28d0606086e429fb1121dab2d17db58d7932b27d2bb4ad38b8", + "PROOF.md": "2a7d84a83d34495dcf46ff9241ee3d7ec18ffc7d49c5476ab15fe0834046f2a3", + "PrintAxioms.lean": "6f3032539edaf260f66c9cf65d152f15d3735245ca9919fb5f4c921223e2436d", + "README.md": "2fce420252f63e9ef6e427bdcf3a788fea3c13740d59bd2f048b6875840018e9", + "code/check_adapters.py": "c3b0739a3ffaa5bdf1d6abda93bcc773f758a00f745bf05e13eb6948ea685c86", + "code/check_extended_labels.py": "9e072754d350e79e5657196bee30cd18ed0a0677628aa66d16a15ce2aab1d2ea", + "lake-manifest.json": "a6082ec3e086d463f5eb3ba1befdbec45e868e2b328c6b066e25fcc82d1353f8", + "lakefile.toml": "0d6ef7ebfd0c900dde7c8b5075ec4b7b47942e801dc5effb4288e078c17e203b", + "lean-toolchain": "d24fed434d3b13adfaab57724a0a7f270ea8bf1c818b5ae5cf25cbce24dd685c", + "verify.py": "de50182c753b4d17e88c7fb9b7efa322b4494e6fe33cef9254ceb6513a978b8f" + } +} diff --git a/research/e8-lemma-g-lean/NOTICE.md b/research/e8-lemma-g-lean/NOTICE.md new file mode 100644 index 0000000000..c3e27c84a8 --- /dev/null +++ b/research/e8-lemma-g-lean/NOTICE.md @@ -0,0 +1,7 @@ +Apache-2.0 (see `LICENSE`). Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. + +The Lean sources are new. They formalise Lemma G of PR #484 (DreamingOfClouds), which reduces to PR #425's common-frame +conjugation lemma (jacklightChen / Zhihao Chen, OpenAI Codex), PR #458's one-helper rule and paid wrappers (chafreaky) and +PR #471's virtual entrance (Dugongue). The toolchain and Mathlib pin are those of `formal/lean` on main; the package layout +and axiom reporting follow PRs #487/#488 (jamesyc). `code/check_extended_labels.py` imports PR #484's +`research/e8-complex-gauge-kernel/code/lemmaG/lg_lib.py` (read-only) to load the emitted artefacts. diff --git a/research/e8-lemma-g-lean/PROOF.md b/research/e8-lemma-g-lean/PROOF.md new file mode 100644 index 0000000000..6b24da0ab8 --- /dev/null +++ b/research/e8-lemma-g-lean/PROOF.md @@ -0,0 +1,182 @@ +# Lemma G: clean statement and proof + +Lemma G is the entrance-gauge lemma of PR #484 (`research/e8-complex-gauge-kernel/PROOF.md` §2): target-side compensation at nonzero +frames, labelled targets, and the centre scatter along a chain. This file splits it into + +* **(i) an abstract lemma**, proved once for all: Theorems 1–4 below, formalised in Lean (`LemmaG/*.lean`, names in brackets), and +* **(ii) instance hypotheses H1–H6** on the emitted streams, checked exhaustively by Python: #484's stage `code/lemmaG/` and + this package's `code/check_extended_labels.py`. + +§5 lists what changed relative to #484's §2. + +## 1. Setting + +* `K` is a semiring and `M` is a `K`-module. For the word, `K = Q` and `M = C^(2^9)`, which is a `Q`-module. +* `Λ` is a set of labels. `T : Λ → (M ≃ₗ[K] M)` gives each label a linear automorphism. Nothing else about `T` is used. +* `ι` is a finite set of registers. A state is `h : ι → M` and a labelling is `λ : ι → Λ`. +* The events and their effects: + +| event | physical effect | label effect | admissible at `λ` iff | +| --- | --- | --- | --- | +| `relabel r A B` | `h_r ← rec(A,B) h_r` | `λ_r := B` | `λ_r = A` | +| `add t s q` | `h_t ← h_t + q·h_s` | none | `λ_t = λ_s` | +| `scale t q` | `h_t ← q·h_t` | none | always | +| `copy c r F` | `h_c ← h_r` | `λ_c := F` | `λ_r = F` | +| `clear c F` | `h_c ← 0` | `λ_c := F` | always | + +* `rec(A,B)` is the operator the hardware executes, i.e. the serialized recipe. +* A stream `es` is **well labelled** from `λ⁰` if every event is admissible at the labels current when it runs (`WellLabelled`). +* Its **recipes are exact** if every `relabel r A B` in `es` executes `T_B T_A⁻¹` (`RecipesExact`). +* `λ¹ = labRun es λ⁰` is the final labelling. +* The **scalar shadow** `scal_es` is `es` with every relabel deleted, run on any `K`-module (`scalRun`). +* Its matrix is `S_rs := (scal_es e_s)_r` over `K` (`S`). Here `e_s` is the basis column. +* `D(λ)h := (T_{λ_r} h_r)_r` (`D`, `Dinv`). + +## 2. Exactness + +**Theorem 1 (common-frame conjugation)** [`Stream.conj`, `Stream.conj'`, `Stream.conj_matrix`]. Let `es` be well labelled from `λ⁰`, with exact recipes. +* Operator form: `physRun es = D(λ¹) ∘ scal_es ∘ D(λ⁰)⁻¹`. +* Matrix form: for every input `h` and every register `r`, + + `h_r(final) = T_{λ¹_r} ( Σ_s S_rs · T_{λ⁰_s}⁻¹ h_s ).` + +*Proof.* The operator form is the invariant `h = D(λ)ℓ`. Here ℓ runs the scalar shadow and λ runs the labels. We check one event at a time (`Stream.step`): +* A relabel with `λ_r = A` maps `T_A ℓ_r` to `T_B T_A⁻¹ T_A ℓ_r = T_B ℓ_r`, and the label becomes `B`. +* An add with `λ_t = λ_s = F` gives `T_F ℓ_t + q·T_F ℓ_s = T_F(ℓ_t + q·ℓ_s)`. +* A scale commutes with `T_F`. +* A copy with `λ_r = F` gives `T_F ℓ_r` under the new label `F`. +* A clear gives `0 = T_F 0`. + +Induct over the stream, then start from `ℓ = D(λ⁰)⁻¹h`. + +For the matrix form: every event commutes with any `K`-linear map applied register-wise (`scal_map`), and the shadow is additive (`scalRun_add`). Write `h = Σ_s e_s ⊗ h_s`. Then the shadow acts on any module through `S` (`scalRun_eq_sum`). ∎ + +**The row form of `S`** [`Stream.S_rowform`]. `S_rs` is the coefficient of `e_s` in register `r` after one symbolic replay in which register `i` holds `e_i`. #484's `lg_lib.scalar_replay` computes exactly this: +* each register is a dict of coefficients; +* private copies start empty. + +On inputs whose private registers are empty, the columns of the private registers do not contribute, because `T⁻¹0 = 0`. + +**Corollary 2 (the word's rows)** [`Stream.row_unit`, `Stream.row_pair`]. +* If row `r` of `S` is `e_r`, then `h_r(final) = T_{λ¹_r} T_{λ⁰_r}⁻¹ h_r`. +* If row `r` is `e_r + a·e_{s₀}`, then `h_r(final) = T_{λ¹_r}(T_{λ⁰_r}⁻¹ h_r + a·T_{λ⁰_{s₀}}⁻¹ h_{s₀})`. + +## 3. Schedule and accounting + +Frames form a partial order with a **strictly monotone rank** (`rk A < rk B` whenever `A < B`). The subspaces of F₂⁹, with inclusion and dimension, are an instance [`frameRank_strictMono`]. + +**Lemma 3.0** [`le_of_rk_le`, `eq_of_rk_eq`]. If `A`, `B` are comparable and `rk A ≤ rk B`, then `A ≤ B`; equal rank gives `A = B`. +* *Proof.* If `B < A`, then `rk B < rk A`. ∎ + +**Emitter.** A schedule is a list of gates `(mover, partner, frame F, q, direction)`. Before each gate, the emitter relabels the mover from its current label to `F` unless it is already there. It then emits `mover += q·partner` or `partner += q·mover` (`emit`). +* Step 3 of #484's emission (compensation segment): mover = target `t`, partner = gauge helper `j`, `F = E_j`. +* The kernel updates (Lemma K): mover = donor, partner = pivot, `F` = class entrance. +* Step 6 (centre phase): mover = private copy `C_k`, partner = served target `t`, `F = L_t`. + +**Theorem 3 (schedule)** [`emit_spec`, `emit_wellLabelled`, `comp_segment`, `comp_segment_frames`, `centre_forward`, `centre_backward`, `moveLab_top`, `moveLab_mem`]. +1. *Exactness part.* Assume no partner is ever a mover, and each partner sits at its gate's frame. Then the emitted segment is well labelled. No order condition is needed. +2. *Compensation segment.* Assume also: + * every target starts at `0`, or more generally below each of its frames; + * the gates are emitted in order of non-decreasing rank; + * **(b)** the frames of each target form a chain. + + Then every relabel is a strict nested ascent `A < B`. Target `t` ends at `L_t = max ℰ_t`: above every frame of its gates, and equal to one of them. Registers that are not targets keep their labels. +3. *Centre phase, forward orientation.* Copy `C_k ← r` at `c_k`, gates in order of non-increasing rank, clear. Assume: + * the centre register `r` is at `c_k`; + * `C_k` is not a served target; + * each served target is at `L_t`; + * **(c)** the levels form a chain inside `c_k`. + + Then the phase is well labelled and every centre step is a strict nested descent. +4. *Centre phase, backward orientation.* Clear at the bottom, gather in order of non-decreasing rank, and end with the gate `r += −C_k` at `c_k`. The phase is well labelled and every step is a strict nested ascent. + +*Proof.* Induct over the gates (`emit_spec`, which is parametrised by a relation `R`) with three invariants: +* the partners are still at their frames, since they never move; +* each mover is `R`-below every frame still ahead of it; +* the mover sits at the gate's frame when the gate is emitted. + +At a gate: +* both operands are at `F`, so the gate is admissible; +* the emitted relabel starts at the current label, so it is admissible; +* the relabel is a proper `R`-step: it is emitted only when the current label differs from `F`. + +Taking `R` = "always true" gives part 1. For parts 2–4, Lemma 3.0 turns "chain + sorted by rank" into "sorted by `≤`" (or by `≥`), and the invariant follows from that. The end label is the last frame (`moveLab_mem`). By transitivity it lies above all the others (`moveLab_top`). ∎ + +**Theorem 4 (accounting)** [`paid_telescopes`]. Let `es` be well labelled. Suppose every relabel of register `m` is rank-ascending, and nothing copies into or clears `m`. Then the paid rank of `m`, `Σ |rk B − rk A|` over its relabels, equals `rk λ¹_m − rk λ⁰_m`. The descending case is the same with the order reversed. ∎ + +**Frame of the other events** [`Stream.labRun_untouched`, `Stream.wellLabelled_append`, `Stream.labRun_append`]. +* A sub-stream that never relabels register `i` leaves `λ_i` unchanged. +* Well-labelledness of a concatenation splits at the junction. + +**Bit side** [`Dbit_one_mul`, `Dbit_conj`]. For `D_P = [[1−P, P], [P, 1−P]]` over any commutative ring: +* `D_1 D_P = D_{1−P}`; +* `diag(g,g)ᵀ D_P diag(g,g) = D_{gᵀPg}` whenever `gᵀg = 1`. + +These are the two identities of the bit-side entrance transfer (`D_I D_E = D_{E⊥}`, a pure conjugation of the coordinate frame), proved for every `P`. The complex word does not use them. + +## 4. Lemma G for the word + +**Extended labels.** A label is a pair (tag, frame `F`). +* Tag `T` is the word's family: `T_(T,F) = canonical_frame(F)`. +* The other tags are register-specific: + * `(pre, i)`: source `i` before its entry adapter; + * `(prew, j)`: entering helper `j` before `R_E⁻¹`; + * `(post, t)`: target `t` after its exit adapter; + * `(done, j)`: entering helper `j` after `L_E⁻¹`. +* Their operators are defined so that each conversion event executes `T_B T_A⁻¹`: + * `T_(pre,i),p = M_i⁻¹ T_p`; + * `T_(prew,j),E = R_E T_E`; + * `T_(post,t),F = N_t⁻¹ T_F`; + * `T_(done,j),FULL = L_E⁻¹ T_FULL`. + + Here `M_i` and `N_t` are the serialized source and target endpoint monomials; the target's is applied inverted. The identity adapters, on all other registers, keep tag `T`. +* Under this reading, every climb, centre step, data adapter and wrapper is a `relabel`. Theorem 1 then applies to the **complete** emitted stream, both orientations, with no event left outside. + +**Instance hypotheses (checked; the checks read the emitted artefacts of each variant).** + +| | hypothesis | where it is checked | result (headline word, both orientations) | +| --- | --- | --- | --- | +| H1 | well labelled in the extended labels | frames: #484 `lg_lib.check_labels` (G0 at every add and copy, G2 climb source, G3 centre-step source and copy label); tags: `code/check_extended_labels.py` | 0 violations on all four words; 3 adapter mutants rejected on every word, plus 2 wrapper mutants on the three wrapper words | +| H2 | exact recipes | climbs and centre steps: #484 `lg_instances` I-tr, every used transition on all 512 basis columns (not run on the anchor); a recipe is a circuit of linear primitives, so it is `C`-linear and 512 columns determine it on every vector. Adapters and wrappers: exact by the definition of the extended family, given the bridge that `code/check_extended_labels.py` enforces, as `lg_phys.run` executes it: each source has exactly one entry adapter, `(pre,i) → T`, executing `M_i`; each target has exactly one exit adapter, `T → (post,t)`, executing `N_t⁻¹`; every other adapter has no serialized operator, i.e. is the identity, at frame 0 (entry) or FULL (exit); each entering helper has exactly one pre and one post wrapper, keyed by its start frame (#484 G1 also checks this) | 2945 transitions, 0 failures | +| H3 | `S` = `(x,s,y) ↦ (x,s,y+x)` forward, `(x−y,s,y)` backward | #484 `lg_lib.scalar_replay`, exact rational replay, all 800 columns; private copies cleared | exact | +| H4 | endpoint labels | #484 G4: sources at their port lines, targets at 0, helpers at 0 or `E_j`; final labels as in W | 0 violations | +| H5 | accounting | #484 G2 (ascending nested climbs), G3 (strict nested centre steps), ACC (per-register telescoping, centre mass `dim c_k`, paid profile = `local_profile`) | 0 violations | +| H6 | #433's data-adapter identities: `T_{p_i}⁻¹ M_i = C_{q_i}⁻¹`, `T_FULL T_{p_i}⁻¹ M_i = F C_{q_i}⁻¹`, `N_t⁻¹ T_{final_t} = F C_{q_i}⁻¹` | `code/check_adapters.py`, every port, all 512 basis columns, exact | 0 failures on all four words | + +**Lemma G.** Assume H1–H4 hold for the emitted word V of a variant. Then for **every** input with empty private registers, each orientation of V computes `D(λ¹) S D(λ⁰)⁻¹` (Theorem 1). By Corollary 2 and H3: +* *Sources and targets.* Each row is `e_r` or `e_r ± e_{pair(r)}`, and the labels at both ends are W's (H4, with the same adapters). The data block is therefore **W's data block**. With H6 it is the intended #433 transform: source `i ↦ F x_i` and target `v+i ↦ F C_{q_i}⁻¹(h_{v+i} + x_i)` forward, with `x_i = C_{q_i}⁻¹ h_i`, and the backward rows likewise. +* *Cross blocks.* No helper column enters a data row, and no data column enters a helper row. So the cross blocks are 0. +* *Helpers.* The block of entering helper `j` is + + `T_(done,j) T_(prew,j)⁻¹ = L_E⁻¹ · T_FULL T_E⁻¹ · R_E⁻¹ = L_E⁻¹ Φ_E R_E⁻¹`, + + which is the virtual entrance of #471/#458 with its wrappers. Lemma A (#484 I-helper) evaluates it to `C_[w] ⊗ I`. + +Hence, given H1–H6 and Lemma A, the complete emitted program equals #484's end-to-end formula on every input with empty private registers. #484's `lg_e2e.py` sampled 814 columns of that identity. + +Assume H5 as well. By Theorem 4, each non-private register pays `rk λ¹ − rk λ⁰`, and each centre copy pays `dim c_k`. The only start labels that differ from W are `λ⁰_j = E_j`, and the final labels agree. So the local mass is `mass(W) − Σ_j dim E_j`. + +**A priori route to H1 and H5 (Theorem 3).** The direct checks above suffice. Theorem 3 also *derives* the frame part of H1, and H5, from the selection hypotheses of #484 §2.4, independently of the checker: +* *Exactness.* Theorem 3.1 needs only that helpers are not targets and that each partner sits at its frame: + * entering helpers at `E_j`: the virtual entrance; the preconditioner does not touch them; + * targets at `L_t` when the centre phase starts: A does not relabel targets (`labRun_untouched`); + * the centre register at `c_k` at the cut. +* *Accounting.* + * **(a)** `E_j ⊆ F_1(j)` makes helper `j`'s first climb nested. + * **(b)** and the rank order make the compensation climbs strict nested ascents (Theorem 3.2). + * **(c)** makes the centre steps strict nested descents (Theorem 3.3/3.4). With `0 ∈ Λ_k`, their ranks sum to `dim c_k`. + * **(d)** `L_t ⊆ B_1(t)` makes the junction climb nested. Theorem 4 then gives the target the same paid rank as in W. + +## 5. Changes relative to #484 PROOF.md §2 + +1. **Relabel source.** Lemma C's hypothesis named only G0 for adds and copies. The proof also needs every climb or centre step `A → B` to find its register at `A`. This is now part of admissibility. #484's checker already enforced it (G2, G3). +2. **Adapters and wrappers: an implicit commutation step.** #484 §2.1 left adapters and wrappers outside Lemma C as endpoint operators. Register-wise this is right. In every word and orientation, each non-identity adapter and each wrapper is the first or last event on its register. The adapters that sit mid-stream (headline forward: 550 entry, 672 exit) are all identities. But Lemma C as stated covers a stream without adapter events. Using it needs the unwritten step "an operator that is first (last) on its register commutes past every event on other registers", which #484 checked only indirectly (phase order, G0, G4). The clean proof reads adapters and wrappers as relabel events of an extended label set, so Theorem 1 covers the whole stream. The condition this needs is checked directly by the new `code/check_extended_labels.py`, including the bridge in the H2 row. All four words pass. Three mutants are rejected on every word: a dropped source entry adapter, a duplicated source entry adapter, and a target exit adapter moved before the target's last add. Two more are rejected on the three wrapper words: a dropped `R_E⁻¹`, and an `L_E⁻¹` moved before the helper's last add. +3. **From the rational replay to the action on `H`.** "S, the rational matrix of the scalar events" is now a proved step: `scalRun_eq_sum` and `S_rowform`. That step also explains why the replay's empty private copies are harmless. +4. **Minimal label condition.** Exactness needs `λ_t = λ_s` at an add, `λ_r = F` at a copy, and nothing at a scale. The checker's G0 (operands at the annotated frame, scale at its operand's label) is stronger. +5. **(a)–(d) are not needed for exactness at all** (Theorem 3.1). #484 says (b), (c) and nestedness are accounting conditions. The clean proof also places (a) and (d) there, and confirms that the emitter's well-labelledness uses only "partners do not move, partners at their frames". This matches the mutant classification of #484 §2.6 (M3, M3b, M7, M8: physics PASS). +6. **Implicit side conditions made explicit:** + * gauge helpers are not targets; + * the private copy is not a served target; + * Claim 2's "dim E ≤ dim E′ ⇒ E ⊆ E′ in a chain" needs a strictly monotone rank (Lemma 3.0). +7. **The kernel updates** are an instance of the same emitter, with the donor as mover. Their exactness therefore needs only the class entrance condition of Lemma K. +8. **The "every input" claim names its inherited facts.** It rests on #433's data-adapter identities, now checked exhaustively (H6, `code/check_adapters.py`), and on Lemma A (#484 I-helper, exhaustive). It holds for inputs with empty private registers. diff --git a/research/e8-lemma-g-lean/PrintAxioms.lean b/research/e8-lemma-g-lean/PrintAxioms.lean new file mode 100644 index 0000000000..9fc7dc7651 --- /dev/null +++ b/research/e8-lemma-g-lean/PrintAxioms.lean @@ -0,0 +1,17 @@ +import LemmaG +#print axioms LemmaG.Stream.conj +#print axioms LemmaG.Stream.conj_matrix +#print axioms LemmaG.Stream.S_rowform +#print axioms LemmaG.Stream.row_unit +#print axioms LemmaG.Stream.row_pair +#print axioms LemmaG.Stream.labRun_untouched +#print axioms LemmaG.Stream.wellLabelled_append +#print axioms LemmaG.emit_spec +#print axioms LemmaG.emit_wellLabelled +#print axioms LemmaG.comp_segment +#print axioms LemmaG.comp_segment_frames +#print axioms LemmaG.centre_forward +#print axioms LemmaG.centre_backward +#print axioms LemmaG.paid_telescopes +#print axioms LemmaG.Dbit_one_mul +#print axioms LemmaG.Dbit_conj diff --git a/research/e8-lemma-g-lean/README.md b/research/e8-lemma-g-lean/README.md new file mode 100644 index 0000000000..d8db958d33 --- /dev/null +++ b/research/e8-lemma-g-lean/README.md @@ -0,0 +1,98 @@ +# Lemma G (entrance gauge) of PR #484: clean proof and Lean 4 formalisation + +Lemma G is the entrance-gauge lemma of PR #484. It covers three steps: +* target-side compensation at nonzero frames; +* labelled targets; +* the centre scatter along a chain. + +Its value is measurable. With no-bank hosting (#496/#500), the full gauge/kernel word reaches complex `b = 1.333854e-3`. The Lemma-G-free path (kernel79 only) reaches `1.310216e-3`, so Lemma G is worth +1.80% of `b`. + +This package splits Lemma G into two parts: +* **an abstract lemma, proved in Lean 4** for every semiring (in particular every field), every module and every family of invertible label operators; +* **finitely many instance hypotheses on the emitted streams**, checked exhaustively by Python. + +`PROOF.md` holds the clean statement and proof. Its §5 lists what changed relative to #484's §2. + +## Proved in Lean (`LemmaG/`, Lean 4.21.0 + Mathlib v4.21.0, as `formal/lean` on main) + +**Main theorem.** Here `K` is any semiring, `M` any `K`-module, and `T : Λ → M ≃ₗ[K] M` any label family: + +```lean +theorem LemmaG.Stream.conj_matrix (T : Λ → M ≃ₗ[K] M) (rec : Λ → Λ → M → M) (es : List (Event ι Λ K)) + (l : ι → Λ) (h : ι → M) (hrec : RecipesExact T rec es) (hw : WellLabelled es l) (r : ι) : + physRun rec es h r = T (labRun es l r) (∑ s, S es r s • (T (l s)).symm (h s)) +``` + +In words: if a stream of relabel/add/scale/copy/clear events is well labelled and every relabel executes `T_B T_A⁻¹`, then for every input, + +`h_r(final) = T_{λ¹_r}(Σ_s S_rs T_{λ⁰_s}⁻¹ h_s)`, + +where `S` is the matrix of the scalar shadow. This is #425's conjugation lemma with all of its hypotheses explicit, together with the step from the rational replay to the action on the module. + +| theorem | content | +| --- | --- | +| `Stream.conj`, `Stream.conj'` | operator form: physical run = `D(λ¹) ∘ scalar shadow ∘ D(λ⁰)⁻¹` | +| `Stream.conj_matrix`, `Stream.S_rowform` | matrix form. `S` is exactly what #484's `lg_lib.scalar_replay` computes: one symbolic replay, row form | +| `Stream.row_unit`, `Stream.row_pair` | the rows of the word: unit rows (helpers, so the entering-helper block is `T_{λ¹}T_{λ⁰}⁻¹`) and paired rows (targets forward, sources backward) | +| `emit_spec`, `emit_wellLabelled` | the schedule emitter is well labelled as soon as partners stay at their frames; no order condition is needed for exactness | +| `comp_segment`, `comp_segment_frames` | compensation segment. Under (b) and the rank order, every climb is a strict nested ascent and each target ends at `L_t = max ℰ_t`. Stated for an abstract order with strictly monotone rank, and for the subspaces of F₂⁹ | +| `centre_forward`, `centre_backward` | centre phase. Under (c), every step is a strict nested descent (forward) or ascent (backward) | +| `paid_telescopes` | accounting: paid ranks telescope to `rk λ¹ − rk λ⁰` | +| `Stream.labRun_untouched`, `Stream.wellLabelled_append` | frame and junction lemmas (Claim 3) | +| `Dbit_one_mul`, `Dbit_conj` | bit-side transfer of the entrance step: `D_I D_P = D_{I−P}` and `diag(g,g)ᵀ D_P diag(g,g) = D_{gᵀPg}` for `gᵀg = 1`, for every `P`. Not used by the complex word | + +Every theorem is general. No instance data is enumerated in Lean, and `decide` and `native_decide` are not used. `#print axioms` gives a subset of `[propext, Classical.choice, Quot.sound]` for every theorem above (`PrintAxioms.lean`). + +## Checked in Python (the instance hypotheses, PROOF.md §4) + +| | hypothesis | check | +| --- | --- | --- | +| H1 | the emitted stream is well labelled (extended labels: tag × frame) | frames: #484 `code/lemmaG/lg_lib.check_labels` (G0, G2, G3). Tags: `code/check_extended_labels.py` (new; 3 adapter mutants rejected on every word, 2 wrapper mutants on the wrapper words) | +| H2 | every climb and centre step executes `T_b T_a⁻¹`; each source and target has exactly one non-identity adapter and every other adapter is the identity, at frame 0 or FULL | #484 `lg_instances` I-tr, on all 512 basis columns of every used transition (recipes are circuits of linear primitives, so 512 columns determine them; not run on the anchor). Adapter bridge: `code/check_extended_labels.py` | +| H3 | `S = (x,s,y) ↦ (x,s,y+x)` forward, `(x−y,s,y)` backward | #484 `lg_lib.scalar_replay`, exact, all 800 columns | +| H4 | endpoint labels as in W | #484 G4 | +| H5 | accounting (nested ascents, strict centre chains, mass) | #484 G2, G3, ACC | +| H6 | #433's data-adapter identities (`T_p⁻¹M_i = C_q⁻¹`, `T_FULL T_p⁻¹M_i = F C_q⁻¹`, `N_t⁻¹T_final = F C_q⁻¹`) | `code/check_adapters.py` (new), every port, all 512 columns, exact | + +On all four words (anchor, kernel79, gauge80, headline), H1, H3, H4, H5 and H6 hold in both orientations, with 0 violations and 0 failures; H2 (I-tr) holds on the three gauge/kernel words, 2945/2945 on the headline. Together with Lemma A (#484 I-helper), the Lean theorem then gives the end-to-end identity of the complete emitted program **for every input with empty private registers**. #484's `lg_e2e.py` tests that identity on 814 sampled columns; here it follows from the exhaustive checks. + +## Trust base + +* **Lean kernel** (4.21.0), **Mathlib** v4.21.0 (`lake-manifest.json` pins rev `308445d`, the same as `formal/lean` on main), and the axioms `propext`, `Classical.choice`, `Quot.sound`. +* **The Python instance checks**, as listed above, including the reading of the emitted JSON events as Lean `Event`s (PROOF.md §4, "Extended labels"). +* **Inherited interfaces outside Lemma G:** + * #433's data-adapter endpoint: its three identities are now checked exhaustively (H6); + * Lemma A, which turns `L_E⁻¹ Φ_E R_E⁻¹` into `C_[w] ⊗ I` (#484 I-helper, exhaustive); + * #442's accounting model: a nested climb `A ⊆ B` is charged `|B| − |A|`. + +## Run + +```sh +python3 research/e8-lemma-g-lean/verify.py # Lean: manifest, source scan, cache get, build, axioms +python3 research/e8-lemma-g-lean/verify.py --instances /abs/out/of/484/verify # also the instance checks (numpy) +``` + +* Requirements: elan on `PATH` (`lean-toolchain` pins `leanprover/lean4:v4.21.0`), network access for `lake exe cache get`, and Python 3.9+ (with numpy for `--instances`, as #484's stage). +* A cold run downloads Mathlib's prebuilt cache, then builds this package's five modules in about a minute. +* `--instances` needs the output directory of #484's `verify.py`, which takes about 25 minutes. It checks every word present: the headline and the anchor, plus gauge80 and kernel79 when #484 ran with `--all`. For each word it confirms that #484's own checks passed on inputs equal to #484's `EXPECTED.json`, then runs H1 (tags) and H6. The #484 files it imports or compares against are pinned in `MANIFEST.json` (`external_files`). + +## Files + +| path | content | +| --- | --- | +| `LemmaG/Stream.lean` | events, semantics, Theorem 1, the matrix form, Corollary 2 | +| `LemmaG/Schedule.lean` | emitter, compensation segment, centre phase, telescoping (Theorems 3 and 4) | +| `LemmaG/Frames.lean` | the frames of F₂⁹ satisfy the order hypotheses | +| `LemmaG/BitEntrance.lean` | the bit-side identities | +| `PrintAxioms.lean` | the axiom probe | +| `code/check_extended_labels.py` | instance check H1: tags and the adapter/wrapper bridge, with mutants | +| `code/check_adapters.py` | instance check H6: #433's data-adapter identities | +| `verify.py`, `MANIFEST.json` | the check script and the sha256 of every file | + +## Credits + +* The conjugation lemma and scalar interface: #425 (Zhihao Chen). +* The one-helper rule and paid wrappers: #458 (chafreaky). +* The virtual entrance and complete-invocation normalisation: #471 (Dugongue). +* The gauge construction, Lemma G and its Python stage: #484 (DreamingOfClouds). +* Lean conventions: the toolchain and Mathlib pin of `formal/lean` on main; the standalone package layout, axiom reporting and author-check practice of #487/#488 (jamesyc). diff --git a/research/e8-lemma-g-lean/code/check_adapters.py b/research/e8-lemma-g-lean/code/check_adapters.py new file mode 100644 index 0000000000..e855f9df64 --- /dev/null +++ b/research/e8-lemma-g-lean/code/check_adapters.py @@ -0,0 +1,52 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +"""Instance check H6 (PROOF.md §4): the #433 data-adapter identities, exhaustively on all 512 basis columns. + +With the extended labels, the Lean theorem gives source i the block T_(T,final_i) T_(pre,i)^-1 = T_{final_i} T_{p_i}^-1 M_i +(M_i = the serialized source endpoint monomial) and target t = v+i the block T_(post,t) = N_t^-1 T_{final_t} (N_t = the +serialized target endpoint monomial, applied inverted). The intended transform of #433 +(lg_phys.expected) is F C_{q_i}^-1 for both, with F the Fourier gate on all nine axes and C_q the port gate. This script +checks, for every port i, on all 512 basis columns, exactly over Z[i][1/2]: + T_{p_i}^-1 M_i == C_{q_i}^-1 + T_{final_i} T_{p_i}^-1 M_i == F C_{q_i}^-1 + N_t^-1 T_{final_t} == F C_{q_i}^-1 +T_F and C_q are the DEFINITIONS (vendored canonical_frame / cgate); M_i and N_t are decoded from the serialized recipes. + +usage: check_adapters.py BASE VARIANT [VARIANT ...] (BASE = the output directory of #484's verify.py; needs numpy)""" +import sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE.parents[1] / 'e8-complex-gauge-kernel' / 'code' / 'lemmaG')) +from lg_lib import load # noqa: E402 +from lg_phys import Model # noqa: E402 +from gd import identity_batch, fourier_circ # noqa: E402 + + +def check(d): + m = Model(d); c = d['c']; v = c['v']; I = identity_batch(); F = fourier_circ(range(9)) + fail = {'T_p^-1 M_i == C_q^-1': 0, 'T_final T_p^-1 M_i == F C_q^-1': 0, 'N_t^-1 T_final == F C_q^-1': 0} + for i in range(v): + fs, Mi = m.src_ad[i]; ft, Nt = m.tgt_ad[i] + if fs != c['start'][i] or ft != c['final'][v + i] or Mi is None or Nt is None: + raise SystemExit(f'port {i}: adapter frames ({fs}, {ft}) or operators do not match the word') + Cinv = I.copy().apply_circ(m.Cq(i), inverse=True) + a = I.copy().apply_circ(Mi).apply_circ(m.T(fs), inverse=True) + fail['T_p^-1 M_i == C_q^-1'] += not a.equals(Cinv) + target = Cinv.copy().apply_circ(F) + fail['T_final T_p^-1 M_i == F C_q^-1'] += not a.copy().apply_circ(m.T(c['final'][i])).equals(target) + fail['N_t^-1 T_final == F C_q^-1'] += not I.copy().apply_circ(m.T(ft)).apply_circ(Nt, inverse=True).equals(target) + return v, fail + + +def main(): + base, ok = Path(sys.argv[1]), True + for name in sys.argv[2:]: + ports, fail = check(load(base / name)) + ok &= not any(fail.values()) + print(name, 'ports', ports, 'columns 512 each', 'failures', fail, flush=True) + print('PASS adapter identities' if ok else 'FAIL adapter identities') + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/research/e8-lemma-g-lean/code/check_extended_labels.py b/research/e8-lemma-g-lean/code/check_extended_labels.py new file mode 100644 index 0000000000..bc1d9c3218 --- /dev/null +++ b/research/e8-lemma-g-lean/code/check_extended_labels.py @@ -0,0 +1,139 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +"""Instance check E (PROOF.md §3, hypothesis H1 for the conversion events). + +The Lean theorem `LemmaG.Stream.conj_matrix` is applied to the COMPLETE emitted stream, with data adapters and residual +wrappers read as relabel events of an extended label set (tag, frame): + tag 'T' the word's family T_F (canonical_frame); identity adapters keep it; + ('pre', r) a source before its (non-identity) entry adapter; ('prew', r) an entering helper before R_E^-1; + ('post', r) a target after its (non-identity) exit adapter; ('done', r) an entering helper after L_E^-1. +A register-specific tag is carried only by its register (and by a private copy taken from it), so G0 in the extended labels +says exactly: no add/copy meets a source before its entry adapter, a target after its exit adapter, or an entering helper +outside its wrappers, and every climb / centre step happens in the word's family. The conversions themselves are pinned +as in lg_phys.run: each source has exactly one entry adapter (the non-identity monomial M_i, tag ('pre',i) -> 'T'), each +target exactly one exit adapter after its tag-'T' life (N_t^-1, 'T' -> ('post',t)); every other adapter has no serialized +operator, i.e. is the identity, and must sit at frame 0 (entry) or FULL (exit); each entering helper has exactly one pre and +one post wrapper keyed by its start frame (R_E^-1, L_E^-1). The frame component (G0, G2, G3) is checked by #484's lg_lib.check_labels; this script +re-tracks the frames and adds the tags. + +usage: check_extended_labels.py BASE VARIANT [VARIANT ...] [--mutants] (BASE = the output directory of #484's verify.py) +Imports #484's lg_lib (read-only) for loading the emitted artefacts; exits non-zero on any violation.""" +import json, sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE.parents[1] / 'e8-complex-gauge-kernel' / 'code' / 'lemmaG')) +from lg_lib import load # noqa: E402 + +FULL = 1 # frame-table row of the full frame (as in lg_phys.run) + + +def check(c, events): + v, R = c['v'], c['R']; n = 2 * v + R; start, final = c['start'], c['final'] + entering = {r for r in range(2 * v, n) if start[r] != 0} + assert len(c['frames'][FULL]) == 9 and not c['frames'][0], 'frame-table rows 0 and 1 are not the zero frame and FULL' + tag = {} + for r in range(n): + tag[('L', r)] = ('pre', r) if r < v else ('prew', r) if r in entering else 'T' + lam = {('L', r): start[r] for r in range(n)} + viol = []; counts = dict(adds=0, copies=0, climbs=0, centre_steps=0, entry_adapters=0, exit_adapters=0, pre_wrappers=0, post_wrappers=0) + bad = lambda m: viol.append(m) if len(viol) < 50 else None + for idx, e in enumerate(events): + k = e[0] + if k == 'phase': + continue + if k == 'scalar': + op, f = e[1], e[2]; t = tuple(op[1]) + if op[0] == 'add': + s = tuple(op[2]); counts['adds'] += 1 + if (tag.get(t), lam.get(t)) != (tag.get(s), lam.get(s)): bad(f'add {idx}: {t} {(tag.get(t), lam.get(t))} vs {s} {(tag.get(s), lam.get(s))}') + elif op[0] == 'copy': + s = tuple(op[2]); counts['copies'] += 1 + if lam.get(s) != f: bad(f'copy {idx}: source {s} at {lam.get(s)} not {f}') + tag[t], lam[t] = tag.get(s), f + elif op[0] == 'clear': + tag[t], lam[t] = 'T', f + elif op[0] != 'scale': # scale: no label condition + bad(f'unknown scalar {op[0]} at {idx}') + elif k == 'climb': + _, _, r, a, b, _ = e; x = ('L', r); counts['climbs'] += 1 + if tag[x] != 'T' or lam[x] != a: bad(f'climb {idx}: {r} at {(tag[x], lam[x])} not (T,{a})') + lam[x] = b + elif k == 'center': + _, kk, a, b, _ = e; x = ('C', kk); counts['centre_steps'] += 1 + if tag.get(x) != 'T' or lam.get(x) != a: bad(f'centre step {idx}: copy {kk} at {(tag.get(x), lam.get(x))} not (T,{a})') + lam[x] = b + elif k == 'adapter': + _, way, r, f = e; x = ('L', r) + if lam[x] != f: bad(f'adapter {idx}: {r} at frame {lam[x]} not {f}') + if way == 'old_to_new': + counts['entry_adapters'] += 1 + want = ('pre', r) if r < v else 'T' # a source converts exactly once; other entry adapters are identities + if tag[x] != want: bad(f'entry adapter {idx}: {r} tag {tag[x]} not {want}') + if r >= v and f != 0: bad(f'identity entry adapter {idx}: {r} at frame {f} not 0') + tag[x] = 'T' + elif way == 'new_to_old': + counts['exit_adapters'] += 1 + if tag[x] != 'T': bad(f'exit adapter {idx}: {r} tag {tag[x]}') + if not (v <= r < 2 * v) and f != FULL: bad(f'identity exit adapter {idx}: {r} at frame {f} not FULL') + tag[x] = ('post', r) if v <= r < 2 * v else 'T' + else: + bad(f'unknown adapter {way} at {idx}') + elif k == 'residual_adapter': + _, side, r, f = e; x = ('L', r) + if f != start[r]: bad(f'wrapper {idx}: {r} keyed by frame {f} not its start {start[r]}') + if lam[x] != f and side == 'pre': bad(f'pre wrapper {idx}: {r} at {lam[x]} not {f}') + if side == 'pre': + counts['pre_wrappers'] += 1 + if tag[x] != ('prew', r): bad(f'pre wrapper {idx}: {r} tag {tag[x]}') + tag[x] = 'T' + else: + counts['post_wrappers'] += 1 + if tag[x] != 'T': bad(f'post wrapper {idx}: {r} tag {tag[x]}') + tag[x] = ('done', r) + else: + bad(f'unknown event {k} at {idx}') + for r in range(n): + want = ('post', r) if v <= r < 2 * v else ('done', r) if r in entering else 'T' + if tag[('L', r)] != want: bad(f'register {r} ends with tag {tag[("L", r)]} not {want}') + if lam[('L', r)] != final[r]: bad(f'register {r} ends at frame {lam[("L", r)]} not {final[r]}') + return viol, counts + + +def mutants(c, ev): + """Necessity controls: each edit must be rejected (adapter edits on every word, wrapper edits on the wrapper words).""" + v = c['v']; ev = list(ev); res = {} + i = next(i for i, e in enumerate(ev) if e[0] == 'adapter' and e[1] == 'old_to_new' and e[2] < v) + res['drop a source entry adapter'] = len(check(c, ev[:i] + ev[i + 1:])[0]) + res['duplicate a source entry adapter'] = len(check(c, ev[:i + 1] + [ev[i]] + ev[i + 1:])[0]) + j = next(i for i, e in enumerate(ev) if e[0] == 'adapter' and e[1] == 'new_to_old' and v <= e[2] < 2 * v); t = ('L', ev[j][2]) + k = max(i for i, e in enumerate(ev[:j]) if e[0] == 'scalar' and e[1][0] == 'add' and t in (tuple(e[1][1]), tuple(e[1][2]))) + res['target exit adapter before its last add'] = len(check(c, ev[:k] + [ev[j]] + ev[k:j] + ev[j + 1:])[0]) + if any(e[0] == 'residual_adapter' for e in ev): + w = next(i for i, e in enumerate(ev) if e[0] == 'residual_adapter' and e[1] == 'pre') + res['drop a pre wrapper'] = len(check(c, ev[:w] + ev[w + 1:])[0]) + w = next(i for i, e in enumerate(ev) if e[0] == 'residual_adapter' and e[1] == 'post'); r = ('L', ev[w][2]) + k = max(i for i, e in enumerate(ev[:w]) if e[0] == 'scalar' and e[1][0] == 'add' and r in (tuple(e[1][1]), tuple(e[1][2]))) + res['post wrapper before the helper\'s last add'] = len(check(c, ev[:k] + [ev[w]] + ev[k:w] + ev[w + 1:])[0]) + return res + + +def main(): + base, names = Path(sys.argv[1]), [a for a in sys.argv[2:] if not a.startswith('--')] + out, ok = {}, True + for name in names: + d = load(base / name); c = d['c']; out[name] = {'inputs': d['shas']} + for o in ('forward', 'backward'): + viol, counts = check(c, d['progs'][o]) + out[name][o] = dict(violations=len(viol), first=viol[:5], **counts) + ok &= not viol + print(name, o, 'violations', len(viol), counts, flush=True) + if '--mutants' in sys.argv: + m = mutants(c, d['progs'][o]); out[name][o]['mutants_rejected'] = m + ok &= all(x > 0 for x in m.values()); print(' ', 'mutants (violations each):', m, flush=True) + print(json.dumps(out, indent=1, sort_keys=True)) + print('PASS extended labels' if ok else 'FAIL extended labels') + sys.exit(0 if ok else 1) + + +if __name__ == '__main__': + main() diff --git a/research/e8-lemma-g-lean/lake-manifest.json b/research/e8-lemma-g-lean/lake-manifest.json new file mode 100644 index 0000000000..cda5516394 --- /dev/null +++ b/research/e8-lemma-g-lean/lake-manifest.json @@ -0,0 +1,95 @@ +{"version": "1.1.0", + "packagesDir": ".lake/packages", + "packages": + [{"url": "https://github.com/leanprover-community/mathlib4", + "type": "git", + "subDir": null, + "scope": "", + "rev": "308445d7985027f538e281e18df29ca16ede2ba3", + "name": "mathlib", + "manifestFile": "lake-manifest.json", + "inputRev": "v4.21.0", + "inherited": false, + "configFile": "lakefile.lean"}, + {"url": "https://github.com/leanprover-community/plausible", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "c4aa78186d388e50a436e8362b947bae125a2933", + "name": "plausible", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml"}, + {"url": "https://github.com/leanprover-community/LeanSearchClient", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "6c62474116f525d2814f0157bb468bf3a4f9f120", + "name": "LeanSearchClient", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml"}, + {"url": "https://github.com/leanprover-community/import-graph", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "d07bd64f1910f1cc5e4cc87b6b9c590080e7a457", + "name": "importGraph", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml"}, + {"url": "https://github.com/leanprover-community/ProofWidgets4", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "6980f6ca164de593cb77cd03d8eac549cc444156", + "name": "proofwidgets", + "manifestFile": "lake-manifest.json", + "inputRev": "v0.0.62", + "inherited": true, + "configFile": "lakefile.lean"}, + {"url": "https://github.com/leanprover-community/aesop", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "8ff27701d003456fd59f13a9212431239d902aef", + "name": "aesop", + "manifestFile": "lake-manifest.json", + "inputRev": "master", + "inherited": true, + "configFile": "lakefile.toml"}, + {"url": "https://github.com/leanprover-community/quote4", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "e9c65db4823976353cd0bb03199a172719efbeb7", + "name": "Qq", + "manifestFile": "lake-manifest.json", + "inputRev": "master", + "inherited": true, + "configFile": "lakefile.toml"}, + {"url": "https://github.com/leanprover-community/batteries", + "type": "git", + "subDir": null, + "scope": "leanprover-community", + "rev": "8d2067bf518731a70a255d4a61b5c103922c772e", + "name": "batteries", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml"}, + {"url": "https://github.com/leanprover/lean4-cli", + "type": "git", + "subDir": null, + "scope": "leanprover", + "rev": "7c6aef5f75a43ebbba763b44d535175a1b04c9e0", + "name": "Cli", + "manifestFile": "lake-manifest.json", + "inputRev": "main", + "inherited": true, + "configFile": "lakefile.toml"}], + "name": "LemmaG", + "lakeDir": ".lake"} diff --git a/research/e8-lemma-g-lean/lakefile.toml b/research/e8-lemma-g-lean/lakefile.toml new file mode 100644 index 0000000000..4848a71a28 --- /dev/null +++ b/research/e8-lemma-g-lean/lakefile.toml @@ -0,0 +1,10 @@ +name = "LemmaG" +defaultTargets = ["LemmaG"] + +[[require]] +name = "mathlib" +git = "https://github.com/leanprover-community/mathlib4" +rev = "v4.21.0" + +[[lean_lib]] +name = "LemmaG" diff --git a/research/e8-lemma-g-lean/lean-toolchain b/research/e8-lemma-g-lean/lean-toolchain new file mode 100644 index 0000000000..980709bbba --- /dev/null +++ b/research/e8-lemma-g-lean/lean-toolchain @@ -0,0 +1 @@ +leanprover/lean4:v4.21.0 diff --git a/research/e8-lemma-g-lean/verify.py b/research/e8-lemma-g-lean/verify.py new file mode 100644 index 0000000000..64c7cd2792 --- /dev/null +++ b/research/e8-lemma-g-lean/verify.py @@ -0,0 +1,104 @@ +# Apache-2.0. Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code. +"""Verify the Lean formalisation of Lemma G. + +usage: python3 verify.py [--no-cache] [--instances BASE] + 1. every file listed in MANIFEST.json has its recorded sha256 and no unlisted file sits in LemmaG/ or code/; the files of + PR #484 that the instance checks import or compare against ("external_files") have their recorded sha256; + 2. the Lean sources contain no `sorry`, `admit`, `axiom`, `native_decide`, `implemented_by`, `extern`, `unsafe`, `opaque` + and no `set_option` other than the heartbeat limits; + 3. `lake exe cache get` (Mathlib's pinned build, skipped with --no-cache) and `lake build`, warnings shown; + 4. `lake env lean PrintAxioms.lean`: each main theorem depends only on propext, Classical.choice, Quot.sound; + 5. with --instances BASE (BASE = the output directory of PR #484's verify.py, with or without --all), on every word present + (headline and anchor required; --all adds gauge80 and kernel79): + a. BASE/lemmaG//LEMMA-G-CHECK.json: #484's checks passed (0 label violations, exact scalar replay, I-tr and the + other instance identities 0 failures, calls bound, end-to-end PASS) on inputs equal to #484's EXPECTED.json; + b. code/check_extended_labels.py --mutants (H1 tags, conversion bridge); + c. code/check_adapters.py (H6, the #433 data-adapter identities on all 512 columns). +Python 3.9+, standard library only (numpy for --instances, as #484's stage); `lake` from elan on PATH (the toolchain is pinned +by lean-toolchain).""" +import hashlib, json, os, re, subprocess, sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +ALLOWED = {'propext', 'Classical.choice', 'Quot.sound'} +FORBIDDEN = re.compile(r'\b(sorry|admit|axiom|native_decide|implemented_by|extern|unsafe|opaque)\b|set_option\s+(?!maxHeartbeats|maxRecDepth)') + + +def fail(msg): + print('FAIL', msg, flush=True); sys.exit(1) + + +def run(cmd, timeout): + print('$', ' '.join(cmd), flush=True) + p = subprocess.run(cmd, cwd=HERE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=timeout) + if p.returncode: + print(p.stdout[-4000:]); fail(f'{cmd[0]} {cmd[1]} exited {p.returncode}') + return p.stdout + + +def strip_comments(src): + src = re.sub(r'/-.*?-/', ' ', src, flags=re.S) # block and doc comments (not nested in these sources) + return re.sub(r'--[^\n]*', ' ', src) + + +def main(): + args = sys.argv[1:] + man = json.loads((HERE / 'MANIFEST.json').read_text()) + for rel, sha in man['files'].items(): + got = hashlib.sha256((HERE / rel).read_bytes()).hexdigest() + if got != sha: fail(f'sha256 of {rel}') + for d in ('LemmaG', 'code'): + for p in (HERE / d).rglob('*'): + if p.is_file() and '__pycache__' not in p.parts and str(p.relative_to(HERE)) not in man['files']: + fail(f'unlisted file {p.relative_to(HERE)}') + for rel, sha in man['external_files'].items(): + if hashlib.sha256((HERE / rel).read_bytes()).hexdigest() != sha: fail(f'sha256 of {rel}') + print('manifest: %d files and %d #484 files OK' % (len(man['files']), len(man['external_files'])), flush=True) + + lean_files = sorted(HERE.glob('LemmaG/*.lean')) + [HERE / 'LemmaG.lean', HERE / 'PrintAxioms.lean'] + for p in lean_files: + m = FORBIDDEN.search(strip_comments(p.read_text())) + if m: fail(f'forbidden token {m.group(0)!r} in {p.name}') + print('sources: no sorry / admit / axiom / native_decide / unsafe / opaque / extern in %d files' % len(lean_files), flush=True) + + if '--no-cache' not in args: + run(['lake', 'exe', 'cache', 'get'], 3600) + out = run(['lake', 'build'], 3600) + print('\n'.join(l for l in out.splitlines() if 'warning' in l or 'error' in l or 'Build completed' in l), flush=True) + + out = run(['lake', 'env', 'lean', 'PrintAxioms.lean'], 1200) + wanted = [l.split()[2] for l in (HERE / 'PrintAxioms.lean').read_text().splitlines() if l.startswith('#print axioms')] + seen = {} + for m in re.finditer(r"'([\w.']+)' depends on axioms: \[([^\]]*)\]", out): + seen[m.group(1)] = [a.strip() for a in m.group(2).split(',') if a.strip()] + for m in re.finditer(r"'([\w.']+)' does not depend on any axioms", out): + seen[m.group(1)] = [] + print(out.strip(), flush=True) + for name in wanted: + if name not in seen: fail(f'no axiom report for {name}') + if not set(seen[name]) <= ALLOWED: fail(f'{name} depends on {seen[name]}') + print('axioms: %d theorems, only %s' % (len(wanted), sorted(ALLOWED)), flush=True) + + if '--instances' in args: + base = Path(args[args.index('--instances') + 1]) + words = [w for w in ('gauge80-kernel42', 'gauge80', 'kernel79', 'anchor') if (base / w / 'split-centres').is_dir()] + if not {'gauge80-kernel42', 'anchor'} <= set(words): fail(f'{base} lacks the headline word or the anchor') + expected = json.loads((HERE.parent / 'e8-complex-gauge-kernel' / 'EXPECTED.json').read_text())['lemma_G_independent_checks'] + for w in words: + L = json.loads((base / 'lemmaG' / w / 'LEMMA-G-CHECK.json').read_text()) + if L['inputs'] != expected[w]['inputs']: fail(f'{w}: emitted inputs differ from #484 EXPECTED.json') + for o in ('forward', 'backward'): + if L['labels'][o]['n_label_violations'] or L['labels'][o]['scalar_violations']: fail(f'{w} {o}: #484 label/scalar check') + if not L['calls']['ok'] or L['end_to_end']['status'] != 'PASS' or L['end_to_end']['failures']: fail(f'{w}: #484 calls/end-to-end') + if w != 'anchor' and any(x['failures'] for x in L['instances'].values()): fail(f'{w}: #484 instance identities') + print('instances: %s: #484 checks passed on the expected inputs%s' % (w, '' if w == 'anchor' else + ' (I-tr %d transitions)' % L['instances']['I-tr']['transitions']), flush=True) + run([sys.executable, '-B', 'code/check_extended_labels.py', str(base), *words, '--mutants'], 3600) + print('instances: extended-label check PASS on', ', '.join(words), flush=True) + run([sys.executable, '-B', 'code/check_adapters.py', str(base), *words], 3600) + print('instances: adapter identities PASS on', ', '.join(words), flush=True) + print('PASS Lemma G Lean verification', flush=True) + + +if __name__ == '__main__': + main() diff --git a/research/idle-axis-hosting/EXPECTED.json b/research/idle-axis-hosting/EXPECTED.json new file mode 100644 index 0000000000..1b0811df29 --- /dev/null +++ b/research/idle-axis-hosting/EXPECTED.json @@ -0,0 +1,10 @@ +{ + "status": "PASS_CONDITIONAL_IDLE_AXIS_HOSTING_ASSEMBLY", + "kappa": "618775866623647/500000000000000000", + "kappa_decimal": "0.001237551733247294", + "bit_lower": "1239085165241180038597/1000000000000000000000000", + "complex_lower": "1267453159029119/1000000000000000000", + "binding_component": "bit", + "bit_template_sha256": "dd7833dcaff8c84b258847f4c4d65b6402c702700ae37d2c464083ee37b24126", + "complex_template_sha256": "6f48c811e981bbd76436dfe19f497ed627794987fd4347daf123d0d698a5fe3f" +} diff --git a/research/idle-axis-hosting/LICENSE b/research/idle-axis-hosting/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/idle-axis-hosting/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/idle-axis-hosting/MANIFEST.json b/research/idle-axis-hosting/MANIFEST.json new file mode 100644 index 0000000000..542ee2f988 --- /dev/null +++ b/research/idle-axis-hosting/MANIFEST.json @@ -0,0 +1,17 @@ +{ + "files": { + "EXPECTED.json": "ed83c1bf1ca2d01eaab5149a34520806a07ef375dfa9e3ed69d123f4be4c9960", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "NOTICE.md": "027a868628d0408602dbeae688b031ed9b4abfd6e5401f6e8106a3eb25ebc4ca", + "PROOF.md": "cfe34bf0b64259661312dae22c3a23adc5bf6f6326951eee5c1488ccfc347542", + "README.md": "1151f74cad54ac4937282b7a8b5d1108ed4ce35944ef9b7bb7d17abfce1fe4a0", + "SELECTION.json": "315d54be472842707cce879618be477d8b897050e873bc136d114eec6a232f97", + "assemble.py": "f9a2e6a42aadcf971702a5a867760a092566ed03356f4f34387d38f4093ad1a6", + "audit.py": "38594423a401110bd430b734037c6ecba422ee6a94d71709984e0afa9cd1edf8", + "bit_hosted.py": "6dfbf26213e8adf87563b3575cfb722bd07ecd65627f056b3293411dd3d89a61", + "complex_hosted.py": "829c5c4f4bdfccedadd31505f1f0a394f7a208d1446b7bbf9cc92d3aa1530c0c", + "hosting_core.py": "d8b90cd5d152df3c7c351230863d9e61816ad5e1f21d69bea1a86a5daad559a3", + "verify.py": "737a974d79fdd232b6c4b9e059c56835079971447342ed7ca3b82a614e30cb53" + }, + "parent_manifest_sha256": "95a9570287b64d22de30e6ae3acf931d5f6daef1a163f0c99532e1a24639fbc2" +} diff --git a/research/idle-axis-hosting/NOTICE.md b/research/idle-axis-hosting/NOTICE.md new file mode 100644 index 0000000000..391e865e06 --- /dev/null +++ b/research/idle-axis-hosting/NOTICE.md @@ -0,0 +1,18 @@ +# Notice + +This package adds idle-axis hosting on top of the following work. Their packages are used unchanged and run fresh by +`verify.py`; their notices remain in their own directories. + +- #434, Rohan Arun with OpenAI Codex: early resets and the shared-donor kernel. This is the parent composition and its + verifier. +- #433, icekylinx with Codex: split centres (complex supplier) and source-centre bit composition, together with their + engines and invoices. +- #435 / #417, chafreaky: the response kernel and mixed-width banks. +- #426, ai-nanachi: clean-reset reuse. +- #425 and #386, Zhihao Chen with OpenAI Codex: the mutable-basis complex interface and the compressed nine-stage + geometry, routes and banks. +- #370, Dylan Crow with Anthropic Claude: the Hamming E8 bit producer. +- Jacob Sussman: the E8 unit and the frame/compiler interfaces. + +The hosting construction, its generators, audit and assembly scripts are new here, and were prepared with assistance +from Claude. They are released under the Apache-2.0 license in `LICENSE`. diff --git a/research/idle-axis-hosting/PROOF.md b/research/idle-axis-hosting/PROOF.md new file mode 100644 index 0000000000..4468a00349 --- /dev/null +++ b/research/idle-axis-hosting/PROOF.md @@ -0,0 +1,105 @@ +# Idle-axis hosting: helper residuals on pending idle coordinates + +This package changes only the global nine-stage templates of #434's two suppliers. Both local words are unchanged: + +- the complex word is #433's split-centre word, R = 560, m = 73; +- the bit word is #434's early-reset kernel word, R = 747, m = 64. + +So are their local programs, scalar replays, data routes, bridges, terminal exchange and cover correction. What +changes is where whole dirty-helper residuals live. Many of them move from bank streams onto coordinates of *idle* +data families that would otherwise be advanced later by an idle child. + +## 1. The two inherited facts used + +**(a) Dirty invocations act on a helper stream as its residual.** The complete dirty local invocation is block +diagonal on helpers at its endpoint and admits arbitrary correlated helper values (#425/#433, #386/#434). On the +physical stream that owns a helper residual of width w, it acts as an exact coordinate factor on w coordinates: + +- complex: P_g C_block P_g⁻¹ (PR425-COMPLEX §5, INHERITED-COMPLEX-GEOMETRY); +- bit: D_P with P the width-w coordinate projector (PR386-BIT-GEOMETRY; mixed widths 8 − entrance rank, #434). + +This holds whatever the stream held before. Banks rely on exactly this: eight sequential residuals and a pad tile a +bank stream. + +**(b) An idle child is a product of coordinate factors.** Advancing a data pair from level a to level b applies, on +every physical data stream (F, g) of that pair, the commuting product of coordinate factors on its pending set S: + +- complex: C over S, in the basis U_q ⊕ I used by the inherited idle factorisation; +- bit: D_{P_V−P_U}, an orthogonal coordinate projector difference. + +Factors on disjoint coordinate sets commute and multiply: + +- complex: C_{S'}·C_{S∖S'} = C_S; +- bit: D_{P'}·D_{P−P'} = D_P for P' ≤ P (the parent's identity D_I·D_P = D_{I−P}). + +## 2. Hosting lemma + +Fix a data family F (replica r, pair j, side, port) and an idle child Γ that advances pair j at recipe position τ. +Let λ be the position of the last local invocation or bridge that names pair j before τ; idle children do not +count as touches, since they act on other coordinates or on the other member. Let ι be any local invocation with +λ < ι < τ. Then: + +1. ι is an invocation on another pair, and nothing touches F between ι and τ. +2. A helper residual of ι, of width w, may be owned by stream (F, d·σ⁻¹) instead of a bank slot. Here d is the + invocation's cover class, and σ is a coordinate isometry carrying the local residual block onto a set S' ⊂ S of + w pending coordinates. When S' meets the local block of a level −1 advance, σ is composed with U_q ⊕ I. +3. Γ is replaced by Γ' acting on S ∖ ⋃S' over all hosted residuals of F, which have pairwise disjoint S'. + +The complete program's operator is unchanged: + +- By (a), ι applies exactly the factor on S' to (F, d·σ⁻¹), for any prior contents. +- Nothing else acts on F between ι and τ, so this factor may be moved to τ. +- By (b), the moved factors times Γ' equal Γ. + +Distinct slots of one invocation have distinct σ, so distinct physical classes for every d. They are also disjoint +from the invocation's own data owners, because pair j is not active, and from bank owners, because the families +differ. Residuals of different invocations on F occupy disjoint coordinates. They are sequential, exactly as the +parent's banks are co-owned sequentially by different cover classes. + +Two further points: + +- **Phases.** The stored Z₄ translations after Γ remain valid, because Γ'·∏(hosted factors) = Γ as exact operators. + The final X_δ(g) correction still applies to every live family; hosting changes no data endpoint. +- **Reflection.** The inverse-transpose program reverses chronology and reflects each factor. The window condition + (no touch strictly between ι and τ) is symmetric, so hosting commutes with reflection. + +## 3. What is checked here + +- `bit_hosted.py` and `complex_hosted.py` read #434's freshly regenerated templates and compute windows from each + recipe. They apply a frozen integer-programme selection (`SELECTION.json`; `--discover` recomputes it with scipy) + and emit new owners, remainder children and banks. + - Bit: unhosted residuals keep an exact width-64 tiling with no padding. + - Complex: eight per bank plus one paid pad; a final partial bank pays the larger pad. +- `audit.py` shares no code with the generators. It re-derives every window from the template schedule. For every + replica and invocation it checks that: + - each helper has exactly one owner; + - each hosted slot is inside its child's pending set, disjoint from other slots, outside the active pair, and in + window; + - every remainder child is exact, and the bank tiling is exact. + + It also recomputes the paid profile and the rank deficit 2496, and rejects nine mutations. +- `assemble.py` prices both suppliers with the two inherited rational moment engines and recomputes both finite + invoices with the hosted stock. Route charging is conservative: two extra route factors per helper selector, and + the parent's larger complex per-vertex bill is kept. It then runs #434's strict outer assembly: six bootstrap + levels and 47 inequalities. The next grid point and the zero-η, zero-β and unit-β controls are rejected. + +## 4. Result + +| | live stock | max child | hosted residuals | certified saving | +| --- | ---: | ---: | ---: | --- | +| bit | 14,259 → 9,457 | 42 → 8 | 39,568 of 53,784 | c = 1239085165241180038597/10²⁴ | +| complex | 12,720 → 8,400 | 48 → 8 | 34,560 of 40,320 | b = 1267453159029119/10¹⁸ | + +κ = 618775866623647/(5·10¹⁷) ≈ 1.237551733247294·10⁻³, bit-bound, +9.218% over #434. + +## 5. Scope + +This is a written finite extension of the inherited correlated dirty-bank and compressed-window interfaces. The +streams that own residuals now include data streams during idle windows. It is the principal new review point. + +All other interfaces remain inherited assumptions: the all-size compiler, restored-work, tape/common-grid, precision +and analytic interfaces. + +No Lean proof and no unconditional integer-multiplication theorem is claimed. The global operator identity is argued +from (a) and (b) and checked combinatorially. It is not replayed numerically on the 2⁷³- and 2⁶⁴-point address +spaces; neither parent does that either. diff --git a/research/idle-axis-hosting/README.md b/research/idle-axis-hosting/README.md new file mode 100644 index 0000000000..9d9b80cc3b --- /dev/null +++ b/research/idle-axis-hosting/README.md @@ -0,0 +1,42 @@ +# Idle-axis hosting on #434: conditional κ ≈ 1.2375517·10⁻³ + +This package moves whole dirty-helper residuals of both E8 suppliers from bank streams onto the pending coordinates of +idle data families. Those coordinates would otherwise be advanced by idle children later in the nine-stage template. + +Neither local word changes: + +- complex: #433's split-centre word, R = 560; +- bit: #434's early-reset kernel word, R = 747. + +**Result:** κ = 618775866623647/(5·10¹⁷) ≈ 1.237551733247294·10⁻³, bit-bound, **+9.218% over #434** +(1.133100552284434·10⁻³). + +| supplier | parent saving | hosted saving | live stock | max child | +| --- | --- | --- | --- | --- | +| bit, m = 64 | 1.134386·10⁻³ | **1.239085·10⁻³** | 14,259 → 9,457 | 42 → 8 | +| complex, m = 73 | 1.183987·10⁻³ | **1.267453·10⁻³** | 12,720 → 8,400 | 48 → 8 | + +**Why it gains.** Idle advance children are about a sixth of the paid cost of the compressed window. A dirty helper +residual acts on its stream as the same kind of coordinate factor an idle child applies. Hosting the residual there +removes the bank stream, its padding, and that part of the idle child, and the rank deficit stays at 2496. + +The validity condition is a window: the host family must be untouched between the hosting invocation and its +scheduled advance. [PROOF.md](PROOF.md) gives the argument and its scope. + +## Verify + +```sh +python3 -B research/idle-axis-hosting/verify.py /absolute/new/output +``` + +- Uses Python 3.11+ and the standard library only. +- The output directory must not exist. +- It runs #434's complete `verify.py` from scratch, then the bit and complex hosting generators, the independent + audit (nine mutation controls) and the exact assembly. It compares every value with `EXPECTED.json`. +- `SELECTION.json` freezes the integer-programme choice. `--discover` on either generator recomputes it with scipy. + +## Scope + +This is conditional, like its parents. The extension of the correlated dirty-bank interface to idle data streams is +the new review point. All-size compiler, compressed-window, restored-work, tape/common-grid, precision and analytic +interfaces are inherited. No Lean proof or unconditional theorem is claimed. diff --git a/research/idle-axis-hosting/SELECTION.json b/research/idle-axis-hosting/SELECTION.json new file mode 100644 index 0000000000..e3303cd97d --- /dev/null +++ b/research/idle-axis-hosting/SELECTION.json @@ -0,0 +1,553 @@ +{ + "bit": { + "patterns": [ + [ + 0, + [ + 7, + 7 + ], + 104 + ], + [ + 0, + [ + 8 + ], + 136 + ], + [ + 1, + [], + 136 + ], + [ + 1, + [ + 7 + ], + 104 + ], + [ + 2, + [ + 7, + 7, + 7, + 7 + ], + 26 + ], + [ + 2, + [ + 8, + 8, + 8 + ], + 190 + ], + [ + 2, + [ + 8, + 8, + 8, + 4 + ], + 24 + ], + [ + 3, + [], + 130 + ], + [ + 3, + [ + 4 + ], + 6 + ], + [ + 3, + [ + 7 + ], + 104 + ], + [ + 4, + [ + 8, + 8, + 8, + 8, + 8 + ], + 240 + ], + [ + 5, + [], + 136 + ], + [ + 5, + [ + 7 + ], + 104 + ], + [ + 6, + [ + 8, + 8, + 8, + 8, + 8 + ], + 240 + ], + [ + 7, + [ + 7, + 7, + 7, + 7 + ], + 26 + ], + [ + 7, + [ + 8, + 8, + 8 + ], + 190 + ], + [ + 7, + [ + 8, + 8, + 8, + 4 + ], + 24 + ], + [ + 8, + [ + 7, + 7 + ], + 104 + ], + [ + 8, + [ + 8 + ], + 136 + ] + ], + "proxy_saving": 23281.85835940203, + "stages": [ + [ + 0, + 7, + 0, + 104 + ], + [ + 0, + 7, + 1, + 104 + ], + [ + 0, + 8, + 1, + 136 + ], + [ + 1, + 7, + 2, + 104 + ], + [ + 2, + 4, + 0, + 6 + ], + [ + 2, + 4, + 1, + 6 + ], + [ + 2, + 4, + 2, + 6 + ], + [ + 2, + 4, + 3, + 6 + ], + [ + 2, + 7, + 3, + 104 + ], + [ + 2, + 8, + 1, + 5 + ], + [ + 2, + 8, + 2, + 637 + ], + [ + 3, + 4, + 4, + 6 + ], + [ + 3, + 7, + 4, + 104 + ], + [ + 4, + 8, + 3, + 637 + ], + [ + 4, + 8, + 5, + 563 + ], + [ + 5, + 7, + 6, + 104 + ], + [ + 6, + 8, + 4, + 563 + ], + [ + 6, + 8, + 6, + 637 + ], + [ + 7, + 4, + 5, + 6 + ], + [ + 7, + 4, + 6, + 6 + ], + [ + 7, + 4, + 7, + 6 + ], + [ + 7, + 4, + 8, + 6 + ], + [ + 7, + 7, + 5, + 104 + ], + [ + 7, + 8, + 7, + 501 + ], + [ + 7, + 8, + 8, + 141 + ], + [ + 8, + 7, + 7, + 104 + ], + [ + 8, + 7, + 8, + 104 + ], + [ + 8, + 8, + 7, + 136 + ] + ] + }, + "complex": { + "patterns": [ + [ + 0, + [ + 9 + ], + 120 + ], + [ + 2, + [ + 9 + ], + 120 + ], + [ + 4, + [ + 9, + 9, + 9 + ], + 120 + ], + [ + 6, + [ + 9, + 9, + 9 + ], + 120 + ], + [ + 8, + [ + 9, + 9, + 9, + 9, + 9 + ], + 120 + ], + [ + 10, + [ + 9, + 9, + 9, + 9, + 9 + ], + 120 + ], + [ + 12, + [ + 9, + 9, + 9, + 9, + 9 + ], + 120 + ], + [ + 13, + [ + 9, + 9, + 9, + 9, + 9 + ], + 120 + ], + [ + 14, + [ + 9, + 9, + 9 + ], + 120 + ], + [ + 15, + [ + 9, + 9, + 9 + ], + 120 + ], + [ + 16, + [ + 9 + ], + 120 + ], + [ + 17, + [ + 9 + ], + 120 + ] + ], + "proxy_saving": 17393.16581129622, + "stages": [ + [ + 0, + 9, + 0, + 120 + ], + [ + 2, + 9, + 0, + 80 + ], + [ + 2, + 9, + 1, + 40 + ], + [ + 4, + 9, + 3, + 360 + ], + [ + 6, + 9, + 0, + 360 + ], + [ + 8, + 9, + 1, + 520 + ], + [ + 8, + 9, + 5, + 80 + ], + [ + 10, + 9, + 2, + 560 + ], + [ + 10, + 9, + 3, + 40 + ], + [ + 12, + 9, + 4, + 560 + ], + [ + 12, + 9, + 7, + 40 + ], + [ + 13, + 9, + 5, + 360 + ], + [ + 13, + 9, + 6, + 200 + ], + [ + 13, + 9, + 7, + 40 + ], + [ + 14, + 9, + 6, + 360 + ], + [ + 15, + 9, + 7, + 360 + ], + [ + 16, + 9, + 8, + 120 + ], + [ + 17, + 9, + 7, + 120 + ] + ] + } +} diff --git a/research/idle-axis-hosting/assemble.py b/research/idle-axis-hosting/assemble.py new file mode 100644 index 0000000000..f07a598643 --- /dev/null +++ b/research/idle-axis-hosting/assemble.py @@ -0,0 +1,82 @@ +"""Two exact moments for both hosted suppliers, fresh finite invoices with the hosted stock, and the strict outer +assembly of #434 (six bootstrap levels, 47 inequalities, next-grid and parameter controls). +usage: assemble.py PARENT_CHANGED_DIR BIT_DIR COMPLEX_DIR AUDIT.json OUT.json""" +import gzip, hashlib, importlib.util, json, math, sys +from fractions import Fraction as Q +from pathlib import Path +par, bd, cd, ap, outp = map(Path, sys.argv[1:6]) +def load(name): + sp = importlib.util.spec_from_file_location('hosted_' + name, par / 'work/pr361/code/engines' / (name + '.py')) + mod = importlib.util.module_from_spec(sp); sp.loader.exec_module(mod); return mod +M, Other, Outer = load('moment'), load('base_two_moment'), load('outer') +audit = json.loads(ap.read_text()); bg = json.loads((bd / 'GLOBAL.json').read_text()); ch = json.loads((cd / 'HOSTED.json').read_text()) +assert audit['bit_template_sha256'] == bg['template_sha256'] and audit['complex_template_sha256'] == ch['template_sha256'] +# ---------------- bit: two moments and the parent's invoice formulas with the hosted stock +P = {int(r): n for r, n in audit['bit_profile'].items()}; m, W = 64, audit['bit_live']; E = sum(P.values()) +geo = json.loads((par / 'bit426-source-centres/global/GEOMETRY.json').read_text()) +pg = json.loads((par / 'bit426-source-centres/global/GLOBAL.json').read_text()) +T, L, R, V, K = 8, 9, 747, 120, 4 +mass = sum(r * z for r, z in P.items()); assert m * W - mass == 2496 +physical = W + 9; d = m * m; N = 2 * m +unit = L * T * pg['local_additions'] + pg['bridge_additions'] +J = 8 * T * L * (2 * V + R) + 8 * (2 * K * V * T) + 2 * L * T * R + 2 * pg['copy_erase_episodes'] # every helper route charged (bank or hosted) +high = 16 * (d + 1) ** 2; good = 8 * m * m + 8; compiler = 128 * N ** 3 +selectors = 2 * L * T * ((W - 1) + R * m * (geo['max_route_factors'] + 2 + (m - 1) + m)) # +2: hosted route may add a slot permutation and U_q +prefix = int(pg['global_prefix_bound']); charged_prefix = 64 * ((prefix.bit_length() + 63) // 64) +coefficient = unit + J * high + J * physical + E * (good + compiler) + 16 * m ** 3 + pg['copy_erase_episodes'] + selectors + prefix + 1 +two = (coefficient + 1) ** 2 * (E + 1) ** 2; charged_two = 64 * ((two.bit_length() + 63) // 64) +assert two < 1 << charged_two and 2 * max(P) ** 2 < m * m +row = 2 * (m * m + 1) + 9909 + 252; assert row == 18355 < 20161 +root = M.certify(P, m, W, True); c = Q(root['lower']); chi = Q(root['upper']) +fb = 32 * m * m * E +lo, hi = Other.moment(m, W, list(P.items()), c); bl, bh = Other.moment(m, W, [(1, fb)], c); assert hi + bh / 10 ** 16 < 1 +lo2, hi2 = Other.moment(m, W, list(P.items()), chi); bl2, bh2 = Other.moment(m, W, [(1, fb)], chi); assert lo2 + bl2 / 10 ** 16 > 1 +# ---------------- complex: two moments and the parent's invoice with the hosted stock +PC = {int(r): n for r, n in audit['complex_profile'].items()}; mc, WC = 73, audit['complex_live']; EC = sum(PC.values()) +massc = sum(r * z for r, z in PC.items()); assert mc * WC - massc == 2496 +rc = M.certify(PC, mc, WC, True); b = Q(int(Q(rc['lower']) * 10 ** 18), 10 ** 18) +fbc = 32 * mc * mc * EC +l3, h3 = Other.moment(mc, WC, list(PC.items()), b); b3, bh3 = Other.moment(mc, WC, [(1, fbc)], b); assert h3 + bh3 / 10 ** 16 < 1 +integ = json.loads((par / 'split-centres/INTEGRATION.json').read_text()); inv = integ['finite_invoice'] +physc = ch['physical']; Rc = 560; v = 120 +compilerc = 64 * (mc + 1) ** 3 +pervertex = inv['pervertex'] - integ['physical'] * (64 + 1) + physc * (64 + 1) - integ['live'] + WC # stock-dependent terms re-based +r_ = mc // 2; group = 2 ** (r_ * r_) * math.prod(2 ** (2 * i) - 1 for i in range(1, r_ + 1)); stock = group * physc +smass = group * massc; logical = group * max(pervertex, inv['pervertex']) + 64; router = compilerc * (logical + 1) * (stock + 1) ** 2 +GG, EE, C0 = 1 << 30000, 1 << 100000, 1 << 210000; BB = smass + EE +literal = 2 * GG * stock ** 2 + 8 * smass + 4 * stock + 4 + 32 * mc +assert logical < 1 << 6050 and router < GG and literal < EE and BB < 1 << 100001 and 32 * mc * BB * BB < C0 and 2 * BB + 18 < C0 +depth = 2; assert mc ** depth > 2 * max(PC) ** depth +rowc = depth * stock.bit_length() + 9909 + 252; assert rowc < 20161 +# ---------------- outer assembly exactly as #434's combined.py +eta = beta = Q(1, 10 ** 18); grid = Q(1, 10 ** 18); s = min(c, (1 - beta) * b) - Q(1, 10 ** 24) +assert 0 < s < c and s < (1 - beta) * b +chain = [Q(384599, 10 ** 10)]; cutoffs = [] +def ceil(x): return -((-x.numerator) // x.denominator) +for j in range(6): + old = chain[-1]; a = (1 - s) * s + s * old + gap = min(s - a, 1 - a - s, 1 - a - s * (1 - old), 1 - s); assert old < a < s < 1 - a and gap > 0 + cutoff = max(ceil(36 / gap ** 2), ceil(2 * (4 + charged_two) / gap)); assert cutoff * gap ** 2 >= 36 and cutoff * gap >= 2 * (4 + charged_two) + cutoffs.append(dict(gap=str(gap), cutoff_log2=str(cutoff))); chain.append(a) +q = chain[-1] * (1 - 2 * eta); margin = (1 - eta) * q / (1 + q); ticks = margin / grid; k = grid * ((ticks.numerator - 1) // ticks.denominator) +bridge = {'semantic': {'C0': {'base': 2, 'exponent': 210000}, 'strict_literal_gap': 1}, 'rows': {'degree_gap': Q(10 ** 6) - Q(51 * 20161, 25)}} +a = Outer.assembly(chain[-1], b, bridge, k, eta=eta, beta=beta) +assert len(a['strict_constraints']) == 47 and all(x > 0 for x in a['strict_constraints'].values()) +controls = [] +for name, kk, ee, bb in [('next_grid', k + grid, eta, beta), ('zero_eta', k, Q(0), beta), ('zero_beta', k, eta, Q(0)), ('unit_beta', k, eta, Q(1))]: + try: Outer.assembly(chain[-1], b, bridge, kk, eta=ee, beta=bb) + except AssertionError: controls.append(name) + else: raise AssertionError(name) +parent_k = Q(566550276142217, 500000000000000000) +res = dict(status='PASS_CONDITIONAL_IDLE_AXIS_HOSTING_ASSEMBLY', kappa=str(k), kappa_decimal=format(float(k), '.18f'), + bit_lower=str(c), complex_lower=str(b), binding_component='bit' if c < (1 - beta) * b else 'complex', + gain_over_pr434_percent=float(100 * (k / parent_k - 1)), + bit=dict(live=W, physical=physical, maxchild=max(P), rank_mass=mass, hosted_residuals=audit['bit_hosted_residuals'], + prefix_bits=prefix.bit_length(), charged_prefix_bits=charged_prefix, coefficient_bits=coefficient.bit_length(), + two_level_coefficient_bits=two.bit_length(), charged_two_level_coefficient_bits=charged_two, row_coefficient=row), + complex=dict(live=WC, physical=physc, maxchild=max(PC), rank_mass=massc, hosted_residuals=audit['complex_hosted_residuals'], + physical_stock_bits=stock.bit_length(), router_bits=router.bit_length(), literal_bits=literal.bit_length(), row_coefficient=rowc), + strict_outer_constraints={n: str(x) for n, x in a['strict_constraints'].items()}, outer_controls=controls, bootstrap=cutoffs, + bit_template_sha256=bg['template_sha256'], complex_template_sha256=ch['template_sha256']) +outp.write_text(json.dumps(res, indent=2) + '\n') +print(res['status'], res['kappa_decimal'], 'binding', res['binding_component'], 'gain over #434 %.4f%%' % res['gain_over_pr434_percent']) diff --git a/research/idle-axis-hosting/audit.py b/research/idle-axis-hosting/audit.py new file mode 100644 index 0000000000..bd40b9b791 --- /dev/null +++ b/research/idle-axis-hosting/audit.py @@ -0,0 +1,159 @@ +"""Independent audit of the two idle-axis-hosted templates (no code shared with the generators). +Re-derives hosting windows from each template's own schedule and checks, for every replica and invocation: + * every helper residual has exactly one owner: a bank slot or a hosted slot; + * a hosted slot lies on the data family of the idle child it names, inside that child's pending coordinates, + disjoint from every other hosted slot of the family, and its invocation lies strictly between the last + local invocation or bridge naming that pair and the child (the window); + * the child keeps exactly the remaining coordinates; banks are tiled exactly (bit) or padded (complex); + * the emitted paid profile, live stock and rank deficit 2496 are recomputed from scratch. +Mutation controls must be rejected. usage: audit.py PARENT_CHANGED_DIR BIT_DIR COMPLEX_DIR OUT.json""" +import copy, gzip, hashlib, json, sys +from collections import Counter, defaultdict +from pathlib import Path +V, K, T, L = 120, 4, 8, 9 +DATA = 2 * K * V * T + +def wins(events): + """events: ('local', stage, pair) | ('bridge', a, b) | ('idle', idx, pair); window = local stages after the last + local/bridge touch of the pair and before the child""" + last = {}; seen = []; w = {} + for pos, e in enumerate(events): + if e[0] == 'local': seen.append((pos, e[1], e[2])); last[e[2]] = pos + elif e[0] == 'bridge': last[e[1]] = pos; last[e[2]] = pos + else: + lo = last.get(e[2], -1); w[e[1]] = {s for q, s, p in seen if lo < q < pos and p != e[2]} + return w + +def audit_bit(t, parent_t, widths): + assert t['local_programs'] == parent_t['local_programs'] and len(t['calls']) == 72 + ev = []; rank = {}; pair = {} + for e in t['schedule']: + if e['kind'] == 'local_cover_sweep': ev.append(('local', e['stage'], e['pair'])) + elif e['kind'] == 'bridge': ev.append(('bridge', e['dst'], e['src'])) + elif e['kind'] == 'idle': + ev.append(('idle', e['idx'], e['pair'])); rank[e['idx']] = e['rank']; pair[e['idx']] = e['pair'] + W = wins(ev); hs = t['hosting'] + used = defaultdict(set); hosted = {} + for i, cp, off, w, s, h in hs['slots']: + assert s in W[i], ('window', i, s) + assert w == widths[h] and 0 <= off and off + w <= rank[i] + cells = set(range(off, off + w)); assert not cells & used[i, cp], ('overlap', i, cp); used[i, cp] |= cells + assert (s, h) not in hosted; hosted[s, h] = (i, cp, off, w) + rem = {} + for i in rank: + if rank[i] == 0: continue + for cp in range(2 * V): rem[i, cp] = rank[i] - len(used[i, cp]) + rr = Counter(rem[i, cp] for cp in range(2 * V)) + if str(i) in hs['remainders']: assert {int(k): v for k, v in hs['remainders'][str(i)].items()} == dict(rr) + else: assert rr == Counter({rank[i]: 2 * V}) + occ = defaultdict(set); LIVE = t['live']; bank_lo = {} + for c in t['calls']: + s, rep, p = c['stage'], c['replica'], c['pair']; own = c['owners']; assert len(own) == 2 * V + len(widths) + assert own[:2 * V] == next(q for q in parent_t['calls'] if (q['stage'], q['replica']) == (s, rep))['owners'][:2 * V] + for h, (f, r) in enumerate(own[2 * V:]): + if (s, h) in hosted: + i, cp, off, w = hosted[s, h]; side, port = divmod(cp, V) + assert r == ['hosted', i, off, w] and f == rep * 960 + (2 * pair[i] + side) * V + port + assert pair[i] != p + occ['h', f, i, s, rep, h] = True + else: + assert r[0] == 'bank' and r[2] == widths[h] and DATA <= f < LIVE + cells = set(range(r[1], r[1] + r[2])); assert cells <= set(range(64)) and not cells & occ[f]; occ[f] |= cells + bank_lo[f] = s + banks = [f for f in occ if isinstance(f, int)] + assert sorted(banks) == list(range(DATA, LIVE)) and all(occ[f] == set(range(64)) for f in banks) + paid = Counter() + for c in t['calls']: + for z in t['local_programs'][c['orientation']]: + if z[0] == 0 and z[4]: paid[z[4]] += 1 + if z[0] == 2: paid[z[5]] += 1 + for (i, cp), r_ in rem.items(): + if r_: paid[r_] += T + mass = sum(r * n for r, n in paid.items()); assert 64 * LIVE - mass == 2496 + assert 64 * 64 > 2 * max(paid) ** 2 + return paid, sum(1 for _ in hosted) * T + +def audit_complex(t, parent_t, local_checks): + R = 560; m = 73 + assert t['local_programs'] == parent_t['local_programs'] and len(t['calls']) == 72 + prank = {} + for it in parent_t['idle_children']: prank.setdefault(it['child'], it['rank']) + stage_pair = {e['stage']: e['pair'] for e in t['recipe'] if e['kind'] == 'local'} + ev = []; side = {}; pairs = {} + for e in t['execution_schedule']: + if e['kind'] == 'local_cover_sweep': ev.append(('local', e['stage'], stage_pair[e['stage']])) + elif e['kind'] == 'bridge': ev.append(('bridge', e['dst'], e['src'])) + elif e['kind'] == 'idle_cover_sweep': + for sd, ch in enumerate(e['child_indices']): + if ch in prank: ev.append(('idle', ch, e['pair'])); side[ch] = sd; pairs[ch] = e['pair'] + W = wins(ev); hs = t['hosting'] + used = defaultdict(set); hosted = {} + for i, port, off, w, s, h in hs['slots']: + assert w == 9 and s in W[i] and 0 <= off and off + 9 <= prank[i] + cells = set(range(off, off + 9)); assert not cells & used[i, port]; used[i, port] |= cells + assert (s, h) not in hosted; hosted[s, h] = (i, port, off) + rem = {} + for it in parent_t['idle_children']: rem[it['child'], it['port']] = it['rank'] - len(used[it['child'], it['port']]) + got = {(it['child'], it['port']): it['rank'] for it in t['idle_children']} + assert got == {k: r for k, r in rem.items() if r} and all(it['replicas'] == T for it in t['idle_children']) + LIVE = t['live']; occ = defaultdict(set) + for c in t['calls']: + s, rep, p = c['stage'], c['replica'], c['pair']; own = c['owners']; assert len(own) == 2 * V + R + assert own[:2 * V] == next(q for q in parent_t['calls'] if (q['stage'], q['replica']) == (s, rep))['owners'][:2 * V] + for h, (f, r) in enumerate(own[2 * V:]): + if (s, h) in hosted: + i, port, off = hosted[s, h] + assert r == [3, i, off] and f == rep * 960 + (2 * pairs[i] + side[i]) * V + port and pairs[i] != p + else: + assert r[0] == 2 and 0 <= r[1] < 8 and DATA <= f < LIVE and r[1] not in occ[f]; occ[f].add(r[1]) + banks = sorted(occ); assert banks == list(range(DATA, LIVE)) + paid = Counter() + for c in t['calls']: + for r_, z in local_checks[c['orientation']]['paid_profile'].items(): paid[int(r_)] += z + for (ch, port), r_ in rem.items(): + if r_: paid[r_] += T + for f in banks: paid[m - 9 * len(occ[f])] += 1 + mass = sum(r * n for r, n in paid.items()); assert m * LIVE - mass == 2496 + assert m * m > 2 * max(paid) ** 2 + return paid, len(hosted) * T + +def main(): + par, bd, cd, outp = map(Path, sys.argv[1:5]) + pbt = json.loads(gzip.decompress((par / 'bit426-source-centres/global/GLOBAL-TEMPLATE.json.gz').read_bytes())) + bt = json.loads(gzip.decompress((bd / 'GLOBAL-TEMPLATE.json.gz').read_bytes())) + bg = json.loads((bd / 'GLOBAL.json').read_text()) + assert hashlib.sha256(gzip.decompress((bd / 'GLOBAL-TEMPLATE.json.gz').read_bytes())).hexdigest() == bg['template_sha256'] + st = json.loads((par / 'bit426-source-centres/records/249-states.json').read_text()) + fs = json.loads((par / 'bit426-source-centres/records/frames.json').read_text())['frames'] + widths = [8 - fs[str(st['initial'][str(i)])]['dim'] for i in range(240, 987)] + pct = json.loads(gzip.decompress((par / 'split-centres/GLOBAL-TEMPLATE.json.gz').read_bytes())) + ct = json.loads(gzip.decompress((cd / 'GLOBAL-TEMPLATE.json.gz').read_bytes())) + ch = json.loads((cd / 'HOSTED.json').read_text()) + assert hashlib.sha256(gzip.decompress((cd / 'GLOBAL-TEMPLATE.json.gz').read_bytes())).hexdigest() == ch['template_sha256'] + lc = json.loads((par / 'split-centres/LOCAL-CHECKS.json').read_text()) + bp, bh = audit_bit(bt, pbt, widths); assert bp == Counter({int(k): v for k, v in bg['profile'].items()}) + cp, chh = audit_complex(ct, pct, lc); assert cp == Counter({int(k): v for k, v in ch['global_profile'].items()}) + controls = [] + def reject(name, fn, which): + q = copy.deepcopy(bt if which == 'bit' else ct); fn(q) + try: + (audit_bit(q, pbt, widths) if which == 'bit' else audit_complex(q, pct, lc)) + except (AssertionError, KeyError, IndexError, StopIteration): controls.append(name) + else: raise AssertionError('mutation accepted: ' + name) + def outside(q): # move one hosted residual to a stage outside its window + sl = q['hosting']['slots'][0]; i = sl[0]; s_bad = next(s for s in range(9) if s not in q['hosting']['windows'][str(i)][2]); sl[4] = s_bad + reject('bit: hosted residual outside its window', outside, 'bit') + reject('bit: overlapping hosted coordinates', lambda q: q['hosting']['slots'][1].__setitem__(2, q['hosting']['slots'][0][2]) if q['hosting']['slots'][1][:2] == q['hosting']['slots'][0][:2] else q['hosting']['slots'][1].__setitem__(1, q['hosting']['slots'][0][1]) or q['hosting']['slots'][1].__setitem__(2, q['hosting']['slots'][0][2]), 'bit') + reject('bit: understated live stock', lambda q: q.__setitem__('live', q['live'] - 1), 'bit') + reject('bit: hosted owner on the active pair', lambda q: q['calls'][0]['owners'].__setitem__(240 + next(h for h in range(747) if q['calls'][0]['owners'][240 + h][1][0] == 'hosted'), [0, ['hosted', 0, 0, 8]]), 'bit') + reject('bit: missing remainder child', lambda q: q['hosting']['slots'].pop(), 'bit') + reject('complex: hosted residual outside its window', lambda q: q['hosting']['slots'][0].__setitem__(4, next(s for s in range(9) if s not in q['hosting']['windows'][str(q['hosting']['slots'][0][0])][2])), 'complex') + reject('complex: remainder child understated', lambda q: q['idle_children'][0].__setitem__('rank', q['idle_children'][0]['rank'] - 1), 'complex') + reject('complex: dropped bank', lambda q: q.__setitem__('live', q['live'] - 1), 'complex') + reject('complex: duplicated hosted residual', lambda q: q['hosting']['slots'].append(list(q['hosting']['slots'][0])), 'complex') + res = dict(status='PASS_INDEPENDENT_IDLE_AXIS_HOSTING_AUDIT', bit_template_sha256=bg['template_sha256'], complex_template_sha256=ch['template_sha256'], + bit_profile={str(k): v for k, v in sorted(bp.items())}, complex_profile={str(k): v for k, v in sorted(cp.items())}, + bit_live=bt['live'], complex_live=ct['live'], bit_hosted_residuals=bh, complex_hosted_residuals=chh, + bit_maxchild=max(bp), complex_maxchild=max(cp), mutations_rejected=controls) + outp.write_text(json.dumps(res, indent=2) + '\n'); print(json.dumps({k: v for k, v in res.items() if 'profile' not in k})) +if __name__ == '__main__': main() diff --git a/research/idle-axis-hosting/bit_hosted.py b/research/idle-axis-hosting/bit_hosted.py new file mode 100644 index 0000000000..e2f015dbb7 --- /dev/null +++ b/research/idle-axis-hosting/bit_hosted.py @@ -0,0 +1,118 @@ +"""Idle-axis hosting for #434's compressed nine-stage bit template (m=64). +Reads the emitted parent template, keeps every local program and scalar replay unchanged, and moves whole helper +residuals from banks onto pending idle-advance coordinates of untouched data families. Emits a new template, +GLOBAL.json with the new live stock and paid profile. usage: bit_hosted.py PARENT_GLOBAL_DIR LOCAL_CHECK_DIR OUT""" +import gzip, hashlib, importlib.util, json, sys, time +from collections import Counter +from pathlib import Path +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE)) +import hosting_core as HC +spec = importlib.util.spec_from_file_location('bitparent', HERE.parent / 'e8-early-reset-kernel/bit_global.py') +BP = importlib.util.module_from_spec(spec); spec.loader.exec_module(BP) +H, V, R, L, K, T, M = 8, 120, 747, 9, 4, 8, 64 +DATA = 2 * K * V * T +DISCOVER = False +sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest() +def main(parent, local, out): + t0 = time.monotonic(); out.mkdir(parents=True, exist_ok=False) + blob = gzip.decompress((parent / 'GLOBAL-TEMPLATE.json.gz').read_bytes()); t = json.loads(blob) + g = json.loads((parent / 'GLOBAL.json').read_text()) + assert hashlib.sha256(blob).hexdigest() == g['template_sha256'] + st = json.loads((local / 'records/249-states.json').read_text()) + fs = json.loads((local / 'records/frames.json').read_text())['frames']; dims = {int(f): z['dim'] for f, z in fs.items()} + width = [H - dims[st['initial'][str(i)]] for i in range(2 * V, 2 * V + R)] + # schedule with indexed idle children + sched = []; idx = 0 + for e in t['schedule']: + if e['kind'] == 'local_cover_sweep': sched.append(dict(kind='local', stage=e['stage'], pair=e['pair'])) + elif e['kind'] == 'bridge': sched.append(dict(kind='bridge', dst=e['dst'], src=e['src'])) + elif e['kind'] == 'idle': + sched.append(dict(kind='idle', pair=e['pair'], rank=e['rank'], idx=idx)); e['idx'] = idx; idx += 1 + win = {k: x for k, x in HC.windows(sched).items() if x[1] > 0 and x[2]} + avail = Counter() + for s in range(L): + for w in width: avail[s, w] += 1 + sel = HERE / 'SELECTION.json'; key = 'bit' + if DISCOVER: + ys, zs, val = HC.solve(win, 2 * V, dict(avail), M, group={7: 8, 4: 2}); HC.save_selection(sel, key, ys, zs, val) + ys, zs, val = HC.load_selection(sel, key) + helpers = {s: [(h, width[h]) for h in range(R)] for s in range(L)} + slots, rem = HC.expand(win, ys, zs, helpers, 2 * V) + hosted = {(s, h): (i, c, off, w) for i, c, off, w, s, h in slots} + # remaining helpers -> exact width-64 banks (per stage, same set of helpers in every replica) + left = {s: [h for h in range(R) if (s, h) not in hosted] for s in range(L)} + nb = {}; place = {} + for s in range(L): + wl = {h: width[h] for h in left[s]} + slotsS = sorted(((wl[h], rep, h) for rep in range(T) for h in left[s]), key=lambda x: (-x[0], x[1], x[2])) + by = {} + for w_, rep, h in slotsS: by.setdefault(w_, []).append((rep, h)) + bins = [] + def take(w_): return by[w_].pop(0) + for w_ in sorted(by, reverse=True): + if w_ == 8: continue + while by.get(w_): + cont = []; off = 0 + if w_ == 7: + for _ in range(8): rep, h = take(7); cont.append((rep, h, off, 7)); off += 7 + rep, h = take(8); cont.append((rep, h, off, 8)); off += 8 + else: + for _ in range(64 // w_): rep, h = take(w_); cont.append((rep, h, off, w_)); off += w_ + assert off == 64; bins.append(cont) + while by.get(8): + cont = []; off = 0 + for _ in range(8): rep, h = take(8); cont.append((rep, h, off, 8)); off += 8 + bins.append(cont) + nb[s] = len(bins) + for b, cont in enumerate(bins): + for rep, h, off, w_ in cont: place[s, rep, h] = (b, off, w_) + base = [DATA] + for s in range(L): base.append(base[-1] + nb[s]) + LIVE = base[-1] + # owners + for c in t['calls']: + s, rep, p = c['stage'], c['replica'], c['pair']; own = c['owners'][:2 * V] + for h in range(R): + if (s, h) in hosted: + i, cp, off, w = hosted[s, h]; pair = win[i][0]; side, port = divmod(cp, V) + own.append([rep * 960 + (2 * pair + side) * V + port, ['hosted', i, off, w]]) + else: + b, off, w = place[s, rep, h]; own.append([base[s] + b, ['bank', off, w]]) + assert len({(f, tuple(r)) for f, r in own}) == 2 * V + R and all(0 <= f < LIVE for f, r in own) + c['owners'] = own + # profile: local programs unchanged; idle children replaced by remainders + paid = Counter() + for c in t['calls']: + for z in t['local_programs'][c['orientation']]: + if z[0] == 0 and z[4]: paid[z[4]] += 1 + if z[0] == 2: paid[z[5]] += 1 + remainder = {} + for e in t['schedule']: + if e['kind'] == 'idle' and e['rank']: + i = e['idx'] + if i in win: + rr = Counter(rem[i, cp] for cp in range(2 * V)); remainder[i] = {str(k): v for k, v in sorted(rr.items())} + for r_, n in rr.items(): + if r_: paid[r_] += n * T + else: + paid[e['rank']] += 2 * V * T + mass = sum(r * n for r, n in paid.items()); assert M * LIVE - mass == 2496, M * LIVE - mass + t.update(version='compressed-nine-e8-bit-v1+idle-axis-hosting', live=LIVE, + hosting=dict(windows={str(i): [w[0], w[1], sorted(w[2])] for i, w in win.items()}, + slots=[list(x) for x in slots], remainders=remainder, banks_per_stage=nb, + rule='helper (stage s, helper h) of replica r owns coordinates [off, off+w) of the pending idle-child ' + 'projector of data family r*960+(2*pair+side)*120+port (copy = side*120+port); s lies strictly between ' + 'the last local/bridge touch of that pair and the child; the child keeps the remaining coordinates.'), + helper_route='bank owner (exact width-64 tiling of the unhosted residuals of each stage) or hosted owner (data family, pending idle coordinates)') + tb = json.dumps(t, separators=(',', ':'), sort_keys=True).encode(); (out / 'GLOBAL-TEMPLATE.json.gz').write_bytes(gzip.compress(tb, mtime=0)) + res = dict(g); res.update(status='PASS_IDLE_AXIS_HOSTED_BIT_TEMPLATE', live=LIVE, physical=LIVE + 9, template_sha256=hashlib.sha256(tb).hexdigest(), + parent_template_sha256=g['template_sha256'], profile=dict(sorted(paid.items())), paid_calls=sum(paid.values()), rank_mass=mass, + maxchild=max(paid), banks_per_stage_hosted=nb, hosted_residuals_per_replica=len(slots), hosted_residuals=len(slots) * T, + hosted_coordinates_per_replica=sum(x[3] for x in slots), saved_idle_cost_proxy=val, seconds=time.monotonic() - t0) + res['bank_assignments'] = sum(1 for c in t['calls'] for f, r in c['owners'][2 * V:] if r[0] == 'bank') + (out / 'GLOBAL.json').write_text(json.dumps(res, indent=2) + '\n') + print(json.dumps({k: res[k] for k in ('live', 'maxchild', 'hosted_residuals', 'banks_per_stage_hosted', 'rank_mass')}), flush=True) +if __name__ == '__main__': + DISCOVER = '--discover' in sys.argv; args = [a for a in sys.argv[1:] if a != '--discover'] + main(Path(args[0]), Path(args[1]), Path(args[2])) diff --git a/research/idle-axis-hosting/complex_hosted.py b/research/idle-axis-hosting/complex_hosted.py new file mode 100644 index 0000000000..56e15c15ae --- /dev/null +++ b/research/idle-axis-hosting/complex_hosted.py @@ -0,0 +1,87 @@ +"""Idle-axis hosting for #433's compressed nine-stage complex template (m=73, R=560, whole rank-nine residuals). +Local programs, data routes and the cover correction are unchanged; bank slots of hosted residuals move onto pending +idle-child coordinates of untouched data families; unhosted residuals are re-tiled eight per bank with one paid pad +(a final partial bank pays the larger pad). usage: complex_hosted.py SPLIT_CENTRES_DIR OUT""" +import gzip, hashlib, json, math, sys, time +from collections import Counter +from pathlib import Path +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE)) +import hosting_core as HC +V, K, T, L, M, R = 120, 4, 8, 9, 73, 560 +DATA = 2 * K * V * T +DISCOVER = False +def main(src, out): + t0 = time.monotonic(); out.mkdir(parents=True, exist_ok=False) + blob = gzip.decompress((src / 'GLOBAL-TEMPLATE.json.gz').read_bytes()); t = json.loads(blob) + integ = json.loads((src / 'INTEGRATION.json').read_text()); checks = json.loads((src / 'LOCAL-CHECKS.json').read_text()) + assert hashlib.sha256(blob).hexdigest() == integ['global_template_sha256'] and t['live'] == integ['live'] + rank = {} + for it in t['idle_children']: + assert it['replicas'] == T; rank.setdefault(it['child'], it['rank']); assert rank[it['child']] == it['rank'] + pair_of_stage = {e['stage']: e['pair'] for e in t['recipe'] if e['kind'] == 'local'} + sched = []; side_of = {}; pair_of = {} + for e in t['execution_schedule']: + if e['kind'] == 'local_cover_sweep': sched.append(dict(kind='local', stage=e['stage'], pair=pair_of_stage[e['stage']])) + elif e['kind'] == 'bridge': sched.append(dict(kind='bridge', dst=e['dst'], src=e['src'])) + elif e['kind'] == 'idle_cover_sweep': + for sd, ch in enumerate(e['child_indices']): + if ch in rank: + sched.append(dict(kind='idle', pair=e['pair'], rank=rank[ch], idx=ch)); side_of[ch] = sd; pair_of[ch] = e['pair'] + win = {k: x for k, x in HC.windows(sched).items() if x[1] >= 9 and x[2]} + avail = {(s, 9): R for s in range(L)} + sel = HERE / 'SELECTION.json'; key = 'complex' + if DISCOVER: + ys, zs, val = HC.solve(win, V, avail, M, pad_value=HC.cost(1, M) / 8); HC.save_selection(sel, key, ys, zs, val) + ys, zs, val = HC.load_selection(sel, key) + slots, rem = HC.expand(win, ys, zs, {s: [(h, 9) for h in range(R)] for s in range(L)}, V) + hosted = {(s, h): (i, port, off) for i, port, off, w, s, h in slots} + # re-tile unhosted residuals: per stage, z = rank among (replica, helper) unhosted pairs; eight per bank + base = [DATA]; tile = {}; partial = Counter() + for s in range(L): + left = [(rep, h) for rep in range(T) for h in range(R) if (s, h) not in hosted] + for z, (rep, h) in enumerate(left): tile[s, rep, h] = divmod(z, 8) + nb = -(-len(left) // 8); base.append(base[-1] + nb) + if len(left) % 8: partial[M - 9 * (len(left) % 8)] += 1 + full = len(left) // 8 + partial[M - 72] += full + W = base[-1] + for c in t['calls']: + s, rep, p = c['stage'], c['replica'], c['pair']; own = c['owners'][:2 * V] + for h in range(R): + if (s, h) in hosted: + i, port, off = hosted[s, h]; own.append([rep * 960 + (2 * pair_of[i] + side_of[i]) * V + port, [3, i, off]]) + else: + b, sl = tile[s, rep, h]; own.append([base[s] + b, [2, sl]]) + assert len({(f, tuple(r)) for f, r in own}) == 2 * V + R and all(f < W for f, r in own) + c['owners'] = own + paid = Counter() + for c in t['calls']: + for r_, z in checks[c['orientation']]['paid_profile'].items(): paid[int(r_)] += z + newidle = [] + for it in t['idle_children']: + ch, port = it['child'], it['port']; rr = rem.get((ch, port), it['rank']) if ch in win else it['rank'] + if rr: newidle.append(dict(child=ch, port=port, rank=rr, hosted=it['rank'] - rr, replicas=T)); paid[rr] += T + for r_, n in partial.items(): paid[r_] += L * n if False else n * 1 + # padding: one pad child per bank per stage (already per-stage counted above), the template replays all stages + mass = sum(r * n for r, n in paid.items()); D = M * W - mass + assert D == 2496, D + t.update(version='hamming-mutable-basis-nine-v1+idle-axis-hosting', live=W, idle_children=newidle, + physical=W + R + (integ['physical'] - integ['live'] - R), + hosting=dict(windows={str(i): [w[0], w[1], sorted(w[2])] for i, w in win.items()}, sides=side_of, pairs=pair_of, + slots=[list(x) for x in slots], banks=[base[s + 1] - base[s] for s in range(L)])) + t['bank_padding']['families'] = list(range(DATA, W)); t['cover_final_correction']['families'] = [0, W] + t['cover_final_correction']['charged_calls_per_cover'] = W + for e in t['execution_schedule']: + if e['kind'] == 'bank_padding_cover_sweep': e['families'] = [DATA, W] + elif e['kind'] == 'translate_every_live_family': e.update(t['cover_final_correction']) + tb = json.dumps(t, sort_keys=True, separators=(',', ':')).encode(); (out / 'GLOBAL-TEMPLATE.json.gz').write_bytes(gzip.compress(tb, mtime=0)) + res = dict(status='PASS_IDLE_AXIS_HOSTED_COMPLEX_TEMPLATE', parent_template_sha256=integ['global_template_sha256'], + template_sha256=hashlib.sha256(tb).hexdigest(), live=W, physical=t['physical'], global_profile=dict(sorted(paid.items())), + rank_mass=mass, deficit=D, maxchild=max(paid), hosted_residuals=len(slots) * T, banks_per_stage=t['hosting']['banks'], + saved_cost_proxy=val, seconds=time.monotonic() - t0) + (out / 'HOSTED.json').write_text(json.dumps(res, indent=2) + '\n') + print(json.dumps({k: res[k] for k in ('live', 'maxchild', 'hosted_residuals', 'banks_per_stage', 'deficit')})) +if __name__ == '__main__': + DISCOVER = '--discover' in sys.argv; args = [a for a in sys.argv[1:] if a != '--discover'] + main(Path(args[0]), Path(args[1])) diff --git a/research/idle-axis-hosting/hosting_core.py b/research/idle-axis-hosting/hosting_core.py new file mode 100644 index 0000000000..68b536daa9 --- /dev/null +++ b/research/idle-axis-hosting/hosting_core.py @@ -0,0 +1,138 @@ +"""Idle-axis hosting: place whole dirty-helper residuals on the pending coordinates of an idle data family. + +A data family that is advanced by an idle child from level a to level b receives the commuting coordinate factors of +that child. If the family is untouched (no local invocation on its pair and no bridge naming its pair) during an +interval of local invocations ending at the child, a helper residual of width w from an invocation inside that +interval may own w of those pending coordinates instead of a bank slot. The child keeps only the remaining +coordinates. This module computes the windows from the recipe and chooses, per replica, how many residuals of each +width each child hosts (exact integer programme), then expands that choice into explicit slot assignments. +Standard library plus scipy for the integer programme; the emitted assignment is re-checked without scipy.""" +import math +from collections import Counter, defaultdict + +def windows(schedule): + """schedule: ordered events dict(kind='local',stage,pair) | dict(kind='bridge',dst,src) | dict(kind='idle',pair,rank,idx). + Returns {idx: (pair, rank, frozenset(stages))} - stages whose invocation lies strictly between the last touch of + the pair and the idle child.""" + last = {}; out = {}; locals_ = [] + for pos, e in enumerate(schedule): + k = e['kind'] + if k == 'local': + locals_.append((pos, e['stage'], e['pair'])); last[e['pair']] = pos + elif k == 'bridge': + last[e['dst']] = pos; last[e['src']] = pos + elif k == 'idle': + p = e['pair']; lo = last.get(p, -1) + st = frozenset(s for q, s, pp in locals_ if lo < q < pos and pp != p) + out[e['idx']] = (p, e['rank'], st) # an idle child acts on other coordinates (or the other member): not a touch + return out + +def patterns(rank, widths, maxk=12): + """multisets of widths with sum <= rank (as sorted tuples)""" + ws = sorted(set(widths), reverse=True); res = [] + def rec(i, cur, s): + if i == len(ws): res.append(tuple(cur)); return + w = ws[i]; k = 0 + while s + k * w <= rank and len(cur) + k <= maxk: + rec(i + 1, cur + [w] * k, s + k * w); k += 1 + rec(0, [], 0) + return res + +def cost(r, m): + return r * math.log(m / r) if r else 0.0 + +def solve(win, copies, avail, m, pad_value=0.0, group=None): + """win: {idx: (pair, rank, stages)}; copies: piece copies per replica of each idx (2V); + avail: {(stage, width): count per replica}; maximise saved idle cost (+ pad_value per hosted residual). + group: optional {width: g} - remaining count of that width per stage must be a multiple of g (exact bank tiling). + Returns {(idx, pattern): copies} and {(idx, width, stage): count}.""" + import numpy as np + from scipy.optimize import milp, LinearConstraint, Bounds + widths = sorted({w for (_, w) in avail}) + var = []; index = {} + for idx, (p, r, st) in win.items(): + for pat in patterns(r, widths): + index[('y', idx, pat)] = len(var); var.append(('y', idx, pat)) + for w in widths: + for s in st: + if avail.get((s, w), 0): + index[('z', idx, w, s)] = len(var); var.append(('z', idx, w, s)) + stages = sorted({s for (s, _) in avail}) + if group: + for w, g in group.items(): + for s in stages: + index[('g', w, s)] = len(var); var.append(('g', w, s)) + n = len(var); c = np.zeros(n); integ = np.ones(n); lb = np.zeros(n); ub = np.full(n, np.inf) + for key, j in index.items(): + if key[0] == 'y': + _, idx, pat = key; r = win[idx][1]; c[j] = -(cost(r, m) - cost(r - sum(pat), m) + pad_value * len(pat)) + rows, lo, hi = [], [], [] + for idx in win: + row = np.zeros(n) + for key, j in index.items(): + if key[0] == 'y' and key[1] == idx: row[j] = 1 + rows.append(row); lo.append(copies); hi.append(copies) + for w in widths: + row = np.zeros(n) + for key, j in index.items(): + if key[0] == 'y' and key[1] == idx: row[j] = key[2].count(w) + if key[0] == 'z' and key[1] == idx and key[2] == w: row[j] = -1 + rows.append(row); lo.append(0); hi.append(0) + for (s, w), a in avail.items(): + row = np.zeros(n) + for key, j in index.items(): + if key[0] == 'z' and key[2] == w and key[3] == s: row[j] = 1 + if group and w in group: + row[index[('g', w, s)]] = group[w]; rows.append(row); lo.append(a); hi.append(a) # used + g*k = avail + else: + rows.append(row); lo.append(0); hi.append(a) + res = milp(c, constraints=LinearConstraint(np.array(rows), lo, hi), integrality=integ, bounds=Bounds(lb, ub), + options=dict(time_limit=600, disp=False)) + assert res.x is not None, res.message + x = [int(round(t)) for t in res.x] + ys = {(k[1], k[2]): x[j] for k, j in index.items() if k[0] == 'y' and x[j]} + zs = {(k[1], k[2], k[3]): x[j] for k, j in index.items() if k[0] == 'z' and x[j]} + return ys, zs, -res.fun + +def expand(win, ys, zs, helpers, V2): + """helpers: {stage: [(helper, width), ...]} for ONE replica; returns list of + (idx, copy, offset, width, stage, helper) and the remainder rank of every (idx, copy). + Copies of a piece are the 2V (side, port) data families; residuals packed from offset 0 in decreasing width.""" + pool = defaultdict(list) # (stage, width) -> helpers + for s, hs in helpers.items(): + for h, w in hs: pool[s, w].append(h) + for k in pool: pool[k].sort() + need = defaultdict(list) # (idx, width) -> stages multiset in deterministic order + for (idx, w, s), cnt in sorted(zs.items()): need[idx, w] += [s] * cnt + out = []; rem = {} + for idx in sorted(win): + pats = sorted([(pat, cnt) for (i, pat), cnt in ys.items() if i == idx], key=lambda t: (-sum(t[0]), t[0])) + copy = 0; ptr = Counter() + r = win[idx][1] + for pat, cnt in pats: + for _ in range(cnt): + off = 0 + for w in sorted(pat, reverse=True): + s = need[idx, w][ptr[idx, w]]; ptr[idx, w] += 1 + h = pool[s, w].pop(0) + out.append((idx, copy, off, w, s, h)); off += w + rem[idx, copy] = r - off; copy += 1 + while copy < V2: rem[idx, copy] = r; copy += 1 + return out, rem + +def save_selection(path, key, ys, zs, val): + """freeze the integer-programme choice (patterns per child, residual stages per child) for stdlib-only replay""" + import json + from pathlib import Path + p = Path(path); d = json.loads(p.read_text()) if p.exists() else {} + d[key] = dict(patterns=sorted([[i, list(pat), n] for (i, pat), n in ys.items()]), + stages=sorted([[i, w, s, n] for (i, w, s), n in zs.items()]), proxy_saving=val) + p.write_text(json.dumps(d, indent=1, sort_keys=True) + '\n') + +def load_selection(path, key): + import json + from pathlib import Path + d = json.loads(Path(path).read_text())[key] + ys = {(i, tuple(pat)): n for i, pat, n in d['patterns']} + zs = {(i, w, s): n for i, w, s, n in d['stages']} + return ys, zs, d['proxy_saving'] diff --git a/research/idle-axis-hosting/verify.py b/research/idle-axis-hosting/verify.py new file mode 100644 index 0000000000..0aa6cefd02 --- /dev/null +++ b/research/idle-axis-hosting/verify.py @@ -0,0 +1,38 @@ +"""Fresh replay: #434 in full, then idle-axis hosting of both suppliers, independent audit and exact assembly. +usage: python -B research/idle-axis-hosting/verify.py /absolute/new/output (Python 3.11+, standard library only)""" +from pathlib import Path +import gzip, hashlib, json, os, subprocess, sys, time +assert __debug__ +ROOT = Path(__file__).resolve().parent; PARENT = ROOT.parent / 'e8-early-reset-kernel' +out = Path(sys.argv[1]).resolve(); assert not out.exists() and not out.is_relative_to(ROOT.parent) +read = lambda p: json.loads(Path(p).read_text()); sha = lambda p: hashlib.sha256(Path(p).read_bytes()).hexdigest() +def integrity(): + files = {p.relative_to(ROOT).as_posix(): sha(p) for p in ROOT.rglob('*') if p.is_file() and p.name != 'MANIFEST.json' and '__pycache__' not in p.parts} + assert files == read(ROOT / 'MANIFEST.json')['files'], 'manifest mismatch' + assert sha(PARENT / 'MANIFEST.json') == read(ROOT / 'MANIFEST.json')['parent_manifest_sha256'], 'parent package changed' +integrity(); out.mkdir(parents=True) +env = dict(os.environ, PYTHONDONTWRITEBYTECODE='1', PYTHONINTMAXSTRDIGITS='0'); env.pop('PYTHONOPTIMIZE', None); steps = [] +def run(name, file, *args, cwd=None): + t = time.monotonic(); log = out / (name + '.log'); print('RUN', name, flush=True) + with log.open('w') as f: q = subprocess.run([sys.executable, '-B', str(file), *map(str, args)], cwd=cwd, env=env, stdout=f, stderr=subprocess.STDOUT) + if q.returncode: raise RuntimeError((name, q.returncode, log.read_text()[-3000:])) + steps.append(dict(name=name, seconds=round(time.monotonic() - t, 1), log_sha256=sha(log))); print('PASS', name, flush=True) +try: + run('parent-434-full', PARENT / 'verify.py', out / 'parent') + changed = out / 'parent/changed' + run('bit-hosting', ROOT / 'bit_hosted.py', 'bit426-source-centres/global', 'bit426-source-centres', out / 'bit', cwd=changed) + run('complex-hosting', ROOT / 'complex_hosted.py', 'split-centres', out / 'complex', cwd=changed) + run('independent-audit', ROOT / 'audit.py', changed, out / 'bit', out / 'complex', out / 'AUDIT.json') + run('exact-assembly', ROOT / 'assemble.py', changed, out / 'bit', out / 'complex', out / 'AUDIT.json', out / 'RESULT.json') + actual = read(out / 'RESULT.json'); expected = read(ROOT / 'EXPECTED.json') + for k, v in expected.items(): assert actual[k] == v, (k, actual[k], v) + for side, d in (('bit', 'bit'), ('complex', 'complex')): + h = hashlib.sha256(gzip.decompress((out / d / 'GLOBAL-TEMPLATE.json.gz').read_bytes())).hexdigest() + assert h == expected[side + '_template_sha256'], (side, h) + integrity() + receipt = dict(status='PASS_FULL_IDLE_AXIS_HOSTING_COMPOSITION', kappa=actual['kappa'], kappa_decimal=actual['kappa_decimal'], + gain_over_pr434_percent=actual['gain_over_pr434_percent'], manifest_sha256=sha(ROOT / 'MANIFEST.json'), checks=steps, + python=sys.version.split()[0]) + (out / 'RECEIPT.json').write_text(json.dumps(receipt, indent=2) + '\n'); print(json.dumps(receipt, indent=2)) +except BaseException as e: + (out / 'FAILURE.json').write_text(json.dumps(dict(error=repr(e), completed=steps), indent=2) + '\n'); raise diff --git a/research/split-centres-global/.gitattributes b/research/split-centres-global/.gitattributes new file mode 100644 index 0000000000..a251e913f2 --- /dev/null +++ b/research/split-centres-global/.gitattributes @@ -0,0 +1,6 @@ +# Hashes bind exact imported and generated bytes. +* -text +vendor/** -whitespace +inputs/** -whitespace +notices/** -whitespace +proofs/** -whitespace diff --git a/research/split-centres-global/CERTIFICATE.json b/research/split-centres-global/CERTIFICATE.json new file mode 100644 index 0000000000..7e807079c1 --- /dev/null +++ b/research/split-centres-global/CERTIFICATE.json @@ -0,0 +1,119 @@ +{ + "status": "PASS_CONDITIONAL_SPLIT_CENTRE_ASSEMBLY", + "kappa": "560432476129139/500000000000000000", + "kappa_decimal": "0.001120864952258278", + "bit_lower": "561061350132569610283/500000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "gain_over_pr425_percent": 6.9522005058117555, + "bit_invoice": { + "prefix_bits": 223, + "charged_prefix_bits": 256, + "coefficient_bits": 223, + "two_level_coefficient_bits": 483, + "charged_two_level_coefficient_bits": 512, + "row_coefficient": 18355, + "live": 14502, + "physical": 14511 + }, + "strict_outer_constraints": { + "bit_positive": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_above_bit": "791857266447229204459483569705102945201339627252022591017013352985113602942786795000164759817249951996149235225861576966507630300630689893816878766552471016817/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "complex_below_one_over32": "30066013450793671/1000000000000000000", + "beta_positive": "1/1000000000000000000", + "beta_below_one": "999999999999999999/1000000000000000000", + "leaf_saving_above_bit": "791857266447229189304455739864091745201339627252022591017013352985113602942786795000164759817249951996149235225861576966507630300630689893816878766552471016817/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_positive": "7181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_internal": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_leaf": "395928633223614609015398433325827868141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_positive": "7181585281696892583407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "c_below_one": "6392818414718303107416592912348246333468141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "q_below_reservations": "1/4000000000000000000", + "lambda_above_tau": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_sigma": "791857266447229218822654133098884940741856057546919645815673725733091011925773442015051156874463156995984475408611624970358395074769112927309248465921781123000121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_above_internal": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "lambda_prime_above_lambda": "14363170563393781995540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_leaf": "395928633223614609015398433325827868141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_reservations": "1/4000000000000000000", + "lambda_prime_below_one": "7181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "epsilon_positive": "6399999999999999993600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "epsilon_below_one": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "guard_width": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "K_geometry": "4807181585281696892583407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817000000000000000000", + "K_dominates_log": "231664041345061050845983947421186256401668584010497584446258683699366907737186677571792433338340060113453513521617978855187267028104098984087218414251878140832554446748323117142213588175726741393/206683276944570867451077647988766247307479316572776744891925575256476111799662761934047904233001101994161357746522719973016545013550824072000632231965075950141464786411824273258607000000000000000000", + "record_suffix": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "phase_local": "57452682253575172660075115932332441271463422396879066665683849849996634666672126693120783994727674596531689914600391489101073218400050692643898107263289403063667839215065313749127621233447528983183/51257452682253575127867256701214029332254870510048632733197542663606075726316364959643880249784273294552016721137634553308103163360604369856156793527338835635083267030132419768134536000000000000000000", + "phase_boundary": "11490536450715029406269754961108975467567014357972880107649718965136053613580158978016584167309038954918313004492748842618542529916554807718463285392220894997054215109129499241498821233447528983183/10251490536450715025573451340242805866450974102009726546639508532721215145263272991928776049956854658910403344227526910661620632672120873971231358705467767127016653406026483953626907200000000000000000", + "gamma_sublinear": "1/2000000000000000000", + "cell_above_band": "12799999999999999980792818414718303109016592912348246333468141186243920908350307167049240534210454380044514968776965838180997909857795680836487104579924453767980400809082645545614591621233447528983183/25628726341126787563933628350607014666127435255024316366598771331803037863158182479821940124892136647276008360568817276654051581680302184928078396763669417817541633515066209884067268000000000000000000", + "prime_interval_packing": "7181585281696897383407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817", + "alpha_positive": "14363170563393788359632590021810442080310539860404516767526852145439839929398406960210596656522703682519149061374476508023700697946773300526302961759162676751217566615750487648225621233447528983183/12814363170563393781966814175303507333063717627512158183299385665901518931579091239910970062446068323638004180284408638327025790840151092464039198381834708908770816757533104942033634000000000000000000", + "alpha_below_one": "12799999999999999993607181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817/12814363170563393781966814175303507333063717627512158183299385665901518931579091239910970062446068323638004180284408638327025790840151092464039198381834708908770816757533104942033634000000000000000000", + "alpha_below_one_fourth": "3189227622077454657132070953804066391185618867017635029057319564329939892965374403017531918954994377226981896009727683073732747012090999815483496633699514550441486622767525747860182878766552471016817/12814363170563393781966814175303507333063717627512158183299385665901518931579091239910970062446068323638004180284408638327025790840151092464039198381834708908770816757533104942033634000000000000000000", + "delta_positive": "1/8000000000000000000", + "delta_below_one_eighth": "999999999999999999/8000000000000000000", + "short_record_fallback": "81827972558059963142482295831039750365059753405165839859500887157900070163784215146039541956047009515286378723945407637791323146319740145866082020356197908534083134290654194352838948148633280800174595114507063924980758679362172726895650066012032777455278212210736064133662717611940569491044304210260992667579958374711353997952140066809896811489/82011924291605720204587610721942446931607792816077812373116068261769721162106183935430208399654837271283226753820215285292965061376966991769850869643742137016133227248211871629015257600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "small_field_exposure": "1/1000000000000000000", + "artificial_boundary": "358859621458028601093359598365557325330989185343344322865175917750116843085479998176003320395642823216282588862770178911921831577311447916339793034478937323776724933813811421508232513136299657413050451/51257452682253575127867256701214029332254870510048632733197542663606075726316364959643880249784273294552016721137634553308103163360604369856156793527338835635083267030132419768134536000000000000000000", + "literal_scalar_guard": "1", + "row_product_gap": "23971789/25", + "balanced_prefix_above_kappa": "5122866517862023505724960619093421545844111701898553134698525509504383311993872387184513125657251444712150871805627114225726283245038727038504547469670408073428467093191496467269437/3203590792640848445491703543825876833265929406878039545824846416475379732894772809977742515611517080909501045071102159581756447710037773116009799595458677227192704189383276235508408500000000000000000", + "coordinate_movement_above_kappa": "16099174487823595540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "compact_phase_layer_above_kappa": "3838551450442350120466514150535089425156364590041027177747358186058007158198199154413541220091468727605299653469049909287939671070001907844989495748423461692471525807616440463522057/6407181585281696890983407087651753666531858813756079091649692832950759465789545619955485031223034161819002090142204319163512895420075546232019599190917354454385408378766552471016817000000000000000000", + "bulk_exposure_above_kappa": "16099174487823595540516430294897054798660372747977408982986647014886397057213204999835240182750048003850764774138423033492369699369310106183121233447528983183/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Gaussian_arithmetic_above_kappa": "49929956359383891636682334467235976400846493161596454696927943987316335662954230095174784854400852306299403498179012231794056054820241901455974763560139756902928431597231181121226907/51257452682253575127867256701214029332254870510048632733197542663606075726316364959643880249784273294552016721137634553308103163360604369856156793527338835635083267030132419768134536000000000000000000", + "scalar_work_above_kappa": "3022347308020427168024638512713719642678957136664830842541068612764774941044496502999868999171719558143016474349913180337924305460021763455362126412952366988818802604491895640211767/2050298107290143005114690268048561173290194820401945309327901706544243029052654598385755209991370931782080668845505382132324126534424174794246271741093553425403330681205296790725381440000000000000000", + "dimension_above_kappa": "3196409207359151553231162974036146672459031212215382000019265285423173401803752699526640796382355306275012080586149285130394424095589341109716483649580049811311843280287131837920058593191496467269437/3203590792640848445491703543825876833265929406878039545824846416475379732894772809977742515611517080909501045071102159581756447710037773116009799595458677227192704189383276235508408500000000000000000" + }, + "outer_controls": [ + "next_grid", + "zero_eta", + "zero_beta", + "unit_beta" + ], + "bootstrap": [ + { + "gap": "48640105104416009930955104551272628756769/40000000000000000000000000000000000000000000000", + "cutoff_log2": "24346328299693" + }, + { + "gap": "10916033216189494908506938862091413300675156484737667525550897/8000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "19335382939135799529" + }, + { + "gap": "2449825733746901655394438404809502019511708753179325050819248403056515410563319361/1600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "15355787073969246541017124" + }, + { + "gap": "549801013506219857550281901936704203615404924098069138182437287931091972275689180385852832590942771793/320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "12195269025875323655994833423982" + }, + { + "gap": "123388839576821941106964776874551364767558290306753584545234931806617408234472738882773008179061080923160999418343337504609/64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "9685246734476302780854842486398253310" + }, + { + "gap": "27691483569705102945201339627252022591017013352985113602942786795000164759817249951996149235225861576966507630300630689893816878766552471016817/12800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "cutoff_log2": "7691835588756193183914168151850588989363719" + } + ], + "bit_template_sha256": "c40f89a2ae3c2c5635ddf8f18d74f24567ddf67fc8c8e93a1fc7a1a8098e857e", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f", + "scope": "Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim.", + "verification_steps": [ + "hamming_packets", + "complex_construct", + "complex_audit", + "complex_emit", + "complex_phases", + "bit_construct", + "bit_export", + "bit_global", + "bit_audit", + "bit_price", + "complex_integrate", + "complex_replay", + "combined" + ], + "phase_mode": "source-bound unchanged evidence" +} diff --git a/research/split-centres-global/EXPECTED.json b/research/split-centres-global/EXPECTED.json new file mode 100644 index 0000000000..de7c122419 --- /dev/null +++ b/research/split-centres-global/EXPECTED.json @@ -0,0 +1,9 @@ +{ + "kappa": "560432476129139/500000000000000000", + "kappa_decimal": "0.001120864952258278", + "bit_lower": "561061350132569610283/500000000000000000000000", + "complex_lower": "1183986549206329/1000000000000000000", + "binding_component": "bit", + "bit_template_sha256": "c40f89a2ae3c2c5635ddf8f18d74f24567ddf67fc8c8e93a1fc7a1a8098e857e", + "complex_template_sha256": "942d030fa43316c560c88d7d7d904583446e1a96945b3ebd37a91c88a192ab4f" +} diff --git a/research/split-centres-global/LICENSE b/research/split-centres-global/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/split-centres-global/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/split-centres-global/MANIFEST.json b/research/split-centres-global/MANIFEST.json new file mode 100644 index 0000000000..1695125698 --- /dev/null +++ b/research/split-centres-global/MANIFEST.json @@ -0,0 +1,51 @@ +{ + "format": "split-centres-global-manifest/1", + "files": { + ".gitattributes": "2f9541c7c27f084baad73b4cd50ddaeb264cc3aa8dbf13ec21df5ab3f673ca7e", + "CERTIFICATE.json": "f71580f22193726fb582eae604807ff70a7302265e001d9484a718e63bbe14c4", + "EXPECTED.json": "9b8e56eee3d5bdabd2e3e6e4ba0d9eba537525fba25a54126f9f0e41d2491a06", + "LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "NOTICE.md": "66101a9e74d0ba9c2da4c8802bcb1968534adfa7130b954628eb8bf515fc0389", + "PROOF.md": "6983e75f29af6eeaab20a30b08307ec6fab75ccb8b10291df8f9eb04d497f894", + "README.md": "b432292594adf2fcba2a8ddd87eda6167c76ff055e85aa5e3e2af7dd7e0f976e", + "SOURCES.json": "11aa666d678fed084b01d1e8e47239e1674eaedbc6fe0cee7edb2753477af9be", + "VALIDATION.json": "656d9bd7bd66058fdeb60cc90bd887e7ce75c0e0f9a100514e2bd84b95de89b6", + "code/bit_audit.py": "7fdbc077b7501a53662769ff2bf2ab44cc2e32dafc34478d7ef2c10e3144503a", + "code/bit_construct.py": "a461e6c983531beb5c8ac82ff593f39ce4e056387d1d6061f6e6b294dde4395f", + "code/bit_global.py": "3b2cb3ba21e5cf9b4deddb9e606322f33e9d8082020c0ee9092c21f4ebd9ad48", + "code/bit_price.py": "36bf15803567a95b139a908461541bf19efe1f5b85fb31c270021833ab1393ee", + "code/combined.py": "9c5bc70f2331b7342ceb252adcddb993581c45f80c37bcc58642dbad3b9775c2", + "code/complex_audit.py": "adeba5ea113652b60105db2e8719b18ffa292d3cc23730cca614b40272348330", + "code/complex_construct.py": "0f7f45b2333ec7daf4291e2bf675b49bc330b97fb5965dd27220ba353c291d6f", + "code/complex_emit.py": "f56d5f01f7c121741f175814138dca7190d769920f0a27e2d5b99c21aebed0f1", + "code/complex_integrate.py": "3792f41e409383e6989bda22801a4836a646a530f99e99bbd7244a8f3a1a8b4f", + "code/complex_phases.py": "13a959c52092776ae217df554b51c0298fa9eb3a350279acff6dece651c3f9cc", + "code/complex_phases_full.py": "0f2795aaffafe0c64d77f3748ef2109a3c42c58da867e4cf269a0a8cb6109466", + "code/complex_replay.py": "be2dccce2d1ad2c4f5c01a851c9c3896cc88236b5aeae706aad2ab16d6bfdad9", + "inputs/bit-geometry.json.gz": "5c980202227859e8bb9b863f94503930c2a59d460c0421356688e2b0d828b4a1", + "inputs/bit-r767.json.gz": "bd3b84244528767b85d8d7fe423b155630b5c659e21e51563674b1dcb6305ad7", + "inputs/complex-data-phases.json.gz": "c972b5b60649c2a52354f5160f69adc0f4a270fa09d32012beff9888774ab84f", + "inputs/complex-phase-receipt.json": "01763fee5017745de982f2ff5ee68004e815d6684097cc88011dfbfb1e789581", + "inputs/complex-phase-recipes.json.gz": "b5472bb1d3f9ff41b0819780a42886a7686b4caf3c0617bb1dc86158b3fb8671", + "inputs/complex-ports.json.gz": "77b0c0fa19ef3da1c7316010e13493aa5eea1a50c3506eddc08f7480e659878b", + "inputs/complex-template.json.gz": "1b84904a31a733aab9bfdda3f528c06719f590d2133a43687a8bded955dc991e", + "inputs/e8-r865.json.gz": "1fb726ea3818fe0837cceb0dd22a71a0814f064e5e781628104610d6468e0e55", + "notices/NOTICE-PR352.md": "967e6d7e76e216e4898cf543c75b527e8d397ec1ddba3800cb20701f24c89524", + "notices/NOTICE.md": "025773f32fb43667395e64c627a1752877bdc93afbfe01b106703eee438d21d3", + "notices/PR386.txt": "ae2241615a23063b18a04f1b7a88a52e62b3d7d42e333fbd21e3668567ab83d1", + "notices/PR426-SOURCE-PINS.json": "18ace817f2f9af22511bb303e99656ed114e534b87f3dd95a65ca4ca670baf2f", + "notices/PR426.md": "6a5593d0f284a2f0865037f5c5fa9e5f76f9e12cf50ec5284486d3b8137c89da", + "notices/SUSSMAN-NOTICE": "9419dd03a2f52cf8bdfc4d18216ce29f263ab583b27f01ced8e420985bcb7c81", + "proofs/INHERITED-COMPLEX-GEOMETRY.txt": "c1ff55536594222a8d2a30bc0e0956959774e1be2d5420b7838ad553ee556df2", + "proofs/PR386-BIT-GEOMETRY.txt": "c5f077b849e9add9957ab4ee36095dd47bc678dee7e09baa146dac4c0a0d66b2", + "proofs/PR425-COMPLEX.txt": "2cda27b9b9a1eb24127c38c2c7a6e085155a2472183e220189a3ea2c2b7720dc", + "proofs/PR426.md": "5787738ceb6faf14d3d96e8452592860a6c6a469733a9bcf196e8d1562ba1ffb", + "vendor/clifford_exact.py": "2982ead07721e83358dc67c6f49c2b4c16a236a6bebdfd72f58221be1f5d0962", + "vendor/engines/base_two_moment.py": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098", + "vendor/engines/moment.py": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482", + "vendor/engines/outer.py": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c", + "vendor/export_records.py": "8a5999601f917dbb492bb9ae9a344611f18cc7cedc53dc3c76496a369e530eb3", + "vendor/hamming_packets.py": "daa9301e2767a711cfe66c6bebaad68e1a3bdb97ec9e848c927527ab43b37ae5", + "verify.py": "12fcdb20a87f75812b09c4916fbfc86305982cb410247186a123b5c58d517b4c" + } +} diff --git a/research/split-centres-global/NOTICE.md b/research/split-centres-global/NOTICE.md new file mode 100644 index 0000000000..b7daf8de49 --- /dev/null +++ b/research/split-centres-global/NOTICE.md @@ -0,0 +1,41 @@ +# Attribution + +Copyright 2026 icekylinx. New split-centre cancellation, reversible source-centre +composition, integration and verification changes were prepared by icekylinx +with substantial OpenAI Codex assistance. Apache-2.0 applies to these changes. +Earlier private Pro exploration used GPT-6 Astra; the new construction and +composition in this package were developed with Codex. + +## Direct sources + +- Zhihao Chen, with OpenAI Codex assistance: PR425's mutable-basis Hamming packet + producer, common-frame scalar interface, exact phase lowering and verification; + PR386's compressed nine-stage bit geometry, owner template, audit and finite + accounting. These supply the immediate complex and geometric baselines. +- ai-nanachi, with OpenAI Codex assistance: PR426's R767 bit word, including 55 + clean-reset helper reuses and 54 frame changes. The complete selected word is + imported unchanged before the nine source-centre replacements. +- Dylan Crow (utcorvusvolat-dotcom), with Anthropic Claude assistance: PR370's + Hamming E8 bit producer, root table, record exporter and local format. +- Jacob Sussman: the E8 family, complex unit and underlying interchange framework. +- applecrusher, Dugongue, eumemic, Rohan Arun, Chafik Boukhalfa, DaysSky, + DreamingOfClouds, Henry Grant, Evan McKinney, LJH-217 and other contributors: + the source, frame, compiler, rational-pricing and analytic lineage detailed + in the preserved original notices. + +The current value is computed from the two actual resulting programs. +Independently published improvements are not added numerically. `SOURCES.json` +records original commits and file hashes; `notices/` preserves source notices. +Files under `proofs/` describe their original packages and retain their original +scope and attribution; the current statement is in `PROOF.md`. + +## Earlier contributions by icekylinx + +The earlier #10, #18, #24, #32 and #36 contributions developed projector batching, +partial-swap frames, endpoint gauges and conditional analytic/tape integration. +The subsequent #104, #115, #130 and #144 contributions covered stopped-product +integration, partial gauges, three-stage covers and paired-cube/source chronology. +These provide historical context, not additional savings in this ledger. The +source-centre idea from the preceding local round is used here on PR426's bit +word. Unselected research experiments and superseded submission candidates are +not part of this package. diff --git a/research/split-centres-global/PROOF.md b/research/split-centres-global/PROOF.md new file mode 100644 index 0000000000..8366a89e36 --- /dev/null +++ b/research/split-centres-global/PROOF.md @@ -0,0 +1,184 @@ +# Split centres and a joint conditional exponent + +The finite construction gives + +$$ +T(n)=O\!\left(n(\log n)^{1-\kappa}\right), +\qquad \kappa=0.001120864952258278, +$$ + +conditional on the retained all-size compiler, compressed-window, correlated +bank-dirt, restored-work, fixed-tape/common-grid, precision and analytic +interfaces. The changes below concern both finite suppliers. Original source +proofs and notices are retained; they do not replace the changed checks. + +## 1. Cancel coordinate terms before lifting the complex decoder + +Partition the 120 Hamming E8 root lines into the 112 code lines C and the eight +coordinate lines F, represented by 2e_i. Write r_s for a root representative and +G_ts = r_t · r_s / 2. The parent decoder is the rank-eight centre factorization +G/2 together with its negative off-diagonal entries. + +For each code target t, the coordinate-source centre contribution is +r_ti x_(2e_i)/2. Its side contribution is its negative. Cancel this pair before +constructing the lifted program. For code targets retain only + +$$ +Z_i=\sum_{s\in C}r_{si}x_s, +\qquad +\sum_i\frac{r_{ti}}4Z_i +-\sum_{\substack{s\in C\\s\ne t}}\frac{G_{ts}}2x_s=x_t. +$$ + +For coordinate targets, implement the identity x_(2e_i) directly. Thus the +entire 120-by-120 clean decoder is still the identity, including both cross +blocks between C and F. + +In the parent's binary address realization, + +$$ +p_s\cdot p_t=1+G_{st}\pmod2. +$$ + +Every code source contributing to Z_i is orthogonal to p_(2e_i), because its +ith root coordinate is ±1. The already constructed global sum Z_i lies in that +rank-eight hyperplane. Copy it there, lower the private copy to frame zero with +one rank-eight child, and scatter into the code targets. The eight coordinate +identities copy their source lines with one rank-one child each. Each private +copy has a sequential lifetime, and is erased before the next episode. + +The total copied rank is unchanged: + +$$ +8\cdot8+8\cdot1=72. +$$ + +The 112 coordinate-source helpers and eight dedicated full-centre helpers are +removed. Own-block corrections use their original source-copy rows directly; +all remaining signed packets and selected target butterflies are retained. +The actual helper count is 560. No rank-four recovered row is substituted for +a rank-three input. + +## 2. Arbitrary dirt and heterogeneous copy frames + +The explicit main word has block form z' = Uz and y' = Vy + x + Ks, where +z=(x,s), and U,V are invertible. No target feeds z. At the common initial frame, +apply V^-1 to the target basis and the literal correction -V^-1 Ks. Recompute K +from the new word. After all main gates and final climbs, apply the literal +inverse of the source/helper subword at the common full frame. This restores +all sources and arbitrary helpers while adding x to y. + +The parent common-frame proof applies to each copy separately. A private copy +created at label L(F) is lowered by the exact operator L(0)L(F)^-1, whether F +has rank one or eight. Scalar operations occur only at equal labels. Adding +the common exterior window to both labels cancels it exactly. The proof +therefore does not require a full-frame centre, or infer an operator from rank +alone. The inverse-transpose negates/transposes each scalar shear in the same +order and reverses each private gather/child/scatter operation as emitted. + +Both scalar orientations and the serialized private-work programs replay all +800 input columns. Both restore arbitrary source/helper inputs and erase private +work. The changed exact Gaussian recipes include the heterogeneous centre +transitions and their global phases. Of 2,918 selected directed pairs, 248 were +newly computed; 2,670 were unchanged source-bound exact pairs already checked in +the local phase run. The release optionally replays all selected pairs. + +The local paid profile is + +$$ +\{1:1912,\ 2:784,\ 3:168,\ 4:224,\ 5:392,\ 8:24\}. +$$ + +The compressed complex geometry uses m=73, eight replicas and nine stages. +There are 560 banks per stage, each holding eight whole rank-nine residuals and +one paid rank-one pad. Live width is 12,720; physical stock is 13,298, including +16 centre slots, the conservative 560-row tableau reserve and two coefficient +streams. The global rank deficit is 2,496. Explicit owner tables, padding, +terminal translations and the cover correction are independently decoded. +The largest child is 48; 73² > 2·48² gives two-level halving. + +The fresh invoice fits the retained 2^30000 router, 2^100000 literal and 2^210000 +precision reserves. Two exact rational engines certify + +$$ +b=0.001183986549206329. +$$ + +## 3. Source-centre bit composition + +Start with the exact R767 word from PR426. Its nine retained rows are written +only by original sources at the full frame and are not read by ordinary A/B +gates. Their nine independent binary forms have an invertible minor in source +columns 0,1,2,4,8,9,16,32,64. + +Replace those rows of the 120-dimensional identity by the nine retained forms. +Exact elimination produces an invertible source basis T, emitted as 559 XOR +additions. Delete the nine retained helper rows and their old-dirt columns. +After A apply T, perform the same nine sequential copies using the designated +source rows, and immediately apply T^-1 before B. The copies have unchanged +rank eight. All scalar operations of T and its inverse use the full frame. + +All 998 columns, arbitrary dirt, frame incidences and restoration pass. Omitting +T^-1 or the remaining old-dirt correction fails. The actual exported record +stream is reflected in reverse order with complementary frames. A reflected +ERASE becomes a fresh COPY at that chronological point; the original source +row remains unchanged within each copy episode. Both reflected programs and +all nine composed invocations are replayed, rather than assuming that mutable +source rows meet an old immutability restriction. + +Use the unchanged compressed bit windows in dimension 64: a local eight-space +and eight exterior seven-spaces. The root data, rational frame family, form, +port isometries and bank slots are source-bound to PR386. Every changed nested +pair is checked by exact rational spans; positive definiteness gives the +projector identity and its reflected version. There are 758 banks per stage, +each filled by eight rank-eight residuals, with no padding. Live width is 14,502 +and physical stock is 14,511. All 54,576 owner assignments are checked. The +unbanked global replay restores all 7,782 independent columns. + +The bit local profile is + +$$ +\{1:2367,\ 2:875,\ 3:475,\ 4:321,\ 5:164,\ 7:14,\ 8:9\}. +$$ + +Its global deficit is again 2,496. The maximum child is 42 and 64² > 2·42². +The actual cancellation-free prefix bound needs 223 bits; the new charge is +256 bits, replacing the parent's 192-bit allowance. The finite two-level +coefficient needs 483 bits and fits the retained 2^512 allowance. The row +coefficient is 18,355 < 20,161. These costs, including the basis operations, +are recomputed from the emitted word. Two exact rational moment engines give + +$$ +c=0.001122122700265139220566. +$$ + +## 4. Joint strict assembly + +Both moments include the inherited 10^-16 bad-branch allowance. The bit supplier +binds because c < b. Let eta=beta=10^-18 and + +$$ +s=\min\{c,(1-\beta)b\}-10^{-24}. +$$ + +Starting at a_0=384599/10^10, use six fixed ordinary bootstrap levels + +$$ +a_{j+1}=(1-s)s+sa_j. +$$ + +All bootstrap cutoff inequalities are checked with the actual charged finite +coefficient. With q=a_6(1-2eta), choose the greatest 10^-18 grid point strictly +below (1-eta)q/(1+q). It is + +$$ +\kappa=\frac{560432476129139}{500000000000000000} + =0.001120864952258278. +$$ + +All 47 retained strict outer inequalities pass. The next grid point, zero eta, +zero beta and unit beta are rejected. The candidate is computed from both +actual new templates; no independently reported savings are added together. + +The source-bound finite claims above do not discharge the inherited all-size +interfaces or establish unconditional integer-multiplication complexity. diff --git a/research/split-centres-global/README.md b/research/split-centres-global/README.md new file mode 100644 index 0000000000..1e31463921 --- /dev/null +++ b/research/split-centres-global/README.md @@ -0,0 +1,56 @@ +# Conditional κ = 0.001120864952258278 + +This package combines a split-centre Hamming complex construction with a +source-centre bit construction in compressed nine-stage windows. The resulting +conditional exponent saving is + +$$ +\kappa=\frac{560432476129139}{500000000000000000} + =0.001120864952258278. +$$ + +This is approximately **6.9522% above PR425**. Both components change: + +| Component | Helpers | Ambient width | Certified saving | +|---|---:|---:|---:| +| Complex | 560 | 73 | 0.001183986549206329 | +| Bit | 758 | 64 | 0.001122122700265139220566 | + +The bit component limits the final assembly. The complex construction removes +coordinate contributions that cancel in the decoder, replacing eight full +centres with eight rank-eight and eight rank-one copies. The bit construction +starts from PR426's R767 word, computes its nine retained forms reversibly in +source rows, and uses PR386's compressed windows. + +## Verification + +Python 3.11+ and its standard library suffice. Use a new output directory: + +```sh +python3 -B research/split-centres-global/verify.py /tmp/split-centres-check +``` + +The default replays both changed words, reflected/inverse-transpose programs, +bank ownership, costs, two rational moment engines and 47 strict outer +inequalities. Exact complex phase evidence is reused only when the regenerated +canonical word and complete recipe hashes match. To regenerate every selected +Gaussian phase pair as well: + +```sh +python3 -B research/split-centres-global/verify.py /tmp/split-centres-full-phases --replay-phases +``` + +The unchanged historical repository suite and PDF build are not required by +this package. `EXPECTED.json` binds the result to both emitted global templates; +`MANIFEST.json` binds the package files; `SOURCES.json` pins imported sources. + +## Scope + +[PROOF.md](PROOF.md) supplies the changed finite construction. The all-size +compressed-window and correlated dirty-bank semantics, recursive compiler, +restored-work/tape/common-grid precision, and analytic transfer interfaces remain +conditional. This does not claim unchanged legacy gx/gxcore acceptance, a new +Lean proof, or an unconditional multiplication theorem. + +Contributor history and AI assistance are recorded in [NOTICE.md](NOTICE.md). +Original notices and the inherited proofs are retained separately. diff --git a/research/split-centres-global/SOURCES.json b/research/split-centres-global/SOURCES.json new file mode 100644 index 0000000000..215f58a649 --- /dev/null +++ b/research/split-centres-global/SOURCES.json @@ -0,0 +1,134 @@ +{ + "upstream_base": "12a4934d15006e8c10f9b2264f13f8f341be802b", + "pr425": "e11ccea1d092beb1b01b4ee4ce49da478234254c", + "pr426": "88d552526893cd15325948bb1487e9a4d4bf32f6", + "imported_files": [ + { + "path": "vendor/hamming_packets.py", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/hamming_packets.py", + "sha256": "daa9301e2767a711cfe66c6bebaad68e1a3bdb97ec9e848c927527ab43b37ae5" + }, + { + "path": "vendor/clifford_exact.py", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/odd-stages/clifford_exact.py", + "sha256": "2982ead07721e83358dc67c6f49c2b4c16a236a6bebdfd72f58221be1f5d0962" + }, + { + "path": "inputs/complex-ports.json.gz", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/higher-stage-e8/verified/gcert1-e8-retimed.json.gz", + "sha256": "77b0c0fa19ef3da1c7316010e13493aa5eea1a50c3506eddc08f7480e659878b" + }, + { + "path": "inputs/complex-template.json.gz", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-nine-native/GLOBAL-TEMPLATE.json.gz", + "sha256": "1b84904a31a733aab9bfdda3f528c06719f590d2133a43687a8bded955dc991e" + }, + { + "path": "inputs/complex-data-phases.json.gz", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-nine-native/DATA-PHASES.json", + "sha256": "c972b5b60649c2a52354f5160f69adc0f4a270fa09d32012beff9888774ab84f", + "source_sha256": "f621f6d4296cb215f334830356c5f79fe10d6d04d15b3ccda76ba0885ab67d0a", + "encoding": "gzip; decoded bytes identical to source" + }, + { + "path": "inputs/e8-r865.json.gz", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr370-source/research/e8-bit/data/bit/bitE8-r865.json.gz", + "sha256": "1fb726ea3818fe0837cceb0dd22a71a0814f064e5e781628104610d6468e0e55" + }, + { + "path": "proofs/PR425-COMPLEX.txt", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/hamming/PROOF.txt", + "sha256": "2cda27b9b9a1eb24127c38c2c7a6e085155a2472183e220189a3ea2c2b7720dc" + }, + { + "path": "proofs/INHERITED-COMPLEX-GEOMETRY.txt", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-nine-native/PROOF.txt", + "sha256": "c1ff55536594222a8d2a30bc0e0956959774e1be2d5420b7838ad553ee556df2" + }, + { + "path": "vendor/engines/moment.py", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr361/code/engines/moment.py", + "sha256": "81cbc864e106418fc7854322746f72180cb8110ff39f74450a3b8d55a82c1482" + }, + { + "path": "vendor/engines/base_two_moment.py", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr361/code/engines/base_two_moment.py", + "sha256": "aee70c242a2f1d225528fabe2002e1564d1dc884797c07d28a831c7878ee9098" + }, + { + "path": "vendor/engines/outer.py", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr361/code/engines/outer.py", + "sha256": "c1ebb52163a7219504c728a5c2b098bf1e50bf20148a2879c5a74c3cadc7c03c" + }, + { + "path": "vendor/export_records.py", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit/code/bit/export_records.py", + "sha256": "8a5999601f917dbb492bb9ae9a344611f18cc7cedc53dc3c76496a369e530eb3" + }, + { + "path": "inputs/bit-geometry.json.gz", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit-complex-nine-validation/GEOMETRY.json.gz", + "sha256": "5c980202227859e8bb9b863f94503930c2a59d460c0421356688e2b0d828b4a1" + }, + { + "path": "proofs/PR386-BIT-GEOMETRY.txt", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit-complex-nine/PROOF.txt", + "sha256": "c5f077b849e9add9957ab4ee36095dd47bc678dee7e09baa146dac4c0a0d66b2" + }, + { + "path": "notices/PR386.txt", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit-complex-nine/NOTICE.txt", + "sha256": "ae2241615a23063b18a04f1b7a88a52e62b3d7d42e333fbd21e3668567ab83d1" + }, + { + "path": "inputs/bit-r767.json.gz", + "source": "CrocSwap/integer-mult-bounds@88d552526893cd15325948bb1487e9a4d4bf32f6:research/e8-clean-reuse-extension/data/bit-candidate.json.gz", + "sha256": "bd3b84244528767b85d8d7fe423b155630b5c659e21e51563674b1dcb6305ad7" + }, + { + "path": "notices/PR426.md", + "source": "CrocSwap/integer-mult-bounds@88d552526893cd15325948bb1487e9a4d4bf32f6:research/e8-clean-reuse-extension/NOTICE.md", + "sha256": "6a5593d0f284a2f0865037f5c5fa9e5f76f9e12cf50ec5284486d3b8137c89da" + }, + { + "path": "proofs/PR426.md", + "source": "CrocSwap/integer-mult-bounds@88d552526893cd15325948bb1487e9a4d4bf32f6:research/e8-clean-reuse-extension/PROOF.md", + "sha256": "5787738ceb6faf14d3d96e8452592860a6c6a469733a9bcf196e8d1562ba1ffb" + }, + { + "path": "notices/PR426-SOURCE-PINS.json", + "source": "CrocSwap/integer-mult-bounds@88d552526893cd15325948bb1487e9a4d4bf32f6:research/e8-clean-reuse-extension/SOURCE-PINS.json", + "sha256": "18ace817f2f9af22511bb303e99656ed114e534b87f3dd95a65ca4ca670baf2f" + }, + { + "path": "notices/NOTICE-PR352.md", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr370-source/research/e8-bit/NOTICE-PR352.md", + "sha256": "967e6d7e76e216e4898cf543c75b527e8d397ec1ddba3800cb20701f24c89524" + }, + { + "path": "notices/NOTICE.md", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr370-source/research/e8-bit/NOTICE.md", + "sha256": "025773f32fb43667395e64c627a1752877bdc93afbfe01b106703eee438d21d3" + }, + { + "path": "LICENSE", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/pr370-source/research/e8-bit/LICENSE", + "sha256": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4" + }, + { + "path": "notices/SUSSMAN-NOTICE", + "source": "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit/code/complex/inputs/complex/NOTICE", + "sha256": "9419dd03a2f52cf8bdfc4d18216ce29f263ab583b27f01ced8e420985bcb7c81" + } + ], + "adapted_sources": { + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/hamming_full.py": "613796df039dfc08de708831582533e553316eaf157485531e4df2d897bdb3bb", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/audit_full.py": "fdc1da8fa95716d60076383e691a5be1bf8bec0b229b7582bc056afac28951d0", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/integrate.py": "eb5b427f2095578f28a1fb320b4694047e20abdbe0c8bcdc65b1e9e05ab90d01", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/phase_full.py": "5c2bd267cc3106c9eee8787132c460614fdde8177c0c2653435f8a7b110ebac1", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/hamming-mutable-basis-complex/work/complex-network/replay_ir.py": "f7a3829118581ee59fdeefc1f91166d8e7bb94686ea92e7743a2ef7d50139dcc", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit-complex-nine/global_word.py": "2c438be46213e014170e607a745185e45e33c7b7240b833efc86a2330de0d1f6", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit-complex-nine/audit.py": "75811327b0d6cbd56aae8e28d72abd42d57c7f3f3630781d045efee2d36446e9", + "CrocSwap/integer-mult-bounds@e11ccea1d092beb1b01b4ee4ce49da478234254c:research/e8-bit-complex-nine/certify.py": "550b1408fb3a581dd6b82c90e3f84ad7a9f78746d2be11ffa1cf543d719ae2d4" + } +} diff --git a/research/split-centres-global/VALIDATION.json b/research/split-centres-global/VALIDATION.json new file mode 100644 index 0000000000..70b00c0bc7 --- /dev/null +++ b/research/split-centres-global/VALIDATION.json @@ -0,0 +1,39 @@ +{ + "status": "PASS_CLEAN_DIRECTORY_INCREMENTAL_REPLAY", + "python": "3.14", + "tested_code_vendor_input_digest": "c15599626c4222a95ddb4f0a9da028cfce5c8636c7a737d6869155c2f33301ed", + "steps": [ + "hamming_packets", + "complex_construct", + "complex_audit", + "complex_emit", + "complex_phases", + "bit_construct", + "bit_export", + "bit_global", + "bit_audit", + "bit_price", + "complex_integrate", + "complex_replay", + "combined" + ], + "phase_mode": "source-bound unchanged evidence", + "new_complex_phase_pairs": 248, + "reused_verified_complex_phase_pairs": 2670, + "source_bound_bit_geometry": "PR386; exact unchanged root/frame/port/slot identities", + "historical_full_suite_rerun": false, + "pdf_built": false, + "ci_status": "Not yet run for this commit", + "post_replay_packaging": "Phase JSON gzip round-trip matched the verified decoded bytes; mathematical code and witnesses unchanged.", + "portability_validation": { + "python": "3.11.17", + "status": "PASS_ALL_PACKAGE_STEPS_AND_UNCHANGED_EXPECTED_RESULT", + "cause": "gzip OS header differs from Python 3.14; exact decoded canonical bytes agree", + "phase_binding": "SHA256 of exact decompressed bytes; current archive hash remains bound in downstream receipts", + "negative_control": "A modified canonical witness is rejected", + "python314_incremental": "Changed phase-binding step passed against the previously validated output", + "historical_full_suite_rerun": false + }, + "portability_code_vendor_input_digest": "a2534c803ecb3afb25662517ad542c1b05869046ced4ac78250625b1707014e4", + "portability_digest_format": "SHA256 of compact sorted JSON mapping package-relative code/vendor/inputs paths to file SHA256" +} diff --git a/research/split-centres-global/code/bit_audit.py b/research/split-centres-global/code/bit_audit.py new file mode 100644 index 0000000000..82e1663e58 --- /dev/null +++ b/research/split-centres-global/code/bit_audit.py @@ -0,0 +1,126 @@ +# Adapted with exact rational span checks by icekylinx; Codex assistance. +"""Independent audit of the emitted bit template, including mutation controls. +Prepared by Zhihao Chen with OpenAI Codex assistance; Apache-2.0. +""" +import argparse, copy, gzip, hashlib, json, struct, time +from collections import Counter, defaultdict +from pathlib import Path +from fractions import Fraction as Q + +def sha(p): return hashlib.sha256(p.read_bytes()).hexdigest() + +def main(): + ap=argparse.ArgumentParser(); ap.add_argument('--local-check',type=Path,required=True); ap.add_argument('--out',type=Path,required=True) + a=ap.parse_args(); start=time.monotonic(); out=a.out + blob=gzip.decompress((out/'GLOBAL-TEMPLATE.json.gz').read_bytes()); t=json.loads(blob) + g=json.loads((out/'GLOBAL.json').read_text()); geo=json.loads((out/'GEOMETRY.json').read_text()) + assert hashlib.sha256(blob).hexdigest()==g['template_sha256'] + assert t['geometry_sha256']==sha(out/'GEOMETRY.json') and t['source_record_sha256']==sha(a.local_check/'records/249-records.bin') + fs=json.loads((a.local_check/'records/frames.json').read_text())['frames'] + records=list(struct.iter_unpack('<6i',(a.local_check/'records/249-records.bin').read_bytes())) + word=json.loads((a.local_check/'bit-source-centres.json').read_text()) + assert g['word_sha256']==sha(a.local_check/'bit-source-centres.json') + def rank(rows): + piv={} + for rr in rows: + row=list(map(Q,rr)) + for k,b in sorted(piv.items()): + q=row[k] + if q:row=[x-q*y for x,y in zip(row,b)] + k=next((j for j,x in enumerate(row) if x),None) + if k is not None: + q=row[k];piv[k]=[x/q for x in row] + return len(piv) + dimensions={};proj={} + for key,f in fs.items(): + k=int(key);B=f['B'];roots=[word['lines'][j] for j in word['frames'][k]] + assert rank(B)==f['dim']==rank(B+roots)==rank(roots) + dimensions[k]=f['dim'];proj[k]=B + sets=[set(f) for f in word['frames']];pairs={} + for op,x,y,c,r,z in records: + if op==0: + assert sets[y]<=sets[c] and dimensions[c]-dimensions[y]==r + pairs[y,c]=r + # Positive definite rational form: exact inclusion implies commuting + # orthogonal projectors and rank(P_V-P_U)=dim(V)-dim(U), also in reflection. + assert len(proj)==944 + expected={} + for rev in (False,True): + es=[] + for op,x,y,c,f,z in (reversed(records) if rev else records): + if op==0: es.append([0,x,c if rev else y,y if rev else c,f,int(rev)]) + elif op==1: es.append([1,x,y,-c if rev else c,f,int(rev)]) + elif op==(3 if rev else 2): es.append([2,x,y,c,f,abs(dimensions[c]-dimensions[f]),int(rev)]) + else: es.append([3,x,y,c,f,z,int(rev)]) + expected['reverse' if rev else 'forward']=es + assert t['local_programs']==expected + + def validate(q,check_profile=True): + assert (q['m'],q['live'],q['replicas'],q['stages'])==(64,14502,8,9) + assert q['bank_padding'] is None and q['local_programs']==expected + hist=Counter(); occupation=defaultdict(set); calls=set() + for c in q['calls']: + st,rep,p=c['stage'],c['replica'],c['pair']; rev=c['orientation']=='reverse' + assert 0<=st<9 and 0<=rep<8 and p==max(0,(st-1)//2) + assert rev==(st in (1,3,5,7)) and (st,rep) not in calls; calls.add((st,rep)) + own=c['owners']; assert len(own)==998 + assert len({(f,tuple(r)) for f,r in own})==998 + for i,(family,route) in enumerate(own): + assert 0<=family<14502 + if i<240: + side=i//120; side=1-side if rev else side + assert family==rep*960+(2*p+side)*120+i%120 and route==['data',st,i%120] + else: + j=i-240; bank,slot=divmod(rep*758+j,8) + assert family==7680+st*758+bank and route==['bank',slot] + assert slot not in occupation[family]; occupation[family].add(slot) + for e in q['local_programs'][c['orientation']]: + if e[0]==0 and e[4]: hist[e[4]]+=1 + if e[0]==2: hist[e[5]]+=1 + assert calls=={(s,r) for s in range(9) for r in range(8)} + assert set(occupation)==set(range(7680,14502)) and all(s==set(range(8)) for s in occupation.values()) + levels=[-1]*4; scalar=[1<> p & 1: + row ^= q + assert row, 'Retained forms must be independent' + p = (row & -row).bit_length() - 1 + echelon[p] = row + pivots = sorted(echelon) + matrix = [1 << i for i in range(v)] + for p, row in zip(pivots, rows): + matrix[p] = row + target = matrix[:] + elimination = [] + def add(d, s): + matrix[d] ^= matrix[s] + elimination.append((d, s)) + for p in range(v): + q = next(i for i in range(p, v) if matrix[i] >> p & 1) + if q != p: + add(p, q); add(q, p); add(p, q) + for i in range(v): + if i != p and matrix[i] >> p & 1: + add(i, p) + assert matrix == [1 << i for i in range(v)] + forward = [[full, d, [s]] for d, s in reversed(elimination)] + inverse = list(reversed(forward)) + check = [1 << i for i in range(v)] + for f, d, ss in forward: + check[d] ^= check[ss[0]] + assert check == target + out = copy.deepcopy(old) + physical = [i for i in range(2*v+old['R']) if i not in retired] + index = {r: i for i, r in enumerate(physical)} + def remap(gs): + return [[f, index[d], [index[s] for s in ss if s not in retired]] + for f, d, ss in gs if d not in retired] + out['R'] -= len(retired) + out['ret'] = pivots + out['D'] = remap(old['D']) + out['A'] = remap(old['A']) + forward + out['B'] = inverse + remap(old['B']) + out['C'] = remap(old['C']) + out['start'] = [old['start'][i] for i in physical] + out['final'] = [old['final'][i] for i in physical] + out['source_basis_gates'] = len(forward) + assert replay(out), 'All independent source, target and dirty columns' + assert not replay(out, skip_inverse=True) + assert not replay(out, skip_dirt=True) + # Frame incidence inclusion uses the root-closed sets in this bit format. + frames = [set(f) for f in out['frames']] + cur = out['start'][:] + for phase in ['D', 'A', 'B', 'C']: + for f, d, ss in out[phase]: + for r in [d] + ss: + assert frames[cur[r]] <= frames[f], (phase, r, cur[r], f) + cur[r] = f + if phase == 'A': + assert all(cur[r] == full for r in out['ret']) + assert all(frames[f] <= frames[g] for f, g in zip(cur, out['final'])) + raw = json.dumps(out, sort_keys=True, separators=(',', ':')).encode() + (ROOT / 'bit-source-centres.json').write_bytes(raw) + result = dict(status='PASS_LOCAL_ALL_COLUMNS_AND_NESTED_FRAMES', + original_R=old['R'], new_R=out['R'], + removed_retained_helpers=sorted(retired), retained_source_rows=pivots, + formal_columns=2*v+out['R'], reversible_basis_gates_each_way=len(forward), + source_sha256=sha256(source.read_bytes()).hexdigest(), + output_sha256=sha256(raw).hexdigest(), + controls=['unmodified word passes', 'missing inverse rejected', 'missing dirt rejected'], + kappa_claimed=False, + remaining=['global ordinary-call and reflected integration', 'finite coefficient and tape invoice', 'exact priced component comparison']) + (ROOT / 'bit-source-centres-receipt.json').write_text(json.dumps(result, indent=2)+'\n') + print(json.dumps(result)) + + +if __name__ == '__main__': + main() diff --git a/research/split-centres-global/code/bit_global.py b/research/split-centres-global/code/bit_global.py new file mode 100644 index 0000000000..5ccf622825 --- /dev/null +++ b/research/split-centres-global/code/bit_global.py @@ -0,0 +1,226 @@ +# Adapted for the PR426/source-centre composition by icekylinx with Codex assistance. +"""Source-bound compressed nine-stage bit template and exact scalar audits. + +Prepared by Zhihao Chen with OpenAI Codex assistance, Apache-2.0. +The local E8 bit word is Dylan Crow's pinned PR #370 contribution. +""" +import argparse, gzip, hashlib, json, struct, time +from collections import Counter +from pathlib import Path + +H,V,R,L,K,T,M=8,120,758,9,4,8,64 +LOCAL=2*V+R; DATA=2*K*V*T; LIVE=DATA+L*R +def sha(p): return hashlib.sha256(p.read_bytes()).hexdigest() +def write(p,x): p.write_text(json.dumps(x,indent=2)+'\n') + +def recipe(): + out=[dict(kind='local',stage=0,pair=0,reverse=False)]; stage=1 + for j in range(K): + out.append(dict(kind='local',stage=stage,pair=j,reverse=True)); stage+=1 + if j=0 + cur[x]=newf + if f: hist[f]+=1 + events.append([0,x,oldf,newf,f,int(reverse)]) + elif op==1: + assert cur[x]==cur[y]==f and x!=y and x0 + cutoff=max(ceil(36/gap**2),ceil(2*(4+512)/gap)) + assert cutoff*gap**2>=36 and cutoff*gap>=2*(4+512) + cutoffs.append(dict(gap=str(gap),cutoff_log2=str(cutoff)));chain.append(a) +q=chain[-1]*(1-2*eta);margin=(1-eta)*q/(1+q);ticks=margin/grid;k=grid*((ticks.numerator-1)//ticks.denominator) +bridge={'semantic':{'C0':{'base':2,'exponent':210000},'strict_literal_gap':1},'rows':{'degree_gap':Q(10**6)-Q(51*20161,25)}} +a=Outer.assembly(chain[-1],b,bridge,k,eta=eta,beta=beta) +assert len(a['strict_constraints'])==47 and all(x>0 for x in a['strict_constraints'].values()) +controls=[] +for name,kk,ee,bb in [('next_grid',k+grid,eta,beta),('zero_eta',k,Q(0),beta),('zero_beta',k,eta,Q(0)),('unit_beta',k,eta,Q(1))]: + try:Outer.assembly(chain[-1],b,bridge,kk,eta=ee,beta=bb) + except AssertionError:controls.append(name) + else:raise AssertionError(name) +result=dict(status='PASS_CONDITIONAL_SPLIT_CENTRE_ASSEMBLY',kappa=str(k),kappa_decimal=format(float(k),'.18f'),bit_lower=str(c),complex_lower=str(b),binding_component='bit',gain_over_pr425_percent=float(100*(k/Q(1048005508028206,10**18)-1)),bit_invoice=dict(prefix_bits=prefix.bit_length(),charged_prefix_bits=256,coefficient_bits=coefficient.bit_length(),two_level_coefficient_bits=two.bit_length(),charged_two_level_coefficient_bits=512,row_coefficient=row,live=W,physical=physical),strict_outer_constraints={n:str(x) for n,x in a['strict_constraints'].items()},outer_controls=controls,bootstrap=cutoffs,bit_template_sha256=g['template_sha256'],complex_template_sha256=cx['global_template_sha256'],scope='Finite research composition with explicit changed words, exact local and global replay and incremental phase evidence. All-size correlated dirty-bank, compressed-window, compiler, restored-work, tape/common-grid, precision and analytic interfaces remain inherited assumptions. This certificate makes no unconditional integer-multiplication or Lean-kernel claim.') +(ROOT/'RESULT.json').write_text(json.dumps(result,indent=2)+'\n') +print(result['status'],result['kappa_decimal'],result['gain_over_pr425_percent'],result['bit_invoice']) diff --git a/research/split-centres-global/code/complex_audit.py b/research/split-centres-global/code/complex_audit.py new file mode 100644 index 0000000000..ba6789a3a6 --- /dev/null +++ b/research/split-centres-global/code/complex_audit.py @@ -0,0 +1,168 @@ +# Modified from PR425 by icekylinx with Codex assistance. +"""Read-back audit, independent of the Hamming producer and its row state.""" +import copy,gzip,hashlib,importlib.util,json,math,time +from collections import Counter +from fractions import Fraction as Q +from pathlib import Path + +OUT=Path('split-centres');p=OUT/'FULL-WORD.json.gz' +word=json.load(gzip.open(p));v=120;n=240+word['report']['R'];start=time.monotonic() +def apply(e,rows): + if e[0]=='scale': + _,t,a,b,*_=e;q=Q(a,b);assert q + rows[t]={j:q*x for j,x in rows[t].items()} + else: + _,t,s,a,b,*_=e;q=Q(a,b);assert t!=s + for j,x in list(rows[s].items()): + z=rows[t].get(j,Q(0))+q*x + if z:rows[t][j]=z + else:rows[t].pop(j,None) +def ident():return [{r:Q(1)} for r in range(n)] +def inv(e): + e=copy.deepcopy(e) + if e[0]=='add':e[3]*=-1 + else:e[2],e[3]=e[3],e[2] + return e +def dual(e): + e=inv(e) + if e[0]=='add':e[1],e[2]=e[2],e[1] + return e + +main=word['A']+word['cut']+word['B'] +assert all(not 120<=e[2]<240 for e in word['A']+word['B'] if e[0]=='add' and not 120<=e[1]<240) +matrix=ident() +for e in main:apply(e,matrix) +print('full main columns',n,'replayed',flush=True) +# Compute -A_Y^-1 B_S using only rows of the explicit main operator. +dirty=[{} for r in range(n)] +for r in range(v,2*v):dirty[r]={j:x for j,x in matrix[r].items() if j>=2*v} +for e in word['precondition']:apply(e,dirty) +comp=[] +for r in range(v,2*v): + for j,q in sorted(dirty[r].items()):comp.append(['add',r,j,-q.numerator,q.denominator,[]]) + +cleanup=[inv(e) for e in reversed(word['A']+word['B']) if not v<=e[1]<2*v] +assert [e[:-1] for e in cleanup]==[e[:-1] for e in word['cleanup']] +program=word['precondition']+comp+main+cleanup +actual=ident() +for e in program:apply(e,actual) +expected=ident() +for t in range(v):expected[v+t][t]=Q(1) +assert actual==expected +print('PASS exact arbitrary dirt and restored sources/helpers',flush=True) +back=ident() +for e in program:apply(dual(e),back) +expected_back=ident() +for t in range(v):expected_back[t][v+t]=Q(-1) +assert back==expected_back +print('PASS exact inverse-transpose on every column',flush=True) +# Independent sparse vector controls avoid repeating a dense full replay. +def vector(es,x): + x=list(map(Q,x)) + for e in es: + if e[0]=='scale':x[e[1]]*=Q(e[2],e[3]) + else:x[e[1]]+=Q(e[3],e[4])*x[e[2]] + return x +sample=[((i*137+13)%101)-50 for i in range(n)] +want=vector(program,sample) +controls={ + 'missing_dirty_compensation':word['precondition']+main+cleanup, + 'missing_Y_inverse_basis':comp+main+cleanup, + 'missing_source_cleanup':word['precondition']+comp+main, + 'wrong_dual_event_order':[dual(e) for e in reversed(program)], +} +for name,es in controls.items(): + expected_sample=vector([dual(e) for e in program],sample) if name=='wrong_dual_event_order' else want + assert vector(es,sample)!=expected_sample,name + +# Orthogonal transvection and a port permutation bring the new geometry onto +# the already fixed 120-port routing family. Every incidence is transformed. +old=json.load(gzip.open('work/higher-stage-e8/verified/gcert1-e8-retimed.json.gz')) +def tau(x):return x^(43 if (x&43).bit_count()%2 else 0) +assert 43 .bit_count()%2==0 +assert set(map(tau,word['ports']))==set(old['ports']) +mapping={i:old['ports'].index(tau(q)) for i,q in enumerate(word['ports'])} +mapping.update({v+i:v+mapping[i] for i in range(v)}) +mapping.update({r:r for r in range(2*v,n)}) +def basis(vs): + b={} + for x in vs: + for k in sorted(b,reverse=True): + if x>>k&1:x^=b[k] + if x: + k=x.bit_length()-1 + for j in b: + if b[j]>>k&1:b[j]^=x + b[k]=x + return tuple(b[k] for k in sorted(b,reverse=True)) +def perp(x):return basis([z for z in range(1,512) if not (x&z).bit_count()%2]) +full=tuple(1<0 + edges.add((old,f));paid[delta]+=1;cur[r]=f +for part in ('A','B'): + if part=='B': + assert all(cur[r]==f for r,f in zip(can['centers'],can['center_frames'])) + assert all(cur[r]==0 for r in range(v,2*v)) + for f in can['center_frames']:paid[len(frames[f])]+=1 + for e in can[part]: + rs=[e[1]]+([e[2]] if e[0]=='add' else []) + for r in rs:climb(r,e[-1]);incidences+=1 +for r,f in enumerate(can['final']):climb(r,f) +assert dict(paid)=={int(r):x for r,x in word['report']['local_profile'].items()} +assert sum(r*x for r,x in paid.items())==9*can['R']+240*8+72 +can['local_profile']=dict(sorted(paid.items()));can['edges']=sorted(edges) +cp=OUT/'CANONICAL-WORD.json.gz';cp.write_bytes(gzip.compress(json.dumps(can,sort_keys=True,separators=(',',':')).encode(),mtime=0)) + +def engine(name): + p=Path('work/pr361/code/engines')/(name+'.py');s=importlib.util.spec_from_file_location('hamming_'+name,p) + m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m +M,M2=engine('moment'),engine('base_two_moment');m,W=73,12720 +HG={int(r):z for r,z in word['report']['global_profile'].items()} +root=M.certify(HG,m,W,True);b=Q(int(Q(root['lower'])*10**18),10**18);grid=Q(1,10**18) +assert M.moment(HG,m,W,b,True)[1]<1>p&1:x^=b[p] + if x: + p=x.bit_length()-1 + for q in b: + if b[q]>>p&1:b[q]^=x + b[p]=x + return tuple(b[p] for p in sorted(b,reverse=True)) +def inside(a,b):return basis(a+b)==b +def hyper(p):return basis([x for x in range(1,512) if (x&p).bit_count()%2==0]) +FULL=basis([1<>p&1:x^=b[p] + if x: + p=x.bit_length()-1 + for q in b: + if b[q]>>p&1:b[q]^=x + b[p]=x + return tuple(b[p] for p in sorted(b,reverse=True)) +def dual(e): + e=list(e) + if e[0]=='add':e[1],e[2]=e[2],e[1];e[3]*=-1 + else:e[2],e[3]=e[3],e[2] + return e +def scalar(e,back): + e=dual(e) if back else list(e) + if e[0]=='add':return ['add',['L',e[1]],['L',e[2]],e[3],e[4]] + return ['scale',['L',e[1]],e[2],e[3]] +def primitive_bound(e): + if e[0] in ('clear','copy'):return 1 + q=Q(e[3],e[4]) if e[0]=='add' else Q(e[2],e[3]) + a,b=abs(q.numerator),q.denominator + assert b&(b-1)==0 + if e[0]=='scale': + assert a&(a-1)==0 + return abs(a.bit_length()-b.bit_length())+int(q<0) + # Exact binary Horner multiplication on a cleared private stream, repeated + # halving, signed accumulation into the target, then clear the private stream. + return 3+(a.bit_length()-1)+a.bit_count()+(b.bit_length()-1) + +def emit(back): + out=[];cur=c['start'].copy() + def event(e):out.append(e) + def scal(e,f):event(['scalar',e,f]) + event(['phase','zero_frame_precondition']) + for e in c['precondition']+c['compensation']: + regs=[e[1]]+([e[2]] if e[0]=='add' else []) + assert all(c['start'][r]==0 for r in regs) + scal(scalar(e,back),0) + event(['phase','entry_adapters']) + for r,f in enumerate(c['start']):event(['adapter','old_to_new',r,f]) + def climb(r,f,part): + old=cur[r] + if old==f:return + assert basis(frames[old]+frames[f])==tuple(frames[f]) + rank=len(frames[f])-len(frames[old]);assert rank>0 + event(['climb',part,r,old,f,rank]);cur[r]=f + for part in ('A','centers','B','final'): + event(['phase',part]) + if part in ('A','B'): + for e in c[part]: + regs=[e[1]]+([e[2]] if e[0]=='add' else []) + for r in regs:climb(r,e[-1],part) + scal(scalar(e,back),e[-1]) + elif part=='centers': + assert all(cur[r]==0 for r in range(v,2*v)) + for k,r in enumerate(c['centers']): + cf=c['center_frames'][k];rank=len(frames[cf]);assert cur[r]==cf + C=['C',k];scal(['clear',C],0 if back else cf) + terms=[e for e in c['cut'] if e[2]==r] + if back: + for e in terms:scal(['add',C,['L',e[1]],e[3],e[4]],0) + else:scal(['copy',C,['L',r]],cf) + event(['center',k,0 if back else cf,cf if back else 0,rank]) + if back:scal(['add',['L',r],C,-1,1],cf) + else: + for e in terms:scal(['add',['L',e[1]],C,e[3],e[4]],0) + scal(['clear',C],cf if back else 0) + else: + for r,f in enumerate(c['final']):climb(r,f,part) + event(['phase','exit_adapters']) + for r,f in enumerate(c['final']):event(['adapter','new_to_old',r,f]) + event(['phase','full_frame_cleanup']) + for e in c['cleanup']: + regs=[e[1]]+([e[2]] if e[0]=='add' else []) + assert all(c['final'][r]==1 for r in regs) + scal(scalar(e,back),1) + event(['phase','done']) + return out + +def check_local(events,back): + # Literal scalar replay of the emitted stream, including center lifetimes. + state={('L',r):{r:Q(1)} for r in range(n)};live=[];paid=Counter();prims=0;macros=0 + for e in events: + if e[0]=='climb':assert not live;paid[e[5]]+=1 + elif e[0]=='center':assert live==[e[1]];paid[e[4]]+=1 + elif e[0]=='scalar': + op=e[1];tag=op[0];t=tuple(op[1]);macros+=1;prims+=2*primitive_bound(op) + if tag=='clear': + state[t]={} + if t[0]=='C' and t[1] in live:live.remove(t[1]) + elif tag=='copy':state[t]=dict(state.get(tuple(op[2]),{}));live.append(t[1]) + elif tag=='scale':state[t]={j:Q(op[2],op[3])*x for j,x in state[t].items()} + else: + s=tuple(op[2]);q=Q(op[3],op[4]);row=state.setdefault(t,{}) + if t[0]=='C' and t[1] not in live:live.append(t[1]) + for j,x in list(state.get(s,{}).items()): + z=row.get(j,Q(0))+q*x + if z:row[j]=z + else:row.pop(j,None) + assert not live and all(not row for r,row in state.items() if r[0]=='C') + for r in range(n): + expected={r:Q(1)} + if back and r2*maxchild**depth +assert local_bound<1<<48 and logical<1<<6050 and router0 + bound=max(math.ceil(36/gap**2),math.ceil(2*(4+512)/gap)) + assert bound*gap**2>=36 and bound*gap>=2*(4+512) + cutoffs.append(str(bound));chain.append(z) +bridge={'semantic':{'C0':{'base':2,'exponent':210000},'strict_literal_gap':1}, + 'rows':{'degree_gap':Q(10**6)-Q(51*20161,25)}} +q=chain[-1]*(1-2*eta);ticks=(1-eta)*q/(1+q)/grid;kap=Q((ticks.numerator-1)//ticks.denominator,10**18) +assembly=Outer.assembly(chain[-1],b,bridge,kap,eta=eta,beta=beta) +try:Outer.assembly(chain[-1],b,bridge,kap+grid,eta=eta,beta=beta) +except AssertionError:pass +else:raise AssertionError('next kappa grid accepted') +result={'status':'PASS_NEW_STRUCTURAL_PROGRAM_AND_FINITE_ASSEMBLY_PENDING_REPLAY', + 'canonical_word_sha256':sha(cp),'scalar_audit_sha256':sha(OUT/'SCALAR-FRAME-AUDIT.json'), + 'exact_phase_receipt_sha256':sha(OUT/'CLIFFORD-REVIEW.json'),'global_template_sha256':hashlib.sha256(blob).hexdigest(), + 'local_program_checks':checks,'R':R,'m':m,'live':W,'physical':physical, + 'bank_assignments':len(assignments),'rank_mass':mass,'deficit':2496, + 'global_profile':dict(sorted(paid.items())),'emitted_local_events_all_calls':event_count, + 'finite_invoice':{'local_primitive_bound':local_bound,'local_adapters':adapters, + 'pervertex':pervertex,'physical_stock_bits':stock.bit_length(), + 'router_bits':router.bit_length(),'literal_bits':literal.bit_length(), + 'physical_row_coefficient':row,'retained_row_coefficient':20161, + 'compiler':compiler,'G_exponent':30000,'E_exponent':100000,'C0_exponent':210000, + 'required_C0_bits':(32*m*BB*BB).bit_length(),'halving_degree':depth, + 'halving_integer_inequality':[m**depth,2*maxchild**depth]}, + 'complex_b':str(b),'bit_c':str(bit),'prospective_kappa':str(kap),'kappa_float':float(kap), + 'log2_kappa':math.log2(float(kap)), + 'kappa_gain_percent':float(100*(kap/Q(998390813251625,10**18)-1)), + 'strict_outer_constraints':{name:str(z) for name,z in assembly['strict_constraints'].items()}, + 'next_kappa_grid_rejected':True,'bootstrap_cutoffs_log2':cutoffs, + 'scope':'New finite scalar interface with a written conjugation proof, conditional on inherited all-size compiler, precision/tape and analytic transfer. Independent emitted-program replay and fresh package replay still required before final promotion.'} +(OUT/'INTEGRATION.json').write_text(json.dumps(result,indent=2)+'\n') +print('PASS prospective kappa',float(kap),'gain',result['kappa_gain_percent'],'percent',flush=True) diff --git a/research/split-centres-global/code/complex_phases.py b/research/split-centres-global/code/complex_phases.py new file mode 100644 index 0000000000..88d6afa045 --- /dev/null +++ b/research/split-centres-global/code/complex_phases.py @@ -0,0 +1,24 @@ +"""Bind unchanged exact phase evidence, or regenerate all selected phase pairs.""" +import gzip,hashlib,json,os,subprocess,sys +from pathlib import Path +P=Path(__file__).resolve().parent.parent;O=Path('split-centres') +def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest() +c=json.load(gzip.open(O/'CANONICAL-WORD.json.gz')) +r=json.loads((P/'inputs/complex-phase-receipt.json').read_text()) +raw=gzip.decompress((P/'inputs/complex-phase-recipes.json.gz').read_bytes());recipes=json.loads(raw) +# Bind the exact decoded witness, independently of gzip implementation metadata. +assert hashlib.sha256(gzip.decompress((O/'CANONICAL-WORD.json.gz').read_bytes())).hexdigest()==r['canonical_word_payload_sha256'] +r['canonical_word_sha256']=sha(O/'CANONICAL-WORD.json.gz') +assert hashlib.sha256(raw).hexdigest()==r['recipe_sha256'] +edges=set(map(tuple,c['edges']))|{(a,b) for f in c['center_frames'] for a,b in ((f,0),(0,f))} +assert {(z['old'],z['new']) for z in recipes['children']}==edges +assert len(recipes['children'])==len(edges) and len(recipes['endpoint_adapters'])==240 +for z in recipes['children']:assert z['rank']==abs(len(c['frames'][z['old']])-len(c['frames'][z['new']])) +if os.environ.get('E8_REPLAY_PHASES')=='1': + subprocess.run([sys.executable,'-B',str(P/'code/complex_phases_full.py')],check=True) + assert (O/'CLIFFORD-RECIPES.json').read_bytes()==raw +else: + (O/'CLIFFORD-RECIPES.json').write_bytes(raw) + r['validation_mode']='Reuse exact phase evidence bound to the unchanged canonical word and recipe hashes' + (O/'CLIFFORD-REVIEW.json').write_text(json.dumps(r,indent=2)+'\n') +print('PASS source-bound phase recipes',len(edges)) diff --git a/research/split-centres-global/code/complex_phases_full.py b/research/split-centres-global/code/complex_phases_full.py new file mode 100644 index 0000000000..b5a5bd64b4 --- /dev/null +++ b/research/split-centres-global/code/complex_phases_full.py @@ -0,0 +1,39 @@ +# Adapted from PR425 for heterogeneous centres by icekylinx with Codex assistance. +"""Exact phase-aware lowering of every used edge of the new structural word.""" +import gzip,hashlib,json,sys,time +from collections import Counter +from pathlib import Path +sys.path.insert(0,str(Path('work/odd-stages').resolve())) +from clifford_exact import * + +OUT=Path('split-centres');P=OUT/'CANONICAL-WORD.json.gz' +c=json.load(gzip.open(P));n=c['h'];frames=c['frames'];start=time.monotonic();ops=[] +for U in frames: + op=canonical_frame(n,U) + L=[u|(u<>(y.bit_length()-1)&1:x^=y + if x:return False + return True +def local(events,back): + rows={('L',r):{r:Q(1)} for r in range(n)} + norm={('L',r):Q(1) for r in range(n)};prefix=Q(1);cur=c['start'].copy();private={} + hist=Counter();phases=[];entry=[];exit=[];centers=[];matrix_hash=hashlib.sha256() + allowed=['zero_frame_precondition','entry_adapters','A','centers','B','final','exit_adapters','full_frame_cleanup','done'] + for event in events: + tag=event[0] + if tag=='phase': + phases.append(event[1]);assert phases==allowed[:len(phases)] + if event[1]=='A':assert entry==list(enumerate(c['start'])) + if event[1]=='centers':assert all(cur[r]==0 for r in range(v,2*v)) + if event[1]=='full_frame_cleanup':assert cur==c['final'] and exit==list(enumerate(c['final'])) + assert not private + elif tag=='adapter': + assert event[3]==(c['start'] if event[1]=='old_to_new' else c['final'])[event[2]] + (entry if event[1]=='old_to_new' else exit).append((event[2],event[3])) + elif tag=='climb': + _,part,r,a,b,rank=event + assert not private and phases[-1]==part and cur[r]==a + assert contains(frames[a],frames[b]) and rank==len(frames[b])-len(frames[a])>0 + hist[rank]+=1;cur[r]=b + elif tag=='center': + _,k,a,b,rank=event + assert phases[-1]=='centers' and private=={('C',k):a} + cf=c['center_frames'][k];cr=len(frames[cf]) + assert (a,b,rank)==((0,cf,cr) if back else (cf,0,cr)) + private['C',k]=b;hist[rank]+=1;centers.append(k) + elif tag=='scalar': + _,e,f=event;op=e[0];target=tuple(e[1]);source=tuple(e[2]) if op in ('copy','add') else None + if target[0]=='C' and op=='clear': + assert private.get(target,f)==f + private.pop(target,None) + else: + for r in (target,source): + if r is None:continue + if r[0]=='L':assert cur[r[1]]==f,('common frame',r,cur[r[1]],f) + else: + if r==target and r not in private:private[r]=f + assert private[r]==f + if op=='clear':rows[target]={};norm[target]=Q(0) + elif op=='copy':rows[target]=dict(rows[source]);norm[target]=norm[source] + elif op=='scale': + q=Q(e[2],e[3]);a,b=abs(q.numerator),q.denominator + assert a&(a-1)==0 and b&(b-1)==0 + rows[target]={j:q*x for j,x in rows[target].items()};norm[target]*=abs(q) + else: + q=Q(e[3],e[4]);a,b=abs(q.numerator),q.denominator + assert source!=target and b&(b-1)==0 + # Independent symbolic replay of the cleared coefficient work. + w=0 + for bit in bin(a)[2:]:w=2*w+int(bit) + assert Q(w,b)*(1 if q>0 else -1)==q + prefix=max(prefix,Q(a)*norm[source]) + norm[target]=norm.get(target,Q(0))+abs(q)*norm[source] + row=rows.setdefault(target,{}) + for j,x in list(rows[source].items()): + z=row.get(j,Q(0))+q*x + if z:row[j]=z + else:row.pop(j,None) + prefix=max(prefix,norm[target]) + else:raise AssertionError(tag) + assert phases==allowed and centers==list(range(len(c['centers']))) and not private + assert all(not row for reg,row in rows.items() if reg[0]=='C') + for r in range(n): + expected={r:Q(1)} + if back and r x + ((q+e_j).x)(q+e_j). Its remaining columns are an orthonormal basis +of q^perp. For s>0, rho_s,q exchanges that complement in the local block +with exterior block s and fixes q and all other exterior coordinates. +It is a symmetric orthogonal involution. The stage data owners are +g=d*rho_s,q, with rho_0,q=I, so the right factors are bijections of O(73,2). + +Use canonical data levels X_s=C_[0,9+8s), Y_s=X_s C_q^(-1), and initially +X_(-1)=C_q, Y_(-1)=I. The routed stage starts at level s-1 and ends at level s. +Their binary preimages agree with the window endpoints. Exact phase +polynomials determine the translation that reconciles each endpoint, and +the template applies that translation. There are 3840 nonzero such +translations across the 120 port types and nine stages, before replica +multiplicity. These operators are not silently identified from equal +binary matrices. + +Four-pair scalar chain and idle children + +Starting with F_0 (Y_0 += X_0), for j=0,1,2,3 apply B_j (X_j -= Y_j), +then for j<3 apply X_j += X_(j+1), Y_(j+1) -= Y_j, apply F_j, and undo +that bridge. The last pair has B_3,F_3 without a following bridge. +Afterwards apply, in descending j=2,1,0, X_(j+1)+=X_j and Y_j-=Y_(j+1). +Finally exchange each pair by newX=oldY, newY=-oldX. The complete signed +integer scalar matrix is the identity; omission of every bridge fails. + +Before a bridge, advance the idle pair to the active pair's level. The +two advances for the newly used pairs have ranks (16,8), (32,8), (48,8). +The final advances have ranks 48,32,16,0. Each rank occurs on both members +of the pair, each of 120 ports, and each of eight replicas. A nested idle +transition is factored in the explicit orthonormal basis U_q direct_sum I. +Its exact Z4 phase is reconciled by the stored translation after that child. + +The final Y endpoint is C_all C_q^(-1). A source began at C_q, so its +unadjusted exchange route would be C_all C_q^(-2)=C_all X_q. Applying the +literal X_q to each final Y before the signed exchange removes this factor. +The corresponding 120 omission controls fail. This correction is charged. + +Banks and arbitrary correlated dirt + +There are eight replicas of each of the four data pairs, hence 7680 data +families. Each stage has 783 independent bank families. Number a local +helper occurrence by z=783*replica+helper. It uses bank floor(z/8) and slot +z mod 8, with its nine-dimensional residual assigned to coordinates +[9*slot,9*slot+9). A paid coordinate C child at coordinate 72 completes +each bank. All eight whole residuals and this padding fill dimension 73. +Thus there are 9*783=7047 bank families and live stock 14727. + +Let Pi_slot swap the first nine coordinates with the assigned block. The +local invocation at class d uses the bank class g=d*Pi_slot^(-1). Its +residual at that owner is P_g C_block P_g^(-1). Right multiplication is a +bijection. Local helpers sharing one bank have distinct slots, hence +different right factors and different actual bank classes for every d. +All data and private families are disjoint from banks. The checker verifies +these injections for all 72 invocation/replica templates and 56376 residual +assignments. A complete cover sweep for one replica finishes before the +next begins. The local dirty invocation is block diagonal on helpers at +its endpoint and permits arbitrary correlated helper values. Therefore +overlap between different invocations does not impose a cleanliness or +independence assumption. At each bank class, the eight residuals and the +padding are coordinate factors in one common conjugated basis, and their +exact product is P_g C_all P_g^(-1). + +One more exact correction is essential. Orthogonality alone does not imply +that P_g commutes with C_all as an exact operator. In fact + P_g C_all P_g^(-1) = C_all X_delta(g), + delta(g)_i = (weight(row_i(g))-1)/2 mod 2. +The quadratic terms cancel by row orthogonality and the remaining even +linear terms give the displayed translation. Both sides fix the uniform +vector, fixing the global scalar. Apply X_delta(g) to EVERY final live +family in cover class g, after the bank padding and signed data exchange. +The template includes and charges all 14727 corrections per cover. This +identity is also checked on every orthogonal matrix in dimensions 1..5. + +Finite work and recurrence charges + +The source emitter is regenerated and revalidated in both orientations. +It accounts for 1242936 local events over 72 invocations, with all copied +center and dirty-tableau lifetimes intact. Forward and backward scalar +words freshly replay all 1023 independent dirty live columns. Only the +private work starts at zero. Work comprises 783 tableau streams, nine +reserved center streams (eight used), and one coefficient stream. Each +invocation completes and erases its private work before the next. Physical +stock is therefore 15520 per cover; scalar-only work is excluded from the +recursion-volume denominator. + +GLOBAL-REVIEW.json records the complete recomputed finite overcharge, with +64*(73+1)^3 compiler groups per rank-zero adapter, source-counted scalar +primitives, and overcharges for all data routes, bank selectors, phases, +padding, bridges, exchanges and cover corrections. The O(73,2) order is +2^(36^2)*product(2^(2i)-1,i=1..36); its bit length is 2628. The recomputed +router fits 2^30000, the literal charge fits 2^100000, and the precision +guard fits C0=2^210000. No even-dimensional orthogonal-order formula is used. + +Largest child 48 does not satisfy one-layer halving. Instead +73^2=5329>2*48^2=4608, so two nested children have width strictly below +half the parent, including floors. The general depth is bounded by +2*ceil(log2 e), with direct small leaves. For B=s+E the completed-child +semantic induction has 2B(73-48)-s-E=49B>0. The resulting conservative +complete-row coefficient is 2*2642+9909+252=15445<20161, retaining the +external bit/base-row allowance as an explicit interface assumption. +The inherited bad-branch envelope is priced conservatively as before. + +Two independent rational moment engines admit +b=999240641319551/10^18 and exclude b+10^-18 for the source-bound profile. +The rank mass is 1072575, and 73*14727-1072575=2496=8*(8*120-9*72). +This complex component exceeds 1/1024 but does not improve the current +bit bottleneck. No improved final kappa or completed PR milestone follows. diff --git a/research/split-centres-global/proofs/PR386-BIT-GEOMETRY.txt b/research/split-centres-global/proofs/PR386-BIT-GEOMETRY.txt new file mode 100644 index 0000000000..31efe31268 --- /dev/null +++ b/research/split-centres-global/proofs/PR386-BIT-GEOMETRY.txt @@ -0,0 +1,191 @@ +Compressed nine-stage E8 bit supplier and combined conditional bound + +Claim and source assumptions + +The conditional combined value is + kappa = 998243154231047 / 10^18 = 0.000998243154231047 > 1/1024. +It is approximately 2^-9.9683211064. This is a conditional finite construction +in the inherited supplier framework, not a Lean proof of integer multiplication. +No priority claim is made. + +The E8 bit word, its 120 root lines, all 865 helpers, and nine retained totals +are taken without modification from Dylan Crow's PR #370, commit +b7fe9cdf2da009c947ff6b334c562bc190b30373. Its raw word has SHA256 +1fb726ea3818fe0837cceb0dd22a71a0814f064e5e781628104610d6468e0e55. +The original verification is rerun, including regeneration, independent +1105-column F2 checking, official record legality/formal columns, all-frame +Gram and prime witnesses, negative controls, and the original regression set. +Its five-stage c is 904072820242522/10^18, insufficient by itself for -10. + +The complex supplier is the separately reconstructed compressed nine-stage +component from PR #377, with b = 999240641319551/10^18. Its complete source, +notices, exact Clifford and Z4 phase checks, global template and finite bill +remain included. In particular, its terminal X_q and every-live-family +X_delta(g) corrections are retained; equality of binary matrices is not +substituted for equality of complex operators. + +The inherited all-size weighted bit compiler, tape/prime/precision and +analytic transfer interfaces remain conditional. PR #370's explicit admission +of nine copied totals at h=8 is retained. The complex local E8 theorem, +Clifford compiler, common fine-grid, restored-row and analytic interfaces +remain conditional exactly as stated in the companion component. The new +window, banking and two-level finite charges are described below rather +than inferred from a rank histogram. + +Exact bit operators and compressed ambient space + +Over an admitted odd address field, the E8 form is G=I_8/2. For a nondegenerate +subspace U, write P_U for its orthogonal projector. On the doubled address +space define + D_U = [[I-P_U, P_U], [P_U, I-P_U]]. +Thus D_U is an exact involution. If U is contained in V then +D_V D_U = D_(V intersect U-perp), with rank dim(V)-dim(U). Also + D_I D_P = D_(I-P). +These are literal address matrices. Unlike the complex C operators, they +have no hidden scalar phase. The auditor reconstructs all 944 rational +projectors and checks all 3289 used nested pairs, in both orientations. + +Set V_global = Q^8 direct_sum (Q^7)^8, m=64, with form I_64/2. +Let E_s be the first s exterior 7-blocks, s=0,...,8. At stage s lift the +entire local word by replacing U with U direct_sum E_s. Both ends of every +local transition contain the same E_s, so it cancels exactly; the child +projector and rank are unchanged. This holds for copied totals as well: +the temporary transforms between the source and scatter frames, whose +common E_s cancels. COPY/ERASE windows remain sequential and immutable. +No assumption that m is a multiple of 9h is used. + +Port routes + +The reference root is q*=2e_0. For every root q, the checked product g_q +of at most two E8 root reflections sends q* to plus or minus q. Let A_q be +its last seven columns. They form an orthonormal basis of q-perp: + A_q^T A_q=I_7, A_q A_q^T=I_8-P_q, P_q=q q^T/4. +For stage s>0 use, on the local block and exterior block s, + rho_(s,q) = [[P_q, A_q], [A_q^T, 0]], +and fix all other coordinates. For s=0 use the identity. These matrices +are orthogonal involutions. Conjugating the lifted endpoints gives + (P_q,E_s) -> (I_8,E_(s-1)), (I_8,E_s) -> (I_8,E_s), + (0,E_s) -> (I_8-P_q,E_(s-1)), + (I_8-P_q,E_s) -> (I_8-P_q,E_s). +These equalities are checked as exact rational matrices for every port. +Each nontrivial route has a replayed elementary factorization, at most +77 factors, with denominators 1,2,4. Omitting a factor fails. Thus all +routes remain defined at every odd address prime; there is no new odd +exceptional prime. The existing local prime witnesses are rerun separately. + +Nine-stage scalar recipe and deferred endpoint completion + +Use four data pairs (X_j,Y_j). Start with F_0: Y_0 += X_0. For j=0,...,3, +apply B_j: X_j -= Y_j; when j<3 insert the two shears + X_j += X_(j+1), Y_(j+1) -= Y_j; +apply F_j; then undo those two shears. After all stages, for j=2,1,0 apply + X_(j+1) += X_j, Y_j -= Y_(j+1). +Finally replace (X_j,Y_j) by (Y_j,-X_j). The complete signed integer +8-by-8 scalar matrix is the identity. Omitting any of the eighteen +individual bridge shears changes it. + +Each B_j is the reflected inverse of the actual local record stream: +reverse the order, negate ADD coefficients, replace U by U-perp, and +turn ERASE into a fresh COPY from the original unchanged center. No erase +is inverted. PR #370 stores zero in the ERASE rank field; the reflected +COPY rank is freshly derived from its two frames, giving rank 8. Both +oriented streams replay all 1105 independent input columns and close work. + +Before each bridge the newly used pair is advanced to the active level. +The two idle increments are (14,7), (28,7), (42,7). Endpoint completion of +the earlier pairs is deferred to the final stage, with ranks 42,28,14,0. +Every increment acts on both members of every port pair and every replica. +The schedule checker requires equal complete frames at every bridge. +The signed terminal exchange completes the data transform using the exact +identity D_I D_P=D_(I-P). Scalar replay on 8745 independent columns includes +960 data and 7785 separate stage-helper inputs. All are restored after +the exchange; the reflected copy work closes to zero. + +Whole-block banks and arbitrary correlated dirt + +Use eight replicas. There are 4*2*120*8=7680 data families. For each stage, +number a local helper occurrence by z=865*replica+helper, and assign it +to bank floor(z/8), slot z mod 8. There are 865 banks at each of nine +stages. Each slot is one whole 8-dimensional coordinate block in Q^64. +The eight slots are mutually perpendicular and fill the ambient space; +no padding child is needed. Live recursion stock is 7680+9*865=15465. +Nine private center slots are reserved and excluded from recursion volume, +so charged physical stock is 15474. Only one such slot is used at a time. + +Let Pi_slot exchange the first eight coordinates with its bank block. +For a cover class d in O(I_64/2,F_q), the helper owner is the bank class +g=d Pi_slot^-1, and a data owner is d rho_(s,q). Right multiplication is a +bijection of the finite cover. Within every local invocation, helpers in +the same bank have different slots, hence different actual cover classes; +all data and work families are disjoint from banks. All 62280 assignments +are checked, and every physical bank receives each of its eight slots once. + +The local all-column theorem permits arbitrary helper inputs, including +correlations created by earlier invocations. After its endpoint each helper +has only the known residual D_H. The common E_s cancels, so no cleanliness +assumption is imposed by a previous bank action. Complete cover sweeps run +sequentially. At a fixed bank owner g the residuals are D on the eight +orthogonal coordinate blocks conjugated by g. They commute and multiply +to D_I. Since diag(g,g) commutes with the literal head/tail exchange D_I, +no complex-style cover phase correction is needed on the bit side. +This is a symbolic finite cover proof, not an enumeration of O(64,F_q). + +Actual emitted ledger + +The source-bound template emits 72 local invocations and 1355328 events. +All local COPY/ERASE and helper lifetimes are rechecked. Its paid profile is + 1:149472, 2:67824, 3:32256, 4:30096, 5:22176, 6:144, + 7:5760, 8:1296, 14:3840, 28:3840, 42:3840. +There are 320544 paid children, rank mass 987264 and deficit + 64*15465-987264 = 2496 = 8*(8*120-9*72). +The independent auditor recomputes the profile from the emitted template +and rejects missing idle/bridge/exchange/invocation events, bank-slot aliasing, +understated stock, a missing local MOVE and a wrong reflected COPY charge. + +Finite cost, precision allowance and two-level halving + +The largest child is 42, so one-level halving is false. Two levels suffice: + 2*42^2=3528 < 64^2=4096. +Floors only reduce descendant widths. The exact one-level moment, including +the inherited 10^-16 bad-branch envelope, is strictly below one; composing +two levels squares this contraction. The finite composite may be used with +the inherited halving-based compiler and direct small leaves. + +The old five-stage 104-bit payload-prefix guard is not reused. Fresh local +cancellation-free row bounds are 742 forward and 6308 reverse. For five +forward calls, four reflected calls and eighteen bridge shears, the bound + 2^18 * 742^5 * 6308^4 +has 117 bits. We explicitly charge 192 bits per nine-stage block. The actual +source operations, copy episodes, 77-factor routes, selectors, all owner +adapters and this prefix bound enter certify.py's finite coefficient. It +has 117 bits; the charged two-level coefficient has 269 bits and is bounded +by 2^512. This deliberately increases the finite cutoff, rather than passing +the old 104-bit assertion. The exact three bootstrap cutoff inequalities +are checked using the changed coefficient. + +For cover/routing enumeration use the inherited coarse q^(m^2+1) bound; +two levels and the retained additive row charges give + 2*(64^2+1)+9909+252 = 18355 < 20161. +The explicit rational bit routes introduce only powers of two. The new +finite constants fit well below the companion bridge's 2^30000 reserve, +and the common external C0=2^210000 and row allowance 20161 are retained. +As for the companion complex component, the general compiler/common-grid +interfaces are assumptions; no new Lean formalization is asserted. + +Exact price and combined assembly + +Two independent rational moment engines, both with the 10^-16 envelope, +admit c=1057833103534317/10^18 and reject c+10^-18. The complex supplier +therefore binds. With eta=10^-12 and beta=10^-9 choose + s=999240640320309/10^18 < (1-beta)*b < c. +Start a0=384599/10^10 and apply a_(j+1)=(1-s)s+s*a_j three times. The retained +outer assembly at (a3,b) admits kappa=998243154231047/10^18. All 47 strict +constraints are positive; the next 10^-18 kappa grid point is rejected. +The strict excess over 1/1024 is 21680654231047/10^18. Final kappa is about +24.0286% above frozen #361, within the explicitly retained assumptions. + +Attribution: Dylan Crow / Anthropic Claude for PR #370's new local bit word; +Jacob Sussman for E8 and the complex unit; the inherited source527, PR234, +PR266, PR315, PR346, PR352 and PR363 contributors as listed in the preserved +notices; Zhihao Chen with OpenAI Codex assistance for this compressed bit +composition, its independent audit, and the combined nine-stage package. diff --git a/research/split-centres-global/proofs/PR425-COMPLEX.txt b/research/split-centres-global/proofs/PR425-COMPLEX.txt new file mode 100644 index 0000000000..41061757ce --- /dev/null +++ b/research/split-centres-global/proofs/PR425-COMPLEX.txt @@ -0,0 +1,211 @@ +Hamming packets with mutable source and target bases +Conditional finite extension of the complex E8 supplier + +1. What is new + +The old r783 word keeps source values fixed and does not read target registers. +Those are sufficient restrictions on a scalar word, not necessary conditions +for a common-frame linear program. The new word uses 680 helper registers: + + * source registers themselves carry one branch of a simultaneous signed + packet computation; + * retired packet registers retain a full source basis, from which the eight + central coordinate sums are reconstructed; + * 56 pairs of targets carry a first two-output butterfly, with its input + basis explicitly compensated at frame zero and in the center decoder; + * an exact inverse on all source/helper registers is executed at their + common full frame after the last recursive climb. + +No recursive work is deleted from the ledger. A helper is counted for its +entire lifetime, including unused final climbs. All 120 sources and targets +retain their original line/full and zero/hyperplane endpoint ranks. + +The new local histogram is + {1:2248, 2:896, 3:168, 4:336, 5:392, 8:24, 9:8}. +Its rank mass is 9*680 + 240*8 + 72 = 8112. There are 4072 local children. +There are more local children than in the old r783 word, but substantially +less helper rank mass; the complete moment, not a count proxy, decides gain. + +2. Exact Hamming geometry and signed packet algebra + +Use the pinned PR370 table of 120 E8 root lines in Construction-A coordinates: +eight coordinate lines 2e_i and 112 sign lines on the 14 weight-four Hamming +blocks. For integer representatives r_s, let G_st = r_s dot r_t / 2. +The matrix C_st = 1 + G_st mod 2 has binary rank nine. The construction gives +an explicit orthonormal realization p_s in F_2^9 with + + p_s dot p_t = C_st, and p_s dot p_s = 1. + +Consequently the nonzero off-diagonal entries of G/2 occur only where a source +line lies in the target hyperplane. The rank-eight central factorization is + + (G/2)_ts = sum_i r_ti r_si / 4. + +For a source Hamming block d, a coordinate pair {i,j} in d, and epsilon=+-1, +define the signed face packet + + P(d,ij,epsilon) = sum_{s in d, r_si*r_sj=epsilon} r_si x_s. + +Each packet has four terms and its binary port span has rank three. Split +the eight sign lines of a block into its two parity tetrads. Each tetrad pair +occurs in two face packets with independent signed coefficient rows. The two +rows are formed simultaneously by two determinant-one shears, rather than +forming independent one-output sums. The packet factory uses its eight source +registers and sixteen additional helpers. Its twelve retired registers can +be oriented to retain a full rank-eight source basis. Exact elimination on +that stock produces four coordinate sums without allocating more helpers. + +This comparison of an individual factory is not a claim that the whole old +supplier used 48 helpers per block. The relevant complete counts are 783 and +680, both charged with their full actual profiles. + +For two target/source blocks whose intersection is {i,j}, the contribution +to target t is -r_ti P(d,ij,r_ti*r_tj)/2. The remaining within-block and +coordinate-line contributions are explicit four-output signed transforms. +Every one of the 14400 rational decoder entries is rechecked. Adding the +eight coordinate centers leaves precisely the identity matrix on sources. + +The binary transvection x -> x+(x dot 43)*43 is orthogonal because 43 has +even weight. It maps the constructed port set exactly to the old fixed E8 +port set. All frames and register indices are transported, so the old nine- +window data routes and their global phase correction apply to exactly the +same ordered ports, without introducing an unproved new covering geometry. + +3. General scalar-interface lemma + +Write z=(x,s) for the source and arbitrary dirty helper streams, and y for +the targets. Permit scalar additions and invertible dyadic scalings between +registers at the same current label. No target may feed a z register. The +raw A/center/B word therefore has block form + + z' = U z, + y' = V y + J x + K s, + +where U and V are invertible, and the retained-center operations are included +in J and K. The actual word has J=I after its adjusted center scatter. The +checks compute every coefficient over Q, rather than inferring it from a +desired sparsity pattern. + +At frame zero, before entry adapters or recursive children, execute + + y <- V^{-1} y - V^{-1} K s. + +Both y and s have label zero there. The code emits the literal inverse of +the 56 disjoint two-output target bases and a direct, charged dyadic old- +response matrix with 13216 additions. There is no uncharged oracle for K. +It is computed from the explicit scalar word and serialized. All coefficient +work is cleared immediately after its use. + +After the last main gate, finish every z register's climb to the full frame, +then execute U^{-1} by reversing and inverting the non-target gates. These +gates are legal at one common full frame, including helper-to-source gates. +The result is exactly + + (x,s,y) -> (x,s,y+x). + +The second orientation is the inverse transpose: negate and transpose every +addition and invert every scale in the SAME event order. Each retained +center is implemented by the transposed gather/child/scatter stream. The +result is (x,s,y) -> (x-y,s,y). Both orientations are replayed on all 920 +independent live columns, including all 680 arbitrary helper columns. +Missing compensation, missing output preconditioning, missing cleanup and +the wrong inverse-transpose order are rejected. + +Why the scalar argument lifts to exact complex labels: for each binary +subspace F use the exact canonical representative L(F). A climb from A to B +acts as L(B)L(A)^{-1}. If two registers share F, a scalar addition commutes +with their common L(F), as does a scalar scaling. Induction through the +actual stream therefore gives the block-diagonal conjugation of its scalar +matrix by the current labels. Center copies explicitly move from full to +zero, or zero to full in the other orientation. The preconditioner uses +only label-zero registers, and the z cleanup uses only full-label registers. +Thus the proof never moves a scalar operation across unequal labels or +identifies two frames merely because their ranks agree. + +Every used canonical frame, nested transition, center direction and endpoint +adapter is independently lowered by the exact Gaussian Clifford compiler. +Equalities include global phase. The old restricted gx gate-shape checker +is not used to admit this new interface; the stronger explicit matrix and +common-frame checks replace its source-immutability/target-read restrictions. +This is a written finite algebraic extension, not a new Lean theorem. + +4. Complete programs and work lifetimes + +Each orientation emits 27537 events, including startup, entry/exit adapters, +all recursive climbs, eight sequential center children, scalar operations +and final cleanup. Temporary centers are initialized, used and erased one +at a time. No center or coefficient work stream survives a live child. + +All added coefficients are dyadic. To apply a/2^j, compute |a| times the +source by binary Horner additions on a cleared private stream, halve j +times, accumulate with its sign, and clear the private stream. In-place +scales are signed powers of two. Every such primitive is charged. This +introduces no new denominator prime. Independent replay bounds the actual +cancellation-free prefix norms, including coefficient work; a 192-bit local +payload allowance is retained conservatively. + +5. Nine-window composition and finite bill + +Use the previously verified m=73 compressed nine-window geometry, four data +pairs, eight replicas, and the original signed bridges, idle children, +terminal exchange, terminal translations and full-cover phase correction. +The source scalar identity and its negative inverse-transpose are exactly +the two local interfaces consumed by that unchanged geometry. + +There are 680 whole-block banks per stage, each containing eight rank-nine +helper blocks plus one paid rank-one padding child. The live width is + + W = 240*4*8 + 9*680 = 13800. + +The conservative physical width is W+680+9+2=14491. The old-response matrix +uses no persistent tableau, but the old-size reserve is still charged. +The emitted owner table has 48960 distinct stage/replica/helper assignments. +The new global profile is + + {1:167976, 2:64512, 3:12096, 4:24192, 5:28224, + 8:7488, 9:576, 16:3840, 32:3840, 48:3840}. + +Its rank deficit is 73*13800 - sum(r*H_r) = 2496. The maximum child is 48, +and 73^2 > 2*48^2 supplies the same charged two-level halving argument. + +The finite bill is recomputed from the new scalar programs, bank owners, +work stock and adapter counts. It is not asserted unchanged. The local +primitive bound fits 2^48; the tape router fits 2^30000; the literal envelope +fits 2^100000; the precision envelope fits 2^210000. The physical row +coefficient is 15445, below the explicitly inherited external allowance +20161. Full-cover corrections apply to all 13800 live families. + +6. Conditional numerical conclusion and retained assumptions + +Two independent rational moment engines, with the inherited 10^-16 bad- +branch envelope, accept + + b = 1049104978040580 / 10^18 = 0.001049104978040580 + +and reject the next 10^-18 grid point. With the unchanged bit parameter +c=0.001057833103534317, three bootstrap steps and all 47 strict outer +conditions give the prospective finite-assembly value + + kappa = 1048005508028206 / 10^18 + = 0.001048005508028206, approximately 2^-9.898137985359. + +The finite statement is conditional on the same all-size weighted compiler, +common fine grid, restored-row/base allowance, tape/prime/precision and +analytic transfer interfaces as the retained nine-stage result. The new +scalar-interface lemma above and its serialized program are additional +reviewable material, not an appeal to gx accepting a program outside its +grammar. No unconditional integer-multiplication theorem is claimed. +The result is approximately +4.97% over the locally verified retimed bound, +and remains well short of 2^-9. A fresh extracted-package replay is required +by this research workflow before publication or final promotion. + +Attribution + +The root table and the motivation to use Hamming coordinates come from the +already pinned PR370 bit package (Dylan Crow, with Anthropic Claude assistance). +The E8 complex label family, original scalar word and gx interfaces are due +to Jacob Sussman. The retained complex admission, pricing and global analytic +interfaces are credited in the original package notices and PROOF.txt. +The mutable-basis packet word, transported geometry, expanded scalar proof, +new finite program and the present checks were developed in this local +research session by Zhihao Chen with OpenAI Codex assistance. diff --git a/research/split-centres-global/proofs/PR426.md b/research/split-centres-global/proofs/PR426.md new file mode 100644 index 0000000000..e589cfbf50 --- /dev/null +++ b/research/split-centres-global/proofs/PR426.md @@ -0,0 +1,108 @@ +# Construction, dependencies and sufficient argument + +The fixed complex witness starts from Chafik Boukhalfa's far-retimed E8 word +and applecrusher's two equal-helper substitutions and two frame refinements. +It additionally replaces helper 556 by -2 times helpers 354 and 461, then +helper 576 by -2 times helpers 402 and 478 after compaction. Exact clean +linear forms agree at every substituted read. The backward upper-frame and +forward nested repairs retain copied-total pins and final address caps. +R is 779. The actual new dirty response and cleanup are regenerated: equality +on clean values alone is not the arbitrary-dirt proof. + +The signed prefix restoration is the PR390/395 bracket. For 25 disjoint +targets, subtract lambda times the donor before the prefix, emit the exact +source/write-version/frame difference, and restore lambda times that donor +at the common recovery frame. Lambda is +1 or -1. The full rational main +operator and all retained totals agree with the explicit same-width R779 +baseline on all 1,019 independent columns. Source/helper subwords agree +exactly, so the new baseline's explicit dirty response and cleanup remain +valid. The changed compiler permits a main Y read only when its target is Y; +helper-to-X remains forbidden. Both signed orientations and private lifetimes +are freshly admitted, with all actual Clifford phases and physical incidences. + +The shared entrance construction follows PR401/404. Each pivot p satisfies +K_p + sum_d a_pd K_d = 0 in the explicit baseline response. Four re-pivots +from PR412 replace the basis of these same relations, including the +half-valued donor that otherwise fails the original sixths-denominator +condition. PR410 enlarges eight entrance subspaces. Removed original helpers +556 and 577 are mapped explicitly onto our R779 word. The shared layer has +192 pivots, rank mass 350, and 496 literal unit shears. Its pivots and donors +are disjoint, so this layer alone has (S-I)^2=0. + +PR409's four ordered groups, with PR412's two additional re-pivots, prepend +55 more shears and admit ten further pivots. The combined word has 202 +gauges of rank mass 360 and 551 entrance shears. The complete chronological +prefix need not have (S-I)^2=0. We check its actual product M S, all retained +totals, and that every gauged target-response column is zero. Every entrance +source is read before any earlier entrance operation writes it. + +Every one of the 551 omission controls is recomputed from the suffix +response. If shear t += q s is removed, its suffix response is multiplied +by -q times the original independent s column: earlier operations leave s +unchanged by the read-before-write condition. A nonzero response is required +for each omission; the entire changed scalar schedule is also replayed for +sampled omissions. No global donor/pivot disjointness is assumed here. Both +unchanged original gx.check1 and gxcore.mirror checkers pass, including the +native denominator conditions. Every actual nested transition is charged. + +PR376's additional target201/helper491 frame change from rank eight to seven +is checked for full operator equality and nested paid paths before gauging. +PR404's target125/124 overlapping-prefix recovery requires a different +chronological input and is not imported. Its numerical gain is not included. + +Each entrance chart is normalized explicitly. Even and degenerate E_p use +the full two-sided exact Clifford factorization of F T_E inverse. The right +inverse adapter precedes the entire old-response invocation; the left inverse +adapter follows all main and helper cleanup. Both orientations retain every +unitary address operator in the inverse-adjoint chronology. Rank-zero adapters +are costed. All old/new/reflected Gaussian child pairs are recomputed, +including Pauli signs and global phase. Newly assigned mixed-bank coordinate +permutations and inverse owners are emitted and independently decoded. +Padding is an exact fixed integer witness, not a claim of solver optimality. + +The new bit operation differs from the preceding all-dirt reset: a retired +helper only needs its clean X-content zeroed before a new logical helper is +placed in the same slot. An arbitrary residual helper value is allowed. The +new helper basis determines a newly computed initial D compensation. C is +the reversed helper subword, restoring every physical helper, including its +original independent dirt. Each reset is checked exactly before reuse; the +retired slot has no later original use, the new helper has no earlier use, +and copied totals are protected. The combined word is checked over every +independent binary column. It uses 55 fewer helpers (822 to 767). The initial 27 reuses and 26 frame +moves are followed by two fixed rounds of 14 reuses and 14 frame moves. +The later resets use exact two- or three-parent clean forms; every parent +and all rebuilt dirty compensation are charged and independently checked. Integer signed-prefix bounds, lifting, +copied-center controls, routes and whole-bank packing are recomputed rather +than inferred from the clean calculation. + +The complex assembly has dimension 73, 14,286 live and +15,075 physical families, 734 banks per stage, deficit 2,496, +maximum child rank 48 and halving degree two. The bit assembly has dimension +56, 10,409 live families, deficit 1,512 and halving degree two. Actual row +coefficients fit the common 20,161 reserve. Both finite invoices and both +exact rational moment engines retain the positive 10^-16 fallback. Adjacent +10^-24 complex coarse grid points are rejected; the unchanged bit coarse +grid remains 10^-18. The exact outer assembly uses positive eta=10^-24, +beta=10^-18, eight finite bootstrap continuations and a 10^-27 grid; it +checks 47 strict constraints and invalid eta/beta/adjacent-point controls. + +The complex coefficient is 254951444354246755323/250000000000000000000000. The bit coefficient is +104575879789097/100000000000000000. The resulting conditional kappa is 40750673324589432209923/40000000000000000000000000. +Using the preceding unchanged bit supplier with this same complex coefficient +gives 203354853562950029967497/200000000000000000000000000, where the bit side +binds. The new clean-reuse bit supplier removes that bottleneck. Its exact +additional kappa contribution is recorded as the difference from this fair +control; the combined witness is limited by the new complex coefficient. + +All original files are manifest-bound and immutable. A copied supplier tree +is changed only through asserted literal edits. DERIVATION.json records every +old/new digest, changed pin and textual difference. Both full predecessor +supplier suites run before the changed admission. Expected records are checked +after recomputation, rather than used to obtain a PASS. + +This is a sufficient finite conditional construction. The inherited all-size +recursive suppliers, canonical/rank-zero compiler, compressed Clifford windows, +dirty banking/cover, routing, restored-row, fixed tape, common-grid, Gaussian +precision/recovery and analytic interfaces remain assumptions. No new full +Lean theorem or unconditional integer-multiplication exponent is asserted. +The target kappa > 0.002 is not attained by this witness. diff --git a/research/split-centres-global/vendor/clifford_exact.py b/research/split-centres-global/vendor/clifford_exact.py new file mode 100644 index 0000000000..166841a037 --- /dev/null +++ b/research/split-centres-global/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: + x /= 2 + k += 1 + lo, hi = log_unit(x) + l2, u2 = log_unit(Q(2)) + lo, hi = lo+k*l2, hi+k*u2 + # Outward rational rounding keeps later certificates compact. + return Q((lo*GRID).__floor__(), GRID), Q((hi*GRID).__ceil__(), GRID) + + +def exp_bounds(x): + require(0 <= x < 1, "exponential range") + term = total = Q(1) + for j in range(1, 13): + term *= x/j + total += term + tail = term*x/13/(1-x/14) + return total, total+tail + + +def moment(m, W, entries, saving): + lo = hi = Q(0) + for t, count in entries: + t, count = int(t), int(count) + require(0 < t < m and count > 0, "improper child") + l, u = log_bounds(Q(m, t)) + lower = exp_bounds(saving*l)[0] + upper = exp_bounds(saving*u)[1] + lo += Q(t*count, m*W)*lower + hi += Q(t*count, m*W)*upper + return Q((lo*GRID).__floor__(), GRID), Q((hi*GRID).__ceil__(), GRID) + diff --git a/research/split-centres-global/vendor/engines/moment.py b/research/split-centres-global/vendor/engines/moment.py new file mode 100644 index 0000000000..7d697cb452 --- /dev/null +++ b/research/split-centres-global/vendor/engines/moment.py @@ -0,0 +1,113 @@ +"""Independent prospective ordinary five-stage cost, never supplier admission. + +Consumes a raw one-invocation ledger made from the actual source/internal/target +paths. No packed profile is used as an input. Missing physical/finite/compiler +obligations must remain explicit in the accompanying report. +""" +from collections import Counter +from decimal import Decimal, localcontext, ROUND_FLOOR +from fractions import Fraction as F +from functools import lru_cache +from math import factorial +import hashlib, json, sys +from pathlib import Path + +DYAD = 1 << 224 + +def floor(x): return F(x.numerator*DYAD//x.denominator, DYAD) +def ceil(x): return -floor(-x) + +@lru_cache(None) +def logarithm(x): + """Mercator bounds after binary reduction; ln(2) via two Mercator sums. + + For 1 <= y < 2, log(y) is an alternating series in z=y-1. + We instead reduce to 1 <= y < 3/2, and bound log(3/2) and + log(2) by the same alternating series at z=1/2 and z=1/3, + using log(2)=log(3/2)+log(4/3). All sums are exact rationals. + """ + assert x >= 1 + k = 0 + while x >= 2: x /= 2; k += 1 + j = int(x >= F(3, 2)) + if j: x /= F(3, 2) + def mercator(y): + z=y-1 + assert 0 <= z <= F(1,2) + # An even partial sum is below log; the next term bounds its tail. + t=z; s=F(0) + for n in range(1, 225): + s += (t if n & 1 else -t)/n + t *= z + return s, s+t/225 + a,b=mercator(x); c,d=mercator(F(3,2)); e,f=mercator(F(4,3)) + return floor(a+(k+j)*c+k*e), ceil(b+(k+j)*d+k*f) + +def exponential(l,u): + assert 0 <= l <= u < F(1,10) + def poly(x): + s=t=F(1) + for j in range(1,25): t=t*x/j; s+=t + return s,t + lo,_=poly(l);hi,last=poly(u) + return floor(lo),ceil(hi+last*u/25/(1-u/26)) + +def moment(H,m,W,a,bad=False): + lo=hi=F(0) + for r,n in H.items(): + assert 0 < r < m and n > 0 + l,u=logarithm(F(m,r)); e,f=exponential(a*l,a*u) + p=F(r*n,m*W);lo+=p*e;hi+=p*f + if bad: + # Existing envelope shape, only conditionally portable to the new cover. + l,u=logarithm(F(m));e,f=exponential(a*l,a*u) + p=F(32*m*sum(H.values()),10**16*W) + lo+=p*e;hi+=p*f + return floor(lo),ceil(hi) + +def decimal(x): + with localcontext() as c: + c.prec=70 + return str(Decimal(x.numerator)/Decimal(x.denominator)) + +def certify(H,m,W,bad=False): + with localcontext() as c: + c.prec=70 + terms=[(Decimal(r*n)/Decimal(m*W),(Decimal(m)/Decimal(r)).ln()) for r,n in H.items()] + fallback=Decimal(32*m*sum(H.values()))/Decimal(10**16*W) if bad else Decimal(0) + lm=Decimal(m).ln();lo=Decimal(0);hi=Decimal('.003') + for _ in range(210): + a=(lo+hi)/2 + if sum(p*(a*l).exp() for p,l in terms)+fallback*(a*lm).exp()<1:lo=a + else:hi=a + q=int(((lo+hi)/2*10**24).to_integral_value(rounding=ROUND_FLOOR)) + lo=F(q,10**24);hi=lo+F(1,10**24) + lv=moment(H,m,W,lo,bad);hv=moment(H,m,W,hi,bad) + assert lv[1]<10 for v in slacks.values()),{k:str(v) for k,v in slacks.items() if v<=0} + assert min(margins.values())==minimum + assert margins['balanced_prefix']-minimum==eta and 1-eps-r==eta/2 + assert 1-eps*(1+c)==eta-eps*eta/4 + return dict(parameters=dict(a_bit=a,a_complex=b,tau=tau,sigma=sigma, + eta=eta,beta=beta,q=q,c=c,epsilon=eps,lambda_=lam, + lambda_prime=lp,alpha_squared_power=r,delta=delta, + C0=bridge['semantic']['C0'],C1=1,kappa=kappa), + strict_constraints=slacks,margins=margins,minimum_margin=minimum, + absorption_gap=minimum-kappa, + recurrence=dict(internal=internal,leaf=leaf,reservations=1-c)) diff --git a/research/split-centres-global/vendor/export_records.py b/research/split-centres-global/vendor/export_records.py new file mode 100644 index 0000000000..3632d37048 --- /dev/null +++ b/research/split-centres-global/vendor/export_records.py @@ -0,0 +1,72 @@ +"""Export a bitE8/1 word to the PR249 record format read by PR #266's official cohort checkers and PR #315's engines. +usage: python3 export_records.py word.json[.gz] OUTDIR -> OUTDIR/{249-records.bin,249-states.json,frames.json} +Records are int32 six-tuples: MOVE(0,role,old,new,rank,0), ADD(1,dst,src,1,frame,phase), COPY(2,centre,temp,frame,ZERO,rank), +ERASE(3,centre,temp,frame,ZERO,0). A multi-source gate becomes one ADD per source, preceded by the MOVEs of every +register of the gate to the gate frame. Frames: integer basis rows B (label vectors of the frame's root lines in the +word's coordinates, a rational basis) and integer annihilator rows A (standard dot product), as PR #266 expects. +Dylan Crow, with Anthropic Claude assistance; Apache-2.0.""" +import sys, json, gzip, struct, os +from fractions import Fraction as Fr +from math import gcd +def load(p): + with (gzip.open(p,'rt') if p.endswith('.gz') else open(p)) as f: return json.load(f) +c=load(sys.argv[1]); out=sys.argv[2]; os.makedirs(out,exist_ok=True) +v,R,h=c['v'],c['R'],c['h']; n=2*v+R; lines=c['lines'] +def basis(idx): + rows=[]; piv=[]; B=[] + for i in idx: + x=[Fr(a) for a in lines[i]] + for p,r in zip(piv,rows): + if x[p]: f=x[p]/r[p]; x=[a-f*b for a,b in zip(x,r)] + nz=[k for k in range(h) if x[k]] + if nz: rows.append(x); piv.append(nz[0]); B.append(list(lines[i])) + return B,rows,piv +def annihilator(rows,piv): + # rows in echelon (pivot columns piv); free columns give the null space of the row space under the dot product + # reduce to RREF + R_=[r[:] for r in rows] + for i,(p,r) in enumerate(zip(piv,R_)): + R_[i]=[a/r[p] for a in r] + for i,p in enumerate(piv): + for j in range(len(R_)): + if j!=i and R_[j][p]: f=R_[j][p]; R_[j]=[a-f*b for a,b in zip(R_[j],R_[i])] + free=[k for k in range(h) if k not in piv]; A=[] + for f in free: + a=[Fr(0)]*h; a[f]=Fr(1) + for i,p in enumerate(piv): a[p]=-R_[i][f] + L=1 + for x in a: L=L*x.denominator//gcd(L,x.denominator) + ai=[int(x*L) for x in a]; g=0 + for x in ai: g=gcd(g,abs(x)) + A.append([x//g for x in ai]) + return A +frames={} +for k,idx in enumerate(c['frames']): + B,rows,piv=basis(idx); A=annihilator(rows,piv) if B else [[int(i==j) for j in range(h)] for i in range(h)] + assert all(sum(a*b for a,b in zip(x,y))==0 for x in A for y in B) and len(A)+len(B)==h + frames[str(k)]=dict(dim=len(B),B=B,A=A) +dim=[frames[str(k)]['dim'] for k in range(len(c['frames']))] +ZERO=[k for k in range(len(dim)) if dim[k]==0]; assert len(ZERO)==1; ZERO=ZERO[0] +cur=list(c['start']); rec=[] +def move(r,f): + if cur[r]!=f: rec.append((0,r,cur[r],f,dim[f]-dim[cur[r]],0)); cur[r]=f +def run(gates,ph): + for f,d,srcs in gates: + for r in [d]+srcs: move(r,f) + for s in srcs: rec.append((1,d,s,1,f,ph)) +run(c['D'],1); run(c['A'],2) +temp=n +for k,q in enumerate(c['ret']): + fq=cur[q]; rec.append((2,q,temp,fq,ZERO,dim[fq])) + for t,row in enumerate(c['scatter']): + if k in row: rec.append((1,v+t,temp,1,ZERO,3)) + rec.append((3,q,temp,fq,ZERO,0)) +run(c['B'],4); run(c['C'],5) +for r in range(n): move(r,c['final'][r]) +with open(out+'/249-records.bin','wb') as f: + for e in rec: f.write(struct.pack('<6i',*e)) +st=dict(n=n,v=v,h=h,R=R,ZERO=ZERO,initial={str(r):c['start'][r] for r in range(n)},final={str(r):c['final'][r] for r in range(n)}, + retained_totals=c['ret'],source_owned_roles=[],regs=[]) +json.dump(st,open(out+'/249-states.json','w'),sort_keys=True,separators=(',',':')) +json.dump(dict(frames=frames),open(out+'/frames.json','w'),sort_keys=True,separators=(',',':')) +print('exported',len(rec),'records,',len(frames),'frames, n',n,'ZERO',ZERO) diff --git a/research/split-centres-global/vendor/hamming_packets.py b/research/split-centres-global/vendor/hamming_packets.py new file mode 100644 index 0000000000..c129996656 --- /dev/null +++ b/research/split-centres-global/vendor/hamming_packets.py @@ -0,0 +1,253 @@ +"""A structural prototype: mutable source bases and simultaneous signed packets. + +Input geometry is the pinned PR370 Hamming E8 root table. The binary realization, +packet construction, two-shear synthesis and arbitrary-dirt replay below are new +local experiments. This does NOT produce a complete improved E8 supplier. +""" +import gzip +import hashlib +import itertools as it +import json +import random +from collections import Counter,defaultdict +from fractions import Fraction as Q +from pathlib import Path + +OUT=Path('work/complex-network/hamming');OUT.mkdir(parents=True,exist_ok=True) +SRC=Path('work/pr370-source/research/e8-bit/data/bit/bitE8-r865.json.gz') +word=json.load(gzip.open(SRC));roots=word['lines'];v=len(roots) +G=[[sum(x*y for x,y in zip(a,b))//2 for b in roots] for a in roots] +C=[sum((1^(G[i][j]&1))<>p&1:x^=b[p] + if x: + p=x.bit_length()-1 + for q in b: + if b[q]>>p&1:b[q]^=x + b[p]=x + return tuple(b[p] for p in sorted(b,reverse=True)) + +def inside(a,b):return basis(a+b)==b + +indices=[] +for i,row in enumerate(C): + if len(basis([C[j] for j in indices]+[row]))>len(indices):indices.append(i) +assert len(indices)==9 +gram=[sum(((C[i]>>j)&1)<>i)&1)*((gram[i]&b).bit_count()&1) for i in range(9))&1 +orth=[] +for step in range(9): + choices=[x for x in range(1,512) if ip(x,x) and all(not ip(x,y) for y in orth)] + chosen=next(x for x in choices if step==8 or any(y!=x and not ip(x,y) for y in choices)) + orth.append(chosen) +assert all(ip(x,y)==int(i==j) for i,x in enumerate(orth) for j,y in enumerate(orth)) +ports=[] +for i in range(v): + row=sum(((C[i]>>j)&1)<>j)&1) for i in range(v) for j in range(v)) + +blocks=defaultdict(list);frame_lines={} +for i,r in enumerate(roots): + support=tuple(k for k,x in enumerate(r) if x) + if len(support)==4:blocks[support].append(i) + else:assert len(support)==1;frame_lines[support[0]]=i +assert len(blocks)==14 and all(len(xs)==8 for xs in blocks.values()) + +def sparse_add(rows,t,s,q): + for j,x in list(rows[s].items()): + z=rows[t].get(j,Q(0))+q*x + if z:rows[t][j]=z + else:rows[t].pop(j,None) + +def simulate(n,events): + rows=[{r:Q(1)} for r in range(n)] + for t,s,q in events:sparse_add(rows,t,s,q) + return rows + +def serialize(events):return [[t,s,q.numerator,q.denominator] for t,s,q in events] + +packet_table={};module_receipts=[];all_programs=[] +for block,ids in sorted(blocks.items()): + ids=sorted(ids);pos={s:i for i,s in enumerate(ids)} + tetrads=[sorted(s for s in ids if sum(roots[s][k]<0 for k in block)%2==p) for p in (0,1)] + assert all(len(t)==4 for t in tetrads) + faces=[] + for i,j in it.combinations(block,2): + for epsilon in (-1,1): + support=[s for s in ids if roots[s][i]*roots[s][j]==epsilon] + content={s:Q(roots[s][i]) for s in support} + frame=basis([ports[s] for s in support]);assert len(frame)==3 + key=(block,(i,j),epsilon);packet_table[key]=(content,frame) + faces.append((key,content,frame)) + pair_uses=defaultdict(list) + for f,(_,content,frame) in enumerate(faces): + for tet in tetrads: + pair=tuple(s for s in tet if s in content) + assert len(pair)==2 + pair_uses[pair].append(f) + assert len(pair_uses)==12 and all(len(fs)==2 for fs in pair_uses.values()) + bysource=defaultdict(list) + for pair in sorted(pair_uses): + for s in pair:bysource[s].append(pair) + # One of the three pair branches is carried by x itself, two by helpers. + regs={};nextreg=8;events=[];event_frames=[];cur=[basis([ports[s]]) for s in ids] + start=list(cur);dead=[] + def add(t,s,q,F): + assert t!=s and inside(cur[t],F) and inside(cur[s],F) + cur[t]=cur[s]=F;events.append((t,s,Q(q)));event_frames.append(F) + for s in ids: + for j,pair in enumerate(sorted(bysource[s])): + if j==0:reg=pos[s] + else: + reg=nextreg;nextreg+=1;cur.append(());start.append(()) + add(reg,pos[s],1,basis([ports[s]])) + regs[pair,s]=reg + assert nextreg==24 + partial={} + for pair,fs in sorted(pair_uses.items()): + s,t=pair;a,b=regs[pair,s],regs[pair,t];f,g=fs + alpha,beta=faces[f][1][s],faces[f][1][t] + gamma,delta=faces[g][1][s],faces[g][1][t] + assert alpha*delta-beta*gamma in (-2,2) + F=basis([ports[s],ports[t]]);assert len(F)==2 + add(a,b,beta/alpha,F) + k=gamma/(delta-gamma*beta/alpha) + add(b,a,k,F) + partial[f,pair]=(a,alpha) + partial[g,pair]=(b,delta-gamma*beta/alpha) + pre_packets=simulate(24,events) + def clean_rank(registers): + piv={} + for reg in registers: + row=[pre_packets[reg].get(i,Q(0)) for i in range(8)] + for j in sorted(piv): + q=row[j] + if q:row=[a-q*b for a,b in zip(row,piv[j])] + j=next((i for i,q in enumerate(row) if q),None) + if j is not None: + q=row[j];piv[j]=[a/q for a in row] + return len(piv) + choices=[[value for (ff,pair),value in partial.items() if ff==f] for f in range(12)] + rng=random.Random(38639);orientation=None + for trial in range(4096): + bits=rng.randrange(1<<12) + if clean_rank([pieces[1-((bits>>f)&1)][0] for f,pieces in enumerate(choices)])==8: + orientation=bits;break + assert orientation is not None + outputs=[] + for f,(key,content,F) in enumerate(faces): + pieces=[value for (ff,pair),value in partial.items() if ff==f] + assert len(pieces)==2 + if orientation>>f&1:pieces.reverse() + (a,alpha),(b,beta)=pieces + add(a,b,beta/alpha,F) + outputs.append((a,alpha));dead.append(b) + assert len(set(r for r,a in outputs))==12 and len(set(dead))==12 + assert not set(dead)&{r for r,a in outputs} + core=simulate(24,events) + for f,(reg,scale) in enumerate(outputs): + clean={ids[j]:scale*x for j,x in core[reg].items() if j<8 and x} + assert clean==faces[f][1] + + # Probe complete borrowing: output each packet, cancel its old dirt at label + # zero, then undo every source/helper operation at the full frame. + # Actual supplier consumers and their remaining chronology are NOT inferred. + n=36;main=events.copy();dirt=[];chosen_targets=[] + for f,(reg,scale) in enumerate(outputs): + main.append((24+f,reg,scale)) + for j,q in core[reg].items(): + if j>=8:dirt.append((24+f,j,-scale*q)) + valid=[t for t in range(v) if all((ports[t]&x).bit_count()%2==0 for x in faces[f][2])] + assert valid;chosen_targets.append(valid[0]) + cleanup=[(t,s,-q) for t,s,q in reversed(events)] + actual=simulate(n,dirt+main+cleanup) + for r in range(24):assert actual[r]=={r:Q(1)} + for f in range(12): + expected={24+f:Q(1)} + expected.update({pos[s]:q for s,q in faces[f][1].items()}) + assert actual[24+f]==expected + # A mutation of the compensator must corrupt at least one arbitrary dirt column. + wrong=simulate(n,main+cleanup) + assert any(wrong[r]!=actual[r] for r in range(24,36)) + # Inverse-transpose: transpose and negate each elementary shear in the SAME + # event order. Reversing as well would generally compute the wrong map. + dual=simulate(n,[(s,t,-q) for t,s,q in dirt+main+cleanup]) + for r in range(n): + expected={r:Q(1)} + if r<8: + expected.update({24+f:-content[ids[r]] for f,(_,content,F) in enumerate(faces) if ids[r] in content}) + assert dual[r]==expected + receipt={'block':block,'source_lines':ids,'packets':12,'pair_butterflies':12, + 'packet_additions':len(events),'live_source_registers_borrowed':8, + 'helper_registers':16,'total_source_and_helper_registers':24, + 'retired_register_clean_rank':8, + 'independent_pair_branch_comparison_helpers':48, + 'comparison_scope':'48 is a specified independent two-input-form implementation, not the helper count of the current r783 supplier.', + 'frame_rank_counts':dict(Counter(map(len,event_frames))), + 'all_dirty_columns_forward_and_inverse_transpose':n, + 'compensator_omission_rejected':True, + 'scope':'A 12-output packet factory and probe sinks. Not a complete 120-port supplier or global frame schedule.'} + module_receipts.append(receipt) + all_programs.append({'receipt':receipt,'start_frames':start,'events':serialize(events), + 'event_frames':event_frames,'outputs':[[r,str(q)] for r,q in outputs], + 'dead_registers':dead, + 'dirt':serialize(dirt),'cleanup':serialize(cleanup), + 'probe_target_ports':[ports[t] for t in chosen_targets]}) + +# Reconstruct the entire signed E8 neighbour correction from the packet family. +# This proves all 120 rational source columns of the abstract decomposition. +decomposition=[] +for target,r in enumerate(roots): + row=defaultdict(Q);terms=[];support=[i for i,x in enumerate(r) if x] + if len(support)==4: + c=tuple(support) + for d in blocks: + inter=tuple(sorted(set(c)&set(d))) + if len(inter)!=2:continue + i,j=inter;epsilon=r[i]*r[j];content,F=packet_table[d,inter,epsilon] + coefficient=-Q(r[i],2) + assert all((ports[target]&p).bit_count()%2==0 for p in F) + for s,a in content.items():row[s]+=coefficient*a + terms.append({'source_block':d,'pair':inter,'epsilon':epsilon,'coefficient':str(coefficient)}) + for s in blocks[c]+list(frame_lines.values()): + if s!=target and G[target][s]:row[s]-=Q(G[target][s],2) + else: + i=support[0] + for d in blocks: + if i in d: + for s in blocks[d]:row[s]-=Q(roots[s][i],2) + expected={s:-Q(G[target][s],2) for s in range(v) if s!=target and G[target][s]} + assert {s:a for s,a in row.items() if a}==expected + # Eight coordinate centers recover the diagonal after side corrections. + for s in range(v): + center=sum(Q(r[i]*roots[s][i],4) for i in range(8)) + assert center+row.get(s,Q(0))==int(s==target) + decomposition.append({'target':target,'cross_block_packets':terms,'side_support':len(expected)}) + +program_path=OUT/'PACKET-PROGRAMS.json.gz' +program_path.write_bytes(gzip.compress(json.dumps(all_programs,sort_keys=True,separators=(',',':')).encode(),mtime=0)) +report={'status':'PASS_STRUCTURAL_PACKET_PROTOTYPE_NOT_A_NEW_SUPPLIER', + 'source_sha256':hashlib.sha256(SRC.read_bytes()).hexdigest(), + 'binary_address_dimension':9,'binary_gram_rank':len(indices), + 'binary_ports':ports,'root_lines':roots, + 'binary_gram_identity':'p_s dot p_t = 1 + (root_s dot root_t / 2) mod 2', + 'modules':module_receipts,'signed_packets':len(packet_table), + 'full_target_decomposition_columns':120,'full_target_decomposition_entries':120*120, + 'program_sha256':hashlib.sha256(program_path.read_bytes()).hexdigest(), + 'decomposition':decomposition, + 'remaining':['Joint scheduling and charging of all packet fan-outs and target accumulations', + 'Forming all eight centers from the available mixed source basis without an uncharged restore', + 'Full 120-port arbitrary-dirt forward/backward program and restored work stocks', + 'Exact complex adapters and global phases; finite invoice; two independent prices and outer assembly'], + 'no_new_coarse_b_or_kappa_claim':True} +(OUT/'PROTOTYPE.json').write_text(json.dumps(report,indent=2)+'\n') +print('PASS: 14 factories, 168 signed packets; each factory uses 8 source + 16 helper registers') +print('PASS: exact dirty forward and inverse-transpose columns, omission controls, all 14400 decoder entries') +print('NOT A SUPPLIER: global scheduling, mixed-basis centers, phase and full price remain open') diff --git a/research/split-centres-global/verify.py b/research/split-centres-global/verify.py new file mode 100644 index 0000000000..01d78bf0d1 --- /dev/null +++ b/research/split-centres-global/verify.py @@ -0,0 +1,51 @@ +"""Verify the selected two-supplier composition using Python's standard library.""" +import argparse,gzip,hashlib,json,os,shutil,subprocess,sys +from pathlib import Path +assert __debug__, 'Assertions must remain enabled' +ROOT=Path(__file__).resolve().parent +ap=argparse.ArgumentParser(description=__doc__) +ap.add_argument('output',type=Path,help='A new output directory outside this package') +ap.add_argument('--replay-phases',action='store_true',help='Recompute all selected Gaussian phase pairs instead of reusing their source-bound evidence') +a=ap.parse_args();out=a.output.resolve() +assert not out.exists() and not out.is_relative_to(ROOT) +def snapshot(): + return {p.relative_to(ROOT).as_posix():hashlib.sha256(p.read_bytes()).hexdigest() for p in ROOT.rglob('*') if p.is_file() and p.name!='MANIFEST.json'} +manifest=json.loads((ROOT/'MANIFEST.json').read_text());assert snapshot()==manifest['files'],'Source manifest mismatch' +sources=json.loads((ROOT/'SOURCES.json').read_text()) +for z in sources['imported_files']: + data=(ROOT/z['path']).read_bytes();assert hashlib.sha256(data).hexdigest()==z['sha256'] + if 'source_sha256' in z:assert hashlib.sha256(gzip.decompress(data)).hexdigest()==z['source_sha256'] +out.mkdir(parents=True) +def copy(src,dst): + p=out/dst;p.parent.mkdir(parents=True,exist_ok=True) + data=(ROOT/src).read_bytes();p.write_bytes(gzip.decompress(data) if src.endswith('.gz') and not dst.endswith('.gz') else data) +for src,dst in [ + ('inputs/e8-r865.json.gz','work/pr370-source/research/e8-bit/data/bit/bitE8-r865.json.gz'), + ('inputs/complex-ports.json.gz','work/higher-stage-e8/verified/gcert1-e8-retimed.json.gz'), + ('inputs/complex-template.json.gz','work/complex-nine-native/GLOBAL-TEMPLATE.json.gz'), + ('inputs/complex-data-phases.json.gz','work/complex-nine-native/DATA-PHASES.json'), + ('inputs/bit-geometry.json.gz','inherited/bit-geometry.json.gz'), + ('vendor/clifford_exact.py','work/odd-stages/clifford_exact.py')]:copy(src,dst) +for name in ('moment','base_two_moment','outer'):copy('vendor/engines/'+name+'.py','work/pr361/code/engines/'+name+'.py') +p=out/'bit426-source-centres';p.mkdir();(p/'bit-input.json').write_bytes(gzip.decompress((ROOT/'inputs/bit-r767.json.gz').read_bytes())) +env=dict(os.environ,E8_OUTPUT=str(out),E8_REPLAY_PHASES=str(int(a.replay_phases)),PYTHONDONTWRITEBYTECODE='1');env.pop('PYTHONOPTIMIZE',None) +steps=[] +def run(name,file,*args): + with (out/(name+'.log')).open('w') as log: + r=subprocess.run([sys.executable,'-B',str(ROOT/file),*map(str,args)],cwd=out,env=env,stdout=log,stderr=subprocess.STDOUT) + if r.returncode: + print((out/(name+'.log')).read_text()[-16000:],file=sys.stderr,flush=True) + raise RuntimeError((name,r.returncode,str(out/(name+'.log')))) + steps.append(name);print('PASS',name,flush=True) +run('hamming_packets','vendor/hamming_packets.py') +for name in ('complex_construct','complex_audit','complex_emit','complex_phases','bit_construct'):run(name,'code/'+name+'.py') +run('bit_export','vendor/export_records.py',p/'bit-source-centres.json',p/'records') +run('bit_global','code/bit_global.py','--source',p,'--local-check',p,'--out',p/'global') +run('bit_audit','code/bit_audit.py','--local-check',p,'--out',p/'global') +for name in ('bit_price','complex_integrate','complex_replay','combined'):run(name,'code/'+name+'.py') +assert snapshot()==manifest['files'],'Package modified during verification' +r=json.loads((out/'RESULT.json').read_text());expected=json.loads((ROOT/'EXPECTED.json').read_text()) +for key,value in expected.items():assert r[key]==value,(key,r[key],value) +r['verification_steps']=steps;r['phase_mode']='full replay' if a.replay_phases else 'source-bound unchanged evidence';r['manifest_sha256']=hashlib.sha256((ROOT/'MANIFEST.json').read_bytes()).hexdigest() +(out/'RESULT.json').write_text(json.dumps(r,indent=2)+'\n') +print('PASS conditional kappa',r['kappa_decimal'])