diff --git a/CHANGELOG.md b/CHANGELOG.md index c91c1855..7b431d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Hence, occasionally changes will be backwards incompatible (although they will a - Incorrect scalar in the Z-X bialgebra rule when both spiders carry Pauli phases, including symbolic Boolean phases (by @dlyongemallo). - `subgraph_from_vertices` copies only variables used in the subgraph (by @dlyongemallo). - `extract_circuit` raises `ValueError` for graphs containing ground vertices or mismatched input/output counts, instead of a `KeyError` crash (by @dlyongemallo). +- Missed copying `_grounds` in `clone()`, incorrectly checking destination `is_ground` instead of source in `tensor()` (by @dlyongemallo). ### Changed - Migrated project configuration from `setup.py` to `pyproject.toml`. Make the `galois` package an optional dependency, as it is only used in `pyzx.web`. (by @dlyongemallo) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index f0bb7da2..1be68d50 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -620,7 +620,7 @@ def tensor(self, other: BaseGraph[VT,ET]) -> BaseGraph[VT,ET]: phases = other.phases() vertex_map = dict() for v in other.vertices(): - w = g.add_vertex(ts[v],qs[v]+height,rs[v],phases[v],g.is_ground(v)) + w = g.add_vertex(ts[v],qs[v]+height,rs[v],phases[v],other.is_ground(v)) g.set_vdata_dict(w, other.vdata_dict(v)) vertex_map[v] = w for e in other.edges(): diff --git a/pyzx/graph/graph_s.py b/pyzx/graph/graph_s.py index 450d5667..d145c2a9 100644 --- a/pyzx/graph/graph_s.py +++ b/pyzx/graph/graph_s.py @@ -59,6 +59,7 @@ def clone(self) -> 'GraphS': cpy._maxr = self._maxr cpy._vdata = self._vdata.copy() cpy.scalar = self.scalar.copy() + cpy._grounds = self._grounds.copy() cpy._inputs = tuple(list(self._inputs)) cpy._outputs = tuple(list(self._outputs)) cpy.track_phases = self.track_phases diff --git a/pyzx/graph/multigraph.py b/pyzx/graph/multigraph.py index 98c42b8b..26f7f75d 100644 --- a/pyzx/graph/multigraph.py +++ b/pyzx/graph/multigraph.py @@ -97,6 +97,7 @@ def clone(self) -> 'Multigraph': cpy._vdata = self._vdata.copy() cpy._edata = {k: v.copy() for k, v in self._edata.items()} cpy.scalar = self.scalar.copy() + cpy._grounds = self._grounds.copy() cpy._inputs = tuple(list(self._inputs)) cpy._outputs = tuple(list(self._outputs)) cpy.track_phases = self.track_phases diff --git a/tests/test_graph.py b/tests/test_graph.py index 3571f211..872f75a5 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -160,6 +160,31 @@ def test_copy(self): v1, v2 = list(g2.vertices()) self.assertEqual(g.edge_type(g.edge(v1,v2)),EdgeType.HADAMARD) + def test_clone_grounds(self): + """clone() should preserve ground status of vertices.""" + for backend in ["simple", "multigraph"]: + with self.subTest(backend=backend): + g = Graph(backend=backend) + v1 = g.add_vertex(VertexType.Z, 0, 0) + v2 = g.add_vertex(VertexType.Z, 0, 1, ground=True) + g.add_edge((v1, v2)) + g2 = g.clone() + self.assertTrue(g2.is_ground(v2)) + self.assertFalse(g2.is_ground(v1)) + + def test_tensor_grounds(self): + """tensor() should preserve grounds from the other graph.""" + for backend in ["simple", "multigraph"]: + with self.subTest(backend=backend): + g1 = Graph(backend=backend) + g1.add_vertex(VertexType.Z, 0, 0) + + g2 = Graph(backend=backend) + g2.add_vertex(VertexType.Z, 0, 0, ground=True) + + g = g1.tensor(g2) + self.assertEqual(len(g.grounds()), 1) + def test_adjoint_scalar(self): g = Graph() scalar = Scalar()