qiskit 2.0.2__cp39-abi3-macosx_11_0_arm64.whl → 2.1.0rc1__cp39-abi3-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +19 -1
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +13 -21
- qiskit/circuit/_add_control.py +57 -31
- qiskit/circuit/_classical_resource_map.py +4 -0
- qiskit/circuit/annotation.py +404 -0
- qiskit/circuit/classical/expr/__init__.py +1 -1
- qiskit/circuit/classical/expr/expr.py +104 -446
- qiskit/circuit/classical/expr/visitors.py +6 -0
- qiskit/circuit/classical/types/types.py +7 -130
- qiskit/circuit/controlflow/box.py +32 -7
- qiskit/circuit/delay.py +11 -9
- qiskit/circuit/library/arithmetic/adders/adder.py +5 -5
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -3
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +7 -3
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
- qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
- qiskit/circuit/library/basis_change/qft.py +2 -2
- qiskit/circuit/library/blueprintcircuit.py +6 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
- qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
- qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
- qiskit/circuit/library/fourier_checking.py +2 -2
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
- qiskit/circuit/library/generalized_gates/gms.py +5 -1
- qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +5 -1
- qiskit/circuit/library/generalized_gates/uc.py +1 -1
- qiskit/circuit/library/generalized_gates/unitary.py +21 -2
- qiskit/circuit/library/graph_state.py +2 -2
- qiskit/circuit/library/grover_operator.py +2 -2
- qiskit/circuit/library/hidden_linear_function.py +2 -2
- qiskit/circuit/library/iqp.py +2 -2
- qiskit/circuit/library/n_local/efficient_su2.py +2 -2
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
- qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
- qiskit/circuit/library/n_local/n_local.py +4 -3
- qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
- qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
- qiskit/circuit/library/n_local/two_local.py +2 -2
- qiskit/circuit/library/overlap.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +3 -2
- qiskit/circuit/library/phase_estimation.py +2 -2
- qiskit/circuit/library/standard_gates/dcx.py +11 -12
- qiskit/circuit/library/standard_gates/ecr.py +21 -24
- qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
- qiskit/circuit/library/standard_gates/global_phase.py +5 -6
- qiskit/circuit/library/standard_gates/h.py +22 -45
- qiskit/circuit/library/standard_gates/i.py +1 -1
- qiskit/circuit/library/standard_gates/iswap.py +13 -31
- qiskit/circuit/library/standard_gates/p.py +19 -26
- qiskit/circuit/library/standard_gates/r.py +11 -17
- qiskit/circuit/library/standard_gates/rx.py +21 -45
- qiskit/circuit/library/standard_gates/rxx.py +7 -22
- qiskit/circuit/library/standard_gates/ry.py +21 -39
- qiskit/circuit/library/standard_gates/ryy.py +13 -28
- qiskit/circuit/library/standard_gates/rz.py +18 -35
- qiskit/circuit/library/standard_gates/rzx.py +7 -22
- qiskit/circuit/library/standard_gates/rzz.py +7 -19
- qiskit/circuit/library/standard_gates/s.py +44 -39
- qiskit/circuit/library/standard_gates/swap.py +25 -38
- qiskit/circuit/library/standard_gates/sx.py +34 -41
- qiskit/circuit/library/standard_gates/t.py +18 -27
- qiskit/circuit/library/standard_gates/u.py +8 -24
- qiskit/circuit/library/standard_gates/u1.py +28 -52
- qiskit/circuit/library/standard_gates/u2.py +9 -9
- qiskit/circuit/library/standard_gates/u3.py +24 -40
- qiskit/circuit/library/standard_gates/x.py +190 -336
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
- qiskit/circuit/library/standard_gates/y.py +19 -23
- qiskit/circuit/library/standard_gates/z.py +31 -38
- qiskit/circuit/parameter.py +14 -5
- qiskit/circuit/parameterexpression.py +109 -75
- qiskit/circuit/quantumcircuit.py +168 -98
- qiskit/circuit/quantumcircuitdata.py +1 -0
- qiskit/circuit/random/__init__.py +37 -2
- qiskit/circuit/random/utils.py +445 -56
- qiskit/circuit/tools/pi_check.py +5 -13
- qiskit/compiler/transpiler.py +1 -1
- qiskit/converters/circuit_to_instruction.py +2 -2
- qiskit/dagcircuit/dagnode.py +8 -3
- qiskit/primitives/__init__.py +2 -2
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +0 -3
- qiskit/primitives/containers/observables_array.py +192 -108
- qiskit/primitives/primitive_job.py +29 -10
- qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
- qiskit/qasm3/__init__.py +106 -12
- qiskit/qasm3/ast.py +15 -1
- qiskit/qasm3/exporter.py +59 -36
- qiskit/qasm3/printer.py +12 -0
- qiskit/qpy/__init__.py +183 -7
- qiskit/qpy/binary_io/circuits.py +256 -24
- qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
- qiskit/qpy/binary_io/schedules.py +12 -32
- qiskit/qpy/binary_io/value.py +36 -18
- qiskit/qpy/common.py +11 -3
- qiskit/qpy/formats.py +17 -1
- qiskit/qpy/interface.py +52 -12
- qiskit/qpy/type_keys.py +7 -1
- qiskit/quantum_info/__init__.py +10 -0
- qiskit/quantum_info/operators/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1 -1
- qiskit/result/sampled_expval.py +3 -1
- qiskit/synthesis/__init__.py +10 -0
- qiskit/synthesis/arithmetic/__init__.py +1 -1
- qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
- qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
- qiskit/synthesis/evolution/lie_trotter.py +10 -7
- qiskit/synthesis/evolution/product_formula.py +10 -7
- qiskit/synthesis/evolution/qdrift.py +10 -7
- qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
- qiskit/synthesis/multi_controlled/__init__.py +4 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
- qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
- qiskit/synthesis/unitary/qsd.py +80 -9
- qiskit/transpiler/__init__.py +19 -8
- qiskit/transpiler/instruction_durations.py +2 -20
- qiskit/transpiler/passes/__init__.py +4 -2
- qiskit/transpiler/passes/layout/dense_layout.py +26 -6
- qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
- qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
- qiskit/transpiler/passes/layout/vf2_utils.py +13 -1
- qiskit/transpiler/passes/optimization/__init__.py +1 -1
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
- qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
- qiskit/transpiler/passes/routing/sabre_swap.py +12 -2
- qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
- qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
- qiskit/transpiler/passes/synthesis/__init__.py +1 -0
- qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +472 -92
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
- qiskit/transpiler/passmanager_config.py +3 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
- qiskit/transpiler/preset_passmanagers/common.py +101 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
- qiskit/transpiler/preset_passmanagers/level3.py +2 -2
- qiskit/utils/optionals.py +6 -5
- qiskit/visualization/circuit/_utils.py +5 -3
- qiskit/visualization/circuit/latex.py +9 -2
- qiskit/visualization/circuit/matplotlib.py +26 -4
- qiskit/visualization/circuit/qcstyle.py +9 -157
- qiskit/visualization/dag/__init__.py +13 -0
- qiskit/visualization/dag/dagstyle.py +103 -0
- qiskit/visualization/dag/styles/__init__.py +13 -0
- qiskit/visualization/dag/styles/color.json +10 -0
- qiskit/visualization/dag/styles/plain.json +5 -0
- qiskit/visualization/dag_visualization.py +169 -98
- qiskit/visualization/style.py +223 -0
- {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/METADATA +14 -13
- {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/RECORD +177 -168
- {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/entry_points.txt +6 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
- qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
- {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/WHEEL +0 -0
- {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/licenses/LICENSE.txt +0 -0
- {qiskit-2.0.2.dist-info → qiskit-2.1.0rc1.dist-info}/top_level.txt +0 -0
@@ -12,12 +12,6 @@
|
|
12
12
|
|
13
13
|
"""Expression-tree nodes."""
|
14
14
|
|
15
|
-
# Given the nature of the tree representation and that there are helper functions associated with
|
16
|
-
# many of the classes whose arguments naturally share names with themselves, it's inconvenient to
|
17
|
-
# use synonyms everywhere. This goes for the builtin 'type' as well.
|
18
|
-
# pylint: disable=redefined-builtin,redefined-outer-name
|
19
|
-
|
20
|
-
from __future__ import annotations
|
21
15
|
|
22
16
|
__all__ = [
|
23
17
|
"Expr",
|
@@ -30,469 +24,133 @@ __all__ = [
|
|
30
24
|
"Index",
|
31
25
|
]
|
32
26
|
|
33
|
-
import abc
|
34
27
|
import enum
|
35
|
-
import typing
|
36
|
-
import uuid
|
37
|
-
|
38
|
-
from .. import types
|
39
|
-
|
40
|
-
if typing.TYPE_CHECKING:
|
41
|
-
import qiskit
|
42
|
-
|
43
|
-
|
44
|
-
_T_co = typing.TypeVar("_T_co", covariant=True)
|
45
|
-
|
46
|
-
|
47
|
-
# If adding nodes, remember to update `visitors.ExprVisitor` as well.
|
48
|
-
|
49
|
-
|
50
|
-
class Expr(abc.ABC):
|
51
|
-
"""Root base class of all nodes in the expression tree. The base case should never be
|
52
|
-
instantiated directly.
|
53
|
-
|
54
|
-
This must not be subclassed by users; subclasses form the internal data of the representation of
|
55
|
-
expressions, and it does not make sense to add more outside of Qiskit library code.
|
56
|
-
|
57
|
-
All subclasses are responsible for setting their ``type`` attribute in their ``__init__``, and
|
58
|
-
should not call the parent initializer."""
|
59
|
-
|
60
|
-
__slots__ = ("type", "const")
|
61
28
|
|
62
|
-
|
63
|
-
|
29
|
+
from qiskit._accelerate.circuit.classical.expr import (
|
30
|
+
Expr,
|
31
|
+
Var,
|
32
|
+
Stretch,
|
33
|
+
Value,
|
34
|
+
Cast,
|
35
|
+
Unary,
|
36
|
+
Binary,
|
37
|
+
Index,
|
38
|
+
) # pylint: disable=unused-import
|
64
39
|
|
65
|
-
# Sentinel to prevent instantiation of the base class.
|
66
|
-
@abc.abstractmethod
|
67
|
-
def __init__(self): # pragma: no cover
|
68
|
-
pass
|
69
|
-
|
70
|
-
def accept(
|
71
|
-
self, visitor: qiskit.circuit.classical.expr.ExprVisitor[_T_co], /
|
72
|
-
) -> _T_co: # pragma: no cover
|
73
|
-
"""Call the relevant ``visit_*`` method on the given :class:`ExprVisitor`. The usual entry
|
74
|
-
point for a simple visitor is to construct it, and then call :meth:`accept` on the root
|
75
|
-
object to be visited. For example::
|
76
|
-
|
77
|
-
expr = ...
|
78
|
-
visitor = MyVisitor()
|
79
|
-
visitor.accept(expr)
|
80
|
-
|
81
|
-
Subclasses of :class:`Expr` should override this to call the correct virtual method on the
|
82
|
-
visitor. This implements double dispatch with the visitor."""
|
83
|
-
return visitor.visit_generic(self)
|
84
|
-
|
85
|
-
|
86
|
-
@typing.final
|
87
|
-
class Cast(Expr):
|
88
|
-
"""A cast from one type to another, implied by the use of an expression in a different
|
89
|
-
context."""
|
90
|
-
|
91
|
-
__slots__ = ("operand", "implicit")
|
92
|
-
|
93
|
-
def __init__(self, operand: Expr, type: types.Type, implicit: bool = False):
|
94
|
-
self.type = type
|
95
|
-
self.const = operand.const
|
96
|
-
self.operand = operand
|
97
|
-
self.implicit = implicit
|
98
|
-
|
99
|
-
def accept(self, visitor, /):
|
100
|
-
return visitor.visit_cast(self)
|
101
|
-
|
102
|
-
def __eq__(self, other):
|
103
|
-
return (
|
104
|
-
isinstance(other, Cast)
|
105
|
-
and self.type == other.type
|
106
|
-
and self.const == other.const
|
107
|
-
and self.operand == other.operand
|
108
|
-
and self.implicit == other.implicit
|
109
|
-
)
|
110
|
-
|
111
|
-
def __repr__(self):
|
112
|
-
return f"Cast({self.operand}, {self.type}, implicit={self.implicit})"
|
113
40
|
|
41
|
+
class _UnaryOp(enum.Enum):
|
42
|
+
"""Enumeration of the opcodes for unary operations.
|
114
43
|
|
115
|
-
|
116
|
-
|
117
|
-
"""A classical variable.
|
44
|
+
The bitwise negation :data:`BIT_NOT` takes a single bit or an unsigned integer of known
|
45
|
+
width, and returns a value of the same type.
|
118
46
|
|
119
|
-
|
120
|
-
|
121
|
-
:class:`.ClassicalRegister` instance that is owned by some containing circuit. In general,
|
122
|
-
construction of variables for use in programs should use :meth:`Var.new` or
|
123
|
-
:meth:`.QuantumCircuit.add_var`.
|
124
|
-
|
125
|
-
Variables are immutable after construction, so they can be used as dictionary keys."""
|
126
|
-
|
127
|
-
__slots__ = ("var", "name")
|
128
|
-
|
129
|
-
var: qiskit.circuit.Clbit | qiskit.circuit.ClassicalRegister | uuid.UUID
|
130
|
-
"""A reference to the backing data storage of the :class:`Var` instance. When lifting
|
131
|
-
old-style :class:`.Clbit` or :class:`.ClassicalRegister` instances into a :class:`Var`,
|
132
|
-
this is exactly the :class:`.Clbit` or :class:`.ClassicalRegister`. If the variable is a
|
133
|
-
new-style classical variable (one that owns its own storage separate to the old
|
134
|
-
:class:`.Clbit`/:class:`.ClassicalRegister` model), this field will be a :class:`~uuid.UUID`
|
135
|
-
to uniquely identify it."""
|
136
|
-
name: str | None
|
137
|
-
"""The name of the variable. This is required to exist if the backing :attr:`var` attribute
|
138
|
-
is a :class:`~uuid.UUID`, i.e. if it is a new-style variable, and must be ``None`` if it is
|
139
|
-
an old-style variable."""
|
140
|
-
|
141
|
-
def __init__(
|
142
|
-
self,
|
143
|
-
var: qiskit.circuit.Clbit | qiskit.circuit.ClassicalRegister | uuid.UUID,
|
144
|
-
type: types.Type,
|
145
|
-
*,
|
146
|
-
name: str | None = None,
|
147
|
-
):
|
148
|
-
super().__setattr__("type", type)
|
149
|
-
super().__setattr__("const", False)
|
150
|
-
super().__setattr__("var", var)
|
151
|
-
super().__setattr__("name", name)
|
152
|
-
|
153
|
-
@classmethod
|
154
|
-
def new(cls, name: str, type: types.Type) -> typing.Self:
|
155
|
-
"""Generate a new named variable that owns its own backing storage."""
|
156
|
-
return cls(uuid.uuid4(), type, name=name)
|
157
|
-
|
158
|
-
@property
|
159
|
-
def standalone(self) -> bool:
|
160
|
-
"""Whether this :class:`Var` is a standalone variable that owns its storage
|
161
|
-
location, if applicable. If false, this is a wrapper :class:`Var` around a
|
162
|
-
pre-existing circuit object."""
|
163
|
-
return isinstance(self.var, uuid.UUID)
|
164
|
-
|
165
|
-
def accept(self, visitor, /):
|
166
|
-
return visitor.visit_var(self)
|
167
|
-
|
168
|
-
def __setattr__(self, key, value):
|
169
|
-
if hasattr(self, key):
|
170
|
-
raise AttributeError(f"'Var' object attribute '{key}' is read-only")
|
171
|
-
raise AttributeError(f"'Var' object has no attribute '{key}'")
|
172
|
-
|
173
|
-
def __hash__(self):
|
174
|
-
return hash((self.type, self.var, self.name))
|
175
|
-
|
176
|
-
def __eq__(self, other):
|
177
|
-
return (
|
178
|
-
isinstance(other, Var)
|
179
|
-
and self.type == other.type
|
180
|
-
and self.var == other.var
|
181
|
-
and self.name == other.name
|
182
|
-
)
|
183
|
-
|
184
|
-
def __repr__(self):
|
185
|
-
if self.name is None:
|
186
|
-
return f"Var({self.var}, {self.type})"
|
187
|
-
return f"Var({self.var}, {self.type}, name='{self.name}')"
|
188
|
-
|
189
|
-
def __getstate__(self):
|
190
|
-
return (self.var, self.type, self.name)
|
191
|
-
|
192
|
-
def __setstate__(self, state):
|
193
|
-
var, type, name = state
|
194
|
-
super().__setattr__("type", type)
|
195
|
-
super().__setattr__("const", False)
|
196
|
-
super().__setattr__("var", var)
|
197
|
-
super().__setattr__("name", name)
|
198
|
-
|
199
|
-
def __copy__(self):
|
200
|
-
# I am immutable...
|
201
|
-
return self
|
202
|
-
|
203
|
-
def __deepcopy__(self, memo):
|
204
|
-
# ... as are all my constituent parts.
|
205
|
-
return self
|
206
|
-
|
207
|
-
|
208
|
-
@typing.final
|
209
|
-
class Stretch(Expr):
|
210
|
-
"""A stretch variable.
|
211
|
-
|
212
|
-
In general, construction of stretch variables for use in programs should use :meth:`Stretch.new`
|
213
|
-
or :meth:`.QuantumCircuit.add_stretch`.
|
47
|
+
The logical negation :data:`LOGIC_NOT` takes an input that is implicitly coerced to a
|
48
|
+
Boolean, and returns a Boolean.
|
214
49
|
"""
|
215
50
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
"""
|
223
|
-
|
224
|
-
"""
|
225
|
-
|
226
|
-
def __init__(
|
227
|
-
self,
|
228
|
-
var: uuid.UUID,
|
229
|
-
name: str,
|
230
|
-
):
|
231
|
-
super().__setattr__("type", types.Duration())
|
232
|
-
super().__setattr__("const", True)
|
233
|
-
super().__setattr__("var", var)
|
234
|
-
super().__setattr__("name", name)
|
235
|
-
|
236
|
-
@classmethod
|
237
|
-
def new(cls, name: str) -> typing.Self:
|
238
|
-
"""Generate a new named stretch variable."""
|
239
|
-
return cls(uuid.uuid4(), name)
|
51
|
+
# If adding opcodes, remember to add helper constructor functions in `constructors.py`.
|
52
|
+
# The opcode integers should be considered a public interface; they are used by
|
53
|
+
# serialization formats that may transfer data between different versions of Qiskit.
|
54
|
+
#
|
55
|
+
# !!! YOU MUST ALSO UPDATE the underlying Rust enum if you touch this.
|
56
|
+
BIT_NOT = 1
|
57
|
+
"""Bitwise negation. ``~operand``."""
|
58
|
+
LOGIC_NOT = 2
|
59
|
+
"""Logical negation. ``!operand``."""
|
240
60
|
|
241
|
-
def
|
242
|
-
return
|
243
|
-
|
244
|
-
def __setattr__(self, key, value):
|
245
|
-
if hasattr(self, key):
|
246
|
-
raise AttributeError(f"'Stretch' object attribute '{key}' is read-only")
|
247
|
-
raise AttributeError(f"'Stretch' object has no attribute '{key}'")
|
248
|
-
|
249
|
-
def __hash__(self):
|
250
|
-
return hash((self.var, self.name))
|
251
|
-
|
252
|
-
def __eq__(self, other):
|
253
|
-
return isinstance(other, Stretch) and self.var == other.var and self.name == other.name
|
61
|
+
def __str__(self):
|
62
|
+
return f"Unary.{super().__str__()}"
|
254
63
|
|
255
64
|
def __repr__(self):
|
256
|
-
return f"
|
257
|
-
|
258
|
-
def __getstate__(self):
|
259
|
-
return (self.var, self.name)
|
260
|
-
|
261
|
-
def __setstate__(self, state):
|
262
|
-
var, name = state
|
263
|
-
super().__setattr__("type", types.Duration())
|
264
|
-
super().__setattr__("const", True)
|
265
|
-
super().__setattr__("var", var)
|
266
|
-
super().__setattr__("name", name)
|
267
|
-
|
268
|
-
def __copy__(self):
|
269
|
-
# I am immutable...
|
270
|
-
return self
|
65
|
+
return f"Unary.{super().__repr__()}"
|
271
66
|
|
272
|
-
def __deepcopy__(self, memo):
|
273
|
-
# ... as are all my constituent parts.
|
274
|
-
return self
|
275
67
|
|
68
|
+
# Setting these tricks Sphinx into thinking that this enum is actually
|
69
|
+
# defined as an inner class of the Rust pyclass.
|
70
|
+
_UnaryOp.__module__ = "qiskit._accelerate.circuit.classical.expr"
|
71
|
+
_UnaryOp.__name__ = "Op"
|
72
|
+
_UnaryOp.__qualname__ = "Unary.Op"
|
276
73
|
|
277
|
-
@typing.final
|
278
|
-
class Value(Expr):
|
279
|
-
"""A single scalar value."""
|
280
74
|
|
281
|
-
|
75
|
+
class _BinaryOp(enum.Enum):
|
76
|
+
"""Enumeration of the opcodes for binary operations.
|
282
77
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
self.const = True
|
78
|
+
The bitwise operations :data:`BIT_AND`, :data:`BIT_OR` and :data:`BIT_XOR` apply to two
|
79
|
+
operands of the same type, which must be a single bit or an unsigned integer of fixed width.
|
80
|
+
The resultant type is the same as the two input types.
|
287
81
|
|
288
|
-
|
289
|
-
|
82
|
+
The logical operations :data:`LOGIC_AND` and :data:`LOGIC_OR` first implicitly coerce their
|
83
|
+
arguments to Booleans, and then apply the logical operation. The resultant type is always
|
84
|
+
Boolean.
|
290
85
|
|
291
|
-
|
292
|
-
|
86
|
+
The binary mathematical relations :data:`EQUAL`, :data:`NOT_EQUAL`, :data:`LESS`,
|
87
|
+
:data:`LESS_EQUAL`, :data:`GREATER` and :data:`GREATER_EQUAL` take unsigned integers
|
88
|
+
(with an implicit cast to make them the same width), and return a Boolean.
|
293
89
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
@typing.final
|
299
|
-
class Unary(Expr):
|
300
|
-
"""A unary expression.
|
90
|
+
The bitshift operations :data:`SHIFT_LEFT` and :data:`SHIFT_RIGHT` can take bit-like
|
91
|
+
container types (e.g. unsigned integers) as the left operand, and any integer type as the
|
92
|
+
right-hand operand. In all cases, the output bit width is the same as the input, and zeros
|
93
|
+
fill in the "exposed" spaces.
|
301
94
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
95
|
+
The binary arithmetic operators :data:`ADD`, :data:`SUB:, :data:`MUL`, and :data:`DIV`
|
96
|
+
can be applied to two floats or two unsigned integers, which should be made to be of
|
97
|
+
the same width during construction via a cast.
|
98
|
+
The :data:`ADD`, :data:`SUB`, and :data:`DIV` operators can be applied on two durations
|
99
|
+
yielding another duration, or a float in the case of :data:`DIV`. The :data:`MUL` operator
|
100
|
+
can also be applied to a duration and a numeric type, yielding another duration. Finally,
|
101
|
+
the :data:`DIV` operator can be used to divide a duration by a numeric type, yielding a
|
102
|
+
duration.
|
306
103
|
"""
|
307
104
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
)
|
105
|
+
# If adding opcodes, remember to add helper constructor functions in `constructors.py`
|
106
|
+
# The opcode integers should be considered a public interface; they are used by
|
107
|
+
# serialization formats that may transfer data between different versions of Qiskit.
|
108
|
+
#
|
109
|
+
# !!! YOU MUST ALSO UPDATE the underlying Rust enum if you touch this.
|
110
|
+
BIT_AND = 1
|
111
|
+
"""Bitwise "and". ``lhs & rhs``."""
|
112
|
+
BIT_OR = 2
|
113
|
+
"""Bitwise "or". ``lhs | rhs``."""
|
114
|
+
BIT_XOR = 3
|
115
|
+
"""Bitwise "exclusive or". ``lhs ^ rhs``."""
|
116
|
+
LOGIC_AND = 4
|
117
|
+
"""Logical "and". ``lhs && rhs``."""
|
118
|
+
LOGIC_OR = 5
|
119
|
+
"""Logical "or". ``lhs || rhs``."""
|
120
|
+
EQUAL = 6
|
121
|
+
"""Numeric equality. ``lhs == rhs``."""
|
122
|
+
NOT_EQUAL = 7
|
123
|
+
"""Numeric inequality. ``lhs != rhs``."""
|
124
|
+
LESS = 8
|
125
|
+
"""Numeric less than. ``lhs < rhs``."""
|
126
|
+
LESS_EQUAL = 9
|
127
|
+
"""Numeric less than or equal to. ``lhs <= rhs``"""
|
128
|
+
GREATER = 10
|
129
|
+
"""Numeric greater than. ``lhs > rhs``."""
|
130
|
+
GREATER_EQUAL = 11
|
131
|
+
"""Numeric greater than or equal to. ``lhs >= rhs``."""
|
132
|
+
SHIFT_LEFT = 12
|
133
|
+
"""Zero-padding bitshift to the left. ``lhs << rhs``."""
|
134
|
+
SHIFT_RIGHT = 13
|
135
|
+
"""Zero-padding bitshift to the right. ``lhs >> rhs``."""
|
136
|
+
ADD = 14
|
137
|
+
"""Addition. ``lhs + rhs``."""
|
138
|
+
SUB = 15
|
139
|
+
"""Subtraction. ``lhs - rhs``."""
|
140
|
+
MUL = 16
|
141
|
+
"""Multiplication. ``lhs * rhs``."""
|
142
|
+
DIV = 17
|
143
|
+
"""Division. ``lhs / rhs``."""
|
144
|
+
|
145
|
+
def __str__(self):
|
146
|
+
return f"Binary.{super().__str__()}"
|
351
147
|
|
352
148
|
def __repr__(self):
|
353
|
-
return f"
|
354
|
-
|
355
|
-
|
356
|
-
@typing.final
|
357
|
-
class Binary(Expr):
|
358
|
-
"""A binary expression.
|
359
|
-
|
360
|
-
Args:
|
361
|
-
op: The opcode describing which operation is being done.
|
362
|
-
left: The left-hand operand.
|
363
|
-
right: The right-hand operand.
|
364
|
-
type: The resolved type of the result.
|
365
|
-
"""
|
366
|
-
|
367
|
-
__slots__ = ("op", "left", "right")
|
149
|
+
return f"Binary.{super().__repr__()}"
|
368
150
|
|
369
|
-
class Op(enum.Enum):
|
370
|
-
"""Enumeration of the opcodes for binary operations.
|
371
151
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
arguments to Booleans, and then apply the logical operation. The resultant type is always
|
378
|
-
Boolean.
|
379
|
-
|
380
|
-
The binary mathematical relations :data:`EQUAL`, :data:`NOT_EQUAL`, :data:`LESS`,
|
381
|
-
:data:`LESS_EQUAL`, :data:`GREATER` and :data:`GREATER_EQUAL` take unsigned integers
|
382
|
-
(with an implicit cast to make them the same width), and return a Boolean.
|
383
|
-
|
384
|
-
The bitshift operations :data:`SHIFT_LEFT` and :data:`SHIFT_RIGHT` can take bit-like
|
385
|
-
container types (e.g. unsigned integers) as the left operand, and any integer type as the
|
386
|
-
right-hand operand. In all cases, the output bit width is the same as the input, and zeros
|
387
|
-
fill in the "exposed" spaces.
|
388
|
-
|
389
|
-
The binary arithmetic operators :data:`ADD`, :data:`SUB:, :data:`MUL`, and :data:`DIV`
|
390
|
-
can be applied to two floats or two unsigned integers, which should be made to be of
|
391
|
-
the same width during construction via a cast.
|
392
|
-
The :data:`ADD`, :data:`SUB`, and :data:`DIV` operators can be applied on two durations
|
393
|
-
yielding another duration, or a float in the case of :data:`DIV`. The :data:`MUL` operator
|
394
|
-
can also be applied to a duration and a numeric type, yielding another duration. Finally,
|
395
|
-
the :data:`DIV` operator can be used to divide a duration by a numeric type, yielding a
|
396
|
-
duration.
|
397
|
-
"""
|
398
|
-
|
399
|
-
# If adding opcodes, remember to add helper constructor functions in `constructors.py`
|
400
|
-
# The opcode integers should be considered a public interface; they are used by
|
401
|
-
# serialization formats that may transfer data between different versions of Qiskit.
|
402
|
-
BIT_AND = 1
|
403
|
-
"""Bitwise "and". ``lhs & rhs``."""
|
404
|
-
BIT_OR = 2
|
405
|
-
"""Bitwise "or". ``lhs | rhs``."""
|
406
|
-
BIT_XOR = 3
|
407
|
-
"""Bitwise "exclusive or". ``lhs ^ rhs``."""
|
408
|
-
LOGIC_AND = 4
|
409
|
-
"""Logical "and". ``lhs && rhs``."""
|
410
|
-
LOGIC_OR = 5
|
411
|
-
"""Logical "or". ``lhs || rhs``."""
|
412
|
-
EQUAL = 6
|
413
|
-
"""Numeric equality. ``lhs == rhs``."""
|
414
|
-
NOT_EQUAL = 7
|
415
|
-
"""Numeric inequality. ``lhs != rhs``."""
|
416
|
-
LESS = 8
|
417
|
-
"""Numeric less than. ``lhs < rhs``."""
|
418
|
-
LESS_EQUAL = 9
|
419
|
-
"""Numeric less than or equal to. ``lhs <= rhs``"""
|
420
|
-
GREATER = 10
|
421
|
-
"""Numeric greater than. ``lhs > rhs``."""
|
422
|
-
GREATER_EQUAL = 11
|
423
|
-
"""Numeric greater than or equal to. ``lhs >= rhs``."""
|
424
|
-
SHIFT_LEFT = 12
|
425
|
-
"""Zero-padding bitshift to the left. ``lhs << rhs``."""
|
426
|
-
SHIFT_RIGHT = 13
|
427
|
-
"""Zero-padding bitshift to the right. ``lhs >> rhs``."""
|
428
|
-
ADD = 14
|
429
|
-
"""Addition. ``lhs + rhs``."""
|
430
|
-
SUB = 15
|
431
|
-
"""Subtraction. ``lhs - rhs``."""
|
432
|
-
MUL = 16
|
433
|
-
"""Multiplication. ``lhs * rhs``."""
|
434
|
-
DIV = 17
|
435
|
-
"""Division. ``lhs / rhs``."""
|
436
|
-
|
437
|
-
def __str__(self):
|
438
|
-
return f"Binary.{super().__str__()}"
|
439
|
-
|
440
|
-
def __repr__(self):
|
441
|
-
return f"Binary.{super().__repr__()}"
|
442
|
-
|
443
|
-
def __init__(self, op: Binary.Op, left: Expr, right: Expr, type: types.Type):
|
444
|
-
self.op = op
|
445
|
-
self.left = left
|
446
|
-
self.right = right
|
447
|
-
self.type = type
|
448
|
-
self.const = left.const and right.const
|
449
|
-
|
450
|
-
def accept(self, visitor, /):
|
451
|
-
return visitor.visit_binary(self)
|
452
|
-
|
453
|
-
def __eq__(self, other):
|
454
|
-
return (
|
455
|
-
isinstance(other, Binary)
|
456
|
-
and self.type == other.type
|
457
|
-
and self.const == other.const
|
458
|
-
and self.op is other.op
|
459
|
-
and self.left == other.left
|
460
|
-
and self.right == other.right
|
461
|
-
)
|
462
|
-
|
463
|
-
def __repr__(self):
|
464
|
-
return f"Binary({self.op}, {self.left}, {self.right}, {self.type})"
|
465
|
-
|
466
|
-
|
467
|
-
@typing.final
|
468
|
-
class Index(Expr):
|
469
|
-
"""An indexing expression.
|
470
|
-
|
471
|
-
Args:
|
472
|
-
target: The object being indexed.
|
473
|
-
index: The expression doing the indexing.
|
474
|
-
type: The resolved type of the result.
|
475
|
-
"""
|
476
|
-
|
477
|
-
__slots__ = ("target", "index")
|
478
|
-
|
479
|
-
def __init__(self, target: Expr, index: Expr, type: types.Type):
|
480
|
-
self.target = target
|
481
|
-
self.index = index
|
482
|
-
self.type = type
|
483
|
-
self.const = target.const and index.const
|
484
|
-
|
485
|
-
def accept(self, visitor, /):
|
486
|
-
return visitor.visit_index(self)
|
487
|
-
|
488
|
-
def __eq__(self, other):
|
489
|
-
return (
|
490
|
-
isinstance(other, Index)
|
491
|
-
and self.type == other.type
|
492
|
-
and self.const == other.const
|
493
|
-
and self.target == other.target
|
494
|
-
and self.index == other.index
|
495
|
-
)
|
496
|
-
|
497
|
-
def __repr__(self):
|
498
|
-
return f"Index({self.target}, {self.index}, {self.type})"
|
152
|
+
# Setting these tricks Sphinx into thinking that this enum is actually
|
153
|
+
# defined as an inner class of the Rust pyclass.
|
154
|
+
_BinaryOp.__module__ = "qiskit._accelerate.circuit.classical.expr"
|
155
|
+
_BinaryOp.__name__ = "Op"
|
156
|
+
_BinaryOp.__qualname__ = "Binary.Op"
|
@@ -65,15 +65,21 @@ class ExprVisitor(typing.Generic[_T_co]):
|
|
65
65
|
|
66
66
|
|
67
67
|
class _VarWalkerImpl(ExprVisitor[typing.Iterable[expr.Var]]):
|
68
|
+
# We don't want docstrings for the inherited visitor methods, which are self-explanatory and
|
69
|
+
# would just be noise.
|
70
|
+
# pylint: disable=missing-function-docstring
|
71
|
+
|
68
72
|
__slots__ = ()
|
69
73
|
|
70
74
|
def visit_var(self, node, /):
|
71
75
|
yield node
|
72
76
|
|
73
77
|
def visit_stretch(self, node, /):
|
78
|
+
# pylint: disable=unused-argument
|
74
79
|
yield from ()
|
75
80
|
|
76
81
|
def visit_value(self, node, /):
|
82
|
+
# pylint: disable=unused-argument
|
77
83
|
yield from ()
|
78
84
|
|
79
85
|
def visit_unary(self, node, /):
|