From 3493b7f58c167706ff4332dc8c948875c06c1928 Mon Sep 17 00:00:00 2001 From: Will Cashman Date: Wed, 13 Dec 2023 10:58:16 +0000 Subject: [PATCH 1/4] Fix variable names --- zxlive/proof.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/zxlive/proof.py b/zxlive/proof.py index af2efa9f..f3ebb2eb 100644 --- a/zxlive/proof.py +++ b/zxlive/proof.py @@ -137,12 +137,11 @@ def rename_step(self, index: int, name: str) -> None: def to_json(self) -> str: """Serializes the model to JSON.""" - initial_graph_tikz = self.graphs[0].to_json() - proof_steps = [] - for step in self.steps: - proof_steps.append(step.to_json()) + initial_graph = self.graphs[0].to_json() + proof_steps = [step.to_json() for step in self.steps] + return json.dumps({ - "initial_graph": initial_graph_tikz, + "initial_graph": initial_graph, "proof_steps": proof_steps }) From 7ff2edb9ff8fc7c2f9b81660a50a019769d0aecc Mon Sep 17 00:00:00 2001 From: Will Cashman Date: Wed, 13 Dec 2023 11:09:37 +0000 Subject: [PATCH 2/4] Remove graph diffs Previously we stored the proof as both a series of graphs and as an initial graph together with a series of diffs. Now we have removed the diffs to avoid possible synchronisation issues. Additionally, the diffs did not record repositioned vertices, which made adding an OCM step difficult (Issue: #150) --- zxlive/commands.py | 9 +++--- zxlive/mainwindow.py | 6 ++-- zxlive/proof.py | 68 +++++++++++++++++++++----------------------- zxlive/tikz.py | 2 +- 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/zxlive/commands.py b/zxlive/commands.py index 82e96125..34ff6252 100644 --- a/zxlive/commands.py +++ b/zxlive/commands.py @@ -385,8 +385,7 @@ def redo(self) -> None: for _ in range(self.proof_model.rowCount() - self._old_selected - 1): self._old_steps.append(self.proof_model.pop_rewrite()) - diff = self.diff or GraphDiff(self.g, self.new_g) - self.proof_model.add_rewrite(Rewrite(self.name, self.name, diff), self.new_g) + self.proof_model.add_rewrite(Rewrite(self.name, self.name, self.new_g)) # Select the added step idx = self.step_view.model().index(self.proof_model.rowCount() - 1, 0, QModelIndex()) @@ -403,7 +402,7 @@ def undo(self) -> None: # Add back steps that were previously removed for rewrite, graph in reversed(self._old_steps): - self.proof_model.add_rewrite(rewrite, graph) + self.proof_model.add_rewrite(rewrite) # Select the previously selected step assert self._old_selected is not None @@ -456,10 +455,10 @@ def redo(self) -> None: super().redo() model = self.step_view.model() assert isinstance(model, ProofModel) - model.graphs[self.step_view.currentIndex().row()] = self.g + model.set_graph(self.step_view.currentIndex().row(), self.g) def undo(self) -> None: super().undo() model = self.step_view.model() assert isinstance(model, ProofModel) - model.graphs[self.step_view.currentIndex().row()] = self.g + model.set_graph(self.step_view.currentIndex().row(), self.g) diff --git a/zxlive/mainwindow.py b/zxlive/mainwindow.py index 9361de6d..006783cb 100644 --- a/zxlive/mainwindow.py +++ b/zxlive/mainwindow.py @@ -282,7 +282,7 @@ def _open_file_from_output(self, out: ImportGraphOutput | ImportProofOutput | Im if isinstance(out, ImportGraphOutput): self.new_graph(out.g, name) elif isinstance(out, ImportProofOutput): - graph = out.p.graphs[-1] + graph = out.p.graphs()[-1] self.new_deriv(graph, name) assert isinstance(self.active_panel, ProofPanel) proof_panel: ProofPanel = self.active_panel @@ -544,8 +544,8 @@ def proof_as_lemma(self) -> None: name, description = get_lemma_name_and_description(self) if name is None or description is None: return - lhs_graph = self.active_panel.proof_model.graphs[0] - rhs_graph = self.active_panel.proof_model.graphs[-1] + lhs_graph = self.active_panel.proof_model.graphs()[0] + rhs_graph = self.active_panel.proof_model.graphs()[-1] rule = CustomRule(lhs_graph, rhs_graph, name, description) save_rule_dialog(rule, self, name + ".zxr" if name else "") diff --git a/zxlive/proof.py b/zxlive/proof.py index f3ebb2eb..99583e17 100644 --- a/zxlive/proof.py +++ b/zxlive/proof.py @@ -14,14 +14,14 @@ class Rewrite(NamedTuple): display_name: str # Name of proof displayed to user rule: str # Name of the rule that was applied to get to this step - diff: GraphDiff # Diff from the last step to this step + graph: GraphT # Diff from the last step to this step def to_json(self) -> str: """Serializes the rewrite to JSON.""" return json.dumps({ "display_name": self.display_name, "rule": self.rule, - "diff": self.diff.to_json() + "graph": self.graph.to_json() }) @staticmethod @@ -32,7 +32,7 @@ def from_json(json_str: str) -> "Rewrite": return Rewrite( display_name=d.get("display_name", d["rule"]), # Old proofs may not have display names rule=d["rule"], - diff=GraphDiff.from_json(d["diff"]) + graph=GraphT.from_json(d["graph"]), ) class ProofModel(QAbstractListModel): @@ -42,29 +42,29 @@ class ProofModel(QAbstractListModel): rewrite that was used to go from one graph to next. """ - graphs: list[GraphT] # n graphs - steps: list[Rewrite] # n-1 rewrite steps + initial_graph: GraphT + steps: list[Rewrite] def __init__(self, start_graph: GraphT): super().__init__() - self.graphs = [start_graph] + self.initial_graph = start_graph self.steps = [] - def set_data(self, graphs: list[GraphT], steps: list[Rewrite]) -> None: - """Sets the model data. + def set_graph(self, index: int, graph: GraphT): + if index == 0: + self.initial_graph = graph + else: + old_step = self.steps[index-1] + new_step = Rewrite(old_step.display_name, old_step.rule, graph) + self.steps[index-1] = new_step - Can be used to load the model from a saved state. - """ - assert len(steps) == len(graphs) - 1 - self.beginResetModel() - self.graphs = graphs - self.steps = steps - self.endResetModel() + def graphs(self) -> [GraphT]: + return [self.initial_graph] + [step.graph for step in self.steps] def data(self, index: Union[QModelIndex, QPersistentModelIndex], role: int=Qt.ItemDataRole.DisplayRole) -> Any: """Overrides `QAbstractItemModel.data` to populate a view with rewrite steps""" - if index.row() >= len(self.graphs) or index.column() >= 1: + if index.row() >= len(self.steps)+1 or index.column() >= 1: return None if role == Qt.ItemDataRole.DisplayRole: @@ -93,14 +93,13 @@ def rowCount(self, index: Union[QModelIndex, QPersistentModelIndex] = QModelInde # user has to specify the index of the parent. In a list, we always expect the # parent to be `None` or the empty `QModelIndex()` if not index or not index.isValid(): - return len(self.graphs) + return len(self.steps)+1 else: return 0 - def add_rewrite(self, rewrite: Rewrite, new_graph: GraphT) -> None: + def add_rewrite(self, rewrite: Rewrite) -> None: """Adds a rewrite step to the model.""" - self.beginInsertRows(QModelIndex(), len(self.graphs), len(self.graphs)) - self.graphs.append(new_graph) + self.beginInsertRows(QModelIndex(), len(self.steps), len(self.steps)) self.steps.append(rewrite) self.endInsertRows() @@ -109,35 +108,37 @@ def pop_rewrite(self) -> tuple[Rewrite, GraphT]: Returns the rewrite and the graph that previously resulted from this rewrite. """ - self.beginRemoveRows(QModelIndex(), len(self.graphs) - 1, len(self.graphs) - 1) + self.beginRemoveRows(QModelIndex(), len(self.steps), len(self.steps)) rewrite = self.steps.pop() - graph = self.graphs.pop() self.endRemoveRows() - return rewrite, graph + return rewrite, rewrite.graph def get_graph(self, index: int) -> GraphT: """Returns the grap at a given position in the proof.""" - copy = self.graphs[index].copy() - # Mypy issue: https://github.com/python/mypy/issues/11673 - assert isinstance(copy, GraphT) # type: ignore - return copy + if index == 0: + return self.initial_graph.copy() + else: + copy = self.steps[index-1].graph.copy() + # Mypy issue: https://github.com/python/mypy/issues/11673 + assert isinstance(copy, GraphT) # type: ignore + return copy def rename_step(self, index: int, name: str) -> None: """Change the display name""" - old_step = self.steps[index] + old_step = self.steps[index-1] # Must create a new Rewrite object instead of modifying current object # since Rewrite inherits NamedTuple and is hence immutable - self.steps[index] = Rewrite(name, old_step.rule, old_step.diff) + self.steps[index-1] = Rewrite(name, old_step.rule, old_step.graph) # Rerender the proof step otherwise it will display the old name until # the cursor moves - modelIndex = self.createIndex(index, 0) + modelIndex = self.createIndex(index-1, 0) self.dataChanged.emit(modelIndex, modelIndex, []) def to_json(self) -> str: """Serializes the model to JSON.""" - initial_graph = self.graphs[0].to_json() + initial_graph = self.initial_graph.to_json() proof_steps = [step.to_json() for step in self.steps] return json.dumps({ @@ -155,8 +156,5 @@ def from_json(json_str: str) -> "ProofModel": model = ProofModel(initial_graph) for step in d["proof_steps"]: rewrite = Rewrite.from_json(step) - rewritten_graph = rewrite.diff.apply_diff(model.graphs[-1]) - # Mypy issue: https://github.com/python/mypy/issues/11673 - assert isinstance(rewritten_graph, GraphT) # type: ignore - model.add_rewrite(rewrite, rewritten_graph) + model.add_rewrite(rewrite) return model diff --git a/zxlive/tikz.py b/zxlive/tikz.py index c3ef1a4b..c9b3e40e 100644 --- a/zxlive/tikz.py +++ b/zxlive/tikz.py @@ -15,7 +15,7 @@ def proof_to_tikz(proof: ProofModel) -> str: yoffset = -10 idoffset = 0 total_verts, total_edges = [], [] - for i, g in enumerate(proof.graphs): + for i, g in enumerate(proof.graphs()): # Compute graph dimensions width = max(g.row(v) for v in g.vertices()) - min(g.row(v) for v in g.vertices()) height = max(g.qubit(v) for v in g.vertices()) - min(g.qubit(v) for v in g.vertices()) From bf9fcb6811c6b56811fd12ed4cc3fbfe0fb3d1c7 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Thu, 25 Jan 2024 20:27:36 +0000 Subject: [PATCH 3/4] minor changes to the pr --- zxlive/proof.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zxlive/proof.py b/zxlive/proof.py index 99583e17..8670b016 100644 --- a/zxlive/proof.py +++ b/zxlive/proof.py @@ -14,7 +14,7 @@ class Rewrite(NamedTuple): display_name: str # Name of proof displayed to user rule: str # Name of the rule that was applied to get to this step - graph: GraphT # Diff from the last step to this step + graph: GraphT # New graph after applying the rewrite def to_json(self) -> str: """Serializes the rewrite to JSON.""" @@ -58,7 +58,7 @@ def set_graph(self, index: int, graph: GraphT): new_step = Rewrite(old_step.display_name, old_step.rule, graph) self.steps[index-1] = new_step - def graphs(self) -> [GraphT]: + def graphs(self) -> list[GraphT]: return [self.initial_graph] + [step.graph for step in self.steps] def data(self, index: Union[QModelIndex, QPersistentModelIndex], role: int=Qt.ItemDataRole.DisplayRole) -> Any: @@ -114,7 +114,7 @@ def pop_rewrite(self) -> tuple[Rewrite, GraphT]: return rewrite, rewrite.graph def get_graph(self, index: int) -> GraphT: - """Returns the grap at a given position in the proof.""" + """Returns the graph at a given position in the proof.""" if index == 0: return self.initial_graph.copy() else: From 3f2eefd211c48dab00db461d6c95c477c8ed3610 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Thu, 25 Jan 2024 20:42:13 +0000 Subject: [PATCH 4/4] replace the proof test file to match new file format --- test/demo.zxp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/demo.zxp b/test/demo.zxp index 7a757ff4..0961c003 100644 --- a/test/demo.zxp +++ b/test/demo.zxp @@ -1 +1 @@ -{"initial_graph": "{\"wire_vertices\": {\"b0\": {\"annotation\": {\"boundary\": true, \"coord\": [1, 0], \"input\": 0}}, \"b1\": {\"annotation\": {\"boundary\": true, \"coord\": [1, -1], \"input\": 1}}, \"b2\": {\"annotation\": {\"boundary\": true, \"coord\": [1, -2], \"input\": 2}}, \"b3\": {\"annotation\": {\"boundary\": true, \"coord\": [1, -3], \"input\": 3}}, \"b4\": {\"annotation\": {\"boundary\": true, \"coord\": [6, 0], \"output\": 0}}, \"b5\": {\"annotation\": {\"boundary\": true, \"coord\": [6, -1], \"output\": 1}}, \"b6\": {\"annotation\": {\"boundary\": true, \"coord\": [6, -2], \"output\": 2}}, \"b7\": {\"annotation\": {\"boundary\": true, \"coord\": [6, -3], \"output\": 3}}}, \"node_vertices\": {\"v0\": {\"annotation\": {\"coord\": [2, 0]}, \"data\": {\"type\": \"Z\"}}, \"v1\": {\"annotation\": {\"coord\": [2, -1]}, \"data\": {\"type\": \"X\"}}, \"v2\": {\"annotation\": {\"coord\": [2, -2]}, \"data\": {\"type\": \"Z\"}}, \"v3\": {\"annotation\": {\"coord\": [2, -3]}, \"data\": {\"type\": \"Z\"}}, \"v4\": {\"annotation\": {\"coord\": [3, 0]}, \"data\": {\"type\": \"Z\"}}, \"v5\": {\"annotation\": {\"coord\": [3, -1]}, \"data\": {\"type\": \"Z\"}}, \"v6\": {\"annotation\": {\"coord\": [3, -2]}, \"data\": {\"type\": \"X\"}}, \"v7\": {\"annotation\": {\"coord\": [3, -3]}, \"data\": {\"type\": \"Z\"}}, \"v8\": {\"annotation\": {\"coord\": [4, 0]}, \"data\": {\"type\": \"Z\"}}, \"v9\": {\"annotation\": {\"coord\": [4, -1]}, \"data\": {\"type\": \"X\"}}, \"v10\": {\"annotation\": {\"coord\": [4, -2]}, \"data\": {\"type\": \"Z\"}}, \"v11\": {\"annotation\": {\"coord\": [4, -3]}, \"data\": {\"type\": \"Z\"}}, \"v12\": {\"annotation\": {\"coord\": [5, 0]}, \"data\": {\"type\": \"X\"}}, \"v13\": {\"annotation\": {\"coord\": [5, -1]}, \"data\": {\"type\": \"X\"}}, \"v14\": {\"annotation\": {\"coord\": [5, -2]}, \"data\": {\"type\": \"Z\"}}, \"v15\": {\"annotation\": {\"coord\": [5, -3]}, \"data\": {\"type\": \"X\"}}, \"v16\": {\"annotation\": {\"coord\": [3.5, -1.0]}, \"data\": {\"type\": \"hadamard\", \"is_edge\": \"true\"}}, \"v17\": {\"annotation\": {\"coord\": [4.5, -1.0]}, \"data\": {\"type\": \"hadamard\", \"is_edge\": \"true\"}}, \"v18\": {\"annotation\": {\"coord\": [4.5, -1.5]}, \"data\": {\"type\": \"hadamard\", \"is_edge\": \"true\"}}}, \"undir_edges\": {\"e0\": {\"src\": \"b0\", \"tgt\": \"v0\"}, \"e1\": {\"src\": \"b1\", \"tgt\": \"v1\"}, \"e2\": {\"src\": \"b2\", \"tgt\": \"v2\"}, \"e3\": {\"src\": \"b3\", \"tgt\": \"v3\"}, \"e4\": {\"src\": \"v0\", \"tgt\": \"v1\"}, \"e5\": {\"src\": \"v0\", \"tgt\": \"v4\"}, \"e6\": {\"src\": \"v1\", \"tgt\": \"v5\"}, \"e7\": {\"src\": \"v1\", \"tgt\": \"v6\"}, \"e8\": {\"src\": \"v2\", \"tgt\": \"v6\"}, \"e9\": {\"src\": \"v3\", \"tgt\": \"v7\"}, \"e10\": {\"src\": \"v4\", \"tgt\": \"v8\"}, \"e11\": {\"src\": \"v5\", \"tgt\": \"v16\"}, \"e12\": {\"src\": \"v9\", \"tgt\": \"v16\"}, \"e13\": {\"src\": \"v6\", \"tgt\": \"v10\"}, \"e14\": {\"src\": \"v7\", \"tgt\": \"v11\"}, \"e15\": {\"src\": \"v8\", \"tgt\": \"v12\"}, \"e16\": {\"src\": \"v8\", \"tgt\": \"v13\"}, \"e17\": {\"src\": \"v9\", \"tgt\": \"v17\"}, \"e18\": {\"src\": \"v13\", \"tgt\": \"v17\"}, \"e19\": {\"src\": \"v9\", \"tgt\": \"v18\"}, \"e20\": {\"src\": \"v14\", \"tgt\": \"v18\"}, \"e21\": {\"src\": \"v10\", \"tgt\": \"v13\"}, \"e22\": {\"src\": \"v10\", \"tgt\": \"v14\"}, \"e23\": {\"src\": \"v11\", \"tgt\": \"v14\"}, \"e24\": {\"src\": \"v11\", \"tgt\": \"v15\"}, \"e25\": {\"src\": \"v12\", \"tgt\": \"b4\"}, \"e26\": {\"src\": \"v13\", \"tgt\": \"b5\"}, \"e27\": {\"src\": \"v14\", \"tgt\": \"b6\"}, \"e28\": {\"src\": \"v15\", \"tgt\": \"b7\"}}, \"scalar\": \"{\\\"power2\\\": 0, \\\"phase\\\": \\\"0\\\"}\"}", "proof_steps": ["{\"display_name\": \"fuse spiders\", \"rule\": \"fuse spiders\", \"diff\": \"{\\\"removed_verts\\\": [8], \\\"new_verts\\\": [], \\\"removed_edges\\\": [], \\\"new_edges\\\": [[4, 12]], \\\"changed_vertex_types\\\": {}, \\\"changed_edge_types\\\": {\\\"4,12\\\": 1}, \\\"changed_phases\\\": {}, \\\"changed_pos\\\": {}, \\\"changed_vdata\\\": {}, \\\"variable_types\\\": {}}\"}"]} \ No newline at end of file +{"initial_graph": "{\"wire_vertices\": {\"b0\": {\"annotation\": {\"boundary\": true, \"coord\": [1, 0], \"input\": 0}}, \"b1\": {\"annotation\": {\"boundary\": true, \"coord\": [1, -1], \"input\": 1}}, \"b2\": {\"annotation\": {\"boundary\": true, \"coord\": [1, -2], \"input\": 2}}, \"b3\": {\"annotation\": {\"boundary\": true, \"coord\": [1, -3], \"input\": 3}}, \"b4\": {\"annotation\": {\"boundary\": true, \"coord\": [6, 0], \"output\": 0}}, \"b5\": {\"annotation\": {\"boundary\": true, \"coord\": [6, -1], \"output\": 1}}, \"b6\": {\"annotation\": {\"boundary\": true, \"coord\": [6, -2], \"output\": 2}}, \"b7\": {\"annotation\": {\"boundary\": true, \"coord\": [6, -3], \"output\": 3}}}, \"node_vertices\": {\"v0\": {\"annotation\": {\"coord\": [2, 0]}, \"data\": {\"type\": \"Z\"}}, \"v1\": {\"annotation\": {\"coord\": [2, -1]}, \"data\": {\"type\": \"X\"}}, \"v2\": {\"annotation\": {\"coord\": [2, -2]}, \"data\": {\"type\": \"Z\"}}, \"v3\": {\"annotation\": {\"coord\": [2, -3]}, \"data\": {\"type\": \"Z\"}}, \"v4\": {\"annotation\": {\"coord\": [3, 0]}, \"data\": {\"type\": \"Z\"}}, \"v5\": {\"annotation\": {\"coord\": [3, -1]}, \"data\": {\"type\": \"Z\"}}, \"v6\": {\"annotation\": {\"coord\": [3, -2]}, \"data\": {\"type\": \"X\"}}, \"v7\": {\"annotation\": {\"coord\": [3, -3]}, \"data\": {\"type\": \"Z\"}}, \"v8\": {\"annotation\": {\"coord\": [4, 0]}, \"data\": {\"type\": \"Z\"}}, \"v9\": {\"annotation\": {\"coord\": [4, -1]}, \"data\": {\"type\": \"X\"}}, \"v10\": {\"annotation\": {\"coord\": [4, -2]}, \"data\": {\"type\": \"Z\"}}, \"v11\": {\"annotation\": {\"coord\": [4, -3]}, \"data\": {\"type\": \"Z\"}}, \"v12\": {\"annotation\": {\"coord\": [5, 0]}, \"data\": {\"type\": \"X\"}}, \"v13\": {\"annotation\": {\"coord\": [5, -1]}, \"data\": {\"type\": \"X\"}}, \"v14\": {\"annotation\": {\"coord\": [5, -2]}, \"data\": {\"type\": \"Z\"}}, \"v15\": {\"annotation\": {\"coord\": [5, -3]}, \"data\": {\"type\": \"X\"}}, \"v16\": {\"annotation\": {\"coord\": [3.5, -1.0]}, \"data\": {\"type\": \"hadamard\", \"is_edge\": \"true\"}}, \"v17\": {\"annotation\": {\"coord\": [4.5, -1.0]}, \"data\": {\"type\": \"hadamard\", \"is_edge\": \"true\"}}, \"v18\": {\"annotation\": {\"coord\": [4.5, -1.5]}, \"data\": {\"type\": \"hadamard\", \"is_edge\": \"true\"}}}, \"undir_edges\": {\"e0\": {\"src\": \"b0\", \"tgt\": \"v0\"}, \"e1\": {\"src\": \"b1\", \"tgt\": \"v1\"}, \"e2\": {\"src\": \"b2\", \"tgt\": \"v2\"}, \"e3\": {\"src\": \"b3\", \"tgt\": \"v3\"}, \"e4\": {\"src\": \"v0\", \"tgt\": \"v1\"}, \"e5\": {\"src\": \"v0\", \"tgt\": \"v4\"}, \"e6\": {\"src\": \"v1\", \"tgt\": \"v5\"}, \"e7\": {\"src\": \"v1\", \"tgt\": \"v6\"}, \"e8\": {\"src\": \"v2\", \"tgt\": \"v6\"}, \"e9\": {\"src\": \"v3\", \"tgt\": \"v7\"}, \"e10\": {\"src\": \"v4\", \"tgt\": \"v8\"}, \"e11\": {\"src\": \"v5\", \"tgt\": \"v16\"}, \"e12\": {\"src\": \"v9\", \"tgt\": \"v16\"}, \"e13\": {\"src\": \"v6\", \"tgt\": \"v10\"}, \"e14\": {\"src\": \"v7\", \"tgt\": \"v11\"}, \"e15\": {\"src\": \"v8\", \"tgt\": \"v12\"}, \"e16\": {\"src\": \"v8\", \"tgt\": \"v13\"}, \"e17\": {\"src\": \"v9\", \"tgt\": \"v17\"}, \"e18\": {\"src\": \"v13\", \"tgt\": \"v17\"}, \"e19\": {\"src\": \"v9\", \"tgt\": \"v18\"}, \"e20\": {\"src\": \"v14\", \"tgt\": \"v18\"}, \"e21\": {\"src\": \"v10\", \"tgt\": \"v13\"}, \"e22\": {\"src\": \"v10\", \"tgt\": \"v14\"}, \"e23\": {\"src\": \"v11\", \"tgt\": \"v14\"}, \"e24\": {\"src\": \"v11\", \"tgt\": \"v15\"}, \"e25\": {\"src\": \"v12\", \"tgt\": \"b4\"}, \"e26\": {\"src\": \"v13\", \"tgt\": \"b5\"}, \"e27\": {\"src\": \"v14\", \"tgt\": \"b6\"}, \"e28\": {\"src\": \"v15\", \"tgt\": \"b7\"}}, \"scalar\": \"{\\\"power2\\\": 0, \\\"phase\\\": \\\"0\\\"}\"}", "proof_steps": ["{\"display_name\": \"fuse spiders\", \"rule\": \"fuse spiders\", \"graph\": \"{\\\"wire_vertices\\\": {\\\"b0\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, 0], \\\"input\\\": 0}}, \\\"b1\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, -1], \\\"input\\\": 1}}, \\\"b2\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, -2], \\\"input\\\": 2}}, \\\"b3\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, -3], \\\"input\\\": 3}}, \\\"b4\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, 0], \\\"output\\\": 0}}, \\\"b5\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, -1], \\\"output\\\": 1}}, \\\"b6\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, -2], \\\"output\\\": 2}}, \\\"b7\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, -3], \\\"output\\\": 3}}}, \\\"node_vertices\\\": {\\\"v0\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, 0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v1\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, -1]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v2\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, -2]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v3\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, -3]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v4\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, 0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v5\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, -1]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v6\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, -2]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v7\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, -3]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v8\\\": {\\\"annotation\\\": {\\\"coord\\\": [4, 0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v9\\\": {\\\"annotation\\\": {\\\"coord\\\": [4, -1]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v10\\\": {\\\"annotation\\\": {\\\"coord\\\": [4, -2]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v11\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, 0]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v12\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, -1]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v13\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, -2]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v14\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, -3]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v15\\\": {\\\"annotation\\\": {\\\"coord\\\": [3.5, -1.0]}, \\\"data\\\": {\\\"type\\\": \\\"hadamard\\\", \\\"is_edge\\\": \\\"true\\\"}}, \\\"v16\\\": {\\\"annotation\\\": {\\\"coord\\\": [4.5, -1.0]}, \\\"data\\\": {\\\"type\\\": \\\"hadamard\\\", \\\"is_edge\\\": \\\"true\\\"}}, \\\"v17\\\": {\\\"annotation\\\": {\\\"coord\\\": [4.5, -1.5]}, \\\"data\\\": {\\\"type\\\": \\\"hadamard\\\", \\\"is_edge\\\": \\\"true\\\"}}}, \\\"undir_edges\\\": {\\\"e0\\\": {\\\"src\\\": \\\"b0\\\", \\\"tgt\\\": \\\"v0\\\"}, \\\"e1\\\": {\\\"src\\\": \\\"b1\\\", \\\"tgt\\\": \\\"v1\\\"}, \\\"e2\\\": {\\\"src\\\": \\\"b2\\\", \\\"tgt\\\": \\\"v2\\\"}, \\\"e3\\\": {\\\"src\\\": \\\"b3\\\", \\\"tgt\\\": \\\"v3\\\"}, \\\"e4\\\": {\\\"src\\\": \\\"v0\\\", \\\"tgt\\\": \\\"v1\\\"}, \\\"e5\\\": {\\\"src\\\": \\\"v0\\\", \\\"tgt\\\": \\\"v4\\\"}, \\\"e6\\\": {\\\"src\\\": \\\"v1\\\", \\\"tgt\\\": \\\"v5\\\"}, \\\"e7\\\": {\\\"src\\\": \\\"v1\\\", \\\"tgt\\\": \\\"v6\\\"}, \\\"e8\\\": {\\\"src\\\": \\\"v2\\\", \\\"tgt\\\": \\\"v6\\\"}, \\\"e9\\\": {\\\"src\\\": \\\"v3\\\", \\\"tgt\\\": \\\"v7\\\"}, \\\"e10\\\": {\\\"src\\\": \\\"v4\\\", \\\"tgt\\\": \\\"v8\\\"}, \\\"e11\\\": {\\\"src\\\": \\\"v5\\\", \\\"tgt\\\": \\\"v15\\\"}, \\\"e12\\\": {\\\"src\\\": \\\"v9\\\", \\\"tgt\\\": \\\"v15\\\"}, \\\"e13\\\": {\\\"src\\\": \\\"v6\\\", \\\"tgt\\\": \\\"v10\\\"}, \\\"e14\\\": {\\\"src\\\": \\\"v7\\\", \\\"tgt\\\": \\\"v13\\\"}, \\\"e15\\\": {\\\"src\\\": \\\"v8\\\", \\\"tgt\\\": \\\"v11\\\"}, \\\"e16\\\": {\\\"src\\\": \\\"v8\\\", \\\"tgt\\\": \\\"v12\\\"}, \\\"e17\\\": {\\\"src\\\": \\\"v9\\\", \\\"tgt\\\": \\\"v16\\\"}, \\\"e18\\\": {\\\"src\\\": \\\"v12\\\", \\\"tgt\\\": \\\"v16\\\"}, \\\"e19\\\": {\\\"src\\\": \\\"v9\\\", \\\"tgt\\\": \\\"v17\\\"}, \\\"e20\\\": {\\\"src\\\": \\\"v13\\\", \\\"tgt\\\": \\\"v17\\\"}, \\\"e21\\\": {\\\"src\\\": \\\"v10\\\", \\\"tgt\\\": \\\"v12\\\"}, \\\"e22\\\": {\\\"src\\\": \\\"v10\\\", \\\"tgt\\\": \\\"v13\\\"}, \\\"e23\\\": {\\\"src\\\": \\\"v11\\\", \\\"tgt\\\": \\\"b4\\\"}, \\\"e24\\\": {\\\"src\\\": \\\"v12\\\", \\\"tgt\\\": \\\"b5\\\"}, \\\"e25\\\": {\\\"src\\\": \\\"v13\\\", \\\"tgt\\\": \\\"b6\\\"}, \\\"e26\\\": {\\\"src\\\": \\\"v13\\\", \\\"tgt\\\": \\\"v14\\\"}, \\\"e27\\\": {\\\"src\\\": \\\"v14\\\", \\\"tgt\\\": \\\"b7\\\"}}, \\\"scalar\\\": \\\"{\\\\\\\"power2\\\\\\\": 0, \\\\\\\"phase\\\\\\\": \\\\\\\"0\\\\\\\"}\\\"}\"}", "{\"display_name\": \"bialgebra\", \"rule\": \"bialgebra\", \"graph\": \"{\\\"wire_vertices\\\": {\\\"b0\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, 0], \\\"input\\\": 0}}, \\\"b1\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, -1], \\\"input\\\": 1}}, \\\"b2\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, -2], \\\"input\\\": 2}}, \\\"b3\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [1, -3], \\\"input\\\": 3}}, \\\"b4\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, 0], \\\"output\\\": 0}}, \\\"b5\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, -1], \\\"output\\\": 1}}, \\\"b6\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, -2], \\\"output\\\": 2}}, \\\"b7\\\": {\\\"annotation\\\": {\\\"boundary\\\": true, \\\"coord\\\": [6, -3], \\\"output\\\": 3}}}, \\\"node_vertices\\\": {\\\"v0\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, 0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v1\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, -1]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v2\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, -2]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v3\\\": {\\\"annotation\\\": {\\\"coord\\\": [2, -3]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v4\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, 0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v5\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, -1]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v6\\\": {\\\"annotation\\\": {\\\"coord\\\": [3, -3]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v7\\\": {\\\"annotation\\\": {\\\"coord\\\": [4, 0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v8\\\": {\\\"annotation\\\": {\\\"coord\\\": [4, -1]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v9\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, 0]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v10\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, -1]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v11\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, -2]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v12\\\": {\\\"annotation\\\": {\\\"coord\\\": [5, -3]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v13\\\": {\\\"annotation\\\": {\\\"coord\\\": [4.4, -1.6]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v14\\\": {\\\"annotation\\\": {\\\"coord\\\": [4.4, -2.0]}, \\\"data\\\": {\\\"type\\\": \\\"X\\\"}}, \\\"v15\\\": {\\\"annotation\\\": {\\\"coord\\\": [2.6, -1.6]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v16\\\": {\\\"annotation\\\": {\\\"coord\\\": [2.6, -2.0]}, \\\"data\\\": {\\\"type\\\": \\\"Z\\\"}}, \\\"v17\\\": {\\\"annotation\\\": {\\\"coord\\\": [3.5, -1.0]}, \\\"data\\\": {\\\"type\\\": \\\"hadamard\\\", \\\"is_edge\\\": \\\"true\\\"}}, \\\"v18\\\": {\\\"annotation\\\": {\\\"coord\\\": [4.5, -1.0]}, \\\"data\\\": {\\\"type\\\": \\\"hadamard\\\", \\\"is_edge\\\": \\\"true\\\"}}, \\\"v19\\\": {\\\"annotation\\\": {\\\"coord\\\": [4.5, -1.5]}, \\\"data\\\": {\\\"type\\\": \\\"hadamard\\\", \\\"is_edge\\\": \\\"true\\\"}}}, \\\"undir_edges\\\": {\\\"e0\\\": {\\\"src\\\": \\\"b0\\\", \\\"tgt\\\": \\\"v0\\\"}, \\\"e1\\\": {\\\"src\\\": \\\"b1\\\", \\\"tgt\\\": \\\"v1\\\"}, \\\"e2\\\": {\\\"src\\\": \\\"b2\\\", \\\"tgt\\\": \\\"v2\\\"}, \\\"e3\\\": {\\\"src\\\": \\\"b3\\\", \\\"tgt\\\": \\\"v3\\\"}, \\\"e4\\\": {\\\"src\\\": \\\"v0\\\", \\\"tgt\\\": \\\"v1\\\"}, \\\"e5\\\": {\\\"src\\\": \\\"v0\\\", \\\"tgt\\\": \\\"v4\\\"}, \\\"e6\\\": {\\\"src\\\": \\\"v1\\\", \\\"tgt\\\": \\\"v5\\\"}, \\\"e7\\\": {\\\"src\\\": \\\"v1\\\", \\\"tgt\\\": \\\"v15\\\"}, \\\"e8\\\": {\\\"src\\\": \\\"v2\\\", \\\"tgt\\\": \\\"v16\\\"}, \\\"e9\\\": {\\\"src\\\": \\\"v3\\\", \\\"tgt\\\": \\\"v6\\\"}, \\\"e10\\\": {\\\"src\\\": \\\"v4\\\", \\\"tgt\\\": \\\"v7\\\"}, \\\"e11\\\": {\\\"src\\\": \\\"v5\\\", \\\"tgt\\\": \\\"v17\\\"}, \\\"e12\\\": {\\\"src\\\": \\\"v8\\\", \\\"tgt\\\": \\\"v17\\\"}, \\\"e13\\\": {\\\"src\\\": \\\"v6\\\", \\\"tgt\\\": \\\"v11\\\"}, \\\"e14\\\": {\\\"src\\\": \\\"v7\\\", \\\"tgt\\\": \\\"v9\\\"}, \\\"e15\\\": {\\\"src\\\": \\\"v7\\\", \\\"tgt\\\": \\\"v10\\\"}, \\\"e16\\\": {\\\"src\\\": \\\"v8\\\", \\\"tgt\\\": \\\"v18\\\"}, \\\"e17\\\": {\\\"src\\\": \\\"v10\\\", \\\"tgt\\\": \\\"v18\\\"}, \\\"e18\\\": {\\\"src\\\": \\\"v8\\\", \\\"tgt\\\": \\\"v19\\\"}, \\\"e19\\\": {\\\"src\\\": \\\"v11\\\", \\\"tgt\\\": \\\"v19\\\"}, \\\"e20\\\": {\\\"src\\\": \\\"v9\\\", \\\"tgt\\\": \\\"b4\\\"}, \\\"e21\\\": {\\\"src\\\": \\\"v10\\\", \\\"tgt\\\": \\\"b5\\\"}, \\\"e22\\\": {\\\"src\\\": \\\"v10\\\", \\\"tgt\\\": \\\"v13\\\"}, \\\"e23\\\": {\\\"src\\\": \\\"v11\\\", \\\"tgt\\\": \\\"b6\\\"}, \\\"e24\\\": {\\\"src\\\": \\\"v11\\\", \\\"tgt\\\": \\\"v12\\\"}, \\\"e25\\\": {\\\"src\\\": \\\"v11\\\", \\\"tgt\\\": \\\"v14\\\"}, \\\"e26\\\": {\\\"src\\\": \\\"v12\\\", \\\"tgt\\\": \\\"b7\\\"}, \\\"e27\\\": {\\\"src\\\": \\\"v13\\\", \\\"tgt\\\": \\\"v15\\\"}, \\\"e28\\\": {\\\"src\\\": \\\"v13\\\", \\\"tgt\\\": \\\"v16\\\"}, \\\"e29\\\": {\\\"src\\\": \\\"v14\\\", \\\"tgt\\\": \\\"v15\\\"}, \\\"e30\\\": {\\\"src\\\": \\\"v14\\\", \\\"tgt\\\": \\\"v16\\\"}}, \\\"scalar\\\": \\\"{\\\\\\\"power2\\\\\\\": 1, \\\\\\\"phase\\\\\\\": \\\\\\\"0\\\\\\\"}\\\"}\"}"]} \ No newline at end of file