diff --git a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/chained_seam_findings.md b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/chained_seam_findings.md index 5f8e5d6..8cd82fd 100644 --- a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/chained_seam_findings.md +++ b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/chained_seam_findings.md @@ -192,12 +192,41 @@ first branching nodes) by one explicit regular seam family: paint every even lev cycle one colour, and every odd level cycle as a single monochromatic block plus the two parity-forced off-colour vertices. +## Finding 8 — the regular family is REFUTED at n=15 + +`kempe_regular_family_test.py` (tests the fixed regular family with per-tile +early-exit). At n=12 it threads 614/614 (matches the CSP). **At n=15 it FAILS**, on two +distinct classes of no-separating-triangle tiles: + +- **non-branching, large even outer + odd inner:** e.g. `UUUUUUDUDUDUDUD` (no bite), + p=10, inner face size 5. Monochromatic `σ10 = 0^10` on the 10-up rim cannot coexist + with `σ5 = 00012` on the inner face. +- **branching, odd outer + two even inner faces:** e.g. `UDUDUDDUDUDDDDD` bite=(5,12), + p=5, faces `[4,4]`. `σ5` outer with monochromatic `σ4` on *both* inner faces is not + jointly realisable. Branching tiles: **1011/1022 threaded, 11 fail.** + +So the clean regular conjecture is **false**. Crucially this refutation is exactly the +`R_T` **coupling** (Finding 1) asserting itself at scale: the regular family sets outer +and inner states *independently per size*, but `R_T` is not a product, so a large +monochromatic rim over-constrains the annular cycle and forbids the paired inner +necklace. The failure is not about branching per se — it hits large even rims (non- +branching) and small odd rims with two even children (branching) alike. + +### What it means for strategy +The uniform "one state per size, everywhere" family was a **too-strong shortcut** — +much stronger than the chain-pigeonhole conjecture, which only needs *some* compatible +selection per chain with freedom to choose a *different* state at each interface. Its +failure costs a cheap constructive route, **not** the conjecture: pairwise overlap +still always holds. The load transfers to the genuine object — **per-interface +selection respecting `R_T` coupling**, i.e. composing `R_T` along chains/trees with +per-seam freedom rather than a global family. + ## Open threads -- **Conjecture the regular family always works.** Does `σ_m = 0^m` (even) / - `0^{m-2}12` (odd) thread *every* no-separating-triangle tile for all `n`? Push to - n=15, 16 (branching grows: 1022 branching tiles at n=15) and look for any failure. -- **Why does the restriction make monochromatic-even universal?** Separating-triangle - tiles are exactly what blocked an all-one-colour rim; removing them frees it. -- **`R_T` composition along real trees** rather than per-size uniformity — the fully - general conjecture. +- **Per-interface `R_T` composition** along real chains/trees (per-seam freedom, + respecting coupling) — the paper's §6 conjecture proper, now the main line. +- **Structural lemma for the over-constraint.** Why does a monochromatic large rim + forbid the paired odd-inner necklace? A parity/structure argument on the annular + cycle for these specific failing tiles is small and concrete. +- (Set aside) whether *some* irregular uniform family still works at n=15 (full CSP) + — reframed away from; expensive (~hours) and not the conjecture. diff --git a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_regular_family_test.py b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_regular_family_test.py new file mode 100644 index 0000000..22db251 --- /dev/null +++ b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_regular_family_test.py @@ -0,0 +1,105 @@ +"""Stress-test the regular uniform seam family on no-separating-triangle tiles. + +Regular family (parity-admissible): + sigma_m = 0^m (monochromatic) if m even + sigma_m = 0^(m-2) 1 2 (one block + 1 + 2) if m odd + +Conjecture: sigma threads every tile with no length-3 boundary -- i.e. some +Kempe-balanced colouring shows sigma on the outer rim AND sigma on every inner +face simultaneously. This tests it at a given n, streaming progress and printing +any failure immediately (a failure would be a counterexample). + +Run: python3 kempe_regular_family_test.py --n 15 +""" + +from __future__ import annotations + +import argparse +import sys +import time +from collections import defaultdict + +from full_medial_tire_generator import generate, innermost_bite +from kempe_valid_colorings import classify_colorings +from kempe_transfer_relation_probe import necklace +from kempe_universal_trend_probe import has_length3_boundary +from kempe_up_tooth_sequences import seq_str + + +def sigma(m: int) -> tuple[int, ...]: + pat = tuple([0] * m) if m % 2 == 0 else tuple([0] * (m - 2) + [1, 2]) + return necklace(pat) + + +def inner_faces(g): + faces = defaultdict(list) + for e in g.singleton_down_edges: + faces[innermost_bite(e, g.bites)].append(e) + return [sorted(es) for es in faces.values() if len(es) >= 3] + + +def threads(g, faces) -> bool: + want_o = sigma(len(g.up_edges)) + want_i = [sigma(len(f)) for f in faces] + for c, v in classify_colorings(g, dedup_colors=True): + if not v.valid: + continue + if necklace(tuple(c[f"u{e}"] for e in g.up_edges)) != want_o: + continue + if all(necklace(tuple(c[f"d{e}"] for e in f)) == w + for f, w in zip(faces, want_i)): + return True + return False + + +def run(args): + n = args.n + print(f"n={n}: regular family sigma_m = 0^m (even) / 0^(m-2)12 (odd) " + f"vs no-separating-triangle tiles\n") + t0 = time.time() + tested = passed = branch_tested = branch_passed = 0 + failures = [] + for g in generate(n, min_up_teeth=3, dedup=True): + faces = inner_faces(g) + if not faces or has_length3_boundary(g): + continue + is_branch = len(faces) >= 2 + if args.branch_only and not is_branch: + continue + ok = threads(g, faces) + tested += 1 + passed += ok + if is_branch: + branch_tested += 1 + branch_passed += ok + if not ok: + b = ",".join(f"({i},{j})" for i, j in sorted(g.bites)) or "-" + rec = (f"word={g.tooth_word} bites={b} p={len(g.up_edges)} " + f"faces={[len(f) for f in faces]}") + failures.append(rec) + print(f" !! FAILURE: {rec}") + sys.stdout.flush() + if tested % 1000 == 0: + print(f" ... {tested} tiles, {passed} ok, {len(failures)} fail " + f"[{time.time() - t0:.0f}s]") + sys.stdout.flush() + print(f"\nn={n}: {passed}/{tested} tiles threaded " + f"(branching {branch_passed}/{branch_tested}) [{time.time() - t0:.0f}s]") + if failures: + print(f"{len(failures)} FAILURE(S) -- regular family is NOT universal:") + for r in failures[:30]: + print(" ", r) + else: + print("=> regular family threads EVERY no-separating-triangle tile at this n.") + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--n", type=int, default=15) + parser.add_argument("--branch-only", action="store_true", + help="test only branching tiles (>=2 inner faces)") + run(parser.parse_args()) + + +if __name__ == "__main__": + main()