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,239 @@
1
+ from collections.abc import Sequence
2
+ from typing import Optional
3
+
4
+ from classiq.interface.exceptions import (
5
+ ClassiqExpansionError,
6
+ ClassiqInternalExpansionError,
7
+ )
8
+ from classiq.interface.generator.expressions.expression import Expression
9
+ from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
10
+ from classiq.interface.generator.functions.type_name import (
11
+ TypeName,
12
+ )
13
+ from classiq.interface.model.bind_operation import BindOperation
14
+ from classiq.interface.model.inplace_binary_operation import BinaryOperation
15
+ from classiq.interface.model.port_declaration import PortDeclaration
16
+ from classiq.interface.model.quantum_function_declaration import PositionalArg
17
+ from classiq.interface.model.quantum_type import (
18
+ QuantumBit,
19
+ QuantumBitvector,
20
+ QuantumNumeric,
21
+ QuantumScalar,
22
+ QuantumType,
23
+ )
24
+
25
+ from classiq.model_expansions.scope import QuantumSymbol, Scope
26
+
27
+
28
+ def copy_type_information(
29
+ from_type: QuantumType,
30
+ to_type: QuantumType,
31
+ to_param_name: str,
32
+ ) -> None:
33
+ if isinstance(to_type, QuantumBit):
34
+ set_size(to_type, from_type.size_in_bits, to_param_name)
35
+ elif isinstance(to_type, QuantumNumeric):
36
+ set_is_signed(to_type, getattr(from_type, "sign_value", None), to_param_name)
37
+ set_fraction_digits(
38
+ to_type,
39
+ getattr(from_type, "fraction_digits_value", None),
40
+ to_param_name,
41
+ )
42
+ set_size(to_type, from_type.size_in_bits, to_param_name)
43
+ elif isinstance(to_type, QuantumBitvector):
44
+ if isinstance(from_type, QuantumBitvector) and type( # noqa: E721
45
+ from_type.element_type
46
+ ) == type(to_type.element_type):
47
+ copy_type_information(
48
+ from_type.element_type, to_type.element_type, to_param_name
49
+ )
50
+ set_size(to_type, from_type.size_in_bits, to_param_name)
51
+ elif isinstance(to_type, TypeName):
52
+ if isinstance(from_type, TypeName) and from_type.name == to_type.name:
53
+ for field in from_type.fields:
54
+ copy_type_information(
55
+ from_type.fields[field], to_type.fields[field], to_param_name
56
+ )
57
+ set_size(to_type, from_type.size_in_bits, to_param_name)
58
+ else:
59
+ raise ClassiqInternalExpansionError
60
+
61
+
62
+ def set_size(quantum_type: QuantumType, size: int, param_name: str) -> None:
63
+ if size <= 0:
64
+ raise ClassiqExpansionError(
65
+ f"Size for {param_name!r} was deduced to be non-positive: {size!r}"
66
+ )
67
+
68
+ if quantum_type.has_size_in_bits and quantum_type.size_in_bits != size:
69
+ raise ClassiqExpansionError(
70
+ f"Size mismatch for port {param_name!r} between declared size {quantum_type.size_in_bits} and assigned size {size}"
71
+ )
72
+
73
+ if isinstance(quantum_type, QuantumNumeric):
74
+ quantum_type.size = Expression(expr=str(size))
75
+ if not quantum_type.has_sign or not quantum_type.has_fraction_digits:
76
+ set_is_signed(quantum_type, False, param_name)
77
+ set_fraction_digits(quantum_type, 0, param_name)
78
+ elif isinstance(quantum_type, QuantumBitvector):
79
+ if quantum_type.has_length:
80
+ if size % quantum_type.length_value != 0:
81
+ raise ClassiqExpansionError(
82
+ f"Size mismatch for port {param_name!r}. Cannot fit {size} "
83
+ f"qubits into an array of {quantum_type.length_value} elements."
84
+ )
85
+ set_size(
86
+ quantum_type.element_type,
87
+ size // quantum_type.length_value,
88
+ param_name,
89
+ )
90
+ set_length_by_size(quantum_type, size, param_name)
91
+ elif isinstance(quantum_type, TypeName):
92
+ fields_without_size = [
93
+ field_type
94
+ for field_type in quantum_type.fields.values()
95
+ if not field_type.has_size_in_bits
96
+ ]
97
+ if len(fields_without_size) > 1:
98
+ raise ClassiqInternalExpansionError(
99
+ f"QuantumStruct should have at most one field without "
100
+ f"predetermined size. Found {fields_without_size}."
101
+ )
102
+ if len(fields_without_size) == 1:
103
+ predetermined_size_part = sum(
104
+ field_type.size_in_bits if field_type.has_size_in_bits else 0
105
+ for field_type in quantum_type.fields.values()
106
+ )
107
+ set_size(fields_without_size[0], size - predetermined_size_part, param_name)
108
+
109
+
110
+ def set_fraction_digits(
111
+ quantum_numeric: QuantumNumeric, fraction_digits: Optional[int], param_name: str
112
+ ) -> None:
113
+ if fraction_digits is not None and fraction_digits < 0:
114
+ raise ClassiqExpansionError(
115
+ f"Number of fraction digits for {param_name!r} was deduced to be negative: "
116
+ f"{fraction_digits!r}"
117
+ )
118
+
119
+ if (
120
+ fraction_digits is not None
121
+ and quantum_numeric.fraction_digits is not None
122
+ and quantum_numeric.fraction_digits.is_evaluated()
123
+ and quantum_numeric.fraction_digits_value != fraction_digits
124
+ ):
125
+ raise ClassiqExpansionError(
126
+ f"Fraction digits mismatch for port {param_name!r} between declared "
127
+ f"fraction digits {quantum_numeric.fraction_digits_value!r} and assigned fraction "
128
+ f"digits {fraction_digits!r}"
129
+ )
130
+
131
+ if not (
132
+ quantum_numeric.fraction_digits is not None
133
+ and quantum_numeric.fraction_digits.is_evaluated()
134
+ ):
135
+ quantum_numeric.fraction_digits = Expression(expr=str(fraction_digits or 0))
136
+
137
+
138
+ def set_is_signed(
139
+ quantum_numeric: QuantumNumeric, is_signed: Optional[bool], param_name: str
140
+ ) -> None:
141
+ if (
142
+ is_signed is not None
143
+ and quantum_numeric.is_signed is not None
144
+ and quantum_numeric.is_signed.is_evaluated()
145
+ and quantum_numeric.sign_value != is_signed
146
+ ):
147
+ raise ClassiqExpansionError(
148
+ f"Sign mismatch for port {param_name!r} between declared sign {quantum_numeric.sign_value!r} and assigned sign {is_signed!r}"
149
+ )
150
+
151
+ if not (
152
+ quantum_numeric.is_signed is not None
153
+ and quantum_numeric.is_signed.is_evaluated()
154
+ ):
155
+ quantum_numeric.is_signed = Expression(expr=str(is_signed or False))
156
+
157
+
158
+ def set_element_type(
159
+ quantum_array: QuantumBitvector, element_type: ConcreteQuantumType
160
+ ) -> None:
161
+ quantum_array.element_type = element_type
162
+
163
+
164
+ def set_length(quantum_array: QuantumBitvector, length: int) -> None:
165
+ quantum_array.length = Expression(expr=str(length))
166
+
167
+
168
+ def set_length_by_size(
169
+ quantum_array: QuantumBitvector, size: int, param_name: str
170
+ ) -> None:
171
+ if size <= 0:
172
+ raise ClassiqExpansionError(
173
+ f"Size for {param_name!r} was deduced to be non-positive: {size!r}"
174
+ )
175
+
176
+ if quantum_array.has_size_in_bits and quantum_array.size_in_bits != size:
177
+ raise ClassiqExpansionError(
178
+ f"Size mismatch for port {param_name!r} between declared size "
179
+ f"{quantum_array.size_in_bits} ({quantum_array.length_value} elements of "
180
+ f"size {quantum_array.element_type.size_in_bits}) and assigned size {size}."
181
+ )
182
+
183
+ if not quantum_array.element_type.has_size_in_bits:
184
+ raise ClassiqExpansionError(
185
+ f"Could not infer element size for array {param_name!r}."
186
+ )
187
+ element_size = quantum_array.element_type.size_in_bits
188
+
189
+ if size % element_size != 0:
190
+ raise ClassiqExpansionError(
191
+ f"Size mismatch for port {param_name!r}. Cannot fit elements of type "
192
+ f"{quantum_array.element_type.qmod_type_name} (size {element_size}) into "
193
+ f"{size} qubits."
194
+ )
195
+
196
+ quantum_array.length = Expression(expr=str(size // element_size))
197
+
198
+
199
+ def validate_bind_targets(bind: BindOperation, scope: Scope) -> None:
200
+ illegal_qnum_bind_targets = []
201
+ for out_handle in bind.out_handles:
202
+ out_var = scope[out_handle.name].as_type(QuantumSymbol)
203
+ out_var_type = out_var.quantum_type
204
+ if not isinstance(out_var_type, QuantumNumeric):
205
+ continue
206
+ if not out_var_type.has_size_in_bits:
207
+ illegal_qnum_bind_targets.append(str(out_var.handle))
208
+ elif not out_var_type.has_sign:
209
+ assert not out_var_type.has_fraction_digits
210
+ illegal_qnum_bind_targets.append(str(out_var.handle))
211
+ if len(illegal_qnum_bind_targets) > 0:
212
+ raise ClassiqExpansionError(
213
+ f"QNum bind targets {illegal_qnum_bind_targets!r} must be declared or initialized with size, sign, and fraction digits"
214
+ )
215
+
216
+
217
+ def get_inplace_op_scalar_as_numeric(
218
+ var: QuantumSymbol, operation: BinaryOperation, var_kind: str
219
+ ) -> QuantumNumeric:
220
+ if not isinstance(var.quantum_type, QuantumScalar):
221
+ raise ClassiqExpansionError(
222
+ f"Cannot perform inplace {operation.name.lower()} with non-scalar {var_kind} {var.handle}"
223
+ )
224
+ if isinstance(var.quantum_type, QuantumNumeric):
225
+ return var.quantum_type
226
+ if isinstance(var.quantum_type, QuantumBit):
227
+ return QuantumNumeric(
228
+ size=Expression(expr="1"),
229
+ is_signed=Expression(expr="False"),
230
+ fraction_digits=Expression(expr="0"),
231
+ )
232
+ raise ClassiqInternalExpansionError(f"Unexpected scalar type {var.quantum_type}")
233
+
234
+
235
+ def is_signature_monomorphic(params: Sequence[PositionalArg]) -> bool:
236
+ return all(
237
+ isinstance(param, PortDeclaration) and param.quantum_type.is_evaluated
238
+ for param in params
239
+ )
@@ -0,0 +1,90 @@
1
+ from collections.abc import Sequence
2
+
3
+ from classiq.interface.exceptions import (
4
+ ClassiqExpansionError,
5
+ ClassiqInternalExpansionError,
6
+ )
7
+ from classiq.interface.model.classical_parameter_declaration import (
8
+ AnonClassicalParameterDeclaration,
9
+ )
10
+ from classiq.interface.model.port_declaration import AnonPortDeclaration
11
+ from classiq.interface.model.quantum_function_declaration import (
12
+ AnonPositionalArg,
13
+ AnonQuantumOperandDeclaration,
14
+ )
15
+
16
+
17
+ def check_signature_match(
18
+ decl_params: Sequence[AnonPositionalArg],
19
+ op_params: Sequence[AnonPositionalArg],
20
+ location_str: str,
21
+ ) -> None:
22
+ if len(decl_params) != len(op_params):
23
+ raise ClassiqExpansionError(
24
+ f"{location_str} should have {len(decl_params)} parameters, "
25
+ f"not {len(op_params)}"
26
+ )
27
+ for idx, (decl_param, op_param) in enumerate(zip(decl_params, op_params)):
28
+ message_prefix = f"Argument {idx} in {location_str} has incompatible type; "
29
+ _check_type_match(op_param, decl_param, location_str, message_prefix)
30
+
31
+
32
+ def _check_type_match(
33
+ op_param: AnonPositionalArg,
34
+ decl_param: AnonPositionalArg,
35
+ location_str: str,
36
+ message_prefix: str,
37
+ ) -> None:
38
+ if isinstance(decl_param, AnonPortDeclaration):
39
+ error_message = message_prefix + "expected quantum parameter"
40
+ _check_qvar_type_match(op_param, error_message)
41
+ elif isinstance(decl_param, AnonQuantumOperandDeclaration):
42
+ if decl_param.is_list:
43
+ error_message = message_prefix + "expected operand list parameter"
44
+ else:
45
+ error_message = message_prefix + "expected operand parameter"
46
+ _check_operand_type_match(op_param, decl_param, location_str, error_message)
47
+ elif isinstance(decl_param, AnonClassicalParameterDeclaration):
48
+ error_message = (
49
+ message_prefix + f"expected classical {decl_param.classical_type} parameter"
50
+ )
51
+ _check_classical_type_match(op_param, decl_param, error_message)
52
+ else:
53
+ raise ClassiqInternalExpansionError(
54
+ f"unexpected parameter declaration type: {type(decl_param).__name__}"
55
+ )
56
+
57
+
58
+ def _check_qvar_type_match(op_param: AnonPositionalArg, error_message: str) -> None:
59
+ if not isinstance(op_param, AnonPortDeclaration):
60
+ raise ClassiqExpansionError(error_message)
61
+
62
+
63
+ def _check_operand_type_match(
64
+ op_param: AnonPositionalArg,
65
+ decl_param: AnonQuantumOperandDeclaration,
66
+ location_str: str,
67
+ error_message: str,
68
+ ) -> None:
69
+ if (
70
+ not isinstance(op_param, AnonQuantumOperandDeclaration)
71
+ or decl_param.is_list ^ op_param.is_list
72
+ ):
73
+ raise ClassiqExpansionError(error_message)
74
+ check_signature_match(
75
+ decl_param.positional_arg_declarations,
76
+ op_param.positional_arg_declarations,
77
+ f"operand {decl_param.name} in {location_str}",
78
+ )
79
+
80
+
81
+ def _check_classical_type_match(
82
+ op_param: AnonPositionalArg,
83
+ decl_param: AnonClassicalParameterDeclaration,
84
+ error_message: str,
85
+ ) -> None:
86
+ if (
87
+ not isinstance(op_param, AnonClassicalParameterDeclaration)
88
+ or decl_param.classical_type != op_param.classical_type
89
+ ):
90
+ raise ClassiqExpansionError(error_message)
@@ -0,0 +1,135 @@
1
+ import ast
2
+ import re
3
+ from collections.abc import Mapping
4
+ from enum import EnumMeta
5
+ from typing import Any, Optional
6
+
7
+ from sympy import sympify
8
+
9
+ from classiq.interface.exceptions import ClassiqExpansionError
10
+ from classiq.interface.generator.constant import Constant
11
+ from classiq.interface.generator.expressions.evaluated_expression import (
12
+ EvaluatedExpression,
13
+ )
14
+ from classiq.interface.generator.expressions.expression import Expression
15
+ from classiq.interface.generator.expressions.expression_constants import (
16
+ CPARAM_EXECUTION_SUFFIX_PATTERN,
17
+ )
18
+ from classiq.interface.generator.expressions.expression_types import ExpressionValue
19
+ from classiq.interface.generator.expressions.sympy_supported_expressions import (
20
+ SYMPY_SUPPORTED_EXPRESSIONS,
21
+ )
22
+
23
+ from classiq.model_expansions.atomic_expression_functions_defs import (
24
+ ATOMIC_EXPRESSION_FUNCTIONS,
25
+ qmod_val_to_python,
26
+ )
27
+ from classiq.model_expansions.sympy_conversion.expression_to_sympy import (
28
+ translate_to_sympy,
29
+ )
30
+ from classiq.model_expansions.sympy_conversion.sympy_to_python import sympy_to_python
31
+ from classiq.qmod import symbolic
32
+ from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
33
+ from classiq.qmod.model_state_container import QMODULE
34
+
35
+
36
+ def evaluate_constants(constants: list[Constant]) -> dict[str, EvaluatedExpression]:
37
+ result: dict[str, EvaluatedExpression] = {}
38
+ for constant in constants:
39
+ result[constant.name] = evaluate(constant.value, result)
40
+ return result
41
+
42
+
43
+ def evaluate_constants_as_python(constants: list[Constant]) -> dict[str, Any]:
44
+ evaluated = evaluate_constants(constants)
45
+ return {
46
+ constant.name: qmod_val_to_python(
47
+ evaluated[constant.name].value, constant.const_type
48
+ )
49
+ for constant in constants
50
+ }
51
+
52
+
53
+ def evaluate(
54
+ expr: Expression,
55
+ locals_dict: Mapping[str, EvaluatedExpression],
56
+ uninitialized_locals: Optional[set[str]] = None,
57
+ ) -> EvaluatedExpression:
58
+ model_locals: dict[str, ExpressionValue] = {}
59
+ model_locals.update(ATOMIC_EXPRESSION_FUNCTIONS)
60
+ model_locals.update(
61
+ {
62
+ enum_decl.name: enum_decl.create_enum()
63
+ for enum_decl in (QMODULE.enum_decls | BUILTIN_ENUM_DECLARATIONS).values()
64
+ }
65
+ )
66
+ # locals override builtin-functions
67
+ model_locals.update({name: expr.value for name, expr in locals_dict.items()})
68
+ uninitialized_locals = uninitialized_locals or set()
69
+
70
+ _validate_undefined_vars(expr.expr, model_locals, uninitialized_locals)
71
+
72
+ sympy_expr = translate_to_sympy(expr.expr)
73
+ try:
74
+ sympify_result = sympify(sympy_expr, locals=model_locals)
75
+ except (TypeError, IndexError) as e:
76
+ raise ClassiqExpansionError(str(e)) from None
77
+ except AttributeError as e:
78
+ if isinstance(e.obj, EnumMeta):
79
+ raise ClassiqExpansionError(
80
+ f"Enum {e.obj.__name__} has no member {e.name!r}. Available members: "
81
+ f"{', '.join(e.obj.__members__)}"
82
+ ) from e
83
+ raise
84
+
85
+ return EvaluatedExpression(
86
+ value=sympy_to_python(sympify_result, locals=model_locals)
87
+ )
88
+
89
+
90
+ def _validate_undefined_vars(
91
+ expr: str,
92
+ model_locals: dict[str, ExpressionValue],
93
+ uninitialized_locals: Optional[set[str]],
94
+ ) -> None:
95
+ uninitialized_locals = uninitialized_locals or set()
96
+ id_visitor = _VarsCollector()
97
+ id_visitor.visit(ast.parse(expr))
98
+ identifiers = id_visitor.vars
99
+ undefined_vars = (
100
+ identifiers
101
+ - model_locals.keys()
102
+ - set(SYMPY_SUPPORTED_EXPRESSIONS)
103
+ - set(symbolic.__all__)
104
+ - uninitialized_locals
105
+ )
106
+
107
+ # Ignore expanded execution parameters
108
+ undefined_vars = {
109
+ var
110
+ for var in undefined_vars
111
+ if not re.search(CPARAM_EXECUTION_SUFFIX_PATTERN, var)
112
+ }
113
+
114
+ if len(undefined_vars) == 1:
115
+ undefined_var = undefined_vars.__iter__().__next__()
116
+ raise ClassiqExpansionError(f"Variable {undefined_var!r} is undefined")
117
+ elif len(undefined_vars) > 1:
118
+ raise ClassiqExpansionError(f"Variables {list(undefined_vars)} are undefined")
119
+
120
+
121
+ class _VarsCollector(ast.NodeTransformer):
122
+ def __init__(self) -> None:
123
+ self.vars: set[str] = set()
124
+
125
+ def visit_Name(self, node: ast.Name) -> None:
126
+ self.vars.add(node.id)
127
+
128
+ def visit_Call(self, node: ast.Call) -> None:
129
+ func = node.func
130
+ self.visit(func)
131
+ if not isinstance(func, ast.Name) or func.id != "struct_literal":
132
+ for arg in node.args:
133
+ self.visit(arg)
134
+ for kw in node.keywords:
135
+ self.visit(kw)
@@ -0,0 +1,76 @@
1
+ import ast
2
+ from collections.abc import Sequence
3
+
4
+ from classiq.interface.generator.expressions.expression import Expression
5
+ from classiq.interface.generator.expressions.expression_constants import (
6
+ RESERVED_EXPRESSIONS,
7
+ )
8
+ from classiq.interface.generator.visitor import Transformer
9
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
10
+ from classiq.interface.model.quantum_function_declaration import (
11
+ ClassicalParameterDeclaration,
12
+ PositionalArg,
13
+ )
14
+
15
+ from classiq.model_expansions.visitors.variable_references import VarRefTransformer
16
+
17
+
18
+ class ExpressionRenamer(Transformer):
19
+
20
+ def __init__(self, var_mapping: dict[str, str]) -> None:
21
+ self.var_ref_transformer = VarRefTransformer(var_mapping)
22
+
23
+ @property
24
+ def var_mapping(self) -> dict[str, str]:
25
+ return self.var_ref_transformer.var_mapping
26
+
27
+ def visit_QuantumFunctionCall(
28
+ self, node: QuantumFunctionCall
29
+ ) -> QuantumFunctionCall:
30
+ update_dict = dict(
31
+ positional_args=[self.visit(arg) for arg in node.positional_args],
32
+ )
33
+ return node.model_copy(update=update_dict)
34
+
35
+ def visit_Expression(self, expression: Expression) -> Expression:
36
+ parsed_expr = ast.parse(expression.expr)
37
+ renamed_expr = self.var_ref_transformer.visit(parsed_expr)
38
+ return Expression(expr=ast.unparse(renamed_expr))
39
+
40
+ def rename_string(self, name: str) -> str:
41
+ return self.var_mapping.get(name, name)
42
+
43
+ def rename_expression_dict(
44
+ self, expr_dict: dict[str, Expression]
45
+ ) -> dict[str, Expression]:
46
+ return {
47
+ self.rename_string(key): self.visit(val) for key, val in expr_dict.items()
48
+ }
49
+
50
+ @classmethod
51
+ def from_positional_arg_declarations(
52
+ cls, positional_arg_declarations: Sequence[PositionalArg], suffix: str
53
+ ) -> "ExpressionRenamer":
54
+ var_mapping: dict[str, str] = dict()
55
+ for arg in positional_arg_declarations:
56
+ if not isinstance(arg, ClassicalParameterDeclaration):
57
+ continue
58
+ if arg.name in RESERVED_EXPRESSIONS:
59
+ continue
60
+ new_name = arg.name + suffix
61
+ var_mapping[arg.name] = new_name
62
+
63
+ return cls(var_mapping)
64
+
65
+ def rename_positional_arg_declarations(
66
+ self, positional_arg_declarations: Sequence[PositionalArg]
67
+ ) -> Sequence[PositionalArg]:
68
+ return tuple(
69
+ (
70
+ arg.rename(self.var_mapping[arg.name])
71
+ if isinstance(arg, ClassicalParameterDeclaration)
72
+ and arg.name in self.var_mapping
73
+ else arg
74
+ )
75
+ for arg in positional_arg_declarations
76
+ )