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
150 changes: 150 additions & 0 deletions research/depth5-chain-connector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Shortest unsigned depth-five chain connector: small m and 9 <= m <= 20

This package answers open question 2 of
[#4263](https://github.com/CrocSwap/integer-mult-bounds/pull/4263) for depth
five in a bounded range of characteristics. The contribution was produced by
Nick Petalas.

The complete calls are `z_l += B_l z_{l-1}` for l = 1, ..., 5, with x = z_0
immutable and z_1, ..., z_4 and y = z_5 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_4
and add `c B5 B4 B3 B2 B1 x` to y. There are no sign or inverse calls.

| m | 2 | 3 | 4 | 5 to 8 | 9 to 20 |
|---|---:|---:|---:|---|---:|
| shortest length | 16 = 8m | 24 = 8m | 28 (c = 1, 3), 24 (c = 2) | 5m for the listed c only | 5m for every c |
| evidence | exhaustive BFS | exhaustive BFS | exhaustive BFS (opt-in) + words | witnesses | witnesses |

- **m = 2, 3:** the minimum is 8m, well above the per-call floor 5m. At depth
four the same characteristics cost 6m (#4249).
- **m = 4:** the minimum depends on c. It is 24 = 6m for c = 2 and 28 = 7m for
c = 1 and c = 3. Shortest words are recorded for each c; the optimal ones read
back from the search double calls 2 and 3 (c = 1, 3) or call 3 (c = 2).
- **m = 5 to 8:** the floor 5m is attained for (5, 1), (6, 3), (7, 1..4) and
(8, 1..4, 6). For the other eleven residues in this range the bounded search
found no 5m word; that is a **search failure**, not a lower bound.
- **9 <= m <= 20:** the floor 5m is attained for every nonzero c (162 pairs).

So the depth-five premium is larger than at depth four and lasts at least to
m = 4 for every residue. It is gone for every residue from m = 9 to m = 20.
Whether it persists for some residues at m = 5 to 8 is open.

Claim types: **exhaustive finite computation** for the minima at m = 2, 3, 4
(the m = 4 lower bound is an opt-in run, see below), and a **finite
certificate** for each listed witness. No all-m theorem, no new κ, no supplier
admission and no change to the selected frontier.

## Argument

**Lemma 1 (floor; #4249).** 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 the product of the generators I + e_{l,l+1} in UT6(Z/m) equals
I + c e_{1,6}, iff every N[i..j] is 0 mod m except N[1..5], which is c mod m.
Each call therefore appears a positive multiple of m times, so every correct
word has at least 5m calls, and lengths between multiples of m are impossible.

A word with exactly m copies of each call that meets the interval conditions
therefore has the shortest length 5m.

**Exact minima.** Breadth-first search from the identity over all
m^15 elements of UT6(Z/m), with the five generators as edges, gives the
distance to every I + c e_{1,6}. Any positive word reaching that element is a
correct word, and conversely, so the BFS distance is the exact minimum. The
same routine at depth four reproduces #4249's 12, 18, 20 and 25 at m = 2..5 as
a positive control.

**Observation.** A cyclic rotation of a correct word is correct: if
w = a v then v a = a^{-1} (a v) a, and I + c e_{1,6} is central. Rotations
were not used to produce witnesses.

## Evidence and reproduction

From the repository root, with CPython 3.12 and numpy:

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

Any CPython 3.12 with numpy 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_DEPTH5_CHAIN_CONNECTOR bfs_cases=6 witnesses=173 m4_words=3`. It checks:

- BFS minima: depth five at m = 2, 3; depth four at m = 2..5.
- For every witness: length 5m and exactly m copies of each call; the interval
conditions by one chronological counting pass; separately, the UT6(Z/m)
matrix product; and two literal replays with dirty registers in (Z/m)^2 and
random, generally noncommuting 2x2 maps, checking that z_1..z_4 are restored
and y gains exactly c B5 B4 B3 B2 B1 x.
- Full rows: every c from 1 to m - 1 is present for 9 <= m <= 20.
- The three m = 4 words, at lengths 28, 24, 28, by the same three checks.
- Five rejection controls on the (m, c) = (14, 1) witness: a wrong coefficient,
a dropped call, a swap of adjacent noncommuting calls, one relabelled call
and one extra call.

The m = 4 lower bounds need a BFS over 4^15 ≈ 1.07 × 10^9 elements. It takes
about 9 minutes and 20 GB of memory, so it is opt-in and not a registered
check:

```sh
/Users/nick/git/integer-mult-bounds/.venv/bin/python3.12 -W error -B research/depth5-chain-connector/verify.py --exhaustive-m4
```

It asserts the distances {1: 28, 2: 24, 3: 28}. This path ran to completion
locally (CPython 3.12.15, numpy 2.5.4, macOS arm64) in 8 min 52 s and printed
`PASS_DEPTH5_CHAIN_CONNECTOR bfs_cases=7`. An equivalent standalone BFS gave the
same distances and saved the distance table from which the m = 4 words were
read back. Hosted CI does not run this path, so the m = 4 lower bounds are
local evidence that a reviewer can rerun with the command above.

[search_witnesses.c](search_witnesses.c) is the simulated-annealing search that
found the 5m witnesses (`cc -O2 -o anneal search_witnesses.c -lm`, then
`./anneal 5 M C SEED TRIES SWEEPS`). It is not part of the replay; the verifier
checks the words themselves. Three rounds were run: 40 restarts of 3 × 10^6
sweeps for 4 <= m <= 20, then 60 × 6 × 10^6 and 150 × 8 × 10^6 on the
residues still missing.

## Limitations

The m = 4 lower bounds rest on the opt-in exhaustive run described above, which hosted CI does not repeat. The
missing residues at m = 5 to 8 and every m > 20 are not decided. Each witness
is a finite certificate for its own (m, c); no all-m theorem is claimed.
Independent human and formal proof-kernel review are unclaimed. Every call
carries its complete implementation price. Admission, dispatch, routing of the
four 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 argument and the
depth-four minima at m = 2..5 come from
[#4249](https://github.com/CrocSwap/integer-mult-bounds/pull/4249); the
depth-four floor for 6 <= m <= 32 and the depth-five question come from
[#4263](https://github.com/CrocSwap/integer-mult-bounds/pull/4263), whose
annealing objective search_witnesses.c adapts. Ross Richardson's
[#943/#934 lineage](../universal-connector-boundary/README.md) supplies the
complete-call dirty-connector interface. The new results here are the
depth-five minima at m = 2, 3, 4, the residue dependence at m = 4, and the 173
floor witnesses. Subword counts, unitriangular matrices and BFS 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 and #4263. 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. What are the exact depth-five minima at m = 5, 6, 7, 8 for the eleven
residues with no 5m witness here? A meet-in-the-middle search over balanced
prefixes and suffixes could exclude 5m without the full m^15 BFS.
2. Is the depth-five minimum exactly 5m for every m >= 9?
3. Why does the m = 4 minimum depend on c? A 2-adic obstruction might be
provable by hand and might recur at m = 8.
38 changes: 38 additions & 0 deletions research/depth5-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": "Chain model, the interval-count reduction and the per-call floor argument, and the depth-four minima 12, 18, 20, 25 at m = 2..5, which the BFS here reproduces as a control; no executable dependency."
},
{
"url": "https://github.com/CrocSwap/integer-mult-bounds/pull/4263",
"head_commit": "2183322b32a5975ecb4a6aec2ec8f43ac08b1aec",
"credit": "Nick Petalas",
"role": "Depth-four floor 4m for 6 <= m <= 32 and its open question 2 (depth five), which this package answers in part; the annealing objective is adapted from its search script. No executable dependency."
}
]
}
74 changes: 74 additions & 0 deletions research/depth5-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": "Determine the shortest unsigned word for the depth-five dirty chain connector z_l += B_l z_{l-1} (l = 1..5, z_0 = x immutable, z_1..z_4 and y = z_5 dirty) over characteristic m, answering open question 2 of PR #4263 in a bounded range: exact minima at m = 2, 3, 4 by exhaustive search, and the per-call floor 5m attained for every nonzero residue c when 9 <= m <= 20.",
"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 and depth-four side questions of PRs #4249 and #4263. It does not extend a source-count census or claim a supplier improvement.",
"bottleneck_link": "A recursive boundary that routes through four dirty intermediates pays this call count. The premium over the floor is larger and lasts longer than at depth four (8m at m = 2, 3; 6m or 7m at m = 4 depending on c) and is gone for 9 <= m <= 20. Side result: no consumer, paid profile or kappa change is supplied.",
"budget_minutes": 60,
"stop_rule": "Stop after exhaustive minima for the smallest characteristics and explicit floor witnesses for every (m, c) in a bounded range, with literal dirty replay and source-bound publication checks. No all-m construction is attempted.",
"outcome": "completed",
"evidence": "verify.py runs BFS over all of UT6(Z/m) for m = 2, 3 (and over UT5 for m = 2..5 as a control against #4249), checks 173 floor witnesses (every c for 9 <= m <= 20, eleven pairs at m = 5..8) and three m = 4 words by interval counts, an independent UT6 product and literal dirty replays, and prints a receipt with package and input SHA-256 values. The m = 4 lower bounds come from a full BFS over 4^15 elements, run with verify.py --exhaustive-m4 (about 9 minutes and 20 GB locally; not a registered check).",
"author": "Nick Petalas",
"ai_assistance": "Independent human and formal proof-kernel review are unclaimed.",
"open_questions": [
{
"question": "What are the exact depth-five minima at m = 5, 6, 7, 8 for the residues with no floor witness here?",
"why_it_matters": "It would locate exactly where the depth-five premium ends; the search found the 5m floor only for some c in this range.",
"first_step": "For each missing (m, c), test whether 6m is attained by annealing with one doubled call (search_witnesses.c accepts count vectors), and exclude 5m by a meet-in-the-middle search over balanced prefixes and suffixes.",
"blocked_by": "A full BFS needs m^15 states (3e10 at m = 5); annealing failure at 5m is not a proof of impossibility."
},
{
"question": "Is the depth-five minimum exactly 5m for every m >= 9?",
"why_it_matters": "It would make the premium a small-characteristic effect at depth five as well.",
"first_step": "Look for a parametric family of the four interleaving sequences (the depth-five form of #4263 Lemma 2).",
"blocked_by": "The depth-four all-m question of #4263 is itself open."
},
{
"question": "Why does the m = 4 minimum depend on c (24 for c = 2, 28 for c = 1, 3)?",
"why_it_matters": "A residue-dependent premium suggests a 2-adic obstruction that might be provable by hand and extend to m = 8 or other even m.",
"first_step": "Compare the reachable top-corner residues of balanced and one-doubled words at m = 4 and m = 8.",
"blocked_by": "Only the m = 4 BFS is available; m = 8 is far beyond exhaustive search."
}
]
}
36 changes: 36 additions & 0 deletions research/depth5-chain-connector/VERIFY.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"schema_version": 1,
"status": "ready",
"python": "3.12",
"requirements": [
"numpy==2.5.4"
],
"inputs": [
"research/universal-connector-boundary/README.md"
],
"commands": [
{
"argv": [
"{python}",
"-W",
"error",
"-B",
"{package}/verify.py"
],
"timeout_seconds": 300,
"checks": "Exhaustive BFS over UT(K+1, Z/m): depth five at m = 2, 3 (minima 16, 24) and depth four at m = 2..5 as a control (12, 18, 20, 25). Every witness in witnesses.json: exactly m copies of each call, interval subword counts, independent UT6(Z/m) product, two literal dirty noncommuting replays; full rows for 9 <= m <= 20; the three m = 4 words of lengths 28, 24, 28; five rejection controls; source hashes."
},
{
"argv": [
"{python}",
"-O",
"-W",
"error",
"-B",
"{package}/verify.py"
],
"timeout_seconds": 300,
"checks": "The same checks with Python assertions disabled; all contracts use explicit exceptions."
}
]
}
37 changes: 37 additions & 0 deletions research/depth5-chain-connector/search_witnesses.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* Simulated annealing for a depth-K chain word with the given letter counts
(default: M copies of each call) whose interval counts N[i..j] are 0 mod M
except N[1..K] = C. Not part of the replay: verify.py checks the words.
Build: cc -O2 -o anneal search_witnesses.c -lm
Usage: ./anneal K M C SEED TRIES SWEEPS [count_1 ... count_K] */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static unsigned long long s;
static unsigned long long rnd(void){ s ^= s << 13; s ^= s >> 7; s ^= s << 17; return s; }
static int K, M, C, L, w[1024];
static int cost(void){
long N[8][8] = {{0}};
for (int t = 0; t < L; t++){ int l = w[t]; for (int i = l - 1; i >= 1; i--) N[i][l] = (N[i][l] + N[i][l-1]) % M; N[l][l]++; }
int tot = 0;
for (int i = 1; i <= K; i++) for (int j = i + 1; j <= K; j++){
int want = (i == 1 && j == K) ? C : 0; int a = (int)((N[i][j] - want) % M + M) % M; tot += a < M - a ? a : M - a; }
return tot;
}
int main(int argc, char **argv){
K = atoi(argv[1]); M = atoi(argv[2]); C = atoi(argv[3]); s = 88172645463325252ULL ^ (unsigned long long)atoll(argv[4]) * 2654435761ULL;
int tries = atoi(argv[5]); long sweeps = atol(argv[6]);
int cnt[8]; for (int l = 1; l <= K; l++) cnt[l] = argc > 6 + l ? atoi(argv[6 + l]) : M;
for (int a = 0; a < tries; a++){
L = 0; for (int l = 1; l <= K; l++) for (int k = 0; k < cnt[l]; k++) w[L++] = l;
for (int t = L - 1; t > 0; t--){ int u = rnd() % (t + 1); int x = w[t]; w[t] = w[u]; w[u] = x; }
int cur = cost(); double T = 2.0;
for (long it = 0; it < sweeps && cur; it++){
int i = rnd() % L, j = rnd() % L; if (w[i] == w[j]) continue;
int x = w[i]; w[i] = w[j]; w[j] = x; int nw = cost();
if (nw <= cur || (rnd() % 1000000) / 1e6 < exp((cur - nw) / T)) cur = nw; else { w[j] = w[i]; w[i] = x; }
T = T * 0.99999; if (T < 0.3) T = 0.3;
}
if (!cur){ printf("%d %d %d ", M, C, a); for (int t = 0; t < L; t++) printf("%d", w[t]); printf("\n"); return 0; }
}
printf("%d %d NONE\n", M, C); return 1;
}
Loading