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,401 @@
1
+ from collections.abc import Mapping
2
+ from typing import Optional, Union
3
+
4
+ from classiq.interface.generator.constant import Constant
5
+ from classiq.interface.generator.expressions.expression import Expression
6
+ from classiq.interface.generator.functions.classical_type import (
7
+ Bool,
8
+ ClassicalArray,
9
+ ClassicalList,
10
+ Integer,
11
+ Real,
12
+ )
13
+ from classiq.interface.generator.functions.concrete_types import (
14
+ ConcreteClassicalType,
15
+ ConcreteQuantumType,
16
+ )
17
+ from classiq.interface.generator.functions.port_declaration import (
18
+ PortDeclarationDirection,
19
+ )
20
+ from classiq.interface.generator.functions.type_name import TypeName
21
+ from classiq.interface.generator.types.enum_declaration import EnumDeclaration
22
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
23
+ from classiq.interface.generator.types.struct_declaration import StructDeclaration
24
+ from classiq.interface.generator.visitor import NodeType, Visitor
25
+ from classiq.interface.model.allocate import Allocate
26
+ from classiq.interface.model.bind_operation import BindOperation
27
+ from classiq.interface.model.classical_if import ClassicalIf
28
+ from classiq.interface.model.classical_parameter_declaration import (
29
+ AnonClassicalParameterDeclaration,
30
+ )
31
+ from classiq.interface.model.control import Control
32
+ from classiq.interface.model.handle_binding import (
33
+ FieldHandleBinding,
34
+ HandleBinding,
35
+ SlicedHandleBinding,
36
+ SubscriptHandleBinding,
37
+ )
38
+ from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
39
+ from classiq.interface.model.invert import Invert
40
+ from classiq.interface.model.model import Model
41
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
42
+ from classiq.interface.model.phase_operation import PhaseOperation
43
+ from classiq.interface.model.port_declaration import (
44
+ AnonPortDeclaration,
45
+ )
46
+ from classiq.interface.model.power import Power
47
+ from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
48
+ AmplitudeLoadingOperation,
49
+ )
50
+ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
51
+ ArithmeticOperation,
52
+ ArithmeticOperationKind,
53
+ )
54
+ from classiq.interface.model.quantum_function_call import (
55
+ QuantumFunctionCall,
56
+ )
57
+ from classiq.interface.model.quantum_function_declaration import (
58
+ AnonQuantumFunctionDeclaration,
59
+ AnonQuantumOperandDeclaration,
60
+ QuantumFunctionDeclaration,
61
+ QuantumOperandDeclaration,
62
+ )
63
+ from classiq.interface.model.quantum_lambda_function import (
64
+ OperandIdentifier,
65
+ QuantumLambdaFunction,
66
+ )
67
+ from classiq.interface.model.quantum_type import (
68
+ QuantumBit,
69
+ QuantumBitvector,
70
+ QuantumNumeric,
71
+ )
72
+ from classiq.interface.model.quantum_variable_declaration import (
73
+ QuantumVariableDeclaration,
74
+ )
75
+ from classiq.interface.model.repeat import Repeat
76
+ from classiq.interface.model.statement_block import StatementBlock
77
+ from classiq.interface.model.variable_declaration_statement import (
78
+ VariableDeclarationStatement,
79
+ )
80
+ from classiq.interface.model.within_apply_operation import WithinApply
81
+
82
+ from classiq.open_library.functions import OPEN_LIBRARY_FUNCTIONS
83
+ from classiq.qmod.native.expression_to_qmod import transform_expression
84
+ from classiq.qmod.semantics.annotation.call_annotation import resolve_function_calls
85
+ from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
86
+
87
+
88
+ class DSLPrettyPrinter(Visitor):
89
+ def __init__(
90
+ self,
91
+ decimal_precision: Optional[int] = DEFAULT_DECIMAL_PRECISION,
92
+ emit_open_lib_functions: bool = False,
93
+ ) -> None:
94
+ self._level = 0
95
+ self._decimal_precision = decimal_precision
96
+ self._emit_open_lib_functions = emit_open_lib_functions
97
+
98
+ def visit(self, node: NodeType) -> str:
99
+ res = super().visit(node)
100
+ if not isinstance(res, str):
101
+ raise AssertionError(f"Pretty printing for {type(node)} is not supported ")
102
+ return res
103
+
104
+ def visit_Model(self, model: Model) -> str:
105
+ # FIXME - CAD-20149: Remove this line once the froggies are removed, and the visit of lambdas can be done without accessing the func_decl property (with rename_params values only).
106
+ resolve_function_calls(model, model.function_dict)
107
+ enum_decls = [self.visit(enum_decl) for enum_decl in model.enums]
108
+ struct_decls = [self.visit(struct_decl) for struct_decl in model.types]
109
+ qstruct_decls = [self.visit(qstruct_decl) for qstruct_decl in model.qstructs]
110
+ func_defs = [self.visit(func_def) for func_def in model.functions]
111
+ constants = [self.visit(constant) for constant in model.constants]
112
+ classical_code = (
113
+ [f"cscope ```\n{model.classical_execution_code}\n```\n"]
114
+ if model.classical_execution_code
115
+ else []
116
+ )
117
+
118
+ items = [
119
+ *constants,
120
+ *enum_decls,
121
+ *struct_decls,
122
+ *qstruct_decls,
123
+ *func_defs,
124
+ *classical_code,
125
+ ]
126
+ return "\n".join([item for item in items if item != ""])
127
+
128
+ def visit_Constant(self, constant: Constant) -> str:
129
+ return f"{self._indent}{self.visit(constant.name)}: {self.visit(constant.const_type)} = {self.visit(constant.value)};\n"
130
+
131
+ def _visit_arg_decls(self, func_def: AnonQuantumFunctionDeclaration) -> str:
132
+ positional_args = ", ".join(
133
+ self.visit(arg_decl) for arg_decl in func_def.positional_arg_declarations
134
+ )
135
+ return f"({positional_args})"
136
+
137
+ def visit_QuantumFunctionDeclaration(
138
+ self, func_decl: QuantumFunctionDeclaration
139
+ ) -> str:
140
+ return f"qfunc {func_decl.name}{self._visit_arg_decls(func_decl)}"
141
+
142
+ def visit_EnumDeclaration(self, enum_decl: EnumDeclaration) -> str:
143
+ return f"enum {enum_decl.name} {{\n{self._visit_members(enum_decl.members)}}}\n"
144
+
145
+ def _visit_members(self, members: dict[str, int]) -> str:
146
+ self._level += 1
147
+ members_str = "".join(
148
+ f"{self._indent}{self.visit(member_name)} = {member_value};\n"
149
+ for member_name, member_value in members.items()
150
+ )
151
+ self._level -= 1
152
+ return members_str
153
+
154
+ def visit_StructDeclaration(self, struct_decl: StructDeclaration) -> str:
155
+ return f"struct {struct_decl.name} {{\n{self._visit_variables(struct_decl.variables)}}}\n"
156
+
157
+ def visit_QStructDeclaration(self, qstruct_decl: QStructDeclaration) -> str:
158
+ return f"qstruct {qstruct_decl.name} {{\n{self._visit_variables(qstruct_decl.fields)}}}\n"
159
+
160
+ def _visit_variables(
161
+ self, variables: Mapping[str, Union[ConcreteClassicalType, ConcreteQuantumType]]
162
+ ) -> str:
163
+ self._level += 1
164
+ variables_str = "".join(
165
+ f"{self._indent}{self.visit(field_name)}: {self.visit(var_decl)};\n"
166
+ for field_name, var_decl in variables.items()
167
+ )
168
+ self._level -= 1
169
+ return variables_str
170
+
171
+ def visit_QuantumVariableDeclaration(
172
+ self, var_decl: QuantumVariableDeclaration
173
+ ) -> str:
174
+ return f"{var_decl.name}: {self.visit(var_decl.quantum_type)}"
175
+
176
+ def visit_AnonPortDeclaration(self, port_decl: AnonPortDeclaration) -> str:
177
+ dir_str = (
178
+ f"{port_decl.direction} "
179
+ if port_decl.direction != PortDeclarationDirection.Inout
180
+ else ""
181
+ )
182
+ param_name = f"{port_decl.name}: " if port_decl.name is not None else ""
183
+ return f"{dir_str}{param_name}{self.visit(port_decl.quantum_type)}"
184
+
185
+ def visit_QuantumBit(self, qtype: QuantumBit) -> str:
186
+ return "qbit"
187
+
188
+ def visit_QuantumBitvector(self, qtype: QuantumBitvector) -> str:
189
+ element_type = self.visit(qtype.element_type)
190
+ if qtype.length is not None:
191
+ return f"{element_type}[{self.visit(qtype.length)}]"
192
+ return f"{element_type}[]"
193
+
194
+ def visit_QuantumNumeric(self, qtype: QuantumNumeric) -> str:
195
+ params = ""
196
+ if qtype.size is not None:
197
+ params = "<{}>".format(
198
+ ", ".join(
199
+ self.visit(param)
200
+ for param in [qtype.size, qtype.is_signed, qtype.fraction_digits]
201
+ if param is not None
202
+ )
203
+ )
204
+
205
+ return f"qnum{params}"
206
+
207
+ def visit_AnonClassicalParameterDeclaration(
208
+ self, cparam: AnonClassicalParameterDeclaration
209
+ ) -> str:
210
+ param_name = f"{cparam.name}: " if cparam.name is not None else ""
211
+ return f"{param_name}{self.visit(cparam.classical_type)}"
212
+
213
+ def visit_Integer(self, ctint: Integer) -> str:
214
+ return "int"
215
+
216
+ def visit_Real(self, ctint: Real) -> str:
217
+ return "real"
218
+
219
+ def visit_Bool(self, ctbool: Bool) -> str:
220
+ return "bool"
221
+
222
+ def visit_ClassicalList(self, ctlist: ClassicalList) -> str:
223
+ return f"{self.visit(ctlist.element_type)}[]"
224
+
225
+ def visit_ClassicalArray(self, ctarray: ClassicalArray) -> str:
226
+ return f"{self.visit(ctarray.element_type)}[{ctarray.size}]"
227
+
228
+ def visit_TypeName(self, type_: TypeName) -> str:
229
+ return type_.name
230
+
231
+ def visit_VariableDeclarationStatement(
232
+ self, local_decl: VariableDeclarationStatement
233
+ ) -> str:
234
+ return f"{self._indent}{self.visit_QuantumVariableDeclaration(local_decl)};\n"
235
+
236
+ def visit_AnonQuantumOperandDeclaration(
237
+ self, op_decl: AnonQuantumOperandDeclaration
238
+ ) -> str:
239
+ param_name = f"{op_decl.name}: " if op_decl.name is not None else ""
240
+ return f"{param_name}qfunc{[] if op_decl.is_list else ''} {self._visit_arg_decls(op_decl)}"
241
+
242
+ def visit_QuantumOperandDeclaration(
243
+ self, op_decl: QuantumOperandDeclaration
244
+ ) -> str:
245
+ return self.visit_AnonQuantumOperandDeclaration(op_decl)
246
+
247
+ def visit_NativeFunctionDefinition(self, func_def: NativeFunctionDefinition) -> str:
248
+ if not self._emit_open_lib_functions and func_def.name in [
249
+ qfunc_.func_decl.name for qfunc_ in OPEN_LIBRARY_FUNCTIONS
250
+ ]:
251
+ return ""
252
+ self._level += 1
253
+ body = "".join(self.visit(qvar_decl) for qvar_decl in func_def.body)
254
+ self._level -= 1
255
+ return f"{self.visit_QuantumFunctionDeclaration(func_def)} {{\n{body}}}\n"
256
+
257
+ def visit_Allocate(self, allocate: Allocate) -> str:
258
+ if allocate.size is not None:
259
+ size = f"{self.visit(allocate.size)}, "
260
+ else:
261
+ size = ""
262
+ return f"{self._indent}allocate({size}{self.visit(allocate.target)});\n"
263
+
264
+ def visit_QuantumFunctionCall(self, func_call: QuantumFunctionCall) -> str:
265
+ positional_args = ", ".join(
266
+ self.visit(arg_decl) for arg_decl in func_call.positional_args
267
+ )
268
+ return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}({positional_args});\n"
269
+
270
+ def visit_Control(self, op: Control) -> str:
271
+ control = f"{self._indent}control ({self.visit(op.expression)}) {{\n"
272
+ control += self._visit_body(op.body)
273
+ control += f"{self._indent}}}"
274
+ if op.else_block is not None:
275
+ control += " else {\n"
276
+ control += self._visit_body(op.else_block)
277
+ control += f"{self._indent}}}"
278
+ control += "\n"
279
+ return control
280
+
281
+ def visit_PhaseOperation(self, op: PhaseOperation) -> str:
282
+ theta = f", {self.visit(op.theta)}" if op.theta else ""
283
+ phase = f"{self._indent}phase ({self.visit(op.expression)}{theta});\n"
284
+ return phase
285
+
286
+ def visit_ClassicalIf(self, op: ClassicalIf) -> str:
287
+ classical_if = f"{self._indent}if ({self.visit(op.condition)}) {{\n"
288
+ if not op.then:
289
+ raise AssertionError('Expected non empty "then" block')
290
+ classical_if += self._visit_body(op.then)
291
+
292
+ if op.else_:
293
+ classical_if += f"{self._indent}}} else {{\n"
294
+ classical_if += self._visit_body(op.else_)
295
+
296
+ classical_if += f"{self._indent}}}\n"
297
+ return classical_if
298
+
299
+ def visit_WithinApply(self, op: WithinApply) -> str:
300
+ within_apply_code = f"{self._indent}within {{\n"
301
+ within_apply_code += self._visit_body(op.compute)
302
+ within_apply_code += f"{self._indent}}} apply {{\n"
303
+ within_apply_code += self._visit_body(op.action)
304
+ within_apply_code += f"{self._indent}}}\n"
305
+ return within_apply_code
306
+
307
+ def visit_Repeat(self, repeat: Repeat) -> str:
308
+ repeat_code = f"{self._indent}repeat ({self.visit(repeat.iter_var)}: {self.visit(repeat.count)}) {{\n"
309
+ repeat_code += self._visit_body(repeat.body)
310
+ repeat_code += f"{self._indent}}}\n"
311
+ return repeat_code
312
+
313
+ def visit_Power(self, power: Power) -> str:
314
+ power_code = f"{self._indent}power ({self.visit(power.power)}) {{\n"
315
+ power_code += self._visit_body(power.body)
316
+ power_code += f"{self._indent}}}\n"
317
+ return power_code
318
+
319
+ def visit_Invert(self, invert: Invert) -> str:
320
+ invert_code = f"{self._indent}invert {{\n"
321
+ invert_code += self._visit_body(invert.body)
322
+ invert_code += f"{self._indent}}}\n"
323
+ return invert_code
324
+
325
+ def _visit_body(self, body: StatementBlock) -> str:
326
+ code = ""
327
+ self._level += 1
328
+ for statement in body:
329
+ code += self.visit(statement)
330
+ self._level -= 1
331
+ return code
332
+
333
+ def visit_InplaceBinaryOperation(self, op: InplaceBinaryOperation) -> str:
334
+ return f"{self._indent}{op.operation.value}({self.visit(op.value)}, {self.visit(op.target)});\n"
335
+
336
+ def _visit_pack_expr(self, vars: list[HandleBinding]) -> str:
337
+ if len(vars) == 1:
338
+ return self.visit(vars[0])
339
+
340
+ var_list_str = ", ".join(self.visit(var) for var in vars)
341
+ return f"{{{var_list_str}}}"
342
+
343
+ def visit_Expression(self, expr: Expression) -> str:
344
+ return transform_expression(
345
+ expr.expr, level=self._level, decimal_precision=self._decimal_precision
346
+ )
347
+
348
+ def visit_QuantumLambdaFunction(self, qlambda: QuantumLambdaFunction) -> str:
349
+ positional_args = ", ".join(
350
+ qlambda.pos_rename_params[idx]
351
+ for idx, arg_decl in enumerate(
352
+ qlambda.func_decl.positional_arg_declarations
353
+ )
354
+ )
355
+ body = self._visit_body(qlambda.body)
356
+ return f"lambda({positional_args}) {{\n{body}{self._indent}}}"
357
+
358
+ def visit_HandleBinding(self, var_ref: HandleBinding) -> str:
359
+ return var_ref.name
360
+
361
+ def visit_SlicedHandleBinding(self, var_ref: SlicedHandleBinding) -> str:
362
+ return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
363
+
364
+ def visit_SubscriptHandleBinding(self, var_ref: SubscriptHandleBinding) -> str:
365
+ return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.index)}]"
366
+
367
+ def visit_FieldHandleBinding(self, var_ref: FieldHandleBinding) -> str:
368
+ return f"{self.visit(var_ref.base_handle)}.{self.visit(var_ref.field)}"
369
+
370
+ def visit_ArithmeticOperation(self, arith_op: ArithmeticOperation) -> str:
371
+ if arith_op.operation_kind == ArithmeticOperationKind.Assignment:
372
+ op = "="
373
+ elif arith_op.operation_kind == ArithmeticOperationKind.InplaceXor:
374
+ op = "^="
375
+ else:
376
+ op = "+="
377
+ return f"{self._indent}{self.visit(arith_op.result_var)} {op} {self.visit(arith_op.expression)};\n"
378
+
379
+ def visit_AmplitudeLoadingOperation(
380
+ self, amplitude_loading_op: AmplitudeLoadingOperation
381
+ ) -> str:
382
+ return f"{self._indent}{self.visit(amplitude_loading_op.result_var)} *= {self.visit(amplitude_loading_op.expression)};\n"
383
+
384
+ def _print_bind_handles(self, handles: list[HandleBinding]) -> str:
385
+ if len(handles) == 1:
386
+ return self.visit(handles[0])
387
+
388
+ return "{" + ", ".join(self.visit(handle) for handle in handles) + "}"
389
+
390
+ def visit_BindOperation(self, bind_op: BindOperation) -> str:
391
+ return f"{self._indent}{self._print_bind_handles(bind_op.in_handles)} -> {self._print_bind_handles(bind_op.out_handles)};\n"
392
+
393
+ def visit_list(self, node: list) -> str:
394
+ return "[" + ", ".join(self.visit(elem) for elem in node) + "]"
395
+
396
+ def visit_OperandIdentifier(self, op: OperandIdentifier) -> str:
397
+ return str(op)
398
+
399
+ @property
400
+ def _indent(self) -> str:
401
+ return " " * self._level
@@ -0,0 +1,7 @@
1
+ from .pretty_printer import PythonPrettyPrinter
2
+
3
+ __all__ = ["PythonPrettyPrinter"]
4
+
5
+
6
+ def __dir__() -> list[str]:
7
+ return __all__
@@ -0,0 +1,222 @@
1
+ import ast
2
+ import re
3
+ from collections.abc import Mapping
4
+ from dataclasses import dataclass
5
+ from typing import Callable
6
+
7
+ import numpy as np
8
+
9
+ import classiq
10
+ from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
11
+
12
+ IDENTIFIER = re.compile(r"[a-zA-Z_]\w*")
13
+ BINARY_OPS: Mapping[type[ast.operator], str] = {
14
+ ast.Add: "+",
15
+ ast.Sub: "-",
16
+ ast.Mult: "*",
17
+ ast.Div: "/",
18
+ ast.Mod: "%",
19
+ ast.Pow: "**",
20
+ ast.BitAnd: "&",
21
+ ast.BitOr: "|",
22
+ ast.BitXor: "^",
23
+ ast.LShift: "<<",
24
+ ast.RShift: ">>",
25
+ }
26
+ BOOL_OPS: Mapping[type[ast.boolop], str] = {ast.And: "and", ast.Or: "or"}
27
+ UNARY_OPS: Mapping[type[ast.unaryop], str] = {
28
+ ast.UAdd: "+",
29
+ ast.USub: "-",
30
+ ast.Invert: "~",
31
+ ast.Not: "not",
32
+ }
33
+ COMPARE_OPS: Mapping[type[ast.cmpop], str] = {
34
+ ast.Eq: "==",
35
+ ast.NotEq: "!=",
36
+ ast.Lt: "<",
37
+ ast.LtE: "<=",
38
+ ast.Gt: ">",
39
+ ast.GtE: ">=",
40
+ }
41
+ LIST_FORMAT_CHAR_LIMIT = 20
42
+
43
+
44
+ @dataclass
45
+ class ASTToQMODCode(ast.NodeVisitor):
46
+ level: int
47
+ imports: dict[str, int]
48
+ symbolic_imports: dict[str, int]
49
+ decimal_precision: int
50
+ indent_seq: str = " "
51
+
52
+ @property
53
+ def indent(self) -> str:
54
+ return self.level * self.indent_seq
55
+
56
+ def _handle_imports(self, name: str, is_possibly_symbolic: bool = False) -> None:
57
+ if name in dir(classiq):
58
+ self.imports[name] = 1
59
+ if is_possibly_symbolic and name in dir(classiq.qmod.symbolic):
60
+ self.symbolic_imports[name] = 1
61
+
62
+ def visit(self, node: ast.AST) -> str:
63
+ res = super().visit(node)
64
+ if not isinstance(res, str):
65
+ raise AssertionError("Error parsing expression: unsupported AST node.")
66
+ return res
67
+
68
+ def visit_Module(self, node: ast.Module) -> str:
69
+ return self.indent.join(self.visit(child) for child in node.body)
70
+
71
+ def visit_Attribute(self, node: ast.Attribute) -> str:
72
+ if not isinstance(node.value, ast.Name) or not isinstance(node.attr, str):
73
+ raise AssertionError("Error parsing enum attribute access")
74
+ if not (IDENTIFIER.match(node.value.id) and IDENTIFIER.match(node.attr)):
75
+ raise AssertionError("Error parsing enum attribute access")
76
+ self._handle_imports(node.value.id)
77
+ return f"{node.value.id!s}.{node.attr!s}"
78
+
79
+ def visit_Name(self, node: ast.Name) -> str:
80
+ self._handle_imports(node.id, True)
81
+ return node.id
82
+
83
+ def visit_Num(self, node: ast.Num) -> str:
84
+ return str(np.round(node.n, self.decimal_precision))
85
+
86
+ def visit_Str(self, node: ast.Str) -> str:
87
+ return repr(node.s)
88
+
89
+ def visit_Constant(self, node: ast.Constant) -> str:
90
+ return repr(node.value)
91
+
92
+ def visit_BinOp(self, node: ast.BinOp) -> str:
93
+ return "({} {} {})".format(
94
+ self.visit(node.left),
95
+ BINARY_OPS[type(node.op)],
96
+ self.visit(node.right),
97
+ )
98
+
99
+ def visit_UnaryOp(self, node: ast.UnaryOp) -> str:
100
+ unary_op = UNARY_OPS[type(node.op)]
101
+ space = " " if unary_op == "not" else ""
102
+ return f"({unary_op}{space}{self.visit(node.operand)})"
103
+
104
+ def visit_BoolOp(self, node: ast.BoolOp) -> str:
105
+ return "({})".format(
106
+ (" " + BOOL_OPS[type(node.op)] + " ").join(
107
+ self.visit(value) for value in node.values
108
+ )
109
+ )
110
+
111
+ def visit_Compare(self, node: ast.Compare) -> str:
112
+ if len(node.ops) != 1 or len(node.comparators) != 1:
113
+ raise AssertionError("Error parsing comparison expression.")
114
+ return "({} {} {})".format(
115
+ self.visit(node.left),
116
+ COMPARE_OPS[type(node.ops[0])],
117
+ self.visit(node.comparators[0]),
118
+ )
119
+
120
+ def visit_List(self, node: ast.List) -> str:
121
+ elts = node.elts
122
+ elements = self.indent_items(lambda: [self.visit(element) for element in elts])
123
+ return f"[{elements}]"
124
+
125
+ def visit_Subscript(self, node: ast.Subscript) -> str:
126
+ return f"{self.visit(node.value)}[{_remove_redundant_parentheses(self.visit(node.slice))}]"
127
+
128
+ def visit_Slice(self, node: ast.Slice) -> str:
129
+ if node.lower is None or node.upper is None or node.step is not None:
130
+ raise AssertionError("Error parsing slice expression.")
131
+ return f"{self.visit(node.lower)}:{self.visit(node.upper)}"
132
+
133
+ def visit_Call(self, node: ast.Call) -> str:
134
+ func = self.visit(node.func)
135
+ self._handle_imports(func, True)
136
+ if func == "get_field":
137
+ if len(node.args) != 2:
138
+ raise AssertionError("Error parsing struct field access.")
139
+ field = str(self.visit(node.args[1])).replace("'", "")
140
+ if not IDENTIFIER.match(field):
141
+ raise AssertionError("Error parsing struct field access.")
142
+ return f"{self.visit(node.args[0])}.{field}"
143
+ elif func == "struct_literal":
144
+ if len(node.args) != 1 or not isinstance(node.args[0], ast.Name):
145
+ raise AssertionError("Error parsing struct literal.")
146
+ keywords = node.keywords
147
+ initializer_list = self.indent_items(
148
+ lambda: [
149
+ f"{keyword.arg} = {self._cleaned_ast_to_code(keyword.value)}"
150
+ for keyword in keywords
151
+ if keyword.arg is not None
152
+ ]
153
+ )
154
+ return f"{self.visit(node.args[0])}({initializer_list})"
155
+ else:
156
+ return "{}({})".format(
157
+ func, ", ".join(self._cleaned_ast_to_code(arg) for arg in node.args)
158
+ )
159
+
160
+ def visit_Expr(self, node: ast.Expr) -> str:
161
+ return self._cleaned_ast_to_code(node.value)
162
+
163
+ def generic_visit(self, node: ast.AST) -> None:
164
+ raise AssertionError("Cannot parse node of type: " + type(node).__name__)
165
+
166
+ def indent_items(self, items: Callable[[], list[str]]) -> str:
167
+ should_indent = (
168
+ len("".join([i.strip() for i in items()])) >= LIST_FORMAT_CHAR_LIMIT
169
+ )
170
+ if should_indent:
171
+ self.level += 1
172
+ left_ws = "\n" + self.indent
173
+ inner_ws = ",\n" + self.indent
174
+ else:
175
+ left_ws = ""
176
+ inner_ws = ", "
177
+ items_ = items()
178
+ if should_indent:
179
+ self.level -= 1
180
+ right_ws = "\n" + self.indent
181
+ else:
182
+ right_ws = ""
183
+ return f"{left_ws}{inner_ws.join(items_)}{right_ws}"
184
+
185
+ def _cleaned_ast_to_code(self, node: ast.AST) -> str:
186
+ return _remove_redundant_parentheses(self.visit(node))
187
+
188
+
189
+ def _remove_redundant_parentheses(expr: str) -> str:
190
+ if not (expr.startswith("(") and expr.endswith(")")):
191
+ return expr
192
+ parentheses_map: dict[int, int] = dict()
193
+ stack: list[int] = []
194
+ for index, char in enumerate(expr):
195
+ if char == "(":
196
+ stack.append(index)
197
+ elif char == ")":
198
+ parentheses_map[stack.pop()] = index
199
+ index = 0
200
+ original_length = len(expr)
201
+ while (
202
+ index in parentheses_map
203
+ and parentheses_map[index] == original_length - index - 1
204
+ ):
205
+ expr = expr[1:-1]
206
+ index += 1
207
+ return expr
208
+
209
+
210
+ def transform_expression(
211
+ expr: str,
212
+ imports: dict[str, int],
213
+ symbolic_imports: dict[str, int],
214
+ level: int = 0,
215
+ decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
216
+ ) -> str:
217
+ return ASTToQMODCode(
218
+ level=level,
219
+ decimal_precision=decimal_precision,
220
+ imports=imports,
221
+ symbolic_imports=symbolic_imports,
222
+ ).visit(ast.parse(expr))