From 894fd12cd29946b9b0f6b32bb73bd33bc437158f Mon Sep 17 00:00:00 2001 From: Nick Petalas Date: Wed, 21 Oct 2026 01:54:31 +0100 Subject: [PATCH] feat(research): lower seven-source ternary connector to 6600 calls --- research/f3-ternary-seven-source/README.md | 167 ++++++++++++++ research/f3-ternary-seven-source/SOURCES.json | 30 +++ research/f3-ternary-seven-source/TASK.json | 92 ++++++++ research/f3-ternary-seven-source/VERIFY.json | 32 +++ research/f3-ternary-seven-source/verify.py | 206 ++++++++++++++++++ 5 files changed, 527 insertions(+) create mode 100644 research/f3-ternary-seven-source/README.md create mode 100644 research/f3-ternary-seven-source/SOURCES.json create mode 100644 research/f3-ternary-seven-source/TASK.json create mode 100644 research/f3-ternary-seven-source/VERIFY.json create mode 100644 research/f3-ternary-seven-source/verify.py diff --git a/research/f3-ternary-seven-source/README.md b/research/f3-ternary-seven-source/README.md new file mode 100644 index 0000000000..95840a2338 --- /dev/null +++ b/research/f3-ternary-seven-source/README.md @@ -0,0 +1,167 @@ +# A 6600-call seven-source full ternary connector + +The unsigned dirty connector with seven immutable sources and all 2186 +nonzero coefficient rows over F3 has a **6600-call construction**, improving +[#4256](https://github.com/CrocSwap/integer-mult-bounds/pull/4256)'s upper +bound of 6603 by three complete calls. This answers its open question 2 with +a small improvement. The claim type is a **finite construction certificate**, +with the prefix identity explaining why the certified word works in every +compatible dimension. No exact optimum, new kappa or supplier admission is +claimed. The cited lower bound from +[#4244](https://github.com/CrocSwap/integer-mult-bounds/pull/4244) remains +6588, so the current cited interval is 6588 <= OPT_3(7) <= 6600. + +## Exact interface + +For each j = 0..6, x_j is immutable. The connector z and all distinct outputs +y_v are arbitrarily dirty. For every nonzero v in F3^7 the required action is + +```text +y_v += sum_j v_j A_v B_j x_j; z and every x_j are unchanged. +``` + +The maps are arbitrary compatible F3-linear maps, including singular and +noncommuting maps. Only unsigned complete calls are permitted: + +```text +B_j: z += B_j x_j +A_v: y_v += A_v z +``` + +Every call restores its private scratch and heads. Outputs are observed only +after the batch and cannot be borrowed. There are no inverses, direct A_v B_j +calls, extra connectors, frames, source mutation or free copies. The word is +independent of data and map entries. This is the full-demand interface of +Nick Petalas's #4238/#4244, building on the credited connector lineage below. +The number priced here is complete calls at unit prices. Physical costs that +are not part of those complete primitive implementations remain additional. + +## Certificate and argument + +Use this 42-event source word, with one digit denoting the source index: + +```text +260536506545241601014125215430234634321306 +``` + +Each of the seven source labels occurs six times, so the connector is +restored in characteristic three. Let q_t be the vector of source counts +modulo three before event t, for t = 0..41. The closing boundary is q_42 = 0 +and duplicates q_0. The verifier enumerates all +binomial(44, 3) = 13244 boundary triples with repetition and checks + +```text +{q_a + q_b + q_c : 0 <= a <= b <= c < 42} = F3^7. +``` + +For each nonzero row v, take its lexicographically first such triple and +place its three A_v calls at those boundaries. Several readouts at the same +boundary mean consecutive calls. Readouts do not change z, so all chosen +triples can be scheduled together, in boundary order. At boundary t, + +```text +z = z_initial + sum_j (q_t)_j B_j x_j. +``` + +The three readouts add three copies of A_v z_initial, which vanish, and +sum_j v_j A_v B_j x_j. This uses only linearity and never interchanges A_v +and B_j. Each target receives exactly its required increment. The total is + +```text +42 source calls + 3 * (3^7 - 1) readouts = 42 + 6558 = 6600. +``` + +The predecessor #4256 has 45 source calls and the same 6558 readouts, giving +6603. Both totals and the shared row/readout counts are checked numerically +by the arithmetic above. No predecessor census or theorem is reverified. + +The source path was found by a bounded swap search starting with six uses of +every source. Search stopped at the first covering path. Discovery is not +part of the certificate: the explicit word and exhaustive triple check are +sufficient, and no search-failure or optimality claim is made. + +## Evidence and reproduction + +The standard-library verifier writes no files and imports no predecessor +code. It checks all 2187 rows including zero using both packed base-three +arithmetic and a separately written tuple computation. It then emits and +replays all 6600 calls using a generic coefficient ledger. That ledger tracks +incoming dirt and each B_j x_j separately, with A_v acting on the left. + +Eight dense executions use dimensions 1..4, two fixtures per dimension, dirty +connectors and outputs, and explicit singular noncommuting maps in dimensions +at least two. Six mutations must fail: a dropped source call, a dropped +readout, a misrouted output, relabelled source calls, an appended source call, +and execution in characteristic six. The last control detects the unpaid +assumption that three readouts always cancel incoming dirt. + +From the repository root, with CPython 3.12: + +```sh +~/git/integer-mult-bounds/.venv/bin/python3.12 -W error -B research/f3-ternary-seven-source/verify.py +~/git/integer-mult-bounds/.venv/bin/python3.12 -W error -O -B research/f3-ternary-seven-source/verify.py +~/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/research_package.py --package research/f3-ternary-seven-source +~/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/check_research_commit.py --package research/f3-ternary-seven-source --check-source-history +``` + +Expected marker: `PASS_F3_TERNARY_SEVEN_SOURCE`, with `calls=6600`, +`rows=2186`, `source_calls=42`, `dense_cases=8` and `rejected_controls=6`. +The generated stdout receipt binds the counts to SHA256 hashes of all five +package files. No hand-written receipt or generated replay output is stored. +[SOURCES.json](SOURCES.json) pins historical provenance at the public base. +The pending predecessors are citations rather than executable dependencies. + +The code is nonrecursive, and every loop is bounded by fixed certificate +sizes, at most 64 source events, 2186 rows and dense dimension four. Each +function is shorter than 60 physical lines. Python-managed allocation is an +explicit Power of Ten deviation: dynamic objects are required by the runtime; +live verification storage is bounded by these fixed domains. There is no +unbounded input, background process or generated file. Warnings are errors +in both registered modes; checks use explicit exceptions and remain enabled +under optimization. + +## Limits and family decision + +This finite certificate supplies an upper bound. It does not exclude shorter +words or improve #4256's asymptotic exponent. The interval's lower endpoint +is the cited result of #4244 and is not a new proof here. A proof-kernel build, +independent human review and the selected cold replay are unclaimed and unrun. + +The call count is proved for the abstract interface. A concrete consumer for +full ternary demand is unknown. Coefficient preparation, physical dispatch, +stock, hosting, precision, tape costs and complete supplier admission remain +unknown. Unknown costs are not zero. No selected source, frontier, shared +code or predecessor package changes. + +The catalogue card asks for an alphabet extension. This is explicitly a +changed scope: the alphabet is retained and a full-demand finite upper bound +is improved. The family decision is to finish this small result and stop. +There is no downstream implementation campaign or claim that the complete +consumer fits a supplier budget. + +## Open next questions + +Structured questions are in [TASK.json](TASK.json). + +1. Is the cited lower bound 6588 attained? Start with a restored 30-event + source path covering all ternary rows by triples, or a word that trades + source calls for extra readouts. An unsuccessful search is not exclusion. +2. Can the 42-event path yield a smaller leading constant in an all-n + construction? A lifting argument must preserve all triple decompositions + and charge every source event, rather than merely multiplying palette + sizes. No such lifting is supplied here. +3. Does a concrete caller need every ternary row? Identify its complete maps, + dirty-state contract and physical invoice before extending this family. + +## Credit + +This contribution was produced by Nick Petalas. Nick Petalas's #4256 posed +the seven-source upper-bound question and supplied the 6603-call torus-block +baseline; #4238/#4244 introduced full ternary demand and its cited lower +bounds. Credit #4231 for the unsigned ring interface, Riquelme Soares's +#4189 for the unsigned F3 predecessor, Ross Richardson's #943/#934 for the +prefix-connector and Gray-block lineage, conorholds's #2208 for block palettes +and all-word counting in different alphabets, and ywz65 for the five-source +contract map. No priority is claimed for elementary prefix sums or dirty +cancellation. Predecessor credit is unchanged. Independent human and formal +proof-kernel review are unclaimed. Apache-2.0. diff --git a/research/f3-ternary-seven-source/SOURCES.json b/research/f3-ternary-seven-source/SOURCES.json new file mode 100644 index 0000000000..915c72b0fe --- /dev/null +++ b/research/f3-ternary-seven-source/SOURCES.json @@ -0,0 +1,30 @@ +{ + "schema_version": 1, + "base_commit": "12fa8c5c844be21bfefb38a19503fbd867a11244", + "files": [ + { + "path": "certificates/selected-result.json", + "usage": "provenance", + "git_blob": "b1fea0c94436b236cc2b7d41a7be032811b94c81", + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129" + }, + { + "path": "docs/research/agent-task-catalog.json", + "usage": "provenance", + "git_blob": "64bfc5af6709ed9811171e0a2108f05e1219cb65", + "sha256": "352a6184713b8843d96fd2c2071eb7aeaa655906b7c51d45ad444912666c8a96" + }, + { + "path": "research/universal-connector-boundary/README.md", + "usage": "provenance", + "git_blob": "d277f7c5830b1f2bc42e1ff41ab86e7d7564929f", + "sha256": "23415f7829ab8d80a783142f10f7d31abbce84579362769984680af3df954476" + }, + { + "path": "docs/research/five-source-connector-scope-map.md", + "usage": "provenance", + "git_blob": "c4b56250e35eb52f07987f7e96c7dba18fac75d1", + "sha256": "5b541588a5ddb38b4dbbf5dca91cc9e6684f67462d515e25f838d833ec30f62f" + } + ] +} diff --git a/research/f3-ternary-seven-source/TASK.json b/research/f3-ternary-seven-source/TASK.json new file mode 100644 index 0000000000..a6f5e76ed6 --- /dev/null +++ b/research/f3-ternary-seven-source/TASK.json @@ -0,0 +1,92 @@ +{ + "schema_version": 1, + "task_id": "connector-alphabet-change", + "priority_revision": 7, + "base_commit": "12fa8c5c844be21bfefb38a19503fbd867a11244", + "original_card": { + "id": "connector-alphabet-change", + "question": "Does one explicit extension of the connector alphabet offer a favorable completed budget?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/universal-connector-boundary/README.md", + "certificates/selected-result.json" + ], + "methods": [ + "Construct and charge a legal extra operation on a minimal instance.", + "Prove a target-specific bound after adding one specified operation family." + ], + "acceptance_gate": "State which fixed-alphabet premise changes and charge its implementation; do not declare it free. 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", + "research/universal-connector-boundary/verify.py" + ], + "expected": "PASS_UNIVERSAL_CONNECTOR_BOUNDARY", + "inspect": "Reproduce the 945-pairing control, then read Exact interface to list the allowed calls.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "Add exactly one legally priced operation and test a tiny dirty-input instance before enumerating larger cases.", + "bottleneck_link": "A new legal connector operation could change recursive interface cost; a larger census in the same alphabet is a separate side result.", + "allowed_variations": [ + "Choose one additional operation and a small source count for its first counterexample." + ], + "scope_change_triggers": [ + "Keeping the alphabet and only increasing the source count; record this as a changed assignment.", + "Extending a source-count census without naming a supplier/interface decision it could change; audit #2973 pruning concerns before relying on the affected predecessor exclusions." + ], + "overlap_terms": [ + "universal connector", + "source-toggle", + "connector alphabet" + ] + }, + "scope_status": "changed", + "actual_scope": "A 6600-call upper bound for the seven-source unsigned F3 dirty connector with all 2186 nonzero ternary rows.", + "scope_change_reason": "Retains the alphabet and improves a full-demand finite construction, answering PR4256 open question 2 rather than extending the operation alphabet.", + "bottleneck_link": "Side result on a recursive connector interface. A concrete full-demand consumer and complete supplier invoice are unknown; no kappa claim.", + "budget_minutes": 60, + "stop_rule": "Stop research at the first verified upper-bound improvement, then package it. No shorter-word search after the 42-event witness.", + "outcome": "completed", + "evidence": "All 13244 boundary triples cover all 2187 rows; packed and tuple arithmetic agree. Literal 6600-call replay, eight dense dirty executions and six rejection controls pass.", + "author": "Nick Petalas", + "ai_assistance": "Independent human and formal proof-kernel review are unclaimed.", + "open_questions": [ + { + "question": "Is the cited lower bound 6588 attained?", + "why_it_matters": "Would settle the seven-source full ternary optimum.", + "first_step": "Seek a restored 30-event path covering every row by triples, or a legal source/readout tradeoff.", + "blocked_by": "No covering shorter word or stronger all-word lower bound is supplied." + }, + { + "question": "Can this finite palette reduce the leading constant of an all-n construction?", + "why_it_matters": "PR4256 matches the exponent but leaves a constant gap.", + "first_step": "Prove a lifting rule preserving triple decompositions and count every positive source step.", + "blocked_by": "No such lifting rule is known here." + }, + { + "question": "Which concrete caller requires full ternary demand?", + "why_it_matters": "A local call saving needs a consumer before it can affect a supplier.", + "first_step": "Pin a caller and price maps, dispatch and dirty return.", + "blocked_by": "Caller, stock, precision and physical implementation are unknown." + } + ], + "predecessors": [ + { + "pr": 4256, + "head": "6a95ef419f94e7b5c2fff710e34081520cc6aba2", + "role": "6603 upper bound and open question 2; citation only" + }, + { + "pr": 4244, + "head": "f436d2911351e5be2842208fe96b0b66442323a4", + "role": "full-demand interface and cited 6588 lower bound; citation only" + }, + { + "pr": 4238, + "head": "191a905d7adba6695b079f744140a73e832787a8", + "role": "full ternary demand predecessor; citation only" + } + ], + "result": "Finite construction certificate: 42 source calls and 6558 readouts, total 6600, three fewer than the cited 6603 upper bound." +} diff --git a/research/f3-ternary-seven-source/VERIFY.json b/research/f3-ternary-seven-source/VERIFY.json new file mode 100644 index 0000000000..42ec469368 --- /dev/null +++ b/research/f3-ternary-seven-source/VERIFY.json @@ -0,0 +1,32 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "inputs": [], + "commands": [ + { + "argv": [ + "{python}", + "-W", + "error", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "Independent complete triple coverage, literal dirty coefficient replay, eight dense noncommuting fixtures and six rejection controls." + }, + { + "argv": [ + "{python}", + "-W", + "error", + "-O", + "-B", + "{package}/verify.py" + ], + "timeout_seconds": 120, + "checks": "The same scientific checks with Python optimization enabled; all contracts remain active." + } + ] +} diff --git a/research/f3-ternary-seven-source/verify.py b/research/f3-ternary-seven-source/verify.py new file mode 100644 index 0000000000..2b8066873a --- /dev/null +++ b/research/f3-ternary-seven-source/verify.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +"""Replay the 6600-call seven-source full ternary certificate. + +Produced by Nick Petalas. Apache-2.0. +""" +from collections import Counter +from hashlib import sha256 +from itertools import combinations_with_replacement, product +import json +from math import comb +from pathlib import Path +import random + + +SOURCES = 7 +ROWS = 3 ** SOURCES - 1 +SOURCE_WORD = tuple(map(int, "260536506545241601014125215430234634321306")) + + +def require(condition, message): + if not condition: + raise ValueError(message) + + +def digits(value): + require(0 <= value <= ROWS, "coefficient row out of range") + result = [] + for _ in range(SOURCES): + value, digit = divmod(value, 3) + result.append(digit) + return tuple(result) + + +def packed_sum(left, right): + value, place = 0, 1 + for _ in range(SOURCES): + value += ((left % 3 + right % 3) % 3) * place + left //= 3 + right //= 3 + place *= 3 + return value + + +def packed_prefixes(word): + require(0 < len(word) <= 64, "source path length out of bounds") + state, prefixes = 0, [] + for source in word: + require(0 <= source < SOURCES, "invalid source") + prefixes.append(state) + state = packed_sum(state, 3 ** source) + require(state == 0, "source path is not restored") + return prefixes + + +def construct(): + require(len(SOURCE_WORD) == 42, "wrong source count") + require(Counter(SOURCE_WORD) == Counter({j: 6 for j in range(SOURCES)}), + "wrong source multiplicities") + prefixes = packed_prefixes(SOURCE_WORD) + witnesses = {} + for a, b, c in combinations_with_replacement(range(42), 3): + row = packed_sum(packed_sum(prefixes[a], prefixes[b]), prefixes[c]) + if row not in witnesses: + witnesses[row] = (a, b, c) + require(len(witnesses) == ROWS + 1, "a ternary row is missing") + events = [[] for _ in range(42)] + for row in range(1, ROWS + 1): + for boundary in witnesses[row]: + events[boundary].append(("A", row)) + calls = [] + for boundary, source in enumerate(SOURCE_WORD): + calls.extend(events[boundary]) + calls.append(("B", source)) + require(len(calls) == 6600, "wrong complete-call count") + return calls, witnesses + + +def independent_coverage(): + # Tuple arithmetic, independently of packed_sum and the constructed schedule. + state, prefixes = [0] * SOURCES, [] + for source in SOURCE_WORD: + prefixes.append(tuple(state)) + state[source] = (state[source] + 1) % 3 + require(state == [0] * SOURCES, "tuple path is not restored") + covered = set() + for a, b, c in combinations_with_replacement(prefixes, 3): + covered.add(tuple((x + y + z) % 3 for x, y, z in zip(a, b, c))) + require(covered == set(product(range(3), repeat=SOURCES)), + "tuple coverage is incomplete") + return len(covered) + + +def formal_replay(calls, modulus=3): + require(len(calls) <= 6601 and modulus in (3, 6), "replay bound exceeded") + # Entries stand for incoming connector dirt, then B_j x_j. + connector = [1] + [0] * SOURCES + outputs = [[0] * (SOURCES + 1) for _ in range(ROWS)] + for kind, label in calls: + if kind == "B": + require(0 <= label < SOURCES, "invalid source call") + connector[label + 1] = (connector[label + 1] + 1) % modulus + else: + require(kind == "A" and 1 <= label <= ROWS, "invalid readout") + target = outputs[label - 1] + for j, coefficient in enumerate(connector): + target[j] = (target[j] + coefficient) % modulus + require(connector == [1] + [0] * SOURCES, "connector dirt changed") + for row, target in enumerate(outputs, 1): + # A_row left-multiplies every symbol. No A/B commutation is used. + require(target == [0] + list(digits(row)), f"wrong row {row}") + return len(outputs) + + +def matvec(matrix, vector): + return [sum(a * b for a, b in zip(row, vector)) % 3 for row in matrix] + + +def matmul(left, right): + size = len(left) + return [[sum(left[i][k] * right[k][j] for k in range(size)) % 3 + for j in range(size)] for i in range(size)] + + +def dense_replay(calls, size, seed): + require(1 <= size <= 4, "dense dimension out of bounds") + rng = random.Random(seed) + sources = [[rng.randrange(3) for _ in range(size)] for _ in range(SOURCES)] + b_maps = [[[rng.randrange(3) for _ in range(size)] for _ in range(size)] + for _ in range(SOURCES)] + if size >= 2: + # Singular noncommuting maps are included, not assumed generic. + b_maps[0] = [[int(i == 0 and j == 1) for j in range(size)] + for i in range(size)] + b_maps[1] = [[int(i == 1 and j == 0) for j in range(size)] + for i in range(size)] + require(matmul(b_maps[0], b_maps[1]) != matmul(b_maps[1], b_maps[0]), + "dense fixture lost noncommutation") + a_maps = [[[rng.randrange(3) for _ in range(size)] for _ in range(size)] + for _ in range(ROWS)] + connector = [rng.randrange(3) for _ in range(size)] + initial_connector = connector[:] + outputs = [[rng.randrange(3) for _ in range(size)] for _ in range(ROWS)] + expected = [row[:] for row in outputs] + images = [matvec(matrix, source) for matrix, source in zip(b_maps, sources)] + for row in range(1, ROWS + 1): + vector = [sum(d * image[k] for d, image in zip(digits(row), images)) % 3 + for k in range(size)] + increment = matvec(a_maps[row - 1], vector) + expected[row - 1] = [(x + y) % 3 for x, y in zip(expected[row - 1], increment)] + for kind, label in calls: + if kind == "B": + increment, target = matvec(b_maps[label], sources[label]), connector + else: + increment = matvec(a_maps[label - 1], connector) + target = outputs[label - 1] + target[:] = [(x + y) % 3 for x, y in zip(target, increment)] + require(connector == initial_connector, "dense connector not restored") + require(outputs == expected, "dense output is wrong") + return ROWS + + +def controls(calls): + first_b = next(i for i, call in enumerate(calls) if call[0] == "B") + first_a = next(i for i, call in enumerate(calls) if call[0] == "A") + dropped_b = calls[:first_b] + calls[first_b + 1:] + dropped_a = calls[:first_a] + calls[first_a + 1:] + misrouted = calls[:] + misrouted[first_a] = ("A", misrouted[first_a][1] % ROWS + 1) + relabelled = [(kind, (label + 1) % SOURCES if kind == "B" else label) + for kind, label in calls] + appended = calls + [("B", 0)] + cases = [(dropped_b, 3), (dropped_a, 3), (misrouted, 3), + (relabelled, 3), (appended, 3), (calls, 6)] + rejected = 0 + for mutant, modulus in cases: + try: + formal_replay(mutant, modulus) + except ValueError: + rejected += 1 + require(rejected == len(cases), "a semantic control was accepted") + return rejected + + +def main(): + calls, witnesses = construct() + require(formal_replay(calls) == ROWS, "formal row count changed") + covered = independent_coverage() + dense_cases = 0 + for size in range(1, 5): + for seed in (621, 1020): + require(dense_replay(calls, size, seed) == ROWS, "dense row count changed") + dense_cases += 1 + rejected = controls(calls) + folder = Path(__file__).resolve().parent + hashes = {name: sha256((folder / name).read_bytes()).hexdigest() + for name in ("README.md", "SOURCES.json", "TASK.json", "VERIFY.json", "verify.py")} + receipt = {"marker": "PASS_F3_TERNARY_SEVEN_SOURCE", "source_calls": 42, + "readouts": 3 * ROWS, "calls": len(calls), "rows": ROWS, + "covered_including_zero": covered, "boundary_triples": comb(44, 3), + "dense_cases": dense_cases, "rejected_controls": rejected, + "witness_rows": len(witnesses) - 1, "sha256": hashes} + print(json.dumps(receipt, sort_keys=True)) + + +if __name__ == "__main__": + main()