Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions research/depth4-chain-connector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Shortest unsigned depth-four chain connector, 6 <= m <= 32

This finite certificate answers open question 1 of
[#4249](https://github.com/CrocSwap/integer-mult-bounds/pull/4249) for
characteristics 6 to 32. The contribution was produced by Nick Petalas.

The complete calls are `z_l += B_l z_{l-1}` for l = 1, 2, 3, 4, with x = z_0
immutable and z_1, z_2, z_3 and y = z_4 holding arbitrary dirty data. The maps
are arbitrary and the coefficients lie in a nonzero unital ring of exact
characteristic m. For a nonzero residue c the word must restore z_1, z_2 and
z_3 and add `c B4 B3 B2 B1 x` to y. There are no sign or inverse calls.

```text
shortest length = 4m for every 6 <= m <= 32 and every c != 0 (mod m)
```

The per-call floor is 4m. #4249 found that depth four costs more than this
floor in small characteristic: exact search there gives 12, 18, 20 and 25
calls at m = 2, 3, 4 and 5. This package shows that the premium is gone at
m = 6 and stays gone through m = 32, for all 486 pairs (m, c). With the m <= 5
values from #4249, the depth-four minimum is known exactly for 2 <= m <= 32.

| m | 2 | 3 | 4 | 5 | 6 to 32 |
|---|---:|---:|---:|---:|---:|
| shortest length | 12 = 6m | 18 = 6m | 20 = 5m | 25 = 5m | 4m |
| source | #4249 | #4249 | #4249 | #4249 | this package |

Claim type: **finite certificate** for each listed (m, c). No all-m theorem,
no new κ, no supplier admission and no change to the selected frontier.

## Argument

**Lemma 1 (floor; #4249, Lemmas 1 and 2).** Write N[i..j] for the number of
scattered occurrences of the subword i(i+1)...j in the word. The word is correct
for c iff every N[i..j] is 0 mod m, except N[1..4] which is c mod m. Since
N[l..l] is the number of calls l, each call appears a multiple of m times, and
at least once because N[1..4] is nonzero. So every correct word has at least 4m
calls. Equivalently, the product of the generators I + e_{l,l+1} in UT5(Z/m)
must equal I + c e_{1,5}.

So a word with exactly m copies of each call that meets the interval
conditions has the shortest length 4m. [witnesses.json](witnesses.json) gives
one for every pair (m, c) with 6 <= m <= 32 and 1 <= c < m.

**Lemma 2 (three interleavings).** Calls l and l' commute unless |l - l'| = 1,
so a word is determined, up to its action, by three sequences: x_j, the number
of calls 1 before the j-th call 2; y_k, the number of calls 2 before the k-th
call 3; and z_l, the number of calls 3 before the l-th call 4. Write
X(s) = x_1 + ... + x_s and Y(s) = y_1 + ... + y_s. Then

```text
N[1..2] = Σ x_j N[2..3] = Σ y_k N[3..4] = Σ z_l
N[1..3] = Σ_k X(y_k) N[2..4] = Σ_l Y(z_l)
N[1..4] = Σ_l Σ_{k <= z_l} X(y_k)
```

*Proof.* A call 3 completes N[1..3] once for each 1-2 pair before it, which is
X(y_k) for the k-th call 3. The other lines follow in the same way, one level
at a time. ∎

The verifier checks Lemma 2 against direct counting on 2,000 random balanced
words. It is only used to state the open question below; the certificate does
not depend on it.

### What did not give an all-m law

A uniform construction was attempted and not found. These attempts are recorded
so the next contributor does not repeat them:

- Minimum-block witnesses: the smallest number of blocks `l^e` in a 4m
witness is 13 to 18 at m = 6, depending on c, and 16 for every c at m = 7.
At m = 7 the six minimum-block witnesses use only two mirrored {1,2,3}
skeletons, with the calls 4 split over three gaps. For a fixed skeleton the
conditions on the three gap multiplicities are linear mod m.
- That m = 7 skeleton, with letter sequence 3 2 3 2 3 1 2 3 2 3 1 2 1, one
large block per call and every other block of length 1 or 2, does not give a
uniform family. Two such skeletons cover every residue at m = 9 with three
gaps; none covers every residue at m = 10, and none at m = 11.
- With x_j = j - 1 and z_l = l - 1 (odd m) and a single interior block of
y-values, no solution exists with up to four interior values at m = 7 to 15.
Up to seven values gives only a few residues.
- With z restricted to two interior picks and y to one interior block of three
values, solutions exist at m = 7 and 13, via a cube root of unity
(y-block (1, q, q²)), but not at m = 9 or 11.
- Several block designs make Y(s) - s equal the weighted 1-2-3 count at every
gap, which forces c = 0.

These were local exploratory searches; their scripts are not part of the
package.

## Evidence and reproduction

From the repository root, with CPython 3.12 and its standard library:

```sh
/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -W error -B research/depth4-chain-connector/verify.py
/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -O -W error -B research/depth4-chain-connector/verify.py
/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/research_package.py --package research/depth4-chain-connector
/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -B scripts/check_research_commit.py --package research/depth4-chain-connector --check-source-history
```

Any CPython 3.12 can replace the local interpreter path. The verifier writes no
files. It prints a JSON receipt with the SHA-256 of every package file and
input, then `PASS_DEPTH4_CHAIN_CONNECTOR moduli=27 witnesses=486`. It checks:

- For every witness: length 4m and exactly m copies of each call.
- The interval conditions of Lemma 1, by one chronological counting pass.
- Separately, the UT5(Z/m) matrix product equals I + c e_{1,5}.
- Two literal replays per witness, 972 in all, with dirty registers in
(Z/m)^2 and random 2x2 maps. These maps generally do not commute. The replay
checks that z_1, z_2 and z_3 are restored and y gains exactly c B4 B3 B2 B1 x.
- Six rejection controls on the witness for (m, c) = (7, 3): a wrong
coefficient, a dropped call, a swap of adjacent noncommuting calls, the
reversed word, one extra call, and the floor predicate.
- Lemma 2 on 2,000 random balanced words.

[search_witnesses.py](search_witnesses.py) is how the witnesses were found.
It runs simulated annealing over balanced words, seeded by (m, c), with
`search_witnesses.py M C`. It is not part of the replay. The verifier checks
the words themselves, so it does not matter how they were found.

## Limitations

The result covers only 6 <= m <= 32. It is a finite certificate per (m, c),
not an all-m theorem. The m <= 5 values are #4249's and are not rechecked
here. Independent human and formal proof-kernel review are unclaimed. Every
call carries its complete implementation price. Admission, dispatch, routing of
the three intermediates and word-dependent physical costs are extra. No
supplier caller, precision analysis, outer multiplication theorem or new κ is
supplied.

## Attribution and scope

The chain model, the interval-count reduction, the floor and the m <= 5
depth-four minima come from
[#4249](https://github.com/CrocSwap/integer-mult-bounds/pull/4249). The
depth-two chain and its 2m floor come from
[#4231](https://github.com/CrocSwap/integer-mult-bounds/pull/4231) and
[#4236](https://github.com/CrocSwap/integer-mult-bounds/pull/4236). Ross
Richardson's [#943/#934 lineage](../universal-connector-boundary/README.md)
supplies the complete-call dirty-connector interface. The new results here
are the 486 witnesses, the exact minimum 4m for 6 <= m <= 32, Lemma 2 as
stated and the recorded failed families. Subword counts and unitriangular
matrices are classical tools; no novelty is claimed for them. Exact pins are in
[SOURCES.json](SOURCES.json).

The `connector-alphabet-change` card is explicitly changed to this side
question, as in #4249. The alphabet stays unsigned and complete; only the chain
gets one more call. Apache-2.0.

## Open next questions

The structured questions in [TASK.json](TASK.json) give first steps and
blockers.

1. Is the depth-four minimum exactly 4m for every m >= 6? A parametric family
of the sequences x, y, z of Lemma 2 would prove it. The failed families above
show which simple shapes do not work.
2. Does the per-call floor km hold at depth k >= 5 for all large m, and from
which m on?
3. Does any concrete recursive caller route through three dirty intermediates
with a favorable complete invoice for these 4m calls?
38 changes: 38 additions & 0 deletions research/depth4-chain-connector/SOURCES.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"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": "input",
"git_blob": "d277f7c5830b1f2bc42e1ff41ab86e7d7564929f",
"sha256": "23415f7829ab8d80a783142f10f7d31abbce84579362769984680af3df954476"
}
],
"context_only": [
{
"url": "https://github.com/CrocSwap/integer-mult-bounds/pull/4249",
"head_commit": "03b8a19d7442edebb3565064631f6ca2408d731e",
"credit": "Nick Petalas",
"role": "Depth-three chain law, the interval-count reduction and the 4m floor argument, and the exact depth-four minima 12, 18, 20, 25 at m = 2..5. Open question 1 there is answered here for 6 <= m <= 32; no executable dependency."
},
{
"url": "https://github.com/CrocSwap/integer-mult-bounds/pull/4236",
"head_commit": "bd9b426837cddd37338dd284e49cc2303de57ca0",
"credit": "Nick Petalas",
"role": "Depth-two (one-source) unsigned connector and its 2m floor; no executable dependency."
}
]
}
74 changes: 74 additions & 0 deletions research/depth4-chain-connector/TASK.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"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": "Decide the shortest unsigned word for the depth-four dirty chain connector z_l += B_l z_{l-1} (l = 1..4, z_0 = x immutable, z_1..z_3 and y = z_4 dirty) over characteristic m, answering open question 1 of PR #4249 for 6 <= m <= 32: the per-call floor 4m is attained for every nonzero residue c, by explicit witness words.",
"scope_change_reason": "The card asks about one extension of the connector alphabet. This package keeps the unsigned complete-call alphabet and lengthens the one-source chain by one more call, continuing the depth-three side question of PR #4249, whose open question 1 asks for the depth-four minimum. It does not extend a source-count census or claim a supplier improvement.",
"bottleneck_link": "A recursive boundary that routes through three dirty intermediates pays this call count. PR #4249 found a premium over the per-call floor for m <= 5 (12, 18, 20, 25 calls); this package shows the premium disappears for 6 <= m <= 32. Side result: no consumer, paid profile or kappa change is supplied.",
"budget_minutes": 60,
"stop_rule": "Stop after explicit witnesses for every (m, c) in a bounded range with literal dirty replay and source-bound publication checks. A uniform all-m construction was attempted for part of the session and not found; no all-m theorem is claimed.",
"outcome": "completed",
"evidence": "witnesses.json lists one word with exactly m copies of each call for each of the 523 pairs (m, c), 6 <= m <= 32, 1 <= c < m. verify.py checks each word by interval subword counts, by an independent UT5(Z/m) matrix product and by two literal replays with dirty registers and random 2x2 maps, plus rejection controls, and prints a receipt with package and input SHA-256 values. The 4m floor is Lemma 1 in README.md.",
"author": "Nick Petalas",
"ai_assistance": "Independent human and formal proof-kernel review are unclaimed.",
"open_questions": [
{
"question": "Is the depth-four minimum exactly 4m for every m >= 6?",
"why_it_matters": "It would make the depth-four premium a small-characteristic effect, m <= 5 only, matching the depth-three law of PR #4249 where only three exceptions exist.",
"first_step": "Use the three-interleaving form of README Lemma 2. Find a parametric family of the sequences x, y, z for odd m and for even m, and test it against the 523 witnesses here.",
"blocked_by": "The structured families tried here (single interior blocks, x_j = j - 1, z_l = l - 1) either collapse c to 0 or exist only when m has a nontrivial cube root of unity."
},
{
"question": "Does the per-call floor km hold at depth k >= 5 for all large m, and from which m on?",
"why_it_matters": "This would say whether longer dirty chains pay only a small-characteristic premium.",
"first_step": "Run search_witnesses.py adapted to depth five for m from 6 to 12, and an exhaustive balanced-word search where m^(k(k-1)/2) states allow it.",
"blocked_by": "No depth-five search was run here."
},
{
"question": "Can a concrete recursive caller use a depth-four chain through three dirty intermediates at a favorable complete invoice?",
"why_it_matters": "The call count is exact in the stated range, but admission, dispatch and routing are unpriced.",
"first_step": "Locate one pinned caller that composes four complete calls through dirty workspace and price all 4m calls plus its frame changes.",
"blocked_by": "No selected-supplier caller is bound here."
}
]
}
34 changes: 34 additions & 0 deletions research/depth4-chain-connector/VERIFY.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"schema_version": 1,
"status": "ready",
"python": "3.12",
"requirements": [],
"inputs": [
"research/universal-connector-boundary/README.md"
],
"commands": [
{
"argv": [
"{python}",
"-W",
"error",
"-B",
"{package}/verify.py"
],
"timeout_seconds": 240,
"checks": "Every witness in witnesses.json for 6 <= m <= 32 and 1 <= c < m: exactly m copies of each call, interval subword counts, independent UT5(Z/m) product, two literal dirty noncommuting replays each; six rejection controls; source hashes."
},
{
"argv": [
"{python}",
"-O",
"-W",
"error",
"-B",
"{package}/verify.py"
],
"timeout_seconds": 240,
"checks": "The same checks with Python assertions disabled; all contracts use explicit exceptions."
}
]
}
80 changes: 80 additions & 0 deletions research/depth4-chain-connector/search_witnesses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""Search for a balanced depth-four witness for one (m, c); not part of the replay.

Simulated annealing over words with exactly m copies of each call, moving by
swapping two different calls. The objective is the circular distance of the
six non-diagonal interval counts from (0, 0, 0, 0, 0, c) mod m. This is how
witnesses.json was produced; verify.py checks the words themselves, so any
other search method would serve equally. Usage: search_witnesses.py M C
"""
import math
import random
import sys

DEPTH = 4
SWEEPS = 400_000


def interval_residues(word: list, m: int) -> tuple:
n1 = n2 = n3 = n12 = n23 = n34 = n13 = n24 = n14 = 0
for letter in word:
if letter == 1:
n1 += 1
elif letter == 2:
n12 += n1
n2 += 1
elif letter == 3:
n13 += n12
n23 += n2
n3 += 1
else:
n14 += n13
n24 += n23
n34 += n3
return (n12 % m, n23 % m, n34 % m, n13 % m, n24 % m, n14 % m)


def distance(residues: tuple, m: int, c: int) -> int:
target = (0, 0, 0, 0, 0, c)
return sum(min((a - b) % m, (b - a) % m) for a, b in zip(residues, target))


def anneal(m: int, c: int, rng: random.Random):
word = [l for l in range(1, DEPTH + 1) for _ in range(m)]
rng.shuffle(word)
cost = distance(interval_residues(word, m), m, c)
temperature = 2.0
for _ in range(SWEEPS):
if cost == 0:
return word
i, j = rng.randrange(len(word)), rng.randrange(len(word))
if word[i] == word[j]:
continue
word[i], word[j] = word[j], word[i]
new = distance(interval_residues(word, m), m, c)
if new <= cost or rng.random() < math.exp((cost - new) / temperature):
cost = new
else:
word[i], word[j] = word[j], word[i]
temperature = max(0.3, temperature * 0.99995)
return None


def main() -> None:
if len(sys.argv) != 3:
raise SystemExit("usage: search_witnesses.py M C")
m, c = int(sys.argv[1]), int(sys.argv[2])
if not (2 <= m and 1 <= c < m):
raise SystemExit("need m >= 2 and 1 <= c < m")
rng = random.Random(1000 * m + c)
for attempt in range(1, 101):
word = anneal(m, c, rng)
if word is not None:
assert interval_residues(word, m) == (0, 0, 0, 0, 0, c)
print(m, c, attempt, "".join(map(str, word)))
return
raise SystemExit(f"no witness for (m, c) = ({m}, {c}) in 100 restarts")


if __name__ == "__main__":
main()
Loading