classiq 0.38.0__py3-none-any.whl → 0.65.4__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.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.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.4.dist-info}/WHEEL +0 -0
@@ -1,7 +1,18 @@
1
- from typing import Any, ClassVar, Dict, List, Mapping, Sequence, Set, Type, Union
1
+ from collections.abc import Sequence
2
+ from typing import (
3
+ Annotated,
4
+ Any,
5
+ Literal,
6
+ Union,
7
+ )
2
8
 
3
9
  import pydantic
10
+ from pydantic import SerializeAsAny
11
+ from pydantic_core.core_schema import ValidationInfo
12
+ from typing_extensions import Self
4
13
 
14
+ from classiq.interface.exceptions import ClassiqInternalError
15
+ from classiq.interface.generator.arith.register_user_input import RegisterUserInput
5
16
  from classiq.interface.generator.function_params import ArithmeticIODict, PortDirection
6
17
  from classiq.interface.generator.functions.function_declaration import (
7
18
  FunctionDeclaration,
@@ -9,219 +20,241 @@ from classiq.interface.generator.functions.function_declaration import (
9
20
  from classiq.interface.generator.functions.port_declaration import (
10
21
  PortDeclarationDirection,
11
22
  )
12
- from classiq.interface.helpers.pydantic_model_helpers import Nameable
13
- from classiq.interface.helpers.validation_helpers import (
14
- validate_nameables_mapping,
15
- validate_nameables_no_overlap,
23
+ from classiq.interface.helpers.pydantic_model_helpers import (
24
+ values_with_discriminator,
16
25
  )
17
26
  from classiq.interface.model.classical_parameter_declaration import (
27
+ AnonClassicalParameterDeclaration,
18
28
  ClassicalParameterDeclaration,
19
29
  )
20
- from classiq.interface.model.port_declaration import PortDeclaration
30
+ from classiq.interface.model.port_declaration import (
31
+ AnonPortDeclaration,
32
+ PortDeclaration,
33
+ )
21
34
  from classiq.interface.model.quantum_type import quantum_var_to_register
22
35
 
23
- from classiq.exceptions import ClassiqValueError
24
-
25
-
26
- def _is_equiv_kw_and_pos_decl(kw_decl: Nameable, pos_decl: Nameable) -> bool:
27
- if isinstance(pos_decl, ClassicalParameterDeclaration):
28
- return pos_decl.classical_type == kw_decl
29
- return pos_decl == kw_decl
30
-
31
-
32
- def _populate_declaration_dicts_with_positional_lists(
33
- pos_decls: Sequence[Nameable],
34
- kw_decls: Dict[str, Nameable],
35
- param_type: Type[Nameable],
36
- ) -> None:
37
- for pos_decl in pos_decls:
38
- if not isinstance(pos_decl, param_type):
39
- continue
40
- kw_decl = kw_decls.get(pos_decl.name)
41
- if kw_decl is not None and not _is_equiv_kw_and_pos_decl(kw_decl, pos_decl):
42
- raise ClassiqValueError(
43
- f"{param_type.__name__} parameter with name {pos_decl.name} already declared"
44
- )
45
- kw_decls[pos_decl.name] = (
46
- pos_decl.classical_type # type:ignore[assignment]
47
- if isinstance(pos_decl, ClassicalParameterDeclaration)
48
- else pos_decl
49
- )
50
-
51
-
52
- PositionalArg = Union[
53
- ClassicalParameterDeclaration, "QuantumOperandDeclaration", PortDeclaration
36
+ AnonPositionalArg = Annotated[
37
+ Union[
38
+ AnonClassicalParameterDeclaration,
39
+ "AnonQuantumOperandDeclaration",
40
+ AnonPortDeclaration,
41
+ ],
42
+ pydantic.Field(..., discriminator="kind"),
54
43
  ]
55
44
 
56
45
 
57
46
  def _ports_to_registers(
58
- port_declarations: Dict[str, PortDeclaration], direction: PortDirection
59
- ) -> ArithmeticIODict:
60
- return {
61
- name: quantum_var_to_register(name, port_decl.quantum_type)
62
- for name, port_decl in port_declarations.items()
47
+ port_declarations: Sequence[AnonPortDeclaration], direction: PortDirection
48
+ ) -> Sequence[RegisterUserInput]:
49
+ return [
50
+ quantum_var_to_register(port_decl.get_name(), port_decl.quantum_type)
51
+ for port_decl in port_declarations
63
52
  if port_decl.direction.includes_port_direction(direction)
64
- }
53
+ ]
65
54
 
66
55
 
67
- class QuantumFunctionDeclaration(FunctionDeclaration):
56
+ class AnonQuantumFunctionDeclaration(FunctionDeclaration):
68
57
  """
69
58
  Facilitates the creation of a common quantum function interface object.
70
59
  """
71
60
 
72
- port_declarations: Dict[str, PortDeclaration] = pydantic.Field(
73
- description="The input and output ports of the function.",
74
- default_factory=dict,
61
+ positional_arg_declarations: Sequence[AnonPositionalArg] = pydantic.Field(
62
+ default_factory=list
75
63
  )
76
64
 
77
- operand_declarations: Mapping[str, "QuantumOperandDeclaration"] = pydantic.Field(
78
- description="The expected interface of the quantum function operands",
79
- default_factory=dict,
80
- )
65
+ @property
66
+ def port_declarations(self) -> Sequence[AnonPortDeclaration]:
67
+ return [
68
+ arg
69
+ for arg in self.positional_arg_declarations
70
+ if isinstance(arg, AnonPortDeclaration)
71
+ ]
81
72
 
82
- positional_arg_declarations: List[PositionalArg] = pydantic.Field(
83
- default_factory=list
84
- )
73
+ @property
74
+ def operand_declarations(self) -> Sequence["AnonQuantumOperandDeclaration"]:
75
+ return [
76
+ arg
77
+ for arg in self.positional_arg_declarations
78
+ if isinstance(arg, AnonQuantumOperandDeclaration)
79
+ ]
85
80
 
86
- BUILTIN_FUNCTION_DECLARATIONS: ClassVar[Dict[str, "QuantumFunctionDeclaration"]] = (
87
- {}
88
- )
81
+ @property
82
+ def param_decls(self) -> Sequence[AnonClassicalParameterDeclaration]:
83
+ return [
84
+ arg
85
+ for arg in self.positional_arg_declarations
86
+ if isinstance(arg, AnonClassicalParameterDeclaration)
87
+ ]
88
+
89
+ @property
90
+ def param_names(self) -> Sequence[str]:
91
+ return [param.get_name() for param in self.param_decls]
89
92
 
90
93
  @property
91
- def input_set(self) -> Set[str]:
92
- return set(self.inputs.keys())
94
+ def input_set(self) -> set[str]:
95
+ return {inp.name for inp in self.inputs}
93
96
 
94
97
  @property
95
- def output_set(self) -> Set[str]:
96
- return set(self.outputs.keys())
98
+ def output_set(self) -> set[str]:
99
+ return {output.name for output in self.outputs}
97
100
 
98
101
  @property
99
- def inputs(self) -> ArithmeticIODict:
102
+ def inputs(self) -> Sequence[RegisterUserInput]:
100
103
  return _ports_to_registers(self.port_declarations, PortDirection.Input)
101
104
 
102
105
  @property
103
- def outputs(self) -> ArithmeticIODict:
106
+ def outputs(self) -> Sequence[RegisterUserInput]:
104
107
  return _ports_to_registers(self.port_declarations, PortDirection.Output)
105
108
 
106
- def update_logic_flow(
107
- self, function_dict: Mapping[str, "QuantumFunctionDeclaration"]
108
- ) -> None:
109
- pass
110
-
111
109
  @property
112
- def port_names(self) -> List[str]:
113
- return list(self.port_declarations.keys())
110
+ def port_names(self) -> Sequence[str]:
111
+ return [port.get_name() for port in self.port_declarations]
114
112
 
115
113
  @property
116
- def operand_names(self) -> List[str]:
117
- return list(self.operand_declarations.keys())
114
+ def operand_names(self) -> Sequence[str]:
115
+ return [operand.get_name() for operand in self.operand_declarations]
118
116
 
119
117
  def ports_by_direction(
120
118
  self, direction: PortDirection
121
- ) -> Mapping[str, PortDeclaration]:
122
- return {
123
- name: port
124
- for name, port in self.port_declarations.items()
119
+ ) -> Sequence[AnonPortDeclaration]:
120
+ return [
121
+ port
122
+ for port in self.port_declarations
125
123
  if port.direction.includes_port_direction(direction)
126
- }
124
+ ]
127
125
 
128
126
  def ports_by_declaration_direction(
129
127
  self, direction: PortDeclarationDirection
130
- ) -> Set[str]:
128
+ ) -> set[str]:
131
129
  return {
132
- name
133
- for name, port in self.port_declarations.items()
130
+ port.get_name()
131
+ for port in self.port_declarations
134
132
  if port.direction == direction
135
133
  }
136
134
 
137
- def get_positional_arg_decls(self) -> List[PositionalArg]:
138
- result: List[PositionalArg] = self.positional_arg_declarations
139
- if not result:
140
- result = [
141
- ClassicalParameterDeclaration(name=name, classical_type=ctype)
142
- for name, ctype in self.param_decls.items()
143
- ]
144
- result.extend(self.operand_declarations.values())
145
- result.extend(self.port_declarations.values())
146
- return result
147
-
148
- @pydantic.validator("operand_declarations")
149
- def _validate_operand_declarations_names(
150
- cls, operand_declarations: Dict[str, "QuantumOperandDeclaration"]
151
- ) -> Dict[str, "QuantumOperandDeclaration"]:
152
- validate_nameables_mapping(operand_declarations, "Operand")
153
- return operand_declarations
154
-
155
- @pydantic.validator("port_declarations")
156
- def _validate_port_declarations_names(
157
- cls, port_declarations: Dict[str, PortDeclaration]
158
- ) -> Dict[str, PortDeclaration]:
159
- validate_nameables_mapping(port_declarations, "Port")
160
- return port_declarations
161
-
162
- @pydantic.root_validator()
163
- def _validate_params_and_operands_uniqueness(
164
- cls, values: Dict[str, Any]
165
- ) -> Dict[str, Any]:
166
- operand_declarations = values.get("operand_declarations")
167
- parameter_declarations = values.get("param_decls")
168
- port_declarations = values.get("port_declarations")
169
- operand_parameter = validate_nameables_no_overlap(
170
- operand_declarations, parameter_declarations, "operand", "parameter"
171
- )
172
- operand_port = validate_nameables_no_overlap(
173
- operand_declarations, port_declarations, "operand", "port"
174
- )
175
- parameter_port = validate_nameables_no_overlap(
176
- parameter_declarations, port_declarations, "parameter", "port"
177
- )
178
- error_message = ",".join(
179
- msg
180
- for msg in [operand_parameter, operand_port, parameter_port]
181
- if msg is not None
135
+ def rename(self, new_name: str) -> "QuantumFunctionDeclaration":
136
+ if type(self) not in (
137
+ AnonQuantumFunctionDeclaration,
138
+ QuantumFunctionDeclaration,
139
+ NamedParamsQuantumFunctionDeclaration,
140
+ ):
141
+ raise ClassiqInternalError
142
+ return QuantumFunctionDeclaration(
143
+ **{
144
+ **{
145
+ field_name: field_value
146
+ for field_name, field_value in self.__dict__.items()
147
+ if field_name in AnonQuantumFunctionDeclaration.model_fields
148
+ },
149
+ "name": new_name,
150
+ }
182
151
  )
183
152
 
184
- if error_message:
185
- raise ClassiqValueError(error_message)
186
153
 
187
- return values
154
+ class AnonQuantumOperandDeclaration(AnonQuantumFunctionDeclaration):
155
+ kind: Literal["QuantumOperandDeclaration"]
156
+
157
+ is_list: bool = pydantic.Field(
158
+ description="Indicate whether the operand expects an unnamed list of lambdas",
159
+ default=False,
160
+ )
188
161
 
189
- @pydantic.root_validator()
190
- def _reduce_positional_declarations_to_keyword(
191
- cls, values: Dict[str, Any]
192
- ) -> Dict[str, Any]:
193
- operand_declarations = values.get("operand_declarations", dict())
194
- parameter_declarations = values.get("param_decls", dict())
195
- port_declarations = values.get("port_declarations", dict())
162
+ @pydantic.model_validator(mode="before")
163
+ @classmethod
164
+ def _set_kind(cls, values: Any) -> dict[str, Any]:
165
+ return values_with_discriminator(values, "kind", "QuantumOperandDeclaration")
196
166
 
197
- positional_arg_declarations = values.get("positional_arg_declarations", list())
167
+ def rename(self, new_name: str) -> "QuantumOperandDeclaration":
168
+ if type(self) not in (AnonQuantumOperandDeclaration, QuantumOperandDeclaration):
169
+ raise ClassiqInternalError
170
+ new_instance_data = self.__dict__.copy()
171
+ new_instance_data["name"] = new_name
172
+ new_instance_data["kind"] = "QuantumOperandDeclaration"
173
+ return QuantumOperandDeclaration(**new_instance_data)
198
174
 
199
- _populate_declaration_dicts_with_positional_lists(
200
- positional_arg_declarations,
201
- parameter_declarations,
202
- ClassicalParameterDeclaration,
203
- )
204
- _populate_declaration_dicts_with_positional_lists(
205
- positional_arg_declarations,
206
- operand_declarations,
207
- QuantumOperandDeclaration,
208
- )
209
- _populate_declaration_dicts_with_positional_lists(
210
- positional_arg_declarations, port_declarations, PortDeclaration
211
- )
175
+ @property
176
+ def element_declaration(self) -> Self:
177
+ if not self.is_list:
178
+ raise ClassiqInternalError
179
+ return self.model_copy(update={"is_list": False})
212
180
 
213
- values["operand_declarations"] = operand_declarations
214
- values["param_decls"] = parameter_declarations
215
- values["port_declarations"] = port_declarations
216
181
 
182
+ AnonQuantumFunctionDeclaration.model_rebuild()
183
+
184
+
185
+ class QuantumFunctionDeclaration(AnonQuantumFunctionDeclaration):
186
+ name: str
187
+
188
+
189
+ class QuantumOperandDeclaration(
190
+ AnonQuantumOperandDeclaration, QuantumFunctionDeclaration
191
+ ):
192
+ @pydantic.model_validator(mode="before")
193
+ @classmethod
194
+ def _set_none(cls, values: Any, info: ValidationInfo) -> dict[str, Any]:
217
195
  return values
218
196
 
219
197
 
220
- class QuantumOperandDeclaration(QuantumFunctionDeclaration):
221
- is_list: bool = pydantic.Field(
222
- description="Indicate whether the operand expects an unnamed list of lambdas",
223
- default=False,
198
+ PositionalArg = Annotated[
199
+ SerializeAsAny[
200
+ Union[
201
+ ClassicalParameterDeclaration,
202
+ QuantumOperandDeclaration,
203
+ PortDeclaration,
204
+ ]
205
+ ],
206
+ pydantic.Field(..., discriminator="kind"),
207
+ ]
208
+
209
+
210
+ class NamedParamsQuantumFunctionDeclaration(QuantumFunctionDeclaration):
211
+
212
+ positional_arg_declarations: Sequence[PositionalArg] = pydantic.Field(
213
+ default_factory=list
224
214
  )
225
215
 
216
+ @property
217
+ def port_declarations_dict(self) -> dict[str, PortDeclaration]:
218
+ return {port.name: port for port in self.port_declarations}
219
+
220
+ @property
221
+ def operand_declarations_dict(self) -> dict[str, QuantumOperandDeclaration]:
222
+ return {op.name: op for op in self.operand_declarations}
223
+
224
+ @property
225
+ def param_decls_dict(self) -> dict[str, ClassicalParameterDeclaration]:
226
+ return {param.name: param for param in self.param_decls}
227
+
228
+ @property
229
+ def inputs_dict(self) -> ArithmeticIODict:
230
+ return _ports_to_registers_dict(self.port_declarations, PortDirection.Input)
231
+
232
+ @property
233
+ def inouts_dict(self) -> ArithmeticIODict:
234
+ return _ports_to_registers_dict(self.port_declarations, PortDirection.Inout)
235
+
236
+ @property
237
+ def outputs_dict(self) -> ArithmeticIODict:
238
+ return _ports_to_registers_dict(self.port_declarations, PortDirection.Output)
239
+
240
+ @property
241
+ def port_declarations(self) -> Sequence[PortDeclaration]:
242
+ return super().port_declarations # type:ignore[return-value]
226
243
 
227
- QuantumFunctionDeclaration.update_forward_refs()
244
+ @property
245
+ def operand_declarations(self) -> Sequence[QuantumOperandDeclaration]:
246
+ return super().operand_declarations # type:ignore[return-value]
247
+
248
+ @property
249
+ def param_decls(self) -> Sequence[ClassicalParameterDeclaration]:
250
+ return super().param_decls # type:ignore[return-value]
251
+
252
+
253
+ def _ports_to_registers_dict(
254
+ port_declarations: Sequence[PortDeclaration], direction: PortDirection
255
+ ) -> ArithmeticIODict:
256
+ return {
257
+ port_decl.name: quantum_var_to_register(port_decl.name, port_decl.quantum_type)
258
+ for port_decl in port_declarations
259
+ if port_decl.direction.includes_port_direction(direction)
260
+ }
@@ -1,64 +1,65 @@
1
- from typing import TYPE_CHECKING, Dict, List, Optional, Union
1
+ from typing import TYPE_CHECKING, Callable, Optional, Union
2
2
 
3
3
  import pydantic
4
- from pydantic import BaseModel
5
4
 
5
+ from classiq.interface.ast_node import ASTNode
6
+ from classiq.interface.exceptions import ClassiqError
6
7
  from classiq.interface.generator.expressions.expression import Expression
7
8
  from classiq.interface.model.quantum_function_declaration import (
8
- QuantumOperandDeclaration,
9
+ AnonQuantumOperandDeclaration,
9
10
  )
10
- from classiq.interface.model.quantum_if_operation import QuantumIfOperation
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from classiq.interface.model.statement_block import StatementBlock
14
14
 
15
- from classiq.interface.model.within_apply_operation import WithinApplyOperation
16
15
 
17
-
18
- class QuantumLambdaFunction(BaseModel):
16
+ class QuantumLambdaFunction(ASTNode):
19
17
  """
20
18
  The definition of an anonymous function passed as operand to higher-level functions
21
19
  """
22
20
 
23
- rename_params: Dict[str, str] = pydantic.Field(
24
- default_factory=dict,
25
- description="Mapping of the declared param to the actual variable name used ",
21
+ pos_rename_params: list[str] = pydantic.Field(
22
+ default_factory=list,
23
+ description="Mapping of the declared param to the actual variable name used",
26
24
  )
27
25
 
28
26
  body: "StatementBlock" = pydantic.Field(
29
27
  description="A list of function calls passed to the operator"
30
28
  )
31
29
 
32
- _func_decl: Optional[QuantumOperandDeclaration] = pydantic.PrivateAttr(default=None)
30
+ _func_decl: Optional[AnonQuantumOperandDeclaration] = pydantic.PrivateAttr(
31
+ default=None
32
+ )
33
+
34
+ _py_callable: Callable = pydantic.PrivateAttr(default=None)
33
35
 
34
36
  @property
35
- def func_decl(self) -> Optional[QuantumOperandDeclaration]:
36
- return self._func_decl
37
+ def py_callable(self) -> Callable:
38
+ return self._py_callable
37
39
 
38
- def set_op_decl(self, fd: QuantumOperandDeclaration) -> None:
39
- self._func_decl = fd
40
+ def is_generative(self) -> bool:
41
+ return self.py_callable is not None
40
42
 
43
+ def set_py_callable(self, py_callable: Callable) -> None:
44
+ self._py_callable = py_callable
41
45
 
42
- class LambdaListComprehension(BaseModel):
43
- """
44
- Specification of a list of lambda functions iteratively
45
- """
46
+ @property
47
+ def func_decl(self) -> AnonQuantumOperandDeclaration:
48
+ if self._func_decl is None:
49
+ raise ClassiqError("Could not resolve lambda signature.")
50
+ return self._func_decl
46
51
 
47
- count: Expression = pydantic.Field(
48
- description="The number of lambda functions in the list"
49
- )
52
+ def set_op_decl(self, fd: AnonQuantumOperandDeclaration) -> None:
53
+ self._func_decl = fd
50
54
 
51
- index_var: str = pydantic.Field(
52
- description="The name of the integer variable holding the iteration index"
53
- )
54
55
 
55
- func: QuantumLambdaFunction = pydantic.Field(
56
- description="A lambda function definition replicated for index values 0 to count-1"
57
- )
56
+ class OperandIdentifier(ASTNode):
57
+ name: str
58
+ index: Expression
58
59
 
60
+ def __str__(self) -> str:
61
+ return f"{self.name}[{self.index.expr}]"
59
62
 
60
- QuantumCallable = Union[str, QuantumLambdaFunction]
61
- QuantumOperand = Union[QuantumCallable, List[QuantumCallable], LambdaListComprehension]
62
63
 
63
- QuantumIfOperation.update_forward_refs(QuantumOperand=QuantumOperand)
64
- WithinApplyOperation.update_forward_refs(QuantumOperand=QuantumOperand)
64
+ QuantumCallable = Union[str, OperandIdentifier, QuantumLambdaFunction]
65
+ QuantumOperand = Union[QuantumCallable, list[QuantumCallable]]
@@ -1,32 +1,91 @@
1
- from typing import Mapping, Union
1
+ from collections.abc import Mapping, Sequence
2
+ from dataclasses import dataclass
3
+ from typing import Any, Callable, Optional
4
+ from uuid import UUID, uuid4
2
5
 
3
- from pydantic import BaseModel, Extra
6
+ import pydantic
7
+ from pydantic import ConfigDict
4
8
 
9
+ from classiq.interface.ast_node import ASTNode
10
+ from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
5
11
  from classiq.interface.model.handle_binding import (
12
+ ConcreteHandleBinding,
6
13
  HandleBinding,
7
- SlicedHandleBinding,
8
- SubscriptHandleBinding,
9
14
  )
10
15
 
11
16
 
12
- class QuantumStatement(BaseModel):
13
- class Config:
14
- extra = Extra.forbid
17
+ class QuantumStatement(ASTNode):
18
+ kind: str
19
+ model_config = ConfigDict(extra="forbid")
20
+
21
+ @pydantic.model_validator(mode="before")
22
+ @classmethod
23
+ def _set_kind(cls, values: Any) -> dict[str, Any]:
24
+ return values_with_discriminator(values, "kind", cls.__name__)
25
+
26
+
27
+ @dataclass
28
+ class HandleMetadata:
29
+ handle: HandleBinding
30
+ readable_location: Optional[str] = None
15
31
 
16
32
 
17
33
  class QuantumOperation(QuantumStatement):
34
+ uuid: UUID = pydantic.Field(
35
+ description="A unique identifier for this operation", default_factory=uuid4
36
+ )
37
+ _generative_blocks: dict[str, Callable] = pydantic.PrivateAttr(default_factory=dict)
38
+
18
39
  @property
19
40
  def wiring_inputs(self) -> Mapping[str, HandleBinding]:
20
41
  return dict()
21
42
 
22
43
  @property
23
- def wiring_inouts(
24
- self,
25
- ) -> Mapping[
26
- str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
27
- ]:
44
+ def inputs(self) -> Sequence[HandleBinding]:
45
+ return list(self.wiring_inputs.values())
46
+
47
+ @property
48
+ def wiring_inouts(self) -> Mapping[str, ConcreteHandleBinding]:
28
49
  return dict()
29
50
 
51
+ @property
52
+ def inouts(self) -> Sequence[HandleBinding]:
53
+ return list(self.wiring_inouts.values())
54
+
30
55
  @property
31
56
  def wiring_outputs(self) -> Mapping[str, HandleBinding]:
32
57
  return dict()
58
+
59
+ @property
60
+ def outputs(self) -> Sequence[HandleBinding]:
61
+ return list(self.wiring_outputs.values())
62
+
63
+ @property
64
+ def readable_inputs(self) -> Sequence[HandleMetadata]:
65
+ return [HandleMetadata(handle=handle) for handle in self.inputs]
66
+
67
+ @property
68
+ def readable_inouts(self) -> Sequence[HandleMetadata]:
69
+ return [HandleMetadata(handle=handle) for handle in self.inouts]
70
+
71
+ @property
72
+ def readable_outputs(self) -> Sequence[HandleMetadata]:
73
+ return [HandleMetadata(handle=handle) for handle in self.outputs]
74
+
75
+ def set_generative_block(self, block_name: str, py_callable: Callable) -> None:
76
+ self._generative_blocks[block_name] = py_callable
77
+
78
+ def remove_generative_block(self, block_name: str) -> None:
79
+ self._generative_blocks.pop(block_name)
80
+
81
+ def get_generative_block(self, block_name: str) -> Callable:
82
+ return self._generative_blocks[block_name]
83
+
84
+ def has_generative_block(self, block_name: str) -> bool:
85
+ return block_name in self._generative_blocks
86
+
87
+ def is_generative(self) -> bool:
88
+ return len(self._generative_blocks) > 0
89
+
90
+ def clear_generative_blocks(self) -> None:
91
+ self._generative_blocks.clear()