From 34ffd44f2d6257e9c2bcfd01970b5fce61113ab2 Mon Sep 17 00:00:00 2001 From: Nick Petalas Date: Tue, 3 Nov 2026 15:58:01 +0000 Subject: [PATCH 1/2] chore(research): retain exact P111 query and scatter inputs --- .../p111-redundant-query-scatter/ORIGINS.json | 37 ++++ .../inputs/CENTRE-SEED.json | 172 ++++++++++++++++++ .../inputs/PR1525-NOTICE.md | 19 ++ .../inputs/PR1525-PREDECESSOR-NOTICE.md | 8 + .../inputs/word.json.gz | Bin 0 -> 57371 bytes 5 files changed, 236 insertions(+) create mode 100644 research/p111-redundant-query-scatter/ORIGINS.json create mode 100644 research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json create mode 100644 research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md create mode 100644 research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md create mode 100644 research/p111-redundant-query-scatter/inputs/word.json.gz diff --git a/research/p111-redundant-query-scatter/ORIGINS.json b/research/p111-redundant-query-scatter/ORIGINS.json new file mode 100644 index 0000000000..bb898f02db --- /dev/null +++ b/research/p111-redundant-query-scatter/ORIGINS.json @@ -0,0 +1,37 @@ +{ + "schema_version": 1, + "files": { + "word.json.gz": { + "repository": "CrocSwap/integer-mult-bounds", + "pr": 1525, + "head": "90d39a5603c7fbfd8d8d957e9732d9b6ebd6317f", + "path": "research/p111-early-merge-query/inputs/word-base.json.gz", + "git_blob": "eacf8c773cb50637f93a762342b3b5f0853fe29a", + "sha256": "e8e6e78ff7422275c38324499e1f33fb2ecd30de9503aef2b8f1ee80d8c4df8e" + }, + "CENTRE-SEED.json": { + "repository": "CrocSwap/integer-mult-bounds", + "pr": 1525, + "head": "90d39a5603c7fbfd8d8d957e9732d9b6ebd6317f", + "path": "research/p111-early-merge-query/CENTRE-SEED.json", + "git_blob": "d5bea849fdde3bb43d38ff44d7b5a2c34e754954", + "sha256": "228e178662fc01895bbcd8472a52114d3a3d11ea8c7ae44d99cd1c8cf9e89147" + }, + "PR1525-NOTICE.md": { + "repository": "CrocSwap/integer-mult-bounds", + "pr": 1525, + "head": "90d39a5603c7fbfd8d8d957e9732d9b6ebd6317f", + "path": "research/p111-early-merge-query/NOTICE.md", + "git_blob": "0f587a9f5fc2394ebaca23f5ce9a25f039b12170", + "sha256": "15bcaa301ca2513b03809c18731051368daf40a8cf93f86441da30608a1a6a3e" + }, + "PR1525-PREDECESSOR-NOTICE.md": { + "repository": "CrocSwap/integer-mult-bounds", + "pr": 1525, + "head": "90d39a5603c7fbfd8d8d957e9732d9b6ebd6317f", + "path": "research/p111-early-merge-query/PREDECESSOR-NOTICE.md", + "git_blob": "0c256b6df08327b4955e46fc34a3ef69f4c63205", + "sha256": "4c7ff8b40efb09d549d65ae59db04d99f24ae5d6ce4bc67f195b859484c3cb7c" + } + } +} diff --git a/research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json b/research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json new file mode 100644 index 0000000000..d5bea849fd --- /dev/null +++ b/research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json @@ -0,0 +1,172 @@ +{ + "status": "PASS_SCOPED_NONNESTED_CENTRE_QUERY_NATIVE", + "puncture": 0, + "terms": [ + { + "center": 61, + "weight": "1/2", + "frame": [ + 256, + 128, + 64, + 32, + 16, + 8, + 5, + 3 + ] + }, + { + "center": 63, + "weight": "1/2", + "frame": [ + 256, + 128, + 64, + 32, + 17, + 9, + 4, + 2 + ] + }, + { + "center": 31, + "weight": "1/2", + "frame": [ + 256, + 128, + 65, + 33, + 17, + 9, + 4, + 2 + ] + }, + { + "center": 256, + "weight": "1/2", + "frame": [ + 256, + 128, + 65, + 33, + 16, + 8, + 5, + 3 + ] + } + ], + "query_frame": [ + 2, + 5, + 9, + 16, + 32, + 64, + 128, + 256 + ], + "transport_profile": { + "2": 4 + }, + "rank_mass": 8, + "omitted_source_coefficient": "2", + "dirty_columns": 62, + "dirty_coefficients": { + "239": "-1", + "225": "-1", + "237": "-1", + "224": "2", + "255": "-1", + "241": "-1", + "253": "-1", + "240": "1", + "242": "1", + "271": "-2", + "256": "1", + "261": "1", + "270": "1", + "351": "-3", + "340": "1", + "350": "1", + "336": "1", + "367": "-1", + "356": "1", + "366": "1", + "352": "1", + "383": "-1", + "379": "1", + "368": "1", + "399": "-2", + "388": "1", + "398": "1", + "395": "1", + "227": "1", + "283": "-1", + "287": "-2", + "280": "-1", + "272": "1", + "299": "-1", + "303": "-2", + "292": "1", + "302": "1", + "400": "1", + "403": "2", + "409": "1", + "402": "-1", + "411": "1", + "416": "1", + "419": "1", + "425": "1", + "418": "-1", + "421": "1", + "430": "1", + "417": "1", + "429": "1", + "243": "1", + "319": "-2", + "435": "1", + "441": "1", + "434": "-1", + "437": "1", + "446": "1", + "433": "1", + "445": "1", + "267": "-1", + "431": "-1", + "447": "-1" + }, + "fixtures": [ + { + "trial": 0, + "forward_and_inverse_transpose": true, + "streaming_peak_temporaries": 2, + "weighted_accumulations": 4, + "source_copies": 4, + "temporary_discards": 5 + }, + { + "trial": 1, + "forward_and_inverse_transpose": true, + "streaming_peak_temporaries": 2, + "weighted_accumulations": 4, + "source_copies": 4, + "temporary_discards": 5 + } + ], + "optimistic_moment": "0.999971277929646601478394497346102075481621", + "optimistic_profile": { + "1": 2340, + "4": 130, + "3": 414, + "2": 508, + "5": 80, + "8": 7, + "7": 1 + }, + "optimistic_idle": 14274, + "scope": "Four source-stable whole-stream copies at nonnested frame transitions. Exact signed Pauli/global phase checks and two dense Gaussian fixtures in each orientation. The omitted source must be zero and dirty response compensated. Two-stream peak includes query accumulator and one live converted centre copy. Storage, all-size native recursion, nonmonotone owner hosting, full scatter and exact recovery/precision/analytic transfer are unadmitted. Favorable moment grants incompatible deletion/endpoint/hosting credits, not a new bound." +} \ No newline at end of file diff --git a/research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md b/research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md new file mode 100644 index 0000000000..0f587a9f5f --- /dev/null +++ b/research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md @@ -0,0 +1,19 @@ +SPDX-License-Identifier: Apache-2.0 + +Prepared for Rohan Arun with substantial OpenAI Codex assistance. No independent +human review is claimed. This draft is a scoped query-tree witness, not a kappa +record or complete multiplication theorem. + +Credit Ali Romman / PR1134 for the fixed-U8 transport obstruction, favorable +volume accounting, and rational moment checker; PR1060 for the physical P111 +decoder and nonzero-endpoint-last schedule. The vendored PR1134 verifier is +retained byte-for-byte, with only its arithmetic/subspace functions used here; +its original main pipeline is not run or claimed replayed. + +Credit DreamingOfClouds / PR717 and themilkman216 / PR968 for P111 decoder and +copy-cost results; Rohan Arun / PR1297,1319,1485 for current word and endpoint; +Jeremy Kothe, Jeremy Diviney, Thomas DiFiore, Hao Yan, Zhihao Chen / icekylinx, +eumemic, Douglas Colkitt, and the retained geometry/supplier/controller lineage. +See PREDECESSOR-NOTICE.md for the current-word package's retained notices. + +Native interface extension: unchanged exact Clifford compiler, literal Gaussian array executor and transpose helper from PR1060 (head d27499553138bde007f5b1163e65e71da1b18899); original Apache-2.0 code and authorship retained. Source hashes in SOURCES.json and pr1060/SOURCE-RECEIPT.json. This extension verifies only our local query interface. diff --git a/research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md b/research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md new file mode 100644 index 0000000000..0c256b6df0 --- /dev/null +++ b/research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md @@ -0,0 +1,8 @@ +New research prepared by Rohan Arun with substantial OpenAI Codex assistance. Apache-2.0. Parent words and build recipe method derive from Jeremy Kothe PR1274 and Rohan Arun PR1218, with lineage credited in README.md. All inherited mathematical qualifications are retained. +Additional pivot555 and567 composition by Rohan Arun with substantial OpenAI Codex assistance. + +T74 exact-fill owner construction by Rohan Arun with substantial OpenAI Codex assistance. + +PR1377 grid refinement credited to Jeremy Kothe. Outer witness refinement by Rohan Arun with OpenAI Codex assistance; construction unchanged. + +PR1458 finer base-two engine and endpoint refinement: Jeremy Kothe, with oh-my-pi assistance. Further finite64 endpoint and outer refinement: Rohan Arun with OpenAI Codex assistance. Construction unchanged. diff --git a/research/p111-redundant-query-scatter/inputs/word.json.gz b/research/p111-redundant-query-scatter/inputs/word.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..eacf8c773cb50637f93a762342b3b5f0853fe29a GIT binary patch literal 57371 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 Date: Tue, 3 Nov 2026 16:02:58 +0000 Subject: [PATCH 2/2] feat(research): prove sharp retained-query scatter support floor --- .../p111-redundant-query-scatter/PROOF.md | 110 +++++++++ .../p111-redundant-query-scatter/README.md | 147 ++++++++++++ .../p111-redundant-query-scatter/SOURCES.json | 53 +++++ .../p111-redundant-query-scatter/TASK.json | 102 ++++++++ .../p111-redundant-query-scatter/VERIFY.json | 38 +++ .../p111-redundant-query-scatter/oracle.py | 54 +++++ .../p111-redundant-query-scatter/verify.py | 225 ++++++++++++++++++ 7 files changed, 729 insertions(+) create mode 100644 research/p111-redundant-query-scatter/PROOF.md create mode 100644 research/p111-redundant-query-scatter/README.md create mode 100644 research/p111-redundant-query-scatter/SOURCES.json create mode 100644 research/p111-redundant-query-scatter/TASK.json create mode 100644 research/p111-redundant-query-scatter/VERIFY.json create mode 100644 research/p111-redundant-query-scatter/oracle.py create mode 100644 research/p111-redundant-query-scatter/verify.py diff --git a/research/p111-redundant-query-scatter/PROOF.md b/research/p111-redundant-query-scatter/PROOF.md new file mode 100644 index 0000000000..600832f994 --- /dev/null +++ b/research/p111-redundant-query-scatter/PROOF.md @@ -0,0 +1,110 @@ +# A retained four-centre query cannot sparsify this scatter + +This scoped proof was produced by Nick Petalas. Work over the rational +numbers. The same proof holds over the real or complex numbers. It concerns +direct scalar ADD coefficients, with arbitrary coefficients permitted. + +Let c be an arbitrary vector of eight independent centre values in the order +`(60,61,63,224,31,240,23,256)`. Put J=`{61,63,31,256}` and + +```text +q = (c61+c63+c31+c256)/2. +``` + +Let S be the 112-by-8 matrix of the pinned PR1525 word's `cut` array. We +ask for matrices B with nine columns such that + +```text +B (c,q) = S c for every c. +``` + +All eight old readouts are retained. Only their use in this direct scatter +is being optimized. The price of B is its number of nonzero entries. Each +entry denotes one scaled ADD to the corresponding arbitrary dirty output. +No sharing, intermediate accumulator, target mixing or basis change is +included in this price model. Readout acquisition and frames are not free +physical operations merely because the algebra grants their availability. + +## Every exact correction and its cost + +Fix a row a of S. If the coefficient of q in its replacement row is t, +coefficient comparison on the eight independent centre variables forces + +```text +b_j = a_j-t/2 for j in J, +b_j = a_j for j outside J. +``` + +Conversely these coefficients work for every t. This describes every exact +row, without a finite coefficient restriction. In particular no independent +correction freedom is omitted by the following optimization. + +Let z be the number of zero entries of a on J. If t is nonzero, all z of +these entries become nonzero, the query adds one nonzero entry, and the only +cancellations are entries with a_j=t/2. If m(t/2) counts those entries, the +exact increase in row support is + +```text +1+z-m(t/2). +``` + +The finite source census below finds at most two nonzero entries on J in +every row. Thus z>=2 and m(t/2)<=2. Every nonzero query coefficient strictly +increases that row's support, by at least one. A query-free row is forced +to equal a. Since the rows have independent coefficients, the unique +minimum-support B is `[S | 0]`, of support 176. + +If at least one query coefficient must be nonzero, support is at least 177. +Equality is possible exactly by activating one row with z=2 and two equal +nonzero coefficients a_j=t/2, and leaving every other row unchanged. This +also characterizes every matrix attaining 177. + +## Complete finite census and attainment + +Every coefficient of S is 0 or plus/minus 1/4. The checker classifies every +row by its entries on J. The counts and minimum nonzero-query penalties are: + +| Entries on J | Rows | Minimum increase | +|---|---:|---:| +| Four zeros | 40 | 5 | +| One nonzero | 56 | 3 | +| Two equal nonzeros | 8 | 1 | +| Two opposite nonzeros | 8 | 2 | + +For each of the eight equal-pair rows, choose t twice the common coefficient. +The two original nonzero entries disappear, the two previously zero entries +become their negatives, and q adds one term. This gives an exact 177-entry +matrix. The replay reports all eight receiver IDs, and emits one attaining +row's receiver and coefficient. The finite arithmetic census supplies the +source-specific premise; the argument above supplies the quantifier over +every rational coefficient and every exact direct-scatter matrix. + +An independent checker enumerates all 512 subsets of the nine readouts for +each of the 112 rows. It uses exact integer elimination for rational span +membership, without the frequency formula. With q present, a nonzero query +coefficient exists if q is dependent on the selected centres, or, when it +is independent, if a is absent from the selected-centre span. This also +handles zero rows, where query use requires compensating centre terms. +All 57,344 support-subset cases give the same two per-row minima. + +## Dirty values and the precise obstruction + +The matrix identity holds for arbitrary c. Therefore it holds for every +possible prior linear or nonlinear dependence of c on original inputs and +dirty workspace. Adding B(c,q) to arbitrary outputs preserves precisely the +same dirty dependence as adding Sc. No original dirty coefficient has been +discarded, specialized to zero or claimed compensated. The direct ADD program +reads c and q without changing them. Reversing its ADD signs restores the +outputs exactly. This is an algebraic restoration statement. + +The lower bound requires exact equality for every independent centre vector. +Restricted-value inputs or a caller that needs a different output are other +contracts. Shared arithmetic can compute a direct matrix more cheaply than +its nonzero count, so this is not an ADD-circuit lower bound. Multiple new +queries, changed source bases and changing the scatter itself are outside +scope. In particular this result does not reject PR1525's whole research +direction or reprove PR6640's different eight-readout price check. + +The two-zero premise matters. A row with coefficient 1/4 on all four query +centres has four old terms and equals q/2, which has one. The replay includes +this changed-premise positive control. diff --git a/research/p111-redundant-query-scatter/README.md b/research/p111-redundant-query-scatter/README.md new file mode 100644 index 0000000000..06b5f21d3d --- /dev/null +++ b/research/p111-redundant-query-scatter/README.md @@ -0,0 +1,147 @@ +# Sharp support obstruction for the retained P111 line-7 query + +This contribution was produced by Nick Petalas. Claim type: scoped proof +with exact finite corroboration. No new kappa is claimed. + +For the PR1525 puncture-0 scatter, retain all eight independent original +centre readouts and add `q=(c61+c63+c31+c256)/2`. Among every rational +direct-scatter matrix preserving the original map, the unique minimum has +176 nonzero coefficients and ignores q. If q must be used, the exact minimum +is 177. Exactly eight matrices attain that constrained minimum, one for each +receiver in `(112,113,115,119,152,153,179,183)`. + +The new result closes a favorable direct-matrix relaxation of Open next +question 2 in [unpaidmoon's PR6640](https://github.com/CrocSwap/integer-mult-bounds/pull/6640). +The original eight readouts remain available, so this is a changed contract +from substituting q for one centre. It is an obstruction over all rational +coefficients, rather than a failed finite search. The predecessor's 176-entry +scatter is the baseline input, not a new count claimed here. + +The [proof](PROOF.md) characterizes every exact correction. On each row a, +the query coefficient t forces subtraction of t/2 from each of the four +query-centre coefficients. Every source row omits at least two of these +centres. A nonzero t therefore creates at least two new terms, cancels at +most two, and adds its own term. This proves the strict penalty and the +unique unrestricted optimum. Eight equal-pair rows attain penalty one. + +This prices direct coefficients only. General ADD circuits may share +intermediates and have a smaller operation count. A ninth readout also has +acquisition, frame, lifetime and restoration costs that are not priced here. +This result supplies neither a physical scatter nor a complete paid invoice. + +## Evidence and reproduction + +From the repository root, using CPython 3.12 and the standard library: + +```sh +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -W error -B research/p111-redundant-query-scatter/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -O -W error -B research/p111-redundant-query-scatter/verify.py +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/research_package.py --package research/p111-redundant-query-scatter +/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/check_research_commit.py --package research/p111-redundant-query-scatter --check-source-history +``` + +Another CPython 3.12 interpreter may replace the absolute local path. +Direct replay prints `PASS_P111_REDUNDANT_QUERY_SCATTER` in a fresh JSON +receipt bound to all twelve package files. It writes nothing. Registered +normal and optimized checks run the same complete domain with explicit +guards that remain enabled under `-O`. + +The primary checker constructs one attaining matrix and compares all eight +formal centre coefficients of every output. It classifies all 112 rows. +The separate [support oracle](oracle.py) enumerates all 512 readout subsets +for each row, for 57,344 cases, and uses integer elimination over Q rather +than the cancellation-frequency formula. It checks both unrestricted +support and a genuinely nonzero query coefficient. + +Eight centre-basis fixtures use arbitrary nonzero rational dirty targets; +the literal ADD interpreter checks the exact endpoint, unchanged readouts +and reverse restoration. Six controls reject changed query/correction +coefficients, a missing query centre, a false equal-cost claim and invalid +target/denominator inputs. A dense-row positive control reduces four terms +to one and confirms that the two-zero premise is essential. The written +identity gives arbitrary dirty-input coverage; these fixtures corroborate +its implementation. + +## Sources, credit and overlap + +Rohan Arun / rohanarun's [PR1525](https://github.com/CrocSwap/integer-mult-bounds/pull/1525), +head `90d39a5603c7fbfd8d8d957e9732d9b6ebd6317f`, supplies the query and +word. Four source files, including both unchanged predecessor notices, are +retained under `inputs/`. [ORIGINS.json](ORIGINS.json) records their original +paths, Git blobs and SHA256 values. They were first retained at commit +`34ffd44f2d6257e9c2bcfd01970b5fce61113ab2`; [SOURCES.json](SOURCES.json) +pins these ancestor bytes. No unmerged foreign Git object is required. +The checker uses only the source `cut`, centre order and query terms. It +does not execute or validate the predecessor's native, dirty-query or +whole-word verifier. + +Credit unpaidmoon for the question and frozen-interface price screen, and +JoyboyBrian for the earlier triangular identity in Discussion1166 comment +19143427. Credit PR1297/1134/1060 and the retained Rohan Arun, Ali Romman, +DreamingOfClouds, eumemic, geometry, supplier and controller lineage. +Sparse linear representation and rational elimination are classical. +Independent human and formal proof-kernel review are unclaimed. + +Related open work at the overlap checkpoint: + +- PR6640 studies the eight-readout substitution and its physical price. + This theorem optimizes a different, redundant nine-readout direct matrix. +- PR1525 supplies the underlying query and leaves a physical continuation + open. This local obstruction does not settle that larger question. +- PR1900 constructs five plane queries on the P111 boundary. That changes + both factors and is outside this single retained-query model. +- PR3045 and PR2832 concern fitting-matrix decoder rank floors and global + decoder reductions. Neither is a direct coefficient-support objective + for the fixed centre query here. + +The live overlap cache covered 613 open PRs and 6,708 Discussion records. +Its sparse local scan covered 127 of 8,917 note paths; main-branch README +searches supplemented it. Closed PR and recent account searches were also +used. This is a stated search scope, not proof of literature novelty. + +The joint-query-controller card is refined to this algebraic relaxation. +The pinned catalogue is revision 8 at canonical main +`7c49fe32c55de02c2c873655c804b16e4c3fef0a`. The selected record identifies +PR6030; historical priority prose retains an older checkpoint. The selected +frontier is unchanged. + +## Limits and implementation constraints + +The theorem requires the same exact output map for all independent centre +values and all 112 original cut rows. Omitting a punctured or unused output +changes the consumer contract. Restricted-value inputs, shared intermediate arithmetic, changed +bases, other queries and a changed consumer remain outside scope. Native +frames, query acquisition, independent dirty-state compensation, physical +mixing, owner lifetimes, complete restoration costs, precision/tape, +compiler closure and a complete supplier invoice remain unproved. The five +framework assumptions remain. No selected cold replay, Lean or Docker run +is claimed. + +The new checker has no recursion, network access or subprocesses. Every loop +uses a finite bound: 112 rows, eight centre coordinates, nine readouts, +512 support subsets, at most four cancellation candidates and at most +1,024 source cut events. Elimination has at most ten rows and eight columns. +Compressed/file reads are capped at one MiB and expanded word bytes at two +MiB. Functions fit within 60 physical lines. Warning-strict normal and +optimized commands are the available diagnostics; no new static-analysis +dependency is added. + +Power-of-ten rule 3 deviation: CPython allocates managed integers, Fractions +and containers during the bounded one-shot replay. Fixed runtime allocation +is not available. The finite domains and byte limits above bound live +resources; context managers close files on success and failure. A fixed +allocation implementation would need a separate runtime if required. +Rule 9 deviation: the rejection helper dispatches only six statically named +local control calls. Each has a fixed fixture, and unexpected exceptions +propagate. All six rejection paths run in both registered modes. + +## Open next questions + +Can shared intermediate arithmetic exploit this query after its actual +acquisition, frame and restoration costs are charged? A useful first step +is one explicit chronological shared-accumulator scatter with the same eight +centres and q, followed by a complete price for its readouts and temporaries. +A physical nine-readout caller and legal lifetime/restoration contract are +the blockers. No wider construction search is reserved here. + +New work is Apache-2.0. Source notices are retained unchanged. diff --git a/research/p111-redundant-query-scatter/SOURCES.json b/research/p111-redundant-query-scatter/SOURCES.json new file mode 100644 index 0000000000..1e026e86cd --- /dev/null +++ b/research/p111-redundant-query-scatter/SOURCES.json @@ -0,0 +1,53 @@ +{ + "schema_version": 1, + "base_commit": "7c49fe32c55de02c2c873655c804b16e4c3fef0a", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "d59b5035e7b4cbaa9d688a1d32dd0d6eb79c466a", + "sha256": "9b8d0eea95b3bf0dfcb7938a732a6439b87a2685dec2a5ab9e525b3b34debbfa" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "3404fbdd5e7529a0674eef26114b5071e4586cec", + "sha256": "ead6cdc9d0af6d58e8a49744d8ec8c7c15e13d2ba93c276c434bcf9b51b93a81" + }, + { + "path": "research/p111-redundant-query-scatter/ORIGINS.json", + "usage": "input", + "pin": "head:34ffd44f2d6257e9c2bcfd01970b5fce61113ab2:research/p111-redundant-query-scatter/ORIGINS.json", + "git_blob": "bb898f02db1ed6fb4b04836e3f8f6832a254f2e9", + "sha256": "2222abdd0dde549bdc118ae29b6e039f79ed2b422f8112f029f1a6eebea8ad7b" + }, + { + "path": "research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json", + "usage": "input", + "pin": "head:34ffd44f2d6257e9c2bcfd01970b5fce61113ab2:research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json", + "git_blob": "d5bea849fdde3bb43d38ff44d7b5a2c34e754954", + "sha256": "228e178662fc01895bbcd8472a52114d3a3d11ea8c7ae44d99cd1c8cf9e89147" + }, + { + "path": "research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md", + "usage": "input", + "pin": "head:34ffd44f2d6257e9c2bcfd01970b5fce61113ab2:research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md", + "git_blob": "0f587a9f5fc2394ebaca23f5ce9a25f039b12170", + "sha256": "15bcaa301ca2513b03809c18731051368daf40a8cf93f86441da30608a1a6a3e" + }, + { + "path": "research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md", + "usage": "input", + "pin": "head:34ffd44f2d6257e9c2bcfd01970b5fce61113ab2:research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md", + "git_blob": "0c256b6df08327b4955e46fc34a3ef69f4c63205", + "sha256": "4c7ff8b40efb09d549d65ae59db04d99f24ae5d6ce4bc67f195b859484c3cb7c" + }, + { + "path": "research/p111-redundant-query-scatter/inputs/word.json.gz", + "usage": "input", + "pin": "head:34ffd44f2d6257e9c2bcfd01970b5fce61113ab2:research/p111-redundant-query-scatter/inputs/word.json.gz", + "git_blob": "eacf8c773cb50637f93a762342b3b5f0853fe29a", + "sha256": "e8e6e78ff7422275c38324499e1f33fb2ecd30de9503aef2b8f1ee80d8c4df8e" + } + ] +} diff --git a/research/p111-redundant-query-scatter/TASK.json b/research/p111-redundant-query-scatter/TASK.json new file mode 100644 index 0000000000..f52d7e1156 --- /dev/null +++ b/research/p111-redundant-query-scatter/TASK.json @@ -0,0 +1,102 @@ +{ + "schema_version": 1, + "task_id": "joint-query-controller", + "priority_revision": 8, + "base_commit": "7c49fe32c55de02c2c873655c804b16e4c3fef0a", + "original_card": { + "id": "joint-query-controller", + "question": "Can a changed query demand or caller remove real work while satisfying native chronology and restoration?", + "starting_points": [ + "docs/research/current-priorities.md", + "docs/research/research-family-status.md", + "certificates/selected-result.json", + "docs/research/pr-intake-evidence/pr5599-completion/PROOF-REVIEW.md" + ], + "methods": [ + "Construct and independently check one source-bound instance of the stated first experiment.", + "Seek an exact counterexample or target-specific complete-budget obstruction to that same proposed change." + ], + "acceptance_gate": "A source-bound arbitrary-input identity and legal producer/consumer boundary with the complete paid and productive target invoice, including restoration, ownership, native alignment and extra charges. Price under the actual current model; historical ceiling.py assumptions must be established before use. A favorable optimistic relaxation keeps a route open but is not a completed supplier. A scoped local result remains useful; expansion requires the family-level budget gate.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_selected_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read revision 8, the selected review and live exact-source handoffs. Then follow this card's bounded first_experiment.", + "scope": "Source-bound orientation only, not a supplier replay or theorem proof." + }, + "first_experiment": "Choose an exact caller and a new demand/interface hypothesis. Read the scoped #5617/#5631/#5649/#5747 and #5720/#5745 objections before rebuilding an excluded schedule. Compare the complete matched source/consumer protocols including all retained helper outputs. For an active-mode injection, first check #5745: its canonical delivery claim repays the eight removed centre jobs. Audit that exact claim or change its channel/feedback hypothesis; do not repeat the same free-injection search. Stop if the full favorable budget fails or the required restored output is unobservable.", + "bottleneck_link": "Judge the actual current supplier contract and complete signed target/paid bill; frozen-profile ceilings require an applicability proof.", + "allowed_variations": [ + "One exact source head, helper/cut region or quantified proposition and changed hypothesis; check live handoffs first. Different seeds are not different scopes." + ], + "scope_change_triggers": [ + "Changing source head, helper/cut domain, operation alphabet or caller boundary without recording the new scope.", + "Treating an archived proposal or local numerical pass as complete supplier admission." + ], + "overlap_terms": [ + "query demand", + "active mode", + "5720", + "5745", + "5747", + "caller" + ], + "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": "Selected PR5599: complete helper-subspace construction and independent caller replay; five framework assumptions remain.", + "evidence": "docs/research/pr-intake-evidence/pr5599-completion/PROOF-REVIEW.md", + "remaining": "The next experiment must identify uncovered source-specific work. Successor archive intake does not transfer this admission.", + "status": "reviewed", + "source_commit": "09dd0965711ca7eeb169057a420abab1c9052137", + "selected_record_sha256": "2a0220e866417774606e0f991e41b9c1d26b1f43b97857238cf478dbc7d330b5" + } + ] + }, + "scope_status": "refined", + "actual_scope": "Prove the sharp direct-scatter coefficient-support optimum for the fixed PR1525 puncture-0 query when all eight original independent centre readouts are retained alongside the query. The unique unrestricted optimum ignores the query and has 176 coefficients; requiring query use has exact optimum 177 and eight attaining matrices.", + "scope_change_reason": "The caller question is restricted to an algebraic nine-readout relaxation. This grants additional readout availability and optimizes direct matrix support, not shared circuit complexity or physical delivery.", + "bottleneck_link": "Rules out direct matrix sparsification by this single added query, even under favorable retained-readout availability. A useful continuation must change basis, share intermediate arithmetic, add other queries or change the consumer; no supplier improvement follows.", + "budget_minutes": 60, + "stop_rule": "Stop at the first exact sparse-scatter optimum and attaining witness; package it without expanding the mechanism.", + "outcome": "negative-result", + "evidence": "PROOF.md and freshly generated verify.py output; 112 rows, 57344 support-subset cases, 8 dirty-basis endpoint/inverse cases and 6 rejecting controls.", + "author": "Nick Petalas", + "ai_assistance": "Independent human and formal proof-kernel review are unclaimed.", + "open_questions": [ + { + "question": "Can shared intermediate arithmetic exploit this query after its actual acquisition, frame and restoration costs are charged?", + "why_it_matters": "The direct support obstruction does not bound general ADD circuits, which can share computations across rows.", + "first_step": "Give one explicit chronological shared-accumulator scatter with the same eight original centre values and q, then price the extra readout and every temporary.", + "blocked_by": "A physical nine-readout caller, legal frames, availability, restoration and complete paid invoice are absent." + } + ], + "predecessors": [ + { + "pr": 6640, + "author": "unpaidmoon", + "role": "Open next question 2 and frozen triangular price context; not replayed" + }, + { + "pr": 1525, + "author": "Rohan Arun / rohanarun", + "head": "90d39a5603c7fbfd8d8d957e9732d9b6ebd6317f", + "role": "Fixed centre query and cut matrix; four exact source files retained" + }, + { + "discussion_comment": 19143427, + "author": "JoyboyBrian", + "role": "Earlier triangular identity; cited context only" + } + ] +} diff --git a/research/p111-redundant-query-scatter/VERIFY.json b/research/p111-redundant-query-scatter/VERIFY.json new file mode 100644 index 0000000000..71dff5031c --- /dev/null +++ b/research/p111-redundant-query-scatter/VERIFY.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/p111-redundant-query-scatter/ORIGINS.json", + "research/p111-redundant-query-scatter/inputs/CENTRE-SEED.json", + "research/p111-redundant-query-scatter/inputs/PR1525-NOTICE.md", + "research/p111-redundant-query-scatter/inputs/PR1525-PREDECESSOR-NOTICE.md", + "research/p111-redundant-query-scatter/inputs/word.json.gz" + ], + "commands": [ + { + "argv": [ + "{python}", + "-W", + "error", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Complete exact support optimization, 57344 subset-span oracle cases, formal identity, dirty endpoints/inverses, six rejecting controls and dense positive control" + }, + { + "argv": [ + "{python}", + "-O", + "-W", + "error", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Same complete evidence with Python assertions disabled; guards remain explicit" + } + ] +} diff --git a/research/p111-redundant-query-scatter/oracle.py b/research/p111-redundant-query-scatter/oracle.py new file mode 100644 index 0000000000..1559bb6094 --- /dev/null +++ b/research/p111-redundant-query-scatter/oracle.py @@ -0,0 +1,54 @@ +"""Exhaust readout supports using exact rational ranks. + +This checker does not use the row-frequency optimization in verify.py. +Produced by Nick Petalas. Apache-2.0. +""" + + +def rank(rows): + """Fraction-free elimination with at most ten rows of length eight.""" + if len(rows) > 10 or any(len(row) != 8 for row in rows): + raise ValueError("rank domain is at most 10 by 8") + work = [list(row) for row in rows] + used = 0 + for col in range(8): + pivot = next((i for i in range(used, len(work)) if work[i][col]), None) + if pivot is None: + continue + work[used], work[pivot] = work[pivot], work[used] + for i in range(used + 1, len(work)): + multiplier = work[i][col] + if multiplier: + value = work[used][col] + work[i] = [value * a - multiplier * b + for a, b in zip(work[i], work[used], strict=True)] + used += 1 + return used + + +def support_oracle(rows, query_slots): + """Return each row's unrestricted and genuinely-query-using minima.""" + if len(rows) != 112 or len(query_slots) != 4: + raise ValueError("oracle requires 112 rows and four query slots") + vectors = [tuple(int(i == j) for i in range(8)) for j in range(8)] + vectors.append(tuple(int(i in query_slots) for i in range(8))) + supports = [] + for mask in range(512): + old = [vectors[i] for i in range(8) if mask >> i & 1] + full = old + ([vectors[8]] if mask >> 8 & 1 else []) + supports.append((mask.bit_count(), old, full, rank(old), rank(full))) + answers = [] + for row in rows: + best, active = 10, 10 + for mask, (cost, old, full, old_rank, full_rank) in enumerate(supports): + if rank(full + [row]) != full_rank: + continue + best = min(best, cost) + if mask >> 8 & 1: + # Dependent q admits any coefficient. Otherwise it is forced. + if full_rank == old_rank or rank(old + [row]) > old_rank: + active = min(active, cost) + if best == 10 or active == 10: + raise AssertionError("dictionary must span every row") + answers.append((best, active)) + return answers, 112 * 512 diff --git a/research/p111-redundant-query-scatter/verify.py b/research/p111-redundant-query-scatter/verify.py new file mode 100644 index 0000000000..71801e8be4 --- /dev/null +++ b/research/p111-redundant-query-scatter/verify.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +"""Sharp direct-scatter support obstruction for one retained P111 query. + +Produced by Nick Petalas. Apache-2.0. +""" +import gzip +import hashlib +import io +import json +import platform +import sys +from collections import Counter +from fractions import Fraction as Q +from pathlib import Path + +from oracle import support_oracle + +ROOT = Path(__file__).resolve().parent +CENTRES = (60, 61, 63, 224, 31, 240, 23, 256) +QUERY_CENTRES = (61, 63, 31, 256) +FILES = ( + "README.md", "PROOF.md", "TASK.json", "SOURCES.json", "VERIFY.json", + "verify.py", "oracle.py", "ORIGINS.json", "inputs/word.json.gz", + "inputs/CENTRE-SEED.json", "inputs/PR1525-NOTICE.md", + "inputs/PR1525-PREDECESSOR-NOTICE.md", +) + + +def need(condition, message): + if not condition: + raise AssertionError(message) + + +def read_bytes(name): + with (ROOT / name).open("rb") as handle: + raw = handle.read(1_048_577) + need(len(raw) <= 1_048_576, "file size bound: " + name) + return raw + + +def read_inputs(): + origins = json.loads(read_bytes("ORIGINS.json"))["files"] + need(len(origins) == 4, "four retained source files") + for name, origin in origins.items(): + need(name in {Path(f).name for f in FILES if f.startswith("inputs/")}, + "unexpected source path") + raw = read_bytes("inputs/" + name) + need(hashlib.sha256(raw).hexdigest() == origin["sha256"], "source hash") + blob = b"blob " + str(len(raw)).encode("ascii") + b"\0" + raw + need(hashlib.sha1(blob).hexdigest() == origin["git_blob"], "source blob") + raw = read_bytes("inputs/word.json.gz") + need(hashlib.sha256(raw).hexdigest() == + "e8e6e78ff7422275c38324499e1f33fb2ecd30de9503aef2b8f1ee80d8c4df8e", + "fixed PR1525 word") + with gzip.GzipFile(fileobj=io.BytesIO(raw)) as handle: + expanded = handle.read(2_097_153) + need(len(expanded) <= 2_097_152, "decompressed word bound") + word = json.loads(expanded) + seed_raw = read_bytes("inputs/CENTRE-SEED.json") + need(hashlib.sha256(seed_raw).hexdigest() == + "228e178662fc01895bbcd8472a52114d3a3d11ea8c7ae44d99cd1c8cf9e89147", + "fixed PR1525 query seed") + seed = json.loads(seed_raw) + need(word["centers"] == list(CENTRES), "centre order") + terms = seed["terms"] + need(seed["puncture"] == 0 and len(terms) == 4, "query domain") + need(tuple(t["center"] for t in terms) == QUERY_CENTRES, "query support") + need(all(Q(t["weight"]) == Q(1, 2) for t in terms), "query weights") + return word + + +def scatter(word): + events = word["cut"] + need(isinstance(events, list) and len(events) <= 1024, "cut bound") + result = [[Q(0) for _ in range(8)] for _ in range(112)] + for event in events: + need(isinstance(event, list) and len(event) == 6, "cut event shape") + op, target, source, numerator, denominator, frame = event + need(op == "add" and frame is None, "cut event kind") + need(type(target) is int and 112 <= target < 224, "output role") + need(type(source) is int and source in CENTRES, "centre role") + need(type(numerator) is int and numerator in (-1, 1), "numerator") + need(type(denominator) is int and denominator == 4, "denominator") + result[target - 112][CENTRES.index(source)] += Q(numerator, denominator) + need(all(value in (Q(-1, 4), Q(0), Q(1, 4)) + for row in result for value in row), "quarter-grid scatter") + return result + + +def corrected(row, coefficient, slots): + return [value - coefficient / 2 if j in slots else value + for j, value in enumerate(row)] + [coefficient] + + +def nnz(row): + return sum(value != 0 for value in row) + + +def row_optimum(row, slots): + # All exceptional cancellation points, plus zero and one generic point. + candidates = {Q(0), Q(1)} | {2 * row[j] for j in slots if row[j]} + need(len(candidates) <= 4, "bounded candidate set") + costs = [(nnz(corrected(row, t, slots)), t) for t in sorted(candidates)] + best = min(cost for cost, _ in costs) + active = min((cost, t) for cost, t in costs if t) + need([t for cost, t in costs if cost == best] == [Q(0)], + "unique optimum must ignore query") + return best, active + + +def check_identity(original, replacement, slots): + need(len(original) == len(replacement) == 112, "matrix rows") + for old, new in zip(original, replacement, strict=True): + need(len(old) == 8 and len(new) == 9, "matrix columns") + actual = [new[j] + new[8] / 2 if j in slots else new[j] + for j in range(8)] + need(actual == old, "exact formal centre identity") + + +def execute(matrix, centres, targets, reverse=False): + need(len(centres) == 9 and len(targets) == 112, "execution domain") + output = targets[:] + sign = -1 if reverse else 1 + for i, row in enumerate(matrix): + for value, source in zip(row, centres, strict=True): + if value: + output[i] += sign * value * source + return output + + +def expect_failure(action): + try: + action() + except (AssertionError, ValueError): + return + raise AssertionError("control was accepted") + + +def controls(rows, witness, slots): + bad = [row[:] for row in witness] + chosen = next(i for i, row in enumerate(bad) if row[8]) + bad[chosen][8] = 0 + expect_failure(lambda: check_identity(rows, bad, slots)) + bad = [row[:] for row in witness] + bad[chosen][slots[0]] += Q(1, 4) + expect_failure(lambda: check_identity(rows, bad, slots)) + expect_failure(lambda: check_identity(rows, witness, slots[:-1])) + expect_failure(lambda: need(sum(nnz(row) for row in witness) == 176, + "query use increases support cost")) + # Without the two-zero premise a query really can save terms. + dense = [Q(1, 4) if j in slots else Q(0) for j in range(8)] + need(nnz(corrected(dense, Q(1, 2), slots)) == 1 < nnz(dense), + "dense changed-contract positive control") + expect_failure(lambda: scatter({"cut": [["add", 111, 61, 1, 4, None]]})) + expect_failure(lambda: scatter({"cut": [["add", 112, 61, 1, 0, None]]})) + return 6 + + +def analyze(rows, slots): + types, minima, active, witnesses = Counter(), [], [], [] + for i, row in enumerate(rows): + values = [row[j] for j in slots if row[j]] + need(len(values) <= 2, "at least two absent query centres in each row") + kind = ("zero" if not values else "single" if len(values) == 1 + else "same" if values[0] == values[1] else "opposite") + types[kind] += 1 + best, (cost, t) = row_optimum(row, slots) + minima.append(best) + active.append(cost) + if cost - best == 1: + witnesses.append((i, t)) + need(types == {"zero": 40, "single": 56, "same": 8, "opposite": 8}, + "complete row census") + need(sum(minima) == 176 and len(witnesses) == 8, "exact optima") + need(Counter(b - a for a, b in zip(minima, active, strict=True)) + == {1: 8, 2: 8, 3: 56, 5: 40}, "all row activation penalties") + integers = [[int(4 * value) for value in row] for row in rows] + answers, cases = support_oracle(integers, slots) + need(answers == list(zip(minima, active, strict=True)), "support oracle") + return types, witnesses, cases + + +def dirty_checks(rows, matrix, slots): + for column in range(8): + centres = [Q(int(j == column)) for j in range(8)] + query = sum(centres[j] for j in slots) / 2 + dirty = [Q((7 * j) % 23 - 11, j % 5 + 1) for j in range(112)] + readouts = centres + [query] + saved = readouts[:] + output = execute(matrix, readouts, dirty) + expected = [dirty[j] + rows[j][column] for j in range(112)] + need(output == expected and readouts == saved, "dirty endpoint") + need(execute(matrix, readouts, output, reverse=True) == dirty, + "literal reverse ADD restoration") + need(readouts == saved, "reverse readout restoration") + + +def main(): + rows = scatter(read_inputs()) + slots = tuple(CENTRES.index(c) for c in QUERY_CENTRES) + types, witnesses, cases = analyze(rows, slots) + matrix = [row + [Q(0)] for row in rows] + index, coefficient = witnesses[0] + matrix[index] = corrected(rows[index], coefficient, slots) + check_identity(rows, matrix, slots) + need(sum(nnz(row) for row in matrix) == 177, "attaining forced-query matrix") + dirty_checks(rows, matrix, slots) + rejected = controls(rows, matrix, slots) + receipt = { + "status": "PASS_P111_REDUNDANT_QUERY_SCATTER", "claim_type": "scoped proof", + "unrestricted_minimum": 176, "query_used_minimum": 177, + "query_free_optimum_unique": True, "row_types": dict(types), + "optimal_query_receivers": [112 + i for i, _ in witnesses], + "witness_receiver": 112 + index, + "witness_query_coefficient": str(coefficient), + "support_subsets_checked": cases, "rejection_controls": rejected, + "dirty_basis_cases": 8, "dense_scope_control": "4 terms to 1", + "python": sys.version, "platform": platform.platform(), "no_new_kappa": True, + "sha256": {name: hashlib.sha256(read_bytes(name)).hexdigest() for name in FILES}, + } + print(json.dumps(receipt, indent=2, sort_keys=True)) + + +if __name__ == "__main__": + main()