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,146 +1,50 @@
1
- import itertools
2
- import re
3
- from typing import Any, Dict, List, Mapping, Optional, Set, Union
1
+ from collections.abc import Iterable, Mapping, Sequence
2
+ from typing import (
3
+ Literal,
4
+ Optional,
5
+ Union,
6
+ )
4
7
 
5
8
  import pydantic
6
- from pydantic import BaseModel
7
9
 
10
+ from classiq.interface.exceptions import ClassiqError, ClassiqValueError
8
11
  from classiq.interface.generator.expressions.expression import Expression
9
- from classiq.interface.generator.functions.function_declaration import (
10
- FunctionDeclaration,
11
- )
12
12
  from classiq.interface.generator.functions.port_declaration import (
13
13
  PortDeclarationDirection,
14
14
  )
15
- from classiq.interface.model.call_synthesis_data import CallSynthesisData
16
15
  from classiq.interface.model.handle_binding import (
16
+ ConcreteHandleBinding,
17
17
  HandleBinding,
18
- SlicedHandleBinding,
19
- SubscriptHandleBinding,
20
18
  )
19
+ from classiq.interface.model.port_declaration import AnonPortDeclaration
21
20
  from classiq.interface.model.quantum_function_declaration import (
22
21
  QuantumFunctionDeclaration,
23
- QuantumOperandDeclaration,
24
22
  )
25
23
  from classiq.interface.model.quantum_lambda_function import (
26
- LambdaListComprehension,
27
- QuantumCallable,
28
- QuantumLambdaFunction,
24
+ OperandIdentifier,
29
25
  QuantumOperand,
30
26
  )
31
- from classiq.interface.model.quantum_statement import QuantumOperation
32
- from classiq.interface.model.validation_handle import get_unique_handle_names
33
-
34
- from classiq.exceptions import ClassiqError, ClassiqValueError
35
-
36
-
37
- def _validate_no_duplicated_ports(
38
- inputs: Mapping[str, HandleBinding],
39
- outputs: Mapping[str, HandleBinding],
40
- inouts: Mapping[str, HandleBinding],
41
- ) -> None:
42
- inputs_and_inouts = inputs.keys() & inouts.keys()
43
- if inputs_and_inouts:
44
- raise ClassiqValueError(
45
- f"{inputs_and_inouts} are used as ports in both inputs and inouts"
46
- )
47
-
48
- outputs_and_inouts = outputs.keys() & inouts.keys()
49
- if outputs_and_inouts:
50
- raise ClassiqValueError(
51
- f"{outputs_and_inouts} are used as ports in both outputs and inouts"
52
- )
53
-
54
-
55
- def _validate_no_duplicated_handles(
56
- inputs: Mapping[str, HandleBinding],
57
- outputs: Mapping[str, HandleBinding],
58
- inouts: Mapping[str, HandleBinding],
59
- ) -> None:
60
- inputs_and_inouts = get_unique_handle_names(inputs) & get_unique_handle_names(
61
- inouts
62
- )
63
- if inputs_and_inouts:
64
- raise ClassiqValueError(
65
- f"{inputs_and_inouts} are used as handles in both inputs and inouts"
66
- )
67
-
68
- outputs_and_inouts = get_unique_handle_names(outputs) & get_unique_handle_names(
69
- inouts
70
- )
71
- if outputs_and_inouts:
72
- raise ClassiqValueError(
73
- f"{outputs_and_inouts} are used as handles in both outputs and inouts"
74
- )
75
-
76
-
77
- def _validate_no_mixing_sliced_and_whole_handles(
78
- inouts: Mapping[str, HandleBinding],
79
- ) -> None:
80
- inout_handle_names_to_types = {
81
- handle_name: {type(handle) for handle in handles}
82
- for handle_name, handles in itertools.groupby(
83
- inouts.values(), lambda handle: handle.name
84
- )
85
- }
86
- invalid_handles = [
87
- handle
88
- for handle, types in inout_handle_names_to_types.items()
89
- if len(types) > 1
90
- ]
91
- if invalid_handles:
92
- raise ClassiqValueError(
93
- f"Inout handles {', '.join(invalid_handles)} mix sliced and whole handles"
94
- )
95
-
27
+ from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
96
28
 
97
29
  ArgValue = Union[
98
30
  Expression,
99
31
  QuantumOperand,
100
- SlicedHandleBinding,
101
- SubscriptHandleBinding,
102
- HandleBinding,
32
+ ConcreteHandleBinding,
103
33
  ]
104
34
 
105
35
 
106
- class OperandIdentifier(BaseModel):
107
- name: str
108
- index: Expression
109
-
110
-
111
36
  class QuantumFunctionCall(QuantumOperation):
37
+ kind: Literal["QuantumFunctionCall"]
38
+
112
39
  function: Union[str, OperandIdentifier] = pydantic.Field(
113
40
  description="The function that is called"
114
41
  )
115
- params: Dict[str, Expression] = pydantic.Field(default_factory=dict)
116
- inputs: Dict[str, HandleBinding] = pydantic.Field(
117
- default_factory=dict,
118
- description="A mapping from the input name to the wire it connects to",
119
- )
120
- inouts: Dict[
121
- str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
122
- ] = pydantic.Field(
123
- default_factory=dict,
124
- description="A mapping from in/out name to the wires that connect to it",
125
- )
126
- outputs: Dict[str, HandleBinding] = pydantic.Field(
127
- default_factory=dict,
128
- description="A mapping from the output name to the wire it connects to",
129
- )
130
- operands: Dict[str, QuantumOperand] = pydantic.Field(
131
- description="Function calls passed to the operator",
132
- default_factory=dict,
133
- )
134
- positional_args: List[ArgValue] = pydantic.Field(default_factory=list)
42
+ positional_args: list[ArgValue] = pydantic.Field(default_factory=list)
135
43
 
136
44
  _func_decl: Optional[QuantumFunctionDeclaration] = pydantic.PrivateAttr(
137
45
  default=None
138
46
  )
139
47
 
140
- _synthesis_data: CallSynthesisData = pydantic.PrivateAttr(
141
- default_factory=CallSynthesisData
142
- )
143
-
144
48
  @property
145
49
  def func_decl(self) -> QuantumFunctionDeclaration:
146
50
  if self._func_decl is None:
@@ -148,7 +52,7 @@ class QuantumFunctionCall(QuantumOperation):
148
52
 
149
53
  return self._func_decl
150
54
 
151
- def set_func_decl(self, fd: Optional[FunctionDeclaration]) -> None:
55
+ def set_func_decl(self, fd: Optional[QuantumFunctionDeclaration]) -> None:
152
56
  if fd is not None and not isinstance(fd, QuantumFunctionDeclaration):
153
57
  raise ClassiqValueError(
154
58
  "the declaration of a quantum function call cannot be set to a non-quantum function declaration."
@@ -163,258 +67,152 @@ class QuantumFunctionCall(QuantumOperation):
163
67
 
164
68
  @property
165
69
  def wiring_inputs(self) -> Mapping[str, HandleBinding]:
166
- return self.inputs
70
+ return self._get_pos_port_args_by_direction(PortDeclarationDirection.Input)
167
71
 
168
72
  @property
169
- def wiring_inouts(
170
- self,
171
- ) -> Mapping[
172
- str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
173
- ]:
174
- return self.inouts
73
+ def inputs(self) -> Sequence[HandleBinding]:
74
+ return [
75
+ handle
76
+ for _, _, handle in self._get_handles_by_direction(
77
+ PortDeclarationDirection.Input
78
+ )
79
+ ]
175
80
 
176
81
  @property
177
- def wiring_outputs(self) -> Mapping[str, HandleBinding]:
178
- return self.outputs
179
-
180
- def get_positional_args(self) -> List[ArgValue]:
181
- result: List[ArgValue] = self.positional_args
182
- if not result:
183
- result = list(self.params.values())
184
- result.extend(self.operands.values())
185
- result.extend(self.inputs.values())
186
- result.extend(self.inouts.values())
187
- result.extend(self.outputs.values())
188
- return result
82
+ def readable_inputs(self) -> Sequence[HandleMetadata]:
83
+ return [
84
+ HandleMetadata(
85
+ handle=handle,
86
+ readable_location=self._get_readable_location(param_idx, param),
87
+ )
88
+ for param_idx, param, handle in self._get_handles_by_direction(
89
+ PortDeclarationDirection.Input
90
+ )
91
+ ]
189
92
 
190
93
  @property
191
- def pos_param_args(self) -> Dict[str, Expression]:
192
- return dict(
193
- zip(
194
- self.func_decl.param_decls.keys(),
195
- (
196
- param
197
- for param in self.positional_args
198
- if isinstance(param, Expression)
199
- ),
200
- )
201
- )
94
+ def wiring_inouts(
95
+ self,
96
+ ) -> Mapping[str, ConcreteHandleBinding]:
97
+ return self._get_pos_port_args_by_direction(PortDeclarationDirection.Inout)
202
98
 
203
99
  @property
204
- def pos_operand_args(self) -> Dict[str, "QuantumOperand"]:
205
- return dict(
206
- zip(
207
- self.func_decl.operand_declarations.keys(),
208
- (
209
- param
210
- for param in self.positional_args
211
- if not isinstance(param, (Expression, HandleBinding))
212
- ),
100
+ def inouts(self) -> Sequence[HandleBinding]:
101
+ return [
102
+ handle
103
+ for _, _, handle in self._get_handles_by_direction(
104
+ PortDeclarationDirection.Inout
213
105
  )
214
- )
106
+ ]
215
107
 
216
108
  @property
217
- def pos_port_args(self) -> Dict[str, HandleBinding]:
218
- return dict(
219
- zip(
220
- self.func_decl.port_declarations.keys(),
221
- (
222
- param
223
- for param in self.positional_args
224
- if isinstance(param, HandleBinding)
225
- ),
109
+ def readable_inouts(self) -> Sequence[HandleMetadata]:
110
+ return [
111
+ HandleMetadata(
112
+ handle=handle,
113
+ readable_location=self._get_readable_location(param_idx, param),
226
114
  )
227
- )
228
-
229
- def _update_pos_port_params(self) -> None:
230
- for name, port_decl in self.func_decl.port_declarations.items():
231
- if port_decl.direction == PortDeclarationDirection.Input:
232
- self.inputs[name] = self.pos_port_args[name]
233
- elif port_decl.direction == PortDeclarationDirection.Output:
234
- self.outputs[name] = self.pos_port_args[name]
235
- else:
236
- self.inouts[name] = self.pos_port_args[name]
237
-
238
- def _reduce_positional_args_to_keywords(self) -> None:
239
- self.params.update(self.pos_param_args)
240
- self.operands.update(self.pos_operand_args)
241
- self._update_pos_port_params()
242
-
243
- def resolve_function_decl(
244
- self,
245
- function_dict: Mapping[str, QuantumFunctionDeclaration],
246
- check_operands: bool,
247
- ) -> None:
248
- if self._func_decl is None:
249
- func_decl = function_dict.get(self.func_name)
250
- if func_decl is None:
251
- raise ClassiqValueError(
252
- f"Error resolving function {self.func_name}, the function is not found in included library."
253
- )
254
- self.set_func_decl(func_decl)
255
-
256
- if self.positional_args:
257
- self._reduce_positional_args_to_keywords()
258
-
259
- _check_params_against_declaration(
260
- set(self.params.keys()),
261
- set(self.func_decl.param_decls.keys()),
262
- self.func_decl.name,
263
- )
264
- _check_ports_against_declaration(self, self.func_decl)
265
- _check_params_against_declaration(
266
- set(self.operands.keys()),
267
- set(self.func_decl.operand_declarations.keys()),
268
- self.func_name,
269
- )
270
- if check_operands:
271
- _check_operands_against_declaration(self, self.func_decl, function_dict)
272
-
273
- for name, op in self.operands.items():
274
- op_decl = self.func_decl.operand_declarations[name]
275
- for qlambda in get_lambda_defs(op):
276
- if isinstance(qlambda, QuantumLambdaFunction):
277
- qlambda.set_op_decl(op_decl)
115
+ for param_idx, param, handle in self._get_handles_by_direction(
116
+ PortDeclarationDirection.Inout
117
+ )
118
+ ]
278
119
 
279
120
  @property
280
- def synthesis_data(self) -> CallSynthesisData:
281
- return self._synthesis_data
282
-
283
- def merge_synthesis_data(self, other: CallSynthesisData) -> None:
284
- self._synthesis_data = self._synthesis_data.merge(other)
285
-
286
- @pydantic.root_validator()
287
- def validate_handles(cls, values: Dict[str, Any]) -> Dict[str, Any]:
288
- inputs = values.get("inputs", dict())
289
- outputs = values.get("outputs", dict())
290
- inouts = values.get("inouts", dict())
291
-
292
- _validate_no_duplicated_ports(inputs, outputs, inouts)
293
- _validate_no_duplicated_handles(inputs, outputs, inouts)
294
- _validate_no_mixing_sliced_and_whole_handles(inouts)
295
-
296
- return values
297
-
298
-
299
- def get_lambda_defs(operand: QuantumOperand) -> List[QuantumCallable]:
300
- if isinstance(operand, list):
301
- return operand
302
- elif isinstance(operand, LambdaListComprehension):
303
- return [operand.func]
304
- else:
305
- return [operand]
306
-
307
-
308
- def _check_ports_against_declaration(
309
- call: QuantumFunctionCall, decl: QuantumFunctionDeclaration
310
- ) -> None:
311
- call_input_names = set(call.inputs.keys())
312
-
313
- _check_params_against_declaration(
314
- call_input_names,
315
- decl.ports_by_declaration_direction(PortDeclarationDirection.Input),
316
- call.func_name,
317
- )
318
-
319
- call_output_names = set(call.outputs.keys())
320
-
321
- _check_params_against_declaration(
322
- call_output_names,
323
- decl.ports_by_declaration_direction(PortDeclarationDirection.Output),
324
- call.func_name,
325
- )
326
-
327
- inout_params = set(call.inouts.keys())
328
-
329
- _check_params_against_declaration(
330
- inout_params,
331
- decl.ports_by_declaration_direction(PortDeclarationDirection.Inout),
332
- call.func_name,
333
- )
334
-
121
+ def wiring_outputs(self) -> Mapping[str, HandleBinding]:
122
+ return self._get_pos_port_args_by_direction(PortDeclarationDirection.Output)
335
123
 
336
- def _check_operand_against_declaration(
337
- call: QuantumFunctionCall,
338
- operand_decl: QuantumOperandDeclaration,
339
- operand_argument: QuantumOperand,
340
- function_dict: Mapping[str, QuantumFunctionDeclaration],
341
- in_list: bool = False,
342
- ) -> None:
343
- if isinstance(operand_argument, list):
344
- if in_list:
345
- raise ClassiqValueError(
346
- f"{str(operand_argument)!r} argument to {call.func_decl.name!r} is not "
347
- f"a valid operand. Nested operand lists are not permitted"
124
+ @property
125
+ def outputs(self) -> Sequence[HandleBinding]:
126
+ return [
127
+ handle
128
+ for _, _, handle in self._get_handles_by_direction(
129
+ PortDeclarationDirection.Output
348
130
  )
349
- for arg in operand_argument:
350
- _check_operand_against_declaration(
351
- call, operand_decl, arg, function_dict, in_list=True
131
+ ]
132
+
133
+ @property
134
+ def readable_outputs(self) -> Sequence[HandleMetadata]:
135
+ return [
136
+ HandleMetadata(
137
+ handle=handle,
138
+ readable_location=self._get_readable_location(param_idx, param),
352
139
  )
353
- return
354
- operand_arg_decl: QuantumFunctionDeclaration
355
- if isinstance(operand_argument, str):
356
- if operand_argument not in function_dict:
357
- raise ClassiqValueError(
358
- f"{operand_argument!r} argument to {call.func_decl.name!r} is not a "
359
- f"registered function"
140
+ for param_idx, param, handle in self._get_handles_by_direction(
141
+ PortDeclarationDirection.Output
360
142
  )
361
- operand_arg_decl = function_dict[operand_argument]
362
- elif isinstance(operand_argument, QuantumLambdaFunction):
363
- if operand_argument.func_decl is None:
364
- return
365
- operand_arg_decl = operand_argument.func_decl
366
- elif isinstance(operand_argument, LambdaListComprehension):
367
- if operand_argument.func.func_decl is None:
368
- return
369
- operand_arg_decl = operand_argument.func.func_decl
370
- else:
371
- raise ClassiqValueError(
372
- f"{str(operand_argument)!r} argument to {call.func_decl.name!r} is not a "
373
- f"valid operand"
374
- )
375
- num_arg_parameters = len(operand_arg_decl.get_positional_arg_decls())
376
- num_decl_parameters = len(operand_decl.get_positional_arg_decls())
377
- if num_arg_parameters != num_decl_parameters:
378
- raise ClassiqValueError(
379
- f"Signature of argument {operand_argument!r} to {call.func_decl.name!r} "
380
- f"does not match the signature of parameter {operand_decl.name!r}. "
381
- f"{operand_decl.name!r} accepts {num_decl_parameters} parameters but "
382
- f"{operand_argument!r} accepts {num_arg_parameters} parameters"
383
- )
143
+ ]
384
144
 
145
+ @property
146
+ def params(self) -> list[Expression]:
147
+ return [
148
+ param for param in self.positional_args if isinstance(param, Expression)
149
+ ]
385
150
 
386
- def _check_operands_against_declaration(
387
- call: QuantumFunctionCall,
388
- decl: QuantumFunctionDeclaration,
389
- function_dict: Mapping[str, QuantumFunctionDeclaration],
390
- ) -> None:
391
- for operand_parameter, operand_argument in call.operands.items():
392
- _check_operand_against_declaration(
393
- call,
394
- decl.operand_declarations[operand_parameter],
395
- operand_argument,
396
- function_dict,
397
- )
151
+ @property
152
+ def params_dict(self) -> dict[str, Expression]:
153
+ return dict(zip(self.func_decl.param_names, self.params))
398
154
 
155
+ @property
156
+ def operands(self) -> list["QuantumOperand"]:
157
+ return [
158
+ param
159
+ for param in self.positional_args
160
+ if not isinstance(param, (Expression, HandleBinding))
161
+ ]
399
162
 
400
- def _check_params_against_declaration(
401
- call_params: Set[str],
402
- param_decls: Set[str],
403
- callee_name: str,
404
- ) -> None:
405
- unknown_params = call_params - param_decls
406
- if any(re.match(r"arg\d+", param) for param in unknown_params):
407
- error_msg = (
408
- f"Unsupported passing of named function {callee_name!r} as an operand."
409
- "\nSuggestion: replace the named function with lambda function."
410
- )
411
- else:
412
- error_msg = f"Unknown parameters {unknown_params} in call to {callee_name!r}."
413
- if unknown_params:
414
- raise ClassiqValueError(error_msg)
163
+ @property
164
+ def ports(self) -> list[HandleBinding]:
165
+ return [
166
+ param for param in self.positional_args if isinstance(param, HandleBinding)
167
+ ]
168
+
169
+ def _get_handles_by_direction(
170
+ self, direction: PortDeclarationDirection
171
+ ) -> list[tuple[int, AnonPortDeclaration, HandleBinding]]:
172
+ return [
173
+ (idx, port_decl, handle)
174
+ for idx, port_decl, handle in self._get_handles_with_declarations()
175
+ if direction == port_decl.direction
176
+ ]
177
+
178
+ def _get_pos_port_args_by_direction(
179
+ self, direction: PortDeclarationDirection
180
+ ) -> dict[str, HandleBinding]:
181
+ # This is a hack for handles to wires reduction tests,
182
+ # that initialize function definitions or calls not in the scope of a model,
183
+ # so there is no function resolution annotation.
184
+ if self._func_decl is None:
185
+ return dict()
186
+ return {
187
+ port_decl.get_name(): handle
188
+ for _, port_decl, handle in self._get_handles_with_declarations()
189
+ if direction == port_decl.direction
190
+ }
191
+
192
+ def _get_handles_with_declarations(
193
+ self,
194
+ ) -> Iterable[tuple[int, AnonPortDeclaration, HandleBinding]]:
195
+ return [
196
+ (idx, port, handle)
197
+ for idx, (port, handle) in enumerate(
198
+ zip(
199
+ (port_decl for port_decl in self.func_decl.port_declarations),
200
+ (
201
+ param
202
+ for param in self.positional_args
203
+ if isinstance(param, HandleBinding)
204
+ ),
205
+ )
206
+ )
207
+ ]
415
208
 
416
- missing_params = param_decls - call_params
417
- if missing_params:
418
- raise ClassiqValueError(
419
- f"Missing parameters {missing_params} in call to {callee_name!r}."
209
+ def _get_readable_location(
210
+ self, param_index: int, param_decl: AnonPortDeclaration
211
+ ) -> str:
212
+ param_name = (
213
+ repr(param_decl.name) if param_decl.name is not None else f"#{param_index}"
214
+ )
215
+ param_text = (
216
+ f" for parameter {param_name}" if len(self.positional_args) > 1 else ""
420
217
  )
218
+ return f"as an argument{param_text} of function {self.func_name!r}"