classiq 0.38.0__py3-none-any.whl → 0.65.3__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 (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -1,60 +1,116 @@
1
1
  import ast
2
2
  import functools
3
- from typing import Any, Callable, Dict, List, Optional, Tuple, get_origin
3
+ from abc import abstractmethod
4
+ from collections import defaultdict
5
+ from dataclasses import is_dataclass
6
+ from enum import EnumMeta
7
+ from inspect import isclass
8
+ from typing import Any, Callable, Optional, get_origin
4
9
 
10
+ from classiq.interface.exceptions import ClassiqError
5
11
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
12
+ from classiq.interface.generator.functions.port_declaration import (
13
+ PortDeclarationDirection,
14
+ )
6
15
  from classiq.interface.generator.model.constraints import Constraints
7
16
  from classiq.interface.generator.model.preferences.preferences import Preferences
8
- from classiq.interface.model.model import Model, SerializedModel
9
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
17
+ from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
18
+ from classiq.interface.model.model import Model
19
+ from classiq.interface.model.native_function_definition import (
20
+ NativeFunctionDefinition,
21
+ )
10
22
  from classiq.interface.model.quantum_function_declaration import (
11
- QuantumFunctionDeclaration,
23
+ NamedParamsQuantumFunctionDeclaration,
12
24
  )
13
25
 
14
- from classiq.exceptions import ClassiqError
15
26
  from classiq.qmod.classical_function import CFunc
16
27
  from classiq.qmod.declaration_inferrer import infer_func_decl
28
+ from classiq.qmod.generative import set_frontend_interpreter
17
29
  from classiq.qmod.qmod_constant import QConstant
18
- from classiq.qmod.qmod_parameter import QParam
30
+ from classiq.qmod.qmod_parameter import CArray, CParam
19
31
  from classiq.qmod.qmod_variable import QVar
20
32
  from classiq.qmod.quantum_callable import QCallable, QCallableList
21
33
  from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
22
- from classiq.qmod.utilities import mangle_keyword, unmangle_keyword
34
+ from classiq.qmod.utilities import mangle_keyword
23
35
 
24
36
 
25
- def _lookup_qfunc(name: str) -> Optional[QuantumFunctionDeclaration]:
26
- # FIXME: to be generalized to existing user-defined functions
27
- return QuantumFunctionDeclaration.BUILTIN_FUNCTION_DECLARATIONS.get(name)
37
+ class BaseQFunc(QExpandable):
38
+ def __init__(
39
+ self,
40
+ py_callable: Callable,
41
+ compilation_metadata: Optional[CompilationMetadata] = None,
42
+ ) -> None:
43
+ super().__init__(py_callable)
44
+ self.compilation_metadata = compilation_metadata
45
+
46
+ @property
47
+ def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
48
+ raise NotImplementedError
28
49
 
50
+ @property
51
+ def _has_inputs(self) -> bool:
52
+ return any(
53
+ port.direction == PortDeclarationDirection.Input
54
+ for port in self.func_decl.port_declarations
55
+ )
29
56
 
30
- def create_model(
31
- entry_point: "QFunc",
32
- constraints: Optional[Constraints] = None,
33
- execution_preferences: Optional[ExecutionPreferences] = None,
34
- preferences: Optional[Preferences] = None,
35
- classical_execution_function: Optional[CFunc] = None,
36
- ) -> SerializedModel:
37
- return entry_point.create_model(
38
- constraints, execution_preferences, preferences, classical_execution_function
39
- ).get_model()
57
+ def update_compilation_metadata(self, **kwargs: Any) -> None:
58
+ if kwargs["should_synthesize_separately"] and self._has_inputs:
59
+ raise ClassiqError("Can't synthesize separately a function with inputs")
60
+ self.compilation_metadata = self._compilation_metadata.model_copy(update=kwargs)
40
61
 
62
+ @property
63
+ def _compilation_metadata(self) -> CompilationMetadata:
64
+ if self.compilation_metadata is None:
65
+ return CompilationMetadata()
66
+ return self.compilation_metadata
41
67
 
42
- class QFunc(QExpandable):
43
- def __init__(self, py_callable: Callable) -> None:
68
+ @abstractmethod
69
+ def create_model(
70
+ self,
71
+ constraints: Optional[Constraints] = None,
72
+ execution_preferences: Optional[ExecutionPreferences] = None,
73
+ preferences: Optional[Preferences] = None,
74
+ classical_execution_function: Optional[CFunc] = None,
75
+ ) -> Model:
76
+ pass
77
+
78
+
79
+ class QFunc(BaseQFunc):
80
+ FRAME_DEPTH = 3
81
+
82
+ def __init__(
83
+ self,
84
+ py_callable: Callable,
85
+ compilation_metadata: Optional[CompilationMetadata] = None,
86
+ ) -> None:
44
87
  _validate_no_gen_params(py_callable.__annotations__)
45
- super().__init__(py_callable)
88
+ super().__init__(py_callable, compilation_metadata)
46
89
  functools.update_wrapper(self, py_callable)
90
+ self.compilation_metadata: Optional[CompilationMetadata] = None
47
91
 
48
92
  @property
49
- def func_decl(self) -> QuantumFunctionDeclaration:
50
- return self._qmodule.native_defs.get(
51
- self._py_callable.__name__,
52
- infer_func_decl(self._py_callable, qmodule=self._qmodule),
93
+ def pure_decl(self) -> NamedParamsQuantumFunctionDeclaration:
94
+ if type(self.func_decl) is NamedParamsQuantumFunctionDeclaration:
95
+ return self.func_decl
96
+ return NamedParamsQuantumFunctionDeclaration(
97
+ **{
98
+ k: v
99
+ for k, v in self.func_decl.model_dump().items()
100
+ if k in NamedParamsQuantumFunctionDeclaration.model_fields
101
+ }
53
102
  )
54
103
 
104
+ @property
105
+ def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
106
+ name = self._py_callable.__name__
107
+ if hasattr(self._qmodule, "native_defs") and name in self._qmodule.native_defs:
108
+ return self._qmodule.native_defs[name]
109
+ return infer_func_decl(self._py_callable, qmodule=self._qmodule)
110
+
55
111
  def __call__(self, *args: Any, **kwargs: Any) -> None:
112
+ self.expand()
56
113
  super().__call__(*args, **kwargs)
57
- self._add_native_func_def()
58
114
 
59
115
  def create_model(
60
116
  self,
@@ -63,12 +119,17 @@ class QFunc(QExpandable):
63
119
  preferences: Optional[Preferences] = None,
64
120
  classical_execution_function: Optional[CFunc] = None,
65
121
  ) -> Model:
122
+ self._qmodule.enum_decls = dict()
66
123
  self._qmodule.type_decls = dict()
124
+ self._qmodule.qstruct_decls = dict()
67
125
  self._qmodule.native_defs = dict()
68
126
  self._qmodule.constants = dict()
127
+ self._qmodule.functions_compilation_metadata = dict()
128
+ self._qmodule.generative_functions = dict()
129
+ self._qmodule.function_dependencies = defaultdict(list)
69
130
  QConstant.set_current_model(self._qmodule)
70
- self._add_native_func_def()
71
- model_extra_settings: List[Tuple[str, Any]] = [
131
+ self.expand()
132
+ model_extra_settings: list[tuple[str, Any]] = [
72
133
  ("constraints", constraints),
73
134
  ("execution_preferences", execution_preferences),
74
135
  ("preferences", preferences),
@@ -78,20 +139,51 @@ class QFunc(QExpandable):
78
139
  model_extra_settings.append(
79
140
  ("classical_execution_code", classical_execution_function.code)
80
141
  )
81
- return Model(
142
+ model = Model(
82
143
  constants=list(self._qmodule.constants.values()),
83
144
  functions=list(self._qmodule.native_defs.values()),
145
+ enums=list(self._qmodule.enum_decls.values()),
84
146
  types=list(self._qmodule.type_decls.values()),
147
+ qstructs=list(self._qmodule.qstruct_decls.values()),
148
+ functions_compilation_metadata=self._qmodule.functions_compilation_metadata,
85
149
  **{key: value for key, value in model_extra_settings if value},
86
150
  )
151
+ if len(self._qmodule.generative_functions) > 0:
152
+ return self._create_generative_model(model)
153
+ return model
154
+
155
+ def _create_generative_model(self, model_stub: Model) -> Model:
156
+ from classiq.model_expansions.interpreters.frontend_generative_interpreter import (
157
+ FrontendGenerativeInterpreter,
158
+ )
159
+ from classiq.qmod.semantics.annotation.call_annotation import (
160
+ resolve_function_calls,
161
+ )
87
162
 
88
- def _add_native_func_def(self) -> None:
163
+ generative_functions = list(self._qmodule.generative_functions.values())
164
+ resolve_function_calls(
165
+ model_stub,
166
+ dict(model_stub.function_dict)
167
+ | {
168
+ gen_func.func_decl.name: gen_func.func_decl
169
+ for gen_func in generative_functions
170
+ },
171
+ )
172
+ interpreter = FrontendGenerativeInterpreter(model_stub, generative_functions)
173
+ set_frontend_interpreter(interpreter)
174
+ return interpreter.expand()
175
+
176
+ def expand(self) -> None:
89
177
  if self.func_decl.name in self._qmodule.native_defs:
90
178
  return
91
- self.expand()
179
+ super().expand()
92
180
  self._qmodule.native_defs[self.func_decl.name] = NativeFunctionDefinition(
93
- **self.func_decl.__dict__, body=self.body
181
+ **{**self.func_decl.model_dump(), **{"body": self.body}}
94
182
  )
183
+ if self.compilation_metadata is not None:
184
+ self._qmodule.functions_compilation_metadata[self.func_decl.name] = (
185
+ self.compilation_metadata
186
+ )
95
187
 
96
188
  def _add_constants_from_classical_code(
97
189
  self, classical_execution_function: CFunc
@@ -120,14 +212,15 @@ class QFunc(QExpandable):
120
212
 
121
213
 
122
214
  class ExternalQFunc(QTerminalCallable):
215
+ _decl: NamedParamsQuantumFunctionDeclaration
216
+
123
217
  def __init__(self, py_callable: Callable) -> None:
124
- decl = _lookup_qfunc(unmangle_keyword(py_callable.__name__))
125
- if decl is None:
126
- raise ClassiqError(f"Definition of {py_callable.__name__!r} not found")
218
+ self._py_callable = py_callable
219
+ decl = infer_func_decl(py_callable)
127
220
 
128
221
  py_callable.__annotations__.pop("return", None)
129
222
  if py_callable.__annotations__.keys() != {
130
- mangle_keyword(arg.name) for arg in decl.get_positional_arg_decls()
223
+ mangle_keyword(arg.name) for arg in decl.positional_arg_declarations
131
224
  }:
132
225
  raise ClassiqError(
133
226
  f"Parameter type hints for {py_callable.__name__!r} do not match imported declaration"
@@ -135,24 +228,86 @@ class ExternalQFunc(QTerminalCallable):
135
228
  super().__init__(decl)
136
229
  functools.update_wrapper(self, py_callable)
137
230
 
231
+ @property
232
+ def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
233
+ return self._decl
234
+
235
+ @property
236
+ def pure_decl(self) -> NamedParamsQuantumFunctionDeclaration:
237
+ return self.func_decl
238
+
239
+ def get_implementation(self) -> NativeFunctionDefinition:
240
+ model = QFunc(self._py_callable).create_model()
241
+ return [
242
+ func for func in model.functions if func.name == self._py_callable.__name__
243
+ ][0]
244
+
245
+
246
+ class GenerativeQFunc(BaseQFunc):
247
+ FRAME_DEPTH = 3
248
+
249
+ def __init__(
250
+ self,
251
+ py_callable: Callable,
252
+ func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
253
+ compilation_metadata: Optional[CompilationMetadata] = None,
254
+ ) -> None:
255
+ super().__init__(py_callable, compilation_metadata)
256
+ self._func_decl = func_decl
257
+
258
+ @property
259
+ def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
260
+ if self._func_decl is None:
261
+ self._func_decl = infer_func_decl(self._py_callable, self._qmodule)
262
+ return self._func_decl
263
+
264
+ def __call__(self, *args: Any, **kwargs: Any) -> None:
265
+ self._qmodule.generative_functions[self.func_decl.name] = self
266
+ super().__call__(*args, **kwargs)
267
+
268
+ def create_model(
269
+ self,
270
+ constraints: Optional[Constraints] = None,
271
+ execution_preferences: Optional[ExecutionPreferences] = None,
272
+ preferences: Optional[Preferences] = None,
273
+ classical_execution_function: Optional[CFunc] = None,
274
+ ) -> Model:
275
+ def _dec_main(*args: Any, **kwargs: Any) -> None:
276
+ self(*args, **kwargs)
277
+
278
+ _dec_main.__annotations__ = self._py_callable.__annotations__
279
+
280
+ return QFunc(_dec_main).create_model(
281
+ constraints=constraints,
282
+ execution_preferences=execution_preferences,
283
+ preferences=preferences,
284
+ classical_execution_function=classical_execution_function,
285
+ )
286
+
138
287
 
139
288
  ILLEGAL_PARAM_ERROR = "Unsupported type hint '{annotation}' for argument '{name}'."
140
289
 
141
290
 
142
291
  class IllegalParamsError(ClassiqError):
143
- _HINT = "\nNote - QMOD functions can declare classical parameters using the type hint 'QParam'."
292
+ _HINT = (
293
+ "\nNote - QMOD functions can declare classical parameters using the type hints "
294
+ "'CInt', 'CReal', 'CBool', and 'CArray'."
295
+ )
144
296
 
145
297
  def __init__(self, message: str) -> None:
146
298
  super().__init__(message + self._HINT)
147
299
 
148
300
 
149
- def _validate_no_gen_params(annotations: Dict[str, Any]) -> None:
301
+ def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
150
302
  _illegal_params = {
151
303
  name: annotation
152
304
  for name, annotation in annotations.items()
153
305
  if not (
154
306
  name == "return"
155
- or get_origin(annotation) is QParam
307
+ or (isclass(annotation) and issubclass(annotation, CParam))
308
+ or (isclass(annotation) and is_dataclass(annotation))
309
+ or (isclass(annotation) and isinstance(annotation, EnumMeta))
310
+ or get_origin(annotation) is CArray
156
311
  or (get_origin(annotation) or annotation) is QCallable
157
312
  or (get_origin(annotation) or annotation) is QCallableList
158
313
  or QVar.from_type_hint(annotation) is not None
File without changes
File without changes
@@ -0,0 +1,92 @@
1
+ from collections.abc import Iterator, Mapping
2
+ from contextlib import contextmanager
3
+ from typing import Any
4
+
5
+ from classiq.interface.exceptions import ClassiqError
6
+ from classiq.interface.generator.visitor import Visitor
7
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
8
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
9
+ from classiq.interface.model.quantum_function_declaration import (
10
+ AnonQuantumOperandDeclaration,
11
+ QuantumFunctionDeclaration,
12
+ QuantumOperandDeclaration,
13
+ )
14
+ from classiq.interface.model.quantum_lambda_function import (
15
+ QuantumLambdaFunction,
16
+ )
17
+
18
+ from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
19
+ from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
20
+ from classiq.qmod.semantics.error_manager import ErrorManager
21
+ from classiq.qmod.semantics.lambdas import get_renamed_parameters
22
+
23
+
24
+ def _annotate_function_call_decl(
25
+ fc: QuantumFunctionCall,
26
+ function_dict: Mapping[str, QuantumFunctionDeclaration],
27
+ ) -> None:
28
+ if fc._func_decl is None:
29
+ func_decl = function_dict.get(fc.func_name)
30
+ if func_decl is None:
31
+ raise ClassiqError(
32
+ f"Error resolving function {fc.func_name}, the function is not found in included library."
33
+ )
34
+ fc.set_func_decl(func_decl)
35
+
36
+ for arg, param in zip(fc.positional_args, fc.func_decl.positional_arg_declarations):
37
+ if not isinstance(param, AnonQuantumOperandDeclaration):
38
+ continue
39
+ args: list
40
+ if isinstance(arg, list):
41
+ args = arg
42
+ else:
43
+ args = [arg]
44
+ for qlambda in args:
45
+ if isinstance(qlambda, QuantumLambdaFunction):
46
+ qlambda.set_op_decl(param)
47
+
48
+
49
+ class _CallLambdaAnnotator(Visitor):
50
+ def __init__(
51
+ self, quantum_functions: Mapping[str, QuantumFunctionDeclaration]
52
+ ) -> None:
53
+ self._quantum_functions = dict(quantum_functions)
54
+ self._current_operands: dict[str, QuantumOperandDeclaration] = {}
55
+
56
+ @contextmanager
57
+ def set_operands(
58
+ self, operands: dict[str, QuantumOperandDeclaration]
59
+ ) -> Iterator[None]:
60
+ previous_operands = self._current_operands
61
+ self._current_operands = operands
62
+ yield
63
+ self._current_operands = previous_operands
64
+
65
+ def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
66
+ with self.set_operands(func.operand_declarations_dict):
67
+ self.generic_visit(func)
68
+
69
+ def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
70
+ lambda_operands = get_renamed_parameters(lambda_func)[1]
71
+ with self.set_operands(self._current_operands | lambda_operands):
72
+ self.generic_visit(lambda_func)
73
+
74
+ def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
75
+ _annotate_function_call_decl(
76
+ call, self._quantum_functions | self._current_operands
77
+ )
78
+ self.generic_visit(call)
79
+
80
+
81
+ def resolve_function_calls(
82
+ root: Any,
83
+ quantum_function_dict: Mapping[str, QuantumFunctionDeclaration],
84
+ ) -> None:
85
+ all_functions: Mapping[str, QuantumFunctionDeclaration] = {
86
+ **BUILTIN_FUNCTION_DECLARATIONS,
87
+ **quantum_function_dict,
88
+ }
89
+ with ErrorManager().ignore_errors_context():
90
+ QStructAnnotator().visit(quantum_function_dict)
91
+ QStructAnnotator().visit(root)
92
+ _CallLambdaAnnotator(all_functions).visit(root)
@@ -0,0 +1,23 @@
1
+ from classiq.interface.generator.functions.type_name import TypeName
2
+ from classiq.interface.generator.visitor import Visitor
3
+
4
+ from classiq.qmod.model_state_container import QMODULE
5
+
6
+
7
+ class QStructAnnotator(Visitor):
8
+ def __init__(self) -> None:
9
+ self._visited: set[TypeName] = set()
10
+
11
+ def visit_TypeName(self, type_name: TypeName) -> None:
12
+ decl = QMODULE.qstruct_decls.get(type_name.name)
13
+ if decl is None or type_name.has_fields or (type_name in self._visited):
14
+ return
15
+ self._visited.add(type_name)
16
+ new_fields = {
17
+ field_name: field_type.model_copy()
18
+ for field_name, field_type in decl.fields.items()
19
+ }
20
+ # We first visit the new fields and then set to deal with recursive
21
+ # qstructs
22
+ self.visit(new_fields)
23
+ type_name.set_fields(new_fields)
@@ -0,0 +1,88 @@
1
+ from collections.abc import Iterator
2
+ from contextlib import contextmanager
3
+ from typing import Optional
4
+
5
+ from classiq.interface.ast_node import ASTNode
6
+ from classiq.interface.exceptions import CLASSIQ_SLACK_COMMUNITY_LINK
7
+ from classiq.interface.source_reference import SourceReferencedError
8
+
9
+
10
+ class ErrorManager:
11
+ def __new__(cls) -> "ErrorManager":
12
+ if not hasattr(cls, "_instance"):
13
+ cls._instance = super().__new__(cls)
14
+ return cls._instance
15
+
16
+ def __init__(self) -> None:
17
+ if hasattr(self, "_instantiated"):
18
+ return
19
+ self._instantiated = True
20
+ self._errors: list[SourceReferencedError] = []
21
+ self._current_nodes_stack: list[ASTNode] = []
22
+ self._call_stack: list[str] = []
23
+ self._ignore_errors: bool = False
24
+
25
+ @contextmanager
26
+ def ignore_errors_context(self) -> Iterator[None]:
27
+ previous = self._ignore_errors
28
+ self._ignore_errors = True
29
+ try:
30
+ yield
31
+ finally:
32
+ self._ignore_errors = previous
33
+
34
+ @property
35
+ def annotated_errors(self) -> list[str]:
36
+ return [str(error) for error in self._errors]
37
+
38
+ def add_error(self, error: str) -> None:
39
+ if not self._ignore_errors:
40
+ self._errors.append(
41
+ SourceReferencedError(
42
+ error=error.replace(CLASSIQ_SLACK_COMMUNITY_LINK, ""),
43
+ source_ref=(
44
+ self._current_nodes_stack[-1].source_ref
45
+ if self._current_nodes_stack
46
+ else None
47
+ ),
48
+ function=self.current_function,
49
+ )
50
+ )
51
+
52
+ def get_errors(self) -> list[SourceReferencedError]:
53
+ return self._errors
54
+
55
+ def clear(self) -> None:
56
+ self._current_nodes_stack = []
57
+ self._errors = []
58
+
59
+ def has_errors(self) -> bool:
60
+ return len(self._errors) > 0
61
+
62
+ def report_errors(self, error_type: type[Exception]) -> None:
63
+ if self.has_errors():
64
+ errors = self.annotated_errors
65
+ self.clear()
66
+ raise error_type("\n\t" + "\n\t".join(errors))
67
+
68
+ @property
69
+ def current_function(self) -> Optional[str]:
70
+ return self._call_stack[-1] if self._call_stack else None
71
+
72
+ @contextmanager
73
+ def node_context(self, node: ASTNode) -> Iterator[None]:
74
+ self._current_nodes_stack.append(node)
75
+ yield
76
+ self._current_nodes_stack.pop()
77
+
78
+ @contextmanager
79
+ def call(self, func_name: str) -> Iterator[None]:
80
+ self._call_stack.append(func_name)
81
+ yield
82
+ self._call_stack.pop()
83
+
84
+
85
+ def append_error(node: ASTNode, message: str) -> None:
86
+ instance = ErrorManager()
87
+ with instance.node_context(node):
88
+ instance.add_error(message)
@@ -0,0 +1,25 @@
1
+ from classiq.interface.model.port_declaration import PortDeclaration
2
+ from classiq.interface.model.quantum_function_declaration import (
3
+ AnonQuantumOperandDeclaration,
4
+ QuantumOperandDeclaration,
5
+ )
6
+ from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
7
+
8
+ from classiq import AnonClassicalParameterDeclaration
9
+
10
+
11
+ def get_renamed_parameters(
12
+ lambda_func: QuantumLambdaFunction,
13
+ ) -> tuple[list[str], dict[str, QuantumOperandDeclaration], list[PortDeclaration]]:
14
+ renamed_parameters: list[str] = []
15
+ renamed_operands: dict[str, QuantumOperandDeclaration] = {}
16
+ renamed_ports: list[PortDeclaration] = []
17
+ for idx, param in enumerate(lambda_func.func_decl.positional_arg_declarations):
18
+ param_name = lambda_func.pos_rename_params[idx]
19
+ if isinstance(param, AnonClassicalParameterDeclaration):
20
+ renamed_parameters.append(param_name)
21
+ elif isinstance(param, AnonQuantumOperandDeclaration):
22
+ renamed_operands[param_name] = param.rename(param_name)
23
+ else:
24
+ renamed_ports.append(param.rename(param_name))
25
+ return renamed_parameters, renamed_operands, renamed_ports