From 5bdf6c27b1fad08605ec0a538bc5f287a80ce446 Mon Sep 17 00:00:00 2001 From: Boldi Date: Sat, 22 Jun 2024 12:04:25 +0100 Subject: [PATCH] Fix multigraph color change --- pyzx/editor_actions.py | 3 +-- pyzx/graph/base.py | 6 ++++++ pyzx/graph/graph_ig.py | 3 +++ pyzx/graph/graph_s.py | 6 +++++- pyzx/graph/multigraph.py | 5 +++++ pyzx/utils.py | 6 +++++- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/pyzx/editor_actions.py b/pyzx/editor_actions.py index 67481b2c..857d61e8 100644 --- a/pyzx/editor_actions.py +++ b/pyzx/editor_actions.py @@ -53,8 +53,7 @@ def color_change(g: BaseGraph[VT,ET], matches: List[VT]) -> rules.RewriteOutputT for v in matches: g.set_type(v, toggle_vertex(g.type(v))) for e in g.incident_edges(v): - et = g.edge_type(e) - g.set_edge_type(e, toggle_edge(et)) + g.toggle_edge_type(e) return ({}, [],[],False) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index 8f6cfec4..0d205c0c 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -872,6 +872,12 @@ def set_edge_type(self, e: ET, t: EdgeType.Type) -> None: """Sets the type of the given edge.""" raise NotImplementedError("Not implemented on backend " + type(self).backend) + def toggle_edge_type(self, e: ET) -> None: + """Toggles the type of the edge between ``EdgeType.SIMPLE`` and ``EdgeType.HADAMARD``. + Does nothing if the edge is empty. + """ + raise NotImplementedError("Not implemented on backend " + type(self).backend) + def type(self, vertex: VT) -> VertexType.Type: """Returns the type of the given vertex: VertexType.BOUNDARY if it is a boundary, VertexType.Z if it is a Z node, diff --git a/pyzx/graph/graph_ig.py b/pyzx/graph/graph_ig.py index ab81d899..47cb671d 100644 --- a/pyzx/graph/graph_ig.py +++ b/pyzx/graph/graph_ig.py @@ -21,6 +21,7 @@ ig = None from .base import BaseGraph, VertexType, EdgeType +from ..utils import toggle_edge class GraphIG(BaseGraph): """Implementation of :class:`~graph.base.BaseGraph` using ``python-igraph`` @@ -115,6 +116,8 @@ def edge_type(self, e): def set_edge_type(self, e, t): self.graph.es[e]['_t'] = t + def toggle_edge_type(self, e): + self.set_edge_type(e, toggle_edge(self.graph.es[e]['_t'])) def type(self, v): t = self.graph.vs[v]['_t'] diff --git a/pyzx/graph/graph_s.py b/pyzx/graph/graph_s.py index a4e47214..89fc131e 100644 --- a/pyzx/graph/graph_s.py +++ b/pyzx/graph/graph_s.py @@ -19,7 +19,7 @@ from .base import BaseGraph -from ..utils import VertexType, EdgeType, FractionLike, FloatInt, vertex_is_zx_like, vertex_is_z_like, set_z_box_label, get_z_box_label +from ..utils import VertexType, EdgeType, FractionLike, FloatInt, vertex_is_zx_like, vertex_is_z_like, set_z_box_label, get_z_box_label, toggle_edge class GraphS(BaseGraph[int,Tuple[int,int]]): """Purely Pythonic implementation of :class:`~graph.base.BaseGraph`.""" @@ -275,6 +275,10 @@ def set_edge_type(self, e, t): self.graph[v1][v2] = t self.graph[v2][v1] = t + def toggle_edge_type(self, e): + if edge_type := self.edge_type(e): + self.set_edge_type(e, toggle_edge(edge_type)) + def type(self, vertex): return self.ty[vertex] def types(self): diff --git a/pyzx/graph/multigraph.py b/pyzx/graph/multigraph.py index 7a2541ce..2a3d0b83 100644 --- a/pyzx/graph/multigraph.py +++ b/pyzx/graph/multigraph.py @@ -348,6 +348,11 @@ def set_edge_type(self, edge, t): elif t == EdgeType.HADAMARD: e.add(h=1) else: e.add(w_io=1) + def toggle_edge_type(self, edge): + v1,v2 = edge + e = self.graph[v1][v2] + e.h, e.s = e.s, e.h + def type(self, vertex): return self.ty[vertex] def types(self): diff --git a/pyzx/utils.py b/pyzx/utils.py index 46464c73..a7588af2 100644 --- a/pyzx/utils.py +++ b/pyzx/utils.py @@ -82,7 +82,11 @@ class EdgeType: def toggle_edge(ty: EdgeType.Type) -> EdgeType.Type: """Swap the regular and Hadamard edge types.""" - return EdgeType.HADAMARD if ty == EdgeType.SIMPLE else EdgeType.SIMPLE + if ty == EdgeType.SIMPLE: + return EdgeType.HADAMARD + if ty == EdgeType.HADAMARD: + return EdgeType.SIMPLE + return ty def phase_to_s(a: FractionLike, t:VertexType.Type=VertexType.Z) -> str: if isinstance(a, Fraction) or isinstance(a, int):