classiq 0.89.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 (86) hide show
  1. classiq/__init__.py +1 -0
  2. classiq/_internals/api_wrapper.py +16 -32
  3. classiq/analyzer/show_interactive_hack.py +26 -1
  4. classiq/applications/chemistry/chemistry_model_constructor.py +14 -2
  5. classiq/applications/combinatorial_helpers/pyomo_utils.py +9 -6
  6. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
  7. classiq/applications/combinatorial_optimization/combinatorial_problem.py +16 -8
  8. classiq/evaluators/classical_expression.py +63 -41
  9. classiq/evaluators/control.py +31 -52
  10. classiq/evaluators/expression_evaluator.py +8 -4
  11. classiq/evaluators/parameter_types.py +200 -104
  12. classiq/evaluators/qmod_annotated_expression.py +3 -1
  13. classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +12 -37
  14. classiq/evaluators/qmod_node_evaluators/constant_evaluation.py +8 -17
  15. classiq/evaluators/qmod_node_evaluators/measurement_evaluation.py +1 -1
  16. classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +7 -1
  17. classiq/evaluators/qmod_node_evaluators/name_evaluation.py +0 -1
  18. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +9 -1
  19. classiq/evaluators/qmod_node_evaluators/utils.py +33 -0
  20. classiq/evaluators/qmod_type_inference/classical_type_inference.py +4 -7
  21. classiq/interface/_version.py +1 -1
  22. classiq/interface/analyzer/analysis_params.py +1 -25
  23. classiq/interface/analyzer/result.py +4 -0
  24. classiq/interface/chemistry/ground_state_problem.py +16 -2
  25. classiq/interface/executor/optimizer_preferences.py +0 -112
  26. classiq/interface/generator/application_apis/chemistry_declarations.py +3 -1
  27. classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -7
  28. classiq/interface/generator/expressions/evaluated_expression.py +3 -13
  29. classiq/interface/generator/expressions/expression_types.py +8 -22
  30. classiq/interface/generator/expressions/proxies/classical/classical_proxy.py +2 -2
  31. classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +1 -2
  32. classiq/interface/generator/functions/concrete_types.py +1 -1
  33. classiq/interface/generator/generated_circuit_data.py +4 -0
  34. classiq/interface/generator/preferences/qasm_to_qmod_params.py +14 -0
  35. classiq/interface/helpers/model_normalizer.py +0 -6
  36. classiq/interface/ide/visual_model.py +1 -0
  37. classiq/interface/model/handle_binding.py +1 -1
  38. classiq/interface/model/port_declaration.py +2 -1
  39. classiq/interface/model/quantum_expressions/arithmetic_operation.py +16 -12
  40. classiq/interface/model/quantum_type.py +1 -1
  41. classiq/interface/server/routes.py +2 -3
  42. classiq/model_expansions/atomic_expression_functions_defs.py +4 -22
  43. classiq/model_expansions/capturing/captured_vars.py +7 -3
  44. classiq/model_expansions/closure.py +8 -0
  45. classiq/model_expansions/interpreters/base_interpreter.py +84 -22
  46. classiq/model_expansions/interpreters/frontend_generative_interpreter.py +1 -1
  47. classiq/model_expansions/interpreters/generative_interpreter.py +7 -5
  48. classiq/model_expansions/quantum_operations/allocate.py +92 -21
  49. classiq/model_expansions/quantum_operations/assignment_result_processor.py +28 -27
  50. classiq/model_expansions/quantum_operations/call_emitter.py +32 -26
  51. classiq/model_expansions/quantum_operations/classical_var_emitter.py +6 -2
  52. classiq/model_expansions/quantum_operations/emitter.py +39 -69
  53. classiq/model_expansions/quantum_operations/expression_evaluator.py +13 -2
  54. classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -5
  55. classiq/model_expansions/quantum_operations/variable_decleration.py +16 -11
  56. classiq/model_expansions/scope.py +36 -29
  57. classiq/model_expansions/scope_initialization.py +3 -6
  58. classiq/model_expansions/sympy_conversion/sympy_to_python.py +6 -2
  59. classiq/model_expansions/transformers/model_renamer.py +35 -64
  60. classiq/model_expansions/transformers/type_modifier_inference.py +6 -6
  61. classiq/model_expansions/visitors/boolean_expression_transformers.py +7 -31
  62. classiq/model_expansions/visitors/symbolic_param_inference.py +9 -3
  63. classiq/open_library/functions/state_preparation.py +3 -3
  64. classiq/qmod/builtins/functions/allocation.py +8 -8
  65. classiq/qmod/builtins/functions/arithmetic.py +1 -1
  66. classiq/qmod/builtins/functions/chemistry.py +64 -0
  67. classiq/qmod/builtins/functions/exponentiation.py +7 -13
  68. classiq/qmod/builtins/functions/qsvm.py +1 -1
  69. classiq/qmod/builtins/operations.py +38 -10
  70. classiq/qmod/generative.py +2 -4
  71. classiq/qmod/native/pretty_printer.py +1 -1
  72. classiq/qmod/pretty_print/pretty_printer.py +1 -1
  73. classiq/qmod/qmod_constant.py +1 -1
  74. classiq/qmod/qmod_parameter.py +2 -2
  75. classiq/qmod/qmod_variable.py +15 -15
  76. classiq/qmod/quantum_expandable.py +1 -1
  77. classiq/synthesis.py +37 -1
  78. classiq/visualization.py +1 -1
  79. {classiq-0.89.0.dist-info → classiq-0.90.0.dist-info}/METADATA +1 -1
  80. {classiq-0.89.0.dist-info → classiq-0.90.0.dist-info}/RECORD +81 -85
  81. classiq/evaluators/arg_type_match.py +0 -168
  82. classiq/evaluators/classical_type_inference.py +0 -121
  83. classiq/interface/combinatorial_optimization/optimization_problem.py +0 -17
  84. classiq/interface/combinatorial_optimization/result.py +0 -9
  85. classiq/model_expansions/transformers/ast_renamer.py +0 -26
  86. {classiq-0.89.0.dist-info → classiq-0.90.0.dist-info}/WHEEL +0 -0
@@ -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.89.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,
@@ -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"
@@ -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:
@@ -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)
@@ -47,7 +47,7 @@ PythonClassicalPydanticTypes = (Enum,)
47
47
 
48
48
  ConcreteQuantumType = Annotated[
49
49
  Union[QuantumBit, QuantumBitvector, QuantumNumeric, TypeName],
50
- Field(discriminator="kind", default_factory=QuantumBitvector),
50
+ Field(discriminator="kind"),
51
51
  ]
52
52
  QuantumBitvector.model_rebuild()
53
53
  TypeName.model_rebuild()
@@ -17,6 +17,7 @@ from classiq.interface.generator.register_role import RegisterRole
17
17
  from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
18
18
  ExecutionData,
19
19
  )
20
+ from classiq.interface.model.block import Block
20
21
  from classiq.interface.model.quantum_expressions.arithmetic_operation import (
21
22
  ArithmeticOperationKind,
22
23
  )
@@ -210,10 +211,13 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
210
211
  )
211
212
  name_with_suffix = self.add_suffix_from_generated_name(generated_name, name)
212
213
  return name_with_suffix
214
+ if isinstance(back_ref, Block) and back_ref.label is not None:
215
+ return back_ref.label
213
216
 
214
217
  statement_kind: str = back_ref.kind
215
218
  if isinstance(back_ref, ArithmeticOperation):
216
219
  statement_kind = back_ref.operation_kind.value
220
+
217
221
  return self.add_suffix_from_generated_name(
218
222
  generated_name, STATEMENTS_NAME[statement_kind]
219
223
  )
@@ -0,0 +1,14 @@
1
+ from pydantic import BaseModel
2
+
3
+ from classiq.interface.analyzer.result import QasmCode
4
+ from classiq.interface.enum_utils import StrEnum
5
+
6
+
7
+ class QmodFormat(StrEnum):
8
+ NATIVE = "native"
9
+ PYTHON = "python"
10
+
11
+
12
+ class QasmToQmodParams(BaseModel):
13
+ qasm: QasmCode
14
+ qmod_format: QmodFormat
@@ -1,4 +1,3 @@
1
- import ast
2
1
  from typing import Any
3
2
 
4
3
  from classiq.interface.ast_node import ASTNode
@@ -10,8 +9,6 @@ from classiq.interface.generator.visitor import Transformer, Visitor
10
9
  from classiq.interface.model.model import Model
11
10
  from classiq.interface.model.port_declaration import AnonPortDeclaration
12
11
 
13
- from classiq.model_expansions.transformers.model_renamer import ExprNormalizer
14
-
15
12
 
16
13
  class ModelNormalizer(Visitor):
17
14
  def visit(self, node: Any) -> None:
@@ -28,9 +25,6 @@ class ModelNormalizer(Visitor):
28
25
  model.functions.sort(key=lambda x: x.name)
29
26
  self.generic_visit(model)
30
27
 
31
- def visit_Expression(self, expr: Expression) -> None:
32
- expr.expr = ast.unparse(ExprNormalizer().visit(ast.parse(expr.expr)))
33
-
34
28
  def visit_AnonPortDeclaration(self, decl: AnonPortDeclaration) -> None:
35
29
  decl.type_modifier = TypeModifier.Mutable
36
30
 
@@ -171,6 +171,7 @@ class Operation(pydantic.BaseModel):
171
171
  expanded: bool = pydantic.Field(default=False)
172
172
  show_expanded_label: bool = pydantic.Field(default=False)
173
173
  is_low_level_fallback: bool = pydantic.Field(default=False)
174
+ is_measurement: bool = pydantic.Field(default=False)
174
175
 
175
176
  model_config = ConfigDict(frozen=True)
176
177
 
@@ -349,7 +349,7 @@ class FieldHandleBinding(NestedHandleBinding):
349
349
 
350
350
  @property
351
351
  def qmod_expr(self) -> str:
352
- return f"get_field({self.base_handle.qmod_expr}, '{self.field}')"
352
+ return f"{self.base_handle.qmod_expr}.{self.field}"
353
353
 
354
354
  @property
355
355
  def identifier(self) -> str:
@@ -13,10 +13,11 @@ from classiq.interface.generator.functions.type_modifier import (
13
13
  )
14
14
  from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
15
15
  from classiq.interface.model.parameter import Parameter
16
+ from classiq.interface.model.quantum_type import QuantumBitvector
16
17
 
17
18
 
18
19
  class AnonPortDeclaration(Parameter):
19
- quantum_type: ConcreteQuantumType
20
+ quantum_type: ConcreteQuantumType = pydantic.Field(default_factory=QuantumBitvector)
20
21
  direction: PortDeclarationDirection
21
22
  kind: Literal["PortDeclaration"]
22
23
  type_modifier: TypeModifier
@@ -1,12 +1,9 @@
1
1
  from collections.abc import Mapping, Sequence
2
- from typing import Literal
3
-
4
- from pydantic import PrivateAttr
2
+ from typing import Literal, cast
5
3
 
6
4
  from classiq.interface.enum_utils import StrEnum
7
5
  from classiq.interface.generator.arith.arithmetic import (
8
6
  ARITHMETIC_EXPRESSION_RESULT_NAME,
9
- compute_arithmetic_result_type,
10
7
  )
11
8
  from classiq.interface.model.handle_binding import (
12
9
  ConcreteHandleBinding,
@@ -18,6 +15,9 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
18
15
  from classiq.interface.model.quantum_statement import HandleMetadata
19
16
  from classiq.interface.model.quantum_type import QuantumType
20
17
 
18
+ from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
19
+ from classiq.model_expansions.arithmetic import NumericAttributes
20
+
21
21
 
22
22
  class ArithmeticOperationKind(StrEnum):
23
23
  InplaceAdd = "inplace_add"
@@ -29,7 +29,7 @@ class ArithmeticOperation(QuantumAssignmentOperation):
29
29
  kind: Literal["ArithmeticOperation"]
30
30
 
31
31
  operation_kind: ArithmeticOperationKind
32
- _classical_assignment: bool = PrivateAttr(default=False)
32
+ classical_assignment: bool = False
33
33
 
34
34
  @property
35
35
  def is_inplace(self) -> bool:
@@ -44,16 +44,20 @@ class ArithmeticOperation(QuantumAssignmentOperation):
44
44
  machine_precision: int,
45
45
  ) -> None:
46
46
  super().initialize_var_types(var_types, machine_precision)
47
- self._result_type = compute_arithmetic_result_type(
48
- self.expression.expr, var_types, machine_precision
49
- )
47
+ expr_val = self.expression.value.value
48
+ if isinstance(expr_val, QmodAnnotatedExpression):
49
+ self._result_type = expr_val.get_quantum_type(expr_val.root)
50
+ else:
51
+ self._result_type = NumericAttributes.from_constant(
52
+ cast(float, expr_val), machine_precision
53
+ ).to_quantum_numeric()
50
54
 
51
55
  @property
52
56
  def wiring_inouts(
53
57
  self,
54
58
  ) -> Mapping[str, ConcreteHandleBinding]:
55
59
  inouts = dict(super().wiring_inouts)
56
- if self.is_inplace and not self._classical_assignment:
60
+ if self.is_inplace and not self.classical_assignment:
57
61
  inouts[self.result_name()] = self.result_var
58
62
  return inouts
59
63
 
@@ -63,7 +67,7 @@ class ArithmeticOperation(QuantumAssignmentOperation):
63
67
  HandleMetadata(handle=handle, readable_location="in an expression")
64
68
  for handle in self.var_handles
65
69
  ]
66
- if self.is_inplace and not self._classical_assignment:
70
+ if self.is_inplace and not self.classical_assignment:
67
71
  inouts.append(
68
72
  HandleMetadata(
69
73
  handle=self.result_var,
@@ -74,13 +78,13 @@ class ArithmeticOperation(QuantumAssignmentOperation):
74
78
 
75
79
  @property
76
80
  def wiring_outputs(self) -> Mapping[str, HandleBinding]:
77
- if self.is_inplace or self._classical_assignment:
81
+ if self.is_inplace or self.classical_assignment:
78
82
  return {}
79
83
  return super().wiring_outputs
80
84
 
81
85
  @property
82
86
  def readable_outputs(self) -> Sequence[HandleMetadata]:
83
- if self.is_inplace or self._classical_assignment:
87
+ if self.is_inplace or self.classical_assignment:
84
88
  return []
85
89
  return [
86
90
  HandleMetadata(
@@ -532,7 +532,7 @@ class QuantumNumeric(QuantumScalar):
532
532
 
533
533
 
534
534
  class RegisterQuantumType(BaseModel):
535
- quantum_types: "ConcreteQuantumType"
535
+ quantum_types: "ConcreteQuantumType" = Field(default_factory=QuantumBitvector)
536
536
  size: int = Field(default=1)
537
537
 
538
538
  @property
@@ -44,9 +44,6 @@ TASKS_VISUALIZE_SUFFIX = TASKS_SUFFIX + "/visualize"
44
44
  TASKS_VISUAL_MODEL_SUFFIX = TASKS_SUFFIX + "/visual_model"
45
45
  TASKS_SOLVE_SUFFIX = "/tasks/solve"
46
46
 
47
- CHEMISTRY_QMOD_PATH = "/generate_model/chemistry/qmod"
48
-
49
-
50
47
  TASK_TRAIN_SUFFIX = TASKS_SUFFIX + "/train"
51
48
  TASK_TEST_SUFFIX = TASKS_SUFFIX + "/test"
52
49
  TASK_PREDICT_SUFFIX = TASKS_SUFFIX + "/predict"
@@ -75,6 +72,8 @@ CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX = "/execution_input"
75
72
  CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_FULL = (
76
73
  CONVERSION_PREFIX + CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX
77
74
  )
75
+ QASM_TO_QMOD_SUFFIX = "/qasm_to_qmod"
76
+ QASM_TO_QMOD_FULL_PATH = CONVERSION_PREFIX + QASM_TO_QMOD_SUFFIX
78
77
 
79
78
  STATIC_SEMANTICS_VALIDATION_PATH = "/validate_static_semantics"
80
79