Revert "coloring_nested_tire_graphs: empirical uniqueness-break figure (HM_0)"

This reverts commit 22fa29a8bb.
This commit is contained in:
2026-05-26 23:48:54 -04:00
parent 22fa29a8bb
commit 32dd4d3553
7 changed files with 47 additions and 481 deletions
@@ -1,226 +0,0 @@
"""Draw an empirical uniqueness-break case using TRUE planar
embedding coordinates (not spring layout).
We need a LOW-SIDE face f of H_d such that f's interior contains
H_{d-1} edges from multiple H_{d-1} faces.
The most reliable low-side face: the OUTER (unbounded) face of H_d.
For d >= 2, the outer face of H_d contains all of H_{d-1} (= depth-
(d-1) subgraph) plus pendants.
Algorithm:
- For HM_0 cut #1 side 1 (a known interesting case), use the
primal planar embedding for vertex positions.
- Identify the outer face of H_2 (= largest face by area, or by
Sage's outer-face-of-embedding).
- Verify it contains H_1 edges from multiple H_1 faces in its
interior region.
- Draw.
"""
import os, sys
from collections import defaultdict
import matplotlib.pyplot as plt
from sage.all import Graph
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 compute_H_d_faces
from tree_structure_sweep import all_six_edge_cuts
def planar_layout_for_H(H):
"""Return planar layout of H using Sage's planar embedding."""
# Try planar layout
H2 = H.copy()
try:
H2.is_planar(set_embedding=True)
# Use Sage's planar layout
pos = H2.layout(layout='planar')
# pos values are (x, y) but Sage returns dict v -> (x,y)
return pos
except Exception as e:
print(f' Planar layout failed: {e}')
return None
def main():
gs = parse_planar_code(HM_FILE)
G = gs[0]
G.is_planar(set_embedding=True)
base_pos = compute_nice_layout(G)
cuts = all_six_edge_cuts(G, max_cuts=5)
S, cut_edges = cuts[1]
S1 = frozenset(G.vertices()) - S
H, _, ed, _, _, _ = apply_procedure(
G, S1, cut_edges, base_pos, '1',
pendant_start_id=max(G.vertices()) + 501)
print(f'|V(H)|={H.order()}, |E(H)|={H.size()}')
print(f'Depths: {sorted(set(ed.values()))}')
# Use Sage's planar layout for H
pos = planar_layout_for_H(H)
if pos is None:
pos = H.layout(layout='spring')
print(f'Got positions for {len(pos)} vertices')
# Compute faces of H_1, H_2, H_3
faces_1, _ = compute_H_d_faces(H, ed, 1)
faces_2, _ = compute_H_d_faces(H, ed, 2)
faces_3, _ = compute_H_d_faces(H, ed, 3)
print(f'H_1: {len(faces_1)} faces, lengths {[len(f) for f in faces_1]}')
print(f'H_2: {len(faces_2)} faces, lengths {[len(f) for f in faces_2]}')
print(f'H_3: {len(faces_3)} faces, lengths {[len(f) for f in faces_3]}')
# Identify the LOW-side face of H_2.
# A low-side face contains depth-<2 edges (= pendants + H_1 edges).
# Equivalently: it's the face whose interior in the planar embedding
# contains the pendant vertices.
pendant_verts = {v for e, d in ed.items() if d == 0 for v in e}
# We pick the face whose boundary walk encloses the pendants.
# In Sage's planar embedding, this is the "outer" face often.
# Heuristic: the H_2 face NOT containing H_3 edges in its interior.
# Or: the largest face by vertex count.
# Most reliable: the face that, when removed from the plane, the
# pendants are in the remaining unbounded region.
# Use Sage's faces() — the first face is the outer face by default.
# For now, pick the face with the most vertices.
target_face_idx = max(range(len(faces_2)),
key=lambda i: len(set(v for u, v in faces_2[i])
| set(u for u, v in faces_2[i])))
target_face = faces_2[target_face_idx]
target_verts = set()
for u, v in target_face:
target_verts.add(u); target_verts.add(v)
print(f'\nTarget face (H_2 face {target_face_idx}): {len(target_face)} '
f'edges, {len(target_verts)} verts')
print(f' vertices: {sorted(target_verts)}')
# Identify H_1 edges in the "interior" of the target face.
# Heuristic: H_1 edges whose endpoints are NOT on the target face
# boundary, OR endpoints on the boundary but the edge "points
# inward" by planar embedding.
# For simplicity, look at all H_1 edges with at least one endpoint
# on target_verts and the OTHER endpoint NOT on H_2's outer
# boundary.
h1_in_interior = []
h1_face_of_edge = {}
for fi, walk in enumerate(faces_1):
for u, v in walk:
e = tuple(sorted((u, v)))
h1_face_of_edge.setdefault(e, []).append(fi)
for e, d in ed.items():
if d != 1:
continue
# An H_1 edge "in target face's interior" if at least one
# endpoint is in target_verts (= boundary of target face).
if e[0] in target_verts or e[1] in target_verts:
h1_in_interior.append(e)
h1_in_int_by_face = defaultdict(list)
for e in h1_in_interior:
for fi in h1_face_of_edge.get(e, []):
h1_in_int_by_face[fi].append(e)
print(f'\nH_1 edges adjacent to target face boundary:')
for fi, eds in sorted(h1_in_int_by_face.items()):
print(f' H_1 face {fi}: {len(set(eds))} edges')
# Draw
fig, ax = plt.subplots(figsize=(11, 10))
# All H edges in light gray as background
for u, v in H.edges(labels=False):
e = tuple(sorted((u, v)))
x1, y1 = pos[u]; x2, y2 = pos[v]
de = ed.get(e, -1)
if de == 0:
color = '#888888'; lw = 0.8; alpha = 0.4
elif de == 1:
color = '#4477CC'; lw = 2.0; alpha = 0.8
elif de == 2:
color = '#DD7733'; lw = 3.5; alpha = 1.0
elif de == 3:
color = '#999999'; lw = 0.8; alpha = 0.3
else:
color = '#CCCCCC'; lw = 0.5; alpha = 0.2
ax.plot([x1, x2], [y1, y2], color=color, linewidth=lw,
alpha=alpha, zorder=2)
# Highlight target H_2 face boundary
for u, v in target_face:
x1, y1 = pos[u]; x2, y2 = pos[v]
ax.plot([x1, x2], [y1, y2], color='#DD7733', linewidth=5.5,
alpha=1.0, zorder=4, solid_capstyle='round')
# H_1 edges colored by their H_1 face
h1_colors = {'face 0': '#22AA88', 'face 1': '#AA22AA',
'face 2': '#225599'}
color_list = ['#22AA88', '#AA22AA', '#225599']
for fi, eds in sorted(h1_in_int_by_face.items()):
col = color_list[fi % len(color_list)]
for e in set(eds):
u, v = e
x1, y1 = pos[u]; x2, y2 = pos[v]
ax.plot([x1, x2], [y1, y2], color=col, linewidth=4.0,
alpha=0.95, zorder=5, solid_capstyle='round')
# Vertices
for v in H.vertices():
x, y = pos[v]
in_target = v in target_verts
is_pendant = v in pendant_verts
if is_pendant:
ax.plot(x, y, 'o', color='#CC3333', markersize=6, zorder=6)
elif in_target:
ax.plot(x, y, 'o', color='#DD7733', markersize=7, zorder=6,
markeredgecolor='black', markeredgewidth=1)
ax.annotate(str(v), (x, y), textcoords='offset points',
xytext=(7, 7), fontsize=9, color='black', zorder=7)
else:
ax.plot(x, y, 'ko', markersize=4, zorder=6)
from matplotlib.lines import Line2D
legend = [
Line2D([0], [0], color='#DD7733', lw=5,
label=f'$H_2$ face {target_face_idx} boundary '
f'({len(target_face)} edges)'),
Line2D([0], [0], color='#22AA88', lw=4,
label=f'$H_1$ edges in face 0'),
Line2D([0], [0], color='#AA22AA', lw=4,
label=f'$H_1$ edges in face 1'),
Line2D([0], [0], color='#225599', lw=4,
label=f'$H_1$ edges in face 2'),
Line2D([0], [0], color='#4477CC', lw=1.5, label='other $H_1$ edges'),
Line2D([0], [0], color='#888888', lw=0.8, label='pendants ($d=0$)'),
Line2D([0], [0], color='#999999', lw=0.8, label='$H_3+$ edges'),
Line2D([0], [0], marker='o', color='#CC3333', lw=0,
label='pendant vertex', markersize=8),
Line2D([0], [0], marker='o', color='#DD7733', lw=0,
label='$H_2$ face vertex', markersize=8,
markeredgecolor='black'),
]
ax.legend(handles=legend, loc='upper left', fontsize=8,
framealpha=0.95)
ax.set_aspect('equal')
ax.axis('off')
n_h1_faces = len(h1_in_int_by_face)
ax.set_title(
f'HM_0 cut #1 side 1, $d=2$: this $H_2$ face has $H_1$ edges '
f'from {n_h1_faces} different $H_1$ faces adjacent\n'
f'(planar embedding from Sage; $H_2$ face shown in orange; '
f'$H_1$ edges grouped by face)')
out = os.path.join(os.path.dirname(HERE), 'notes',
'uniqueness_break_example.pdf')
fig.savefig(out, bbox_inches='tight', dpi=120)
print(f'\nWrote {out}')
if __name__ == '__main__':
main()
@@ -1,171 +0,0 @@
"""Find an empirical case where the low-side face of H_d spans
multiple faces of H_{d-1} (= the case high-side restriction is
needed for).
For each (G, cut, side), iterate (d, face) and check:
- Is `face` the low-side face of H_d?
- Does face's interior contain H_{d-1} edges from multiple
H_{d-1} faces?
Output: a clear description of the case + edges of H_d, H_{d-1},
and their face structures, so we can draw it.
"""
import os, sys
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,
apply_procedure, compute_nice_layout,
)
from cut_tire_tree import build_tree, compute_H_d_faces
from tree_structure_sweep import all_six_edge_cuts
def classify_face(face, edge_depth, d):
"""Returns 'low', 'high', or 'mixed' based on adjacency to non-Hd
edges by depth around the face vertices."""
verts = set()
for u, v in face:
verts.add(u); verts.add(v)
seen_lower = False
seen_higher = False
# For each vertex in face, look at incident edges NOT on this face
face_e_set = {tuple(sorted(e)) for e in face}
# Approach: any incident edge with depth < d → "lower" hint;
# any with depth > d → "higher" hint. (The face's interior could
# contain stuff via vertex-adjacency.)
return None # not used, we'll classify differently
def find_face_of_edge(faces, e_norm):
"""Find which face(s) of a graph have edge e_norm in their walk."""
matches = []
for fi, walk in enumerate(faces):
for u, v in walk:
if tuple(sorted((u, v))) == e_norm:
matches.append(fi)
break
return matches
def analyze_cut(G, cut_idx, cuts, base_pos):
S, cut_edges = cuts[cut_idx]
S0, S1 = S, frozenset(G.vertices()) - S
for side, S_side in [('0', S0), ('1', S1)]:
if len(S_side) < 6 or len(S_side) > G.order() - 6:
continue
try:
H, _, ed, _, _, _ = apply_procedure(
G, S_side, cut_edges, base_pos, side,
pendant_start_id=max(G.vertices()) + 1 + (
0 if side == '0' else 500))
except Exception:
continue
if not ed:
continue
max_d = max(ed.values())
for d in range(2, max_d + 1):
faces_d, H_d = compute_H_d_faces(H, ed, d)
faces_dm1, H_dm1 = compute_H_d_faces(H, ed, d - 1)
if not faces_d or not faces_dm1 or len(faces_dm1) < 2:
continue
# For each face of H_d, find which H_{d-1} edges are
# "inside" it (= H_{d-1} edges with both endpoints among
# face's vertex closure, intuitively).
# Simpler: a low-side face of H_d is one whose interior
# contains depth-<d edges. Detect by adjacency:
# any vertex of face has incident depth-<d edges → low.
for fi, face in enumerate(faces_d):
face_verts = set()
for u, v in face:
face_verts.add(u); face_verts.add(v)
# Edges of H_{d-1} adjacent to face_verts (= edges of
# depth d-1 incident to a face vertex)
hdm1_neighbor_edges = set()
for v in face_verts:
for nb in H.neighbors(v):
e = tuple(sorted((v, nb)))
if ed.get(e) == d - 1:
hdm1_neighbor_edges.add(e)
if len(hdm1_neighbor_edges) < 2:
continue
# Which H_{d-1} faces do these edges belong to?
# Edges in H_{d-1} face boundary
hdm1_face_of_edge = {}
for fjk, walk in enumerate(faces_dm1):
for u, v in walk:
e = tuple(sorted((u, v)))
hdm1_face_of_edge.setdefault(e, set()).add(fjk)
faces_touched = set()
edge_to_face = defaultdict(list)
for e in hdm1_neighbor_edges:
for fjk in hdm1_face_of_edge.get(e, set()):
faces_touched.add(fjk)
edge_to_face[fjk].append(e)
# Filter: must have unique edges across faces (the
# same edge in multiple faces is the trivial shared-
# boundary case, not interesting).
edge_unique_to_face = defaultdict(set)
for fjk, eds in edge_to_face.items():
for e in eds:
edge_unique_to_face[e].add(fjk)
# Count edges that appear in only one face
unique_edges = {e for e, fjks in edge_unique_to_face.items()
if len(fjks) == 1}
if len(faces_touched) >= 2 and len(face) >= 6 and \
len(unique_edges) >= 4:
print(f'\n=== FOUND: side {side}, d={d}, face {fi} of '
f'H_d spans {len(faces_touched)} H_{{d-1}} '
f'faces ===', flush=True)
print(f' Cut: |S0|={len(S0)}, |S1|={len(S1)}')
print(f' H_d face boundary edges ({len(face)}):',
flush=True)
for u, v in face[:8]:
print(f' ({u},{v})')
if len(face) > 8:
print(f' ... ({len(face)-8} more)')
print(f' H_{{d-1}} edges adjacent to face '
f'(broken across H_{{d-1}} faces):')
for fjk in sorted(faces_touched):
print(f' H_{{d-1}} face {fjk}: '
f'{[(min(e),max(e)) for e in edge_to_face[fjk][:5]]}')
return {
'side': side, 'd': d, 'face_idx': fi,
'face_walk': face, 'face_verts': face_verts,
'H_d_edges': [(u,v) for u,v in face],
'H_dm1_faces': {fjk: edge_to_face[fjk]
for fjk in faces_touched},
'all_H_d_faces': faces_d,
'all_H_dm1_faces': faces_dm1,
'edge_depth': ed,
}
return None
def main():
gs = parse_planar_code(HM_FILE)
candidates = [('Dodecahedron', graphs.DodecahedralGraph())]
for i, g in enumerate(gs):
candidates.append((f'HM_{i}', g))
for name, G in candidates:
G.is_planar(set_embedding=True)
base_pos = compute_nice_layout(G)
cuts = all_six_edge_cuts(G, max_cuts=30)
print(f'\n=== {name}: testing {len(cuts)} cuts ===', flush=True)
for ci in range(len(cuts)):
res = analyze_cut(G, ci, cuts, base_pos)
if res:
print(f'\nFOUND case in cut #{ci} of {name}', flush=True)
res['graph_name'] = name
res['cut_idx'] = ci
return res
print('No example found.')
return None
if __name__ == '__main__':
main()
@@ -1,15 +1,14 @@
\relax
\@writefile{toc}{\contentsline {paragraph}{Why low-side faces break uniqueness.}{1}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{An empirically observed case.}{2}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{The coverage gap.}{3}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Resolution.}{3}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Setup.}{3}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{The low-side face of $H_1$.}{3}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Picture.}{3}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{What $T_\partial $ looks like in special cases.}{4}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Role in the chain DP.}{5}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{What this closes.}{6}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{What it leaves open.}{6}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Why the chain DP can still work.}{6}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Logical status of the extended framework.}{6}{}\protected@file@percent }
\gdef \@abspage@last{6}
\@writefile{toc}{\contentsline {paragraph}{The coverage gap.}{2}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Resolution.}{2}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Setup.}{2}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{The low-side face of $H_1$.}{2}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Picture.}{2}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{What $T_\partial $ looks like in special cases.}{3}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Role in the chain DP.}{4}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{What this closes.}{5}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{What it leaves open.}{5}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Why the chain DP can still work.}{5}{}\protected@file@percent }
\@writefile{toc}{\contentsline {paragraph}{Logical status of the extended framework.}{5}{}\protected@file@percent }
\gdef \@abspage@last{5}
@@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 26 MAY 2026 23:44
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 26 MAY 2026 23:36
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
@@ -583,49 +583,44 @@ LaTeX Font Info: Trying to load font information for U+msb on input line 20.
File: umsb.fd 2013/01/14 v3.01 AMS symbols B
) [1
{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
<uniqueness_break_example.pdf, id=26, 570.93298pt x 602.04924pt>
File: uniqueness_break_example.pdf Graphic file (type pdf)
<use uniqueness_break_example.pdf>
Package pdftex.def Info: uniqueness_break_example.pdf used on input line 107.
(pdftex.def) Requested size: 446.26582pt x 470.60703pt.
[2 <./uniqueness_break_example.pdf>] [3] [4] [5] [6] (./boundary_cut_tire.aux)
)
{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] [2] [3]
[4] [5]
(./boundary_cut_tire.aux) )
Here is how much of TeX's memory you used:
14747 strings out of 478268
301412 string characters out of 5846347
568832 words of memory out of 5000000
32701 multiletter control sequences out of 15000+600000
14740 strings out of 478268
301161 string characters out of 5846347
568755 words of memory out of 5000000
32695 multiletter control sequences out of 15000+600000
482413 words of font info for 79 fonts, out of 8000000 for 9000
1141 hyphenation exceptions out of 8191
84i,6n,89p,452b,713s stack positions out of 10000i,1000n,20000p,200000b,200000s
{/usr/local/texlive/2022/texmf-dist/fonts/enc/dvips/cm-super/cm-super-ts1.enc
}</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb>
</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb><
/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></
usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi12.pfb></u
sr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb></usr
/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi8.pfb></usr/l
ocal/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/loc
al/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr17.pfb></usr/local
/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr6.pfb></usr/local/te
xlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/local/texli
ve/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></usr/local/texlive/
2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/local/texlive/2
022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy5.pfb></usr/local/texlive/202
2/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy6.pfb></usr/local/texlive/2022/
texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></usr/local/texlive/2022/te
xmf-dist/fonts/type1/public/amsfonts/cm/cmsy8.pfb></usr/local/texlive/2022/texm
f-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb></usr/local/texlive/2022/texmf
-dist/fonts/type1/public/amsfonts/cm/cmti7.pfb></usr/local/texlive/2022/texmf-d
ist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/local/texlive/2022/texmf-dis
t/fonts/type1/public/amsfonts/cm/cmtt10.pfb></usr/local/texlive/2022/texmf-dist
/fonts/type1/public/amsfonts/symbols/msbm10.pfb></usr/local/texlive/2022/texmf-
dist/fonts/type1/public/cm-super/sfrm1095.pfb>
Output written on boundary_cut_tire.pdf (6 pages, 274500 bytes).
{/usr/local/texlive/2022/texmf-dist/fonts/enc/dvips/
cm-super/cm-super-ts1.enc}</usr/local/texlive/2022/texmf-dist/fonts/type1/publi
c/amsfonts/cm/cmbx10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public
/amsfonts/cm/cmbx12.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/
amsfonts/cm/cmmi10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/a
msfonts/cm/cmmi12.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/am
sfonts/cm/cmmi7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsf
onts/cm/cmmi8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfon
ts/cm/cmr10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts
/cm/cmr17.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/c
m/cmr6.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/c
mr7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8
.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy10.
pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy5.pf
b></usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy6.pfb>
</usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb></
usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy8.pfb></us
r/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb></usr
/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti7.pfb></usr/l
ocal/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/loc
al/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt10.pfb></usr/loca
l/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msbm10.pfb></usr/
local/texlive/2022/texmf-dist/fonts/type1/public/cm-super/sfrm1095.pfb>
Output written on boundary_cut_tire.pdf (5 pages, 251070 bytes).
PDF statistics:
193 PDF objects out of 1000 (max. 8388607)
93 compressed objects within 1 object stream
134 PDF objects out of 1000 (max. 8388607)
82 compressed objects within 1 object stream
0 named destinations out of 1000 (max. 500000)
18 words of extra memory for PDF output out of 10000 (max. 10000000)
13 words of extra memory for PDF output out of 10000 (max. 10000000)
@@ -85,37 +85,6 @@ By contrast, face $A$ (high-side, inside the inner cycle) sits
entirely inside face $X$ of $H_{d-1}$. Unique parent. This is
why the forest proposition restricts to high-side faces.
\paragraph{An empirically observed case.} Holton--McKay graph
$\mathrm{HM}_0$, $6$-edge cut \#$1$, side $1$ (with $|S_1| = 28$).
At $d = 2$: $H_2$ has three faces of lengths $4, 4, 12$; $H_1$ also
has three faces of lengths $4, 4, 12$. The outer face of $H_2$
(the length-$12$ one, $7$ vertices: $\{16,19,20,21,23,24,28\}$) is
low-side --- in its interior live the depth-$0$ pendants and all
of the depth-$1$ ($H_1$) edges. Those $H_1$ edges are spread
across all three faces of $H_1$:
\begin{itemize}
\item $H_1$ face $0$: contributes edge $(15,19)$.
\item $H_1$ face $1$: contributes edge $(17,21)$.
\item $H_1$ face $2$: contributes edges $(23, 27), (28, 33), (24, 29),
(28, 34)$.
\end{itemize}
So this single low-side face of $H_2$ has $H_1$ edges from
\emph{three} different $H_1$ faces adjacent to its boundary --- no
single $H_1$ face contains all of them, hence no unique parent.
\begin{center}
\includegraphics[width=0.95\textwidth]{uniqueness_break_example.pdf}
\end{center}
The orange ring is the boundary of the low-side $H_2$ face. The
three coloured edges (green, purple, blue) are $H_1$ edges
adjacent to the orange ring's vertices, coloured by which $H_1$
face they belong to. The diagram is laid out using Sage's planar
embedding of $H$. If we tried to assign this $H_2$ face a single
``parent'' in $H_1$, none of the three $H_1$ faces would contain
it. $T_\partial$ exists precisely to handle this low-side
exception.
\paragraph{The coverage gap.} Empirically
(\texttt{chain\_dp\_joint.py} on the dodecahedron, cut $\#0$, side
$0$): when $|S_i|$ is small, $H_1$ on side $i$ can be a