classiq 0.52.0__py3-none-any.whl → 0.54.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 (303) hide show
  1. classiq/__init__.py +1 -3
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/__init__.py +0 -20
  4. classiq/_internals/api_wrapper.py +23 -17
  5. classiq/_internals/async_utils.py +1 -3
  6. classiq/_internals/authentication/auth0.py +5 -5
  7. classiq/_internals/authentication/device.py +5 -4
  8. classiq/_internals/authentication/password_manager.py +3 -3
  9. classiq/_internals/authentication/token_manager.py +3 -2
  10. classiq/_internals/client.py +11 -13
  11. classiq/_internals/config.py +2 -2
  12. classiq/_internals/jobs.py +7 -6
  13. classiq/_internals/type_validation.py +9 -9
  14. classiq/analyzer/__init__.py +1 -3
  15. classiq/analyzer/analyzer.py +8 -7
  16. classiq/analyzer/analyzer_utilities.py +8 -8
  17. classiq/analyzer/rb.py +11 -11
  18. classiq/applications/__init__.py +1 -3
  19. classiq/applications/chemistry/__init__.py +1 -3
  20. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  21. classiq/applications/chemistry/chemistry_model_constructor.py +10 -9
  22. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +26 -9
  23. classiq/applications/combinatorial_helpers/encoding_mapping.py +10 -10
  24. classiq/applications/combinatorial_helpers/encoding_utils.py +4 -4
  25. classiq/applications/combinatorial_helpers/memory.py +5 -7
  26. classiq/applications/combinatorial_helpers/optimization_model.py +43 -24
  27. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +4 -6
  28. classiq/applications/combinatorial_helpers/pyomo_utils.py +95 -24
  29. classiq/applications/combinatorial_helpers/sympy_utils.py +2 -2
  30. classiq/applications/combinatorial_helpers/transformations/encoding.py +8 -8
  31. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -5
  32. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +7 -9
  33. classiq/applications/combinatorial_helpers/transformations/penalty.py +1 -2
  34. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -2
  35. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +1 -2
  36. classiq/applications/combinatorial_optimization/__init__.py +1 -3
  37. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  38. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  39. classiq/applications/finance/__init__.py +1 -3
  40. classiq/applications/grover/__init__.py +1 -3
  41. classiq/applications/grover/grover_model_constructor.py +7 -9
  42. classiq/applications/hamiltonian/pauli_decomposition.py +6 -6
  43. classiq/applications/qnn/__init__.py +1 -3
  44. classiq/applications/qnn/circuit_utils.py +5 -5
  45. classiq/applications/qnn/datasets/__init__.py +1 -3
  46. classiq/applications/qnn/datasets/dataset_base_classes.py +5 -4
  47. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  48. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  49. classiq/applications/qnn/qlayer.py +25 -6
  50. classiq/applications/qnn/torch_utils.py +2 -2
  51. classiq/applications/qnn/types.py +5 -5
  52. classiq/applications/qsvm/qsvm.py +1 -3
  53. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  54. classiq/applications/qsvm/qsvm_model_constructor.py +5 -5
  55. classiq/execution/__init__.py +3 -3
  56. classiq/execution/all_hardware_devices.py +1 -3
  57. classiq/execution/execution_session.py +57 -16
  58. classiq/execution/iqcc.py +1 -1
  59. classiq/execution/jobs.py +4 -4
  60. classiq/execution/qaoa.py +84 -0
  61. classiq/execution/qnn.py +3 -3
  62. classiq/executor.py +4 -4
  63. classiq/interface/_version.py +1 -1
  64. classiq/interface/analyzer/analysis_params.py +9 -10
  65. classiq/interface/analyzer/cytoscape_graph.py +5 -5
  66. classiq/interface/analyzer/result.py +17 -17
  67. classiq/interface/applications/qsvm.py +6 -10
  68. classiq/interface/backend/backend_preferences.py +4 -3
  69. classiq/interface/backend/ionq/ionq_quantum_program.py +4 -5
  70. classiq/interface/backend/pydantic_backend.py +1 -2
  71. classiq/interface/chemistry/fermionic_operator.py +5 -5
  72. classiq/interface/chemistry/ground_state_problem.py +7 -8
  73. classiq/interface/chemistry/molecule.py +4 -4
  74. classiq/interface/chemistry/operator.py +11 -13
  75. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  76. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  77. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  78. classiq/interface/combinatorial_optimization/examples/mht.py +2 -3
  79. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  80. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  81. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +5 -7
  82. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  83. classiq/interface/combinatorial_optimization/result.py +1 -3
  84. classiq/interface/debug_info/debug_info.py +8 -7
  85. classiq/interface/exceptions.py +11 -7
  86. classiq/interface/execution/iqcc.py +1 -3
  87. classiq/interface/execution/jobs.py +2 -2
  88. classiq/interface/execution/primitives.py +3 -3
  89. classiq/interface/executor/aws_execution_cost.py +4 -4
  90. classiq/interface/executor/execution_request.py +2 -3
  91. classiq/interface/executor/execution_result.py +3 -3
  92. classiq/interface/executor/iqae_result.py +3 -5
  93. classiq/interface/executor/optimizer_preferences.py +2 -2
  94. classiq/interface/executor/quantum_code.py +6 -6
  95. classiq/interface/executor/register_initialization.py +2 -4
  96. classiq/interface/executor/result.py +35 -28
  97. classiq/interface/executor/vqe_result.py +8 -8
  98. classiq/interface/finance/function_input.py +2 -2
  99. classiq/interface/finance/gaussian_model_input.py +5 -5
  100. classiq/interface/finance/log_normal_model_input.py +2 -2
  101. classiq/interface/finance/model_input.py +1 -2
  102. classiq/interface/generator/adjacency.py +1 -3
  103. classiq/interface/generator/ansatz_library.py +4 -4
  104. classiq/interface/generator/application_apis/finance_declarations.py +1 -1
  105. classiq/interface/generator/arith/argument_utils.py +3 -3
  106. classiq/interface/generator/arith/arithmetic.py +7 -7
  107. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +5 -5
  108. classiq/interface/generator/arith/arithmetic_expression_abc.py +11 -11
  109. classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
  110. classiq/interface/generator/arith/arithmetic_expression_validator.py +8 -8
  111. classiq/interface/generator/arith/arithmetic_operations.py +4 -3
  112. classiq/interface/generator/arith/arithmetic_param_getters.py +6 -6
  113. classiq/interface/generator/arith/arithmetic_result_builder.py +9 -9
  114. classiq/interface/generator/arith/ast_node_rewrite.py +2 -1
  115. classiq/interface/generator/arith/binary_ops.py +10 -13
  116. classiq/interface/generator/arith/extremum_operations.py +3 -2
  117. classiq/interface/generator/arith/logical_ops.py +7 -6
  118. classiq/interface/generator/arith/number_utils.py +4 -4
  119. classiq/interface/generator/arith/register_user_input.py +4 -4
  120. classiq/interface/generator/arith/unary_ops.py +2 -1
  121. classiq/interface/generator/builtin_api_builder.py +2 -1
  122. classiq/interface/generator/circuit_code/circuit_code.py +4 -4
  123. classiq/interface/generator/circuit_code/types_and_constants.py +3 -5
  124. classiq/interface/generator/complex_type.py +1 -2
  125. classiq/interface/generator/control_state.py +2 -2
  126. classiq/interface/generator/custom_ansatz.py +1 -3
  127. classiq/interface/generator/distance.py +3 -5
  128. classiq/interface/generator/excitations.py +3 -2
  129. classiq/interface/generator/expressions/enums/finance_functions.py +1 -3
  130. classiq/interface/generator/expressions/evaluated_expression.py +4 -3
  131. classiq/interface/generator/expressions/expression.py +4 -5
  132. classiq/interface/generator/expressions/expression_constants.py +4 -4
  133. classiq/interface/generator/expressions/qmod_qarray_proxy.py +2 -1
  134. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -1
  135. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +2 -1
  136. classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -1
  137. classiq/interface/generator/expressions/qmod_struct_instance.py +2 -1
  138. classiq/interface/generator/expressions/sympy_supported_expressions.py +11 -13
  139. classiq/interface/generator/finance.py +2 -2
  140. classiq/interface/generator/function_param_library.py +6 -6
  141. classiq/interface/generator/function_params.py +13 -19
  142. classiq/interface/generator/functions/classical_function_declaration.py +4 -3
  143. classiq/interface/generator/functions/classical_type.py +13 -13
  144. classiq/interface/generator/functions/concrete_types.py +1 -2
  145. classiq/interface/generator/functions/function_declaration.py +1 -1
  146. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  147. classiq/interface/generator/functions/type_name.py +3 -2
  148. classiq/interface/generator/generated_circuit_data.py +34 -22
  149. classiq/interface/generator/grover_diffuser.py +7 -7
  150. classiq/interface/generator/grover_operator.py +2 -2
  151. classiq/interface/generator/hardware/hardware_data.py +7 -6
  152. classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
  153. classiq/interface/generator/identity.py +5 -6
  154. classiq/interface/generator/linear_pauli_rotations.py +6 -6
  155. classiq/interface/generator/mcu.py +2 -2
  156. classiq/interface/generator/mcx.py +6 -6
  157. classiq/interface/generator/model/__init__.py +1 -3
  158. classiq/interface/generator/model/constraints.py +2 -2
  159. classiq/interface/generator/model/model.py +5 -6
  160. classiq/interface/generator/model/preferences/preferences.py +7 -6
  161. classiq/interface/generator/model/quantum_register.py +6 -11
  162. classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
  163. classiq/interface/generator/oracles/custom_oracle.py +2 -2
  164. classiq/interface/generator/oracles/oracle_abc.py +6 -5
  165. classiq/interface/generator/partitioned_register.py +6 -5
  166. classiq/interface/generator/piecewise_linear_amplitude_loading.py +8 -7
  167. classiq/interface/generator/qpe.py +4 -4
  168. classiq/interface/generator/qsvm.py +3 -3
  169. classiq/interface/generator/quantum_function_call.py +24 -29
  170. classiq/interface/generator/quantum_program.py +9 -9
  171. classiq/interface/generator/register_role.py +2 -4
  172. classiq/interface/generator/slice_parsing_utils.py +4 -3
  173. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  174. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  175. classiq/interface/generator/state_preparation/distributions.py +6 -5
  176. classiq/interface/generator/state_preparation/metrics.py +2 -4
  177. classiq/interface/generator/state_preparation/state_preparation.py +4 -4
  178. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -3
  179. classiq/interface/generator/transpiler_basis_gates.py +2 -2
  180. classiq/interface/generator/types/enum_declaration.py +2 -3
  181. classiq/interface/generator/types/qstruct_declaration.py +2 -1
  182. classiq/interface/generator/types/struct_declaration.py +3 -2
  183. classiq/interface/generator/ucc.py +2 -1
  184. classiq/interface/generator/unitary_gate.py +2 -2
  185. classiq/interface/generator/user_defined_function_params.py +1 -1
  186. classiq/interface/generator/validations/flow_graph.py +6 -5
  187. classiq/interface/generator/validations/validator_functions.py +3 -2
  188. classiq/interface/generator/visitor.py +9 -14
  189. classiq/interface/hardware.py +5 -6
  190. classiq/interface/helpers/custom_encoders.py +2 -2
  191. classiq/interface/helpers/custom_pydantic_types.py +8 -9
  192. classiq/interface/helpers/dotdict.py +18 -0
  193. classiq/interface/helpers/hashable_mixin.py +3 -2
  194. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  195. classiq/interface/helpers/pydantic_model_helpers.py +4 -3
  196. classiq/interface/helpers/validation_helpers.py +2 -2
  197. classiq/interface/ide/ide_data.py +11 -15
  198. classiq/interface/ide/visual_model.py +33 -22
  199. classiq/interface/jobs.py +2 -2
  200. classiq/interface/model/bind_operation.py +5 -4
  201. classiq/interface/model/classical_parameter_declaration.py +2 -2
  202. classiq/interface/model/handle_binding.py +3 -2
  203. classiq/interface/model/inplace_binary_operation.py +2 -1
  204. classiq/interface/model/model.py +12 -11
  205. classiq/interface/model/native_function_definition.py +10 -0
  206. classiq/interface/model/port_declaration.py +2 -2
  207. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +3 -2
  208. classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -2
  209. classiq/interface/model/quantum_expressions/quantum_expression.py +8 -7
  210. classiq/interface/model/quantum_function_call.py +9 -14
  211. classiq/interface/model/quantum_function_declaration.py +10 -12
  212. classiq/interface/model/quantum_lambda_function.py +3 -16
  213. classiq/interface/model/quantum_statement.py +4 -3
  214. classiq/interface/model/quantum_type.py +5 -5
  215. classiq/interface/model/statement_block.py +2 -3
  216. classiq/interface/model/validation_handle.py +5 -4
  217. classiq/interface/server/global_versions.py +3 -3
  218. classiq/model_expansions/atomic_expression_functions_defs.py +3 -2
  219. classiq/model_expansions/call_to_model_converter.py +190 -0
  220. classiq/model_expansions/capturing/captured_var_manager.py +4 -6
  221. classiq/model_expansions/capturing/propagated_var_stack.py +7 -7
  222. classiq/model_expansions/closure.py +17 -9
  223. classiq/model_expansions/evaluators/arg_type_match.py +3 -2
  224. classiq/model_expansions/evaluators/argument_types.py +3 -3
  225. classiq/model_expansions/evaluators/control.py +3 -3
  226. classiq/model_expansions/evaluators/parameter_types.py +7 -7
  227. classiq/model_expansions/evaluators/quantum_type_utils.py +2 -1
  228. classiq/model_expansions/evaluators/type_type_match.py +1 -1
  229. classiq/model_expansions/expression_evaluator.py +10 -9
  230. classiq/model_expansions/expression_renamer.py +6 -6
  231. classiq/model_expansions/function_builder.py +19 -12
  232. classiq/model_expansions/generative_functions.py +3 -2
  233. classiq/model_expansions/interpreter.py +31 -19
  234. classiq/model_expansions/model_tables.py +14 -14
  235. classiq/model_expansions/quantum_operations/bind.py +2 -4
  236. classiq/model_expansions/quantum_operations/classicalif.py +1 -1
  237. classiq/model_expansions/quantum_operations/control.py +2 -4
  238. classiq/model_expansions/quantum_operations/emitter.py +10 -13
  239. classiq/model_expansions/quantum_operations/expression_operation.py +23 -16
  240. classiq/model_expansions/quantum_operations/inplace_binary_operation.py +164 -38
  241. classiq/model_expansions/quantum_operations/phase.py +6 -6
  242. classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +25 -5
  243. classiq/model_expansions/quantum_operations/quantum_function_call.py +41 -2
  244. classiq/model_expansions/quantum_operations/repeat.py +1 -3
  245. classiq/model_expansions/scope.py +11 -10
  246. classiq/model_expansions/scope_initialization.py +6 -5
  247. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +6 -6
  248. classiq/model_expansions/sympy_conversion/sympy_to_python.py +2 -2
  249. classiq/model_expansions/visitors/variable_references.py +5 -4
  250. classiq/qmod/__init__.py +2 -0
  251. classiq/qmod/builtins/classical_execution_primitives.py +9 -9
  252. classiq/qmod/builtins/functions/__init__.py +75 -53
  253. classiq/qmod/builtins/functions/amplitude_estimation.py +4 -1
  254. classiq/qmod/builtins/functions/arithmetic.py +14 -1
  255. classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +86 -6
  256. classiq/qmod/builtins/functions/grover.py +41 -45
  257. classiq/qmod/builtins/functions/hea.py +60 -4
  258. classiq/qmod/builtins/functions/linear_pauli_rotation.py +26 -4
  259. classiq/qmod/builtins/functions/modular_exponentiation.py +90 -29
  260. classiq/qmod/builtins/functions/operators.py +1 -1
  261. classiq/qmod/builtins/functions/qaoa_penalty.py +14 -5
  262. classiq/qmod/builtins/functions/qft_functions.py +57 -0
  263. classiq/qmod/builtins/functions/qpe.py +20 -4
  264. classiq/qmod/builtins/functions/qsvt.py +49 -4
  265. classiq/qmod/builtins/functions/standard_gates.py +18 -18
  266. classiq/qmod/builtins/functions/state_preparation.py +92 -10
  267. classiq/qmod/builtins/functions/swap_test.py +7 -1
  268. classiq/qmod/builtins/functions/utility_functions.py +43 -0
  269. classiq/qmod/builtins/functions/variational.py +53 -0
  270. classiq/qmod/builtins/operations.py +4 -5
  271. classiq/qmod/cfunc.py +2 -2
  272. classiq/qmod/classical_function.py +3 -7
  273. classiq/qmod/create_model_function.py +19 -8
  274. classiq/qmod/declaration_inferrer.py +7 -10
  275. classiq/qmod/expression_query.py +3 -3
  276. classiq/qmod/generative.py +2 -1
  277. classiq/qmod/model_state_container.py +5 -7
  278. classiq/qmod/native/__init__.py +1 -3
  279. classiq/qmod/native/expression_to_qmod.py +9 -8
  280. classiq/qmod/native/pretty_printer.py +6 -5
  281. classiq/qmod/pretty_print/__init__.py +1 -3
  282. classiq/qmod/pretty_print/expression_to_python.py +13 -12
  283. classiq/qmod/pretty_print/pretty_printer.py +13 -12
  284. classiq/qmod/python_classical_type.py +8 -4
  285. classiq/qmod/qfunc.py +4 -4
  286. classiq/qmod/qmod_parameter.py +3 -1
  287. classiq/qmod/qmod_variable.py +11 -10
  288. classiq/qmod/quantum_expandable.py +32 -15
  289. classiq/qmod/quantum_function.py +34 -5
  290. classiq/qmod/semantics/annotation.py +1 -1
  291. classiq/qmod/semantics/error_manager.py +8 -7
  292. classiq/qmod/semantics/static_semantics_visitor.py +19 -24
  293. classiq/qmod/semantics/validation/constants_validation.py +1 -1
  294. classiq/qmod/semantics/validation/func_call_validation.py +2 -2
  295. classiq/qmod/semantics/validation/main_validation.py +33 -0
  296. classiq/qmod/semantics/validation/types_validation.py +2 -1
  297. classiq/qmod/symbolic.py +5 -8
  298. classiq/qmod/symbolic_type.py +2 -2
  299. classiq/qmod/synthesize_separately.py +16 -0
  300. {classiq-0.52.0.dist-info → classiq-0.54.0.dist-info}/METADATA +1 -1
  301. {classiq-0.52.0.dist-info → classiq-0.54.0.dist-info}/RECORD +302 -295
  302. classiq/qmod/builtins/functions/qft.py +0 -23
  303. {classiq-0.52.0.dist-info → classiq-0.54.0.dist-info}/WHEEL +0 -0
@@ -3,14 +3,17 @@ import functools
3
3
  from dataclasses import is_dataclass
4
4
  from enum import EnumMeta
5
5
  from inspect import isclass
6
- from typing import Any, Callable, Dict, List, Optional, Tuple, get_origin
6
+ from typing import Any, Callable, Optional, get_origin
7
7
 
8
8
  from classiq.interface.exceptions import ClassiqError
9
9
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
10
10
  from classiq.interface.generator.model.constraints import Constraints
11
11
  from classiq.interface.generator.model.preferences.preferences import Preferences
12
12
  from classiq.interface.model.model import Model
13
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
13
+ from classiq.interface.model.native_function_definition import (
14
+ FunctionSynthesisData,
15
+ NativeFunctionDefinition,
16
+ )
14
17
  from classiq.interface.model.quantum_function_declaration import (
15
18
  NamedParamsQuantumFunctionDeclaration,
16
19
  )
@@ -32,6 +35,7 @@ class QFunc(QExpandable):
32
35
  _validate_no_gen_params(py_callable.__annotations__)
33
36
  super().__init__(py_callable)
34
37
  functools.update_wrapper(self, py_callable)
38
+ self._synthesis_data: Optional[FunctionSynthesisData] = None
35
39
 
36
40
  @property
37
41
  def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
@@ -40,6 +44,14 @@ class QFunc(QExpandable):
40
44
  infer_func_decl(self._py_callable, qmodule=self._qmodule),
41
45
  )
42
46
 
47
+ @property
48
+ def synthesis_data(self) -> Optional[FunctionSynthesisData]:
49
+ return self._synthesis_data
50
+
51
+ @synthesis_data.setter
52
+ def synthesis_data(self, value: FunctionSynthesisData) -> None:
53
+ self._synthesis_data = value
54
+
43
55
  def __call__(self, *args: Any, **kwargs: Any) -> None:
44
56
  super().__call__(*args, **kwargs)
45
57
  self.expand()
@@ -58,7 +70,7 @@ class QFunc(QExpandable):
58
70
  self._qmodule.constants = dict()
59
71
  QConstant.set_current_model(self._qmodule)
60
72
  self.expand()
61
- model_extra_settings: List[Tuple[str, Any]] = [
73
+ model_extra_settings: list[tuple[str, Any]] = [
62
74
  ("constraints", constraints),
63
75
  ("execution_preferences", execution_preferences),
64
76
  ("preferences", preferences),
@@ -82,7 +94,17 @@ class QFunc(QExpandable):
82
94
  return
83
95
  super().expand()
84
96
  self._qmodule.native_defs[self.func_decl.name] = NativeFunctionDefinition(
85
- **{**self.func_decl.model_dump(), **{"body": self.body}}
97
+ **{
98
+ **self.func_decl.model_dump(),
99
+ **{
100
+ "body": self.body,
101
+ "synthesis_data": (
102
+ self.synthesis_data
103
+ if self.synthesis_data is not None
104
+ else FunctionSynthesisData()
105
+ ),
106
+ },
107
+ },
86
108
  )
87
109
 
88
110
  def _add_constants_from_classical_code(
@@ -115,6 +137,7 @@ class ExternalQFunc(QTerminalCallable):
115
137
  _decl: NamedParamsQuantumFunctionDeclaration
116
138
 
117
139
  def __init__(self, py_callable: Callable) -> None:
140
+ self._py_callable = py_callable
118
141
  decl = infer_func_decl(py_callable)
119
142
 
120
143
  py_callable.__annotations__.pop("return", None)
@@ -131,6 +154,12 @@ class ExternalQFunc(QTerminalCallable):
131
154
  def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
132
155
  return self._decl
133
156
 
157
+ def get_implementation(self) -> NativeFunctionDefinition:
158
+ model = QFunc(self._py_callable).create_model()
159
+ return [
160
+ func for func in model.functions if func.name == self._py_callable.__name__
161
+ ][0]
162
+
134
163
 
135
164
  class GenerativeQFunc(QExpandable):
136
165
  def __init__(
@@ -161,7 +190,7 @@ class IllegalParamsError(ClassiqError):
161
190
  super().__init__(message + self._HINT)
162
191
 
163
192
 
164
- def _validate_no_gen_params(annotations: Dict[str, Any]) -> None:
193
+ def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
165
194
  _illegal_params = {
166
195
  name: annotation
167
196
  for name, annotation in annotations.items()
@@ -1,4 +1,4 @@
1
- from typing import Mapping
1
+ from collections.abc import Mapping
2
2
 
3
3
  from classiq.interface.exceptions import ClassiqError
4
4
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
@@ -1,5 +1,6 @@
1
+ from collections.abc import Iterator
1
2
  from contextlib import contextmanager
2
- from typing import Iterator, List, Optional, Type
3
+ from typing import Optional
3
4
 
4
5
  from classiq.interface.ast_node import ASTNode
5
6
  from classiq.interface.exceptions import CLASSIQ_SLACK_COMMUNITY_LINK
@@ -16,9 +17,9 @@ class ErrorManager:
16
17
  if hasattr(self, "_instantiated"):
17
18
  return
18
19
  self._instantiated = True
19
- self._errors: List[SourceReferencedError] = []
20
- self._current_nodes_stack: List[ASTNode] = []
21
- self._call_stack: List[str] = []
20
+ self._errors: list[SourceReferencedError] = []
21
+ self._current_nodes_stack: list[ASTNode] = []
22
+ self._call_stack: list[str] = []
22
23
  self._ignore_errors: bool = False
23
24
 
24
25
  @contextmanager
@@ -31,7 +32,7 @@ class ErrorManager:
31
32
  self._ignore_errors = previous
32
33
 
33
34
  @property
34
- def annotated_errors(self) -> List[str]:
35
+ def annotated_errors(self) -> list[str]:
35
36
  return [str(error) for error in self._errors]
36
37
 
37
38
  def add_error(self, error: str) -> None:
@@ -48,7 +49,7 @@ class ErrorManager:
48
49
  )
49
50
  )
50
51
 
51
- def get_errors(self) -> List[SourceReferencedError]:
52
+ def get_errors(self) -> list[SourceReferencedError]:
52
53
  return self._errors
53
54
 
54
55
  def clear(self) -> None:
@@ -58,7 +59,7 @@ class ErrorManager:
58
59
  def has_errors(self) -> bool:
59
60
  return len(self._errors) > 0
60
61
 
61
- def report_errors(self, error_type: Type[Exception]) -> None:
62
+ def report_errors(self, error_type: type[Exception]) -> None:
62
63
  if self.has_errors():
63
64
  errors = self.annotated_errors
64
65
  self.clear()
@@ -1,15 +1,8 @@
1
+ from collections.abc import Iterator, Mapping, Sequence
1
2
  from contextlib import contextmanager
2
3
  from typing import (
3
4
  Any,
4
- Dict,
5
- Iterator,
6
- List,
7
- Mapping,
8
5
  Optional,
9
- Sequence,
10
- Set,
11
- Tuple,
12
- Type,
13
6
  )
14
7
 
15
8
  from classiq.interface.exceptions import ClassiqSemanticError
@@ -59,6 +52,7 @@ from classiq.qmod.semantics.validation.func_call_validation import (
59
52
  validate_call_arguments,
60
53
  )
61
54
  from classiq.qmod.semantics.validation.handle_validation import resolve_handle
55
+ from classiq.qmod.semantics.validation.main_validation import validate_main_function
62
56
  from classiq.qmod.semantics.validation.types_validation import (
63
57
  check_cstruct_has_fields,
64
58
  check_duplicate_types,
@@ -79,10 +73,10 @@ class StaticScope:
79
73
 
80
74
  def __init__(
81
75
  self,
82
- parameters: List[str],
83
- operands: Dict[str, QuantumOperandDeclaration],
84
- variables_to_states: Dict[str, HandleState],
85
- variables_to_types: Dict[str, ConcreteQuantumType],
76
+ parameters: list[str],
77
+ operands: dict[str, QuantumOperandDeclaration],
78
+ variables_to_states: dict[str, HandleState],
79
+ variables_to_types: dict[str, ConcreteQuantumType],
86
80
  ) -> None:
87
81
  self.parameters = parameters
88
82
  self.operands = operands
@@ -94,9 +88,9 @@ class StaticSemanticsVisitor(Visitor):
94
88
  def __init__(
95
89
  self,
96
90
  functions_dict: Mapping[str, QuantumFunctionDeclaration],
97
- constants: List[str],
91
+ constants: list[str],
98
92
  ) -> None:
99
- self._scope: List[StaticScope] = []
93
+ self._scope: list[StaticScope] = []
100
94
  self._error_manager = ErrorManager()
101
95
  self._functions_dict = functions_dict
102
96
  self._constants = constants
@@ -122,6 +116,7 @@ class StaticSemanticsVisitor(Visitor):
122
116
  check_qstruct_flexibility(qstruct)
123
117
  for cstruct in model.types:
124
118
  check_cstruct_has_fields(cstruct)
119
+ validate_main_function(model.main_func)
125
120
  self.visit_BaseModel(model)
126
121
 
127
122
  def visit_NativeFunctionDefinition(
@@ -141,7 +136,7 @@ class StaticSemanticsVisitor(Visitor):
141
136
  parameter_declaration_names = [
142
137
  decl.name for decl in func_def.positional_arg_declarations
143
138
  ]
144
- seen_names: Set[str] = set()
139
+ seen_names: set[str] = set()
145
140
  for name in parameter_declaration_names:
146
141
  if name in seen_names:
147
142
  self._error_manager.add_error(
@@ -254,12 +249,12 @@ class StaticSemanticsVisitor(Visitor):
254
249
 
255
250
  def _get_renamed_parameters(
256
251
  self, lambda_func: QuantumLambdaFunction
257
- ) -> Tuple[List[str], Dict[str, QuantumOperandDeclaration], List[PortDeclaration]]:
258
- renamed_parameters: List[str] = []
259
- renamed_operands: Dict[str, QuantumOperandDeclaration] = {}
260
- renamed_ports: List[PortDeclaration] = []
252
+ ) -> tuple[list[str], dict[str, QuantumOperandDeclaration], list[PortDeclaration]]:
253
+ renamed_parameters: list[str] = []
254
+ renamed_operands: dict[str, QuantumOperandDeclaration] = {}
255
+ renamed_ports: list[PortDeclaration] = []
261
256
  for idx, param in enumerate(lambda_func.func_decl.positional_arg_declarations):
262
- param_name = lambda_func.get_rename_params()[idx]
257
+ param_name = lambda_func.pos_rename_params[idx]
263
258
  if isinstance(param, AnonClassicalParameterDeclaration):
264
259
  renamed_parameters.append(param_name)
265
260
  elif isinstance(param, AnonQuantumOperandDeclaration):
@@ -375,7 +370,7 @@ def resolve_function_calls(
375
370
 
376
371
 
377
372
  def static_semantics_analysis_pass(
378
- model: Model, error_type: Optional[Type[Exception]] = ClassiqSemanticError
373
+ model: Model, error_type: Optional[type[Exception]] = ClassiqSemanticError
379
374
  ) -> None:
380
375
  StaticSemanticsVisitor(
381
376
  {**BUILTIN_FUNCTION_DECLARATIONS, **model.function_dict},
@@ -385,7 +380,7 @@ def static_semantics_analysis_pass(
385
380
  ErrorManager().report_errors(error_type)
386
381
 
387
382
 
388
- EXPECTED_TERMINAL_STATES: Dict[PortDeclarationDirection, HandleState] = {
383
+ EXPECTED_TERMINAL_STATES: dict[PortDeclarationDirection, HandleState] = {
389
384
  PortDeclarationDirection.Output: HandleState.INITIALIZED,
390
385
  PortDeclarationDirection.Inout: HandleState.INITIALIZED,
391
386
  }
@@ -393,8 +388,8 @@ EXPECTED_TERMINAL_STATES: Dict[PortDeclarationDirection, HandleState] = {
393
388
 
394
389
  def initialize_variables_to_state(
395
390
  port_declarations: Sequence[PortDeclaration],
396
- ) -> Dict[str, HandleState]:
397
- variables_to_state: Dict[str, HandleState] = dict()
391
+ ) -> dict[str, HandleState]:
392
+ variables_to_state: dict[str, HandleState] = dict()
398
393
 
399
394
  for port_decl in port_declarations:
400
395
  variables_to_state[port_decl.name] = (
@@ -1,4 +1,4 @@
1
- from typing import Sequence
1
+ from collections.abc import Sequence
2
2
 
3
3
  from classiq.interface.generator.constant import Constant
4
4
 
@@ -1,4 +1,4 @@
1
- from typing import List, Mapping
1
+ from collections.abc import Mapping
2
2
 
3
3
  from classiq.interface.exceptions import ClassiqError
4
4
  from classiq.interface.generator.expressions.expression import Expression
@@ -83,7 +83,7 @@ def _check_operand_against_declaration(
83
83
 
84
84
 
85
85
  def check_no_overlapping_quantum_args(
86
- args: List[HandleBinding], func_name: str
86
+ args: list[HandleBinding], func_name: str
87
87
  ) -> None:
88
88
  for idx, arg in enumerate(args):
89
89
  for other_arg in args[idx + 1 :]:
@@ -0,0 +1,33 @@
1
+ from classiq.interface.generator.functions.classical_type import (
2
+ ClassicalArray,
3
+ ClassicalList,
4
+ )
5
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
6
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
7
+ from classiq.interface.model.quantum_function_declaration import PositionalArg
8
+
9
+ from classiq import ClassicalParameterDeclaration
10
+ from classiq.qmod.semantics.error_manager import append_error
11
+
12
+
13
+ def validate_main_function(func: NativeFunctionDefinition) -> None:
14
+ for param in func.positional_arg_declarations:
15
+ _validate_main_param(param)
16
+
17
+
18
+ def _validate_main_param(param: PositionalArg) -> None:
19
+ if isinstance(param, ClassicalParameterDeclaration):
20
+ _validate_main_classical_param_type(param.classical_type, param.name)
21
+
22
+
23
+ def _validate_main_classical_param_type(
24
+ param: ConcreteClassicalType, param_name: str
25
+ ) -> None:
26
+ if isinstance(param, ClassicalList):
27
+ append_error(
28
+ param,
29
+ f"Classical array parameter {param_name!r} of function 'main' must must "
30
+ f"specify array length",
31
+ )
32
+ if isinstance(param, ClassicalArray):
33
+ _validate_main_classical_param_type(param.element_type, param_name)
@@ -1,4 +1,5 @@
1
- from typing import Sequence, Union
1
+ from collections.abc import Sequence
2
+ from typing import Union
2
3
 
3
4
  from classiq.interface.generator.functions.type_name import TypeName
4
5
  from classiq.interface.generator.types.enum_declaration import EnumDeclaration
classiq/qmod/symbolic.py CHANGED
@@ -2,10 +2,7 @@ import sys
2
2
  from typing import (
3
3
  TYPE_CHECKING,
4
4
  Any,
5
- List,
6
5
  Optional,
7
- Tuple,
8
- Type,
9
6
  TypeVar,
10
7
  Union,
11
8
  overload,
@@ -41,10 +38,10 @@ def symbolic_function(*args: Any, return_type: None = None) -> CParamScalar: ...
41
38
 
42
39
 
43
40
  @overload
44
- def symbolic_function(*args: Any, return_type: Type[T]) -> T: ...
41
+ def symbolic_function(*args: Any, return_type: type[T]) -> T: ...
45
42
 
46
43
 
47
- def symbolic_function(*args: Any, return_type: Optional[Type[T]] = None) -> CParam:
44
+ def symbolic_function(*args: Any, return_type: Optional[type[T]] = None) -> CParam:
48
45
  qmodule = (
49
46
  model_state_container.QMODULE
50
47
  ) # FIXME: https://classiq.atlassian.net/browse/CAD-15126
@@ -266,7 +263,7 @@ def catalan(x: SymbolicTypes) -> CParamScalar:
266
263
  return symbolic_function(x)
267
264
 
268
265
 
269
- def Piecewise(*args: Tuple[SymbolicTypes, SymbolicTypes]) -> CParamScalar: # noqa: N802
266
+ def Piecewise(*args: tuple[SymbolicTypes, SymbolicTypes]) -> CParamScalar: # noqa: N802
270
267
  return symbolic_function(*args)
271
268
 
272
269
 
@@ -299,7 +296,7 @@ def sum(arr: SymbolicTypes) -> CParamScalar:
299
296
 
300
297
 
301
298
  def subscript(
302
- amplitudes: Union[List[float], List[CReal], List[CParamScalar], CArray[CReal]],
299
+ amplitudes: Union[list[float], list[CReal], list[CParamScalar], CArray[CReal]],
303
300
  index: QNum,
304
301
  ) -> CParamScalar:
305
302
  return CParamScalar(expr=f"{amplitudes}[{index}]")
@@ -373,5 +370,5 @@ __all__ = [
373
370
  ]
374
371
 
375
372
 
376
- def __dir__() -> List[str]:
373
+ def __dir__() -> list[str]:
377
374
  return __all__
@@ -1,5 +1,5 @@
1
- from typing import Tuple, Union
1
+ from typing import Union
2
2
 
3
3
  from classiq.qmod.symbolic_expr import SymbolicExpr
4
4
 
5
- SymbolicTypes = Union[SymbolicExpr, int, float, bool, Tuple["SymbolicTypes", ...]]
5
+ SymbolicTypes = Union[SymbolicExpr, int, float, bool, tuple["SymbolicTypes", ...]]
@@ -0,0 +1,16 @@
1
+ from typing import Union
2
+
3
+ from classiq.interface.exceptions import ClassiqError
4
+ from classiq.interface.model.native_function_definition import FunctionSynthesisData
5
+
6
+ from classiq.qmod.quantum_function import ExternalQFunc, GenerativeQFunc, QFunc
7
+
8
+
9
+ def synthesize_separately(qfunc: Union[QFunc, GenerativeQFunc, ExternalQFunc]) -> QFunc:
10
+ if isinstance(qfunc, QFunc):
11
+ qfunc.synthesis_data = FunctionSynthesisData(should_synthesize_separately=True)
12
+ return qfunc
13
+ if isinstance(qfunc, GenerativeQFunc):
14
+ raise ClassiqError("Generative functions can not be synthesized separately")
15
+ if isinstance(qfunc, ExternalQFunc):
16
+ raise ClassiqError("External functions can not be synthesized separately")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: classiq
3
- Version: 0.52.0
3
+ Version: 0.54.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  Home-page: https://classiq.io
6
6
  License: Proprietary