1# Copyright 2018 The Cirq Developers 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15from typing import Any, Dict, Sequence, Tuple, TypeVar, TYPE_CHECKING 16 17import abc 18 19from cirq import protocols 20from cirq.ops import pauli_string as ps, raw_types 21 22if TYPE_CHECKING: 23 import cirq 24 25TSelf_PauliStringGateOperation = TypeVar( 26 'TSelf_PauliStringGateOperation', bound='PauliStringGateOperation' 27) 28 29 30class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta): 31 def __init__(self, pauli_string: ps.PauliString) -> None: 32 self.pauli_string = pauli_string 33 34 def validate_args(self, qubits: Sequence[raw_types.Qid]) -> None: 35 if len(qubits) != len(self.pauli_string): 36 raise ValueError('Incorrect number of qubits for gate') 37 38 def with_qubits( 39 self: TSelf_PauliStringGateOperation, *new_qubits: 'cirq.Qid' 40 ) -> TSelf_PauliStringGateOperation: 41 self.validate_args(new_qubits) 42 return self.map_qubits(dict(zip(self.pauli_string.qubits, new_qubits))) 43 44 @abc.abstractmethod 45 def map_qubits( 46 self: TSelf_PauliStringGateOperation, qubit_map: Dict[raw_types.Qid, raw_types.Qid] 47 ) -> TSelf_PauliStringGateOperation: 48 """Return an equivalent operation on new qubits with its Pauli string 49 mapped to new qubits. 50 51 new_pauli_string = self.pauli_string.map_qubits(qubit_map) 52 """ 53 54 @property 55 def qubits(self) -> Tuple[raw_types.Qid, ...]: 56 return tuple(self.pauli_string) 57 58 def _pauli_string_diagram_info( 59 self, 60 args: 'protocols.CircuitDiagramInfoArgs', 61 exponent: Any = 1, 62 ) -> 'cirq.CircuitDiagramInfo': 63 qubits = self.qubits if args.known_qubits is None else args.known_qubits 64 syms = tuple(f'[{self.pauli_string[qubit]}]' for qubit in qubits) 65 return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=exponent) 66