diff --git a/papers/coloring_nested_tire_graphs/experiments/check_r1_concrete.py b/papers/coloring_nested_tire_graphs/experiments/check_r1_concrete.py new file mode 100644 index 0000000..6f41060 --- /dev/null +++ b/papers/coloring_nested_tire_graphs/experiments/check_r1_concrete.py @@ -0,0 +1,122 @@ +"""Find a concrete claimed (R1) violation and verify it by hand. + +Iterate over small maximal planar graphs, for each single-vertex source +find a depth-d component flagged as having a pinch vertex by the cyclic- +rotation check. Save the graph + the pinch vertex's rotation, the +depth of each face incident to the pinch vertex, and the cyclic +sequence of "is this face in the component?" booleans. +""" +import sys +from collections import defaultdict + +from sage.all import Graph +from sage.graphs.graph_generators import graphs + + +def face_edges_set(face): + return frozenset(frozenset(e) for e in face) + + +def main(): + for n in range(7, 12): + for G in graphs.triangulations(n): + G.is_planar(set_embedding=True) + emb = G.get_embedding() + faces = G.faces(embedding=emb) + for v_source in G.vertices(): + dist = G.shortest_path_lengths(v_source) + face_depths = [] + for face in faces: + verts = set() + for u, v in face: + verts.add(u); verts.add(v) + d = min(dist[u] for u in verts) + face_depths.append((face, d, verts)) + max_d = max(fd[1] for fd in face_depths) + for target_d in range(max_d + 1): + cands = [(i, fd) for i, fd in enumerate(face_depths) + if fd[1] == target_d] + if not cands: + continue + edge_to_idxs = defaultdict(list) + for k, (i, fd) in enumerate(cands): + for e in [frozenset(ed) for ed in fd[0]]: + edge_to_idxs[e].append(k) + n_c = len(cands) + adj = [[] for _ in range(n_c)] + for idxs in edge_to_idxs.values(): + if len(idxs) >= 2: + for a in idxs: + for b in idxs: + if a != b: + adj[a].append(b) + visited = [False] * n_c + comps = [] + for s in range(n_c): + if visited[s]: + continue + stack = [s]; comp = [] + while stack: + x = stack.pop() + if visited[x]: continue + visited[x] = True; comp.append(cands[x]) + for y in adj[x]: + if not visited[y]: stack.append(y) + comps.append(comp) + + for comp in comps: + comp_fes_set = {face_edges_set(fd[0]) + for _, fd in comp} + vertices = set() + for fes in comp_fes_set: + for e in fes: + vertices.update(e) + for v in vertices: + rot = emb[v] + in_c = [] + for i in range(len(rot)): + u = rot[i] + w = rot[(i + 1) % len(rot)] + tri = frozenset({frozenset({v, u}), + frozenset({u, w}), + frozenset({v, w})}) + in_c.append(tri in comp_fes_set) + n_true = sum(in_c) + if n_true == 0 or n_true == len(in_c): + continue + n_runs = sum( + 1 for i in range(len(in_c)) + if in_c[i] and not in_c[(i - 1) % len(in_c)]) + if n_runs > 1: + # Found one + print(f"=== R1 violation candidate ===") + print(f"n={n}, source={v_source}, " + f"depth={target_d}, pinch vertex={v}") + print(f"edges of G: " + f"{sorted([tuple(sorted(e)) for e in G.edges(labels=False)])}") + print(f"BFS distances: {dict(dist)}") + print(f"rotation around v={v}: {rot}") + lvls = [dist[u] for u in rot] + print(f" levels: {lvls}") + face_depths_around_v = [] + for i in range(len(rot)): + u = rot[i] + w = rot[(i + 1) % len(rot)] + d_face = min(dist[v], dist[u], dist[w]) + face_depths_around_v.append(d_face) + print(f" face depths: {face_depths_around_v}") + print(f" in_component: {in_c}") + print(f" n_runs of True: {n_runs}") + # Also list the depth-d faces at v + d_target_at_v = [ + (rot[i], rot[(i + 1) % len(rot)]) + for i in range(len(rot)) + if face_depths_around_v[i] == target_d + ] + print(f" depth-{target_d} faces at v: " + f"{d_target_at_v}") + return + + +if __name__ == '__main__': + main() diff --git a/papers/coloring_nested_tire_graphs/experiments/classify_r1_pinches.py b/papers/coloring_nested_tire_graphs/experiments/classify_r1_pinches.py new file mode 100644 index 0000000..7990b97 --- /dev/null +++ b/papers/coloring_nested_tire_graphs/experiments/classify_r1_pinches.py @@ -0,0 +1,146 @@ +"""For each claimed (R1) pinch vertex, classify it as: + (a) a cut-vertex of O = G[L_{d+1} cap V_{C'}] (level d+1 pinch) + (b) a cut-vertex of G[L_d cap V_{C'}] (level d pinch) + (c) other +""" +import sys +from collections import defaultdict + +from sage.all import Graph +from sage.graphs.graph_generators import graphs + + +def face_edges_set(face): + return frozenset(frozenset(e) for e in face) + + +def is_cut_vertex(G, v): + """Return True if removing v disconnects the connected component of v.""" + if v not in G: + return False + H = G.copy() + H.delete_vertex(v) + if H.order() == 0: + return False + return not H.is_connected() + + +def main(): + counts = defaultdict(int) + n_components = 0 + n_pinches = 0 + sample_each = {} + for n in range(7, 12): + for G in graphs.triangulations(n): + G.is_planar(set_embedding=True) + emb = G.get_embedding() + faces = G.faces(embedding=emb) + for v_source in G.vertices(): + dist = G.shortest_path_lengths(v_source) + face_depths = [] + for face in faces: + verts = set() + for u, v in face: + verts.add(u); verts.add(v) + d = min(dist[u] for u in verts) + face_depths.append((face, d, verts)) + max_d = max(fd[1] for fd in face_depths) + for target_d in range(max_d + 1): + cands = [(i, fd) for i, fd in enumerate(face_depths) + if fd[1] == target_d] + if not cands: + continue + edge_to_idxs = defaultdict(list) + for k, (i, fd) in enumerate(cands): + for e in [frozenset(ed) for ed in fd[0]]: + edge_to_idxs[e].append(k) + n_c = len(cands) + adj = [[] for _ in range(n_c)] + for idxs in edge_to_idxs.values(): + if len(idxs) >= 2: + for a in idxs: + for b in idxs: + if a != b: + adj[a].append(b) + visited = [False] * n_c + comps = [] + for s in range(n_c): + if visited[s]: + continue + stack = [s]; comp = [] + while stack: + x = stack.pop() + if visited[x]: continue + visited[x] = True; comp.append(cands[x]) + for y in adj[x]: + if not visited[y]: stack.append(y) + comps.append(comp) + + for comp in comps: + n_components += 1 + comp_fes_set = {face_edges_set(fd[0]) + for _, fd in comp} + vertices_in_comp = set() + for fes in comp_fes_set: + for e in fes: + vertices_in_comp.update(e) + Vd = {v for v in vertices_in_comp if dist[v] == target_d} + Vdp1 = {v for v in vertices_in_comp if dist[v] == target_d + 1} + O = G.subgraph(vertices=list(Vdp1)) + Bout_graph = G.subgraph(vertices=list(Vd)) + for v in vertices_in_comp: + rot = emb[v] + in_c = [] + for i in range(len(rot)): + u = rot[i] + w = rot[(i + 1) % len(rot)] + tri = frozenset({frozenset({v, u}), + frozenset({u, w}), + frozenset({v, w})}) + in_c.append(tri in comp_fes_set) + n_true = sum(in_c) + if n_true == 0 or n_true == len(in_c): + continue + n_runs = sum( + 1 for i in range(len(in_c)) + if in_c[i] and not in_c[(i - 1) % len(in_c)]) + if n_runs <= 1: + continue + # Pinch at v. Classify. + n_pinches += 1 + level_v = dist[v] + if level_v == target_d: + lvl_label = 'd' + # Check if v is a cut vertex of B_out_graph + cut_bout = is_cut_vertex(Bout_graph, v) + key = ('d', cut_bout) + elif level_v == target_d + 1: + lvl_label = 'd+1' + cut_o = is_cut_vertex(O, v) + key = ('d+1', cut_o) + else: + key = ('other', None) + counts[key] += 1 + if key not in sample_each: + sample_each[key] = { + 'n': n, 'source': int(v_source), + 'depth': target_d, 'pinch_v': v, + 'level_v': level_v, + 'edges': sorted(tuple(sorted(e)) + for e in G.edges(labels=False)), + } + + print(f"Total components: {n_components}") + print(f"Total pinches: {n_pinches}") + print() + print("Classification by (level of pinch, is cut-vertex of corresponding side):") + for k, c in sorted(counts.items()): + print(f" {k}: {c}") + print() + print("Samples:") + for k, sample in sample_each.items(): + print(f" key={k}: {sample}") + + +if __name__ == '__main__': + main() diff --git a/papers/coloring_nested_tire_graphs/experiments/draw_r1_candidate.py b/papers/coloring_nested_tire_graphs/experiments/draw_r1_candidate.py new file mode 100644 index 0000000..c1d8039 --- /dev/null +++ b/papers/coloring_nested_tire_graphs/experiments/draw_r1_candidate.py @@ -0,0 +1,172 @@ +"""Draw the claimed (R1) violation: n=9, source=5, depth=1, vertex 9. + +The depth-1 component has 9 triangles, and vertex 9 has 4 of them +incident (in two arcs of the rotation around 9, separated by 2 +depth-2 faces -- the two triangles of the bowtie at L_2). + +The question: is vertex 9 a real "pinch" of the tire, or is it just +a cut-vertex of the inner outerplanar graph O (= the bowtie on +{2, 3, 7, 8, 9}), naturally handled by the relaxed Definition 1.5? +""" +import math +import os +import sys +from collections import defaultdict + +from sage.all import Graph +import matplotlib.pyplot as plt +import matplotlib.patches as patches + +HERE = os.path.dirname(os.path.abspath(__file__)) + +EDGES = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), + (2, 3), (2, 9), (3, 4), (3, 9), (4, 5), (4, 6), (4, 7), (4, 9), + (5, 6), (6, 7), (7, 8), (7, 9), (8, 9)] +SOURCE = 5 + + +def main(): + G = Graph(EDGES) + G.is_planar(set_embedding=True) + emb = G.get_embedding() + dist = G.shortest_path_lengths(SOURCE) + + # Pick an external face that doesn't contain source 5 so source + # ends up in the interior. + # Faces of G that don't contain 5: triangle {1,2,3} for example. + pos = G.layout(layout='planar', external_face=(1, 2)) + # Normalise + xs = [p[0] for p in pos.values()]; ys = [p[1] for p in pos.values()] + cx, cy = (max(xs)+min(xs))/2, (max(ys)+min(ys))/2 + scale = max(max(xs)-min(xs), max(ys)-min(ys)) + pos = {v: ((p[0]-cx)/scale, (p[1]-cy)/scale) for v, p in pos.items()} + + faces = G.faces(embedding=emb) + face_depths = [] + for face in faces: + verts = set() + for u, v in face: + verts.add(u); verts.add(v) + d = min(dist[u] for u in verts) + face_depths.append((face, d, verts)) + depth1_faces = [fd for fd in face_depths if fd[1] == 1] + depth2_faces = [fd for fd in face_depths if fd[1] == 2] + + fig, ax = plt.subplots(figsize=(10, 9)) + + # Fill depth-1 faces (R_{C'}) + for face, _, _ in depth1_faces: + verts = [e[0] for e in face] + xy = [pos[v] for v in verts] + poly = plt.Polygon(xy, facecolor='#fff3cd', edgecolor='#e8d8a8', + linewidth=0.5, alpha=0.85, zorder=1) + ax.add_patch(poly) + + # Fill depth-2 faces (the bowtie's two triangles) in a different colour + for face, _, _ in depth2_faces: + verts = [e[0] for e in face] + xy = [pos[v] for v in verts] + poly = plt.Polygon(xy, facecolor='#d62728', edgecolor='#a01818', + linewidth=0.5, alpha=0.40, zorder=1) + ax.add_patch(poly) + + # All edges of G in grey + for u, v in G.edges(labels=False): + x1, y1 = pos[u]; x2, y2 = pos[v] + ax.plot([x1, x2], [y1, y2], color='lightgray', linewidth=1.0, + zorder=2) + + # Highlight the bowtie edges (= edges of O = G[L_2]) + L2 = [v for v in G.vertices() if dist[v] == 2] + print(f"L_2 = {sorted(L2)}") + bowtie_edges = [(u, v) for u, v in G.edges(labels=False) + if u in L2 and v in L2] + print(f"Edges of O = G[L_2]: {bowtie_edges}") + for u, v in bowtie_edges: + x1, y1 = pos[u]; x2, y2 = pos[v] + ax.plot([x1, x2], [y1, y2], color='#a01818', linewidth=3.0, + zorder=3) + + # Highlight the source-side cycle = G[L_1] + L1 = [v for v in G.vertices() if dist[v] == 1] + print(f"L_1 = {sorted(L1)}") + L1_edges = [(u, v) for u, v in G.edges(labels=False) + if u in L1 and v in L1] + print(f"Edges of B_out candidate = G[L_1]: {L1_edges}") + for u, v in L1_edges: + x1, y1 = pos[u]; x2, y2 = pos[v] + ax.plot([x1, x2], [y1, y2], color='#1f77b4', linewidth=3.0, + zorder=3) + + # Vertices + level_colors = {0: 'black', 1: '#1f77b4', 2: '#d62728'} + for v in G.vertices(): + x, y = pos[v] + c = level_colors.get(dist[v], 'gray') + ax.plot(x, y, 'o', color=c, markersize=22, zorder=4) + ax.annotate(f"{v}", (x, y), color='white', ha='center', va='center', + fontsize=11, fontweight='bold', zorder=5) + + # Special annotation: vertex 9 is the cut-vertex of O + if 9 in pos: + x, y = pos[9] + ax.annotate('cut-vertex of $O$', + xy=(x, y), xytext=(x + 0.10, y + 0.18), + fontsize=10, color='#a01818', fontweight='bold', + arrowprops=dict(arrowstyle='->', color='#a01818', lw=1.5), + zorder=6, + bbox=dict(boxstyle='round,pad=0.25', + facecolor='white', edgecolor='#a01818', + alpha=0.95)) + + if SOURCE in pos: + sx, sy = pos[SOURCE] + ax.annotate(f'source $v_0={SOURCE}$', + xy=(sx, sy), xytext=(sx + 0.08, sy + 0.10), + fontsize=10, color='black', fontweight='bold', + arrowprops=dict(arrowstyle='->', color='black', lw=1.2), + zorder=6, + bbox=dict(boxstyle='round,pad=0.2', + facecolor='white', edgecolor='gray', alpha=0.95)) + + legend_items = [ + plt.Line2D([], [], marker='o', color='w', markerfacecolor='black', + markersize=12, label=f'source ($\\ell=0$)'), + plt.Line2D([], [], marker='o', color='w', markerfacecolor='#1f77b4', + markersize=12, label='$\\ell=1$'), + plt.Line2D([], [], marker='o', color='w', markerfacecolor='#d62728', + markersize=12, label='$\\ell=2$'), + patches.Patch(facecolor='#fff3cd', edgecolor='#e8d8a8', + label='$R_{C^\\prime}$ (depth-1 component, ' + '9 triangles)'), + patches.Patch(facecolor='#d62728', alpha=0.4, + label='depth-2 faces (interior faces of $O$)'), + plt.Line2D([], [], color='#1f77b4', linewidth=3.0, + label='$B_{\\mathrm{out}} = G[L_1]$'), + plt.Line2D([], [], color='#a01818', linewidth=3.0, + label='$O = G[L_2]$ = bowtie with cut-vertex 9'), + ] + ax.legend(handles=legend_items, loc='upper right', fontsize=9, + framealpha=0.95) + + ax.set_title( + '"(R1) candidate": vertex 9 is a cut-vertex of $O$ (the bowtie),\n' + 'not a true pinch of the tire under the relaxed Definition 1.5\n' + '(n=9, source $v_0=5$, depth 1)', + fontsize=11) + ax.set_aspect('equal') + ax.axis('off') + pad = 0.08 + ax.set_xlim(min(p[0] for p in pos.values()) - pad, + max(p[0] for p in pos.values()) + pad) + ax.set_ylim(min(p[1] for p in pos.values()) - pad, + max(p[1] for p in pos.values()) + pad) + + out = os.path.join(HERE, 'r1_candidate.png') + plt.savefig(out, dpi=160, bbox_inches='tight') + plt.close() + print(f"wrote {out}") + + +if __name__ == '__main__': + main() diff --git a/papers/coloring_nested_tire_graphs/experiments/r1_candidate.png b/papers/coloring_nested_tire_graphs/experiments/r1_candidate.png new file mode 100644 index 0000000..5d1cffa Binary files /dev/null and b/papers/coloring_nested_tire_graphs/experiments/r1_candidate.png differ diff --git a/papers/coloring_nested_tire_graphs/paper.aux b/papers/coloring_nested_tire_graphs/paper.aux index 5f89a21..86a1424 100644 --- a/papers/coloring_nested_tire_graphs/paper.aux +++ b/papers/coloring_nested_tire_graphs/paper.aux @@ -4,12 +4,12 @@ \@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Dual depth in a stacked-ring triangulation $G$ with level source $S = \{0\}$. Each $G$ vertex is labelled by its level $\ell $. Each bounded face carries a dual vertex (square, joined by dashed dual edges) coloured by its dual depth $\delta (d_f) = \qopname \relax m{min}_{v \in V(f)} \ell (v)$: the central fan has depth $0$, the inner annulus depth $1$, and the outer annulus depth $2$. The outer face (the level-$3$ triangle) is excluded from the inner dual and carries no dual vertex.}}{2}{}\protected@file@percent } \newlabel{fig:dual-depth}{{1}{2}} \newlabel{def:tire-graph}{{1.5}{2}} +\citation{bauerfeld-pds} \@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces A tire graph with non-degenerate boundaries: outer boundary $B_{\mathrm {out}}$ a $6$-cycle on vertices $0,\dots ,5$ (blue), inner boundary $B_{\mathrm {in}}$ a $4$-cycle on vertices $6,\dots ,9$ (red), inner outerplanar graph $O = B_{\mathrm {in}} \cup \{7\text {--}9\}$ (with one chord, orange), and $E_{\mathrm {ann}}$ (grey) tiling the annulus between $B_{\mathrm {out}}$ and $B_{\mathrm {in}}$ by ten triangular faces.}}{3}{}\protected@file@percent } \newlabel{fig:tire-example}{{2}{3}} \newlabel{rem:tire-counts}{{1.6}{3}} \newlabel{lem:tire-component}{{1.7}{3}} \citation{bauerfeld-pds} -\citation{bauerfeld-pds} \bibcite{bauerfeld-pds}{1} \newlabel{tocindent-1}{0pt} \newlabel{tocindent0}{12.7778pt} @@ -17,6 +17,6 @@ \newlabel{tocindent2}{0pt} \newlabel{tocindent3}{0pt} \newlabel{rem:tire-component-degenerate}{{1.8}{5}} -\newlabel{rem:R1-when}{{1.9}{5}} +\newlabel{rem:tire-no-extra-hypotheses}{{1.9}{5}} \@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{5}{}\protected@file@percent } \gdef \@abspage@last{5} diff --git a/papers/coloring_nested_tire_graphs/paper.log b/papers/coloring_nested_tire_graphs/paper.log index 95b8b1e..4e088e5 100644 --- a/papers/coloring_nested_tire_graphs/paper.log +++ b/papers/coloring_nested_tire_graphs/paper.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 16:26 +This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 16:37 entering extended mode restricted \write18 enabled. %&-line parsing enabled. @@ -205,13 +205,13 @@ LaTeX Warning: `h' float specifier changed to `ht'. File: fig_tire_example.png Graphic file (type png) -Package pdftex.def Info: fig_tire_example.png used on input line 158. +Package pdftex.def Info: fig_tire_example.png used on input line 160. (pdftex.def) Requested size: 280.79956pt x 188.56097pt. [3 <./fig_tire_example.png>] [4] [5] (./paper.aux) ) Here is how much of TeX's memory you used: 3007 strings out of 478268 - 41998 string characters out of 5846347 - 343166 words of memory out of 5000000 + 42015 string characters out of 5846347 + 344166 words of memory out of 5000000 21054 multiletter control sequences out of 15000+600000 475666 words of font info for 53 fonts, out of 8000000 for 9000 1302 hyphenation exceptions out of 8191 @@ -233,7 +233,7 @@ e1/public/amsfonts/cm/cmsy5.pfb> -Output written on paper.pdf (5 pages, 486084 bytes). +Output written on paper.pdf (5 pages, 483570 bytes). PDF statistics: 105 PDF objects out of 1000 (max. 8388607) 61 compressed objects within 1 object stream diff --git a/papers/coloring_nested_tire_graphs/paper.pdf b/papers/coloring_nested_tire_graphs/paper.pdf index 3a5764f..a4e2680 100644 Binary files a/papers/coloring_nested_tire_graphs/paper.pdf and b/papers/coloring_nested_tire_graphs/paper.pdf differ diff --git a/papers/coloring_nested_tire_graphs/paper.tex b/papers/coloring_nested_tire_graphs/paper.tex index 1ee12d5..7846514 100644 --- a/papers/coloring_nested_tire_graphs/paper.tex +++ b/papers/coloring_nested_tire_graphs/paper.tex @@ -145,12 +145,14 @@ $B_{\mathrm{in}}$ is partitioned into triangular faces of $T$ whose union is $R$. When $B_{\mathrm{out}}$ is a simple cycle and $O$ is $2$-connected, -$R$ is a closed annulus. More generally, $R$ is a planar -$2$-manifold with boundary whose inner boundary may be a closed walk -rather than a simple cycle, accommodating outerplanar inner graphs -with bridges, cut-vertices, or multiple connected components. When -either boundary is degenerate, $R$ is a closed disk with that vertex -as apex. +$R$ is a closed annulus. More generally, $R$ is a closed planar +region that may fail to be a $2$-manifold at cut-vertices of $O$ (where +two ``lobes'' of the depth-$d$ region meet at a single vertex); the +inner boundary $B_{\mathrm{in}}$ is then a non-simple closed walk that +visits the cut-vertex multiple times. The relaxed definition +accommodates outerplanar inner graphs with bridges, cut-vertices, or +multiple connected components. When either boundary is degenerate, +$R$ is a closed disk with that vertex as apex. \end{definition} \begin{figure}[h] @@ -192,13 +194,6 @@ $V_{C'} := \bigcup_{f \in F_{C'}} V(f)$, and let $C := G[V_{C'}]$ inherit its embedding from $\Pi_G$. Set $R_{C'} := \bigcup_{f \in F_{C'}} f \subseteq |\Pi_G|$. -Assume: -\begin{itemize} -\item[\emph{(R1)}] $R_{C'}$ is a topological $2$-manifold with boundary; - equivalently, at every $v \in V_{C'}$ the faces of $F_{C'}$ - incident to $v$ form a single contiguous arc in the rotation - around $v$ in $\Pi_G$. -\end{itemize} Then $C$, with the inherited embedding, is a tire graph in the sense of Definition~\ref{def:tire-graph}. Its outer boundary $B_{\mathrm{out}}$ is the side of $R_{C'}$ closer to $S$ in $\Pi_G$, @@ -251,14 +246,14 @@ incident to it (by R1, see below), both of the same type, so its level is fixed. Therefore each boundary component of $\partial R_{C'}$ is monochromatic in level. -\emph{Boundary structure.} By hypothesis (R1), $R_{C'}$ is a -$2$-manifold with boundary, so locally at any boundary point $p$ the -region $R_{C'}$ is homeomorphic to a half-disk; the boundary -$\partial R_{C'}$ is therefore a disjoint union of simple closed -curves in $|\Pi_G|$. Each such curve traces a closed walk in $G$ -visiting each of its vertices exactly once (a simple cycle), and the -monochromaticity above forces the entire curve to lie in either -$L_d$ or $L_{d+1}$. +\emph{Boundary structure.} Each connected component of +$\partial R_{C'}$ traces a closed walk in $G$ that, by the +monochromaticity above, lies entirely in $L_d$ or entirely in +$L_{d+1}$. At a vertex $v \in V_{C'}$ where the faces of $F_{C'}$ +split into multiple arcs of $v$'s rotation, the boundary walk visits +$v$ correspondingly many times; this occurs precisely when $v$ is a +cut-vertex of the induced subgraph on its level (either $L_d$ or +$L_{d+1}$). \emph{Outer boundary.} Because $S$ lies on the outer face of $\Pi_G$, the boundary curve(s) of $R_{C'}$ on the $L_d$ side are closer to $S$ @@ -306,37 +301,31 @@ the level-$D_{\max}$ cycle as the outer boundary. \end{remark} \begin{remark} -\label{rem:R1-when} -Hypothesis (R1) of Lemma~\ref{lem:tire-component} holds in many -natural settings but can fail. (R1) fails at a \emph{pinch vertex} -$v \in V_{C'}$ when the faces of $F_{C'}$ incident to $v$ split into -two or more disjoint arcs of the rotation around $v$ in $\Pi_G$. -Such a $v$ has at least four neighbours $w_i, w_{i+1}, w_j, w_{j+1}$ -(with $i + 1 < j$) in cyclic order such that the faces -$\{v, w_i, w_{i+1}\}$ and $\{v, w_j, w_{j+1}\}$ are both depth-$d$ -while at least one face in each of the rotation gaps between them -carries depth $\neq d$. Concretely, this occurs precisely when the -cyclic level sequence $\ell(w_1), \ldots, \ell(w_{\deg v})$ enters and -leaves $\{d, d+1\}$ more than once. Whenever such a $v$ exists and -the two arcs are joined to a common component of $G'_d$ by some -\emph{other} path of depth-$d$ faces (not through $v$), the resulting -$R_{C'}$ is a wedge of two manifold regions at $v$, violating (R1). +\label{rem:tire-no-extra-hypotheses} +Two structural features of $R_{C'}$ that might at first appear to +obstruct the tire-graph conclusion are both already accommodated by +Definition~\ref{def:tire-graph}: -Multi-hole topology (where $R_{C'}$ encloses several disjoint -depth-$>d$ sub-regions) does \emph{not} require an additional -hypothesis: the inner outerplanar graph $O = G[V_{C'} \cap L_{d+1}]$ -captures the multi-hole structure as a disconnected (or -non-$2$-connected) outerplanar graph, and its outer-face boundary -closed walk serves as $B_{\mathrm{in}}$. In particular, two disjoint -$L_{d+1}$ triangles inside $R_{C'}$ joined by a bridge edge in $O$ -give a $B_{\mathrm{in}}$ that traverses the bridge twice and visits -the bridge endpoints twice each --- not a simple cycle, but a -well-defined closed walk on $V(O)$. +\emph{Cut-vertices of $O$.} A vertex $v \in V_{C'} \cap L_{d+1}$ may +have the faces of $F_{C'}$ incident to it split into two or more +arcs in $v$'s rotation in $\Pi_G$, separated by faces of higher +depth. This corresponds exactly to $v$ being a cut-vertex of +$O = G[V_{C'} \cap L_{d+1}]$, and the inner boundary closed walk +$B_{\mathrm{in}}$ then visits $v$ multiple times --- once for each +arc. No additional hypothesis is needed. -In the special case $d = 0$ with single-vertex source $S = \{v_0\}$ -(R1) holds automatically: $R_{C'}$ is the star of $v_0$, a topological -closed disk with one boundary cycle (the link of $v_0$), giving a -tire graph with degenerate outer boundary $\{v_0\}$. +\emph{Multi-hole topology of $R_{C'}$.} Even when $R_{C'}$ encloses +several disjoint depth-$>d$ sub-regions, the inner outerplanar graph +$O$ captures the multi-hole structure as a disconnected or +non-$2$-connected outerplanar graph (with bridges or multiple +components), and its outer-face boundary closed walk serves as +$B_{\mathrm{in}}$ traversing bridges twice and visiting cut-vertices +multiple times. + +In the special case $d = 0$ with single-vertex source $S = \{v_0\}$, +$R_{C'}$ is the star of $v_0$, a topological closed disk with one +boundary cycle (the link of $v_0$); the corresponding tire graph has +degenerate outer boundary $\{v_0\}$. \end{remark} \begin{thebibliography}{9}