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,156 +0,0 @@
1
- from typing import Dict, Mapping, Set, Union
2
-
3
- from classiq.interface.generator.function_params import PortDirection
4
- from classiq.interface.generator.functions.core_lib_declarations.quantum_operators import (
5
- APPLY_OPERATOR,
6
- )
7
- from classiq.interface.model.handle_binding import (
8
- HandleBinding,
9
- SlicedHandleBinding,
10
- SubscriptHandleBinding,
11
- )
12
- from classiq.interface.model.port_declaration import PortDeclaration
13
- from classiq.interface.model.quantum_function_call import QuantumFunctionCall
14
- from classiq.interface.model.quantum_lambda_function import (
15
- QuantumLambdaFunction,
16
- QuantumOperand,
17
- )
18
- from classiq.interface.model.quantum_statement import QuantumOperation
19
- from classiq.interface.model.validation_handle import HandleState, ValidationHandle
20
- from classiq.interface.model.validations.handle_validation_base import (
21
- HandleValidationBase,
22
- )
23
- from classiq.interface.model.variable_declaration_statement import (
24
- VariableDeclarationStatement,
25
- )
26
- from classiq.interface.model.within_apply_operation import WithinApplyOperation
27
-
28
- from classiq.exceptions import ClassiqValueError
29
-
30
-
31
- def _initialize_handles_to_state(
32
- port_declarations: Mapping[str, PortDeclaration],
33
- ) -> Dict[str, ValidationHandle]:
34
- handles_to_state: Dict[str, ValidationHandle] = dict()
35
-
36
- for port_decl in port_declarations.values():
37
- handles_to_state[port_decl.name] = ValidationHandle(
38
- initial_state=(
39
- HandleState.INITIALIZED
40
- if port_decl.direction.includes_port_direction(PortDirection.Input)
41
- else HandleState.UNINITIALIZED
42
- )
43
- )
44
-
45
- return handles_to_state
46
-
47
-
48
- class HandleValidator(HandleValidationBase):
49
- def __init__(
50
- self,
51
- port_declarations: Mapping[str, PortDeclaration],
52
- ) -> None:
53
- super().__init__(port_declarations)
54
- self._port_declarations = port_declarations.values()
55
- self._handles_to_state = _initialize_handles_to_state(port_declarations)
56
-
57
- @property
58
- def _validation_handles_state(self) -> Mapping[str, ValidationHandle]:
59
- return self._handles_to_state
60
-
61
- def handle_operation(self, op: QuantumOperation) -> None:
62
- if isinstance(op, QuantumFunctionCall) and op.function == APPLY_OPERATOR.name:
63
- self._handle_apply(op.operands[APPLY_OPERATOR.operand_names[0]])
64
- elif isinstance(op, WithinApplyOperation):
65
- self._handle_apply(op.action)
66
- self._handle_inputs(op.wiring_inputs)
67
- self._handle_outputs(op.wiring_outputs)
68
- self._handle_inouts(op.wiring_inouts)
69
-
70
- def handle_variable_declaration(
71
- self, declaration: VariableDeclarationStatement
72
- ) -> None:
73
- handle_wiring_state = self._handles_to_state.get(declaration.name)
74
- if handle_wiring_state is not None:
75
- handle_wiring_state.append_error(
76
- f"Trying to declare a variable of the same name as previously declared variable {declaration.name}"
77
- )
78
- return
79
-
80
- self._handles_to_state[declaration.name] = ValidationHandle(
81
- HandleState.UNINITIALIZED
82
- )
83
-
84
- def _handle_inputs(self, inputs: Mapping[str, HandleBinding]) -> None:
85
- for handle_binding in inputs.values():
86
- handle_wiring_state = self._handles_to_state[handle_binding.name]
87
- if handle_wiring_state.state is not HandleState.INITIALIZED:
88
- handle_wiring_state.append_error(
89
- f"Trying to access handle {handle_binding.name!r} as input but it is in incorrect state"
90
- )
91
- continue
92
-
93
- handle_wiring_state.uninitialize()
94
-
95
- def _handle_outputs(self, outputs: Mapping[str, HandleBinding]) -> None:
96
- for handle_binding in outputs.values():
97
- handle_wiring_state = self._handles_to_state[handle_binding.name]
98
-
99
- if handle_wiring_state.state is not HandleState.UNINITIALIZED:
100
- handle_wiring_state.append_error(
101
- f"Trying to access handle {handle_binding.name!r} as output but it is in incorrect state"
102
- )
103
- continue
104
-
105
- handle_wiring_state.initialize()
106
-
107
- def _handle_inouts(
108
- self,
109
- inouts: Mapping[
110
- str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
111
- ],
112
- ) -> None:
113
- sliced_handles = set()
114
- whole_handles = set()
115
-
116
- for handle_binding in inouts.values():
117
- handle_wiring_state = self._handles_to_state[handle_binding.name]
118
-
119
- if handle_wiring_state.state is not HandleState.INITIALIZED:
120
- handle_wiring_state.append_error(
121
- f"Trying to access handle {handle_binding.name!r} as inout but it is in incorrect state"
122
- )
123
-
124
- if isinstance(
125
- handle_binding, (SlicedHandleBinding, SubscriptHandleBinding)
126
- ):
127
- sliced_handles.add(handle_binding.name)
128
- else:
129
- whole_handles.add(handle_binding.name)
130
-
131
- for handle in sliced_handles & whole_handles:
132
- self._handles_to_state[handle].append_error(
133
- f"Invalid use of inout handle {handle!r}, used both in slice or subscript and whole"
134
- )
135
-
136
- def _handle_apply(self, operand: QuantumOperand) -> None:
137
- if not isinstance(operand, QuantumLambdaFunction):
138
- return
139
- local_variables: Set[str] = set()
140
- output_capturing_variables: Set[str] = set()
141
- for statement in operand.body:
142
- if isinstance(statement, VariableDeclarationStatement):
143
- local_variables.add(statement.name)
144
- elif isinstance(statement, QuantumOperation):
145
- for handle in statement.wiring_outputs.values():
146
- if (
147
- handle.name in local_variables
148
- or handle.name in output_capturing_variables
149
- ):
150
- continue
151
- output_capturing_variables.add(handle.name)
152
- self._handles_to_state[handle.name].initialize()
153
- else:
154
- raise ClassiqValueError(
155
- f"Unknown statement type {type(statement).__name__}"
156
- )
@@ -1,12 +0,0 @@
1
- import typing
2
- from collections import Counter
3
-
4
-
5
- class PortToWireNameGenerator:
6
- def __init__(self) -> None:
7
- self._name_counter: typing.Counter[str] = Counter()
8
-
9
- def get(self, port_name: str) -> str:
10
- counter = self._name_counter[port_name]
11
- self._name_counter[port_name] += 1
12
- return f"{port_name}_{counter}"
classiq/model/__init__.py DELETED
@@ -1,14 +0,0 @@
1
- from typing import List
2
-
3
- from classiq.interface.generator.model import * # noqa: F403
4
- from classiq.interface.generator.model import __all__ as _model_all
5
-
6
- from classiq.model.composite_function_generator import FunctionGenerator
7
- from classiq.model.model import Model
8
-
9
- __all__ = ["FunctionGenerator", "Model"]
10
- __all__.extend(_model_all)
11
-
12
-
13
- def __dir__() -> List[str]:
14
- return __all__
@@ -1,33 +0,0 @@
1
- from typing import List
2
-
3
- from classiq.interface.generator.function_params import PortDirection
4
- from classiq.interface.generator.functions import SynthesisNativeFunctionDefinition
5
- from classiq.interface.generator.quantum_function_call import (
6
- SynthesisQuantumFunctionCall,
7
- )
8
-
9
- from classiq.model import function_handler
10
- from classiq.quantum_functions.function_library import FunctionLibrary
11
-
12
-
13
- class FunctionGenerator(function_handler.FunctionHandler):
14
- def __init__(self, function_name: str) -> None:
15
- super().__init__()
16
- self._name = function_name
17
- self._logic_flow_list: List[SynthesisQuantumFunctionCall] = list()
18
-
19
- @property
20
- def _body(self) -> List[SynthesisQuantumFunctionCall]:
21
- return self._logic_flow_list
22
-
23
- def to_function_definition(self) -> SynthesisNativeFunctionDefinition:
24
- return SynthesisNativeFunctionDefinition(
25
- name=self._name,
26
- body=self._body,
27
- port_declarations=self._port_declarations,
28
- input_ports_wiring=self._external_port_wiring[PortDirection.Input],
29
- output_ports_wiring=self._external_port_wiring[PortDirection.Output],
30
- )
31
-
32
- def create_library(self) -> None:
33
- self.include_library(FunctionLibrary())
@@ -1,462 +0,0 @@
1
- import abc
2
- import collections.abc
3
- import functools
4
- from typing import (
5
- Any,
6
- Callable,
7
- Collection,
8
- Dict,
9
- Iterable,
10
- List,
11
- Mapping,
12
- Optional,
13
- Tuple,
14
- Union,
15
- cast,
16
- )
17
-
18
- from classiq.interface.generator import function_param_list, function_params
19
- from classiq.interface.generator.control_state import ControlState
20
- from classiq.interface.generator.function_params import IOName, PortDirection
21
- from classiq.interface.generator.functions.port_declaration import (
22
- PortDeclarationDirection,
23
- SynthesisPortDeclaration,
24
- )
25
- from classiq.interface.generator.identity import Identity
26
- from classiq.interface.generator.quantum_function_call import (
27
- SynthesisQuantumFunctionCall,
28
- WireDict,
29
- )
30
- from classiq.interface.generator.slice_parsing_utils import parse_io_slicing
31
- from classiq.interface.generator.user_defined_function_params import CustomFunction
32
-
33
- from classiq.exceptions import ClassiqValueError, ClassiqWiringError
34
- from classiq.model import logic_flow_change_handler
35
- from classiq.model.logic_flow import LogicFlowBuilder
36
- from classiq.quantum_functions.function_library import (
37
- FunctionLibrary,
38
- QuantumFunction,
39
- SynthesisQuantumFunctionDeclaration,
40
- )
41
- from classiq.quantum_register import QReg, QRegGenericAlias
42
-
43
- SupportedInputArgs = Union[
44
- Mapping[IOName, QReg],
45
- Collection[QReg],
46
- QReg,
47
- ]
48
-
49
- _SAME_INPUT_NAME_ERROR_MSG: str = "Cannot create multiple inputs with the same name"
50
- _INPUT_AS_OUTPUT_ERROR_MSG: str = "Can't connect input directly to output"
51
- ILLEGAL_INPUT_OR_SLICING_ERROR_MSG: str = "is not a valid input name/slice"
52
- ILLEGAL_OUTPUT_ERROR_MSG: str = "Illegal output provided"
53
-
54
- ASSIGNED = "_assigned_"
55
-
56
-
57
- def _get_identity_call_name(name: str, io: PortDirection) -> str:
58
- return f"{name}_{io.value}_Identity"
59
-
60
-
61
- class FunctionHandler(abc.ABC):
62
- def __init__(self) -> None:
63
- self._function_library: Optional[FunctionLibrary] = None
64
- self._port_declarations: Dict[IOName, SynthesisPortDeclaration] = dict()
65
- self._external_port_wiring: Dict[PortDirection, WireDict] = {
66
- PortDirection.Input: dict(),
67
- PortDirection.Output: dict(),
68
- }
69
- self._generated_qregs: Dict[IOName, QReg] = dict()
70
- self._logic_flow_builder: LogicFlowBuilder = LogicFlowBuilder()
71
-
72
- @property
73
- def input_wires(self) -> WireDict:
74
- return self._external_port_wiring[PortDirection.Input]
75
-
76
- @property
77
- def output_wires(self) -> WireDict:
78
- return self._external_port_wiring[PortDirection.Output]
79
-
80
- def _verify_unique_inputs(self, input_names: Iterable[IOName]) -> None:
81
- input_port_declarations = {
82
- name: port_declaration
83
- for name, port_declaration in self._port_declarations.items()
84
- if port_declaration.direction.is_input
85
- }
86
- if not input_port_declarations.keys().isdisjoint(input_names):
87
- raise ClassiqWiringError(_SAME_INPUT_NAME_ERROR_MSG)
88
-
89
- def _verify_no_inputs_as_outputs(self, output_qregs: Iterable[QReg]) -> None:
90
- for qreg in output_qregs:
91
- if any(
92
- qreg.isoverlapping(gen_qreg)
93
- for gen_qreg in self._generated_qregs.values()
94
- ):
95
- raise ClassiqWiringError(f"{_INPUT_AS_OUTPUT_ERROR_MSG} {qreg}")
96
-
97
- @staticmethod
98
- def _parse_control_states(
99
- control_states: Optional[Union[ControlState, Iterable[ControlState]]] = None
100
- ) -> List[ControlState]:
101
- if control_states is None:
102
- return list()
103
- elif isinstance(control_states, ControlState):
104
- return [control_states]
105
- return list(control_states)
106
-
107
- def create_inputs(
108
- self,
109
- inputs: Mapping[IOName, QRegGenericAlias],
110
- ) -> Dict[IOName, QReg]:
111
- self._verify_unique_inputs(inputs.keys())
112
- qregs_dict = {
113
- name: self._create_input_with_identity(name, qreg_type)
114
- for name, qreg_type in inputs.items()
115
- }
116
- self._generated_qregs.update(qregs_dict)
117
- return qregs_dict
118
-
119
- def _create_input_with_identity(
120
- self, name: IOName, qreg_type: QRegGenericAlias
121
- ) -> QReg:
122
- qreg = qreg_type()
123
- self._handle_io_with_identity(PortDirection.Input, name, qreg)
124
- return qreg
125
-
126
- def set_outputs(self, outputs: Mapping[IOName, QReg]) -> None:
127
- for name, qreg in outputs.items():
128
- self._set_output_with_identity(name, qreg)
129
-
130
- def _set_output_with_identity(self, name: IOName, qreg: QReg) -> None:
131
- self._handle_io_with_identity(PortDirection.Output, name, qreg)
132
-
133
- def _handle_io_with_identity(
134
- self, port_direction: PortDirection, name: IOName, qreg: QReg
135
- ) -> None:
136
- # We need to add an Identity call on each input/output of the logic flow,
137
- # since function input/output pins don't support "pin slicing".
138
- # (Which means we cannot use QRegs in the wiring directly - because it gets
139
- # decomposed into 1 bit wirings).
140
- # Adding the identity also indirectly adds support for slicing on IOs
141
- # (via the QReg slicing).
142
- rui = qreg.to_register_user_input(name)
143
- identity_call = SynthesisQuantumFunctionCall(
144
- name=_get_identity_call_name(name, port_direction),
145
- function_params=Identity(arguments=[rui]),
146
- )
147
- self._body.append(identity_call)
148
- wire_name = logic_flow_change_handler.handle_io_connection(
149
- port_direction, identity_call, name
150
- )
151
- if port_direction == PortDirection.Input:
152
- self._logic_flow_builder.connect_func_call_to_qreg(
153
- identity_call, name, qreg
154
- )
155
- else:
156
- self._logic_flow_builder.connect_qreg_to_func_call(
157
- qreg, name, identity_call
158
- )
159
- declaration_direction = PortDeclarationDirection.from_port_direction(
160
- port_direction
161
- )
162
- if (
163
- name in self._port_declarations
164
- and self._port_declarations[name].direction != declaration_direction
165
- ):
166
- declaration_direction = PortDeclarationDirection.Inout
167
- self._port_declarations[name] = SynthesisPortDeclaration(
168
- name=name,
169
- size=rui.size,
170
- direction=declaration_direction,
171
- )
172
- external_port_wiring_dict = dict(self._external_port_wiring[port_direction])
173
- external_port_wiring_dict[name] = wire_name
174
- self._external_port_wiring[port_direction] = external_port_wiring_dict
175
-
176
- def apply(
177
- self,
178
- function_name: Union[
179
- str,
180
- SynthesisQuantumFunctionDeclaration,
181
- QuantumFunction,
182
- ],
183
- in_wires: Optional[SupportedInputArgs] = None,
184
- out_wires: Optional[SupportedInputArgs] = None,
185
- is_inverse: bool = False,
186
- strict_zero_ios: bool = True,
187
- release_by_inverse: bool = False,
188
- control_states: Optional[Union[ControlState, Iterable[ControlState]]] = None,
189
- should_control: bool = True,
190
- power: int = 1,
191
- call_name: Optional[str] = None,
192
- ) -> Dict[IOName, QReg]:
193
- # if there's no function library, create one
194
- if self._function_library is None:
195
- self.create_library()
196
-
197
- if isinstance(function_name, SynthesisQuantumFunctionDeclaration):
198
- function_data = function_name
199
- elif isinstance(function_name, QuantumFunction):
200
- function_data = function_name.function_data
201
- else:
202
- function_data = None
203
-
204
- if function_data:
205
- if function_data.name not in self._function_library.function_dict: # type: ignore[union-attr]
206
- self._function_library.add_function(function_data) # type: ignore[union-attr]
207
-
208
- function_name = function_data.name
209
-
210
- function_name = cast(str, function_name)
211
- return self._add_function_call(
212
- function_name,
213
- self._function_library.get_function(function_name), # type: ignore[union-attr]
214
- in_wires=in_wires,
215
- out_wires=out_wires,
216
- is_inverse=is_inverse,
217
- strict_zero_ios=strict_zero_ios,
218
- release_by_inverse=release_by_inverse,
219
- control_states=control_states,
220
- should_control=should_control,
221
- power=power,
222
- call_name=call_name,
223
- )
224
-
225
- def release_qregs(self, qregs: Union[QReg, Collection[QReg]]) -> None:
226
- if isinstance(qregs, QReg):
227
- qregs = [qregs]
228
- for qreg in qregs:
229
- self._logic_flow_builder.connect_qreg_to_zero(qreg)
230
-
231
- def _add_function_call(
232
- self,
233
- function: str,
234
- params: function_params.FunctionParams,
235
- control_states: Optional[Union[ControlState, Iterable[ControlState]]] = None,
236
- in_wires: Optional[SupportedInputArgs] = None,
237
- out_wires: Optional[SupportedInputArgs] = None,
238
- is_inverse: bool = False,
239
- release_by_inverse: bool = False,
240
- should_control: bool = True,
241
- power: int = 1,
242
- call_name: Optional[str] = None,
243
- strict_zero_ios: bool = True,
244
- ) -> Dict[IOName, QReg]:
245
- if function != type(params).__name__ and not isinstance(params, CustomFunction):
246
- raise ClassiqValueError(
247
- "The FunctionParams type does not match function name"
248
- )
249
-
250
- if (
251
- isinstance(params, CustomFunction)
252
- and self._function_library
253
- and function not in self._function_library.function_dict
254
- ):
255
- raise ClassiqValueError(
256
- "QuantumFunctionCall: The function is not found in included library."
257
- )
258
-
259
- call = SynthesisQuantumFunctionCall(
260
- function=function,
261
- function_params=params,
262
- is_inverse=is_inverse,
263
- release_by_inverse=release_by_inverse,
264
- strict_zero_ios=strict_zero_ios,
265
- control_states=self._parse_control_states(control_states),
266
- should_control=should_control,
267
- power=power,
268
- name=call_name,
269
- )
270
-
271
- if in_wires is not None:
272
- self._connect_in_qregs(call=call, in_wires=in_wires)
273
-
274
- self._body.append(call)
275
-
276
- return self._connect_out_qregs(call=call, out_wires=out_wires or {})
277
-
278
- def _connect_in_qregs(
279
- self,
280
- call: SynthesisQuantumFunctionCall,
281
- in_wires: SupportedInputArgs,
282
- ) -> None:
283
- if isinstance(in_wires, dict):
284
- self._connect_named_in_qregs(call=call, in_wires=in_wires)
285
- elif isinstance(in_wires, QReg):
286
- self._connect_unnamed_in_qregs(call=call, in_wires=[in_wires])
287
- elif isinstance(in_wires, collections.abc.Collection):
288
- self._connect_unnamed_in_qregs(
289
- # mypy doesn't recognize that `dict` wouldn't reach this point
290
- call=call,
291
- in_wires=in_wires, # type: ignore[arg-type]
292
- )
293
- else:
294
- raise ClassiqWiringError(
295
- f"Invalid in_wires type: {type(in_wires).__name__}"
296
- )
297
-
298
- def _connect_unnamed_in_qregs(
299
- self,
300
- call: SynthesisQuantumFunctionCall,
301
- in_wires: Collection[QReg],
302
- ) -> None:
303
- call_inputs = call.function_params.inputs_full(call.strict_zero_ios).keys()
304
- self._connect_named_in_qregs(call, dict(zip(call_inputs, in_wires)))
305
-
306
- def _connect_named_in_qregs(
307
- self,
308
- call: SynthesisQuantumFunctionCall,
309
- in_wires: Dict[IOName, QReg],
310
- ) -> None:
311
- for input_name, in_qreg in in_wires.items():
312
- pin_name, pin_indices = self._get_pin_name_and_indices(input_name, call)
313
- if len(in_qreg) != len(pin_indices):
314
- raise ClassiqWiringError(
315
- f"Incorrect size of input QReg: expected {len(pin_indices)}, actual {len(in_qreg)}"
316
- )
317
- self._logic_flow_builder.connect_qreg_to_func_call(
318
- in_qreg, pin_name, call, pin_indices
319
- )
320
-
321
- @staticmethod
322
- def _get_pin_name_and_indices(
323
- input_name: IOName,
324
- call: SynthesisQuantumFunctionCall,
325
- ) -> Tuple[IOName, range]:
326
- try:
327
- name, slicing = parse_io_slicing(input_name)
328
- except (AssertionError, ValueError) as e:
329
- raise ClassiqWiringError(
330
- f"{input_name} {ILLEGAL_INPUT_OR_SLICING_ERROR_MSG}"
331
- ) from e
332
- pin_info = call.input_regs_dict.get(name)
333
- if pin_info is None:
334
- raise ClassiqWiringError(
335
- f"No register size information on input pin {name}"
336
- )
337
- indices = range(pin_info.size)[slicing]
338
- return name, indices
339
-
340
- def _connect_out_qregs(
341
- self,
342
- call: SynthesisQuantumFunctionCall,
343
- out_wires: SupportedInputArgs,
344
- ) -> Dict[IOName, QReg]:
345
- if isinstance(out_wires, dict):
346
- return self._connect_named_out_qregs(call, out_wires)
347
- elif isinstance(out_wires, QReg):
348
- return self._connect_unnamed_out_qregs(call, [out_wires])
349
- elif isinstance(out_wires, collections.abc.Collection):
350
- return self._connect_unnamed_out_qregs(
351
- # mypy doesn't recognize that `dict` wouldn't reach this point
352
- call,
353
- out_wires, # type: ignore[arg-type]
354
- )
355
- else:
356
- raise ClassiqWiringError(
357
- f"Invalid in_wires type: {type(out_wires).__name__}"
358
- )
359
-
360
- def _connect_unnamed_out_qregs(
361
- self,
362
- call: SynthesisQuantumFunctionCall,
363
- out_wires: Collection[QReg],
364
- ) -> Dict[IOName, QReg]:
365
- call_outputs = call.function_params.outputs.keys()
366
- return self._connect_named_out_qregs(call, dict(zip(call_outputs, out_wires)))
367
-
368
- def _connect_named_out_qregs(
369
- self,
370
- call: SynthesisQuantumFunctionCall,
371
- out_wires: Mapping[IOName, QReg],
372
- ) -> Dict[IOName, QReg]:
373
- if not all(output_name in call.output_regs_dict for output_name in out_wires):
374
- raise ClassiqWiringError(ILLEGAL_OUTPUT_ERROR_MSG)
375
- output_dict = {}
376
- for output_name, reg_user_input in call.output_regs_dict.items():
377
- if reg_user_input is None:
378
- raise ClassiqValueError(
379
- f"No output register information for {output_name}"
380
- )
381
- qreg = out_wires.get(output_name) or QReg.from_arithmetic_info(
382
- reg_user_input
383
- )
384
- self._logic_flow_builder.connect_func_call_to_qreg(call, output_name, qreg)
385
- output_dict[output_name] = qreg
386
- return output_dict
387
-
388
- def __getattr__(self, item: str) -> Callable[..., Any]:
389
- # This is added due to problematic behaviour in deepcopy.
390
- # deepcopy approaches __getattr__ before __init__ is called,
391
- # and therefore self._function_library doesn't exist.
392
- # Thus, we treat _function_library differently.
393
-
394
- if item == "_function_library":
395
- raise AttributeError(
396
- f"{self.__class__.__name__!r} has no attribute {item!r}"
397
- )
398
-
399
- is_builtin_function_name = any(
400
- item == func.__name__
401
- for func in function_param_list.function_param_library.param_list
402
- )
403
-
404
- if is_builtin_function_name:
405
- return functools.partial(self._add_function_call, item)
406
-
407
- is_user_function_name = (
408
- self._function_library is not None
409
- and item in self._function_library.function_names
410
- )
411
-
412
- if is_user_function_name:
413
- return functools.partial(self.apply, item)
414
-
415
- if (
416
- self._function_library is not None
417
- and item in self._function_library.function_factory_names
418
- ):
419
- return functools.partial(
420
- self._function_library.get_function_factory(item),
421
- add_method=functools.partial(
422
- self._function_library.add_function,
423
- override_existing_functions=True,
424
- ),
425
- apply_method=self.apply,
426
- )
427
-
428
- raise AttributeError(f"{self.__class__.__name__!r} has no attribute {item!r}")
429
-
430
- def __dir__(self) -> List[str]:
431
- builtin_func_name = [
432
- func.__name__
433
- for func in function_param_list.function_param_library.param_list
434
- ]
435
- user_func_names = (
436
- list(self._function_library.function_names)
437
- if self._function_library is not None
438
- else list()
439
- )
440
- return list(super().__dir__()) + builtin_func_name + user_func_names
441
-
442
- def include_library(self, library: FunctionLibrary) -> None:
443
- """Includes a function library.
444
-
445
- Args:
446
- library (FunctionLibrary): The function library.
447
- """
448
- if self._function_library is not None:
449
- raise ClassiqValueError("Another function library is already included.")
450
-
451
- self._function_library = library
452
-
453
- @property
454
- @abc.abstractmethod
455
- def _body(
456
- self,
457
- ) -> List[SynthesisQuantumFunctionCall]:
458
- pass
459
-
460
- @abc.abstractmethod
461
- def create_library(self) -> None:
462
- pass