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 15"""Marker classes for indicating which additional features gates support. 16 17For example: some gates are reversible, some have known matrices, etc. 18""" 19 20import abc 21import warnings 22 23from cirq import value, ops 24from cirq._compat import deprecated_class 25from cirq.ops import raw_types 26 27 28class InterchangeableQubitsGate(metaclass=abc.ABCMeta): 29 """Indicates operations should be equal under some qubit permutations.""" 30 31 def qubit_index_to_equivalence_group_key(self, index: int) -> int: 32 """Returns a key that differs between non-interchangeable qubits.""" 33 return 0 34 35 36class _SupportsOnEachGateMeta(value.ABCMetaImplementAnyOneOf): 37 def __instancecheck__(cls, instance): 38 return isinstance(instance, (SingleQubitGate, ops.DepolarizingChannel)) or issubclass( 39 type(instance), SupportsOnEachGate 40 ) 41 42 43@deprecated_class( 44 deadline='v0.14', 45 fix='Remove `SupportsOnEachGate` from the list of parent classes. ' 46 '`on_each` is now directly supported in the `Gate` base class.', 47) 48class SupportsOnEachGate(raw_types.Gate, metaclass=_SupportsOnEachGateMeta): 49 pass 50 51 52class SingleQubitGate(raw_types.Gate, metaclass=abc.ABCMeta): 53 """A gate that must be applied to exactly one qubit.""" 54 55 def _num_qubits_(self) -> int: 56 return 1 57 58 59class _TwoQubitGateMeta(value.ABCMetaImplementAnyOneOf): 60 def __instancecheck__(cls, instance): 61 warnings.warn( 62 'isinstance(gate, TwoQubitGate) is deprecated. Use cirq.num_qubits(gate) == 2 instead', 63 DeprecationWarning, 64 ) 65 return isinstance(instance, raw_types.Gate) and instance._num_qubits_() == 2 66 67 68@deprecated_class(deadline='v0.14', fix='Define _num_qubits_ manually.') 69class TwoQubitGate(raw_types.Gate, metaclass=_TwoQubitGateMeta): 70 """A gate that must be applied to exactly two qubits.""" 71 72 def _num_qubits_(self) -> int: 73 return 2 74 75 76class _ThreeQubitGateMeta(value.ABCMetaImplementAnyOneOf): 77 def __instancecheck__(cls, instance): 78 warnings.warn( 79 'isinstance(gate, TwoQubitGate) is deprecated. Use cirq.num_qubits(gate) == 3 instead', 80 DeprecationWarning, 81 ) 82 return isinstance(instance, raw_types.Gate) and instance._num_qubits_() == 3 83 84 85@deprecated_class(deadline='v0.14', fix='Define _num_qubits_ manually.') 86class ThreeQubitGate(raw_types.Gate, metaclass=_ThreeQubitGateMeta): 87 """A gate that must be applied to exactly three qubits.""" 88 89 def _num_qubits_(self) -> int: 90 return 3 91