From e5e514176f100a3ca0c4a6c217765593430062e7 Mon Sep 17 00:00:00 2001 From: CubeJerry <80299683+CubeJerry@users.noreply.github.com> Date: Wed, 28 Oct 2026 19:24:01 +0800 Subject: [PATCH] Bound every first-read G20 helper subset with an exact flag certificate Prepared for @CubeJerry with substantial OpenAI Codex assistance. No new kappa; fixed PR5708 word and individual first-read schedule only. --- .../PARTITION.json.gz | Bin 0 -> 47531 bytes .../g20-joint-capture-flag-bound/PROOF.md | 183 +++++++++++++++++ .../g20-joint-capture-flag-bound/README.md | 118 +++++++++++ .../g20-joint-capture-flag-bound/RESULT.json | 162 +++++++++++++++ .../g20-joint-capture-flag-bound/SOURCES.json | 36 ++++ .../g20-joint-capture-flag-bound/TASK.json | 157 +++++++++++++++ .../g20-joint-capture-flag-bound/VERIFY.json | 35 ++++ .../g20-joint-capture-flag-bound/discover.py | 121 ++++++++++++ .../g20-joint-capture-flag-bound/model.py | 180 +++++++++++++++++ .../g20-joint-capture-flag-bound/verify.py | 187 ++++++++++++++++++ 10 files changed, 1179 insertions(+) create mode 100644 research/g20-joint-capture-flag-bound/PARTITION.json.gz create mode 100644 research/g20-joint-capture-flag-bound/PROOF.md create mode 100644 research/g20-joint-capture-flag-bound/README.md create mode 100644 research/g20-joint-capture-flag-bound/RESULT.json create mode 100644 research/g20-joint-capture-flag-bound/SOURCES.json create mode 100644 research/g20-joint-capture-flag-bound/TASK.json create mode 100644 research/g20-joint-capture-flag-bound/VERIFY.json create mode 100644 research/g20-joint-capture-flag-bound/discover.py create mode 100644 research/g20-joint-capture-flag-bound/model.py create mode 100644 research/g20-joint-capture-flag-bound/verify.py diff --git a/research/g20-joint-capture-flag-bound/PARTITION.json.gz b/research/g20-joint-capture-flag-bound/PARTITION.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..3dcd98fa7ba0dc604e6f9ea199ff4112c067fd60 GIT binary patch literal 47531 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. For subsets of P alone it is only a +non-improvement bound, consistent with the predecessor's neutral helper 684. +No new κ. This is a written proof with an exact finite certificate, not a +formalization of the multiplication theorem or enumeration of payload guesses. + +## 1. Necessary parity equations + +A native address permutation fixes the constant-one function. Evaluation on +constant input functions therefore sends a finite F2 sum of native terms to +the parity of its input labels: ADD becomes XOR, Q/ZERO_Q preserve the row, +and ERASE zeros it. This is the augmentation homomorphism of the native +operator algebra. Native zero implies projected zero; the converse is unused. + +Original owned inputs are zero. The census temporarily gives them independent +labels and checks that none appears in any of the 2,846 paid query rows, so +discarding those labels changes none of the certificate rows. Every paid row +is nonzero. Frame chronology, query ranks and the published paid profile are +checked, but native operator identities and endpoints are not reproved. + +## 2. First reads give a graph kernel + +Let V have the 637 original non-owned input labels as basis. Before helper h's +first source read, its label x_h has never left that wire. Its projected base +value is `x_h + a_h`, with no still-unread helper label in a_h. + +Process captures chronologically. Define L to fix retained inputs. At h's +capture set `L(x_h)=f_h=w_h+L(a_h)`, where w_h is its projected injected payload. +All labels in a_h are retained or belong to earlier captures, so f_h uses +retained inputs only. Outside a chosen helper's held-zero prefix, its modified +projected value is L of its base value. Indeed, a held-zero helper has no +outgoing ADD, so dropping its writes affects no other wire; the capture +equation establishes agreement at first read, and subsequent operations +preserve it. This induction holds for every subset and payload. + +Thus `R=ker L` has basis `{x_h+f_h : h in H}` and projection R→coordinates H +is an isomorphism. Every removed query outside an owned held-zero prefix has +its base row in R. + +Partition helpers into P, F, O. P is the two partial helpers. F is the 180 +rank-8 helpers with an early own rank-2 query. O is the other 233 rank-8 +helpers. The census checks at most one early own query per helper, of rank 1 +or 2, and none for P. Write dP=|H∩P|, and similarly dF,dO. The graph property +implies + +\[ +\dim R=d_P+d_F+d_O,\quad +\dim(R\cap\{v_P=0\})\leq d_F+d_O,\quad +\dim(R\cap\{v_P=v_F=0\})\leq d_O. +\] + +Indeed, projection onto H is injective and the indicated coordinates vanish; +zeros on retained helper coordinates can only lower these dimensions further. +These stronger bounds distinguish cheap partial targets and costly early +frees; an unweighted |H|-only bound does not use them. + +## 3. Cover early cross-helper effects + +Grant held-zero-prefix savings separately, at most `2^t dF + dO`. This even +grants an H1 to each of O's 111 helpers without an early query. Other removed +queries must contain a helper label, since L fixes non-helper inputs. + +An early query on an unchosen helper can disappear through a *different* +chosen helper. Keep an early query in the token census whenever its row +contains another helper label. These three events (zero-based) qualify: + +| Event | Destination | Rank | Helper-label support | +| --- | ---: | ---: | --- | +| 6231 | 467 | 1 | 274, 467 | +| 6291 | 297 | 1 | 297, 465 | +| 6510 | 464 | 1 | 323, 464 | + +Other early own queries can be omitted: if their destination is chosen they +are already granted free; otherwise L fixes their nonzero row. Double counting +a cross-helper query in the free allowance and token bound is harmless for an +upper bound. This leaves **2,216 eligible queries and 1,945 distinct rows**. +PR6113's printed census had 2,213: the three-query difference is intentional +coverage, not a claim that its numerical pair results are false. A negative +control omits event 6291's tokens and must fail exact coverage. + +## 4. The finite flag certificate + +For query ranks r=1,2,3,4,5,6 use respectively m(r)=17,33,49,64,80,96 copies +of the row. Throughout the stated interval, `r^t <= m(r)4^t/64`. For r<4, +`(r/4)^t` is largest at t=99/100; integer inequalities +`r^99 64^100 <= 4^99 m(r)^100` certify the claim. For r>=4 use +`(r/4)^t <= r/4 = m(r)/64`. No floating-point acceptance is used. + +`PARTITION.json.gz` partitions all **64,274 tokens into 108 colors**: + +| Colors (zero based) | Count | Allowed rows | +| --- | ---: | --- | +| 0–63 | 64 | unrestricted | +| 64–91 | 28 | zero on P | +| 92–107 | 16 | zero on P and F | + +Each color is F2-linearly independent. Rows are reconstructed from the word; +every token multiplicity and flag is checked, and independence is checked by +both highest-pivot and lowest-pivot elimination. IDs are the increasing integer +order of distinct eligible rows. The witness suffices; no optimality or search +completeness claim is made about the discovery algorithm. + +An independent set meets a subspace in at most its dimension. Summing the +three graph-kernel dimension bounds across colors yields + +\[ +\text{non-prefix savings}\leq4^t +\left(d_P+\frac{92}{64}d_F+\frac{108}{64}d_O\right). +\] + +This single certificate covers all `2^415` ownership sets. They are not +enumerated, and 108 is not asserted to be the minimum number of colors. + +## 5. Optimistic complete budget + +Lost target credit is `4^t dP + 8^t(dF+dO)`. Add prefix savings and subtract +that debit: + +\[ +\Delta\leq4^t\left[ +\left(\frac{92}{64}+2^{-t}-2^t\right)d_F+ +\left(\frac{108}{64}+4^{-t}-2^t\right)d_O\right]. +\] + +Exact integer powers establish, on the full interval, +`2^t > 127/64`, `2^(-t) < 65/128`, and `4^(-t) < 33/128`. +For example the first is checked at the lower endpoint by +`2^99 64^100 > 127^100`; the reciprocal inequalities are checked similarly. +Both coefficients are strictly below -5/128: +`184+65-254=-5` and `216+33-254=-5`. This proves the statement. Charging actual +setup, source reads, frame changes, copies, erasure, restoration or recursive +children cannot reverse this failed optimistic budget if they add nonnegative +charges without changing the stipulated word or contract. + +## Limits and evidence status + +This closes the larger-set question for **individual first-read schedules on +this exact word**, including both partial helpers. Joint deadness can permit +later capture after a helper has influenced other wires; then a single entry +substitution need not apply. Changed words, other input subspaces, unrestricted +non-native-linear payload operators and other exponents remain outside scope. + +The projection implication and triangular argument are written mathematics, +not Lean proofs. Seven deterministic payload/subset fixtures exercise the +lemma but do not prove it. Two row representations and opposite elimination +pivots reduce implementation dependence; they are not external peer review. +The native/adjoint endpoint and complete caller were not replayed. No recursive +supplier was built, and the selected theorem's native, owned-erasure, compiler, +precision/tape and analytic-recovery assumptions remain unchanged. diff --git a/research/g20-joint-capture-flag-bound/README.md b/research/g20-joint-capture-flag-bound/README.md new file mode 100644 index 0000000000..f759de119a --- /dev/null +++ b/research/g20-joint-capture-flag-bound/README.md @@ -0,0 +1,118 @@ +# All-subset bound for G20 first-read helper captures + +**No new κ.** On the exact PR5708 word, simultaneous first-read capture of +**any subset of all 415 retained helpers** cannot improve the local BIT signed +moment for `0 <= C <= 0.01` (`t=1-C`). This includes the 180 helpers with an +early rank-2 query and both partial rank-4 helpers. Every captured rank-8 +helper loses strictly more than `(5/128)*4^t` in the optimistic bill. Subsets +containing only partial helpers have gain at most zero. + +The result grants arbitrary native-linear injected payloads and free setup, +source access and restoration. It closes a fixed-schedule larger-set question +left by [PR6113](https://github.com/CrocSwap/integer-mult-bounds/pull/6113), so +further work on this mechanism must change that schedule or another stated +premise. It is a scoped negative result, not an improved supplier or a general +impossibility theorem. + +## Evidence and what is new + +[PROOF.md](PROOF.md) reduces capture to an entry substitution on constant-input +parities. Its kernel projects injectively onto captured coordinates. A new +**flag-constrained weighted partition** respects three different helper tariffs: +64 unrestricted independent colors, 28 avoiding partial-helper coordinates, +and 16 also avoiding early-rank-2 coordinates. This prices all subsets without +enumerating their payloads. Exact integer powers extend the comparison over +the full exponent interval; there is no floating-point acceptance decision. + +[PARTITION.json.gz](PARTITION.json.gz) covers 64,274 tokens from 2,216 queries +and 1,945 rows. In particular it includes three cross-helper early queries +(6231, 6291, 6510) that cannot simply be excluded from a uniform token census. +[RESULT.json](RESULT.json) records the exact counts and row digest. + +PR6113 supplied the native-payload/individual-capture model, single/pair census +and an unweighted token bound, but explicitly left larger sets with multiple +rank-2 frees open. Its numerical pair findings are not contradicted here. +PR5604's entry-subspace capacity bound concerned a different, static model +and older word. This package adds a dynamic first-read graph-kernel argument, +a tariff-sensitive certificate covering all helper sets, and exact uniform +moment inequalities. No predecessor implementation is imported. + +## Reproduce + +From the repository root, using Python 3.12 and only its standard library: + +```sh +python3.12 -B scripts/research_package.py --package research/g20-joint-capture-flag-bound +``` + +Both normal and explicit isolated optimized runs must print +`PASS_G20_ALL_SUBSET_FIRST_READ_FLAG_BOUND`. Each run authenticates the three +live inputs, checks all 14,794 events, compares integer-mask and set replays, +checks every token and both Gaussian-elimination directions, verifies seven +entry-substitution fixtures, and rejects eight corruptions: omitted tokens, +duplicate/dependent color rows, both wrong flags, omitted cross-helper event +6291, a forged query rank and changed source bytes. The fixtures support the +written lemma; they are not a proof by exhaustive testing. + +The optional deterministic discovery command is separate from verification: + +```sh +python3.12 -B research/g20-joint-capture-flag-bound/discover.py /tmp/g20-partition.json.gz +``` + +It stops at the first verified 108-color partition, a 1,200-second deadline, +or exhaustion of its augmenting-path search. A timeout/failure is not an +impossibility claim. Reproduction compares decompressed JSON, not gzip bytes. +The successful discovery used 2,062 augmentations after the greedy stage. +The verifier requires neither discovery nor any third-party solver. + +## Pins, boundaries and coordination + +Scientific and branch base: `721c03822c421b7f7fcbb2598993b947c4d88419`. +[SOURCES.json](SOURCES.json) pins the exact word, frames and local invoice by +Git blob and SHA256. Historical predecessor heads are PR5708 +`829d01fc031f7323ffcfa423fdfd1f24dcbe3190`, PR6113 +`f6712095d07d555969b6e67b792a0e98e8eea8d3`, and PR5604 +`b7c27a263b9e57d4e04b5e2dcb7b3199cc8c4170`. PR6113 is a credited research +lead, not a live executable dependency. The selected certificate at the base +is PR6030, conditional κ=781451/250000000; no selected record is changed. + +Only first-read individual capture schedules, coordinate ownership, native +permutation-linear payloads and this exponent interval are covered. Later +joint-dead captures, changed words and other input contracts remain open. +Native/adjoint endpoints, the complete caller and recursive construction were +not replayed. The selected theorem's native, owned-erasure, compiler, +precision/tape and analytic-recovery assumptions are unchanged. This is an +exact certificate plus a written proof, not a formal theorem audit. + +[TASK.json](TASK.json) records seed 08 (bit supplier), three candidate tasks, +scope selection, checkpoint freshness and overlap limits. The local overlap +inventory covered 8,348 research records; connected GitHub reads covered the +latest 100 open PR bodies, focused searches and predecessor heads. Visible +handoff posts were checked, not all discussion pagination or PR code diffs. +No pinned sprint issue was found. The available connector cannot post to +Discussions and the browser was signed out; an advance claim was recorded +locally at 10:39 UTC rather than represented as a public reservation. + +## Open next questions + +- Can a jointly dead interval support a **later** reinjection whose complete + target and paid bill improves? Start with a triple extending PR6113's five + joint-dead pairs; emit an exact changed word and native endpoint before a + large search. The present graph-kernel proof does not apply after propagation. +- Can this flag-certificate technique bound a different changed word? First + recompute early tariffs, query rows and projection flags on its exact source. + The current witness cannot be transferred by matching aggregate profiles. + +Structured first steps and blockers are in [TASK.json](TASK.json). + +## Credit + +Jerry Chen (@CubeJerry), with substantial OpenAI Codex assistance in research, +proof drafting, implementation and verification. No subagents. Apache-2.0. +Credit Matarener for PR6113 and its explicit larger-set handoff; Ali Romman for +PR5604, PR5679 and the PR5708 word; ai-nanachi for PR5512's G20 construction; +and Dugongue for the underlying refinements and late-binding work. The source +packages and their original notices are unchanged. Binary matroid partition +and augmentation are standard methods; the source-specific flag allocation, +all-subset proof and finite witness are this contribution. diff --git a/research/g20-joint-capture-flag-bound/RESULT.json b/research/g20-joint-capture-flag-bound/RESULT.json new file mode 100644 index 0000000000..80a1c4a8b8 --- /dev/null +++ b/research/g20-joint-capture-flag-bound/RESULT.json @@ -0,0 +1,162 @@ +{ + "status": "PASS_G20_ALL_SUBSET_FIRST_READ_FLAG_BOUND", + "wire_count": 685, + "event_count": 14794, + "helper_count": 415, + "full_helpers": 413, + "partial_helpers": [ + 465, + 684 + ], + "rank_two_early_helpers": 180, + "paid_profile": { + "1": 1281, + "2": 1338, + "3": 58, + "4": 57, + "5": 102, + "6": 10 + }, + "query_count": 2846, + "eligible_queries": 2216, + "distinct_rows": 1945, + "tokens": 64274, + "color_limits": [ + 64, + 92, + 108 + ], + "color_sizes": [ + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 637, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 634, + 454, + 454, + 448, + 421, + 396, + 374, + 354, + 337, + 326, + 320, + 312, + 312, + 312, + 312, + 311, + 311 + ], + "cross_helper_early_queries": [ + 6231, + 6291, + 6510 + ], + "query_rows_sha256": "8e72818d9a2f7d6838b4c087dd2c3db05138b6aff36b045d82aa7d7a08a9307d", + "t_interval": [ + "99/100", + "1" + ], + "full_helper_loss_lower_bound": "(5/128)*4^t", + "substitution_fixtures": 7, + "negative_controls": [ + "omitted token", + "duplicate token in color", + "distinct dependent row", + "partial helper in restricted color", + "rank-two helper in restricted color", + "omit cross-helper early query 6291", + "forged query rank", + "changed source bytes" + ], + "kappa_change": false +} diff --git a/research/g20-joint-capture-flag-bound/SOURCES.json b/research/g20-joint-capture-flag-bound/SOURCES.json new file mode 100644 index 0000000000..09837bb20f --- /dev/null +++ b/research/g20-joint-capture-flag-bound/SOURCES.json @@ -0,0 +1,36 @@ +{ + "schema_version": 1, + "base_commit": "721c03822c421b7f7fcbb2598993b947c4d88419", + "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/g20-conjugation-admission/LOCAL-RESULT.json", + "usage": "input", + "git_blob": "29cd42b8baa531f2598b9b8894fd514c754ed17c", + "sha256": "ec37bf5ddf743caf6a415bd4ce6fcd9c0f40922f0066ea79f6d2321ee0f18e96" + }, + { + "path": "research/g20-conjugation-admission/WORD.json.gz", + "usage": "input", + "git_blob": "3877a72d8a15adb03f6492f7d2fd8fa902ecb639", + "sha256": "8dd441fdb9c8923df06eb5ebfda37d03e4539f2305763e688d8c7025d196c4b1" + }, + { + "path": "research/g20-conjugation-admission/prior/prior/prior/source/vendor/g20/inputs/FRAMES.json", + "usage": "input", + "git_blob": "9edf8d95b45a9c9c766a956bfcd3c19cf07bc13c", + "sha256": "0d99fc6b8f45c03dfba5252a03dd9e7fe23be3a7593dfe15368e34da6629a654" + } + ] +} diff --git a/research/g20-joint-capture-flag-bound/TASK.json b/research/g20-joint-capture-flag-bound/TASK.json new file mode 100644 index 0000000000..e626443ac3 --- /dev/null +++ b/research/g20-joint-capture-flag-bound/TASK.json @@ -0,0 +1,157 @@ +{ + "schema_version": 1, + "task_id": "bit-helper-contract", + "priority_revision": 8, + "base_commit": "721c03822c421b7f7fcbb2598993b947c4d88419", + "original_card": { + "id": "bit-helper-contract", + "question": "Can a changed G20 helper path or independent-target split improve the complete BIT moment without losing its physical endpoint?", + "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", + "research/g20-helper-split/README.md", + "research/g20-conjugation-admission/README.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 full boundary contract and paid profile; unchanged scalar counts alone are insufficient. 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_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": "First read #5679/#5708 and their audits as pending component proposals. Choose one uncovered helper group/cut on an exact word; compare arbitrary-input native action, targets, owned storage, both orientations and full signed bill. Stop if the gain is only a scalar count or repaid by lost targets. Do not rerun the frozen #5609 common-frame domain without changing its hypothesis.", + "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": [ + "G20", + "helper split", + "5679", + "5708", + "independent target" + ], + "existing_checks": [ + { + "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": "Rule out profitable simultaneous first-read captures of any subset of the 415 retained helpers on the frozen PR5708 word, with arbitrary native-linear payloads and an optimistic complete target/paid moment comparison for 99/100 <= t <= 1.", + "scope_change_reason": "Follow PR6113’s explicit larger-set handoff with a graph-kernel flag certificate. This is the card’s scoped obstruction alternative, not a new supplier. Extend the same certificate to all 415 helpers, including the two partial targets; do not reopen a frozen common-frame search.", + "bottleneck_link": "A helper saving that loses more productive target moment cannot improve this local BIT supplier. Closing the individual first-read ownership family redirects construction effort to later joint-dead captures or changed words. No claim is made about the global selected frontier.", + "budget_minutes": 120, + "stop_rule": "Orientation within 24 minutes; stop this investigation when a complete exact certificate is found, or at 12:00 UTC for verification and handoff. One refinement from full helpers to all helpers is within the same capture hypothesis. Do not claim an impossibility from a failed partition search. Hard session end 12:30 UTC.", + "outcome": "negative-result", + "evidence": "PROOF.md gives the all-subset graph-kernel argument; PARTITION.json.gz partitions every eligible token into 108 flag-constrained independent colors; RESULT.json and verify.py record exact replay, interval inequalities and eight rejection controls.", + "author": "Jerry Chen (@CubeJerry)", + "ai_assistance": "Substantial OpenAI Codex assistance in task selection, mathematics, proof drafting, coding, verification and packaging. No subagents.", + "open_questions": [ + { + "question": "Can later reinjection in a jointly dead interval improve a complete G20 helper bill?", + "why_it_matters": "It changes the first-read premise used by this obstruction and is a remaining mechanism-level route to BIT savings.", + "first_step": "Take one triple extending a joint-dead pair from PR6113, emit its exact capture word, and certify retained native endpoints and all paid and target changes before enlarging the search.", + "blocked_by": "No implemented later-capture construction or complete invoice; the graph-kernel proof need not survive prior propagation." + }, + { + "question": "Does another changed G20 word admit a comparable tariff-sensitive partition?", + "why_it_matters": "The certificate method can screen a different exact mechanism without enumerating all ownership subsets.", + "first_step": "Pin that word, independently derive early tariffs and query rows, and attempt the corresponding weighted flag partition.", + "blocked_by": "The present source-specific certificate cannot transfer from aggregate profiles; new source rows and native assumptions require review." + } + ], + "os_random_draw": 8, + "track": "bit supplier", + "picker_seed": "00000000000000000000000000000008", + "candidate_tasks": [ + { + "task": "bit-helper-contract", + "scope": "PR6113 all-subset first-read capture budget on the PR5708 word", + "decision": "Chosen: explicit larger-set handoff; seed 8 favors parity/dual certificate over payload enumeration." + }, + { + "task": "bit-new-register-model", + "scope": "One four-register native BIT identity outside the three-register alphabet; price the smallest completed instance before extending word length.", + "decision": "Several recent obstruction claims; broader new-mechanism search." + }, + { + "task": "r437-carrier-integration", + "scope": "One pooled-compiler request-alignment obligation for the pinned R437 two-window exchange.", + "decision": "More extensive source closure than the bounded helper question." + } + ], + "claim": { + "kind": "local", + "time_utc": "2026-10-28T10:39:00Z", + "expected_finish_utc": "2026-10-28T12:30:00Z", + "reason": "No pinned sprint issue found. Connector has no Discussion posting operation and browser is signed out. Local claim permitted by donor. No retrospective public reservation claimed." + }, + "overlap": { + "local_records": 8348, + "local_inventory_complete": true, + "remote_scope": "Latest 100 open PR bodies, focused all-state capture/flag searches, exact predecessor heads and recent visible discussion 1166 posts. Review ledger and prior negative records inspected.", + "limitations": "find_overlap remote refresh unavailable because gh is absent. Full discussion pagination and every PR code diff were not inspected; no-match is not proof of novelty.", + "nearest_sources": { + "6113": "f6712095d07d555969b6e67b792a0e98e8eea8d3", + "5708": "829d01fc031f7323ffcfa423fdfd1f24dcbe3190", + "5604": "b7c27a263b9e57d4e04b5e2dcb7b3199cc8c4170", + "5679": "715dda75fc4cefb1e492349fa0e331d5f15d0f53" + }, + "completion_refresh": { + "time_utc": "2026-10-28T11:21:00.532149+00:00", + "focused_query": "repo:CrocSwap/integer-mult-bounds G20 capture", + "results": [ + 6113, + 5604, + 5512, + 2190 + ], + "predecessor_6113_head_unchanged": true, + "finding": "No overlapping all-subset flag certificate in the inspected result bodies. The broader first-read/flag search also checked 30 result bodies. Coverage limitations remain." + } + }, + "discovery": { + "domain": "Fixed pinned word, all 415 coordinate helpers, individual first-read schedule; arbitrary native-linear payloads. Certificate search on 1945 projected rows and 64274 prescribed tokens with limits [64,92,108].", + "seed": 8, + "randomness_use": "OS draw selects the track and certificate-oriented approach; exploratory tie ordering and replay fixtures use seed 8. The published augmenting-path search is deterministic.", + "stopping_rule": "First verified partition, 1200-second search deadline, or exhausted augmenting paths; failure does not certify a mathematical obstruction.", + "completed_coverage": "All 64274 tokens assigned after 2062 augmentations. A written graph-kernel argument turns the checked witness into a bound for every ownership subset, not an enumeration of subsets or payloads.", + "optimality_claim": false + }, + "checkpoints": [ + { + "time_utc": "2026-10-28T10:39:00Z", + "upstream_commit": "721c03822c421b7f7fcbb2598993b947c4d88419", + "priority_revision": 8, + "selected_kappa": "781451/250000000", + "decision": "Initial canonical main and selected source/review orientation recorded in the local claim by this time." + }, + { + "time_utc": "2026-10-28T11:16:10.134336+00:00", + "upstream_commit": "721c03822c421b7f7fcbb2598993b947c4d88419", + "priority_revision": 8, + "selected_kappa": "781451/250000000", + "decision": "Certificate complete; guidance, selected record, ledger and source unchanged. Preserve frozen inputs and continue verification." + } + ] +} diff --git a/research/g20-joint-capture-flag-bound/VERIFY.json b/research/g20-joint-capture-flag-bound/VERIFY.json new file mode 100644 index 0000000000..68f2aece7f --- /dev/null +++ b/research/g20-joint-capture-flag-bound/VERIFY.json @@ -0,0 +1,35 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [ + "research/g20-conjugation-admission/LOCAL-RESULT.json", + "research/g20-conjugation-admission/WORD.json.gz", + "research/g20-conjugation-admission/prior/prior/prior/source/vendor/g20/inputs/FRAMES.json" + ], + "commands": [ + { + "argv": [ + "{python}", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Exact source/row/flag/multiplicity and integer-power checks; independent set replay; seven substitution fixtures and eight negative controls." + }, + { + "argv": [ + "{python}", + "-I", + "-O", + "-W", + "error", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Same proof-relevant checks in isolated optimized Python; no assert-dependent acceptance." + } + ] +} diff --git a/research/g20-joint-capture-flag-bound/discover.py b/research/g20-joint-capture-flag-bound/discover.py new file mode 100644 index 0000000000..62cbe8b275 --- /dev/null +++ b/research/g20-joint-capture-flag-bound/discover.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +"""Optional deterministic flag-constrained matroid partition search. + +Outputs to the requested scratch path. Verification never calls this search. +Jerry Chen (@CubeJerry), with OpenAI Codex assistance. Apache-2.0. +""" +import argparse +from collections import deque +import gzip +import importlib.util +import json +from pathlib import Path +import time + +HERE = Path(__file__).resolve().parent +SPEC = importlib.util.spec_from_file_location("g20_flag_model", HERE / "model.py") +model = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(model) + + +def discover(data, seconds): + vectors = data["vectors"] + colors = [set() for _ in range(108)] + bases = [{} for _ in colors] + partial = sum(1 << h for h in data["partial"]) + two = sum(1 << h for h in data["free_two"]) + deadline = time.monotonic() + seconds + + def limit(x): + return 64 if vectors[x] & partial else 92 if vectors[x] & two else 108 + + def reduce(index, value): + combination = 0 + basis = bases[index] + while value: + pivot = value.bit_length() - 1 + if pivot not in basis: + return value, combination + row, support = basis[pivot] + value ^= row + combination ^= support + return value, combination + + def add(index, x): + value, combination = reduce(index, vectors[x]) + model.require(value != 0, "discovery inserted dependence") + bases[index][value.bit_length() - 1] = (value, combination ^ (1 << x)) + colors[index].add(x) + + def rebuild(index): + members = sorted(colors[index]) + colors[index], bases[index] = set(), {} + for x in members: + add(index, x) + + remaining = data["multiplicities"].copy() + for index in range(108): + for x in sorted(remaining, key=lambda x: (limit(x), -remaining[x], vectors[x])): + if index < limit(x) and reduce(index, vectors[x])[0]: + add(index, x) + remaining[x] -= 1 + remaining = +remaining + print("Greedy remainder:", sum(remaining.values()), flush=True) + steps = 0 + for root in sorted(remaining, key=lambda x: (limit(x), -remaining[x], vectors[x])): + for _ in range(remaining[root]): + previous, queue, found = {root: None}, deque([root]), None + while queue and found is None: + if time.monotonic() > deadline: + raise TimeoutError("search stopped; no impossibility conclusion") + x = queue.popleft() + for index in range(limit(x)): + if x in colors[index]: + continue + value, support = reduce(index, vectors[x]) + if value: + found = (x, index) + break + while support: + bit = support & -support + y = bit.bit_length() - 1 + if y not in previous: + previous[y] = (x, index) + queue.append(y) + support ^= bit + model.require(found is not None, "search exhausted; no mathematical obstruction claimed") + x, index = found + colors[index].add(x) + changed = {index} + while previous[x] is not None: + y, index = previous[x] + colors[index].remove(x) + colors[index].add(y) + changed.add(index) + x = y + for index in sorted(changed): + rebuild(index) + steps += 1 + if steps % 200 == 0: + print("Augmentations:", steps, flush=True) + certificate = {"schema": "g20-first-read-flag-partition/v1", + "limits": [64, 92, 108], "groups": [sorted(c) for c in colors]} + model.check_partition(data, certificate) + return certificate + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("output", type=Path) + parser.add_argument("--seconds", type=int, default=1200) + args = parser.parse_args() + model.require(not args.output.exists(), "refuse to overwrite an existing artifact") + data = model.census(*model.inputs()) + certificate = discover(data, args.seconds) + raw = (json.dumps(certificate, separators=(",", ":")) + "\n").encode() + args.output.write_bytes(gzip.compress(raw, mtime=0)) + print("WROTE_VERIFIED_FLAG_PARTITION", args.output) + + +if __name__ == "__main__": + main() diff --git a/research/g20-joint-capture-flag-bound/model.py b/research/g20-joint-capture-flag-bound/model.py new file mode 100644 index 0000000000..a58d64545d --- /dev/null +++ b/research/g20-joint-capture-flag-bound/model.py @@ -0,0 +1,180 @@ +"""Constant-input necessary conditions for first-read G20 captures. + +Jerry Chen (@CubeJerry), with OpenAI Codex assistance. Apache-2.0. +No predecessor implementation is imported. Native address permutations act +as identity on constant functions; this is a necessary-condition projection, +not an exact native interpreter. +""" +from collections import Counter +from hashlib import sha256 +from pathlib import Path +import gzip +import json + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] +PREFIX = "research/g20-conjugation-admission/" +WORD = PREFIX + "WORD.json.gz" +FRAMES = PREFIX + "prior/prior/prior/source/vendor/g20/inputs/FRAMES.json" +LOCAL = PREFIX + "LOCAL-RESULT.json" +TOKENS = {1: 17, 2: 33, 3: 49, 4: 64, 5: 80, 6: 96} + + +def require(ok, reason): + if not ok: + raise ValueError(reason) + + +def authenticate(data, digest, name): + require(sha256(data).hexdigest() == digest, "source hash: " + name) + + +def inputs(): + source = json.loads((HERE / "SOURCES.json").read_text()) + blobs = {} + for row in source["files"]: + if row["usage"] == "input": + data = (ROOT / row["path"]).read_bytes() + authenticate(data, row["sha256"], row["path"]) + blobs[row["path"]] = data + require(set(blobs) == {WORD, FRAMES, LOCAL}, "complete input manifest") + return (json.loads(gzip.decompress(blobs[WORD])), + json.loads(blobs[FRAMES])["frames"], json.loads(blobs[LOCAL])) + + +def census(word, frames, expected): + records, start, final = word["records"], word["start"], word["final"] + width = len(start) + require(len(final) == width, "boundary width") + owned = set(word["owned"]) + helpers = set(range(222, width)) - owned + helper_mask = sum(1 << h for h in helpers) + owned_mask = sum(1 << h for h in owned) + dims = {int(f): row["dim"] for f, row in frames.items()} + targets = {h: abs(dims[start[h]] - dims[final[h]]) for h in helpers} + first, last = {}, {} + for index, event in enumerate(records): + if event[0] == "ADD": + first.setdefault(event[2], index) + last[event[2]] = index + require(helpers <= first.keys(), "every helper has a first read") + rows = [1 << i for i in range(width)] + state = list(start) + queries, eligible, early_cross = [], [], [] + early = {h: [] for h in helpers} + paid = Counter() + for index, event in enumerate(records): + op, dest = event[:2] + require(0 <= dest < width, "destination range") + if op == "ADD": + _, _, src, frame = event + require(0 <= src < width and src != dest, "ADD operands") + require(state[dest] == state[src] == frame, "ADD frame") + rows[dest] ^= rows[src] + elif op in ("ERASE", "INIT"): + require(dest in owned, "reset of public input") + if op == "ERASE": + rows[dest] = 0 + state[dest] = event[2] + elif op in ("Q", "ZERO_Q"): + _, _, src_frame, dst_frame, rank = event + require(state[dest] == src_frame, "query frame") + require(abs(dims[src_frame] - dims[dst_frame]) == rank, "query rank") + if op == "ZERO_Q": + require(rows[dest] == 0, "nonzero free query") + else: + row = rows[dest] + require(row != 0 and not row & owned_mask, "query input support") + paid[rank] += 1 + before_read = dest in helpers and index < first[dest] + query = (index, dest, rank, row) + queries.append(query) + if before_read: + early[dest].append((index, rank)) + support = row & helper_mask + # If dest is not captured, its early query can still vanish + # through ANOTHER captured helper. Keep those queries here. + if support and (not before_read or support & ~(1 << dest)): + eligible.append(query) + if before_read: + early_cross.append(index) + state[dest] = dst_frame + else: + raise ValueError("unknown event: " + op) + require(state == final, "final frames") + require(dict(sorted(paid.items())) == + {int(k): v for k, v in expected["stats"]["paid"].items()}, "paid profile") + require(Counter(targets.values()) == {8: 413, 4: 2}, "target inventory") + partial = {h for h in helpers if targets[h] == 4} + require(partial == {465, 684}, "partial helpers") + require(all(len(q) <= 1 and all(rank in (1, 2) for _, rank in q) + for q in early.values()), "early-query tariff") + require(all(not early[h] for h in partial), "partial early-query tariff") + require(not any(h in helpers and i > last[h] for i, h, _, _ in queries), + "no unpriced post-last-read query") + free_two = {h for h in helpers if early[h] and early[h][0][1] == 2} + vectors = sorted({row for _, _, _, row in eligible}) + ids = {row: i for i, row in enumerate(vectors)} + multiplicities = Counter() + for _, _, rank, row in eligible: + multiplicities[ids[row]] += TOKENS[rank] + return dict(word=word, helpers=helpers, targets=targets, first=first, + early=early, partial=partial, free_two=free_two, vectors=vectors, + multiplicities=multiplicities, queries=queries, eligible=eligible, + early_cross=early_cross, final_rows=rows, paid=paid) + + +def independent(rows, low=False): + basis = {} + for value in rows: + while value: + pivot = (value & -value).bit_length() - 1 if low else value.bit_length() - 1 + if pivot not in basis: + basis[pivot] = value + break + value ^= basis[pivot] + else: + return False + return True + + +def check_partition(data, certificate): + require(certificate["schema"] == "g20-first-read-flag-partition/v1", "certificate schema") + limits = certificate["limits"] + require(limits == [64, 92, 108], "flag capacities") + groups = certificate["groups"] + require(len(groups) == limits[2], "color count") + vectors = data["vectors"] + partial_mask = sum(1 << h for h in data["partial"]) + two_mask = sum(1 << h for h in data["free_two"]) + seen = Counter() + for i, group in enumerate(groups): + require(all(type(x) is int and 0 <= x < len(vectors) for x in group), "row ID") + require(len(group) == len(set(group)), "duplicate in color") + rows = [vectors[x] for x in group] + if i >= limits[0]: + require(all(not row & partial_mask for row in rows), "partial flag") + if i >= limits[1]: + require(all(not row & two_mask for row in rows), "rank-two flag") + require(independent(rows) and independent(rows, low=True), "dependent color") + seen.update(group) + require(seen == data["multiplicities"], "complete token coverage") + return [len(group) for group in groups] + + +def power_bounds(): + # Integer powers prove all inequalities on the full 99/100 <= t <= 1 + # interval, by monotonicity. No floating-point acceptance decision. + for r in (1, 2, 3): + require(r**99 * 64**100 <= 4**99 * TOKENS[r]**100, "rank token envelope") + require(all(TOKENS[r] * 4 == 64 * r for r in (4, 5, 6)), "large-rank envelope") + require(2**99 * 64**100 > 127**100, "lower 2^t") + require(4**99 * 33**100 > 128**100, "upper 4^-t") + require(2**99 * 65**100 > 128**100, "upper 2^-t") + # The 108-color bound has uniform positive full-helper margins: + require(127 * 2 - 92 * 2 - 65 == 5, "rank-two strict margin") + require(127 * 2 - 108 * 2 - 33 == 5, "other strict margin") + + +def read_certificate(): + return json.loads(gzip.decompress((HERE / "PARTITION.json.gz").read_bytes())) diff --git a/research/g20-joint-capture-flag-bound/verify.py b/research/g20-joint-capture-flag-bound/verify.py new file mode 100644 index 0000000000..38a61034d0 --- /dev/null +++ b/research/g20-joint-capture-flag-bound/verify.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 +"""Exact certificate, independent set replay and failure controls. + +Jerry Chen (@CubeJerry), with OpenAI Codex assistance. Apache-2.0. +""" +import copy +import hashlib +import importlib.util +import json +from pathlib import Path +import random + +# Explicit sibling load works under -I and in an exported, Git-free package. +HERE = Path(__file__).resolve().parent +SPEC = importlib.util.spec_from_file_location("g20_flag_model", HERE / "model.py") +model = importlib.util.module_from_spec(SPEC) +SPEC.loader.exec_module(model) +require = model.require + + +def set_replay(word): + """Separate representation: literal sets, not integer row arithmetic.""" + rows = [{i} for i in range(len(word["start"]))] + queries = [] + for index, event in enumerate(word["records"]): + op, dest = event[:2] + if op == "ADD": + rows[dest] = rows[dest].symmetric_difference(rows[event[2]]) + elif op == "ERASE": + rows[dest] = set() + elif op == "Q": + queries.append((index, dest, event[-1], frozenset(rows[dest]))) + elif op == "ZERO_Q": + require(not rows[dest], "set replay nonzero free query") + return queries + + +def apply_map(row, mapping): + out = 0 + while row: + bit = row & -row + out ^= mapping[bit.bit_length() - 1] + row ^= bit + return out + + +def substitution_fixture(data, captured, payloads): + """Direct held-zero replay versus one triangular entry substitution. + + These finite fixtures exercise the lemma; PROOF.md gives its argument + for every subset and every native-linear payload. + """ + width = len(data["word"]["start"]) + owned = set(data["word"]["owned"]) + base = [0 if i in owned else 1 << i for i in range(width)] + mapping = [0 if i in captured or i in owned else 1 << i for i in range(width)] + dynamic = list(mapping) + pending = set(captured) + for index, event in enumerate(data["word"]["records"]): + op, dest = event[:2] + if op == "ADD" and event[2] in pending: + h = event[2] + require(index == data["first"][h], "capture epoch") + require(base[h] & (1 << h), "unit unread diagonal") + require(not base[h] & sum(1 << j for j in pending - {h}), + "unread triangularity") + mapping[h] = payloads[h] ^ apply_map(base[h] ^ (1 << h), mapping) + dynamic[h] = payloads[h] + pending.remove(h) + if op == "ADD": + base[dest] ^= base[event[2]] + if dest not in pending: + dynamic[dest] ^= dynamic[event[2]] + elif op == "ERASE": + base[dest] = dynamic[dest] = 0 + if dest not in pending: + require(dynamic[dest] == apply_map(base[dest], mapping), + "first-read substitution identity") + require(not pending, "all captures executed") + mask = sum(1 << h for h in captured) + require(all(not mapping[h] & mask for h in captured), "graph-kernel projection") + + +def rejected(label, operation, expected): + try: + operation() + except ValueError as error: + require(expected in str(error), "wrong rejection for " + label) + return label + raise ValueError("negative control accepted: " + label) + + +def controls(data, certificate, frames, local): + names = [] + bad = copy.deepcopy(certificate) + bad["groups"][0].pop() + names.append(rejected("omitted token", lambda: model.check_partition(data, bad), + "complete token coverage")) + bad = copy.deepcopy(certificate) + bad["groups"][0].append(bad["groups"][0][0]) + names.append(rejected("duplicate token in color", lambda: model.check_partition(data, bad), + "duplicate in color")) + bad = copy.deepcopy(certificate) + absent = next(i for i in range(len(data["vectors"])) if i not in bad["groups"][0]) + bad["groups"][0].append(absent) + names.append(rejected("distinct dependent row", lambda: model.check_partition(data, bad), + "dependent color")) + for name, index, mask, reason in ( + ("partial helper in restricted color", 64, + sum(1 << h for h in data["partial"]), "partial flag"), + ("rank-two helper in restricted color", 92, + sum(1 << h for h in data["free_two"]), "rank-two flag"), + ): + bad = copy.deepcopy(certificate) + row_id = next(i for i, v in enumerate(data["vectors"]) if v & mask and + (index == 64 or not v & sum(1 << h for h in data["partial"]))) + bad["groups"][index].append(row_id) + names.append(rejected(name, lambda: model.check_partition(data, bad), reason)) + bad_data = dict(data) + bad_data["multiplicities"] = data["multiplicities"].copy() + _, _, rank, row = next(q for q in data["eligible"] if q[0] == 6291) + bad_data["multiplicities"][data["vectors"].index(row)] -= model.TOKENS[rank] + names.append(rejected("omit cross-helper early query 6291", + lambda: model.check_partition(bad_data, certificate), + "complete token coverage")) + bad_word = copy.deepcopy(data["word"]) + first_q = next(e for e in bad_word["records"] if e[0] == "Q") + first_q[-1] += 1 + names.append(rejected("forged query rank", lambda: model.census(bad_word, frames, local), + "query rank")) + source = (model.ROOT / model.WORD).read_bytes() + damaged = bytes([source[0] ^ 1]) + source[1:] + names.append(rejected("changed source bytes", lambda: model.authenticate( + damaged, hashlib.sha256(source).hexdigest(), model.WORD), "source hash")) + return names + + +def verify(): + word, frames, local = model.inputs() + data = model.census(word, frames, local) + expected_sets = [(i, h, r, frozenset(j for j in range(len(word["start"])) + if row & (1 << j))) + for i, h, r, row in data["queries"]] + require(set_replay(word) == expected_sets, "independent set replay") + certificate = model.read_certificate() + sizes = model.check_partition(data, certificate) + model.power_bounds() + rng = random.Random(8) + helpers = sorted(data["helpers"]) + cases = [set(), {684}, {465, 684}, {274, 297, 467}, set(data["free_two"]), + set(helpers), set(rng.sample(helpers, 32))] + for captured in cases: + retained = set(range(len(word["start"]))) - captured - set(word["owned"]) + mask = sum(1 << h for h in retained) + payloads = {h: rng.getrandbits(len(word["start"])) & mask for h in sorted(captured)} + substitution_fixture(data, captured, payloads) + names = controls(data, certificate, frames, local) + query_bytes = json.dumps([(i, h, r, hex(v)) for i, h, r, v in data["queries"]], + separators=(",", ":")).encode() + result = { + "status": "PASS_G20_ALL_SUBSET_FIRST_READ_FLAG_BOUND", + "wire_count": len(word["start"]), "event_count": len(word["records"]), + "helper_count": len(helpers), "full_helpers": 413, "partial_helpers": [465, 684], + "rank_two_early_helpers": len(data["free_two"]), + "paid_profile": {str(k): v for k, v in sorted(data["paid"].items())}, + "query_count": len(data["queries"]), "eligible_queries": len(data["eligible"]), + "distinct_rows": len(data["vectors"]), "tokens": sum(sizes), + "color_limits": certificate["limits"], "color_sizes": sizes, + "cross_helper_early_queries": data["early_cross"], + "query_rows_sha256": hashlib.sha256(query_bytes).hexdigest(), + "t_interval": ["99/100", "1"], "full_helper_loss_lower_bound": "(5/128)*4^t", + "substitution_fixtures": len(cases), "negative_controls": names, + "kappa_change": False, + } + return result + + +def main(): + result = verify() + expected = json.loads((HERE / "RESULT.json").read_text()) + require(result == expected, "recorded result mismatch") + print(result["status"]) + print("415 helpers; 2216 queries; 64274 tokens; 108 colors; 8 rejected controls") + + +if __name__ == "__main__": + main()