From 59f6ab86a030ba9ee26218c5e41b9c0dea0e4b23 Mon Sep 17 00:00:00 2001 From: Ali Romman <226877337+aliromman@users.noreply.github.com> Date: Sun, 25 Oct 2026 23:24:43 -0500 Subject: [PATCH 1/2] Prove one-sided connector obstruction for all full-rank star splits --- .../crossed-connector-caller/DISCOVERY.md | 84 ++ .../crossed-connector-caller/ESCAPE-WORD.json | 351 +++++ .../PAIR-CERTIFICATES.json | 1131 +++++++++++++++++ research/crossed-connector-caller/PROOF.md | 231 ++++ research/crossed-connector-caller/README.md | 86 ++ research/crossed-connector-caller/RESULT.json | 169 +++ .../crossed-connector-caller/SOURCES.json | 66 + research/crossed-connector-caller/TASK.json | 102 ++ .../crossed-connector-caller/VALIDATION.json | 17 + research/crossed-connector-caller/VERIFY.json | 32 + research/crossed-connector-caller/check.py | 286 +++++ .../discovery/RESULTS.json.gz | Bin 0 -> 63381 bytes .../discovery/aggregate_search.py | 81 ++ .../discovery/coupled_five_search.py | 57 + .../discovery/cycle_search.py | 88 ++ .../discovery/free_algebra.py | 117 ++ .../discovery/gap_search.py | 52 + .../discovery/ideal_completion.py | 70 + .../discovery/leaf_echo_search.py | 111 ++ .../discovery/m3_frame_search.py | 96 ++ .../discovery/multisplit_search.py | 67 + .../discovery/order_search.py | 56 + .../discovery/tournament_search.py | 42 + .../crossed-connector-caller/test_verify.py | 32 + .../vendor/algebra.py | 110 ++ research/crossed-connector-caller/verify.py | 62 + .../crossed-connector-caller/word_replay.py | 49 + 27 files changed, 3645 insertions(+) create mode 100644 research/crossed-connector-caller/DISCOVERY.md create mode 100644 research/crossed-connector-caller/ESCAPE-WORD.json create mode 100644 research/crossed-connector-caller/PAIR-CERTIFICATES.json create mode 100644 research/crossed-connector-caller/PROOF.md create mode 100644 research/crossed-connector-caller/README.md create mode 100644 research/crossed-connector-caller/RESULT.json create mode 100644 research/crossed-connector-caller/SOURCES.json create mode 100644 research/crossed-connector-caller/TASK.json create mode 100644 research/crossed-connector-caller/VALIDATION.json create mode 100644 research/crossed-connector-caller/VERIFY.json create mode 100644 research/crossed-connector-caller/check.py create mode 100644 research/crossed-connector-caller/discovery/RESULTS.json.gz create mode 100644 research/crossed-connector-caller/discovery/aggregate_search.py create mode 100644 research/crossed-connector-caller/discovery/coupled_five_search.py create mode 100644 research/crossed-connector-caller/discovery/cycle_search.py create mode 100644 research/crossed-connector-caller/discovery/free_algebra.py create mode 100644 research/crossed-connector-caller/discovery/gap_search.py create mode 100644 research/crossed-connector-caller/discovery/ideal_completion.py create mode 100644 research/crossed-connector-caller/discovery/leaf_echo_search.py create mode 100644 research/crossed-connector-caller/discovery/m3_frame_search.py create mode 100644 research/crossed-connector-caller/discovery/multisplit_search.py create mode 100644 research/crossed-connector-caller/discovery/order_search.py create mode 100644 research/crossed-connector-caller/discovery/tournament_search.py create mode 100644 research/crossed-connector-caller/test_verify.py create mode 100644 research/crossed-connector-caller/vendor/algebra.py create mode 100644 research/crossed-connector-caller/verify.py create mode 100644 research/crossed-connector-caller/word_replay.py diff --git a/research/crossed-connector-caller/DISCOVERY.md b/research/crossed-connector-caller/DISCOVERY.md new file mode 100644 index 0000000000..f77f550f1f --- /dev/null +++ b/research/crossed-connector-caller/DISCOVERY.md @@ -0,0 +1,84 @@ +# Discovery record + +The new theorem replaces these bounded searches. It does not derive an +unbounded claim from their counts. `discovery/RESULTS.json.gz` retains the +JSON outputs under their original file names. The archive uses fixed gzip +metadata. It is data, not instructions or a registered proof dependency. + +| Experiment | Coverage and result | +| --- | --- | +| Different C,D forward/reverse splits | All 75,600 relative orders: 71,880 degree-two and 3,720 degree-three contradictions | +| Four arbitrary minimum-rank aggregate connectors | All 3,150 relative orders: 2,995 degree-two and 155 degree-three contradictions | +| Arbitrary aggregate map in every gap | Fifteen paired-stage orders; each has a degree-three contradiction | +| Three calls per stage, arbitrary aggregate gaps | All 280 orders: 279 degree-three contradictions; word reduction gives a degree-four certificate for the remaining cyclic sweep | +| Four calls per stage | The cyclic sweep only; a bounded word-reduction certificate. This is not an order census | +| Three-way, zero-B matrix frames | 168 binary frames, 24 pair-compatible frames, 144 complete stage words; no compatible aggregate chronology found | +| Six arbitrary thin queries, three paired stages | Twenty orders; solver reports 17 unsat and 3 unknown. This first screen did not impose the separate stage-word conditions | +| Eight arbitrary thin queries | Sixty orders; 23 sat, 19 unsat, 18 unknown. Sat means necessary conditions only. The full word rejects some sat candidates | +| At most seven active queries in eight thin slots | Seventy orders; 22 unsat and 48 unknown | +| Coupled ports, five rank-two thin queries | Eight orders at three leaves: two unsat and six unknown; no positive word | +| Three-stage cycle, two thin queries | Fifty basis-parameterized orders: 42 unsat, 8 unknown. Fifty direct-projector orders: 43 unsat, 7 unknown | + +`ESCAPE-WORD.json` selects case 11 of the eight-query search. Its complete +word is checked again by the separate default checker. All fields and all +independent stage exponents are retained. Case 8 in that same search is an +example that passes first mixed coefficients but fails the full word. + +## Discovery commands + +The algebra searches use the standard library. Run them from the package +folder or give the full path. They write new JSON files beside their scripts; +the archived results remain unchanged. + +```sh +python3 -B discovery/order_search.py --degree 2 +python3 -B discovery/aggregate_search.py --degree 2 +python3 -B discovery/gap_search.py +python3 -B discovery/multisplit_search.py --splits 3 --degree 3 +python3 -B discovery/ideal_completion.py --splits 3 --degree 4 +python3 -B discovery/m3_frame_search.py +python3 -B discovery/tournament_search.py +``` + +The original degree-four dense monomial expansion was interrupted before a +result because it was too large. `ideal_completion.py` uses bounded word +reduction and literal certificate expansion instead. It produced the retained +three- and four-way cyclic-sweep certificates. It is discovery code; it is +not a general decision procedure. + +The finite matrix searches used Python 3.12.13 and `z3-solver==5.3.2.0`. +The default verifier needs neither Z3 nor the search code. The published +cycle tool uses the direct-projector parameterization; the earlier +basis-parameterized results are historical discovery data. The current +six-query tool includes stage-word constraints added after its first run. +These changes are stated so that a different replay is not treated as the +same frozen experiment. + +```sh +python3 -B discovery/leaf_echo_search.py --thin 8 --cases 60 --timeout 4000 --seed 3 +python3 -B discovery/leaf_echo_search.py --thin 8 --budget 7 --cases 70 --timeout 4000 --seed 3 +python3 -B discovery/cycle_search.py --g 3 --thin 2 --cases 50 --timeout 5000 --seed 91 +python3 -B discovery/coupled_five_search.py --cases 8 --timeout 10000 +``` + +Time limits are milliseconds per solver call. A timeout is unknown. The +solver models and timing-dependent statuses are not independent theorem +certificates. A rerun can choose a different model. Use `check.py` to verify +the frozen full positive word, rather than expect a solver to emit identical +bytes. + +## Orientation and boundaries + +Canonical main was refreshed before selection and before the aggregate and +cycle pivots. Its base was `df0137efd35e11b4445734bf612bdd4c7ebc330c`, with +selected kappa .00310045 and priority revision seven. The complete remote +overlap refresh at 03:10 UTC covered 344 PRs and 4,952 Discussion records; +7,655 local HEAD note paths were not searched by the sparse overlap scan. +Targeted historical controller notes were then read. No claim of exhaustive +novelty is made. Active P104, Cao and G20 native-word claims were kept separate. + +The scoped claim and changes are in Discussion5593, starting with +[the claim](https://github.com/CrocSwap/integer-mult-bounds/discussions/5593#discussioncomment-19187529). +PR5650 and PR5440 were comparison points, not source upgrades to the bill. +The pinned PR5599 tariff stays fixed. The stronger open BIT admission in +PR5653 does not itself supply a compatible complex caller. diff --git a/research/crossed-connector-caller/ESCAPE-WORD.json b/research/crossed-connector-caller/ESCAPE-WORD.json new file mode 100644 index 0000000000..aae71c6ad2 --- /dev/null +++ b/research/crossed-connector-caller/ESCAPE-WORD.json @@ -0,0 +1,351 @@ +{ + "source": "Finite search case11, seed3; all matrices over F2", + "scope": "Binary normalized operator only; six full calls and eight rank-one thin calls", + "case": 11, + "order": [ + 1, + 3, + 8, + 11, + 7, + 6, + 12, + 13, + 2, + 9, + 4, + 0, + 10, + 5 + ], + "status": "sat", + "calls": [ + { + "stage": 0, + "p": [ + 1, + 1, + 4, + 4, + 0, + 0, + 0, + 0 + ], + "r": [ + 5, + 5, + 5, + 5, + 0, + 0, + 0, + 0 + ] + }, + { + "stage": 0, + "p": [ + 0, + 3, + 0, + 12, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 15, + 0, + 15, + 0, + 0, + 0, + 0 + ] + }, + { + "stage": 1, + "p": [ + 0, + 3, + 0, + 0, + 0, + 48, + 0, + 0 + ], + "r": [ + 0, + 51, + 0, + 0, + 0, + 51, + 0, + 0 + ] + }, + { + "stage": 1, + "p": [ + 1, + 1, + 0, + 0, + 16, + 16, + 0, + 0 + ], + "r": [ + 17, + 17, + 0, + 0, + 17, + 17, + 0, + 0 + ] + }, + { + "stage": 2, + "p": [ + 1, + 1, + 0, + 0, + 0, + 0, + 64, + 64 + ], + "r": [ + 65, + 65, + 0, + 0, + 0, + 0, + 65, + 65 + ] + }, + { + "stage": 2, + "p": [ + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 192 + ], + "r": [ + 0, + 195, + 0, + 0, + 0, + 0, + 0, + 195 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 104, + 0, + 104, + 104, + 0, + 104, + 0 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 111, + 111, + 111, + 111, + 0, + 0, + 0, + 111 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 2, + 0, + 2, + 0, + 0, + 2, + 0, + 2 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 195, + 0, + 0, + 0, + 0, + 0, + 195 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 5, + 5, + 5, + 5, + 0, + 0, + 0, + 0 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 172, + 172, + 0, + 172, + 0, + 172, + 172 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 60, + 60, + 60, + 0, + 60, + 0, + 60, + 0 + ] + }, + { + "stage": 3, + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 249, + 249, + 0, + 249, + 0, + 249, + 0 + ] + } + ], + "choices": [ + 5, + 1, + 5 + ] +} diff --git a/research/crossed-connector-caller/PAIR-CERTIFICATES.json b/research/crossed-connector-caller/PAIR-CERTIFICATES.json new file mode 100644 index 0000000000..d67c6fe17e --- /dev/null +++ b/research/crossed-connector-caller/PAIR-CERTIFICATES.json @@ -0,0 +1,1131 @@ +[ + { + "order": [ + [ + 0, + 0 + ], + [ + 0, + 1 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 13, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 0, + 1 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 4, + [], + [ + 2 + ] + ], + [ + 8, + [], + [] + ], + [ + 8, + [], + [ + 1 + ] + ], + [ + 8, + [ + 1 + ], + [] + ], + [ + 8, + [ + 1 + ], + [ + 1 + ] + ], + [ + 13, + [], + [] + ], + [ + 13, + [], + [ + 1 + ] + ], + [ + 13, + [], + [ + 2 + ] + ], + [ + 13, + [ + 1 + ], + [] + ], + [ + 13, + [], + [ + 2, + 1 + ] + ], + [ + 14, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 0, + 1 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ], + [ + 1, + 1 + ] + ], + "terms": [ + [ + 13, + [], + [] + ], + [ + 14, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 0, + 1 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 0, + [ + 1 + ], + [] + ], + [ + 12, + [], + [] + ], + [ + 12, + [], + [ + 0 + ] + ], + [ + 13, + [], + [] + ], + [ + 13, + [], + [ + 0 + ] + ], + [ + 13, + [ + 0 + ], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 0, + 1 + ], + [ + 2, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 4, + [], + [] + ], + [ + 4, + [], + [ + 0 + ] + ], + [ + 4, + [], + [ + 2 + ] + ], + [ + 12, + [ + 1 + ], + [] + ], + [ + 13, + [], + [] + ], + [ + 13, + [], + [ + 1 + ] + ], + [ + 13, + [ + 1 + ], + [] + ], + [ + 14, + [], + [] + ], + [ + 14, + [ + 1 + ], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 0, + 1 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ], + [ + 1, + 1 + ] + ], + "terms": [ + [ + 4, + [], + [] + ], + [ + 12, + [ + 1 + ], + [] + ], + [ + 13, + [], + [ + 1 + ] + ], + [ + 14, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 0, + 1 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 12, + [], + [] + ], + [ + 13, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + 0, + 1 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 12, + [], + [] + ], + [ + 13, + [], + [] + ], + [ + 13, + [], + [ + 2 + ] + ], + [ + 13, + [ + 2 + ], + [] + ], + [ + 14, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ], + [ + 0, + 1 + ] + ], + "terms": [ + [ + 13, + [], + [] + ], + [ + 14, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 0, + 1 + ], + [ + 1, + 1 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 0, + [ + 2 + ], + [] + ], + [ + 4, + [], + [ + 0 + ] + ], + [ + 4, + [], + [ + 1 + ] + ], + [ + 4, + [], + [ + 2 + ] + ], + [ + 4, + [ + 2 + ], + [] + ], + [ + 4, + [], + [ + 0, + 1 + ] + ], + [ + 4, + [], + [ + 2, + 1 + ] + ], + [ + 8, + [], + [] + ], + [ + 8, + [ + 1 + ], + [] + ], + [ + 12, + [ + 1 + ], + [] + ], + [ + 12, + [ + 2 + ], + [] + ], + [ + 13, + [], + [] + ], + [ + 13, + [], + [ + 2 + ] + ], + [ + 13, + [ + 1 + ], + [] + ], + [ + 13, + [ + 2 + ], + [] + ], + [ + 13, + [ + 1 + ], + [ + 1 + ] + ], + [ + 14, + [], + [] + ], + [ + 14, + [], + [ + 0 + ] + ], + [ + 14, + [], + [ + 1 + ] + ], + [ + 14, + [], + [ + 2 + ] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 0, + 1 + ], + [ + 2, + 1 + ], + [ + 1, + 1 + ] + ], + "terms": [ + [ + 0, + [ + 2 + ], + [] + ], + [ + 12, + [], + [] + ], + [ + 12, + [], + [ + 0 + ] + ], + [ + 13, + [ + 0 + ], + [] + ], + [ + 14, + [], + [] + ], + [ + 14, + [], + [ + 0 + ] + ], + [ + 14, + [ + 0 + ], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 1, + 1 + ], + [ + 0, + 1 + ], + [ + 2, + 1 + ] + ], + "terms": [ + [ + 4, + [], + [ + 2 + ] + ], + [ + 4, + [], + [ + 2, + 2 + ] + ], + [ + 8, + [], + [] + ], + [ + 8, + [], + [ + 0 + ] + ], + [ + 8, + [], + [ + 1 + ] + ], + [ + 8, + [ + 1 + ], + [] + ], + [ + 8, + [ + 1 + ], + [ + 0 + ] + ], + [ + 8, + [ + 1 + ], + [ + 1 + ] + ], + [ + 12, + [], + [] + ], + [ + 12, + [], + [ + 0 + ] + ], + [ + 12, + [], + [ + 1 + ] + ], + [ + 12, + [ + 1 + ], + [] + ], + [ + 13, + [], + [ + 0 + ] + ], + [ + 13, + [], + [ + 1 + ] + ], + [ + 13, + [], + [ + 2 + ] + ], + [ + 13, + [ + 1 + ], + [] + ], + [ + 13, + [], + [ + 2, + 0 + ] + ], + [ + 13, + [], + [ + 2, + 1 + ] + ], + [ + 13, + [ + 1 + ], + [ + 2 + ] + ], + [ + 14, + [], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 1, + 1 + ], + [ + 2, + 1 + ], + [ + 0, + 1 + ] + ], + "terms": [ + [ + 4, + [], + [ + 2 + ] + ], + [ + 4, + [ + 2 + ], + [] + ], + [ + 13, + [], + [] + ], + [ + 13, + [], + [ + 1 + ] + ], + [ + 13, + [ + 1 + ], + [] + ], + [ + 14, + [], + [] + ], + [ + 14, + [], + [ + 1 + ] + ], + [ + 14, + [ + 1 + ], + [] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ], + [ + 0, + 1 + ], + [ + 1, + 1 + ] + ], + "terms": [ + [ + 0, + [], + [] + ], + [ + 4, + [], + [] + ], + [ + 12, + [], + [] + ], + [ + 13, + [], + [] + ], + [ + 14, + [], + [ + 0 + ] + ], + [ + 14, + [], + [ + 1 + ] + ] + ] + }, + { + "order": [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 2, + 1 + ], + [ + 1, + 1 + ], + [ + 0, + 1 + ] + ], + "terms": [ + [ + 13, + [], + [] + ], + [ + 14, + [], + [] + ] + ] + } +] diff --git a/research/crossed-connector-caller/PROOF.md b/research/crossed-connector-caller/PROOF.md new file mode 100644 index 0000000000..e3800fbcf1 --- /dev/null +++ b/research/crossed-connector-caller/PROOF.md @@ -0,0 +1,231 @@ +# A connector must distinguish leaves in both directions + +This is a theorem about finite matrices in characteristic two. It is not a +native multiplication theorem. No new kappa is established. + +## 1. Contract + +Let the main space be `W_0 + W_1 + ... + W_g`, with each block of dimension +`d > 0`. Block zero is the core. Stage j acts on the core and leaf j. On these +two blocks put + +```text +E_j = diag(I,I), T_j = [[I,I],[I,I]]. +``` + +Thus `T_j^2=0`. Stage j can have any finite number of full calls. Their +projectors `P_jh` form an orthogonal resolution of `E_j`, and commute with +`T_j`. Their query maps are `R_jh=P_jh T_j`. There is no bound on the number +of stages, the number of splits, the block dimension, or their call order. + +In the normalized ring `F[e,D_1,...,D_g]/(e^2)`, a full call is + +```text +(I+(D_j+1)P_jh)(I+e R_jh). +``` + +A thin call is `I+e Z`. The proof permits arbitrary matrices Z. In particular, +it does not impose a rank, a square-zero condition, or a count on thin calls. +The required word is `Q product_j (I+(D_j+1)E_j)`, where `Q=1+e`. +The main fields are independent. All D variables remain independent. + +This is the star stage contract from PR5631/5649, with arbitrary stage splits +and a much larger connector class. It excludes no general complex or dyadic +caller. It also excludes no caller with a different grouped stage map, a +nonfull stage, a different output, or paid idle multipliers. + +## 2. The one-sided theorem + +**Theorem.** A successful word cannot have three distinct leaves whose block +columns are identical in every thin matrix Z. It also cannot have three +leaves whose block rows are identical in every thin matrix Z. + +Only one of these two equalities is needed for exclusion. Thus changing the +forward split, adding more queries, increasing their rank, or adding more +stage splits cannot repair connectors which only see the sum of the leaves. + +### Local form and chronology + +Commutation with T and the local support give + +```text +P_jh = [[A_jh+B_jh, B_jh], [B_jh, A_jh+B_jh]], +R_jh = [[A_jh, A_jh], [A_jh, A_jh]]. +``` + +The A matrices form an orthogonal resolution of I. In particular, +`A_jh A_jk=0` for `h!=k`, `A_jh^2=A_jh`, and `sum_h A_jh=I`. +These statements do not require the A matrices of different stages to commute. +The orthogonal-resolution hypothesis also follows from full rank use: if the +projectors sum to E and their ranks sum to rank E, their images form a direct +sum. Each projector is then the corresponding coordinate projection on that +sum. Stages with a rank deficit are a different contract. + +Set all D variables to one. The coefficient of e requires `sum R=I`, including +thin queries. The mixed coefficient of `e(D_j+1)` then requires + +```text +sum_(full call i in stage j) [P_i, sum_(calls l later than i) R_l] = 0. (1) +``` + +This necessary condition follows by expanding the literal ordered word. +No full-word converse is used. + +For distinct selected stages j,k define + +```text +S_jk = sum_(call (j,h) before call (k,l)) A_jh A_kl. (2) +``` + +In (1), add block rows zero and j, and read block column k. The contribution +of good calls is S_jk. The contribution of a later thin map Z is +`A_jh (Z_0k+Z_jk)`. If the three selected leaf columns of every Z are equal, +this thin contribution is the same for the two choices of k other than j. +Consequently + +```text +S_jk = S_jl for each permutation (j,k,l) of the three stages. (3) +``` + +Other good stages do not contribute to these blocks. Thus the argument +restricts to any three selected leaves in a larger star. + +### The prefix determinant argument + +Read just the calls of the three selected stages in their original order. +Before a call with projection A from stage j, let P_k be the sum of the A +projections already read from stage k. Left multiplication of (2) by A and +orthogonality within stage j give + +```text +A S_jk = A(I+P_k). +``` + +Equation (3) gives `A P_k=A P_l`. Also `A P_j=0`. Therefore, for the total +prefix `S=P_0+P_1+P_2`, every update satisfies + +```text +A S=0. (4) +``` + +Introduce an independent central variable x. Equation (4) implies + +```text +(I+xA)(I+xS) = I+x(S+A). +``` + +Starting at S=0, the product of all these factors is `I+xS_final`. +At the end, `S_final=I+I+I=I`. On the other hand, an idempotent of rank r +has determinant `det(I+xA)=(1+x)^r`. Each stage is a resolution of I, +so its ranks sum to d. Taking determinants now gives + +```text +(1+x)^(3d) = det(product(I+xA)) = det((1+x)I) = (1+x)^d. +``` + +This is impossible for positive d. This proves the column statement for +all finite dimensions and all finite split counts. It uses no list of orders. +Transpose all matrices and reverse the order to obtain the row statement. + +## 3. A paid-rank and finite-field cut + +Assume g is at least three. The sum of the good queries is +`sum T_j`. Hence the thin sum must be + +```text +K = I+sum T_j = epsilon E_core + F+G, +epsilon = (g+1) mod 2, +F: each leaf -> core by I, G: core -> each leaf by I. +``` + +The rank of K is `2d`. Its column space is the core plus the diagonal leaf +space, and its row space is the core plus the leaf-sum space. + +Let U be the span of all thin images, and V the span of all thin row spaces. +Write `dim U=2d+a`, `dim V=2d+b`, and let R be the sum of thin ranks. +Factor each thin map at its actual rank, then concatenate those factors. +Sylvester's rank inequality gives + +```text +R >= dim U + dim V - rank K = 2d+a+b. (5) +``` + +Both a and b must be positive. Otherwise one side of the one-sided theorem +applies to all leaves. In particular **R >= 2d+2**, over any field of +characteristic two. + +For a finite field of size s, choose b additional row basis vectors beyond +the row space of K. Their restriction to one leaf is a `b by d` matrix. +There are at most `s^(bd)` such signatures. Equal signatures imply equal +leaf columns for every thin map. Each signature can occur at most twice. +The column-space argument is the same. Therefore + +```text +g <= 2 s^(bd), g <= 2 s^(ad), +R >= 2d + 2 h, h = min {z >= 0 : g <= 2 s^(dz)}. (6) +``` + +This is a necessary condition, not a construction or a sufficient test. +It concerns a common field and a fixed block basis. For one-port binary +copies, d=2. It gives R>=6 for g=3..8, R>=8 for g=9..32, and R>=10 for +g=33..128. For coupled ports, use the actual larger d. Do not apply the +one-port bound per port after ports have been coupled. + +At g=31, five rank-one connectors fail this cut. Five rank-two connectors +with d=4 meet it exactly: `2d+2=10`. Thus coupled pairs of ports are a precise +remaining target. The cut does not prove that such a word exists. + +## 4. Constructive escape and its price + +`ESCAPE-WORD.json` contains a complete eight-field binary word. It has three +paired stages, six full calls with rank-one queries, and eight rank-one thin calls. +Every local projector, query rank and compatibility relation is checked. +The verifier retains every exponent of each independent D variable and +checks every coefficient of the full word. It also checks that the thin +maps distinguish all three leaves in both directions. + +Thus the changed connector contract has a real positive operator. It does +not give a profitable supplier. At the pinned PR5599 tariff, 104 copies have +complete optimistic moment coefficients + +```text +208 H25 + 624 H9 + 6 helpers - 6 paid - 832 H1. +``` + +Its linear margin is -336. After common ranks are cancelled, all positive +terms have rank at least eight and all negative terms have rank at most +seven. For every `0<=t<=1`, the margin is at most `8^(t-1)*(-336)<0`. +Additional physical adapters cannot repair that price. + +The new cut still leaves a useful target. At g=127, ten thin queries are +allowed by (6) for one-port binary copies. The optimistic PR5599 profile +has a positive exact margin at saving `7/2000=.0035`, and its numerical +crossing is about .00364156. **No 127-leaf word is supplied.** This screen +also does not establish a characteristic-zero lift, native frame adapters, +compiler admission, an outer transfer, or a new kappa. + +A smaller coupled target is g=31 with five rank-two connectors per two-port +block. Its optimistic bill, scaled to 104 ports, also has positive exact +margin at .0035. It needs only 62 full calls. No such word is supplied either. +Coupling physical ports can require new frame maps; their costs must be +charged before this screen can become a supplier claim. + +## 5. Evidence and limits + +The main result is a written finite-dimensional matrix proof. The checker +also verifies fifteen exact free-algebra certificates for the paired-stage +case, without a solver or the discovery implementation. Matrix and formal +polynomial controls test the chronology extraction, restriction to three +leaves, prefix factorization and determinant formula. They support the +proof; finite tests alone do not prove its unbounded statements. + +The discovery archive retains changed C,D splits, arbitrary aggregate maps, +extra thin queries, a different cycle frame, and three-/four-way splits. +Timeouts remain unknown. Passing first mixed coefficients is not passing the +full word. No proof assistant or independent human acceptance is claimed. + +Credit Cinna Davis's controller and simplex work; PR5617/5631/5649 for the +query-frame and fixed-star line; and the complete P104/native/helper/compiler +lineage for the tariff. This proof, cut, search and escape word were prepared +for Ali Romman with substantial OpenAI Codex assistance. No subagents. +New work is Apache-2.0. diff --git a/research/crossed-connector-caller/README.md b/research/crossed-connector-caller/README.md new file mode 100644 index 0000000000..64eb1d580e --- /dev/null +++ b/research/crossed-connector-caller/README.md @@ -0,0 +1,86 @@ +# One-sided connector obstruction, rank cuts, and a complete escape word + +**No new kappa.** The new result is an unbounded obstruction with a short +proof, an explicit positive word outside it, and a precise search target +whose optimistic price remains favorable. + +In the full-rank star stage contract, no three leaves can have identical +columns in every thin connector. The same statement holds for rows. This +covers every finite port dimension, every finite number of orthogonal stage +splits, every call order, and any number or rank of connector queries. It +strictly extends [PR5649](https://github.com/CrocSwap/integer-mult-bounds/pull/5649), +which kept four prescribed connectors and two calls per stage. + +[PROOF.md](PROOF.md) replaces the order census by a prefix identity. The +forbidden chronology would make a matrix product have both determinants +`(1+x)^(3d)` and `(1+x)^d`. It also gives a rank and signature cut for arbitrary +connectors. For one-port binary copies, 127 leaves require at least ten thin +queries. Coupled ports must use their actual block dimension in this cut. + +[ESCAPE-WORD.json](ESCAPE-WORD.json) is a real binary escape: eight fields, +six full calls, eight thin queries, and sixteen exact coefficients in the +complete polynomial endpoint. Its connectors distinguish individual leaves. +The proof prices it and rejects every concave moment at the pinned P104 +bill. The separate 127-leaf, ten-query profile has an exact positive price +margin at saving .0035, but **has no operator**. A smaller target with 31 +leaves and five rank-two connectors also passes that price test. The new +cut permits its coupled-port budget and rejects the corresponding one-port +budget. Both are search targets. + +The cycle-frame and smaller-connector searches remain incomplete. Their +solver timeouts are retained as unknown. [DISCOVERY.md](DISCOVERY.md) records +what was searched and which positive candidates failed higher coefficients. +It also gives commands for the saved discovery tools and archive. + +## Reproduce + +Python 3.12 and the standard library suffice for the read-only checks. The +registered metadata check also needs the explicitly pinned PR5649 Git object. +In a fresh clone, fetch that provenance object first: + +```sh +git fetch https://github.com/CrocSwap/integer-mult-bounds.git 0c27282f56a0e8ec6c1fbad0f2ccca646d0d8442 +python3.12 -B scripts/research_package.py --package research/crossed-connector-caller +python3.12 -I -O -B research/crossed-connector-caller/verify.py +python3.12 -I -O -B research/crossed-connector-caller/test_verify.py +``` + +Expected status: `PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION`. +[RESULT.json](RESULT.json) records the exact evidence. The independent checker +uses no solver or discovery module. It checks fifteen paired-order identities, +the full positive word, coupled chronology controls, the prefix factorization, +rank cuts, exact integer-power price intervals, and corruptions. + +The general theorem is a written matrix proof. Finite controls support it; +they do not constitute proof-assistant or independent human acceptance. The +binary word does not establish a characteristic-zero lift, native frame +adapters, ownership, a complete compiler, or a new outer bound. Selected +kappa remains .00310045 at the pinned base. This package changes no frontier. + +## Open next questions + +- Construct a long word whose connectors have distinct leaf signatures in + both directions. Start with 31 leaves and five rank-two queries per coupled + port pair, or 127 leaves and ten rank-one queries per binary copy. Both + optimistic prices pass at .0035. Begin with the saved + eight-field word and test the full polynomial endpoint after each extension. +- Solve or certify the remaining finite searches. Seven thin queries at three + leaves and the separate cycle frame have timeout cases. First use exact + certificates or longer bounded solves on those saved cases. A timeout is + not an obstruction. +- Give a native lift and complete invoice for any profitable binary word. + Charge every adapter, helper, query, copy, clear, return and route. The + current P104 tariff is only an optimistic comparison for this algebra. + +Structured versions are in [TASK.json](TASK.json). Work began on canonical +main `df0137efd35e11b4445734bf612bdd4c7ebc330c`, priority revision seven. +The canonical investigation is [Discussion5593](https://github.com/CrocSwap/integer-mult-bounds/discussions/5593). +The live remote overlap check covered 344 open PRs and 4,952 Discussion +records; the sparse local notes were incomplete. Active native-word claims +were kept separate. [SOURCES.json](SOURCES.json) records exact source pins. + +Credit Cinna Davis's controller/simplex work; PR5617/5631/5649 for the +query-frame and fixed-star work; and all retained P104, native, helper, +compiler and outer contributors. The vendored discovery alphabet retains +Cinna Davis's notice. Prepared for Ali Romman with substantial OpenAI Codex +assistance; no subagents. Apache-2.0. diff --git a/research/crossed-connector-caller/RESULT.json b/research/crossed-connector-caller/RESULT.json new file mode 100644 index 0000000000..3fbb19095a --- /dev/null +++ b/research/crossed-connector-caller/RESULT.json @@ -0,0 +1,169 @@ +{ + "authenticated_inputs": 1, + "controls": { + "chronology": { + "coupled_frames": 6, + "literal_mixed_coefficients": 18, + "one_sided_nonaggregate_frames": 6, + "prefix_equations": 84 + }, + "escape": { + "deleted_query_rejected": true, + "distinct_leaf_column_signatures": 3, + "distinct_leaf_row_signatures": 3, + "fields": 8, + "full_calls": 6, + "full_polynomial_coefficients": 16, + "moved_call_rejected": true, + "thin_queries": 8 + }, + "paired_certificates": { + "deleted_term_rejected": true, + "maximum_degree": 4, + "orders": 15, + "terms": 105 + }, + "prefix": { + "matrix_flags": 60, + "prefix_updates": 180, + "projection_determinants": 60, + "restarted_walks_rejected": 60 + }, + "rank_cut_cases": [ + { + "d": 2, + "field_size": 2, + "g": 3, + "thin_rank_lower_bound": 6 + }, + { + "d": 2, + "field_size": 2, + "g": 4, + "thin_rank_lower_bound": 6 + }, + { + "d": 2, + "field_size": 2, + "g": 7, + "thin_rank_lower_bound": 6 + }, + { + "d": 2, + "field_size": 2, + "g": 8, + "thin_rank_lower_bound": 6 + }, + { + "d": 2, + "field_size": 2, + "g": 9, + "thin_rank_lower_bound": 8 + }, + { + "d": 2, + "field_size": 2, + "g": 31, + "thin_rank_lower_bound": 8 + }, + { + "d": 2, + "field_size": 2, + "g": 32, + "thin_rank_lower_bound": 8 + }, + { + "d": 2, + "field_size": 2, + "g": 33, + "thin_rank_lower_bound": 10 + }, + { + "d": 2, + "field_size": 2, + "g": 63, + "thin_rank_lower_bound": 10 + }, + { + "d": 2, + "field_size": 2, + "g": 127, + "thin_rank_lower_bound": 10 + }, + { + "d": 2, + "field_size": 2, + "g": 128, + "thin_rank_lower_bound": 10 + }, + { + "d": 2, + "field_size": 2, + "g": 129, + "thin_rank_lower_bound": 12 + }, + { + "d": 2, + "field_size": 2, + "g": 255, + "thin_rank_lower_bound": 12 + } + ] + }, + "limits": [ + "No kappa increase", + "The full escape word is binary algebra, not a physical native caller", + "The 127-leaf price profile has no operator", + "No proof-assistant or independent human acceptance" + ], + "pricing": { + "escape": { + "all_concave_moments_rejected": true, + "g": 3, + "linear_margin": -336, + "q": 104, + "signed_profile": { + "1": -14038, + "2": -2724, + "25": 208, + "3": -2958, + "4": -18, + "5": -942, + "6": -108, + "7": -54, + "8": 96, + "9": 3096 + }, + "thin_queries_per_copy": 8 + }, + "pinned_supplier": "PR5599 09dd0965711ca7eeb169057a420abab1c9052137", + "unconstructed_candidates": [ + { + "full_calls": 254, + "g": 127, + "moment_denominator": "1099511627776", + "moment_lower_numerator": "481572756146950", + "moment_upper_numerator": "481572756570322", + "ports_per_binary_block": 1, + "q": 104, + "saving": "7/2000", + "status": "POSITIVE_OPTIMISTIC_PRICE_ONLY; NO CALLER OR KAPPA CLAIM", + "thin_queries_per_native_port": 10 + }, + { + "full_calls": 62, + "g": 31, + "moment_denominator": "1099511627776", + "moment_lower_numerator": "268079792788678", + "moment_upper_numerator": "268079792892178", + "ports_per_binary_block": 2, + "q": 104, + "saving": "7/2000", + "status": "POSITIVE_OPTIMISTIC_PRICE_ONLY; NO CALLER OR KAPPA CLAIM", + "thin_queries_per_native_port": 5 + } + ] + }, + "scope": "Finite matrices over every characteristic-two field; any finite star stage splits and call order; one-sided equal leaf signatures", + "status": "PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION" +} diff --git a/research/crossed-connector-caller/SOURCES.json b/research/crossed-connector-caller/SOURCES.json new file mode 100644 index 0000000000..3bc934f537 --- /dev/null +++ b/research/crossed-connector-caller/SOURCES.json @@ -0,0 +1,66 @@ +{ + "schema_version": 1, + "base_commit": "df0137efd35e11b4445734bf612bdd4c7ebc330c", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "581f8d87008354eb5b869f7ed9de1317ad837ce8", + "sha256": "2a0220e866417774606e0f991e41b9c1d26b1f43b97857238cf478dbc7d330b5" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "f126dd2e2dad2b669e75d1d0d0bd05c600725602", + "sha256": "f7a48bfa2659b88378282a8eee7d9fe52cdf505594124c4d1686b58510fffd72" + }, + { + "path": "research/p104-helper-subspace-splits/RESULT.json", + "usage": "input", + "git_blob": "35f75c8555193c6e845cd52cc562ca23fd5924cb", + "sha256": "1d92e587915052110dfb3aca8890df5afdaf496164efa5a4a52e69ceeb3c70f3" + }, + { + "path": "research/productive-controller-basis-search/algebra.py", + "usage": "provenance", + "pin": "head:df0137efd35e11b4445734bf612bdd4c7ebc330c:research/productive-controller-basis-search/algebra.py", + "git_blob": "2f0d4f290c280cfdfc17714009a2ae0f220556d4", + "sha256": "ab85b113cd70e20c38f6b0c0e0501876b751206bcd2a7ea5a61054ce3b92f2b2" + }, + { + "path": "research/productive-controller-basis-search/GLOBAL-PROOF.md", + "usage": "provenance", + "pin": "head:df0137efd35e11b4445734bf612bdd4c7ebc330c:research/productive-controller-basis-search/GLOBAL-PROOF.md", + "git_blob": "74b67e22e6c063193a83825207cdec19a8fef7a4", + "sha256": "adc377b13924701bf5b0b50b091d8b69c90195d50ce0f6808f7fb4c7e0b16457" + }, + { + "path": "research/longer-coupled-port-caller/PROOF.md", + "usage": "provenance", + "pin": "head:0c27282f56a0e8ec6c1fbad0f2ccca646d0d8442:research/longer-coupled-port-caller/PROOF.md", + "git_blob": "7df31b1dac06fe966f190bcc0798dc9bba77eeb0", + "sha256": "b9784e6ab84e55ab13c44834a54c29d12a51aaae5c91ae2e4fc7fbfd24999f5d" + }, + { + "path": "research/longer-coupled-port-caller/nc_star.py", + "usage": "provenance", + "pin": "head:0c27282f56a0e8ec6c1fbad0f2ccca646d0d8442:research/longer-coupled-port-caller/nc_star.py", + "git_blob": "f9eb610002a9c28e0829c5755671f0824d035442", + "sha256": "d4f16d6800633143888d26d5e12be5f086f6d92e255883c287fe32da098840a4" + }, + { + "path": "research/longer-coupled-port-caller/search_orders.py", + "usage": "provenance", + "pin": "head:0c27282f56a0e8ec6c1fbad0f2ccca646d0d8442:research/longer-coupled-port-caller/search_orders.py", + "git_blob": "afbdb06c552d61c61e4a7a08c4a68fb1faa0a3e3", + "sha256": "f54fb7da58a790c2df61835e45d41780e3b80bf66685c2073d7c5da2a00eb573" + }, + { + "path": "research/longer-coupled-port-caller/search_star.py", + "usage": "provenance", + "pin": "head:0c27282f56a0e8ec6c1fbad0f2ccca646d0d8442:research/longer-coupled-port-caller/search_star.py", + "git_blob": "3091607d92bbbd2716a662af33929f7dd12b1827", + "sha256": "e5d0b0d335a7153438685f8a89373cfd035b4d4189e45a036915474b903cbb66" + } + ] +} diff --git a/research/crossed-connector-caller/TASK.json b/research/crossed-connector-caller/TASK.json new file mode 100644 index 0000000000..ff538aef83 --- /dev/null +++ b/research/crossed-connector-caller/TASK.json @@ -0,0 +1,102 @@ +{ + "schema_version": 1, + "task_id": "joint-query-controller", + "priority_revision": 7, + "base_commit": "df0137efd35e11b4445734bf612bdd4c7ebc330c", + "original_card": { + "id": "joint-query-controller", + "question": "Can the installed QQ16 caller win a complete matched protocol bill, or can a changed demand eliminate actual paid work?", + "starting_points": [ + "docs/research/research-family-status.md", + "certificates/selected-result.json", + "research/qq16-caller-install/README.md" + ], + "methods": [ + "Derive the matched whole-caller physical bill for installed and baseline protocols.", + "Change the actual demanded observations and prove a cheaper legal producer/consumer contract." + ], + "acceptance_gate": "Name the changed premise of the fixed F0/B1 observation obstruction. Show exactly which query is recovered, legal native reads and restoration, and a full favorable budget including cover maps, helpers and endpoints. Local inverse identities alone do not close the global controller. A scoped local result may be retained without a complete supplier. Expanding it into further construction rounds requires the family-level budget and obligation gate in research-family-status.md; an optimistic passing relaxation alone is not acceptance.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read #4166 COST.md and ADMISSION.json. An actual caller connection is now proposed. Its native-component profile loses; parent park/restore versus external-call costs remain unresolved. Retain the producer and recovery lineage rather than rebuild it.", + "scope": "Source-binding orientation only; no scientific replay, theorem acceptance or supplier admission. Budget any heavy replay separately." + }, + "first_experiment": "At the actual installed cut, compare matched complete parent park/restore and external input/return protocols at the same bank/packet geometry, including every later root call and service cost. Alternatively pin both bridge observations and derive a genuinely smaller source-compatible demand. Stop if the complete necessary inequality fails or an essential cost is unknown; no larger decoder scan from a local tape-action saving.", + "bottleneck_link": "The native local words exist; retained query information and its physical access are the missing link to a composed recursive interface.", + "allowed_variations": [ + "One paid query, one changed first pair, or one precisely specified affine helper state.", + "A counterexample or lower bound for that exact proposed repair.", + "One unresolved obligation of a newer local decoder, with exact source heads and a distinct claim/domain." + ], + "scope_change_triggers": [ + "Retaining the fixed first pair and ordinary schedule while allowing only homogeneous selected-only control, already excluded by the witness.", + "Treating cover-map counts as zero-cost physical address operations.", + "Recreating the pending complete local decoder or early-record/output-bank coalescing already under investigation without a distinct audit or changed premise.", + "Treating a completed-output defect inequality as a producer-interior, dirty-range or physical-cost certificate.", + "Recreating completed-output recovery or caller wiring already supplied by #4166 without new independent coverage.", + "Dropping retained later root calls or claiming native-profile dominance from the isolated publication saving." + ], + "overlap_terms": [ + "QQ16", + "joint-query", + "changing-chart controller", + "selected observation", + "1969", + "2540", + "early record", + "output-bank retention", + "complete native decoder", + "2965", + "producer defect", + "dirty-helper range", + "F17 consumer", + "4166", + "qq16-caller-install" + ], + "existing_checks": [ + { + "scope": "PR #4166: author-checked installed producer/service/return/bridge connection; native-component comparison loses.", + "evidence": "research/qq16-caller-install/README.md", + "remaining": "Complete matched physical protocol bill, or changed source-compatible demand/circuit; no affordable supplier yet.", + "status": "author-checked", + "source_commit": "0b082d22a0e9a442d264ab0633e35ef26c790630", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + } + ] + }, + "scope_status": "changed", + "actual_scope": "One-sided connector obstruction for all finite full-rank star splits; paid-rank signature cuts; a complete binary escape word; different-frame discovery searches", + "scope_change_reason": "The user requests a changed connector or query frame. Four prescribed connectors were replaced by arbitrary one-sided connectors, then by leaf-specific queries and a cycle frame. The theorem now uses a prefix determinant argument and no order census.", + "bottleneck_link": "A different connector can retain useful full-call stages while using cheap thin queries; success requires a complete endpoint and paid bill.", + "budget_minutes": 120, + "stop_rule": "Complete and verify the unbounded theorem and real escape word. Do not claim a kappa increase from a price screen or an incomplete search.", + "outcome": "completed", + "evidence": "PROOF.md, ESCAPE-WORD.json, RESULT.json, PAIR-CERTIFICATES.json, DISCOVERY.md", + "author": "Ali Romman with substantial OpenAI Codex assistance", + "ai_assistance": "Substantial OpenAI Codex assistance; no subagents.", + "open_questions": [ + { + "question": "Can 31 leaves use five rank-two thin queries per coupled port pair, or can 127 leaves use ten rank-one thin queries?", + "why_it_matters": "The new signature cut permits this profile and its optimistic P104 price passes at saving .0035.", + "first_step": "Use the new rank/signature cut and the saved coupled-five and full-word tools. Check the full endpoint after each finite extension.", + "blocked_by": "No such long word is known; signatures and price alone do not construct it." + }, + { + "question": "Do the remaining seven-query and cycle-frame cases have solutions?", + "why_it_matters": "These change the excluded contract and could guide a longer caller.", + "first_step": "Use the archived orders for longer bounded solves or exact contradiction certificates.", + "blocked_by": "The saved solver timeouts are unknown, not negative proofs." + }, + { + "question": "Can a profitable binary word be lifted to the actual native supplier?", + "why_it_matters": "Only a full physical bill and admitted outer transfer can improve kappa.", + "first_step": "Compile native maps, frame adapters, ownership and returns before pricing the complete caller.", + "blocked_by": "No profitable binary word or native lift is supplied by this package." + } + ] +} diff --git a/research/crossed-connector-caller/VALIDATION.json b/research/crossed-connector-caller/VALIDATION.json new file mode 100644 index 0000000000..fa1b6e8fbc --- /dev/null +++ b/research/crossed-connector-caller/VALIDATION.json @@ -0,0 +1,17 @@ +{ + "python": "3.12.13 (main, May 10 2026, 19:20:41) [Clang 22.1.3 ]", + "platform": "macOS-26.6.1-arm64-arm-64bit", + "base": "df0137efd35e11b4445734bf612bdd4c7ebc330c", + "registered": "PASS_REGISTERED_RESEARCH_PACKAGE outcome=completed", + "optimized": "PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION", + "mutations": 4, + "git_free_read_only": { + "path": "/var/folders/ph/5swjdlqd3997q5j1y6zvmty80000gp/T/imb-one-sided-gitfree-vl4q8ns3", + "cwd": "/", + "PATH": "/nonexistent", + "status": "PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION" + }, + "source_history": "Not run: PR5649 is an explicitly pinned open provenance source, not an ancestor of the new main base.", + "hosted_ci": "Not yet submitted", + "independent_human_review": "Not claimed" +} diff --git a/research/crossed-connector-caller/VERIFY.json b/research/crossed-connector-caller/VERIFY.json new file mode 100644 index 0000000000..90f5cf0861 --- /dev/null +++ b/research/crossed-connector-caller/VERIFY.json @@ -0,0 +1,32 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/p104-helper-subspace-splits/RESULT.json" + ], + "commands": [ + { + "argv": [ + "{python}", + "-I", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 60, + "checks": "Source authentication, full escape word, projected chronology, prefix determinant controls, exact pair certificates, rank cuts and integer-power pricing" + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-B", + "{package}/test_verify.py" + ], + "timeout_seconds": 60, + "checks": "Reject changed certificate, query, source bill and result receipt" + } + ] +} diff --git a/research/crossed-connector-caller/check.py b/research/crossed-connector-caller/check.py new file mode 100644 index 0000000000..6c6986643d --- /dev/null +++ b/research/crossed-connector-caller/check.py @@ -0,0 +1,286 @@ +"""Independent exact checks for the connector theorem and escape word. + +The default replay uses no search program, solver, or predecessor code. +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import itertools +import json +from pathlib import Path +import random + +PACKAGE=Path(__file__).resolve().parent + +def require(value,message): + if not value:raise ValueError(message) + +def eye(n):return tuple(1<>k&1)*(b[k]>>j&1) for k in range(len(b)))%2)<>j&1);rows[j],rows[p]=rows[p],rows[j] + for i in range(n): + if i!=j and rows[i]>>j&1:rows[i]^=rows[j] + return tuple(row>>n for row in rows) + +def product(a,b): + n=len(next(iter(a.values())));out={} + for x,ax in a.items(): + for y,by in b.items(): + if x[0]+y[0]>1:continue + key=tuple(u+v for u,v in zip(x,y));out[key]=add(out.get(key,zero(n)),mul(ax,by)) + return {k:v for k,v in out.items() if any(v)} + +def replay(calls,order,g): + n=len(calls[0]['p']);base=(0,)*(g+1);ebit=(1,)+(0,)*g + word={base:eye(n)};expected={base:eye(n),ebit:eye(n)};targets=[zero(n) for _ in range(g)] + for c in calls: + if c['stage']>j)&1 for i in range(n) for j in block) for c in thin)) + rows.append(tuple(tuple(c['r'][i] for i in block) for c in thin)) + require(len(set(columns))==3 and len(set(rows))==3,'The word must leave both equal-signature classes') + return {'fields':n,'full_calls':6,'thin_queries':8,'full_polynomial_coefficients':len(word),'deleted_query_rejected':True,'moved_call_rejected':True,'distinct_leaf_column_signatures':3,'distinct_leaf_row_signatures':3} + +# Polynomials in three free, noncommuting variables over F2. +ONE=frozenset(((),));Z=frozenset() +def times(a,b): + result=set() + for x in a: + for y in b: + w=x+y + if w in result:result.remove(w) + else:result.add(w) + return frozenset(result) + +def pair_equations(order): + projections=[(frozenset(((j,),)),ONE^frozenset(((j,),))) for j in range(3)];eq=[] + for j in range(3): + for h,k in itertools.product(range(2),repeat=2): + p=times(projections[j][h],projections[j][k])^(projections[j][h] if h==k else Z) + if p:eq.append(p) + ordered={} + for j,k in itertools.permutations(range(3),2): + p=Z + for pos,(c,h) in enumerate(order): + if c!=j:continue + for d,l in order[pos+1:]: + if d==k:p^=times(projections[j][h],projections[k][l]) + ordered[j,k]=p + for j in range(3): + k,l=[x for x in range(3) if x!=j];eq.append(ordered[j,k]^ordered[j,l]) + return eq + +def orders(): + result=[] + for word in sorted(set(itertools.permutations((0,0,1,1,2,2)))): + if not word.index(0)>=1;a<<=1 + return out + +def determinant_polynomial(matrix): + n=len(matrix);out=0 + for permutation in itertools.permutations(range(n)): + value=1 + for i,j in enumerate(permutation):value=scalar_multiply(value,matrix[i][j]) + out^=value + return out + +def prefix_controls(): + checked=0;updates=0;rejections=0;rng=random.Random(20261026) + for n in (2,3,4): + for trial in range(20): + change=list(eye(n)) + for _ in range(5*n): + i,j=rng.sample(range(n),2);change[i]^=change[j] + change=tuple(change);back=inverse(change) + flags=[mul(mul(change,tuple(1<>j)&1)<<1) for j in range(n)] for i in range(n)]) + expected=1 + for _ in range(n):expected=scalar_multiply(expected,3) + require(determinant==expected,'Projection determinant');checked+=1 + require(mul(flags[0],prefix)!=zero(n),'A completed resolution cannot restart this prefix walk');rejections+=1 + return {'matrix_flags':checked,'prefix_updates':updates,'projection_determinants':checked,'restarted_walks_rejected':rejections} + +def rank_cut(g,d,field_size): + require(g>=3 and d>=1 and field_size>=2 and field_size&(field_size-1)==0,'Rank-cut parameters');h=0 + while 2*field_size**(d*h)=g and (h==0 or 2*2**(2*(h-1))>(col*d))&((1<0,'One-sided connector must fail a necessary equation') + z=calls[-2]['r'];one_sided+=block(z,1,0,d)!=block(z,2,0,d);cases+=1 + require(one_sided>0,'Controls must leave the old two-sided aggregate contract') + return {'coupled_frames':cases,'literal_mixed_coefficients':coefficient_checks,'prefix_equations':prefix_checks,'one_sided_nonaggregate_frames':one_sided} + + +def run(): + return {'escape':escape(),'paired_certificates':certificates(),'prefix':prefix_controls(),'rank_cut_cases':rank_controls(),'chronology':chronology_controls()} + +if __name__=='__main__':print(json.dumps(run(),indent=2)) diff --git a/research/crossed-connector-caller/discovery/RESULTS.json.gz b/research/crossed-connector-caller/discovery/RESULTS.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..92ebc03c1116bd4d05754074cb297776b4991b57 GIT binary patch literal 63381 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 lJvo#7WKsbiqp7;;6vn@6fl0)][int(c>0)] for c in range(n)] for r in range(n)] for k in ks] + tail=[[Z]*n for _ in range(n)];out=[[[Z]*n for _ in range(n)] for _ in range(g)] + for j,k in reversed(order): + if j=args.limit:break + r=F.certificate(3,o,args.degree) + if 'one' in r['certificates']: + hits+=1 + if len(first)<3:first.append(r) + else:miss.append(o) + if (i+1)%100==0:print(i+1,hits,len(miss),round(time.monotonic()-start,2),flush=True) + report={'degree':args.degree,'orders':hits+len(miss),'certificates':hits,'unresolved':miss,'examples':first} + Path(__file__).with_name(f'AGGREGATE-D{args.degree}.json').write_text(json.dumps(report,indent=2)+'\n') + print('FINAL',hits,len(miss),flush=True) +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/discovery/coupled_five_search.py b/research/crossed-connector-caller/discovery/coupled_five_search.py new file mode 100644 index 0000000000..96e019e86d --- /dev/null +++ b/research/crossed-connector-caller/discovery/coupled_five_search.py @@ -0,0 +1,57 @@ +"""Search five rank-two connectors with coupled four-channel stages. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import argparse +import itertools +import json +from pathlib import Path +import random +import time +import z3 +import cycle_search as C + +def setup(): + d=4;n=16;solver=z3.Solver();calls=[] + for stage in range(3): + a=[[z3.Bool(f'a{stage}_{i}_{j}') for j in range(d)] for i in range(d)] + b=[[z3.Bool(f'b{stage}_{i}_{j}') for j in range(d)] for i in range(d)] + square=C.product(a,a);relation=C.plus(C.product(a,b),C.product(b,a)) + for i,j in itertools.product(range(d),repeat=2):solver.add(square[i][j]==a[i][j],relation[i][j]==b[i][j]) + solver.add(z3.Not(C.xor(*(a[i][i] for i in range(d))))) + solver.add(z3.Or(*[a[i][j] for i,j in itertools.product(range(d),repeat=2)])) + solver.add(z3.Or(*[z3.Xor(a[i][j],z3.BoolVal(i==j)) for i,j in itertools.product(range(d),repeat=2)])) + for half in range(2): + p=C.zero(n);r=C.zero(n) + for row,col in itertools.product((0,stage+1),repeat=2): + for i,j in itertools.product(range(d),repeat=2): + value=z3.Xor(a[i][j],b[i][j]) if row==col else b[i][j] + if half and row==col and i==j:value=z3.Not(value) + p[row*d+i][col*d+j]=value + r[row*d+i][col*d+j]=z3.Xor(a[i][j],z3.BoolVal(bool(half and i==j))) + calls.append((stage,p,r)) + for k in range(5): + u=[[z3.Bool(f'u{k}_{i}_{j}') for j in range(2)] for i in range(n)] + v=[[z3.Bool(f'v{k}_{i}_{j}') for j in range(n)] for i in range(2)] + for j in range(2):solver.add(z3.Or(*(u[i][j] for i in range(n))),z3.Or(*v[j])) + solver.add(z3.Or(*(z3.Xor(u[i][0],u[i][1]) for i in range(n))),z3.Or(*(z3.Xor(v[0][i],v[1][i]) for i in range(n)))) + for row in C.product(v,u): + for x in row:solver.add(z3.Not(x)) + calls.append((3,C.zero(n),C.product(u,v))) + total=C.zero(n) + for _,_,r in calls:total=C.plus(total,r) + for i,j in itertools.product(range(n),repeat=2):solver.add(total[i][j]==(i==j)) + return solver,calls + +def main(): + parser=argparse.ArgumentParser();parser.add_argument('--cases',type=int,default=8);parser.add_argument('--timeout',type=int,default=10000);args=parser.parse_args();rng=random.Random(271828);rows=[];start=time.monotonic() + for case in range(args.cases): + solver,calls=setup();solver.set(timeout=args.timeout);order=list(range(11));rng.shuffle(order);C.constraints(solver,calls,order,3);status=solver.check();row={'case':case,'order':order,'status':str(status)} + if status==z3.sat: + model=solver.model();row['calls']=[{'stage':j,'p':[sum(int(z3.is_true(model.eval(x,model_completion=True)))<>i&1] + # Independent literal expansion of the relation. + check=ZERO + for ei,left,right in terms:check^=frozenset(tuple(left)+w+tuple(right) for w in eq[ei][1]) + if check!=p:raise ValueError('Bad ideal certificate') + tested[label]=terms + return {'g':g,'order':order,'degree':degree,'names':names,'equations':[(label,[list(w) for w in sorted(p)]) for label,p in eq],'monomials':len(words),'rows':len(generators),'rank':len(basis),'certificates':tested} + + +def main(): + ap=argparse.ArgumentParser();ap.add_argument('--degree',type=int,default=3);ap.add_argument('--limit',type=int,default=1);args=ap.parse_args() + g=3;records=[];start=time.monotonic() + for second in itertools.permutations(range(g)): + for bad in itertools.permutations(((3,0),(3,1),(4,0),(4,1))): + order=[(j,0) for j in range(g)]+list(bad)+[(j,1) for j in second] + r=certificate(g,order,args.degree);records.append(r) + print(json.dumps({k:r[k] for k in ('order','rows','rank','monomials')}|{'certificates':{k:len(v) for k,v in r['certificates'].items()},'seconds':round(time.monotonic()-start,2)}),flush=True) + if len(records)>=args.limit:break + if len(records)>=args.limit:break + Path(__file__).with_name(f'NC-STAR-D{args.degree}.json').write_text(json.dumps(records,indent=2)+'\n') + +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/discovery/gap_search.py b/research/crossed-connector-caller/discovery/gap_search.py new file mode 100644 index 0000000000..73b7b6c708 --- /dev/null +++ b/research/crossed-connector-caller/discovery/gap_search.py @@ -0,0 +1,52 @@ +"""Allow an arbitrary aggregate matrix in every gap of the good word. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import itertools +import json +from pathlib import Path +import free_algebra as F +Z=F.ZERO;I=F.ONE + +def orders(): + for good in sorted(set(itertools.permutations((0,0,1,1,2,2)))): + if good.index(0)0)][int(c>0)] for c in range(n)] for r in range(n)]) + tail=[[Z]*n for _ in range(n)];out=[[[Z]*n for _ in range(n)] for _ in range(g)] + for i,(j,k) in reversed(list(enumerate(order))): + p,r=good[j][k];total=F.add(tail,tails[i]) + out[j]=F.add(out[j],F.add(F.mul(p,total),F.mul(total,p)));tail=F.add(tail,r) + for j,m in enumerate(out): + for r,row in enumerate(m): + for c,poly in enumerate(row): + if r in (0,j+1) and c in (0,j+1):continue + if poly:eq.append((f'chronology {j}:{r},{c}',poly)) + return names,eq + +def main(): + F.equations=equations;records=[] + for o in orders(): + r=F.certificate(3,o,3);records.append(r) + print(o,{k:len(v) for k,v in r['certificates'].items()},flush=True) + Path(__file__).with_name('GAP-SEARCH.json').write_text(json.dumps(records,indent=2)+'\n') +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/discovery/ideal_completion.py b/research/crossed-connector-caller/discovery/ideal_completion.py new file mode 100644 index 0000000000..bcc736c3c4 --- /dev/null +++ b/research/crossed-connector-caller/discovery/ideal_completion.py @@ -0,0 +1,70 @@ +"""Find a bounded noncommuting polynomial certificate by word reduction. + +This discovery code is not used by the independent certificate checker. +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import argparse +import heapq +import json +from pathlib import Path +import time +import multisplit_search as M + +def lead(poly):return max(poly,key=lambda w:(len(w),w)) +def shift(poly,left,right):return {left+w+right for w in poly} +def proof_shift(proof,left,right):return {(i,left+a,b+right) for i,a,b in proof} + +def complete(equations,max_degree=4,max_rules=500,max_pairs=30000): + rules=[];queue=[];counter=0;done=0;start=time.monotonic() + def reduce(poly,proof): + poly=set(poly);proof=set(proof) + while poly: + found=None + for word in sorted(poly,key=lambda w:(len(w),w),reverse=True): + for leading,p,r in rules: + for pos in range(len(word)-len(leading)+1): + if word[pos:pos+len(leading)]==leading: + found=(word,pos,leading,p,r);break + if found:break + if found:break + if not found:break + word,pos,leading,p,r=found;left=word[:pos];right=word[pos+len(leading):] + poly^=shift(p,left,right);proof^=proof_shift(r,left,right) + return poly,proof + def insert(poly,proof): + nonlocal counter + if not poly:return + leading=lead(poly);idx=len(rules);rules.append((leading,poly,proof)) + for other in range(idx+1): + for i,j in ((idx,other),(other,idx)): + u=rules[i][0];v=rules[j][0] + for k in range(1,min(len(u),len(v))+1): + if u[-k:]==v[:k] and len(u)+len(v)-k<=max_degree: + item=(i,(),v[k:],j,u[:-k],());counter+=1;heapq.heappush(queue,(len(u)+len(v)-k,counter,item)) + for pos in range(len(u)-len(v)+1): + if u[pos:pos+len(v)]==v: + item=(i,(),(),j,u[:pos],u[pos+len(v):]);counter+=1;heapq.heappush(queue,(len(u),counter,item)) + for ei,(_,p) in enumerate(equations): + p,r=reduce(p,{(ei,(),())});insert(p,r) + if p=={()}:return {'proof':sorted(r),'rules':len(rules),'pairs':done} + while queue and done>j&1)) for j in range(N)] for row in a] +def embed(a,indices): + out=[0]*N + for i,row in enumerate(a):out[indices[i]]=sum(1<>j&1) + return tuple(out) +def add(a,b):return tuple(x^y for x,y in zip(a,b)) +def mul(a,b):return tuple(sum((sum((row>>k&1)*(b[k]>>j&1) for k in range(len(a)))%2)<>col&1]) for col in range(N)] for row in range(N)]) + good.append((j,*matrices)) + thin=[];active=[] + for k in range(thin_count): + u=[z3.Bool(f'u{k}_{i}') for i in range(N)];v=[z3.Bool(f'v{k}_{i}') for i in range(N)] + enabled=z3.Bool(f'enabled{k}');active.append(enabled) + solver.add(enabled==z3.And(z3.Or(*u),z3.Or(*v)),z3.Not(xor(*(z3.And(a,b) for a,b in zip(u,v))))) + if budget is None:solver.add(enabled) + r=[[z3.And(u[i],v[j]) for j in range(N)] for i in range(N)] + thin.append((3,zero(),r)) + if budget is not None:solver.add(z3.PbLe([(x,1) for x in active],budget)) + calls=good+thin;total=zero() + for _,_,r in calls:total=matxor(total,r) + for i,j in itertools.product(range(N),repeat=2):solver.add(total[i][j]==(i==j)) + return solver,calls,choices,options + +def constraints(solver,calls,order): + tail=zero();out=[zero() for _ in range(3)] + for index in reversed(order): + stage,p,r=calls[index] + if stage<3:out[stage]=matxor(out[stage],matxor(product(p,tail),product(tail,p))) + tail=matxor(tail,r) + for mat in out: + for row in mat: + for val in row:solver.add(z3.Not(val)) + +def stage_constraints(solver,calls,order): + # Pairwise scalar-stage coefficients are necessary for the full word. + places={k:order.index(k) for k in range(6)} + for j,k in itertools.combinations(range(3),2): + a,b=sorted((places[2*j],places[2*j+1]));c,d=sorted((places[2*k],places[2*k+1])) + if b>j&1:val^=b[j] + out.append(val) + return tuple(out) +def rank(a): + basis={} + for v in a: + while v: + j=v.bit_length()-1 + if j not in basis:basis[j]=v;break + v^=basis[j] + return len(basis) +def inv(a): + n=len(a);r=[x|(1<<(n+i)) for i,x in enumerate(a)] + for j in range(n): + k=next(i for i in range(j,n) if r[i]>>j&1);r[j],r[k]=r[k],r[j] + for i in range(n): + if i!=j and r[i]>>j&1:r[i]^=r[j] + return tuple(x>>n for x in r) +def frame(a): + b=inv(a) + return [tuple(b[k] if row>>k&1 else 0 for row in a) for k in range(3)] +def poly_product(a,b): + out={};z=(0,0,0) + for i,ai in a.items(): + for j,bj in b.items(): + k=tuple(x+y for x,y in zip(i,j));out[k]=add(out.get(k,z),mul(ai,bj)) + return {k:v for k,v in out.items() if any(v)} +def word(fs): + g=len(fs);base=(0,)*g;w={base:eye(3)} + for h in range(3): + for j in range(g): + d=list(base);d[j]=1;w=poly_product({base:eye(3),tuple(d):fs[j][h]},w) + return w=={x:eye(3) for x in itertools.product((0,1),repeat=g)} + +def linear(fs): + order=[(j,k) for k in range(3) for j in range(3)];names,eq=M.equations(3,order) + fixed=[] + for f in fs:fixed.extend((f[0],(0,0,0),f[1],(0,0,0))) + unknowns=(len(names)-len(fixed))*9;rows=[] + for label,p in eq: + values=[0]*9 + for w in p: + letters=[(i,fixed[i] if i>c)&1)<>c)&1)<<(start+3*rr+cc) + rows.extend(values) + basis={};mask=(1<>unknowns:return None + solution=0 + for j,row in sorted(basis.items()): + if ((row&solution).bit_count()^(row>>unknowns))&1:solution|=1<>(9*k+3*r))&7 for r in range(3)) for k in range(unknowns//9)] + +def main(): + start=time.monotonic();frames=[frame(a) for a in itertools.product(range(8),repeat=3) if rank(a)==3];base=frame(eye(3)) + compatible=[f for f in frames if word([base,f])];print('frames',len(frames),'pair-compatible',len(compatible),flush=True) + count=0;surv=[] + for a,b in itertools.product(compatible,repeat=2): + fs=[base,a,b] + if not word(fs):continue + count+=1;sol=linear(fs) + if sol is not None:surv.append({'frames':fs,'tails':sol});print('FOUND',len(surv),flush=True) + print('FINAL',count,len(surv),'seconds',round(time.monotonic()-start,2),flush=True) + Path(__file__).with_name('M3-FRAME-SEARCH.json').write_text(json.dumps({'frames':len(frames),'pair_compatible':len(compatible),'full_stage_words':count,'survivors':surv},indent=2)+'\n') +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/discovery/multisplit_search.py b/research/crossed-connector-caller/discovery/multisplit_search.py new file mode 100644 index 0000000000..4be46df7c6 --- /dev/null +++ b/research/crossed-connector-caller/discovery/multisplit_search.py @@ -0,0 +1,67 @@ +"""Test three or more native calls per shared stage. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import argparse +import itertools +import json +from pathlib import Path +import time +import free_algebra as F +Z=F.ZERO;I=F.ONE +SPLITS=3 + +def orders(m): + def rec(word,counts,max_seen): + if len(word)==3*m:yield [(j,word[:i].count(j)) for i,j in enumerate(word)];return + for j in range(min(2,max_seen+1)+1): + if counts[j]0)][int(c>0)] for c in range(n)] for r in range(n)]) + tail=[[Z]*n for _ in range(n)];out=[[[Z]*n for _ in range(n)] for _ in range(g)] + for i,(j,k) in reversed(list(enumerate(order))): + p,r=good[j][k];total=F.add(tail,tails[i]);out[j]=F.add(out[j],F.add(F.mul(p,total),F.mul(total,p)));tail=F.add(tail,r) + for j,mat in enumerate(out): + for row,values in enumerate(mat): + for col,poly in enumerate(values): + if row in (0,j+1) and col in (0,j+1):continue + if poly:eq.append((f'chronology {j}:{row},{col}',poly)) + return names,eq + +def main(): + global SPLITS + ap=argparse.ArgumentParser();ap.add_argument('--splits',type=int,default=3);ap.add_argument('--degree',type=int,default=2);ap.add_argument('--limit',type=int,default=280);args=ap.parse_args();SPLITS=args.splits + F.equations=equations;start=time.monotonic();hit=0;miss=[] + for i,o in enumerate(orders(SPLITS)): + if i>=args.limit:break + r=F.certificate(3,o,args.degree) + if 'one' in r['certificates']:hit+=1 + else:miss.append(o) + if (i+1)%20==0:print(i+1,hit,len(miss),round(time.monotonic()-start,2),flush=True) + Path(__file__).with_name(f'MULTISPLIT-M{SPLITS}-D{args.degree}.json').write_text(json.dumps({'orders':hit+len(miss),'certificates':hit,'unresolved':miss},indent=2)+'\n') + print('FINAL',hit,len(miss),flush=True) +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/discovery/order_search.py b/research/crossed-connector-caller/discovery/order_search.py new file mode 100644 index 0000000000..3727f5c500 --- /dev/null +++ b/research/crossed-connector-caller/discovery/order_search.py @@ -0,0 +1,56 @@ +"""Search all order types of three leaves and four fixed connectors. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import argparse +import itertools +import json +from pathlib import Path +import time +import free_algebra as N + +_original=N.equations + +def pair_equations(g,order): + names,eq=_original(g,order);out=[] + for label,p in eq: + if not label.startswith('chronology'): + out.append((label,p));continue + head,rc=label.split(':');c=int(head.split()[1]);r,col=map(int,rc.split(',')) + if c>=g:continue + if r in (0,c+1) and col in (0,c+1):continue + out.append((label,p)) + return names,out + + +def orders(): + good_words=sorted(set(itertools.permutations((0,0,1,1,2,2)))) + good_words=[w for w in good_words if w.index(0)=args.limit:break + r=N.certificate(3,order,args.degree) + if 'one' in r['certificates']: + hits+=1 + if len(examples)<3:examples.append(r) + else:misses.append(order) + if (i+1)%1000==0:print(json.dumps({'orders':i+1,'certificates':hits,'unresolved':len(misses),'seconds':round(time.monotonic()-start,2)}),flush=True) + report={'scope':'All order types of three good pairs and the four fixed connectors; no matrix size bound','degree':args.degree,'orders':hits+len(misses),'certificates':hits,'unresolved':misses,'examples':examples} + Path(__file__).with_name(f'ORDER-SEARCH-D{args.degree}.json').write_text(json.dumps(report,indent=2)+'\n') + print(json.dumps({k:report[k] for k in ('scope','degree','orders','certificates')}|{'unresolved':len(misses)}),flush=True) + +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/discovery/tournament_search.py b/research/crossed-connector-caller/discovery/tournament_search.py new file mode 100644 index 0000000000..417595a2f0 --- /dev/null +++ b/research/crossed-connector-caller/discovery/tournament_search.py @@ -0,0 +1,42 @@ +"""Test the projected chronology equations without connector matrices. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import json,itertools +from pathlib import Path +import free_algebra as F,gap_search as G +MODE='rows';SPLITS=2 + +def equations(g,order): + m=SPLITS;names=[];aa=[];eq=[] + for j in range(g): + row=[];last=F.ONE + for h in range(m-1):row.append(F.var(len(names)));names.append(f'A{j}_{h}');last^=row[-1] + row.append(last);aa.append(row) + for h,k in itertools.product(range(m),repeat=2): + v=F.prod(row[h],row[k])^(row[h] if h==k else F.ZERO) + if v:eq.append((f'A{j}:{h},{k}',v)) + s={} + for j,k in itertools.permutations(range(g),2): + v=F.ZERO + for i,(c,h) in enumerate(order): + if c!=j:continue + for d,l in order[i+1:]: + if d==k:v^=F.prod(aa[j][h],aa[k][l]) + s[j,k]=v + for j in range(g): + k,l=[i for i in range(g) if i!=j] + if MODE in ('rows','both'):eq.append((f'row {j}',s[j,k]^s[j,l])) + if MODE in ('cols','both'):eq.append((f'col {j}',s[k,j]^s[l,j])) + return names,eq + +def main(): + global MODE + F.equations=equations;out={} + for MODE in ('rows','cols','both'): + records=[] + for o in G.orders(): + r=F.certificate(3,o,4);records.append(r) + print(MODE,len(records),sum('one' in r['certificates'] for r in records),flush=True);out[MODE]=records + Path(__file__).with_name('TOURNAMENT-SEARCH.json').write_text(json.dumps(out,indent=2)+'\n') +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/test_verify.py b/research/crossed-connector-caller/test_verify.py new file mode 100644 index 0000000000..60364a5d07 --- /dev/null +++ b/research/crossed-connector-caller/test_verify.py @@ -0,0 +1,32 @@ +"""Reject changed mathematical evidence and a changed source bill. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import json +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile + +PACKAGE=Path(__file__).resolve().parent +ROOT=PACKAGE.parents[1] + +def require(value,message): + if not value:raise ValueError(message) + +def main(): + for kind,expected in [('certificate','Free-algebra certificate'),('query','Query rank and square'),('source','Source digest:'),('receipt','Committed result differs')]: + with tempfile.TemporaryDirectory() as folder: + root=Path(folder);package=root/'research/crossed-connector-caller';shutil.copytree(PACKAGE,package,ignore=shutil.ignore_patterns('__pycache__')) + source=root/'research/p104-helper-subspace-splits/RESULT.json';source.parent.mkdir(parents=True);shutil.copyfile(ROOT/'research/p104-helper-subspace-splits/RESULT.json',source) + if kind=='certificate': + path=package/'PAIR-CERTIFICATES.json';x=json.loads(path.read_text());x[0]['terms']=[];path.write_text(json.dumps(x)) + elif kind=='query': + path=package/'ESCAPE-WORD.json';x=json.loads(path.read_text());x['calls'][6]['r']=[0]*8;path.write_text(json.dumps(x)) + elif kind=='source':source.write_text(source.read_text()+' ') + else:(package/'RESULT.json').write_text('{}\n') + result=subprocess.run([sys.executable,'-I','-O','-B',str(package/'verify.py')],cwd=root,capture_output=True,text=True,timeout=30) + require(result.returncode!=0 and expected in result.stderr,'Mutation was not rejected: '+kind) + print('PASS_CONNECTOR_MUTATIONS: 4 corrupted packages rejected') +if __name__=='__main__':main() diff --git a/research/crossed-connector-caller/vendor/algebra.py b/research/crossed-connector-caller/vendor/algebra.py new file mode 100644 index 0000000000..2f0d4f290c --- /dev/null +++ b/research/crossed-connector-caller/vendor/algebra.py @@ -0,0 +1,110 @@ +"""Literal GF(2) polynomial matrices, independently of the GF(16) search. + +Apache-2.0. Cinna Davis, with substantial OpenAI Codex assistance. +""" +from collections import Counter + +EVEN = sum(1 << i for i in range(0, 256, 2)) + + +def query(poly): + """Multiply by the formal involution Q, without setting Q = 1.""" + return ((poly & EVEN) << 1) | ((poly & (EVEN << 1)) >> 1) + + +def rank(rows): + basis = {} + for value in rows: + while value: + pivot = value.bit_length() - 1 + if pivot not in basis: + basis[pivot] = value + break + value ^= basis[pivot] + return len(basis) + + +def gate_inventory(): + """All rank-one nilpotents and their rank-two projector extensions.""" + full, thin = [], [] + for u in range(1, 16): + for v in range(1, 16): + if (u & v).bit_count() % 2: + continue + nilpotent = tuple(v if u >> i & 1 else 0 for i in range(4)) + thin.append(((0,) * 4, nilpotent)) + seen = set() + for a in range(1, 16): + if not (v & a).bit_count() % 2: + continue + for b in range(1, 16): + if not (u & b).bit_count() % 2 or (a & b).bit_count() % 2: + continue + projector = tuple((b if u >> i & 1 else 0) ^ + (v if a >> i & 1 else 0) for i in range(4)) + if projector not in seen: + seen.add(projector) + full.append((projector, nilpotent)) + return full, thin + + +FULL, THIN = gate_inventory() + + +def identity(): + return [[int(i == j) for j in range(4)] for i in range(4)] + + +def literal(mask, ids): + """Each bit is a monomial Q^q product(D_s); no D is specialized.""" + matrix = identity() + for stage, gate_id in enumerate(ids): + thick = bool(mask >> stage & 1) + projector, nilpotent = (FULL if thick else THIN)[gate_id] + sums = [[0] * 4 for _ in range(16)] + for subset in range(1, 16): + low = (subset & -subset).bit_length() - 1 + sums[subset] = [a ^ b for a, b in + zip(sums[subset & (subset - 1)], matrix[low])] + changed = [row[:] for row in matrix] + for i in range(4): + for j in range(4): + p = sums[projector[i]][j] + n = query(sums[nilpotent[i]][j]) + if thick: + shift = 1 << (stage + 1) + changed[i][j] ^= p ^ (p << shift) ^ (n << shift) + else: + changed[i][j] ^= n + matrix = changed + return matrix + + +def coefficients(matrix): + result = {} + groups = {g for row in matrix for poly in row + for g in range(poly.bit_length()) if poly >> g & 1} + for g in groups: + result[g] = [sum(((matrix[i][j] >> g) & 1) << j for j in range(4)) + for i in range(4)] + return result + + +def stats(matrix): + coeff = coefficients(matrix) + return { + 'central_query_on_every_output': all(g & 1 for g in coeff), + 'coefficient_rank_sum': sum(rank(rows) for rows in coeff.values()), + 'ranks': dict(sorted((g, rank(rows)) for g, rows in coeff.items())), + } + + +def elementary(source, destination): + nilpotent = tuple((1 << source) if i == destination else 0 for i in range(4)) + projector = tuple((1 << i) if i in (source, destination) else 0 for i in range(4)) + return FULL.index((projector, nilpotent)) + + +def multiply_binary(a, b): + return [sum(((sum(((row >> k) & 1) * ((b[k] >> j) & 1) + for k in range(4))) % 2) << j for j in range(4)) for row in a] diff --git a/research/crossed-connector-caller/verify.py b/research/crossed-connector-caller/verify.py new file mode 100644 index 0000000000..78a5af8da9 --- /dev/null +++ b/research/crossed-connector-caller/verify.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +"""Replay the connector theorem package and its paid profiles. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import hashlib +import importlib.util +import json +from pathlib import Path +import sys + +PACKAGE=Path(__file__).resolve().parent +ROOT=PACKAGE.parents[1] + +def require(value,message): + if not value:raise ValueError(message) + +def load_check(): + spec=importlib.util.spec_from_file_location('connector_check',PACKAGE/'check.py') + module=importlib.util.module_from_spec(spec);spec.loader.exec_module(module);return module + +def power_bound(rank,numerator,denominator,bits=40): + scale=1<1: + mid=(lo+hi)//2 + if pow(mid,denominator)<=goal:lo=mid + else:hi=mid + return lo,lo if pow(lo,denominator)==goal else lo+1 + +def profile(source,g,thin): + counts={int(r):-2*g*v for r,v in source['paid'].items()} + for r,v in source['helpers'].items():counts[int(r)]=counts.get(int(r),0)+2*g*v + counts[8*g+1]=counts.get(8*g+1,0)+208;counts[9]=counts.get(9,0)+208*g;counts[1]-=104*thin + return {r:c for r,c in counts.items() if c} + +def pricing(): + source=json.loads((ROOT/'research/p104-helper-subspace-splits/RESULT.json').read_text())['local'];bad=profile(source,3,8) + linear=sum(r*c for r,c in bad.items());require(linear==-336,'Escape price mass') + require(min(r for r,c in bad.items() if c>0)==8,'Positive escape rank floor') + require(max(r for r,c in bad.items() if c<0)==7,'Negative escape rank ceiling') + candidates=[] + for g,thin,ports in ((127,10,1),(31,5,2)): + candidate=profile(source,g,thin);lo=hi=0 + for r,c in candidate.items(): + a,b=power_bound(r,1993,2000) + lo+=c*(a if c>=0 else b);hi+=c*(b if c>=0 else a) + require(lo>0,'The long relaxation must retain a positive exact price margin') + candidates.append({'q':104,'g':g,'ports_per_binary_block':ports,'full_calls':2*g,'thin_queries_per_native_port':thin,'saving':'7/2000','moment_lower_numerator':str(lo),'moment_upper_numerator':str(hi),'moment_denominator':str(1<<40),'status':'POSITIVE_OPTIMISTIC_PRICE_ONLY; NO CALLER OR KAPPA CLAIM'}) + return {'pinned_supplier':'PR5599 09dd0965711ca7eeb169057a420abab1c9052137','escape':{'q':104,'g':3,'thin_queries_per_copy':8,'signed_profile':{str(r):v for r,v in sorted(bad.items())},'linear_margin':linear,'all_concave_moments_rejected':True},'unconstructed_candidates':candidates} + +def run(): + sources=json.loads((PACKAGE/'SOURCES.json').read_text());count=0 + for row in sources['files']: + if row['usage']=='input': + require(hashlib.sha256((ROOT/row['path']).read_bytes()).hexdigest()==row['sha256'],'Source digest: '+row['path']);count+=1 + checker=load_check();controls=checker.run() + result={'status':'PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION','scope':'Finite matrices over every characteristic-two field; any finite star stage splits and call order; one-sided equal leaf signatures','authenticated_inputs':count,'controls':controls,'pricing':pricing(),'limits':['No kappa increase','The full escape word is binary algebra, not a physical native caller','The 127-leaf price profile has no operator','No proof-assistant or independent human acceptance']} + encoded=json.dumps(result,indent=2,sort_keys=True)+'\n' + if '--write-result' in sys.argv:(PACKAGE/'RESULT.json').write_text(encoded) + else:require((PACKAGE/'RESULT.json').read_text()==encoded,'Committed result differs') + print(encoded,end='') +if __name__=='__main__':run() diff --git a/research/crossed-connector-caller/word_replay.py b/research/crossed-connector-caller/word_replay.py new file mode 100644 index 0000000000..037ed3f765 --- /dev/null +++ b/research/crossed-connector-caller/word_replay.py @@ -0,0 +1,49 @@ +"""Replay the complete binary word with independent stage variables. + +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import json +from pathlib import Path + +def eye(n):return tuple(1<1:continue + key=tuple(a+b for a,b in zip(x,y));out[key]=add(out.get(key,zero),mul(ax,by)) + return {k:v for k,v in out.items() if any(v)} + +def replay(calls,order): + n=len(calls[0]['p']);g=max(c['stage'] for c in calls);base=(0,)*(g+1);ebit=(1,)+(0,)*g + word={base:eye(n)};expected={base:eye(n),ebit:eye(n)};targets=[(0,)*n for _ in range(g)] + for c in calls: + if c['stage'] Date: Sun, 25 Oct 2026 23:33:02 -0500 Subject: [PATCH 2/2] Preserve complete-word trap and bounded caller growth searches --- .../crossed-connector-caller/DISCOVERY.md | 13 +- .../MIXED-ONLY-CANDIDATE.json | 349 ++++++++++++++++++ research/crossed-connector-caller/README.md | 5 +- research/crossed-connector-caller/RESULT.json | 1 + research/crossed-connector-caller/TASK.json | 2 +- .../crossed-connector-caller/VALIDATION.json | 4 +- research/crossed-connector-caller/check.py | 12 +- .../discovery/RESULTS.json.gz | Bin 63381 -> 63539 bytes .../discovery/grow_escape.py | 103 ++++++ .../crossed-connector-caller/test_verify.py | 5 +- 10 files changed, 485 insertions(+), 9 deletions(-) create mode 100644 research/crossed-connector-caller/MIXED-ONLY-CANDIDATE.json create mode 100644 research/crossed-connector-caller/discovery/grow_escape.py diff --git a/research/crossed-connector-caller/DISCOVERY.md b/research/crossed-connector-caller/DISCOVERY.md index f77f550f1f..cde7987ae1 100644 --- a/research/crossed-connector-caller/DISCOVERY.md +++ b/research/crossed-connector-caller/DISCOVERY.md @@ -16,13 +16,16 @@ metadata. It is data, not instructions or a registered proof dependency. | Six arbitrary thin queries, three paired stages | Twenty orders; solver reports 17 unsat and 3 unknown. This first screen did not impose the separate stage-word conditions | | Eight arbitrary thin queries | Sixty orders; 23 sat, 19 unsat, 18 unknown. Sat means necessary conditions only. The full word rejects some sat candidates | | At most seven active queries in eight thin slots | Seventy orders; 22 unsat and 48 unknown | +| Grow a complete escape word by two leaves | Four fixed-source extension tests reported unsat: case11 with identical and independent new signatures, and cases13/20 with identical signatures. All retain eight thin factors and the old call order | | Coupled ports, five rank-two thin queries | Eight orders at three leaves: two unsat and six unknown; no positive word | | Three-stage cycle, two thin queries | Fifty basis-parameterized orders: 42 unsat, 8 unknown. Fifty direct-projector orders: 43 unsat, 7 unknown | `ESCAPE-WORD.json` selects case 11 of the eight-query search. Its complete word is checked again by the separate default checker. All fields and all independent stage exponents are retained. Case 8 in that same search is an -example that passes first mixed coefficients but fails the full word. +example that passes the pure stage word and first mixed coefficients but +fails higher mixed coefficients. `MIXED-ONLY-CANDIDATE.json` preserves it, and +the separate checker rejects it. ## Discovery commands @@ -59,8 +62,16 @@ python3 -B discovery/leaf_echo_search.py --thin 8 --cases 60 --timeout 4000 --se python3 -B discovery/leaf_echo_search.py --thin 8 --budget 7 --cases 70 --timeout 4000 --seed 3 python3 -B discovery/cycle_search.py --g 3 --thin 2 --cases 50 --timeout 5000 --seed 91 python3 -B discovery/coupled_five_search.py --cases 8 --timeout 10000 +python3 -B discovery/grow_escape.py --case 11 --distinct --timeout 30000 +python3 -B discovery/grow_escape.py --case 13 --timeout 30000 +python3 -B discovery/grow_escape.py --case 20 --timeout 30000 ``` +The growth model retains every old query factor on the old coordinates and +the old call order. New full calls can enter any gap. It allows either equal +or independent signatures for the two new leaves. Its four negative results +do not exclude changing an old query or order, or other source words. + Time limits are milliseconds per solver call. A timeout is unknown. The solver models and timing-dependent statuses are not independent theorem certificates. A rerun can choose a different model. Use `check.py` to verify diff --git a/research/crossed-connector-caller/MIXED-ONLY-CANDIDATE.json b/research/crossed-connector-caller/MIXED-ONLY-CANDIDATE.json new file mode 100644 index 0000000000..ccce3c2910 --- /dev/null +++ b/research/crossed-connector-caller/MIXED-ONLY-CANDIDATE.json @@ -0,0 +1,349 @@ +{ + "calls": [ + { + "p": [ + 2, + 2, + 8, + 8, + 0, + 0, + 0, + 0 + ], + "r": [ + 10, + 10, + 10, + 10, + 0, + 0, + 0, + 0 + ], + "stage": 0 + }, + { + "p": [ + 3, + 0, + 12, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 15, + 0, + 15, + 0, + 0, + 0, + 0, + 0 + ], + "stage": 0 + }, + { + "p": [ + 1, + 0, + 0, + 0, + 16, + 0, + 0, + 0 + ], + "r": [ + 17, + 0, + 0, + 0, + 17, + 0, + 0, + 0 + ], + "stage": 1 + }, + { + "p": [ + 0, + 2, + 0, + 0, + 0, + 32, + 0, + 0 + ], + "r": [ + 0, + 34, + 0, + 0, + 0, + 34, + 0, + 0 + ], + "stage": 1 + }, + { + "p": [ + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 128 + ], + "r": [ + 0, + 130, + 0, + 0, + 0, + 0, + 0, + 130 + ], + "stage": 2 + }, + { + "p": [ + 1, + 0, + 0, + 0, + 0, + 0, + 64, + 0 + ], + "r": [ + 65, + 0, + 0, + 0, + 0, + 0, + 65, + 0 + ], + "stage": 2 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 80, + 0, + 80, + 0, + 0, + 0, + 0, + 0 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 3, + 3, + 3, + 0, + 3, + 0, + 3, + 0 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 0, + 88, + 0, + 0, + 0, + 0, + 0 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 161, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 0, + 2, + 2, + 0, + 0, + 0, + 2 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 5, + 5, + 5, + 0, + 0, + 0, + 0, + 0 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 0, + 15, + 15, + 0, + 0, + 0, + 0, + 0 + ], + "stage": 3 + }, + { + "p": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "r": [ + 2, + 0, + 2, + 0, + 2, + 2, + 2, + 0 + ], + "stage": 3 + } + ], + "case": 8, + "choices": [ + 8, + 4, + 0 + ], + "order": [ + 5, + 13, + 7, + 3, + 9, + 8, + 6, + 4, + 12, + 2, + 1, + 10, + 0, + 11 + ], + "status": "sat" +} diff --git a/research/crossed-connector-caller/README.md b/research/crossed-connector-caller/README.md index 64eb1d580e..1ed7848890 100644 --- a/research/crossed-connector-caller/README.md +++ b/research/crossed-connector-caller/README.md @@ -62,8 +62,9 @@ kappa remains .00310045 at the pinned base. This package changes no frontier. - Construct a long word whose connectors have distinct leaf signatures in both directions. Start with 31 leaves and five rank-two queries per coupled port pair, or 127 leaves and ten rank-one queries per binary copy. Both - optimistic prices pass at .0035. Begin with the saved - eight-field word and test the full polynomial endpoint after each extension. + optimistic prices pass at .0035. Use the saved word as a positive control. + The fixed-source growth tests fail; resynthesize old connector restrictions + or call order, then test every polynomial coefficient. - Solve or certify the remaining finite searches. Seven thin queries at three leaves and the separate cycle frame have timeout cases. First use exact certificates or longer bounded solves on those saved cases. A timeout is diff --git a/research/crossed-connector-caller/RESULT.json b/research/crossed-connector-caller/RESULT.json index 3fbb19095a..879461d539 100644 --- a/research/crossed-connector-caller/RESULT.json +++ b/research/crossed-connector-caller/RESULT.json @@ -12,6 +12,7 @@ "distinct_leaf_column_signatures": 3, "distinct_leaf_row_signatures": 3, "fields": 8, + "first_mixed_false_positive_rejected": true, "full_calls": 6, "full_polynomial_coefficients": 16, "moved_call_rejected": true, diff --git a/research/crossed-connector-caller/TASK.json b/research/crossed-connector-caller/TASK.json index ff538aef83..9bac84b1ad 100644 --- a/research/crossed-connector-caller/TASK.json +++ b/research/crossed-connector-caller/TASK.json @@ -83,7 +83,7 @@ { "question": "Can 31 leaves use five rank-two thin queries per coupled port pair, or can 127 leaves use ten rank-one thin queries?", "why_it_matters": "The new signature cut permits this profile and its optimistic P104 price passes at saving .0035.", - "first_step": "Use the new rank/signature cut and the saved coupled-five and full-word tools. Check the full endpoint after each finite extension.", + "first_step": "Resynthesize connector restrictions or call order, using the rank/signature cut and the saved coupled-five and full-word tools. The four fixed-source growth tests fail; do not repeat those templates unchanged.", "blocked_by": "No such long word is known; signatures and price alone do not construct it." }, { diff --git a/research/crossed-connector-caller/VALIDATION.json b/research/crossed-connector-caller/VALIDATION.json index fa1b6e8fbc..5aaea2c9f0 100644 --- a/research/crossed-connector-caller/VALIDATION.json +++ b/research/crossed-connector-caller/VALIDATION.json @@ -4,9 +4,9 @@ "base": "df0137efd35e11b4445734bf612bdd4c7ebc330c", "registered": "PASS_REGISTERED_RESEARCH_PACKAGE outcome=completed", "optimized": "PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION", - "mutations": 4, + "mutations": 5, "git_free_read_only": { - "path": "/var/folders/ph/5swjdlqd3997q5j1y6zvmty80000gp/T/imb-one-sided-gitfree-vl4q8ns3", + "path": "/var/folders/ph/5swjdlqd3997q5j1y6zvmty80000gp/T/imb-one-sided-final-e_mhg2tm", "cwd": "/", "PATH": "/nonexistent", "status": "PASS_ONE_SIDED_CONNECTOR_OBSTRUCTION" diff --git a/research/crossed-connector-caller/check.py b/research/crossed-connector-caller/check.py index 6c6986643d..96570d3a1b 100644 --- a/research/crossed-connector-caller/check.py +++ b/research/crossed-connector-caller/check.py @@ -78,6 +78,10 @@ def escape(): for j in range(g): a,b=calls[2*j:2*j+2];e=tuple(1<>j)&1 for i in range(n) for j in block) for c in thin)) rows.append(tuple(tuple(c['r'][i] for i in block) for c in thin)) require(len(set(columns))==3 and len(set(rows))==3,'The word must leave both equal-signature classes') - return {'fields':n,'full_calls':6,'thin_queries':8,'full_polynomial_coefficients':len(word),'deleted_query_rejected':True,'moved_call_rejected':True,'distinct_leaf_column_signatures':3,'distinct_leaf_row_signatures':3} + trap=json.loads((PACKAGE/'MIXED-ONLY-CANDIDATE.json').read_text());wrong,wanted=replay(trap['calls'],trap['order'],g) + for j in range(g): + key=[1,0,0,0];key[j+1]=1 + require(wrong.get(tuple(key),zero(n))==wanted.get(tuple(key),zero(n)),'First mixed coefficient control') + require(all(wrong.get(k,zero(n))==wanted.get(k,zero(n)) for k in wrong.keys()|wanted.keys() if k[0]==0),'Pure stage word control') + require(wrong!=wanted,'Full-word trap must fail') + return {'first_mixed_false_positive_rejected':True,'fields':n,'full_calls':6,'thin_queries':8,'full_polynomial_coefficients':len(word),'deleted_query_rejected':True,'moved_call_rejected':True,'distinct_leaf_column_signatures':3,'distinct_leaf_row_signatures':3} # Polynomials in three free, noncommuting variables over F2. ONE=frozenset(((),));Z=frozenset() diff --git a/research/crossed-connector-caller/discovery/RESULTS.json.gz b/research/crossed-connector-caller/discovery/RESULTS.json.gz index 92ebc03c1116bd4d05754074cb297776b4991b57..8b3223c079e90db85a794fef4fb81e16be68564e 100644 GIT binary patch delta 24237 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 diff --git a/research/crossed-connector-caller/discovery/grow_escape.py b/research/crossed-connector-caller/discovery/grow_escape.py new file mode 100644 index 0000000000..a035eaff70 --- /dev/null +++ b/research/crossed-connector-caller/discovery/grow_escape.py @@ -0,0 +1,103 @@ +"""Add a pair of leaves while keeping the eight thin query factors. + +The old call order is retained. New calls can enter any gap. +Ali Romman with substantial OpenAI Codex assistance. Apache-2.0. +""" +import argparse +import itertools +import gzip +import json +from pathlib import Path +import sys +import time +import z3 +import cycle_search as C +import leaf_echo_search as L + +PARENT=Path(__file__).resolve().parents[1] + +def embed(a,indices,n): + out=C.zero(n) + for i,row in enumerate(a): + for j in range(4):out[indices[i]][indices[j]]=z3.BoolVal(bool(row>>j&1)) + return out + +def build(case,distinct): + if case==11:original=json.loads((PARENT/'ESCAPE-WORD.json').read_text()) + else: + corpus=json.load(gzip.open(Path(__file__).with_name('RESULTS.json.gz'),'rt')) + original=corpus['LEAF-THIN8-SEED3.json'][case] + sys.path.insert(0,str(PARENT));from word_replay import replay + if original['status']!='sat' or not replay(original['calls'],original['order'])['passed']:raise ValueError('The source must be a complete positive word') + n=12;solver=z3.Solver();calls=[] + for c in original['calls'][:6]: + p=C.zero(n);r=C.zero(n) + for i,j in itertools.product(range(8),repeat=2):p[i][j]=z3.BoolVal(bool(c['p'][i]>>j&1));r[i][j]=z3.BoolVal(bool(c['r'][i]>>j&1)) + calls.append((c['stage'],p,r)) + new_u=[[z3.Bool(f'u{k}_{i}') for i in range(4 if distinct else 2)] for k in range(8)] + new_v=[[z3.Bool(f'v{k}_{i}') for i in range(4 if distinct else 2)] for k in range(8)] + old_u=[];old_v=[] + for k,c in enumerate(original['calls'][6:]): + v=next(row for row in c['r'] if row);u=sum(1<>i&1)) for i in range(8)]+(new_u[k] if distinct else new_u[k]*2) + vv=[z3.BoolVal(bool(v>>i&1)) for i in range(8)]+(new_v[k] if distinct else new_v[k]*2) + solver.add(z3.Not(C.xor(*(z3.And(a,b) for a,b in zip(uu,vv))))) + calls.append((5,C.zero(n),[[z3.And(a,b) for b in vv] for a in uu])) + # Reject three equal signatures among the new leaves and an old leaf. + for leaf in range(3): + solver.add(z3.Or(*[z3.Xor(new_u[k][i],z3.BoolVal(bool(old_u[k]>>(2+2*leaf+(i%2))&1))) for k in range(8) for i in range(4 if distinct else 2)])) + solver.add(z3.Or(*[z3.Xor(new_v[k][i],z3.BoolVal(bool(old_v[k]>>(2+2*leaf+(i%2))&1))) for k in range(8) for i in range(4 if distinct else 2)])) + local=(5,10,5,10);unit=(1,2,4,8);options=[] + for p in sorted(set(p for p,_ in L.source.FULL)): + if L.mul(p,local)!=L.mul(local,p):continue + r=L.mul(p,local) + if L.source.rank(r)!=1:continue + options.append(((p,r),(L.add(p,unit),L.add(r,local)))) + choices=[] + for leaf in (3,4): + chosen=[z3.Bool(f'c{leaf}_{k}') for k in range(24)];choices.extend(chosen);solver.add(z3.PbEq([(c,1) for c in chosen],1));indices=(0,1,2+2*leaf,3+2*leaf) + for half in range(2): + matrices=[] + for kind in range(2): + vals=[embed(o[half][kind],indices,n) for o in options] + matrices.append([[z3.Or(*[chosen[k] for k,a in enumerate(vals) if z3.is_true(a[i][j])]) for j in range(n)] for i in range(n)]) + calls.append((leaf,*matrices)) + positions=[z3.Int(f'pos{i}') for i in range(18)];solver.add(z3.Distinct(*positions)) + for p in positions:solver.add(p>=0,p<18) + for a,b in zip(original['order'],original['order'][1:]):solver.add(positions[a]