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 18343ab..39efd08 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 @@ -104,12 +104,46 @@ overlap always holds, so chains still glue by choosing states per interface. The conjecture's difficulty is thus concentrated in rare exceptional tiles and the branch-coupled selection around them, not in any single seam or in a scaling trend. +## Finding 5 — restricting to no separating triangles REMOVES the obstruction + +The 4CT reduces to triangulations with no separating triangles (internally +4-connected). In the tread model, a separating (non-facial) triangle in `G` shows up +as a **length-3 boundary walk** of a tread: an outer rim of 3 up teeth, or an inner +face holding exactly 3 singleton down teeth (the `012` seam). Restricting to tiles +with **no length-3 boundary** (`kempe_universal_trend_probe.py --no-tri`, +`kempe_uniform_family_probe.py --no-tri`): + +- The n=12 breaker `UUUDUDUDUDUD` bite=(3,11) has a size-3 inner face (the bite + encloses exactly `d5,d7,d9`), so it is **excluded** — along with its kin. +- The size-7 universal at n=12 is **restored**: `|D[7]|` goes `0 → 2`, on a reduced + population (211 → 76 size-7 boundaries). Across `n = 6..13` and all sizes, **every + `|D[m]| ≥ 1`** — no empty universal anywhere. +- The uniform-family CSP becomes **FEASIBLE at n=12** (was infeasible). The threading + family is now the simplest one — **monochromatic on even sizes, min-cut on odd**: + + ``` + σ4 = 0000 σ5 = 00012 σ6 = 000000 σ7 = 0000012 σ8 = 00000000 + ``` + + (Without the restriction, `σ4` had to be `0011`, not monochromatic, because + separating-triangle tiles blocked the all-0 rim. Removing them lets monochromatic + even seams work.) + +So the **only** universal failure we found (n=12, size 7) was an artifact of admitting +tiles that correspond to **non-4-connected** triangulations. On the 4CT-relevant class +(no separating triangles), the uniform seam family exists and gluing is constructively +trivial throughout the tested range — no pigeonhole needed. + +Caveat: even at n=12 the restricted population has **0 branching tiles** (multi-inner +faces all require a size-3 face at this n), so the branching case stays untested under +the restriction; and this is `n ≤ 13` only. + ## Open threads -- **Why n=12 / why this tile?** The breaker is the most-alternating 7-up word with an - antipodal bite. Is the sporadic failure tied to `n` even / specific bite spans? - Worth checking n=14, 16 for size-7 (and other) re-failures. -- **CSP at n=13.** With `|D[m]| > 0` for every size, the per-size obstruction is gone; - whether the joint uniform-family CSP is feasible again at n=13 needs a run. -- **Branch-tree composition.** n=12 has 175 true branching tiles; composing `R_T` - along actual trees (not just per-size uniformity) is the conjecture proper. +- **Branching under the restriction.** No-separating-triangle branching tiles need + larger `n` (every inner face ≥ 4). Find the smallest `n` that has them and test the + uniform family there — the genuine conjecture case. +- **Does the restricted uniform family persist?** It holds for `n ≤ 13`; a single + later failure (as in the unrestricted n=12 case) would be very informative. Push to + n=14, 16. +- **`R_T` composition along real trees** rather than per-size uniformity. diff --git a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_uniform_family_probe.py b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_uniform_family_probe.py index bdc880e..b4bd0c8 100644 --- a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_uniform_family_probe.py +++ b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_uniform_family_probe.py @@ -26,6 +26,7 @@ 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, cuts +from kempe_universal_trend_probe import has_length3_boundary from kempe_up_tooth_sequences import seq_str @@ -64,6 +65,8 @@ def run(args): for g in generate(n, min_up_teeth=3, dedup=True): if not inner_faces(g): continue + if args.no_tri and has_length3_boundary(g): + continue t = Tile(g) tiles.append(t) # marginal realisable sets per boundary (for domain restriction) @@ -135,6 +138,9 @@ def run(args): def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--n", type=int, default=9) + parser.add_argument("--no-tri", action="store_true", + help="exclude tiles with a length-3 boundary " + "(no separating triangle in G)") run(parser.parse_args()) diff --git a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_universal_trend_probe.py b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_universal_trend_probe.py index bf860b7..b10e28c 100644 --- a/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_universal_trend_probe.py +++ b/papers/medial_tire_decompositions_of_plane_triangulations/experiments/kempe_universal_trend_probe.py @@ -24,10 +24,23 @@ from kempe_valid_colorings import classify_colorings from kempe_transfer_relation_probe import necklace, admissible_necklaces -def per_size_universals(n: int): +def has_length3_boundary(g) -> bool: + """A length-3 boundary walk = a separating (non-facial) triangle in G: + outer rim of 3 up teeth, or an inner face holding exactly 3 singleton downs.""" + if len(g.up_edges) == 3: + return True + faces = defaultdict(list) + for e in g.singleton_down_edges: + faces[innermost_bite(e, g.bites)].append(e) + return any(len(es) == 3 for es in faces.values()) + + +def per_size_universals(n: int, no_tri: bool = False): """size m -> (num boundaries, |D[m]|, best coverage count).""" boundaries: dict[int, list[set]] = defaultdict(list) for g in generate(n, min_up_teeth=3, dedup=True): + if no_tri and has_length3_boundary(g): + continue valid = [c for c, v in classify_colorings(g, dedup_colors=True) if v.valid] if not valid: continue @@ -59,9 +72,12 @@ def run(args): print("|D[m]| = number of universal boundary necklaces of size m " "(0 => uniform shortcut dead at that size)\n") print("legend per cell: |D[m]| (best_coverage/num_boundaries)\n") + if args.no_tri: + print("[restricted to tiles with NO length-3 boundary " + "(no separating triangle in G)]\n") for n in range(args.min_n, args.max_n + 1): t0 = time.time() - res = per_size_universals(n) + res = per_size_universals(n, no_tri=args.no_tri) dt = time.time() - t0 cells = [] for m in sorted(res): @@ -77,6 +93,9 @@ def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--min-n", type=int, default=6) parser.add_argument("--max-n", type=int, default=12) + parser.add_argument("--no-tri", action="store_true", + help="exclude tiles with a length-3 boundary " + "(no separating triangle in G)") run(parser.parse_args())