classiq 0.38.0__py3-none-any.whl → 0.65.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -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)
@@ -0,0 +1,240 @@
1
+ import itertools
2
+ import re
3
+ from collections import UserDict
4
+ from collections.abc import Iterator
5
+ from dataclasses import dataclass
6
+ from functools import singledispatch
7
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
8
+
9
+ from sympy import Symbol
10
+
11
+ from classiq.interface.exceptions import (
12
+ ClassiqExpansionError,
13
+ ClassiqInternalExpansionError,
14
+ )
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.expressions.expression_constants import (
20
+ CPARAM_EXECUTION_SUFFIX_PATTERN,
21
+ )
22
+ from classiq.interface.generator.expressions.qmod_struct_instance import (
23
+ QmodStructInstance,
24
+ )
25
+ from classiq.interface.generator.functions.type_name import TypeName
26
+ from classiq.interface.model.handle_binding import (
27
+ FieldHandleBinding,
28
+ HandleBinding,
29
+ SlicedHandleBinding,
30
+ SubscriptHandleBinding,
31
+ )
32
+ from classiq.interface.model.quantum_function_call import ArgValue
33
+ from classiq.interface.model.quantum_type import (
34
+ QuantumBitvector,
35
+ QuantumType,
36
+ )
37
+
38
+ if TYPE_CHECKING:
39
+ from classiq.model_expansions.closure import FunctionClosure
40
+
41
+ T = TypeVar("T")
42
+
43
+
44
+ @dataclass(frozen=True)
45
+ class QuantumSymbol:
46
+ handle: HandleBinding
47
+ quantum_type: QuantumType
48
+
49
+ @property
50
+ def is_subscript(self) -> bool:
51
+ return isinstance(self.handle, (SubscriptHandleBinding, SlicedHandleBinding))
52
+
53
+ def emit(self) -> HandleBinding:
54
+ return self.handle
55
+
56
+ def __getitem__(self, item: Union[slice, int]) -> "QuantumSymbol":
57
+ if isinstance(item, int):
58
+ return self._subscript(item)
59
+
60
+ return self._slice(item.start, item.stop)
61
+
62
+ def _slice(self, start: int, end: int) -> "QuantumSymbol":
63
+ if not isinstance(self.quantum_type, QuantumBitvector):
64
+ raise ClassiqExpansionError(
65
+ f"{self.quantum_type.type_name} is not subscriptable"
66
+ )
67
+ if start >= end:
68
+ raise ClassiqExpansionError(
69
+ f"{self.quantum_type.type_name} slice '{self.handle}[{start}:{end}]' "
70
+ f"has non-positive length"
71
+ )
72
+ array_length = self.quantum_type.length_value
73
+ if start < 0 or end > array_length:
74
+ raise ClassiqExpansionError(
75
+ f"Slice [{start}:{end}] is out of bounds of "
76
+ f"{self.quantum_type.type_name} {str(self.handle)!r} of length "
77
+ f"{array_length}"
78
+ )
79
+ return QuantumSymbol(
80
+ handle=SlicedHandleBinding(
81
+ base_handle=self.handle,
82
+ start=Expression(expr=str(start)),
83
+ end=Expression(expr=str(end)),
84
+ ),
85
+ quantum_type=QuantumBitvector(
86
+ element_type=self.quantum_type.element_type,
87
+ length=Expression(expr=str(end - start)),
88
+ ),
89
+ )
90
+
91
+ def _subscript(self, index: int) -> "QuantumSymbol":
92
+ if not isinstance(self.quantum_type, QuantumBitvector):
93
+ raise ClassiqExpansionError(
94
+ f"{self.quantum_type.type_name} is not subscriptable"
95
+ )
96
+ array_length = self.quantum_type.length_value
97
+ if index < 0 or index >= array_length:
98
+ raise ClassiqExpansionError(
99
+ f"Subscript {index} is out of bounds of {self.quantum_type.type_name} "
100
+ f"{str(self.handle)!r} of length {array_length}"
101
+ )
102
+ return QuantumSymbol(
103
+ handle=SubscriptHandleBinding(
104
+ base_handle=self.handle,
105
+ index=Expression(expr=str(index)),
106
+ ),
107
+ quantum_type=self.quantum_type.element_type,
108
+ )
109
+
110
+ @property
111
+ def fields(self) -> dict[str, "QuantumSymbol"]:
112
+ quantum_type = self.quantum_type
113
+ if not isinstance(quantum_type, TypeName):
114
+ raise ClassiqExpansionError(
115
+ f"{self.quantum_type.type_name} is not a struct"
116
+ )
117
+ return {
118
+ field_name: QuantumSymbol(
119
+ handle=FieldHandleBinding(base_handle=self.handle, field=field_name),
120
+ quantum_type=field_type,
121
+ )
122
+ for field_name, field_type in quantum_type.fields.items()
123
+ }
124
+
125
+
126
+ @singledispatch
127
+ def evaluated_to_str(value: Any) -> str:
128
+ return str(value)
129
+
130
+
131
+ @evaluated_to_str.register
132
+ def _evaluated_to_str_list(value: list) -> str:
133
+ return f"[{', '.join(evaluated_to_str(x) for x in value)}]"
134
+
135
+
136
+ @evaluated_to_str.register
137
+ def _evaluated_to_str_struct_literal(value: QmodStructInstance) -> str:
138
+ return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={evaluated_to_str(v)}' for k, v in value.fields.items())})"
139
+
140
+
141
+ @dataclass(frozen=True)
142
+ class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
143
+ value: Any
144
+ defining_function: Optional["FunctionClosure"] = None
145
+
146
+ def as_type(self, t: type[T]) -> T:
147
+ if t is int:
148
+ return self._as_int() # type: ignore[return-value]
149
+
150
+ if not isinstance(self.value, t):
151
+ raise ClassiqExpansionError(
152
+ f"Invalid access to expression {self.value!r} as {t}"
153
+ )
154
+
155
+ return self.value
156
+
157
+ def _as_int(self) -> int:
158
+ if not isinstance(self.value, (int, float)):
159
+ raise ClassiqExpansionError(
160
+ f"Invalid access to expression {self.value!r} as {int}"
161
+ )
162
+
163
+ return int(self.value)
164
+
165
+ def emit(self) -> ArgValue:
166
+ from classiq.model_expansions.closure import FunctionClosure
167
+
168
+ if isinstance(self.value, (QuantumSymbol, FunctionClosure)):
169
+ return self.value.emit()
170
+ if isinstance(self.value, list) and all(
171
+ isinstance(item, FunctionClosure) for item in self.value
172
+ ):
173
+ return [item.emit() for item in self.value]
174
+
175
+ ret = Expression(expr=evaluated_to_str(self.value))
176
+ ret._evaluated_expr = EvaluatedExpression(value=self.value)
177
+ return ret
178
+
179
+
180
+ if TYPE_CHECKING:
181
+ EvaluatedUserDict = UserDict[str, Evaluated]
182
+ else:
183
+ EvaluatedUserDict = UserDict
184
+
185
+
186
+ class Scope(EvaluatedUserDict):
187
+ def __init__(
188
+ self,
189
+ data: Optional[dict[str, Evaluated]] = None,
190
+ /,
191
+ *,
192
+ parent: Optional["Scope"] = None,
193
+ ) -> None:
194
+ super().__init__(data or {})
195
+ self._parent: Optional["Scope"] = parent
196
+
197
+ @property
198
+ def parent(self) -> Optional["Scope"]:
199
+ return self._parent
200
+
201
+ def __getitem__(self, name: str) -> Evaluated:
202
+ if name in self.data:
203
+ return self.data[name]
204
+ if self._parent is not None:
205
+ return self._parent[name]
206
+ if re.search(CPARAM_EXECUTION_SUFFIX_PATTERN, name):
207
+ return Evaluated(value=Symbol(name))
208
+ raise ClassiqExpansionError(f"Variable {name!r} is undefined")
209
+
210
+ def __contains__(self, item: Any) -> bool:
211
+ return item in self.data or (self._parent is not None and item in self._parent)
212
+
213
+ def __iter__(self) -> Iterator[str]:
214
+ if self._parent is None:
215
+ return iter(self.data)
216
+ return iter(itertools.chain(self.data, self._parent))
217
+
218
+ def iter_without_top_level(self) -> Iterator[str]:
219
+ if self.parent is None:
220
+ return iter(tuple())
221
+ return iter(itertools.chain(self.data, self.parent.iter_without_top_level()))
222
+
223
+ def __or__(self, other: Any) -> "Scope": # type: ignore[override]
224
+ if not (isinstance(other, Scope) and isinstance(self, Scope)):
225
+ raise ClassiqInternalExpansionError
226
+
227
+ if self.parent is None:
228
+ parent = other.parent
229
+ elif other.parent is None:
230
+ parent = self.parent
231
+ else:
232
+ parent = self.parent | other.parent
233
+
234
+ return Scope(
235
+ (self.data or {}) | (other.data or {}),
236
+ parent=parent,
237
+ )
238
+
239
+ def clone(self) -> "Scope":
240
+ return Scope(self.data, parent=self._parent)
@@ -0,0 +1,150 @@
1
+ from collections.abc import Sequence
2
+ from typing import TYPE_CHECKING
3
+
4
+ from classiq.interface.exceptions import ClassiqError
5
+ from classiq.interface.generator.constant import Constant
6
+ from classiq.interface.generator.expressions.expression_constants import (
7
+ CPARAM_EXECUTION_SUFFIX,
8
+ )
9
+ from classiq.interface.model.classical_parameter_declaration import (
10
+ ClassicalParameterDeclaration,
11
+ )
12
+ from classiq.interface.model.handle_binding import HandleBinding
13
+ from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
14
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
15
+ from classiq.interface.model.port_declaration import PortDeclaration
16
+ from classiq.interface.model.quantum_function_declaration import (
17
+ NamedParamsQuantumFunctionDeclaration,
18
+ PositionalArg,
19
+ QuantumFunctionDeclaration,
20
+ )
21
+
22
+ from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
23
+ from classiq.model_expansions.evaluators.classical_expression import (
24
+ evaluate_classical_expression,
25
+ )
26
+ from classiq.model_expansions.evaluators.parameter_types import (
27
+ evaluate_type_in_quantum_symbol,
28
+ )
29
+ from classiq.model_expansions.expression_renamer import ExpressionRenamer
30
+ from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
31
+ from classiq.qmod.builtins import BUILTIN_CONSTANTS
32
+ from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
33
+ from classiq.qmod.builtins.functions import (
34
+ CORE_LIB_DECLS,
35
+ STD_QMOD_OPERATORS,
36
+ )
37
+ from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
38
+ from classiq.qmod.model_state_container import QMODULE
39
+ from classiq.qmod.quantum_function import GenerativeQFunc
40
+
41
+
42
+ def get_main_renamer(
43
+ func_decls: Sequence[QuantumFunctionDeclaration],
44
+ ) -> ExpressionRenamer:
45
+ for func_decl in func_decls:
46
+ if func_decl.name == MAIN_FUNCTION_NAME:
47
+ if TYPE_CHECKING:
48
+ assert isinstance(func_decl, NamedParamsQuantumFunctionDeclaration)
49
+ return ExpressionRenamer.from_positional_arg_declarations(
50
+ func_decl.positional_arg_declarations, CPARAM_EXECUTION_SUFFIX
51
+ )
52
+ return ExpressionRenamer(var_mapping={})
53
+
54
+
55
+ def add_constants_to_scope(constants: list[Constant], scope: Scope) -> None:
56
+ for constant in constants:
57
+ scope[constant.name] = Evaluated(
58
+ value=evaluate_classical_expression(constant.value, scope).value
59
+ )
60
+
61
+
62
+ def add_functions_to_scope(
63
+ functions: Sequence[NativeFunctionDefinition], scope: Scope
64
+ ) -> None:
65
+ for function in functions:
66
+ if function.name not in scope:
67
+ scope[function.name] = Evaluated(
68
+ value=FunctionClosure.create(
69
+ name=function.name,
70
+ positional_arg_declarations=function.positional_arg_declarations,
71
+ body=function.body,
72
+ scope=Scope(parent=scope),
73
+ )
74
+ )
75
+
76
+
77
+ def add_generative_functions_to_scope(
78
+ functions: Sequence[GenerativeQFunc], scope: Scope
79
+ ) -> None:
80
+ for function in functions:
81
+ name = function.func_decl.name
82
+ if name == MAIN_FUNCTION_NAME or name not in scope:
83
+ scope[function.func_decl.name] = Evaluated(
84
+ value=GenerativeFunctionClosure.create(
85
+ name=function.func_decl.name,
86
+ positional_arg_declarations=function.func_decl.positional_arg_declarations,
87
+ scope=Scope(parent=scope),
88
+ generative_blocks={"body": function},
89
+ )
90
+ )
91
+
92
+
93
+ def _init_builtins_scope(scope: Scope) -> None:
94
+ for builtin_function in CORE_LIB_DECLS:
95
+ scope[builtin_function.name] = Evaluated(
96
+ value=FunctionClosure.create(
97
+ name=builtin_function.name,
98
+ positional_arg_declarations=builtin_function.positional_arg_declarations,
99
+ scope=Scope(parent=scope),
100
+ is_atomic=True,
101
+ )
102
+ )
103
+ for builtin_function in STD_QMOD_OPERATORS:
104
+ scope[builtin_function.name] = Evaluated(
105
+ value=FunctionClosure.create(
106
+ name=builtin_function.name,
107
+ positional_arg_declarations=builtin_function.positional_arg_declarations,
108
+ scope=Scope(parent=scope),
109
+ )
110
+ )
111
+ for constant in BUILTIN_CONSTANTS:
112
+ value = constant.value
113
+ if not value.is_evaluated():
114
+ raise ClassiqError(
115
+ f"Unevaluated built-in constants not supported. Offending constant: "
116
+ f"{constant.name} = {value}"
117
+ )
118
+ scope[constant.name] = Evaluated(value=value.value.value)
119
+
120
+
121
+ def add_entry_point_params_to_scope(
122
+ parameters: Sequence[PositionalArg], main_closure: FunctionClosure
123
+ ) -> None:
124
+ for parameter in parameters:
125
+ if isinstance(parameter, PortDeclaration):
126
+ main_closure.scope[parameter.name] = Evaluated(
127
+ value=QuantumSymbol(
128
+ handle=HandleBinding(name=parameter.name),
129
+ quantum_type=evaluate_type_in_quantum_symbol(
130
+ parameter.quantum_type, main_closure.scope, parameter.name
131
+ ),
132
+ ),
133
+ defining_function=main_closure,
134
+ )
135
+ elif isinstance(parameter, ClassicalParameterDeclaration):
136
+ main_closure.scope[parameter.name] = Evaluated(
137
+ value=parameter.classical_type.as_symbolic(parameter.name),
138
+ defining_function=main_closure,
139
+ )
140
+
141
+
142
+ def init_top_level_scope(model: Model, scope: Scope) -> None:
143
+ add_functions_to_scope(model.functions, scope)
144
+ add_constants_to_scope(model.constants, scope)
145
+ _init_builtins_scope(scope)
146
+
147
+
148
+ def init_builtin_types() -> None:
149
+ QMODULE.enum_decls |= BUILTIN_ENUM_DECLARATIONS
150
+ QMODULE.type_decls |= BUILTIN_STRUCT_DECLARATIONS
File without changes
@@ -0,0 +1,49 @@
1
+ from typing import Any, Optional
2
+
3
+ from sympy import Function, Integer
4
+ from sympy.logic.boolalg import BooleanFunction
5
+
6
+
7
+ class BitwiseAnd(Function):
8
+ @classmethod
9
+ def eval(cls, a: Any, b: Any) -> Optional[int]:
10
+ if isinstance(a, Integer) and isinstance(b, Integer):
11
+ return a & b
12
+
13
+ return None
14
+
15
+
16
+ class BitwiseXor(Function):
17
+ @classmethod
18
+ def eval(cls, a: Any, b: Any) -> Optional[int]:
19
+ if isinstance(a, Integer) and isinstance(b, Integer):
20
+ return a ^ b
21
+
22
+ return None
23
+
24
+
25
+ class LogicalXor(BooleanFunction):
26
+ @classmethod
27
+ def eval(cls, a: Any, b: Any) -> Optional[bool]:
28
+ if isinstance(a, bool) and isinstance(b, bool):
29
+ return a ^ b
30
+
31
+ return None
32
+
33
+
34
+ class BitwiseOr(Function):
35
+ @classmethod
36
+ def eval(cls, a: Any, b: Any) -> Optional[int]:
37
+ if isinstance(a, Integer) and isinstance(b, Integer):
38
+ return a | b
39
+
40
+ return None
41
+
42
+
43
+ class BitwiseNot(Function):
44
+ @classmethod
45
+ def eval(cls, a: Any) -> Optional[int]:
46
+ if isinstance(a, Integer):
47
+ return ~a
48
+
49
+ return None