qiskit 1.4.0__cp39-abi3-macosx_11_0_arm64.whl → 2.0.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.
Files changed (456) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +2 -5
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +24 -5
  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 +248 -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 +7 -140
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +34 -5
  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/hamiltonian_gate.py +1 -1
  60. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  61. qiskit/circuit/library/n_local/n_local.py +1 -1
  62. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  63. qiskit/circuit/library/overlap.py +2 -2
  64. qiskit/circuit/library/pauli_evolution.py +39 -24
  65. qiskit/circuit/library/phase_oracle.py +130 -51
  66. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  67. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  68. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  69. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  70. qiskit/circuit/library/standard_gates/h.py +4 -9
  71. qiskit/circuit/library/standard_gates/i.py +2 -2
  72. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  73. qiskit/circuit/library/standard_gates/p.py +15 -34
  74. qiskit/circuit/library/standard_gates/r.py +2 -6
  75. qiskit/circuit/library/standard_gates/rx.py +5 -15
  76. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  77. qiskit/circuit/library/standard_gates/ry.py +5 -17
  78. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  79. qiskit/circuit/library/standard_gates/rz.py +5 -17
  80. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  82. qiskit/circuit/library/standard_gates/s.py +6 -15
  83. qiskit/circuit/library/standard_gates/swap.py +4 -11
  84. qiskit/circuit/library/standard_gates/sx.py +7 -12
  85. qiskit/circuit/library/standard_gates/t.py +6 -7
  86. qiskit/circuit/library/standard_gates/u.py +2 -10
  87. qiskit/circuit/library/standard_gates/u1.py +5 -16
  88. qiskit/circuit/library/standard_gates/u2.py +2 -6
  89. qiskit/circuit/library/standard_gates/u3.py +3 -11
  90. qiskit/circuit/library/standard_gates/x.py +13 -60
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/y.py +4 -9
  94. qiskit/circuit/library/standard_gates/z.py +5 -15
  95. qiskit/circuit/measure.py +11 -2
  96. qiskit/circuit/parameterexpression.py +4 -0
  97. qiskit/circuit/quantumcircuit.py +881 -555
  98. qiskit/circuit/random/utils.py +12 -6
  99. qiskit/circuit/reset.py +5 -2
  100. qiskit/circuit/singleton.py +5 -11
  101. qiskit/circuit/store.py +0 -8
  102. qiskit/compiler/__init__.py +1 -7
  103. qiskit/compiler/transpiler.py +38 -196
  104. qiskit/converters/circuit_to_dag.py +4 -2
  105. qiskit/converters/circuit_to_dagdependency.py +0 -2
  106. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  107. qiskit/converters/circuit_to_gate.py +1 -1
  108. qiskit/converters/circuit_to_instruction.py +16 -29
  109. qiskit/converters/dag_to_circuit.py +5 -5
  110. qiskit/converters/dag_to_dagdependency.py +0 -1
  111. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  112. qiskit/converters/dagdependency_to_circuit.py +0 -6
  113. qiskit/converters/dagdependency_to_dag.py +0 -6
  114. qiskit/dagcircuit/collect_blocks.py +32 -20
  115. qiskit/dagcircuit/dagdependency.py +3 -37
  116. qiskit/dagcircuit/dagdependency_v2.py +2 -80
  117. qiskit/dagcircuit/dagnode.py +14 -2
  118. qiskit/passmanager/__init__.py +24 -6
  119. qiskit/passmanager/passmanager.py +26 -24
  120. qiskit/primitives/__init__.py +44 -35
  121. qiskit/primitives/backend_estimator_v2.py +102 -23
  122. qiskit/primitives/backend_sampler_v2.py +5 -20
  123. qiskit/primitives/base/__init__.py +4 -4
  124. qiskit/primitives/base/base_estimator.py +77 -82
  125. qiskit/primitives/base/base_primitive_job.py +2 -2
  126. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  127. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  128. qiskit/primitives/base/base_sampler.py +52 -60
  129. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  130. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  131. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  132. qiskit/primitives/containers/bindings_array.py +3 -1
  133. qiskit/primitives/containers/bit_array.py +23 -0
  134. qiskit/primitives/containers/data_bin.py +3 -1
  135. qiskit/primitives/containers/observables_array.py +19 -2
  136. qiskit/primitives/statevector_sampler.py +6 -8
  137. qiskit/primitives/utils.py +14 -189
  138. qiskit/providers/__init__.py +4 -130
  139. qiskit/providers/backend.py +11 -314
  140. qiskit/providers/basic_provider/__init__.py +3 -1
  141. qiskit/providers/basic_provider/basic_provider.py +29 -9
  142. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  143. qiskit/providers/exceptions.py +0 -33
  144. qiskit/providers/fake_provider/__init__.py +0 -37
  145. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  146. qiskit/qasm2/__init__.py +21 -6
  147. qiskit/qasm2/export.py +2 -10
  148. qiskit/qasm2/parse.py +11 -25
  149. qiskit/qasm3/__init__.py +5 -1
  150. qiskit/qasm3/ast.py +44 -0
  151. qiskit/qasm3/exporter.py +65 -27
  152. qiskit/qasm3/printer.py +35 -4
  153. qiskit/qpy/__init__.py +141 -19
  154. qiskit/qpy/binary_io/__init__.py +0 -1
  155. qiskit/qpy/binary_io/circuits.py +91 -116
  156. qiskit/qpy/binary_io/schedules.py +61 -388
  157. qiskit/qpy/binary_io/value.py +168 -28
  158. qiskit/qpy/common.py +10 -7
  159. qiskit/qpy/formats.py +41 -0
  160. qiskit/qpy/interface.py +29 -62
  161. qiskit/qpy/type_keys.py +58 -221
  162. qiskit/quantum_info/analysis/distance.py +3 -1
  163. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  164. qiskit/quantum_info/operators/operator.py +6 -2
  165. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  166. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  167. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  169. qiskit/quantum_info/states/densitymatrix.py +16 -6
  170. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  171. qiskit/quantum_info/states/statevector.py +16 -6
  172. qiskit/result/__init__.py +5 -17
  173. qiskit/result/models.py +18 -10
  174. qiskit/result/result.py +28 -126
  175. qiskit/result/sampled_expval.py +1 -2
  176. qiskit/result/utils.py +3 -4
  177. qiskit/synthesis/__init__.py +21 -1
  178. qiskit/synthesis/arithmetic/__init__.py +3 -1
  179. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  180. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  181. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  182. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  183. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  184. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  185. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  186. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  187. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  188. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  189. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  190. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  191. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  192. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  193. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  194. qiskit/synthesis/evolution/product_formula.py +44 -35
  195. qiskit/synthesis/evolution/qdrift.py +17 -24
  196. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  197. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  198. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  199. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  200. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  201. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  202. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  203. qiskit/synthesis/two_qubit/__init__.py +1 -0
  204. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  205. qiskit/transpiler/__init__.py +32 -232
  206. qiskit/transpiler/basepasses.py +20 -51
  207. qiskit/transpiler/layout.py +1 -1
  208. qiskit/transpiler/passes/__init__.py +2 -40
  209. qiskit/transpiler/passes/basis/basis_translator.py +4 -3
  210. qiskit/transpiler/passes/basis/decompose.py +1 -15
  211. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  212. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  213. qiskit/transpiler/passes/layout/apply_layout.py +5 -0
  214. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  215. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
  216. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  217. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  218. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  219. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  220. qiskit/transpiler/passes/optimization/__init__.py +1 -3
  221. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  222. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  224. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  225. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  226. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  227. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  228. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  229. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  230. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  231. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  232. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  233. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  234. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  235. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  236. qiskit/transpiler/passes/routing/__init__.py +0 -1
  237. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  238. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  239. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  240. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  241. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  242. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  243. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  244. qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
  245. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
  246. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
  247. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  248. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  249. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  250. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
  251. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  252. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  253. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  254. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  255. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  256. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  257. qiskit/transpiler/passes/utils/__init__.py +0 -1
  258. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  259. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  260. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  261. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  262. qiskit/transpiler/passmanager.py +13 -0
  263. qiskit/transpiler/passmanager_config.py +5 -81
  264. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  265. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  266. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
  267. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  268. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  269. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  270. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  272. qiskit/transpiler/target.py +67 -524
  273. qiskit/user_config.py +8 -4
  274. qiskit/utils/__init__.py +13 -12
  275. qiskit/utils/deprecation.py +4 -112
  276. qiskit/utils/optionals.py +11 -4
  277. qiskit/utils/parallel.py +214 -87
  278. qiskit/utils/units.py +4 -1
  279. qiskit/visualization/__init__.py +3 -7
  280. qiskit/visualization/array.py +4 -1
  281. qiskit/visualization/bloch.py +1 -1
  282. qiskit/visualization/circuit/_utils.py +19 -19
  283. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  284. qiskit/visualization/circuit/matplotlib.py +13 -23
  285. qiskit/visualization/circuit/text.py +7 -3
  286. qiskit/visualization/dag_visualization.py +2 -1
  287. qiskit/visualization/gate_map.py +39 -154
  288. qiskit/visualization/pass_manager_visualization.py +6 -2
  289. qiskit/visualization/state_visualization.py +6 -0
  290. qiskit/visualization/timeline/core.py +27 -12
  291. qiskit/visualization/timeline/interface.py +23 -18
  292. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
  293. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
  294. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
  295. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/entry_points.txt +8 -2
  296. qiskit/assembler/__init__.py +0 -42
  297. qiskit/assembler/assemble_circuits.py +0 -451
  298. qiskit/assembler/assemble_schedules.py +0 -367
  299. qiskit/assembler/disassemble.py +0 -310
  300. qiskit/assembler/run_config.py +0 -77
  301. qiskit/circuit/bit.py +0 -106
  302. qiskit/circuit/classicalfunction/__init__.py +0 -152
  303. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  304. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  305. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  306. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  307. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  308. qiskit/circuit/classicalfunction/types.py +0 -18
  309. qiskit/circuit/classicalfunction/utils.py +0 -91
  310. qiskit/circuit/classicalregister.py +0 -57
  311. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  312. qiskit/circuit/quantumregister.py +0 -75
  313. qiskit/circuit/register.py +0 -246
  314. qiskit/compiler/assembler.py +0 -689
  315. qiskit/compiler/scheduler.py +0 -109
  316. qiskit/compiler/sequencer.py +0 -71
  317. qiskit/primitives/backend_estimator.py +0 -486
  318. qiskit/primitives/backend_sampler.py +0 -222
  319. qiskit/primitives/estimator.py +0 -172
  320. qiskit/primitives/sampler.py +0 -162
  321. qiskit/providers/backend_compat.py +0 -507
  322. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  323. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  324. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  325. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  326. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  327. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  328. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  330. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  332. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  333. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  335. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  337. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  338. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  339. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  341. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  343. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  344. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  345. qiskit/providers/fake_provider/fake_1q.py +0 -91
  346. qiskit/providers/fake_provider/fake_backend.py +0 -165
  347. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  348. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  349. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  350. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  351. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  352. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  353. qiskit/providers/models/__init__.py +0 -89
  354. qiskit/providers/models/backendconfiguration.py +0 -1040
  355. qiskit/providers/models/backendproperties.py +0 -535
  356. qiskit/providers/models/backendstatus.py +0 -104
  357. qiskit/providers/models/jobstatus.py +0 -77
  358. qiskit/providers/models/pulsedefaults.py +0 -305
  359. qiskit/providers/provider.py +0 -95
  360. qiskit/pulse/__init__.py +0 -158
  361. qiskit/pulse/builder.py +0 -2262
  362. qiskit/pulse/calibration_entries.py +0 -381
  363. qiskit/pulse/channels.py +0 -227
  364. qiskit/pulse/configuration.py +0 -245
  365. qiskit/pulse/exceptions.py +0 -45
  366. qiskit/pulse/filters.py +0 -309
  367. qiskit/pulse/instruction_schedule_map.py +0 -424
  368. qiskit/pulse/instructions/__init__.py +0 -67
  369. qiskit/pulse/instructions/acquire.py +0 -150
  370. qiskit/pulse/instructions/delay.py +0 -71
  371. qiskit/pulse/instructions/directives.py +0 -154
  372. qiskit/pulse/instructions/frequency.py +0 -135
  373. qiskit/pulse/instructions/instruction.py +0 -270
  374. qiskit/pulse/instructions/phase.py +0 -152
  375. qiskit/pulse/instructions/play.py +0 -99
  376. qiskit/pulse/instructions/reference.py +0 -100
  377. qiskit/pulse/instructions/snapshot.py +0 -82
  378. qiskit/pulse/library/__init__.py +0 -97
  379. qiskit/pulse/library/continuous.py +0 -430
  380. qiskit/pulse/library/pulse.py +0 -148
  381. qiskit/pulse/library/samplers/__init__.py +0 -15
  382. qiskit/pulse/library/samplers/decorators.py +0 -295
  383. qiskit/pulse/library/samplers/strategies.py +0 -71
  384. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  385. qiskit/pulse/library/waveform.py +0 -136
  386. qiskit/pulse/macros.py +0 -262
  387. qiskit/pulse/parameter_manager.py +0 -445
  388. qiskit/pulse/parser.py +0 -314
  389. qiskit/pulse/reference_manager.py +0 -58
  390. qiskit/pulse/schedule.py +0 -1854
  391. qiskit/pulse/transforms/__init__.py +0 -106
  392. qiskit/pulse/transforms/alignments.py +0 -406
  393. qiskit/pulse/transforms/base_transforms.py +0 -71
  394. qiskit/pulse/transforms/canonicalization.py +0 -498
  395. qiskit/pulse/transforms/dag.py +0 -122
  396. qiskit/pulse/utils.py +0 -149
  397. qiskit/qobj/__init__.py +0 -75
  398. qiskit/qobj/common.py +0 -81
  399. qiskit/qobj/converters/__init__.py +0 -18
  400. qiskit/qobj/converters/lo_config.py +0 -177
  401. qiskit/qobj/converters/pulse_instruction.py +0 -897
  402. qiskit/qobj/pulse_qobj.py +0 -709
  403. qiskit/qobj/qasm_qobj.py +0 -708
  404. qiskit/qobj/utils.py +0 -46
  405. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  406. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  407. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  408. qiskit/result/mitigation/utils.py +0 -217
  409. qiskit/scheduler/__init__.py +0 -40
  410. qiskit/scheduler/config.py +0 -37
  411. qiskit/scheduler/lowering.py +0 -187
  412. qiskit/scheduler/methods/__init__.py +0 -15
  413. qiskit/scheduler/methods/basic.py +0 -140
  414. qiskit/scheduler/schedule_circuit.py +0 -69
  415. qiskit/scheduler/sequence.py +0 -104
  416. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  417. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  418. qiskit/transpiler/passes/calibration/builders.py +0 -20
  419. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  420. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  421. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  422. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  423. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  424. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  425. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  426. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  427. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  428. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  429. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  430. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  431. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  432. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  433. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  434. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  435. qiskit/utils/deprecate_pulse.py +0 -119
  436. qiskit/utils/multiprocessing.py +0 -56
  437. qiskit/visualization/pulse_v2/__init__.py +0 -21
  438. qiskit/visualization/pulse_v2/core.py +0 -901
  439. qiskit/visualization/pulse_v2/device_info.py +0 -173
  440. qiskit/visualization/pulse_v2/drawings.py +0 -253
  441. qiskit/visualization/pulse_v2/events.py +0 -254
  442. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  443. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  444. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  445. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  446. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  447. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  448. qiskit/visualization/pulse_v2/interface.py +0 -459
  449. qiskit/visualization/pulse_v2/layouts.py +0 -387
  450. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  451. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  452. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  453. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  454. qiskit/visualization/pulse_v2/types.py +0 -242
  455. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
  456. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.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,209 @@ 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
+ if not right.const:
687
+ raise ValueError(
688
+ f"multiplying operands '{left}' and '{right}' would result in a non-const '{left.type}'"
689
+ )
690
+ type = left.type
691
+ elif right.type.kind is types.Duration and left.type.kind in {types.Uint, types.Float}:
692
+ if not left.const:
693
+ raise ValueError(
694
+ f"multiplying operands '{left}' and '{right}' would result in a non-const '{right.type}'"
695
+ )
696
+ type = right.type
697
+ else:
698
+ raise TypeError(f"invalid types for '{Binary.Op.MUL}': '{left.type}' and '{right.type}'")
699
+ return Binary(
700
+ Binary.Op.MUL,
701
+ left,
702
+ right,
703
+ type,
704
+ )
705
+
706
+
707
+ def div(left: typing.Any, right: typing.Any) -> Expr:
708
+ """Create a division expression node from the given values, resolving any implicit casts and
709
+ lifting the values into :class:`Value` nodes if required.
710
+
711
+ This can be used to divide numeric operands of the same type kind, to divide a
712
+ :class`~.types.Duration` operand by a numeric operand, or to divide two
713
+ :class`~.types.Duration` operands which yields an expression of type
714
+ :class:`~.types.Float`.
715
+
716
+ Examples:
717
+ Division of two floating point numbers::
718
+
719
+ >>> from qiskit.circuit.classical import expr
720
+ >>> expr.div(5.0, 2.0)
721
+ Binary(\
722
+ Binary.Op.DIV, \
723
+ Value(5.0, Float()), \
724
+ Value(2.0, Float()), \
725
+ Float())
726
+
727
+ Division of two durations::
728
+
729
+ >>> from qiskit.circuit import Duration
730
+ >>> from qiskit.circuit.classical import expr
731
+ >>> expr.div(Duration.dt(10000), Duration.dt(1000))
732
+ Binary(\
733
+ Binary.Op.DIV, \
734
+ Value(Duration.dt(10000), Duration()), \
735
+ Value(Duration.dt(1000), Duration()), \
736
+ Float())
737
+
738
+
739
+ Division of a duration by a float::
740
+
741
+ >>> from qiskit.circuit import Duration
742
+ >>> from qiskit.circuit.classical import expr
743
+ >>> expr.div(Duration.dt(10000), 12.0)
744
+ Binary(\
745
+ Binary.Op.DIV, \
746
+ Value(Duration.dt(10000), Duration()), \
747
+ Value(12.0, types.Float()), \
748
+ Duration())
749
+ """
750
+ left, right = _lift_binary_operands(left, right)
751
+ type: types.Type
752
+ if left.type.kind is right.type.kind and left.type.kind in {
753
+ types.Duration,
754
+ types.Uint,
755
+ types.Float,
756
+ }:
757
+ if left.type.kind is types.Duration:
758
+ type = types.Float()
759
+ elif types.order(left.type, right.type) is not types.Ordering.NONE:
760
+ type = types.greater(left.type, right.type)
761
+ left = _coerce_lossless(left, type)
762
+ right = _coerce_lossless(right, type)
763
+ elif left.type.kind is types.Duration and right.type.kind in {types.Uint, types.Float}:
764
+ if not right.const:
765
+ raise ValueError(
766
+ f"division of '{left}' and '{right}' would result in a non-const '{left.type}'"
767
+ )
768
+ type = left.type
769
+ else:
770
+ raise TypeError(f"invalid types for '{Binary.Op.DIV}': '{left.type}' and '{right.type}'")
771
+ return Binary(
772
+ Binary.Op.DIV,
773
+ left,
774
+ right,
775
+ type,
776
+ )
@@ -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
  )