"""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()
