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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,572 @@
1
+ from collections.abc import Mapping
2
+ from typing import Optional, Union, cast
3
+
4
+ import black
5
+
6
+ from classiq.interface.exceptions import ClassiqInternalError
7
+ from classiq.interface.generator.constant import Constant
8
+ from classiq.interface.generator.expressions.expression import Expression
9
+ from classiq.interface.generator.functions.classical_type import (
10
+ Bool,
11
+ ClassicalArray,
12
+ ClassicalList,
13
+ Integer,
14
+ Real,
15
+ )
16
+ from classiq.interface.generator.functions.concrete_types import (
17
+ ConcreteClassicalType,
18
+ ConcreteQuantumType,
19
+ )
20
+ from classiq.interface.generator.functions.port_declaration import (
21
+ PortDeclarationDirection,
22
+ )
23
+ from classiq.interface.generator.functions.type_name import TypeName
24
+ from classiq.interface.generator.types.enum_declaration import EnumDeclaration
25
+ from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
26
+ from classiq.interface.generator.types.struct_declaration import StructDeclaration
27
+ from classiq.interface.generator.visitor import NodeType, Visitor
28
+ from classiq.interface.model.allocate import Allocate
29
+ from classiq.interface.model.bind_operation import BindOperation
30
+ from classiq.interface.model.classical_if import ClassicalIf
31
+ from classiq.interface.model.classical_parameter_declaration import (
32
+ AnonClassicalParameterDeclaration,
33
+ )
34
+ from classiq.interface.model.control import Control
35
+ from classiq.interface.model.handle_binding import (
36
+ FieldHandleBinding,
37
+ HandleBinding,
38
+ SlicedHandleBinding,
39
+ SubscriptHandleBinding,
40
+ )
41
+ from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
42
+ from classiq.interface.model.invert import Invert
43
+ from classiq.interface.model.model import Model
44
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
45
+ from classiq.interface.model.phase_operation import PhaseOperation
46
+ from classiq.interface.model.port_declaration import AnonPortDeclaration
47
+ from classiq.interface.model.power import Power
48
+ from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
49
+ AmplitudeLoadingOperation,
50
+ )
51
+ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
52
+ ArithmeticOperation,
53
+ ArithmeticOperationKind,
54
+ )
55
+ from classiq.interface.model.quantum_function_call import (
56
+ QuantumFunctionCall,
57
+ )
58
+ from classiq.interface.model.quantum_function_declaration import (
59
+ AnonPositionalArg,
60
+ AnonQuantumOperandDeclaration,
61
+ QuantumFunctionDeclaration,
62
+ QuantumOperandDeclaration,
63
+ )
64
+ from classiq.interface.model.quantum_lambda_function import (
65
+ OperandIdentifier,
66
+ QuantumLambdaFunction,
67
+ )
68
+ from classiq.interface.model.quantum_type import (
69
+ QuantumBit,
70
+ QuantumBitvector,
71
+ QuantumNumeric,
72
+ )
73
+ from classiq.interface.model.quantum_variable_declaration import (
74
+ QuantumVariableDeclaration,
75
+ )
76
+ from classiq.interface.model.repeat import Repeat
77
+ from classiq.interface.model.statement_block import StatementBlock
78
+ from classiq.interface.model.variable_declaration_statement import (
79
+ VariableDeclarationStatement,
80
+ )
81
+ from classiq.interface.model.within_apply_operation import WithinApply
82
+
83
+ import classiq
84
+ from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
85
+ from classiq.qmod.pretty_print.expression_to_python import transform_expression
86
+ from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
87
+
88
+
89
+ class VariableDeclarationAssignment(Visitor):
90
+ def __init__(self, pretty_printer: "PythonPrettyPrinter") -> None:
91
+ self.pretty_printer = pretty_printer
92
+
93
+ def visit(self, node: NodeType) -> tuple[str, list[str]]:
94
+ res = super().visit(node)
95
+ if not isinstance(res, tuple):
96
+ raise AssertionError(f"Pretty printing for {type(node)} is not supported ")
97
+ return res # type: ignore[return-value]
98
+
99
+ def visit_QuantumBit(self, qtype: QuantumBit) -> tuple[str, list[str]]:
100
+ self.pretty_printer._imports["QBit"] = 1
101
+ return "QBit", []
102
+
103
+ def visit_QuantumBitvector(
104
+ self, qtype: QuantumBitvector
105
+ ) -> tuple[str, Optional[list[str]]]:
106
+ self.pretty_printer._imports["QArray"] = 1
107
+
108
+ element_type = self.pretty_printer.visit(qtype.element_type)
109
+ if qtype.length is not None:
110
+ return "QArray", [element_type, self.pretty_printer.visit(qtype.length)]
111
+ return "QArray", [element_type]
112
+
113
+ def visit_QuantumNumeric(
114
+ self, qtype: QuantumNumeric
115
+ ) -> tuple[str, Optional[list[str]]]:
116
+ self.pretty_printer._imports["QNum"] = 1
117
+ return "QNum", self.pretty_printer._get_qnum_properties(qtype)
118
+
119
+ def visit_TypeName(self, qtype: TypeName) -> tuple[str, list[str]]:
120
+ return qtype.name, []
121
+
122
+
123
+ class PythonPrettyPrinter(Visitor):
124
+ def __init__(self, decimal_precision: int = DEFAULT_DECIMAL_PRECISION) -> None:
125
+ self._level = 0
126
+ self._decimal_precision = decimal_precision
127
+ self._imports = {"qfunc": 1}
128
+ self._import_enum = False
129
+ self._import_dataclass = False
130
+ self._import_annotated = False
131
+ self._symbolic_imports: dict[str, int] = dict()
132
+ self._functions: Optional[Mapping[str, QuantumFunctionDeclaration]] = None
133
+
134
+ def visit(self, node: NodeType) -> str:
135
+ res = super().visit(node)
136
+ if not isinstance(res, str):
137
+ raise AssertionError(f"Pretty printing for {type(node)} is not supported ")
138
+ return res
139
+
140
+ def visit_Model(self, model: Model) -> str:
141
+ self._functions = {**model.function_dict, **BUILTIN_FUNCTION_DECLARATIONS}
142
+ enum_decls = [self.visit(decl) for decl in model.enums]
143
+ struct_decls = [self.visit(decl) for decl in model.types]
144
+ qstruct_decls = [self.visit(qstruct_decl) for qstruct_decl in model.qstructs]
145
+ func_defs = [self.visit(func) for func in model.functions]
146
+ constants = [self.visit(const) for const in model.constants]
147
+ classical_code = self.format_classical_code(model.classical_execution_code)
148
+
149
+ code = f"{self.format_imports()}\n\n{self.join_code_parts(*constants, *enum_decls, *struct_decls, *qstruct_decls, *func_defs, classical_code)}"
150
+ return black.format_str(code, mode=black.FileMode())
151
+
152
+ def format_classical_code(self, code: str) -> str:
153
+ if not code:
154
+ return ""
155
+ self._imports["cfunc"] = 1
156
+ self.check_execution_primitives(code)
157
+ formatted_code = code.replace("\n", "\n" + self._indent + " ")
158
+ return f"{self._indent}@cfunc\n{self._indent}def cmain() -> None:\n{self._indent} {formatted_code}"
159
+
160
+ def check_execution_primitives(self, code: str) -> None:
161
+ for primitive in dir(classiq.qmod.builtins.classical_execution_primitives):
162
+ if primitive + "(" in code:
163
+ self._imports[primitive] = 1
164
+
165
+ def format_imports(self) -> str:
166
+ imports = f"from classiq import {', '.join(self._imports.keys())}\n"
167
+ symbolic_imports = (
168
+ f"from classiq.qmod.symbolic import {', '.join(self._symbolic_imports.keys())}\n"
169
+ if self._symbolic_imports
170
+ else ""
171
+ )
172
+ return self.special_imports + imports + symbolic_imports
173
+
174
+ @property
175
+ def special_imports(self) -> str:
176
+ imports = ""
177
+ if self._import_annotated:
178
+ imports += "from typing import Annotated\n"
179
+ if self._import_dataclass:
180
+ imports += "from dataclasses import dataclass\n"
181
+ if self._import_enum:
182
+ imports += "from enum import IntEnum\n"
183
+ return imports
184
+
185
+ def join_code_parts(self, *code_parts: str) -> str:
186
+ return "\n".join(code_parts)
187
+
188
+ def visit_Constant(self, constant: Constant) -> str:
189
+ self._imports["QConstant"] = 1
190
+ constant_name = self.visit(constant.name)
191
+ return f'{self._indent}{constant_name} = QConstant("{constant_name}", {self.visit(constant.const_type)}, {self.visit(constant.value)})\n'
192
+
193
+ def _visit_arg_decls(self, func_def: QuantumFunctionDeclaration) -> str:
194
+ return ", ".join(
195
+ self.visit(arg_decl) for arg_decl in func_def.positional_arg_declarations
196
+ )
197
+
198
+ def visit_QuantumFunctionDeclaration(
199
+ self, func_decl: QuantumFunctionDeclaration
200
+ ) -> str:
201
+ return (
202
+ f"@qfunc\ndef {func_decl.name}({self._visit_arg_decls(func_decl)}) -> None:"
203
+ )
204
+
205
+ def visit_EnumDeclaration(self, enum_decl: EnumDeclaration) -> str:
206
+ self._import_enum = True
207
+ return f"class {enum_decl.name}(IntEnum):\n{self._visit_members(enum_decl.members)}\n"
208
+
209
+ def _visit_members(self, members: dict[str, int]) -> str:
210
+ self._level += 1
211
+ members_str = "".join(
212
+ f"{self._indent}{self.visit(member_name)} = {member_value}\n"
213
+ for member_name, member_value in members.items()
214
+ )
215
+ self._level -= 1
216
+ return members_str
217
+
218
+ def visit_StructDeclaration(self, struct_decl: StructDeclaration) -> str:
219
+ self._import_dataclass = True
220
+ return f"@dataclass\nclass {struct_decl.name}:\n{self._visit_variables(struct_decl.variables)}\n"
221
+
222
+ def visit_QStructDeclaration(self, qstruct_decl: QStructDeclaration) -> str:
223
+ self._imports["QStruct"] = 1
224
+ return f"class {qstruct_decl.name}(QStruct):\n{self._visit_variables(qstruct_decl.fields)}\n"
225
+
226
+ def _visit_variables(
227
+ self, variables: Mapping[str, Union[ConcreteClassicalType, ConcreteQuantumType]]
228
+ ) -> str:
229
+ self._level += 1
230
+ variables_str = "".join(
231
+ f"{self._indent}{self.visit(field_name)}: {self.visit(var_decl)};\n"
232
+ for field_name, var_decl in variables.items()
233
+ )
234
+ self._level -= 1
235
+ return variables_str
236
+
237
+ def visit_QuantumVariableDeclaration(
238
+ self, var_decl: QuantumVariableDeclaration
239
+ ) -> str:
240
+ return f"{var_decl.name}: {self.visit(var_decl.quantum_type)}"
241
+
242
+ def visit_AnonPortDeclaration(self, port_decl: AnonPortDeclaration) -> str:
243
+ var = f"{port_decl.name}: {self.visit(port_decl.quantum_type)}"
244
+ var_name, var_type = var.split(": ")
245
+ for direction in PortDeclarationDirection:
246
+ if port_decl.direction == PortDeclarationDirection.Inout:
247
+ return var
248
+ if port_decl.direction == direction:
249
+ direction_identifier = direction.name
250
+ self._imports[direction_identifier] = 1
251
+ return f"{var_name}: {direction_identifier}[{var_type}]"
252
+ raise RuntimeError("Should not reach here")
253
+
254
+ def visit_QuantumBit(self, qtype: QuantumBit) -> str:
255
+ self._imports["QBit"] = 1
256
+ return "QBit"
257
+
258
+ def visit_QuantumBitvector(self, qtype: QuantumBitvector) -> str:
259
+ self._imports.update({"QArray": 1, "QBit": 1})
260
+ element_type = self.visit(qtype.element_type)
261
+ if qtype.length is not None:
262
+ return f"QArray[{element_type}, {_add_quotes(self.visit(qtype.length))}]"
263
+ return f"QArray[{element_type}]"
264
+
265
+ def visit_QuantumNumeric(self, qtype: QuantumNumeric) -> str:
266
+ self._imports["QNum"] = 1
267
+ params = ""
268
+ qnum_properties = self._get_qnum_properties(qtype)
269
+ if len(qnum_properties) > 0:
270
+ params = "[{}]".format(
271
+ ", ".join(_add_quotes(param) for param in qnum_properties)
272
+ )
273
+ return f"QNum{params}"
274
+
275
+ def _get_qnum_properties(self, qtype: QuantumNumeric) -> list[str]:
276
+ params: list[str] = []
277
+ if qtype.size is None:
278
+ return params
279
+ params.append(self.visit(qtype.size))
280
+
281
+ is_signed_expr = qtype.is_signed
282
+ fraction_digits_expr = qtype.fraction_digits
283
+ if is_signed_expr is None:
284
+ if fraction_digits_expr is not None:
285
+ raise ClassiqInternalError
286
+ return params
287
+ if fraction_digits_expr is None:
288
+ raise ClassiqInternalError
289
+
290
+ is_unsigned = (
291
+ is_signed_expr.is_evaluated() and not is_signed_expr.to_bool_value()
292
+ ) or is_signed_expr.expr == "UNSIGNED"
293
+ is_integer = (
294
+ fraction_digits_expr.is_evaluated()
295
+ and fraction_digits_expr.to_int_value() == 0
296
+ )
297
+ if is_unsigned and is_integer:
298
+ return params
299
+ params.append(self.visit(is_signed_expr))
300
+ params.append(self.visit(fraction_digits_expr))
301
+
302
+ return params
303
+
304
+ def visit_AnonClassicalParameterDeclaration(
305
+ self, cparam: AnonClassicalParameterDeclaration
306
+ ) -> str:
307
+ return f"{cparam.name}: {self.visit(cparam.classical_type)}"
308
+
309
+ def visit_Integer(self, ctint: Integer) -> str:
310
+ self._imports["CInt"] = 1
311
+ return "CInt"
312
+
313
+ def visit_Real(self, ctint: Real) -> str:
314
+ self._imports["CReal"] = 1
315
+ return "CReal"
316
+
317
+ def visit_Bool(self, ctbool: Bool) -> str:
318
+ self._imports["CBool"] = 1
319
+ return "CBool"
320
+
321
+ def visit_ClassicalList(self, ctlist: ClassicalList) -> str:
322
+ self._imports["CArray"] = 1
323
+ return f"CArray[{self.visit(ctlist.element_type)}]"
324
+
325
+ def visit_ClassicalArray(self, ctarray: ClassicalArray) -> str:
326
+ self._imports["CArray"] = 1
327
+ return f"CArray[{self.visit(ctarray.element_type)}, {ctarray.size}]"
328
+
329
+ def visit_TypeName(self, type_: TypeName) -> str:
330
+ self._import_type_name(type_)
331
+ return type_.name
332
+
333
+ def _import_type_name(self, type_: TypeName) -> None:
334
+ if type_.name in dir(classiq.qmod.builtins.enums) + dir(
335
+ classiq.qmod.builtins.structs
336
+ ):
337
+ self._imports[type_.name] = 1
338
+
339
+ def visit_VariableDeclarationStatement(
340
+ self, local_decl: VariableDeclarationStatement
341
+ ) -> str:
342
+ type_name, params = VariableDeclarationAssignment(self).visit(
343
+ local_decl.quantum_type
344
+ )
345
+ params = [f'"{local_decl.name}"'] + params
346
+ param_args = ", ".join(params)
347
+ return f"{self._indent}{self.visit_QuantumVariableDeclaration(local_decl)} = {type_name}({param_args})\n"
348
+
349
+ def _visit_operand_arg_decl(self, arg_decl: AnonPositionalArg) -> str:
350
+ if isinstance(arg_decl, AnonPortDeclaration):
351
+ type_str = self.visit(arg_decl.quantum_type)
352
+ elif isinstance(arg_decl, AnonClassicalParameterDeclaration):
353
+ type_str = self.visit(arg_decl.classical_type)
354
+ else:
355
+ type_str = self.visit_AnonQuantumOperandDeclaration(arg_decl, no_param=True)
356
+ if arg_decl.name is None:
357
+ return type_str
358
+ self._import_annotated = True
359
+ return f'Annotated[{type_str}, "{arg_decl.name}"]'
360
+
361
+ def visit_AnonQuantumOperandDeclaration(
362
+ self, op_decl: AnonQuantumOperandDeclaration, no_param: bool = False
363
+ ) -> str:
364
+ qcallable_identifier = "QCallableList" if op_decl.is_list else "QCallable"
365
+ self._imports[qcallable_identifier] = 1
366
+ args = ", ".join(
367
+ self._visit_operand_arg_decl(arg_decl)
368
+ for arg_decl in op_decl.positional_arg_declarations
369
+ )
370
+ param_name = "" if no_param else f"{op_decl.name}: "
371
+ return f"{param_name}{qcallable_identifier}" + (f"[{args}]" if args else "")
372
+
373
+ def visit_QuantumOperandDeclaration(
374
+ self, op_decl: QuantumOperandDeclaration
375
+ ) -> str:
376
+ return self.visit_AnonQuantumOperandDeclaration(op_decl)
377
+
378
+ def visit_NativeFunctionDefinition(self, func_def: NativeFunctionDefinition) -> str:
379
+ self._level += 1
380
+ if len(func_def.body) == 0:
381
+ body = " pass"
382
+ else:
383
+ body = "".join(self.visit(statement) for statement in func_def.body)
384
+ self._level -= 1
385
+ return f"{self.visit_QuantumFunctionDeclaration(func_def)} \n{body}\n"
386
+
387
+ def visit_QuantumFunctionCall(self, func_call: QuantumFunctionCall) -> str:
388
+ args = self._get_args(func_call)
389
+ if func_call.func_name in dir(classiq.qmod.builtins.functions):
390
+ self._imports[func_call.func_name] = 1
391
+ return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}({args})\n"
392
+
393
+ def _get_args(self, func_call: QuantumFunctionCall) -> str:
394
+ if len(func_call.positional_args) > 2 and self._functions is not None:
395
+ func_decl = self._functions[func_call.func_name]
396
+ if all(
397
+ param.name is not None
398
+ for param in func_decl.positional_arg_declarations
399
+ ):
400
+ return ", ".join(
401
+ f"{self.visit(cast(str, arg_decl.name))}={self.visit(arg)}"
402
+ for arg_decl, arg in zip(
403
+ func_decl.positional_arg_declarations,
404
+ func_call.positional_args,
405
+ )
406
+ )
407
+ return ", ".join(self.visit(arg) for arg in func_call.positional_args)
408
+
409
+ def visit_Allocate(self, allocate: Allocate) -> str:
410
+ if allocate.size is not None:
411
+ size = f"{self.visit(allocate.size)}, "
412
+ else:
413
+ size = ""
414
+ return f"{self._indent}allocate({size}{self.visit(allocate.target)})\n"
415
+
416
+ def visit_Control(self, op: Control) -> str:
417
+ self._imports["control"] = 1
418
+ control_else = (
419
+ f", {self._visit_body(op.else_block)}" if op.else_block is not None else ""
420
+ )
421
+ return f"{self._indent}control({self.visit(op.expression)}, {self._visit_body(op.body)}{control_else})\n"
422
+
423
+ def visit_PhaseOperation(self, op: PhaseOperation) -> str:
424
+ self._imports["phase"] = 1
425
+ theta = f", {self.visit(op.theta)}" if op.theta is not None else ""
426
+ return f"{self._indent}phase({self.visit(op.expression)}{theta})\n"
427
+
428
+ def visit_ClassicalIf(self, op: ClassicalIf) -> str:
429
+ self._imports["if_"] = 1
430
+ return f"{self._indent}if_(condition={self.visit(op.condition)}, then={self._visit_body(op.then)}, else_={self._visit_body(op.else_)})\n"
431
+
432
+ def visit_WithinApply(self, op: WithinApply) -> str:
433
+ self._imports["within_apply"] = 1
434
+ return f"{self._indent}within_apply({self._visit_body(op.compute)}, {self._visit_body(op.action)})\n"
435
+
436
+ def visit_Repeat(self, repeat: Repeat) -> str:
437
+ self._imports["repeat"] = 1
438
+ return f"{self._indent}repeat({self.visit(repeat.count)}, {self._visit_body(repeat.body, [repeat.iter_var])})\n"
439
+
440
+ def visit_Power(self, power: Power) -> str:
441
+ self._imports["power"] = 1
442
+ return f"{self._indent}power({self.visit(power.power)}, {self._visit_body(power.body)})\n"
443
+
444
+ def visit_Invert(self, invert: Invert) -> str:
445
+ self._imports["invert"] = 1
446
+ return f"{self._indent}invert({self._visit_body(invert.body)})\n"
447
+
448
+ def _visit_body(
449
+ self, body: StatementBlock, operand_arguments: Optional[list[str]] = None
450
+ ) -> str:
451
+ if len(body) == 0:
452
+ return "lambda: []"
453
+ argument_string = (
454
+ (" " + ", ".join(operand_arguments)) if operand_arguments else ""
455
+ )
456
+ code = f"lambda{argument_string}: {'[' if len(body) > 1 else ''}\n"
457
+ self._level += 1
458
+ for i, statement in enumerate(body):
459
+ if isinstance(statement, VariableDeclarationStatement):
460
+ raise AssertionError(
461
+ "pretty printing variable declaration statements in quantum lambda function is unsupported."
462
+ )
463
+ if isinstance(statement, AmplitudeLoadingOperation):
464
+ code += self.visit_AmplitudeLoadingOperation(statement, in_lambda=True)
465
+ elif isinstance(statement, ArithmeticOperation):
466
+ code += self.visit_ArithmeticOperation(statement, in_lambda=True)
467
+ else:
468
+ code += self.visit(statement)
469
+ if i < len(body) - 1:
470
+ code += ","
471
+ self._level -= 1
472
+ return f"{code}{']' if len(body) > 1 else ''}"
473
+
474
+ def visit_InplaceBinaryOperation(self, op: InplaceBinaryOperation) -> str:
475
+ self._imports[op.operation.value] = 1
476
+ return f"{self._indent}{op.operation.value}({self.visit(op.value)}, {self.visit(op.target)})\n"
477
+
478
+ def visit_Expression(self, expr: Expression) -> str:
479
+ return transform_expression(
480
+ expr.expr,
481
+ level=self._level,
482
+ decimal_precision=self._decimal_precision,
483
+ imports=self._imports,
484
+ symbolic_imports=self._symbolic_imports,
485
+ )
486
+
487
+ def visit_QuantumLambdaFunction(self, qlambda: QuantumLambdaFunction) -> str:
488
+ return self._visit_body(qlambda.body, qlambda.pos_rename_params)
489
+
490
+ def visit_HandleBinding(self, var_ref: HandleBinding) -> str:
491
+ return var_ref.name
492
+
493
+ def visit_SlicedHandleBinding(self, var_ref: SlicedHandleBinding) -> str:
494
+ return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
495
+
496
+ def visit_SubscriptHandleBinding(self, var_ref: SubscriptHandleBinding) -> str:
497
+ return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.index)}]"
498
+
499
+ def visit_FieldHandleBinding(self, var_ref: FieldHandleBinding) -> str:
500
+ return f"{self.visit(var_ref.base_handle)}.{self.visit(var_ref.field)}"
501
+
502
+ def visit_ArithmeticOperation(
503
+ self, arith_op: ArithmeticOperation, in_lambda: bool = False
504
+ ) -> str:
505
+ if arith_op.operation_kind == ArithmeticOperationKind.Assignment:
506
+ op = "|="
507
+ func = "assign"
508
+ elif arith_op.operation_kind == ArithmeticOperationKind.InplaceXor:
509
+ op = "^="
510
+ func = "inplace_xor"
511
+ else:
512
+ op = "+="
513
+ func = "inplace_add"
514
+ if in_lambda:
515
+ self._imports[func] = 1
516
+ return f"{func}({self.visit(arith_op.expression)}, {self._indent}{self.visit(arith_op.result_var)})\n"
517
+ return f"{self._indent}{self.visit(arith_op.result_var)} {op} {self.visit(arith_op.expression)}\n"
518
+
519
+ def visit_AmplitudeLoadingOperation(
520
+ self, amplitude_loading_op: AmplitudeLoadingOperation, in_lambda: bool = False
521
+ ) -> str:
522
+ if in_lambda:
523
+ self._imports["assign_amplitude"] = 1
524
+ return f"assign_amplitude({self.visit(amplitude_loading_op.expression)}, {self._indent}{self.visit(amplitude_loading_op.result_var)})\n"
525
+ return f"{self._indent}{self.visit(amplitude_loading_op.result_var)} *= {self.visit(amplitude_loading_op.expression)}\n"
526
+
527
+ def _print_bind_handles(self, handles: list[HandleBinding]) -> str:
528
+ if len(handles) == 1:
529
+ return self.visit(handles[0])
530
+
531
+ return "[" + ", ".join(self.visit(handle) for handle in handles) + "]"
532
+
533
+ def visit_BindOperation(self, bind_op: BindOperation) -> str:
534
+ self._imports["bind"] = 1
535
+ return f"{self._indent}bind({self._print_bind_handles(bind_op.in_handles)}, {self._print_bind_handles(bind_op.out_handles)})\n"
536
+
537
+ def visit_list(self, node: list) -> str:
538
+ return "[" + ", ".join(self.visit(elem) for elem in node) + "]"
539
+
540
+ def visit_OperandIdentifier(self, op: OperandIdentifier) -> str:
541
+ return str(op)
542
+
543
+ @property
544
+ def _indent(self) -> str:
545
+ return " " * self._level
546
+
547
+
548
+ def _add_quotes(exp: str) -> str:
549
+ if (
550
+ exp.lower() == "true"
551
+ or exp.lower() == "false"
552
+ or _convertible_to_number(exp)
553
+ or _is_constant(exp)
554
+ ):
555
+ return exp
556
+
557
+ return f'"{exp}"'
558
+
559
+
560
+ def _convertible_to_number(exp: str) -> bool:
561
+ for number_type in [int, float]:
562
+ try:
563
+ number_type(exp)
564
+ except ValueError:
565
+ pass
566
+ else:
567
+ return True
568
+ return False
569
+
570
+
571
+ def _is_constant(exp: str) -> bool:
572
+ return exp in ("SIGNED", "UNSIGNED")
@@ -0,0 +1,67 @@
1
+ import dataclasses
2
+ import inspect
3
+ from enum import EnumMeta
4
+ from typing import (
5
+ Optional,
6
+ get_args,
7
+ get_origin,
8
+ )
9
+
10
+ from classiq.interface.exceptions import ClassiqValueError
11
+ from classiq.interface.generator.functions.classical_type import (
12
+ Bool,
13
+ ClassicalArray,
14
+ ClassicalList,
15
+ Integer,
16
+ Real,
17
+ )
18
+ from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
19
+ from classiq.interface.generator.functions.type_name import Enum, Struct
20
+
21
+ from classiq.qmod.cparam import CArray, CBool, CInt, CReal
22
+ from classiq.qmod.qmod_variable import get_type_hint_expr
23
+ from classiq.qmod.utilities import version_portable_get_args
24
+
25
+ CARRAY_ERROR_MESSAGE = (
26
+ "CArray accepts one or two generic parameters in the form "
27
+ "`CArray[<element-type>]` or `CArray[<element-type>, <size>]`"
28
+ )
29
+
30
+
31
+ class PythonClassicalType:
32
+ def convert(self, py_type: type) -> Optional[ConcreteClassicalType]:
33
+ if py_type is int or py_type is CInt:
34
+ return Integer()
35
+ elif py_type in (float, complex) or py_type is CReal:
36
+ return Real()
37
+ elif py_type is bool or py_type is CBool:
38
+ return Bool()
39
+ elif get_origin(py_type) is list:
40
+ element_type = self.convert(get_args(py_type)[0])
41
+ if element_type is not None:
42
+ return ClassicalList(element_type=element_type)
43
+ elif get_origin(py_type) is CArray:
44
+ array_args = version_portable_get_args(py_type)
45
+ if len(array_args) == 1:
46
+ return ClassicalList(element_type=self.convert(array_args[0]))
47
+ elif len(array_args) == 2:
48
+ return ClassicalArray(
49
+ element_type=self.convert(array_args[0]),
50
+ size=get_type_hint_expr(array_args[1]),
51
+ )
52
+ raise ClassiqValueError(CARRAY_ERROR_MESSAGE)
53
+ elif inspect.isclass(py_type) and dataclasses.is_dataclass(py_type):
54
+ self.register_struct(py_type)
55
+ return Struct(name=py_type.__name__)
56
+ elif inspect.isclass(py_type) and isinstance(py_type, EnumMeta):
57
+ self.register_enum(py_type)
58
+ return Enum(name=py_type.__name__)
59
+ elif py_type in (CArray, list):
60
+ raise ClassiqValueError(CARRAY_ERROR_MESSAGE)
61
+ return None
62
+
63
+ def register_struct(self, py_type: type) -> None:
64
+ pass
65
+
66
+ def register_enum(self, py_type: EnumMeta) -> None:
67
+ pass