qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0__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.
Files changed (462) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +3 -9
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +35 -10
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +236 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +469 -154
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/graph_state.py +1 -0
  60. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  61. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  62. qiskit/circuit/library/n_local/n_local.py +1 -1
  63. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  64. qiskit/circuit/library/overlap.py +2 -2
  65. qiskit/circuit/library/pauli_evolution.py +39 -24
  66. qiskit/circuit/library/phase_oracle.py +130 -51
  67. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  69. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  70. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  71. qiskit/circuit/library/standard_gates/h.py +4 -9
  72. qiskit/circuit/library/standard_gates/i.py +2 -2
  73. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  74. qiskit/circuit/library/standard_gates/p.py +15 -34
  75. qiskit/circuit/library/standard_gates/r.py +7 -10
  76. qiskit/circuit/library/standard_gates/rx.py +5 -15
  77. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  78. qiskit/circuit/library/standard_gates/ry.py +5 -17
  79. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  80. qiskit/circuit/library/standard_gates/rz.py +5 -17
  81. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  82. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  83. qiskit/circuit/library/standard_gates/s.py +6 -15
  84. qiskit/circuit/library/standard_gates/swap.py +4 -11
  85. qiskit/circuit/library/standard_gates/sx.py +7 -12
  86. qiskit/circuit/library/standard_gates/t.py +6 -7
  87. qiskit/circuit/library/standard_gates/u.py +2 -10
  88. qiskit/circuit/library/standard_gates/u1.py +5 -16
  89. qiskit/circuit/library/standard_gates/u2.py +2 -6
  90. qiskit/circuit/library/standard_gates/u3.py +3 -11
  91. qiskit/circuit/library/standard_gates/x.py +14 -62
  92. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  94. qiskit/circuit/library/standard_gates/y.py +4 -9
  95. qiskit/circuit/library/standard_gates/z.py +5 -15
  96. qiskit/circuit/measure.py +11 -2
  97. qiskit/circuit/parameterexpression.py +11 -0
  98. qiskit/circuit/quantumcircuit.py +890 -564
  99. qiskit/circuit/random/utils.py +12 -6
  100. qiskit/circuit/reset.py +5 -2
  101. qiskit/circuit/singleton.py +5 -11
  102. qiskit/circuit/store.py +0 -8
  103. qiskit/circuit/tools/pi_check.py +3 -0
  104. qiskit/compiler/__init__.py +1 -7
  105. qiskit/compiler/transpiler.py +38 -196
  106. qiskit/converters/circuit_to_dag.py +6 -4
  107. qiskit/converters/circuit_to_dagdependency.py +0 -2
  108. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  109. qiskit/converters/circuit_to_gate.py +1 -1
  110. qiskit/converters/circuit_to_instruction.py +16 -29
  111. qiskit/converters/dag_to_circuit.py +7 -8
  112. qiskit/converters/dag_to_dagdependency.py +0 -1
  113. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  114. qiskit/converters/dagdependency_to_circuit.py +0 -6
  115. qiskit/converters/dagdependency_to_dag.py +0 -6
  116. qiskit/dagcircuit/collect_blocks.py +32 -20
  117. qiskit/dagcircuit/dagdependency.py +3 -37
  118. qiskit/dagcircuit/dagdependency_v2.py +5 -82
  119. qiskit/dagcircuit/dagnode.py +14 -2
  120. qiskit/passmanager/__init__.py +24 -6
  121. qiskit/passmanager/passmanager.py +26 -24
  122. qiskit/primitives/__init__.py +44 -35
  123. qiskit/primitives/backend_estimator_v2.py +102 -23
  124. qiskit/primitives/backend_sampler_v2.py +5 -20
  125. qiskit/primitives/base/__init__.py +4 -4
  126. qiskit/primitives/base/base_estimator.py +77 -82
  127. qiskit/primitives/base/base_primitive_job.py +2 -2
  128. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  129. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  130. qiskit/primitives/base/base_sampler.py +52 -60
  131. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  132. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  133. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  134. qiskit/primitives/containers/bindings_array.py +3 -1
  135. qiskit/primitives/containers/bit_array.py +23 -0
  136. qiskit/primitives/containers/data_bin.py +3 -1
  137. qiskit/primitives/containers/observables_array.py +19 -2
  138. qiskit/primitives/statevector_sampler.py +6 -8
  139. qiskit/primitives/utils.py +14 -189
  140. qiskit/providers/__init__.py +4 -130
  141. qiskit/providers/backend.py +11 -314
  142. qiskit/providers/basic_provider/__init__.py +3 -1
  143. qiskit/providers/basic_provider/basic_provider.py +29 -9
  144. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  145. qiskit/providers/exceptions.py +0 -33
  146. qiskit/providers/fake_provider/__init__.py +0 -37
  147. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  148. qiskit/qasm2/__init__.py +21 -6
  149. qiskit/qasm2/export.py +2 -10
  150. qiskit/qasm2/parse.py +11 -25
  151. qiskit/qasm3/__init__.py +5 -1
  152. qiskit/qasm3/ast.py +44 -0
  153. qiskit/qasm3/exporter.py +65 -27
  154. qiskit/qasm3/printer.py +35 -4
  155. qiskit/qpy/__init__.py +162 -19
  156. qiskit/qpy/binary_io/__init__.py +0 -1
  157. qiskit/qpy/binary_io/circuits.py +96 -116
  158. qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
  159. qiskit/qpy/binary_io/schedules.py +61 -388
  160. qiskit/qpy/binary_io/value.py +159 -33
  161. qiskit/qpy/common.py +10 -7
  162. qiskit/qpy/formats.py +41 -0
  163. qiskit/qpy/interface.py +29 -62
  164. qiskit/qpy/type_keys.py +58 -221
  165. qiskit/quantum_info/analysis/distance.py +3 -1
  166. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  167. qiskit/quantum_info/operators/operator.py +6 -2
  168. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  169. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  170. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  171. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  172. qiskit/quantum_info/states/densitymatrix.py +16 -6
  173. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  174. qiskit/quantum_info/states/statevector.py +16 -6
  175. qiskit/result/__init__.py +5 -17
  176. qiskit/result/models.py +18 -11
  177. qiskit/result/result.py +38 -134
  178. qiskit/result/sampled_expval.py +1 -2
  179. qiskit/result/utils.py +3 -4
  180. qiskit/synthesis/__init__.py +21 -1
  181. qiskit/synthesis/arithmetic/__init__.py +3 -1
  182. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  183. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  184. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  185. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  186. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  187. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  188. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  189. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  190. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  191. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  192. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  193. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  194. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  195. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  196. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  197. qiskit/synthesis/evolution/product_formula.py +44 -35
  198. qiskit/synthesis/evolution/qdrift.py +17 -24
  199. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  200. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  201. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  202. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  203. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  204. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  205. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  206. qiskit/synthesis/two_qubit/__init__.py +1 -0
  207. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  208. qiskit/transpiler/__init__.py +32 -232
  209. qiskit/transpiler/basepasses.py +20 -51
  210. qiskit/transpiler/layout.py +1 -1
  211. qiskit/transpiler/passes/__init__.py +4 -40
  212. qiskit/transpiler/passes/basis/basis_translator.py +5 -4
  213. qiskit/transpiler/passes/basis/decompose.py +1 -15
  214. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  215. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  216. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  217. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  218. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -4
  219. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  220. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  221. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  222. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  223. qiskit/transpiler/passes/optimization/__init__.py +2 -3
  224. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  225. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  226. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  227. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  228. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  229. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  230. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  231. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  232. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  233. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  234. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  235. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  236. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  237. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  238. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -2
  239. qiskit/transpiler/passes/routing/__init__.py +0 -1
  240. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  241. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  242. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  243. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  244. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  245. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  246. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  247. qiskit/transpiler/passes/scheduling/padding/base_padding.py +32 -4
  248. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
  249. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
  250. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  251. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  252. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  253. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +134 -62
  254. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  255. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  256. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  257. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  258. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  259. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  260. qiskit/transpiler/passes/utils/__init__.py +0 -1
  261. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  262. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  263. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  264. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  265. qiskit/transpiler/passmanager.py +13 -0
  266. qiskit/transpiler/passmanager_config.py +5 -81
  267. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  268. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  269. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +107 -322
  270. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  272. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  273. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  274. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  275. qiskit/transpiler/target.py +78 -524
  276. qiskit/user_config.py +8 -4
  277. qiskit/utils/__init__.py +13 -12
  278. qiskit/utils/deprecation.py +4 -112
  279. qiskit/utils/optionals.py +11 -4
  280. qiskit/utils/parallel.py +214 -87
  281. qiskit/utils/units.py +4 -1
  282. qiskit/visualization/__init__.py +3 -7
  283. qiskit/visualization/array.py +4 -1
  284. qiskit/visualization/bloch.py +1 -1
  285. qiskit/visualization/circuit/_utils.py +19 -19
  286. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  287. qiskit/visualization/circuit/matplotlib.py +13 -23
  288. qiskit/visualization/circuit/text.py +7 -3
  289. qiskit/visualization/counts_visualization.py +4 -0
  290. qiskit/visualization/dag_visualization.py +2 -1
  291. qiskit/visualization/gate_map.py +39 -154
  292. qiskit/visualization/library.py +4 -1
  293. qiskit/visualization/pass_manager_visualization.py +6 -2
  294. qiskit/visualization/state_visualization.py +19 -2
  295. qiskit/visualization/timeline/core.py +19 -13
  296. qiskit/visualization/timeline/interface.py +19 -18
  297. qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
  298. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
  299. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/RECORD +303 -449
  300. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/WHEEL +2 -1
  301. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/entry_points.txt +8 -2
  302. qiskit/assembler/__init__.py +0 -42
  303. qiskit/assembler/assemble_circuits.py +0 -451
  304. qiskit/assembler/assemble_schedules.py +0 -367
  305. qiskit/assembler/disassemble.py +0 -310
  306. qiskit/assembler/run_config.py +0 -77
  307. qiskit/circuit/bit.py +0 -106
  308. qiskit/circuit/classicalfunction/__init__.py +0 -152
  309. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  310. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  311. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  312. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  313. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  314. qiskit/circuit/classicalfunction/types.py +0 -18
  315. qiskit/circuit/classicalfunction/utils.py +0 -91
  316. qiskit/circuit/classicalregister.py +0 -57
  317. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  318. qiskit/circuit/quantumregister.py +0 -75
  319. qiskit/circuit/register.py +0 -246
  320. qiskit/compiler/assembler.py +0 -689
  321. qiskit/compiler/scheduler.py +0 -109
  322. qiskit/compiler/sequencer.py +0 -71
  323. qiskit/primitives/backend_estimator.py +0 -486
  324. qiskit/primitives/backend_sampler.py +0 -222
  325. qiskit/primitives/estimator.py +0 -172
  326. qiskit/primitives/sampler.py +0 -162
  327. qiskit/providers/backend_compat.py +0 -507
  328. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  329. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  330. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  332. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  333. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  335. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  336. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  337. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  338. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  339. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  341. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  343. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  344. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  345. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  346. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  347. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  348. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  349. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  350. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  351. qiskit/providers/fake_provider/fake_1q.py +0 -91
  352. qiskit/providers/fake_provider/fake_backend.py +0 -165
  353. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  354. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  355. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  356. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  357. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  358. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  359. qiskit/providers/models/__init__.py +0 -89
  360. qiskit/providers/models/backendconfiguration.py +0 -1040
  361. qiskit/providers/models/backendproperties.py +0 -535
  362. qiskit/providers/models/backendstatus.py +0 -104
  363. qiskit/providers/models/jobstatus.py +0 -77
  364. qiskit/providers/models/pulsedefaults.py +0 -305
  365. qiskit/providers/provider.py +0 -95
  366. qiskit/pulse/__init__.py +0 -158
  367. qiskit/pulse/builder.py +0 -2262
  368. qiskit/pulse/calibration_entries.py +0 -381
  369. qiskit/pulse/channels.py +0 -227
  370. qiskit/pulse/configuration.py +0 -245
  371. qiskit/pulse/exceptions.py +0 -45
  372. qiskit/pulse/filters.py +0 -309
  373. qiskit/pulse/instruction_schedule_map.py +0 -424
  374. qiskit/pulse/instructions/__init__.py +0 -67
  375. qiskit/pulse/instructions/acquire.py +0 -150
  376. qiskit/pulse/instructions/delay.py +0 -71
  377. qiskit/pulse/instructions/directives.py +0 -154
  378. qiskit/pulse/instructions/frequency.py +0 -135
  379. qiskit/pulse/instructions/instruction.py +0 -270
  380. qiskit/pulse/instructions/phase.py +0 -152
  381. qiskit/pulse/instructions/play.py +0 -99
  382. qiskit/pulse/instructions/reference.py +0 -100
  383. qiskit/pulse/instructions/snapshot.py +0 -82
  384. qiskit/pulse/library/__init__.py +0 -97
  385. qiskit/pulse/library/continuous.py +0 -430
  386. qiskit/pulse/library/pulse.py +0 -148
  387. qiskit/pulse/library/samplers/__init__.py +0 -15
  388. qiskit/pulse/library/samplers/decorators.py +0 -295
  389. qiskit/pulse/library/samplers/strategies.py +0 -71
  390. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  391. qiskit/pulse/library/waveform.py +0 -136
  392. qiskit/pulse/macros.py +0 -262
  393. qiskit/pulse/parameter_manager.py +0 -445
  394. qiskit/pulse/parser.py +0 -314
  395. qiskit/pulse/reference_manager.py +0 -58
  396. qiskit/pulse/schedule.py +0 -1854
  397. qiskit/pulse/transforms/__init__.py +0 -106
  398. qiskit/pulse/transforms/alignments.py +0 -406
  399. qiskit/pulse/transforms/base_transforms.py +0 -71
  400. qiskit/pulse/transforms/canonicalization.py +0 -498
  401. qiskit/pulse/transforms/dag.py +0 -122
  402. qiskit/pulse/utils.py +0 -149
  403. qiskit/qobj/__init__.py +0 -75
  404. qiskit/qobj/common.py +0 -81
  405. qiskit/qobj/converters/__init__.py +0 -18
  406. qiskit/qobj/converters/lo_config.py +0 -177
  407. qiskit/qobj/converters/pulse_instruction.py +0 -897
  408. qiskit/qobj/pulse_qobj.py +0 -709
  409. qiskit/qobj/qasm_qobj.py +0 -708
  410. qiskit/qobj/utils.py +0 -46
  411. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  412. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  413. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  414. qiskit/result/mitigation/utils.py +0 -217
  415. qiskit/scheduler/__init__.py +0 -40
  416. qiskit/scheduler/config.py +0 -37
  417. qiskit/scheduler/lowering.py +0 -187
  418. qiskit/scheduler/methods/__init__.py +0 -15
  419. qiskit/scheduler/methods/basic.py +0 -140
  420. qiskit/scheduler/schedule_circuit.py +0 -69
  421. qiskit/scheduler/sequence.py +0 -104
  422. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  423. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  424. qiskit/transpiler/passes/calibration/builders.py +0 -20
  425. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  426. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  427. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  428. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  429. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  430. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  431. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  432. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  433. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  434. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  435. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  436. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  437. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  438. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  439. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  440. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  441. qiskit/utils/deprecate_pulse.py +0 -119
  442. qiskit/utils/multiprocessing.py +0 -56
  443. qiskit/visualization/pulse_v2/__init__.py +0 -21
  444. qiskit/visualization/pulse_v2/core.py +0 -901
  445. qiskit/visualization/pulse_v2/device_info.py +0 -173
  446. qiskit/visualization/pulse_v2/drawings.py +0 -253
  447. qiskit/visualization/pulse_v2/events.py +0 -254
  448. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  449. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  450. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  451. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  452. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  453. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  454. qiskit/visualization/pulse_v2/interface.py +0 -459
  455. qiskit/visualization/pulse_v2/layouts.py +0 -387
  456. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  457. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  458. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  459. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  460. qiskit/visualization/pulse_v2/types.py +0 -242
  461. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  462. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
@@ -19,6 +19,7 @@ from __future__ import annotations
19
19
 
20
20
  __all__ = [
21
21
  "lift",
22
+ "cast",
22
23
  "bit_not",
23
24
  "logic_not",
24
25
  "bit_and",
@@ -32,6 +33,13 @@ __all__ = [
32
33
  "less_equal",
33
34
  "greater",
34
35
  "greater_equal",
36
+ "shift_left",
37
+ "shift_right",
38
+ "index",
39
+ "add",
40
+ "sub",
41
+ "mul",
42
+ "div",
35
43
  "lift_legacy_condition",
36
44
  ]
37
45
 
@@ -45,9 +53,9 @@ if typing.TYPE_CHECKING:
45
53
  import qiskit
46
54
 
47
55
 
48
- def _coerce_lossless(expr: Expr, type: types.Type) -> Expr:
56
+ def _coerce_lossless(expr: Expr, type: types.Type) -> Expr | None:
49
57
  """Coerce ``expr`` to ``type`` by inserting a suitable :class:`Cast` node, if the cast is
50
- lossless. Otherwise, raise a ``TypeError``."""
58
+ lossless. Otherwise, return ``None``."""
51
59
  kind = cast_kind(expr.type, type)
52
60
  if kind is CastKind.EQUAL:
53
61
  return expr
@@ -55,29 +63,13 @@ def _coerce_lossless(expr: Expr, type: types.Type) -> Expr:
55
63
  return Cast(expr, type, implicit=True)
56
64
  if kind is CastKind.LOSSLESS:
57
65
  return Cast(expr, type, implicit=False)
58
- if kind is CastKind.DANGEROUS:
59
- raise TypeError(f"cannot cast '{expr}' to '{type}' without loss of precision")
60
- raise TypeError(f"no cast is defined to take '{expr}' to '{type}'")
66
+ return None
61
67
 
62
68
 
63
69
  def lift_legacy_condition(
64
70
  condition: tuple[qiskit.circuit.Clbit | qiskit.circuit.ClassicalRegister, int], /
65
71
  ) -> Expr:
66
- """Lift a legacy two-tuple equality condition into a new-style :class:`Expr`.
67
-
68
- Examples:
69
- Taking an old-style conditional instruction and getting an :class:`Expr` from its
70
- condition::
71
-
72
- from qiskit.circuit import ClassicalRegister
73
- from qiskit.circuit.library import HGate
74
- from qiskit.circuit.classical import expr
75
-
76
- cr = ClassicalRegister(2)
77
- instr = HGate().c_if(cr, 3)
78
-
79
- lifted = expr.lift_legacy_condition(instr.condition)
80
- """
72
+ """Lift a legacy two-tuple equality condition into a new-style :class:`Expr`."""
81
73
  from qiskit.circuit import Clbit # pylint: disable=cyclic-import
82
74
 
83
75
  target, value = condition
@@ -121,7 +113,7 @@ def lift(value: typing.Any, /, type: types.Type | None = None) -> Expr:
121
113
  if type is not None:
122
114
  raise ValueError("use 'cast' to cast existing expressions, not 'lift'")
123
115
  return value
124
- from qiskit.circuit import Clbit, ClassicalRegister # pylint: disable=cyclic-import
116
+ from qiskit.circuit import Clbit, ClassicalRegister, Duration # pylint: disable=cyclic-import
125
117
 
126
118
  inferred: types.Type
127
119
  if value is True or value is False or isinstance(value, Clbit):
@@ -135,6 +127,12 @@ def lift(value: typing.Any, /, type: types.Type | None = None) -> Expr:
135
127
  raise ValueError("cannot represent a negative value")
136
128
  inferred = types.Uint(width=value.bit_length() or 1)
137
129
  constructor = Value
130
+ elif isinstance(value, float):
131
+ inferred = types.Float()
132
+ constructor = Value
133
+ elif isinstance(value, Duration):
134
+ inferred = types.Duration()
135
+ constructor = Value
138
136
  else:
139
137
  raise TypeError(f"failed to infer a type for '{value}'")
140
138
  if type is None:
@@ -195,11 +193,15 @@ def logic_not(operand: typing.Any, /) -> Expr:
195
193
  >>> expr.logic_not(ClassicalRegister(3, "c"))
196
194
  Unary(\
197
195
  Unary.Op.LOGIC_NOT, \
198
- Cast(Var(ClassicalRegister(3, 'c'), Uint(3)), Bool(), implicit=True), \
196
+ Cast(Var(ClassicalRegister(3, 'c'), Uint(3)), \
197
+ Bool(), implicit=True), \
199
198
  Bool())
200
199
  """
201
- operand = _coerce_lossless(lift(operand), types.Bool())
202
- return Unary(Unary.Op.LOGIC_NOT, operand, operand.type)
200
+ operand = lift(operand)
201
+ coerced_operand = _coerce_lossless(operand, types.Bool())
202
+ if coerced_operand is None:
203
+ raise TypeError(f"cannot apply '{Unary.Op.LOGIC_NOT}' to type '{operand.type}'")
204
+ return Unary(Unary.Op.LOGIC_NOT, coerced_operand, coerced_operand.type)
203
205
 
204
206
 
205
207
  def _lift_binary_operands(left: typing.Any, right: typing.Any) -> tuple[Expr, Expr]:
@@ -314,9 +316,13 @@ Uint(3))
314
316
 
315
317
  def _binary_logical(op: Binary.Op, left: typing.Any, right: typing.Any) -> Expr:
316
318
  bool_ = types.Bool()
317
- left = _coerce_lossless(lift(left), bool_)
318
- right = _coerce_lossless(lift(right), bool_)
319
- return Binary(op, left, right, bool_)
319
+ left = lift(left)
320
+ right = lift(right)
321
+ coerced_left = _coerce_lossless(left, bool_)
322
+ coerced_right = _coerce_lossless(right, bool_)
323
+ if coerced_left is None or coerced_right is None:
324
+ raise TypeError(f"invalid types for '{op}': '{left.type}' and '{right.type}'")
325
+ return Binary(op, coerced_left, coerced_right, bool_)
320
326
 
321
327
 
322
328
  def logic_and(left: typing.Any, right: typing.Any, /) -> Expr:
@@ -354,6 +360,8 @@ def _equal_like(op: Binary.Op, left: typing.Any, right: typing.Any) -> Expr:
354
360
  if left.type.kind is not right.type.kind:
355
361
  raise TypeError(f"invalid types for '{op}': '{left.type}' and '{right.type}'")
356
362
  type = types.greater(left.type, right.type)
363
+ # Note that we don't check the return value of _coerce_lossless for these
364
+ # since 'left' and 'right' are guaranteed to be the same kind here.
357
365
  return Binary(op, _coerce_lossless(left, type), _coerce_lossless(right, type), types.Bool())
358
366
 
359
367
 
@@ -398,6 +406,8 @@ def _binary_relation(op: Binary.Op, left: typing.Any, right: typing.Any) -> Expr
398
406
  if left.type.kind is not right.type.kind or left.type.kind is types.Bool:
399
407
  raise TypeError(f"invalid types for '{op}': '{left.type}' and '{right.type}'")
400
408
  type = types.greater(left.type, right.type)
409
+ # Note that we don't check the return value of _coerce_lossless for these
410
+ # since 'left' and 'right' are guaranteed to be the same kind here.
401
411
  return Binary(op, _coerce_lossless(left, type), _coerce_lossless(right, type), types.Bool())
402
412
 
403
413
 
@@ -479,7 +489,11 @@ def _shift_like(
479
489
  if type is not None and type.kind is not types.Uint:
480
490
  raise TypeError(f"type '{type}' is not a valid bitshift operand type")
481
491
  if isinstance(left, Expr):
482
- left = _coerce_lossless(left, type) if type is not None else left
492
+ if type is not None:
493
+ coerced_left = _coerce_lossless(left, type)
494
+ if coerced_left is None:
495
+ raise TypeError(f"type '{type}' cannot losslessly represent '{left.type}'")
496
+ left = coerced_left
483
497
  else:
484
498
  left = lift(left, type)
485
499
  right = lift(right)
@@ -554,3 +568,197 @@ def index(target: typing.Any, index: typing.Any, /) -> Expr:
554
568
  if target.type.kind is not types.Uint or index.type.kind is not types.Uint:
555
569
  raise TypeError(f"invalid types for indexing: '{target.type}' and '{index.type}'")
556
570
  return Index(target, index, types.Bool())
571
+
572
+
573
+ def _binary_sum(op: Binary.Op, left: typing.Any, right: typing.Any) -> Expr:
574
+ left, right = _lift_binary_operands(left, right)
575
+ if left.type.kind is right.type.kind and left.type.kind in {
576
+ types.Uint,
577
+ types.Float,
578
+ types.Duration,
579
+ }:
580
+ type = types.greater(left.type, right.type)
581
+ return Binary(
582
+ op,
583
+ _coerce_lossless(left, type),
584
+ _coerce_lossless(right, type),
585
+ type,
586
+ )
587
+ raise TypeError(f"invalid types for '{op}': '{left.type}' and '{right.type}'")
588
+
589
+
590
+ def add(left: typing.Any, right: typing.Any, /) -> Expr:
591
+ """Create an addition expression node from the given values, resolving any implicit casts and
592
+ lifting the values into :class:`Value` nodes if required.
593
+
594
+ Examples:
595
+ Addition of two floating point numbers::
596
+
597
+ >>> from qiskit.circuit.classical import expr
598
+ >>> expr.add(5.0, 2.0)
599
+ Binary(\
600
+ Binary.Op.ADD, \
601
+ Value(5.0, Float()), \
602
+ Value(2.0, Float()), \
603
+ Float())
604
+
605
+ Addition of two durations::
606
+
607
+ >>> from qiskit.circuit import Duration
608
+ >>> from qiskit.circuit.classical import expr
609
+ >>> expr.add(Duration.dt(1000), Duration.dt(1000))
610
+ Binary(\
611
+ Binary.Op.ADD, \
612
+ Value(Duration.dt(1000), Duration()), \
613
+ Value(Duration.dt(1000), Duration()), \
614
+ Duration())
615
+ """
616
+ return _binary_sum(Binary.Op.ADD, left, right)
617
+
618
+
619
+ def sub(left: typing.Any, right: typing.Any, /) -> Expr:
620
+ """Create a subtraction expression node from the given values, resolving any implicit casts and
621
+ lifting the values into :class:`Value` nodes if required.
622
+
623
+ Examples:
624
+ Subtraction of two floating point numbers::
625
+
626
+ >>> from qiskit.circuit.classical import expr
627
+ >>> expr.sub(5.0, 2.0)
628
+ Binary(\
629
+ Binary.Op.SUB, \
630
+ Value(5.0, Float()), \
631
+ Value(2.0, Float()), \
632
+ Float())
633
+
634
+ Subtraction of two durations::
635
+
636
+ >>> from qiskit.circuit import Duration
637
+ >>> from qiskit.circuit.classical import expr
638
+ >>> expr.add(Duration.dt(1000), Duration.dt(1000))
639
+ Binary(\
640
+ Binary.Op.SUB, \
641
+ Value(Duration.dt(1000), Duration()), \
642
+ Value(Duration.dt(1000), Duration()), \
643
+ Duration())
644
+ """
645
+ return _binary_sum(Binary.Op.SUB, left, right)
646
+
647
+
648
+ def mul(left: typing.Any, right: typing.Any) -> Expr:
649
+ """Create a multiplication expression node from the given values, resolving any implicit casts and
650
+ lifting the values into :class:`Value` nodes if required.
651
+
652
+ This can be used to multiply numeric operands of the same type kind, or to multiply a duration
653
+ operand by a numeric operand.
654
+
655
+ Examples:
656
+ Multiplication of two floating point numbers::
657
+
658
+ >>> from qiskit.circuit.classical import expr
659
+ >>> expr.mul(5.0, 2.0)
660
+ Binary(\
661
+ Binary.Op.MUL, \
662
+ Value(5.0, Float()), \
663
+ Value(2.0, Float()), \
664
+ Float())
665
+
666
+ Multiplication of a duration by a float::
667
+
668
+ >>> from qiskit.circuit import Duration
669
+ >>> from qiskit.circuit.classical import expr
670
+ >>> expr.mul(Duration.dt(1000), 0.5)
671
+ Binary(\
672
+ Binary.Op.MUL, \
673
+ Value(Duration.dt(1000), Duration()), \
674
+ Value(0.5, Float()), \
675
+ Duration())
676
+ """
677
+ left, right = _lift_binary_operands(left, right)
678
+ type: types.Type
679
+ if left.type.kind is right.type.kind is types.Duration:
680
+ raise TypeError("cannot multiply two durations")
681
+ if left.type.kind is right.type.kind and left.type.kind in {types.Uint, types.Float}:
682
+ type = types.greater(left.type, right.type)
683
+ left = _coerce_lossless(left, type)
684
+ right = _coerce_lossless(right, type)
685
+ elif left.type.kind is types.Duration and right.type.kind in {types.Uint, types.Float}:
686
+ type = left.type
687
+ elif right.type.kind is types.Duration and left.type.kind in {types.Uint, types.Float}:
688
+ type = right.type
689
+ else:
690
+ raise TypeError(f"invalid types for '{Binary.Op.MUL}': '{left.type}' and '{right.type}'")
691
+ return Binary(
692
+ Binary.Op.MUL,
693
+ left,
694
+ right,
695
+ type,
696
+ )
697
+
698
+
699
+ def div(left: typing.Any, right: typing.Any) -> Expr:
700
+ """Create a division expression node from the given values, resolving any implicit casts and
701
+ lifting the values into :class:`Value` nodes if required.
702
+
703
+ This can be used to divide numeric operands of the same type kind, to divide a
704
+ :class`~.types.Duration` operand by a numeric operand, or to divide two
705
+ :class`~.types.Duration` operands which yields an expression of type
706
+ :class:`~.types.Float`.
707
+
708
+ Examples:
709
+ Division of two floating point numbers::
710
+
711
+ >>> from qiskit.circuit.classical import expr
712
+ >>> expr.div(5.0, 2.0)
713
+ Binary(\
714
+ Binary.Op.DIV, \
715
+ Value(5.0, Float()), \
716
+ Value(2.0, Float()), \
717
+ Float())
718
+
719
+ Division of two durations::
720
+
721
+ >>> from qiskit.circuit import Duration
722
+ >>> from qiskit.circuit.classical import expr
723
+ >>> expr.div(Duration.dt(10000), Duration.dt(1000))
724
+ Binary(\
725
+ Binary.Op.DIV, \
726
+ Value(Duration.dt(10000), Duration()), \
727
+ Value(Duration.dt(1000), Duration()), \
728
+ Float())
729
+
730
+
731
+ Division of a duration by a float::
732
+
733
+ >>> from qiskit.circuit import Duration
734
+ >>> from qiskit.circuit.classical import expr
735
+ >>> expr.div(Duration.dt(10000), 12.0)
736
+ Binary(\
737
+ Binary.Op.DIV, \
738
+ Value(Duration.dt(10000), Duration()), \
739
+ Value(12.0, types.Float()), \
740
+ Duration())
741
+ """
742
+ left, right = _lift_binary_operands(left, right)
743
+ type: types.Type
744
+ if left.type.kind is right.type.kind and left.type.kind in {
745
+ types.Duration,
746
+ types.Uint,
747
+ types.Float,
748
+ }:
749
+ if left.type.kind is types.Duration:
750
+ type = types.Float()
751
+ elif types.order(left.type, right.type) is not types.Ordering.NONE:
752
+ type = types.greater(left.type, right.type)
753
+ left = _coerce_lossless(left, type)
754
+ right = _coerce_lossless(right, type)
755
+ elif left.type.kind is types.Duration and right.type.kind in {types.Uint, types.Float}:
756
+ type = left.type
757
+ else:
758
+ raise TypeError(f"invalid types for '{Binary.Op.DIV}': '{left.type}' and '{right.type}'")
759
+ return Binary(
760
+ Binary.Op.DIV,
761
+ left,
762
+ right,
763
+ type,
764
+ )
@@ -22,10 +22,12 @@ from __future__ import annotations
22
22
  __all__ = [
23
23
  "Expr",
24
24
  "Var",
25
+ "Stretch",
25
26
  "Value",
26
27
  "Cast",
27
28
  "Unary",
28
29
  "Binary",
30
+ "Index",
29
31
  ]
30
32
 
31
33
  import abc
@@ -55,9 +57,10 @@ class Expr(abc.ABC):
55
57
  All subclasses are responsible for setting their ``type`` attribute in their ``__init__``, and
56
58
  should not call the parent initializer."""
57
59
 
58
- __slots__ = ("type",)
60
+ __slots__ = ("type", "const")
59
61
 
60
62
  type: types.Type
63
+ const: bool
61
64
 
62
65
  # Sentinel to prevent instantiation of the base class.
63
66
  @abc.abstractmethod
@@ -89,6 +92,7 @@ class Cast(Expr):
89
92
 
90
93
  def __init__(self, operand: Expr, type: types.Type, implicit: bool = False):
91
94
  self.type = type
95
+ self.const = operand.const
92
96
  self.operand = operand
93
97
  self.implicit = implicit
94
98
 
@@ -99,6 +103,7 @@ class Cast(Expr):
99
103
  return (
100
104
  isinstance(other, Cast)
101
105
  and self.type == other.type
106
+ and self.const == other.const
102
107
  and self.operand == other.operand
103
108
  and self.implicit == other.implicit
104
109
  )
@@ -141,6 +146,7 @@ class Var(Expr):
141
146
  name: str | None = None,
142
147
  ):
143
148
  super().__setattr__("type", type)
149
+ super().__setattr__("const", False)
144
150
  super().__setattr__("var", var)
145
151
  super().__setattr__("name", name)
146
152
 
@@ -151,8 +157,9 @@ class Var(Expr):
151
157
 
152
158
  @property
153
159
  def standalone(self) -> bool:
154
- """Whether this :class:`Var` is a standalone variable that owns its storage location. If
155
- false, this is a wrapper :class:`Var` around a pre-existing circuit object."""
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."""
156
163
  return isinstance(self.var, uuid.UUID)
157
164
 
158
165
  def accept(self, visitor, /):
@@ -185,6 +192,76 @@ class Var(Expr):
185
192
  def __setstate__(self, state):
186
193
  var, type, name = state
187
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`.
214
+ """
215
+
216
+ __slots__ = (
217
+ "var",
218
+ "name",
219
+ )
220
+
221
+ var: uuid.UUID
222
+ """A :class:`~uuid.UUID` to uniquely identify this stretch."""
223
+ name: str
224
+ """The name of the stretch variable."""
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)
240
+
241
+ def accept(self, visitor, /):
242
+ return visitor.visit_stretch(self)
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
254
+
255
+ def __repr__(self):
256
+ return f"Stretch({self.var}, {self.name})"
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)
188
265
  super().__setattr__("var", var)
189
266
  super().__setattr__("name", name)
190
267
 
@@ -206,6 +283,7 @@ class Value(Expr):
206
283
  def __init__(self, value: typing.Any, type: types.Type):
207
284
  self.type = type
208
285
  self.value = value
286
+ self.const = True
209
287
 
210
288
  def accept(self, visitor, /):
211
289
  return visitor.visit_value(self)
@@ -257,6 +335,7 @@ class Unary(Expr):
257
335
  self.op = op
258
336
  self.operand = operand
259
337
  self.type = type
338
+ self.const = operand.const
260
339
 
261
340
  def accept(self, visitor, /):
262
341
  return visitor.visit_unary(self)
@@ -265,6 +344,7 @@ class Unary(Expr):
265
344
  return (
266
345
  isinstance(other, Unary)
267
346
  and self.type == other.type
347
+ and self.const == other.const
268
348
  and self.op is other.op
269
349
  and self.operand == other.operand
270
350
  )
@@ -305,6 +385,15 @@ class Binary(Expr):
305
385
  container types (e.g. unsigned integers) as the left operand, and any integer type as the
306
386
  right-hand operand. In all cases, the output bit width is the same as the input, and zeros
307
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.
308
397
  """
309
398
 
310
399
  # If adding opcodes, remember to add helper constructor functions in `constructors.py`
@@ -336,6 +425,14 @@ class Binary(Expr):
336
425
  """Zero-padding bitshift to the left. ``lhs << rhs``."""
337
426
  SHIFT_RIGHT = 13
338
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``."""
339
436
 
340
437
  def __str__(self):
341
438
  return f"Binary.{super().__str__()}"
@@ -348,6 +445,7 @@ class Binary(Expr):
348
445
  self.left = left
349
446
  self.right = right
350
447
  self.type = type
448
+ self.const = left.const and right.const
351
449
 
352
450
  def accept(self, visitor, /):
353
451
  return visitor.visit_binary(self)
@@ -356,6 +454,7 @@ class Binary(Expr):
356
454
  return (
357
455
  isinstance(other, Binary)
358
456
  and self.type == other.type
457
+ and self.const == other.const
359
458
  and self.op is other.op
360
459
  and self.left == other.left
361
460
  and self.right == other.right
@@ -381,6 +480,7 @@ class Index(Expr):
381
480
  self.target = target
382
481
  self.index = index
383
482
  self.type = type
483
+ self.const = target.const and index.const
384
484
 
385
485
  def accept(self, visitor, /):
386
486
  return visitor.visit_index(self)
@@ -389,6 +489,7 @@ class Index(Expr):
389
489
  return (
390
490
  isinstance(other, Index)
391
491
  and self.type == other.type
492
+ and self.const == other.const
392
493
  and self.target == other.target
393
494
  and self.index == other.index
394
495
  )
@@ -17,7 +17,9 @@ from __future__ import annotations
17
17
  __all__ = [
18
18
  "ExprVisitor",
19
19
  "iter_vars",
20
+ "iter_identifiers",
20
21
  "structurally_equivalent",
22
+ "is_lvalue",
21
23
  ]
22
24
 
23
25
  import typing
@@ -43,6 +45,9 @@ class ExprVisitor(typing.Generic[_T_co]):
43
45
  def visit_var(self, node: expr.Var, /) -> _T_co: # pragma: no cover
44
46
  return self.visit_generic(node)
45
47
 
48
+ def visit_stretch(self, node: expr.Stretch, /) -> _T_co: # pragma: no cover
49
+ return self.visit_generic(node)
50
+
46
51
  def visit_value(self, node: expr.Value, /) -> _T_co: # pragma: no cover
47
52
  return self.visit_generic(node)
48
53
 
@@ -65,6 +70,36 @@ class _VarWalkerImpl(ExprVisitor[typing.Iterable[expr.Var]]):
65
70
  def visit_var(self, node, /):
66
71
  yield node
67
72
 
73
+ def visit_stretch(self, node, /):
74
+ yield from ()
75
+
76
+ def visit_value(self, node, /):
77
+ yield from ()
78
+
79
+ def visit_unary(self, node, /):
80
+ yield from node.operand.accept(self)
81
+
82
+ def visit_binary(self, node, /):
83
+ yield from node.left.accept(self)
84
+ yield from node.right.accept(self)
85
+
86
+ def visit_cast(self, node, /):
87
+ yield from node.operand.accept(self)
88
+
89
+ def visit_index(self, node, /):
90
+ yield from node.target.accept(self)
91
+ yield from node.index.accept(self)
92
+
93
+
94
+ class _IdentWalkerImpl(ExprVisitor[typing.Iterable[typing.Union[expr.Var, expr.Stretch]]]):
95
+ __slots__ = ()
96
+
97
+ def visit_var(self, node, /):
98
+ yield node
99
+
100
+ def visit_stretch(self, node, /):
101
+ yield node
102
+
68
103
  def visit_value(self, node, /):
69
104
  yield from ()
70
105
 
@@ -84,6 +119,7 @@ class _VarWalkerImpl(ExprVisitor[typing.Iterable[expr.Var]]):
84
119
 
85
120
 
86
121
  _VAR_WALKER = _VarWalkerImpl()
122
+ _IDENT_WALKER = _IdentWalkerImpl()
87
123
 
88
124
 
89
125
  def iter_vars(node: expr.Expr) -> typing.Iterator[expr.Var]:
@@ -102,10 +138,39 @@ def iter_vars(node: expr.Expr) -> typing.Iterator[expr.Var]:
102
138
  for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
103
139
  if isinstance(node.var, ClassicalRegister):
104
140
  print(node.var.name)
141
+
142
+ .. seealso::
143
+ :func:`iter_identifiers`
144
+ Get an iterator over all identifier nodes in the expression, including
145
+ both :class:`~.expr.Var` and :class:`~.expr.Stretch` nodes.
105
146
  """
106
147
  yield from node.accept(_VAR_WALKER)
107
148
 
108
149
 
150
+ def iter_identifiers(node: expr.Expr) -> typing.Iterator[typing.Union[expr.Var, expr.Stretch]]:
151
+ """Get an iterator over the :class:`~.expr.Var` and :class:`~.expr.Stretch`
152
+ nodes referenced at any level in the given :class:`~.expr.Expr`.
153
+
154
+ Examples:
155
+ Print out the name of each :class:`.ClassicalRegister` encountered::
156
+
157
+ from qiskit.circuit import ClassicalRegister
158
+ from qiskit.circuit.classical import expr
159
+
160
+ cr1 = ClassicalRegister(3, "a")
161
+ cr2 = ClassicalRegister(3, "b")
162
+
163
+ for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
164
+ if isinstance(node.var, ClassicalRegister):
165
+ print(node.var.name)
166
+
167
+ .. seealso::
168
+ :func:`iter_vars`
169
+ Get an iterator over just the :class:`~.expr.Var` nodes in the expression.
170
+ """
171
+ yield from node.accept(_IDENT_WALKER)
172
+
173
+
109
174
  class _StructuralEquivalenceImpl(ExprVisitor[bool]):
110
175
  # The strategy here is to continue to do regular double dispatch through the visitor format,
111
176
  # since we simply exit out with a ``False`` as soon as the structure of the two trees isn't the
@@ -134,6 +199,11 @@ class _StructuralEquivalenceImpl(ExprVisitor[bool]):
134
199
  other_var = self.other.var
135
200
  return self_var == other_var
136
201
 
202
+ def visit_stretch(self, node, /):
203
+ if self.other.__class__ is not node.__class__:
204
+ return False
205
+ return node.var == self.other.var
206
+
137
207
  def visit_value(self, node, /):
138
208
  return (
139
209
  node.__class__ is self.other.__class__
@@ -240,6 +310,9 @@ class _IsLValueImpl(ExprVisitor[bool]):
240
310
  def visit_var(self, node, /):
241
311
  return True
242
312
 
313
+ def visit_stretch(self, node, /):
314
+ return False
315
+
243
316
  def visit_value(self, node, /):
244
317
  return False
245
318
 
@@ -268,6 +341,8 @@ def is_lvalue(node: expr.Expr, /) -> bool:
268
341
  the scope that attempts to write to it. This would be an access property of the containing
269
342
  program, however, and not an inherent property of the expression system.
270
343
 
344
+ A constant expression is never an lvalue.
345
+
271
346
  Examples:
272
347
  Literal values are never l-values; there's no memory location associated with (for example)
273
348
  the constant ``1``::