classiq 0.37.1__py3-none-any.whl → 0.39.0__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 (280) hide show
  1. classiq/__init__.py +23 -24
  2. classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
  3. classiq/_analyzer_extras/interactive_hardware.py +3 -3
  4. classiq/_internals/api_wrapper.py +37 -17
  5. classiq/_internals/async_utils.py +1 -74
  6. classiq/_internals/authentication/device.py +9 -4
  7. classiq/_internals/authentication/password_manager.py +25 -10
  8. classiq/_internals/authentication/token_manager.py +2 -2
  9. classiq/_internals/client.py +24 -6
  10. classiq/_internals/jobs.py +10 -7
  11. classiq/analyzer/analyzer.py +29 -29
  12. classiq/analyzer/analyzer_utilities.py +5 -5
  13. classiq/analyzer/rb.py +4 -5
  14. classiq/analyzer/show_interactive_hack.py +6 -6
  15. classiq/applications/__init__.py +1 -8
  16. classiq/applications/chemistry/__init__.py +6 -0
  17. classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +9 -16
  18. classiq/applications/combinatorial_helpers/allowed_constraints.py +20 -0
  19. classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
  20. classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
  21. classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +150 -0
  22. classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
  23. classiq/applications/combinatorial_helpers/encoding_utils.py +122 -0
  24. classiq/applications/combinatorial_helpers/memory.py +77 -0
  25. classiq/applications/combinatorial_helpers/optimization_model.py +162 -0
  26. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
  27. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +75 -0
  28. classiq/applications/combinatorial_helpers/py.typed +0 -0
  29. classiq/applications/combinatorial_helpers/pyomo_utils.py +245 -0
  30. classiq/applications/combinatorial_helpers/solvers/__init__.py +0 -0
  31. classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
  32. classiq/applications/combinatorial_helpers/transformations/__init__.py +0 -0
  33. classiq/applications/combinatorial_helpers/transformations/encoding.py +187 -0
  34. classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +142 -0
  35. classiq/applications/combinatorial_helpers/transformations/ising_converter.py +122 -0
  36. classiq/applications/combinatorial_helpers/transformations/penalty.py +32 -0
  37. classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
  38. classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +75 -0
  39. classiq/applications/combinatorial_helpers/transformations/slack_variables.py +88 -0
  40. classiq/applications/combinatorial_optimization/__init__.py +13 -2
  41. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +134 -0
  42. classiq/applications/finance/__init__.py +3 -2
  43. classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +27 -30
  44. classiq/applications/grover/__init__.py +11 -0
  45. classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +20 -91
  46. classiq/applications/libraries/__init__.py +0 -0
  47. classiq/applications/libraries/qmci_library.py +35 -0
  48. classiq/applications/qnn/circuit_utils.py +2 -2
  49. classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
  50. classiq/applications/qnn/types.py +2 -2
  51. classiq/applications/qsvm/__init__.py +5 -1
  52. classiq/applications/qsvm/qsvm.py +4 -7
  53. classiq/applications/qsvm/qsvm_data_generation.py +2 -5
  54. classiq/exceptions.py +43 -1
  55. classiq/execution/all_hardware_devices.py +13 -0
  56. classiq/executor.py +12 -10
  57. classiq/interface/_version.py +1 -1
  58. classiq/interface/analyzer/analysis_params.py +6 -3
  59. classiq/interface/analyzer/result.py +12 -8
  60. classiq/interface/applications/qsvm.py +17 -3
  61. classiq/interface/ast_node.py +23 -0
  62. classiq/interface/backend/backend_preferences.py +4 -2
  63. classiq/interface/backend/pydantic_backend.py +3 -1
  64. classiq/interface/backend/quantum_backend_providers.py +1 -0
  65. classiq/interface/chemistry/fermionic_operator.py +15 -13
  66. classiq/interface/chemistry/ground_state_problem.py +18 -3
  67. classiq/interface/chemistry/molecule.py +8 -6
  68. classiq/interface/chemistry/operator.py +20 -14
  69. classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -1
  70. classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
  71. classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
  72. classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -2
  73. classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
  74. classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
  75. classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
  76. classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
  77. classiq/interface/combinatorial_optimization/examples/set_cover.py +2 -1
  78. classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
  79. classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
  80. classiq/interface/combinatorial_optimization/mht_qaoa_input.py +9 -3
  81. classiq/interface/executor/aws_execution_cost.py +4 -3
  82. classiq/interface/executor/estimation.py +2 -2
  83. classiq/interface/executor/execution_preferences.py +5 -34
  84. classiq/interface/executor/execution_request.py +15 -48
  85. classiq/interface/executor/optimizer_preferences.py +22 -13
  86. classiq/interface/executor/{quantum_program.py → quantum_code.py} +21 -15
  87. classiq/interface/executor/quantum_instruction_set.py +2 -1
  88. classiq/interface/executor/register_initialization.py +1 -3
  89. classiq/interface/executor/result.py +41 -10
  90. classiq/interface/executor/vqe_result.py +2 -2
  91. classiq/interface/finance/function_input.py +17 -4
  92. classiq/interface/finance/gaussian_model_input.py +3 -1
  93. classiq/interface/finance/log_normal_model_input.py +3 -1
  94. classiq/interface/finance/model_input.py +2 -0
  95. classiq/interface/generator/amplitude_loading.py +6 -3
  96. classiq/interface/generator/application_apis/__init__.py +1 -0
  97. classiq/interface/generator/application_apis/arithmetic_declarations.py +14 -0
  98. classiq/interface/generator/arith/argument_utils.py +14 -4
  99. classiq/interface/generator/arith/arithmetic.py +3 -1
  100. classiq/interface/generator/arith/arithmetic_arg_type_validator.py +12 -13
  101. classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -1
  102. classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -2
  103. classiq/interface/generator/arith/arithmetic_expression_validator.py +16 -2
  104. classiq/interface/generator/arith/arithmetic_operations.py +5 -10
  105. classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
  106. classiq/interface/generator/arith/binary_ops.py +202 -54
  107. classiq/interface/generator/arith/extremum_operations.py +5 -3
  108. classiq/interface/generator/arith/logical_ops.py +4 -2
  109. classiq/interface/generator/arith/machine_precision.py +3 -0
  110. classiq/interface/generator/arith/number_utils.py +34 -44
  111. classiq/interface/generator/arith/register_user_input.py +21 -1
  112. classiq/interface/generator/arith/unary_ops.py +16 -25
  113. classiq/interface/generator/builtin_api_builder.py +0 -5
  114. classiq/interface/generator/chemistry_function_params.py +4 -4
  115. classiq/interface/generator/commuting_pauli_exponentiation.py +3 -1
  116. classiq/interface/generator/compiler_keywords.py +4 -0
  117. classiq/interface/generator/complex_type.py +3 -10
  118. classiq/interface/generator/constant.py +2 -3
  119. classiq/interface/generator/control_state.py +5 -3
  120. classiq/interface/generator/credit_risk_example/linear_gci.py +10 -3
  121. classiq/interface/generator/credit_risk_example/weighted_adder.py +14 -4
  122. classiq/interface/generator/expressions/atomic_expression_functions.py +5 -3
  123. classiq/interface/generator/expressions/evaluated_expression.py +18 -4
  124. classiq/interface/generator/expressions/expression.py +3 -5
  125. classiq/interface/generator/expressions/qmod_qscalar_proxy.py +33 -0
  126. classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
  127. classiq/interface/generator/finance.py +1 -1
  128. classiq/interface/generator/function_params.py +7 -6
  129. classiq/interface/generator/functions/__init__.py +2 -2
  130. classiq/interface/generator/functions/builtins/__init__.py +15 -0
  131. classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
  132. classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
  133. classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
  134. classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +612 -219
  135. classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
  136. classiq/interface/generator/functions/classical_type.py +2 -4
  137. classiq/interface/generator/functions/foreign_function_definition.py +12 -4
  138. classiq/interface/generator/functions/function_declaration.py +2 -2
  139. classiq/interface/generator/functions/function_implementation.py +8 -4
  140. classiq/interface/generator/functions/native_function_definition.py +4 -2
  141. classiq/interface/generator/functions/register.py +4 -2
  142. classiq/interface/generator/functions/register_mapping_data.py +14 -10
  143. classiq/interface/generator/generated_circuit_data.py +2 -2
  144. classiq/interface/generator/grover_operator.py +5 -3
  145. classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +5 -1
  146. classiq/interface/generator/hardware/hardware_data.py +6 -4
  147. classiq/interface/generator/hardware_efficient_ansatz.py +25 -8
  148. classiq/interface/generator/hartree_fock.py +13 -3
  149. classiq/interface/generator/linear_pauli_rotations.py +3 -1
  150. classiq/interface/generator/mcu.py +5 -3
  151. classiq/interface/generator/mcx.py +7 -5
  152. classiq/interface/generator/model/classical_main_validator.py +1 -1
  153. classiq/interface/generator/model/constraints.py +2 -1
  154. classiq/interface/generator/model/model.py +12 -20
  155. classiq/interface/generator/model/preferences/preferences.py +4 -3
  156. classiq/interface/generator/oracles/custom_oracle.py +4 -2
  157. classiq/interface/generator/oracles/oracle_abc.py +2 -2
  158. classiq/interface/generator/qpe.py +6 -4
  159. classiq/interface/generator/qsvm.py +5 -8
  160. classiq/interface/generator/quantum_function_call.py +21 -16
  161. classiq/interface/generator/{generated_circuit.py → quantum_program.py} +10 -14
  162. classiq/interface/generator/range_types.py +3 -1
  163. classiq/interface/generator/slice_parsing_utils.py +8 -3
  164. classiq/interface/generator/standard_gates/controlled_standard_gates.py +4 -2
  165. classiq/interface/generator/state_preparation/metrics.py +2 -1
  166. classiq/interface/generator/state_preparation/state_preparation.py +7 -5
  167. classiq/interface/generator/state_propagator.py +16 -5
  168. classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
  169. classiq/interface/generator/types/struct_declaration.py +10 -7
  170. classiq/interface/generator/ucc.py +6 -4
  171. classiq/interface/generator/unitary_gate.py +7 -3
  172. classiq/interface/generator/validations/flow_graph.py +6 -4
  173. classiq/interface/generator/validations/validator_functions.py +6 -4
  174. classiq/interface/hardware.py +2 -2
  175. classiq/interface/helpers/custom_encoders.py +3 -0
  176. classiq/interface/helpers/pydantic_model_helpers.py +0 -6
  177. classiq/interface/helpers/validation_helpers.py +1 -1
  178. classiq/interface/helpers/versioned_model.py +4 -1
  179. classiq/interface/ide/show.py +2 -2
  180. classiq/interface/jobs.py +72 -3
  181. classiq/interface/model/bind_operation.py +18 -11
  182. classiq/interface/model/call_synthesis_data.py +68 -0
  183. classiq/interface/model/classical_if.py +13 -0
  184. classiq/interface/model/classical_parameter_declaration.py +2 -3
  185. classiq/interface/model/control.py +16 -0
  186. classiq/interface/model/handle_binding.py +3 -2
  187. classiq/interface/model/inplace_binary_operation.py +2 -2
  188. classiq/interface/model/invert.py +10 -0
  189. classiq/interface/model/model.py +29 -22
  190. classiq/interface/model/native_function_definition.py +3 -5
  191. classiq/interface/model/power.py +12 -0
  192. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +9 -4
  193. classiq/interface/model/quantum_expressions/control_state.py +2 -2
  194. classiq/interface/model/quantum_function_call.py +33 -142
  195. classiq/interface/model/quantum_function_declaration.py +8 -0
  196. classiq/interface/model/quantum_if_operation.py +4 -5
  197. classiq/interface/model/quantum_lambda_function.py +58 -0
  198. classiq/{quantum_register.py → interface/model/quantum_register.py} +17 -9
  199. classiq/interface/model/quantum_statement.py +3 -2
  200. classiq/interface/model/quantum_type.py +58 -59
  201. classiq/interface/model/quantum_variable_declaration.py +3 -3
  202. classiq/interface/model/repeat.py +13 -0
  203. classiq/interface/model/resolvers/function_call_resolver.py +26 -0
  204. classiq/interface/model/statement_block.py +49 -0
  205. classiq/interface/model/validations/handles_validator.py +16 -18
  206. classiq/interface/model/within_apply_operation.py +11 -0
  207. classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
  208. classiq/interface/server/routes.py +5 -4
  209. classiq/qmod/__init__.py +13 -6
  210. classiq/qmod/builtins/classical_execution_primitives.py +27 -36
  211. classiq/qmod/builtins/classical_functions.py +22 -12
  212. classiq/qmod/builtins/functions.py +272 -328
  213. classiq/qmod/builtins/operations.py +171 -35
  214. classiq/qmod/builtins/structs.py +15 -15
  215. classiq/qmod/cfunc.py +42 -0
  216. classiq/qmod/classical_function.py +6 -14
  217. classiq/qmod/declaration_inferrer.py +12 -21
  218. classiq/qmod/expression_query.py +23 -0
  219. classiq/qmod/model_state_container.py +2 -0
  220. classiq/qmod/native/__init__.py +0 -0
  221. classiq/qmod/native/expression_to_qmod.py +189 -0
  222. classiq/qmod/native/pretty_printer.py +340 -0
  223. classiq/qmod/qfunc.py +27 -0
  224. classiq/qmod/qmod_constant.py +100 -0
  225. classiq/qmod/qmod_parameter.py +36 -13
  226. classiq/qmod/qmod_struct.py +3 -3
  227. classiq/qmod/qmod_variable.py +148 -31
  228. classiq/qmod/quantum_callable.py +1 -0
  229. classiq/qmod/quantum_expandable.py +18 -19
  230. classiq/qmod/quantum_function.py +41 -8
  231. classiq/qmod/symbolic.py +48 -5
  232. classiq/qmod/symbolic_expr.py +9 -0
  233. classiq/qmod/utilities.py +13 -0
  234. classiq/qmod/write_qmod.py +39 -0
  235. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/METADATA +2 -1
  236. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/RECORD +244 -225
  237. {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/WHEEL +1 -1
  238. classiq/applications/benchmarking/__init__.py +0 -9
  239. classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
  240. classiq/applications/numpy_utils.py +0 -37
  241. classiq/applications_model_constructors/__init__.py +0 -17
  242. classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
  243. classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
  244. classiq/builtin_functions/__init__.py +0 -43
  245. classiq/builtin_functions/amplitude_loading.py +0 -3
  246. classiq/builtin_functions/binary_ops.py +0 -1
  247. classiq/builtin_functions/exponentiation.py +0 -5
  248. classiq/builtin_functions/qpe.py +0 -4
  249. classiq/builtin_functions/qsvm.py +0 -7
  250. classiq/builtin_functions/range_types.py +0 -5
  251. classiq/builtin_functions/standard_gates.py +0 -1
  252. classiq/builtin_functions/state_preparation.py +0 -6
  253. classiq/builtin_functions/suzuki_trotter.py +0 -3
  254. classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
  255. classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
  256. classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
  257. classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
  258. classiq/interface/generator/types/combinatorial_problem.py +0 -26
  259. classiq/interface/model/numeric_reinterpretation.py +0 -25
  260. classiq/interface/model/operator_synthesis_data.py +0 -48
  261. classiq/model/__init__.py +0 -14
  262. classiq/model/composite_function_generator.py +0 -33
  263. classiq/model/function_handler.py +0 -466
  264. classiq/model/function_handler.pyi +0 -152
  265. classiq/model/logic_flow.py +0 -149
  266. classiq/model/logic_flow_change_handler.py +0 -71
  267. classiq/model/model.py +0 -246
  268. classiq/quantum_functions/__init__.py +0 -17
  269. classiq/quantum_functions/annotation_parser.py +0 -207
  270. classiq/quantum_functions/decorators.py +0 -22
  271. classiq/quantum_functions/function_library.py +0 -181
  272. classiq/quantum_functions/function_parser.py +0 -74
  273. classiq/quantum_functions/quantum_function.py +0 -236
  274. /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
  275. /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
  276. /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/pauli_helpers/__init__.py} +0 -0
  277. /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
  278. /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
  279. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
  280. /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
@@ -6,10 +6,10 @@ from classiq.interface.generator.arith.register_user_input import RegisterArithm
6
6
  RegisterOrConst = Union[RegisterArithmeticInfo, float]
7
7
 
8
8
 
9
- def fraction_places(argument: RegisterOrConst, *, machine_precision: int) -> int:
9
+ def fraction_places(argument: RegisterOrConst) -> int:
10
10
  if isinstance(argument, RegisterArithmeticInfo):
11
11
  return argument.fraction_places
12
- return number_utils.fraction_places(argument, machine_precision=machine_precision)
12
+ return number_utils.fraction_places(argument)
13
13
 
14
14
 
15
15
  def integer_part_size(argument: RegisterOrConst) -> int:
@@ -18,10 +18,10 @@ def integer_part_size(argument: RegisterOrConst) -> int:
18
18
  return number_utils.integer_part_size(argument)
19
19
 
20
20
 
21
- def size(argument: RegisterOrConst, *, machine_precision: int) -> int:
21
+ def size(argument: RegisterOrConst) -> int:
22
22
  if isinstance(argument, RegisterArithmeticInfo):
23
23
  return argument.size
24
- return number_utils.size(argument, machine_precision=machine_precision)
24
+ return number_utils.size(argument)
25
25
 
26
26
 
27
27
  def is_signed(argument: RegisterOrConst) -> bool:
@@ -46,3 +46,13 @@ def bounds(argument: RegisterOrConst) -> Tuple[float, float]:
46
46
  if isinstance(argument, RegisterArithmeticInfo):
47
47
  return argument.bounds
48
48
  return argument, argument
49
+
50
+
51
+ def limit_fraction_places(
52
+ argument: RegisterOrConst, *, machine_precision: int
53
+ ) -> RegisterOrConst:
54
+ if isinstance(argument, RegisterArithmeticInfo):
55
+ return argument.limit_fraction_places(machine_precision)
56
+ return number_utils.limit_fraction_places(
57
+ argument, machine_precision=machine_precision
58
+ )
@@ -21,6 +21,8 @@ from classiq.interface.model.quantum_type import (
21
21
  register_info_to_quantum_type,
22
22
  )
23
23
 
24
+ from classiq.exceptions import ClassiqValueError
25
+
24
26
  ARITHMETIC_EXPRESSION_TARGET_NAME: str = "arithmetic_target"
25
27
  ARITHMETIC_EXPRESSION_RESULT_NAME: str = "expression_result"
26
28
 
@@ -47,7 +49,7 @@ class Arithmetic(ArithmeticExpressionABC):
47
49
  degree or operation_allows_target(id2op(node))
48
50
  for node, degree in graph.out_degree
49
51
  ):
50
- raise ValueError("Expression does not support target assignment")
52
+ raise ClassiqValueError("Expression does not support target assignment")
51
53
 
52
54
  def _create_ios(self) -> None:
53
55
  self._inputs = {
@@ -2,23 +2,16 @@ from typing import Callable, Dict, List
2
2
 
3
3
  from typing_extensions import TypeAlias
4
4
 
5
- from classiq.interface.generator.arith.argument_utils import (
6
- RegisterOrConst,
7
- fraction_places,
8
- )
5
+ from classiq.interface.generator.arith import argument_utils
9
6
  from classiq.interface.generator.arith.binary_ops import BOOLEAN_OP_WITH_FRACTIONS_ERROR
10
7
 
11
8
  from classiq.exceptions import ClassiqArithmeticError
12
9
 
13
- ArgTypeValidator: TypeAlias = Callable[[List[RegisterOrConst], int], None]
10
+ ArgTypeValidator: TypeAlias = Callable[[List[argument_utils.RegisterOrConst]], None]
14
11
 
15
12
 
16
- def _validate_bitwise_op_args(
17
- args: List[RegisterOrConst], machine_precision: int
18
- ) -> None:
19
- if any(
20
- fraction_places(arg, machine_precision=machine_precision) > 0 for arg in args
21
- ):
13
+ def _validate_bitwise_op_args(args: List[argument_utils.RegisterOrConst]) -> None:
14
+ if any(argument_utils.fraction_places(arg) > 0 for arg in args):
22
15
  raise ClassiqArithmeticError(BOOLEAN_OP_WITH_FRACTIONS_ERROR)
23
16
 
24
17
 
@@ -30,8 +23,14 @@ arg_type_validator_map: Dict[str, ArgTypeValidator] = dict(
30
23
 
31
24
 
32
25
  def validate_operation_arg_types(
33
- operation: str, args: List[RegisterOrConst], machine_precision: int
26
+ operation: str,
27
+ arguments: List[argument_utils.RegisterOrConst],
28
+ machine_precision: int,
34
29
  ) -> None:
35
30
  if operation not in arg_type_validator_map:
36
31
  return
37
- arg_type_validator_map[operation](args, machine_precision)
32
+ limited_args = [
33
+ argument_utils.limit_fraction_places(arg, machine_precision=machine_precision)
34
+ for arg in arguments
35
+ ]
36
+ arg_type_validator_map[operation](limited_args)
@@ -17,6 +17,9 @@ from classiq.interface.generator.arith.arithmetic_expression_validator import (
17
17
  from classiq.interface.generator.arith.arithmetic_result_builder import (
18
18
  validate_arithmetic_result_type,
19
19
  )
20
+ from classiq.interface.generator.arith.machine_precision import (
21
+ DEFAULT_MACHINE_PRECISION,
22
+ )
20
23
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
21
24
  from classiq.interface.generator.arith.uncomputation_methods import UncomputationMethods
22
25
  from classiq.interface.generator.expressions.expression_constants import (
@@ -36,7 +39,7 @@ ValidDefinitions: TypeAlias = Union[
36
39
 
37
40
  class ArithmeticExpressionABC(abc.ABC, FunctionParams):
38
41
  uncomputation_method: UncomputationMethods = UncomputationMethods.optimized
39
- machine_precision: pydantic.NonNegativeInt = number_utils.MAX_FRACTION_PLACES
42
+ machine_precision: pydantic.NonNegativeInt = DEFAULT_MACHINE_PRECISION
40
43
  expression: PydanticExpressionStr
41
44
  definitions: Dict[str, ValidDefinitions]
42
45
  qubit_count: Optional[pydantic.NonNegativeInt] = None
@@ -19,7 +19,9 @@ from classiq.interface.generator.arith.ast_node_rewrite import (
19
19
  from classiq.exceptions import ClassiqArithmeticError
20
20
 
21
21
  _MULTIPLE_RESULTS_ERROR_MESSAGE: str = "Expression cannot contain multiple result"
22
- _TRIVIAL_ARITHMETIC_ERROR_MESSAGE: str = "Expression must be nontrivial"
22
+ _UNEXPECTED_ARITHMETIC_ERROR_MESSAGE: str = (
23
+ "Unexpected arithmetic error: trivial expression. Please contact support."
24
+ )
23
25
  _ALLOWED_MULTI_ARGUMENT_FUNCTIONS = ("min", "max")
24
26
  Node = Union[str, float, int]
25
27
 
@@ -34,6 +36,10 @@ class ExpressionVisitor(ExpressionValidator):
34
36
  super().__init__(supported_nodes, expression_type, supported_functions)
35
37
  self.graph = nx.DiGraph()
36
38
 
39
+ @classmethod
40
+ def rewrite_ast(cls, expression_ast: AST) -> AST:
41
+ return AstNodeRewrite().visit(expression_ast)
42
+
37
43
  def visit_Compare(self, node: ast.Compare) -> None:
38
44
  self.validate_Compare(node)
39
45
  self.update_graph(node, node.left, node.comparators[0])
@@ -122,7 +128,7 @@ class InDegreeLimiter:
122
128
  if num_results > 1:
123
129
  raise ClassiqArithmeticError(_MULTIPLE_RESULTS_ERROR_MESSAGE)
124
130
  elif num_results == 0:
125
- raise ClassiqArithmeticError(_TRIVIAL_ARITHMETIC_ERROR_MESSAGE)
131
+ raise ClassiqArithmeticError(_UNEXPECTED_ARITHMETIC_ERROR_MESSAGE)
126
132
  return graph
127
133
 
128
134
 
@@ -1,5 +1,6 @@
1
1
  import ast
2
2
  import builtins
3
+ import re
3
4
  from _ast import AST
4
5
  from typing import Any, Optional, Set, Tuple, Type, Union
5
6
 
@@ -15,6 +16,7 @@ from classiq.exceptions import ClassiqArithmeticError, ClassiqValueError
15
16
  DEFAULT_SUPPORTED_FUNC_NAMES: Set[str] = {"CLShift", "CRShift", "min", "max"}
16
17
 
17
18
  DEFAULT_EXPRESSION_TYPE = "arithmetic"
19
+ IDENITIFIER_REGEX = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*")
18
20
 
19
21
  _REPEATED_VARIABLES_ERROR_MESSAGE: str = (
20
22
  "Repeated variables in the beginning of an arithmetic expression are not allowed."
@@ -75,17 +77,25 @@ class ExpressionValidator(ast.NodeVisitor):
75
77
 
76
78
  def validate(self, expression: str) -> None:
77
79
  try:
78
- ast_expr = ast.parse(expression, filename="", mode=self._mode)
80
+ adjusted_expression = self._get_adjusted_expression(expression)
81
+ ast_expr = ast.parse(adjusted_expression, filename="", mode=self._mode)
79
82
  except SyntaxError as e:
80
83
  raise ClassiqValueError(f"Failed to parse expression {expression!r}") from e
81
84
  try:
82
- self._ast_obj = AstNodeRewrite().visit(ast_expr)
85
+ self._ast_obj = self.rewrite_ast(ast_expr)
83
86
  self.visit(self._ast_obj)
84
87
  except RecursionError as e:
85
88
  raise ClassiqValueError(
86
89
  f"Failed to parse expression since it is too long: {expression}"
87
90
  ) from e
88
91
 
92
+ @staticmethod
93
+ def _get_adjusted_expression(expression: str) -> str:
94
+ # This works around the simplification of the trivial expressions such as a + 0, 1 * a, etc.
95
+ if IDENITIFIER_REGEX.fullmatch(expression):
96
+ return f"0 + {expression}"
97
+ return expression
98
+
89
99
  @property
90
100
  def ast_obj(self) -> ast.AST:
91
101
  if not self._ast_obj:
@@ -182,6 +192,10 @@ class ExpressionValidator(ast.NodeVisitor):
182
192
  self._supported_functions.add(node.name)
183
193
  self.generic_visit(node)
184
194
 
195
+ @classmethod
196
+ def rewrite_ast(cls, expression_ast: AST) -> AST:
197
+ return expression_ast
198
+
185
199
 
186
200
  def validate_expression(
187
201
  expression: str,
@@ -1,11 +1,11 @@
1
- from __future__ import annotations
2
-
3
1
  import abc
4
2
  from typing import ClassVar, Iterable, Optional, Tuple
5
3
 
6
4
  import pydantic
7
5
 
8
- from classiq.interface.generator.arith import argument_utils, number_utils
6
+ from classiq.interface.generator.arith.machine_precision import (
7
+ DEFAULT_MACHINE_PRECISION,
8
+ )
9
9
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
10
10
  from classiq.interface.generator.function_params import FunctionParams
11
11
 
@@ -14,7 +14,7 @@ DEFAULT_GARBAGE_OUT_NAME: str = "extra_qubits"
14
14
 
15
15
  class ArithmeticOperationParams(FunctionParams):
16
16
  output_size: Optional[pydantic.PositiveInt]
17
- machine_precision: pydantic.PositiveInt = number_utils.MAX_FRACTION_PLACES
17
+ machine_precision: pydantic.PositiveInt = DEFAULT_MACHINE_PRECISION
18
18
  output_name: ClassVar[str]
19
19
  garbage_output_name: ClassVar[str] = DEFAULT_GARBAGE_OUT_NAME
20
20
  _result_register: Optional[RegisterArithmeticInfo] = pydantic.PrivateAttr(
@@ -46,11 +46,6 @@ class ArithmeticOperationParams(FunctionParams):
46
46
  return suggested_bounds
47
47
  return None
48
48
 
49
- def _compute_fraction_places(self, argument: argument_utils.RegisterOrConst) -> int:
50
- return argument_utils.fraction_places(
51
- argument, machine_precision=self.machine_precision
52
- )
53
-
54
49
  @abc.abstractmethod
55
- def get_params_inplace_options(self) -> Iterable[ArithmeticOperationParams]:
50
+ def get_params_inplace_options(self) -> Iterable["ArithmeticOperationParams"]:
56
51
  pass
@@ -30,7 +30,7 @@ class AstNodeRewrite(ast.NodeTransformer):
30
30
  elif hasattr(node, "op"):
31
31
  return type(node.op).__name__ + next(self.count_str_gen)
32
32
  elif hasattr(node, "func"):
33
- return node.func.id
33
+ return self.extract_node_id(node.func)
34
34
  elif hasattr(node, "value"):
35
35
  return node.value
36
36
  elif hasattr(node, "ops"):