From 5182077ac99c48b9c4abc8404d52c4844dbe31b7 Mon Sep 17 00:00:00 2001 From: Sagar Thakrar Date: Tue, 13 Oct 2026 09:50:26 +0530 Subject: [PATCH 1/2] Add exact dyadic lowering for selected complex scalar programs --- research/complex-dyadic-lowering/CLAIM.json | 21 ++ .../complex-dyadic-lowering/EXPECTED.json | 145 ++++++++++ research/complex-dyadic-lowering/README.md | 165 +++++++++++ .../complex-dyadic-lowering/SOURCE-PINS.json | 16 ++ .../complex-dyadic-lowering/VALIDATION.md | 35 +++ research/complex-dyadic-lowering/lower.py | 56 ++++ research/complex-dyadic-lowering/verify.py | 256 ++++++++++++++++++ 7 files changed, 694 insertions(+) create mode 100644 research/complex-dyadic-lowering/CLAIM.json create mode 100644 research/complex-dyadic-lowering/EXPECTED.json create mode 100644 research/complex-dyadic-lowering/README.md create mode 100644 research/complex-dyadic-lowering/SOURCE-PINS.json create mode 100644 research/complex-dyadic-lowering/VALIDATION.md create mode 100644 research/complex-dyadic-lowering/lower.py create mode 100644 research/complex-dyadic-lowering/verify.py diff --git a/research/complex-dyadic-lowering/CLAIM.json b/research/complex-dyadic-lowering/CLAIM.json new file mode 100644 index 0000000000..2ffc781c21 --- /dev/null +++ b/research/complex-dyadic-lowering/CLAIM.json @@ -0,0 +1,21 @@ +{ + "track": "Complex supplier: scalar coefficient circuit", + "assignment_seed": 22, + "randomness": "Python secrets.randbelow(100), operating-system randomness", + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "claimed_at_utc": "2026-10-13T04:10:00Z", + "expected_finish_utc": "2026-10-13T04:36:37Z", + "coordination": "No pinned issue exists; only open issue #650 requests Discussions. Scope recorded locally.", + "object": "Dyadic scalar-add primitive lowering in the selected PR626 CK and JP8 local programs, both orientations", + "method": "Replace clear plus leading-bit addition by copy; specialize unit coefficients to signed accumulation plus work clear. Exact rational symbolic replay and primitive recount, without changing scalar macros or frame events.", + "deliverable": "Executable lowering, finite verification receipt, proof of unchanged boundaries and prefix envelope, meaningful negative controls; no new kappa", + "candidates": [ + {"task": "Invertible factory coordinate-total resynthesis", "disposition": "Rejected overlap with PR681 at 80d4edbc2d53f058787cb5c43bd0fc22c7e7fdff"}, + {"task": "Selected butterfly pivot/frame scheduling", "disposition": "Rejected overlap with pivot-swap and entrance work in PR641/655"}, + {"task": "Dyadic coefficient primitive lowering", "disposition": "Selected; changes the scalar implementation underneath fixed macro/frame words"} + ], + "prior_work_checked": [651, 679, 681, 683, 687, 667], + "prior_negative_results": "research/structural-gain/factory/README.md and research/experiment-log/README.md. No closed packet, hosting, or retiming search is reopened.", + "seed_use": "Seed 22 selects CK first and the 22nd distinct nonunit coefficient for mutation controls. All coefficients and all four programs are covered, with no randomized search.", + "status": "claimed" +} diff --git a/research/complex-dyadic-lowering/EXPECTED.json b/research/complex-dyadic-lowering/EXPECTED.json new file mode 100644 index 0000000000..6cdc73b886 --- /dev/null +++ b/research/complex-dyadic-lowering/EXPECTED.json @@ -0,0 +1,145 @@ +{ + "controls": { + "coefficient": "-8403008", + "rejected": [ + "missing_cleanup", + "missing_source_copy", + "wrong_sign", + "redundant_work", + "endpoint_neutral_prefix_growth", + "unit_dirty_work_not_cleared", + "nondyadic", + "zero_coefficient", + "source_alias", + "work_alias" + ] + }, + "distinct_coefficients": 686, + "programs": { + "ck/backward": { + "additions": 21451, + "all_input_columns": 716, + "baseline_real_primitives": 224986, + "charged_payload_bits": 192, + "dirty_helper_columns_restored": 492, + "new_real_primitives": 169634, + "paid_profile": { + "1": 2596, + "2": 552, + "3": 304, + "4": 160, + "5": 70, + "6": 8, + "8": 8 + }, + "primitive_tags": { + "add": 24236, + "clear": 42934, + "copy": 30452, + "double": 11170, + "halve": 38998, + "negate": 696, + "subtract": 21148 + }, + "primitive_word_sha256": "e342c630489789aa7e2aa938d8740ffc63d267d2420994be902893e7d9b50bf4", + "retained_prefix_l1_upper": "146068000389976309073/32", + "saved_real_primitives": 55352, + "scalar_macros": 21936, + "unit_additions": 6225 + }, + "ck/forward": { + "additions": 21443, + "all_input_columns": 716, + "baseline_real_primitives": 224938, + "charged_payload_bits": 192, + "dirty_helper_columns_restored": 492, + "new_real_primitives": 169618, + "paid_profile": { + "1": 2596, + "2": 552, + "3": 304, + "4": 160, + "5": 70, + "6": 8, + "8": 8 + }, + "primitive_tags": { + "add": 23838, + "clear": 42918, + "copy": 30468, + "double": 11170, + "halve": 38998, + "negate": 696, + "subtract": 21530 + }, + "primitive_word_sha256": "16ae874e3352c4df265026f62db95359a30399f1edc4c1b151d564d71902380c", + "retained_prefix_l1_upper": "920709848294", + "saved_real_primitives": 55320, + "scalar_macros": 21936, + "unit_additions": 6217 + }, + "jp8/backward": { + "additions": 22219, + "all_input_columns": 716, + "baseline_real_primitives": 257280, + "charged_payload_bits": 192, + "dirty_helper_columns_restored": 492, + "new_real_primitives": 200396, + "paid_profile": { + "1": 2512, + "2": 400, + "3": 448, + "4": 160, + "5": 70, + "6": 8, + "8": 8 + }, + "primitive_tags": { + "add": 29176, + "clear": 44470, + "copy": 31992, + "double": 32576, + "halve": 39438, + "negate": 692, + "subtract": 22052 + }, + "primitive_word_sha256": "c71f7fd2d52031e730f3ed42e56e38878e5746c053d990aad9d6e5c0d55d2bbd", + "retained_prefix_l1_upper": "16753412757380464429924108070201913461/8388608", + "saved_real_primitives": 56884, + "scalar_macros": 22693, + "unit_additions": 6223 + }, + "jp8/forward": { + "additions": 22211, + "all_input_columns": 716, + "baseline_real_primitives": 257232, + "charged_payload_bits": 192, + "dirty_helper_columns_restored": 492, + "new_real_primitives": 200380, + "paid_profile": { + "1": 2512, + "2": 400, + "3": 448, + "4": 160, + "5": 70, + "6": 8, + "8": 8 + }, + "primitive_tags": { + "add": 29050, + "clear": 44454, + "copy": 32008, + "double": 32576, + "halve": 39438, + "negate": 692, + "subtract": 22162 + }, + "primitive_word_sha256": "21bdebedaf5ef43d0a9149e56d15e6287c87d5031bcfaad13973fb5c24a662fe", + "retained_prefix_l1_upper": "4536094588619580433782972610869617/281474976710656", + "saved_real_primitives": 56852, + "scalar_macros": 22693, + "unit_additions": 6215 + } + }, + "status": "PASS_COMPLEX_DYADIC_LOWERING" +} diff --git a/research/complex-dyadic-lowering/README.md b/research/complex-dyadic-lowering/README.md new file mode 100644 index 0000000000..18999b7d25 --- /dev/null +++ b/research/complex-dyadic-lowering/README.md @@ -0,0 +1,165 @@ +# Smaller dyadic circuits for the selected complex suppliers + +This finite circuit improvement reduces the scalar primitive bill of the +selected PR626 complex programs by 22.1–24.6%. It replaces coefficient work +inside each scalar macro, preserving the exact macro, its frame and its source +and target registers. It does not claim a new κ or a measured runtime speedup. + +| Provider | Orientation | Original real primitives | Replacement | Saved | +| --- | --- | ---: | ---: | ---: | +| CK | Forward | 224,938 | 169,618 | 55,320 | +| CK | Backward | 224,986 | 169,634 | 55,352 | +| JP8 | Forward | 257,232 | 200,380 | 56,852 | +| JP8 | Backward | 257,280 | 200,396 | 56,884 | + +These counts include all scalar macros in each complete emitted local program, +including preconditions, compensation, centers and cleanup. They count both real +components of the complex streams. They exclude the unchanged recursive children, +frame adapters and residual wrappers, exactly as the original +`real_component_primitive_bound` field does. + +## Reproduce + +From a checkout containing this contribution, with Python 3.11+ and no external +dependencies: + +```sh +python3 -B research/complex-dyadic-lowering/verify.py +``` + +Expected: + +```text +PASS_COMPLEX_DYADIC_LOWERING programs=4 columns=716 savings=55320,55352,56852,56884 controls=10 +``` + +The command is offline and writes no files. `--json` prints the deterministic +receipt after checking it against [EXPECTED.json](EXPECTED.json). It verifies +source hashes before replaying; gzip pins cover decompressed payload bytes. +It can be run from another working directory by using the script's absolute path. + +## Circuit and cost + +For a nonzero dyadic coefficient `q = ±a/2^k` in reduced form, a scalar macro +updates `T ← T + qS`. The existing binary Horner implementation first clears +private work `W`, then adds `S` for the leading binary digit of `a`. Both +instructions together set `W = S`, even for arbitrary initial `W`. The +replacement uses one copy instruction for that assignment and retains every +remaining binary digit, halving, signed accumulation and final work clear. + +For `q = ±1`, the replacement is simply `T ← T ± S; W ← 0`. The clear is still +charged, so this circuit does not assume a clean private input. Both replacements +have the complete three-register map + +```text +(T, S, W) → (T + qS, S, 0). +``` + +The original cost per real component is +`3 + floor(log2(a)) + popcount(a) + k`. Copy initialization saves one primitive +for every nonunit coefficient. The unit replacement costs two primitives, +instead of four. Thus a program with `A` additions, of which `U` have unit +coefficients, saves exactly `2(A + U)` real-component primitives. + +The executable replacement is [lower.py](lower.py). Its primitive vocabulary is +clear, copy, doubling, halving, negation and signed addition. Scale macros retain +their original signed-power-of-two lowering. Each primitive stays at the scalar +macro's frame. No source is temporarily modified; no helper, source access, +frame change, center copy, restoration or recursive child is added or omitted. +The existing two real coefficient-work streams suffice. + +## Prefix bound and substitution argument + +For a nonunit coefficient, the new copy reaches precisely the old state after +the leading addition. The rest of the instruction sequence is identical. Each +new register value therefore occurs in the old prefix trace, including the +arbitrary initial private-work value. + +For a unit coefficient, the target reaches its old final value directly. The +source remains unchanged. Work retains its initial value until the clear. +Each of these register values also occurs in the original trace. This proves +containment of the maximum over prefixes and registers; it does not assert +entrywise domination of simultaneous transfer matrices. + +The argument holds for arbitrary real or complex inputs and correlated input +values. In particular, it preserves the inherited maximum-row norm bound. +The verifier also reconstructs the original nonnegative scalar/Horner envelope +from the full macro stream and matches the pinned independent replay's exact +`prefix_l1_upper`. Its existing 192-bit charged payload allowance is retained. +This is an exact-arithmetic circuit argument. The all-size rounding and tape +interfaces remain inherited, as they are in the selected result. + +Replacing a macro by a circuit with the same source, target and cleared-work +boundary preserves every following macro's inputs. Induction over the fixed +event stream then preserves the complete scalar program. Frame events, +normalization wrappers, center lifetimes and recursive calls are unchanged. +The existing geometric and physical admission is inherited from the pinned +selected supplier; this package does not independently prove it. + +## Evidence and limits + +[verify.py](verify.py) expands every scalar macro into primitives and executes +those primitives with exact rational sparse rows. Each of the four programs +checks all 716 input columns, including 492 arbitrary dirty helper columns, +plus an arbitrary coefficient-work input column. It verifies the required +forward or backward shear, restored helpers, and cleared private registers. +The imaginary component uses the same real-coefficient circuit, so the exact +linear identity applies separately to it. + +For all 686 distinct addition coefficients, a separate three-register check +compares every candidate register row with the complete reference Horner trace. +This includes the initial state. It checks the full boundary and exact primitive +count. The receipt records hashes of the expanded primitive words, their +operation counts, unchanged paid profiles and inherited prefix bounds. + +Ten controls reject missing cleanup, missing initialization, a wrong sign, +unnecessary work, excessive intermediate growth with a restored endpoint, +uncleared private dirt for a unit coefficient, a nondyadic coefficient, zero, +and source/target or source/work aliasing. The growth control must fail the +prefix check specifically; the unnecessary-work control must fail the count. + +This is deterministic complete coverage of these four frozen programs and their +686 coefficients. There is no randomized circuit search and no optimality claim. +Seed 22 selects the first provider and a coefficient for mutation controls; it +does not stand in for coverage. The general leading-bit proof above is distinct +from the finite replay and does not formalize the multiplication theorem. + +The paid profiles and assembly parameters are unchanged, so the accepted +conditional κ remains `51110230636731/31250000000000000`, or +`0.001635527380375392`. This package supplies an executable local lowering and +an independently reviewable receipt. It does not replace the selected emitter, +regenerate its certificates, or change the accepted frontier. + +## Provenance and sprint scope + +Base commit: `66849e1475c930fd7732b1a0067ffee7e1e95f60`. +[SOURCE-PINS.json](SOURCE-PINS.json) pins every consumed source, the original +lowering and invoice code, and the selected record. The selected PR626 head is +`660de893d27bb7abd1d5b01b1640207528a5c851`; its construction descends from PR622 +at `f69477f4f6d3c7eb1f740b166881bffed4ffa9f6`. + +Credit goes to icekylinx for the scalar operation and coefficient-work lineage +through PR425/433/531, Jeremy Kothe for the K492 construction and schedules, +Chafik Boukhalfa for the selected PR626 packing, and the predecessors retained in +the [maintainer review](../../docs/research/community-k492-review.md), including +DreamingOfClouds' cold-helper construction and Rohan Arun's recurrence correction. +The retained bit supplier is eumemic's PR543. + +Eumemic's historical [PR411](https://github.com/CrocSwap/integer-mult-bounds/pull/411) +at `f58d95f2c5da03445e704ea9c72cc55df9e68190` already used paid copy, halving, +accumulation and clear for quarter/eighth coefficients. It is related prior work, +not a code dependency. This contribution specializes the fixed selected macro +streams and covers all their coefficients, arbitrary private dirt and prefix +containment. It makes no priority claim for copy-based coefficient preparation. + +Current [PR681](https://github.com/CrocSwap/integer-mult-bounds/pull/681), reviewed +for overlap at `80d4edbc2d53f058787cb5c43bd0fc22c7e7fdff`, resynthesizes an +87-operation factory window into 35 scalar operations. That changes a scalar +word. This contribution reduces the primitive cost inside unchanged macros and +does not depend on PR681. PR667 concerns exact logarithm evaluation. Raw-face +sharing, cold-end scheduling and closed packet-factory searches are not reopened. + +The [local claim](CLAIM.json) records seed 22, the three candidate tasks and the +absence of a pinned sprint issue. Contribution by Sagar Thakrar / `thakrarsagar`, +with substantial OpenAI Codex assistance in research, implementation, proof +writing and review. New files are under the repository's Apache-2.0 license. diff --git a/research/complex-dyadic-lowering/SOURCE-PINS.json b/research/complex-dyadic-lowering/SOURCE-PINS.json new file mode 100644 index 0000000000..31e711bef9 --- /dev/null +++ b/research/complex-dyadic-lowering/SOURCE-PINS.json @@ -0,0 +1,16 @@ +{ + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "selected_source_head": "660de893d27bb7abd1d5b01b1640207528a5c851", + "hash_semantics": "SHA256 of decompressed payload for gzip; exact bytes otherwise", + "files": { + "certificates/selected-result.json": "b3bf402f31a69bde0629936a9b569bed48281568d7b16d5fba120b5311ea1f53", + "research/complex-k492-owner-repair/code/hpe_emit_local.py": "7e4a6fbc38c8228157b6311457d1496bf460291393043932d2c365f004f77805", + "research/complex-k492-owner-repair/code/invoice_allcold.py": "141bd2fd58bbfb5b8d0fc8f56f61c45586d5608a5af3487c6b883dd987f998ec", + "research/community-k492-audit/pr626/replay/mixed-global/base/providers/ck/LOCAL-PROGRAMS.json.gz": "854f17274092263dc25e60367f4cd0d29f60a8446becd17cc1883ebed7a97900", + "research/community-k492-audit/pr626/replay/mixed-global/base/providers/ck/LOCAL-CHECKS.json": "059c4e59142bdf5c19dc7c0afebcddfec28e6e60cbc7299b8bdcc624afbc0cbe", + "research/community-k492-audit/pr626/replay/mixed-global/base/providers/ck/INDEPENDENT-LOCAL-REPLAY.json": "ecefb9e661301d8081522be68bbe6640e175c011eb1177f643383d193c6fb2f0", + "research/community-k492-audit/pr626/replay/mixed-global/base/providers/jp8/LOCAL-PROGRAMS.json.gz": "efe45ce7fb025a6f53cc9eb54e951ac2211a5ed927e689a049e4f68ca680654b", + "research/community-k492-audit/pr626/replay/mixed-global/base/providers/jp8/LOCAL-CHECKS.json": "0fad744aa863eedb288a9f87b1c23225a36b316b6275cc3b1bcedd42afe28a67", + "research/community-k492-audit/pr626/replay/mixed-global/base/providers/jp8/INDEPENDENT-LOCAL-REPLAY.json": "cb2f99ed351925dd35434b73de16f4085884fe81a35a69e1c7ce2d5e96cb975b" + } +} diff --git a/research/complex-dyadic-lowering/VALIDATION.md b/research/complex-dyadic-lowering/VALIDATION.md new file mode 100644 index 0000000000..4bd434bda3 --- /dev/null +++ b/research/complex-dyadic-lowering/VALIDATION.md @@ -0,0 +1,35 @@ +# Validation receipt + +Validated locally on macOS on 2026-10-13, based on +`66849e1475c930fd7732b1a0067ffee7e1e95f60`. + +| Command | Result | +| --- | --- | +| `python3 -B research/complex-dyadic-lowering/verify.py` | PASS on Python 3.14.8 | +| `python3.11 -B -O research/complex-dyadic-lowering/verify.py` | PASS on Python 3.11.15, all checks remain active without assertions | +| `make selected-record-check` | PASS, selected source inventory and exact κ unchanged | + +The deterministic evidence is in [EXPECTED.json](EXPECTED.json). Both Python +runs match it, including all four primitive-word hashes. The package makes no +wall-clock performance claim. The original and replacement primitive counts +refer to the same pinned complete scalar inputs. + +An additional scoped AI worker reviewed the algebra, operation vocabulary, +source binding and written scope. That review identified the need to compare +prefixes per register, including the initial dirty-work row. The implementation +now performs that exact comparison. This is AI review, not independent human +peer review or a formal proof assistant result. + +The final overlap refresh inspected 513 open PRs through #693 and fetched +`origin/main`, which remained at the base commit. PR681 changes a factory's +scalar word; this package changes primitive lowering beneath unchanged scalar +words. Historical PR411 is credited for its coefficient microcircuits. PR667 +checks logarithm intervals, PR688 composes bit circuits, and PR693 audits signed +block extraction. None is a dependency of this result. No pinned sprint issue +was present at either coordination check. + +Not run: repository-wide `make verify`, cold selected-construction replay, +Linux CI or Lean. This standalone research package does not modify generators +or selected certificates. The focused primitive replay and selected-record +check cover its changed behavior without regenerating unrelated artifacts. +The geometric, compiler, hosting, rounding and tape contracts remain inherited. diff --git a/research/complex-dyadic-lowering/lower.py b/research/complex-dyadic-lowering/lower.py new file mode 100644 index 0000000000..a2c2889e5b --- /dev/null +++ b/research/complex-dyadic-lowering/lower.py @@ -0,0 +1,56 @@ +"""Smaller exact dyadic circuits for the fixed PR626 complex scalar words. + +Sagar Thakrar, with substantial OpenAI Codex assistance. Apache-2.0. +Primitive vocabulary and the original Horner circuit follow icekylinx's +PR425/433/531 lineage, retained by Jeremy Kothe's PR622 supplier. +""" +from fractions import Fraction + + +def power_of_two(n): + return n > 0 and n & (n - 1) == 0 + + +def lower(op, work=("W", 0)): + """Return real-component primitives; work may be dirty on entry. + + Every addition leaves work zero. All operations use the macro's frame. + The complex circuit applies this word separately to real and imaginary parts. + """ + tag, target = op[0], tuple(op[1]) + if target == work: + raise ValueError("coefficient work aliases a scalar register") + if tag == "clear": + return [("clear", target)] + if tag == "copy": + source = tuple(op[2]) + if source == work: + raise ValueError("coefficient work used as a scalar source") + return [("copy", target, source)] + if tag == "scale": + q = Fraction(op[2], op[3]) + if not power_of_two(abs(q.numerator)) or not power_of_two(q.denominator): + raise ValueError("scale is not a signed power of two") + shift = abs(q.numerator).bit_length() - q.denominator.bit_length() + result = [("double" if shift > 0 else "halve", target)] * abs(shift) + if q < 0: + result.append(("negate", target)) + return result + if tag != "add": + raise ValueError("unknown scalar macro") + source = tuple(op[2]) + q = Fraction(op[3], op[4]) + if source in (target, work) or not q or not power_of_two(q.denominator): + raise ValueError("addition requires distinct registers and a nonzero dyadic") + accumulate = "add" if q > 0 else "subtract" + if abs(q) == 1: + return [(accumulate, target, source), ("clear", work)] + # Copy replaces clear + addition of the leading binary digit. + result = [("copy", work, source)] + for bit in bin(abs(q.numerator))[3:]: + result.append(("double", work)) + if bit == "1": + result.append(("add", work, source)) + result.extend([("halve", work)] * (q.denominator.bit_length() - 1)) + result.extend([(accumulate, target, work), ("clear", work)]) + return result diff --git a/research/complex-dyadic-lowering/verify.py b/research/complex-dyadic-lowering/verify.py new file mode 100644 index 0000000000..116bbc9e81 --- /dev/null +++ b/research/complex-dyadic-lowering/verify.py @@ -0,0 +1,256 @@ +"""Replay four pinned PR626 scalar words with an explicit primitive lowering. + +Sagar Thakrar, with substantial OpenAI Codex assistance. Apache-2.0. +Run from any directory with Python 3.11+; standard library only, no writes. +""" +import argparse +from collections import Counter +from fractions import Fraction as Q +import gzip +import hashlib +import json +from pathlib import Path + +from lower import lower + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] +PROVIDERS = ROOT / "research/community-k492-audit/pr626/replay/mixed-global/base/providers" +WORK = ("W", 0) + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def digest(data): + return hashlib.sha256(data).hexdigest() + + +def read(path): + data = path.read_bytes() + return json.loads(gzip.decompress(data) if path.suffix == ".gz" else data) + + +def step(rows, op): + """Sparse rational row interpreter, with no scalar-macro shortcut.""" + tag, target = op[:2] + if tag == "clear": + rows[target] = {} + elif tag == "copy": + rows[target] = rows[op[2]].copy() + elif tag in ("double", "halve", "negate"): + q = {"double": Q(2), "halve": Q(1, 2), "negate": Q(-1)}[tag] + rows[target] = {j: q * x for j, x in rows[target].items()} + elif tag in ("add", "subtract"): + target_row = rows[target] + for j, x in rows[op[2]].items(): + value = target_row.get(j, Q(0)) + (x if tag == "add" else -x) + if value: + target_row[j] = value + else: + target_row.pop(j, None) + else: + raise ValueError("unknown primitive") + + +def baseline_count(op): + tag = op[0] + if tag in ("clear", "copy"): + return 1 + q = Q(op[3], op[4]) if tag == "add" else Q(op[2], op[3]) + a, b = abs(q.numerator), q.denominator + if tag == "scale": + return abs(a.bit_length() - b.bit_length()) + int(q < 0) + return 3 + a.bit_length() - 1 + a.bit_count() + b.bit_length() - 1 + + +def macro_check(q, circuit): + """Arbitrary T,S,W columns and exact per-register prefix containment.""" + t, s = ("T", 0), ("S", 0) + rows = {t: {0: Q(1)}, s: {1: Q(1)}, WORK: {2: Q(1)}} + reference = [("clear", WORK)] + for index, bit in enumerate(bin(abs(q.numerator))[2:]): + if index: + reference.append(("double", WORK)) + if bit == "1": + reference.append(("add", WORK, s)) + reference.extend([("halve", WORK)] * (q.denominator.bit_length() - 1)) + reference.extend([("add" if q > 0 else "subtract", t, WORK), ("clear", WORK)]) + reference_rows = {register: row.copy() for register, row in rows.items()} + seen = {register: {tuple(sorted(row.items()))} for register, row in rows.items()} + for primitive in reference: + step(reference_rows, primitive) + for register, row in reference_rows.items(): + seen[register].add(tuple(sorted(row.items()))) + for primitive in circuit: + step(rows, primitive) + for register, row in rows.items(): + require(tuple(sorted(row.items())) in seen[register], "prefix row not in reference") + require(rows == {t: {0: Q(1), 1: q}, s: {1: Q(1)}, WORK: {}}, + "macro endpoint or private clearing") + expected = baseline_count(["add", list(t), list(s), q.numerator, q.denominator]) + expected -= 2 if abs(q) == 1 else 1 + require(len(circuit) == expected, "primitive count") + + +def negative_controls(coefficients): + t, s = ["T", 0], ["S", 0] + q = sorted(x for x in coefficients if abs(x) != 1)[22] + op = ["add", t, s, q.numerator, q.denominator] + word = lower(op) + mutations = { + "missing_cleanup": word[:-1], + "missing_source_copy": word[1:], + "wrong_sign": word[:-2] + [("subtract" if word[-2][0] == "add" else "add", *word[-2][1:])] + word[-1:], + "redundant_work": [("clear", WORK)] + word, + } + # Grow a source beyond the allowed envelope, then restore it exactly. + k = abs(q.numerator).bit_length() + 1 + mutations["endpoint_neutral_prefix_growth"] = ( + [("double", tuple(s))] * k + [("halve", tuple(s))] * k + word + ) + unit = lower(["add", t, s, -1, 1]) + mutations["unit_dirty_work_not_cleared"] = unit[:-1] + rejected = [] + for name, circuit in mutations.items(): + try: + macro_check(Q(-1) if name.startswith("unit_") else q, circuit) + except ValueError as error: + if name == "endpoint_neutral_prefix_growth": + require(str(error) == "prefix row not in reference", "prefix control failed for another reason") + if name == "redundant_work": + require(str(error) == "primitive count", "count control failed for another reason") + rejected.append(name) + else: + raise ValueError("accepted negative control: " + name) + for name, invalid in { + "nondyadic": ["add", t, s, 1, 3], + "zero_coefficient": ["add", t, s, 0, 1], + "source_alias": ["add", t, t, 1, 1], + "work_alias": ["add", t, list(WORK), 1, 1], + }.items(): + try: + lower(invalid) + except ValueError: + rejected.append(name) + else: + raise ValueError("accepted invalid macro: " + name) + return {"coefficient": str(q), "rejected": rejected} + + +def replay(provider, orientation, events, checks, inherited): + n, v = 716, 112 + rows = {("L", r): {r: Q(1)} for r in range(n)} + rows[WORK] = {n: Q(1)} + env = {("L", r): Q(1) for r in range(n)} + peak = Q(1) + paid, primitive_tags = Counter(), Counter() + baseline = macros = additions = units = 0 + coefficients = set() + circuit_hash = hashlib.sha256() + for event in events: + if event[0] == "climb": + paid[event[5]] += 1 + elif event[0] == "center": + paid[event[4]] += 1 + elif event[0] != "scalar": + require(event[0] in ("phase", "adapter", "residual_adapter"), "unknown event") + else: + op, frame = event[1:] + tag, target = op[0], tuple(op[1]) + rows.setdefault(target, {}) + word = lower(op) + baseline += 2 * baseline_count(op) + macros += 1 + if tag == "add": + source, q = tuple(op[2]), Q(op[3], op[4]) + coefficients.add(q) + additions += 1 + units += abs(q) == 1 + # Old Horner attains this work bound. New work is a subsequence + # of the old work states, or absent for a unit coefficient. + peak = max(peak, abs(q.numerator) * env[source]) + env[target] = env.get(target, Q(0)) + abs(q) * env[source] + elif tag == "scale": + env[target] *= abs(Q(op[2], op[3])) + elif tag == "clear": + env[target] = Q(0) + elif tag == "copy": + env[target] = env[tuple(op[2])] + peak = max(peak, env[target]) + for primitive in word: + step(rows, primitive) + primitive_tags[primitive[0]] += 2 + circuit_hash.update(json.dumps([frame, primitive], separators=(",", ":")).encode() + b"\n") + if tag == "add": + require(not rows[WORK], "coefficient work survived a macro") + for r in range(n): + expected = {r: Q(1)} + if orientation == "forward" and v <= r < 2 * v: + expected[r - v] = Q(1) + if orientation == "backward" and r < v: + expected[r + v] = Q(-1) + require(rows[("L", r)] == expected, f"{provider}/{orientation} column map at {r}") + require(all(not row for register, row in rows.items() if register[0] != "L"), "private registers not clear") + require(baseline == checks["real_component_primitive_bound"], "baseline primitive receipt") + require(macros == checks["scalar_macros"], "scalar macro count") + require(dict(paid) == {int(k): value for k, value in checks["paid_profile"].items()}, "paid profile") + require(peak == Q(inherited["prefix_l1_upper"]), "inherited prefix envelope") + total = sum(primitive_tags.values()) + require(baseline - total == 2 * (additions + units), "closed-form savings") + return { + "all_input_columns": n, + "dirty_helper_columns_restored": 492, + "scalar_macros": macros, + "additions": additions, + "unit_additions": units, + "baseline_real_primitives": baseline, + "new_real_primitives": total, + "saved_real_primitives": baseline - total, + "primitive_tags": dict(sorted(primitive_tags.items())), + "primitive_word_sha256": circuit_hash.hexdigest(), + "paid_profile": {str(k): value for k, value in sorted(paid.items())}, + "retained_prefix_l1_upper": str(peak), + "charged_payload_bits": inherited["charged_payload_bits"], + }, coefficients + + +def verify(): + pins = read(HERE / "SOURCE-PINS.json") + for name, expected in pins["files"].items(): + path = ROOT / name + payload = gzip.decompress(path.read_bytes()) if path.suffix == ".gz" else path.read_bytes() + require(digest(payload) == expected, "source pin: " + name) + results, coefficients = {}, set() + for provider in ("ck", "jp8"): + directory = PROVIDERS / provider + programs = read(directory / "LOCAL-PROGRAMS.json.gz") + checks = read(directory / "LOCAL-CHECKS.json") + inherited = read(directory / "INDEPENDENT-LOCAL-REPLAY.json") + require(set(programs) == {"forward", "backward"}, "program orientations") + for orientation in ("forward", "backward"): + events = programs[orientation] + require(digest(json.dumps(events, sort_keys=True, separators=(",", ":")).encode()) == checks[orientation]["sha256"], "program semantic hash") + key = provider + "/" + orientation + results[key], used = replay(provider, orientation, events, checks[orientation], inherited["local"][orientation]) + coefficients.update(used) + for q in coefficients: + op = ["add", ["T", 0], ["S", 0], q.numerator, q.denominator] + macro_check(q, lower(op)) + return {"status": "PASS_COMPLEX_DYADIC_LOWERING", "programs": results, + "distinct_coefficients": len(coefficients), "controls": negative_controls(coefficients)} + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--json", action="store_true", help="print the deterministic receipt") + args = parser.parse_args() + result = verify() + require(result == read(HERE / "EXPECTED.json"), "expected receipt mismatch") + if args.json: + print(json.dumps(result, indent=2, sort_keys=True)) + else: + savings = ",".join(str(x["saved_real_primitives"]) for x in result["programs"].values()) + print(f"PASS_COMPLEX_DYADIC_LOWERING programs=4 columns=716 savings={savings} controls={len(result['controls']['rejected'])}") From 5a3f983715027c4fd83f50bc9001d4b18463bed1 Mon Sep 17 00:00:00 2001 From: Sagar Thakrar Date: Tue, 13 Oct 2026 09:51:53 +0530 Subject: [PATCH 2/2] Record focused replay and sprint handoff for PR696 --- research/complex-dyadic-lowering/CLAIM.json | 5 ++++- research/complex-dyadic-lowering/VALIDATION.md | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/research/complex-dyadic-lowering/CLAIM.json b/research/complex-dyadic-lowering/CLAIM.json index 2ffc781c21..fe1ef081dc 100644 --- a/research/complex-dyadic-lowering/CLAIM.json +++ b/research/complex-dyadic-lowering/CLAIM.json @@ -17,5 +17,8 @@ "prior_work_checked": [651, 679, 681, 683, 687, 667], "prior_negative_results": "research/structural-gain/factory/README.md and research/experiment-log/README.md. No closed packet, hosting, or retiming search is reopened.", "seed_use": "Seed 22 selects CK first and the 22nd distinct nonunit coefficient for mutation controls. All coefficients and all four programs are covered, with no randomized search.", - "status": "claimed" + "status": "completed", + "result": "All four 716-column primitive replays and all 686 coefficient checks pass; 10 negative controls rejected. Saved real primitives: CK forward 55320/backward 55352, JP8 forward 56852/backward 56884. Paid profiles and kappa unchanged.", + "pull_request": "https://github.com/CrocSwap/integer-mult-bounds/pull/696", + "final_overlap_check": "513 open PRs through #693; no matching selected-word coefficient-lowering scope. Historical #411 credited; PR681 changes a factory scalar word. origin/main still equals the exact base." } diff --git a/research/complex-dyadic-lowering/VALIDATION.md b/research/complex-dyadic-lowering/VALIDATION.md index 4bd434bda3..e20f5119b6 100644 --- a/research/complex-dyadic-lowering/VALIDATION.md +++ b/research/complex-dyadic-lowering/VALIDATION.md @@ -8,12 +8,18 @@ Validated locally on macOS on 2026-10-13, based on | `python3 -B research/complex-dyadic-lowering/verify.py` | PASS on Python 3.14.8 | | `python3.11 -B -O research/complex-dyadic-lowering/verify.py` | PASS on Python 3.11.15, all checks remain active without assertions | | `make selected-record-check` | PASS, selected source inventory and exact κ unchanged | +| `git diff --cached --check` | PASS, only this research package is added | The deterministic evidence is in [EXPECTED.json](EXPECTED.json). Both Python runs match it, including all four primitive-word hashes. The package makes no wall-clock performance claim. The original and replacement primitive counts refer to the same pinned complete scalar inputs. +A minimal committed archive of the seven package files and nine pinned source +files also passes under Python 3.11.15 with `-O`, invoked by absolute script path +from an unrelated working directory. This checks that no untracked file, local +dependency, repository import or original checkout path is required. + An additional scoped AI worker reviewed the algebra, operation vocabulary, source binding and written scope. That review identified the need to compare prefixes per register, including the initial dirty-work row. The implementation