classiq 0.102.0__py3-none-any.whl → 0.104.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 (65) hide show
  1. classiq/applications/chemistry/op_utils.py +32 -0
  2. classiq/evaluators/qmod_annotated_expression.py +1 -1
  3. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +1 -8
  4. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +1 -1
  5. classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +2 -2
  6. classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +18 -29
  7. classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +1 -6
  8. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +1 -7
  9. classiq/evaluators/qmod_type_inference/quantum_type_comparison.py +52 -0
  10. classiq/execution/execution_session.py +1 -1
  11. classiq/execution/functions/__init__.py +3 -0
  12. classiq/execution/functions/_logging.py +19 -0
  13. classiq/execution/functions/constants.py +9 -0
  14. classiq/execution/functions/parse_provider_backend.py +90 -0
  15. classiq/execution/functions/sample.py +257 -0
  16. classiq/interface/_version.py +1 -1
  17. classiq/interface/backend/backend_preferences.py +15 -0
  18. classiq/interface/backend/provider_config/providers/aqt.py +1 -1
  19. classiq/interface/backend/provider_config/providers/azure.py +1 -2
  20. classiq/interface/backend/provider_config/providers/ibm.py +1 -1
  21. classiq/interface/backend/quantum_backend_providers.py +3 -0
  22. classiq/interface/executor/result.py +9 -5
  23. classiq/interface/generator/arith/binary_ops.py +38 -2
  24. classiq/interface/generator/function_param_list.py +4 -2
  25. classiq/interface/generator/functions/builtins/internal_operators.py +5 -9
  26. classiq/interface/generator/functions/classical_type.py +45 -0
  27. classiq/interface/generator/functions/type_name.py +23 -0
  28. classiq/interface/generator/generated_circuit_data.py +0 -2
  29. classiq/interface/generator/types/compilation_metadata.py +9 -0
  30. classiq/interface/hardware.py +1 -0
  31. classiq/interface/helpers/model_normalizer.py +42 -6
  32. classiq/interface/interface_version.py +1 -1
  33. classiq/interface/model/invert.py +8 -0
  34. classiq/interface/model/model_visitor.py +4 -2
  35. classiq/interface/model/quantum_type.py +21 -0
  36. classiq/interface/model/statement_block.py +0 -4
  37. classiq/model_expansions/capturing/captured_vars.py +16 -12
  38. classiq/model_expansions/function_builder.py +9 -1
  39. classiq/model_expansions/interpreters/base_interpreter.py +9 -8
  40. classiq/model_expansions/interpreters/generative_interpreter.py +9 -24
  41. classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -0
  42. classiq/model_expansions/quantum_operations/assignment_result_processor.py +132 -28
  43. classiq/model_expansions/quantum_operations/bind.py +4 -0
  44. classiq/model_expansions/quantum_operations/call_emitter.py +5 -35
  45. classiq/model_expansions/quantum_operations/emitter.py +1 -4
  46. classiq/model_expansions/quantum_operations/expression_evaluator.py +0 -3
  47. classiq/model_expansions/visitors/uncomputation_signature_inference.py +0 -9
  48. classiq/qmod/builtins/functions/__init__.py +9 -0
  49. classiq/qmod/builtins/functions/arithmetic.py +131 -0
  50. classiq/qmod/builtins/functions/exponentiation.py +32 -2
  51. classiq/qmod/builtins/operations.py +2 -38
  52. classiq/qmod/native/pretty_printer.py +1 -12
  53. classiq/qmod/pretty_print/pretty_printer.py +1 -17
  54. classiq/qmod/qmod_parameter.py +4 -0
  55. classiq/qmod/qmod_variable.py +38 -63
  56. classiq/qmod/quantum_function.py +43 -7
  57. classiq/qmod/semantics/validation/function_name_collisions_validation.py +7 -4
  58. classiq/qmod/semantics/validation/model_validation.py +7 -2
  59. classiq/qmod/symbolic_type.py +4 -2
  60. {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/METADATA +1 -1
  61. {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/RECORD +63 -59
  62. classiq/interface/generator/amplitude_loading.py +0 -103
  63. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +0 -77
  64. {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/WHEEL +0 -0
  65. {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -5,6 +5,7 @@ class CompilationMetadata(BaseModel):
5
5
  should_synthesize_separately: bool = Field(default=False)
6
6
  occurrences_number: NonNegativeInt = Field(default=0)
7
7
  _occupation_number: NonNegativeInt = PrivateAttr(default=0)
8
+ _required_clean_qubit: NonNegativeInt = PrivateAttr(default=0)
8
9
  disable_perm_check: bool = Field(default=False)
9
10
  disable_const_checks: list[str] | bool = Field(default=False)
10
11
 
@@ -16,6 +17,14 @@ class CompilationMetadata(BaseModel):
16
17
  def occupation_number(self, value: NonNegativeInt) -> None:
17
18
  self._occupation_number = value
18
19
 
20
+ @property
21
+ def required_clean_qubit(self) -> NonNegativeInt:
22
+ return self._required_clean_qubit
23
+
24
+ @required_clean_qubit.setter
25
+ def required_clean_qubit(self, value: NonNegativeInt) -> None:
26
+ self._required_clean_qubit = value
27
+
19
28
  @property
20
29
  def has_user_directives(self) -> bool:
21
30
  return bool(self.disable_perm_check or self.disable_const_checks)
@@ -33,6 +33,7 @@ class Provider(StrEnum):
33
33
  INTEL = "Intel"
34
34
  AQT = "AQT"
35
35
  CINECA = "CINECA"
36
+ SOFTBANK = "Softbank"
36
37
 
37
38
  @property
38
39
  def id(self) -> "ProviderIDEnum":
@@ -6,16 +6,31 @@ from classiq.interface.generator.expressions.expression import Expression
6
6
  from classiq.interface.generator.functions.classical_type import ClassicalType
7
7
  from classiq.interface.generator.functions.type_modifier import TypeModifier
8
8
  from classiq.interface.generator.visitor import Transformer, Visitor
9
+ from classiq.interface.model.handle_binding import HandleBinding
9
10
  from classiq.interface.model.model import Model
10
11
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
11
- from classiq.interface.model.port_declaration import AnonPortDeclaration
12
+ from classiq.interface.model.port_declaration import (
13
+ PortDeclaration,
14
+ )
12
15
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
16
+ from classiq.interface.model.variable_declaration_statement import (
17
+ VariableDeclarationStatement,
18
+ )
19
+
20
+ from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
13
21
 
14
22
 
15
23
  class ModelNormalizer(Visitor):
16
- def __init__(self, normalize_names: bool = False) -> None:
17
- self._normalize_names = normalize_names
24
+ def __init__(
25
+ self,
26
+ normalize_func_names: bool = False,
27
+ normalize_quantum_var_names: bool = False,
28
+ ) -> None:
29
+ self._normalize_func_names = normalize_func_names
30
+ self._normalize_quantum_var_names = normalize_quantum_var_names
18
31
  self._funcs_renames: dict[str, str] = {}
32
+ self._count_name = CountedNameAllocator()
33
+ self.original_names: dict[str, str] = {}
19
34
 
20
35
  def visit(self, node: Any) -> None:
21
36
  if isinstance(node, ASTNode):
@@ -35,12 +50,12 @@ class ModelNormalizer(Visitor):
35
50
  self.generic_visit(model)
36
51
 
37
52
  def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
38
- if self._normalize_names:
53
+ if self._normalize_func_names:
39
54
  func.name = self._funcs_renames[func.name]
40
55
  self.generic_visit(func)
41
56
 
42
57
  def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
43
- if self._normalize_names:
58
+ if self._normalize_func_names:
44
59
  if isinstance(call.function, str):
45
60
  if call.function in self._funcs_renames:
46
61
  call.function = self._funcs_renames[call.function]
@@ -49,8 +64,29 @@ class ModelNormalizer(Visitor):
49
64
  call.function.name = self._funcs_renames[call.function.name]
50
65
  self.generic_visit(call)
51
66
 
52
- def visit_AnonPortDeclaration(self, decl: AnonPortDeclaration) -> None:
67
+ def visit_PortDeclaration(self, decl: PortDeclaration) -> None:
53
68
  decl.type_modifier = TypeModifier.Mutable
69
+ self._rename_quantum_var(decl, "_port")
70
+
71
+ def visit_VariableDeclarationStatement(
72
+ self, var: VariableDeclarationStatement
73
+ ) -> None:
74
+ self._rename_quantum_var(var, "_var")
75
+
76
+ def _rename_quantum_var(
77
+ self, var: VariableDeclarationStatement | PortDeclaration, new_name_prefix: str
78
+ ) -> None:
79
+ if self._normalize_quantum_var_names:
80
+ old_name = var.name
81
+ var.name = self._count_name.allocate(new_name_prefix)
82
+ self.original_names[old_name] = var.name
83
+
84
+ def visit_HandleBinding(self, handle: HandleBinding) -> None:
85
+ if self._normalize_quantum_var_names:
86
+ # this is a hack use just for testing, do not use in production
87
+ object.__setattr__(
88
+ handle, "name", self.original_names.get(handle.name, handle.name)
89
+ )
54
90
 
55
91
 
56
92
  class ClearModelInternals(Transformer):
@@ -1 +1 @@
1
- INTERFACE_VERSION = "15"
1
+ INTERFACE_VERSION = "16"
@@ -2,6 +2,8 @@ from typing import TYPE_CHECKING, Literal
2
2
 
3
3
  from classiq.interface.ast_node import ASTNodeType, reset_lists
4
4
  from classiq.interface.enum_utils import StrEnum
5
+ from classiq.interface.exceptions import ClassiqInternalExpansionError
6
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
5
7
  from classiq.interface.model.quantum_statement import QuantumOperation
6
8
 
7
9
  if TYPE_CHECKING:
@@ -25,3 +27,9 @@ class Invert(QuantumOperation):
25
27
  @property
26
28
  def blocks(self) -> dict[str, "StatementBlock"]:
27
29
  return {"body": self.body}
30
+
31
+ def validate_node(self) -> None:
32
+ if self.block_kind == BlockKind.SingleCall and (
33
+ len(self.body) != 1 or not isinstance(self.body[0], QuantumFunctionCall)
34
+ ):
35
+ raise ClassiqInternalExpansionError("Malformed single-call invert")
@@ -10,8 +10,10 @@ from classiq.interface.model.quantum_statement import QuantumStatement
10
10
 
11
11
 
12
12
  class ModelVisitor(Visitor):
13
- def visit_DebugInfoCollection(self, debug_info: DebugInfoCollection) -> None:
14
- return
13
+ def visit_DebugInfoCollection(
14
+ self, debug_info: DebugInfoCollection
15
+ ) -> RetType | None:
16
+ return None
15
17
 
16
18
 
17
19
  class ModelStatementsVisitor(ModelVisitor):
@@ -78,6 +78,9 @@ class QuantumType(HashableASTNode):
78
78
  def without_symbolic_attributes(self) -> Self:
79
79
  return self
80
80
 
81
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
82
+ return {}
83
+
81
84
 
82
85
  class QuantumScalar(QuantumType):
83
86
  @property
@@ -262,6 +265,14 @@ class QuantumBitvector(QuantumType):
262
265
  length = 1
263
266
  return length * self.element_type.minimal_size_in_bits
264
267
 
268
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
269
+ attrs: dict[str, Any] = {}
270
+ if self.has_constant_length:
271
+ attrs[f"{path_expr_prefix}.len"] = self.length_value
272
+ return attrs | self.element_type.get_compile_time_attributes(
273
+ f"{path_expr_prefix}[0]"
274
+ )
275
+
265
276
  def without_symbolic_attributes(self) -> "QuantumBitvector":
266
277
  length = (
267
278
  None
@@ -301,6 +312,16 @@ class QuantumNumeric(QuantumScalar):
301
312
  )
302
313
  return self
303
314
 
315
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
316
+ attrs: dict[str, Any] = {}
317
+ if self.has_size_in_bits:
318
+ attrs[f"{path_expr_prefix}.size"] = self.size_in_bits
319
+ if self.has_constant_sign:
320
+ attrs[f"{path_expr_prefix}.is_signed"] = self.sign_value
321
+ if self.has_constant_fraction_digits:
322
+ attrs[f"{path_expr_prefix}.fraction_digits"] = self.fraction_digits_value
323
+ return attrs
324
+
304
325
  def set_size_in_bits(self, val: int) -> None:
305
326
  super().set_size_in_bits(val)
306
327
  if self.size is not None:
@@ -13,9 +13,6 @@ from classiq.interface.model.invert import Invert
13
13
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
14
14
  from classiq.interface.model.phase_operation import PhaseOperation
15
15
  from classiq.interface.model.power import Power
16
- from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
17
- AmplitudeLoadingOperation,
18
- )
19
16
  from classiq.interface.model.quantum_expressions.arithmetic_operation import (
20
17
  ArithmeticOperation,
21
18
  )
@@ -38,7 +35,6 @@ ConcreteQuantumStatement = Annotated[
38
35
  QuantumFunctionCall,
39
36
  Allocate,
40
37
  ArithmeticOperation,
41
- AmplitudeLoadingOperation,
42
38
  VariableDeclarationStatement,
43
39
  BindOperation,
44
40
  InplaceBinaryOperation,
@@ -56,8 +56,8 @@ if TYPE_CHECKING:
56
56
  from classiq.model_expansions.closure import FunctionClosure
57
57
 
58
58
 
59
- INITIALIZED_VAR_MESSAGE = "Variable '{}' should be uninitialized here"
60
- UNINITIALIZED_VAR_MESSAGE = "Variable '{}' should be initialized here"
59
+ _INITIALIZED_VAR_MESSAGE = "Variable '{}' should be uninitialized here"
60
+ _UNINITIALIZED_VAR_MESSAGE = "Variable '{}' should be initialized here"
61
61
 
62
62
 
63
63
  def _get_symbol_expr(symbol: str, classical_type: ClassicalType) -> Expression:
@@ -311,7 +311,7 @@ class CapturedVars:
311
311
  return PortDirection.Inout
312
312
  if target_direction == PortDirection.Outin:
313
313
  return PortDirection.Input
314
- raise ClassiqExpansionError(UNINITIALIZED_VAR_MESSAGE.format(var_name))
314
+ raise ClassiqExpansionError(_UNINITIALIZED_VAR_MESSAGE.format(var_name))
315
315
 
316
316
  if source_direction == PortDirection.Output:
317
317
  if target_direction == PortDirection.Input:
@@ -320,18 +320,18 @@ class CapturedVars:
320
320
  PortDirection.Output,
321
321
  PortDirection.Outin,
322
322
  ):
323
- raise ClassiqExpansionError(INITIALIZED_VAR_MESSAGE.format(var_name))
323
+ raise ClassiqExpansionError(_INITIALIZED_VAR_MESSAGE.format(var_name))
324
324
  return PortDirection.Output
325
325
 
326
326
  if source_direction == PortDirection.Inout:
327
327
  if target_direction in (PortDirection.Input, PortDirection.Inout):
328
328
  return target_direction
329
- raise ClassiqExpansionError(INITIALIZED_VAR_MESSAGE.format(var_name))
329
+ raise ClassiqExpansionError(_INITIALIZED_VAR_MESSAGE.format(var_name))
330
330
 
331
331
  if source_direction == PortDirection.Outin:
332
332
  if target_direction in (PortDirection.Output, PortDirection.Outin):
333
333
  return target_direction
334
- raise ClassiqExpansionError(UNINITIALIZED_VAR_MESSAGE.format(var_name))
334
+ raise ClassiqExpansionError(_UNINITIALIZED_VAR_MESSAGE.format(var_name))
335
335
 
336
336
  raise ClassiqInternalExpansionError(f"Unexpected direction {source_direction}")
337
337
 
@@ -346,7 +346,7 @@ class CapturedVars:
346
346
  PortDirection.Outin,
347
347
  ):
348
348
  raise ClassiqExpansionError(
349
- UNINITIALIZED_VAR_MESSAGE.format(captured_handle.handle)
349
+ _UNINITIALIZED_VAR_MESSAGE.format(captured_handle.handle)
350
350
  )
351
351
  return existing_captured_handle
352
352
 
@@ -356,7 +356,7 @@ class CapturedVars:
356
356
  PortDirection.Outin,
357
357
  ):
358
358
  raise ClassiqExpansionError(
359
- INITIALIZED_VAR_MESSAGE.format(captured_handle.handle)
359
+ _INITIALIZED_VAR_MESSAGE.format(captured_handle.handle)
360
360
  )
361
361
  return captured_handle
362
362
 
@@ -705,7 +705,9 @@ class CapturedVars:
705
705
  def set_parent(self, parent: "CapturedVars") -> None:
706
706
  self._handle_states += parent._get_handle_states()
707
707
 
708
- def get_state(self, var_name: str, defining_function: "FunctionClosure") -> bool:
708
+ def get_state(
709
+ self, var_name: str, defining_function: "FunctionClosure"
710
+ ) -> bool | None:
709
711
  for name, func, state in self._handle_states:
710
712
  if name == var_name and _same_closure(func, defining_function):
711
713
  return state
@@ -717,9 +719,7 @@ class CapturedVars:
717
719
  PortDirection.Output,
718
720
  PortDirection.Inout,
719
721
  )
720
- raise ClassiqInternalExpansionError(
721
- f"Cannot find {var_name!r} from {defining_function.name!r}"
722
- )
722
+ return None
723
723
 
724
724
  def clone(self) -> "CapturedVars":
725
725
  return CapturedVars(
@@ -846,6 +846,10 @@ def validate_end_state(func: "FunctionClosure", captured_vars: CapturedVars) ->
846
846
  for param in func.positional_arg_declarations:
847
847
  if isinstance(param, PortDeclaration):
848
848
  state = captured_vars.get_state(param.name, func)
849
+ if state is None:
850
+ raise ClassiqInternalExpansionError(
851
+ f"Cannot find {param.name!r} from {func.name!r}"
852
+ )
849
853
  expected_state = param.direction in (
850
854
  PortDeclarationDirection.Output,
851
855
  PortDeclarationDirection.Inout,
@@ -13,6 +13,8 @@ from classiq.interface.generator.compiler_keywords import (
13
13
  )
14
14
  from classiq.interface.generator.functions.builtins.internal_operators import (
15
15
  BLOCK_OPERATOR_NAME,
16
+ INVERT_OPERATOR_NAMES,
17
+ SINGLE_CALL_INVERT_OPERATOR_NAME,
16
18
  SKIP_CONTROL_OPERATOR_NAME,
17
19
  WITHIN_APPLY_NAME,
18
20
  )
@@ -44,6 +46,7 @@ BLOCKS_ALLOWED_CAPTURING = (
44
46
  WITHIN_APPLY_NAME,
45
47
  BLOCK_OPERATOR_NAME,
46
48
  SKIP_CONTROL_OPERATOR_NAME,
49
+ SINGLE_CALL_INVERT_OPERATOR_NAME,
47
50
  )
48
51
 
49
52
 
@@ -155,6 +158,8 @@ class OperationBuilder:
155
158
  self._operations[-1].blocks[block_name] = block
156
159
  yield
157
160
  captured_vars = self.current_block.captured_vars
161
+ if self.current_operation.name in INVERT_OPERATOR_NAMES:
162
+ captured_vars = captured_vars.negate()
158
163
  if (
159
164
  not isinstance(self.current_operation, FunctionClosure)
160
165
  and self.current_operation.name not in BLOCKS_ALLOWED_CAPTURING
@@ -178,7 +183,10 @@ class OperationBuilder:
178
183
  context.closure.captured_vars.init_params(original_operation)
179
184
  else:
180
185
  context = OperationContext(closure=original_operation)
181
- context.closure.captured_vars.set_parent(self.current_block.captured_vars)
186
+ if context.name != SINGLE_CALL_INVERT_OPERATOR_NAME:
187
+ context.closure.captured_vars.set_parent(
188
+ self.current_block.captured_vars
189
+ )
182
190
  self._operations.append(context)
183
191
  yield context
184
192
  self._finalize_within_apply()
@@ -32,6 +32,7 @@ from classiq.interface.model.handle_binding import (
32
32
  from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
33
33
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
34
34
  from classiq.interface.model.quantum_function_declaration import (
35
+ NamedParamsQuantumFunctionDeclaration,
35
36
  QuantumFunctionDeclaration,
36
37
  )
37
38
  from classiq.interface.model.quantum_lambda_function import (
@@ -76,6 +77,7 @@ from classiq.model_expansions.scope_initialization import (
76
77
  from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
77
78
  from classiq.qmod.builtins.constants import __all__ as builtin_constants
78
79
  from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
80
+ from classiq.qmod.builtins.functions import CORE_LIB_DECLS
79
81
  from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
80
82
  from classiq.qmod.model_state_container import QMODULE
81
83
  from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
@@ -98,7 +100,7 @@ class BaseInterpreter:
98
100
  skip_type_modifier_validation: bool = False
99
101
 
100
102
  def __init__(self, model: Model) -> None:
101
- validate_model(model)
103
+ validate_model(model, self.get_builtin_functions())
102
104
  self._model = model
103
105
  self._top_level_scope = Scope()
104
106
  self._counted_name_allocator = CountedNameAllocator()
@@ -121,6 +123,9 @@ class BaseInterpreter:
121
123
  self._counted_name_allocator = CountedNameAllocator()
122
124
  self._error_manager: ErrorManager = ErrorManager()
123
125
 
126
+ def get_builtin_functions(self) -> list[NamedParamsQuantumFunctionDeclaration]:
127
+ return CORE_LIB_DECLS
128
+
124
129
  def _expand_main_func(self) -> None:
125
130
  main_closure = self._get_main_closure(
126
131
  self._top_level_scope[MAIN_FUNCTION_NAME].value
@@ -207,15 +212,14 @@ class BaseInterpreter:
207
212
  expression: Expression,
208
213
  *,
209
214
  simplify: bool = False,
210
- treat_qnum_as_float: bool = False,
211
215
  ) -> Evaluated:
212
216
  if expression.is_evaluated():
213
217
  return Evaluated(value=expression.value.value)
214
218
  expr_ast = ast.parse(expression.expr, mode="eval").body
215
- expr_val = self._eval_expr(ast.unparse(expr_ast), treat_qnum_as_float)
219
+ expr_val = self._eval_expr(ast.unparse(expr_ast))
216
220
  if simplify and not expr_val.has_value(expr_val.root):
217
221
  simplified_expr = simplify_qmod_expression(expr_val)
218
- expr_val = self._eval_expr(simplified_expr, treat_qnum_as_float)
222
+ expr_val = self._eval_expr(simplified_expr)
219
223
  if expr_val.has_value(expr_val.root):
220
224
  value = expr_val.get_value(expr_val.root)
221
225
  else:
@@ -223,12 +227,9 @@ class BaseInterpreter:
223
227
 
224
228
  return Evaluated(value=value)
225
229
 
226
- def _eval_expr(
227
- self, expr: str, treat_qnum_as_float: bool
228
- ) -> QmodAnnotatedExpression:
230
+ def _eval_expr(self, expr: str) -> QmodAnnotatedExpression:
229
231
  return evaluate_qmod_expression(
230
232
  expr,
231
- treat_qnum_as_float=treat_qnum_as_float,
232
233
  machine_precision=self._model.preferences.machine_precision,
233
234
  classical_struct_declarations=list(QMODULE.type_decls.values()),
234
235
  enum_declarations=list(QMODULE.enum_decls.values()),
@@ -9,10 +9,11 @@ from classiq.interface.generator.expressions.expression import Expression
9
9
  from classiq.interface.generator.functions.builtins.internal_operators import (
10
10
  BLOCK_OPERATOR_NAME,
11
11
  CLASSICAL_IF_OPERATOR_NAME,
12
+ COMPOUND_INVERT_OPERATOR_NAME,
12
13
  CONTROL_OPERATOR_NAME,
13
- INVERT_OPERATOR_NAME,
14
14
  POWER_OPERATOR_NAME,
15
15
  REPEAT_OPERATOR_NAME,
16
+ SINGLE_CALL_INVERT_OPERATOR_NAME,
16
17
  SKIP_CONTROL_OPERATOR_NAME,
17
18
  WITHIN_APPLY_NAME,
18
19
  )
@@ -23,14 +24,11 @@ from classiq.interface.model.bounds import SetBoundsStatement
23
24
  from classiq.interface.model.classical_if import ClassicalIf
24
25
  from classiq.interface.model.control import Control
25
26
  from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
26
- from classiq.interface.model.invert import Invert
27
+ from classiq.interface.model.invert import BlockKind, Invert
27
28
  from classiq.interface.model.model import Model
28
29
  from classiq.interface.model.native_function_definition import NativeFunctionDefinition
29
30
  from classiq.interface.model.phase_operation import PhaseOperation
30
31
  from classiq.interface.model.power import Power
31
- from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
32
- AmplitudeLoadingOperation,
33
- )
34
32
  from classiq.interface.model.quantum_expressions.arithmetic_operation import (
35
33
  ArithmeticOperation,
36
34
  )
@@ -199,24 +197,6 @@ class GenerativeInterpreter(BaseInterpreter):
199
197
  bind
200
198
  )
201
199
 
202
- @emit.register
203
- def emit_amplitude_loading_operation(self, op: AmplitudeLoadingOperation) -> None:
204
- CompositeEmitter[AmplitudeLoadingOperation](
205
- self,
206
- [
207
- HandleEvaluator(self, "result_var"),
208
- ExpressionEvaluator(
209
- self,
210
- "expression",
211
- readable_expression_name="amplitude-encoding expression",
212
- simplify=True,
213
- treat_qnum_as_float=True,
214
- allow_runtime_vars=self._symbolic_parameters_switch,
215
- ),
216
- AssignmentResultProcessor(self),
217
- ],
218
- ).emit(op)
219
-
220
200
  @emit.register
221
201
  def _emit_arithmetic_operation(self, op: ArithmeticOperation) -> None:
222
202
  self.emit_arithmetic_operation(op)
@@ -285,7 +265,12 @@ class GenerativeInterpreter(BaseInterpreter):
285
265
 
286
266
  @emit.register
287
267
  def emit_invert(self, invert: Invert) -> None:
288
- BlockEvaluator(self, INVERT_OPERATOR_NAME, "body").emit(invert)
268
+ match invert.block_kind:
269
+ case BlockKind.SingleCall:
270
+ op_name = SINGLE_CALL_INVERT_OPERATOR_NAME
271
+ case BlockKind.Compound:
272
+ op_name = COMPOUND_INVERT_OPERATOR_NAME
273
+ BlockEvaluator(self, op_name, "body").emit(invert)
289
274
 
290
275
  @emit.register
291
276
  def emit_skip_control(self, skip_control: SkipControl) -> None:
@@ -50,6 +50,7 @@ def convert_inplace_op_bool_expression(
50
50
  def _supported_types() -> tuple[str, ...]:
51
51
  return (
52
52
  QuantumBit().qmod_type_name,
53
+ QuantumNumeric().qmod_type_name,
53
54
  QuantumNumeric(
54
55
  size=Expression(expr="1"),
55
56
  is_signed=Expression(expr="False"),