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
@@ -1,160 +1,193 @@
1
1
  import dataclasses
2
- import inspect
3
2
  import sys
4
- from typing import Any, Callable, Dict, List, Optional, Type, get_args, get_origin
3
+ from collections.abc import Sequence
4
+ from enum import EnumMeta
5
+ from typing import (
6
+ Any,
7
+ Callable,
8
+ Literal,
9
+ Optional,
10
+ get_args,
11
+ get_origin,
12
+ overload,
13
+ )
5
14
 
6
15
  from typing_extensions import _AnnotatedAlias
7
16
 
8
- from classiq.interface.generator.functions.classical_type import (
9
- Bool,
10
- ClassicalArray,
11
- ClassicalList,
12
- ConcreteClassicalType,
13
- Integer,
14
- QStructBase,
15
- Real,
16
- Struct,
17
+ from classiq.interface.exceptions import ClassiqValueError
18
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
19
+ from classiq.interface.generator.functions.port_declaration import (
20
+ PortDeclarationDirection,
17
21
  )
22
+ from classiq.interface.generator.types.enum_declaration import declaration_from_enum
23
+ from classiq.interface.generator.types.struct_declaration import StructDeclaration
18
24
  from classiq.interface.model.classical_parameter_declaration import (
19
- ClassicalParameterDeclaration,
25
+ AnonClassicalParameterDeclaration,
20
26
  )
21
- from classiq.interface.model.port_declaration import PortDeclaration
27
+ from classiq.interface.model.port_declaration import AnonPortDeclaration
22
28
  from classiq.interface.model.quantum_function_declaration import (
29
+ AnonPositionalArg,
30
+ AnonQuantumOperandDeclaration,
31
+ NamedParamsQuantumFunctionDeclaration,
23
32
  PositionalArg,
24
- QuantumFunctionDeclaration,
25
- QuantumOperandDeclaration,
26
33
  )
27
34
 
28
- from classiq import StructDeclaration
35
+ from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
36
+ from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
29
37
  from classiq.qmod.model_state_container import ModelStateContainer
30
- from classiq.qmod.qmod_parameter import Array, QParam
31
- from classiq.qmod.qmod_variable import QVar, get_type_hint_expr
32
- from classiq.qmod.quantum_callable import QCallable, QCallableList
33
- from classiq.qmod.utilities import unmangle_keyword
34
-
35
- OPERAND_ARG_NAME = "arg{i}"
36
-
37
-
38
- def _version_portable_get_args(py_type: type) -> tuple:
39
- if get_origin(py_type) is None:
40
- return tuple()
41
- if sys.version_info[0:2] < (3, 10):
42
- return get_args(py_type) # The result of __class_getitem__
43
- else:
44
- return get_args(py_type)[0]
45
-
46
-
47
- def _python_type_to_qmod(
48
- py_type: type, *, qmodule: ModelStateContainer
49
- ) -> Optional[ConcreteClassicalType]:
50
- if py_type == int:
51
- return Integer()
52
- elif py_type == float:
53
- return Real()
54
- elif py_type == bool:
55
- return Bool()
56
- elif get_origin(py_type) == list:
57
- return ClassicalList(
58
- element_type=_python_type_to_qmod(get_args(py_type)[0], qmodule=qmodule)
59
- )
60
- elif get_origin(py_type) == Array:
61
- array_args = _version_portable_get_args(py_type)
62
- if len(array_args) != 2:
63
- raise ValueError(
64
- "Array accepts two generic parameters in the form 'Array[<element-type>, <size>]'"
65
- )
66
- return ClassicalArray(
67
- element_type=_python_type_to_qmod(array_args[0], qmodule=qmodule),
68
- size=get_type_hint_expr(array_args[1]),
38
+ from classiq.qmod.python_classical_type import PythonClassicalType
39
+ from classiq.qmod.qmod_variable import QVar
40
+ from classiq.qmod.quantum_callable import QCallableList
41
+ from classiq.qmod.utilities import unmangle_keyword, version_portable_get_args
42
+
43
+ if sys.version_info[0:2] >= (3, 9):
44
+ from typing import Annotated
45
+
46
+
47
+ class _PythonClassicalType(PythonClassicalType):
48
+ def __init__(self, qmodule: Optional[ModelStateContainer]):
49
+ super().__init__()
50
+ self.qmodule = qmodule
51
+
52
+ def register_enum(self, py_type: EnumMeta) -> None:
53
+ if (
54
+ self.qmodule is None
55
+ or py_type.__name__ in BUILTIN_ENUM_DECLARATIONS
56
+ or py_type.__name__ in self.qmodule.enum_decls
57
+ ):
58
+ return
59
+
60
+ enum_decl = declaration_from_enum(py_type)
61
+ self.qmodule.enum_decls[py_type.__name__] = enum_decl
62
+
63
+ def register_struct(self, py_type: type) -> None:
64
+ if (
65
+ self.qmodule is None
66
+ or py_type.__name__ in BUILTIN_STRUCT_DECLARATIONS
67
+ or py_type.__name__ in self.qmodule.type_decls
68
+ ):
69
+ return
70
+
71
+ struct_decl = StructDeclaration(
72
+ name=py_type.__name__,
73
+ variables={
74
+ f.name: self.convert(f.type) for f in dataclasses.fields(py_type)
75
+ },
69
76
  )
70
- elif inspect.isclass(py_type) and issubclass(py_type, QStructBase):
71
- _add_qmod_struct(py_type, qmodule=qmodule)
72
- return Struct(name=py_type.__name__)
73
- return None
74
-
75
-
76
- def _add_qmod_struct(
77
- py_type: Type[QStructBase], *, qmodule: ModelStateContainer
78
- ) -> None:
79
- if (
80
- py_type.__name__ in StructDeclaration.BUILTIN_STRUCT_DECLARATIONS
81
- or py_type.__name__ in qmodule.type_decls.keys()
82
- ):
83
- return
84
-
85
- qmodule.type_decls[py_type.__name__] = StructDeclaration(
86
- name=py_type.__name__,
87
- variables={
88
- f.name: _python_type_to_qmod(f.type, qmodule=qmodule)
89
- for f in dataclasses.fields(py_type)
90
- },
91
- )
77
+ self.qmodule.type_decls[py_type.__name__] = struct_decl
92
78
 
93
79
 
94
- def _extract_param_decl(
95
- name: str, py_type: Any, *, qmodule: ModelStateContainer
96
- ) -> ClassicalParameterDeclaration:
97
- if len(get_args(py_type)) != 1:
98
- raise ValueError("QParam takes exactly one generic argument")
99
- py_type = get_args(py_type)[0]
100
- return ClassicalParameterDeclaration(
101
- name=name, classical_type=_python_type_to_qmod(py_type, qmodule=qmodule)
102
- )
80
+ def python_type_to_qmod(
81
+ py_type: type, *, qmodule: Optional[ModelStateContainer]
82
+ ) -> Optional[ConcreteClassicalType]:
83
+ return _PythonClassicalType(qmodule).convert(py_type)
103
84
 
104
85
 
105
- def _extract_port_decl(name: str, py_type: Any) -> PortDeclaration:
86
+ def _extract_port_decl(name: Optional[str], py_type: Any) -> AnonPortDeclaration:
106
87
  # FIXME: CAD-13409
107
- qtype: Type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
88
+ qtype: type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
108
89
  direction = qtype.port_direction(py_type)
109
90
  if isinstance(py_type, _AnnotatedAlias):
110
91
  py_type = py_type.__args__[0]
111
- return PortDeclaration(
112
- name=name,
92
+ param = AnonPortDeclaration(
93
+ name=None,
113
94
  direction=direction,
114
95
  quantum_type=qtype.to_qmod_quantum_type(py_type),
115
96
  )
97
+ if name is not None:
98
+ param = param.rename(name)
99
+ return param
116
100
 
117
101
 
118
102
  def _extract_operand_decl(
119
- name: str, py_type: Any, qmodule: ModelStateContainer
120
- ) -> QuantumOperandDeclaration:
121
- qc_args = _version_portable_get_args(py_type)
122
- arg_dict = {
123
- OPERAND_ARG_NAME.format(i=i): arg_type for i, arg_type in enumerate(qc_args)
124
- }
125
- return QuantumOperandDeclaration(
103
+ name: Optional[str], py_type: Any, qmodule: Optional[ModelStateContainer]
104
+ ) -> AnonQuantumOperandDeclaration:
105
+ is_list = (get_origin(py_type) or py_type) is QCallableList
106
+ if get_origin(py_type) is list:
107
+ is_list = True
108
+ py_type = version_portable_get_args(py_type)[0]
109
+ type_args = version_portable_get_args(py_type)
110
+ if len(type_args) > 0 and isinstance(type_args[0], list): # Callable support
111
+ type_args = tuple(type_args[0])
112
+ param_decls = [_extract_operand_param(arg_type) for arg_type in type_args]
113
+ param = AnonQuantumOperandDeclaration(
126
114
  name=name,
127
- positional_arg_declarations=_extract_positional_args(arg_dict, qmodule=qmodule),
128
- is_list=(get_origin(py_type) or py_type) is QCallableList,
115
+ positional_arg_declarations=_extract_positional_args(
116
+ param_decls, qmodule=qmodule
117
+ ),
118
+ is_list=is_list,
119
+ )
120
+ if name is not None:
121
+ param = param.rename(name)
122
+ return param
123
+
124
+
125
+ def _extract_operand_param(py_type: Any) -> tuple[Optional[str], Any]:
126
+ if sys.version_info[0:2] < (3, 9) or get_origin(py_type) is not Annotated:
127
+ return None, py_type
128
+ args = get_args(py_type)
129
+ if len(args) == 2:
130
+ if isinstance(args[1], PortDeclarationDirection):
131
+ return None, py_type
132
+ elif isinstance(args[1], str):
133
+ return args[1], args[0]
134
+ elif get_origin(args[1]) is Literal:
135
+ return version_portable_get_args(args[1])[0], args[0]
136
+ elif len(args) == 3 and isinstance(args[1], PortDeclarationDirection):
137
+ if isinstance(args[2], str):
138
+ return args[2], Annotated[args[0], args[1]]
139
+ elif get_origin(args[2]) is Literal:
140
+ return version_portable_get_args(args[2])[0], Annotated[args[0], args[1]]
141
+ raise ClassiqValueError(
142
+ f"Operand parameter declaration must be of the form <param-type> or "
143
+ f"Annotated[<param-type>, <param-name>]. Got {py_type}"
129
144
  )
130
145
 
131
146
 
147
+ @overload
132
148
  def _extract_positional_args(
133
- args: Dict[str, Any], qmodule: ModelStateContainer
134
- ) -> List[PositionalArg]:
135
- result: List[PositionalArg] = []
136
- for name, py_type in args.items():
149
+ args: Sequence[tuple[str, Any]], qmodule: Optional[ModelStateContainer]
150
+ ) -> Sequence[PositionalArg]:
151
+ pass
152
+
153
+
154
+ @overload
155
+ def _extract_positional_args(
156
+ args: Sequence[tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
157
+ ) -> Sequence[AnonPositionalArg]:
158
+ pass
159
+
160
+
161
+ def _extract_positional_args(
162
+ args: Sequence[tuple[Optional[str], Any]], qmodule: Optional[ModelStateContainer]
163
+ ) -> Sequence[AnonPositionalArg]:
164
+ result: list[AnonPositionalArg] = []
165
+ for name, py_type in args:
137
166
  if name == "return":
138
167
  continue
139
168
  name = unmangle_keyword(name)
140
- if get_origin(py_type) is QParam:
141
- result.append(_extract_param_decl(name, py_type, qmodule=qmodule))
169
+ classical_type = python_type_to_qmod(py_type, qmodule=qmodule)
170
+ if classical_type is not None:
171
+ param = AnonClassicalParameterDeclaration(
172
+ name=None,
173
+ classical_type=classical_type,
174
+ )
175
+ if name is not None:
176
+ param = param.rename(name)
177
+ result.append(param)
142
178
  elif QVar.from_type_hint(py_type) is not None:
143
179
  result.append(_extract_port_decl(name, py_type))
144
180
  else:
145
- assert (get_origin(py_type) or py_type) is QCallable or (
146
- get_origin(py_type) or py_type
147
- ) is QCallableList
148
181
  result.append(_extract_operand_decl(name, py_type, qmodule=qmodule))
149
182
  return result
150
183
 
151
184
 
152
185
  def infer_func_decl(
153
- py_func: Callable, qmodule: ModelStateContainer
154
- ) -> QuantumFunctionDeclaration:
155
- return QuantumFunctionDeclaration(
186
+ py_func: Callable, qmodule: Optional[ModelStateContainer] = None
187
+ ) -> NamedParamsQuantumFunctionDeclaration:
188
+ return NamedParamsQuantumFunctionDeclaration(
156
189
  name=unmangle_keyword(py_func.__name__),
157
190
  positional_arg_declarations=_extract_positional_args(
158
- py_func.__annotations__, qmodule=qmodule
191
+ list(py_func.__annotations__.items()), qmodule=qmodule
159
192
  ),
160
193
  )
@@ -0,0 +1,39 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
4
+ from classiq.interface.generator.arith.number_utils import MAXIMAL_MACHINE_PRECISION
5
+ from classiq.interface.model.quantum_type import QuantumNumeric
6
+
7
+ from classiq.qmod.qmod_variable import QNum
8
+ from classiq.qmod.symbolic_type import SymbolicTypes
9
+
10
+
11
+ def get_expression_numeric_attributes(
12
+ vars: list[QNum],
13
+ expr: SymbolicTypes,
14
+ machine_precision: int = MAXIMAL_MACHINE_PRECISION,
15
+ ) -> tuple[int, bool, int]:
16
+ """
17
+ Computes and returns the numeric attributes of a given symbolic expression.
18
+
19
+ Args:
20
+ vars: A list of `QNum` variables used in the symbolic expression.
21
+ expr: The symbolic expression for which numeric attributes are to be computed.
22
+ machine_precision: The precision level of the machine for the computation. Defaults to MAXIMAL_MACHINE_PRECISION = 20.
23
+
24
+ Returns:
25
+ Tuple[int, bool, int]:
26
+ A tuple containing the following numeric attributes:
27
+ - The size in bits (int) required to represent the result.
28
+ - A boolean indicating whether the result is signed (bool).
29
+ - The number of fraction digits (int) in the result.
30
+
31
+ """
32
+ res_type = compute_arithmetic_result_type(
33
+ expr_str=str(expr),
34
+ var_types={str(var.get_handle_binding()): var.get_qmod_type() for var in vars},
35
+ machine_precision=machine_precision,
36
+ )
37
+ if TYPE_CHECKING:
38
+ assert isinstance(res_type, QuantumNumeric)
39
+ return res_type.size_in_bits, res_type.sign_value, res_type.fraction_digits_value
@@ -0,0 +1,42 @@
1
+ from collections.abc import Iterator
2
+ from contextlib import contextmanager
3
+ from typing import TYPE_CHECKING, Any, Optional
4
+
5
+ from classiq.interface.exceptions import ClassiqError
6
+ from classiq.interface.generator.expressions.expression import Expression
7
+
8
+ if TYPE_CHECKING:
9
+ from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
10
+
11
+ _GENERATIVE_MODE: bool = False
12
+ _FRONTEND_INTERPRETER: Optional["BaseInterpreter"] = None
13
+
14
+
15
+ def is_generative_mode() -> bool:
16
+ return _GENERATIVE_MODE
17
+
18
+
19
+ @contextmanager
20
+ def generative_mode_context(generative: bool) -> Iterator[None]:
21
+ global _GENERATIVE_MODE
22
+ previous = _GENERATIVE_MODE
23
+ _GENERATIVE_MODE = generative
24
+ try:
25
+ yield
26
+ finally:
27
+ _GENERATIVE_MODE = previous
28
+
29
+
30
+ def set_frontend_interpreter(interpreter: "BaseInterpreter") -> None:
31
+ global _FRONTEND_INTERPRETER
32
+ _FRONTEND_INTERPRETER = interpreter
33
+
34
+
35
+ def get_frontend_interpreter() -> "BaseInterpreter":
36
+ if _FRONTEND_INTERPRETER is None:
37
+ raise ClassiqError("Interpreter was not set")
38
+ return _FRONTEND_INTERPRETER
39
+
40
+
41
+ def interpret_expression(expr: str) -> Any:
42
+ return get_frontend_interpreter().evaluate(Expression(expr=expr)).value
@@ -1,13 +1,27 @@
1
- from typing import Dict
1
+ from typing import TYPE_CHECKING
2
2
 
3
- from classiq.interface.model.native_function_definition import NativeFunctionDefinition
3
+ from classiq.interface.generator.constant import Constant
4
+ from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
5
+ from classiq.interface.generator.types.enum_declaration import EnumDeclaration
6
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
7
+ from classiq.interface.generator.types.struct_declaration import StructDeclaration
8
+ from classiq.interface.model.native_function_definition import (
9
+ NativeFunctionDefinition,
10
+ )
4
11
 
5
- from classiq import StructDeclaration
12
+ if TYPE_CHECKING:
13
+ from classiq.qmod.quantum_function import GenerativeQFunc
6
14
 
7
15
 
8
16
  class ModelStateContainer:
9
- type_decls: Dict[str, StructDeclaration]
10
- native_defs: Dict[str, NativeFunctionDefinition]
17
+ enum_decls: dict[str, EnumDeclaration]
18
+ type_decls: dict[str, StructDeclaration]
19
+ qstruct_decls: dict[str, QStructDeclaration]
20
+ native_defs: dict[str, NativeFunctionDefinition]
21
+ constants: dict[str, Constant]
22
+ functions_compilation_metadata: dict[str, CompilationMetadata]
23
+ generative_functions: dict[str, "GenerativeQFunc"]
24
+ function_dependencies: dict[str, list[str]]
11
25
 
12
26
 
13
27
  QMODULE = ModelStateContainer()
@@ -0,0 +1,7 @@
1
+ from .pretty_printer import DSLPrettyPrinter
2
+
3
+ __all__ = ["DSLPrettyPrinter"]
4
+
5
+
6
+ def __dir__() -> list[str]:
7
+ return __all__
@@ -0,0 +1,194 @@
1
+ import ast
2
+ import re
3
+ from collections.abc import Mapping
4
+ from dataclasses import dataclass
5
+ from typing import Callable, Optional
6
+
7
+ import numpy as np
8
+
9
+ from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
10
+
11
+ IDENTIFIER = re.compile(r"[a-zA-Z_]\w*")
12
+ BINARY_OPS: Mapping[type[ast.operator], str] = {
13
+ ast.Add: "+",
14
+ ast.Sub: "-",
15
+ ast.Mult: "*",
16
+ ast.Div: "/",
17
+ ast.Mod: "%",
18
+ ast.Pow: "**",
19
+ ast.BitAnd: "&",
20
+ ast.BitOr: "|",
21
+ ast.BitXor: "^",
22
+ ast.LShift: "<<",
23
+ ast.RShift: ">>",
24
+ }
25
+ BOOL_OPS: Mapping[type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
26
+ UNARY_OPS: Mapping[type[ast.unaryop], str] = {
27
+ ast.UAdd: "+",
28
+ ast.USub: "-",
29
+ ast.Invert: "~",
30
+ ast.Not: "not",
31
+ }
32
+ COMPARE_OPS: Mapping[type[ast.cmpop], str] = {
33
+ ast.Eq: "==",
34
+ ast.NotEq: "!=",
35
+ ast.Lt: "<",
36
+ ast.LtE: "<=",
37
+ ast.Gt: ">",
38
+ ast.GtE: ">=",
39
+ }
40
+ LIST_FORMAT_CHAR_LIMIT = 20
41
+
42
+
43
+ @dataclass
44
+ class ASTToQMODCode:
45
+ level: int
46
+ decimal_precision: Optional[int]
47
+ indent_seq: str = " "
48
+
49
+ @property
50
+ def indent(self) -> str:
51
+ return self.level * self.indent_seq
52
+
53
+ def visit(self, node: ast.AST) -> str:
54
+ return self.ast_to_code(node)
55
+
56
+ def ast_to_code(self, node: ast.AST) -> str:
57
+ if isinstance(node, ast.Module):
58
+ return self.indent.join(self.ast_to_code(child) for child in node.body)
59
+ elif isinstance(node, ast.Attribute):
60
+ # Enum attribute access
61
+ if not isinstance(node.value, ast.Name) or not isinstance(node.attr, str):
62
+ raise AssertionError("Error parsing enum attribute access")
63
+ if not (IDENTIFIER.match(node.value.id) and IDENTIFIER.match(node.attr)):
64
+ raise AssertionError("Error parsing enum attribute access")
65
+ return f"{node.value.id!s}::{node.attr!s}"
66
+ elif isinstance(node, ast.Name):
67
+ return node.id
68
+ elif isinstance(node, ast.Num):
69
+ if self.decimal_precision is None:
70
+ return str(node.n)
71
+ return str(np.round(node.n, self.decimal_precision))
72
+ elif isinstance(node, ast.Str):
73
+ return repr(node.s)
74
+ elif isinstance(node, ast.Constant):
75
+ return repr(node.value)
76
+ elif isinstance(node, ast.BinOp):
77
+ return "({} {} {})".format(
78
+ self.ast_to_code(node.left),
79
+ BINARY_OPS[type(node.op)],
80
+ self.ast_to_code(node.right),
81
+ )
82
+ elif isinstance(node, ast.UnaryOp):
83
+ unary_op = UNARY_OPS[type(node.op)]
84
+ space = " " if unary_op == "not" else ""
85
+ return f"({unary_op}{space}{self.ast_to_code(node.operand)})"
86
+ elif isinstance(node, ast.BoolOp):
87
+ return "({})".format(
88
+ (" " + BOOL_OPS[type(node.op)] + " ").join(
89
+ self.ast_to_code(value) for value in node.values
90
+ )
91
+ )
92
+ elif isinstance(node, ast.Compare):
93
+ if len(node.ops) != 1 or len(node.comparators) != 1:
94
+ raise AssertionError("Error parsing comparison expression.")
95
+ return "({} {} {})".format(
96
+ self.ast_to_code(node.left),
97
+ COMPARE_OPS[type(node.ops[0])],
98
+ self.ast_to_code(node.comparators[0]),
99
+ )
100
+ elif isinstance(node, ast.List):
101
+ elts = node.elts
102
+ elements = self.indent_items(
103
+ lambda: [self.ast_to_code(element) for element in elts]
104
+ )
105
+ return f"[{elements}]"
106
+ elif isinstance(node, ast.Subscript):
107
+ return f"{self.ast_to_code(node.value)}[{_remove_redundant_parentheses(self.ast_to_code(node.slice))}]"
108
+ elif isinstance(node, ast.Slice):
109
+ # A QMOD expression does not support slice step
110
+ if node.lower is None or node.upper is None or node.step is not None:
111
+ raise AssertionError("Error parsing slice expression.")
112
+ return f"{self.ast_to_code(node.lower)}:{self.ast_to_code(node.upper)}"
113
+ elif isinstance(node, ast.Call):
114
+ func = self.ast_to_code(node.func)
115
+ if func == "get_field":
116
+ if len(node.args) != 2:
117
+ raise AssertionError("Error parsing struct field access.")
118
+ field = str(self.ast_to_code(node.args[1])).replace("'", "")
119
+ if not IDENTIFIER.match(field):
120
+ raise AssertionError("Error parsing struct field access.")
121
+ return f"{self.ast_to_code(node.args[0])}.{field}"
122
+ elif func == "struct_literal":
123
+ if len(node.args) != 1 or not isinstance(node.args[0], ast.Name):
124
+ raise AssertionError("Error parsing struct literal.")
125
+ keywords = node.keywords
126
+ initializer_list = self.indent_items(
127
+ lambda: [
128
+ f"{keyword.arg}={self._cleaned_ast_to_code(keyword.value)}"
129
+ for keyword in keywords
130
+ if keyword.arg is not None
131
+ ]
132
+ )
133
+ return f"{self.ast_to_code(node.args[0])} {{{initializer_list}}}"
134
+ else:
135
+ return "{}({})".format(
136
+ func, ", ".join(self._cleaned_ast_to_code(arg) for arg in node.args)
137
+ )
138
+ elif isinstance(node, ast.Expr):
139
+ return self._cleaned_ast_to_code(node.value)
140
+ else:
141
+ raise AssertionError("Error parsing expression: unsupported AST node.")
142
+
143
+ def indent_items(self, items: Callable[[], list[str]]) -> str:
144
+ should_indent = (
145
+ len("".join([i.strip() for i in items()])) >= LIST_FORMAT_CHAR_LIMIT
146
+ )
147
+ if should_indent:
148
+ self.level += 1
149
+ left_ws = "\n" + self.indent
150
+ inner_ws = ",\n" + self.indent
151
+ else:
152
+ left_ws = ""
153
+ inner_ws = ", "
154
+ items_ = items()
155
+ if should_indent:
156
+ self.level -= 1
157
+ right_ws = "\n" + self.indent
158
+ else:
159
+ right_ws = ""
160
+ return f"{left_ws}{inner_ws.join(items_)}{right_ws}"
161
+
162
+ def _cleaned_ast_to_code(self, node: ast.AST) -> str:
163
+ return _remove_redundant_parentheses(self.ast_to_code(node))
164
+
165
+
166
+ def _remove_redundant_parentheses(expr: str) -> str:
167
+ if not (expr.startswith("(") and expr.endswith(")")):
168
+ return expr
169
+ parentheses_map: dict[int, int] = dict()
170
+ stack: list[int] = []
171
+ for index, char in enumerate(expr):
172
+ if char == "(":
173
+ stack.append(index)
174
+ elif char == ")":
175
+ parentheses_map[stack.pop()] = index
176
+ index = 0
177
+ original_length = len(expr)
178
+ while (
179
+ index in parentheses_map
180
+ and parentheses_map[index] == original_length - index - 1
181
+ ):
182
+ expr = expr[1:-1]
183
+ index += 1
184
+ return expr
185
+
186
+
187
+ def transform_expression(
188
+ expr: str,
189
+ level: int = 0,
190
+ decimal_precision: Optional[int] = DEFAULT_DECIMAL_PRECISION,
191
+ ) -> str:
192
+ return ASTToQMODCode(level=level, decimal_precision=decimal_precision).visit(
193
+ ast.parse(expr)
194
+ )