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
@@ -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))])
@@ -0,0 +1,180 @@
1
+ import ast
2
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar
3
+
4
+ from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
5
+ from classiq.interface.generator.expressions.expression import Expression
6
+ from classiq.interface.generator.functions.port_declaration import (
7
+ PortDeclarationDirection,
8
+ )
9
+ from classiq.interface.model.allocate import Allocate
10
+ from classiq.interface.model.handle_binding import HandleBinding
11
+ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
12
+ ArithmeticOperation,
13
+ ArithmeticOperationKind,
14
+ )
15
+ from classiq.interface.model.quantum_expressions.quantum_expression import (
16
+ QuantumAssignmentOperation,
17
+ )
18
+ from classiq.interface.model.quantum_statement import QuantumOperation, QuantumStatement
19
+
20
+ from classiq.model_expansions.closure import Closure
21
+ from classiq.model_expansions.evaluators.quantum_type_utils import (
22
+ copy_type_information,
23
+ set_size,
24
+ )
25
+ from classiq.model_expansions.quantum_operations.emitter import Emitter
26
+ from classiq.model_expansions.scope import QuantumSymbol, Scope
27
+ from classiq.model_expansions.transformers.ast_renamer import rename_variables
28
+ from classiq.model_expansions.visitors.variable_references import VarRefCollector
29
+
30
+ if TYPE_CHECKING:
31
+ from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
32
+
33
+
34
+ QuantumOperationT = TypeVar("QuantumOperationT", bound=QuantumOperation)
35
+ _BLOCK_RENAMES = {
36
+ "compute": "within",
37
+ "action": "apply",
38
+ }
39
+ _REVERSE_BLOCK_RENAMES = {rename: name for name, rename in _BLOCK_RENAMES.items()}
40
+
41
+
42
+ class ShallowEmitter(Emitter[QuantumOperation]):
43
+ def __init__(
44
+ self,
45
+ interpreter: "BaseInterpreter",
46
+ operation_name: str,
47
+ *,
48
+ components: Optional[list[str]] = None,
49
+ ) -> None:
50
+ super().__init__(interpreter)
51
+ self._operation_name = operation_name
52
+ self._components: list[str] = components or []
53
+
54
+ def emit(self, op: QuantumOperation, /) -> None:
55
+ expanded_components: dict[str, Any] = {}
56
+ blocks, expressions, handles = self._split_components(op)
57
+
58
+ if len(blocks) > 0:
59
+ if op.is_generative():
60
+ expanded_blocks = self.expand_generative_blocks(op)
61
+ else:
62
+ expanded_blocks = self.expand_blocks(op, blocks)
63
+ expanded_components.update(expanded_blocks)
64
+
65
+ for expression_name in expressions:
66
+ expression = getattr(op, expression_name)
67
+ expression = self._evaluate_expression(expression, preserve_bool_ops=True)
68
+ self.capture_handles_in_expression(expression)
69
+ expanded_components[expression_name] = expression
70
+
71
+ for handle_name in handles:
72
+ handle = getattr(op, handle_name)
73
+ expanded_components[handle_name] = self._interpreter.evaluate(
74
+ handle
75
+ ).value.handle
76
+
77
+ op = op.model_copy(update=expanded_components)
78
+ if isinstance(op, QuantumAssignmentOperation):
79
+ self._post_process_assignment(op)
80
+ if isinstance(op, Allocate):
81
+ self._post_process_allocate(op)
82
+ self._builder.emit_statement(op)
83
+
84
+ def _post_process_assignment(self, op: QuantumAssignmentOperation) -> None:
85
+ if (
86
+ isinstance(op, ArithmeticOperation)
87
+ and op.operation_kind == ArithmeticOperationKind.Assignment
88
+ ):
89
+ direction = PortDeclarationDirection.Output
90
+ self._update_result_type(op)
91
+ else:
92
+ direction = PortDeclarationDirection.Inout
93
+ self._capture_handle(op.result_var, direction)
94
+
95
+ def _post_process_allocate(self, allocate: Allocate) -> None:
96
+ target_symbol = self._interpreter.evaluate(allocate.target).value
97
+ if not isinstance(target_symbol, QuantumSymbol):
98
+ return
99
+ self._capture_handle(target_symbol.handle, PortDeclarationDirection.Output)
100
+ if allocate.size is None or not allocate.size.is_evaluated():
101
+ return
102
+ set_size(
103
+ target_symbol.quantum_type,
104
+ allocate.size.to_int_value(),
105
+ str(target_symbol.handle),
106
+ )
107
+
108
+ def _split_components(
109
+ self, op: QuantumOperation
110
+ ) -> tuple[list[str], list[str], list[str]]:
111
+ blocks = self._filter_components(op, list)
112
+ expressions = self._filter_components(op, Expression)
113
+ handles = self._filter_components(op, HandleBinding)
114
+ return blocks, expressions, handles
115
+
116
+ def _filter_components(
117
+ self, op: QuantumOperation, component_type: type
118
+ ) -> list[str]:
119
+ return [
120
+ component
121
+ for component in self._components
122
+ if isinstance(getattr(op, component, None), component_type)
123
+ ]
124
+
125
+ def expand_blocks(
126
+ self, op: QuantumOperation, block_names: list[str]
127
+ ) -> dict[str, list[QuantumStatement]]:
128
+ blocks = {
129
+ _BLOCK_RENAMES.get(block, block): block_statements
130
+ for block in block_names
131
+ if (block_statements := getattr(op, block)) is not None
132
+ }
133
+ block_closure = Closure(
134
+ name=self._operation_name,
135
+ scope=Scope(parent=self._current_scope),
136
+ blocks=blocks,
137
+ )
138
+ context = self._expand_operation(block_closure)
139
+ return {
140
+ block: context.statements(_BLOCK_RENAMES.get(block, block))
141
+ for block in block_names
142
+ }
143
+
144
+ def expand_generative_blocks(
145
+ self, op: QuantumOperation
146
+ ) -> dict[str, list[QuantumStatement]]:
147
+ blocks = [block for block in self._components if op.has_generative_block(block)]
148
+ context = self._expand_generative_context(op, self._operation_name, blocks)
149
+ return {
150
+ _REVERSE_BLOCK_RENAMES.get(block, block): context.statements(block)
151
+ for block in blocks
152
+ }
153
+
154
+ def _update_result_type(self, op: ArithmeticOperation) -> None:
155
+ expr = str(self._evaluate_expression(op.expression))
156
+ vrc = VarRefCollector(ignore_duplicated_handles=True)
157
+ vrc.visit(ast.parse(expr))
158
+ symbols: list[QuantumSymbol] = [
159
+ symbol
160
+ for handle in vrc.var_handles
161
+ if isinstance(
162
+ symbol := self._interpreter.evaluate(handle).value, QuantumSymbol
163
+ )
164
+ ]
165
+ expr = rename_variables(
166
+ expr,
167
+ {str(symbol.handle): symbol.handle.identifier for symbol in symbols}
168
+ | {symbol.handle.qmod_expr: symbol.handle.identifier for symbol in symbols},
169
+ )
170
+ for symbol in symbols:
171
+ expr = expr.replace(symbol.handle.qmod_expr, symbol.handle.identifier)
172
+ result_type = compute_arithmetic_result_type(
173
+ expr,
174
+ {symbol.handle.identifier: symbol.quantum_type for symbol in symbols},
175
+ self._machine_precision,
176
+ )
177
+ result_symbol = self._interpreter.evaluate(op.result_var).as_type(QuantumSymbol)
178
+ copy_type_information(
179
+ result_type, result_symbol.quantum_type, str(op.result_var)
180
+ )
@@ -0,0 +1,28 @@
1
+ from classiq.interface.model.handle_binding import HandleBinding
2
+ from classiq.interface.model.variable_declaration_statement import (
3
+ VariableDeclarationStatement,
4
+ )
5
+
6
+ from classiq.model_expansions.evaluators.parameter_types import (
7
+ evaluate_type_in_quantum_symbol,
8
+ )
9
+ from classiq.model_expansions.quantum_operations.emitter import Emitter
10
+ from classiq.model_expansions.scope import Evaluated, QuantumSymbol
11
+
12
+
13
+ class VariableDeclarationStatementEmitter(Emitter[VariableDeclarationStatement]):
14
+ def emit(self, variable_declaration: VariableDeclarationStatement, /) -> None:
15
+ var_decl = variable_declaration.model_copy()
16
+ var_decl.quantum_type = variable_declaration.quantum_type.model_copy()
17
+ self._current_scope[variable_declaration.name] = Evaluated(
18
+ value=QuantumSymbol(
19
+ handle=HandleBinding(name=var_decl.name),
20
+ quantum_type=evaluate_type_in_quantum_symbol(
21
+ var_decl.quantum_type,
22
+ self._current_scope,
23
+ var_decl.name,
24
+ ),
25
+ ),
26
+ defining_function=self._builder.current_function,
27
+ )
28
+ self.emit_statement(var_decl)