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,37 +0,0 @@
1
- import dataclasses
2
- from typing import Any, List, Type
3
-
4
- from typing_extensions import dataclass_transform
5
-
6
- from classiq.interface.generator.functions.classical_type import QStructBase
7
-
8
-
9
- def _qmod_val_to_expr_str(val: Any) -> str:
10
- if dataclasses.is_dataclass(type(val)):
11
- kwargs_str = ", ".join(
12
- [
13
- f"{field.name}={_qmod_val_to_expr_str(vars(val)[field.name])}"
14
- for field in dataclasses.fields(val)
15
- ]
16
- )
17
- return f"struct_literal({type(val).__name__}, {kwargs_str})"
18
-
19
- if isinstance(val, List):
20
- elements_str = ", ".join([_qmod_val_to_expr_str(elem) for elem in val])
21
- return f"[{elements_str}]"
22
-
23
- return str(val)
24
-
25
-
26
- @dataclass_transform()
27
- def QStruct(user_class: Type) -> Type: # noqa: N802 - for consistency with 'QFunc'
28
- def _new_repr(self: Any) -> str:
29
- return _qmod_val_to_expr_str(self)
30
-
31
- user_dataclass = type(
32
- user_class.__name__,
33
- (QStructBase, dataclasses.dataclass(user_class)),
34
- dict(),
35
- )
36
- user_dataclass.__repr__ = _new_repr # type:ignore[assignment]
37
- return user_dataclass
@@ -1,17 +0,0 @@
1
- from classiq.quantum_functions.decorators import quantum_function as qfunc
2
- from classiq.quantum_functions.function_library import (
3
- QASM3_INTRO,
4
- QASM_INTRO,
5
- FunctionLibrary,
6
- QuantumFunction,
7
- QuantumFunctionFactory,
8
- )
9
-
10
- __all__ = [
11
- "qfunc",
12
- "QASM_INTRO",
13
- "QASM3_INTRO",
14
- "FunctionLibrary",
15
- "QuantumFunction",
16
- "QuantumFunctionFactory",
17
- ]
@@ -1,207 +0,0 @@
1
- # type: ignore
2
- # We can either ignore each line individually, or ignore the entire file and wait until mypy can ignore
3
- # specific errors per-file.
4
- import inspect
5
- import sys
6
- from types import FunctionType
7
- from typing import Any, Dict, List, Tuple, Union, _GenericAlias
8
-
9
- from classiq.interface.generator.register_role import RegisterRole as Role
10
-
11
- from classiq.exceptions import ClassiqQFuncError
12
- from classiq.quantum_register import AuxQReg, QReg, QRegGenericAlias, QSFixed, ZeroQReg
13
-
14
- if sys.version_info >= (3, 9):
15
- from types import GenericAlias
16
- else:
17
- GenericAlias = _GenericAlias
18
-
19
- GenericAliasUnion = Union[GenericAlias, _GenericAlias]
20
-
21
-
22
- class AnnotationParser:
23
- def __init__(self, func: FunctionType) -> None:
24
- self._func = func
25
-
26
- self.output_types: Dict[str, GenericAlias] = {}
27
-
28
- def parse(self) -> None:
29
- annotations = self._func.__annotations__.copy()
30
-
31
- # Todo: remove this `if` after introducing `Inplace`
32
- if "return" not in annotations:
33
- raise ClassiqQFuncError("Return value annotations not found")
34
-
35
- self.output_values = self._unpack_output_values(annotations.pop("return"))
36
- self.input_names, self.input_values = self._unpack_input_values(annotations)
37
-
38
- self._validate()
39
-
40
- def _validate(self) -> None:
41
- self._validate_type_hints()
42
- self._validate_qubit_amount()
43
- self._validate_io_length()
44
- self._validate_io_correlation()
45
-
46
- def _validate_type_hints(self) -> None:
47
- # Validate type of type-hints
48
- if not all(
49
- map(
50
- self.is_valid_generic_alias_of_qreg,
51
- self.input_values + self.output_values,
52
- )
53
- ):
54
- raise ClassiqQFuncError("Invalid GenericAlias convection")
55
-
56
- def _validate_qubit_amount(self) -> None:
57
- # Validate qubit amount
58
- if sum(i.size for i in self.output_values) != sum(
59
- i.size for i in self.input_values
60
- ):
61
- raise ClassiqQFuncError(
62
- "Input and output values have different amounts of qubits"
63
- )
64
-
65
- # Todo: Remove this validation by introducing better heuristics
66
- # Or after introducing Inplace
67
- def _validate_io_length(self) -> None:
68
- # Validate amount of inputs and outputs
69
- if len(self.input_values) != len(self.output_values):
70
- raise ClassiqQFuncError(
71
- "Inputs and outputs must have the same number of QRegs"
72
- )
73
-
74
- def _validate_io_correlation(self) -> None:
75
- # Validate correspondence between inputs and outputs
76
- for input_name, input_type, output_type in zip(
77
- self.input_names, self.input_values, self.output_values
78
- ):
79
- # Is arithmetic QReg
80
- if issubclass(input_type.__origin__, QSFixed):
81
- if input_type != output_type:
82
- raise ClassiqQFuncError(
83
- f"Arithmetic QReg must be of the same type and size in both the input and the output. Got {input_type} and {output_type}"
84
- )
85
-
86
- # Is Auxillary QReg
87
- if issubclass(input_type.__origin__, AuxQReg):
88
- if input_type != output_type:
89
- raise ClassiqQFuncError(
90
- f"Auxillary QReg must be of the same type and size in both the input and the output. Got {input_type} and {output_type}"
91
- )
92
-
93
- # Is Zero QReg
94
- if input_type.__origin__ is ZeroQReg:
95
- if output_type.__origin__ is QReg or issubclass(
96
- output_type.__origin__, QSFixed
97
- ):
98
- self.output_types[input_name] = output_type
99
- else:
100
- raise ClassiqQFuncError(
101
- "Invalid output type. Any ZeroQReg in the input must have a corresponding QReg in the output"
102
- )
103
-
104
- @classmethod
105
- def _unpack_output_values(
106
- cls, output_value_type_hint: Any
107
- ) -> Tuple[GenericAlias, ...]:
108
- # Handle QReg type hints
109
- if cls.is_subclass_qreg(output_value_type_hint):
110
- return (cls.to_generic_alias(output_value_type_hint),)
111
-
112
- # Supporting both `typing._GenericAlias` and `types.GenericAlias`
113
- if not cls.is_instance_generic_alias(output_value_type_hint):
114
- raise ClassiqQFuncError(
115
- "Output value type hint must be either a single QReg, `typing.Tuple[QReg, ...]` or, for python>=3.9, `tuple[QReg, ...]`"
116
- )
117
-
118
- # Allowing only a tuple of outputs:
119
- if not cls.is_tuple_generic_alias(output_value_type_hint):
120
- raise ClassiqQFuncError(
121
- "Output value type hint must be either Tuple[QReg, ...] or tuple[QReg, ...]"
122
- )
123
-
124
- # This line may raise ClassiqQFuncError
125
- return tuple(map(cls.to_generic_alias, output_value_type_hint.__args__))
126
-
127
- def _unpack_input_values(
128
- self, annotations: Dict[str, Any]
129
- ) -> Tuple[List[str], Tuple[GenericAlias, ...]]:
130
- input_names = list(annotations.keys())
131
- input_values = tuple(map(self.to_generic_alias, annotations.values()))
132
- return input_names, input_values
133
-
134
- @staticmethod
135
- def to_generic_alias(obj: Any) -> GenericAlias:
136
- # Handle GenericAlias
137
- if isinstance(obj, (QRegGenericAlias, GenericAlias)):
138
- return obj
139
- # Handle _GenericAlias, for python>3.9, i.e. when GenericAlias != _GenericAlias
140
- if isinstance(obj, _GenericAlias):
141
- return GenericAlias(obj.__origin__, obj.__args__)
142
- # Handle a single QReg (not GenericAlias of QReg)
143
- elif inspect.isclass(obj) and issubclass(obj, QReg):
144
- return GenericAlias(obj, tuple())
145
-
146
- raise ClassiqQFuncError(f"Invalid type hint object: {obj.__class__.__name__}")
147
-
148
- @staticmethod
149
- def is_instance_generic_alias(obj: Any) -> bool:
150
- return isinstance(obj, (GenericAlias, _GenericAlias))
151
-
152
- @classmethod
153
- def is_subclass_qreg(cls, obj: Any) -> bool:
154
- if inspect.isclass(obj):
155
- return issubclass(obj, QReg)
156
- elif cls.is_instance_generic_alias(obj):
157
- return issubclass(obj.__origin__, QReg)
158
- return False
159
-
160
- @staticmethod
161
- def is_tuple_generic_alias(obj: GenericAliasUnion) -> bool:
162
- return obj.__origin__.__name__.lower() == "tuple"
163
-
164
- @staticmethod
165
- def is_valid_generic_alias_of_qreg(obj: GenericAlias) -> bool:
166
- return isinstance(obj, QRegGenericAlias)
167
-
168
-
169
- def get_annotation_role(annotation: GenericAlias, default_role: Role) -> Role:
170
- """
171
- Note: this function cannot distinguish between inputs and outputs.
172
- Thus, for inputs, all 3 options are valid
173
- However, for outputs:
174
- a) we don't expect to get ZERO
175
- b) We treat INPUT as OUTPUT
176
- """
177
- ret = None
178
-
179
- if getattr(annotation, "role", None) is not None:
180
- ret = annotation.role
181
- if getattr(annotation.__origin__, "role", None) is not None:
182
- ret = annotation.role
183
-
184
- if issubclass(annotation.__origin__, QReg) and not issubclass(
185
- annotation.__origin__, ZeroQReg
186
- ):
187
- ret = default_role
188
-
189
- if issubclass(annotation.__origin__, ZeroQReg) and not issubclass(
190
- annotation.__origin__, AuxQReg
191
- ):
192
- ret = Role.ZERO_INPUT
193
-
194
- if issubclass(annotation.__origin__, AuxQReg):
195
- ret = Role.AUXILIARY
196
-
197
- # Didn't match anything so far
198
- if ret is None:
199
- raise ClassiqQFuncError("Invalid annotation role")
200
-
201
- if default_role == Role.INPUT and ret == Role.OUTPUT:
202
- raise ClassiqQFuncError("input should not have Role.OUTPUT")
203
-
204
- if default_role == Role.OUTPUT and ret in (Role.ZERO_INPUT, Role.INPUT):
205
- raise ClassiqQFuncError("output should not have Role.ZERO / Role.INPUT")
206
-
207
- return ret
@@ -1,22 +0,0 @@
1
- from typing import Callable, Optional, Union, overload
2
-
3
- from classiq.quantum_functions.quantum_function import QuantumFunction
4
-
5
-
6
- @overload
7
- def quantum_function(func: None = None, name: Optional[str] = None) -> Callable: ...
8
-
9
-
10
- @overload
11
- def quantum_function(func: Callable, name: Optional[str] = None) -> QuantumFunction: ...
12
-
13
-
14
- def quantum_function(
15
- func: Optional[Callable] = None, name: Optional[str] = None
16
- ) -> Union[QuantumFunction, Callable]:
17
- if func is None:
18
- return lambda func: quantum_function(func, name)
19
- else:
20
- qf = QuantumFunction()
21
- qf.add_implementation(func, name)
22
- return qf
@@ -1,181 +0,0 @@
1
- """Function library module, implementing facilities for adding user defined functions to the Classiq platform."""
2
-
3
- from typing import Any, Dict, List, Tuple, Type, Union
4
-
5
- from more_itertools import locate
6
-
7
- from classiq.interface.generator.functions import (
8
- SynthesisForeignFunctionDefinition,
9
- SynthesisNativeFunctionDefinition,
10
- SynthesisQuantumFunctionDeclaration,
11
- )
12
- from classiq.interface.generator.model.model import (
13
- MAIN_FUNCTION_NAME,
14
- ConcreteFunctionDefinition,
15
- )
16
- from classiq.interface.generator.user_defined_function_params import CustomFunction
17
- from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
18
-
19
- from classiq.exceptions import ClassiqValueError
20
- from classiq.quantum_functions.quantum_function import (
21
- QuantumFunction,
22
- QuantumFunctionFactory,
23
- )
24
-
25
- QASM_INTRO = 'OPENQASM 2.0;\ninclude "qelib1.inc";\n'
26
- QASM3_INTRO = 'OPENQASM 3.0;\ninclude "stdgates.inc";\n'
27
-
28
- _INVALID_FUNCTION_LIBRARY_ARGUMENT_ERROR_MSG: str = (
29
- "Argument is not a valid FunctionLibrary object"
30
- )
31
-
32
-
33
- class FunctionLibrary:
34
- """Facility to manage functions."""
35
-
36
- def __init__(
37
- self,
38
- *functions: Union[
39
- SynthesisQuantumFunctionDeclaration,
40
- QuantumFunction,
41
- Type[QuantumFunctionFactory],
42
- ],
43
- ) -> None:
44
- """
45
- Args:
46
- name (:obj:`str`, optional): The name of the function library.
47
- *functions (:obj:`SynthesisQuantumFunctionDeclaration`, optional): A list of functions to initialize the object.
48
- """
49
- self._data: List[ConcreteFunctionDefinition] = list()
50
- self._params: Dict[str, CustomFunction] = dict()
51
- self._func_factories: Dict[str, Type[QuantumFunctionFactory]] = dict()
52
-
53
- for f in functions:
54
- self.add_function(f)
55
-
56
- if MAIN_FUNCTION_NAME not in self.function_dict:
57
- self.add_function(
58
- SynthesisNativeFunctionDefinition(name=MAIN_FUNCTION_NAME)
59
- )
60
-
61
- def get_function(self, function_name: str) -> CustomFunction:
62
- return self._params[function_name]
63
-
64
- def get_function_factory(
65
- self, function_factory_name: str
66
- ) -> Type[QuantumFunctionFactory]:
67
- return self._func_factories[function_factory_name]
68
-
69
- def __getitem__(self, key: Any) -> CustomFunction:
70
- if isinstance(key, str):
71
- return self.get_function(key)
72
- else:
73
- raise ClassiqValueError("Invalid key")
74
-
75
- def add_function(
76
- self,
77
- function_data: Union[
78
- SynthesisQuantumFunctionDeclaration,
79
- QuantumFunction,
80
- Type[QuantumFunctionFactory],
81
- ],
82
- override_existing_functions: bool = False,
83
- ) -> None:
84
- """Adds a function to the function library.
85
-
86
- Args:
87
- function_data (SynthesisQuantumFunctionDeclaration): The function data object.
88
- override_existing_functions (:obj:`bool`, optional): Defaults to False.
89
-
90
- Returns:
91
- None
92
- """
93
- if isinstance(function_data, type) and issubclass(
94
- function_data, QuantumFunctionFactory
95
- ):
96
- self._func_factories[function_data.__name__] = function_data
97
- return
98
- if isinstance(function_data, QuantumFunction):
99
- function_data = function_data.function_data
100
-
101
- if not isinstance(
102
- function_data,
103
- (SynthesisForeignFunctionDefinition, SynthesisNativeFunctionDefinition),
104
- ):
105
- raise ClassiqValueError(
106
- f"Concrete function definition object expected, got {function_data.__class__.__name__}"
107
- )
108
-
109
- function_name = function_data.name
110
- if not override_existing_functions and function_name in self.function_dict:
111
- raise ClassiqValueError("Cannot override existing functions.")
112
-
113
- if isinstance(function_data, SynthesisNativeFunctionDefinition):
114
- for call in filter(
115
- lambda i: isinstance(i.function_params, CustomFunction),
116
- function_data.body,
117
- ):
118
- if self._data and call.function not in self.function_dict:
119
- raise ClassiqValueError(
120
- "FunctionLibrary: The function is not found in included library."
121
- )
122
-
123
- self._data.append(function_data)
124
- self._params[function_name] = self._to_params(function_data)
125
-
126
- @property
127
- def function_names(self) -> Tuple[str, ...]:
128
- """Get a tuple of the names of the functions in the library.
129
-
130
- Returns:
131
- The names of the functions in the library.
132
- """
133
- return tuple(self.function_dict.keys())
134
-
135
- @property
136
- def function_factory_names(self) -> Tuple[str, ...]:
137
- return tuple(self._func_factories.keys())
138
-
139
- @property
140
- def functions(self) -> List[ConcreteFunctionDefinition]:
141
- return list(self._data)
142
-
143
- @property
144
- def function_dict(self) -> Dict[str, SynthesisQuantumFunctionDeclaration]:
145
- return nameables_to_dict(self._data)
146
-
147
- def remove_function_definition(self, name: str) -> None:
148
- idx = list(locate(self.functions, lambda func: func.name == name))
149
- assert len(idx) == 1
150
- self._data.pop(idx[0])
151
-
152
- @staticmethod
153
- def _to_params(data: SynthesisQuantumFunctionDeclaration) -> CustomFunction:
154
- params = CustomFunction(
155
- input_decls=data.inputs,
156
- output_decls=data.outputs,
157
- )
158
- return params
159
-
160
- def __add__(self, other: "FunctionLibrary") -> "FunctionLibrary":
161
- if not isinstance(other, FunctionLibrary):
162
- raise ClassiqValueError(_INVALID_FUNCTION_LIBRARY_ARGUMENT_ERROR_MSG)
163
- joint_library = FunctionLibrary()
164
- for library in (self, other):
165
- for func in library.functions:
166
- if (
167
- func.name == MAIN_FUNCTION_NAME
168
- or func.name in joint_library.function_names
169
- ):
170
- continue
171
- joint_library.add_function(func)
172
- return joint_library
173
-
174
- def __iadd__(self, other: "FunctionLibrary") -> "FunctionLibrary":
175
- if not isinstance(other, FunctionLibrary):
176
- raise ClassiqValueError(_INVALID_FUNCTION_LIBRARY_ARGUMENT_ERROR_MSG)
177
- for func in other.functions:
178
- if func.name == MAIN_FUNCTION_NAME or func.name in self.function_names:
179
- continue
180
- self.add_function(func)
181
- return self
@@ -1,74 +0,0 @@
1
- import sys
2
- from types import FunctionType, MethodType
3
- from typing import Any, Callable, Tuple, _GenericAlias # type: ignore[attr-defined]
4
-
5
- if sys.version_info >= (3, 9):
6
- from types import GenericAlias
7
- else:
8
- GenericAlias = _GenericAlias
9
-
10
-
11
- from classiq.exceptions import ClassiqQFuncError
12
-
13
-
14
- class FunctionParser:
15
- def __init__(self, func: FunctionType) -> None:
16
- self._func = func
17
-
18
- @staticmethod
19
- def _extract_function_output_by_execution(func: FunctionType) -> Any:
20
- # Todo: Parse the type (annotations) of the arguments, and remove only those inheriting from QReg
21
- if func.__code__.co_kwonlyargcount:
22
- raise ClassiqQFuncError("kw only args are not supported")
23
-
24
- arg_count = func.__code__.co_argcount - ("self" in func.__code__.co_varnames)
25
- nones = [None] * arg_count
26
- return func(*nones)
27
-
28
- def extract_function_output(self) -> Any:
29
- output = self._extract_function_output_by_execution(func=self._func)
30
-
31
- self._validate_function_output(output)
32
-
33
- return output
34
-
35
- @staticmethod
36
- def _validate_function_output(output: Any) -> None:
37
- # Todo: validate QASM
38
-
39
- if type(output) is not str:
40
- raise ClassiqQFuncError(
41
- "Invalid output. Please return a string of OpenQASM2.0."
42
- )
43
-
44
-
45
- def _convert_class_to_function(cls: type) -> Tuple[FunctionType, str]:
46
- # Create instance
47
- try:
48
- inst = cls()
49
- except TypeError as exc:
50
- raise ClassiqQFuncError("Unable to initialize class") from exc
51
-
52
- return inst.__call__, inst.__class__.__name__
53
-
54
-
55
- def convert_callable_to_function(func: Callable) -> Tuple[FunctionType, str]:
56
- # There's a story to be told here:
57
- # Functions vs Methods.
58
- # It's a centuries old fight, which won't end soon..
59
- # Functions, being functions, always have a way of telling us about their functionality
60
- # This is done using `func.__code__`
61
- # Methods, being the heigher form of functions, are too proud to have a `__code__` attribute.
62
- # Thus, `"__code__" in method` is false
63
- # However, `method.__code__` exists
64
- # Since it is inherited from the class that initialized the instance who owns the method
65
- # Thus, we reach the important conclusion:
66
- # Methods are shy functions. They are functions, but they don't like telling us that they're functions.
67
- if not callable(func):
68
- raise ClassiqQFuncError("Invalid callable given.")
69
-
70
- if isinstance(func, (FunctionType, MethodType)):
71
- return func, func.__name__ # type: ignore[return-value]
72
-
73
- # Assuming `func` is an instance of some class
74
- return _convert_class_to_function(func) # type: ignore[arg-type]