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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. classiq/__init__.py +47 -32
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
  3. classiq/_internals/api_wrapper.py +235 -97
  4. classiq/_internals/async_utils.py +1 -3
  5. classiq/_internals/authentication/auth0.py +26 -10
  6. classiq/_internals/authentication/authentication.py +11 -0
  7. classiq/_internals/authentication/device.py +10 -5
  8. classiq/_internals/authentication/password_manager.py +18 -6
  9. classiq/_internals/authentication/token_manager.py +10 -5
  10. classiq/_internals/client.py +94 -33
  11. classiq/_internals/config.py +3 -4
  12. classiq/_internals/host_checker.py +38 -15
  13. classiq/_internals/jobs.py +60 -57
  14. classiq/_internals/type_validation.py +9 -9
  15. classiq/analyzer/__init__.py +1 -3
  16. classiq/analyzer/analyzer.py +24 -19
  17. classiq/analyzer/analyzer_utilities.py +10 -10
  18. classiq/analyzer/rb.py +15 -15
  19. classiq/analyzer/show_interactive_hack.py +27 -4
  20. classiq/analyzer/url_utils.py +2 -3
  21. classiq/applications/__init__.py +3 -12
  22. classiq/applications/chemistry/__init__.py +14 -10
  23. classiq/applications/chemistry/ansatz_parameters.py +4 -4
  24. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +165 -158
  25. classiq/applications/chemistry/ground_state_problem.py +1 -1
  26. classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +4 -1
  27. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
  28. classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +1 -1
  29. classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +51 -15
  30. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +12 -12
  31. classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +8 -6
  32. classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +7 -11
  33. classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +67 -40
  34. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +46 -0
  35. classiq/applications/combinatorial_helpers/pyomo_utils.py +447 -0
  36. classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +2 -2
  37. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +15 -20
  38. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +14 -15
  39. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +11 -15
  40. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +1 -2
  41. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
  42. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +2 -3
  43. classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +5 -8
  44. classiq/applications/combinatorial_optimization/__init__.py +20 -6
  45. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
  46. classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +35 -33
  47. classiq/applications/combinatorial_optimization/combinatorial_problem.py +229 -0
  48. classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
  49. classiq/applications/finance/__init__.py +4 -5
  50. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +48 -42
  51. classiq/applications/grover/__init__.py +9 -0
  52. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +52 -51
  53. classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
  54. classiq/applications/libraries/qmci_library.py +22 -0
  55. classiq/applications/qnn/__init__.py +2 -4
  56. classiq/applications/qnn/circuit_utils.py +6 -6
  57. classiq/applications/qnn/datasets/__init__.py +9 -11
  58. classiq/applications/qnn/datasets/dataset_base_classes.py +7 -5
  59. classiq/applications/qnn/datasets/dataset_not.py +2 -1
  60. classiq/applications/qnn/datasets/dataset_parity.py +2 -2
  61. classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
  62. classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
  63. classiq/applications/qnn/qlayer.py +30 -10
  64. classiq/applications/qnn/torch_utils.py +4 -3
  65. classiq/applications/qnn/types.py +5 -5
  66. classiq/applications/qsvm/__init__.py +6 -4
  67. classiq/applications/qsvm/qsvm.py +3 -6
  68. classiq/applications/qsvm/qsvm_data_generation.py +3 -3
  69. classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +30 -28
  70. classiq/execution/__init__.py +8 -3
  71. classiq/execution/all_hardware_devices.py +11 -0
  72. classiq/execution/execution_session.py +400 -0
  73. classiq/execution/iqcc.py +63 -0
  74. classiq/execution/jobs.py +197 -25
  75. classiq/execution/qnn.py +79 -0
  76. classiq/executor.py +20 -115
  77. classiq/interface/_version.py +1 -1
  78. classiq/interface/analyzer/analysis_params.py +43 -13
  79. classiq/interface/analyzer/cytoscape_graph.py +15 -9
  80. classiq/interface/analyzer/result.py +28 -32
  81. classiq/interface/applications/qsvm.py +20 -29
  82. classiq/interface/ast_node.py +16 -0
  83. classiq/interface/backend/backend_preferences.py +390 -121
  84. classiq/interface/backend/ionq/ionq_quantum_program.py +15 -23
  85. classiq/interface/backend/pydantic_backend.py +25 -22
  86. classiq/interface/backend/quantum_backend_providers.py +69 -16
  87. classiq/interface/chemistry/fermionic_operator.py +30 -21
  88. classiq/interface/chemistry/ground_state_problem.py +28 -25
  89. classiq/interface/chemistry/molecule.py +14 -10
  90. classiq/interface/chemistry/operator.py +64 -231
  91. classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
  92. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
  93. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
  94. classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
  95. classiq/interface/combinatorial_optimization/examples/mht.py +10 -6
  96. classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
  97. classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
  98. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +8 -9
  99. classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
  100. classiq/interface/combinatorial_optimization/result.py +1 -3
  101. classiq/interface/combinatorial_optimization/solver_types.py +1 -1
  102. classiq/interface/debug_info/debug_info.py +86 -0
  103. classiq/{exceptions.py → interface/exceptions.py} +37 -9
  104. classiq/interface/execution/iqcc.py +19 -0
  105. classiq/interface/execution/jobs.py +15 -12
  106. classiq/interface/execution/primitives.py +18 -0
  107. classiq/interface/executor/constants.py +1 -0
  108. classiq/interface/executor/execution_preferences.py +26 -114
  109. classiq/interface/executor/execution_request.py +24 -46
  110. classiq/interface/executor/execution_result.py +30 -8
  111. classiq/interface/executor/iqae_result.py +4 -6
  112. classiq/interface/executor/optimizer_preferences.py +17 -14
  113. classiq/interface/executor/quantum_code.py +28 -24
  114. classiq/interface/executor/quantum_instruction_set.py +2 -2
  115. classiq/interface/executor/register_initialization.py +11 -14
  116. classiq/interface/executor/result.py +83 -56
  117. classiq/interface/executor/vqe_result.py +10 -10
  118. classiq/interface/finance/function_input.py +35 -25
  119. classiq/interface/finance/gaussian_model_input.py +5 -5
  120. classiq/interface/finance/log_normal_model_input.py +4 -4
  121. classiq/interface/finance/model_input.py +4 -4
  122. classiq/interface/generator/adjacency.py +1 -3
  123. classiq/interface/generator/amplitude_loading.py +22 -12
  124. classiq/interface/generator/ansatz_library.py +5 -5
  125. classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
  126. classiq/interface/generator/application_apis/chemistry_declarations.py +27 -187
  127. classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +18 -21
  128. classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
  129. classiq/interface/generator/application_apis/finance_declarations.py +48 -69
  130. classiq/interface/generator/application_apis/qsvm_declarations.py +0 -70
  131. classiq/interface/generator/arith/argument_utils.py +46 -5
  132. classiq/interface/generator/arith/arithmetic.py +35 -16
  133. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +6 -7
  134. classiq/interface/generator/arith/arithmetic_expression_abc.py +66 -25
  135. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -11
  136. classiq/interface/generator/arith/arithmetic_expression_validator.py +47 -43
  137. classiq/interface/generator/arith/arithmetic_operations.py +14 -6
  138. classiq/interface/generator/arith/arithmetic_param_getters.py +7 -8
  139. classiq/interface/generator/arith/arithmetic_result_builder.py +21 -17
  140. classiq/interface/generator/arith/ast_node_rewrite.py +3 -2
  141. classiq/interface/generator/arith/binary_ops.py +218 -130
  142. classiq/interface/generator/arith/endianness.py +1 -1
  143. classiq/interface/generator/arith/extremum_operations.py +96 -25
  144. classiq/interface/generator/arith/logical_ops.py +14 -12
  145. classiq/interface/generator/arith/number_utils.py +12 -6
  146. classiq/interface/generator/arith/register_user_input.py +60 -37
  147. classiq/interface/generator/arith/unary_ops.py +49 -29
  148. classiq/interface/generator/arith/uncomputation_methods.py +1 -1
  149. classiq/interface/generator/builtin_api_builder.py +2 -9
  150. classiq/interface/generator/chemistry_function_params.py +3 -3
  151. classiq/interface/generator/circuit_code/circuit_code.py +7 -7
  152. classiq/interface/generator/circuit_code/types_and_constants.py +4 -7
  153. classiq/interface/generator/commuting_pauli_exponentiation.py +7 -7
  154. classiq/interface/generator/compiler_keywords.py +5 -1
  155. classiq/interface/generator/complex_type.py +13 -18
  156. classiq/interface/generator/constant.py +3 -4
  157. classiq/interface/generator/control_state.py +34 -29
  158. classiq/interface/generator/copy.py +47 -0
  159. classiq/interface/generator/custom_ansatz.py +2 -5
  160. classiq/interface/generator/distance.py +3 -5
  161. classiq/interface/generator/excitations.py +3 -2
  162. classiq/interface/generator/expressions/atomic_expression_functions.py +21 -5
  163. classiq/interface/generator/expressions/enums/__init__.py +0 -10
  164. classiq/interface/generator/expressions/enums/finance_functions.py +12 -22
  165. classiq/interface/generator/expressions/evaluated_expression.py +5 -5
  166. classiq/interface/generator/expressions/expression.py +26 -14
  167. classiq/interface/generator/expressions/expression_constants.py +9 -3
  168. classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
  169. classiq/interface/generator/expressions/qmod_qarray_proxy.py +99 -0
  170. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +34 -8
  171. classiq/interface/generator/expressions/qmod_qstruct_proxy.py +36 -0
  172. classiq/interface/generator/expressions/qmod_sized_proxy.py +30 -2
  173. classiq/interface/generator/expressions/qmod_struct_instance.py +14 -2
  174. classiq/interface/generator/expressions/sympy_supported_expressions.py +19 -11
  175. classiq/interface/generator/finance.py +2 -2
  176. classiq/interface/generator/function_param_library.py +6 -6
  177. classiq/interface/generator/function_param_list_without_self_reference.py +2 -10
  178. classiq/interface/generator/function_params.py +36 -64
  179. classiq/interface/generator/functions/__init__.py +0 -22
  180. classiq/interface/generator/functions/builtins/internal_operators.py +16 -0
  181. classiq/interface/generator/functions/classical_function_declaration.py +18 -9
  182. classiq/interface/generator/functions/classical_type.py +47 -166
  183. classiq/interface/generator/functions/concrete_types.py +55 -0
  184. classiq/interface/generator/functions/function_declaration.py +13 -14
  185. classiq/interface/generator/functions/port_declaration.py +1 -13
  186. classiq/interface/generator/functions/qmod_python_interface.py +2 -1
  187. classiq/interface/generator/functions/type_name.py +90 -0
  188. classiq/interface/generator/generated_circuit_data.py +153 -20
  189. classiq/interface/generator/grover_diffuser.py +32 -25
  190. classiq/interface/generator/grover_operator.py +34 -25
  191. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +4 -6
  192. classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
  193. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +9 -9
  194. classiq/interface/generator/hardware/hardware_data.py +72 -34
  195. classiq/interface/generator/hardware_efficient_ansatz.py +20 -16
  196. classiq/interface/generator/hartree_fock.py +13 -5
  197. classiq/interface/generator/identity.py +10 -6
  198. classiq/interface/generator/linear_pauli_rotations.py +32 -20
  199. classiq/interface/generator/mcmt_method.py +1 -1
  200. classiq/interface/generator/mcu.py +17 -15
  201. classiq/interface/generator/mcx.py +24 -17
  202. classiq/interface/generator/model/__init__.py +2 -5
  203. classiq/interface/generator/model/constraints.py +26 -8
  204. classiq/interface/generator/model/model.py +27 -190
  205. classiq/interface/generator/model/preferences/preferences.py +115 -41
  206. classiq/{quantum_register.py → interface/generator/model/quantum_register.py} +14 -17
  207. classiq/interface/generator/oracles/arithmetic_oracle.py +2 -4
  208. classiq/interface/generator/oracles/custom_oracle.py +15 -13
  209. classiq/interface/generator/oracles/oracle_abc.py +7 -7
  210. classiq/interface/generator/partitioned_register.py +7 -7
  211. classiq/interface/generator/piecewise_linear_amplitude_loading.py +45 -29
  212. classiq/interface/generator/preferences/optimization.py +1 -2
  213. classiq/interface/generator/qpe.py +41 -30
  214. classiq/interface/generator/qsvm.py +9 -10
  215. classiq/interface/generator/quantum_function_call.py +88 -73
  216. classiq/interface/generator/quantum_program.py +41 -24
  217. classiq/interface/generator/range_types.py +11 -12
  218. classiq/interface/generator/register_role.py +18 -6
  219. classiq/interface/generator/slice_parsing_utils.py +5 -5
  220. classiq/interface/generator/standard_gates/controlled_standard_gates.py +30 -39
  221. classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
  222. classiq/interface/generator/standard_gates/standard_gates.py +3 -3
  223. classiq/interface/generator/standard_gates/u_gate.py +7 -10
  224. classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
  225. classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
  226. classiq/interface/generator/state_preparation/distributions.py +16 -15
  227. classiq/interface/generator/state_preparation/metrics.py +4 -7
  228. classiq/interface/generator/state_preparation/state_preparation.py +25 -20
  229. classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
  230. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +20 -6
  231. classiq/interface/generator/transpiler_basis_gates.py +7 -3
  232. classiq/interface/generator/types/builtin_enum_declarations.py +178 -0
  233. classiq/interface/generator/types/compilation_metadata.py +6 -0
  234. classiq/interface/generator/types/enum_declaration.py +54 -0
  235. classiq/interface/generator/types/qstruct_declaration.py +18 -0
  236. classiq/interface/generator/types/struct_declaration.py +7 -11
  237. classiq/interface/generator/ucc.py +5 -4
  238. classiq/interface/generator/unitary_gate.py +5 -5
  239. classiq/interface/generator/user_defined_function_params.py +4 -1
  240. classiq/interface/generator/validations/flow_graph.py +7 -7
  241. classiq/interface/generator/validations/validator_functions.py +4 -4
  242. classiq/interface/generator/visitor.py +23 -16
  243. classiq/interface/hardware.py +29 -8
  244. classiq/interface/helpers/classproperty.py +8 -0
  245. classiq/interface/helpers/custom_encoders.py +2 -2
  246. classiq/interface/helpers/custom_pydantic_types.py +40 -50
  247. classiq/interface/helpers/datastructures.py +26 -0
  248. classiq/interface/helpers/hashable_mixin.py +3 -2
  249. classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
  250. classiq/interface/helpers/pydantic_model_helpers.py +7 -5
  251. classiq/interface/helpers/validation_helpers.py +3 -20
  252. classiq/interface/helpers/versioned_model.py +1 -4
  253. classiq/interface/ide/ide_data.py +16 -20
  254. classiq/interface/ide/visual_model.py +130 -0
  255. classiq/interface/interface_version.py +1 -0
  256. classiq/interface/jobs.py +29 -69
  257. classiq/interface/model/allocate.py +16 -0
  258. classiq/interface/model/bind_operation.py +32 -9
  259. classiq/interface/model/classical_if.py +15 -0
  260. classiq/interface/model/classical_parameter_declaration.py +33 -3
  261. classiq/interface/model/control.py +45 -0
  262. classiq/interface/model/handle_binding.py +298 -20
  263. classiq/interface/model/inplace_binary_operation.py +29 -24
  264. classiq/interface/model/invert.py +12 -0
  265. classiq/interface/model/model.py +69 -61
  266. classiq/interface/model/native_function_definition.py +17 -20
  267. classiq/interface/model/parameter.py +13 -0
  268. classiq/interface/model/phase_operation.py +11 -0
  269. classiq/interface/model/port_declaration.py +27 -9
  270. classiq/interface/model/power.py +14 -0
  271. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +30 -18
  272. classiq/interface/model/quantum_expressions/arithmetic_operation.py +51 -14
  273. classiq/interface/model/quantum_expressions/quantum_expression.py +12 -35
  274. classiq/interface/model/quantum_function_call.py +141 -343
  275. classiq/interface/model/quantum_function_declaration.py +190 -157
  276. classiq/interface/model/quantum_lambda_function.py +33 -32
  277. classiq/interface/model/quantum_statement.py +71 -12
  278. classiq/interface/model/quantum_type.py +177 -40
  279. classiq/interface/model/quantum_variable_declaration.py +3 -25
  280. classiq/interface/model/repeat.py +15 -0
  281. classiq/interface/model/statement_block.py +40 -14
  282. classiq/interface/model/validation_handle.py +13 -6
  283. classiq/interface/model/variable_declaration_statement.py +3 -1
  284. classiq/interface/model/within_apply_operation.py +7 -5
  285. classiq/interface/server/global_versions.py +6 -7
  286. classiq/interface/server/routes.py +17 -21
  287. classiq/interface/source_reference.py +59 -0
  288. classiq/model_expansions/atomic_expression_functions_defs.py +253 -0
  289. classiq/model_expansions/capturing/__init__.py +0 -0
  290. classiq/model_expansions/capturing/captured_vars.py +435 -0
  291. classiq/model_expansions/capturing/mangling_utils.py +56 -0
  292. classiq/model_expansions/closure.py +171 -0
  293. classiq/model_expansions/debug_flag.py +3 -0
  294. classiq/model_expansions/evaluators/__init__.py +0 -0
  295. classiq/model_expansions/evaluators/arg_type_match.py +158 -0
  296. classiq/model_expansions/evaluators/argument_types.py +42 -0
  297. classiq/model_expansions/evaluators/classical_expression.py +36 -0
  298. classiq/model_expansions/evaluators/control.py +144 -0
  299. classiq/model_expansions/evaluators/parameter_types.py +226 -0
  300. classiq/model_expansions/evaluators/quantum_type_utils.py +239 -0
  301. classiq/model_expansions/evaluators/type_type_match.py +90 -0
  302. classiq/model_expansions/expression_evaluator.py +135 -0
  303. classiq/model_expansions/expression_renamer.py +76 -0
  304. classiq/model_expansions/function_builder.py +247 -0
  305. classiq/model_expansions/generative_functions.py +158 -0
  306. classiq/model_expansions/interpreters/__init__.py +0 -0
  307. classiq/model_expansions/interpreters/base_interpreter.py +263 -0
  308. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
  309. classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
  310. classiq/model_expansions/model_tables.py +18 -0
  311. classiq/model_expansions/quantum_operations/__init__.py +9 -0
  312. classiq/model_expansions/quantum_operations/bind.py +60 -0
  313. classiq/model_expansions/quantum_operations/call_emitter.py +266 -0
  314. classiq/model_expansions/quantum_operations/classicalif.py +53 -0
  315. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
  316. classiq/model_expansions/quantum_operations/emitter.py +181 -0
  317. classiq/model_expansions/quantum_operations/quantum_function_call.py +33 -0
  318. classiq/model_expansions/quantum_operations/repeat.py +56 -0
  319. classiq/model_expansions/quantum_operations/shallow_emitter.py +180 -0
  320. classiq/model_expansions/quantum_operations/variable_decleration.py +28 -0
  321. classiq/model_expansions/scope.py +240 -0
  322. classiq/model_expansions/scope_initialization.py +150 -0
  323. classiq/model_expansions/sympy_conversion/__init__.py +0 -0
  324. classiq/model_expansions/sympy_conversion/arithmetics.py +49 -0
  325. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +179 -0
  326. classiq/model_expansions/sympy_conversion/sympy_to_python.py +123 -0
  327. classiq/model_expansions/transformers/__init__.py +0 -0
  328. classiq/model_expansions/transformers/ast_renamer.py +26 -0
  329. classiq/model_expansions/transformers/var_splitter.py +299 -0
  330. classiq/model_expansions/utils/__init__.py +0 -0
  331. classiq/model_expansions/utils/counted_name_allocator.py +11 -0
  332. classiq/model_expansions/utils/handles_collector.py +33 -0
  333. classiq/model_expansions/visitors/__init__.py +0 -0
  334. classiq/model_expansions/visitors/boolean_expression_transformers.py +214 -0
  335. classiq/model_expansions/visitors/variable_references.py +144 -0
  336. classiq/open_library/__init__.py +4 -0
  337. classiq/open_library/functions/__init__.py +130 -0
  338. classiq/open_library/functions/amplitude_estimation.py +30 -0
  339. classiq/open_library/functions/discrete_sine_cosine_transform.py +181 -0
  340. classiq/open_library/functions/grover.py +157 -0
  341. classiq/open_library/functions/hea.py +115 -0
  342. classiq/open_library/functions/linear_pauli_rotation.py +82 -0
  343. classiq/open_library/functions/modular_exponentiation.py +201 -0
  344. classiq/open_library/functions/qaoa_penalty.py +117 -0
  345. classiq/open_library/functions/qft_functions.py +54 -0
  346. classiq/open_library/functions/qpe.py +46 -0
  347. classiq/open_library/functions/qsvt.py +331 -0
  348. classiq/open_library/functions/state_preparation.py +301 -0
  349. classiq/open_library/functions/swap_test.py +27 -0
  350. classiq/open_library/functions/utility_functions.py +81 -0
  351. classiq/open_library/functions/variational.py +52 -0
  352. classiq/qmod/__init__.py +10 -10
  353. classiq/qmod/builtins/__init__.py +19 -2
  354. classiq/qmod/builtins/classical_execution_primitives.py +36 -14
  355. classiq/qmod/builtins/classical_functions.py +39 -43
  356. classiq/qmod/builtins/constants.py +10 -0
  357. classiq/qmod/builtins/enums.py +208 -0
  358. classiq/qmod/builtins/functions/__init__.py +137 -0
  359. classiq/qmod/builtins/functions/allocation.py +150 -0
  360. classiq/qmod/builtins/functions/arithmetic.py +55 -0
  361. classiq/qmod/builtins/functions/benchmarking.py +8 -0
  362. classiq/qmod/builtins/functions/chemistry.py +91 -0
  363. classiq/qmod/builtins/functions/exponentiation.py +105 -0
  364. classiq/qmod/builtins/functions/finance.py +34 -0
  365. classiq/qmod/builtins/functions/operators.py +16 -0
  366. classiq/qmod/builtins/functions/qsvm.py +24 -0
  367. classiq/qmod/builtins/functions/standard_gates.py +651 -0
  368. classiq/qmod/builtins/operations.py +373 -40
  369. classiq/qmod/builtins/structs.py +103 -80
  370. classiq/qmod/cfunc.py +2 -2
  371. classiq/qmod/classical_function.py +4 -8
  372. classiq/qmod/cparam.py +64 -0
  373. classiq/qmod/create_model_function.py +56 -0
  374. classiq/qmod/declaration_inferrer.py +143 -101
  375. classiq/qmod/expression_query.py +20 -4
  376. classiq/qmod/generative.py +42 -0
  377. classiq/qmod/model_state_container.py +18 -6
  378. classiq/qmod/native/__init__.py +7 -0
  379. classiq/qmod/native/expression_to_qmod.py +16 -11
  380. classiq/qmod/native/pretty_printer.py +187 -97
  381. classiq/qmod/pretty_print/__init__.py +7 -0
  382. classiq/qmod/pretty_print/expression_to_python.py +222 -0
  383. classiq/qmod/pretty_print/pretty_printer.py +572 -0
  384. classiq/qmod/python_classical_type.py +67 -0
  385. classiq/qmod/qfunc.py +60 -8
  386. classiq/qmod/qmod_constant.py +93 -26
  387. classiq/qmod/qmod_parameter.py +68 -59
  388. classiq/qmod/qmod_variable.py +468 -155
  389. classiq/qmod/quantum_callable.py +17 -7
  390. classiq/qmod/quantum_expandable.py +269 -96
  391. classiq/qmod/quantum_function.py +196 -41
  392. classiq/qmod/semantics/__init__.py +0 -0
  393. classiq/qmod/semantics/annotation/__init__.py +0 -0
  394. classiq/qmod/semantics/annotation/call_annotation.py +92 -0
  395. classiq/qmod/semantics/annotation/qstruct_annotator.py +23 -0
  396. classiq/qmod/semantics/error_manager.py +88 -0
  397. classiq/qmod/semantics/lambdas.py +25 -0
  398. classiq/qmod/semantics/static_semantics_visitor.py +384 -0
  399. classiq/qmod/semantics/validation/__init__.py +0 -0
  400. classiq/qmod/semantics/validation/constants_validation.py +16 -0
  401. classiq/qmod/semantics/validation/func_call_validation.py +99 -0
  402. classiq/qmod/semantics/validation/function_name_collisions_validation.py +23 -0
  403. classiq/qmod/semantics/validation/handle_validation.py +85 -0
  404. classiq/qmod/semantics/validation/main_validation.py +33 -0
  405. classiq/qmod/semantics/validation/types_validation.py +128 -0
  406. classiq/qmod/symbolic.py +147 -123
  407. classiq/qmod/symbolic_expr.py +27 -12
  408. classiq/qmod/symbolic_type.py +2 -5
  409. classiq/qmod/type_attribute_remover.py +32 -0
  410. classiq/qmod/utilities.py +98 -4
  411. classiq/qmod/write_qmod.py +17 -3
  412. classiq/synthesis.py +210 -22
  413. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/METADATA +16 -9
  414. classiq-0.65.4.dist-info/RECORD +521 -0
  415. classiq/_internals/_qfunc_ext.py +0 -6
  416. classiq/applications/benchmarking/__init__.py +0 -9
  417. classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
  418. classiq/applications/numpy_utils.py +0 -37
  419. classiq/applications_model_constructors/__init__.py +0 -25
  420. classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
  421. classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -65
  422. classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +0 -243
  423. classiq/applications_model_constructors/libraries/ampltitude_estimation_library.py +0 -11
  424. classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
  425. classiq/builtin_functions/__init__.py +0 -43
  426. classiq/builtin_functions/amplitude_loading.py +0 -3
  427. classiq/builtin_functions/binary_ops.py +0 -1
  428. classiq/builtin_functions/exponentiation.py +0 -5
  429. classiq/builtin_functions/qpe.py +0 -4
  430. classiq/builtin_functions/qsvm.py +0 -7
  431. classiq/builtin_functions/range_types.py +0 -5
  432. classiq/builtin_functions/standard_gates.py +0 -1
  433. classiq/builtin_functions/state_preparation.py +0 -6
  434. classiq/builtin_functions/suzuki_trotter.py +0 -3
  435. classiq/interface/executor/aws_execution_cost.py +0 -73
  436. classiq/interface/executor/error_mitigation.py +0 -6
  437. classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
  438. classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
  439. classiq/interface/generator/expressions/enums/chemistry.py +0 -28
  440. classiq/interface/generator/expressions/enums/classical_enum.py +0 -5
  441. classiq/interface/generator/expressions/enums/ladder_operator.py +0 -16
  442. classiq/interface/generator/expressions/enums/optimizers.py +0 -9
  443. classiq/interface/generator/expressions/enums/pauli.py +0 -8
  444. classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
  445. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  446. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +0 -641
  447. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/exponentiation_functions.py +0 -89
  448. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +0 -1229
  449. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
  450. classiq/interface/generator/functions/foreign_function_definition.py +0 -114
  451. classiq/interface/generator/functions/function_implementation.py +0 -107
  452. classiq/interface/generator/functions/native_function_definition.py +0 -155
  453. classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
  454. classiq/interface/generator/functions/register.py +0 -44
  455. classiq/interface/generator/functions/register_mapping_data.py +0 -106
  456. classiq/interface/generator/inequality_mixer.py +0 -51
  457. classiq/interface/generator/model/classical_main_validator.py +0 -106
  458. classiq/interface/generator/range_mixer.py +0 -56
  459. classiq/interface/generator/state_propagator.py +0 -74
  460. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  461. classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +0 -22
  462. classiq/interface/ide/show.py +0 -34
  463. classiq/interface/model/call_synthesis_data.py +0 -68
  464. classiq/interface/model/common_model_types.py +0 -23
  465. classiq/interface/model/quantum_expressions/control_state.py +0 -38
  466. classiq/interface/model/quantum_if_operation.py +0 -94
  467. classiq/interface/model/resolvers/function_call_resolver.py +0 -43
  468. classiq/interface/model/validations/handle_validation_base.py +0 -55
  469. classiq/interface/model/validations/handles_validator.py +0 -156
  470. classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
  471. classiq/model/__init__.py +0 -14
  472. classiq/model/composite_function_generator.py +0 -33
  473. classiq/model/function_handler.py +0 -462
  474. classiq/model/logic_flow.py +0 -149
  475. classiq/model/logic_flow_change_handler.py +0 -71
  476. classiq/model/model.py +0 -229
  477. classiq/qmod/builtins/functions.py +0 -913
  478. classiq/qmod/qmod_struct.py +0 -37
  479. classiq/quantum_functions/__init__.py +0 -17
  480. classiq/quantum_functions/annotation_parser.py +0 -205
  481. classiq/quantum_functions/decorators.py +0 -22
  482. classiq/quantum_functions/function_library.py +0 -181
  483. classiq/quantum_functions/function_parser.py +0 -74
  484. classiq/quantum_functions/quantum_function.py +0 -236
  485. classiq-0.38.0.dist-info/RECORD +0 -454
  486. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
  487. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
  488. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
  489. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
  490. /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
  491. /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
  492. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
  493. /classiq/{interface/generator/credit_risk_example → applications/hamiltonian}/__init__.py +0 -0
  494. /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
  495. /classiq/interface/{model/resolvers → debug_info}/__init__.py +0 -0
  496. /classiq/{_internals → interface}/enum_utils.py +0 -0
  497. /classiq/interface/{model/validations → generator/functions/builtins}/__init__.py +0 -0
  498. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → model_expansions/__init__.py} +0 -0
  499. {classiq-0.38.0.dist-info → classiq-0.65.4.dist-info}/WHEEL +0 -0
@@ -6,19 +6,24 @@ from classiq.interface.generator.functions.classical_type import (
6
6
  ClassicalList,
7
7
  Integer,
8
8
  )
9
+ from classiq.interface.model.classical_parameter_declaration import (
10
+ ClassicalParameterDeclaration,
11
+ )
9
12
 
10
13
  GRID_ENTANGLER_GRAPH = ClassicalFunctionDeclaration(
11
14
  name="grid_entangler_graph",
12
- param_decls={
13
- "num_qubits": Integer(),
14
- "schmidt_rank": Integer(),
15
- "grid_randomization": Bool(),
16
- },
15
+ positional_parameters=[
16
+ ClassicalParameterDeclaration(name="num_qubits", classical_type=Integer()),
17
+ ClassicalParameterDeclaration(name="schmidt_rank", classical_type=Integer()),
18
+ ClassicalParameterDeclaration(name="grid_randomization", classical_type=Bool()),
19
+ ],
17
20
  return_type=ClassicalList(element_type=ClassicalList(element_type=Integer())),
18
21
  )
19
22
 
20
23
  HYPERCUBE_ENTANGLER_GRAPH = ClassicalFunctionDeclaration(
21
24
  name="hypercube_entangler_graph",
22
- param_decls={"num_qubits": Integer()},
25
+ positional_parameters=[
26
+ ClassicalParameterDeclaration(name="num_qubits", classical_type=Integer()),
27
+ ],
23
28
  return_type=ClassicalList(element_type=ClassicalList(element_type=Integer())),
24
29
  )
@@ -1,25 +1,23 @@
1
+ from collections.abc import Mapping
1
2
  from enum import Enum
2
- from typing import Mapping
3
3
 
4
4
  from classiq.interface.generator.expressions.expression import Expression
5
5
  from classiq.interface.generator.functions.classical_function_declaration import (
6
6
  ClassicalFunctionDeclaration,
7
7
  )
8
- from classiq.interface.generator.functions.classical_type import (
9
- Bool,
10
- ClassicalList,
11
- Integer,
12
- Real,
13
- Struct,
14
- )
8
+ from classiq.interface.generator.functions.classical_type import Real
15
9
  from classiq.interface.generator.functions.port_declaration import (
16
10
  PortDeclarationDirection,
17
11
  )
18
- from classiq.interface.generator.types.struct_declaration import StructDeclaration
12
+ from classiq.interface.generator.functions.type_name import Struct
13
+ from classiq.interface.model.classical_parameter_declaration import (
14
+ ClassicalParameterDeclaration,
15
+ )
19
16
  from classiq.interface.model.port_declaration import PortDeclaration
20
17
  from classiq.interface.model.quantum_function_declaration import (
21
- QuantumFunctionDeclaration,
18
+ NamedParamsQuantumFunctionDeclaration,
22
19
  )
20
+ from classiq.interface.model.quantum_type import QuantumBit, QuantumBitvector
23
21
 
24
22
  FUNCTION_PORT_NAME = "func_port"
25
23
  OBJECTIVE_PORT_NAME = "obj_port"
@@ -31,32 +29,39 @@ class FinanceModelType(Enum):
31
29
 
32
30
 
33
31
  FINANCE_FUNCTION_PORT_SIZE_MAPPING: Mapping[FinanceModelType, str] = {
34
- FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') + len(get_field(finance_model, 'rhos')) + floor(log(sum(get_field(finance_model, 'loss')), 2)) + 1",
32
+ FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') + get_field(get_field(finance_model, 'rhos'), 'len') + floor(log(sum(get_field(finance_model, 'loss')), 2)) + 1",
35
33
  FinanceModelType.LogNormal: "get_field(finance_model, 'num_qubits')",
36
34
  }
37
35
 
38
36
 
39
37
  def _generate_finance_function(
40
38
  finance_model: FinanceModelType,
41
- ) -> QuantumFunctionDeclaration:
42
- return QuantumFunctionDeclaration(
39
+ ) -> NamedParamsQuantumFunctionDeclaration:
40
+ return NamedParamsQuantumFunctionDeclaration(
43
41
  name=f"{finance_model.value}_finance",
44
- param_decls={
45
- "finance_model": Struct(name=f"{finance_model.name}Model"),
46
- "finance_function": Struct(name="FinanceFunction"),
47
- },
48
- port_declarations={
49
- FUNCTION_PORT_NAME: PortDeclaration(
42
+ positional_arg_declarations=[
43
+ ClassicalParameterDeclaration(
44
+ name="finance_model",
45
+ classical_type=Struct(name=f"{finance_model.name}Model"),
46
+ ),
47
+ ClassicalParameterDeclaration(
48
+ name="finance_function", classical_type=Struct(name="FinanceFunction")
49
+ ),
50
+ PortDeclaration(
50
51
  name=FUNCTION_PORT_NAME,
52
+ quantum_type=QuantumBitvector(
53
+ length=Expression(
54
+ expr=FINANCE_FUNCTION_PORT_SIZE_MAPPING[finance_model]
55
+ )
56
+ ),
51
57
  direction=PortDeclarationDirection.Inout,
52
- size=Expression(expr=FINANCE_FUNCTION_PORT_SIZE_MAPPING[finance_model]),
53
58
  ),
54
- OBJECTIVE_PORT_NAME: PortDeclaration(
59
+ PortDeclaration(
55
60
  name=OBJECTIVE_PORT_NAME,
61
+ quantum_type=QuantumBit(),
56
62
  direction=PortDeclarationDirection.Inout,
57
- size=Expression(expr="1"),
58
63
  ),
59
- },
64
+ ],
60
65
  )
61
66
 
62
67
 
@@ -64,63 +69,37 @@ LOG_NORMAL_FINANCE_FUNCTION = _generate_finance_function(FinanceModelType.LogNor
64
69
 
65
70
  GAUSSIAN_FINANCE_FUNCTION = _generate_finance_function(FinanceModelType.Gaussian)
66
71
 
67
- GAUSSIAN_MODEL = StructDeclaration(
68
- name="GaussianModel",
69
- variables={
70
- "num_qubits": Integer(),
71
- "normal_max_value": Real(),
72
- "default_probabilities": ClassicalList(element_type=Real()),
73
- "rhos": ClassicalList(element_type=Real()),
74
- "loss": ClassicalList(element_type=Integer()),
75
- "min_loss": Integer(),
76
- },
77
- )
78
-
79
-
80
- LOG_NORMAL_MODEL = StructDeclaration(
81
- name="LogNormalModel",
82
- variables={"num_qubits": Integer(), "mu": Real(), "sigma": Real()},
83
- )
84
-
85
-
86
- FINANCE_FUNCTION = StructDeclaration(
87
- name="FinanceFunction",
88
- variables={
89
- "f": Integer(),
90
- "threshold": Real(),
91
- "larger": Bool(),
92
- "polynomial_degree": Integer(),
93
- "use_chebyshev_polynomial_approximation": Bool(),
94
- "tail_probability": Real(),
95
- },
96
- )
97
-
98
72
  LOG_NORMAL_FINANCE_POST_PROCESS = ClassicalFunctionDeclaration(
99
73
  name="log_normal_finance_post_process",
100
- param_decls={
101
- "finance_model": Struct(name="LogNormalModel"),
102
- "estimation_method": Struct(name="FinanceFunction"),
103
- "probability": Real(),
104
- },
74
+ positional_parameters=[
75
+ ClassicalParameterDeclaration(
76
+ name="finance_model", classical_type=Struct(name="LogNormalModel")
77
+ ),
78
+ ClassicalParameterDeclaration(
79
+ name="estimation_method", classical_type=Struct(name="FinanceFunction")
80
+ ),
81
+ ClassicalParameterDeclaration(name="probability", classical_type=Real()),
82
+ ],
105
83
  return_type=Real(),
106
84
  )
107
85
 
108
86
  GAUSSIAN_FINANCE_POST_PROCESS = ClassicalFunctionDeclaration(
109
87
  name="gaussian_finance_post_process",
110
- param_decls={
111
- "finance_model": Struct(name="GaussianModel"),
112
- "estimation_method": Struct(name="FinanceFunction"),
113
- "probability": Real(),
114
- },
88
+ positional_parameters=[
89
+ ClassicalParameterDeclaration(
90
+ name="finance_model", classical_type=Struct(name="GaussianModel")
91
+ ),
92
+ ClassicalParameterDeclaration(
93
+ name="estimation_method", classical_type=Struct(name="FinanceFunction")
94
+ ),
95
+ ClassicalParameterDeclaration(name="probability", classical_type=Real()),
96
+ ],
115
97
  return_type=Real(),
116
98
  )
117
99
 
118
100
  __all__ = [
119
- "LOG_NORMAL_FINANCE_FUNCTION",
120
101
  "GAUSSIAN_FINANCE_FUNCTION",
121
- "GAUSSIAN_MODEL",
122
- "LOG_NORMAL_MODEL",
123
- "FINANCE_FUNCTION",
124
- "LOG_NORMAL_FINANCE_POST_PROCESS",
125
102
  "GAUSSIAN_FINANCE_POST_PROCESS",
103
+ "LOG_NORMAL_FINANCE_FUNCTION",
104
+ "LOG_NORMAL_FINANCE_POST_PROCESS",
126
105
  ]
@@ -1,76 +1,6 @@
1
1
  import enum
2
2
 
3
- from classiq.interface.generator.expressions.expression import Expression
4
- from classiq.interface.generator.functions.classical_type import (
5
- ClassicalList,
6
- Integer,
7
- Pauli,
8
- Real,
9
- Struct,
10
- )
11
- from classiq.interface.generator.functions.port_declaration import (
12
- PortDeclarationDirection,
13
- )
14
- from classiq.interface.generator.types.struct_declaration import StructDeclaration
15
- from classiq.interface.model.port_declaration import PortDeclaration
16
- from classiq.interface.model.quantum_function_declaration import (
17
- QuantumFunctionDeclaration,
18
- )
19
-
20
3
 
21
4
  class FeatureMapType(enum.Enum):
22
5
  BlochSphere = "bloch_sphere"
23
6
  Pauli = "pauli"
24
-
25
-
26
- QSVM_PAULI_FEATURE_MAP_SIZE = "get_field(feature_map, 'feature_dimension')"
27
- QSVM_PAULI_FEATURE_MAP = QuantumFunctionDeclaration(
28
- name="pauli_feature_map",
29
- param_decls={"feature_map": Struct(name="QSVMFeatureMapPauli")},
30
- port_declarations={
31
- "qbv": PortDeclaration(
32
- name="qbv",
33
- direction=PortDeclarationDirection.Inout,
34
- size=Expression(expr=QSVM_PAULI_FEATURE_MAP_SIZE),
35
- )
36
- },
37
- )
38
-
39
- QSVM_BLOCH_SPHERE_FEATURE_MAP_SIZE = "ceiling(feature_dimension/2)"
40
- QSVM_BLOCH_SPHERE_FEATURE_MAP = QuantumFunctionDeclaration(
41
- name="bloch_sphere_feature_map",
42
- param_decls={"feature_dimension": Integer()},
43
- port_declarations={
44
- "qbv": PortDeclaration(
45
- name="qbv",
46
- direction=PortDeclarationDirection.Inout,
47
- size=Expression(expr=QSVM_BLOCH_SPHERE_FEATURE_MAP_SIZE),
48
- )
49
- },
50
- )
51
-
52
- QSVM_FEATURE_MAP_PAULI = StructDeclaration(
53
- name="QSVMFeatureMapPauli",
54
- variables={
55
- "feature_dimension": Integer(),
56
- "reps": Integer(),
57
- "entanglement": Integer(),
58
- "alpha": Real(),
59
- "paulis": ClassicalList(element_type=ClassicalList(element_type=Pauli())),
60
- },
61
- )
62
-
63
- QSVM_RESULT = StructDeclaration(
64
- name="QsvmResult",
65
- variables={
66
- "test_score": Real(),
67
- "predicted_labels": ClassicalList(element_type=Real()),
68
- },
69
- )
70
-
71
- __all__ = [
72
- "QSVM_RESULT",
73
- "QSVM_PAULI_FEATURE_MAP",
74
- "QSVM_BLOCH_SPHERE_FEATURE_MAP",
75
- "QSVM_FEATURE_MAP_PAULI",
76
- ]
@@ -1,6 +1,9 @@
1
- from typing import Tuple, Union
1
+ from typing import Union
2
2
 
3
3
  from classiq.interface.generator.arith import number_utils
4
+ from classiq.interface.generator.arith.number_utils import (
5
+ get_int_representation_and_fraction_places,
6
+ )
4
7
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
5
8
 
6
9
  RegisterOrConst = Union[RegisterArithmeticInfo, float]
@@ -42,17 +45,55 @@ def lower_bound(argument: RegisterOrConst) -> float:
42
45
  return argument
43
46
 
44
47
 
45
- def bounds(argument: RegisterOrConst) -> Tuple[float, float]:
48
+ def bounds(argument: RegisterOrConst) -> tuple[float, float]:
46
49
  if isinstance(argument, RegisterArithmeticInfo):
47
50
  return argument.bounds
48
51
  return argument, argument
49
52
 
50
53
 
51
54
  def limit_fraction_places(
52
- argument: RegisterOrConst, *, machine_precision: int
55
+ argument: RegisterOrConst, machine_precision: int
53
56
  ) -> RegisterOrConst:
54
57
  if isinstance(argument, RegisterArithmeticInfo):
55
58
  return argument.limit_fraction_places(machine_precision)
56
- return number_utils.limit_fraction_places(
57
- argument, machine_precision=machine_precision
59
+ return number_utils.limit_fraction_places(argument, machine_precision)
60
+
61
+
62
+ def arg_bounds_overlap(args: tuple[RegisterOrConst, RegisterOrConst]) -> bool:
63
+ return (max(bounds(args[0])) - min(bounds(args[1]))) * (
64
+ min(bounds(args[0])) - max(bounds(args[1]))
65
+ ) < 0
66
+
67
+
68
+ def as_arithmetic_info(
69
+ arg: RegisterOrConst, with_bounds: bool = True
70
+ ) -> RegisterArithmeticInfo:
71
+ if isinstance(arg, RegisterArithmeticInfo):
72
+ return arg
73
+ return RegisterArithmeticInfo(
74
+ size=number_utils.size(arg),
75
+ is_signed=arg < 0,
76
+ fraction_places=number_utils.fraction_places(arg),
77
+ bounds=(arg, arg) if with_bounds else None,
58
78
  )
79
+
80
+
81
+ def unsigned_integer_interpretation(
82
+ value: float, register: RegisterArithmeticInfo
83
+ ) -> int:
84
+ int_val, fraction_digits = get_int_representation_and_fraction_places(value)
85
+
86
+ # align fraction digits
87
+ fraction_digits_diff = register.fraction_places - fraction_digits
88
+ if fraction_digits_diff < 0:
89
+ int_val >>= -fraction_digits_diff
90
+ else:
91
+ int_val <<= fraction_digits_diff
92
+
93
+ # extend sign bit
94
+ if int(value) < 0:
95
+ bin_val = number_utils.binary_string(int_val)
96
+ bin_val += "1" * (register.size - len(bin_val))
97
+ int_val = number_utils.binary_to_int(bin_val[::-1])
98
+
99
+ return int_val
@@ -1,12 +1,17 @@
1
- from typing import Any, Dict, Optional, Set
1
+ from typing import Any, Final, Optional
2
2
 
3
3
  import networkx as nx
4
4
  import pydantic
5
+ from pydantic_core.core_schema import ValidationInfo
5
6
 
7
+ from classiq.interface.exceptions import ClassiqValueError
6
8
  from classiq.interface.generator.arith import arithmetic_expression_parser
7
9
  from classiq.interface.generator.arith.arithmetic_expression_abc import (
8
10
  ArithmeticExpressionABC,
9
11
  )
12
+ from classiq.interface.generator.arith.arithmetic_expression_validator import (
13
+ is_constant,
14
+ )
10
15
  from classiq.interface.generator.arith.arithmetic_param_getters import (
11
16
  id2op,
12
17
  operation_allows_target,
@@ -15,31 +20,37 @@ from classiq.interface.generator.arith.arithmetic_result_builder import (
15
20
  ArithmeticResultBuilder,
16
21
  )
17
22
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
23
+ from classiq.interface.generator.expressions.expression import Expression
18
24
  from classiq.interface.model.quantum_type import (
25
+ QuantumNumeric,
19
26
  QuantumType,
20
27
  quantum_var_to_register,
21
28
  register_info_to_quantum_type,
22
29
  )
23
30
 
24
- from classiq.exceptions import ClassiqValueError
31
+ ARITHMETIC_EXPRESSION_TARGET_NAME: Final[str] = "arithmetic_target"
32
+ ARITHMETIC_EXPRESSION_RESULT_NAME: Final[str] = "expression_result"
33
+ ARITHMETIC_EXPRESSION_GARBAGE_NAME: Final[str] = "expression_garbage"
34
+
25
35
 
26
- ARITHMETIC_EXPRESSION_TARGET_NAME: str = "arithmetic_target"
27
- ARITHMETIC_EXPRESSION_RESULT_NAME: str = "expression_result"
36
+ def is_zero(expr: str) -> bool:
37
+ return is_constant(expr) and float(expr) == 0
28
38
 
29
39
 
30
40
  class Arithmetic(ArithmeticExpressionABC):
31
41
  target: Optional[RegisterArithmeticInfo] = None
32
- inputs_to_save: Set[str] = pydantic.Field(default_factory=set)
42
+ inputs_to_save: set[str] = pydantic.Field(default_factory=set)
33
43
 
34
- @pydantic.validator("inputs_to_save", always=True)
44
+ @pydantic.field_validator("inputs_to_save")
45
+ @classmethod
35
46
  def _validate_inputs_to_save(
36
- cls, inputs_to_save: Set[str], values: Dict[str, Any]
37
- ) -> Set[str]:
38
- assert all(reg in values.get("definitions", {}) for reg in inputs_to_save)
47
+ cls, inputs_to_save: set[str], info: ValidationInfo
48
+ ) -> set[str]:
49
+ assert all(reg in info.data.get("definitions", {}) for reg in inputs_to_save)
39
50
  return inputs_to_save
40
51
 
41
52
  @staticmethod
42
- def _validate_expression_graph(graph: nx.DiGraph, values: Dict[str, Any]) -> None:
53
+ def _validate_expression_graph(graph: nx.DiGraph, values: dict[str, Any]) -> None:
43
54
  target = values.get("target")
44
55
  if target is None:
45
56
  return
@@ -64,19 +75,21 @@ class Arithmetic(ArithmeticExpressionABC):
64
75
  if name in self._inputs
65
76
  }
66
77
  # TODO: avoid calling the result builder again, as it is called in validation
67
- result_info = ArithmeticResultBuilder(
78
+ result_builder = ArithmeticResultBuilder(
68
79
  graph=arithmetic_expression_parser.parse_expression(self.expression),
69
80
  definitions=self.definitions,
70
81
  machine_precision=self.machine_precision,
71
- ).result
72
- self._outputs[ARITHMETIC_EXPRESSION_RESULT_NAME] = result_info
82
+ )
83
+ self._outputs[ARITHMETIC_EXPRESSION_RESULT_NAME] = result_builder.result
84
+ if result_builder.garbage:
85
+ self._outputs[ARITHMETIC_EXPRESSION_GARBAGE_NAME] = result_builder.garbage
73
86
  if self.target:
74
87
  self._inputs[ARITHMETIC_EXPRESSION_TARGET_NAME] = self.target
75
88
 
76
89
 
77
90
  def get_arithmetic_params(
78
91
  expr_str: str,
79
- var_types: Dict[str, QuantumType],
92
+ var_types: dict[str, QuantumType],
80
93
  machine_precision: int,
81
94
  enable_target: bool = False,
82
95
  ) -> Arithmetic:
@@ -94,8 +107,14 @@ def get_arithmetic_params(
94
107
 
95
108
 
96
109
  def compute_arithmetic_result_type(
97
- expr_str: str, var_types: Dict[str, QuantumType], machine_precision: int
98
- ) -> QuantumType:
110
+ expr_str: str, var_types: dict[str, QuantumType], machine_precision: int
111
+ ) -> QuantumNumeric:
112
+ if is_zero(expr_str):
113
+ return QuantumNumeric(
114
+ size=Expression(expr="1"),
115
+ is_signed=Expression(expr="False"),
116
+ fraction_digits=Expression(expr="0"),
117
+ )
99
118
  arith_param = get_arithmetic_params(expr_str, var_types, machine_precision)
100
119
  return register_info_to_quantum_type(
101
120
  arith_param.outputs[ARITHMETIC_EXPRESSION_RESULT_NAME]
@@ -1,21 +1,20 @@
1
- from typing import Callable, Dict, List
1
+ from typing import Callable
2
2
 
3
3
  from typing_extensions import TypeAlias
4
4
 
5
+ from classiq.interface.exceptions import ClassiqArithmeticError
5
6
  from classiq.interface.generator.arith import argument_utils
6
7
  from classiq.interface.generator.arith.binary_ops import BOOLEAN_OP_WITH_FRACTIONS_ERROR
7
8
 
8
- from classiq.exceptions import ClassiqArithmeticError
9
+ ArgTypeValidator: TypeAlias = Callable[[list[argument_utils.RegisterOrConst]], None]
9
10
 
10
- ArgTypeValidator: TypeAlias = Callable[[List[argument_utils.RegisterOrConst]], None]
11
11
 
12
-
13
- def _validate_bitwise_op_args(args: List[argument_utils.RegisterOrConst]) -> None:
12
+ def _validate_bitwise_op_args(args: list[argument_utils.RegisterOrConst]) -> None:
14
13
  if any(argument_utils.fraction_places(arg) > 0 for arg in args):
15
14
  raise ClassiqArithmeticError(BOOLEAN_OP_WITH_FRACTIONS_ERROR)
16
15
 
17
16
 
18
- arg_type_validator_map: Dict[str, ArgTypeValidator] = dict(
17
+ arg_type_validator_map: dict[str, ArgTypeValidator] = dict(
19
18
  BitXor=_validate_bitwise_op_args,
20
19
  BitAnd=_validate_bitwise_op_args,
21
20
  BitOr=_validate_bitwise_op_args,
@@ -24,7 +23,7 @@ arg_type_validator_map: Dict[str, ArgTypeValidator] = dict(
24
23
 
25
24
  def validate_operation_arg_types(
26
25
  operation: str,
27
- arguments: List[argument_utils.RegisterOrConst],
26
+ arguments: list[argument_utils.RegisterOrConst],
28
27
  machine_precision: int,
29
28
  ) -> None:
30
29
  if operation not in arg_type_validator_map:
@@ -1,12 +1,14 @@
1
1
  import abc
2
2
  import ast
3
3
  import re
4
- from typing import Any, Dict, Optional, Set, Tuple, Union
4
+ from typing import Any, Optional, Union
5
5
 
6
6
  import networkx as nx
7
7
  import pydantic
8
+ from pydantic import TypeAdapter
8
9
  from typing_extensions import TypeAlias
9
10
 
11
+ from classiq.interface.exceptions import ClassiqValueError
10
12
  from classiq.interface.generator.arith import number_utils
11
13
  from classiq.interface.generator.arith.arithmetic_expression_parser import (
12
14
  parse_expression,
@@ -30,8 +32,6 @@ from classiq.interface.generator.expressions.expression_constants import (
30
32
  from classiq.interface.generator.function_params import FunctionParams
31
33
  from classiq.interface.helpers.custom_pydantic_types import PydanticExpressionStr
32
34
 
33
- from classiq.exceptions import ClassiqValueError
34
-
35
35
  ValidDefinitions: TypeAlias = Union[
36
36
  pydantic.StrictInt, pydantic.StrictFloat, RegisterArithmeticInfo
37
37
  ]
@@ -41,20 +41,16 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
41
41
  uncomputation_method: UncomputationMethods = UncomputationMethods.optimized
42
42
  machine_precision: pydantic.NonNegativeInt = DEFAULT_MACHINE_PRECISION
43
43
  expression: PydanticExpressionStr
44
- definitions: Dict[str, ValidDefinitions]
44
+ definitions: dict[str, ValidDefinitions]
45
45
  qubit_count: Optional[pydantic.NonNegativeInt] = None
46
46
 
47
- def _get_literal_set(self) -> Set[str]:
47
+ def _get_literal_set(self) -> set[str]:
48
48
  return _extract_literals(self.expression)
49
49
 
50
- @pydantic.validator("definitions")
50
+ @classmethod
51
51
  def _validate_expression_literals_and_definitions(
52
- cls, definitions: Dict[str, ValidDefinitions], values: Dict[str, Any]
53
- ) -> Dict[str, ValidDefinitions]:
54
- expression = values.get("expression")
55
- if expression is None:
56
- return definitions
57
-
52
+ cls, definitions: dict[str, ValidDefinitions], expression: PydanticExpressionStr
53
+ ) -> dict[str, ValidDefinitions]:
58
54
  literals = _extract_literals(expression)
59
55
 
60
56
  forbidden = literals.intersection(FORBIDDEN_LITERALS)
@@ -71,12 +67,33 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
71
67
  raise ClassiqValueError(f"The following names are undefined: {undefined}")
72
68
  return definitions
73
69
 
74
- @pydantic.root_validator
75
- def _validate_expression(cls, values: Dict[str, Any]) -> Dict[str, Any]:
76
- expression: Optional[str] = values.get("expression")
77
- definitions: Optional[Dict[str, ValidDefinitions]] = values.get("definitions")
78
- machine_precision: Optional[int] = values.get("machine_precision")
79
- if expression is None or definitions is None or machine_precision is None:
70
+ @pydantic.model_validator(mode="before")
71
+ @classmethod
72
+ def _validate_expression(cls, values: Any) -> dict[str, Any]:
73
+ if not isinstance(values, dict):
74
+ return values
75
+ expression_adapter: TypeAdapter = TypeAdapter(Optional[PydanticExpressionStr])
76
+ expression = expression_adapter.validate_python(values.get("expression"))
77
+ definitions_adapter: TypeAdapter = TypeAdapter(
78
+ Optional[dict[str, ValidDefinitions]]
79
+ )
80
+ definition_dict = values.get("definitions")
81
+ if (
82
+ isinstance(definition_dict, list)
83
+ and len(definition_dict) > 0
84
+ and isinstance(definition_dict[0], tuple)
85
+ ):
86
+ definition_dict = dict(definition_dict)
87
+ definitions = definitions_adapter.validate_python(definition_dict)
88
+ machine_precision: Optional[int] = values.get(
89
+ "machine_precision", DEFAULT_MACHINE_PRECISION
90
+ )
91
+ if (
92
+ expression is None
93
+ or expression == ""
94
+ or definitions is None
95
+ or machine_precision is None
96
+ ):
80
97
  return values
81
98
 
82
99
  try:
@@ -88,15 +105,39 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
88
105
  cls._validate_ast_obj(ast_obj)
89
106
 
90
107
  graph = parse_expression(expression)
91
- cls._validate_expression_graph(graph, values)
108
+ try:
109
+ cls._validate_expression_graph(graph, values)
110
+ except ClassiqValueError as e:
111
+ # This flow was created specifically for inplace Boolean XOR operations like q1 ^ q2.
112
+ # We can't plug equality in previous stages due to SymPy restrictions.
113
+ # Note that we don't validate that the expression itself is Boolean (passing non-Boolean expressions
114
+ # as inplace is currently not supported, so it's a bug).
115
+ if not e.raw_message == "Expression does not support target assignment":
116
+ raise
117
+ ast_parsed_expression = ast.parse(expression)
118
+ ast_expr = ast_parsed_expression.body[0]
119
+ if (
120
+ not isinstance(ast_expr, ast.Expr)
121
+ or not isinstance(ast_expr.value, ast.BinOp)
122
+ or not isinstance(ast_expr.value.op, ast.BitXor)
123
+ ):
124
+ raise
125
+ expression = f"({expression}) == 1"
126
+ graph = parse_expression(expression)
127
+ cls._validate_expression_graph(graph, values)
128
+
129
+ validated_defs = cls._validate_expression_literals_and_definitions(
130
+ definitions, expression
131
+ )
132
+
92
133
  validate_arithmetic_result_type(
93
134
  graph=graph,
94
- definitions=definitions,
135
+ definitions=validated_defs,
95
136
  machine_precision=machine_precision,
96
137
  )
97
138
 
98
139
  new_expr, new_defs = cls._replace_const_definitions_in_expression(
99
- expression, definitions, machine_precision
140
+ expression, validated_defs, machine_precision
100
141
  )
101
142
  values["expression"] = new_expr
102
143
  values["definitions"] = new_defs
@@ -107,16 +148,16 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
107
148
  pass
108
149
 
109
150
  @staticmethod
110
- def _validate_expression_graph(graph: nx.DiGraph, values: Dict[str, Any]) -> None:
151
+ def _validate_expression_graph(graph: nx.DiGraph, values: dict[str, Any]) -> None:
111
152
  pass
112
153
 
113
154
  @classmethod
114
155
  def _replace_const_definitions_in_expression(
115
156
  cls,
116
157
  expression: str,
117
- definitions: Dict[str, ValidDefinitions],
158
+ definitions: dict[str, ValidDefinitions],
118
159
  machine_precision: int,
119
- ) -> Tuple[str, Dict[str, RegisterArithmeticInfo]]:
160
+ ) -> tuple[str, dict[str, RegisterArithmeticInfo]]:
120
161
  new_definitions = dict()
121
162
  for var_name, value in definitions.items():
122
163
  if isinstance(value, RegisterArithmeticInfo):
@@ -141,5 +182,5 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
141
182
  return re.sub(r"\b" + var + r"\b", str(value), expression)
142
183
 
143
184
 
144
- def _extract_literals(expression: str) -> Set[str]:
185
+ def _extract_literals(expression: str) -> set[str]:
145
186
  return set(re.findall(SUPPORTED_VAR_NAMES_REG, expression)) - SUPPORTED_FUNC_NAMES