classiq 0.93.0__py3-none-any.whl → 0.94.1__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.

Potentially problematic release.


This version of classiq might be problematic. Click here for more details.

Files changed (261) hide show
  1. classiq/__init__.py +6 -19
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
  3. classiq/_analyzer_extras/interactive_hardware.py +19 -12
  4. classiq/_internals/api_wrapper.py +38 -52
  5. classiq/_internals/async_utils.py +4 -7
  6. classiq/_internals/authentication/auth0.py +3 -3
  7. classiq/_internals/authentication/device.py +4 -4
  8. classiq/_internals/authentication/password_manager.py +13 -13
  9. classiq/_internals/authentication/token_manager.py +4 -5
  10. classiq/_internals/client.py +17 -44
  11. classiq/_internals/config.py +1 -2
  12. classiq/_internals/help.py +1 -2
  13. classiq/_internals/host_checker.py +3 -3
  14. classiq/_internals/jobs.py +14 -14
  15. classiq/_internals/type_validation.py +3 -3
  16. classiq/analyzer/analyzer.py +18 -18
  17. classiq/analyzer/rb.py +17 -8
  18. classiq/applications/chemistry/__init__.py +0 -30
  19. classiq/applications/chemistry/op_utils.py +4 -4
  20. classiq/applications/chemistry/problems.py +3 -3
  21. classiq/applications/chemistry/ucc.py +1 -2
  22. classiq/applications/chemistry/z2_symmetries.py +4 -4
  23. classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
  24. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
  25. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
  26. classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
  27. classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
  28. classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
  29. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
  30. classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
  31. classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
  32. classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
  33. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
  34. classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
  35. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
  36. classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
  37. classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
  38. classiq/applications/iqae/iqae.py +8 -8
  39. classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
  40. classiq/applications/qnn/datasets/dataset_parity.py +6 -6
  41. classiq/applications/qnn/qlayer.py +8 -7
  42. classiq/applications/qnn/torch_utils.py +3 -4
  43. classiq/applications/qnn/types.py +2 -1
  44. classiq/applications/qsp/qsp.py +5 -4
  45. classiq/applications/qsvm/qsvm_data_generation.py +1 -2
  46. classiq/evaluators/classical_expression.py +0 -4
  47. classiq/evaluators/parameter_types.py +7 -8
  48. classiq/evaluators/qmod_annotated_expression.py +24 -26
  49. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
  50. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
  51. classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
  52. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +4 -4
  53. classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
  54. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
  55. classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
  56. classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
  57. classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
  58. classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
  59. classiq/execution/execution_session.py +18 -19
  60. classiq/execution/jobs.py +26 -26
  61. classiq/execution/qnn.py +1 -2
  62. classiq/execution/user_budgets.py +52 -7
  63. classiq/executor.py +1 -3
  64. classiq/interface/_version.py +1 -1
  65. classiq/interface/analyzer/analysis_params.py +4 -4
  66. classiq/interface/analyzer/cytoscape_graph.py +3 -3
  67. classiq/interface/analyzer/result.py +4 -4
  68. classiq/interface/applications/qsvm.py +5 -8
  69. classiq/interface/ast_node.py +3 -3
  70. classiq/interface/backend/backend_preferences.py +16 -16
  71. classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
  72. classiq/interface/chemistry/ansatz_library.py +3 -5
  73. classiq/interface/chemistry/operator.py +3 -3
  74. classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
  75. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
  76. classiq/interface/compression_utils.py +2 -3
  77. classiq/interface/debug_info/debug_info.py +7 -7
  78. classiq/interface/exceptions.py +2 -3
  79. classiq/interface/execution/iqcc.py +1 -3
  80. classiq/interface/execution/primitives.py +6 -6
  81. classiq/interface/executor/estimate_cost.py +1 -1
  82. classiq/interface/executor/execution_preferences.py +3 -5
  83. classiq/interface/executor/execution_request.py +10 -10
  84. classiq/interface/executor/execution_result.py +1 -2
  85. classiq/interface/executor/quantum_code.py +8 -8
  86. classiq/interface/executor/result.py +28 -18
  87. classiq/interface/executor/user_budget.py +2 -3
  88. classiq/interface/executor/vqe_result.py +5 -6
  89. classiq/interface/generator/ansatz_library.py +6 -8
  90. classiq/interface/generator/application_apis/__init__.py +0 -2
  91. classiq/interface/generator/arith/arithmetic.py +2 -2
  92. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
  93. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
  94. classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
  95. classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
  96. classiq/interface/generator/arith/arithmetic_operations.py +4 -6
  97. classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
  98. classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
  99. classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
  100. classiq/interface/generator/arith/binary_ops.py +7 -36
  101. classiq/interface/generator/arith/logical_ops.py +2 -3
  102. classiq/interface/generator/arith/number_utils.py +2 -2
  103. classiq/interface/generator/arith/register_user_input.py +2 -2
  104. classiq/interface/generator/arith/unary_ops.py +2 -2
  105. classiq/interface/generator/circuit_code/circuit_code.py +8 -10
  106. classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
  107. classiq/interface/generator/complex_type.py +2 -2
  108. classiq/interface/generator/copy.py +1 -3
  109. classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
  110. classiq/interface/generator/expressions/evaluated_expression.py +2 -3
  111. classiq/interface/generator/expressions/expression.py +2 -2
  112. classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
  113. classiq/interface/generator/function_param_list.py +0 -20
  114. classiq/interface/generator/function_params.py +5 -6
  115. classiq/interface/generator/functions/classical_function_declaration.py +2 -2
  116. classiq/interface/generator/functions/classical_type.py +3 -3
  117. classiq/interface/generator/functions/type_modifier.py +0 -14
  118. classiq/interface/generator/functions/type_name.py +2 -2
  119. classiq/interface/generator/generated_circuit_data.py +12 -13
  120. classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
  121. classiq/interface/generator/hardware/hardware_data.py +8 -8
  122. classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
  123. classiq/interface/generator/mcu.py +3 -3
  124. classiq/interface/generator/mcx.py +3 -3
  125. classiq/interface/generator/model/constraints.py +34 -5
  126. classiq/interface/generator/model/preferences/preferences.py +15 -21
  127. classiq/interface/generator/model/quantum_register.py +7 -10
  128. classiq/interface/generator/noise_properties.py +3 -7
  129. classiq/interface/generator/parameters.py +1 -1
  130. classiq/interface/generator/partitioned_register.py +1 -2
  131. classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
  132. classiq/interface/generator/qsvm.py +2 -2
  133. classiq/interface/generator/quantum_function_call.py +8 -11
  134. classiq/interface/generator/quantum_program.py +12 -15
  135. classiq/interface/generator/range_types.py +3 -3
  136. classiq/interface/generator/slice_parsing_utils.py +4 -5
  137. classiq/interface/generator/standard_gates/standard_gates.py +2 -4
  138. classiq/interface/generator/state_preparation/state_preparation.py +6 -8
  139. classiq/interface/generator/synthesis_execution_parameter.py +1 -3
  140. classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
  141. classiq/interface/generator/transpiler_basis_gates.py +2 -4
  142. classiq/interface/generator/types/builtin_enum_declarations.py +0 -136
  143. classiq/interface/generator/types/compilation_metadata.py +12 -1
  144. classiq/interface/generator/types/enum_declaration.py +2 -1
  145. classiq/interface/generator/validations/flow_graph.py +3 -3
  146. classiq/interface/generator/visitor.py +10 -12
  147. classiq/interface/hardware.py +2 -2
  148. classiq/interface/helpers/classproperty.py +2 -2
  149. classiq/interface/helpers/custom_encoders.py +2 -1
  150. classiq/interface/helpers/custom_pydantic_types.py +1 -1
  151. classiq/interface/helpers/text_utils.py +1 -4
  152. classiq/interface/ide/visual_model.py +5 -5
  153. classiq/interface/jobs.py +3 -3
  154. classiq/interface/model/allocate.py +4 -4
  155. classiq/interface/model/block.py +2 -2
  156. classiq/interface/model/bounds.py +3 -3
  157. classiq/interface/model/control.py +1 -1
  158. classiq/interface/model/inplace_binary_operation.py +2 -2
  159. classiq/interface/model/model.py +4 -4
  160. classiq/interface/model/parameter.py +1 -3
  161. classiq/interface/model/port_declaration.py +1 -1
  162. classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
  163. classiq/interface/model/quantum_function_call.py +3 -6
  164. classiq/interface/model/quantum_function_declaration.py +1 -0
  165. classiq/interface/model/quantum_lambda_function.py +4 -4
  166. classiq/interface/model/quantum_statement.py +4 -4
  167. classiq/interface/model/quantum_type.py +14 -14
  168. classiq/interface/model/validation_handle.py +2 -3
  169. classiq/interface/model/variable_declaration_statement.py +2 -2
  170. classiq/interface/pretty_print/expression_to_qmod.py +3 -4
  171. classiq/interface/server/routes.py +0 -4
  172. classiq/interface/source_reference.py +3 -4
  173. classiq/model_expansions/arithmetic.py +6 -7
  174. classiq/model_expansions/arithmetic_compute_result_attrs.py +4 -5
  175. classiq/model_expansions/capturing/captured_vars.py +3 -3
  176. classiq/model_expansions/capturing/mangling_utils.py +1 -2
  177. classiq/model_expansions/closure.py +12 -11
  178. classiq/model_expansions/function_builder.py +14 -6
  179. classiq/model_expansions/generative_functions.py +1 -4
  180. classiq/model_expansions/interpreters/base_interpreter.py +2 -6
  181. classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
  182. classiq/model_expansions/quantum_operations/allocate.py +4 -4
  183. classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
  184. classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
  185. classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
  186. classiq/model_expansions/quantum_operations/emitter.py +3 -5
  187. classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
  188. classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
  189. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
  190. classiq/model_expansions/scope.py +7 -7
  191. classiq/model_expansions/scope_initialization.py +4 -0
  192. classiq/model_expansions/visitors/symbolic_param_inference.py +3 -3
  193. classiq/model_expansions/visitors/uncomputation_signature_inference.py +317 -0
  194. classiq/model_expansions/visitors/variable_references.py +15 -14
  195. classiq/open_library/functions/__init__.py +6 -0
  196. classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
  197. classiq/open_library/functions/grover.py +8 -10
  198. classiq/open_library/functions/modular_exponentiation.py +96 -8
  199. classiq/qmod/__init__.py +5 -2
  200. classiq/qmod/builtins/classical_execution_primitives.py +4 -11
  201. classiq/qmod/builtins/classical_functions.py +1 -42
  202. classiq/qmod/builtins/enums.py +0 -136
  203. classiq/qmod/builtins/functions/__init__.py +0 -13
  204. classiq/qmod/builtins/functions/allocation.py +4 -4
  205. classiq/qmod/builtins/functions/arithmetic.py +22 -27
  206. classiq/qmod/builtins/functions/standard_gates.py +27 -27
  207. classiq/qmod/builtins/operations.py +35 -58
  208. classiq/qmod/builtins/structs.py +2 -58
  209. classiq/qmod/cfunc.py +3 -2
  210. classiq/qmod/classical_function.py +2 -1
  211. classiq/qmod/cparam.py +2 -8
  212. classiq/qmod/create_model_function.py +7 -7
  213. classiq/qmod/declaration_inferrer.py +33 -30
  214. classiq/qmod/model_state_container.py +2 -2
  215. classiq/qmod/native/pretty_printer.py +25 -14
  216. classiq/qmod/pretty_print/expression_to_python.py +5 -3
  217. classiq/qmod/pretty_print/pretty_printer.py +39 -17
  218. classiq/qmod/python_classical_type.py +40 -13
  219. classiq/qmod/qfunc.py +139 -16
  220. classiq/qmod/qmod_constant.py +2 -2
  221. classiq/qmod/qmod_parameter.py +5 -2
  222. classiq/qmod/qmod_variable.py +47 -43
  223. classiq/qmod/quantum_callable.py +18 -13
  224. classiq/qmod/quantum_expandable.py +31 -26
  225. classiq/qmod/quantum_function.py +51 -32
  226. classiq/qmod/semantics/annotation/call_annotation.py +2 -2
  227. classiq/qmod/semantics/error_manager.py +5 -6
  228. classiq/qmod/semantics/lambdas.py +1 -2
  229. classiq/qmod/semantics/validation/types_validation.py +1 -2
  230. classiq/qmod/symbolic.py +2 -4
  231. classiq/qmod/utilities.py +13 -10
  232. classiq/qmod/write_qmod.py +3 -4
  233. classiq/quantum_program.py +1 -3
  234. classiq/synthesis.py +11 -7
  235. {classiq-0.93.0.dist-info → classiq-0.94.1.dist-info}/METADATA +2 -3
  236. {classiq-0.93.0.dist-info → classiq-0.94.1.dist-info}/RECORD +238 -260
  237. classiq/applications/chemistry/ansatz_parameters.py +0 -29
  238. classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
  239. classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
  240. classiq/applications/chemistry/ground_state_problem.py +0 -42
  241. classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
  242. classiq/interface/chemistry/elements.py +0 -120
  243. classiq/interface/chemistry/fermionic_operator.py +0 -208
  244. classiq/interface/chemistry/ground_state_problem.py +0 -132
  245. classiq/interface/chemistry/ground_state_result.py +0 -8
  246. classiq/interface/chemistry/molecule.py +0 -71
  247. classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
  248. classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
  249. classiq/interface/generator/chemistry_function_params.py +0 -50
  250. classiq/interface/generator/entangler_params.py +0 -72
  251. classiq/interface/generator/entanglers.py +0 -14
  252. classiq/interface/generator/hartree_fock.py +0 -26
  253. classiq/interface/generator/hva.py +0 -22
  254. classiq/interface/generator/linear_pauli_rotations.py +0 -92
  255. classiq/interface/generator/qft.py +0 -37
  256. classiq/interface/generator/ucc.py +0 -74
  257. classiq/interface/helpers/backward_compatibility.py +0 -9
  258. classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
  259. classiq/qmod/builtins/functions/chemistry.py +0 -123
  260. {classiq-0.93.0.dist-info → classiq-0.94.1.dist-info}/WHEEL +0 -0
  261. {classiq-0.93.0.dist-info → classiq-0.94.1.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,5 +1,4 @@
1
1
  import datetime
2
- from typing import Optional
3
2
 
4
3
  import pydantic
5
4
  from pydantic import ConfigDict, Field
@@ -11,11 +10,11 @@ from classiq.interface.helpers.versioned_model import VersionedModel
11
10
  class UserBudget(VersionedModel):
12
11
  provider: str
13
12
  currency_code: str
14
- organization: Optional[str] = Field(default=None)
13
+ organization: str | None = Field(default=None)
15
14
  available_budget: float
16
15
  used_budget: float
17
16
  last_allocation_date: datetime.datetime
18
- budget_limit: Optional[float] = Field(default=None)
17
+ budget_limit: float | None = Field(default=None)
19
18
 
20
19
  model_config = ConfigDict(extra="ignore")
21
20
 
@@ -1,7 +1,6 @@
1
1
  import base64
2
2
  import io
3
3
  from datetime import datetime
4
- from typing import Optional
5
4
 
6
5
  import pydantic
7
6
  from PIL import Image
@@ -18,8 +17,8 @@ Solution = tuple[int, ...]
18
17
  class SolverResult(BaseModel):
19
18
  energy: float
20
19
  # TODO: add time units (like seconds)
21
- time: Optional[float] = None
22
- solution: Optional[Solution] = None
20
+ time: float | None = None
21
+ solution: Solution | None = None
23
22
 
24
23
 
25
24
  class SolutionData(BaseModel):
@@ -37,7 +36,7 @@ class VQEIntermediateData(BaseModel):
37
36
  parameters: list[float] = pydantic.Field(
38
37
  description="The optimizer parameters for the variational form"
39
38
  )
40
- mean_all_solutions: Optional[float] = pydantic.Field(
39
+ mean_all_solutions: float | None = pydantic.Field(
41
40
  default=None, description="The mean score of all solutions in this iteration"
42
41
  )
43
42
  solutions: list[SolutionData] = pydantic.Field(
@@ -51,12 +50,12 @@ class VQEIntermediateData(BaseModel):
51
50
 
52
51
  class VQESolverResult(SolverResult, QmodPyObject):
53
52
  eigenstate: dict[str, Complex]
54
- reduced_probabilities: Optional[dict[str, float]] = None
53
+ reduced_probabilities: dict[str, float] | None = None
55
54
  optimized_circuit_sample_results: ExecutionDetails
56
55
  intermediate_results: list[VQEIntermediateData]
57
56
  optimal_parameters: dict[str, float]
58
57
  convergence_graph_str: str
59
- num_solutions: Optional[int] = None
58
+ num_solutions: int | None = None
60
59
  num_shots: int
61
60
 
62
61
  def show_convergence_graph(self) -> None:
@@ -1,5 +1,3 @@
1
- from typing import Optional, Union
2
-
3
1
  from pydantic import BaseModel
4
2
 
5
3
  from classiq.interface.enum_utils import StrEnum
@@ -43,20 +41,20 @@ class EntanglingLayersArgs(CustomAnsatzArgs):
43
41
  class RandomArgs(CustomAnsatzArgs):
44
42
  gate_count: int = 100
45
43
  gate_probabilities: dict[str, float] = {"cx": 0.5, "u": 0.5}
46
- random_seed: Optional[int] = None
44
+ random_seed: int | None = None
47
45
 
48
46
 
49
47
  class RandomTwoQubitGatesArgs(CustomAnsatzArgs):
50
48
  random_two_qubit_gate_count_factor: float = 1.0
51
- random_seed: Optional[int] = None
49
+ random_seed: int | None = None
52
50
 
53
51
 
54
52
  class TwoLocalArgs(CustomAnsatzArgs):
55
- rotation_blocks: Optional[Union[RotationBlocksType, list[RotationBlocksType]]] = (
53
+ rotation_blocks: RotationBlocksType | list[RotationBlocksType] | None = (
56
54
  RotationBlocksType.ry
57
55
  )
58
- entanglement_blocks: Optional[
59
- Union[EntanglementBlocksType, list[EntanglementBlocksType]]
60
- ] = EntanglementBlocksType.cx
56
+ entanglement_blocks: None | (
57
+ EntanglementBlocksType | list[EntanglementBlocksType]
58
+ ) = EntanglementBlocksType.cx
61
59
  entanglement: EntanglementStructureType = EntanglementStructureType.full
62
60
  reps: int = 3
@@ -3,9 +3,7 @@ from classiq.interface.generator.builtin_api_builder import (
3
3
  )
4
4
 
5
5
  from .arithmetic_declarations import * # noqa: F403
6
- from .chemistry_declarations import * # noqa: F403
7
6
  from .combinatorial_optimization_declarations import * # noqa: F403
8
- from .entangler_declarations import * # noqa: F403
9
7
  from .qsvm_declarations import * # noqa: F403
10
8
 
11
9
  populate_builtin_declarations(vars().values())
@@ -1,5 +1,5 @@
1
1
  import ast
2
- from typing import Any, Final, Optional, cast
2
+ from typing import Any, Final, cast
3
3
 
4
4
  import networkx as nx
5
5
  import pydantic
@@ -48,7 +48,7 @@ def is_bool(expr: str) -> bool:
48
48
 
49
49
 
50
50
  class Arithmetic(ArithmeticExpressionABC):
51
- target: Optional[RegisterArithmeticInfo] = None
51
+ target: RegisterArithmeticInfo | None = None
52
52
  inputs_to_save: set[str] = pydantic.Field(default_factory=set)
53
53
 
54
54
  @pydantic.field_validator("inputs_to_save")
@@ -1,6 +1,5 @@
1
- from typing import Callable
2
-
3
- from typing_extensions import TypeAlias
1
+ from collections.abc import Callable
2
+ from typing import TypeAlias
4
3
 
5
4
  from classiq.interface.exceptions import ClassiqArithmeticError
6
5
  from classiq.interface.generator.arith import argument_utils
@@ -1,12 +1,11 @@
1
1
  import abc
2
2
  import ast
3
3
  import re
4
- from typing import Any, Optional, Union
4
+ from typing import Any, Optional, TypeAlias, Union
5
5
 
6
6
  import networkx as nx
7
7
  import pydantic
8
8
  from pydantic import TypeAdapter
9
- from typing_extensions import TypeAlias
10
9
 
11
10
  from classiq.interface.exceptions import ClassiqValueError
12
11
  from classiq.interface.generator.arith import number_utils
@@ -42,7 +41,7 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
42
41
  machine_precision: pydantic.NonNegativeInt = DEFAULT_MACHINE_PRECISION
43
42
  expression: PydanticExpressionStr
44
43
  definitions: dict[str, ValidDefinitions]
45
- qubit_count: Optional[pydantic.NonNegativeInt] = None
44
+ qubit_count: pydantic.NonNegativeInt | None = None
46
45
 
47
46
  def _get_literal_set(self) -> set[str]:
48
47
  return _extract_literals(self.expression)
@@ -85,7 +84,7 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
85
84
  ):
86
85
  definition_dict = dict(definition_dict)
87
86
  definitions = definitions_adapter.validate_python(definition_dict)
88
- machine_precision: Optional[int] = values.get(
87
+ machine_precision: int | None = values.get(
89
88
  "machine_precision", DEFAULT_MACHINE_PRECISION
90
89
  )
91
90
  if (
@@ -173,7 +172,7 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
173
172
 
174
173
  @staticmethod
175
174
  def _replace_numeric_value_in_expression(
176
- expression: str, var: str, value: Union[int, float], machine_precision: int
175
+ expression: str, var: str, value: int | float, machine_precision: int
177
176
  ) -> str:
178
177
  if isinstance(value, float):
179
178
  value = number_utils.limit_fraction_places(
@@ -1,7 +1,8 @@
1
1
  import ast
2
+ import re
2
3
  from _ast import AST
3
4
  from collections.abc import Collection
4
- from typing import Optional, Union, cast
5
+ from typing import Union, cast
5
6
 
6
7
  import networkx as nx
7
8
 
@@ -23,6 +24,9 @@ _UNEXPECTED_ARITHMETIC_ERROR_MESSAGE: str = (
23
24
  "Quantum expressions that evaluate to a classical value are not supported"
24
25
  )
25
26
  _ALLOWED_MULTI_ARGUMENT_FUNCTIONS = ("min", "max")
27
+ _ALLOWED_MULTI_ARGUMENT_PATTEN = re.compile(
28
+ rf"(({')|('.join(_ALLOWED_MULTI_ARGUMENT_FUNCTIONS)}))_[0-9]+"
29
+ )
26
30
  Node = Union[str, float, int]
27
31
 
28
32
 
@@ -31,7 +35,7 @@ class ExpressionVisitor(ExpressionValidator):
31
35
  self,
32
36
  supported_nodes: tuple[type[AST], ...],
33
37
  expression_type: str = DEFAULT_EXPRESSION_TYPE,
34
- supported_functions: Optional[set[str]] = None,
38
+ supported_functions: set[str] | None = None,
35
39
  ) -> None:
36
40
  super().__init__(supported_nodes, expression_type, supported_functions)
37
41
  self.graph = nx.DiGraph()
@@ -101,7 +105,10 @@ class InDegreeLimiter:
101
105
 
102
106
  @staticmethod
103
107
  def _condition(graph: nx.DiGraph, node: str) -> bool:
104
- return graph.in_degree[node] > 2 and node in _ALLOWED_MULTI_ARGUMENT_FUNCTIONS
108
+ return (
109
+ graph.in_degree[node] > 2
110
+ and _ALLOWED_MULTI_ARGUMENT_PATTEN.fullmatch(node) is not None
111
+ )
105
112
 
106
113
  @classmethod
107
114
  def _node_conversion(cls, graph: nx.DiGraph, node: str) -> nx.DiGraph:
@@ -137,7 +144,7 @@ def parse_expression(
137
144
  *,
138
145
  supported_nodes: tuple[type[AST], ...] = DEFAULT_SUPPORTED_NODE_TYPES,
139
146
  expression_type: str = DEFAULT_EXPRESSION_TYPE,
140
- supported_functions: Optional[set[str]] = None,
147
+ supported_functions: set[str] | None = None,
141
148
  ) -> nx.DiGraph:
142
149
  supported_functions = supported_functions or DEFAULT_SUPPORTED_FUNC_NAMES
143
150
 
@@ -1,18 +1,16 @@
1
1
  import ast
2
2
  import re
3
3
  from _ast import AST
4
- from typing import Any, Optional, Union
4
+ from typing import Any, TypeAlias, Union, get_args
5
5
 
6
6
  from sympy import Expr
7
- from typing_extensions import TypeAlias, get_args
8
7
 
9
8
  from classiq.interface.exceptions import ClassiqArithmeticError, ClassiqValueError
10
- from classiq.interface.generator.arith.ast_node_rewrite import AstNodeRewrite
11
9
  from classiq.interface.generator.expressions.sympy_supported_expressions import (
12
10
  SYMPY_SUPPORTED_EXPRESSIONS,
13
11
  )
14
12
 
15
- DEFAULT_SUPPORTED_FUNC_NAMES: set[str] = {"CLShift", "CRShift", "min", "max"}
13
+ DEFAULT_SUPPORTED_FUNC_NAMES: set[str] = {"min", "max"}
16
14
 
17
15
  DEFAULT_EXPRESSION_TYPE = "arithmetic"
18
16
  IDENITIFIER_REGEX = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*")
@@ -55,7 +53,7 @@ SupportedNodesTypes = Union[
55
53
  DEFAULT_SUPPORTED_NODE_TYPES = get_args(SupportedNodesTypes)
56
54
 
57
55
 
58
- def is_constant(expr: Union[str, Expr]) -> bool:
56
+ def is_constant(expr: str | Expr) -> bool:
59
57
  try:
60
58
  float(expr)
61
59
  return True
@@ -72,7 +70,7 @@ class ExpressionValidator(ast.NodeVisitor):
72
70
  self,
73
71
  supported_nodes: tuple[type[AST], ...],
74
72
  expression_type: str = DEFAULT_EXPRESSION_TYPE,
75
- supported_functions: Optional[set[str]] = None,
73
+ supported_functions: set[str] | None = None,
76
74
  mode: str = "eval",
77
75
  ) -> None:
78
76
  super().__init__()
@@ -80,7 +78,7 @@ class ExpressionValidator(ast.NodeVisitor):
80
78
  self._expression_type = expression_type
81
79
  self._supported_functions = supported_functions or DEFAULT_SUPPORTED_FUNC_NAMES
82
80
  self._mode = mode
83
- self._ast_obj: Optional[ast.AST] = None
81
+ self._ast_obj: ast.AST | None = None
84
82
 
85
83
  def validate(self, expression: str) -> None:
86
84
  try:
@@ -171,14 +169,13 @@ class ExpressionValidator(ast.NodeVisitor):
171
169
  node,
172
170
  "the first two call arguments are identical",
173
171
  )
174
- node_id = AstNodeRewrite().extract_node_id(node)
175
- if node_id not in self._supported_functions:
176
- raise ClassiqValueError(f"{node_id} not in supported functions")
177
-
178
- if node_id in ("CLShift", "CRShift") and (
179
- len(node.args) != 2 or not isinstance(node.args[1], ast.Constant)
172
+ if (
173
+ not isinstance(node.func, ast.Name)
174
+ or node.func.id not in self._supported_functions
180
175
  ):
181
- raise ClassiqValueError("Cyclic Shift expects 2 arguments (exp, int)")
176
+ raise ClassiqValueError(
177
+ f"{ast.unparse(node.func)} not in supported functions"
178
+ )
182
179
 
183
180
  def visit_Call(self, node: ast.Call) -> None:
184
181
  self.validate_Call(node)
@@ -207,7 +204,7 @@ def validate_expression(
207
204
  *,
208
205
  supported_nodes: tuple[type[AST], ...] = DEFAULT_SUPPORTED_NODE_TYPES,
209
206
  expression_type: str = DEFAULT_EXPRESSION_TYPE,
210
- supported_functions: Optional[set[str]] = None,
207
+ supported_functions: set[str] | None = None,
211
208
  mode: str = "eval",
212
209
  ) -> ast.AST:
213
210
  supported_functions = supported_functions or set(SYMPY_SUPPORTED_EXPRESSIONS).union(
@@ -1,6 +1,6 @@
1
1
  import abc
2
2
  from collections.abc import Iterable
3
- from typing import ClassVar, Final, Optional
3
+ from typing import ClassVar, Final
4
4
 
5
5
  import pydantic
6
6
 
@@ -18,13 +18,11 @@ MODULO_WITH_FRACTION_PLACES_ERROR_MSG: Final[str] = (
18
18
 
19
19
 
20
20
  class ArithmeticOperationParams(FunctionParams):
21
- output_size: Optional[pydantic.PositiveInt] = pydantic.Field(default=None)
21
+ output_size: pydantic.PositiveInt | None = pydantic.Field(default=None)
22
22
  machine_precision: pydantic.PositiveInt = DEFAULT_MACHINE_PRECISION
23
23
  output_name: ClassVar[str]
24
24
  garbage_output_name: ClassVar[str] = DEFAULT_GARBAGE_OUT_NAME
25
- _result_register: Optional[RegisterArithmeticInfo] = pydantic.PrivateAttr(
26
- default=None
27
- )
25
+ _result_register: RegisterArithmeticInfo | None = pydantic.PrivateAttr(default=None)
28
26
 
29
27
  @abc.abstractmethod
30
28
  def _get_result_register(self) -> RegisterArithmeticInfo:
@@ -46,7 +44,7 @@ class ArithmeticOperationParams(FunctionParams):
46
44
 
47
45
  def _legal_bounds(
48
46
  self, suggested_bounds: tuple[float, float], max_bounds: tuple[float, float]
49
- ) -> Optional[tuple[float, float]]:
47
+ ) -> tuple[float, float] | None:
50
48
  if self.output_size is None or (
51
49
  suggested_bounds[0] >= max_bounds[0]
52
50
  and suggested_bounds[1] <= max_bounds[1]