coloring_nested_tire_graphs: chain half analysis + tree DP empirical test
NEW NOTE: chain_half_analysis.tex (4 pages). Formulates the chain half of the loose conjecture as a tree DP over the cut tire forest, identifies what's proven vs. open: PROVEN - Tree structure (high-side forest): from cut_tire_tree_structure.tex - S_3-equivariance of the DP: trivial Lemma in this note - Per-tire half for spoke-only cut tires (n ≥ 3): Prop 1.13 OPEN / GAPS DISCOVERED 1. Cut tires are NOT in general spoke-only. H_d can have degree-3 vertices (= branch points), making face boundaries non-simple cycles. Dodecahedron 6-edge cut yields H_1 with one face of length 20 over only 11 distinct vertices. Prop 1.13's count 2^n + 2(-1)^n applies only to spoke-only tires. 2. OUT-only projection loses S_3 orbit info. The per-tire half guarantees a full S_3 orbit on the JOINT (in + out) projection, but restricting to OUT spokes can collapse to |A|=3 (constant tuples). Empirically observed ~20% of the time on test cases. Correct DP must track joint projection (analog of tire_fiber_step2.tex's joint-support tracking). 3. Non-emptiness preservation through the DP is the genuine open piece (Conj. in this note + Strong per-tire extendibility). EMPIRICAL TESTS - chain_dp_test.py: simple cycle DP (assumes spoke-only). - chain_dp_general.py: handles branched faces via brute-force 3-edge-coloring enumeration (cut off at 12 edges/tire for tractability). - chain_dp_debug.py: diagnostic for inspecting H_d face structure. The general test reveals all three gaps above when run on Dodecahedron + HM #0. Cross-cut R_0 ∩ R_1 should be non-empty for both (they are 3-edge-colorable), but the heuristic parent-finding plus OUT-only projection produce false negatives. Status table at end of note summarizes what's needed to close. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
"""Debug the chain DP: examine the structure of cut tires on a small
|
||||
example to understand why R_i is empty.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import itertools
|
||||
from collections import defaultdict
|
||||
|
||||
from sage.all import Graph, graphs
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
from cut_depth_label import (
|
||||
parse_planar_code, HM_FILE, find_six_edge_cut,
|
||||
apply_procedure, compute_nice_layout,
|
||||
)
|
||||
from cut_tire_tree import build_tree
|
||||
from tree_structure_sweep import all_six_edge_cuts
|
||||
|
||||
|
||||
def examine_cut(G, cut_idx, max_cuts=10):
|
||||
cuts = all_six_edge_cuts(G, max_cuts=max_cuts)
|
||||
if cut_idx >= len(cuts):
|
||||
return
|
||||
S, cut_edges = cuts[cut_idx]
|
||||
base_pos = compute_nice_layout(G)
|
||||
S0 = S
|
||||
S1 = frozenset(G.vertices()) - S
|
||||
print(f'=== Cut #{cut_idx}: |S0|={len(S0)}, |S1|={len(S1)} ===')
|
||||
|
||||
for side, S_side in [('0', S0), ('1', S1)]:
|
||||
print(f'\n--- Side {side} ---')
|
||||
try:
|
||||
H, pos, ed, _, _, _ = apply_procedure(
|
||||
G, S_side, cut_edges, base_pos, side,
|
||||
pendant_start_id=max(G.vertices()) + 1 +
|
||||
(0 if side == '0' else 200))
|
||||
except Exception as e:
|
||||
print(f' apply failed: {e}')
|
||||
continue
|
||||
|
||||
# Depth distribution
|
||||
from collections import Counter
|
||||
depth_count = Counter(ed.values())
|
||||
print(f' edge depths: {dict(depth_count)}')
|
||||
print(f' |H| = {H.order()} vertices, {H.size()} edges')
|
||||
print(f' max depth: {max(ed.values()) if ed else "N/A"}')
|
||||
|
||||
if not ed:
|
||||
continue
|
||||
faces_by_depth, parent_of, _ = build_tree(H, ed)
|
||||
for d in sorted(faces_by_depth.keys()):
|
||||
faces = faces_by_depth[d]
|
||||
print(f' H_{d}: {len(faces)} faces')
|
||||
for f_idx, face in enumerate(faces[:3]):
|
||||
verts = set()
|
||||
for u, v in face:
|
||||
verts.add(u)
|
||||
verts.add(v)
|
||||
# For each vertex, count incident H edges
|
||||
bdry_v_data = []
|
||||
for v in verts:
|
||||
incident = list(H.neighbors(v))
|
||||
incident_depths = [ed[tuple(sorted((v, nb)))]
|
||||
for nb in incident]
|
||||
bdry_v_data.append((v, incident_depths))
|
||||
# Show first few
|
||||
print(f' face {f_idx}: |bdry|={len(face)}, '
|
||||
f'verts={len(verts)}, sample: {bdry_v_data[:3]}')
|
||||
|
||||
|
||||
def main():
|
||||
G = graphs.DodecahedralGraph()
|
||||
G.is_planar(set_embedding=True)
|
||||
examine_cut(G, cut_idx=2, max_cuts=5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,358 @@
|
||||
"""Generalized chain DP for cut tires (handles branched H_d faces).
|
||||
|
||||
A cut tire T_d^{(f)} is treated as:
|
||||
- Edge set E_f = edges in the boundary walk of face f of H_d.
|
||||
- Vertex set V_f = vertices incident to E_f.
|
||||
- For each v in V_f with deg_{H_d}(v) = 2: one labeled pendant
|
||||
(in or out depending on the depth of the non-H_d edge at v).
|
||||
- For each v in V_f with deg_{H_d}(v) = 3: no pendant.
|
||||
|
||||
Proper 3-edge-coloring of T = (E_f ∪ pendants) such that all edges
|
||||
incident at every v in V_f have distinct colors. (The "underlying"
|
||||
graph treats E_f and pendants as edges in a planar multigraph; a
|
||||
branch vertex has 3 incident E_f edges all distinct.)
|
||||
|
||||
Out-spokes projection: tuple of colors on labeled-OUT pendants
|
||||
(depth d-1 edges).
|
||||
|
||||
Chain DP bottom-up:
|
||||
- At each tire, enumerate proper 3-edge-colorings.
|
||||
- Restrict to those compatible with at least one combination
|
||||
of out-spoke colorings from each child.
|
||||
- Project onto own out spokes.
|
||||
|
||||
Verify:
|
||||
(a) At each tire: |A(T)| > 0, contains full S_3 orbit.
|
||||
(b) R_0 ∩ R_1 non-empty at the cut.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import itertools
|
||||
from collections import defaultdict, Counter
|
||||
|
||||
from sage.all import Graph, graphs
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
from cut_depth_label import (
|
||||
parse_planar_code, HM_FILE,
|
||||
apply_procedure, compute_nice_layout,
|
||||
)
|
||||
from cut_tire_tree import build_tree
|
||||
from tree_structure_sweep import all_six_edge_cuts
|
||||
|
||||
|
||||
def cut_tire_structure(H, edge_depth, d, face):
|
||||
"""Extract structure of cut tire T_d^{(face)}.
|
||||
|
||||
Returns dict:
|
||||
'edges_indexed': list of (e_id, edge_tuple) for cycle edges.
|
||||
Order: by appearance in face walk (so duplicates
|
||||
can happen for branch points, but we use each
|
||||
edge once).
|
||||
'pendants_in': dict v -> (pendant_id, depth=d+1 edge)
|
||||
'pendants_out': dict v -> (pendant_id, depth=d-1 edge)
|
||||
'edges_at_v': dict v -> list of edge_ids incident to v
|
||||
(each appearance of v in walk = 1 cycle edge)
|
||||
'cycle_edges': list of (cycle_edge_id, edge_tuple)
|
||||
"""
|
||||
# First normalize: count each unique cycle edge once
|
||||
cycle_e_set = set()
|
||||
cycle_edges = []
|
||||
for u, v in face:
|
||||
e = tuple(sorted((u, v)))
|
||||
if e not in cycle_e_set:
|
||||
cycle_e_set.add(e)
|
||||
cycle_edges.append(e)
|
||||
# Vertices on this face boundary
|
||||
verts_set = set()
|
||||
for u, v in cycle_edges:
|
||||
verts_set.add(u)
|
||||
verts_set.add(v)
|
||||
# Edges incident to each vertex (cycle edges only)
|
||||
edges_at_v = defaultdict(list)
|
||||
for ce_id, (a, b) in enumerate(cycle_edges):
|
||||
edges_at_v[a].append(ce_id)
|
||||
edges_at_v[b].append(ce_id)
|
||||
# Pendants: at each degree-2 vertex of H, identify the third edge
|
||||
pendants_in = {}
|
||||
pendants_out = {}
|
||||
pendant_counter = [len(cycle_edges)] # next available edge id
|
||||
for v in verts_set:
|
||||
H_deg = sum(1 for nb in H.neighbors(v)
|
||||
if tuple(sorted((v, nb))) in cycle_e_set)
|
||||
# Wait — that's just degree restricted to face cycle edges.
|
||||
# But pendant attaches to the H-edge of different depth.
|
||||
# Look at ALL edges of H incident to v:
|
||||
for nb in H.neighbors(v):
|
||||
e_full = tuple(sorted((v, nb)))
|
||||
d_e = edge_depth.get(e_full)
|
||||
if d_e is None:
|
||||
continue
|
||||
if d_e == d:
|
||||
continue # skip cycle edges
|
||||
elif d_e == d + 1:
|
||||
pid = pendant_counter[0]
|
||||
pendant_counter[0] += 1
|
||||
pendants_in[v] = (pid, e_full)
|
||||
edges_at_v[v].append(pid)
|
||||
elif d_e == d - 1:
|
||||
pid = pendant_counter[0]
|
||||
pendant_counter[0] += 1
|
||||
pendants_out[v] = (pid, e_full)
|
||||
edges_at_v[v].append(pid)
|
||||
return {
|
||||
'cycle_edges': cycle_edges,
|
||||
'pendants_in': pendants_in,
|
||||
'pendants_out': pendants_out,
|
||||
'edges_at_v': dict(edges_at_v),
|
||||
'n_edges': pendant_counter[0],
|
||||
}
|
||||
|
||||
|
||||
def proper_3_colorings_general(struct):
|
||||
"""Enumerate all proper 3-edge-colorings of cut tire.
|
||||
Edge ids 0..n_cycle_edges-1 are cycle edges; n_cycle...n_edges-1 are
|
||||
pendants. Constraint: at each vertex v, the colors of edges in
|
||||
edges_at_v[v] are all distinct."""
|
||||
n_e = struct['n_edges']
|
||||
edges_at_v = struct['edges_at_v']
|
||||
# Edge-coloring constraint reduces to: per vertex, colors distinct.
|
||||
# Since vertex can have ≤ 3 incident edges in cubic (since each
|
||||
# vertex in original G' is cubic), and our cut tire is subgraph,
|
||||
# each v has at most 3 incident edges in the cut tire.
|
||||
# We need all colors at each v distinct.
|
||||
out = []
|
||||
# Naive enumeration: 3^n_e then filter. n_e is small (~10-50)
|
||||
# for our test cases, so doable.
|
||||
if n_e > 12:
|
||||
return None # too big
|
||||
for assign in itertools.product([0, 1, 2], repeat=n_e):
|
||||
ok = True
|
||||
for v, eids in edges_at_v.items():
|
||||
colors = [assign[eid] for eid in eids]
|
||||
if len(set(colors)) != len(colors):
|
||||
ok = False
|
||||
break
|
||||
if ok:
|
||||
out.append(assign)
|
||||
return out
|
||||
|
||||
|
||||
def s3_orbit(tup):
|
||||
"""S_3 orbit of color tuple under permutations of {0,1,2}."""
|
||||
orbit = set()
|
||||
for perm in itertools.permutations([0, 1, 2]):
|
||||
orbit.add(tuple(perm[c] for c in tup))
|
||||
return orbit
|
||||
|
||||
|
||||
def has_full_s3_orbit(s):
|
||||
"""Does set s of tuples contain a 6-element S_3 orbit?"""
|
||||
if not s:
|
||||
return False
|
||||
for tup in s:
|
||||
orb = s3_orbit(tup)
|
||||
if len(orb) == 6 and orb <= s:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def chain_dp_general(faces_by_depth, parent_of, H, edge_depth):
|
||||
"""Run chain DP, returns dict node -> A(T) (set of out-spoke
|
||||
color tuples)."""
|
||||
# Build structures for each tire
|
||||
structs = {}
|
||||
for d, faces in faces_by_depth.items():
|
||||
for f_idx, face in enumerate(faces):
|
||||
structs[(d, f_idx)] = cut_tire_structure(H, edge_depth, d, face)
|
||||
|
||||
# Build children list
|
||||
children = defaultdict(list)
|
||||
for node, p in parent_of.items():
|
||||
if p is not None and p != ('cut', None):
|
||||
children[p].append(node)
|
||||
|
||||
# Order by depth (process leaves first)
|
||||
max_d = max(d for (d, _) in structs)
|
||||
A = {}
|
||||
for d in range(max_d, 0, -1):
|
||||
for (dd, f_idx), struct in list(structs.items()):
|
||||
if dd != d:
|
||||
continue
|
||||
node = (d, f_idx)
|
||||
cs = proper_3_colorings_general(struct)
|
||||
if cs is None:
|
||||
A[node] = None # too big
|
||||
continue
|
||||
# Pendant-IN edge ids: those whose pendant_id is in pendants_in
|
||||
in_pids = {v: pid for v, (pid, _) in struct['pendants_in'].items()}
|
||||
out_pids = {v: pid for v, (pid, _) in struct['pendants_out'].items()}
|
||||
in_v_sorted = sorted(in_pids.keys())
|
||||
out_v_sorted = sorted(out_pids.keys())
|
||||
|
||||
# Find correspondence: each pendant-IN edge of this tire
|
||||
# = full edge in G'_i. We need to find which child cycle
|
||||
# edge it corresponds to.
|
||||
# The pendant-IN at v has full edge e (in struct).
|
||||
# Among children, find child c whose cycle_edges contains e.
|
||||
child_links = [] # (child_node, parent_v -> child_edge_id)
|
||||
for ch in children.get(node, []):
|
||||
if ch not in A:
|
||||
continue
|
||||
if A[ch] is None:
|
||||
child_links.append((ch, None)) # too big, skip
|
||||
continue
|
||||
ch_struct = structs[ch]
|
||||
ch_out_v = sorted(ch_struct['pendants_out'].keys())
|
||||
ch_out_full = {v: ch_struct['pendants_out'][v][1]
|
||||
for v in ch_out_v}
|
||||
# Match: parent's pendant-IN edge = child's pendant-OUT edge?
|
||||
# No wait — parent's pendant-IN is a depth-(d+1) edge.
|
||||
# Child T_{d+1}^{(f')} has cycle edges of depth d+1.
|
||||
# So parent's pendant-IN edge = a cycle edge of child.
|
||||
p_v_to_child_cycle_eid = {}
|
||||
for v_p, (pid_p, e_full_p) in struct['pendants_in'].items():
|
||||
# Find edge in child's cycle_edges with same e_full
|
||||
for ce_id, e_c in enumerate(ch_struct['cycle_edges']):
|
||||
if e_c == e_full_p:
|
||||
p_v_to_child_cycle_eid[v_p] = ce_id
|
||||
break
|
||||
child_links.append((ch, p_v_to_child_cycle_eid))
|
||||
|
||||
# For each coloring, check compatibility with each child
|
||||
achievable = set()
|
||||
for assign in cs:
|
||||
# Determine parent's pendant-IN colors
|
||||
p_in_colors = {v: assign[in_pids[v]] for v in in_pids}
|
||||
# For each child, check if there's a child-coloring with
|
||||
# the same colors at the corresponding cycle edges.
|
||||
# We use child's A in terms of OUT-SPOKE colors, but we
|
||||
# need to constrain CYCLE colors. So we need to recompute
|
||||
# per-child compatibility from child's allowed colorings.
|
||||
# ALTERNATE: instead of using A(ch) (out-spoke restriction),
|
||||
# track full child colorings. This blows up but is correct.
|
||||
# Simpler: track child's set of valid (cycle, out) colorings.
|
||||
# For now we use the WEAKER check: out-spoke compatibility
|
||||
# via "any child coloring at all", since A(ch) doesn't
|
||||
# carry cycle-edge info.
|
||||
# Since the chain compatibility is on PARENT'S IN spokes =
|
||||
# CHILD'S CYCLE EDGES (not out spokes), we actually need
|
||||
# the child's projection on cycle edges, not out spokes.
|
||||
# For this test, let's use child's full coloring set.
|
||||
ok = True
|
||||
for ch, link in child_links:
|
||||
if link is None:
|
||||
# child too big — skip compatibility check
|
||||
continue
|
||||
ch_full_colorings = proper_3_colorings_general(structs[ch])
|
||||
if ch_full_colorings is None:
|
||||
continue
|
||||
# Find a ch_coloring with matching cycle-edge colors
|
||||
found = False
|
||||
for ch_assign in ch_full_colorings:
|
||||
match = True
|
||||
for v_p, ce_id_c in link.items():
|
||||
if ch_assign[ce_id_c] != p_in_colors[v_p]:
|
||||
match = False
|
||||
break
|
||||
if match:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
ok = False
|
||||
break
|
||||
if ok:
|
||||
# Project to out spokes
|
||||
if out_v_sorted:
|
||||
tup = tuple(assign[out_pids[v]] for v in out_v_sorted)
|
||||
else:
|
||||
tup = ()
|
||||
achievable.add(tup)
|
||||
A[node] = achievable
|
||||
return A, structs
|
||||
|
||||
|
||||
def test_on_graph(G, name, max_cuts=3):
|
||||
cuts = all_six_edge_cuts(G, max_cuts=max_cuts)
|
||||
print(f'\n=== {name}: V={G.order()}, {len(cuts)} cuts tested ===',
|
||||
flush=True)
|
||||
base_pos = compute_nice_layout(G)
|
||||
n_tests, n_pertire_orbit_ok, n_root_ok, n_cross_ok = 0, 0, 0, 0
|
||||
per_tire_failures = []
|
||||
cross_failures = []
|
||||
for cut_idx, (S, cut_edges) in enumerate(cuts):
|
||||
S0, S1 = S, frozenset(G.vertices()) - S
|
||||
if len(S0) < 4 or len(S1) < 4:
|
||||
continue
|
||||
Rs = {}
|
||||
for side, S_side in [('0', S0), ('1', S1)]:
|
||||
try:
|
||||
H, pos, ed, _, _, _ = apply_procedure(
|
||||
G, S_side, cut_edges, base_pos, side,
|
||||
pendant_start_id=max(G.vertices()) + 1 +
|
||||
(0 if side == '0' else 200))
|
||||
except Exception:
|
||||
continue
|
||||
if not ed:
|
||||
continue
|
||||
faces_by_depth, parent_of, _ = build_tree(H, ed)
|
||||
try:
|
||||
A, structs = chain_dp_general(
|
||||
faces_by_depth, parent_of, H, ed)
|
||||
except Exception as e:
|
||||
print(f' cut #{cut_idx}/{side}: DP failed: {e}', flush=True)
|
||||
continue
|
||||
# Per-tire check
|
||||
for node, a in A.items():
|
||||
if a is None:
|
||||
continue
|
||||
n_tests += 1
|
||||
if a and has_full_s3_orbit(a):
|
||||
n_pertire_orbit_ok += 1
|
||||
else:
|
||||
per_tire_failures.append({
|
||||
'cut': cut_idx, 'side': side, 'node': node,
|
||||
'n_edges': structs[node]['n_edges'],
|
||||
'|A|': len(a),
|
||||
'has_orbit': has_full_s3_orbit(a) if a else False,
|
||||
})
|
||||
# Roots
|
||||
R_i = set()
|
||||
for node in A:
|
||||
if node[0] == 1 and A[node]:
|
||||
R_i |= A[node]
|
||||
if R_i and has_full_s3_orbit(R_i):
|
||||
n_root_ok += 1
|
||||
Rs[side] = R_i
|
||||
if '0' in Rs and '1' in Rs:
|
||||
if Rs['0'] & Rs['1']:
|
||||
n_cross_ok += 1
|
||||
else:
|
||||
cross_failures.append({
|
||||
'cut': cut_idx,
|
||||
'|R0|': len(Rs['0']),
|
||||
'|R1|': len(Rs['1']),
|
||||
})
|
||||
print(f' Per-tire A(T) full-orbit count: {n_pertire_orbit_ok}/{n_tests}',
|
||||
flush=True)
|
||||
if per_tire_failures:
|
||||
print(f' First per-tire failures:')
|
||||
for f in per_tire_failures[:5]:
|
||||
print(f' {f}')
|
||||
print(f' R_i has full orbit (root sides): {n_root_ok}', flush=True)
|
||||
print(f' Cross-cut R_0 ∩ R_1 != empty: {n_cross_ok}', flush=True)
|
||||
if cross_failures:
|
||||
print(f' Cross failures: {cross_failures[:3]}')
|
||||
|
||||
|
||||
def main():
|
||||
G = graphs.DodecahedralGraph()
|
||||
G.is_planar(set_embedding=True)
|
||||
test_on_graph(G, 'Dodecahedron', max_cuts=3)
|
||||
gs = parse_planar_code(HM_FILE)
|
||||
test_on_graph(gs[0], 'HM_0', max_cuts=3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,363 @@
|
||||
"""Empirical test of the chain DP for the loose conjecture.
|
||||
|
||||
For each (G, cut, side), build the cut tire forest. For each cut tire
|
||||
T = D(T) (cycle + pendants), enumerate proper 3-edge-colorings of T.
|
||||
Tree DP bottom-up: at each node, compute the set of out-spoke
|
||||
colorings compatible with at least one valid child combination.
|
||||
|
||||
Verify at roots: R_i != empty, contains a full S_3 orbit.
|
||||
Verify across cut: R_0 ∩ R_1 != empty, contains a full S_3 orbit.
|
||||
|
||||
Per the chain_half_analysis.tex note, this directly tests:
|
||||
- Conjecture (non-emptiness preservation): A(T_p) non-empty if
|
||||
children's A's are non-empty.
|
||||
- Bottom-line: R_0 ∩ R_1 non-empty.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import itertools
|
||||
from collections import defaultdict
|
||||
|
||||
from sage.all import Graph, graphs
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
from cut_depth_label import (
|
||||
parse_planar_code, HM_FILE, find_six_edge_cut,
|
||||
apply_procedure, compute_nice_layout,
|
||||
)
|
||||
from cut_tire_tree import build_tree
|
||||
|
||||
|
||||
def order_cycle(cycle_edges):
|
||||
"""Order edges into a cyclic walk. Returns (verts_in_order,
|
||||
edges_in_order) or (None, None) if not a simple cycle.
|
||||
edges_in_order[i] connects verts_in_order[i] and verts_in_order[i+1]."""
|
||||
n = len(cycle_edges)
|
||||
if n < 2:
|
||||
return None, None
|
||||
e_set = {tuple(sorted(e)) for e in cycle_edges}
|
||||
adj = defaultdict(list)
|
||||
for u, v in e_set:
|
||||
adj[u].append(v)
|
||||
adj[v].append(u)
|
||||
# Every vertex must have exactly 2 neighbors for a simple cycle
|
||||
if any(len(adj[v]) != 2 for v in adj):
|
||||
return None, None
|
||||
start = next(iter(adj))
|
||||
walk = [start]
|
||||
prev = None
|
||||
cur = start
|
||||
while True:
|
||||
nxt = [w for w in adj[cur] if w != prev]
|
||||
if not nxt:
|
||||
return None, None
|
||||
nxt = nxt[0]
|
||||
if nxt == start and len(walk) == n:
|
||||
break
|
||||
walk.append(nxt)
|
||||
prev = cur
|
||||
cur = nxt
|
||||
if len(walk) > n:
|
||||
return None, None
|
||||
if len(walk) != n:
|
||||
return None, None
|
||||
edges_in_order = [tuple(sorted((walk[i], walk[(i + 1) % n])))
|
||||
for i in range(n)]
|
||||
return walk, edges_in_order
|
||||
|
||||
|
||||
def get_tire_data(H, edge_depth, d, face):
|
||||
"""For cut tire T_d^{(face)}, return (verts_in_order, cycle_edges,
|
||||
in_spokes, out_spokes) or None if face is not a simple cycle.
|
||||
|
||||
in_spokes: dict {v: spoke_edge} for depth d+1 spokes
|
||||
out_spokes: dict {v: spoke_edge} for depth d-1 spokes
|
||||
"""
|
||||
cycle_e = [tuple(sorted(e)) for e in face]
|
||||
walk, edges_ord = order_cycle(cycle_e)
|
||||
if walk is None:
|
||||
return None
|
||||
in_sp, out_sp = {}, {}
|
||||
cycle_e_set = set(edges_ord)
|
||||
for v in walk:
|
||||
for nb in H.neighbors(v):
|
||||
e = tuple(sorted((v, nb)))
|
||||
if e in cycle_e_set:
|
||||
continue
|
||||
d_e = edge_depth.get(e)
|
||||
if d_e is None:
|
||||
continue
|
||||
if d_e == d + 1:
|
||||
in_sp[v] = e
|
||||
elif d_e == d - 1:
|
||||
out_sp[v] = e
|
||||
return walk, edges_ord, in_sp, out_sp
|
||||
|
||||
|
||||
def proper_3_colorings(verts, cycle_edges, in_sp, out_sp):
|
||||
"""Enumerate proper 3-edge-colorings of D(T): cycle + spokes.
|
||||
Returns list of dicts {edge: color}.
|
||||
|
||||
For each cycle coloring c[i] (i = 0..n-1) with c[i] != c[i+1]:
|
||||
At vertex v_i, the two cycle edges adjacent are c[i-1] and c[i].
|
||||
Spoke at v_i (if present) gets the third color.
|
||||
"""
|
||||
n = len(cycle_edges)
|
||||
out = []
|
||||
for assign in itertools.product([0, 1, 2], repeat=n):
|
||||
# Proper cycle
|
||||
bad = False
|
||||
for i in range(n):
|
||||
if assign[i] == assign[(i + 1) % n]:
|
||||
bad = True
|
||||
break
|
||||
if bad:
|
||||
continue
|
||||
col = {cycle_edges[i]: assign[i] for i in range(n)}
|
||||
# Determine spoke colors
|
||||
for i, v in enumerate(verts):
|
||||
c_left = assign[(i - 1) % n]
|
||||
c_right = assign[i]
|
||||
third = ({0, 1, 2} - {c_left, c_right})
|
||||
if len(third) != 1:
|
||||
# Degenerate (n=2 case)
|
||||
bad = True
|
||||
break
|
||||
third_c = third.pop()
|
||||
if v in in_sp:
|
||||
col[in_sp[v]] = third_c
|
||||
if v in out_sp:
|
||||
col[out_sp[v]] = third_c
|
||||
if not bad:
|
||||
out.append(col)
|
||||
return out
|
||||
|
||||
|
||||
def s3_orbit(tup):
|
||||
"""Generate S_3 orbit of a color tuple under permutations of {0,1,2}."""
|
||||
orbit = set()
|
||||
for perm in itertools.permutations([0, 1, 2]):
|
||||
orbit.add(tuple(perm[c] for c in tup))
|
||||
return orbit
|
||||
|
||||
|
||||
def has_full_s3_orbit(s):
|
||||
"""Does set s (of tuples) contain a 6-element S_3 orbit?"""
|
||||
for tup in s:
|
||||
if len(s3_orbit(tup)) == 6 and s3_orbit(tup) <= s:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def chain_dp(faces_by_depth, parent_of, H, edge_depth, side_label):
|
||||
"""Run the chain DP on the cut tire forest.
|
||||
|
||||
For each tire T_d^{(f)}, compute:
|
||||
- tire_data: (verts, cycle_e, in_sp, out_sp)
|
||||
- colorings: all proper 3-edge-colorings
|
||||
- A(T): set of (out-spoke-color-tuples), restricted by
|
||||
compatibility with all children.
|
||||
|
||||
Returns: {node: A(T)}, where each A(T) is a set of tuples.
|
||||
Also returns dict of issues found.
|
||||
"""
|
||||
tire_data = {}
|
||||
for d, faces in faces_by_depth.items():
|
||||
for f_idx, face in enumerate(faces):
|
||||
td = get_tire_data(H, edge_depth, d, face)
|
||||
if td is not None:
|
||||
tire_data[(d, f_idx)] = td
|
||||
|
||||
# Build children list
|
||||
children = defaultdict(list)
|
||||
for node, p in parent_of.items():
|
||||
if p is not None and p != ('cut', None):
|
||||
children[p].append(node)
|
||||
|
||||
# Process bottom-up: order nodes by depth descending
|
||||
nodes_by_depth = defaultdict(list)
|
||||
for node in tire_data:
|
||||
nodes_by_depth[node[0]].append(node)
|
||||
max_d = max(nodes_by_depth) if nodes_by_depth else 0
|
||||
|
||||
A = {} # node -> set of out-spoke-color tuples
|
||||
fully_S3 = {} # node -> bool: A(T) contains full S_3 orbit
|
||||
issues = []
|
||||
|
||||
for d in range(max_d, 0, -1):
|
||||
for node in nodes_by_depth[d]:
|
||||
verts, cycle_e, in_sp, out_sp = tire_data[node]
|
||||
if not out_sp and d > 1:
|
||||
# Internal/leaf without out spokes — degenerate
|
||||
A[node] = set()
|
||||
continue
|
||||
cs = proper_3_colorings(verts, cycle_e, in_sp, out_sp)
|
||||
# Order out-spoke positions (by vertex)
|
||||
out_sp_verts = sorted(out_sp.keys())
|
||||
in_sp_verts = sorted(in_sp.keys())
|
||||
|
||||
# For each child, build map: parent-in-spoke-vertex (= parent
|
||||
# boundary vertex with in spoke) -> child-out-spoke-vertex.
|
||||
# Equivalent: the in-spoke edge of parent = an out-spoke edge
|
||||
# of one of its children. The shared endpoint is the parent's
|
||||
# boundary vertex.
|
||||
child_outsp_maps = []
|
||||
for ch in children.get(node, []):
|
||||
if ch not in tire_data:
|
||||
continue
|
||||
ch_verts, ch_cycle, ch_in, ch_out = tire_data[ch]
|
||||
# Match: parent's in-spoke edge == child's out-spoke edge
|
||||
p_in_to_ch_out_v = {}
|
||||
for v_p, e_p in in_sp.items():
|
||||
# Find the vertex w of child with out-spoke e_p
|
||||
for v_c, e_c in ch_out.items():
|
||||
if e_p == e_c:
|
||||
p_in_to_ch_out_v[v_p] = (ch, v_c)
|
||||
break
|
||||
child_outsp_maps.append((ch, p_in_to_ch_out_v))
|
||||
|
||||
# For each coloring, check compatibility with each child's A
|
||||
achievable_out = set()
|
||||
for col in cs:
|
||||
# Extract parent's in-spoke colors
|
||||
p_in_colors_by_v = {v: col[in_sp[v]] for v in in_sp}
|
||||
# For each child, verify the corresponding out-spoke
|
||||
# color (= our in-spoke color) is in A(child)
|
||||
ok = True
|
||||
for ch, mapping in child_outsp_maps:
|
||||
if ch not in A:
|
||||
ok = False # child has no achievable (shouldn't happen)
|
||||
break
|
||||
ch_verts, ch_cycle, ch_in, ch_out = tire_data[ch]
|
||||
ch_out_verts_ordered = sorted(ch_out.keys())
|
||||
# Build the child's out-spoke tuple as we'd need
|
||||
required_ch_out = {}
|
||||
for v_p, (ch_id, v_c) in mapping.items():
|
||||
if ch_id != ch:
|
||||
continue
|
||||
required_ch_out[v_c] = p_in_colors_by_v[v_p]
|
||||
# If some out-spoke vertex of child isn't covered by
|
||||
# any parent in spoke, the value is FREE in A.
|
||||
# So we check: exists tup in A(ch) with tup[i] =
|
||||
# required_ch_out[v] for each i where v is constrained.
|
||||
found_any = False
|
||||
for tup in A[ch]:
|
||||
match = True
|
||||
for i, v in enumerate(ch_out_verts_ordered):
|
||||
if v in required_ch_out and tup[i] != required_ch_out[v]:
|
||||
match = False
|
||||
break
|
||||
if match:
|
||||
found_any = True
|
||||
break
|
||||
if not found_any:
|
||||
ok = False
|
||||
break
|
||||
if ok:
|
||||
# Extract parent's out-spoke colors as a tuple
|
||||
if out_sp_verts:
|
||||
tup = tuple(col[out_sp[v]] for v in out_sp_verts)
|
||||
achievable_out.add(tup)
|
||||
else:
|
||||
# No out spokes (root with empty out projection) —
|
||||
# represent as singleton empty tuple
|
||||
achievable_out.add(())
|
||||
A[node] = achievable_out
|
||||
fully_S3[node] = has_full_s3_orbit(achievable_out)
|
||||
if not achievable_out:
|
||||
issues.append({
|
||||
'type': 'empty_after_chain',
|
||||
'node': node,
|
||||
'side': side_label,
|
||||
'n_children': len(children.get(node, [])),
|
||||
})
|
||||
|
||||
return A, fully_S3, issues, tire_data
|
||||
|
||||
|
||||
def run_test(G, name, max_cuts=5):
|
||||
"""Run chain DP test on G across several 6-edge cuts."""
|
||||
from tree_structure_sweep import all_six_edge_cuts
|
||||
cuts = all_six_edge_cuts(G, max_cuts=max_cuts)
|
||||
print(f'\n=== {name}: V={G.order()}, E={G.size()}, '
|
||||
f'{len(cuts)} cuts tested ===', flush=True)
|
||||
base_pos = compute_nice_layout(G)
|
||||
n_cuts = 0
|
||||
n_empty = 0
|
||||
n_no_orbit = 0
|
||||
n_crossok = 0
|
||||
total_issues = []
|
||||
for cut_idx, (S, cut_edges) in enumerate(cuts):
|
||||
S0 = S
|
||||
S1 = frozenset(G.vertices()) - S
|
||||
if len(S0) < 4 or len(S1) < 4:
|
||||
continue
|
||||
A_per_side = {}
|
||||
for side, S_side in [('0', S0), ('1', S1)]:
|
||||
try:
|
||||
H, pos, ed, _, _, _ = apply_procedure(
|
||||
G, S_side, cut_edges, base_pos, side,
|
||||
pendant_start_id=max(G.vertices()) + 1 +
|
||||
(0 if side == '0' else 200))
|
||||
except Exception as e:
|
||||
print(f' cut #{cut_idx} side {side}: apply_procedure '
|
||||
f'failed: {e}', flush=True)
|
||||
continue
|
||||
faces_by_depth, parent_of, _ = build_tree(H, ed)
|
||||
A, fully_S3, issues, tire_data = chain_dp(
|
||||
faces_by_depth, parent_of, H, ed, side)
|
||||
total_issues.extend(issues)
|
||||
# Look at root tires (depth-1)
|
||||
root_A = []
|
||||
for node in A:
|
||||
if node[0] == 1:
|
||||
root_A.append((node, A[node]))
|
||||
# Combine root A's into R_i: union over roots
|
||||
R_i = set()
|
||||
for node, a in root_A:
|
||||
R_i |= a
|
||||
A_per_side[side] = R_i
|
||||
if not R_i:
|
||||
n_empty += 1
|
||||
print(f' cut #{cut_idx} side {side}: R_i empty!', flush=True)
|
||||
elif not any(len(s3_orbit(t)) == 6 and s3_orbit(t) <= R_i
|
||||
for t in R_i):
|
||||
n_no_orbit += 1
|
||||
print(f' cut #{cut_idx} side {side}: R_i lacks full S_3 '
|
||||
f'orbit (|R_i|={len(R_i)})', flush=True)
|
||||
if '0' in A_per_side and '1' in A_per_side:
|
||||
n_cuts += 1
|
||||
# Cross-cut check: R_0 and R_1 are on the same 6 cut edges,
|
||||
# but indexed by which side's roots. Need bijection.
|
||||
# For now, compare structurally: do they share orbits?
|
||||
R0, R1 = A_per_side['0'], A_per_side['1']
|
||||
common = R0 & R1
|
||||
if common:
|
||||
n_crossok += 1
|
||||
else:
|
||||
print(f' cut #{cut_idx}: R_0 ∩ R_1 = empty '
|
||||
f'(|R_0|={len(R0)}, |R_1|={len(R1)})', flush=True)
|
||||
print(f' cuts tested: {n_cuts}, R_i empty: {n_empty}, '
|
||||
f'R_i no full orbit: {n_no_orbit}, R_0 ∩ R_1 non-empty: '
|
||||
f'{n_crossok}/{n_cuts}', flush=True)
|
||||
return total_issues
|
||||
|
||||
|
||||
def main():
|
||||
# Small test: Dodecahedron
|
||||
G = graphs.DodecahedralGraph()
|
||||
G.is_planar(set_embedding=True)
|
||||
issues_dodec = run_test(G, 'Dodecahedron', max_cuts=5)
|
||||
|
||||
# HM #0
|
||||
gs = parse_planar_code(HM_FILE)
|
||||
issues_hm0 = run_test(gs[0], 'HM_0', max_cuts=5)
|
||||
|
||||
print('\n=== Summary of issues ===', flush=True)
|
||||
print(f'Dodecahedron: {len(issues_dodec)} issues')
|
||||
print(f'HM_0: {len(issues_hm0)} issues')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,18 @@
|
||||
\relax
|
||||
\@writefile{toc}{\contentsline {paragraph}{Per-tire half.}{1}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{Chain half.}{1}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{(1) Leaves.}{1}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{(2) Internal nodes.}{1}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{(3) Roots and the cut.}{2}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{(4) Cross-cut.}{2}{}\protected@file@percent }
|
||||
\newlabel{conj:non-empty-prop}{{}{2}}
|
||||
\@writefile{toc}{\contentsline {paragraph}{Why it isn't trivial.}{2}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{Why it's plausible.}{2}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{What would close the proof.}{2}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{What goes wrong.}{3}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{Consequence for Prop 1.13.}{3}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{Two ways forward.}{3}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{What this changes in the chain DP.}{4}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{Second issue: out-spoke projection loses S$_3$ orbit.}{4}{}\protected@file@percent }
|
||||
\@writefile{toc}{\contentsline {paragraph}{Third issue: heuristic parent-finding.}{4}{}\protected@file@percent }
|
||||
\gdef \@abspage@last{4}
|
||||
@@ -0,0 +1,317 @@
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 26 MAY 2026 22:49
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**chain_half_analysis.tex
|
||||
(./chain_half_analysis.tex
|
||||
LaTeX2e <2021-11-15> patch level 1
|
||||
L3 programming layer <2022-02-24>
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/article.cls
|
||||
Document Class: article 2021/10/04 v1.4n Standard LaTeX document class
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/size11.clo
|
||||
File: size11.clo 2021/10/04 v1.4n Standard LaTeX file (size option)
|
||||
)
|
||||
\c@part=\count185
|
||||
\c@section=\count186
|
||||
\c@subsection=\count187
|
||||
\c@subsubsection=\count188
|
||||
\c@paragraph=\count189
|
||||
\c@subparagraph=\count190
|
||||
\c@figure=\count191
|
||||
\c@table=\count192
|
||||
\abovecaptionskip=\skip47
|
||||
\belowcaptionskip=\skip48
|
||||
\bibindent=\dimen138
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsmath.sty
|
||||
Package: amsmath 2021/10/15 v2.17l AMS math features
|
||||
\@mathmargin=\skip49
|
||||
|
||||
For additional information on amsmath, use the `?' option.
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amstext.sty
|
||||
Package: amstext 2021/08/26 v2.01 AMS text
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsgen.sty
|
||||
File: amsgen.sty 1999/11/30 v2.0 generic functions
|
||||
\@emptytoks=\toks16
|
||||
\ex@=\dimen139
|
||||
))
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsbsy.sty
|
||||
Package: amsbsy 1999/11/29 v1.2d Bold Symbols
|
||||
\pmbraise@=\dimen140
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsmath/amsopn.sty
|
||||
Package: amsopn 2021/08/26 v2.02 operator names
|
||||
)
|
||||
\inf@bad=\count193
|
||||
LaTeX Info: Redefining \frac on input line 234.
|
||||
\uproot@=\count194
|
||||
\leftroot@=\count195
|
||||
LaTeX Info: Redefining \overline on input line 399.
|
||||
\classnum@=\count196
|
||||
\DOTSCASE@=\count197
|
||||
LaTeX Info: Redefining \ldots on input line 496.
|
||||
LaTeX Info: Redefining \dots on input line 499.
|
||||
LaTeX Info: Redefining \cdots on input line 620.
|
||||
\Mathstrutbox@=\box50
|
||||
\strutbox@=\box51
|
||||
\big@size=\dimen141
|
||||
LaTeX Font Info: Redeclaring font encoding OML on input line 743.
|
||||
LaTeX Font Info: Redeclaring font encoding OMS on input line 744.
|
||||
\macc@depth=\count198
|
||||
\c@MaxMatrixCols=\count199
|
||||
\dotsspace@=\muskip16
|
||||
\c@parentequation=\count266
|
||||
\dspbrk@lvl=\count267
|
||||
\tag@help=\toks17
|
||||
\row@=\count268
|
||||
\column@=\count269
|
||||
\maxfields@=\count270
|
||||
\andhelp@=\toks18
|
||||
\eqnshift@=\dimen142
|
||||
\alignsep@=\dimen143
|
||||
\tagshift@=\dimen144
|
||||
\tagwidth@=\dimen145
|
||||
\totwidth@=\dimen146
|
||||
\lineht@=\dimen147
|
||||
\@envbody=\toks19
|
||||
\multlinegap=\skip50
|
||||
\multlinetaggap=\skip51
|
||||
\mathdisplay@stack=\toks20
|
||||
LaTeX Info: Redefining \[ on input line 2938.
|
||||
LaTeX Info: Redefining \] on input line 2939.
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amssymb.sty
|
||||
Package: amssymb 2013/01/14 v3.01 AMS font symbols
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/amsfonts.sty
|
||||
Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support
|
||||
\symAMSa=\mathgroup4
|
||||
\symAMSb=\mathgroup5
|
||||
LaTeX Font Info: Redeclaring math symbol \hbar on input line 98.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
|
||||
(Font) U/euf/m/n --> U/euf/b/n on input line 106.
|
||||
))
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amscls/amsthm.sty
|
||||
Package: amsthm 2020/05/29 v2.20.6
|
||||
\thm@style=\toks21
|
||||
\thm@bodyfont=\toks22
|
||||
\thm@headfont=\toks23
|
||||
\thm@notefont=\toks24
|
||||
\thm@headpunct=\toks25
|
||||
\thm@preskip=\skip52
|
||||
\thm@postskip=\skip53
|
||||
\thm@headsep=\skip54
|
||||
\dth@everypar=\toks26
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphicx.sty
|
||||
Package: graphicx 2021/09/16 v1.2d Enhanced LaTeX Graphics (DPC,SPQR)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/keyval.sty
|
||||
Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
|
||||
\KV@toks@=\toks27
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/graphics.sty
|
||||
Package: graphics 2021/03/04 v1.4d Standard LaTeX Graphics (DPC,SPQR)
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics/trig.sty
|
||||
Package: trig 2021/08/11 v1.11 sin cos tan (DPC)
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-cfg/graphics.cfg
|
||||
File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration
|
||||
)
|
||||
Package graphics Info: Driver file: pdftex.def on input line 107.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/graphics-def/pdftex.def
|
||||
File: pdftex.def 2020/10/05 v1.2a Graphics/color driver for pdftex
|
||||
))
|
||||
\Gin@req@height=\dimen148
|
||||
\Gin@req@width=\dimen149
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/geometry/geometry.sty
|
||||
Package: geometry 2020/01/02 v5.9 Page Geometry
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/iftex/ifvtex.sty
|
||||
Package: ifvtex 2019/10/25 v1.7 ifvtex legacy package. Use iftex instead.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/generic/iftex/iftex.sty
|
||||
Package: iftex 2022/02/03 v1.0f TeX engine tests
|
||||
))
|
||||
\Gm@cnth=\count271
|
||||
\Gm@cntv=\count272
|
||||
\c@Gm@tempcnt=\count273
|
||||
\Gm@bindingoffset=\dimen150
|
||||
\Gm@wd@mp=\dimen151
|
||||
\Gm@odd@mp=\dimen152
|
||||
\Gm@even@mp=\dimen153
|
||||
\Gm@layoutwidth=\dimen154
|
||||
\Gm@layoutheight=\dimen155
|
||||
\Gm@layouthoffset=\dimen156
|
||||
\Gm@layoutvoffset=\dimen157
|
||||
\Gm@dimlist=\toks28
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/booktabs/booktabs.sty
|
||||
Package: booktabs 2020/01/12 v1.61803398 Publication quality tables
|
||||
\heavyrulewidth=\dimen158
|
||||
\lightrulewidth=\dimen159
|
||||
\cmidrulewidth=\dimen160
|
||||
\belowrulesep=\dimen161
|
||||
\belowbottomsep=\dimen162
|
||||
\aboverulesep=\dimen163
|
||||
\abovetopsep=\dimen164
|
||||
\cmidrulesep=\dimen165
|
||||
\cmidrulekern=\dimen166
|
||||
\defaultaddspace=\dimen167
|
||||
\@cmidla=\count274
|
||||
\@cmidlb=\count275
|
||||
\@aboverulesep=\dimen168
|
||||
\@belowrulesep=\dimen169
|
||||
\@thisruleclass=\count276
|
||||
\@lastruleclass=\count277
|
||||
\@thisrulewidth=\dimen170
|
||||
)
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
|
||||
File: l3backend-pdftex.def 2022-02-07 L3 backend support: PDF output (pdfTeX)
|
||||
\l__color_backend_stack_int=\count278
|
||||
\l__pdf_internal_box=\box52
|
||||
)
|
||||
(./chain_half_analysis.aux)
|
||||
\openout1 = `chain_half_analysis.aux'.
|
||||
|
||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 17.
|
||||
LaTeX Font Info: ... okay on input line 17.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
|
||||
[Loading MPS to PDF converter (version 2006.09.02).]
|
||||
\scratchcounter=\count279
|
||||
\scratchdimen=\dimen171
|
||||
\scratchbox=\box53
|
||||
\nofMPsegments=\count280
|
||||
\nofMParguments=\count281
|
||||
\everyMPshowfont=\toks29
|
||||
\MPscratchCnt=\count282
|
||||
\MPscratchDim=\dimen172
|
||||
\MPnumerator=\count283
|
||||
\makeMPintoPDFobject=\count284
|
||||
\everyMPtoPDFconversion=\toks30
|
||||
) (/usr/local/texlive/2022/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty
|
||||
Package: epstopdf-base 2020-01-24 v2.11 Base part for package epstopdf
|
||||
Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4
|
||||
85.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg
|
||||
File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv
|
||||
e
|
||||
))
|
||||
*geometry* driver: auto-detecting
|
||||
*geometry* detected driver: pdftex
|
||||
*geometry* verbose mode - [ preamble ] result:
|
||||
* driver: pdftex
|
||||
* paper: <default>
|
||||
* layout: <same size as paper>
|
||||
* layoutoffset:(h,v)=(0.0pt,0.0pt)
|
||||
* modes:
|
||||
* h-part:(L,W,R)=(72.26999pt, 469.75502pt, 72.26999pt)
|
||||
* v-part:(T,H,B)=(72.26999pt, 650.43001pt, 72.26999pt)
|
||||
* \paperwidth=614.295pt
|
||||
* \paperheight=794.96999pt
|
||||
* \textwidth=469.75502pt
|
||||
* \textheight=650.43001pt
|
||||
* \oddsidemargin=0.0pt
|
||||
* \evensidemargin=0.0pt
|
||||
* \topmargin=-37.0pt
|
||||
* \headheight=12.0pt
|
||||
* \headsep=25.0pt
|
||||
* \topskip=11.0pt
|
||||
* \footskip=30.0pt
|
||||
* \marginparwidth=59.0pt
|
||||
* \marginparsep=10.0pt
|
||||
* \columnsep=10.0pt
|
||||
* \skip\footins=10.0pt plus 4.0pt minus 2.0pt
|
||||
* \hoffset=0.0pt
|
||||
* \voffset=0.0pt
|
||||
* \mag=1000
|
||||
* \@twocolumnfalse
|
||||
* \@twosidefalse
|
||||
* \@mparswitchfalse
|
||||
* \@reversemarginfalse
|
||||
* (1in=72.27pt=25.4mm, 1cm=28.453pt)
|
||||
|
||||
LaTeX Font Info: Trying to load font information for U+msa on input line 18.
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsa.fd
|
||||
File: umsa.fd 2013/01/14 v3.01 AMS symbols A
|
||||
)
|
||||
LaTeX Font Info: Trying to load font information for U+msb on input line 18.
|
||||
|
||||
|
||||
(/usr/local/texlive/2022/texmf-dist/tex/latex/amsfonts/umsb.fd
|
||||
File: umsb.fd 2013/01/14 v3.01 AMS symbols B
|
||||
)
|
||||
Overfull \hbox (31.8519pt too wide) in paragraph at lines 32--37
|
||||
\OT1/cmr/bx/n/10.95 Chain half.[] \OT1/cmr/m/n/10.95 Com-pos-ing per-tire pro-
|
||||
jec-tions through the cut-tire for-est (\OT1/cmtt/m/n/10.95 cut[]tire[]tree[]st
|
||||
ructure.tex\OT1/cmr/m/n/10.95 ,
|
||||
[]
|
||||
|
||||
|
||||
Package amsmath Warning: Foreign command \atop;
|
||||
(amsmath) \frac or \genfrac should be used instead
|
||||
(amsmath) on input line 58.
|
||||
|
||||
[1
|
||||
|
||||
{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
|
||||
Overfull \hbox (41.57079pt too wide) in paragraph at lines 134--142
|
||||
\OT1/cmr/bx/n/10.95 Why it's plau-si-ble.[] \OT1/cmr/m/n/10.95 Em-pir-i-cal da
|
||||
ta from the partial- tire-dual chain pi-geon-hole (\OT1/cmtt/m/n/10.95 tire[]fi
|
||||
ber[]step2.tex\OT1/cmr/m/n/10.95 ):
|
||||
[]
|
||||
|
||||
[2] [3] [4] (./chain_half_analysis.aux) )
|
||||
Here is how much of TeX's memory you used:
|
||||
3256 strings out of 478268
|
||||
48448 string characters out of 5846347
|
||||
348617 words of memory out of 5000000
|
||||
21443 multiletter control sequences out of 15000+600000
|
||||
479693 words of font info for 69 fonts, out of 8000000 for 9000
|
||||
1141 hyphenation exceptions out of 8191
|
||||
55i,8n,62p,236b,241s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
{/usr/local/texlive/2022/texmf-dist/fo
|
||||
nts/enc/dvips/cm-super/cm-super-ts1.enc}</usr/local/texlive/2022/texmf-dist/fon
|
||||
ts/type1/public/amsfonts/cm/cmbx10.pfb></usr/local/texlive/2022/texmf-dist/font
|
||||
s/type1/public/amsfonts/cm/cmbx12.pfb></usr/local/texlive/2022/texmf-dist/fonts
|
||||
/type1/public/amsfonts/cm/cmex10.pfb></usr/local/texlive/2022/texmf-dist/fonts/
|
||||
type1/public/amsfonts/cm/cmmi10.pfb></usr/local/texlive/2022/texmf-dist/fonts/t
|
||||
ype1/public/amsfonts/cm/cmmi12.pfb></usr/local/texlive/2022/texmf-dist/fonts/ty
|
||||
pe1/public/amsfonts/cm/cmmi6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type
|
||||
1/public/amsfonts/cm/cmmi8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/
|
||||
public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/pu
|
||||
blic/amsfonts/cm/cmr17.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/publ
|
||||
ic/amsfonts/cm/cmr6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/
|
||||
amsfonts/cm/cmr7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/ams
|
||||
fonts/cm/cmr8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfon
|
||||
ts/cm/cmsy10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfont
|
||||
s/cm/cmsy8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/
|
||||
cm/cmti10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/c
|
||||
m/cmtt10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/cm-super/sf
|
||||
rm1095.pfb>
|
||||
Output written on chain_half_analysis.pdf (4 pages, 216066 bytes).
|
||||
PDF statistics:
|
||||
103 PDF objects out of 1000 (max. 8388607)
|
||||
62 compressed objects within 1 object stream
|
||||
0 named destinations out of 1000 (max. 500000)
|
||||
1 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,279 @@
|
||||
\documentclass[11pt]{article}
|
||||
\usepackage{amsmath,amssymb,amsthm}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{geometry}
|
||||
\usepackage{booktabs}
|
||||
\geometry{margin=1in}
|
||||
|
||||
\title{Chain half of the loose conjecture: tree DP and where it gates}
|
||||
\author{}
|
||||
\date{}
|
||||
|
||||
\newtheorem*{prop}{Proposition}
|
||||
\newtheorem*{lem}{Lemma}
|
||||
\newtheorem*{conj}{Conjecture}
|
||||
\newtheorem*{obs}{Observation}
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\section*{Recap}
|
||||
|
||||
The loose chain pigeonhole conjecture (k$\ge 2$ form,
|
||||
\texttt{cut\_depth\_label.tex}) has two halves:
|
||||
|
||||
\paragraph{Per-tire half.} For every cut tire $T$ with $\ge 2$
|
||||
in/out spokes total, the joint projection $\pi(T) \subseteq
|
||||
\{1,2,3\}^k$ is non-empty, $S_3$-closed, and contains a full $S_3$
|
||||
orbit of size $6$. Proven for spoke-only cut tires
|
||||
($T'_{\mathrm{ann}}$ = simple cycle $C_n$, $n \ge 3$) via Prop 1.13
|
||||
of \texttt{paper.tex}.
|
||||
|
||||
\paragraph{Chain half.} Composing per-tire projections through the
|
||||
cut-tire forest (\texttt{cut\_tire\_tree\_structure.tex}, rigorously
|
||||
proved) yields $\mathcal{R}_i \ne \emptyset$ on each side $i$ of the
|
||||
cut, with $\mathcal{R}_0 \cap \mathcal{R}_1 \ne \emptyset$ containing
|
||||
a common $S_3$-orbit at the cut.
|
||||
|
||||
\section*{Tree DP formulation of the chain half}
|
||||
|
||||
The high-side cut tires of $G'_i$ form a forest (rigorously proved).
|
||||
Process tires bottom-up:
|
||||
|
||||
\paragraph{(1) Leaves.} A leaf cut tire $T_{d_{\max}}^{(f)}$ has
|
||||
no children. Its ``achievable projection'' onto its out spokes
|
||||
(depth-$(d_{\max} - 1)$ direction) is
|
||||
\[
|
||||
A(T) := \pi_{\mathrm{out}}(T),
|
||||
\]
|
||||
the projection of the per-tire projection $\pi(T)$ onto the out
|
||||
spokes alone (in spokes are unconstrained at leaves). By per-tire,
|
||||
$|A(T)| \ge 6$ with full $S_3$-orbit.
|
||||
|
||||
\paragraph{(2) Internal nodes.} For a cut tire $T_p = T_d^{(f)}$
|
||||
with children $T_{c_1}, \dots, T_{c_r}$, define:
|
||||
\[
|
||||
A(T_p) := \left\{\sigma_{\mathrm{out}}(T_p) : \exists\, \chi
|
||||
\text{ proper edge $3$-coloring of } T_p \text{ such that}
|
||||
\atop \forall\, j : \chi|_{\text{in-spokes corresponding to }
|
||||
T_{c_j}} \in A(T_{c_j})'\right\},
|
||||
\]
|
||||
where $A(T_{c_j})'$ is the ``transferred-back'' achievable
|
||||
projection of child $T_{c_j}$ onto the corresponding parent in-spoke
|
||||
positions.
|
||||
|
||||
The transfer back: an in spoke of $T_p$ at parent boundary vertex
|
||||
$v$ corresponds to a depth-$(d+1)$ edge $e^{**}$ in $G'_i$. This
|
||||
$e^{**}$ is a face-boundary edge of $T_{c_j}$ (the unique child
|
||||
whose face contains $v$ as a boundary endpoint of $e^{**}$). So the
|
||||
parent's in-spoke color at $v$ = child's face-boundary-edge color at
|
||||
$e^{**}$.
|
||||
|
||||
For the projection $A(T_{c_j})$ to constrain parent's in spokes,
|
||||
we'd need to know how child's spoke colors determine cycle edge
|
||||
colors at specific positions. In the spoke-only case (Prop 1.13),
|
||||
each spoke color at $u$ equals the ``third color'' = the unique
|
||||
color not appearing on the two cycle edges incident at $u$. So
|
||||
spoke colors determine the constraint set on cycle colors at each
|
||||
vertex.
|
||||
|
||||
\paragraph{(3) Roots and the cut.} $T_1^{(\cdot)}$ are roots. Their
|
||||
out spokes are the pendant edges $=$ the cut configuration $\sigma_i$.
|
||||
The achievable cut configurations:
|
||||
\[
|
||||
\mathcal{R}_i := \bigcup_{\text{roots } T_1^{(f)}} A(T_1^{(f)})
|
||||
\quad (\text{or restricted, depending on how root constraints compose}).
|
||||
\]
|
||||
|
||||
\paragraph{(4) Cross-cut.} $G'$ is properly $3$-edge-colourable iff
|
||||
$\mathcal{R}_0 \cap \mathcal{R}_1 \ne \emptyset$ (under the
|
||||
bijection between the two sides' cut edges).
|
||||
|
||||
\section*{What's preserved through the tree DP}
|
||||
|
||||
\subsection*{$S_3$-closure: preserved}
|
||||
|
||||
\begin{lem}[$S_3$-equivariance of tree DP]
|
||||
If every $A(T_{c_j})$ is $S_3$-closed (under diagonal action on
|
||||
colours), then $A(T_p)$ is $S_3$-closed.
|
||||
\end{lem}
|
||||
|
||||
\begin{proof}
|
||||
The proper-edge-coloring constraint at every vertex is preserved by
|
||||
$S_3$ acting on colours uniformly. Applying $\pi \in S_3$ to a
|
||||
valid $\chi$ for $T_p$ gives another valid $\chi$. Compatibility
|
||||
with children: parent's in spokes are uniformly $\pi$-shifted, and
|
||||
each child's $A(T_{c_j})$ is $S_3$-closed by hypothesis, so the
|
||||
shifted parent in spokes still hit $A(T_{c_j})$. Hence $\pi(\sigma)
|
||||
\in A(T_p)$ for any $\sigma \in A(T_p)$.
|
||||
\end{proof}
|
||||
|
||||
By induction from leaves (where $A = \pi$ is $S_3$-closed by
|
||||
per-tire half), every $A(T)$ is $S_3$-closed. This is the easy
|
||||
half.
|
||||
|
||||
\subsection*{Non-emptiness: open, but constrained}
|
||||
|
||||
\begin{conj}[Non-emptiness preservation]
|
||||
\label{conj:non-empty-prop}
|
||||
If every $A(T_{c_j})$ contains a full $S_3$-orbit of size $6$, then
|
||||
$A(T_p)$ also contains a full $S_3$-orbit.
|
||||
\end{conj}
|
||||
|
||||
This is the genuine open piece of the chain half.
|
||||
|
||||
\paragraph{Why it isn't trivial.} Two $S_3$-closed subsets of
|
||||
$\{1, 2, 3\}^k$ can have empty intersection even if both contain
|
||||
$S_3$-orbits. Example: orbit of $(1, 2, 3)$ vs orbit of $(1, 1, 2)$
|
||||
in $\{1,2,3\}^3$ are disjoint.
|
||||
|
||||
So the conjecture would require a structural reason that parent +
|
||||
children combined always have at least one common assignment with
|
||||
all 3 colours present (= a full $S_3$-orbit).
|
||||
|
||||
\paragraph{Why it's plausible.} Empirical data from the partial-
|
||||
tire-dual chain pigeonhole (\texttt{tire\_fiber\_step2.tex}):
|
||||
$23/23$ pairwise compatibility tests succeeded, with the
|
||||
intersections containing $S_3$-orbits and structured by ``rainbow''
|
||||
or similar canonical orbits
|
||||
(\texttt{orbit\_decomposition.tex}). These results suggest a
|
||||
structural reason for non-emptiness; we just don't have a clean
|
||||
proof.
|
||||
|
||||
\paragraph{What would close the proof.} Show that for spoke-only
|
||||
cut tires, the per-tire projection $\pi(T)$ has the property:
|
||||
\emph{for any specified colours on the in spokes that come from
|
||||
$S_3$-orbits, there is a compatible parent coloring}. Specifically:
|
||||
|
||||
\begin{conj}[Strong per-tire extendibility]
|
||||
Let $T$ be a spoke-only cut tire with face boundary a simple cycle
|
||||
$C_n$ ($n \ge 3$). For any $\sigma_{\mathrm{in}} \in \{1, 2, 3\}^{n_{\mathrm{in}}}$
|
||||
such that $\sigma_{\mathrm{in}}$ lies in a non-trivial $S_3$-orbit
|
||||
(i.e.\ uses $\ge 2$ colours and is in $\pi(T)$'s $S_3$-symmetric
|
||||
support), there exists a proper edge $3$-coloring $\chi$ of $T$ with
|
||||
$\chi|_{\mathrm{in-spokes}} = \sigma_{\mathrm{in}}$ and
|
||||
$\chi|_{\mathrm{out-spokes}}$ a non-trivial $S_3$-orbit on the
|
||||
out-spoke side.
|
||||
\end{conj}
|
||||
|
||||
If this conjecture holds, the chain DP preserves non-emptiness: for
|
||||
each non-trivial parent $\sigma_{\mathrm{in}}$ (= child's face
|
||||
boundary edges) provided by children, parent has a coloring with
|
||||
out spokes in a non-trivial $S_3$-orbit, hence $A(T_p)$ contains a
|
||||
full $S_3$-orbit.
|
||||
|
||||
\section*{Empirical next step}
|
||||
|
||||
Cut-tire tree DP empirical test:
|
||||
\begin{enumerate}
|
||||
\item For each test graph (HM \#0 through \#5, dodecahedron,
|
||||
BuckyBall), build the cut tire forest on each side.
|
||||
\item For each leaf, compute $A(T_{\mathrm{leaf}})$.
|
||||
\item Bottom-up propagate $A(\cdot)$ to roots.
|
||||
\item Compare $\mathcal{R}_0 \cap \mathcal{R}_1$ at the cut.
|
||||
\end{enumerate}
|
||||
|
||||
This is the analogue of \texttt{tire\_fiber\_step2.tex} for the
|
||||
cut-tire setting. If empirically $\mathcal{R}_0 \cap \mathcal{R}_1
|
||||
\ne \emptyset$ universally, the chain half is on firm empirical
|
||||
ground; the proof would still need Conjecture~\ref{conj:non-empty-prop}
|
||||
or a structural shortcut.
|
||||
|
||||
\section*{Caveat discovered empirically: cut tires are not spoke-only}
|
||||
|
||||
A first-pass empirical test
|
||||
(\texttt{experiments/chain\_dp\_test.py}) on the dodecahedron and
|
||||
Holton--McKay \#0 revealed a structural complication: \emph{cut
|
||||
tires are not in general spoke-only}.
|
||||
|
||||
\paragraph{What goes wrong.} $H_d$ may have vertices of degree $3$
|
||||
(all three incident edges have depth $d$). In a cubic ambient
|
||||
graph $G'_i$, this happens when three depth-$d$ edges meet at a
|
||||
single vertex. At such a vertex:
|
||||
\begin{itemize}
|
||||
\item There is no third edge available to be a spoke.
|
||||
\item The face boundary walk of $H_d$ visits the vertex
|
||||
\emph{twice} (as a branch point).
|
||||
\end{itemize}
|
||||
For example, in the dodecahedron, a $6$-edge cut produces $H_1$
|
||||
with $1$ face whose boundary has length $20$ but only $11$ distinct
|
||||
vertices --- $9$ branch-point visits.
|
||||
|
||||
\paragraph{Consequence for Prop 1.13.} The per-tire half (proven
|
||||
via Prop 1.13) covers \emph{spoke-only} cut tires (face boundary =
|
||||
simple cycle $C_n$, $n \ge 3$). It does \emph{not} cover branched
|
||||
cut tires.
|
||||
|
||||
\paragraph{Two ways forward.}
|
||||
\begin{enumerate}
|
||||
\item \emph{Restrict.} Identify which graphs $G$ have the property
|
||||
that every cut tire of every $6$-edge cut is spoke-only. This
|
||||
is a genuine \emph{a priori} restriction.
|
||||
\item \emph{Generalise.} Extend the per-tire half to branched cut
|
||||
tires. Proper edge $3$-coloring on such a structure is
|
||||
well-defined and probably has a non-empty $S_3$-closed
|
||||
projection by similar arguments, but the explicit count
|
||||
$2^n + 2(-1)^n$ no longer applies.
|
||||
\end{enumerate}
|
||||
|
||||
\paragraph{What this changes in the chain DP.} The chain DP is
|
||||
still well-formed: enumerate proper $3$-edge-colorings of each cut
|
||||
tire (now allowing branches), project to out spokes, restrict via
|
||||
children. The per-tire half just needs the generalized form.
|
||||
|
||||
\paragraph{Second issue: out-spoke projection loses S$_3$ orbit.}
|
||||
The per-tire half guarantees a full $S_3$ orbit on the \emph{joint}
|
||||
in+out spoke projection $\pi(T)$. After restricting to OUT spokes
|
||||
only (which is what the parent uses), the projection $A(T)$ may
|
||||
contain fewer than $6$ elements --- e.g.\ all out spokes might be
|
||||
forced to a constant tuple by some structural symmetry, giving
|
||||
$|A(T)| = 3$ (= $\{(0,0,\dots), (1,1,\dots), (2,2,\dots)\}$).
|
||||
Initial empirical runs on the dodecahedron and HM \#0 see exactly
|
||||
this happen at $\sim 20\%$ of cut tires. This is \emph{not} a bug
|
||||
in the per-tire half; it is a genuine limitation of the OUT-only
|
||||
projection.
|
||||
|
||||
The correct chain DP formulation should track the joint (in + out)
|
||||
projection, not just OUT. This is the analogue of
|
||||
\texttt{tire\_fiber\_step2.tex}'s joint-support tracking.
|
||||
|
||||
\paragraph{Third issue: heuristic parent-finding.} The current
|
||||
\texttt{cut\_tire\_tree.find\_parent\_face} uses a vertex-overlap
|
||||
heuristic (smallest face among overlapping candidates). Per the
|
||||
high-side proposition (\texttt{cut\_tire\_tree\_structure.tex}),
|
||||
the geometrically-correct parent is unique, but the empirical
|
||||
script does not enforce this --- it picks by smallest-face
|
||||
heuristic, which can mis-attribute children to wrong parents.
|
||||
For a rigorous empirical test, parent assignment should use the
|
||||
planar embedding's face-in-face containment, not vertex overlap.
|
||||
|
||||
\section*{Net status of the loose conjecture}
|
||||
|
||||
\begin{center}
|
||||
\small
|
||||
\begin{tabular}{lll}
|
||||
\toprule
|
||||
component & status & note \\
|
||||
\midrule
|
||||
Per-tire half (spoke-only $n \ge 3$) & proven & Prop 1.13 \\
|
||||
Per-tire half (branched) & open, needed for generality & \\
|
||||
Tree structure (forest, high-side) & proven & \texttt{cut\_tire\_tree\_structure.tex} \\
|
||||
Chain DP $S_3$-equivariance & proven & this note, Lemma \\
|
||||
Joint vs.\ OUT projection issue & flagged & need joint-support tracking \\
|
||||
Chain DP non-emptiness preservation & open & Conj.\ \ref{conj:non-empty-prop} \\
|
||||
Bottom-line $\mathcal{R}_0 \cap \mathcal{R}_1 \ne \emptyset$ & open, $G$-colorability gives it & \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
The chain half reduces to multiple structural claims:
|
||||
\begin{itemize}
|
||||
\item per-tire half for branched cut tires;
|
||||
\item joint-support DP (track $\pi(T)$, not just OUT projection);
|
||||
\item non-emptiness preservation (Conj.\ \ref{conj:non-empty-prop}
|
||||
or Strong per-tire extendibility).
|
||||
\end{itemize}
|
||||
None are in hand yet. The $S_3$-equivariance and forest structure
|
||||
are. The full chain half is genuinely open and requires more work.
|
||||
|
||||
\end{document}
|
||||
Reference in New Issue
Block a user