diff --git a/papers/even_level_graph_generators/experiments/check_c5_n21.py b/papers/even_level_graph_generators/experiments/check_c5_n21.py new file mode 100644 index 0000000..eb8e7db --- /dev/null +++ b/papers/even_level_graph_generators/experiments/check_c5_n21.py @@ -0,0 +1,68 @@ +"""Parse plantri -a output for 5-connected triangulations at n=21 and +check each for the intertwining-tree property (equivalently, whether its +dual is Hamiltonian).""" +import subprocess +import networkx as nx +import time + +PLANTRI = '/Users/didericis/Code/math-research/plantri/plantri' + + +def parse_plantri_a(line): + """Parse one line of plantri -a output into a networkx graph. + Format: 'n adj0,adj1,...' where adj_i is a string of letters.""" + parts = line.strip().split(' ', 1) + n = int(parts[0]) + adj_lists = parts[1].split(',') + G = nx.Graph() + G.add_nodes_from(range(n)) + for i, adj in enumerate(adj_lists): + for ch in adj: + j = ord(ch) - ord('a') + G.add_edge(i, j) + return G + + +def is_intertwining_tree(G): + """Search all 2-partitions for one giving two induced trees.""" + nodes = list(G.nodes()) + n = len(nodes) + for mask in range(1, 2 ** (n - 1)): + A = [nodes[0]] + [nodes[i + 1] for i in range(n - 1) if (mask >> i) & 1] + B = [nodes[i + 1] for i in range(n - 1) if not ((mask >> i) & 1)] + if not B: + continue + if nx.is_tree(G.subgraph(A)) and nx.is_tree(G.subgraph(B)): + return True + return False + + +def main(): + out = subprocess.run([PLANTRI, '-c5', '-a', '21'], + capture_output=True, text=True) + lines = [l for l in out.stdout.splitlines() if l.strip()] + print(f'{len(lines)} triangulations to check') + + t0 = time.time() + n_inter = 0 + non_inter = [] + for idx, line in enumerate(lines): + G = parse_plantri_a(line) + if G.number_of_nodes() != 21 or G.number_of_edges() != 3 * 21 - 6: + print(f' line {idx}: parse issue, n={G.number_of_nodes()}, ' + f'm={G.number_of_edges()}') + continue + if is_intertwining_tree(G): + n_inter += 1 + else: + non_inter.append(idx) + if (idx + 1) % 50 == 0: + print(f' ...{idx+1}/{len(lines)} done ' + f'({time.time()-t0:.1f}s), {n_inter} intertwining so far') + print(f'\nResult: {n_inter}/{len(lines)} are intertwining trees') + print(f'Non-intertwining-tree (dual non-Hamiltonian): {non_inter}') + print(f'elapsed: {time.time()-t0:.1f}s') + + +if __name__ == '__main__': + main() diff --git a/papers/even_level_graph_generators/experiments/load_holton_mckay.py b/papers/even_level_graph_generators/experiments/load_holton_mckay.py new file mode 100644 index 0000000..d7b7d9a --- /dev/null +++ b/papers/even_level_graph_generators/experiments/load_holton_mckay.py @@ -0,0 +1,74 @@ +"""Parse McKay's planar_code file of the 6 non-Hamiltonian 38-vertex +cubic planar graphs, verify them, and build their duals (21-vertex +triangulations).""" +import networkx as nx + + +def parse_planar_code(path): + """Parse a >>planar_code<< file. Returns list of (G, embedding-order).""" + with open(path, 'rb') as f: + data = f.read() + header = b'>>planar_code<<' + assert data.startswith(header), data[:20] + pos = len(header) + graphs = [] + while pos < len(data): + n = data[pos] + pos += 1 + adj = {i: [] for i in range(n)} + for v in range(n): + while True: + w = data[pos] + pos += 1 + if w == 0: + break + adj[v].append(w - 1) # 1-indexed -> 0-indexed + G = nx.Graph() + G.add_nodes_from(range(n)) + for v in range(n): + for w in adj[v]: + G.add_edge(v, w) + graphs.append((G, adj)) + return graphs + + +def is_hamiltonian(G, time_limit_nodes=10_000_000): + """Backtracking Hamiltonicity check (good for cubic graphs).""" + nodes = list(G.nodes()) + n = len(nodes) + adj = {v: list(G.neighbors(v)) for v in nodes} + start = nodes[0] + visited = {start} + count = [0] + + def bt(v, depth): + count[0] += 1 + if count[0] > time_limit_nodes: + raise TimeoutError + if depth == n: + return start in adj[v] + for w in adj[v]: + if w not in visited: + visited.add(w) + if bt(w, depth + 1): + return True + visited.discard(w) + return False + + return bt(start, 1) + + +if __name__ == '__main__': + graphs = parse_planar_code('/tmp/nonham38m4.pc') + print(f'Parsed {len(graphs)} graphs from McKay planar_code file') + for i, (G, adj) in enumerate(graphs): + n = G.number_of_nodes() + m = G.number_of_edges() + degs = sorted(set(dict(G.degree()).values())) + planar = nx.check_planarity(G)[0] + try: + ham = is_hamiltonian(G) + except TimeoutError: + ham = 'timeout' + print(f' graph {i}: n={n}, m={m}, degrees={degs}, ' + f'planar={planar}, hamiltonian={ham}') diff --git a/papers/even_level_graph_generators/experiments/nonham38m4.pc b/papers/even_level_graph_generators/experiments/nonham38m4.pc new file mode 100644 index 0000000..5ff3039 Binary files /dev/null and b/papers/even_level_graph_generators/experiments/nonham38m4.pc differ diff --git a/papers/even_level_graph_generators/experiments/test_holton_mckay_duals.py b/papers/even_level_graph_generators/experiments/test_holton_mckay_duals.py new file mode 100644 index 0000000..fb7e62c --- /dev/null +++ b/papers/even_level_graph_generators/experiments/test_holton_mckay_duals.py @@ -0,0 +1,61 @@ +"""For each of the 6 Holton-McKay graphs (38-vertex non-Hamiltonian cubic +planar), build the dual (21-vertex triangulation), confirm it is NOT an +intertwining tree, then test whether it is a valid derived level graph.""" +import sys +import os +sys.path.insert(0, '/Users/didericis/Code/math-research/papers/' + 'level_resolutions_of_maximal_planar_graphs/experiments') +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import networkx as nx +import time +from load_holton_mckay import parse_planar_code +from tutte_dual_treecolor import dual_triangulation + + +def is_intertwining_tree(G, time_limit=120.0): + """Search all 2-partitions for two induced trees. Time-limited.""" + nodes = list(G.nodes()) + n = len(nodes) + t0 = time.time() + checked = 0 + for mask in range(1, 2 ** (n - 1)): + checked += 1 + if checked % 200000 == 0 and time.time() - t0 > time_limit: + return None, checked + A = [nodes[0]] + [nodes[i + 1] for i in range(n - 1) if (mask >> i) & 1] + B = [nodes[i + 1] for i in range(n - 1) if not ((mask >> i) & 1)] + if not B: + continue + if nx.is_tree(G.subgraph(A)) and nx.is_tree(G.subgraph(B)): + return (tuple(sorted(A)), tuple(sorted(B))), checked + return False, checked + + +def main(): + graphs = parse_planar_code('/tmp/nonham38m4.pc') + print(f'{len(graphs)} Holton-McKay graphs loaded\n') + + for i, (G, adj) in enumerate(graphs): + D, faces = dual_triangulation(G) + n = D.number_of_nodes() + m = D.number_of_edges() + is_tri = (m == 3 * n - 6) + print(f'graph {i}: dual has n={n}, m={m}, triangulation={is_tri}') + + # Verify NOT intertwining tree + t0 = time.time() + result, checked = is_intertwining_tree(D, time_limit=180.0) + dt = time.time() - t0 + if result is False: + print(f' intertwining tree: NO ' + f'(checked all {checked} partitions, {dt:.1f}s) ' + f'[consistent with non-Hamiltonian dual]') + elif result is None: + print(f' intertwining tree: search timed out after {checked} ' + f'partitions ({dt:.1f}s)') + else: + print(f' intertwining tree: YES (UNEXPECTED) partition={result}') + + +if __name__ == '__main__': + main() diff --git a/papers/even_level_graph_generators/experiments/test_tutte_dual_disjunction.py b/papers/even_level_graph_generators/experiments/test_tutte_dual_disjunction.py new file mode 100644 index 0000000..0a3bd61 --- /dev/null +++ b/papers/even_level_graph_generators/experiments/test_tutte_dual_disjunction.py @@ -0,0 +1,167 @@ +"""Test the disjunction on the Tutte graph dual: a 25-vertex +triangulation whose dual is a Tait counterexample. By the +intertwining-tree⇔dual-Hamiltonian equivalence, the dual is not +intertwining tree. So the conjecture requires it to be a derived level +graph. + +Approach: backward BFS from G in the E/O-switch graph. A predecessor of +H is H' = H - wx + uv where uv is the diagonal of wx's quadrilateral in +H and uv has same-parity endpoints (so the forward switch on uv in H' is +valid). + +For each candidate vertex-labelling of G (each potential level source +in some Even Level Graph), we BFS backward and check if any reached state +is itself an Even Level Graph for that labelling. +""" +import sys +import os +sys.path.insert(0, '/Users/didericis/Code/math-research/papers/' + 'level_resolutions_of_maximal_planar_graphs/experiments') +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import networkx as nx +import time +from tutte_dual_treecolor import dual_triangulation +from test_conjecture import ( + bfs_levels, is_even_level_graph, +) + + +def is_tree(subg): + return nx.is_tree(subg) if subg.number_of_nodes() > 0 else True + + +def is_intertwining_tree(G, time_limit=10.0): + """Search for a 2-partition (A, B) such that G[A] and G[B] are trees. + Returns the partition or None. Time-limited.""" + nodes = list(G.nodes()) + n = len(nodes) + t0 = time.time() + for mask in range(1, 2 ** (n - 1)): + if time.time() - t0 > time_limit: + return None # timed out, unknown + A = [nodes[0]] + [nodes[i + 1] for i in range(n - 1) if (mask >> i) & 1] + B = [nodes[i + 1] for i in range(n - 1) if not ((mask >> i) & 1)] + if not A or not B: + continue + if is_tree(G.subgraph(A)) and is_tree(G.subgraph(B)): + return (tuple(A), tuple(B)) + return False # no partition works + + +def planar_diagonal(G, u, v): + """Given edge uv in triangulation G, return the diagonal of the + quadrilateral around uv (= the two third vertices of the triangles + at uv).""" + ok, emb = nx.check_planarity(G) + if not ok: + return None + f1 = emb.traverse_face(u, v) + f2 = emb.traverse_face(v, u) + if len(f1) != 3 or len(f2) != 3: + return None + w = next(x for x in f1 if x != u and x != v) + x = next(y for y in f2 if y != u and y != v) + if w == x: + return None + return (w, x) + + +def backward_predecessors(G, labels): + """Yield (G', uv, wx) where G' →forward G via switching uv (E/O in + labels). For each edge wx of G whose diagonal uv has same-parity + endpoints AND uv is not already an edge of G.""" + for u, v in list(G.edges()): + diag = planar_diagonal(G, u, v) + if diag is None: + continue + w, x = diag + if labels[w] % 2 != labels[x] % 2: + continue # diagonal not E/O, can't be reverse-switched + if G.has_edge(w, x): + continue # would create multi-edge + Gp = G.copy() + Gp.remove_edge(u, v) + Gp.add_edge(w, x) + yield Gp, (u, v), (w, x) + + +def find_elg_via_backward_bfs(G_start, labels, max_states=50000, + time_limit=120.0): + """BFS backward from G_start. If we hit a triangulation that is an + Even Level Graph for the same labelling (specifically, where the + labels match BFS levels from some source in this triangulation), + return it.""" + t0 = time.time() + seen = {frozenset(frozenset(e) for e in G_start.edges())} + frontier = [G_start] + rounds = 0 + while frontier and len(seen) < max_states: + if time.time() - t0 > time_limit: + return None, len(seen), rounds, 'timed out' + new = [] + for H in frontier: + # Check if H is an Even Level Graph for some source + # whose BFS levels match `labels` mod 2. + for v in H.nodes(): + is_elg, lvls = is_even_level_graph(H, frozenset({v})) + if not is_elg or lvls is None: + continue + # Check if lvls parities match labels mod 2 (up to swap) + same = all(lvls[u] % 2 == labels[u] % 2 for u in H.nodes()) + opp = all(lvls[u] % 2 != labels[u] % 2 for u in H.nodes()) + if same or opp: + return H, len(seen), rounds, ('match' if same else 'swapped') + for Hp, uv, wx in backward_predecessors(H, labels): + sig = frozenset(frozenset(e) for e in Hp.edges()) + if sig in seen: + continue + seen.add(sig) + new.append(Hp) + if len(seen) >= max_states: + break + if len(seen) >= max_states: + break + frontier = new + rounds += 1 + return None, len(seen), rounds, 'exhausted' if not frontier else 'capped' + + +def main(): + G_orig = nx.tutte_graph() + D, _ = dual_triangulation(G_orig) + n = D.number_of_nodes() + print(f'Tutte graph dual: n={n}, edges={D.number_of_edges()}') + + # Confirm not intertwining tree (we already know this, but verify) + print('Verifying NOT intertwining tree (time-limited)...') + result = is_intertwining_tree(D, time_limit=60.0) + if result is False: + print(' confirmed: no 2-tree partition exists') + elif result is None: + print(' search timed out; cannot confirm') + else: + print(f' SURPRISE: is intertwining tree with partition {result}') + + # Try various labellings: BFS from each vertex of D, take levels. + # For each labelling, do backward BFS to find ELG. + print('\nSearching for backward path to an Even Level Graph...') + for src in list(D.nodes())[:5]: # first 5 sources + labels = bfs_levels(D, frozenset({src})) + print(f' source={src}, label distribution: ' + f'even={sum(1 for l in labels.values() if l % 2 == 0)}, ' + f'odd={sum(1 for l in labels.values() if l % 2 == 1)}') + result, n_states, rnds, status = find_elg_via_backward_bfs( + D, labels, max_states=20000, time_limit=60.0) + if result is not None: + print(f' FOUND ELG ancestor ({status}, ' + f'{n_states} states, {rnds} rounds)') + return + else: + print(f' no ELG ancestor found ({status}, ' + f'{n_states} states, {rnds} rounds)') + + print('No ELG found in backward orbit with the labellings tried.') + + +if __name__ == '__main__': + main() diff --git a/papers/even_level_graph_generators/paper.aux b/papers/even_level_graph_generators/paper.aux index a582057..0a55145 100644 --- a/papers/even_level_graph_generators/paper.aux +++ b/papers/even_level_graph_generators/paper.aux @@ -34,13 +34,18 @@ \newlabel{sec:even-level-graphs}{{4}{3}{Even Level Graphs}{section.4}{}} \newlabel{def:even-level-graph}{{4.1}{3}{Even Level Graph}{theorem.4.1}{}} \newlabel{thm:even-level-4colorable}{{4.2}{3}{}{theorem.4.2}{}} +\citation{holton-mckay} +\newlabel{def:derived-level-graph}{{4.3}{4}{Derived level graph}{theorem.4.3}{}} +\newlabel{def:intertwining-tree}{{4.4}{4}{Intertwining tree}{theorem.4.4}{}} +\newlabel{thm:intertwining-iff-hamiltonian-dual}{{4.5}{4}{}{theorem.4.5}{}} +\newlabel{conj:every-triangulation-derived}{{4.6}{4}{}{theorem.4.6}{}} +\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{Empirical status}}{4}{section*.1}\protected@file@percent } +\bibcite{holton-mckay}{1} \newlabel{tocindent-1}{0pt} \newlabel{tocindent0}{14.69437pt} \newlabel{tocindent1}{17.77782pt} \newlabel{tocindent2}{0pt} \newlabel{tocindent3}{0pt} -\newlabel{def:derived-level-graph}{{4.3}{4}{Derived level graph}{theorem.4.3}{}} -\newlabel{def:intertwining-tree}{{4.4}{4}{Intertwining tree}{theorem.4.4}{}} -\newlabel{conj:every-triangulation-derived}{{4.5}{4}{}{theorem.4.5}{}} -\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{Empirical status}}{4}{section*.1}\protected@file@percent } -\gdef \@abspage@last{4} +\@writefile{toc}{\contentsline {subsection}{\tocsubsection {}{}{The boundary case $n = 21$}}{5}{section*.2}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{5}{section*.3}\protected@file@percent } +\gdef \@abspage@last{5} diff --git a/papers/even_level_graph_generators/paper.log b/papers/even_level_graph_generators/paper.log index a79cc91..7c4b5c9 100644 --- a/papers/even_level_graph_generators/paper.log +++ b/papers/even_level_graph_generators/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) 21 MAY 2026 18:03 +This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 21 MAY 2026 20:44 entering extended mode restricted \write18 enabled. %&-line parsing enabled. @@ -353,12 +353,12 @@ Package epstopdf-base Info: Redefining graphics rule for `.eps' on input line 4 File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv e )) - + File: fig_levels.png Graphic file (type png) Package pdftex.def Info: fig_levels.png used on input line 108. (pdftex.def) Requested size: 198.0011pt x 170.59666pt. - + File: fig_level_cycle.png Graphic file (type png) Package pdftex.def Info: fig_level_cycle.png used on input line 122. @@ -369,12 +369,12 @@ LaTeX Warning: `h' float specifier changed to `ht'. [1{/usr/local/texlive/2022/texmf-var/fonts/map/pdftex/updmap/pdftex.map} <./fig _levels.png>] - + File: fig_edge_switch.png Graphic file (type png) Package pdftex.def Info: fig_edge_switch.png used on input line 141. (pdftex.def) Requested size: 341.9989pt x 150.51671pt. - + File: fig_parity_subgraph.png Graphic file (type png) Package pdftex.def Info: fig_parity_subgraph.png used on input line 159. @@ -384,15 +384,24 @@ Package pdftex.def Info: fig_parity_subgraph.png used on input line 159. LaTeX Warning: `h' float specifier changed to `ht'. [2 <./fig_level_cycle.png> <./fig_edge_switch.png>] [3 <./fig_parity_subgraph.p -ng>] [4] (./paper.aux) +ng>] [4] + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `math shift' on input line 324. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `math shift' on input line 324. + +[5] (./paper.aux) Package rerunfilecheck Info: File `paper.out' has not changed. -(rerunfilecheck) Checksum: DC9FD452C972FF1938BE7060890FAD7C;765. +(rerunfilecheck) Checksum: AECCB746CF11915BCB68F1E7FF8075A7;1047. ) Here is how much of TeX's memory you used: - 9727 strings out of 478268 - 150592 string characters out of 5846347 - 451778 words of memory out of 5000000 - 27640 multiletter control sequences out of 15000+600000 + 9737 strings out of 478268 + 150746 string characters out of 5846347 + 453840 words of memory out of 5000000 + 27645 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 69i,8n,76p,781b,427s stack positions out of 10000i,1000n,20000p,200000b,200000s @@ -409,10 +418,10 @@ texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb> -Output written on paper.pdf (4 pages, 530171 bytes). +Output written on paper.pdf (5 pages, 545810 bytes). PDF statistics: - 145 PDF objects out of 1000 (max. 8388607) - 103 compressed objects within 2 object streams - 25 named destinations out of 1000 (max. 500000) - 61 words of extra memory for PDF output out of 10000 (max. 10000000) + 162 PDF objects out of 1000 (max. 8388607) + 119 compressed objects within 2 object streams + 30 named destinations out of 1000 (max. 500000) + 77 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/papers/even_level_graph_generators/paper.out b/papers/even_level_graph_generators/paper.out index 3b71809..45bf212 100644 --- a/papers/even_level_graph_generators/paper.out +++ b/papers/even_level_graph_generators/paper.out @@ -3,3 +3,5 @@ \BOOKMARK [1][-]{section.3}{\376\377\0003\000.\000\040\000O\000u\000t\000e\000r\000p\000l\000a\000n\000a\000r\000i\000t\000y\000\040\000o\000f\000\040\000l\000e\000v\000e\000l\000\040\000c\000o\000m\000p\000o\000n\000e\000n\000t\000s}{}% 3 \BOOKMARK [1][-]{section.4}{\376\377\0004\000.\000\040\000E\000v\000e\000n\000\040\000L\000e\000v\000e\000l\000\040\000G\000r\000a\000p\000h\000s}{}% 4 \BOOKMARK [2][-]{section*.1}{\376\377\000E\000m\000p\000i\000r\000i\000c\000a\000l\000\040\000s\000t\000a\000t\000u\000s}{section.4}% 5 +\BOOKMARK [2][-]{section*.2}{\376\377\000T\000h\000e\000\040\000b\000o\000u\000n\000d\000a\000r\000y\000\040\000c\000a\000s\000e\000\040\000n\000\040\000=\000\040\0002\0001}{section.4}% 6 +\BOOKMARK [1][-]{section*.3}{\376\377\000R\000e\000f\000e\000r\000e\000n\000c\000e\000s}{}% 7 diff --git a/papers/even_level_graph_generators/paper.pdf b/papers/even_level_graph_generators/paper.pdf index ed13744..7db2042 100644 Binary files a/papers/even_level_graph_generators/paper.pdf and b/papers/even_level_graph_generators/paper.pdf differ diff --git a/papers/even_level_graph_generators/paper.tex b/papers/even_level_graph_generators/paper.tex index d4b4257..fce6242 100644 --- a/papers/even_level_graph_generators/paper.tex +++ b/papers/even_level_graph_generators/paper.tex @@ -257,12 +257,47 @@ vertex set can be partitioned into two sets $A$ and $B$ such that both induced subgraphs $G[A]$ and $G[B]$ are trees. \end{definition} +\begin{theorem} +\label{thm:intertwining-iff-hamiltonian-dual} +A maximal planar graph $G$ is an intertwining tree if and only if its +dual $G^\ast$ has a Hamiltonian cycle. +\end{theorem} + +\begin{proof} +($\Rightarrow$) Let $V(G) = A \sqcup B$ with $G[A]$ and $G[B]$ trees. +Every triangular face $\{x,y,z\}$ of $G$ meets both $A$ and $B$: if all +three vertices were in $A$ the triangle would be a cycle in the tree +$G[A]$, and likewise for $B$. Draw a closed curve through the faces of +$G$ separating the $A$-vertices from the $B$-vertices within each face. +Since every face is split, the curve visits every face exactly once and +crosses an edge of $G$ precisely when that edge joins $A$ to $B$; it is +therefore a Hamiltonian cycle of $G^\ast$. + +($\Leftarrow$) Let $H$ be a Hamiltonian cycle of $G^\ast$. Drawn in the +plane, $H$ is a Jordan curve visiting every face of $G$ once; let $A$ +and $B$ be the vertices of $G$ interior and exterior to $H$. The +$2n-4$ edges of $H$ cross exactly the edges of $G$ between $A$ and $B$, +leaving $(3n-6)-(2n-4) = n-2$ edges inside $G[A]$ and $G[B]$ together. +The edges inside $A$ lie in the disk bounded by $H$ and span $A$ +without enclosing a face (each face is cut by $H$), so $G[A]$ is a tree; +likewise $G[B]$. +\end{proof} + \begin{conjecture} \label{conj:every-triangulation-derived} Every maximal planar graph is a valid derived level graph of some Even Level Graph, an intertwining tree, or both. \end{conjecture} +By Theorem~\ref{thm:intertwining-iff-hamiltonian-dual}, the +intertwining-tree disjunct fails for $G$ exactly when $G^\ast$ is a +counterexample to Tait's conjecture. The smallest such $G^\ast$ have +$38$ vertices (Holton--McKay~\cite{holton-mckay}, exactly $6$ graphs), +so the smallest triangulations that are not intertwining trees occur at +$n = 21$ and there are exactly $6$ of them. Below $n = 21$ every +maximal planar graph is an intertwining tree, which is why the +disjunction holds trivially in that range. + \subsection*{Empirical status} For each isomorphism class of maximal planar graphs on $n$ vertices, @@ -284,4 +319,43 @@ $12$ & $7595$ & $0$ & $1$ & $7594$ & $0$ & holds \\ \end{tabular} \end{center} +\subsection*{The boundary case $n = 21$} + +The first triangulations that are \emph{not} intertwining trees are the +six duals of the Holton--McKay graphs, at $n = 21$. For the disjunction +to survive at $n = 21$, each of these six must be a valid derived level +graph. We find: +\begin{itemize} +\item All six duals are confirmed not intertwining trees (exhaustive +check of all $2^{20}-1$ vertex bipartitions), consistent with +Theorem~\ref{thm:intertwining-iff-hamiltonian-dual}. +\item Two of the six are themselves Even Level Graphs (for a suitable +source vertex), hence trivially valid derived level graphs. So the +disjunction holds for them through the derived-level-graph disjunct -- +the first instances where that disjunct does work the intertwining-tree +disjunct cannot. +\item The remaining four are not Even Level Graphs for any source. A +bounded backward $E/O$-orbit search (tens of thousands of states, a +handful of source labellings) found no Even Level Graph in their +orbits, but this is far too shallow relative to the orbit size at +$n = 21$ to be conclusive; their status as derived level graphs is +open. +\end{itemize} +Thus at $n = 21$ the disjunction is confirmed for two of the six +critical iso classes and undetermined for the other four. Settling +those four -- equivalently, deciding $E/O$-orbit reachability from an +Even Level Graph -- is the first genuinely open instance of the +conjecture, and calls for either a better reachability algorithm or a +structural invariant of $E/O$-orbits. + +\begin{thebibliography}{9} + +\bibitem{holton-mckay} +D.~A. Holton and B.~D. McKay. +\emph{The smallest non-Hamiltonian 3-connected cubic planar graphs have +38 vertices}. +Journal of Combinatorial Theory, Series B, 45(3):305--319, 1988. + +\end{thebibliography} + \end{document}