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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/METADATA +16 -9
  414. classiq-0.65.3.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.3.dist-info}/WHEEL +0 -0
@@ -1,11 +1,14 @@
1
1
  import abc
2
- from typing import Any, Dict, Iterable
2
+ from collections.abc import Iterable
3
+ from typing import Any
3
4
 
4
5
  import pydantic
5
6
 
6
- from classiq.interface.generator.arith import argument_utils
7
+ from classiq.interface.exceptions import ClassiqValueError
8
+ from classiq.interface.generator.arith import argument_utils, number_utils
7
9
  from classiq.interface.generator.arith.argument_utils import RegisterOrConst
8
10
  from classiq.interface.generator.arith.arithmetic_operations import (
11
+ MODULO_WITH_FRACTION_PLACES_ERROR_MSG,
9
12
  ArithmeticOperationParams,
10
13
  )
11
14
  from classiq.interface.generator.arith.binary_ops import (
@@ -15,8 +18,6 @@ from classiq.interface.generator.arith.binary_ops import (
15
18
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
16
19
  from classiq.interface.generator.function_params import get_zero_input_name
17
20
 
18
- from classiq.exceptions import ClassiqValueError
19
-
20
21
  Numeric = (float, int)
21
22
 
22
23
 
@@ -24,16 +25,18 @@ class Extremum(ArithmeticOperationParams):
24
25
  left_arg: RegisterOrConst
25
26
  right_arg: RegisterOrConst
26
27
 
27
- @pydantic.root_validator(pre=True)
28
- def _validate_one_is_register(cls, values: Dict[str, Any]) -> Dict[str, Any]:
29
- left_arg = values.get("left_arg")
30
- right_arg = values.get("right_arg")
31
- if isinstance(left_arg, Numeric) and isinstance(right_arg, Numeric):
32
- raise ClassiqValueError("One argument must be a register")
33
- if left_arg is right_arg and isinstance(left_arg, pydantic.BaseModel):
34
- # In case both arguments refer to the same object, copy it.
35
- # This prevents changes performed on one argument from affecting the other.
36
- values["right_arg"] = left_arg.copy(deep=True)
28
+ @pydantic.model_validator(mode="before")
29
+ @classmethod
30
+ def _validate_one_is_register(cls, values: Any) -> dict[str, Any]:
31
+ if isinstance(values, dict):
32
+ left_arg = values.get("left_arg")
33
+ right_arg = values.get("right_arg")
34
+ if isinstance(left_arg, Numeric) and isinstance(right_arg, Numeric):
35
+ raise ClassiqValueError("One argument must be a register")
36
+ if left_arg is right_arg and isinstance(left_arg, pydantic.BaseModel):
37
+ # In case both arguments refer to the same object, copy it.
38
+ # This prevents changes performed on one argument from affecting the other.
39
+ values["right_arg"] = left_arg.model_copy(deep=True)
37
40
  return values
38
41
 
39
42
  def _create_ios(self) -> None:
@@ -57,31 +60,77 @@ class Extremum(ArithmeticOperationParams):
57
60
  def _bound_calculator(cls, arg1: float, arg2: float) -> float:
58
61
  pass
59
62
 
63
+ @staticmethod
64
+ def _less_qubits_arg(
65
+ arg1: RegisterOrConst, arg2: RegisterOrConst
66
+ ) -> RegisterOrConst:
67
+ if not isinstance(arg1, RegisterArithmeticInfo):
68
+ return arg1
69
+ if not isinstance(arg2, RegisterArithmeticInfo):
70
+ return arg2
71
+ return arg1 if arg1.size <= arg2.size else arg2
72
+
73
+ @classmethod
74
+ @abc.abstractmethod
75
+ def preferred_arg(
76
+ cls, arg1: RegisterOrConst, arg2: RegisterOrConst
77
+ ) -> RegisterOrConst:
78
+ pass
79
+
60
80
  def _get_result_register(self) -> RegisterArithmeticInfo:
81
+ eff_left_arg = argument_utils.limit_fraction_places(
82
+ self.left_arg, self.machine_precision
83
+ )
84
+ eff_right_arg = argument_utils.limit_fraction_places(
85
+ self.right_arg, self.machine_precision
86
+ )
87
+ if argument_utils.arg_bounds_overlap((eff_left_arg, eff_right_arg)):
88
+ return self._get_general_case_result_register(eff_left_arg, eff_right_arg)
89
+ return argument_utils.as_arithmetic_info(
90
+ self.preferred_arg(eff_left_arg, eff_right_arg)
91
+ )
92
+
93
+ def _get_general_case_result_register(
94
+ self, eff_left_arg: RegisterOrConst, eff_right_arg: RegisterOrConst
95
+ ) -> RegisterArithmeticInfo:
61
96
  integer_part_size = max(
62
- argument_utils.integer_part_size(self.left_arg),
63
- argument_utils.integer_part_size(self.right_arg),
97
+ argument_utils.integer_part_size(eff_left_arg),
98
+ argument_utils.integer_part_size(eff_right_arg),
64
99
  )
65
100
  fraction_places = max(
66
- argument_utils.fraction_places(self.left_arg),
67
- argument_utils.fraction_places(self.right_arg),
101
+ argument_utils.fraction_places(eff_left_arg),
102
+ argument_utils.fraction_places(eff_right_arg),
68
103
  )
69
104
  required_size = integer_part_size + fraction_places
70
105
  bounds = (
71
106
  self._bound_calculator(
72
- argument_utils.lower_bound(self.left_arg),
73
- argument_utils.lower_bound(self.right_arg),
107
+ argument_utils.lower_bound(eff_left_arg),
108
+ argument_utils.lower_bound(eff_right_arg),
74
109
  ),
75
110
  self._bound_calculator(
76
- argument_utils.upper_bound(self.left_arg),
77
- argument_utils.upper_bound(self.right_arg),
111
+ argument_utils.upper_bound(eff_left_arg),
112
+ argument_utils.upper_bound(eff_right_arg),
78
113
  ),
79
114
  )
115
+ if self.output_size:
116
+ if fraction_places:
117
+ raise ValueError(MODULO_WITH_FRACTION_PLACES_ERROR_MSG)
118
+ max_bounds = RegisterArithmeticInfo.get_maximal_bounds(
119
+ size=self.output_size, is_signed=False, fraction_places=0
120
+ )
121
+ bounds = number_utils.bounds_cut(bounds, max_bounds)
122
+ size = self.output_size or required_size
123
+ is_signed = self._include_sign and min(bounds) < 0
80
124
  return RegisterArithmeticInfo(
81
- size=self.output_size or required_size,
125
+ size=size,
82
126
  fraction_places=fraction_places,
83
- is_signed=self._include_sign and min(bounds) < 0,
84
- bounds=self._legal_bounds(bounds),
127
+ is_signed=is_signed,
128
+ bounds=self._legal_bounds(
129
+ bounds,
130
+ RegisterArithmeticInfo.get_maximal_bounds(
131
+ size=size, is_signed=is_signed, fraction_places=fraction_places
132
+ ),
133
+ ),
85
134
  )
86
135
 
87
136
 
@@ -92,6 +141,17 @@ class Min(Extremum):
92
141
  def _bound_calculator(cls, arg1: float, arg2: float) -> float:
93
142
  return min(arg1, arg2)
94
143
 
144
+ @classmethod
145
+ def preferred_arg(
146
+ cls, arg1: RegisterOrConst, arg2: RegisterOrConst
147
+ ) -> RegisterOrConst:
148
+ min1, min2 = min(argument_utils.bounds(arg1)), min(argument_utils.bounds(arg2))
149
+ if min1 < min2:
150
+ return arg1
151
+ if min2 < min1:
152
+ return arg2
153
+ return cls._less_qubits_arg(arg1, arg2)
154
+
95
155
 
96
156
  class Max(Extremum):
97
157
  output_name = "max_value"
@@ -99,3 +159,14 @@ class Max(Extremum):
99
159
  @classmethod
100
160
  def _bound_calculator(cls, arg1: float, arg2: float) -> float:
101
161
  return max(arg1, arg2)
162
+
163
+ @classmethod
164
+ def preferred_arg(
165
+ cls, arg1: RegisterOrConst, arg2: RegisterOrConst
166
+ ) -> RegisterOrConst:
167
+ max1, max2 = max(argument_utils.bounds(arg1)), max(argument_utils.bounds(arg2))
168
+ if max1 > max2:
169
+ return arg1
170
+ if max2 > max1:
171
+ return arg2
172
+ return cls._less_qubits_arg(arg1, arg2)
@@ -1,7 +1,10 @@
1
- from typing import Iterable, List, Optional
1
+ from collections.abc import Iterable
2
+ from typing import Optional
2
3
 
3
4
  import pydantic
5
+ from pydantic import ConfigDict
4
6
 
7
+ from classiq.interface.exceptions import ClassiqValueError
5
8
  from classiq.interface.generator.arith.argument_utils import RegisterOrConst
6
9
  from classiq.interface.generator.arith.arithmetic_operations import (
7
10
  ArithmeticOperationParams,
@@ -9,31 +12,31 @@ from classiq.interface.generator.arith.arithmetic_operations import (
9
12
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
10
13
  from classiq.interface.generator.function_params import get_zero_input_name
11
14
 
12
- from classiq.exceptions import ClassiqValueError
13
-
14
15
 
15
16
  def get_arg_name(idx: int) -> str:
16
17
  return f"arg_{idx}"
17
18
 
18
19
 
19
20
  class LogicalOps(ArithmeticOperationParams):
20
- args: List[RegisterOrConst]
21
+ args: list[RegisterOrConst]
21
22
  target: Optional[RegisterArithmeticInfo]
22
- _should_invert_node_list: List[str] = pydantic.PrivateAttr(default_factory=list)
23
+ _should_invert_node_list: list[str] = pydantic.PrivateAttr(default_factory=list)
23
24
 
24
- def update_should_invert_node_list(self, invert_args: List[str]) -> None:
25
+ def update_should_invert_node_list(self, invert_args: list[str]) -> None:
25
26
  self._should_invert_node_list.extend(invert_args)
26
27
 
27
- @pydantic.validator("output_size")
28
+ @pydantic.field_validator("output_size")
29
+ @classmethod
28
30
  def _validate_output_size(cls, output_size: Optional[int]) -> int:
29
31
  if output_size is not None and output_size != 1:
30
32
  raise ClassiqValueError("logical operation output size must be 1")
31
33
  return 1
32
34
 
33
- @pydantic.validator("args")
35
+ @pydantic.field_validator("args")
36
+ @classmethod
34
37
  def _validate_inputs_sizes(
35
- cls, arguments: List[RegisterOrConst]
36
- ) -> List[RegisterOrConst]:
38
+ cls, arguments: list[RegisterOrConst]
39
+ ) -> list[RegisterOrConst]:
37
40
  for arg_idx, arg in enumerate(arguments):
38
41
  if isinstance(arg, RegisterArithmeticInfo) and not arg.is_boolean_register:
39
42
  raise ClassiqValueError(
@@ -65,8 +68,7 @@ class LogicalOps(ArithmeticOperationParams):
65
68
  def get_params_inplace_options(self) -> Iterable["LogicalOps"]:
66
69
  return ()
67
70
 
68
- class Config:
69
- arbitrary_types_allowed = True
71
+ model_config = ConfigDict(arbitrary_types_allowed=True)
70
72
 
71
73
 
72
74
  class LogicalAnd(LogicalOps):
@@ -1,4 +1,4 @@
1
- from typing import Final, Tuple, Union
1
+ from typing import Final, Union
2
2
 
3
3
  MAXIMAL_MACHINE_PRECISION: Final[int] = 20
4
4
 
@@ -12,7 +12,7 @@ def signed_int_to_unsigned(number: int) -> int:
12
12
  return number + 2 ** (number.bit_length() + 1 * not_power2)
13
13
 
14
14
 
15
- def _binary_to_int(bin_rep: str, is_signed: bool) -> int:
15
+ def binary_to_int(bin_rep: str, is_signed: bool = False) -> int:
16
16
  negative_offset: int = -(2 ** len(bin_rep)) * (bin_rep[0] == "1") * is_signed
17
17
  return int(bin_rep, 2) + negative_offset
18
18
 
@@ -20,14 +20,14 @@ def _binary_to_int(bin_rep: str, is_signed: bool) -> int:
20
20
  def binary_to_float(
21
21
  bin_rep: str, fraction_part_size: int = 0, is_signed: bool = False
22
22
  ) -> float:
23
- return _binary_to_int(bin_rep, is_signed) / 2**fraction_part_size
23
+ return binary_to_int(bin_rep, is_signed) / 2**fraction_part_size
24
24
 
25
25
 
26
26
  def binary_to_float_or_int(
27
27
  bin_rep: str, fraction_part_size: int = 0, is_signed: bool = False
28
28
  ) -> Union[float, int]:
29
29
  if fraction_part_size == 0:
30
- return _binary_to_int(bin_rep, is_signed)
30
+ return binary_to_int(bin_rep, is_signed)
31
31
  return binary_to_float(bin_rep, fraction_part_size, is_signed)
32
32
 
33
33
 
@@ -40,7 +40,7 @@ def _get_fraction_places(*, binary_value: str) -> int:
40
40
  return fraction_places
41
41
 
42
42
 
43
- def get_int_representation_and_fraction_places(float_value: float) -> Tuple[int, int]:
43
+ def get_int_representation_and_fraction_places(float_value: float) -> tuple[int, int]:
44
44
  int_val = signed_int_to_unsigned(int(float_value * 2**MAXIMAL_MACHINE_PRECISION))
45
45
  if int_val == 0:
46
46
  return 0, 0
@@ -100,7 +100,7 @@ def bounds_to_integer_part_size(lb: float, ub: float) -> int:
100
100
  )
101
101
 
102
102
 
103
- def limit_fraction_places(number: float, *, machine_precision: int) -> float:
103
+ def limit_fraction_places(number: float, machine_precision: int) -> float:
104
104
  orig_bin_rep = binary_string(number)[::-1]
105
105
  orig_fractions = fraction_places(number)
106
106
 
@@ -110,3 +110,9 @@ def limit_fraction_places(number: float, *, machine_precision: int) -> float:
110
110
  fraction_part_size=orig_fractions - removed_fractions,
111
111
  is_signed=number < 0,
112
112
  )
113
+
114
+
115
+ def bounds_cut(
116
+ bounds1: tuple[float, float], bounds2: tuple[float, float]
117
+ ) -> tuple[float, float]:
118
+ return max(min(bounds1), min(bounds2)), min(max(bounds1), max(bounds2))
@@ -1,55 +1,77 @@
1
- from typing import Any, Dict, Optional
1
+ from typing import Any, Optional
2
2
 
3
3
  import pydantic
4
+ from pydantic import ConfigDict
5
+ from pydantic_core.core_schema import ValidationInfo
4
6
 
7
+ from classiq.interface.exceptions import ClassiqValueError
5
8
  from classiq.interface.generator.arith import number_utils
6
9
  from classiq.interface.helpers.custom_pydantic_types import PydanticFloatTuple
7
10
  from classiq.interface.helpers.hashable_pydantic_base_model import (
8
11
  HashablePydanticBaseModel,
9
12
  )
10
13
 
11
- from classiq.exceptions import ClassiqValueError
12
-
13
14
 
14
15
  class RegisterArithmeticInfo(HashablePydanticBaseModel):
15
- size: pydantic.PositiveInt
16
+ size: pydantic.PositiveInt = pydantic.Field(default=1)
16
17
  is_signed: bool = pydantic.Field(default=False)
17
18
  fraction_places: pydantic.NonNegativeInt = pydantic.Field(default=0)
18
- bounds: PydanticFloatTuple = pydantic.Field(default=None)
19
+ bypass_bounds_validation: bool = pydantic.Field(default=False)
20
+ bounds: PydanticFloatTuple = pydantic.Field(
21
+ default=None,
22
+ validate_default=True,
23
+ )
19
24
 
20
- @pydantic.root_validator(pre=True)
21
- def _remove_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
22
- if "name" in values:
23
- values.pop("name")
25
+ @pydantic.model_validator(mode="before")
26
+ @classmethod
27
+ def _remove_name(cls, values: Any, info: ValidationInfo) -> dict[str, Any]:
28
+ if isinstance(values, dict):
29
+ values = values.copy()
30
+ elif hasattr(values, "__dict__"):
31
+ values = values.__dict__.copy()
32
+ elif values is None and info.data:
33
+ values = info.data.copy()
34
+ else:
35
+ raise ValueError("Unsupported type for removing 'name'.")
36
+
37
+ values.pop("name", None)
24
38
  return values
25
39
 
26
- @pydantic.validator("bounds", always=True)
27
- def _validate_bounds(
28
- cls, bounds: Optional[PydanticFloatTuple], values: Dict[str, Any]
29
- ) -> PydanticFloatTuple:
30
- if bounds is not None:
31
- if min(bounds) < 0:
32
- assert values.get("is_signed")
33
- fraction_places = values.get("fraction_places")
34
- if not isinstance(fraction_places, int):
35
- raise ClassiqValueError(
36
- "RegisterUserInput must have an integer fraction_places"
37
- )
38
- return number_utils.limit_fraction_places(
39
- min(bounds), machine_precision=fraction_places
40
- ), number_utils.limit_fraction_places(
41
- max(bounds), machine_precision=fraction_places
42
- )
43
-
44
- size = values.get("size")
45
- if not isinstance(size, int):
46
- raise ClassiqValueError("RegisterUserInput must have an integer size")
47
- is_signed: bool = values.get("is_signed", False)
40
+ @staticmethod
41
+ def get_maximal_bounds(
42
+ *, size: int, is_signed: bool, fraction_places: int
43
+ ) -> tuple[float, float]:
48
44
  lb = 0 if not is_signed else -(2 ** (size - 1))
49
45
  ub = 2**size - 1 if not is_signed else 2 ** (size - 1) - 1
50
- fraction_factor = float(2 ** -values.get("fraction_places", 0))
46
+ fraction_factor = float(2**-fraction_places)
51
47
  return (lb * fraction_factor, ub * fraction_factor)
52
48
 
49
+ @pydantic.field_validator("bounds", mode="before")
50
+ @classmethod
51
+ def _validate_bounds(
52
+ cls, bounds: Optional[PydanticFloatTuple], info: ValidationInfo
53
+ ) -> PydanticFloatTuple:
54
+ size = info.data.get("size")
55
+ is_signed = info.data.get("is_signed", False)
56
+ fraction_places = info.data.get("fraction_places", 0)
57
+ if not isinstance(size, int):
58
+ raise ClassiqValueError("RegisterArithmeticInfo must have an integer size")
59
+
60
+ maximal_bounds = cls.get_maximal_bounds(
61
+ size=size, is_signed=is_signed, fraction_places=fraction_places
62
+ )
63
+ if bounds is None:
64
+ return maximal_bounds
65
+
66
+ trimmed_bounds = (
67
+ number_utils.limit_fraction_places(min(bounds), fraction_places),
68
+ number_utils.limit_fraction_places(max(bounds), fraction_places),
69
+ )
70
+ if not info.data.get("bypass_bounds_validation", False):
71
+ assert min(trimmed_bounds) >= min(maximal_bounds), "Illegal bound min"
72
+ assert max(trimmed_bounds) <= max(maximal_bounds), "Illegal bound max"
73
+ return trimmed_bounds
74
+
53
75
  def limit_fraction_places(self, machine_precision: int) -> "RegisterArithmeticInfo":
54
76
  truncated_bits: int = max(self.fraction_places - machine_precision, 0)
55
77
  return RegisterArithmeticInfo(
@@ -57,6 +79,7 @@ class RegisterArithmeticInfo(HashablePydanticBaseModel):
57
79
  is_signed=self.is_signed,
58
80
  fraction_places=self.fraction_places - truncated_bits,
59
81
  bounds=self.bounds,
82
+ bypass_bounds_validation=self.bypass_bounds_validation,
60
83
  )
61
84
 
62
85
  @property
@@ -71,8 +94,7 @@ class RegisterArithmeticInfo(HashablePydanticBaseModel):
71
94
  def integer_part_size(self) -> pydantic.NonNegativeInt:
72
95
  return self.size - self.fraction_places
73
96
 
74
- class Config:
75
- frozen = True
97
+ model_config = ConfigDict(frozen=True)
76
98
 
77
99
 
78
100
  class RegisterUserInput(RegisterArithmeticInfo):
@@ -82,12 +104,13 @@ class RegisterUserInput(RegisterArithmeticInfo):
82
104
  super().__init__(**data)
83
105
  self._fields_to_skip_in_hash = frozenset({"name"})
84
106
 
85
- @pydantic.root_validator(pre=True)
86
- def _remove_name(cls, values: Dict[str, Any]) -> Dict[str, Any]:
107
+ @pydantic.model_validator(mode="before")
108
+ @classmethod
109
+ def _remove_name(cls, values: Any, info: ValidationInfo) -> dict[str, Any]:
87
110
  return values
88
111
 
89
112
  def revalued(self, **kwargs: Any) -> "RegisterUserInput":
90
- return self.copy(update=kwargs)
113
+ return self.model_copy(update=kwargs)
91
114
 
92
115
  @classmethod
93
116
  def from_arithmetic_info(
@@ -1,17 +1,19 @@
1
- from typing import TYPE_CHECKING, Iterable, Optional
1
+ from collections.abc import Iterable
2
+ from typing import TYPE_CHECKING, Final, Optional
2
3
 
3
4
  import pydantic
5
+ from pydantic import ConfigDict
4
6
 
7
+ from classiq.interface.exceptions import ClassiqValueError
5
8
  from classiq.interface.generator.arith import argument_utils, number_utils
6
9
  from classiq.interface.generator.arith.arithmetic_operations import (
10
+ MODULO_WITH_FRACTION_PLACES_ERROR_MSG,
7
11
  ArithmeticOperationParams,
8
12
  )
9
13
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
10
14
  from classiq.interface.generator.function_params import get_zero_input_name
11
15
 
12
- from classiq.exceptions import ClassiqValueError
13
-
14
- UNARY_ARG_NAME: str = "arg"
16
+ UNARY_ARG_NAME: Final[str] = "arg"
15
17
 
16
18
 
17
19
  class UnaryOpParams(ArithmeticOperationParams):
@@ -19,17 +21,16 @@ class UnaryOpParams(ArithmeticOperationParams):
19
21
  inplace: bool = False
20
22
 
21
23
  def garbage_output_size(self) -> pydantic.NonNegativeInt:
22
- return int(self.is_inplaced()) * max(
23
- self.arg.size - self.result_register.size, 0
24
+ return int(self.is_inplaced()) * (
25
+ max(self.arg.integer_part_size - self.result_register.integer_part_size, 0)
26
+ + max(self.arg.fraction_places - self.result_register.fraction_places, 0)
24
27
  )
25
28
 
26
29
  def should_add_zero_inputs(self) -> bool:
27
- return not self.is_inplaced() or self.should_add_zero_input_for_extension()
30
+ return not self.is_inplaced() or self.zero_input_for_extension() > 0
28
31
 
29
- def should_add_zero_input_for_extension(
30
- self, output_size: Optional[int] = None
31
- ) -> bool:
32
- return (output_size or self.result_register.size) > self.arg.size
32
+ def zero_input_for_extension(self) -> pydantic.NonNegativeInt:
33
+ return max(0, self.result_register.size - self.arg.size)
33
34
 
34
35
  def _create_ios(self) -> None:
35
36
  self._inputs = {UNARY_ARG_NAME: self.arg}
@@ -41,8 +42,8 @@ class UnaryOpParams(ArithmeticOperationParams):
41
42
  zero_input_register = self.result_register
42
43
  self._zero_inputs = {zero_input_name: zero_input_register}
43
44
  return
44
- if self.should_add_zero_input_for_extension():
45
- output_extension_size = self.result_register.size - self.arg.size
45
+ if self.zero_input_for_extension() > 0:
46
+ output_extension_size = self.zero_input_for_extension()
46
47
  self._create_zero_input_registers({zero_input_name: output_extension_size})
47
48
  if self.garbage_output_size() > 0:
48
49
  self._outputs[self.garbage_output_name] = RegisterArithmeticInfo(
@@ -53,21 +54,18 @@ class UnaryOpParams(ArithmeticOperationParams):
53
54
  return self.inplace
54
55
 
55
56
  def get_params_inplace_options(self) -> Iterable["UnaryOpParams"]:
56
- params_kwargs = self.copy().__dict__
57
+ params_kwargs = self.model_copy().model_dump()
57
58
  params_kwargs["inplace"] = True
58
59
  yield self.__class__(**params_kwargs)
59
60
 
60
- class Config:
61
- arbitrary_types_allowed = True
61
+ model_config = ConfigDict(arbitrary_types_allowed=True)
62
62
 
63
63
 
64
64
  class BitwiseInvert(UnaryOpParams):
65
65
  output_name = "inverted"
66
66
 
67
67
  def _get_result_register(self) -> RegisterArithmeticInfo:
68
- eff_arg = argument_utils.limit_fraction_places(
69
- self.arg, machine_precision=self.machine_precision
70
- )
68
+ eff_arg = argument_utils.limit_fraction_places(self.arg, self.machine_precision)
71
69
  if TYPE_CHECKING:
72
70
  assert isinstance(eff_arg, RegisterArithmeticInfo)
73
71
  return RegisterArithmeticInfo(
@@ -78,30 +76,52 @@ class BitwiseInvert(UnaryOpParams):
78
76
 
79
77
 
80
78
  class Negation(UnaryOpParams):
79
+ bypass_bounds_validation: bool = pydantic.Field(
80
+ default=False
81
+ ) # True for efficient subtraction
81
82
  output_name = "negated"
82
83
 
83
- def _expected_result_size(self) -> pydantic.PositiveInt:
84
- if self.arg.size == 1:
84
+ @staticmethod
85
+ def _expected_result_size(arg: RegisterArithmeticInfo) -> pydantic.PositiveInt:
86
+ if arg.size == 1:
85
87
  return 1
86
- return self.arg.fraction_places + number_utils.bounds_to_integer_part_size(
87
- *(-bound for bound in self.arg.bounds)
88
+ return arg.fraction_places + number_utils.bounds_to_integer_part_size(
89
+ *(-bound for bound in arg.bounds)
88
90
  )
89
91
 
90
92
  def _get_result_register(self) -> RegisterArithmeticInfo:
91
- is_signed = max(self.arg.bounds) > 0 and self._include_sign
92
- bounds = (-max(self.arg.bounds), -min(self.arg.bounds))
93
+ eff_arg = self.arg.limit_fraction_places(self.machine_precision)
94
+ is_signed = max(eff_arg.bounds) > 0 and self._include_sign
95
+ bounds = (-max(eff_arg.bounds), -min(eff_arg.bounds))
96
+ if self.output_size and not self.bypass_bounds_validation:
97
+ if eff_arg.fraction_places:
98
+ raise ValueError(MODULO_WITH_FRACTION_PLACES_ERROR_MSG)
99
+ max_bounds = RegisterArithmeticInfo.get_maximal_bounds(
100
+ size=self.output_size, is_signed=False, fraction_places=0
101
+ )
102
+ bounds = number_utils.bounds_cut(bounds, max_bounds)
93
103
  return RegisterArithmeticInfo(
94
- size=self.output_size or self._expected_result_size(),
95
- fraction_places=self.arg.fraction_places,
104
+ size=self.output_size or self._expected_result_size(eff_arg),
105
+ fraction_places=eff_arg.fraction_places,
96
106
  is_signed=is_signed,
97
- bounds=bounds if (is_signed or min(bounds) >= 0) else None,
107
+ bypass_bounds_validation=self.bypass_bounds_validation,
108
+ bounds=bounds,
98
109
  )
99
110
 
111
+ def zero_input_for_extension(self) -> pydantic.NonNegativeInt:
112
+ eff_arg = self.arg.limit_fraction_places(self.machine_precision)
113
+ if (self.output_size or eff_arg.size) == 1:
114
+ return 0
115
+ return (
116
+ self.output_size or self._expected_result_size(self.arg)
117
+ ) - self.arg.size
118
+
100
119
 
101
120
  class Sign(UnaryOpParams):
102
121
  output_name = "sign"
103
122
 
104
- @pydantic.validator("output_size")
123
+ @pydantic.field_validator("output_size")
124
+ @classmethod
105
125
  def _validate_output_size(
106
126
  cls, output_size: Optional[pydantic.PositiveInt]
107
127
  ) -> pydantic.PositiveInt:
@@ -1,4 +1,4 @@
1
- from classiq._internals.enum_utils import StrEnum
1
+ from classiq.interface.enum_utils import StrEnum
2
2
 
3
3
 
4
4
  class UncomputationMethods(StrEnum):
@@ -1,19 +1,12 @@
1
- from typing import Any, Iterable
1
+ from collections.abc import Iterable
2
+ from typing import Any
2
3
 
3
4
  from classiq.interface.generator.functions.classical_function_declaration import (
4
5
  ClassicalFunctionDeclaration,
5
6
  )
6
- from classiq.interface.generator.types.struct_declaration import StructDeclaration
7
- from classiq.interface.model.quantum_function_declaration import (
8
- QuantumFunctionDeclaration,
9
- )
10
7
 
11
8
 
12
9
  def populate_builtin_declarations(decls: Iterable[Any]) -> None:
13
10
  for decl in decls:
14
- if isinstance(decl, QuantumFunctionDeclaration):
15
- QuantumFunctionDeclaration.BUILTIN_FUNCTION_DECLARATIONS[decl.name] = decl
16
11
  if isinstance(decl, ClassicalFunctionDeclaration):
17
12
  ClassicalFunctionDeclaration.FOREIGN_FUNCTION_DECLARATIONS[decl.name] = decl
18
- if isinstance(decl, StructDeclaration):
19
- StructDeclaration.BUILTIN_STRUCT_DECLARATIONS[decl.name] = decl
@@ -4,6 +4,7 @@ from classiq.interface.chemistry.ground_state_problem import (
4
4
  CHEMISTRY_PROBLEMS_TYPE,
5
5
  GroundStateProblem,
6
6
  )
7
+ from classiq.interface.exceptions import ClassiqValueError
7
8
  from classiq.interface.generator.arith.register_user_input import RegisterUserInput
8
9
  from classiq.interface.generator.function_params import (
9
10
  DEFAULT_INPUT_NAME,
@@ -11,13 +12,12 @@ from classiq.interface.generator.function_params import (
11
12
  FunctionParams,
12
13
  )
13
14
 
14
- from classiq.exceptions import ClassiqValueError
15
-
16
15
 
17
16
  class ChemistryFunctionParams(FunctionParams):
18
17
  gs_problem: CHEMISTRY_PROBLEMS_TYPE
19
18
 
20
- @pydantic.validator("gs_problem")
19
+ @pydantic.field_validator("gs_problem")
20
+ @classmethod
21
21
  def validate_gs_problem_contains_num_qubits(
22
22
  cls, gs_problem: CHEMISTRY_PROBLEMS_TYPE
23
23
  ) -> CHEMISTRY_PROBLEMS_TYPE:
@@ -1,7 +1,8 @@
1
- from typing import Dict, Optional
1
+ from typing import Optional
2
2
 
3
3
  import pydantic
4
4
 
5
+ from classiq.interface.exceptions import ClassiqMissingOutputFormatError
5
6
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
6
7
  from classiq.interface.generator.circuit_code.types_and_constants import (
7
8
  INSTRUCTION_SET_TO_FORMAT,
@@ -12,17 +13,16 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
12
13
  )
13
14
  from classiq.interface.generator.model.preferences.preferences import QuantumFormat
14
15
 
15
- from classiq.exceptions import ClassiqMissingOutputFormatError
16
-
17
16
 
18
17
  class CircuitCodeInterface(pydantic.BaseModel):
19
- outputs: Dict[QuantumFormat, Code]
18
+ outputs: dict[QuantumFormat, Code]
20
19
  qasm_version: QasmVersion
21
20
 
22
- @pydantic.validator("outputs")
21
+ @pydantic.field_validator("outputs")
22
+ @classmethod
23
23
  def reformat_long_string_output_formats(
24
- cls, outputs: Dict[QuantumFormat, str]
25
- ) -> Dict[QuantumFormat, LongStr]:
24
+ cls, outputs: dict[QuantumFormat, str]
25
+ ) -> dict[QuantumFormat, LongStr]:
26
26
  return {key: LongStr(value) for key, value in outputs.items()}
27
27
 
28
28
  @property