diff --git a/colored_pentagon_reduction/example.py b/colored_pentagon_reduction/example.py index 7d8e783..0ec18de 100644 --- a/colored_pentagon_reduction/example.py +++ b/colored_pentagon_reduction/example.py @@ -41,8 +41,8 @@ def operation_sequence_id(ops: list[Operation]) -> str: joined = "\n".join(op_to_transform_id(op) for op in ops) return hashlib.sha256(joined.encode()).hexdigest() -def canonize_colored_graph(g: Graph, coloring: VertexColoring) -> ColoredGraphId: - """Mutate g and coloring to canonical labels and return a canonical ColoredGraphId""" +def canonize_colored_graph(g: Graph, coloring: VertexColoring) -> tuple[Graph, VertexColoring, ColoredGraphId]: + """Return a new canonical graph, new canonical coloring, and a ColoredGraphId without mutating inputs""" canonical, cert = cast( tuple[Graph, dict[Any, int]], g.canonical_label(certificate=True), @@ -55,34 +55,31 @@ def canonize_colored_graph(g: Graph, coloring: VertexColoring) -> ColoredGraphId for orig_v, canon_idx in cert.items(): color_seq[canon_idx] = coloring[orig_v] - coloring.clear() - for canon_idx, color in enumerate(color_seq): - coloring[canon_idx] = color + canonical_coloring = {canon_idx: color for canon_idx, color in enumerate(color_seq)} coloring_id = base64.urlsafe_b64encode(bytes(color_seq)).decode() - g.relabel(cert) - return ColoredGraphId(graph_id=graph_id, coloring_id=coloring_id) + return canonical, canonical_coloring, ColoredGraphId(graph_id=graph_id, coloring_id=coloring_id) def save_colored_graph(g: Graph, coloring: VertexColoring) -> tuple[Graph, VertexColoring, ColoredGraphId]: """ - Relabel g and coloring into canonical form, save to disk, and return both. + Canonize g and coloring, save to disk, and return the canonical forms with id. If already saved, load and return the cached graph. """ - cid = canonize_colored_graph(g, coloring) + g_canon, canonical_coloring, cid = canonize_colored_graph(g, coloring) out_dir = DIR / "data" / "graphs" / cid['graph_id'] / cid['coloring_id'] if (out_dir / "graph.sobj").exists(): g_canon = cast(Graph, load(str(out_dir / 'graph'))) - return g_canon, coloring, cid - g.is_planar(set_embedding=True, set_pos=True) + return g_canon, canonical_coloring, cid + g_canon.is_planar(set_embedding=True, set_pos=True) vertex_colors: defaultdict[str, list[Any]] = defaultdict(list) - for v, c in coloring.items(): + for v, c in canonical_coloring.items(): vertex_colors[PALETTE[c]].append(v) out_dir.mkdir(parents=True, exist_ok=True) - g.plot( + g_canon.plot( vertex_colors=dict(vertex_colors), title=f"graph: {cid['graph_id']} coloring: {cid['coloring_id']}", ).save(out_dir / 'graph.png') - save(g, str(out_dir / 'graph')) - return g, coloring, cid + save(g_canon, str(out_dir / 'graph')) + return g_canon, canonical_coloring, cid def _neighbors_form_cycle(g: Graph, v: Any) -> bool: """Return True if the neighbors of v induce a cycle in g."""