classiq 0.88.0__py3-none-any.whl → 0.90.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.

Potentially problematic release.


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

Files changed (103) hide show
  1. classiq/__init__.py +1 -0
  2. classiq/_internals/api_wrapper.py +16 -32
  3. classiq/_internals/config.py +1 -1
  4. classiq/analyzer/show_interactive_hack.py +26 -1
  5. classiq/applications/chemistry/chemistry_model_constructor.py +14 -2
  6. classiq/applications/combinatorial_helpers/pyomo_utils.py +9 -6
  7. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
  8. classiq/applications/combinatorial_optimization/combinatorial_problem.py +16 -8
  9. classiq/evaluators/classical_expression.py +63 -41
  10. classiq/evaluators/control.py +31 -52
  11. classiq/evaluators/expression_evaluator.py +8 -4
  12. classiq/evaluators/parameter_types.py +200 -104
  13. classiq/evaluators/qmod_annotated_expression.py +10 -9
  14. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +2 -2
  15. classiq/evaluators/qmod_expression_visitors/qmod_expression_renamer.py +1 -1
  16. classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +66 -5
  17. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +12 -37
  18. classiq/evaluators/qmod_node_evaluators/constant_evaluation.py +8 -17
  19. classiq/evaluators/qmod_node_evaluators/measurement_evaluation.py +1 -1
  20. classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +7 -1
  21. classiq/evaluators/qmod_node_evaluators/name_evaluation.py +0 -1
  22. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +9 -1
  23. classiq/evaluators/qmod_node_evaluators/utils.py +33 -0
  24. classiq/evaluators/qmod_type_inference/classical_type_inference.py +4 -7
  25. classiq/interface/_version.py +1 -1
  26. classiq/interface/analyzer/analysis_params.py +2 -26
  27. classiq/interface/analyzer/result.py +4 -0
  28. classiq/interface/backend/backend_preferences.py +1 -1
  29. classiq/interface/chemistry/ground_state_problem.py +16 -2
  30. classiq/interface/executor/optimizer_preferences.py +0 -112
  31. classiq/interface/generator/application_apis/chemistry_declarations.py +3 -1
  32. classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -7
  33. classiq/interface/generator/arith/register_user_input.py +1 -1
  34. classiq/interface/generator/expressions/evaluated_expression.py +3 -13
  35. classiq/interface/generator/expressions/expression_types.py +8 -22
  36. classiq/interface/generator/expressions/proxies/classical/classical_proxy.py +2 -2
  37. classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +1 -2
  38. classiq/interface/generator/functions/classical_type.py +24 -3
  39. classiq/interface/generator/functions/concrete_types.py +1 -1
  40. classiq/interface/generator/functions/function_declaration.py +0 -4
  41. classiq/interface/generator/functions/type_name.py +25 -0
  42. classiq/interface/generator/generated_circuit_data.py +4 -0
  43. classiq/interface/generator/hardware_efficient_ansatz.py +1 -1
  44. classiq/interface/generator/preferences/qasm_to_qmod_params.py +14 -0
  45. classiq/interface/generator/quantum_function_call.py +3 -3
  46. classiq/interface/generator/user_defined_function_params.py +0 -3
  47. classiq/interface/helpers/model_normalizer.py +0 -6
  48. classiq/interface/ide/ide_data.py +1 -1
  49. classiq/interface/ide/visual_model.py +3 -2
  50. classiq/interface/model/block.py +5 -1
  51. classiq/interface/model/handle_binding.py +2 -2
  52. classiq/interface/model/port_declaration.py +2 -1
  53. classiq/interface/model/quantum_expressions/arithmetic_operation.py +16 -12
  54. classiq/interface/model/quantum_lambda_function.py +1 -1
  55. classiq/interface/model/quantum_statement.py +2 -4
  56. classiq/interface/model/quantum_type.py +47 -4
  57. classiq/interface/server/routes.py +2 -3
  58. classiq/model_expansions/atomic_expression_functions_defs.py +4 -22
  59. classiq/model_expansions/capturing/captured_vars.py +7 -3
  60. classiq/model_expansions/closure.py +8 -0
  61. classiq/model_expansions/interpreters/base_interpreter.py +84 -22
  62. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +1 -1
  63. classiq/model_expansions/interpreters/generative_interpreter.py +7 -5
  64. classiq/model_expansions/quantum_operations/allocate.py +92 -21
  65. classiq/model_expansions/quantum_operations/assignment_result_processor.py +28 -27
  66. classiq/model_expansions/quantum_operations/call_emitter.py +32 -26
  67. classiq/model_expansions/quantum_operations/classical_var_emitter.py +6 -2
  68. classiq/model_expansions/quantum_operations/emitter.py +39 -69
  69. classiq/model_expansions/quantum_operations/expression_evaluator.py +13 -2
  70. classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -5
  71. classiq/model_expansions/quantum_operations/variable_decleration.py +16 -11
  72. classiq/model_expansions/scope.py +36 -29
  73. classiq/model_expansions/scope_initialization.py +3 -6
  74. classiq/model_expansions/sympy_conversion/sympy_to_python.py +6 -2
  75. classiq/model_expansions/transformers/model_renamer.py +35 -64
  76. classiq/model_expansions/transformers/type_modifier_inference.py +6 -6
  77. classiq/model_expansions/visitors/boolean_expression_transformers.py +7 -31
  78. classiq/model_expansions/visitors/symbolic_param_inference.py +9 -3
  79. classiq/open_library/functions/__init__.py +2 -0
  80. classiq/open_library/functions/state_preparation.py +140 -5
  81. classiq/qmod/builtins/functions/allocation.py +8 -8
  82. classiq/qmod/builtins/functions/arithmetic.py +1 -1
  83. classiq/qmod/builtins/functions/chemistry.py +64 -0
  84. classiq/qmod/builtins/functions/exponentiation.py +7 -13
  85. classiq/qmod/builtins/functions/qsvm.py +1 -1
  86. classiq/qmod/builtins/operations.py +38 -10
  87. classiq/qmod/generative.py +2 -4
  88. classiq/qmod/native/pretty_printer.py +1 -1
  89. classiq/qmod/pretty_print/pretty_printer.py +1 -1
  90. classiq/qmod/qmod_constant.py +1 -1
  91. classiq/qmod/qmod_parameter.py +2 -2
  92. classiq/qmod/qmod_variable.py +62 -16
  93. classiq/qmod/quantum_expandable.py +1 -1
  94. classiq/synthesis.py +37 -1
  95. classiq/visualization.py +1 -1
  96. {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/METADATA +2 -2
  97. {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/RECORD +98 -102
  98. classiq/evaluators/arg_type_match.py +0 -168
  99. classiq/evaluators/classical_type_inference.py +0 -121
  100. classiq/interface/combinatorial_optimization/optimization_problem.py +0 -17
  101. classiq/interface/combinatorial_optimization/result.py +0 -9
  102. classiq/model_expansions/transformers/ast_renamer.py +0 -26
  103. {classiq-0.88.0.dist-info → classiq-0.90.0.dist-info}/WHEEL +0 -0
@@ -1,5 +1,5 @@
1
1
  import ast
2
- from typing import Any, Callable, Optional, Union, cast
2
+ from typing import Callable, Union, cast
3
3
 
4
4
  import sympy
5
5
 
@@ -184,37 +184,25 @@ def try_eval_sympy_function(
184
184
  if not isinstance(sympy_func, sympy.FunctionClass):
185
185
  return False
186
186
  _validate_no_kwargs(node)
187
- args: Optional[list[Any]] = None
188
- sympy_ret_val: Any = None
189
- if all(expr_val.has_value(arg) for arg in node.args):
190
- args = [expr_val.get_value(arg) for arg in node.args]
191
- sympy_ret_val = sympy_func(*args)
192
- if not isinstance(sympy_ret_val, sympy.Expr):
193
- raise ClassiqInternalExpansionError
194
187
  ret_type: QmodType
195
- ret_val: Any = None
196
188
  if hasattr(sympy_func, "is_Boolean") and sympy_func.is_Boolean:
197
189
  ret_type = Bool()
198
- if args is not None:
199
- ret_val = bool(sympy_ret_val)
200
190
  elif (
201
191
  hasattr(sympy_func, "is_Integer") and sympy_func.is_Integer
202
192
  ) or func_name in INTEGER_FUNCTION_OVERRIDE:
203
193
  ret_type = Integer()
204
- if args is not None:
205
- ret_val = int(sympy_ret_val)
206
194
  else:
207
195
  ret_type = Real()
208
- if sympy_ret_val is not None:
209
- if sympy_ret_val.is_imaginary:
210
- ret_val = complex(sympy_ret_val)
211
- elif sympy_ret_val.is_real:
212
- ret_val = float(sympy_ret_val)
213
- else:
214
- raise ClassiqInternalExpansionError
215
196
  expr_val.set_type(node, ret_type)
216
- if ret_val is not None:
217
- expr_val.set_value(node, ret_val)
197
+
198
+ if any(not expr_val.has_value(arg) for arg in node.args):
199
+ return True
200
+
201
+ args = [expr_val.get_value(arg) for arg in node.args]
202
+ sympy_ret_val = sympy_func(*args)
203
+ if not isinstance(sympy_ret_val, sympy.Basic):
204
+ raise ClassiqInternalExpansionError
205
+ expr_val.set_value(node, sympy_ret_val)
218
206
  return True
219
207
 
220
208
 
@@ -265,14 +253,7 @@ def try_eval_builtin_function(
265
253
  sympy_val = sympy.mod_inverse(
266
254
  *[expr_val.get_value(arg) for arg in node.args]
267
255
  )
268
- ret_val: Any
269
- if isinstance(sympy_val, sympy.Expr) and sympy_val.is_imaginary:
270
- ret_val = complex(sympy_val)
271
- elif args_are_int:
272
- ret_val = int(sympy_val)
273
- else:
274
- ret_val = float(sympy_val)
275
- expr_val.set_value(node, ret_val)
256
+ expr_val.set_value(node, sympy_val)
276
257
  return True
277
258
 
278
259
  if func_name == "sum":
@@ -293,13 +274,7 @@ def try_eval_builtin_function(
293
274
  expr_val.set_type(node, Real())
294
275
  if args_have_values:
295
276
  sympy_val = sympy.sqrt(*[expr_val.get_value(arg) for arg in node.args])
296
- if isinstance(sympy_val, sympy.Expr) and sympy_val.is_imaginary:
297
- ret_val = complex(sympy_val)
298
- elif float(sympy_val) == int(sympy_val):
299
- ret_val = int(sympy_val)
300
- else:
301
- ret_val = float(sympy_val)
302
- expr_val.set_value(node, ret_val)
277
+ expr_val.set_value(node, sympy_val)
303
278
  return True
304
279
 
305
280
  if func_name == "abs":
@@ -16,7 +16,11 @@ from classiq.interface.generator.functions.classical_type import (
16
16
  from classiq.interface.generator.functions.type_name import Enum
17
17
 
18
18
  from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
19
- from classiq.evaluators.qmod_node_evaluators.utils import SYMPY_SYMBOLS, QmodType
19
+ from classiq.evaluators.qmod_node_evaluators.utils import (
20
+ SYMPY_SYMBOLS,
21
+ QmodType,
22
+ get_sympy_type,
23
+ )
20
24
 
21
25
  QMOD_LITERALS: dict[str, tuple[ClassicalType, Any]] = {
22
26
  "false": (Bool(), False),
@@ -68,22 +72,9 @@ def try_eval_qmod_literal(expr_val: QmodAnnotatedExpression, node: ast.Name) ->
68
72
 
69
73
  def try_eval_sympy_constant(expr_val: QmodAnnotatedExpression, node: ast.Name) -> bool:
70
74
  sympy_val = SYMPY_SYMBOLS.get(node.id)
71
- if not isinstance(sympy_val, sympy.Expr) or not sympy_val.is_constant():
75
+ if not isinstance(sympy_val, sympy.Basic) or len(sympy_val.free_symbols) > 0:
72
76
  return False
73
- constant_type: QmodType
74
- constant_value: Any
75
- if sympy_val.is_Integer:
76
- constant_type = Integer()
77
- constant_value = int(sympy_val)
78
- elif sympy_val.is_Boolean:
79
- constant_type = Bool()
80
- constant_value = bool(sympy_val)
81
- elif sympy_val.is_imaginary:
82
- constant_type = Real()
83
- constant_value = complex(sympy_val)
84
- else:
85
- constant_type = Real()
86
- constant_value = float(sympy_val)
77
+ constant_type = get_sympy_type(sympy_val)
87
78
  expr_val.set_type(node, constant_type)
88
- expr_val.set_value(node, constant_value)
79
+ expr_val.set_value(node, sympy_val)
89
80
  return True
@@ -21,5 +21,5 @@ def eval_measurement(expr_val: QmodAnnotatedExpression, node: ast.Call) -> None:
21
21
  if is_classical_type(arg_type):
22
22
  raise ClassiqExpansionError("'measure' expects a quantum input")
23
23
  if not isinstance(arg_type, QuantumBit):
24
- raise ClassiqExpansionError("Currently, 'measure' only supports quantum bits")
24
+ raise ClassiqExpansionError("'measure' only supports QBits")
25
25
  expr_val.set_type(node, Bool())
@@ -1,5 +1,7 @@
1
1
  import ast
2
2
 
3
+ import sympy
4
+
3
5
  from classiq.interface.exceptions import (
4
6
  ClassiqExpansionError,
5
7
  ClassiqInternalExpansionError,
@@ -84,7 +86,11 @@ def eval_min_max_op(
84
86
 
85
87
  if all(expr_val.has_value(arg) for arg in node.args):
86
88
  values = [expr_val.get_value(arg) for arg in node.args]
87
- if not all(isinstance(value, (int, float)) for value in values):
89
+ if not all(
90
+ isinstance(value, (int, float))
91
+ or (isinstance(value, sympy.Expr) and value.is_real)
92
+ for value in values
93
+ ):
88
94
  raise ClassiqExpansionError(f"Invalid argument for function {func_name!r}")
89
95
 
90
96
  if func_name == "min":
@@ -22,7 +22,6 @@ from classiq.evaluators.qmod_type_inference.classical_type_inference import (
22
22
 
23
23
 
24
24
  def eval_name(expr_val: QmodAnnotatedExpression, node: ast.Name, value: Any) -> None:
25
- # FIXME: Remove sympy compatibility (CLS-3214)
26
25
  if isinstance(
27
26
  value, (bool, int, float, complex, list, QmodStructInstance, sympy.Basic)
28
27
  ):
@@ -1,12 +1,18 @@
1
1
  import ast
2
2
  from typing import TYPE_CHECKING, Optional
3
3
 
4
+ import sympy
5
+
4
6
  from classiq.interface.exceptions import ClassiqExpansionError
5
7
  from classiq.interface.generator.functions.classical_type import Bool
6
8
  from classiq.interface.model.quantum_type import QuantumScalar
7
9
 
8
10
  from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
9
- from classiq.evaluators.qmod_node_evaluators.utils import QmodType, is_classical_type
11
+ from classiq.evaluators.qmod_node_evaluators.utils import (
12
+ QmodType,
13
+ get_sympy_val,
14
+ is_classical_type,
15
+ )
10
16
  from classiq.model_expansions.arithmetic import NumericAttributes
11
17
 
12
18
 
@@ -46,6 +52,8 @@ def get_classical_value_for_arithmetic(
46
52
  return None
47
53
 
48
54
  value = expr_val.get_value(node)
55
+ if isinstance(value, sympy.Basic):
56
+ value = get_sympy_val(value)
49
57
  if not isinstance(value, (int, float)):
50
58
  if treat_qnum_as_float and isinstance(value, complex):
51
59
  return None
@@ -4,6 +4,7 @@ import sympy
4
4
 
5
5
  from classiq.interface.exceptions import ClassiqInternalExpansionError
6
6
  from classiq.interface.generator.functions.classical_type import (
7
+ Bool,
7
8
  ClassicalArray,
8
9
  ClassicalTuple,
9
10
  ClassicalType,
@@ -100,3 +101,35 @@ def is_classical_integer(qmod_type: QmodType) -> bool:
100
101
  return isinstance(qmod_type, Integer) or (
101
102
  isinstance(qmod_type, TypeName) and qmod_type.is_enum
102
103
  )
104
+
105
+
106
+ def get_sympy_val(val: sympy.Basic) -> Union[bool, int, float, complex]:
107
+ if hasattr(val, "is_Boolean") and val.is_Boolean:
108
+ return bool(val)
109
+ if (hasattr(val, "is_integer") and val.is_integer) or (
110
+ hasattr(val, "is_Integer") and val.is_Integer
111
+ ):
112
+ return int(val)
113
+ if hasattr(val, "is_real") and val.is_real:
114
+ return float(val)
115
+ if (hasattr(val, "is_complex") and val.is_complex) or (
116
+ hasattr(val, "is_imaginary") and val.is_imaginary
117
+ ):
118
+ return complex(val)
119
+ raise ClassiqInternalExpansionError("Unidentified sympy value")
120
+
121
+
122
+ def get_sympy_type(val: sympy.Basic) -> ClassicalType:
123
+ if hasattr(val, "is_Boolean") and val.is_Boolean:
124
+ return Bool()
125
+ if (hasattr(val, "is_integer") and val.is_integer) or (
126
+ hasattr(val, "is_Integer") and val.is_Integer
127
+ ):
128
+ return Integer()
129
+ if (
130
+ (hasattr(val, "is_real") and val.is_real)
131
+ or (hasattr(val, "is_complex") and val.is_complex)
132
+ or (hasattr(val, "is_imaginary") and val.is_imaginary)
133
+ ):
134
+ return Real()
135
+ raise ClassiqInternalExpansionError("Unidentified sympy value")
@@ -20,6 +20,8 @@ from classiq.interface.generator.functions.type_name import Enum, Struct, TypeNa
20
20
  from classiq.interface.generator.types.struct_declaration import StructDeclaration
21
21
  from classiq.interface.helpers.backward_compatibility import zip_strict
22
22
 
23
+ from classiq.evaluators.qmod_node_evaluators.utils import get_sympy_type
24
+
23
25
 
24
26
  def _copy_generative_flag(
25
27
  from_type: ClassicalType, to_type: Optional[ClassicalType]
@@ -57,13 +59,8 @@ def infer_classical_type(value: Any) -> ClassicalType:
57
59
  )
58
60
  )
59
61
  return classical_type
60
- # FIXME: Remove sympy compatibility (CLS-3214)
61
- if (
62
- isinstance(value, sympy.Basic)
63
- and len(value.free_symbols) == 0
64
- and value.is_complex
65
- ):
66
- return Real()
62
+ if isinstance(value, sympy.Basic):
63
+ return get_sympy_type(value)
67
64
  raise ClassiqInternalExpansionError
68
65
 
69
66
 
@@ -3,5 +3,5 @@ from packaging.version import Version
3
3
  # This file was generated automatically
4
4
  # Please don't track in version control (DONTTRACK)
5
5
 
6
- SEMVER_VERSION = '0.88.0'
6
+ SEMVER_VERSION = '0.90.0'
7
7
  VERSION = str(Version(SEMVER_VERSION))
@@ -1,12 +1,9 @@
1
1
  from typing import Annotated, Optional
2
2
 
3
- import numpy
4
3
  import pydantic
5
- from pydantic import ConfigDict, Field, StringConstraints
4
+ from pydantic import Field, StringConstraints
6
5
 
7
6
  from classiq.interface.backend.quantum_backend_providers import AnalyzerProviderVendor
8
- from classiq.interface.chemistry.ground_state_problem import MoleculeProblem
9
- from classiq.interface.executor.optimizer_preferences import OptimizerPreferences
10
7
  from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
11
8
  from classiq.interface.generator.model.preferences.preferences import (
12
9
  TranspilationOption,
@@ -80,7 +77,7 @@ class AnalysisHardwareListParams(AnalysisParams, HardwareListParams):
80
77
 
81
78
 
82
79
  class HardwareParams(pydantic.BaseModel):
83
- device: PydanticNonEmptyString = pydantic.Field(default=None, description="Devices")
80
+ device: PydanticNonEmptyString = pydantic.Field(default=None, description="Devices") # type: ignore[assignment]
84
81
  provider: AnalyzerProviderVendor
85
82
 
86
83
 
@@ -103,24 +100,3 @@ class AnalysisRBParams(pydantic.BaseModel):
103
100
  num_clifford: list[
104
101
  Annotated[int, Annotated[int, Field(strict=True, gt=0, le=MAX_NUM_CLIFFORD)]]
105
102
  ]
106
-
107
-
108
- class ChemistryGenerationParams(pydantic.BaseModel):
109
- model_config = ConfigDict(title="Chemistry")
110
-
111
- molecule: MoleculeProblem = pydantic.Field(
112
- title="Molecule",
113
- default=...,
114
- description="The molecule to generate the VQE ansatz for",
115
- )
116
- optimizer_preferences: OptimizerPreferences = pydantic.Field(
117
- default=..., description="Execution options for the classical Optimizer"
118
- )
119
-
120
- def initial_point(self) -> Optional[numpy.ndarray]:
121
- if self.optimizer_preferences.initial_point is not None:
122
- return numpy.ndarray(
123
- self.optimizer_preferences.initial_point # type: ignore[arg-type]
124
- )
125
- else:
126
- return None
@@ -40,6 +40,10 @@ class QasmCode(pydantic.BaseModel):
40
40
  code: str = Field(..., max_length=MAX_FILE_LENGTH)
41
41
 
42
42
 
43
+ class QmodCode(VersionedModel):
44
+ code: str = Field(..., max_length=MAX_FILE_LENGTH)
45
+
46
+
43
47
  class AnalysisStatus(StrEnum):
44
48
  NONE = "none"
45
49
  SUCCESS = "success"
@@ -274,7 +274,7 @@ class AzureCredential(BaseSettings):
274
274
 
275
275
  def __init__(self, **data: Any) -> None:
276
276
  initial_data = {
277
- field: data[field] for field in data if field in self.model_fields
277
+ field: data[field] for field in data if field in self.__class__.model_fields
278
278
  }
279
279
  super().__init__(**data)
280
280
  for field, value in initial_data.items():
@@ -1,4 +1,5 @@
1
- from typing import Annotated, Literal, Optional, Union, cast
1
+ import warnings
2
+ from typing import Annotated, Any, Literal, Optional, Union, cast
2
3
 
3
4
  import pydantic
4
5
  from pydantic import ConfigDict, Field
@@ -7,7 +8,7 @@ from pydantic_core.core_schema import ValidationInfo
7
8
  from classiq.interface.chemistry.fermionic_operator import SummedFermionicOperator
8
9
  from classiq.interface.chemistry.molecule import Molecule
9
10
  from classiq.interface.enum_utils import StrEnum
10
- from classiq.interface.exceptions import ClassiqValueError
11
+ from classiq.interface.exceptions import ClassiqDeprecationWarning, ClassiqValueError
11
12
  from classiq.interface.helpers.hashable_pydantic_base_model import (
12
13
  HashablePydanticBaseModel,
13
14
  )
@@ -52,6 +53,19 @@ class GroundStateProblem(HashablePydanticBaseModel):
52
53
  )
53
54
  num_qubits: Optional[int] = pydantic.Field(default=None)
54
55
 
56
+ def __init__(self, /, **data: Any) -> None:
57
+ warnings.warn(
58
+ (
59
+ f"The class `{self.__class__.__name__}` is deprecated and will no "
60
+ "longer be supported starting on 2025-09-18 at the earliest. "
61
+ "For more information on Classiq's chemistry application, see "
62
+ "https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
63
+ ),
64
+ category=ClassiqDeprecationWarning,
65
+ stacklevel=2,
66
+ )
67
+ super().__init__(**data)
68
+
55
69
  @pydantic.field_validator("z2_symmetries")
56
70
  @classmethod
57
71
  def _validate_z2_symmetries(cls, z2_symmetries: bool, info: ValidationInfo) -> bool:
@@ -1,12 +1,4 @@
1
- from typing import Optional
2
-
3
- import pydantic
4
- from pydantic import BaseModel
5
- from pydantic_core.core_schema import ValidationInfo
6
-
7
1
  from classiq.interface.enum_utils import StrEnum
8
- from classiq.interface.exceptions import ClassiqValueError
9
- from classiq.interface.helpers.custom_pydantic_types import PydanticAlphaParamCVAR
10
2
 
11
3
 
12
4
  class CostType(StrEnum):
@@ -22,107 +14,3 @@ class OptimizerType(StrEnum):
22
14
  NELDER_MEAD = "NELDER_MEAD"
23
15
  ADAM = "ADAM"
24
16
  SLSQP = "SLSQP"
25
-
26
-
27
- class OptimizerPreferences(BaseModel):
28
- name: OptimizerType = pydantic.Field(
29
- default=OptimizerType.COBYLA, description="Classical optimization algorithm."
30
- )
31
- num_shots: Optional[pydantic.PositiveInt] = pydantic.Field(
32
- default=None,
33
- description="Number of repetitions of the quantum ansatz.",
34
- )
35
- max_iteration: pydantic.PositiveInt = pydantic.Field(
36
- default=100, description="Maximal number of optimizer iterations"
37
- )
38
- tolerance: Optional[pydantic.PositiveFloat] = pydantic.Field(
39
- default=None, description="Final accuracy in the optimization"
40
- )
41
- step_size: Optional[pydantic.PositiveFloat] = pydantic.Field(
42
- default=None,
43
- description="step size for numerically " "calculating the gradient",
44
- )
45
- random_seed: Optional[int] = pydantic.Field(
46
- default=None,
47
- description="The random seed used for the generation",
48
- )
49
- initial_point: Optional[list[float]] = pydantic.Field(
50
- default=None,
51
- description="Initial values for the ansatz parameters",
52
- )
53
- skip_compute_variance: bool = pydantic.Field(
54
- default=False,
55
- description="If True, the optimizer will not compute the variance of the ansatz.",
56
- )
57
-
58
- @pydantic.field_validator("tolerance", mode="before")
59
- @classmethod
60
- def check_tolerance(
61
- cls, tolerance: Optional[pydantic.PositiveFloat], info: ValidationInfo
62
- ) -> Optional[pydantic.PositiveFloat]:
63
- optimizer_type = info.data.get("type")
64
- if tolerance is not None and optimizer_type == OptimizerType.SPSA:
65
- raise ClassiqValueError("No tolerance param for SPSA optimizer")
66
-
67
- if tolerance is None and optimizer_type != OptimizerType.SPSA:
68
- tolerance = pydantic.PositiveFloat(0.001)
69
-
70
- return tolerance
71
-
72
- @pydantic.field_validator("step_size", mode="before")
73
- @classmethod
74
- def check_step_size(
75
- cls, step_size: Optional[pydantic.PositiveFloat], info: ValidationInfo
76
- ) -> Optional[pydantic.PositiveFloat]:
77
- optimizer_type = info.data.get("name")
78
- if step_size is not None and optimizer_type not in (
79
- OptimizerType.L_BFGS_B,
80
- OptimizerType.ADAM,
81
- ):
82
- raise ClassiqValueError(
83
- "Use step_size only for L_BFGS_B or ADAM optimizers."
84
- )
85
-
86
- if step_size is None and optimizer_type in (
87
- OptimizerType.L_BFGS_B,
88
- OptimizerType.ADAM,
89
- ):
90
- step_size = pydantic.PositiveFloat(0.05)
91
-
92
- return step_size
93
-
94
-
95
- class GroundStateOptimizer(OptimizerPreferences):
96
- pass
97
-
98
-
99
- class CombinatorialOptimizer(OptimizerPreferences):
100
- cost_type: CostType = pydantic.Field(
101
- default=CostType.CVAR,
102
- description="Summarizing method of the measured bit strings",
103
- )
104
- alpha_cvar: Optional[PydanticAlphaParamCVAR] = pydantic.Field(
105
- default=None, description="Parameter for the CVAR summarizing method"
106
- )
107
- is_maximization: bool = pydantic.Field(
108
- default=False,
109
- description="Whether the optimization goal is to maximize",
110
- )
111
- should_check_valid_solutions: bool = pydantic.Field(
112
- default=False,
113
- description="Whether to check if all the solutions satisfy the constraints",
114
- )
115
-
116
- @pydantic.field_validator("alpha_cvar", mode="before")
117
- @classmethod
118
- def check_alpha_cvar(
119
- cls, alpha_cvar: Optional[PydanticAlphaParamCVAR], info: ValidationInfo
120
- ) -> Optional[PydanticAlphaParamCVAR]:
121
- cost_type = info.data.get("cost_type")
122
- if alpha_cvar is not None and cost_type != CostType.CVAR:
123
- raise ClassiqValueError("Use CVAR params only for CostType.CVAR.")
124
-
125
- if alpha_cvar is None and cost_type == CostType.CVAR:
126
- alpha_cvar = PydanticAlphaParamCVAR(0.2)
127
-
128
- return alpha_cvar
@@ -20,7 +20,9 @@ FOCK_HAMILTONIAN_PROBLEM_PARAM = ClassicalParameterDeclaration(
20
20
  name="fock_hamiltonian_problem",
21
21
  classical_type=Struct(name="FockHamiltonianProblem"),
22
22
  )
23
- FOCK_HAMILTONIAN_SIZE = "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
23
+ FOCK_HAMILTONIAN_SIZE = (
24
+ "fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0].pauli.len"
25
+ )
24
26
 
25
27
 
26
28
  class ChemistryProblemType(Enum):
@@ -88,13 +88,8 @@ class ExpressionValidator(ast.NodeVisitor):
88
88
  ast_expr = ast.parse(adjusted_expression, filename="", mode=self._mode)
89
89
  except SyntaxError as e:
90
90
  raise ClassiqValueError(f"Failed to parse expression {expression!r}") from e
91
- try:
92
- self._ast_obj = self.rewrite_ast(ast_expr)
93
- self.visit(self._ast_obj)
94
- except RecursionError as e:
95
- raise ClassiqValueError(
96
- f"Failed to parse expression since it is too long: {expression}"
97
- ) from e
91
+ self._ast_obj = self.rewrite_ast(ast_expr)
92
+ self.visit(self._ast_obj)
98
93
 
99
94
  @staticmethod
100
95
  def _get_adjusted_expression(expression: str) -> str:
@@ -19,7 +19,7 @@ class RegisterArithmeticInfo(HashablePydanticBaseModel):
19
19
  is_signed: bool = pydantic.Field(default=False)
20
20
  fraction_places: pydantic.NonNegativeInt = pydantic.Field(default=0)
21
21
  bypass_bounds_validation: bool = pydantic.Field(default=False)
22
- bounds: PydanticFloatTuple = pydantic.Field(
22
+ bounds: PydanticFloatTuple = pydantic.Field( # type: ignore[assignment]
23
23
  default=None,
24
24
  validate_default=True,
25
25
  )
@@ -10,10 +10,11 @@ from classiq.interface.backend.pydantic_backend import EXECUTION_PARAMETER_PATTE
10
10
  from classiq.interface.exceptions import ClassiqValueError
11
11
  from classiq.interface.generator.expressions.expression_types import (
12
12
  ExpressionValue,
13
- QmodStructInstance,
14
13
  RuntimeConstant,
15
14
  )
16
- from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
15
+ from classiq.interface.generator.expressions.proxies.classical.qmod_struct_instance import (
16
+ QmodStructInstance,
17
+ )
17
18
 
18
19
 
19
20
  @dataclass(frozen=True)
@@ -21,9 +22,6 @@ class EvaluatedExpression:
21
22
  value: ExpressionValue
22
23
 
23
24
  def is_constant(self, constant_type: Optional[type] = None) -> bool:
24
- if self.value is None:
25
- return False
26
-
27
25
  return isinstance(
28
26
  self.value,
29
27
  get_args(RuntimeConstant) if constant_type is None else constant_type,
@@ -49,14 +47,6 @@ class EvaluatedExpression:
49
47
  def to_list(self) -> list:
50
48
  return self.as_constant_type(list)
51
49
 
52
- def to_handle(self) -> HandleIdentifier:
53
- if not isinstance(self.value, HandleIdentifier):
54
- raise ClassiqValueError(
55
- f"Invalid access to expression {self.value} as HandleIdentifier"
56
- )
57
-
58
- return self.value
59
-
60
50
  def to_struct_dict(self) -> Mapping[str, Any]:
61
51
  if not isinstance(self.value, QmodStructInstance):
62
52
  raise ClassiqValueError(
@@ -1,35 +1,21 @@
1
- from typing import Union
1
+ from typing import TYPE_CHECKING, Union
2
2
 
3
- from sympy import Basic
4
- from sympy.logic.boolalg import Boolean
3
+ import sympy
5
4
 
6
- from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
7
- from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
8
- AnyClassicalValue,
9
- )
10
- from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
11
- ClassicalProxy,
12
- )
13
5
  from classiq.interface.generator.expressions.proxies.classical.qmod_struct_instance import (
14
6
  QmodStructInstance,
15
7
  )
16
- from classiq.interface.generator.expressions.proxies.quantum.qmod_sized_proxy import (
17
- QmodSizedProxy,
18
- )
19
- from classiq.interface.generator.expressions.type_proxy import TypeProxy
8
+
9
+ if TYPE_CHECKING:
10
+ from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
20
11
 
21
12
  RuntimeConstant = Union[
22
13
  int,
23
14
  float,
24
15
  list,
25
16
  bool,
17
+ complex,
26
18
  QmodStructInstance,
27
- TypeProxy,
28
- HandleIdentifier,
29
- ]
30
- Proxies = Union[
31
- QmodSizedProxy,
32
- ClassicalProxy,
19
+ sympy.Basic,
33
20
  ]
34
- RuntimeExpression = Union[AnyClassicalValue, Basic, Boolean]
35
- ExpressionValue = Union[RuntimeConstant, Proxies, RuntimeExpression]
21
+ ExpressionValue = Union[RuntimeConstant, "QmodAnnotatedExpression"]
@@ -1,5 +1,5 @@
1
1
  from collections.abc import Mapping
2
- from typing import TYPE_CHECKING
2
+ from typing import TYPE_CHECKING, Union
3
3
 
4
4
  if TYPE_CHECKING:
5
5
  from classiq.interface.generator.expressions.expression_types import ExpressionValue
@@ -18,7 +18,7 @@ class ClassicalProxy:
18
18
  return str(self.handle)
19
19
 
20
20
  @property
21
- def fields(self) -> Mapping[str, "ExpressionValue"]:
21
+ def fields(self) -> Mapping[str, Union["ExpressionValue", "ClassicalProxy"]]:
22
22
  raise NotImplementedError
23
23
 
24
24
  @property
@@ -8,7 +8,6 @@ from classiq.interface.generator.expressions.proxies.classical.classical_proxy i
8
8
  from classiq.interface.model.handle_binding import FieldHandleBinding, HandleBinding
9
9
 
10
10
  if TYPE_CHECKING:
11
- from classiq.interface.generator.expressions.expression_types import ExpressionValue
12
11
  from classiq.interface.generator.types.struct_declaration import StructDeclaration
13
12
 
14
13
 
@@ -22,7 +21,7 @@ class ClassicalStructProxy(NonSymbolicExpr, ClassicalProxy):
22
21
  return self._decl
23
22
 
24
23
  @property
25
- def fields(self) -> Mapping[str, "ExpressionValue"]:
24
+ def fields(self) -> Mapping[str, ClassicalProxy]:
26
25
  return {
27
26
  field_name: field_type.get_classical_proxy(
28
27
  FieldHandleBinding(base_handle=self.handle, field=field_name)