"""Test the disjunction: every maximal planar graph is a valid derived level graph, an intertwining tree, or both. Iterates n=6..12, stops if a counterexample is found.""" 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 time import itertools import networkx as nx from triangulation_gen import enumerate_all_triangulations from test_conjecture import ( canonical_sig, bfs_levels, get_level_sources, is_even_level_graph, bfs_orbit ) def is_intertwining_tree(G): """Search for a 2-partition (A, B) such that G[A] and G[B] are trees.""" nodes = list(G.nodes()) n = len(nodes) # Try all 2^(n-1) partitions (fix node 0 in A by convention) 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 A or not B: continue GA = G.subgraph(A) GB = G.subgraph(B) if nx.is_tree(GA) and nx.is_tree(GB): return True, (tuple(A), tuple(B)) return False, None def derived_level_graph_iso_classes(tris): """Compute the set of iso class signatures that are derived level graphs of some Even Level Graph.""" iso_class_sigs = {canonical_sig(T) for T in tris} derived = set() for G in tris: if len(derived) == len(iso_class_sigs): break for source in get_level_sources(G): is_elg, levels = is_even_level_graph(G, source) if not is_elg: continue reached, _, _ = bfs_orbit(G, levels) derived.update(reached) return derived def test_n(n): t0 = time.time() tris = enumerate_all_triangulations(n) iso_sigs = [canonical_sig(T) for T in tris] derived = derived_level_graph_iso_classes(tris) n_derived = sum(1 for s in iso_sigs if s in derived) # For iso classes that are NOT derived, check intertwining tree counterexamples = [] n_intertwining_only = 0 n_both = 0 for i, G in enumerate(tris): is_derived = iso_sigs[i] in derived is_inter, partition = is_intertwining_tree(G) if is_derived and is_inter: n_both += 1 elif is_derived: pass # only derived elif is_inter: n_intertwining_only += 1 else: counterexamples.append((i, G)) n_total = len(tris) n_only_derived = n_derived - n_both elapsed = time.time() - t0 return { 'n': n, 'total': n_total, 'derived': n_derived, 'intertwining_only': n_intertwining_only, 'both': n_both, 'only_derived': n_only_derived, 'counterexamples': counterexamples, 'elapsed': elapsed, } def main(): results = [] for n in [6, 7, 8, 9, 10, 11, 12]: print(f'\n=== n = {n} ===') r = test_n(n) results.append(r) print(f' total iso classes: {r["total"]}') print(f' derived only: {r["only_derived"]}') print(f' intertwining only: {r["intertwining_only"]}') print(f' both: {r["both"]}') print(f' counterexamples: {len(r["counterexamples"])}') print(f' elapsed: {r["elapsed"]:.1f}s') if r['counterexamples']: print(f' COUNTEREXAMPLE FOUND. Stopping.') for i, G in r['counterexamples'][:3]: print(f' iso[{i}] degree seq = ' f'{sorted([G.degree(v) for v in G.nodes()], reverse=True)}') break print('\n=== Final summary ===') print(f'{"n":>3} {"total":>6} {"deriv":>6} {"inter":>6} {"both":>6} {"missing":>8}') for r in results: cov = r['only_derived'] + r['intertwining_only'] + r['both'] missing = r['total'] - cov print(f'{r["n"]:>3} {r["total"]:>6} {r["only_derived"]:>6} ' f'{r["intertwining_only"]:>6} {r["both"]:>6} {missing:>8}') if __name__ == '__main__': main()