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