From abdd3923bd40911e1c3519e1b3ed6a2221203eb8 Mon Sep 17 00:00:00 2001 From: Doug Strain Date: Mon, 11 Jul 2022 11:54:23 -0700 Subject: [PATCH] Remove Deprecated Quil classes (#5710) - Removes QuilFormatter, QuilOutput, and QuilXQubitGate Changes all typing of QuilFormatter to string.Formatter --- cirq-core/cirq/__init__.py | 3 - cirq-core/cirq/circuits/__init__.py | 2 - cirq-core/cirq/circuits/circuit.py | 10 - cirq-core/cirq/circuits/quil_output.py | 236 --------- cirq-core/cirq/circuits/quil_output_test.py | 476 ------------------ cirq-core/cirq/ops/common_gates.py | 25 +- cirq-core/cirq/ops/gate_operation.py | 3 - cirq-core/cirq/ops/gate_operation_test.py | 2 - cirq-core/cirq/ops/identity.py | 5 +- cirq-core/cirq/ops/measurement_gate.py | 5 +- cirq-core/cirq/ops/measurement_gate_test.py | 26 - cirq-core/cirq/ops/parity_gates.py | 14 +- cirq-core/cirq/ops/swap_gates.py | 7 +- cirq-core/cirq/ops/three_qubit_gates.py | 13 +- cirq-core/cirq/ops/two_qubit_diagonal_gate.py | 5 +- cirq-core/cirq/ops/wait_gate.py | 3 +- cirq-core/cirq/protocols/__init__.py | 1 - .../cirq/protocols/json_test_data/spec.py | 2 - cirq-core/cirq/protocols/quil.py | 84 ---- docs/start/intro.ipynb | 15 +- 20 files changed, 29 insertions(+), 908 deletions(-) delete mode 100644 cirq-core/cirq/circuits/quil_output.py delete mode 100644 cirq-core/cirq/circuits/quil_output_test.py delete mode 100644 cirq-core/cirq/protocols/quil.py diff --git a/cirq-core/cirq/__init__.py b/cirq-core/cirq/__init__.py index 029893cbf10..bfe2db63307 100644 --- a/cirq-core/cirq/__init__.py +++ b/cirq-core/cirq/__init__.py @@ -74,7 +74,6 @@ PointOptimizationSummary, PointOptimizer, QasmOutput, - QuilOutput, TextDiagramDrawer, Unique, ) @@ -606,8 +605,6 @@ qasm, QasmArgs, qid_shape, - quil, - QuilFormatter, read_json_gzip, read_json, resolve_parameters, diff --git a/cirq-core/cirq/circuits/__init__.py b/cirq-core/cirq/circuits/__init__.py index 665ab1ee31c..66f136b82d0 100644 --- a/cirq-core/cirq/circuits/__init__.py +++ b/cirq-core/cirq/circuits/__init__.py @@ -18,8 +18,6 @@ from cirq.circuits.qasm_output import QasmOutput -from cirq.circuits.quil_output import QuilOutput - from cirq.circuits.circuit import AbstractCircuit, Alignment, Circuit from cirq.circuits.circuit_dag import CircuitDag, Unique from cirq.circuits.circuit_operation import CircuitOperation diff --git a/cirq-core/cirq/circuits/circuit.py b/cirq-core/cirq/circuits/circuit.py index 04fc29e5ea6..c63e4ca3ba9 100644 --- a/cirq-core/cirq/circuits/circuit.py +++ b/cirq-core/cirq/circuits/circuit.py @@ -57,7 +57,6 @@ from cirq.circuits.circuit_operation import CircuitOperation from cirq.circuits.insert_strategy import InsertStrategy from cirq.circuits.qasm_output import QasmOutput -from cirq.circuits.quil_output import QuilOutput from cirq.circuits.text_diagram_drawer import TextDiagramDrawer from cirq.circuits.moment import Moment from cirq.protocols import circuit_diagram_info_protocol @@ -1311,12 +1310,6 @@ def _to_qasm_output( version='2.0', ) - def _to_quil_output( - self, qubit_order: 'cirq.QubitOrderOrList' = ops.QubitOrder.DEFAULT - ) -> 'cirq.QuilOutput': - qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for(self.all_qubits()) - return QuilOutput(operations=self.all_operations(), qubits=qubits) - def to_qasm( self, header: Optional[str] = None, @@ -1335,9 +1328,6 @@ def to_qasm( return str(self._to_qasm_output(header, precision, qubit_order)) - def to_quil(self, qubit_order: 'cirq.QubitOrderOrList' = ops.QubitOrder.DEFAULT) -> str: - return str(self._to_quil_output(qubit_order)) - def save_qasm( self, file_path: Union[str, bytes, int], diff --git a/cirq-core/cirq/circuits/quil_output.py b/cirq-core/cirq/circuits/quil_output.py deleted file mode 100644 index 18c1eb91091..00000000000 --- a/cirq-core/cirq/circuits/quil_output.py +++ /dev/null @@ -1,236 +0,0 @@ -# Copyright 2020 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Callable, Dict, Set, Tuple, Union -import numpy as np -import cirq -from cirq import protocols, value, ops - - -def to_quil_complex_format(num) -> str: - """A function for outputting a number to a complex string in QUIL format.""" - cnum = complex(str(num)) - return f"{cnum.real}+{cnum.imag}i" - - -@cirq._compat.deprecated_class( - deadline='v1.0', fix='Use cirq_rigetti.quil_output.QuilOneQubitGate instead.' -) -@value.value_equality(approximate=True) -class QuilOneQubitGate(ops.Gate): - """A QUIL gate representing any single qubit unitary with a DEFGATE and - 2x2 matrix in QUIL. - """ - - def __init__(self, matrix: np.ndarray) -> None: - """Inits QuilOneQubitGate. - - Args: - matrix: The 2x2 unitary matrix for this gate. - """ - self.matrix = matrix - - def _num_qubits_(self) -> int: - return 1 - - def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter') -> str: - return ( - f'DEFGATE USERGATE:\n ' - f'{to_quil_complex_format(self.matrix[0, 0])}, ' - f'{to_quil_complex_format(self.matrix[0, 1])}\n ' - f'{to_quil_complex_format(self.matrix[1, 0])}, ' - f'{to_quil_complex_format(self.matrix[1, 1])}\n' - f'{formatter.format("USERGATE {0}", qubits[0])}\n' - ) - - def __repr__(self) -> str: - return f'cirq.circuits.quil_output.QuilOneQubitGate(matrix=\n{self.matrix}\n)' - - def _value_equality_values_(self): - return self.matrix - - -@cirq._compat.deprecated_class( - deadline='v1.0', fix='Use cirq_rigetti.quil_output.QuilTwoQubitGate instead.' -) -@value.value_equality(approximate=True) -class QuilTwoQubitGate(ops.Gate): - """A two qubit gate represented in QUIL with a DEFGATE and it's 4x4 - unitary matrix. - """ - - def __init__(self, matrix: np.ndarray) -> None: - """Inits QuilTwoQubitGate. - - Args: - matrix: The 4x4 unitary matrix for this gate. - """ - self.matrix = matrix - - def _num_qubits_(self) -> int: - return 2 - - def _value_equality_values_(self): - return self.matrix - - def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter') -> str: - return ( - f'DEFGATE USERGATE:\n ' - f'{to_quil_complex_format(self.matrix[0, 0])}, ' - f'{to_quil_complex_format(self.matrix[0, 1])}, ' - f'{to_quil_complex_format(self.matrix[0, 2])}, ' - f'{to_quil_complex_format(self.matrix[0, 3])}\n ' - f'{to_quil_complex_format(self.matrix[1, 0])}, ' - f'{to_quil_complex_format(self.matrix[1, 1])}, ' - f'{to_quil_complex_format(self.matrix[1, 2])}, ' - f'{to_quil_complex_format(self.matrix[1, 3])}\n ' - f'{to_quil_complex_format(self.matrix[2, 0])}, ' - f'{to_quil_complex_format(self.matrix[2, 1])}, ' - f'{to_quil_complex_format(self.matrix[2, 2])}, ' - f'{to_quil_complex_format(self.matrix[2, 3])}\n ' - f'{to_quil_complex_format(self.matrix[3, 0])}, ' - f'{to_quil_complex_format(self.matrix[3, 1])}, ' - f'{to_quil_complex_format(self.matrix[3, 2])}, ' - f'{to_quil_complex_format(self.matrix[3, 3])}\n' - f'{formatter.format("USERGATE {0} {1}", qubits[0], qubits[1])}\n' - ) - - def __repr__(self) -> str: - return f'cirq.circuits.quil_output.QuilTwoQubitGate(matrix=\n{self.matrix}\n)' - - -@cirq._compat.deprecated_class( - deadline='v1.0', fix='Use cirq_rigetti.quil_output.QuilOutput instead.' -) -class QuilOutput: - """An object for passing operations and qubits then outputting them to - QUIL format. The string representation returns the QUIL output for the - circuit. - """ - - def __init__(self, operations: 'cirq.OP_TREE', qubits: Tuple['cirq.Qid', ...]) -> None: - """Inits QuilOutput. - - Args: - operations: A list or tuple of `cirq.OP_TREE` arguments. - qubits: The qubits used in the operations. - """ - self.qubits = qubits - self.operations = tuple(cirq.ops.flatten_to_ops(operations)) - self.measurements = tuple( - op for op in self.operations if isinstance(op.gate, ops.MeasurementGate) - ) - self.qubit_id_map = self._generate_qubit_ids() - self.measurement_id_map = self._generate_measurement_ids() - self.formatter = protocols.QuilFormatter( - qubit_id_map=self.qubit_id_map, measurement_id_map=self.measurement_id_map - ) - - def _generate_qubit_ids(self) -> Dict['cirq.Qid', str]: - return {qubit: str(i) for i, qubit in enumerate(self.qubits)} - - def _generate_measurement_ids(self) -> Dict[str, str]: - index = 0 - measurement_id_map: Dict[str, str] = {} - for op in self.operations: - if isinstance(op.gate, ops.MeasurementGate): - key = protocols.measurement_key_name(op) - if key in measurement_id_map: - continue - measurement_id_map[key] = f'm{index}' - index += 1 - return measurement_id_map - - def save_to_file(self, path: Union[str, bytes, int]) -> None: - """Write QUIL output to a file specified by path.""" - with open(path, 'w') as f: - f.write(str(self)) - - def __str__(self) -> str: - output = [] - self._write_quil(lambda s: output.append(s)) - return self.rename_defgates(''.join(output)) - - def _write_quil(self, output_func: Callable[[str], None]) -> None: - output_func('# Created using Cirq.\n\n') - if len(self.measurements) > 0: - measurements_declared: Set[str] = set() - for m in self.measurements: - key = protocols.measurement_key_name(m) - if key in measurements_declared: - continue - measurements_declared.add(key) - output_func(f'DECLARE {self.measurement_id_map[key]} BIT[{len(m.qubits)}]\n') - output_func('\n') - - def keep(op: 'cirq.Operation') -> bool: - return protocols.quil(op, formatter=self.formatter) is not None - - def fallback(op): - if len(op.qubits) not in [1, 2]: - return NotImplemented - - mat = protocols.unitary(op, None) - if mat is None: - return NotImplemented - - # Following code is a safety measure - # Could not find a gate that doesn't decompose into a gate - # with a _quil_ implementation - # coverage: ignore - if len(op.qubits) == 1: - return QuilOneQubitGate(mat).on(*op.qubits) - return QuilTwoQubitGate(mat).on(*op.qubits) - - def on_stuck(bad_op): - return ValueError(f'Cannot output operation as QUIL: {bad_op!r}') - - for main_op in self.operations: - decomposed = protocols.decompose( - main_op, keep=keep, fallback_decomposer=fallback, on_stuck_raise=on_stuck - ) - - for decomposed_op in decomposed: - output_func(protocols.quil(decomposed_op, formatter=self.formatter)) - - def rename_defgates(self, output: str) -> str: - """A function for renaming the DEFGATEs within the QUIL output. This - utilizes a second pass to find each DEFGATE and rename it based on - a counter. - """ - result = output - defString = "DEFGATE" - nameString = "USERGATE" - defIdx = 0 - nameIdx = 0 - gateNum = 0 - i = 0 - while i < len(output): - if result[i] == defString[defIdx]: - defIdx += 1 - else: - defIdx = 0 - if result[i] == nameString[nameIdx]: - nameIdx += 1 - else: - nameIdx = 0 - if defIdx == len(defString): - gateNum += 1 - defIdx = 0 - if nameIdx == len(nameString): - result = result[: i + 1] + str(gateNum) + result[i + 1 :] - nameIdx = 0 - i += 1 - i += 1 - return result diff --git a/cirq-core/cirq/circuits/quil_output_test.py b/cirq-core/cirq/circuits/quil_output_test.py deleted file mode 100644 index 2af1ed0f9ed..00000000000 --- a/cirq-core/cirq/circuits/quil_output_test.py +++ /dev/null @@ -1,476 +0,0 @@ -# Copyright 2020 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import numpy as np -import pytest - -import cirq -from cirq.ops.pauli_interaction_gate import PauliInteractionGate -from cirq.circuits.quil_output import QuilOneQubitGate, QuilTwoQubitGate - - -def _make_qubits(n): - return [cirq.NamedQubit(f'q{i}') for i in range(n)] - - -def test_single_gate_no_parameter(): - (q0,) = _make_qubits(1) - with cirq.testing.assert_deprecated(deadline='v1.0', count=6): - output = cirq.QuilOutput((cirq.X(q0),), (q0,)) - assert ( - str(output) - == """# Created using Cirq. - -X 0\n""" - ) - - -def test_single_gate_with_parameter(): - (q0,) = _make_qubits(1) - with cirq.testing.assert_deprecated(deadline='v1.0', count=6): - output = cirq.QuilOutput((cirq.X(q0) ** 0.5,), (q0,)) - assert ( - str(output) - == f"""# Created using Cirq. - -RX({np.pi / 2}) 0\n""" - ) - - -def test_single_gate_named_qubit(): - q = cirq.NamedQubit('qTest') - with cirq.testing.assert_deprecated(deadline='v1.0', count=6): - output = cirq.QuilOutput((cirq.X(q),), (q,)) - assert ( - str(output) - == """# Created using Cirq. - -X 0\n""" - ) - - -def test_h_gate_with_parameter(): - (q0,) = _make_qubits(1) - with cirq.testing.assert_deprecated(deadline='v1.0', count=6): - output = cirq.QuilOutput((cirq.H(q0) ** 0.25,), (q0,)) - assert ( - str(output) - == f"""# Created using Cirq. - -RY({np.pi / 4}) 0 -RX({np.pi / 4}) 0 -RY({-np.pi / 4}) 0\n""" - ) - - -def test_save_to_file(tmpdir): - file_path = os.path.join(tmpdir, 'test.quil') - (q0,) = _make_qubits(1) - with cirq.testing.assert_deprecated(deadline='v1.0', count=6): - output = cirq.QuilOutput((cirq.X(q0)), (q0,)) - output.save_to_file(file_path) - with open(file_path, 'r') as f: - file_content = f.read() - assert ( - file_content - == """# Created using Cirq. - -X 0\n""" - ) - - -def test_quil_one_qubit_gate_repr(): - with cirq.testing.assert_deprecated(deadline='v1.0', count=1): - gate = QuilOneQubitGate(np.array([[1, 0], [0, 1]])) - assert repr(gate) == ( - """cirq.circuits.quil_output.QuilOneQubitGate(matrix= -[[1 0] - [0 1]] -)""" - ) - - -def test_quil_two_qubit_gate_repr(): - with cirq.testing.assert_deprecated(deadline='v1.0', count=1): - gate = QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) - assert repr(gate) == ( - """cirq.circuits.quil_output.QuilTwoQubitGate(matrix= -[[1 0 0 0] - [0 1 0 0] - [0 0 1 0] - [0 0 0 1]] -)""" - ) - - -def test_quil_one_qubit_gate_eq(): - with cirq.testing.assert_deprecated(deadline='v1.0', count=4): - gate = QuilOneQubitGate(np.array([[1, 0], [0, 1]])) - gate2 = QuilOneQubitGate(np.array([[1, 0], [0, 1]])) - assert cirq.approx_eq(gate, gate2, atol=1e-16) - gate3 = QuilOneQubitGate(np.array([[1, 0], [0, 1]])) - gate4 = QuilOneQubitGate(np.array([[1, 0], [0, 2]])) - assert not cirq.approx_eq(gate4, gate3, atol=1e-16) - - -def test_quil_two_qubit_gate_eq(): - with cirq.testing.assert_deprecated(deadline='v1.0', count=4): - gate = QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) - gate2 = QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) - assert cirq.approx_eq(gate, gate2, atol=1e-8) - gate3 = QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) - gate4 = QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 1]])) - assert not cirq.approx_eq(gate4, gate3, atol=1e-8) - - -def test_quil_one_qubit_gate_output(): - (q0,) = _make_qubits(1) - with cirq.testing.assert_deprecated(deadline='v1.0', count=7): - gate = QuilOneQubitGate(np.array([[1, 0], [0, 1]])) - output = cirq.QuilOutput((gate.on(q0),), (q0,)) - assert ( - str(output) - == """# Created using Cirq. - -DEFGATE USERGATE1: - 1.0+0.0i, 0.0+0.0i - 0.0+0.0i, 1.0+0.0i -USERGATE1 0 -""" - ) - - -def test_two_quil_one_qubit_gate_output(): - (q0,) = _make_qubits(1) - with cirq.testing.assert_deprecated(deadline='v1.0', count=12): - gate = QuilOneQubitGate(np.array([[1, 0], [0, 1]])) - gate1 = QuilOneQubitGate(np.array([[2, 0], [0, 3]])) - output = cirq.QuilOutput((gate.on(q0), gate1.on(q0)), (q0,)) - assert ( - str(output) - == """# Created using Cirq. - -DEFGATE USERGATE1: - 1.0+0.0i, 0.0+0.0i - 0.0+0.0i, 1.0+0.0i -USERGATE1 0 -DEFGATE USERGATE2: - 2.0+0.0i, 0.0+0.0i - 0.0+0.0i, 3.0+0.0i -USERGATE2 0 -""" - ) - - -def test_quil_two_qubit_gate_output(): - (q0, q1) = _make_qubits(2) - with cirq.testing.assert_deprecated(deadline='v1.0', count=7): - gate = QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) - output = cirq.QuilOutput((gate.on(q0, q1),), (q0, q1)) - assert ( - str(output) - == """# Created using Cirq. - -DEFGATE USERGATE1: - 1.0+0.0i, 0.0+0.0i, 0.0+0.0i, 0.0+0.0i - 0.0+0.0i, 1.0+0.0i, 0.0+0.0i, 0.0+0.0i - 0.0+0.0i, 0.0+0.0i, 1.0+0.0i, 0.0+0.0i - 0.0+0.0i, 0.0+0.0i, 0.0+0.0i, 1.0+0.0i -USERGATE1 0 1 -""" - ) - - -def test_unsupported_operation(): - (q0,) = _make_qubits(1) - - class UnsupportedOperation(cirq.Operation): - qubits = (q0,) - with_qubits = NotImplemented - - with cirq.testing.assert_deprecated(deadline='v1.0', count=3): - output = cirq.QuilOutput((UnsupportedOperation(),), (q0,)) - with pytest.raises(ValueError): - _ = str(output) - - -def test_i_swap_with_power(): - q0, q1 = _make_qubits(2) - with cirq.testing.assert_deprecated(deadline='v1.0', count=6): - output = cirq.QuilOutput((cirq.ISWAP(q0, q1) ** 0.25,), (q0, q1)) - assert ( - str(output) - == f"""# Created using Cirq. - -XY({np.pi / 4}) 0 1 -""" - ) - - -def test_all_operations(): - qubits = tuple(_make_qubits(5)) - operations = _all_operations(*qubits, include_measurements=False) - with cirq.testing.assert_deprecated(deadline='v1.0', count=316): - output = cirq.QuilOutput(operations, qubits) - assert ( - str(output) - == f"""# Created using Cirq. - -DECLARE m0 BIT[1] -DECLARE m1 BIT[1] -DECLARE m2 BIT[1] -DECLARE m3 BIT[3] - -Z 0 -RZ({5 * np.pi / 8}) 0 -Y 0 -RY({3 * np.pi / 8}) 0 -X 0 -RX({7 * np.pi / 8}) 0 -H 1 -CZ 0 1 -CPHASE({np.pi / 4}) 0 1 -CNOT 0 1 -RY({-np.pi / 2}) 1 -CPHASE({np.pi / 2}) 0 1 -RY({np.pi / 2}) 1 -SWAP 0 1 -SWAP 1 0 -PSWAP({3 * np.pi / 4}) 0 1 -H 2 -CCNOT 0 1 2 -H 2 -CCNOT 0 1 2 -RZ({np.pi / 8}) 0 -RZ({np.pi / 8}) 1 -RZ({np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -RZ({-np.pi / 8}) 1 -RZ({np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -RZ({-np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -RZ({-np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -H 2 -RZ({np.pi / 8}) 0 -RZ({np.pi / 8}) 1 -RZ({np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -RZ({-np.pi / 8}) 1 -RZ({np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -RZ({-np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -RZ({-np.pi / 8}) 2 -CNOT 0 1 -CNOT 1 2 -H 2 -CSWAP 0 1 2 -X 0 -X 1 -RX({3 * np.pi / 4}) 0 -RX({3 * np.pi / 4}) 1 -Y 0 -Y 1 -RY({3 * np.pi / 4}) 0 -RY({3 * np.pi / 4}) 1 -Z 0 -Z 1 -RZ({3 * np.pi / 4}) 0 -RZ({3 * np.pi / 4}) 1 -I 0 -I 0 -I 1 -I 2 -ISWAP 2 0 -RZ({-0.111 * np.pi}) 1 -RX({np.pi / 4}) 1 -RZ({0.111 * np.pi}) 1 -RZ({-0.333 * np.pi}) 1 -RX({np.pi / 2}) 1 -RZ({0.333 * np.pi}) 1 -RZ({-0.777 * np.pi}) 1 -RX({-np.pi / 2}) 1 -RZ({0.777 * np.pi}) 1 -WAIT -MEASURE 0 m0[0] -MEASURE 2 m1[0] -MEASURE 3 m2[0] -MEASURE 2 m1[0] -MEASURE 1 m3[0] -X 2 # Inverting for following measurement -MEASURE 2 m3[1] -MEASURE 3 m3[2] -""" - ) - - -def _all_operations(q0, q1, q2, q3, q4, include_measurements=True): - return ( - cirq.Z(q0), - cirq.Z(q0) ** 0.625, - cirq.Y(q0), - cirq.Y(q0) ** 0.375, - cirq.X(q0), - cirq.X(q0) ** 0.875, - cirq.H(q1), - cirq.CZ(q0, q1), - cirq.CZ(q0, q1) ** 0.25, # Requires 2-qubit decomposition - cirq.CNOT(q0, q1), - cirq.CNOT(q0, q1) ** 0.5, # Requires 2-qubit decomposition - cirq.SWAP(q0, q1), - cirq.SWAP(q1, q0) ** -1, - cirq.SWAP(q0, q1) ** 0.75, # Requires 2-qubit decomposition - cirq.CCZ(q0, q1, q2), - cirq.CCX(q0, q1, q2), - cirq.CCZ(q0, q1, q2) ** 0.5, - cirq.CCX(q0, q1, q2) ** 0.5, - cirq.CSWAP(q0, q1, q2), - cirq.XX(q0, q1), - cirq.XX(q0, q1) ** 0.75, - cirq.YY(q0, q1), - cirq.YY(q0, q1) ** 0.75, - cirq.ZZ(q0, q1), - cirq.ZZ(q0, q1) ** 0.75, - cirq.IdentityGate(1).on(q0), - cirq.IdentityGate(3).on(q0, q1, q2), - cirq.ISWAP(q2, q0), # Requires 2-qubit decomposition - cirq.PhasedXPowGate(phase_exponent=0.111, exponent=0.25).on(q1), - cirq.PhasedXPowGate(phase_exponent=0.333, exponent=0.5).on(q1), - cirq.PhasedXPowGate(phase_exponent=0.777, exponent=-0.5).on(q1), - cirq.wait(q0, nanos=0), - cirq.measure(q0, key='xX'), - cirq.measure(q2, key='x_a'), - cirq.measure(q3, key='X'), - cirq.measure(q2, key='x_a'), - cirq.measure(q1, q2, q3, key='multi', invert_mask=(False, True)), - ) - - -def test_fails_on_big_unknowns(): - class UnrecognizedGate(cirq.testing.ThreeQubitGate): - pass - - c = cirq.Circuit(UnrecognizedGate().on(*cirq.LineQubit.range(3))) - with cirq.testing.assert_deprecated(deadline='v1.0', count=4): - with pytest.raises(ValueError, match='Cannot output operation as QUIL'): - _ = c.to_quil() - - -def test_pauli_interaction_gate(): - (q0, q1) = _make_qubits(2) - with cirq.testing.assert_deprecated(deadline='v1.0', count=16): - output = cirq.QuilOutput(PauliInteractionGate.CZ.on(q0, q1), (q0, q1)) - assert ( - str(output) - == """# Created using Cirq. - -CZ 0 1 -""" - ) - - -def test_equivalent_unitaries(): - """This test covers the factor of pi change. However, it will be skipped - if pyquil is unavailable for import. - - References: - https://docs.pytest.org/en/latest/skipping.html#skipping-on-a-missing-import-dependency - """ - pyquil = pytest.importorskip("pyquil") - pyquil_simulation_tools = pytest.importorskip("pyquil.simulation.tools") - q0, q1 = _make_qubits(2) - operations = [ - cirq.XPowGate(exponent=0.5, global_shift=-0.5)(q0), - cirq.YPowGate(exponent=0.5, global_shift=-0.5)(q0), - cirq.ZPowGate(exponent=0.5, global_shift=-0.5)(q0), - cirq.CZPowGate(exponent=0.5)(q0, q1), - cirq.ISwapPowGate(exponent=0.5)(q0, q1), - ] - with cirq.testing.assert_deprecated(deadline='v1.0', count=22): - output = cirq.QuilOutput(operations, (q0, q1)) - program = pyquil.Program(str(output)) - pyquil_unitary = pyquil_simulation_tools.program_unitary(program, n_qubits=2) - # Qubit ordering differs between pyQuil and Cirq. - cirq_unitary = cirq.Circuit(cirq.SWAP(q0, q1), operations, cirq.SWAP(q0, q1)).unitary() - assert np.allclose(pyquil_unitary, cirq_unitary) - - -QUIL_CPHASES_PROGRAM = """ -CPHASE00(pi/2) 0 1 -CPHASE01(pi/2) 0 1 -CPHASE10(pi/2) 0 1 -CPHASE(pi/2) 0 1 -""" - -QUIL_DIAGONAL_DECOMPOSE_PROGRAM = """ -RZ(0) 0 -RZ(0) 1 -CPHASE(0) 0 1 -X 0 -X 1 -CPHASE(0) 0 1 -X 0 -X 1 -""" - - -def test_two_qubit_diagonal_gate_quil_output(): - pyquil = pytest.importorskip("pyquil") - pyquil_simulation_tools = pytest.importorskip("pyquil.simulation.tools") - q0, q1 = _make_qubits(2) - operations = [ - cirq.TwoQubitDiagonalGate([np.pi / 2, 0, 0, 0])(q0, q1), - cirq.TwoQubitDiagonalGate([0, np.pi / 2, 0, 0])(q0, q1), - cirq.TwoQubitDiagonalGate([0, 0, np.pi / 2, 0])(q0, q1), - cirq.TwoQubitDiagonalGate([0, 0, 0, np.pi / 2])(q0, q1), - ] - with cirq.testing.assert_deprecated(deadline='v1.0', count=54): - output = cirq.QuilOutput(operations, (q0, q1)) - program = pyquil.Program(str(output)) - assert f"\n{program.out()}" == QUIL_CPHASES_PROGRAM - - pyquil_unitary = pyquil_simulation_tools.program_unitary(program, n_qubits=2) - # Qubit ordering differs between pyQuil and Cirq. - cirq_unitary = cirq.Circuit(cirq.SWAP(q0, q1), operations, cirq.SWAP(q0, q1)).unitary() - assert np.allclose(pyquil_unitary, cirq_unitary) - # Also test non-CPHASE case, which decomposes into X/RZ/CPhase - operations = [cirq.TwoQubitDiagonalGate([0, 0, 0, 0])(q0, q1)] - output = cirq.QuilOutput(operations, (q0, q1)) - program = pyquil.Program(str(output)) - assert f"\n{program.out()}" == QUIL_DIAGONAL_DECOMPOSE_PROGRAM - - -def test_parseable_defgate_output(): - pyquil = pytest.importorskip("pyquil") - q0, q1 = _make_qubits(2) - with cirq.testing.assert_deprecated(deadline='v1.0', count=12): - operations = [ - QuilOneQubitGate(np.array([[1, 0], [0, 1]])).on(q0), - QuilTwoQubitGate(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])).on( - q0, q1 - ), - ] - output = cirq.QuilOutput(operations, (q0, q1)) - # Just checks that we can create a pyQuil Program without crashing. - pyquil.Program(str(output)) diff --git a/cirq-core/cirq/ops/common_gates.py b/cirq-core/cirq/ops/common_gates.py index e69b8353c02..b262f85b507 100644 --- a/cirq-core/cirq/ops/common_gates.py +++ b/cirq-core/cirq/ops/common_gates.py @@ -36,6 +36,7 @@ TYPE_CHECKING, Union, ) +import string import numpy as np import sympy @@ -255,9 +256,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio return args.format('sxdg {0};\n', qubits[0]) return args.format('rx({0:half_turns}) {1};\n', self._exponent, qubits[0]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1 and self._global_shift != -0.5: return formatter.format('X {0}\n', qubits[0]) return formatter.format('RX({0}) {1}\n', self._exponent * np.pi, qubits[0]) @@ -437,9 +436,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio return args.format('ry({0:half_turns}) {1};\n', self._exponent, qubits[0]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1 and self.global_shift != -0.5: return formatter.format('Y {0}\n', qubits[0]) return formatter.format('RY({0}) {1}\n', self._exponent * np.pi, qubits[0]) @@ -731,9 +728,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio return args.format('tdg {0};\n', qubits[0]) return args.format('rz({0:half_turns}) {1};\n', self._exponent, qubits[0]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1 and self.global_shift != -0.5: return formatter.format('Z {0}\n', qubits[0]) return formatter.format('RZ({0}) {1}\n', self._exponent * np.pi, qubits[0]) @@ -945,9 +940,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio qubits[0], ) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1: return formatter.format('H {0}\n', qubits[0]) return formatter.format( @@ -1111,9 +1104,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio args.validate_version('2.0') return args.format('cz {0},{1};\n', qubits[0], qubits[1]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1: return formatter.format('CZ {0} {1}\n', qubits[0], qubits[1]) return formatter.format( @@ -1295,9 +1286,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio args.validate_version('2.0') return args.format('cx {0},{1};\n', qubits[0], qubits[1]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1: return formatter.format('CNOT {0} {1}\n', qubits[0], qubits[1]) return None diff --git a/cirq-core/cirq/ops/gate_operation.py b/cirq-core/cirq/ops/gate_operation.py index 268d0498680..0190c06a60a 100644 --- a/cirq-core/cirq/ops/gate_operation.py +++ b/cirq-core/cirq/ops/gate_operation.py @@ -337,9 +337,6 @@ def __rmul__(self, other: Any) -> Any: def _qasm_(self, args: 'protocols.QasmArgs') -> Optional[str]: return protocols.qasm(self.gate, args=args, qubits=self.qubits, default=None) - def _quil_(self, formatter: 'protocols.QuilFormatter') -> Optional[str]: - return protocols.quil(self.gate, qubits=self.qubits, formatter=formatter) - def _equal_up_to_global_phase_( self, other: Any, atol: Union[int, float] = 1e-8 ) -> Union[NotImplementedType, bool]: diff --git a/cirq-core/cirq/ops/gate_operation_test.py b/cirq-core/cirq/ops/gate_operation_test.py index 19a8e427655..f2f888c8902 100644 --- a/cirq-core/cirq/ops/gate_operation_test.py +++ b/cirq-core/cirq/ops/gate_operation_test.py @@ -496,8 +496,6 @@ def all_subclasses(cls): cirq.transformers.analytical_decompositions.two_qubit_to_fsim._BGate, cirq.ops.raw_types._InverseCompositeGate, cirq.circuits.qasm_output.QasmTwoQubitGate, - cirq.circuits.quil_output.QuilTwoQubitGate, - cirq.circuits.quil_output.QuilOneQubitGate, cirq.ops.MSGate, # Interop gates cirq.interop.quirk.QuirkQubitPermutationGate, diff --git a/cirq-core/cirq/ops/identity.py b/cirq-core/cirq/ops/identity.py index dfd3fded96e..dc518226fe5 100644 --- a/cirq-core/cirq/ops/identity.py +++ b/cirq-core/cirq/ops/identity.py @@ -14,6 +14,7 @@ """IdentityGate.""" from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING, Sequence +import string import numpy as np import sympy @@ -134,9 +135,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio args.validate_version('2.0') return ''.join([args.format('id {0};\n', qubit) for qubit in qubits]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: return ''.join(formatter.format('I {0}\n', qubit) for qubit in qubits) @classmethod diff --git a/cirq-core/cirq/ops/measurement_gate.py b/cirq-core/cirq/ops/measurement_gate.py index 539aa673efa..3a476529f7b 100644 --- a/cirq-core/cirq/ops/measurement_gate.py +++ b/cirq-core/cirq/ops/measurement_gate.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import string from typing import ( Any, Dict, @@ -240,9 +241,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio lines.append(args.format('x {0}; // Undo the inversion\n', qubit)) return ''.join(lines) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self.confusion_map or not all(d == 2 for d in self._qid_shape): return NotImplemented invert_mask = self.invert_mask diff --git a/cirq-core/cirq/ops/measurement_gate_test.py b/cirq-core/cirq/ops/measurement_gate_test.py index 22d9239f724..deb21d3ef76 100644 --- a/cirq-core/cirq/ops/measurement_gate_test.py +++ b/cirq-core/cirq/ops/measurement_gate_test.py @@ -159,19 +159,6 @@ def test_qudit_measure_qasm(): ) -def test_qudit_measure_quil(): - q0 = cirq.LineQid(0, 3) - qubit_id_map = {q0: '0'} - with cirq.testing.assert_deprecated(deadline='v1.0', count=3): - assert ( - cirq.quil( - cirq.measure(q0, key='a'), - formatter=cirq.QuilFormatter(qubit_id_map=qubit_id_map, measurement_id_map={}), - ) - is None - ) - - def test_confused_measure_qasm(): q0 = cirq.LineQubit(0) assert ( @@ -184,19 +171,6 @@ def test_confused_measure_qasm(): ) -def test_confused_measure_quil(): - q0 = cirq.LineQubit(0) - qubit_id_map = {q0: '0'} - with cirq.testing.assert_deprecated(deadline='v1.0', count=3): - assert ( - cirq.quil( - cirq.measure(q0, key='a', confusion_map={(0,): np.array([[0, 1], [1, 0]])}), - formatter=cirq.QuilFormatter(qubit_id_map=qubit_id_map, measurement_id_map={}), - ) - is None - ) - - def test_measurement_gate_diagram(): # Shows key. assert cirq.circuit_diagram_info( diff --git a/cirq-core/cirq/ops/parity_gates.py b/cirq-core/cirq/ops/parity_gates.py index 9d49ecd96d2..eea442c8682 100644 --- a/cirq-core/cirq/ops/parity_gates.py +++ b/cirq-core/cirq/ops/parity_gates.py @@ -14,6 +14,8 @@ """Quantum gates that phase with respect to product-of-pauli observables.""" + +import string from typing import Any, Dict, List, Optional, Tuple, Union, TYPE_CHECKING import numpy as np @@ -116,9 +118,7 @@ def _circuit_diagram_info_( wire_symbols=('XX', 'XX'), exponent=self._diagram_exponent(args) ) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1: return formatter.format('X {0}\nX {1}\n', qubits[0], qubits[1]) return formatter.format( @@ -233,9 +233,7 @@ def _circuit_diagram_info_( wire_symbols=('YY', 'YY'), exponent=self._diagram_exponent(args) ) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1: return formatter.format('Y {0}\nY {1}\n', qubits[0], qubits[1]) @@ -322,9 +320,7 @@ def _apply_unitary_(self, args: 'protocols.ApplyUnitaryArgs') -> Optional[np.nda return args.target_tensor - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent == 1: return formatter.format('Z {0}\nZ {1}\n', qubits[0], qubits[1]) diff --git a/cirq-core/cirq/ops/swap_gates.py b/cirq-core/cirq/ops/swap_gates.py index f0aedfdba36..300bab37deb 100644 --- a/cirq-core/cirq/ops/swap_gates.py +++ b/cirq-core/cirq/ops/swap_gates.py @@ -26,6 +26,7 @@ """ from typing import Optional, Tuple, TYPE_CHECKING, List +import string import numpy as np import sympy @@ -151,9 +152,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio args.validate_version('2.0') return args.format('swap {0},{1};\n', qubits[0], qubits[1]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent % 2 == 1: return formatter.format('SWAP {0} {1}\n', qubits[0], qubits[1]) return formatter.format( @@ -299,7 +298,7 @@ def __repr__(self) -> str: return f'(cirq.ISWAP**{e})' return f'cirq.ISwapPowGate(exponent={e}, global_shift={self._global_shift!r})' - def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter') -> str: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> str: if self._exponent == 1: return formatter.format('ISWAP {0} {1}\n', qubits[0], qubits[1]) return formatter.format('XY({0}) {1} {2}\n', self._exponent * np.pi, qubits[0], qubits[1]) diff --git a/cirq-core/cirq/ops/three_qubit_gates.py b/cirq-core/cirq/ops/three_qubit_gates.py index 7a59d3f7dc0..a9556a5c5fe 100644 --- a/cirq-core/cirq/ops/three_qubit_gates.py +++ b/cirq-core/cirq/ops/three_qubit_gates.py @@ -26,6 +26,7 @@ TYPE_CHECKING, Union, ) +import string import numpy as np import sympy @@ -171,9 +172,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio ] return ''.join(lines) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent != 1: return None lines = [ @@ -495,9 +494,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio args.validate_version('2.0') return args.format('ccx {0},{1},{2};\n', qubits[0], qubits[1], qubits[2]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if self._exponent != 1: return None return formatter.format('CCNOT {0} {1} {2}\n', qubits[0], qubits[1], qubits[2]) @@ -677,9 +674,7 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio args.validate_version('2.0') return args.format('cswap {0},{1},{2};\n', qubits[0], qubits[1], qubits[2]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: return formatter.format('CSWAP {0} {1} {2}\n', qubits[0], qubits[1], qubits[2]) def _value_equality_values_(self): diff --git a/cirq-core/cirq/ops/two_qubit_diagonal_gate.py b/cirq-core/cirq/ops/two_qubit_diagonal_gate.py index 2b96e5a6d2c..8cc41f8f435 100644 --- a/cirq-core/cirq/ops/two_qubit_diagonal_gate.py +++ b/cirq-core/cirq/ops/two_qubit_diagonal_gate.py @@ -17,6 +17,7 @@ passed as a list. """ +import string from typing import AbstractSet, Any, Dict, Tuple, Optional, Sequence, TYPE_CHECKING import numpy as np import sympy @@ -141,9 +142,7 @@ def __repr__(self) -> str: def _json_dict_(self) -> Dict[str, Any]: return protocols.obj_to_dict_helper(self, attribute_names=["diag_angles_radians"]) - def _quil_( - self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter' - ) -> Optional[str]: + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter) -> Optional[str]: if np.count_nonzero(self._diag_angles_radians) == 1: if self._diag_angles_radians[0] != 0: return formatter.format( diff --git a/cirq-core/cirq/ops/wait_gate.py b/cirq-core/cirq/ops/wait_gate.py index d5afe5db6c7..2b3fd30955e 100644 --- a/cirq-core/cirq/ops/wait_gate.py +++ b/cirq-core/cirq/ops/wait_gate.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from typing import AbstractSet, Any, Dict, Optional, Tuple, TYPE_CHECKING, Union +import string import sympy @@ -132,7 +133,7 @@ def _from_json_dict_(cls, duration, num_qubits=None, qid_shape=None, **kwargs): def _value_equality_values_(self) -> Any: return self.duration - def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: 'cirq.QuilFormatter'): + def _quil_(self, qubits: Tuple['cirq.Qid', ...], formatter: string.Formatter): return 'WAIT\n' diff --git a/cirq-core/cirq/protocols/__init__.py b/cirq-core/cirq/protocols/__init__.py index ba3cd92fafc..8e977a2432e 100644 --- a/cirq-core/cirq/protocols/__init__.py +++ b/cirq-core/cirq/protocols/__init__.py @@ -103,7 +103,6 @@ SupportsQasmWithArgs, SupportsQasmWithArgsAndQubits, ) -from cirq.protocols.quil import quil, QuilFormatter from cirq.protocols.trace_distance_bound import ( SupportsTraceDistanceBound, trace_distance_bound, diff --git a/cirq-core/cirq/protocols/json_test_data/spec.py b/cirq-core/cirq/protocols/json_test_data/spec.py index b2d97c3fffd..e29d5c3d40a 100644 --- a/cirq-core/cirq/protocols/json_test_data/spec.py +++ b/cirq-core/cirq/protocols/json_test_data/spec.py @@ -53,8 +53,6 @@ 'QasmOutput', 'QuantumState', 'QubitOrder', - 'QuilFormatter', - 'QuilOutput', 'SimulationTrialResult', 'SimulationTrialResultBase', 'SparseSimulatorStep', diff --git a/cirq-core/cirq/protocols/quil.py b/cirq-core/cirq/protocols/quil.py deleted file mode 100644 index 5990a7d5bbc..00000000000 --- a/cirq-core/cirq/protocols/quil.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2020 The Cirq Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import string -from typing import Any, Optional, Dict, Iterable -import cirq - - -@cirq._compat.deprecated_class( - deadline='v1.0', fix='Use cirq_rigetti.quil_output.QuilFormatter instead.' -) -class QuilFormatter(string.Formatter): - """A unique formatter to correctly output values to QUIL.""" - - def __init__( - self, qubit_id_map: Dict['cirq.Qid', str], measurement_id_map: Dict[str, str] - ) -> None: - """Inits QuilFormatter. - - Args: - qubit_id_map: A dictionary {qubit, quil_output_string} for - the proper QUIL output for each qubit. - measurement_id_map: A dictionary {measurement_key, - quil_output_string} for the proper QUIL output for each - measurement key. - """ - self.qubit_id_map = {} if qubit_id_map is None else qubit_id_map - self.measurement_id_map = {} if measurement_id_map is None else measurement_id_map - - def format_field(self, value: Any, spec: str) -> str: - if isinstance(value, cirq.ops.Qid): - value = self.qubit_id_map[value] - if isinstance(value, str) and spec == 'meas': - value = self.measurement_id_map[value] - spec = '' - return super().format_field(value, spec) - - -@cirq._compat.deprecated(deadline="v1.0", fix="Use cirq_rigetti.quil_ouput.QuilOutput instead.") -def quil( - val: Any, - *, - qubits: Optional[Iterable['cirq.Qid']] = None, - formatter: Optional[QuilFormatter] = None, -): - """Returns the QUIL code for the given value. - - Args: - val: The value to turn into QUIL code. - qubits: A list of qubits that the value is being applied to. This is - needed for `cirq.Gate` values, which otherwise wouldn't know what - qubits to talk about. - formatter: A `QuilFormatter` object for properly ouputting the `_quil_` - method in a QUIL format. - - Returns: - The result of `val._quil_(...) if `val` has a `_quil_` method. - Otherwise, returns `None`. (`None` normally indicates that the - `_decompose_` function should be called on `val`) - """ - method = getattr(val, '_quil_', None) - result = NotImplemented - if method is not None: - kwargs: Dict[str, Any] = {} - if qubits is not None: - kwargs['qubits'] = tuple(qubits) - if formatter is not None: - kwargs['formatter'] = formatter - result = method(**kwargs) - if result is not None and result is not NotImplemented: - return result - - return None diff --git a/docs/start/intro.ipynb b/docs/start/intro.ipynb index eb38976410c..f48a42ce8c1 100644 --- a/docs/start/intro.ipynb +++ b/docs/start/intro.ipynb @@ -2880,19 +2880,8 @@ "id": "35b3a411ffae" }, "source": [ - "You can also export a circuit as QUIL:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "951a57e8e0fd" - }, - "outputs": [], - "source": [ - "\"\"\"Export a circuit to QUIL.\"\"\"\n", - "print(circuit.to_quil())" + "You can also export a circuit as QUIL.\n", + "For that functionality, install the cirq-rigetti package." ] }, {