diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b431d75c..1dd754138 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ Hence, occasionally changes will be backwards incompatible (although they will a - `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). +### Removed +- `Measurement.to_graph_ground`; measurements now always use the symbolic boolean representation (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) - Dropped support for Python 3.9 (end of life). Added support for Python 3.13. (by @dlyongemallo) diff --git a/pyzx/circuit/gates.py b/pyzx/circuit/gates.py index ed9a58666..17b412909 100644 --- a/pyzx/circuit/gates.py +++ b/pyzx/circuit/gates.py @@ -1561,32 +1561,6 @@ def reposition(self, mask, bit_mask = None): g.result_bit = bit_mask[self.result_bit] return g - def to_graph_ground(self, g, q_mapper, c_mapper): - """Represent the measurement as a node with a ground symbol.""" - # Discard previous bit value - if self.result_bit is not None: - DiscardBit(self.result_bit).to_graph(g, q_mapper, c_mapper) - # Qubit measurement - r = q_mapper.next_row(self.target) - if self.result_bit is not None: - r = max(r, c_mapper.next_row(self.result_bit)) - v = self.graph_add_node(g, - q_mapper, - VertexType.Z, - self.target, - r, - ground=True) - q_mapper.set_next_row(self.target, r+1) - # Classical result - if self.result_bit is not None: - u = self.graph_add_node(g, - c_mapper, - VertexType.X, - self.result_bit, - r) - g.add_edge((v,u), EdgeType.SIMPLE) - c_mapper.set_next_row(self.result_bit, r+1) - def to_graph_symbolic_boolean(self, g, q_mapper): """Represent the measurement as a node with symbolic boolean phases.""" r = q_mapper.next_row(self.target) @@ -1605,11 +1579,8 @@ def to_graph_symbolic_boolean(self, g, q_mapper): phase=phase) q_mapper.set_next_row(self.target, r+1) - def to_graph(self, g, q_mapper, c_mapper, ground=False): - if ground: - self.to_graph_ground(g, q_mapper, c_mapper) - else: - self.to_graph_symbolic_boolean(g, q_mapper) + def to_graph(self, g, q_mapper, _c_mapper): + self.to_graph_symbolic_boolean(g, q_mapper) gate_types: Dict[str,Type[Gate]] = { "XPhase": XPhase, diff --git a/tests/test_qasm.py b/tests/test_qasm.py index 0f9ba7859..a6423f3ef 100644 --- a/tests/test_qasm.py +++ b/tests/test_qasm.py @@ -1288,56 +1288,6 @@ def test_classical_bits_output_positions(self): output_qubits = sorted(g.qubit(v) for v in g.outputs()) self.assertEqual(output_qubits, [0, 1, 2, 3]) - def test_measurement_ground_mode_with_result_bit(self): - """Measurement with result_bit in ground mode should use c_mapper.""" - from pyzx.circuit.gates import Measurement - from pyzx.circuit.graphparser import circuit_to_graph - c = Circuit(1, bit_amount=1) - c.gates = [Measurement(0, result_bit=0)] - g = circuit_to_graph(c) - # 1 quantum input + 1 classical input = 2 inputs. - self.assertEqual(len(g.inputs()), 2) - # Measurement consumes the qubit (no quantum output), but - # the classical bit still gets an output boundary. - self.assertEqual(len(g.outputs()), 1) - - def test_measurement_ground_mode_graph_structure(self): - """Ground-mode measurement should create correct graph structure.""" - from pyzx.circuit.gates import Measurement - from pyzx.circuit.graphparser import circuit_to_graph - from pyzx.utils import VertexType - c = Circuit(1, bit_amount=1) - m = Measurement(0, result_bit=0) - c.gates = [m] - g = circuit_to_graph(c) - # Count vertex types. - types = [g.type(v) for v in g.vertices()] - n_boundary = types.count(VertexType.BOUNDARY) - # 1 quantum input + 1 classical input + 1 classical output = 3. - self.assertEqual(n_boundary, 3) - - def test_measurement_ground_mode_direct(self): - """Directly test to_graph_ground with c_mapper labels.""" - from pyzx.circuit.gates import Measurement, TargetMapper - from pyzx.utils import VertexType - from pyzx.graph import Graph - g = Graph() - q_mapper = TargetMapper() - c_mapper = TargetMapper() - # Set up one quantum wire and one classical wire. - q_in = g.add_vertex(VertexType.BOUNDARY, 0, 0) - c_in = g.add_vertex(VertexType.BOUNDARY, 1, 0) - q_mapper.add_label(0, 1) - q_mapper.set_prev_vertex(0, q_in) - c_mapper.add_label(0, 1) - c_mapper.set_qubit(0, 1) - c_mapper.set_prev_vertex(0, c_in) - # Call to_graph_ground directly. - m = Measurement(0, result_bit=0) - m.to_graph_ground(g, q_mapper, c_mapper) - # Should not crash, and the graph should have vertices. - self.assertGreater(len(list(g.vertices())), 2) - def test_hththt_t_injection_feedforward(self): """HTHTHT... circuit with T gates implemented via injection.