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
@@ -2,10 +2,11 @@ import ast
2
2
  import functools
3
3
  import warnings
4
4
  from abc import abstractmethod
5
+ from collections.abc import Callable
5
6
  from dataclasses import is_dataclass
6
7
  from enum import EnumMeta
7
8
  from inspect import isclass
8
- from typing import Any, Callable, Optional, get_origin
9
+ from typing import Any, get_origin
9
10
 
10
11
  from classiq.interface.exceptions import ClassiqDeprecationWarning, ClassiqError
11
12
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
@@ -30,7 +31,7 @@ from classiq.qmod.generative import set_frontend_interpreter
30
31
  from classiq.qmod.global_declarative_switch import get_global_declarative_switch
31
32
  from classiq.qmod.qmod_constant import QConstant
32
33
  from classiq.qmod.qmod_parameter import CArray, CParamList
33
- from classiq.qmod.quantum_callable import QCallable, QCallableList
34
+ from classiq.qmod.quantum_callable import QCallable, QCallableList, QPerm, QPermList
34
35
  from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
35
36
  from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
36
37
  from classiq.qmod.semantics.validation.main_validation import validate_main_function
@@ -41,11 +42,13 @@ class BaseQFunc(QExpandable):
41
42
  def __init__(
42
43
  self,
43
44
  py_callable: Callable,
44
- compilation_metadata: Optional[CompilationMetadata] = None,
45
+ compilation_metadata: CompilationMetadata | None = None,
46
+ permutation: bool = False,
45
47
  ) -> None:
46
48
  super().__init__(py_callable)
47
49
  functools.update_wrapper(self, py_callable)
48
50
  self.compilation_metadata = compilation_metadata
51
+ self.permutation = permutation
49
52
 
50
53
  @property
51
54
  def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
@@ -84,10 +87,10 @@ class BaseQFunc(QExpandable):
84
87
  @abstractmethod
85
88
  def create_model(
86
89
  self,
87
- constraints: Optional[Constraints] = None,
88
- execution_preferences: Optional[ExecutionPreferences] = None,
89
- preferences: Optional[Preferences] = None,
90
- classical_execution_function: Optional[CFunc] = None,
90
+ constraints: Constraints | None = None,
91
+ execution_preferences: ExecutionPreferences | None = None,
92
+ preferences: Preferences | None = None,
93
+ classical_execution_function: CFunc | None = None,
91
94
  ) -> Model:
92
95
  pass
93
96
 
@@ -98,13 +101,17 @@ class QFunc(BaseQFunc):
98
101
  def __init__(
99
102
  self,
100
103
  py_callable: Callable,
101
- compilation_metadata: Optional[CompilationMetadata] = None,
104
+ compilation_metadata: CompilationMetadata | None = None,
105
+ permutation: bool = False,
102
106
  ) -> None:
103
107
  _validate_no_gen_params(py_callable.__annotations__)
104
- super().__init__(py_callable, compilation_metadata)
105
- if compilation_metadata is not None and compilation_metadata.unchecked:
106
- self.compilation_metadata: Optional[CompilationMetadata] = (
107
- CompilationMetadata(unchecked=compilation_metadata.unchecked)
108
+ super().__init__(py_callable, compilation_metadata, permutation)
109
+ if (
110
+ compilation_metadata is not None
111
+ and compilation_metadata.has_user_directives
112
+ ):
113
+ self.compilation_metadata: CompilationMetadata | None = (
114
+ compilation_metadata.copy_user_directives()
108
115
  )
109
116
  else:
110
117
  self.compilation_metadata = None
@@ -114,7 +121,9 @@ class QFunc(BaseQFunc):
114
121
  name = self._py_callable.__name__
115
122
  if name in self._qmodule.native_defs:
116
123
  return self._qmodule.native_defs[name]
117
- return infer_func_decl(self._py_callable, qmodule=self._qmodule)
124
+ return infer_func_decl(
125
+ self._py_callable, qmodule=self._qmodule, permutation=self.permutation
126
+ )
118
127
 
119
128
  def __call__(self, *args: Any, **kwargs: Any) -> None:
120
129
  self.expand()
@@ -122,10 +131,10 @@ class QFunc(BaseQFunc):
122
131
 
123
132
  def create_model(
124
133
  self,
125
- constraints: Optional[Constraints] = None,
126
- execution_preferences: Optional[ExecutionPreferences] = None,
127
- preferences: Optional[Preferences] = None,
128
- classical_execution_function: Optional[CFunc] = None,
134
+ constraints: Constraints | None = None,
135
+ execution_preferences: ExecutionPreferences | None = None,
136
+ preferences: Preferences | None = None,
137
+ classical_execution_function: CFunc | None = None,
129
138
  ) -> Model:
130
139
  self._qmodule.reset()
131
140
  QConstant.set_current_model(self._qmodule)
@@ -222,9 +231,10 @@ class ExternalQFunc(QTerminalCallable):
222
231
  FRAME_DEPTH = 2 # FIXME: Remove (CLS-2912)
223
232
  _decl: NamedParamsQuantumFunctionDeclaration
224
233
 
225
- def __init__(self, py_callable: Callable) -> None:
234
+ def __init__(self, py_callable: Callable, permutation: bool = False) -> None:
226
235
  self._py_callable = py_callable
227
- decl = infer_func_decl(py_callable)
236
+ self.permutation = permutation
237
+ decl = infer_func_decl(py_callable, permutation=permutation)
228
238
 
229
239
  py_callable.__annotations__.pop("return", None)
230
240
  if py_callable.__annotations__.keys() != {
@@ -272,10 +282,39 @@ class ExternalQFunc(QTerminalCallable):
272
282
  ):
273
283
  warnings.warn(
274
284
  (
275
- "Parameter type CArray[PauliTerm] to function 'suzuki_trotter' is "
276
- "deprecated and will no longer be supported starting on 21/7/2025 "
277
- "at the earliest. Instead, send a 'SparsePauliOp' (see "
278
- "https://docs.classiq.io/latest/qmod-reference/language-reference/classical-types/#hamiltonians)."
285
+ "Function 'suzuki_trotter' now receives a sparse Hamiltonian "
286
+ "('SparsePauliOp') instead of a list of non-sparse Pauli terms "
287
+ "('CArray[PauliTerm]').\n"
288
+ "Non-sparse pauli terms in 'suzuki_trotter' will no longer be "
289
+ "supported starting on 2025-07-21 at the earliest.\n"
290
+ "See https://docs.classiq.io/latest/qmod-reference/language-reference/classical-types/#hamiltonians"
291
+ ),
292
+ ClassiqDeprecationWarning,
293
+ stacklevel=2,
294
+ )
295
+ if (
296
+ self._py_callable.__name__ == "qdrift"
297
+ and len(args) > 0
298
+ and isinstance(args[0], (list, CParamList))
299
+ ):
300
+ warnings.warn(
301
+ (
302
+ "Function 'qdrift' now receives a sparse Hamiltonian "
303
+ "('SparsePauliOp') instead of a list of non-sparse Pauli terms "
304
+ "('CArray[PauliTerm]').\n"
305
+ "Non-sparse pauli terms in 'qdrift' will no longer be "
306
+ "supported starting on 2025-12-03 at the earliest.\n"
307
+ "See https://docs.classiq.io/latest/qmod-reference/language-reference/classical-types/#hamiltonians"
308
+ ),
309
+ ClassiqDeprecationWarning,
310
+ stacklevel=2,
311
+ )
312
+ if self._py_callable.__name__ == "exponentiation_with_depth_constraint":
313
+ warnings.warn(
314
+ (
315
+ "Function 'exponentiation_with_depth_constraint' is deprecated and will no "
316
+ "longer be supported starting on 2025-12-10 at the earliest. "
317
+ "Instead, use 'exponentiate'."
279
318
  ),
280
319
  ClassiqDeprecationWarning,
281
320
  stacklevel=2,
@@ -289,41 +328,48 @@ class GenerativeQFunc(BaseQFunc):
289
328
  def __init__(
290
329
  self,
291
330
  py_callable: Callable,
292
- func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
293
- compilation_metadata: Optional[CompilationMetadata] = None,
331
+ func_decl: NamedParamsQuantumFunctionDeclaration | None = None,
332
+ compilation_metadata: CompilationMetadata | None = None,
333
+ permutation: bool = False,
294
334
  ) -> None:
295
- super().__init__(py_callable, compilation_metadata)
335
+ super().__init__(py_callable, compilation_metadata, permutation)
296
336
  self._func_decl = func_decl
297
- self._inferred_func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None
337
+ self._inferred_func_decl: NamedParamsQuantumFunctionDeclaration | None = None
298
338
 
299
339
  @property
300
340
  def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
301
341
  if self._func_decl is not None:
302
342
  return self._func_decl
303
343
  if self._inferred_func_decl is None:
304
- self._inferred_func_decl = infer_func_decl(self._py_callable, self._qmodule)
344
+ self._inferred_func_decl = infer_func_decl(
345
+ self._py_callable, self._qmodule, permutation=self.permutation
346
+ )
305
347
  return self._inferred_func_decl
306
348
 
307
349
  def __call__(self, *args: Any, **kwargs: Any) -> None:
308
350
  if get_global_declarative_switch():
309
- return QFunc(self._py_callable, self.compilation_metadata)(*args, **kwargs)
351
+ return QFunc(
352
+ self._py_callable,
353
+ self.compilation_metadata,
354
+ permutation=self.permutation,
355
+ )(*args, **kwargs)
310
356
  if self.func_decl.name not in self._qmodule.generative_functions:
311
357
  self._qmodule.generative_functions[self.func_decl.name] = self
312
358
  if self._func_decl is None:
313
359
  self._inferred_func_decl = infer_func_decl(
314
- self._py_callable, self._qmodule
360
+ self._py_callable, self._qmodule, permutation=self.permutation
315
361
  )
316
362
  super().__call__(*args, **kwargs)
317
363
 
318
364
  def create_model(
319
365
  self,
320
- constraints: Optional[Constraints] = None,
321
- execution_preferences: Optional[ExecutionPreferences] = None,
322
- preferences: Optional[Preferences] = None,
323
- classical_execution_function: Optional[CFunc] = None,
366
+ constraints: Constraints | None = None,
367
+ execution_preferences: ExecutionPreferences | None = None,
368
+ preferences: Preferences | None = None,
369
+ classical_execution_function: CFunc | None = None,
324
370
  ) -> Model:
325
371
  if get_global_declarative_switch():
326
- return QFunc(self._py_callable).create_model(
372
+ return QFunc(self._py_callable, permutation=self.permutation).create_model(
327
373
  constraints,
328
374
  execution_preferences,
329
375
  preferences,
@@ -338,7 +384,7 @@ class GenerativeQFunc(BaseQFunc):
338
384
 
339
385
  _dec_main.__annotations__ = self._py_callable.__annotations__
340
386
 
341
- return QFunc(_dec_main).create_model(
387
+ return QFunc(_dec_main, permutation=self.permutation).create_model(
342
388
  constraints=constraints,
343
389
  execution_preferences=execution_preferences,
344
390
  preferences=preferences,
@@ -371,6 +417,8 @@ def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
371
417
  or get_origin(annotation) is CArray
372
418
  or (get_origin(annotation) or annotation) is QCallable
373
419
  or (get_origin(annotation) or annotation) is QCallableList
420
+ or (get_origin(annotation) or annotation) is QPerm
421
+ or (get_origin(annotation) or annotation) is QPermList
374
422
  or is_qvar(annotation)
375
423
  )
376
424
  }
@@ -1,10 +1,10 @@
1
1
  from collections.abc import Iterator, Mapping
2
2
  from contextlib import contextmanager
3
- from typing import Any, Optional
3
+ from typing import Any
4
4
 
5
5
  from classiq.interface.exceptions import ClassiqError
6
6
  from classiq.interface.model.model import Model
7
- from classiq.interface.model.model_visitor import ModelVisitor
7
+ from classiq.interface.model.model_visitor import ModelStatementsVisitor
8
8
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
9
9
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
10
10
  from classiq.interface.model.quantum_function_declaration import (
@@ -47,7 +47,7 @@ def _annotate_function_call_decl(
47
47
  qlambda.set_op_decl(param)
48
48
 
49
49
 
50
- class _CallLambdaAnnotator(ModelVisitor):
50
+ class _CallLambdaAnnotator(ModelStatementsVisitor):
51
51
  def __init__(
52
52
  self, quantum_functions: Mapping[str, QuantumFunctionDeclaration]
53
53
  ) -> None:
@@ -76,12 +76,12 @@ class _CallLambdaAnnotator(ModelVisitor):
76
76
  _annotate_function_call_decl(
77
77
  call, self._quantum_functions | self._current_operands
78
78
  )
79
- self.generic_visit(call)
79
+ self.visit(call.positional_args)
80
80
 
81
81
 
82
82
  def resolve_function_calls(
83
83
  root: Any,
84
- quantum_function_dict: Optional[Mapping[str, QuantumFunctionDeclaration]] = None,
84
+ quantum_function_dict: Mapping[str, QuantumFunctionDeclaration] | None = None,
85
85
  annotate_types: bool = True,
86
86
  ) -> None:
87
87
  if quantum_function_dict is None:
@@ -1,8 +1,6 @@
1
1
  from collections.abc import Iterator
2
2
  from contextlib import contextmanager
3
- from typing import Optional
4
3
 
5
- from classiq.interface.ast_node import ASTNode
6
4
  from classiq.interface.exceptions import CLASSIQ_SLACK_COMMUNITY_LINK
7
5
  from classiq.interface.source_reference import SourceReference, SourceReferencedError
8
6
 
@@ -19,14 +17,14 @@ class ErrorManager:
19
17
  self._instantiated = True
20
18
  self._errors: list[SourceReferencedError] = []
21
19
  self._warnings: list[SourceReferencedError] = []
22
- self._current_nodes_stack: list[ASTNode] = []
20
+ self._current_refs_stack: list[SourceReference | None] = []
23
21
  self._call_stack: list[str] = []
24
22
  self._ignore_errors: bool = False
25
23
 
26
24
  @property
27
- def _current_source_ref(self) -> Optional[SourceReference]:
28
- if self._current_nodes_stack:
29
- return self._current_nodes_stack[-1].source_ref
25
+ def _current_source_ref(self) -> SourceReference | None:
26
+ if self._current_refs_stack:
27
+ return self._current_refs_stack[-1]
30
28
  return None
31
29
 
32
30
  @contextmanager
@@ -50,8 +48,8 @@ class ErrorManager:
50
48
  self,
51
49
  error: str,
52
50
  *,
53
- source_ref: Optional[SourceReference] = None,
54
- function: Optional[str] = None,
51
+ source_ref: SourceReference | None = None,
52
+ function: str | None = None,
55
53
  warning: bool = False,
56
54
  ) -> None:
57
55
  if self._ignore_errors:
@@ -80,7 +78,7 @@ class ErrorManager:
80
78
  self.clear_warnings()
81
79
 
82
80
  def clear_errors(self) -> None:
83
- self._current_nodes_stack = []
81
+ self._current_refs_stack = []
84
82
  self._errors = []
85
83
 
86
84
  def clear_warnings(self) -> None:
@@ -93,7 +91,7 @@ class ErrorManager:
93
91
  return len(self._warnings) > 0
94
92
 
95
93
  def report_errors(
96
- self, error_type: type[Exception], mask: Optional[list[int]] = None
94
+ self, error_type: type[Exception], mask: list[int] | None = None
97
95
  ) -> None:
98
96
  if self.has_errors():
99
97
  errors = (
@@ -105,14 +103,14 @@ class ErrorManager:
105
103
  raise error_type("\n\t" + "\n\t".join(errors))
106
104
 
107
105
  @property
108
- def current_function(self) -> Optional[str]:
106
+ def current_function(self) -> str | None:
109
107
  return self._call_stack[-1] if self._call_stack else None
110
108
 
111
109
  @contextmanager
112
- def node_context(self, node: ASTNode) -> Iterator[None]:
113
- self._current_nodes_stack.append(node)
110
+ def source_ref_context(self, ref: SourceReference | None) -> Iterator[None]:
111
+ self._current_refs_stack.append(ref)
114
112
  yield
115
- self._current_nodes_stack.pop()
113
+ self._current_refs_stack.pop()
116
114
 
117
115
  @contextmanager
118
116
  def call(self, func_name: str) -> Iterator[None]:
@@ -1,4 +1,3 @@
1
- from classiq.interface.helpers.backward_compatibility import zip_strict
2
1
  from classiq.interface.model.port_declaration import PortDeclaration
3
2
  from classiq.interface.model.quantum_function_declaration import (
4
3
  AnonQuantumOperandDeclaration,
@@ -15,7 +14,7 @@ def get_renamed_parameters(
15
14
  renamed_parameters: list[str] = []
16
15
  renamed_operands: dict[str, QuantumOperandDeclaration] = {}
17
16
  renamed_ports: list[PortDeclaration] = []
18
- for param, param_name in zip_strict(
17
+ for param, param_name in zip(
19
18
  lambda_func.func_decl.positional_arg_declarations,
20
19
  lambda_func.pos_rename_params,
21
20
  strict=False,
@@ -1,5 +1,4 @@
1
1
  from collections.abc import Sequence
2
- from typing import Union
3
2
 
4
3
  from classiq.interface.exceptions import ClassiqExpansionError
5
4
  from classiq.interface.generator.functions.type_name import TypeName
@@ -16,7 +15,7 @@ TYPE_EXISTS_ERROR_MESSAGE = "Type {!r} already exists"
16
15
 
17
16
 
18
17
  def check_duplicate_types(
19
- types: Sequence[Union[EnumDeclaration, StructDeclaration, QStructDeclaration]],
18
+ types: Sequence[EnumDeclaration | StructDeclaration | QStructDeclaration],
20
19
  ) -> None:
21
20
  known_types = {type_.name for type_ in BUILTIN_ENUM_DECLARATIONS.values()}
22
21
  known_types |= {type_.name for type_ in BUILTIN_STRUCT_DECLARATIONS.values()}
classiq/qmod/symbolic.py CHANGED
@@ -2,9 +2,7 @@ import sys
2
2
  from typing import (
3
3
  TYPE_CHECKING,
4
4
  Any,
5
- Optional,
6
5
  TypeVar,
7
- Union,
8
6
  overload,
9
7
  )
10
8
 
@@ -52,7 +50,7 @@ def symbolic_function(*args: Any, return_type: None = None) -> CParamScalar: ...
52
50
  def symbolic_function(*args: Any, return_type: type[T]) -> T: ...
53
51
 
54
52
 
55
- def symbolic_function(*args: Any, return_type: Optional[type[T]] = None) -> CParam:
53
+ def symbolic_function(*args: Any, return_type: type[T] | None = None) -> CParam:
56
54
  qmodule = (
57
55
  model_state_container.QMODULE
58
56
  ) # FIXME: https://classiq.atlassian.net/browse/CAD-15126
@@ -321,7 +319,7 @@ def _subscript_to_str(index: Any) -> str:
321
319
 
322
320
 
323
321
  def subscript(
324
- array: Union[list, CArray[CReal], np.ndarray],
322
+ array: list | CArray[CReal] | np.ndarray,
325
323
  index: Any,
326
324
  ) -> CParamScalar:
327
325
  return CParamScalar(
@@ -6,6 +6,8 @@ from typing import Any
6
6
 
7
7
  import sympy
8
8
 
9
+ from classiq.interface.exceptions import ClassiqTypeError
10
+
9
11
  from classiq.qmod.utilities import qmod_val_to_expr_str
10
12
 
11
13
 
@@ -24,7 +26,7 @@ class Symbolic:
24
26
  try:
25
27
  return bool(ast.literal_eval(self._expr))
26
28
  except ValueError:
27
- raise TypeError(
29
+ raise ClassiqTypeError(
28
30
  f"Symbolic expression {self._expr!r} cannot be converted to bool"
29
31
  ) from None
30
32
 
@@ -38,12 +40,16 @@ class SymbolicExpr(Symbolic):
38
40
  if not isinstance(
39
41
  lhs, (SymbolicExpr, int, float, bool, PythonEnum, sympy.Basic)
40
42
  ):
41
- raise TypeError(f"Invalid lhs argument {lhs!r} for binary operation {op!r}")
43
+ raise ClassiqTypeError(
44
+ f"Invalid lhs argument {lhs!r} for binary operation {op!r}"
45
+ )
42
46
 
43
47
  if not isinstance(
44
48
  rhs, (SymbolicExpr, int, float, bool, PythonEnum, sympy.Basic)
45
49
  ):
46
- raise TypeError(f"Invalid lhs argument {rhs!r} for binary operation {op!r}")
50
+ raise ClassiqTypeError(
51
+ f"Invalid lhs argument {rhs!r} for binary operation {op!r}"
52
+ )
47
53
 
48
54
  lhs_str = qmod_val_to_expr_str(lhs)
49
55
  if not isinstance(lhs, (int, float, bool, PythonEnum)):
@@ -62,7 +68,9 @@ class SymbolicExpr(Symbolic):
62
68
  @staticmethod
63
69
  def _unary_op(arg: Any, op: str) -> SymbolicExpr:
64
70
  if not isinstance(arg, (SymbolicExpr, int, float, bool)):
65
- raise TypeError(f"Invalid argument {arg!r} for unary operation {op!r}")
71
+ raise ClassiqTypeError(
72
+ f"Invalid argument {arg!r} for unary operation {op!r}"
73
+ )
66
74
 
67
75
  arg_is_quantum = isinstance(arg, SymbolicExpr) and arg.is_quantum
68
76
 
classiq/qmod/utilities.py CHANGED
@@ -3,17 +3,14 @@ import inspect
3
3
  import itertools
4
4
  import keyword
5
5
  import sys
6
- from collections import Counter
7
- from collections.abc import Iterable
6
+ from collections.abc import Callable, Iterable
8
7
  from enum import Enum as PythonEnum
9
8
  from types import FrameType
10
9
  from typing import (
11
10
  TYPE_CHECKING,
12
11
  Any,
13
- Callable,
14
12
  ForwardRef,
15
13
  Literal,
16
- Optional,
17
14
  Union,
18
15
  get_args,
19
16
  get_origin,
@@ -49,7 +46,7 @@ def unmangle_keyword(name: None) -> None:
49
46
  pass
50
47
 
51
48
 
52
- def unmangle_keyword(name: Optional[str]) -> Optional[str]:
49
+ def unmangle_keyword(name: str | None) -> str | None:
53
50
  if name is None:
54
51
  return None
55
52
  if name[-1] == "_" and keyword.iskeyword(name[:-1]):
@@ -60,10 +57,7 @@ def unmangle_keyword(name: Optional[str]) -> Optional[str]:
60
57
  def version_portable_get_args(py_type: type) -> tuple:
61
58
  if get_origin(py_type) is None:
62
59
  return tuple()
63
- if sys.version_info[0:2] < (3, 10):
64
- type_args = get_args(py_type) # The result of __class_getitem__
65
- else:
66
- type_args = get_args(py_type)[0]
60
+ type_args = get_args(py_type)[0]
67
61
  if not isinstance(type_args, tuple):
68
62
  return (type_args,)
69
63
  return tuple(
@@ -76,6 +70,12 @@ def version_portable_get_args(py_type: type) -> tuple:
76
70
  )
77
71
 
78
72
 
73
+ def type_to_str(py_type: Any) -> str:
74
+ if isinstance(py_type, type):
75
+ return py_type.__name__
76
+ return str(py_type)
77
+
78
+
79
79
  def get_source_ref(frame: FrameType) -> SourceReference:
80
80
  filename = inspect.getfile(frame)
81
81
  lineno = frame.f_lineno
@@ -101,6 +101,8 @@ def get_source_ref(frame: FrameType) -> SourceReference:
101
101
 
102
102
 
103
103
  def qmod_val_to_expr_str(val: Any) -> str:
104
+ from classiq.qmod.qmod_parameter import CParamList
105
+
104
106
  if isinstance(val, sympy.Basic):
105
107
  return str(val)
106
108
 
@@ -122,7 +124,7 @@ def qmod_val_to_expr_str(val: Any) -> str:
122
124
  )
123
125
  return f"struct_literal({val.struct_declaration.name}, {kwargs_str})"
124
126
 
125
- if isinstance(val, Iterable):
127
+ if isinstance(val, Iterable) and not isinstance(val, CParamList):
126
128
  elements_str = ", ".join([qmod_val_to_expr_str(elem) for elem in val])
127
129
  return f"[{elements_str}]"
128
130
 
@@ -138,7 +140,7 @@ def unwrap_forward_ref(x: Any) -> Any:
138
140
  return x
139
141
 
140
142
 
141
- def varname(depth: int) -> Optional[str]:
143
+ def varname(depth: int) -> str | None:
142
144
  frame = sys._getframe(depth)
143
145
  codes = inspect.getframeinfo(frame).code_context
144
146
  if codes is None or len(codes) != 1:
@@ -192,13 +194,4 @@ def qnum_attributes(max_size: int) -> list[tuple[int, bool, int]]:
192
194
  ]
193
195
 
194
196
 
195
- _VAR_NAME_COUNTER: Counter[str] = Counter()
196
-
197
-
198
- def get_temp_var_name(var_name: str = "temp") -> str:
199
- n = _VAR_NAME_COUNTER[var_name]
200
- _VAR_NAME_COUNTER[var_name] += 1
201
- return f"{var_name}_{n}"
202
-
203
-
204
197
  RealFunction = Callable[Params, float]
@@ -1,6 +1,5 @@
1
1
  import json
2
2
  from pathlib import Path
3
- from typing import Optional, Union
4
3
 
5
4
  from classiq.interface.constants import DEFAULT_DECIMAL_PRECISION
6
5
  from classiq.interface.model.model import Model, SerializedModel
@@ -14,9 +13,9 @@ _SYNTHESIS_OPTIONS_SUFFIX = "synthesis_options.json"
14
13
 
15
14
 
16
15
  def write_qmod(
17
- model: Union[SerializedModel, QFunc, GenerativeQFunc],
16
+ model: SerializedModel | QFunc | GenerativeQFunc,
18
17
  name: str,
19
- directory: Optional[Path] = None,
18
+ directory: Path | None = None,
20
19
  decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
21
20
  symbolic_only: bool = True,
22
21
  ) -> None:
@@ -58,7 +57,7 @@ def write_qmod(
58
57
 
59
58
 
60
59
  def prepare_write_qmod_model(
61
- model: Union[SerializedModel, QFunc, GenerativeQFunc], symbolic_only: bool
60
+ model: SerializedModel | QFunc | GenerativeQFunc, symbolic_only: bool
62
61
  ) -> Model:
63
62
  if isinstance(model, str) and hasattr(model, "entry_point") and symbolic_only:
64
63
  model_obj = Model.model_validate_json(model)
@@ -1,5 +1,3 @@
1
- from typing import Optional
2
-
3
1
  from classiq.interface.executor.quantum_program_params import (
4
2
  ParameterAssignmentsParams,
5
3
  TranspilationParams,
@@ -19,7 +17,7 @@ async def transpile_async(params: TranspilationParams) -> QuantumProgram:
19
17
 
20
18
 
21
19
  def transpile(
22
- quantum_program: QuantumProgram, preferences: Optional[Preferences] = None
20
+ quantum_program: QuantumProgram, preferences: Preferences | None = None
23
21
  ) -> QuantumProgram:
24
22
  """
25
23
  Transpiles a quantum program.
classiq/synthesis.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional, Union
1
+ from typing import Any
2
2
 
3
3
  from classiq.interface.analyzer.result import QasmCode, QmodCode
4
4
  from classiq.interface.exceptions import ClassiqError, ClassiqValueError
@@ -62,10 +62,10 @@ async def synthesize_async(
62
62
 
63
63
 
64
64
  def synthesize(
65
- model: Union[SerializedModel, BaseQFunc],
65
+ model: SerializedModel | BaseQFunc,
66
66
  auto_show: bool = False,
67
- constraints: Optional[Constraints] = None,
68
- preferences: Optional[Preferences] = None,
67
+ constraints: Constraints | None = None,
68
+ preferences: Preferences | None = None,
69
69
  ) -> QuantumProgram:
70
70
  """
71
71
  Synthesize a model with the Classiq engine to receive a quantum program.
@@ -112,6 +112,10 @@ def qasm_to_qmod(qasm: str, qmod_format: QmodFormat) -> str:
112
112
  """
113
113
  Decompiles QASM to Native/Python Qmod.
114
114
 
115
+ Returns Qmod code as a string. Native Qmod can be synthesized in the Classiq IDE,
116
+ while Python Qmod can be copy-pasted to a Python file (`.py`) and synthesized by
117
+ calling `synthesize(main)`.
118
+
115
119
  Args:
116
120
  qasm: QASM 2 or QASM 3 code
117
121
  qmod_format: The requested output format
@@ -129,7 +133,7 @@ def qasm_to_qmod(qasm: str, qmod_format: QmodFormat) -> str:
129
133
 
130
134
  def set_preferences(
131
135
  serialized_model: SerializedModel,
132
- preferences: Optional[Preferences] = None,
136
+ preferences: Preferences | None = None,
133
137
  **kwargs: Any,
134
138
  ) -> SerializedModel:
135
139
  """
@@ -177,7 +181,7 @@ def update_preferences(
177
181
 
178
182
  def set_constraints(
179
183
  serialized_model: SerializedModel,
180
- constraints: Optional[Constraints] = None,
184
+ constraints: Constraints | None = None,
181
185
  **kwargs: Any,
182
186
  ) -> SerializedModel:
183
187
  """
@@ -225,7 +229,7 @@ def update_constraints(
225
229
 
226
230
  def set_execution_preferences(
227
231
  serialized_model: SerializedModel,
228
- execution_preferences: Optional[ExecutionPreferences] = None,
232
+ execution_preferences: ExecutionPreferences | None = None,
229
233
  **kwargs: Any,
230
234
  ) -> SerializedModel:
231
235
  """