classiq 0.37.1__py3-none-any.whl → 0.65.3__py3-none-any.whl

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