classiq 0.92.0__py3-none-any.whl → 0.99.0__py3-none-any.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 (318) hide show
  1. classiq/__init__.py +11 -19
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
  3. classiq/_analyzer_extras/interactive_hardware.py +19 -12
  4. classiq/_internals/api_wrapper.py +31 -142
  5. classiq/_internals/async_utils.py +4 -7
  6. classiq/_internals/authentication/auth0.py +41 -15
  7. classiq/_internals/authentication/authorization_code.py +9 -0
  8. classiq/_internals/authentication/authorization_flow.py +41 -0
  9. classiq/_internals/authentication/device.py +33 -52
  10. classiq/_internals/authentication/hybrid_flow.py +19 -0
  11. classiq/_internals/authentication/password_manager.py +13 -13
  12. classiq/_internals/authentication/token_manager.py +9 -9
  13. classiq/_internals/client.py +17 -44
  14. classiq/_internals/config.py +19 -5
  15. classiq/_internals/help.py +1 -2
  16. classiq/_internals/host_checker.py +3 -3
  17. classiq/_internals/jobs.py +14 -14
  18. classiq/_internals/type_validation.py +3 -3
  19. classiq/analyzer/analyzer.py +18 -18
  20. classiq/analyzer/rb.py +17 -8
  21. classiq/analyzer/show_interactive_hack.py +1 -1
  22. classiq/applications/__init__.py +2 -2
  23. classiq/applications/chemistry/__init__.py +0 -30
  24. classiq/applications/chemistry/op_utils.py +4 -4
  25. classiq/applications/chemistry/problems.py +3 -3
  26. classiq/applications/chemistry/ucc.py +1 -2
  27. classiq/applications/chemistry/z2_symmetries.py +4 -4
  28. classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
  29. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
  30. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
  31. classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
  32. classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
  33. classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
  36. classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
  37. classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
  38. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
  39. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
  40. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
  41. classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
  42. classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
  43. classiq/applications/iqae/iqae.py +14 -11
  44. classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
  45. classiq/applications/qnn/datasets/dataset_parity.py +6 -6
  46. classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
  47. classiq/applications/qnn/qlayer.py +9 -8
  48. classiq/applications/qnn/torch_utils.py +5 -6
  49. classiq/applications/qnn/types.py +2 -1
  50. classiq/applications/qsp/__init__.py +20 -2
  51. classiq/applications/qsp/qsp.py +239 -11
  52. classiq/applications/qsvm/qsvm_data_generation.py +1 -2
  53. classiq/evaluators/classical_expression.py +0 -4
  54. classiq/evaluators/parameter_types.py +20 -12
  55. classiq/evaluators/qmod_annotated_expression.py +31 -26
  56. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
  57. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
  58. classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
  59. classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +4 -4
  60. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +14 -4
  61. classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
  62. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
  63. classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
  64. classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
  65. classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
  66. classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
  67. classiq/execution/__init__.py +0 -3
  68. classiq/execution/execution_session.py +28 -21
  69. classiq/execution/jobs.py +26 -26
  70. classiq/execution/qnn.py +1 -2
  71. classiq/execution/user_budgets.py +71 -37
  72. classiq/executor.py +1 -3
  73. classiq/interface/_version.py +1 -1
  74. classiq/interface/analyzer/analysis_params.py +4 -4
  75. classiq/interface/analyzer/cytoscape_graph.py +3 -3
  76. classiq/interface/analyzer/result.py +4 -4
  77. classiq/interface/ast_node.py +3 -3
  78. classiq/interface/backend/backend_preferences.py +26 -50
  79. classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
  80. classiq/interface/backend/provider_config/__init__.py +0 -0
  81. classiq/interface/backend/provider_config/provider_config.py +8 -0
  82. classiq/interface/backend/provider_config/providers/__init__.py +0 -0
  83. classiq/interface/backend/provider_config/providers/alice_bob.py +47 -0
  84. classiq/interface/backend/provider_config/providers/aqt.py +16 -0
  85. classiq/interface/backend/provider_config/providers/azure.py +37 -0
  86. classiq/interface/backend/provider_config/providers/braket.py +39 -0
  87. classiq/interface/backend/provider_config/providers/ibm.py +26 -0
  88. classiq/interface/backend/provider_config/providers/ionq.py +22 -0
  89. classiq/interface/backend/quantum_backend_providers.py +20 -2
  90. classiq/interface/chemistry/ansatz_library.py +3 -5
  91. classiq/interface/chemistry/operator.py +3 -3
  92. classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
  93. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
  94. classiq/interface/compression_utils.py +2 -3
  95. classiq/interface/debug_info/debug_info.py +8 -7
  96. classiq/interface/exceptions.py +10 -7
  97. classiq/interface/execution/primitives.py +6 -6
  98. classiq/interface/executor/estimate_cost.py +1 -1
  99. classiq/interface/executor/execution_preferences.py +3 -5
  100. classiq/interface/executor/execution_request.py +10 -10
  101. classiq/interface/executor/execution_result.py +1 -2
  102. classiq/interface/executor/quantum_code.py +8 -8
  103. classiq/interface/executor/result.py +28 -18
  104. classiq/interface/executor/user_budget.py +25 -17
  105. classiq/interface/executor/vqe_result.py +5 -6
  106. classiq/interface/generator/ansatz_library.py +6 -8
  107. classiq/interface/generator/application_apis/__init__.py +0 -3
  108. classiq/interface/generator/arith/arithmetic.py +2 -2
  109. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
  110. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
  111. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
  112. classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
  113. classiq/interface/generator/arith/arithmetic_operations.py +4 -6
  114. classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
  115. classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
  116. classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
  117. classiq/interface/generator/arith/binary_ops.py +15 -40
  118. classiq/interface/generator/arith/logical_ops.py +2 -3
  119. classiq/interface/generator/arith/number_utils.py +2 -2
  120. classiq/interface/generator/arith/register_user_input.py +3 -3
  121. classiq/interface/generator/arith/unary_ops.py +2 -2
  122. classiq/interface/generator/circuit_code/circuit_code.py +8 -10
  123. classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
  124. classiq/interface/generator/complex_type.py +2 -2
  125. classiq/interface/generator/copy.py +1 -3
  126. classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
  127. classiq/interface/generator/expressions/evaluated_expression.py +2 -3
  128. classiq/interface/generator/expressions/expression.py +2 -2
  129. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
  130. classiq/interface/generator/function_param_list.py +0 -40
  131. classiq/interface/generator/function_params.py +5 -6
  132. classiq/interface/generator/functions/classical_function_declaration.py +2 -2
  133. classiq/interface/generator/functions/classical_type.py +3 -3
  134. classiq/interface/generator/functions/type_modifier.py +0 -15
  135. classiq/interface/generator/functions/type_name.py +2 -2
  136. classiq/interface/generator/generated_circuit_data.py +14 -18
  137. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
  138. classiq/interface/generator/hardware/hardware_data.py +8 -8
  139. classiq/interface/generator/hardware_efficient_ansatz.py +9 -9
  140. classiq/interface/generator/mcu.py +3 -3
  141. classiq/interface/generator/mcx.py +3 -3
  142. classiq/interface/generator/model/constraints.py +34 -5
  143. classiq/interface/generator/model/preferences/preferences.py +15 -21
  144. classiq/interface/generator/model/quantum_register.py +7 -10
  145. classiq/interface/generator/noise_properties.py +3 -7
  146. classiq/interface/generator/parameters.py +1 -1
  147. classiq/interface/generator/partitioned_register.py +1 -2
  148. classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
  149. classiq/interface/generator/quantum_function_call.py +9 -12
  150. classiq/interface/generator/quantum_program.py +10 -23
  151. classiq/interface/generator/range_types.py +3 -3
  152. classiq/interface/generator/slice_parsing_utils.py +4 -5
  153. classiq/interface/generator/standard_gates/standard_gates.py +2 -4
  154. classiq/interface/generator/synthesis_execution_parameter.py +1 -3
  155. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +9 -0
  156. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
  157. classiq/interface/generator/transpiler_basis_gates.py +12 -4
  158. classiq/interface/generator/types/builtin_enum_declarations.py +0 -145
  159. classiq/interface/generator/types/compilation_metadata.py +12 -1
  160. classiq/interface/generator/types/enum_declaration.py +2 -1
  161. classiq/interface/generator/validations/flow_graph.py +3 -3
  162. classiq/interface/generator/visitor.py +10 -12
  163. classiq/interface/hardware.py +2 -3
  164. classiq/interface/helpers/classproperty.py +2 -2
  165. classiq/interface/helpers/custom_encoders.py +2 -1
  166. classiq/interface/helpers/custom_pydantic_types.py +1 -1
  167. classiq/interface/helpers/text_utils.py +1 -4
  168. classiq/interface/ide/visual_model.py +6 -5
  169. classiq/interface/interface_version.py +1 -1
  170. classiq/interface/jobs.py +3 -3
  171. classiq/interface/model/allocate.py +4 -4
  172. classiq/interface/model/block.py +6 -2
  173. classiq/interface/model/bounds.py +3 -3
  174. classiq/interface/model/classical_if.py +4 -0
  175. classiq/interface/model/control.py +8 -1
  176. classiq/interface/model/inplace_binary_operation.py +2 -2
  177. classiq/interface/model/invert.py +4 -0
  178. classiq/interface/model/model.py +4 -4
  179. classiq/interface/model/model_visitor.py +40 -1
  180. classiq/interface/model/parameter.py +1 -3
  181. classiq/interface/model/port_declaration.py +1 -1
  182. classiq/interface/model/power.py +4 -0
  183. classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
  184. classiq/interface/model/quantum_function_call.py +3 -6
  185. classiq/interface/model/quantum_function_declaration.py +1 -0
  186. classiq/interface/model/quantum_lambda_function.py +4 -4
  187. classiq/interface/model/quantum_statement.py +11 -4
  188. classiq/interface/model/quantum_type.py +14 -14
  189. classiq/interface/model/repeat.py +4 -0
  190. classiq/interface/model/skip_control.py +4 -0
  191. classiq/interface/model/validation_handle.py +2 -3
  192. classiq/interface/model/variable_declaration_statement.py +2 -2
  193. classiq/interface/model/within_apply_operation.py +4 -0
  194. classiq/interface/pretty_print/expression_to_qmod.py +3 -4
  195. classiq/interface/server/routes.py +0 -16
  196. classiq/interface/source_reference.py +3 -4
  197. classiq/model_expansions/arithmetic.py +11 -7
  198. classiq/model_expansions/arithmetic_compute_result_attrs.py +30 -27
  199. classiq/model_expansions/capturing/captured_vars.py +3 -3
  200. classiq/model_expansions/capturing/mangling_utils.py +1 -2
  201. classiq/model_expansions/closure.py +12 -11
  202. classiq/model_expansions/function_builder.py +14 -6
  203. classiq/model_expansions/generative_functions.py +7 -12
  204. classiq/model_expansions/interpreters/base_interpreter.py +3 -7
  205. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +2 -1
  206. classiq/model_expansions/interpreters/generative_interpreter.py +8 -4
  207. classiq/model_expansions/quantum_operations/allocate.py +4 -4
  208. classiq/model_expansions/quantum_operations/assignment_result_processor.py +8 -4
  209. classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
  210. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
  211. classiq/model_expansions/quantum_operations/emitter.py +3 -5
  212. classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
  213. classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
  214. classiq/model_expansions/quantum_operations/variable_decleration.py +61 -29
  215. classiq/model_expansions/scope.py +7 -7
  216. classiq/model_expansions/scope_initialization.py +4 -0
  217. classiq/model_expansions/visitors/symbolic_param_inference.py +6 -6
  218. classiq/model_expansions/visitors/uncomputation_signature_inference.py +328 -0
  219. classiq/model_expansions/visitors/variable_references.py +15 -14
  220. classiq/open_library/functions/__init__.py +28 -11
  221. classiq/open_library/functions/amplitude_loading.py +81 -0
  222. classiq/open_library/functions/discrete_sine_cosine_transform.py +19 -14
  223. classiq/open_library/functions/grover.py +8 -10
  224. classiq/open_library/functions/lcu.py +47 -18
  225. classiq/open_library/functions/modular_exponentiation.py +93 -8
  226. classiq/open_library/functions/qsvt.py +66 -79
  227. classiq/open_library/functions/qsvt_temp.py +536 -0
  228. classiq/open_library/functions/state_preparation.py +130 -27
  229. classiq/qmod/__init__.py +6 -4
  230. classiq/qmod/builtins/classical_execution_primitives.py +4 -23
  231. classiq/qmod/builtins/classical_functions.py +1 -42
  232. classiq/qmod/builtins/enums.py +15 -153
  233. classiq/qmod/builtins/functions/__init__.py +9 -18
  234. classiq/qmod/builtins/functions/allocation.py +25 -4
  235. classiq/qmod/builtins/functions/arithmetic.py +22 -27
  236. classiq/qmod/builtins/functions/exponentiation.py +51 -2
  237. classiq/qmod/builtins/functions/mcx_func.py +7 -0
  238. classiq/qmod/builtins/functions/standard_gates.py +46 -27
  239. classiq/qmod/builtins/operations.py +173 -79
  240. classiq/qmod/builtins/structs.py +24 -91
  241. classiq/qmod/cfunc.py +3 -2
  242. classiq/qmod/classical_function.py +2 -1
  243. classiq/qmod/classical_variable.py +4 -2
  244. classiq/qmod/cparam.py +2 -8
  245. classiq/qmod/create_model_function.py +7 -7
  246. classiq/qmod/declaration_inferrer.py +33 -30
  247. classiq/qmod/expression_query.py +7 -4
  248. classiq/qmod/model_state_container.py +2 -2
  249. classiq/qmod/native/pretty_printer.py +25 -14
  250. classiq/qmod/pretty_print/expression_to_python.py +5 -3
  251. classiq/qmod/pretty_print/pretty_printer.py +39 -17
  252. classiq/qmod/python_classical_type.py +40 -13
  253. classiq/qmod/qfunc.py +124 -19
  254. classiq/qmod/qmod_constant.py +2 -2
  255. classiq/qmod/qmod_parameter.py +5 -2
  256. classiq/qmod/qmod_variable.py +47 -46
  257. classiq/qmod/quantum_callable.py +18 -13
  258. classiq/qmod/quantum_expandable.py +33 -26
  259. classiq/qmod/quantum_function.py +84 -36
  260. classiq/qmod/semantics/annotation/call_annotation.py +5 -5
  261. classiq/qmod/semantics/error_manager.py +12 -14
  262. classiq/qmod/semantics/lambdas.py +1 -2
  263. classiq/qmod/semantics/validation/types_validation.py +1 -2
  264. classiq/qmod/symbolic.py +2 -4
  265. classiq/qmod/symbolic_expr.py +12 -4
  266. classiq/qmod/utilities.py +13 -20
  267. classiq/qmod/write_qmod.py +3 -4
  268. classiq/quantum_program.py +1 -3
  269. classiq/synthesis.py +11 -7
  270. {classiq-0.92.0.dist-info → classiq-0.99.0.dist-info}/METADATA +38 -37
  271. {classiq-0.92.0.dist-info → classiq-0.99.0.dist-info}/RECORD +273 -300
  272. classiq-0.99.0.dist-info/WHEEL +4 -0
  273. classiq-0.99.0.dist-info/licenses/LICENSE.txt +27 -0
  274. classiq/applications/chemistry/ansatz_parameters.py +0 -29
  275. classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
  276. classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
  277. classiq/applications/chemistry/ground_state_problem.py +0 -42
  278. classiq/applications/qsvm/__init__.py +0 -8
  279. classiq/applications/qsvm/qsvm.py +0 -11
  280. classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
  281. classiq/execution/iqcc.py +0 -128
  282. classiq/interface/applications/qsvm.py +0 -117
  283. classiq/interface/chemistry/elements.py +0 -120
  284. classiq/interface/chemistry/fermionic_operator.py +0 -208
  285. classiq/interface/chemistry/ground_state_problem.py +0 -132
  286. classiq/interface/chemistry/ground_state_result.py +0 -8
  287. classiq/interface/chemistry/molecule.py +0 -71
  288. classiq/interface/execution/iqcc.py +0 -44
  289. classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
  290. classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
  291. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -6
  292. classiq/interface/generator/chemistry_function_params.py +0 -50
  293. classiq/interface/generator/entangler_params.py +0 -72
  294. classiq/interface/generator/entanglers.py +0 -14
  295. classiq/interface/generator/hamiltonian_evolution/qdrift.py +0 -27
  296. classiq/interface/generator/hartree_fock.py +0 -26
  297. classiq/interface/generator/hva.py +0 -22
  298. classiq/interface/generator/linear_pauli_rotations.py +0 -92
  299. classiq/interface/generator/qft.py +0 -37
  300. classiq/interface/generator/qsvm.py +0 -96
  301. classiq/interface/generator/state_preparation/__init__.py +0 -14
  302. classiq/interface/generator/state_preparation/bell_state_preparation.py +0 -27
  303. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +0 -28
  304. classiq/interface/generator/state_preparation/distributions.py +0 -53
  305. classiq/interface/generator/state_preparation/exponential_state_preparation.py +0 -14
  306. classiq/interface/generator/state_preparation/ghz_state_preparation.py +0 -14
  307. classiq/interface/generator/state_preparation/metrics.py +0 -41
  308. classiq/interface/generator/state_preparation/state_preparation.py +0 -113
  309. classiq/interface/generator/state_preparation/state_preparation_abc.py +0 -24
  310. classiq/interface/generator/state_preparation/uniform_distibution_state_preparation.py +0 -13
  311. classiq/interface/generator/state_preparation/w_state_preparation.py +0 -13
  312. classiq/interface/generator/ucc.py +0 -74
  313. classiq/interface/helpers/backward_compatibility.py +0 -9
  314. classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
  315. classiq/open_library/functions/lookup_table.py +0 -58
  316. classiq/qmod/builtins/functions/chemistry.py +0 -123
  317. classiq/qmod/builtins/functions/qsvm.py +0 -24
  318. classiq-0.92.0.dist-info/WHEEL +0 -4
@@ -1,15 +1,16 @@
1
1
  import inspect
2
2
  import sys
3
3
  import warnings
4
- from collections.abc import Mapping
4
+ from collections.abc import Callable, Mapping
5
+ from functools import wraps
6
+ from itertools import product
5
7
  from types import FrameType
6
8
  from typing import (
7
9
  Any,
8
- Callable,
9
10
  Final,
10
11
  NoReturn,
11
- Optional,
12
- Union,
12
+ ParamSpec,
13
+ TypeVar,
13
14
  overload,
14
15
  )
15
16
 
@@ -49,19 +50,40 @@ from classiq.interface.model.skip_control import SkipControl
49
50
  from classiq.interface.model.statement_block import StatementBlock
50
51
  from classiq.interface.model.within_apply_operation import WithinApply
51
52
 
53
+ from classiq.qmod.builtins.functions import H, S
52
54
  from classiq.qmod.generative import is_generative_mode
53
55
  from classiq.qmod.qmod_constant import QConstant
54
56
  from classiq.qmod.qmod_variable import Input, Output, QArray, QBit, QNum, QScalar, QVar
55
57
  from classiq.qmod.quantum_callable import QCallable
56
58
  from classiq.qmod.quantum_expandable import prepare_arg
59
+ from classiq.qmod.semantics.error_manager import ErrorManager
57
60
  from classiq.qmod.symbolic_expr import SymbolicExpr
58
- from classiq.qmod.utilities import Statements, get_source_ref, suppress_return_value
61
+ from classiq.qmod.utilities import (
62
+ RealFunction,
63
+ Statements,
64
+ get_source_ref,
65
+ qnum_values,
66
+ suppress_return_value,
67
+ )
59
68
 
60
69
  _MISSING_VALUE: Final[int] = -1
61
70
 
71
+ _Params = ParamSpec("_Params")
72
+ _RetType = TypeVar("_RetType")
73
+
74
+
75
+ def qmod_statement(func: Callable[_Params, _RetType]) -> Callable[_Params, _RetType]:
76
+ @wraps(func)
77
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
78
+ source_ref = get_source_ref(sys._getframe(1))
79
+ with ErrorManager().source_ref_context(source_ref):
80
+ return func(*args, **kwargs)
81
+
82
+ return wrapper
83
+
62
84
 
63
85
  @overload
64
- def allocate(num_qubits: Union[int, SymbolicExpr], out: Output[QVar]) -> None:
86
+ def allocate(num_qubits: int | SymbolicExpr, out: Output[QVar]) -> None:
65
87
  pass
66
88
 
67
89
 
@@ -72,15 +94,16 @@ def allocate(out: Output[QVar]) -> None:
72
94
 
73
95
  @overload
74
96
  def allocate(
75
- num_qubits: Union[int, SymbolicExpr],
76
- is_signed: Union[bool, SymbolicExpr],
77
- fraction_digits: Union[int, SymbolicExpr],
97
+ num_qubits: int | SymbolicExpr,
98
+ is_signed: bool | SymbolicExpr,
99
+ fraction_digits: int | SymbolicExpr,
78
100
  out: Output[QVar],
79
101
  ) -> None:
80
102
  pass
81
103
 
82
104
 
83
105
  @suppress_return_value
106
+ @qmod_statement
84
107
  def allocate(*args: Any, **kwargs: Any) -> None:
85
108
  """
86
109
  Initialize a quantum variable to a new quantum object in the zero state:
@@ -104,29 +127,34 @@ def allocate(*args: Any, **kwargs: Any) -> None:
104
127
  2. The synthesis engine automatically handles the allocation, either by drawing new qubits from the available pool or by reusing existing ones.
105
128
  """
106
129
  assert QCallable.CURRENT_EXPANDABLE is not None
107
- source_ref = get_source_ref(sys._getframe(1))
130
+ source_ref = get_source_ref(sys._getframe(2))
108
131
  if len(args) == 0:
109
132
  size = kwargs.get("num_qubits", None)
110
133
  is_signed = kwargs.get("is_signed", None)
111
134
  fraction_digits = kwargs.get("fraction_digits", None)
112
- target = kwargs["out"]
135
+ out = kwargs["out"]
113
136
  elif len(args) == 1:
114
137
  if "out" in kwargs:
115
138
  size = args[0]
116
139
  is_signed = kwargs.get("is_signed", None)
117
140
  fraction_digits = kwargs.get("fraction_digits", None)
118
- target = kwargs["out"]
141
+ out = kwargs["out"]
119
142
  else:
120
143
  size = None
121
144
  is_signed = None
122
145
  fraction_digits = None
123
- target = args[0]
146
+ out = args[0]
124
147
  elif len(args) == 2:
125
- size, target = args
148
+ size, out = args
126
149
  is_signed = kwargs.get("is_signed", None)
127
150
  fraction_digits = kwargs.get("fraction_digits", None)
128
151
  else:
129
- size, is_signed, fraction_digits, target = args
152
+ size, is_signed, fraction_digits, out = args
153
+ if not isinstance(out, QVar):
154
+ raise ClassiqValueError(
155
+ f"Argument 'out' of operator 'allocate' must be a quantum variable, got "
156
+ f"{type(out).__name__}"
157
+ )
130
158
  if isinstance(size, QConstant):
131
159
  size.add_to_model()
132
160
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
@@ -138,16 +166,17 @@ def allocate(*args: Any, **kwargs: Any) -> None:
138
166
  if fraction_digits is None
139
167
  else Expression(expr=str(fraction_digits))
140
168
  ),
141
- target=target.get_handle_binding(),
169
+ target=out.get_handle_binding(),
142
170
  source_ref=source_ref,
143
171
  )
144
172
  )
145
173
 
146
174
 
147
175
  @suppress_return_value
176
+ @qmod_statement
148
177
  def bind(
149
- source: Union[Input[QVar], list[Input[QVar]]],
150
- destination: Union[Output[QVar], list[Output[QVar]]],
178
+ source: Input[QVar] | list[Input[QVar]],
179
+ destination: Output[QVar] | list[Output[QVar]],
151
180
  ) -> None:
152
181
  """
153
182
  Reassign qubit or arrays of qubits by redirecting their logical identifiers.
@@ -166,7 +195,7 @@ def bind(
166
195
  For more details, see [Qmod Reference](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/bind).
167
196
  """
168
197
  assert QCallable.CURRENT_EXPANDABLE is not None
169
- source_ref = get_source_ref(sys._getframe(1))
198
+ source_ref = get_source_ref(sys._getframe(2))
170
199
  if not isinstance(source, list):
171
200
  source = [source]
172
201
  if not isinstance(destination, list):
@@ -181,10 +210,11 @@ def bind(
181
210
 
182
211
 
183
212
  @suppress_return_value
213
+ @qmod_statement
184
214
  def if_(
185
- condition: Union[SymbolicExpr, bool],
186
- then: Union[QCallable, Callable[[], Statements]],
187
- else_: Union[QCallable, Callable[[], Statements], int] = _MISSING_VALUE,
215
+ condition: SymbolicExpr | bool,
216
+ then: QCallable | Callable[[], Statements],
217
+ else_: QCallable | Callable[[], Statements] | int = _MISSING_VALUE,
188
218
  ) -> None:
189
219
  """
190
220
  Conditionally executes quantum operations based on a symbolic or boolean expression.
@@ -202,7 +232,7 @@ def if_(
202
232
  if else_ != _MISSING_VALUE:
203
233
  _validate_operand(else_)
204
234
  assert QCallable.CURRENT_EXPANDABLE is not None
205
- source_ref = get_source_ref(sys._getframe(1))
235
+ source_ref = get_source_ref(sys._getframe(2))
206
236
 
207
237
  if_stmt = ClassicalIf(
208
238
  condition=Expression(expr=str(condition)),
@@ -218,10 +248,11 @@ def if_(
218
248
 
219
249
 
220
250
  @suppress_return_value
251
+ @qmod_statement
221
252
  def control(
222
- ctrl: Union[SymbolicExpr, QBit, QArray[QBit], list[QVar]],
223
- stmt_block: Union[QCallable, Callable[[], Statements]],
224
- else_block: Union[QCallable, Callable[[], Statements], None] = None,
253
+ ctrl: SymbolicExpr | QBit | QArray[QBit] | list[QVar],
254
+ stmt_block: QCallable | Callable[[], Statements],
255
+ else_block: QCallable | Callable[[], Statements] | None = None,
225
256
  ) -> None:
226
257
  """
227
258
  Conditionally executes quantum operations based on the value of quantum variables or expressions.
@@ -241,7 +272,7 @@ def control(
241
272
  """
242
273
  _validate_operand(stmt_block)
243
274
  assert QCallable.CURRENT_EXPANDABLE is not None
244
- source_ref = get_source_ref(sys._getframe(1))
275
+ source_ref = get_source_ref(sys._getframe(2))
245
276
  control_stmt = Control(
246
277
  expression=Expression(expr=str(ctrl)),
247
278
  body=_operand_to_body(stmt_block, "stmt_block"),
@@ -256,10 +287,19 @@ def control(
256
287
 
257
288
 
258
289
  @suppress_return_value
259
- def skip_control(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
290
+ @qmod_statement
291
+ def skip_control(stmt_block: QCallable | Callable[[], Statements]) -> None:
292
+ """
293
+ Applies quantum statements unconditionally.
294
+
295
+ Args:
296
+ stmt_block: A callable that produces a quantum operation.
297
+
298
+ For more details, see [Qmod Reference](https://docs.classiq.io/latest/qmod-reference/language-reference/statements/skip-control).
299
+ """
260
300
  _validate_operand(stmt_block)
261
301
  assert QCallable.CURRENT_EXPANDABLE is not None
262
- source_ref = get_source_ref(sys._getframe(1))
302
+ source_ref = get_source_ref(sys._getframe(2))
263
303
  sc_stmt = SkipControl(
264
304
  body=_operand_to_body(stmt_block, "stmt_block"),
265
305
  source_ref=source_ref,
@@ -270,6 +310,7 @@ def skip_control(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None
270
310
 
271
311
 
272
312
  @suppress_return_value
313
+ @qmod_statement
273
314
  def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
274
315
  """
275
316
  Initialize a scalar quantum variable using an arithmetic expression.
@@ -283,7 +324,7 @@ def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
283
324
  target_var: An uninitialized scalar quantum variable
284
325
  """
285
326
  assert QCallable.CURRENT_EXPANDABLE is not None
286
- source_ref = get_source_ref(sys._getframe(1))
327
+ source_ref = get_source_ref(sys._getframe(2))
287
328
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
288
329
  ArithmeticOperation(
289
330
  expression=Expression(expr=str(expression)),
@@ -295,6 +336,7 @@ def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
295
336
 
296
337
 
297
338
  @suppress_return_value
339
+ @qmod_statement
298
340
  def assign_amplitude(expression: SymbolicExpr, target_var: QScalar) -> None:
299
341
  """
300
342
  Perform an amplitude-encoding assignment operation on a quantum variable and a
@@ -306,8 +348,15 @@ def assign_amplitude(expression: SymbolicExpr, target_var: QScalar) -> None:
306
348
  expression: A quantum arithmetic expression
307
349
  target_var: A scalar quantum variable
308
350
  """
351
+ warnings.warn(
352
+ "The 'assign_amplitude' function is deprecated and will no longer be "
353
+ "supported starting on 2025-12-03 at the earliest. Use 'assign_amplitude_table' "
354
+ "instead",
355
+ ClassiqDeprecationWarning,
356
+ stacklevel=3,
357
+ )
309
358
  assert QCallable.CURRENT_EXPANDABLE is not None
310
- source_ref = get_source_ref(sys._getframe(1))
359
+ source_ref = get_source_ref(sys._getframe(2))
311
360
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
312
361
  AmplitudeLoadingOperation(
313
362
  expression=Expression(expr=str(expression)),
@@ -318,6 +367,7 @@ def assign_amplitude(expression: SymbolicExpr, target_var: QScalar) -> None:
318
367
 
319
368
 
320
369
  @suppress_return_value
370
+ @qmod_statement
321
371
  def inplace_add(expression: SymbolicExpr, target_var: QScalar) -> None:
322
372
  """
323
373
  Add an arithmetic expression to a quantum variable.
@@ -329,7 +379,7 @@ def inplace_add(expression: SymbolicExpr, target_var: QScalar) -> None:
329
379
  target_var: A scalar quantum variable
330
380
  """
331
381
  assert QCallable.CURRENT_EXPANDABLE is not None
332
- source_ref = get_source_ref(sys._getframe(1))
382
+ source_ref = get_source_ref(sys._getframe(2))
333
383
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
334
384
  ArithmeticOperation(
335
385
  expression=Expression(expr=str(expression)),
@@ -341,6 +391,7 @@ def inplace_add(expression: SymbolicExpr, target_var: QScalar) -> None:
341
391
 
342
392
 
343
393
  @suppress_return_value
394
+ @qmod_statement
344
395
  def inplace_xor(expression: SymbolicExpr, target_var: QScalar) -> None:
345
396
  """
346
397
  Bitwise-XOR a quantum variable with an arithmetic expression.
@@ -352,7 +403,7 @@ def inplace_xor(expression: SymbolicExpr, target_var: QScalar) -> None:
352
403
  target_var: A scalar quantum variable
353
404
  """
354
405
  assert QCallable.CURRENT_EXPANDABLE is not None
355
- source_ref = get_source_ref(sys._getframe(1))
406
+ source_ref = get_source_ref(sys._getframe(2))
356
407
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
357
408
  ArithmeticOperation(
358
409
  expression=Expression(expr=str(expression)),
@@ -364,6 +415,7 @@ def inplace_xor(expression: SymbolicExpr, target_var: QScalar) -> None:
364
415
 
365
416
 
366
417
  @suppress_return_value
418
+ @qmod_statement
367
419
  def within_apply(
368
420
  within: Callable[[], Statements],
369
421
  apply: Callable[[], Statements],
@@ -383,7 +435,7 @@ def within_apply(
383
435
  _validate_operand(within)
384
436
  _validate_operand(apply)
385
437
  assert QCallable.CURRENT_EXPANDABLE is not None
386
- source_ref = get_source_ref(sys._getframe(1))
438
+ source_ref = get_source_ref(sys._getframe(2))
387
439
  within_apply_stmt = WithinApply(
388
440
  compute=_operand_to_body(within, "within"),
389
441
  action=_operand_to_body(apply, "apply"),
@@ -396,9 +448,8 @@ def within_apply(
396
448
 
397
449
 
398
450
  @suppress_return_value
399
- def repeat(
400
- count: Union[SymbolicExpr, int], iteration: Callable[[int], Statements]
401
- ) -> None:
451
+ @qmod_statement
452
+ def repeat(count: SymbolicExpr | int, iteration: Callable[[int], Statements]) -> None:
402
453
  """
403
454
  Executes a quantum loop a specified number of times, applying a quantum operation on each iteration.
404
455
 
@@ -424,7 +475,7 @@ def repeat(
424
475
  """
425
476
  _validate_operand(iteration, num_params=1)
426
477
  assert QCallable.CURRENT_EXPANDABLE is not None
427
- source_ref = get_source_ref(sys._getframe(1))
478
+ source_ref = get_source_ref(sys._getframe(2))
428
479
  iteration_operand = prepare_arg(
429
480
  QuantumOperandDeclaration(
430
481
  name=REPEAT_OPERATOR_NAME,
@@ -453,9 +504,10 @@ def repeat(
453
504
 
454
505
 
455
506
  @suppress_return_value
507
+ @qmod_statement
456
508
  def power(
457
- exponent: Union[SymbolicExpr, int],
458
- stmt_block: Union[QCallable, Callable[[], Statements]],
509
+ exponent: SymbolicExpr | int,
510
+ stmt_block: QCallable | Callable[[], Statements],
459
511
  ) -> None:
460
512
  """
461
513
  Apply a quantum operation raised to a symbolic or integer power.
@@ -487,7 +539,7 @@ def power(
487
539
  """
488
540
  _validate_operand(stmt_block)
489
541
  assert QCallable.CURRENT_EXPANDABLE is not None
490
- source_ref = get_source_ref(sys._getframe(1))
542
+ source_ref = get_source_ref(sys._getframe(2))
491
543
  power_stmt = Power(
492
544
  power=Expression(expr=str(exponent)),
493
545
  body=_operand_to_body(stmt_block, "stmt_block"),
@@ -499,7 +551,8 @@ def power(
499
551
 
500
552
 
501
553
  @suppress_return_value
502
- def invert(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
554
+ @qmod_statement
555
+ def invert(stmt_block: QCallable | Callable[[], Statements]) -> None:
503
556
  """
504
557
  Apply the inverse of a quantum gate.
505
558
 
@@ -523,7 +576,7 @@ def invert(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
523
576
  """
524
577
  _validate_operand(stmt_block)
525
578
  assert QCallable.CURRENT_EXPANDABLE is not None
526
- source_ref = get_source_ref(sys._getframe(1))
579
+ source_ref = get_source_ref(sys._getframe(2))
527
580
  invert_stmt = Invert(
528
581
  body=_operand_to_body(stmt_block, "stmt_block"), source_ref=source_ref
529
582
  )
@@ -532,25 +585,11 @@ def invert(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
532
585
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(invert_stmt)
533
586
 
534
587
 
535
- @overload
536
- def phase(
537
- phase_expr: Union[SymbolicExpr, float], theta: Union[SymbolicExpr, float] = 1.0
538
- ) -> None:
539
- pass
540
-
541
-
542
- @overload
543
- def phase(
544
- *, expr: Union[SymbolicExpr, float], theta: Union[SymbolicExpr, float] = 1.0
545
- ) -> None:
546
- pass
547
-
548
-
549
588
  @suppress_return_value
589
+ @qmod_statement
550
590
  def phase(
551
- phase_expr: Union[SymbolicExpr, float, None] = None,
552
- theta: Union[SymbolicExpr, float] = 1.0,
553
- expr: Any = None,
591
+ phase_expr: SymbolicExpr | float | None = None,
592
+ theta: SymbolicExpr | float = 1.0,
554
593
  ) -> None:
555
594
  """
556
595
  Applies a state-dependent or fixed phase shift (Z rotation) to the quantum state.
@@ -570,17 +609,7 @@ def phase(
570
609
  they are equivalent when the phase_expr is a single-qubit variable.
571
610
  """
572
611
  assert QCallable.CURRENT_EXPANDABLE is not None
573
- if expr is not None:
574
- warnings.warn(
575
- "Parameter 'expr' of function 'phase' has been renamed to "
576
- "'phase_expr'. Parameter 'expr' will no longer be supported starting on "
577
- "2025-09-19 at the earliest.\nHint: Change `phase(expr=..., theta=...)` to "
578
- "`phase(phase_expr=..., theta=...)` or `phase(..., ...)`.",
579
- category=ClassiqDeprecationWarning,
580
- stacklevel=2,
581
- )
582
- phase_expr = expr
583
- source_ref = get_source_ref(sys._getframe(1))
612
+ source_ref = get_source_ref(sys._getframe(2))
584
613
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
585
614
  PhaseOperation(
586
615
  expression=Expression(expr=str(phase_expr)),
@@ -591,12 +620,13 @@ def phase(
591
620
 
592
621
 
593
622
  @suppress_return_value
623
+ @qmod_statement
594
624
  def block(
595
- statements: Union[QCallable, Callable[[], Statements]],
625
+ statements: QCallable | Callable[[], Statements],
596
626
  ) -> None:
597
627
  _validate_operand(statements)
598
628
  assert QCallable.CURRENT_EXPANDABLE is not None
599
- source_ref = get_source_ref(sys._getframe(1))
629
+ source_ref = get_source_ref(sys._getframe(2))
600
630
 
601
631
  block_stmt = Block(
602
632
  statements=_operand_to_body(statements, "statements"),
@@ -617,20 +647,21 @@ def reset_bounds(
617
647
  @overload
618
648
  def reset_bounds(
619
649
  target_var: QNum,
620
- lower_bound: Union[float, SymbolicExpr],
621
- upper_bound: Union[float, SymbolicExpr],
650
+ lower_bound: float | SymbolicExpr,
651
+ upper_bound: float | SymbolicExpr,
622
652
  ) -> None:
623
653
  pass
624
654
 
625
655
 
626
656
  @suppress_return_value
657
+ @qmod_statement
627
658
  def reset_bounds(
628
659
  target_var: QNum,
629
- lower_bound: Optional[Union[float, SymbolicExpr]] = None,
630
- upper_bound: Optional[Union[float, SymbolicExpr]] = None,
660
+ lower_bound: float | SymbolicExpr | None = None,
661
+ upper_bound: float | SymbolicExpr | None = None,
631
662
  ) -> None:
632
663
  assert QCallable.CURRENT_EXPANDABLE is not None
633
- source_ref = get_source_ref(sys._getframe(1))
664
+ source_ref = get_source_ref(sys._getframe(2))
634
665
 
635
666
  lower_bound_expr = (
636
667
  None if lower_bound is None else Expression(expr=str(lower_bound))
@@ -660,6 +691,14 @@ def _validate_operand(stmt_block: Any, num_params: int = 0) -> None:
660
691
  )
661
692
  if isinstance(stmt_block, QCallable):
662
693
  return
694
+ if not callable(stmt_block):
695
+ _raise_operand_error(
696
+ lambda operation_name, operand_arg_name: (
697
+ f"Argument {operand_arg_name!r} to {operation_name!r} must be a "
698
+ f"callable object"
699
+ ),
700
+ num_params,
701
+ )
663
702
  op_spec = inspect.getfullargspec(stmt_block)
664
703
  params = op_spec.args[: len(op_spec.args) - len(op_spec.defaults or ())]
665
704
  if len(params) > num_params or (
@@ -726,7 +765,7 @@ def _get_operand_hint(
726
765
 
727
766
 
728
767
  def _operand_to_body(
729
- callable_: Union[QCallable, Callable[[], Statements]], param_name: str
768
+ callable_: QCallable | Callable[[], Statements], param_name: str
730
769
  ) -> StatementBlock:
731
770
  op_name = sys._getframe(1).f_code.co_name
732
771
  if (
@@ -748,10 +787,64 @@ def _operand_to_body(
748
787
  raise ValueError(f"Unexpected operand type: {type(to_operand)}")
749
788
 
750
789
 
790
+ def assign_amplitude_poly_sin(indicator: QBit, expr: SymbolicExpr) -> None:
791
+ """
792
+ Encodes the value of the sine/cosine of a polynomial into the amplitude of the
793
+ respective computational basis state:
794
+ \\( |x_1, x_2, \\ldots, x_n\\rangle|0\\rangle \\rightarrow cos(poly(x_1, x_2, \\ldots, x_n))|x_1, x_2, \\ldots, x_n\\rangle|0\\rangle + sin(poly(x_1, x_2, \\ldots, x_n))|x_1, x_2, \\ldots, x_n\\rangle|1\\rangle \\)
795
+
796
+ Args:
797
+ indicator: The quantum indicator qubit
798
+ expr: A polynomial expression over quantum scalars x_1, x_2, \\ldots, x_n
799
+ """
800
+ phase(-expr)
801
+ within_apply(
802
+ lambda: H(indicator),
803
+ lambda: control(indicator, lambda: phase(2 * expr)),
804
+ )
805
+ S(indicator)
806
+
807
+
808
+ def _get_qnum_values(num: QNum) -> list[float]:
809
+ size = num.size
810
+ is_signed = num.is_signed
811
+ fraction_digits = num.fraction_digits
812
+ if (
813
+ not isinstance(size, int)
814
+ or not isinstance(is_signed, bool)
815
+ or not isinstance(fraction_digits, int)
816
+ ):
817
+ raise ClassiqValueError(f"QNum argument {str(num)!r} has symbolic attributes")
818
+
819
+ return qnum_values(size, is_signed, fraction_digits)
820
+
821
+
822
+ def lookup_table(func: RealFunction, targets: QNum | list[QNum]) -> list[float]:
823
+ """
824
+ Reduces a classical function into a lookup table over all the possible values
825
+ of the quantum numbers.
826
+
827
+ Args:
828
+ func: A Python function
829
+ targets: One or more initialized quantum numbers
830
+
831
+ Returns:
832
+ The function's lookup table
833
+
834
+ Notes:
835
+ The QNum arguments must have generative attributes
836
+ """
837
+ if not isinstance(targets, list):
838
+ targets = [targets]
839
+ target_vals = [_get_qnum_values(target) for target in targets]
840
+ return [func(*vals[::-1]) for vals in product(*target_vals[::-1])]
841
+
842
+
751
843
  __all__ = [
752
844
  "allocate",
753
845
  "assign",
754
846
  "assign_amplitude",
847
+ "assign_amplitude_poly_sin",
755
848
  "bind",
756
849
  "block",
757
850
  "control",
@@ -759,6 +852,7 @@ __all__ = [
759
852
  "inplace_add",
760
853
  "inplace_xor",
761
854
  "invert",
855
+ "lookup_table",
762
856
  "phase",
763
857
  "power",
764
858
  "repeat",