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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. classiq/__init__.py +49 -34
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +3 -2
  3. classiq/_analyzer_extras/interactive_hardware.py +3 -3
  4. classiq/_internals/api_wrapper.py +241 -95
  5. classiq/_internals/async_utils.py +2 -77
  6. classiq/_internals/authentication/auth0.py +26 -10
  7. classiq/_internals/authentication/authentication.py +11 -0
  8. classiq/_internals/authentication/device.py +18 -8
  9. classiq/_internals/authentication/password_manager.py +40 -13
  10. classiq/_internals/authentication/token_manager.py +11 -6
  11. classiq/_internals/client.py +106 -37
  12. classiq/_internals/config.py +3 -4
  13. classiq/_internals/host_checker.py +38 -15
  14. classiq/_internals/jobs.py +56 -50
  15. classiq/_internals/type_validation.py +9 -9
  16. classiq/analyzer/__init__.py +1 -3
  17. classiq/analyzer/analyzer.py +50 -47
  18. classiq/analyzer/analyzer_utilities.py +15 -15
  19. classiq/analyzer/rb.py +19 -20
  20. classiq/analyzer/show_interactive_hack.py +30 -7
  21. classiq/analyzer/url_utils.py +2 -3
  22. classiq/applications/__init__.py +3 -12
  23. classiq/applications/chemistry/__init__.py +14 -10
  24. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  25. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +170 -170
  26. classiq/applications/chemistry/ground_state_problem.py +1 -1
  27. classiq/applications/combinatorial_helpers/allowed_constraints.py +23 -0
  28. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
  29. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
  30. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +166 -0
  31. classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
  32. classiq/applications/combinatorial_helpers/encoding_utils.py +124 -0
  33. classiq/applications/combinatorial_helpers/memory.py +75 -0
  34. classiq/applications/combinatorial_helpers/optimization_model.py +193 -0
  35. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
  36. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  37. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  38. classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
  39. classiq/applications/combinatorial_helpers/transformations/encoding.py +189 -0
  40. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +143 -0
  41. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +120 -0
  42. classiq/applications/combinatorial_helpers/transformations/penalty.py +31 -0
  43. classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
  44. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +74 -0
  45. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +87 -0
  46. classiq/applications/combinatorial_optimization/__init__.py +24 -5
  47. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  48. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +137 -0
  49. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  50. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  51. classiq/applications/finance/__init__.py +4 -5
  52. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +50 -57
  53. classiq/applications/grover/__init__.py +9 -0
  54. classiq/applications/grover/grover_model_constructor.py +157 -0
  55. classiq/applications/hamiltonian/__init__.py +0 -0
  56. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  57. classiq/applications/libraries/__init__.py +0 -0
  58. classiq/applications/libraries/qmci_library.py +22 -0
  59. classiq/applications/qnn/__init__.py +2 -4
  60. classiq/applications/qnn/circuit_utils.py +8 -8
  61. classiq/applications/qnn/datasets/__init__.py +9 -11
  62. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  63. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  64. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  65. classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
  66. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  67. classiq/applications/qnn/qlayer.py +30 -10
  68. classiq/applications/qnn/torch_utils.py +4 -3
  69. classiq/applications/qnn/types.py +7 -7
  70. classiq/applications/qsvm/__init__.py +6 -4
  71. classiq/applications/qsvm/qsvm.py +4 -10
  72. classiq/applications/qsvm/qsvm_data_generation.py +5 -8
  73. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  74. classiq/execution/__init__.py +8 -3
  75. classiq/execution/all_hardware_devices.py +11 -0
  76. classiq/execution/execution_session.py +400 -0
  77. classiq/execution/iqcc.py +63 -0
  78. classiq/execution/jobs.py +197 -25
  79. classiq/execution/qnn.py +79 -0
  80. classiq/executor.py +23 -117
  81. classiq/interface/_version.py +1 -1
  82. classiq/interface/analyzer/analysis_params.py +49 -16
  83. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  84. classiq/interface/analyzer/result.py +36 -32
  85. classiq/interface/applications/qsvm.py +28 -25
  86. classiq/interface/ast_node.py +16 -0
  87. classiq/interface/backend/backend_preferences.py +390 -119
  88. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  89. classiq/interface/backend/pydantic_backend.py +27 -22
  90. classiq/interface/backend/quantum_backend_providers.py +70 -16
  91. classiq/interface/chemistry/fermionic_operator.py +43 -32
  92. classiq/interface/chemistry/ground_state_problem.py +42 -24
  93. classiq/interface/chemistry/molecule.py +20 -14
  94. classiq/interface/chemistry/operator.py +75 -236
  95. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  96. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +2 -4
  97. classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
  98. classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
  99. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  100. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  101. classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
  102. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  103. classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
  104. classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
  105. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  106. classiq/interface/combinatorial_optimization/examples/set_cover.py +3 -3
  107. classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
  108. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
  109. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +14 -9
  110. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  111. classiq/interface/combinatorial_optimization/result.py +1 -3
  112. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  113. classiq/interface/debug_info/__init__.py +0 -0
  114. classiq/interface/debug_info/debug_info.py +86 -0
  115. classiq/interface/exceptions.py +201 -0
  116. classiq/interface/execution/iqcc.py +19 -0
  117. classiq/interface/execution/jobs.py +15 -12
  118. classiq/interface/execution/primitives.py +18 -0
  119. classiq/interface/executor/constants.py +1 -0
  120. classiq/interface/executor/estimation.py +2 -2
  121. classiq/interface/executor/execution_preferences.py +26 -143
  122. classiq/interface/executor/execution_request.py +36 -56
  123. classiq/interface/executor/execution_result.py +30 -8
  124. classiq/interface/executor/iqae_result.py +4 -6
  125. classiq/interface/executor/optimizer_preferences.py +34 -22
  126. classiq/interface/executor/{quantum_program.py → quantum_code.py} +44 -34
  127. classiq/interface/executor/quantum_instruction_set.py +3 -2
  128. classiq/interface/executor/register_initialization.py +12 -17
  129. classiq/interface/executor/result.py +122 -64
  130. classiq/interface/executor/vqe_result.py +11 -11
  131. classiq/interface/finance/function_input.py +42 -19
  132. classiq/interface/finance/gaussian_model_input.py +7 -5
  133. classiq/interface/finance/log_normal_model_input.py +6 -4
  134. classiq/interface/finance/model_input.py +6 -4
  135. classiq/interface/generator/adjacency.py +1 -3
  136. classiq/interface/generator/amplitude_loading.py +27 -14
  137. classiq/interface/generator/ansatz_library.py +5 -5
  138. classiq/interface/generator/application_apis/__init__.py +1 -0
  139. classiq/interface/generator/application_apis/arithmetic_declarations.py +17 -0
  140. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  141. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  142. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  143. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  144. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  145. classiq/interface/generator/arith/argument_utils.py +57 -6
  146. classiq/interface/generator/arith/arithmetic.py +37 -16
  147. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +15 -17
  148. classiq/interface/generator/arith/arithmetic_expression_abc.py +70 -26
  149. classiq/interface/generator/arith/arithmetic_expression_parser.py +18 -12
  150. classiq/interface/generator/arith/arithmetic_expression_validator.py +61 -43
  151. classiq/interface/generator/arith/arithmetic_operations.py +19 -16
  152. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  153. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  154. classiq/interface/generator/arith/ast_node_rewrite.py +4 -3
  155. classiq/interface/generator/arith/binary_ops.py +375 -139
  156. classiq/interface/generator/arith/endianness.py +1 -1
  157. classiq/interface/generator/arith/extremum_operations.py +96 -23
  158. classiq/interface/generator/arith/logical_ops.py +16 -12
  159. classiq/interface/generator/arith/machine_precision.py +3 -0
  160. classiq/interface/generator/arith/number_utils.py +44 -48
  161. classiq/interface/generator/arith/register_user_input.py +70 -27
  162. classiq/interface/generator/arith/unary_ops.py +57 -46
  163. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  164. classiq/interface/generator/builtin_api_builder.py +2 -9
  165. classiq/interface/generator/chemistry_function_params.py +5 -5
  166. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  167. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  168. classiq/interface/generator/commuting_pauli_exponentiation.py +8 -6
  169. classiq/interface/generator/compiler_keywords.py +8 -0
  170. classiq/interface/generator/complex_type.py +13 -25
  171. classiq/interface/generator/constant.py +3 -4
  172. classiq/interface/generator/control_state.py +35 -28
  173. classiq/interface/generator/copy.py +47 -0
  174. classiq/interface/generator/custom_ansatz.py +2 -5
  175. classiq/interface/generator/distance.py +3 -5
  176. classiq/interface/generator/excitations.py +3 -2
  177. classiq/interface/generator/expressions/atomic_expression_functions.py +26 -8
  178. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  179. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  180. classiq/interface/generator/expressions/evaluated_expression.py +21 -7
  181. classiq/interface/generator/expressions/expression.py +27 -15
  182. classiq/interface/generator/expressions/expression_constants.py +9 -3
  183. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  184. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  185. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +59 -0
  186. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  187. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  188. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  189. classiq/interface/generator/expressions/sympy_supported_expressions.py +20 -11
  190. classiq/interface/generator/finance.py +3 -3
  191. classiq/interface/generator/function_param_library.py +6 -6
  192. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  193. classiq/interface/generator/function_params.py +42 -69
  194. classiq/interface/generator/functions/__init__.py +0 -22
  195. classiq/interface/generator/functions/builtins/__init__.py +0 -0
  196. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  197. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  198. classiq/interface/generator/functions/classical_type.py +47 -166
  199. classiq/interface/generator/functions/concrete_types.py +55 -0
  200. classiq/interface/generator/functions/function_declaration.py +13 -14
  201. classiq/interface/generator/functions/port_declaration.py +1 -13
  202. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  203. classiq/interface/generator/functions/type_name.py +90 -0
  204. classiq/interface/generator/generated_circuit_data.py +155 -22
  205. classiq/interface/generator/grover_diffuser.py +32 -25
  206. classiq/interface/generator/grover_operator.py +34 -23
  207. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  208. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  209. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +12 -8
  210. classiq/interface/generator/hardware/hardware_data.py +76 -36
  211. classiq/interface/generator/hardware_efficient_ansatz.py +38 -17
  212. classiq/interface/generator/hartree_fock.py +14 -4
  213. classiq/interface/generator/identity.py +10 -6
  214. classiq/interface/generator/linear_pauli_rotations.py +33 -19
  215. classiq/interface/generator/mcmt_method.py +1 -1
  216. classiq/interface/generator/mcu.py +20 -16
  217. classiq/interface/generator/mcx.py +29 -20
  218. classiq/interface/generator/model/__init__.py +2 -5
  219. classiq/interface/generator/model/constraints.py +27 -8
  220. classiq/interface/generator/model/model.py +32 -203
  221. classiq/interface/generator/model/preferences/preferences.py +118 -43
  222. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +27 -22
  223. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  224. classiq/interface/generator/oracles/custom_oracle.py +17 -13
  225. classiq/interface/generator/oracles/oracle_abc.py +9 -9
  226. classiq/interface/generator/partitioned_register.py +7 -7
  227. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  228. classiq/interface/generator/preferences/optimization.py +1 -2
  229. classiq/interface/generator/qpe.py +47 -34
  230. classiq/interface/generator/qsvm.py +13 -17
  231. classiq/interface/generator/quantum_function_call.py +107 -87
  232. classiq/interface/generator/{generated_circuit.py → quantum_program.py} +50 -37
  233. classiq/interface/generator/range_types.py +13 -12
  234. classiq/interface/generator/register_role.py +18 -6
  235. classiq/interface/generator/slice_parsing_utils.py +11 -6
  236. classiq/interface/generator/standard_gates/controlled_standard_gates.py +32 -39
  237. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  238. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  239. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  240. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  241. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  242. classiq/interface/generator/state_preparation/distributions.py +16 -15
  243. classiq/interface/generator/state_preparation/metrics.py +5 -7
  244. classiq/interface/generator/state_preparation/state_preparation.py +30 -23
  245. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  246. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  247. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  248. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  249. classiq/interface/generator/types/compilation_metadata.py +6 -0
  250. classiq/interface/generator/types/enum_declaration.py +54 -0
  251. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  252. classiq/interface/generator/types/struct_declaration.py +15 -14
  253. classiq/interface/generator/ucc.py +9 -6
  254. classiq/interface/generator/unitary_gate.py +10 -6
  255. classiq/interface/generator/user_defined_function_params.py +4 -1
  256. classiq/interface/generator/validations/flow_graph.py +11 -9
  257. classiq/interface/generator/validations/validator_functions.py +8 -6
  258. classiq/interface/generator/visitor.py +23 -16
  259. classiq/interface/hardware.py +31 -10
  260. classiq/interface/helpers/classproperty.py +8 -0
  261. classiq/interface/helpers/custom_encoders.py +3 -0
  262. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  263. classiq/interface/helpers/datastructures.py +26 -0
  264. classiq/interface/helpers/hashable_mixin.py +3 -2
  265. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  266. classiq/interface/helpers/pydantic_model_helpers.py +7 -11
  267. classiq/interface/helpers/validation_helpers.py +4 -21
  268. classiq/interface/helpers/versioned_model.py +1 -1
  269. classiq/interface/ide/ide_data.py +16 -20
  270. classiq/interface/ide/visual_model.py +130 -0
  271. classiq/interface/interface_version.py +1 -0
  272. classiq/interface/jobs.py +35 -6
  273. classiq/interface/model/allocate.py +16 -0
  274. classiq/interface/model/bind_operation.py +44 -14
  275. classiq/interface/model/classical_if.py +15 -0
  276. classiq/interface/model/classical_parameter_declaration.py +33 -3
  277. classiq/interface/model/control.py +45 -0
  278. classiq/interface/model/handle_binding.py +298 -20
  279. classiq/interface/model/inplace_binary_operation.py +31 -26
  280. classiq/interface/model/invert.py +12 -0
  281. classiq/interface/model/model.py +87 -73
  282. classiq/interface/model/native_function_definition.py +16 -21
  283. classiq/interface/model/parameter.py +13 -0
  284. classiq/interface/model/phase_operation.py +11 -0
  285. classiq/interface/model/port_declaration.py +27 -9
  286. classiq/interface/model/power.py +14 -0
  287. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +38 -21
  288. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  289. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  290. classiq/interface/model/quantum_function_call.py +146 -462
  291. classiq/interface/model/quantum_function_declaration.py +193 -152
  292. classiq/interface/model/quantum_lambda_function.py +65 -0
  293. classiq/interface/model/quantum_statement.py +71 -12
  294. classiq/interface/model/quantum_type.py +205 -67
  295. classiq/interface/model/quantum_variable_declaration.py +4 -26
  296. classiq/interface/model/repeat.py +15 -0
  297. classiq/interface/model/statement_block.py +58 -0
  298. classiq/interface/model/validation_handle.py +13 -6
  299. classiq/interface/model/variable_declaration_statement.py +3 -1
  300. classiq/interface/model/within_apply_operation.py +13 -0
  301. classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
  302. classiq/interface/server/global_versions.py +6 -7
  303. classiq/interface/server/routes.py +22 -21
  304. classiq/interface/source_reference.py +59 -0
  305. classiq/model_expansions/__init__.py +0 -0
  306. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  307. classiq/model_expansions/capturing/__init__.py +0 -0
  308. classiq/model_expansions/capturing/captured_vars.py +435 -0
  309. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  310. classiq/model_expansions/closure.py +171 -0
  311. classiq/model_expansions/debug_flag.py +3 -0
  312. classiq/model_expansions/evaluators/__init__.py +0 -0
  313. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  314. classiq/model_expansions/evaluators/argument_types.py +42 -0
  315. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  316. classiq/model_expansions/evaluators/control.py +144 -0
  317. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  318. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  319. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  320. classiq/model_expansions/expression_evaluator.py +135 -0
  321. classiq/model_expansions/expression_renamer.py +76 -0
  322. classiq/model_expansions/function_builder.py +247 -0
  323. classiq/model_expansions/generative_functions.py +158 -0
  324. classiq/model_expansions/interpreters/__init__.py +0 -0
  325. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  326. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  327. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  328. classiq/model_expansions/model_tables.py +18 -0
  329. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  330. classiq/model_expansions/quantum_operations/bind.py +60 -0
  331. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  332. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  333. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  334. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  335. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  336. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  337. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  338. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  339. classiq/model_expansions/scope.py +240 -0
  340. classiq/model_expansions/scope_initialization.py +150 -0
  341. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  342. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  343. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  344. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  345. classiq/model_expansions/transformers/__init__.py +0 -0
  346. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  347. classiq/model_expansions/transformers/var_splitter.py +299 -0
  348. classiq/model_expansions/utils/__init__.py +0 -0
  349. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  350. classiq/model_expansions/utils/handles_collector.py +33 -0
  351. classiq/model_expansions/visitors/__init__.py +0 -0
  352. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  353. classiq/model_expansions/visitors/variable_references.py +144 -0
  354. classiq/open_library/__init__.py +4 -0
  355. classiq/open_library/functions/__init__.py +130 -0
  356. classiq/open_library/functions/amplitude_estimation.py +30 -0
  357. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  358. classiq/open_library/functions/grover.py +157 -0
  359. classiq/open_library/functions/hea.py +115 -0
  360. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  361. classiq/open_library/functions/modular_exponentiation.py +201 -0
  362. classiq/open_library/functions/qaoa_penalty.py +117 -0
  363. classiq/open_library/functions/qft_functions.py +54 -0
  364. classiq/open_library/functions/qpe.py +46 -0
  365. classiq/open_library/functions/qsvt.py +331 -0
  366. classiq/open_library/functions/state_preparation.py +301 -0
  367. classiq/open_library/functions/swap_test.py +27 -0
  368. classiq/open_library/functions/utility_functions.py +81 -0
  369. classiq/open_library/functions/variational.py +52 -0
  370. classiq/qmod/__init__.py +17 -10
  371. classiq/qmod/builtins/__init__.py +19 -2
  372. classiq/qmod/builtins/classical_execution_primitives.py +60 -47
  373. classiq/qmod/builtins/classical_functions.py +44 -38
  374. classiq/qmod/builtins/constants.py +10 -0
  375. classiq/qmod/builtins/enums.py +208 -0
  376. classiq/qmod/builtins/functions/__init__.py +137 -0
  377. classiq/qmod/builtins/functions/allocation.py +150 -0
  378. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  379. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  380. classiq/qmod/builtins/functions/chemistry.py +91 -0
  381. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  382. classiq/qmod/builtins/functions/finance.py +34 -0
  383. classiq/qmod/builtins/functions/operators.py +16 -0
  384. classiq/qmod/builtins/functions/qsvm.py +24 -0
  385. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  386. classiq/qmod/builtins/operations.py +379 -57
  387. classiq/qmod/builtins/structs.py +103 -80
  388. classiq/qmod/cfunc.py +42 -0
  389. classiq/qmod/classical_function.py +8 -20
  390. classiq/qmod/cparam.py +64 -0
  391. classiq/qmod/create_model_function.py +56 -0
  392. classiq/qmod/declaration_inferrer.py +145 -112
  393. classiq/qmod/expression_query.py +39 -0
  394. classiq/qmod/generative.py +42 -0
  395. classiq/qmod/model_state_container.py +19 -5
  396. classiq/qmod/native/__init__.py +7 -0
  397. classiq/qmod/native/expression_to_qmod.py +194 -0
  398. classiq/qmod/native/pretty_printer.py +401 -0
  399. classiq/qmod/pretty_print/__init__.py +7 -0
  400. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  401. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  402. classiq/qmod/python_classical_type.py +67 -0
  403. classiq/qmod/qfunc.py +79 -0
  404. classiq/qmod/qmod_constant.py +143 -0
  405. classiq/qmod/qmod_parameter.py +84 -53
  406. classiq/qmod/qmod_variable.py +497 -100
  407. classiq/qmod/quantum_callable.py +17 -7
  408. classiq/qmod/quantum_expandable.py +278 -105
  409. classiq/qmod/quantum_function.py +232 -48
  410. classiq/qmod/semantics/__init__.py +0 -0
  411. classiq/qmod/semantics/annotation/__init__.py +0 -0
  412. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  413. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  414. classiq/qmod/semantics/error_manager.py +88 -0
  415. classiq/qmod/semantics/lambdas.py +25 -0
  416. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  417. classiq/qmod/semantics/validation/__init__.py +0 -0
  418. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  419. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  420. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  421. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  422. classiq/qmod/semantics/validation/main_validation.py +33 -0
  423. classiq/qmod/semantics/validation/types_validation.py +128 -0
  424. classiq/qmod/symbolic.py +178 -111
  425. classiq/qmod/symbolic_expr.py +36 -12
  426. classiq/qmod/symbolic_type.py +2 -5
  427. classiq/qmod/type_attribute_remover.py +32 -0
  428. classiq/qmod/utilities.py +108 -1
  429. classiq/qmod/write_qmod.py +53 -0
  430. classiq/synthesis.py +210 -22
  431. {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -8
  432. classiq-0.65.3.dist-info/RECORD +521 -0
  433. {classiq-0.37.1.dist-info → classiq-0.65.3.dist-info}/WHEEL +1 -1
  434. classiq/_internals/_qfunc_ext.py +0 -6
  435. classiq/applications/benchmarking/__init__.py +0 -9
  436. classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
  437. classiq/applications/numpy_utils.py +0 -37
  438. classiq/applications_model_constructors/__init__.py +0 -17
  439. classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
  440. classiq/applications_model_constructors/grover_model_constructor.py +0 -227
  441. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  442. classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
  443. classiq/builtin_functions/__init__.py +0 -43
  444. classiq/builtin_functions/amplitude_loading.py +0 -3
  445. classiq/builtin_functions/binary_ops.py +0 -1
  446. classiq/builtin_functions/exponentiation.py +0 -5
  447. classiq/builtin_functions/qpe.py +0 -4
  448. classiq/builtin_functions/qsvm.py +0 -7
  449. classiq/builtin_functions/range_types.py +0 -5
  450. classiq/builtin_functions/standard_gates.py +0 -1
  451. classiq/builtin_functions/state_preparation.py +0 -6
  452. classiq/builtin_functions/suzuki_trotter.py +0 -3
  453. classiq/exceptions.py +0 -131
  454. classiq/interface/executor/aws_execution_cost.py +0 -72
  455. classiq/interface/executor/error_mitigation.py +0 -6
  456. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -115
  457. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -59
  458. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  459. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  460. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  461. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  462. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  463. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  464. classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
  465. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  466. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  467. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  468. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -862
  469. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
  470. classiq/interface/generator/functions/foreign_function_definition.py +0 -106
  471. classiq/interface/generator/functions/function_implementation.py +0 -103
  472. classiq/interface/generator/functions/native_function_definition.py +0 -153
  473. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  474. classiq/interface/generator/functions/register.py +0 -42
  475. classiq/interface/generator/functions/register_mapping_data.py +0 -102
  476. classiq/interface/generator/inequality_mixer.py +0 -51
  477. classiq/interface/generator/model/classical_main_validator.py +0 -106
  478. classiq/interface/generator/range_mixer.py +0 -56
  479. classiq/interface/generator/state_propagator.py +0 -63
  480. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -2
  481. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  482. classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
  483. classiq/interface/generator/types/combinatorial_problem.py +0 -26
  484. classiq/interface/ide/show.py +0 -34
  485. classiq/interface/model/common_model_types.py +0 -23
  486. classiq/interface/model/numeric_reinterpretation.py +0 -25
  487. classiq/interface/model/operator_synthesis_data.py +0 -48
  488. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  489. classiq/interface/model/quantum_if_operation.py +0 -95
  490. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  491. classiq/interface/model/validations/handle_validation_base.py +0 -55
  492. classiq/interface/model/validations/handles_validator.py +0 -154
  493. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  494. classiq/model/__init__.py +0 -14
  495. classiq/model/composite_function_generator.py +0 -33
  496. classiq/model/function_handler.py +0 -466
  497. classiq/model/function_handler.pyi +0 -152
  498. classiq/model/logic_flow.py +0 -149
  499. classiq/model/logic_flow_change_handler.py +0 -71
  500. classiq/model/model.py +0 -246
  501. classiq/qmod/builtins/functions.py +0 -896
  502. classiq/qmod/qmod_struct.py +0 -37
  503. classiq/quantum_functions/__init__.py +0 -17
  504. classiq/quantum_functions/annotation_parser.py +0 -207
  505. classiq/quantum_functions/decorators.py +0 -22
  506. classiq/quantum_functions/function_library.py +0 -181
  507. classiq/quantum_functions/function_parser.py +0 -74
  508. classiq/quantum_functions/quantum_function.py +0 -236
  509. classiq-0.37.1.dist-info/RECORD +0 -418
  510. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
  511. /classiq/{interface/generator/credit_risk_example → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
  512. /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/pauli_helpers}/__init__.py +0 -0
  513. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/py.typed} +0 -0
  514. /classiq/{interface/model/resolvers → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  515. /classiq/{interface/model/validations → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  516. /classiq/{_internals → interface}/enum_utils.py +0 -0
@@ -1,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,211 +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
109
+ @property
110
+ def port_names(self) -> Sequence[str]:
111
+ return [port.get_name() for port in self.port_declarations]
112
+
113
+ @property
114
+ def operand_names(self) -> Sequence[str]:
115
+ return [operand.get_name() for operand in self.operand_declarations]
110
116
 
111
117
  def ports_by_direction(
112
118
  self, direction: PortDirection
113
- ) -> Mapping[str, PortDeclaration]:
114
- return {
115
- name: port
116
- for name, port in self.port_declarations.items()
119
+ ) -> Sequence[AnonPortDeclaration]:
120
+ return [
121
+ port
122
+ for port in self.port_declarations
117
123
  if port.direction.includes_port_direction(direction)
118
- }
124
+ ]
119
125
 
120
126
  def ports_by_declaration_direction(
121
127
  self, direction: PortDeclarationDirection
122
- ) -> Set[str]:
128
+ ) -> set[str]:
123
129
  return {
124
- name
125
- for name, port in self.port_declarations.items()
130
+ port.get_name()
131
+ for port in self.port_declarations
126
132
  if port.direction == direction
127
133
  }
128
134
 
129
- def get_positional_arg_decls(self) -> List[PositionalArg]:
130
- result: List[PositionalArg] = self.positional_arg_declarations
131
- if not result:
132
- result = [
133
- ClassicalParameterDeclaration(name=name, classical_type=ctype)
134
- for name, ctype in self.param_decls.items()
135
- ]
136
- result.extend(self.operand_declarations.values())
137
- result.extend(self.port_declarations.values())
138
- return result
139
-
140
- @pydantic.validator("operand_declarations")
141
- def _validate_operand_declarations_names(
142
- cls, operand_declarations: Dict[str, "QuantumOperandDeclaration"]
143
- ) -> Dict[str, "QuantumOperandDeclaration"]:
144
- validate_nameables_mapping(operand_declarations, "Operand")
145
- return operand_declarations
146
-
147
- @pydantic.validator("port_declarations")
148
- def _validate_port_declarations_names(
149
- cls, port_declarations: Dict[str, PortDeclaration]
150
- ) -> Dict[str, PortDeclaration]:
151
- validate_nameables_mapping(port_declarations, "Port")
152
- return port_declarations
153
-
154
- @pydantic.root_validator()
155
- def _validate_params_and_operands_uniqueness(
156
- cls, values: Dict[str, Any]
157
- ) -> Dict[str, Any]:
158
- operand_declarations = values.get("operand_declarations")
159
- parameter_declarations = values.get("param_decls")
160
- port_declarations = values.get("port_declarations")
161
- operand_parameter = validate_nameables_no_overlap(
162
- operand_declarations, parameter_declarations, "operand", "parameter"
163
- )
164
- operand_port = validate_nameables_no_overlap(
165
- operand_declarations, port_declarations, "operand", "port"
166
- )
167
- parameter_port = validate_nameables_no_overlap(
168
- parameter_declarations, port_declarations, "parameter", "port"
169
- )
170
- error_message = ",".join(
171
- msg
172
- for msg in [operand_parameter, operand_port, parameter_port]
173
- 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
+ }
174
151
  )
175
152
 
176
- if error_message:
177
- raise ClassiqValueError(error_message)
178
153
 
179
- 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
+ )
180
161
 
181
- @pydantic.root_validator()
182
- def _reduce_positional_declarations_to_keyword(
183
- cls, values: Dict[str, Any]
184
- ) -> Dict[str, Any]:
185
- operand_declarations = values.get("operand_declarations", dict())
186
- parameter_declarations = values.get("param_decls", dict())
187
- 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")
188
166
 
189
- 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)
190
174
 
191
- _populate_declaration_dicts_with_positional_lists(
192
- positional_arg_declarations,
193
- parameter_declarations,
194
- ClassicalParameterDeclaration,
195
- )
196
- _populate_declaration_dicts_with_positional_lists(
197
- positional_arg_declarations,
198
- operand_declarations,
199
- QuantumOperandDeclaration,
200
- )
201
- _populate_declaration_dicts_with_positional_lists(
202
- positional_arg_declarations, port_declarations, PortDeclaration
203
- )
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})
180
+
181
+
182
+ AnonQuantumFunctionDeclaration.model_rebuild()
183
+
184
+
185
+ class QuantumFunctionDeclaration(AnonQuantumFunctionDeclaration):
186
+ name: str
204
187
 
205
- values["operand_declarations"] = operand_declarations
206
- values["param_decls"] = parameter_declarations
207
- values["port_declarations"] = port_declarations
208
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]:
209
195
  return values
210
196
 
211
197
 
212
- class QuantumOperandDeclaration(QuantumFunctionDeclaration):
213
- is_list: bool = pydantic.Field(
214
- description="Indicate whether the operand expects an unnamed list of lambdas",
215
- 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
216
214
  )
217
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}
218
223
 
219
- QuantumFunctionDeclaration.update_forward_refs()
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]
243
+
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
+ }
@@ -0,0 +1,65 @@
1
+ from typing import TYPE_CHECKING, Callable, Optional, Union
2
+
3
+ import pydantic
4
+
5
+ from classiq.interface.ast_node import ASTNode
6
+ from classiq.interface.exceptions import ClassiqError
7
+ from classiq.interface.generator.expressions.expression import Expression
8
+ from classiq.interface.model.quantum_function_declaration import (
9
+ AnonQuantumOperandDeclaration,
10
+ )
11
+
12
+ if TYPE_CHECKING:
13
+ from classiq.interface.model.statement_block import StatementBlock
14
+
15
+
16
+ class QuantumLambdaFunction(ASTNode):
17
+ """
18
+ The definition of an anonymous function passed as operand to higher-level functions
19
+ """
20
+
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",
24
+ )
25
+
26
+ body: "StatementBlock" = pydantic.Field(
27
+ description="A list of function calls passed to the operator"
28
+ )
29
+
30
+ _func_decl: Optional[AnonQuantumOperandDeclaration] = pydantic.PrivateAttr(
31
+ default=None
32
+ )
33
+
34
+ _py_callable: Callable = pydantic.PrivateAttr(default=None)
35
+
36
+ @property
37
+ def py_callable(self) -> Callable:
38
+ return self._py_callable
39
+
40
+ def is_generative(self) -> bool:
41
+ return self.py_callable is not None
42
+
43
+ def set_py_callable(self, py_callable: Callable) -> None:
44
+ self._py_callable = py_callable
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
51
+
52
+ def set_op_decl(self, fd: AnonQuantumOperandDeclaration) -> None:
53
+ self._func_decl = fd
54
+
55
+
56
+ class OperandIdentifier(ASTNode):
57
+ name: str
58
+ index: Expression
59
+
60
+ def __str__(self) -> str:
61
+ return f"{self.name}[{self.index.expr}]"
62
+
63
+
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()