classiq 0.38.0__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 (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.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.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.3.dist-info}/WHEEL +0 -0
@@ -1,13 +1,13 @@
1
- from typing import Any, Dict, List, Optional
1
+ from typing import Optional
2
2
 
3
3
  import pydantic
4
4
  from pydantic import BaseModel
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.helpers.custom_pydantic_types import PydanticAlphaParamCVAR
7
10
 
8
- from classiq._internals.enum_utils import StrEnum
9
- from classiq.exceptions import ClassiqValueError
10
-
11
11
 
12
12
  class CostType(StrEnum):
13
13
  MIN = "MIN"
@@ -45,7 +45,7 @@ class OptimizerPreferences(BaseModel):
45
45
  default=None,
46
46
  description="The random seed used for the generation",
47
47
  )
48
- initial_point: Optional[List[float]] = pydantic.Field(
48
+ initial_point: Optional[list[float]] = pydantic.Field(
49
49
  default=None,
50
50
  description="Initial values for the ansatz parameters",
51
51
  )
@@ -54,11 +54,12 @@ class OptimizerPreferences(BaseModel):
54
54
  description="If True, the optimizer will not compute the variance of the ansatz.",
55
55
  )
56
56
 
57
- @pydantic.validator("tolerance", pre=True, always=True)
57
+ @pydantic.field_validator("tolerance", mode="before")
58
+ @classmethod
58
59
  def check_tolerance(
59
- cls, tolerance: Optional[pydantic.PositiveFloat], values: Dict[str, Any]
60
+ cls, tolerance: Optional[pydantic.PositiveFloat], info: ValidationInfo
60
61
  ) -> Optional[pydantic.PositiveFloat]:
61
- optimizer_type = values.get("type")
62
+ optimizer_type = info.data.get("type")
62
63
  if tolerance is not None and optimizer_type == OptimizerType.SPSA:
63
64
  raise ClassiqValueError("No tolerance param for SPSA optimizer")
64
65
 
@@ -67,11 +68,12 @@ class OptimizerPreferences(BaseModel):
67
68
 
68
69
  return tolerance
69
70
 
70
- @pydantic.validator("step_size", pre=True, always=True)
71
+ @pydantic.field_validator("step_size", mode="before")
72
+ @classmethod
71
73
  def check_step_size(
72
- cls, step_size: Optional[pydantic.PositiveFloat], values: Dict[str, Any]
74
+ cls, step_size: Optional[pydantic.PositiveFloat], info: ValidationInfo
73
75
  ) -> Optional[pydantic.PositiveFloat]:
74
- optimizer_type = values.get("name")
76
+ optimizer_type = info.data.get("name")
75
77
  if step_size is not None and optimizer_type not in (
76
78
  OptimizerType.L_BFGS_B,
77
79
  OptimizerType.ADAM,
@@ -110,11 +112,12 @@ class CombinatorialOptimizer(OptimizerPreferences):
110
112
  description="Whether to check if all the solutions satisfy the constraints",
111
113
  )
112
114
 
113
- @pydantic.validator("alpha_cvar", pre=True, always=True)
115
+ @pydantic.field_validator("alpha_cvar", mode="before")
116
+ @classmethod
114
117
  def check_alpha_cvar(
115
- cls, alpha_cvar: Optional[PydanticAlphaParamCVAR], values: Dict[str, Any]
118
+ cls, alpha_cvar: Optional[PydanticAlphaParamCVAR], info: ValidationInfo
116
119
  ) -> Optional[PydanticAlphaParamCVAR]:
117
- cost_type = values.get("cost_type")
120
+ cost_type = info.data.get("cost_type")
118
121
  if alpha_cvar is not None and cost_type != CostType.CVAR:
119
122
  raise ClassiqValueError("Use CVAR params only for CostType.CVAR.")
120
123
 
@@ -1,27 +1,27 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
- from typing import Any, Dict, Optional, Tuple, Union
4
+ from typing import Any, Optional, Union
5
5
 
6
6
  import pydantic
7
- from pydantic import BaseModel
7
+ from pydantic import BaseModel, ConfigDict
8
+ from pydantic_core.core_schema import ValidationInfo
8
9
 
9
10
  from classiq.interface.backend.ionq.ionq_quantum_program import IonqQuantumCircuit
10
11
  from classiq.interface.backend.pydantic_backend import PydanticArgumentNameType
12
+ from classiq.interface.exceptions import ClassiqValueError
11
13
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
12
14
  from classiq.interface.executor.register_initialization import RegisterInitialization
13
15
  from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
14
16
  ExecutionData,
15
17
  )
16
18
 
17
- from classiq.exceptions import ClassiqValueError
18
-
19
- Arguments = Dict[PydanticArgumentNameType, Any]
20
- MultipleArguments = Tuple[Arguments, ...]
19
+ Arguments = dict[PydanticArgumentNameType, Any]
20
+ MultipleArguments = tuple[Arguments, ...]
21
21
  CodeType = str
22
- RegistersInitialization = Dict[str, RegisterInitialization]
23
- Qubits = Tuple[int, ...]
24
- OutputQubitsMap = Dict[str, Qubits]
22
+ RegistersInitialization = dict[str, RegisterInitialization]
23
+ Qubits = tuple[int, ...]
24
+ OutputQubitsMap = dict[str, Qubits]
25
25
 
26
26
 
27
27
  class QuantumBaseCode(BaseModel):
@@ -32,17 +32,18 @@ class QuantumBaseCode(BaseModel):
32
32
  ..., description="The textual representation of the program"
33
33
  )
34
34
 
35
- @pydantic.validator("code")
35
+ @pydantic.field_validator("code")
36
+ @classmethod
36
37
  def load_quantum_program(
37
- cls, code: Union[CodeType, IonqQuantumCircuit], values: Dict[str, Any]
38
+ cls, code: Union[CodeType, IonqQuantumCircuit], values: ValidationInfo
38
39
  ) -> CodeType:
39
- syntax = values.get("syntax")
40
+ syntax = values.data.get("syntax")
40
41
  if isinstance(code, IonqQuantumCircuit):
41
42
  if syntax != QuantumInstructionSet.IONQ:
42
43
  raise ClassiqValueError(
43
44
  f"Invalid code type {type(code)} for syntax: {syntax}"
44
45
  )
45
- return code.json()
46
+ return code.model_dump_json()
46
47
 
47
48
  return code
48
49
 
@@ -57,41 +58,44 @@ class QuantumCode(QuantumBaseCode):
57
58
  description="The map of outputs to their qubits in the circuit.",
58
59
  )
59
60
  registers_initialization: Optional[RegistersInitialization] = pydantic.Field(
60
- default_factory=None,
61
+ default=None,
61
62
  description="Initial conditions for the different registers in the circuit.",
62
63
  )
63
64
  synthesis_execution_data: Optional[ExecutionData] = pydantic.Field(default=None)
64
65
  synthesis_execution_arguments: Arguments = pydantic.Field(default_factory=dict)
66
+ model_config = ConfigDict(validate_assignment=True)
65
67
 
66
- class Config:
67
- validate_assignment = True
68
-
69
- @pydantic.validator("arguments")
68
+ @pydantic.field_validator("arguments", mode="before")
69
+ @classmethod
70
70
  def validate_arguments(
71
- cls, arguments: MultipleArguments, values: Dict[str, Any]
71
+ cls, arguments: MultipleArguments, info: ValidationInfo
72
72
  ) -> MultipleArguments:
73
- if arguments and values.get("syntax") not in (
73
+ if arguments and info.data.get("syntax") not in (
74
74
  QuantumInstructionSet.QSHARP,
75
75
  QuantumInstructionSet.QASM,
76
76
  ):
77
77
  raise ClassiqValueError("Only QASM or Q# programs support arguments")
78
78
 
79
- if values.get("syntax") == QuantumInstructionSet.QSHARP and len(arguments) > 1:
79
+ if (
80
+ info.data.get("syntax") == QuantumInstructionSet.QSHARP
81
+ and len(arguments) > 1
82
+ ):
80
83
  raise ClassiqValueError(
81
84
  f"Q# programs supports only one group of arguments. {len(arguments)} given"
82
85
  )
83
86
 
84
87
  return arguments
85
88
 
86
- @pydantic.validator("synthesis_execution_data")
89
+ @pydantic.field_validator("synthesis_execution_data")
90
+ @classmethod
87
91
  def validate_synthesis_execution_data(
88
92
  cls,
89
93
  synthesis_execution_data: Optional[ExecutionData],
90
- values: Dict[str, Any],
94
+ values: ValidationInfo,
91
95
  ) -> Optional[ExecutionData]:
92
96
  if (
93
97
  synthesis_execution_data is not None
94
- and values.get("syntax") is not QuantumInstructionSet.QASM
98
+ and values.data.get("syntax") is not QuantumInstructionSet.QASM
95
99
  ):
96
100
  raise ClassiqValueError("Only QASM supports the requested configuration")
97
101
 
@@ -1,5 +1,5 @@
1
- from classiq._internals.enum_utils import StrEnum
2
- from classiq.exceptions import ClassiqValueError
1
+ from classiq.interface.enum_utils import StrEnum
2
+ from classiq.interface.exceptions import ClassiqValueError
3
3
 
4
4
 
5
5
  class QuantumInstructionSet(StrEnum):
@@ -1,11 +1,9 @@
1
- from typing import Any, Dict, List
2
-
3
1
  import pydantic
2
+ from typing_extensions import Self
4
3
 
4
+ from classiq.interface.exceptions import ClassiqStateInitializationError
5
5
  from classiq.interface.generator.arith import number_utils
6
6
 
7
- from classiq.exceptions import ClassiqStateInitializationError
8
-
9
7
  _NON_INTEGER_INITIALIZATION_ERROR_MSG: str = (
10
8
  "Only natural numbers are supported as initial conditions"
11
9
  )
@@ -13,22 +11,21 @@ _NON_INTEGER_INITIALIZATION_ERROR_MSG: str = (
13
11
 
14
12
  class RegisterInitialization(pydantic.BaseModel):
15
13
  name: str
16
- qubits: List[int]
14
+ qubits: list[int]
17
15
  initial_condition: pydantic.NonNegativeInt
18
16
 
19
- @pydantic.validator("initial_condition", pre=True)
17
+ @pydantic.field_validator("initial_condition", mode="before")
18
+ @classmethod
20
19
  def _validate_initial_condition(cls, value: int) -> int:
21
20
  if not isinstance(value, int) or value < 0:
22
21
  raise ClassiqStateInitializationError(_NON_INTEGER_INITIALIZATION_ERROR_MSG)
23
22
  return value
24
23
 
25
- @pydantic.root_validator()
26
- def _validate_register_initialization(
27
- cls, values: Dict[str, Any]
28
- ) -> Dict[str, Any]:
29
- qubits: List[int] = values.get("qubits", list())
30
- initial_condition: int = values.get("initial_condition", 0)
31
- name: str = values.get("name", "")
24
+ @pydantic.model_validator(mode="after")
25
+ def _validate_register_initialization(self) -> Self:
26
+ qubits: list[int] = self.qubits or []
27
+ initial_condition: int = self.initial_condition or 0
28
+ name: str = self.name or ""
32
29
 
33
30
  initial_condition_length = number_utils.size(initial_condition)
34
31
  register_length = len(qubits)
@@ -36,4 +33,4 @@ class RegisterInitialization(pydantic.BaseModel):
36
33
  raise ClassiqStateInitializationError(
37
34
  f"Register {name} has {register_length} qubits, which is not enough to represent the number {initial_condition}."
38
35
  )
39
- return values
36
+ return self
@@ -1,54 +1,64 @@
1
1
  import functools
2
2
  import operator
3
3
  from collections import defaultdict
4
+ from collections.abc import Iterator, Mapping
4
5
  from typing import (
6
+ TYPE_CHECKING,
5
7
  Any,
6
8
  DefaultDict,
7
- Dict,
8
- Iterator,
9
- List,
10
- Mapping,
11
9
  Optional,
12
- Tuple,
13
10
  Union,
14
11
  )
15
12
 
16
13
  import pydantic
17
14
  from pydantic import BaseModel
18
- from typing_extensions import TypeAlias
15
+ from typing_extensions import Self, TypeAlias
19
16
 
17
+ from classiq.interface.exceptions import ClassiqError
20
18
  from classiq.interface.executor.quantum_code import OutputQubitsMap, Qubits
21
19
  from classiq.interface.generator.arith import number_utils
22
20
  from classiq.interface.generator.complex_type import Complex
23
21
  from classiq.interface.generator.functions.classical_type import QmodPyObject
24
22
  from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
23
+ from classiq.interface.helpers.datastructures import get_sdk_compatible_python_object
25
24
  from classiq.interface.helpers.versioned_model import VersionedModel
26
25
 
27
- from classiq.exceptions import ClassiqError
28
-
29
26
  _ILLEGAL_QUBIT_ERROR_MSG: str = "Illegal qubit index requested"
30
27
  _REPEATED_QUBIT_ERROR_MSG: str = "Requested a qubit more than once"
31
28
  _UNAVAILABLE_OUTPUT_ERROR_MSG: str = "Requested output doesn't exist in the circuit"
32
29
 
33
30
  State: TypeAlias = str
34
31
  Name: TypeAlias = str
35
- RegisterValue: TypeAlias = Union[float, int]
32
+ RegisterValue: TypeAlias = Union[float, int, list, dict]
36
33
  MeasuredShots: TypeAlias = pydantic.NonNegativeInt
37
34
  ParsedState: TypeAlias = Mapping[Name, RegisterValue]
38
35
  ParsedStates: TypeAlias = Mapping[State, ParsedState]
39
- Counts: TypeAlias = Dict[State, MeasuredShots]
40
- StateVector: TypeAlias = Optional[Dict[str, Any]]
36
+ Counts: TypeAlias = dict[State, MeasuredShots]
37
+ StateVector: TypeAlias = Optional[dict[str, Complex]]
38
+
39
+ if TYPE_CHECKING:
40
+ DotAccessParsedState = Mapping[Name, Any]
41
+ else:
42
+ DotAccessParsedState = ParsedState
41
43
 
42
44
 
43
45
  class SampledState(BaseModel):
44
- state: ParsedState
46
+ state: DotAccessParsedState
45
47
  shots: MeasuredShots
46
48
 
47
49
  def __repr__(self) -> str:
48
50
  return f"{self.state}: {self.shots}"
49
51
 
52
+ @pydantic.field_validator("state", mode="after")
53
+ @classmethod
54
+ def _make_state_sdk_compatible(cls, state: ParsedState) -> DotAccessParsedState:
55
+ return {
56
+ name: get_sdk_compatible_python_object(value)
57
+ for name, value in state.items()
58
+ }
59
+
50
60
 
51
- ParsedCounts: TypeAlias = List[SampledState]
61
+ ParsedCounts: TypeAlias = list[SampledState]
52
62
 
53
63
 
54
64
  class SimulatedState(BaseModel):
@@ -60,7 +70,8 @@ class SimulatedState(BaseModel):
60
70
  return self.state[item]
61
71
 
62
72
 
63
- ParsedStateVector: TypeAlias = List[SimulatedState]
73
+ SimulatedState.model_rebuild()
74
+ ParsedStateVector: TypeAlias = list[SimulatedState]
64
75
 
65
76
 
66
77
  class VaRResult(BaseModel):
@@ -69,10 +80,10 @@ class VaRResult(BaseModel):
69
80
 
70
81
 
71
82
  class GroverSimulationResults(VersionedModel):
72
- result: Dict[str, Any]
83
+ result: dict[str, Any]
73
84
 
74
85
 
75
- def _validate_qubit_indices(counts: Counts, indices: Tuple[int, ...]) -> None:
86
+ def _validate_qubit_indices(counts: Counts, indices: tuple[int, ...]) -> None:
76
87
  if not indices:
77
88
  raise ClassiqError(_ILLEGAL_QUBIT_ERROR_MSG)
78
89
 
@@ -83,7 +94,7 @@ def _validate_qubit_indices(counts: Counts, indices: Tuple[int, ...]) -> None:
83
94
  raise ClassiqError(_REPEATED_QUBIT_ERROR_MSG)
84
95
 
85
96
 
86
- def _slice_str(s: str, indices: Tuple[int, ...]) -> str:
97
+ def _slice_str(s: str, indices: tuple[int, ...]) -> str:
87
98
  return "".join(s[i] for i in indices)
88
99
 
89
100
 
@@ -101,7 +112,7 @@ def get_sampled_state(
101
112
 
102
113
 
103
114
  def reduce_parsed_states(
104
- parsed_states: ParsedStates, outputs: Tuple[Name, ...]
115
+ parsed_states: ParsedStates, outputs: tuple[Name, ...]
105
116
  ) -> ParsedStates:
106
117
  return {
107
118
  state: {
@@ -122,8 +133,25 @@ def get_parsed_counts(counts: Counts, parsed_states: ParsedStates) -> ParsedCoun
122
133
  return sorted(parsed_counts, key=lambda k: k.shots, reverse=True)
123
134
 
124
135
 
136
+ def prepare_parsed_state_vector(
137
+ state_vector: StateVector, parsed_state_vector_states: ParsedStates
138
+ ) -> Optional[ParsedStateVector]:
139
+ if not state_vector:
140
+ return None
141
+
142
+ parsed_state_vector = [
143
+ SimulatedState(
144
+ state=parsed_state_vector_states[bitstring],
145
+ bitstring=bitstring,
146
+ amplitude=complex(amplitude_str),
147
+ )
148
+ for bitstring, amplitude_str in state_vector.items()
149
+ ]
150
+ return sorted(parsed_state_vector, key=lambda k: abs(k.amplitude), reverse=True)
151
+
152
+
125
153
  class ExecutionDetails(BaseModel, QmodPyObject):
126
- vendor_format_result: Dict[str, Any] = pydantic.Field(
154
+ vendor_format_result: dict[str, Any] = pydantic.Field(
127
155
  ..., description="Result in proprietary vendor format"
128
156
  )
129
157
  counts: Counts = pydantic.Field(
@@ -133,11 +161,14 @@ class ExecutionDetails(BaseModel, QmodPyObject):
133
161
  True,
134
162
  description="Is the qubit order of counts field such that the LSB is right?",
135
163
  )
164
+ probabilities: dict[State, pydantic.NonNegativeFloat] = pydantic.Field(
165
+ default_factory=dict, description="Probabilities of each state"
166
+ )
136
167
  parsed_states: ParsedStates = pydantic.Field(
137
168
  default_factory=dict,
138
169
  description="A mapping between the raw states of counts (bitstrings) to their parsed states (registers' values)",
139
170
  )
140
- histogram: Optional[Dict[State, pydantic.NonNegativeFloat]] = pydantic.Field(
171
+ histogram: Optional[dict[State, pydantic.NonNegativeFloat]] = pydantic.Field(
141
172
  None,
142
173
  description="Histogram of probability per state (an alternative to counts)",
143
174
  )
@@ -149,7 +180,7 @@ class ExecutionDetails(BaseModel, QmodPyObject):
149
180
  default=None,
150
181
  description="The state vector when executed on a simulator, with LSB right qubit order",
151
182
  )
152
- parsed_state_vector_states: ParsedStates = pydantic.Field(
183
+ parsed_state_vector_states: Optional[ParsedStates] = pydantic.Field(
153
184
  default=None,
154
185
  description="A mapping between the raw states of the state vector (bitstrings) to their parsed states (registers' values)",
155
186
  )
@@ -161,22 +192,23 @@ class ExecutionDetails(BaseModel, QmodPyObject):
161
192
  default=None, description="The total number of shots the circuit was executed"
162
193
  )
163
194
 
164
- @pydantic.validator("counts", pre=True)
195
+ @pydantic.field_validator("counts", mode="after")
196
+ @classmethod
165
197
  def _clean_spaces_from_counts_keys(cls, v: Counts) -> Counts:
166
198
  if not v or " " not in list(v.keys())[0]:
167
199
  return v
168
200
  return {state.replace(" ", ""): v[state] for state in v}
169
201
 
170
- @pydantic.validator("num_shots", always=True)
171
- def _validate_num_shots(
172
- cls, num_shots: Optional[int], values: Dict[str, Any]
173
- ) -> Optional[int]:
174
- if num_shots is not None:
175
- return num_shots
176
- counts = values.get("counts")
177
- if not counts:
178
- return None
179
- return sum(shots for _, shots in counts.items())
202
+ @pydantic.model_validator(mode="after")
203
+ def _validate_num_shots(self) -> Self:
204
+ if isinstance(self, ExecutionDetails):
205
+ if self.num_shots is not None:
206
+ return self
207
+ counts = self.counts
208
+ if not counts:
209
+ return self
210
+ self.num_shots = sum(shots for _, shots in counts.items())
211
+ return self
180
212
 
181
213
  @property
182
214
  def parsed_counts(self) -> ParsedCounts:
@@ -184,17 +216,11 @@ class ExecutionDetails(BaseModel, QmodPyObject):
184
216
 
185
217
  @property
186
218
  def parsed_state_vector(self) -> Optional[ParsedStateVector]:
187
- if not self.state_vector:
188
- return None
189
- parsed_state_vector = [
190
- SimulatedState(
191
- state=self.parsed_state_vector_states[bitstring],
192
- bitstring=bitstring,
193
- amplitude=complex(amplitude_str),
194
- )
195
- for bitstring, amplitude_str in self.state_vector.items()
196
- ]
197
- return sorted(parsed_state_vector, key=lambda k: abs(k.amplitude), reverse=True)
219
+ if TYPE_CHECKING:
220
+ assert self.parsed_state_vector_states is not None
221
+ return prepare_parsed_state_vector(
222
+ self.state_vector, self.parsed_state_vector_states
223
+ )
198
224
 
199
225
  def flip_execution_counts_bitstring(self) -> None:
200
226
  """Backends should return result count bitstring in right to left form"""
@@ -225,15 +251,15 @@ class ExecutionDetails(BaseModel, QmodPyObject):
225
251
  return self.counts_of_qubits(*self.output_qubits_map[output_name])
226
252
 
227
253
  def counts_of_multiple_outputs(
228
- self, output_names: Tuple[Name, ...]
229
- ) -> Dict[Tuple[State, ...], pydantic.NonNegativeInt]:
254
+ self, output_names: tuple[Name, ...]
255
+ ) -> dict[tuple[State, ...], pydantic.NonNegativeInt]:
230
256
  if any(name not in self.output_qubits_map for name in output_names):
231
257
  raise ClassiqError(_UNAVAILABLE_OUTPUT_ERROR_MSG)
232
258
 
233
- output_regs: Tuple[Qubits, ...] = tuple(
259
+ output_regs: tuple[Qubits, ...] = tuple(
234
260
  self.output_qubits_map[name] for name in output_names
235
261
  )
236
- reduced_counts: DefaultDict[Tuple[State, ...], int] = defaultdict(int)
262
+ reduced_counts: DefaultDict[tuple[State, ...], int] = defaultdict(int)
237
263
  for state_str, state_count in self.counts_by_qubit_order(
238
264
  lsb_right=False
239
265
  ).items():
@@ -242,7 +268,7 @@ class ExecutionDetails(BaseModel, QmodPyObject):
242
268
  return dict(reduced_counts)
243
269
 
244
270
  def parsed_counts_of_outputs(
245
- self, output_names: Union[Name, Tuple[Name, ...]]
271
+ self, output_names: Union[Name, tuple[Name, ...]]
246
272
  ) -> ParsedCounts:
247
273
  if isinstance(output_names, Name):
248
274
  output_names = (output_names,)
@@ -252,8 +278,8 @@ class ExecutionDetails(BaseModel, QmodPyObject):
252
278
  reduced_parsed_states = reduce_parsed_states(self.parsed_states, output_names)
253
279
  return get_parsed_counts(self.counts, reduced_parsed_states)
254
280
 
255
- def register_output_from_qubits(self, qubits: Tuple[int, ...]) -> Dict[float, int]:
256
- register_output: Dict[float, int] = {}
281
+ def register_output_from_qubits(self, qubits: tuple[int, ...]) -> dict[float, int]:
282
+ register_output: dict[float, int] = {}
257
283
  value_from_str_bin = functools.partial(
258
284
  self._get_register_value_from_binary_string_results, register_qubits=qubits
259
285
  )
@@ -261,13 +287,15 @@ class ExecutionDetails(BaseModel, QmodPyObject):
261
287
  lsb_right=False
262
288
  ).items():
263
289
  value = value_from_str_bin(binary_string=results_binary_key)
290
+ if TYPE_CHECKING:
291
+ assert isinstance(value, float)
264
292
  register_output[value] = register_output.get(value, 0) + counts
265
293
 
266
294
  return register_output
267
295
 
268
296
  @staticmethod
269
297
  def _get_register_value_from_binary_string_results(
270
- binary_string: str, register_qubits: List[int]
298
+ binary_string: str, register_qubits: list[int]
271
299
  ) -> RegisterValue:
272
300
  register_binary_string = "".join(
273
301
  operator.itemgetter(*register_qubits)(binary_string)
@@ -276,28 +304,27 @@ class ExecutionDetails(BaseModel, QmodPyObject):
276
304
 
277
305
 
278
306
  class MultipleExecutionDetails(VersionedModel):
279
- details: List[ExecutionDetails]
307
+ details: list[ExecutionDetails]
280
308
 
281
309
  def __getitem__(self, index: int) -> ExecutionDetails:
282
310
  return self.details[index]
283
311
 
284
312
 
285
- class EstimationMetadata(BaseModel, extra=pydantic.Extra.allow):
313
+ class EstimationMetadata(BaseModel, extra="allow"):
286
314
  shots: Optional[pydantic.NonNegativeInt] = None
287
315
  remapped_qubits: bool = False
288
- input_qubit_map: Optional[List[PydanticNonNegIntTuple]] = None
316
+ input_qubit_map: Optional[list[PydanticNonNegIntTuple]] = None
289
317
 
290
318
 
291
319
  class EstimationResult(BaseModel, QmodPyObject):
292
320
  value: Complex = pydantic.Field(..., description="Estimation for the operator")
293
- variance: Complex = pydantic.Field(..., description="Variance of the estimation")
294
321
  metadata: EstimationMetadata = pydantic.Field(
295
322
  ..., description="Metadata for the estimation"
296
323
  )
297
324
 
298
325
 
299
326
  class EstimationResults(VersionedModel):
300
- results: List[EstimationResult]
327
+ results: list[EstimationResult]
301
328
 
302
329
  def __len__(self) -> int:
303
330
  return len(self.results)
@@ -1,7 +1,7 @@
1
1
  import base64
2
2
  import io
3
3
  from datetime import datetime
4
- from typing import Dict, List, Optional, Tuple
4
+ from typing import Optional
5
5
 
6
6
  import pydantic
7
7
  from PIL import Image
@@ -12,14 +12,14 @@ from classiq.interface.generator.complex_type import Complex
12
12
  from classiq.interface.generator.functions.classical_type import QmodPyObject
13
13
  from classiq.interface.helpers.custom_pydantic_types import PydanticProbabilityFloat
14
14
 
15
- Solution = Tuple[int, ...]
15
+ Solution = tuple[int, ...]
16
16
 
17
17
 
18
18
  class SolverResult(BaseModel):
19
19
  energy: float
20
20
  # TODO: add time units (like seconds)
21
21
  time: Optional[float] = None
22
- solution: Optional[Solution]
22
+ solution: Optional[Solution] = None
23
23
 
24
24
 
25
25
  class SolutionData(BaseModel):
@@ -34,13 +34,13 @@ class VQEIntermediateData(BaseModel):
34
34
  iteration_number: pydantic.PositiveInt = pydantic.Field(
35
35
  description="The iteration's number (evaluation count)"
36
36
  )
37
- parameters: List[float] = pydantic.Field(
37
+ parameters: list[float] = pydantic.Field(
38
38
  description="The optimizer parameters for the variational form"
39
39
  )
40
40
  mean_all_solutions: Optional[float] = pydantic.Field(
41
41
  default=None, description="The mean score of all solutions in this iteration"
42
42
  )
43
- solutions: List[SolutionData] = pydantic.Field(
43
+ solutions: list[SolutionData] = pydantic.Field(
44
44
  description="Solutions found in this iteration, their score and"
45
45
  "number of repetitions"
46
46
  )
@@ -50,11 +50,11 @@ class VQEIntermediateData(BaseModel):
50
50
 
51
51
 
52
52
  class VQESolverResult(SolverResult, QmodPyObject):
53
- eigenstate: Dict[str, Complex]
54
- reduced_probabilities: Optional[Dict[str, float]] = None
53
+ eigenstate: dict[str, Complex]
54
+ reduced_probabilities: Optional[dict[str, float]] = None
55
55
  optimized_circuit_sample_results: ExecutionDetails
56
- intermediate_results: List[VQEIntermediateData]
57
- optimal_parameters: Dict[str, float]
56
+ intermediate_results: list[VQEIntermediateData]
57
+ optimal_parameters: dict[str, float]
58
58
  convergence_graph_str: str
59
59
  num_solutions: Optional[int] = None
60
60
  num_shots: int
@@ -63,7 +63,7 @@ class VQESolverResult(SolverResult, QmodPyObject):
63
63
  self.convergence_graph.show()
64
64
 
65
65
  @property
66
- def convergence_graph(self):
66
+ def convergence_graph(self) -> Image.Image:
67
67
  return Image.open(io.BytesIO(base64.b64decode(self.convergence_graph_str)))
68
68
 
69
69
  @property