Skip to content

research: bound A5 caller embedding into additive addresses - #3914

Draft
1337isnot1337 wants to merge 1 commit into
CrocSwap:mainfrom
1337isnot1337:research/luna-pass-20261018-laptop-02
Draft

1337isnot1337 wants to merge 1 commit into
CrocSwap:mainfrom
1337isnot1337:research/luna-pass-20261018-laptop-02

Conversation

@1337isnot1337

Copy link
Copy Markdown
Contributor

Summary

This adds a scoped caller-interface lemma for the completed two-register A5 word from PR #2246. A5 is perfect, so every homomorphism from its label group into an abelian source address group is trivial. In particular, mapping the A5 labels into the additive M_3(Q) caller model sends every group-algebra basis label to [0]; diag([xy],[yx]) becomes the identity. Every action then has the same address-side trace. Cleanup can return the borrowed registers unchanged, but that restoration alone cannot supply the missing A5 action distinction.

The package does not repeat the A5 word search or claim a native supplier, a kappa improvement, or a universal impossibility result. It identifies the exact missing escape route: a nonabelian native carrier or another caller implementation that does not induce the specified group homomorphism.

Evidence

  • python3 -I -B research/a5-abelian-caller-interface/verify.py passes. It reconstructs A5, verifies the (2,3,5) target relations and distinct nonidentity order-five labels, checks the exact four-call positive word, and verifies the commutator proof of perfectness.
  • python3 scripts/research_package.py --package research/a5-abelian-caller-interface --check-only passes metadata and source-pin checks.
  • python3 -B scripts/check_research_commit.py --package research/a5-abelian-caller-interface --check-source-history passes committed-byte and source-history checks.
  • python3 -B scripts/research_baseline.py passes PASS_RESEARCH_BASELINE_BINDINGS_ONLY; the selected full replay and registered Python 3.12 replay were not run.

Scope and credit

The A5 target, four-call word and finite lower bound come from 1337isnot1337's merged PR #2246. The additive caller contract comes from the cited three-register baseline. This package contributes only the caller-collapse proof and its focused verification. No independent human or proof-assistant review is claimed, and the selected frontier remains unchanged.

Publication validation

python3.12 scripts/research_package.py --package research/a5-abelian-caller-interface passed on CPython 3.12.3, and python3.12 scripts/check_research_commit.py --package research/a5-abelian-caller-interface --check-source-history passed. The registered replay left the worktree clean. This supersedes any earlier pending note above for the registered package replay; separate full selected cold-replay limits remain as stated.

@rcfc-jreed

Copy link
Copy Markdown
Contributor

Independent scoped audit of the A5 abelian caller embedding at e44c6355: packaging defect (missing RESULT.json); group algebra otherwise agrees (19/19)

Code-disjoint checks; does not import package verify.py. Package bytes from head e44c63550d59173d7f5425b97c7fe22764214e0b via GitHub contents API. CLAIM.

Defect found:

  • D1 — missing RESULT.json. verify.py prints PASS_A5_ABELIAN_CALLER_COLLAPSE …, but the package ships no committed RESULT.json.

What still passes:

  1. Pins: base 20ecf289…; VERIFY ready.
  2. A5: |A5|=60; generators x=(01)(23), y=(024) generate A5 with orders (2,3).
  3. Target: xy/yx order 5 and distinct; four diagonal F₂[A5] factors yield diag(xy,yx).
  4. Perfectness controls: 20 three-cycles, each a commutator, generate A5; abelian-image / F₂-cancellation controls.

Not covered: new κ; formal-kernel proof; supplier construction.

This is a finite group-algebra replay, not a formal proof. Adding a committed RESULT.json would close D1.

check.py
#!/usr/bin/env python3
"""Code-disjoint audit of PR #3914 A5 abelian caller embedding."""

from __future__ import annotations

import hashlib
import json
from itertools import permutations
from pathlib import Path

ROOT = Path(__file__).resolve().parent
PKG = ROOT / "pkg"
BASE = "20ecf2891d80b5acf18d980b2164fb44ea7faa90"
HEAD = "e44c63550d59173d7f5425b97c7fe22764214e0b"


def check(name: str, cond: bool) -> bool:
    print(f"[{'PASS' if cond else 'FAIL'}] {name}")
    return bool(cond)


def sha256_file(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def mul(p, q):
    return tuple(p[q[i]] for i in range(len(p)))


def inv(p):
    out = [0] * len(p)
    for i, image in enumerate(p):
        out[image] = i
    return tuple(out)


def cyc(*cycles):
    out = list(range(5))
    for support in cycles:
        for i, value in enumerate(support):
            out[value] = support[(i + 1) % len(support)]
    return tuple(out)


def is_even(p):
    return sum(p[i] > p[j] for i in range(5) for j in range(i + 1, 5)) % 2 == 0


def generate(identity, generators):
    steps = set(generators) | {inv(g) for g in generators}
    seen = {identity}
    pending = [identity]
    while pending:
        cur = pending.pop()
        for step in steps:
            prod = mul(cur, step)
            if prod not in seen:
                seen.add(prod)
                pending.append(prod)
    return seen


def ord_of(g, identity):
    cur = identity
    for n in range(1, 61):
        cur = mul(cur, g)
        if cur == identity:
            return n
    return None


def f2_mul(left, right):
    out = set()
    for a in left:
        for b in right:
            p = mul(a, b)
            if p in out:
                out.remove(p)
            else:
                out.add(p)
    return frozenset(out)


def mat_mul(A, B):
    z = frozenset()
    rows = []
    for i in range(2):
        row = []
        for j in range(2):
            entry = z
            for k in range(2):
                entry ^= f2_mul(A[i][k], B[k][j])
            row.append(entry)
        rows.append(tuple(row))
    return tuple(rows)


def id_mat(identity):
    u = frozenset((identity,))
    z = frozenset()
    return ((u, z), (z, u))


def diag_factor(label, role, identity):
    u = frozenset((identity,))
    z = frozenset()
    diff = frozenset((label, identity))
    M = [list(r) for r in id_mat(identity)]
    M[role][role] ^= diff
    return tuple(tuple(r) for r in M)


def main() -> int:
    results: list[tuple[str, bool]] = []
    sources = json.loads((PKG / "SOURCES.json").read_text(encoding="utf-8"))
    task = json.loads((PKG / "TASK.json").read_text(encoding="utf-8"))
    verify = json.loads((PKG / "VERIFY.json").read_text(encoding="utf-8"))
    readme = (PKG / "README.md").read_text(encoding="utf-8")

    results.append(("D1 RESULT.json absent (packaging)", not (PKG / "RESULT.json").exists()))
    results.append(("D2 SOURCES.base_commit", sources.get("base_commit") == BASE))
    results.append(("D3 TASK.base_commit", task.get("base_commit") == BASE))
    results.append(("D4 VERIFY.status ready", verify.get("status") == "ready"))
    results.append(("D5 TASK.outcome", task.get("outcome") in ("completed", "partial", "negative-result")))
    results.append(("D6 README mentions A5", "A5" in readme))

    identity = tuple(range(5))
    a5 = {p for p in permutations(range(5)) if is_even(p)}
    x = cyc((0, 1), (2, 3))
    y = cyc((0, 2, 4))
    results.append(("G1 |A5|==60", len(a5) == 60))
    results.append(("G2 generators in A5", x in a5 and y in a5))
    results.append(("G3 <x,y>=A5", generate(identity, (x, y)) == a5))
    results.append(("G4 orders (2,3)", ord_of(x, identity) == 2 and ord_of(y, identity) == 3))

    xy = mul(x, y)
    yx = mul(y, x)
    results.append(("T1 xy,yx order 5", ord_of(xy, identity) == 5 and ord_of(yx, identity) == 5))
    results.append(("T2 xy≠yx≠id", xy != yx and xy != identity and yx != identity))

    word = id_mat(identity)
    for label, role in ((x, 0), (y, 0), (y, 1), (x, 1)):
        word = mat_mul(word, diag_factor(label, role, identity))
    z = frozenset()
    target = ((frozenset((xy,)), z), (z, frozenset((yx,))))
    results.append(("W1 four-call diag(xy,yx)", word == target))

    three = [g for g in a5 if ord_of(g, identity) == 3]
    results.append(("P1 twenty 3-cycles", len(three) == 20))
    comm_ok = True
    for r in three:
        a = next(i for i in range(5) if r[i] != i)
        b = r[a]
        d, e = [i for i in range(5) if i not in (a, b, r[b])]
        s = cyc((a, b), (d, e))
        commutator = mul(mul(mul(r, s), inv(r)), inv(s))
        if not (s in a5 and commutator == inv(r)):
            comm_ok = False
            break
    results.append(("P2 every 3-cycle is a commutator", comm_ok))
    results.append(("P3 3-cycles generate A5", generate(identity, three) == a5))

    rational_zero = (0,) * 9
    results.append(("C1 trivial abelian image singleton", len({rational_zero for _ in a5}) == 1))
    invalid_x = (1,) + (0,) * 8
    results.append(("C2 2*phi(x)≠0 torsion control", tuple(2 * v for v in invalid_x) != rational_zero))
    mapped = frozenset((identity,)) ^ frozenset((identity,))
    results.append(("C3 F2 paid difference cancels", mapped == z))

    digests = {p.name: sha256_file(p) for p in sorted(PKG.iterdir()) if p.is_file()}
    (ROOT / "digests.json").write_text(json.dumps(digests, indent=2) + "\n", encoding="utf-8")

    passed = sum(1 for name, cond in results if check(name, cond))
    total = len(results)
    print(f"SUMMARY {passed}/{total}")
    (ROOT / "summary.txt").write_text(f"{passed}/{total}\n", encoding="utf-8")
    return 0 if passed == total else 1


if __name__ == "__main__":
    raise SystemExit(main())

James Reed (@rcfc-jreed), with substantial AI assistance (Claude, in Cursor).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants