classiq 0.38.0__py3-none-any.whl → 0.65.4__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.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.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.4.dist-info}/WHEEL +0 -0
@@ -0,0 +1,266 @@
1
+ from collections.abc import Sequence
2
+ from itertools import chain
3
+ from typing import (
4
+ TYPE_CHECKING,
5
+ Generic,
6
+ Optional,
7
+ cast,
8
+ )
9
+
10
+ from classiq.interface.debug_info.debug_info import FunctionDebugInfo
11
+ from classiq.interface.generator.generated_circuit_data import OperationLevel
12
+ from classiq.interface.model.classical_parameter_declaration import (
13
+ ClassicalParameterDeclaration,
14
+ )
15
+ from classiq.interface.model.handle_binding import HandleBinding
16
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
17
+ from classiq.interface.model.port_declaration import PortDeclaration
18
+ from classiq.interface.model.quantum_function_call import ArgValue, QuantumFunctionCall
19
+ from classiq.interface.model.quantum_function_declaration import (
20
+ NamedParamsQuantumFunctionDeclaration,
21
+ PositionalArg,
22
+ )
23
+ from classiq.interface.model.quantum_statement import QuantumStatement
24
+ from classiq.interface.model.variable_declaration_statement import (
25
+ VariableDeclarationStatement,
26
+ )
27
+
28
+ from classiq.model_expansions.capturing.captured_vars import (
29
+ validate_args_are_not_propagated,
30
+ )
31
+ from classiq.model_expansions.closure import FunctionClosure
32
+ from classiq.model_expansions.evaluators.argument_types import (
33
+ add_information_from_output_arguments,
34
+ )
35
+ from classiq.model_expansions.evaluators.parameter_types import (
36
+ evaluate_parameter_types_from_args,
37
+ )
38
+ from classiq.model_expansions.function_builder import (
39
+ FunctionContext,
40
+ )
41
+ from classiq.model_expansions.quantum_operations.emitter import (
42
+ Emitter,
43
+ QuantumStatementT,
44
+ )
45
+ from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
46
+ from classiq.model_expansions.transformers.var_splitter import VarSplitter
47
+ from classiq.qmod.builtins.functions import allocate, free
48
+
49
+ if TYPE_CHECKING:
50
+ from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
51
+
52
+
53
+ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSplitter):
54
+ def __init__(self, interpreter: "BaseInterpreter") -> None:
55
+ Emitter.__init__(self, interpreter)
56
+ VarSplitter.__init__(self, interpreter._builder.current_scope)
57
+
58
+ @staticmethod
59
+ def _should_wrap(body: Sequence[QuantumStatement]) -> bool:
60
+ # This protects shadowing of captured variables (i.e, bad user code) by wrapping the body in a function
61
+ # I'm sure there are better ways to handle it, but this is the simplest way to do it for now
62
+ return any(isinstance(stmt, VariableDeclarationStatement) for stmt in body)
63
+
64
+ def _create_expanded_wrapping_function(
65
+ self, name: str, body: Sequence[QuantumStatement]
66
+ ) -> QuantumFunctionCall:
67
+ wrapping_function = FunctionClosure.create(
68
+ name=self._counted_name_allocator.allocate(name),
69
+ body=body,
70
+ scope=Scope(parent=self._current_scope),
71
+ is_lambda=True,
72
+ )
73
+ return self._create_quantum_function_call(wrapping_function, list())
74
+
75
+ def _emit_quantum_function_call(
76
+ self,
77
+ function: FunctionClosure,
78
+ args: list[ArgValue],
79
+ propagated_debug_info: Optional[FunctionDebugInfo] = None,
80
+ ) -> QuantumFunctionCall:
81
+ call = self._create_quantum_function_call(
82
+ function, args, propagated_debug_info=propagated_debug_info
83
+ )
84
+ self.emit_statement(call)
85
+ return call
86
+
87
+ def _create_quantum_function_call(
88
+ self,
89
+ function: FunctionClosure,
90
+ args: list[ArgValue],
91
+ propagated_debug_info: Optional[FunctionDebugInfo] = None,
92
+ ) -> QuantumFunctionCall:
93
+ function = function.clone()
94
+ function = function.set_depth(self._builder.current_function.depth + 1)
95
+ evaluated_args = [self._interpreter.evaluate(arg) for arg in args]
96
+ new_declaration = self._prepare_fully_typed_declaration(
97
+ function, evaluated_args
98
+ )
99
+ new_positional_arg_decls = new_declaration.positional_arg_declarations
100
+ if not self.should_expand_function(function, evaluated_args):
101
+ is_atomic = True
102
+ new_declaration = self._expanded_functions_by_name.get(
103
+ function.name, new_declaration
104
+ )
105
+ else:
106
+ is_atomic = False
107
+ new_declaration = self._expand_function(
108
+ evaluated_args, new_declaration, function
109
+ )
110
+
111
+ new_positional_args = self._get_new_positional_args(
112
+ evaluated_args, is_atomic, new_positional_arg_decls
113
+ )
114
+ captured_args = function.captured_vars.get_captured_args(
115
+ self._builder.current_function
116
+ )
117
+ validate_args_are_not_propagated(new_positional_args, captured_args)
118
+ new_positional_args.extend(captured_args)
119
+ new_call = QuantumFunctionCall(
120
+ function=new_declaration.name, positional_args=new_positional_args
121
+ )
122
+ is_allocate_or_free = (
123
+ new_call.func_name == allocate.func_decl.name
124
+ or new_call.func_name == free.func_decl.name
125
+ )
126
+ parameters = {
127
+ arg_decl.name: FunctionDebugInfo.param_controller(value=evaluated_arg.value)
128
+ for arg_decl, evaluated_arg in zip(new_positional_arg_decls, evaluated_args)
129
+ if isinstance(arg_decl, ClassicalParameterDeclaration)
130
+ }
131
+
132
+ port_to_passed_variable_map = {
133
+ arg_decl.name: str(evaluated_arg.value.handle)
134
+ for arg_decl, evaluated_arg in zip(new_positional_arg_decls, evaluated_args)
135
+ if isinstance(arg_decl, PortDeclaration)
136
+ }
137
+ self._debug_info[new_call.uuid] = FunctionDebugInfo(
138
+ name=new_call.func_name,
139
+ level=OperationLevel.QMOD_FUNCTION_CALL,
140
+ parameters=(
141
+ parameters
142
+ if propagated_debug_info is None
143
+ else propagated_debug_info.parameters
144
+ ),
145
+ is_allocate_or_free=is_allocate_or_free,
146
+ port_to_passed_variable_map=port_to_passed_variable_map,
147
+ )
148
+ new_call.set_func_decl(new_declaration)
149
+ return new_call
150
+
151
+ def should_expand_function(
152
+ self, function: FunctionClosure, args: list[Evaluated]
153
+ ) -> bool:
154
+ return not function.is_atomic
155
+
156
+ def _expand_function(
157
+ self,
158
+ args: list[Evaluated],
159
+ decl: NamedParamsQuantumFunctionDeclaration,
160
+ function: FunctionClosure,
161
+ ) -> NamedParamsQuantumFunctionDeclaration:
162
+ self._add_params_to_scope(decl.positional_arg_declarations, args, function)
163
+ context = self._expand_operation(function.with_new_declaration(decl))
164
+ function_context = cast(FunctionContext, context)
165
+ closure_id = function_context.closure.closure_id
166
+ if closure_id in self._expanded_functions:
167
+ function_def = self._expanded_functions[closure_id]
168
+ self._expanded_functions_compilation_metadata[
169
+ function_def.name
170
+ ].occurrences_number += 1
171
+ return function_def
172
+
173
+ function_def = self._create_function_definition(function_context)
174
+ self._expanded_functions[closure_id] = function_def
175
+ self._top_level_scope[function_def.name] = Evaluated(
176
+ value=function_context.closure.with_new_declaration(function_def)
177
+ )
178
+ compilation_metadata = self._functions_compilation_metadata.get(function.name)
179
+ if compilation_metadata is not None:
180
+ self._expanded_functions_compilation_metadata[function_def.name] = (
181
+ compilation_metadata
182
+ )
183
+ return function_def
184
+
185
+ def _create_function_definition(
186
+ self, function_context: FunctionContext
187
+ ) -> NativeFunctionDefinition:
188
+ func_def = self._builder.create_definition(function_context)
189
+
190
+ captured_ports = function_context.closure.captured_vars.get_captured_ports()
191
+ if len(captured_ports) == 0:
192
+ return func_def
193
+ func_def.positional_arg_declarations = list(
194
+ chain.from_iterable((func_def.positional_arg_declarations, captured_ports))
195
+ )
196
+
197
+ if not function_context.is_lambda:
198
+ return func_def
199
+ func_def.body = self.rewrite(
200
+ func_def.body, function_context.closure.captured_vars.get_captured_mapping()
201
+ )
202
+
203
+ return func_def
204
+
205
+ @staticmethod
206
+ def _add_params_to_scope(
207
+ parameters: Sequence[PositionalArg],
208
+ arguments: Sequence[Evaluated],
209
+ closure: FunctionClosure,
210
+ ) -> None:
211
+ for parameter, argument in zip(parameters, arguments):
212
+ if isinstance(argument.value, QuantumSymbol):
213
+ assert isinstance(parameter, PortDeclaration)
214
+ closure.scope[parameter.name] = Evaluated(
215
+ QuantumSymbol(
216
+ handle=HandleBinding(name=parameter.name),
217
+ quantum_type=parameter.quantum_type,
218
+ ),
219
+ defining_function=closure,
220
+ )
221
+ else:
222
+ closure.scope[parameter.name] = argument
223
+
224
+ def _get_new_positional_args(
225
+ self,
226
+ evaluated_args: list[Evaluated],
227
+ is_atomic: bool,
228
+ new_positional_arg_decls: Sequence[PositionalArg],
229
+ ) -> list[ArgValue]:
230
+ evaluated_args = add_information_from_output_arguments(
231
+ new_positional_arg_decls, evaluated_args
232
+ )
233
+ if is_atomic:
234
+ return [arg.emit() for arg in evaluated_args]
235
+
236
+ positional_args = [
237
+ arg.emit() for arg in evaluated_args if isinstance(arg.value, QuantumSymbol)
238
+ ]
239
+
240
+ return positional_args
241
+
242
+ def _prepare_fully_typed_declaration(
243
+ self, function: FunctionClosure, evaluated_args: list[Evaluated]
244
+ ) -> NamedParamsQuantumFunctionDeclaration:
245
+ """
246
+ Given, for example,
247
+ def my_func(x: int, q: QArray["x"], p: QArray[]) -> None:
248
+ ...
249
+ def main(...):
250
+ ...
251
+ allocate(5, s)
252
+ my_func(3, r, s)
253
+ The code below will evaluate x to be 3, q to be of size 3 and p to be of size 5.
254
+ Note that it requires a scope for the parameter declaration space, which is
255
+ different from the call scope. For example, the former uses r,s and the latter
256
+ uses p, q.
257
+ """
258
+ # The signature scope is passed as a separate argument to avoid contaminating the statement execution scope
259
+ return NamedParamsQuantumFunctionDeclaration(
260
+ name=function.name,
261
+ positional_arg_declarations=evaluate_parameter_types_from_args(
262
+ function,
263
+ function.signature_scope,
264
+ evaluated_args,
265
+ ),
266
+ )
@@ -0,0 +1,53 @@
1
+ from collections.abc import Sequence
2
+
3
+ from classiq.interface.model.classical_if import ClassicalIf
4
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
5
+ from classiq.interface.model.quantum_statement import QuantumStatement
6
+
7
+ from classiq.model_expansions.closure import FunctionClosure
8
+ from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
9
+ from classiq.model_expansions.scope import Scope
10
+
11
+
12
+ def _is_all_identity_calls(body: Sequence[QuantumStatement]) -> bool:
13
+ return all(
14
+ isinstance(stmt, QuantumFunctionCall) and stmt.func_name.lower() == "identity"
15
+ for stmt in body
16
+ )
17
+
18
+
19
+ class ClassicalIfEmitter(CallEmitter[ClassicalIf]):
20
+ def emit(self, classical_if: ClassicalIf, /) -> None:
21
+ condition = self._interpreter.evaluate(classical_if.condition).as_type(bool)
22
+ op_name = "then" if condition else "else"
23
+ is_generative = classical_if.is_generative()
24
+
25
+ body: Sequence[QuantumStatement]
26
+ if is_generative:
27
+ if not classical_if.has_generative_block(op_name):
28
+ return
29
+ context = self._expand_generative_context(classical_if, op_name, op_name)
30
+ context.blocks["body"] = context.blocks[op_name]
31
+ context.blocks.pop(op_name)
32
+ body = context.statements("body")
33
+ else:
34
+ body = classical_if.then if condition else classical_if.else_
35
+
36
+ if _is_all_identity_calls(body):
37
+ return
38
+
39
+ if is_generative or not self._should_wrap(body):
40
+ for stmt in body:
41
+ if is_generative:
42
+ self._interpreter._builder.emit_statement(stmt)
43
+ else:
44
+ self._interpreter.emit_statement(stmt)
45
+ return
46
+
47
+ then_else_func = FunctionClosure.create(
48
+ name=self._counted_name_allocator.allocate("then" if condition else "else"),
49
+ body=body,
50
+ scope=Scope(parent=self._current_scope),
51
+ is_lambda=True,
52
+ )
53
+ self._emit_quantum_function_call(then_else_func, list())
@@ -0,0 +1,87 @@
1
+ from itertools import chain
2
+ from typing import TYPE_CHECKING, Generic
3
+
4
+ from classiq.interface.generator.functions.port_declaration import (
5
+ PortDeclarationDirection,
6
+ )
7
+ from classiq.interface.model.port_declaration import PortDeclaration
8
+
9
+ from classiq.model_expansions.closure import FunctionClosure, GenerativeClosure
10
+ from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
11
+ from classiq.model_expansions.quantum_operations.emitter import QuantumStatementT
12
+ from classiq.model_expansions.scope import Evaluated
13
+ from classiq.qmod.model_state_container import QMODULE
14
+
15
+ if TYPE_CHECKING:
16
+ from classiq.model_expansions.interpreters.generative_interpreter import (
17
+ GenerativeInterpreter,
18
+ )
19
+
20
+
21
+ class DeclarativeCallEmitter(
22
+ Generic[QuantumStatementT], CallEmitter[QuantumStatementT]
23
+ ):
24
+ _interpreter: "GenerativeInterpreter"
25
+
26
+ def __init__(self, interpreter: "GenerativeInterpreter") -> None:
27
+ super().__init__(interpreter)
28
+
29
+ def should_expand_function(
30
+ self, function: FunctionClosure, args: list[Evaluated]
31
+ ) -> bool:
32
+ if not super().should_expand_function(function, args):
33
+ return False
34
+
35
+ if self._is_function_purely_declarative(
36
+ function
37
+ ) and self._are_args_purely_declarative(args):
38
+ self._interpreter.add_purely_declarative_function(function)
39
+ return False
40
+
41
+ return True
42
+
43
+ def _is_function_purely_declarative(self, function: FunctionClosure) -> bool:
44
+ if function.name not in QMODULE.native_defs:
45
+ return False
46
+
47
+ if isinstance(function, GenerativeClosure):
48
+ return False
49
+
50
+ if any(
51
+ not param.quantum_type.is_instantiated
52
+ for param in function.positional_arg_declarations
53
+ if isinstance(param, PortDeclaration)
54
+ and param.direction == PortDeclarationDirection.Output
55
+ ):
56
+ return False
57
+
58
+ dependencies = QMODULE.function_dependencies[function.name]
59
+ return self._are_identifiers_purely_declarative(dependencies)
60
+
61
+ def _are_args_purely_declarative(self, args: list[Evaluated]) -> bool:
62
+ values = [arg.value for arg in args]
63
+ function_inputs: list[FunctionClosure] = list(
64
+ chain.from_iterable(
65
+ (
66
+ [arg]
67
+ if isinstance(arg, FunctionClosure)
68
+ else (
69
+ arg
70
+ if isinstance(arg, list)
71
+ and any(isinstance(item, FunctionClosure) for item in arg)
72
+ else []
73
+ )
74
+ )
75
+ for arg in values
76
+ )
77
+ )
78
+ if any(func.is_lambda for func in function_inputs):
79
+ return False
80
+ dependencies = [func.name for func in function_inputs if not func.is_lambda]
81
+ return self._are_identifiers_purely_declarative(dependencies)
82
+
83
+ def _are_identifiers_purely_declarative(self, dependencies: list[str]) -> bool:
84
+ return not any(
85
+ isinstance(self._current_scope[dep].value, GenerativeClosure)
86
+ for dep in dependencies
87
+ )
@@ -0,0 +1,181 @@
1
+ import ast
2
+ from abc import abstractmethod
3
+ from typing import (
4
+ TYPE_CHECKING,
5
+ Generic,
6
+ Optional,
7
+ TypeVar,
8
+ Union,
9
+ )
10
+
11
+ import sympy
12
+
13
+ from classiq.interface.debug_info.debug_info import DebugInfoCollection
14
+ from classiq.interface.exceptions import ClassiqInternalExpansionError
15
+ from classiq.interface.generator.expressions.evaluated_expression import (
16
+ EvaluatedExpression,
17
+ )
18
+ from classiq.interface.generator.expressions.expression import Expression
19
+ from classiq.interface.generator.functions.port_declaration import (
20
+ PortDeclarationDirection,
21
+ )
22
+ from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
23
+ from classiq.interface.model.handle_binding import HandleBinding
24
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
25
+ from classiq.interface.model.quantum_function_declaration import (
26
+ NamedParamsQuantumFunctionDeclaration,
27
+ )
28
+ from classiq.interface.model.quantum_statement import QuantumOperation, QuantumStatement
29
+
30
+ from classiq.model_expansions.closure import Closure, GenerativeClosure
31
+ from classiq.model_expansions.function_builder import (
32
+ OperationBuilder,
33
+ OperationContext,
34
+ )
35
+ from classiq.model_expansions.scope import QuantumSymbol, Scope
36
+ from classiq.model_expansions.sympy_conversion.sympy_to_python import (
37
+ translate_sympy_quantum_expression,
38
+ )
39
+ from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
40
+ from classiq.model_expansions.visitors.variable_references import VarRefCollector
41
+ from classiq.qmod.quantum_function import GenerativeQFunc
42
+
43
+ if TYPE_CHECKING:
44
+ from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
45
+
46
+ QuantumStatementT = TypeVar("QuantumStatementT", bound=QuantumStatement)
47
+
48
+
49
+ class Emitter(Generic[QuantumStatementT]):
50
+ def __init__(self, interpreter: "BaseInterpreter") -> None:
51
+ self._interpreter = interpreter
52
+
53
+ self._machine_precision = self._interpreter._model.preferences.machine_precision
54
+ self._expanded_functions_compilation_metadata = (
55
+ self._interpreter._expanded_functions_compilation_metadata
56
+ )
57
+ self._functions_compilation_metadata = (
58
+ self._interpreter._functions_compilation_metadata
59
+ )
60
+
61
+ @abstractmethod
62
+ def emit(self, statement: QuantumStatementT, /) -> None:
63
+ pass
64
+
65
+ def _expand_operation(self, closure: Closure) -> OperationContext:
66
+ return self._interpreter._expand_operation(closure)
67
+
68
+ @property
69
+ def _builder(self) -> OperationBuilder:
70
+ return self._interpreter._builder
71
+
72
+ @property
73
+ def _current_scope(self) -> Scope:
74
+ return self._builder.current_scope
75
+
76
+ @property
77
+ def _top_level_scope(self) -> Scope:
78
+ return self._interpreter._top_level_scope
79
+
80
+ @property
81
+ def _expanded_functions(self) -> dict[str, NativeFunctionDefinition]:
82
+ return self._interpreter._expanded_functions
83
+
84
+ @property
85
+ def _expanded_functions_by_name(self) -> dict[str, NativeFunctionDefinition]:
86
+ return nameables_to_dict(list(self._interpreter._expanded_functions.values()))
87
+
88
+ @property
89
+ def _counted_name_allocator(self) -> CountedNameAllocator:
90
+ return self._interpreter._counted_name_allocator
91
+
92
+ @property
93
+ def _debug_info(self) -> DebugInfoCollection:
94
+ return self._interpreter._model.debug_info
95
+
96
+ def _expand_generative_context(
97
+ self,
98
+ op: QuantumOperation,
99
+ context_name: str,
100
+ block_names: Union[None, str, list[str]] = None,
101
+ func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
102
+ ) -> OperationContext:
103
+ if isinstance(block_names, str):
104
+ block_names = [block_names]
105
+ block_names = block_names or ["body"]
106
+ func_decl = func_decl or NamedParamsQuantumFunctionDeclaration(
107
+ name=context_name
108
+ )
109
+ gen_closure = GenerativeClosure(
110
+ name=func_decl.name,
111
+ scope=Scope(parent=self._interpreter._builder.current_scope),
112
+ blocks={},
113
+ generative_blocks={
114
+ block_name: GenerativeQFunc(
115
+ op.get_generative_block(block_name), func_decl
116
+ )
117
+ for block_name in block_names
118
+ },
119
+ )
120
+ context = self._interpreter._expand_operation(gen_closure)
121
+ op.clear_generative_blocks()
122
+ return context
123
+
124
+ def _evaluate_expression(
125
+ self, expression: Expression, preserve_bool_ops: bool = False
126
+ ) -> Expression:
127
+ evaluated_expression = self._interpreter.evaluate(expression)
128
+ if isinstance(evaluated_expression.value, sympy.Basic):
129
+ new_expression = Expression(
130
+ expr=translate_sympy_quantum_expression(
131
+ evaluated_expression.value,
132
+ preserve_bool_ops=preserve_bool_ops,
133
+ )
134
+ )
135
+ else:
136
+ new_expression = Expression(expr=str(evaluated_expression.value))
137
+ new_expression._evaluated_expr = EvaluatedExpression(
138
+ value=evaluated_expression.value
139
+ )
140
+ return new_expression
141
+
142
+ def emit_statement(self, statement: QuantumStatement) -> None:
143
+ if isinstance(statement, QuantumOperation):
144
+ self._update_captured_vars(statement)
145
+ self._builder.emit_statement(statement)
146
+
147
+ def _update_captured_vars(self, op: QuantumOperation) -> None:
148
+ handles = (
149
+ [(handle, PortDeclarationDirection.Input) for handle in op.inputs]
150
+ + [(handle, PortDeclarationDirection.Output) for handle in op.outputs]
151
+ + [(handle, PortDeclarationDirection.Inout) for handle in op.inouts]
152
+ )
153
+ for handle, direction in handles:
154
+ self._capture_handle(handle, direction)
155
+
156
+ def _capture_handle(
157
+ self, handle: HandleBinding, direction: PortDeclarationDirection
158
+ ) -> None:
159
+ if handle.name not in self._current_scope:
160
+ return
161
+ defining_function = self._current_scope[handle.name].defining_function
162
+ if defining_function is None:
163
+ raise ClassiqInternalExpansionError
164
+ symbol: QuantumSymbol = self._interpreter.evaluate(handle).value
165
+ self._builder.current_block.captured_vars.capture_handle(
166
+ handle=symbol.handle,
167
+ quantum_type=symbol.quantum_type,
168
+ defining_function=defining_function,
169
+ direction=direction,
170
+ )
171
+
172
+ def capture_handles_in_expression(self, expr: Expression) -> None:
173
+ vrc = VarRefCollector(ignore_duplicated_handles=True)
174
+ vrc.visit(ast.parse(expr.expr))
175
+ handles = dict.fromkeys(
176
+ handle
177
+ for handle in vrc.var_handles
178
+ if isinstance(self._current_scope[handle.name].value, QuantumSymbol)
179
+ )
180
+ for handle in handles:
181
+ self._capture_handle(handle, PortDeclarationDirection.Inout)
@@ -0,0 +1,33 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
4
+
5
+ from classiq.model_expansions.closure import FunctionClosure
6
+ from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
7
+ from classiq.model_expansions.quantum_operations.declarative_call_emitter import (
8
+ DeclarativeCallEmitter,
9
+ )
10
+ from classiq.qmod.semantics.error_manager import ErrorManager
11
+
12
+ if TYPE_CHECKING:
13
+ from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
14
+
15
+
16
+ class QuantumFunctionCallEmitter(CallEmitter[QuantumFunctionCall]):
17
+ def __init__(self, interpreter: "BaseInterpreter") -> None:
18
+ super().__init__(interpreter)
19
+ self._model = self._interpreter._model
20
+
21
+ def emit(self, call: QuantumFunctionCall, /) -> None:
22
+ function = self._interpreter.evaluate(call.function).as_type(FunctionClosure)
23
+ args = call.positional_args
24
+ with ErrorManager().call(function.name):
25
+ self._emit_quantum_function_call(
26
+ function, args, self._debug_info.get(call.uuid)
27
+ )
28
+
29
+
30
+ class DeclarativeQuantumFunctionCallEmitter(
31
+ QuantumFunctionCallEmitter, DeclarativeCallEmitter
32
+ ):
33
+ pass
@@ -0,0 +1,56 @@
1
+ from classiq.interface.exceptions import ClassiqExpansionError
2
+ from classiq.interface.generator.expressions.expression import Expression
3
+ from classiq.interface.generator.functions.builtins.internal_operators import (
4
+ REPEAT_OPERATOR_NAME,
5
+ )
6
+ from classiq.interface.generator.functions.classical_type import Integer
7
+ from classiq.interface.model.classical_parameter_declaration import (
8
+ ClassicalParameterDeclaration,
9
+ )
10
+ from classiq.interface.model.repeat import Repeat
11
+
12
+ from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
13
+ from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
14
+ from classiq.model_expansions.scope import Scope
15
+ from classiq.qmod.quantum_function import GenerativeQFunc
16
+
17
+
18
+ class RepeatEmitter(CallEmitter[Repeat]):
19
+ def emit(self, repeat: Repeat, /) -> None:
20
+ count = self._interpreter.evaluate(repeat.count).as_type(int)
21
+ if count < 0:
22
+ raise ClassiqExpansionError(
23
+ f"repeat count must be non-negative, got {count}"
24
+ )
25
+ op_name = self._counted_name_allocator.allocate(REPEAT_OPERATOR_NAME)
26
+ for i in range(count):
27
+ self._emit_iteration(repeat, i, op_name)
28
+
29
+ def _emit_iteration(self, repeat: Repeat, i: int, op_name: str) -> None:
30
+ closure_constructor: type[FunctionClosure]
31
+ extra_args: dict
32
+ if repeat.is_generative():
33
+ closure_constructor = GenerativeFunctionClosure
34
+ extra_args = {
35
+ "generative_blocks": {
36
+ "body": GenerativeQFunc(
37
+ repeat.get_generative_block("body"),
38
+ ),
39
+ }
40
+ }
41
+ else:
42
+ closure_constructor = FunctionClosure
43
+ extra_args = {}
44
+ iteration_function = closure_constructor.create(
45
+ name=op_name,
46
+ positional_arg_declarations=[
47
+ ClassicalParameterDeclaration(
48
+ name=repeat.iter_var, classical_type=Integer()
49
+ )
50
+ ],
51
+ body=repeat.body,
52
+ scope=Scope(parent=self._current_scope),
53
+ is_lambda=True,
54
+ **extra_args,
55
+ )
56
+ self._emit_quantum_function_call(iteration_function, [Expression(expr=str(i))])