classiq 0.38.0__py3-none-any.whl → 0.65.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/WHEEL +0 -0
@@ -6,25 +6,25 @@ import random
6
6
  import re
7
7
  import string
8
8
  from collections import defaultdict
9
+ from collections.abc import Iterable, Mapping, Sequence
10
+ from re import Match
9
11
  from typing import (
10
12
  Any,
11
- Dict,
12
- Iterable,
13
- List,
14
- Mapping,
15
- Match,
16
13
  Optional,
17
- Sequence,
18
- Tuple,
19
14
  Union,
20
15
  )
16
+ from uuid import UUID, uuid4
21
17
 
22
18
  import pydantic
23
- from pydantic import BaseModel, Extra
19
+ from pydantic import BaseModel, ConfigDict
20
+ from pydantic_core.core_schema import ValidationInfo
24
21
 
22
+ from classiq.interface.exceptions import ClassiqControlError, ClassiqValueError
25
23
  from classiq.interface.generator import function_param_list, function_params as f_params
26
24
  from classiq.interface.generator.arith.arithmetic import Arithmetic
27
- from classiq.interface.generator.compiler_keywords import EXPANDED_KEYWORD
25
+ from classiq.interface.generator.compiler_keywords import (
26
+ generate_original_function_name,
27
+ )
28
28
  from classiq.interface.generator.control_state import ControlState
29
29
  from classiq.interface.generator.function_params import (
30
30
  NAME_REGEX,
@@ -47,8 +47,6 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
47
47
  HashablePydanticBaseModel,
48
48
  )
49
49
 
50
- from classiq.exceptions import ClassiqControlError, ClassiqValueError
51
-
52
50
  DEFAULT_SUFFIX_LEN: int = 6
53
51
  BAD_INPUT_ERROR_MSG = "Bad input name given"
54
52
  BAD_OUTPUT_ERROR_MSG = "Bad output name given"
@@ -63,7 +61,7 @@ LEGAL_SLICING = rf"(\-?\d+)?({SEPARATOR}(\-?\d+)?)?({SEPARATOR}(\-?\d+)?)?"
63
61
 
64
62
  _ALPHANUM_CHARACTERS = string.ascii_letters + string.digits
65
63
 
66
- RegNameAndSlice = Tuple[str, slice]
64
+ RegNameAndSlice = tuple[str, slice]
67
65
 
68
66
  ZERO_INDICATOR = "0"
69
67
  INVERSE_SUFFIX = "_qinverse"
@@ -80,12 +78,12 @@ class WirePair(HashablePydanticBaseModel):
80
78
  out_wire: WireName
81
79
 
82
80
 
83
- SUFFIX_RANDOMIZER = random.Random()
81
+ SUFFIX_RANDOMIZER = random.Random() # noqa: S311
84
82
 
85
83
 
86
84
  def split_wire_pair_to_wires(
87
85
  inout: WirePair,
88
- ) -> Tuple[WireName, WireName]:
86
+ ) -> tuple[WireName, WireName]:
89
87
  return inout.in_wire, inout.out_wire
90
88
 
91
89
 
@@ -97,7 +95,7 @@ def randomize_suffix(suffix_len: int = DEFAULT_SUFFIX_LEN) -> str:
97
95
 
98
96
  def get_non_zero_wires(
99
97
  wires: Iterable[WireName],
100
- ) -> List[WireName]:
98
+ ) -> list[WireName]:
101
99
  return [wire for wire in wires if wire != ZERO_INDICATOR]
102
100
 
103
101
 
@@ -121,7 +119,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
121
119
  release_by_inverse: bool = pydantic.Field(
122
120
  default=False, description="Release zero inputs in inverse call."
123
121
  )
124
- control_states: List[ControlState] = pydantic.Field(
122
+ control_states: list[ControlState] = pydantic.Field(
125
123
  default_factory=list,
126
124
  description="Call the controlled function with the given controlled states.",
127
125
  )
@@ -146,9 +144,15 @@ class SynthesisQuantumFunctionCall(BaseModel):
146
144
  )
147
145
  name: PydanticNonEmptyString = pydantic.Field(
148
146
  default=None,
147
+ validate_default=True,
149
148
  description="The name of the function instance. "
150
149
  "If not set, determined automatically.",
151
150
  )
151
+ source_id: Optional[UUID] = pydantic.Field(default=None)
152
+ arithmetic_id: Optional[str] = pydantic.Field(default=None)
153
+ inverse_op_id: Optional[UUID] = pydantic.Field(default=None)
154
+
155
+ uuid: UUID = pydantic.Field(default_factory=uuid4)
152
156
 
153
157
  def __eq__(self, other: Any) -> bool:
154
158
  return (
@@ -159,14 +163,14 @@ class SynthesisQuantumFunctionCall(BaseModel):
159
163
  return hash(self.name)
160
164
 
161
165
  @property
162
- def non_zero_input_wires(self) -> List[WireName]:
166
+ def non_zero_input_wires(self) -> list[WireName]:
163
167
  in_out_input_wires = [
164
168
  split_wire_pair_to_wires(inout)[0] for inout in self.inouts.values()
165
169
  ]
166
170
  return get_non_zero_wires(self.inputs_dict.values()) + in_out_input_wires
167
171
 
168
172
  @property
169
- def non_zero_output_wires(self) -> List[WireName]:
173
+ def non_zero_output_wires(self) -> list[WireName]:
170
174
  in_out_output_wires = [
171
175
  split_wire_pair_to_wires(inout)[1] for inout in self.inouts.values()
172
176
  ]
@@ -209,8 +213,9 @@ class SynthesisQuantumFunctionCall(BaseModel):
209
213
  return self.function_params.inputs_full(self.strict_zero_ios)
210
214
  return self.function_params.outputs
211
215
 
212
- @pydantic.validator("name", pre=True, always=True)
213
- def _create_name(cls, name: Optional[str], values: Dict[str, Any]) -> str:
216
+ @pydantic.field_validator("name", mode="before")
217
+ @classmethod
218
+ def _create_name(cls, name: Optional[str], info: ValidationInfo) -> str:
214
219
  """
215
220
  generates a name to a user defined-functions as follows:
216
221
  <function_name>_<SUFFIX_MARKER>_<random_suffix>
@@ -221,9 +226,9 @@ class SynthesisQuantumFunctionCall(BaseModel):
221
226
  raise ClassiqValueError(BAD_CALL_NAME_ERROR_MSG)
222
227
  return name
223
228
 
224
- function = values.get("function")
229
+ function = info.data.get("function")
225
230
 
226
- params = values.get("function_params")
231
+ params = info.data.get("function_params")
227
232
  if (
228
233
  isinstance(params, CustomFunction)
229
234
  and function == CustomFunction.discriminator()
@@ -234,27 +239,32 @@ class SynthesisQuantumFunctionCall(BaseModel):
234
239
  suffix = f"{SUFFIX_MARKER}_{randomize_suffix()}"
235
240
  if not function or params is None:
236
241
  return name if name else suffix
237
- return f"{function.split(f'_{EXPANDED_KEYWORD}')[0]}_{suffix}"
242
+ return f"{generate_original_function_name(function)}_{suffix}"
238
243
 
239
- @pydantic.root_validator(pre=True)
240
- def validate_composite_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
241
- if isinstance(values.get("unitary_params"), CustomFunction) and not values.get(
242
- "unitary"
244
+ @pydantic.model_validator(mode="before")
245
+ @classmethod
246
+ def validate_composite_name(cls, values: Any) -> dict[str, Any]:
247
+ if (
248
+ isinstance(values, dict)
249
+ and isinstance(values.get("unitary_params"), CustomFunction)
250
+ and not values.get("unitary")
243
251
  ):
244
252
  raise ClassiqValueError(
245
253
  "`PhaseEstimation` of a user define function (`CustomFunction`) must receive the function name from the `unitary` field"
246
254
  )
247
255
  return values
248
256
 
249
- @pydantic.root_validator(pre=True)
250
- def _parse_function_params(cls, values: Dict[str, Any]) -> Dict[str, Any]:
251
- f_params.parse_function_params_values(
252
- values=values,
253
- params_key="function_params",
254
- discriminator_key="function",
255
- param_classes=function_param_list.function_param_library.param_list,
256
- default_parser_class=CustomFunction,
257
- )
257
+ @pydantic.model_validator(mode="before")
258
+ @classmethod
259
+ def _parse_function_params(cls, values: Any) -> dict[str, Any]:
260
+ if isinstance(values, dict):
261
+ f_params.parse_function_params_values(
262
+ values=values,
263
+ params_key="function_params",
264
+ discriminator_key="function",
265
+ param_classes=function_param_list.function_param_library.param_list,
266
+ default_parser_class=CustomFunction,
267
+ )
258
268
  return values
259
269
 
260
270
  # TODO: note that this checks QuantumFunctionCall input register names
@@ -266,7 +276,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
266
276
  params: f_params.FunctionParams,
267
277
  inputs: WireDict,
268
278
  is_inverse: bool,
269
- control_states: List[ControlState],
279
+ control_states: list[ControlState],
270
280
  strict_zero_ios: bool,
271
281
  ) -> None:
272
282
  (
@@ -290,22 +300,25 @@ class SynthesisQuantumFunctionCall(BaseModel):
290
300
  if error_msg:
291
301
  raise ClassiqValueError("\n".join(error_msg))
292
302
 
293
- @pydantic.validator("strict_zero_ios")
303
+ @pydantic.field_validator("strict_zero_ios")
304
+ @classmethod
294
305
  def _validate_arithmetic_cannot_strict_zero_ios(
295
- cls, strict_zero_ios: bool, values: Dict[str, Any]
306
+ cls, strict_zero_ios: bool, info: ValidationInfo
296
307
  ) -> bool:
297
308
  assert not (
298
- values.get("function") == Arithmetic.discriminator() and not strict_zero_ios
309
+ info.data.get("function") == Arithmetic.discriminator()
310
+ and not strict_zero_ios
299
311
  ), "when using the Arithmetic function, assign to the expression result register via the target parameter instead of the strict_zero_ios flag"
300
312
  return strict_zero_ios
301
313
 
302
- @pydantic.validator("control_states")
314
+ @pydantic.field_validator("control_states")
315
+ @classmethod
303
316
  def _validate_control_states(
304
- cls, control_states: List[ControlState], values: Dict[str, Any]
305
- ) -> List[ControlState]:
317
+ cls, control_states: list[ControlState], info: ValidationInfo
318
+ ) -> list[ControlState]:
306
319
  control_names = [ctrl_state.name for ctrl_state in control_states]
307
- function_params = values.get("function_params")
308
- strict_zero_ios = values.get("strict_zero_ios")
320
+ function_params = info.data.get("function_params")
321
+ strict_zero_ios = info.data.get("strict_zero_ios")
309
322
  if not (
310
323
  isinstance(function_params, FunctionParams)
311
324
  and isinstance(strict_zero_ios, bool)
@@ -333,10 +346,10 @@ class SynthesisQuantumFunctionCall(BaseModel):
333
346
  inputs: IOType,
334
347
  fp: FunctionParams,
335
348
  strict_zero_ios: bool,
336
- control_states: List[ControlState],
349
+ control_states: list[ControlState],
337
350
  ) -> None:
338
351
  name_slice_pairs = [parse_io_slicing(input) for input in inputs]
339
- slices_dict: Dict[str, List[slice]] = defaultdict(list)
352
+ slices_dict: dict[str, list[slice]] = defaultdict(list)
340
353
  for name, slice in name_slice_pairs:
341
354
  slices_dict[name].append(slice)
342
355
 
@@ -358,7 +371,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
358
371
  raise ClassiqValueError(BAD_INPUT_SLICING_MSG)
359
372
 
360
373
  @staticmethod
361
- def _register_validate_slices(slices: List[slice], reg_width: int) -> bool:
374
+ def _register_validate_slices(slices: list[slice], reg_width: int) -> bool:
362
375
  widths_separated = [len(range(reg_width)[reg_slice]) for reg_slice in slices]
363
376
  # examples: slice(0), slice(5,None) when width <= 5, slice(5,3)
364
377
  empty_slices = 0 in widths_separated
@@ -377,12 +390,13 @@ class SynthesisQuantumFunctionCall(BaseModel):
377
390
 
378
391
  return not any((empty_slices, out_of_range, overlapping_slices))
379
392
 
380
- @pydantic.validator("inputs")
381
- def _validate_inputs(cls, inputs: IOType, values: Dict[str, Any]) -> WireDict:
382
- params: Optional[FunctionParams] = values.get("function_params")
383
- is_inverse: bool = values.get("is_inverse", False)
384
- strict_zero_ios: bool = values.get("strict_zero_ios", True)
385
- control_states: List[ControlState] = values.get("control_states", list())
393
+ @pydantic.field_validator("inputs", mode="before")
394
+ @classmethod
395
+ def _validate_inputs(cls, inputs: IOType, info: ValidationInfo) -> WireDict:
396
+ params: Optional[FunctionParams] = info.data.get("function_params")
397
+ is_inverse: bool = info.data.get("is_inverse", False)
398
+ strict_zero_ios: bool = info.data.get("strict_zero_ios", True)
399
+ control_states: list[ControlState] = info.data.get("control_states", list())
386
400
  if params is None:
387
401
  return dict()
388
402
  if isinstance(params, CustomFunction):
@@ -423,7 +437,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
423
437
  params: f_params.FunctionParams,
424
438
  outputs: WireDict,
425
439
  is_inverse: bool,
426
- control_states: List[ControlState],
440
+ control_states: list[ControlState],
427
441
  strict_zero_ios: bool,
428
442
  ) -> None:
429
443
  (
@@ -447,12 +461,13 @@ class SynthesisQuantumFunctionCall(BaseModel):
447
461
  if error_msg:
448
462
  raise ClassiqValueError("\n".join(error_msg))
449
463
 
450
- @pydantic.validator("outputs")
451
- def _validate_outputs(cls, outputs: IOType, values: Dict[str, Any]) -> IOType:
452
- params = values.get("function_params")
453
- is_inverse: bool = values.get("is_inverse", False)
454
- strict_zero_ios: bool = values.get("strict_zero_ios", True)
455
- control_states = values.get("control_states", list())
464
+ @pydantic.field_validator("outputs", mode="before")
465
+ @classmethod
466
+ def _validate_outputs(cls, outputs: IOType, info: ValidationInfo) -> IOType:
467
+ params = info.data.get("function_params")
468
+ is_inverse: bool = info.data.get("is_inverse", False)
469
+ strict_zero_ios: bool = info.data.get("strict_zero_ios", True)
470
+ control_states = info.data.get("control_states", list())
456
471
  if params is None:
457
472
  return outputs
458
473
  if isinstance(params, CustomFunction):
@@ -487,15 +502,16 @@ class SynthesisQuantumFunctionCall(BaseModel):
487
502
 
488
503
  return outputs
489
504
 
490
- @pydantic.validator("power", always=True)
505
+ @pydantic.field_validator("power")
506
+ @classmethod
491
507
  def _validate_power(
492
- cls, power: pydantic.NonNegativeInt, values: Dict[str, Any]
508
+ cls, power: pydantic.NonNegativeInt, info: ValidationInfo
493
509
  ) -> pydantic.NonNegativeInt:
494
- function_params = values.get("function_params")
510
+ function_params = info.data.get("function_params")
495
511
  if function_params is None:
496
512
  return power
497
513
  if power != 1 and not function_params.is_powerable(
498
- values.get("strict_zero_ios")
514
+ info.data.get("strict_zero_ios")
499
515
  ):
500
516
  raise ClassiqValueError("Cannot power this operator")
501
517
  return power
@@ -530,15 +546,15 @@ class SynthesisQuantumFunctionCall(BaseModel):
530
546
  expressions: Iterable[str],
531
547
  params: f_params.FunctionParams,
532
548
  io: f_params.PortDirection,
533
- control_states: List[ControlState],
549
+ control_states: list[ControlState],
534
550
  strict_zero_ios: bool,
535
- ) -> Tuple[List[str], List[str], List[str]]:
551
+ ) -> tuple[list[str], list[str], list[str]]:
536
552
  expression_matches: Iterable[Optional[Match]] = map(
537
553
  functools.partial(re.fullmatch, IO_REGEX), expressions
538
554
  )
539
555
 
540
- valid_matches: List[Match] = []
541
- invalid_expressions: List[str] = []
556
+ valid_matches: list[Match] = []
557
+ invalid_expressions: list[str] = []
542
558
  for expression, expression_match in zip(expressions, expression_matches):
543
559
  (
544
560
  invalid_expressions.append(expression)
@@ -546,8 +562,8 @@ class SynthesisQuantumFunctionCall(BaseModel):
546
562
  else valid_matches.append(expression_match)
547
563
  )
548
564
 
549
- invalid_slicings: List[str] = []
550
- invalid_names: List[str] = []
565
+ invalid_slicings: list[str] = []
566
+ invalid_names: list[str] = []
551
567
  valid_names = frozenset(
552
568
  params.inputs_full(strict_zero_ios)
553
569
  if io == PortDirection.Input
@@ -628,8 +644,7 @@ class SynthesisQuantumFunctionCall(BaseModel):
628
644
  call_kwargs["control_states"] = self.control_states + [control_state]
629
645
  return SynthesisQuantumFunctionCall(**call_kwargs)
630
646
 
631
- class Config:
632
- extra = Extra.forbid
647
+ model_config = ConfigDict(extra="forbid")
633
648
 
634
649
 
635
650
  def _generate_single_io_err(
@@ -1,11 +1,16 @@
1
1
  import uuid
2
- from datetime import datetime
2
+ from datetime import datetime, timezone
3
3
  from pathlib import Path
4
- from typing import Dict, List, Optional, Tuple, Union
4
+ from typing import Optional, Union
5
5
 
6
6
  import pydantic
7
7
  from typing_extensions import TypeAlias
8
8
 
9
+ from classiq.interface.exceptions import (
10
+ ClassiqMissingOutputFormatError,
11
+ ClassiqStateInitializationError,
12
+ )
13
+ from classiq.interface.execution.primitives import PrimitivesInput
9
14
  from classiq.interface.executor import quantum_code
10
15
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
11
16
  from classiq.interface.executor.register_initialization import RegisterInitialization
@@ -17,7 +22,7 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
17
22
  CodeAndSyntax,
18
23
  )
19
24
  from classiq.interface.generator.generated_circuit_data import (
20
- FunctionDebugInfo,
25
+ FunctionDebugInfoInterface,
21
26
  GeneratedCircuitData,
22
27
  )
23
28
  from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
@@ -26,22 +31,17 @@ from classiq.interface.generator.synthesis_metadata.synthesis_duration import (
26
31
  SynthesisStepDurations,
27
32
  )
28
33
  from classiq.interface.helpers.versioned_model import VersionedModel
29
- from classiq.interface.ide.ide_data import CircuitMetrics
30
-
31
- from classiq.exceptions import (
32
- ClassiqMissingOutputFormatError,
33
- ClassiqStateInitializationError,
34
- )
34
+ from classiq.interface.ide.visual_model import CircuitMetrics
35
35
 
36
36
  RegisterName: TypeAlias = str
37
- InitialConditions: TypeAlias = Dict[RegisterName, int]
37
+ InitialConditions: TypeAlias = dict[RegisterName, int]
38
38
 
39
39
 
40
40
  class TranspiledCircuitData(CircuitCodeInterface):
41
41
  depth: int
42
- count_ops: Dict[str, int]
43
- logical_to_physical_input_qubit_map: List[int]
44
- logical_to_physical_output_qubit_map: List[int]
42
+ count_ops: dict[str, int]
43
+ logical_to_physical_input_qubit_map: list[int]
44
+ logical_to_physical_output_qubit_map: list[int]
45
45
 
46
46
  def get_circuit_metrics(self) -> CircuitMetrics:
47
47
  return CircuitMetrics(depth=self.depth, count_ops=self.count_ops)
@@ -51,16 +51,25 @@ def get_uuid_as_str() -> str:
51
51
  return str(uuid.uuid4())
52
52
 
53
53
 
54
+ def _get_formatted_utc_current_time() -> str:
55
+ # The purpose of this method is to replicate the behavior of
56
+ # datetime.utcnow().isoformat(), since `utcnow` is now deprecated
57
+ return datetime.now(timezone.utc).isoformat().split("+")[0]
58
+
59
+
54
60
  class QuantumProgram(VersionedModel, CircuitCodeInterface):
55
61
  hardware_data: SynthesisHardwareData
56
- initial_values: Optional[InitialConditions]
62
+ initial_values: Optional[InitialConditions] = pydantic.Field(default=None)
57
63
  data: GeneratedCircuitData
58
64
  model: ExecutionModel
59
- transpiled_circuit: Optional[TranspiledCircuitData]
60
- creation_time: str = pydantic.Field(default_factory=datetime.utcnow().isoformat)
61
- synthesis_duration: Optional[SynthesisStepDurations]
62
- debug_info: Optional[List[FunctionDebugInfo]]
65
+ transpiled_circuit: Optional[TranspiledCircuitData] = pydantic.Field(default=None)
66
+ creation_time: str = pydantic.Field(default_factory=_get_formatted_utc_current_time)
67
+ synthesis_duration: Optional[SynthesisStepDurations] = pydantic.Field(default=None)
68
+ debug_info: Optional[list[FunctionDebugInfoInterface]] = pydantic.Field(
69
+ default=None
70
+ )
63
71
  program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
72
+ execution_primitives_input: Optional[PrimitivesInput] = pydantic.Field(default=None)
64
73
 
65
74
  def _hardware_agnostic_program_code(self) -> CodeAndSyntax:
66
75
  circuit_code = self.program_circuit.get_code_by_priority()
@@ -114,7 +123,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
114
123
  synthesis_execution_data=self.data.execution_data,
115
124
  )
116
125
 
117
- def _get_initialization_qubits(self, name: str) -> Tuple[int, ...]:
126
+ def _get_initialization_qubits(self, name: str) -> tuple[int, ...]:
118
127
  qubits = self.data.qubit_mapping.logical_inputs.get(name)
119
128
  if qubits is None:
120
129
  raise ClassiqStateInitializationError(
@@ -124,7 +133,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
124
133
 
125
134
  def get_registers_initialization(
126
135
  self, initial_values: InitialConditions
127
- ) -> Dict[RegisterName, RegisterInitialization]:
136
+ ) -> dict[RegisterName, RegisterInitialization]:
128
137
  return {
129
138
  name: RegisterInitialization(
130
139
  name=name,
@@ -136,11 +145,10 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
136
145
 
137
146
  def save_results(self, filename: Optional[Union[str, Path]] = None) -> None:
138
147
  """
139
- Saves quantum program results as json.
148
+ Saves quantum program results as json into a file.
140
149
  Parameters:
141
150
  filename (Union[str, Path]): Optional, path + filename of file.
142
151
  If filename supplied add `.json` suffix.
143
-
144
152
  Returns:
145
153
  None
146
154
  """
@@ -148,11 +156,20 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
148
156
  filename = f"synthesised_circuit_{self.creation_time}.json"
149
157
 
150
158
  with open(filename, "w") as file:
151
- file.write(self.json(indent=4))
159
+ file.write(self.model_dump_json(indent=4))
152
160
 
153
161
  @classmethod
154
162
  def from_qprog(cls, qprog: str) -> "QuantumProgram":
155
- return cls.parse_raw(qprog)
163
+ """
164
+ Creates a `QuantumProgram` instance from a raw quantum program string.
165
+
166
+ Args:
167
+ qprog: The raw quantum program in string format.
168
+
169
+ Returns:
170
+ QuantumProgram: The `QuantumProgram` instance.
171
+ """
172
+ return cls.model_validate_json(qprog)
156
173
 
157
174
  @property
158
175
  def _can_use_transpiled_code(self) -> bool:
@@ -1,10 +1,11 @@
1
1
  import math
2
- from typing import Any, Dict, Generic, Optional, TypeVar
2
+ from typing import Generic, Optional, TypeVar
3
3
 
4
4
  import pydantic
5
- from pydantic.generics import GenericModel
5
+ from pydantic import BaseModel, ConfigDict
6
+ from typing_extensions import Self
6
7
 
7
- from classiq.exceptions import ClassiqValueError
8
+ from classiq.interface.exceptions import ClassiqValueError
8
9
 
9
10
  RangeType = TypeVar("RangeType", int, float)
10
11
 
@@ -15,17 +16,15 @@ DEF_ATOL: float = 1e-08
15
16
  DEF_RTOL: float = 1e-05
16
17
 
17
18
 
18
- class Range(GenericModel, Generic[RangeType]):
19
+ class Range(BaseModel, Generic[RangeType]):
19
20
  lower_bound: Optional[RangeType] = None
20
21
  upper_bound: Optional[RangeType] = None
22
+ model_config = ConfigDict(frozen=True)
21
23
 
22
- class Config:
23
- frozen = True
24
-
25
- @pydantic.root_validator()
26
- def _validate_bounds_order(cls, values: Dict[str, Any]) -> Dict[str, Any]:
27
- lower_bound = values.get("lower_bound")
28
- upper_bound = values.get("upper_bound")
24
+ @pydantic.model_validator(mode="after")
25
+ def _validate_bounds_order(self) -> Self:
26
+ lower_bound = self.lower_bound
27
+ upper_bound = self.upper_bound
29
28
 
30
29
  if (
31
30
  lower_bound is not None
@@ -34,7 +33,7 @@ class Range(GenericModel, Generic[RangeType]):
34
33
  ):
35
34
  raise ClassiqValueError("lower bound must not be greater than upper bound")
36
35
 
37
- return values
36
+ return self
38
37
 
39
38
  def is_lower_bound_sat_by(
40
39
  self, value: float, atol: float = DEF_ATOL, rtol: float = DEF_RTOL
@@ -1,6 +1,4 @@
1
- from typing import Set
2
-
3
- from classiq._internals.enum_utils import StrEnum
1
+ from classiq.interface.enum_utils import StrEnum
4
2
 
5
3
 
6
4
  class RegisterRole(StrEnum):
@@ -10,9 +8,10 @@ class RegisterRole(StrEnum):
10
8
  ZERO_INPUT = "zero_input"
11
9
  ZERO_OUTPUT = "zero_output"
12
10
  GARBAGE_OUTPUT = "garbage_output"
11
+ EXPLICIT_ZERO_INPUT = "explicit_zero_input"
13
12
 
14
13
  @staticmethod
15
- def output_roles(include_garbage: bool = False) -> Set["RegisterRole"]:
14
+ def output_roles(include_garbage: bool = False) -> set["RegisterRole"]:
16
15
  roles = {
17
16
  RegisterRole.OUTPUT,
18
17
  RegisterRole.ZERO_OUTPUT,
@@ -23,5 +22,18 @@ class RegisterRole(StrEnum):
23
22
  return roles
24
23
 
25
24
  @staticmethod
26
- def input_roles() -> Set["RegisterRole"]:
27
- return {RegisterRole.INPUT, RegisterRole.ZERO_INPUT, RegisterRole.AUXILIARY}
25
+ def input_roles() -> set["RegisterRole"]:
26
+ return {
27
+ RegisterRole.INPUT,
28
+ RegisterRole.ZERO_INPUT,
29
+ RegisterRole.AUXILIARY,
30
+ RegisterRole.EXPLICIT_ZERO_INPUT,
31
+ }
32
+
33
+ @staticmethod
34
+ def clean_output_roles() -> set["RegisterRole"]:
35
+ return {RegisterRole.ZERO_OUTPUT, RegisterRole.AUXILIARY}
36
+
37
+ @staticmethod
38
+ def dirty_output_roles() -> set["RegisterRole"]:
39
+ return {RegisterRole.OUTPUT, RegisterRole.GARBAGE_OUTPUT}
@@ -1,10 +1,10 @@
1
1
  import re
2
- from typing import Match, Optional, Tuple
2
+ from re import Match
3
+ from typing import Optional
3
4
 
5
+ from classiq.interface.exceptions import ClassiqValueError
4
6
  from classiq.interface.generator.function_params import NAME_REGEX
5
7
 
6
- from classiq.exceptions import ClassiqValueError
7
-
8
8
  NAME = "name"
9
9
  SLICING = "slicing"
10
10
  SEPARATOR = ":"
@@ -12,12 +12,12 @@ SLICING_CHARS = rf"[0-9\-{SEPARATOR}]+"
12
12
  IO_REGEX = rf"(?P<{NAME}>{NAME_REGEX})(\[(?P<{SLICING}>{SLICING_CHARS})\])?"
13
13
 
14
14
 
15
- def parse_io_slicing(io_str: str) -> Tuple[str, slice]:
15
+ def parse_io_slicing(io_str: str) -> tuple[str, slice]:
16
16
  name, slicing = separate_name_and_slice(io_str)
17
17
  return name, get_slice(slicing)
18
18
 
19
19
 
20
- def separate_name_and_slice(io_str: str) -> Tuple[str, Optional[str]]:
20
+ def separate_name_and_slice(io_str: str) -> tuple[str, Optional[str]]:
21
21
  match: Optional[Match] = re.fullmatch(IO_REGEX, io_str)
22
22
  if match is None:
23
23
  raise AssertionError("Input/output name validation error")