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,10 +1,13 @@
1
1
  import itertools
2
2
  from collections import defaultdict
3
- from typing import Any, Dict, List, MutableSet, Optional
3
+ from collections.abc import MutableSet
4
+ from typing import Any, Optional
4
5
 
5
6
  import pydantic
7
+ from typing_extensions import Self
6
8
 
7
9
  from classiq.interface.backend.backend_preferences import BackendPreferences
10
+ from classiq.interface.exceptions import ClassiqValueError
8
11
  from classiq.interface.generator.transpiler_basis_gates import (
9
12
  DEFAULT_BASIS_GATES,
10
13
  DEFAULT_ROUTING_BASIS_GATES,
@@ -14,14 +17,32 @@ from classiq.interface.generator.transpiler_basis_gates import (
14
17
  )
15
18
  from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
16
19
 
17
- ConnectivityMap = List[PydanticNonNegIntTuple]
20
+ ConnectivityMap = list[PydanticNonNegIntTuple]
18
21
  BACKEND_VALIDATION_ERROR_MESSAGE = (
19
22
  "Backend service provider and backend name should be specified together."
20
23
  )
21
24
 
22
25
 
23
26
  class HardwareData(pydantic.BaseModel):
24
- basis_gates: List[str] = pydantic.Field(
27
+ """
28
+ Hardware-specific settings used in quantum circuit synthesis,
29
+ including basis gates, connectivity map, and connectivity symmetry.
30
+
31
+ Attributes:
32
+ basis_gates (List[str]):
33
+ The basis gates of the hardware, used during model optimization.
34
+ If not provided, default values are used based on the connectivity map's symmetry.
35
+
36
+ connectivity_map(Optional[ConnectivityMap]):
37
+ The qubit connectivity map, defined as a list of qubit pairs [[q0, q1], [q1, q2],...].
38
+ If not provided, the hardware is assumed to be fully connected.
39
+
40
+ is_symmetric_connectivity(bool):
41
+ Indicates whether the coupling map forms an undirected graph, meaning
42
+ that both qubits in each pair can act as control and target. Defaults to True.
43
+ """
44
+
45
+ basis_gates: list[str] = pydantic.Field(
25
46
  default=list(),
26
47
  description="The basis gates of the hardware. "
27
48
  "This set will be used during the model optimization. "
@@ -41,73 +62,79 @@ class HardwareData(pydantic.BaseModel):
41
62
  "If false, the first / second qubit denotes the control / target, respectively",
42
63
  )
43
64
 
44
- @pydantic.validator("connectivity_map")
65
+ @pydantic.field_validator("connectivity_map")
66
+ @classmethod
45
67
  def _validate_connectivity_map(
46
68
  cls, connectivity_map: Optional[ConnectivityMap]
47
69
  ) -> Optional[ConnectivityMap]:
48
70
  if connectivity_map is None:
49
71
  return connectivity_map
50
72
  if not connectivity_map:
51
- raise ValueError("Connectivity map cannot be empty")
73
+ raise ClassiqValueError("Connectivity map cannot be empty")
52
74
  connectivity_map = _reindex_qubits(connectivity_map)
53
75
  return connectivity_map
54
76
 
55
- @pydantic.root_validator()
56
- def _symmetrize_connectivity_map(cls, values: Dict[str, Any]) -> Dict[str, Any]:
57
- connectivity_map = values.get("connectivity_map")
77
+ @pydantic.model_validator(mode="after")
78
+ def _symmetrize_connectivity_map(self) -> Self:
79
+ connectivity_map = self.connectivity_map
58
80
  if connectivity_map is None:
59
- return values
81
+ return self
60
82
 
61
- is_symmetric = values.get("is_symmetric_connectivity")
83
+ is_symmetric = self.is_symmetric_connectivity
62
84
  if is_symmetric:
63
85
  connectivity_map = _symmetrize_connectivity_map(connectivity_map)
64
- values["connectivity_map"] = connectivity_map
86
+ self.connectivity_map = connectivity_map
65
87
 
66
88
  if not _is_connected_map(connectivity_map):
67
- raise ValueError(
89
+ raise ClassiqValueError(
68
90
  f"Connectivity map must be connected: {connectivity_map} is not connected."
69
91
  )
70
- return values
92
+ return self
71
93
 
72
- @pydantic.root_validator()
73
- def _validate_basis_gates(cls, values: Dict[str, Any]) -> Dict[str, Any]:
74
- connectivity_map = values.get("connectivity_map")
75
- specified_basis_gates = values.get("basis_gates", [])
94
+ @pydantic.model_validator(mode="after")
95
+ def _validate_basis_gates(self) -> Self:
96
+ connectivity_map = self.connectivity_map
97
+ specified_basis_gates = self.basis_gates
76
98
  if connectivity_map is None:
77
- values["basis_gates"] = specified_basis_gates or list(DEFAULT_BASIS_GATES)
78
- return values
99
+ self.basis_gates = specified_basis_gates or list(DEFAULT_BASIS_GATES)
100
+ return self
79
101
 
80
- is_symmetric_connectivity = values.get("is_symmetric")
102
+ is_symmetric_connectivity = self.is_symmetric_connectivity
81
103
  if is_symmetric_connectivity or _check_symmetry(connectivity_map):
82
- values["basis_gates"] = specified_basis_gates or list(DEFAULT_BASIS_GATES)
83
- return values
104
+ self.basis_gates = specified_basis_gates or list(DEFAULT_BASIS_GATES)
105
+ return self
84
106
 
85
- values["basis_gates"] = specified_basis_gates or list(
86
- DEFAULT_ROUTING_BASIS_GATES
87
- )
107
+ self.basis_gates = specified_basis_gates or list(DEFAULT_ROUTING_BASIS_GATES)
88
108
  invalid_gates = [
89
109
  gate
90
110
  for gate in specified_basis_gates
91
111
  if gate in TWO_QUBIT_GATES and gate not in ROUTING_TWO_QUBIT_BASIS_GATES
92
112
  ]
93
113
  if invalid_gates:
94
- raise ValueError(
114
+ raise ClassiqValueError(
95
115
  "Connectivity-aware synthesis with non-symmetric coupling map "
96
116
  "is currently supported for the following two-qubit gates only: cx, ecr, rzx."
97
117
  )
98
118
 
99
- return values
119
+ return self
100
120
 
101
121
 
102
122
  class CustomHardwareSettings(HardwareData):
123
+ """
124
+ Custom hardware settings for quantum circuit synthesis.
125
+ This class inherits from HardwareData (please see class for more details)
126
+
127
+ """
128
+
103
129
  _width: Optional[int] = pydantic.PrivateAttr(default=None)
104
130
 
105
- @pydantic.validator("basis_gates")
106
- def validate_basis_gates(cls, basis_gates: List[str]) -> List[TranspilerBasisGates]:
131
+ @pydantic.field_validator("basis_gates", mode="after")
132
+ @classmethod
133
+ def validate_basis_gates(cls, basis_gates: list[str]) -> list[TranspilerBasisGates]:
107
134
  valid_gates = list(TranspilerBasisGates)
108
135
  invalid_gates = [gate for gate in basis_gates if gate not in valid_gates]
109
136
  if invalid_gates:
110
- raise ValueError(
137
+ raise ClassiqValueError(
111
138
  "Invalid gates for hardware-aware synthesis: " + str(invalid_gates)
112
139
  )
113
140
 
@@ -128,7 +155,7 @@ class CustomHardwareSettings(HardwareData):
128
155
 
129
156
  def _is_connected_map(connectivity_map: ConnectivityMap) -> bool:
130
157
  nodes: MutableSet[int] = set()
131
- node_to_neighbors: Dict[int, MutableSet[int]] = defaultdict(set)
158
+ node_to_neighbors: dict[int, MutableSet[int]] = defaultdict(set)
132
159
  for edge in connectivity_map:
133
160
  nodes.add(edge[0])
134
161
  nodes.add(edge[1])
@@ -141,7 +168,7 @@ def _is_connected_map(connectivity_map: ConnectivityMap) -> bool:
141
168
 
142
169
 
143
170
  def _node_dfs(
144
- node: int, node_to_neighbors: Dict[int, MutableSet[int]], visited: MutableSet[int]
171
+ node: int, node_to_neighbors: dict[int, MutableSet[int]], visited: MutableSet[int]
145
172
  ) -> None:
146
173
  visited.add(node)
147
174
  neighbors = node_to_neighbors[node]
@@ -154,7 +181,7 @@ def _node_dfs(
154
181
 
155
182
  def _reindex_qubits(connectivity_map: ConnectivityMap) -> ConnectivityMap:
156
183
  qubits = sorted({q for pair in connectivity_map for q in pair})
157
- return [(qubits.index(pair[0]), qubits.index(pair[1])) for pair in connectivity_map]
184
+ return [[qubits.index(pair[0]), qubits.index(pair[1])] for pair in connectivity_map]
158
185
 
159
186
 
160
187
  def _check_symmetry(connectivity_map: ConnectivityMap) -> bool:
@@ -166,17 +193,30 @@ def _symmetrize_connectivity_map(connectivity_map: ConnectivityMap) -> Connectiv
166
193
  # A more complicated implementation than using set to maintain the order
167
194
  connectivity_map_no_duplicates = []
168
195
  for edge in connectivity_map:
169
- reversed_edge = (edge[1], edge[0])
196
+ reversed_edge = [edge[1], edge[0]]
170
197
  if (
171
198
  edge not in connectivity_map_no_duplicates
172
199
  and reversed_edge not in connectivity_map_no_duplicates
173
200
  ):
174
201
  connectivity_map_no_duplicates.append(edge)
175
202
  reversed_connectivity_map = [
176
- (edge[1], edge[0]) for edge in connectivity_map_no_duplicates
203
+ [edge[1], edge[0]] for edge in connectivity_map_no_duplicates
177
204
  ]
178
205
  return connectivity_map_no_duplicates + reversed_connectivity_map
179
206
 
180
207
 
181
208
  class SynthesisHardwareData(HardwareData):
182
- backend_data: Optional[BackendPreferences]
209
+ """
210
+ Represents the synthesis-specific hardware data for a quantum circuit.
211
+
212
+ This class extends `HardwareData` and includes additional attributes that
213
+ pertain specifically to the hardware used during the synthesis of a quantum circuit.
214
+
215
+ Attributes:
216
+ backend_data (Optional[BackendPreferences]):
217
+ Preferences for the backend used during the synthesis process.
218
+ This can include specific backend configurations or settings.
219
+ Defaults to `None`.
220
+ """
221
+
222
+ backend_data: Optional[BackendPreferences] = pydantic.Field(default=None)
@@ -1,8 +1,11 @@
1
1
  import itertools
2
- from typing import List, Union
2
+ from typing import TYPE_CHECKING, Optional, Union
3
3
 
4
4
  import pydantic
5
+ from pydantic_core.core_schema import ValidationInfo
5
6
 
7
+ from classiq.interface.enum_utils import StrEnum
8
+ from classiq.interface.exceptions import ClassiqValueError
6
9
  from classiq.interface.generator import function_params
7
10
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
8
11
  from classiq.interface.generator.function_params import (
@@ -15,9 +18,7 @@ from classiq.interface.generator.transpiler_basis_gates import (
15
18
  )
16
19
  from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
17
20
 
18
- from classiq._internals.enum_utils import StrEnum
19
-
20
- ConnectivityMap = List[PydanticNonNegIntTuple]
21
+ ConnectivityMap = list[PydanticNonNegIntTuple]
21
22
 
22
23
 
23
24
  class SupportedConnectivityMaps(StrEnum):
@@ -44,16 +45,17 @@ class HardwareEfficientAnsatz(function_params.FunctionParams):
44
45
  num_qubits: pydantic.PositiveInt = pydantic.Field(
45
46
  default=None,
46
47
  description="Number of qubits in the ansatz.",
48
+ validate_default=True,
47
49
  )
48
50
  reps: pydantic.PositiveInt = pydantic.Field(
49
51
  default=1, description="Number of layers in the Ansatz"
50
52
  )
51
53
 
52
- one_qubit_gates: Union[str, List[str]] = pydantic.Field(
54
+ one_qubit_gates: Union[str, list[str]] = pydantic.Field(
53
55
  default=["x", "ry"],
54
56
  description='List of gates for the one qubit gates layer, e.g. ["x", "ry"]',
55
57
  )
56
- two_qubit_gates: Union[str, List[str]] = pydantic.Field(
58
+ two_qubit_gates: Union[str, list[str]] = pydantic.Field(
57
59
  default=["cx"],
58
60
  description='List of gates for the two qubit gates entangling layer, e.g. ["cx", "cry"]',
59
61
  )
@@ -62,51 +64,70 @@ class HardwareEfficientAnsatz(function_params.FunctionParams):
62
64
  description="Prefix for the generated parameters",
63
65
  )
64
66
 
65
- @pydantic.validator("num_qubits", pre=True, always=True)
66
- def validate_num_qubits(cls, num_qubits, values):
67
- connectivity_map = values.get("connectivity_map")
67
+ @pydantic.field_validator("num_qubits", mode="before")
68
+ @classmethod
69
+ def validate_num_qubits(
70
+ cls, num_qubits: Optional[pydantic.PositiveInt], info: ValidationInfo
71
+ ) -> pydantic.PositiveInt:
72
+ connectivity_map = info.data.get("connectivity_map")
68
73
  conn_map_is_not_list = (
69
74
  isinstance(connectivity_map, SupportedConnectivityMaps)
70
75
  or connectivity_map is None
71
76
  )
72
77
 
73
78
  if num_qubits is None and conn_map_is_not_list:
74
- raise ValueError(_NUM_QUBITS_NOT_PROVIDED_ERROR)
79
+ raise ClassiqValueError(_NUM_QUBITS_NOT_PROVIDED_ERROR)
75
80
  if num_qubits is None:
81
+ if conn_map_is_not_list:
82
+ raise ValueError(_NUM_QUBITS_NOT_PROVIDED_ERROR)
83
+
84
+ if TYPE_CHECKING:
85
+ assert connectivity_map is not None
86
+
76
87
  return len(set(itertools.chain.from_iterable(connectivity_map)))
88
+
77
89
  if conn_map_is_not_list:
78
90
  return num_qubits
79
91
 
92
+ if TYPE_CHECKING:
93
+ assert connectivity_map is not None
94
+
80
95
  invalid_qubits = {
81
96
  qubit
82
97
  for qubit in itertools.chain.from_iterable(connectivity_map)
83
98
  if qubit >= num_qubits
84
99
  }
85
100
  if invalid_qubits:
86
- raise ValueError(
101
+ raise ClassiqValueError(
87
102
  f"Invalid qubits: {invalid_qubits} "
88
103
  f"out of range specified by num_qubits: [0, {num_qubits - 1}]"
89
104
  )
90
105
  return num_qubits
91
106
 
92
- @pydantic.validator("one_qubit_gates")
93
- def validate_one_qubit_gates(cls, one_qubit_gates):
107
+ @pydantic.field_validator("one_qubit_gates")
108
+ @classmethod
109
+ def validate_one_qubit_gates(
110
+ cls, one_qubit_gates: Union[str, list[str]]
111
+ ) -> Union[str, list[str]]:
94
112
  one_qubit_gates_list = (
95
113
  [one_qubit_gates] if isinstance(one_qubit_gates, str) else one_qubit_gates
96
114
  )
97
115
  for one_qubit_gate in one_qubit_gates_list:
98
116
  if one_qubit_gate not in SINGLE_QUBIT_GATES:
99
- raise ValueError(f"Invalid one qubit gate: {one_qubit_gate}")
117
+ raise ClassiqValueError(f"Invalid one qubit gate: {one_qubit_gate}")
100
118
  return one_qubit_gates
101
119
 
102
- @pydantic.validator("two_qubit_gates")
103
- def validate_two_qubit_gates(cls, two_qubit_gates):
120
+ @pydantic.field_validator("two_qubit_gates")
121
+ @classmethod
122
+ def validate_two_qubit_gates(
123
+ cls, two_qubit_gates: Union[str, list[str]]
124
+ ) -> Union[str, list[str]]:
104
125
  two_qubit_gates_list = (
105
126
  [two_qubit_gates] if isinstance(two_qubit_gates, str) else two_qubit_gates
106
127
  )
107
128
  for two_qubit_gate in two_qubit_gates_list:
108
129
  if two_qubit_gate not in TWO_QUBIT_GATES:
109
- raise ValueError(f"Invalid two qubit gate: {two_qubit_gate}")
130
+ raise ClassiqValueError(f"Invalid two qubit gate: {two_qubit_gate}")
110
131
  return two_qubit_gates
111
132
 
112
133
  def _create_ios(self) -> None:
@@ -1,16 +1,26 @@
1
+ from typing import Any, Union
2
+
1
3
  import pydantic
2
4
 
3
- from classiq.interface.chemistry.ground_state_problem import CHEMISTRY_PROBLEMS
5
+ from classiq.interface.chemistry.ground_state_problem import (
6
+ CHEMISTRY_PROBLEMS,
7
+ HamiltonianProblem,
8
+ MoleculeProblem,
9
+ )
10
+ from classiq.interface.exceptions import ClassiqValueError
4
11
  from classiq.interface.generator.chemistry_function_params import (
5
12
  ChemistryFunctionParams,
6
13
  )
7
14
 
8
15
 
9
16
  class HartreeFock(ChemistryFunctionParams):
10
- @pydantic.validator("gs_problem")
11
- def validate_gs_problem(cls, gs_problem):
17
+ @pydantic.field_validator("gs_problem")
18
+ @classmethod
19
+ def validate_gs_problem(
20
+ cls, gs_problem: Any
21
+ ) -> Union[MoleculeProblem, HamiltonianProblem]:
12
22
  if not isinstance(gs_problem, CHEMISTRY_PROBLEMS):
13
- raise ValueError(
23
+ raise ClassiqValueError(
14
24
  f"ground state problem must be of type {CHEMISTRY_PROBLEMS}"
15
25
  )
16
26
  return gs_problem
@@ -1,14 +1,17 @@
1
- from typing import TYPE_CHECKING, List
1
+ from typing import TYPE_CHECKING, Annotated
2
2
 
3
3
  import pydantic
4
+ from pydantic import Field
4
5
 
5
6
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
6
7
  from classiq.interface.generator.function_params import FunctionParams
7
8
 
8
9
  if TYPE_CHECKING:
9
- NonEmptyRegisterUserInputList = List[RegisterUserInput]
10
+ NonEmptyRegisterUserInputList = list[RegisterUserInput]
10
11
  else:
11
- NonEmptyRegisterUserInputList = pydantic.conlist(RegisterUserInput, min_items=1)
12
+ NonEmptyRegisterUserInputList = Annotated[
13
+ list[RegisterUserInput], Field(min_length=1)
14
+ ]
12
15
 
13
16
 
14
17
  class Identity(FunctionParams):
@@ -16,10 +19,11 @@ class Identity(FunctionParams):
16
19
  description="registers describing the state (ordered)"
17
20
  )
18
21
 
19
- @pydantic.validator("arguments")
22
+ @pydantic.field_validator("arguments")
23
+ @classmethod
20
24
  def _validate_argument_names(
21
- cls, arguments: List[RegisterUserInput]
22
- ) -> List[RegisterUserInput]:
25
+ cls, arguments: list[RegisterUserInput]
26
+ ) -> list[RegisterUserInput]:
23
27
  return [
24
28
  arg if arg.name else arg.revalued(name=cls._get_default_arg_name(index))
25
29
  for index, arg in enumerate(arguments)
@@ -1,22 +1,28 @@
1
- from typing import TYPE_CHECKING, Any, Dict, List
1
+ from typing import TYPE_CHECKING, Annotated, Any
2
2
 
3
3
  import pydantic
4
+ from pydantic import StringConstraints
5
+ from typing_extensions import Self
4
6
 
7
+ from classiq.interface.exceptions import ClassiqValueError
5
8
  from classiq.interface.generator import function_params
6
9
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
7
10
 
8
11
  STATE = "state"
9
12
  TARGET = "target"
10
13
 
11
- LENGTH_ERROR_MESSAGE = "Slopes, offsets and basis values must have the same length"
14
+ LENGTH_ERROR_MESSAGE = "Field required"
12
15
 
13
16
  if TYPE_CHECKING:
14
17
  PydanticPauliBasisStr = str
15
18
  else:
16
- PydanticPauliBasisStr = pydantic.constr(
17
- to_lower=True,
18
- regex=r"[xyz]",
19
- )
19
+ PydanticPauliBasisStr = Annotated[
20
+ str,
21
+ StringConstraints(
22
+ to_lower=True,
23
+ pattern=r"[xyz]",
24
+ ),
25
+ ]
20
26
 
21
27
 
22
28
  class LinearPauliRotations(function_params.FunctionParams):
@@ -45,30 +51,38 @@ class LinearPauliRotations(function_params.FunctionParams):
45
51
  num_state_qubits: pydantic.PositiveInt = pydantic.Field(
46
52
  description="The number of input qubits"
47
53
  )
48
- bases: List[PydanticPauliBasisStr] = pydantic.Field(
54
+ bases: list[PydanticPauliBasisStr] = pydantic.Field(
49
55
  description="The types of Pauli rotations ('X', 'Y', 'Z')."
50
56
  )
51
- slopes: List[float] = pydantic.Field(
57
+ slopes: list[float] = pydantic.Field(
52
58
  description="The slopes of the controlled rotations."
53
59
  )
54
- offsets: List[float] = pydantic.Field(
60
+ offsets: list[float] = pydantic.Field(
55
61
  description="The offsets of the controlled rotations."
56
62
  )
57
63
 
58
- @pydantic.validator("bases", "slopes", "offsets", pre=True, always=True)
59
- def as_list(cls, v: Any) -> List[Any]:
64
+ @pydantic.field_validator("bases", "slopes", "offsets", mode="before")
65
+ @classmethod
66
+ def as_list(cls, v: Any) -> list[Any]:
60
67
  if not isinstance(v, list):
61
68
  v = [v]
62
- return v
69
+ res = []
70
+ for x in v:
71
+ element = x
72
+ if isinstance(x, str):
73
+ res.append(element.lower())
74
+ else:
75
+ res.append(element)
76
+ return res
63
77
 
64
- @pydantic.root_validator()
65
- def validate_lists(cls, values: Dict[str, Any]) -> Dict[str, Any]:
66
- offsets = values.get("offsets", list())
67
- bases = values.get("bases", list())
68
- slopes = values.get("slopes", list())
78
+ @pydantic.model_validator(mode="after")
79
+ def validate_lists(self) -> Self:
80
+ offsets = self.offsets or list()
81
+ bases = self.bases or list()
82
+ slopes = self.slopes or list()
69
83
  if len(slopes) == len(offsets) and len(offsets) == len(bases):
70
- return values
71
- raise ValueError(LENGTH_ERROR_MESSAGE)
84
+ return self
85
+ raise ClassiqValueError(LENGTH_ERROR_MESSAGE)
72
86
 
73
87
  def _create_ios(self) -> None:
74
88
  self._inputs = {
@@ -1,4 +1,4 @@
1
- from classiq._internals.enum_utils import StrEnum
1
+ from classiq.interface.enum_utils import StrEnum
2
2
 
3
3
 
4
4
  class McmtMethod(StrEnum):
@@ -1,11 +1,14 @@
1
- from typing import Any, Dict, Optional, cast
1
+ from typing import Any, Optional, cast
2
2
 
3
3
  import pydantic
4
4
 
5
+ from classiq.interface.exceptions import ClassiqValueError
5
6
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
6
7
  from classiq.interface.generator.control_state import ControlState
7
- from classiq.interface.generator.function_params import FunctionParams
8
- from classiq.interface.generator.parameters import ParameterFloatType
8
+ from classiq.interface.generator.function_params import (
9
+ FunctionParams,
10
+ FunctionParamsNumericParameter,
11
+ )
9
12
 
10
13
  CTRL = "CTRL"
11
14
  TARGET = "TARGET"
@@ -28,17 +31,17 @@ class Mcu(FunctionParams):
28
31
  e^(i*phi)*sin(theta/2) & e^(i*(phi+lam))*cos(theta/2) \\
29
32
  """
30
33
 
31
- theta: ParameterFloatType = pydantic.Field(
32
- default=0, description="Theta radian angle.", is_exec_param=True
34
+ theta: FunctionParamsNumericParameter = pydantic.Field(
35
+ default=0, description="Theta radian angle."
33
36
  )
34
- phi: ParameterFloatType = pydantic.Field(
35
- default=0, description="Phi radian angle.", is_exec_param=True
37
+ phi: FunctionParamsNumericParameter = pydantic.Field(
38
+ default=0, description="Phi radian angle."
36
39
  )
37
- lam: ParameterFloatType = pydantic.Field(
38
- default=0, description="Lambda radian angle.", is_exec_param=True
40
+ lam: FunctionParamsNumericParameter = pydantic.Field(
41
+ default=0, description="Lambda radian angle."
39
42
  )
40
- gam: ParameterFloatType = pydantic.Field(
41
- default=0, description="gam radian angle.", is_exec_param=True
43
+ gam: FunctionParamsNumericParameter = pydantic.Field(
44
+ default=0, description="gam radian angle."
42
45
  )
43
46
 
44
47
  num_ctrl_qubits: Optional[pydantic.PositiveInt] = pydantic.Field(
@@ -48,8 +51,9 @@ class Mcu(FunctionParams):
48
51
  default=None, description="string of the control state"
49
52
  )
50
53
 
51
- @pydantic.root_validator()
52
- def _validate_control(cls, values: Dict[str, Any]) -> Dict[str, Any]:
54
+ @pydantic.model_validator(mode="before")
55
+ @classmethod
56
+ def _validate_control(cls, values: Any) -> dict[str, Any]:
53
57
  num_ctrl_qubits = values.get("num_ctrl_qubits")
54
58
  ctrl_state = values.get("ctrl_state")
55
59
 
@@ -58,7 +62,7 @@ class Mcu(FunctionParams):
58
62
  ControlState.validate_control_string(ctrl_state)
59
63
 
60
64
  if ctrl_state is None and num_ctrl_qubits is None:
61
- raise ValueError("num_ctrl_qubits or ctrl_state must exist.")
65
+ raise ClassiqValueError("num_ctrl_qubits or ctrl_state must exist.")
62
66
 
63
67
  if ctrl_state is None and num_ctrl_qubits is not None:
64
68
  values["ctrl_state"] = "1" * num_ctrl_qubits
@@ -69,7 +73,7 @@ class Mcu(FunctionParams):
69
73
  values["num_ctrl_qubits"] = num_ctrl_qubits
70
74
 
71
75
  if len(ctrl_state) != num_ctrl_qubits:
72
- raise ValueError(
76
+ raise ClassiqValueError(
73
77
  "control state length should be equal to the number of control qubits"
74
78
  )
75
79
 
@@ -77,7 +81,7 @@ class Mcu(FunctionParams):
77
81
 
78
82
  def _create_ios(self) -> None:
79
83
  if self.num_ctrl_qubits is None:
80
- raise ValueError("num_ctrl_qubits must have a valid value.")
84
+ raise ClassiqValueError("num_ctrl_qubits must have a valid value.")
81
85
  ctrl_register = RegisterUserInput(size=self.num_ctrl_qubits, name=CTRL)
82
86
  target_register = RegisterUserInput(size=1, name=TARGET)
83
87
  self._inputs = {reg.name: reg for reg in (ctrl_register, target_register)}