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,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
@@ -0,0 +1,179 @@
1
+ import ast
2
+ from typing import TYPE_CHECKING, cast
3
+
4
+ from classiq.interface.exceptions import ClassiqExpansionError
5
+
6
+ MISSING_SLICE_VALUE_PLACEHOLDER = "MISSING_SLICE_VALUE"
7
+
8
+
9
+ def translate_to_sympy(expr: str) -> str:
10
+ node = ast.parse(expr)
11
+ node = ExpressionSympyTranslator().visit(node)
12
+ # node is a Module, we want an Expression
13
+ if TYPE_CHECKING:
14
+ assert isinstance(node.body[0], ast.Expr)
15
+ expression = ast.Expression(node.body[0].value)
16
+
17
+ return ast.unparse(ast.fix_missing_locations(expression))
18
+
19
+
20
+ class ExpressionSympyTranslator(ast.NodeTransformer):
21
+ BINARY_OPERATORS: dict[type[ast.AST], str] = {
22
+ ast.BitOr: "BitwiseOr",
23
+ ast.BitAnd: "BitwiseAnd",
24
+ ast.BitXor: "BitwiseXor",
25
+ ast.Div: "do_div",
26
+ }
27
+
28
+ UNARY_OPERATORS: dict[type[ast.AST], str] = {
29
+ ast.Invert: "BitwiseNot",
30
+ ast.Not: "Not",
31
+ }
32
+
33
+ BOOLEAN_OPERATORS: dict[type[ast.AST], str] = {
34
+ ast.Or: "Or",
35
+ ast.And: "And",
36
+ }
37
+
38
+ COMPARE_OPERATORS: dict[type[ast.AST], str] = {
39
+ ast.Eq: "Eq",
40
+ ast.NotEq: "Ne",
41
+ }
42
+
43
+ SPECIAL_FUNCTIONS: dict[str, str] = {
44
+ "max": "Max",
45
+ "min": "Min",
46
+ }
47
+
48
+ def visit_BinOp(self, node: ast.BinOp) -> ast.AST:
49
+ sympy_class = self.BINARY_OPERATORS.get(node.op.__class__)
50
+ if sympy_class is not None:
51
+ left = self.visit(node.left)
52
+ right = self.visit(node.right)
53
+
54
+ new_node = ast.Call(
55
+ func=ast.Name(id=sympy_class, ctx=ast.Load()),
56
+ args=[left, right],
57
+ starargs=None,
58
+ keywords=[],
59
+ kwargs=None,
60
+ )
61
+
62
+ return new_node
63
+ return self.generic_visit(node)
64
+
65
+ def visit_Compare(self, node: ast.Compare) -> ast.AST:
66
+ if len(node.ops) > 1:
67
+ raise ClassiqExpansionError(
68
+ f"Qmod expressions do not support chained comparison, as done in {ast.unparse(node)}"
69
+ )
70
+ sympy_class = self.COMPARE_OPERATORS.get(node.ops[0].__class__)
71
+ if sympy_class is not None:
72
+ left = self.visit(node.left)
73
+ right = self.visit(node.comparators[0])
74
+
75
+ new_node = ast.Call(
76
+ func=ast.Name(id=sympy_class, ctx=ast.Load()),
77
+ args=[left, right],
78
+ starargs=None,
79
+ keywords=[],
80
+ kwargs=None,
81
+ )
82
+
83
+ return new_node
84
+ return self.generic_visit(node)
85
+
86
+ def visit_BoolOp(self, node: ast.BoolOp) -> ast.AST:
87
+ sympy_class = self.BOOLEAN_OPERATORS.get(node.op.__class__)
88
+ if sympy_class is not None:
89
+ values = [self.visit(value) for value in node.values]
90
+
91
+ new_node = ast.Call(
92
+ func=ast.Name(id=sympy_class, ctx=ast.Load()),
93
+ args=values,
94
+ starargs=None,
95
+ keywords=[],
96
+ kwargs=None,
97
+ )
98
+
99
+ return new_node
100
+ return self.generic_visit(node)
101
+
102
+ def visit_UnaryOp(self, node: ast.UnaryOp) -> ast.AST:
103
+ sympy_class = self.UNARY_OPERATORS.get(node.op.__class__)
104
+ if sympy_class is not None:
105
+ operand = self.visit(node.operand)
106
+
107
+ new_node = ast.Call(
108
+ func=ast.Name(id=sympy_class, ctx=ast.Load()),
109
+ args=[operand],
110
+ starargs=None,
111
+ keywords=[],
112
+ kwargs=None,
113
+ )
114
+
115
+ return new_node
116
+ return self.generic_visit(node)
117
+
118
+ def visit_Call(self, node: ast.Call) -> ast.AST:
119
+ if isinstance(node.func, ast.Name) and node.func.id == "Piecewise":
120
+ return self._visit_piecewise(node)
121
+
122
+ if (
123
+ not isinstance(node.func, ast.Name)
124
+ or node.func.id not in self.SPECIAL_FUNCTIONS
125
+ ):
126
+ return self.generic_visit(node)
127
+
128
+ return ast.Call(
129
+ func=ast.Name(self.SPECIAL_FUNCTIONS[node.func.id]),
130
+ args=[self.visit(arg) for arg in (node.args)],
131
+ keywords=[self.visit(arg) for arg in node.keywords],
132
+ )
133
+
134
+ def _visit_piecewise(self, node: ast.Call) -> ast.AST:
135
+ # sympy Piecewise expression may include bitwise operations:
136
+ # Piecewise((0, Eq(x, 0)), (0.5, Eq(x, 1) | Eq(x, 2)), (1, True))
137
+ # ^
138
+ # We should avoid converting these to 'BitwiseOr' and such.
139
+ return ast.Call(
140
+ func=node.func,
141
+ args=[
142
+ ast.Tuple(
143
+ elts=(
144
+ self.generic_visit(cast(ast.Tuple, arg).elts[0]),
145
+ cast(ast.Tuple, arg).elts[1],
146
+ )
147
+ )
148
+ for arg in node.args
149
+ ],
150
+ keywords=node.keywords,
151
+ )
152
+
153
+ def visit_Subscript(self, node: ast.Subscript) -> ast.AST:
154
+ if isinstance(node.slice, ast.Slice):
155
+ if node.slice.lower is not None:
156
+ lower = self.visit(node.slice.lower)
157
+ else:
158
+ lower = ast.Name(MISSING_SLICE_VALUE_PLACEHOLDER)
159
+ if node.slice.upper is not None:
160
+ upper = self.visit(node.slice.upper)
161
+ else:
162
+ upper = ast.Name(MISSING_SLICE_VALUE_PLACEHOLDER)
163
+ return ast.Call(
164
+ func=ast.Name("do_slice"),
165
+ args=[self.visit(node.value), lower, upper],
166
+ keywords=[],
167
+ )
168
+ return ast.Call(
169
+ func=ast.Name("do_subscript"),
170
+ args=[self.visit(node.value), self.visit(node.slice)],
171
+ keywords=[],
172
+ )
173
+
174
+ def visit_Attribute(self, node: ast.Attribute) -> ast.Call:
175
+ return ast.Call(
176
+ func=ast.Name("get_field"),
177
+ args=[node.value, ast.Constant(value=node.attr)],
178
+ keywords=[],
179
+ )