classiq 0.82.1__py3-none-any.whl → 0.84.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 (96) hide show
  1. classiq/_internals/api_wrapper.py +27 -0
  2. classiq/applications/chemistry/chemistry_model_constructor.py +2 -4
  3. classiq/applications/chemistry/hartree_fock.py +68 -0
  4. classiq/applications/chemistry/mapping.py +85 -0
  5. classiq/applications/chemistry/op_utils.py +79 -0
  6. classiq/applications/chemistry/problems.py +195 -0
  7. classiq/applications/chemistry/ucc.py +109 -0
  8. classiq/applications/chemistry/z2_symmetries.py +368 -0
  9. classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +30 -1
  10. classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
  11. classiq/{model_expansions/evaluators → evaluators}/arg_type_match.py +12 -4
  12. classiq/{model_expansions/evaluators → evaluators}/argument_types.py +3 -3
  13. classiq/{model_expansions/evaluators → evaluators}/classical_expression.py +1 -1
  14. classiq/{model_expansions/evaluators → evaluators}/classical_type_inference.py +3 -4
  15. classiq/{model_expansions/evaluators → evaluators}/parameter_types.py +17 -15
  16. classiq/execution/__init__.py +12 -1
  17. classiq/execution/execution_session.py +189 -43
  18. classiq/execution/jobs.py +26 -1
  19. classiq/execution/qnn.py +2 -2
  20. classiq/execution/user_budgets.py +39 -0
  21. classiq/interface/_version.py +1 -1
  22. classiq/interface/constants.py +1 -0
  23. classiq/interface/execution/primitives.py +29 -1
  24. classiq/interface/executor/estimate_cost.py +35 -0
  25. classiq/interface/executor/execution_result.py +13 -0
  26. classiq/interface/executor/result.py +116 -1
  27. classiq/interface/executor/user_budget.py +26 -33
  28. classiq/interface/generator/application_apis/finance_declarations.py +3 -3
  29. classiq/interface/generator/expressions/atomic_expression_functions.py +11 -3
  30. classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +0 -6
  31. classiq/interface/generator/functions/classical_type.py +2 -35
  32. classiq/interface/generator/functions/concrete_types.py +0 -3
  33. classiq/interface/generator/functions/type_modifier.py +22 -0
  34. classiq/interface/generator/generated_circuit_data.py +5 -16
  35. classiq/interface/generator/model/model.py +8 -0
  36. classiq/interface/generator/quantum_program.py +0 -13
  37. classiq/interface/generator/types/compilation_metadata.py +0 -3
  38. classiq/interface/helpers/model_normalizer.py +2 -2
  39. classiq/interface/ide/visual_model.py +6 -2
  40. classiq/interface/model/model.py +12 -7
  41. classiq/interface/model/port_declaration.py +4 -2
  42. classiq/interface/pretty_print/__init__.py +0 -0
  43. classiq/{qmod/native → interface/pretty_print}/expression_to_qmod.py +18 -11
  44. classiq/interface/server/routes.py +4 -0
  45. classiq/model_expansions/atomic_expression_functions_defs.py +42 -5
  46. classiq/model_expansions/capturing/captured_vars.py +21 -8
  47. classiq/model_expansions/interpreters/base_interpreter.py +3 -3
  48. classiq/model_expansions/quantum_operations/allocate.py +1 -1
  49. classiq/model_expansions/quantum_operations/assignment_result_processor.py +1 -1
  50. classiq/model_expansions/quantum_operations/bind.py +2 -2
  51. classiq/model_expansions/quantum_operations/call_emitter.py +42 -36
  52. classiq/model_expansions/quantum_operations/variable_decleration.py +1 -1
  53. classiq/model_expansions/scope_initialization.py +3 -3
  54. classiq/model_expansions/transformers/model_renamer.py +16 -5
  55. classiq/model_expansions/transformers/{type_qualifier_inference.py → type_modifier_inference.py} +134 -100
  56. classiq/model_expansions/visitors/symbolic_param_inference.py +10 -7
  57. classiq/open_library/functions/__init__.py +3 -0
  58. classiq/open_library/functions/amplitude_amplification.py +10 -18
  59. classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
  60. classiq/open_library/functions/grover.py +14 -6
  61. classiq/open_library/functions/modular_exponentiation.py +22 -20
  62. classiq/open_library/functions/state_preparation.py +18 -1
  63. classiq/qmod/__init__.py +2 -2
  64. classiq/qmod/builtins/enums.py +23 -0
  65. classiq/qmod/builtins/functions/__init__.py +2 -0
  66. classiq/qmod/builtins/functions/allocation.py +2 -2
  67. classiq/qmod/builtins/functions/arithmetic.py +16 -8
  68. classiq/qmod/builtins/functions/exponentiation.py +32 -4
  69. classiq/qmod/builtins/functions/standard_gates.py +7 -7
  70. classiq/qmod/builtins/structs.py +55 -3
  71. classiq/qmod/declaration_inferrer.py +8 -7
  72. classiq/qmod/native/pretty_printer.py +7 -11
  73. classiq/qmod/pretty_print/expression_to_python.py +2 -1
  74. classiq/qmod/pretty_print/pretty_printer.py +7 -12
  75. classiq/qmod/python_classical_type.py +12 -5
  76. classiq/qmod/qfunc.py +1 -1
  77. classiq/qmod/qmod_constant.py +2 -5
  78. classiq/qmod/qmod_parameter.py +2 -5
  79. classiq/qmod/qmod_variable.py +66 -25
  80. classiq/qmod/quantum_expandable.py +4 -2
  81. classiq/qmod/quantum_function.py +7 -2
  82. classiq/qmod/semantics/annotation/qstruct_annotator.py +1 -1
  83. classiq/qmod/semantics/validation/main_validation.py +1 -9
  84. classiq/qmod/semantics/validation/type_hints.py +9 -9
  85. classiq/qmod/utilities.py +0 -2
  86. classiq/qmod/write_qmod.py +1 -1
  87. classiq/synthesis.py +0 -2
  88. {classiq-0.82.1.dist-info → classiq-0.84.0.dist-info}/METADATA +4 -1
  89. {classiq-0.82.1.dist-info → classiq-0.84.0.dist-info}/RECORD +95 -86
  90. classiq/interface/generator/functions/type_qualifier.py +0 -22
  91. /classiq/{model_expansions/evaluators → evaluators}/__init__.py +0 -0
  92. /classiq/{model_expansions/evaluators → evaluators}/control.py +0 -0
  93. /classiq/{model_expansions → evaluators}/expression_evaluator.py +0 -0
  94. /classiq/{model_expansions/evaluators → evaluators}/quantum_type_utils.py +0 -0
  95. /classiq/{model_expansions/evaluators → evaluators}/type_type_match.py +0 -0
  96. {classiq-0.82.1.dist-info → classiq-0.84.0.dist-info}/WHEEL +0 -0
@@ -10,6 +10,9 @@ from classiq.interface.exceptions import (
10
10
  ClassiqExpansionError,
11
11
  ClassiqInternalExpansionError,
12
12
  )
13
+ from classiq.interface.generator.expressions.evaluated_expression import (
14
+ EvaluatedExpression,
15
+ )
13
16
  from classiq.interface.generator.expressions.expression import Expression
14
17
  from classiq.interface.generator.functions.classical_type import (
15
18
  CLASSICAL_ATTRIBUTES_TYPES,
@@ -18,7 +21,7 @@ from classiq.interface.generator.functions.classical_type import (
18
21
  from classiq.interface.generator.functions.port_declaration import (
19
22
  PortDeclarationDirection,
20
23
  )
21
- from classiq.interface.generator.functions.type_qualifier import TypeQualifier
24
+ from classiq.interface.generator.functions.type_modifier import TypeModifier
22
25
  from classiq.interface.helpers.text_utils import are, readable_list, s, they
23
26
  from classiq.interface.model.classical_parameter_declaration import (
24
27
  ClassicalParameterDeclaration,
@@ -56,6 +59,14 @@ INITIALIZED_VAR_MESSAGE = "Variable '{}' should be uninitialized here"
56
59
  UNINITIALIZED_VAR_MESSAGE = "Variable '{}' should be initialized here"
57
60
 
58
61
 
62
+ def _get_symbol_expr(symbol: str, classical_type: ClassicalType) -> Expression:
63
+ expr = Expression(expr=symbol)
64
+ expr._evaluated_expr = EvaluatedExpression(
65
+ value=classical_type.get_classical_proxy(handle=HandleBinding(name=symbol))
66
+ )
67
+ return expr
68
+
69
+
59
70
  class PortDirection(StrEnum):
60
71
  Input = "input"
61
72
  Inout = "inout"
@@ -138,7 +149,7 @@ class _CapturedHandle(_Captured):
138
149
  name=self.mangled_name,
139
150
  quantum_type=self.quantum_type,
140
151
  direction=self.direction.dump(),
141
- type_qualifier=TypeQualifier.Inferred, # TODO https://classiq.atlassian.net/browse/CLS-1830
152
+ type_modifier=TypeModifier.Inferred,
142
153
  )
143
154
 
144
155
  def is_same_var(self, other: "_CapturedHandle") -> bool:
@@ -556,24 +567,26 @@ class CapturedVars:
556
567
  def get_captured_args(self, current_function: "FunctionClosure") -> list[ArgValue]:
557
568
  args: list[ArgValue]
558
569
  args = [
559
- Expression(
560
- expr=(
570
+ _get_symbol_expr(
571
+ (
561
572
  captured_classical_var.name
562
573
  if _same_closure(
563
574
  current_function, captured_classical_var.defining_function
564
575
  )
565
576
  else captured_classical_var.mangled_name
566
- )
577
+ ),
578
+ captured_classical_var.classical_type,
567
579
  )
568
580
  for captured_classical_var in self._captured_classical_vars
569
581
  ]
570
582
  args += [
571
- Expression(
572
- expr=(
583
+ _get_symbol_expr(
584
+ (
573
585
  str(captured_qta.handle)
574
586
  if _same_closure(current_function, captured_qta.defining_function)
575
587
  else captured_qta.mangled_name
576
- )
588
+ ),
589
+ captured_qta.classical_type,
577
590
  )
578
591
  for captured_qta in self._captured_quantum_type_attributes
579
592
  ]
@@ -39,14 +39,14 @@ from classiq.interface.model.quantum_lambda_function import (
39
39
  )
40
40
  from classiq.interface.model.quantum_statement import QuantumStatement
41
41
 
42
+ from classiq.evaluators.classical_expression import (
43
+ evaluate_classical_expression,
44
+ )
42
45
  from classiq.model_expansions.closure import (
43
46
  Closure,
44
47
  FunctionClosure,
45
48
  )
46
49
  from classiq.model_expansions.debug_flag import debug_mode
47
- from classiq.model_expansions.evaluators.classical_expression import (
48
- evaluate_classical_expression,
49
- )
50
50
  from classiq.model_expansions.function_builder import (
51
51
  FunctionContext,
52
52
  OperationBuilder,
@@ -12,7 +12,7 @@ from classiq.interface.model.quantum_type import (
12
12
  QuantumNumeric,
13
13
  )
14
14
 
15
- from classiq.model_expansions.evaluators.quantum_type_utils import copy_type_information
15
+ from classiq.evaluators.quantum_type_utils import copy_type_information
16
16
  from classiq.model_expansions.quantum_operations.emitter import Emitter
17
17
  from classiq.model_expansions.scope import QuantumSymbol
18
18
 
@@ -24,7 +24,7 @@ from classiq.interface.model.variable_declaration_statement import (
24
24
  )
25
25
  from classiq.interface.model.within_apply_operation import WithinApply
26
26
 
27
- from classiq.model_expansions.evaluators.quantum_type_utils import copy_type_information
27
+ from classiq.evaluators.quantum_type_utils import copy_type_information
28
28
  from classiq.model_expansions.quantum_operations.arithmetic.explicit_boolean_expressions import (
29
29
  convert_assignment_bool_expression,
30
30
  validate_assignment_bool_expression,
@@ -8,10 +8,10 @@ from classiq.interface.exceptions import (
8
8
  from classiq.interface.model.bind_operation import BindOperation
9
9
  from classiq.interface.model.quantum_type import QuantumNumeric
10
10
 
11
- from classiq.model_expansions.evaluators.parameter_types import (
11
+ from classiq.evaluators.parameter_types import (
12
12
  evaluate_types_in_quantum_symbols,
13
13
  )
14
- from classiq.model_expansions.evaluators.quantum_type_utils import (
14
+ from classiq.evaluators.quantum_type_utils import (
15
15
  set_size,
16
16
  validate_bind_targets,
17
17
  )
@@ -28,7 +28,7 @@ from classiq.interface.generator.expressions.proxies.classical.qmod_struct_insta
28
28
  from classiq.interface.generator.functions.port_declaration import (
29
29
  PortDeclarationDirection,
30
30
  )
31
- from classiq.interface.generator.functions.type_qualifier import TypeQualifier
31
+ from classiq.interface.generator.functions.type_modifier import TypeModifier
32
32
  from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
33
33
  from classiq.interface.helpers.backward_compatibility import zip_strict
34
34
  from classiq.interface.helpers.text_utils import are, readable_list, s
@@ -50,19 +50,19 @@ from classiq.interface.model.variable_declaration_statement import (
50
50
  VariableDeclarationStatement,
51
51
  )
52
52
 
53
+ from classiq.evaluators.argument_types import (
54
+ add_information_from_output_arguments,
55
+ handle_args_numeric_bounds,
56
+ )
57
+ from classiq.evaluators.parameter_types import (
58
+ evaluate_parameter_types_from_args,
59
+ )
53
60
  from classiq.model_expansions.capturing.captured_vars import (
54
61
  INITIALIZED_VAR_MESSAGE,
55
62
  UNINITIALIZED_VAR_MESSAGE,
56
63
  validate_args_are_not_propagated,
57
64
  )
58
65
  from classiq.model_expansions.closure import Closure, FunctionClosure
59
- from classiq.model_expansions.evaluators.argument_types import (
60
- add_information_from_output_arguments,
61
- handle_args_numeric_bounds,
62
- )
63
- from classiq.model_expansions.evaluators.parameter_types import (
64
- evaluate_parameter_types_from_args,
65
- )
66
66
  from classiq.model_expansions.function_builder import (
67
67
  FunctionContext,
68
68
  )
@@ -80,8 +80,8 @@ from classiq.model_expansions.scope import (
80
80
  QuantumVariable,
81
81
  Scope,
82
82
  )
83
- from classiq.model_expansions.transformers.type_qualifier_inference import (
84
- TypeQualifierValidation,
83
+ from classiq.model_expansions.transformers.type_modifier_inference import (
84
+ TypeModifierValidation,
85
85
  )
86
86
  from classiq.model_expansions.transformers.var_splitter import VarSplitter
87
87
  from classiq.qmod.pretty_print.expression_to_python import transform_expression
@@ -135,13 +135,13 @@ def _validate_gen_args(
135
135
  ):
136
136
  if (
137
137
  isinstance(param, ClassicalParameterDeclaration)
138
- and param.classical_type.is_purely_generative
138
+ and not param.classical_type.is_purely_declarative
139
139
  and _is_symbolic(arg.value)
140
140
  ):
141
+ readable_expr = transform_expression(str(arg.value), {}, {}, one_line=True)
141
142
  raise ClassiqExpansionError(
142
- f"Parameter {param.name!r} is used in a compile-time expression "
143
- f"context but is passed a runtime expression "
144
- f"{transform_expression(str(arg.value), {}, {}, one_line=True)!r}"
143
+ f"Cannot pass symbolic expression {readable_expr!r} as Python-type "
144
+ f"parameter {param.name!r}"
145
145
  )
146
146
 
147
147
 
@@ -209,17 +209,21 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
209
209
  function.name, new_declaration
210
210
  )
211
211
  else:
212
- # FIXME: enable for BE (CLS-2390)
213
- if type(self._interpreter).__name__ == "FrontendGenerativeInterpreter":
214
- _validate_gen_args(function, evaluated_args)
212
+ _validate_gen_args(function, evaluated_args)
215
213
  new_declaration = self._expand_function(
216
214
  evaluated_args, new_declaration, function
217
215
  )
218
216
  new_positional_arg_decls = new_declaration.positional_arg_declarations
219
217
  evaluated_args = [
220
218
  arg
221
- for arg in evaluated_args
222
- if isinstance(arg.value, QuantumVariable) or _is_symbolic(arg.value)
219
+ for param, arg in zip_strict(
220
+ function.positional_arg_declarations, evaluated_args, strict=True
221
+ )
222
+ if isinstance(arg.value, QuantumVariable)
223
+ or (
224
+ isinstance(param, ClassicalParameterDeclaration)
225
+ and param.classical_type.is_purely_declarative
226
+ )
223
227
  ]
224
228
 
225
229
  add_information_from_output_arguments(new_positional_arg_decls, evaluated_args)
@@ -291,7 +295,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
291
295
  context = self._expand_operation(function)
292
296
  function_context = cast(FunctionContext, context)
293
297
  function_def = self._create_function_definition(function_context, args)
294
- self._validate_type_qualifiers(function_context, function_def)
298
+ self._validate_type_modifiers(function_context, function_def)
295
299
  self._expanded_functions[cache_key] = function_def
296
300
  self._top_level_scope[function_def.name] = Evaluated(
297
301
  value=function_context.closure.with_new_declaration(function_def)
@@ -312,7 +316,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
312
316
  if isinstance(param, PortDeclaration)
313
317
  or (
314
318
  isinstance(param, ClassicalParameterDeclaration)
315
- and _is_symbolic(arg.value)
319
+ and param.classical_type.is_purely_declarative
316
320
  )
317
321
  ]
318
322
  func_def = self._builder.create_definition(function_context, params)
@@ -350,8 +354,10 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
350
354
  ),
351
355
  defining_function=closure,
352
356
  )
353
- elif _is_symbolic(argument.value):
354
- assert isinstance(parameter, ClassicalParameterDeclaration)
357
+ elif (
358
+ isinstance(parameter, ClassicalParameterDeclaration)
359
+ and parameter.classical_type.is_purely_declarative
360
+ ):
355
361
  inferred_arg = Evaluated(
356
362
  value=parameter.classical_type.get_classical_proxy(param_handle),
357
363
  defining_function=closure,
@@ -415,29 +421,29 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
415
421
  if var_state and param.direction == PortDeclarationDirection.Output:
416
422
  raise ClassiqExpansionError(INITIALIZED_VAR_MESSAGE.format(var_name))
417
423
 
418
- def _validate_type_qualifiers(
424
+ def _validate_type_modifiers(
419
425
  self, func_context: FunctionContext, func_def: NativeFunctionDefinition
420
426
  ) -> None:
421
- if self._should_override_type_qualifiers(func_context):
422
- self._override_type_qualifiers(func_def)
427
+ if self._should_override_type_modifiers(func_context):
428
+ self._override_type_modifiers(func_def)
423
429
 
424
430
  unchecked = self._functions_compilation_metadata.get(
425
431
  func_context.name, CompilationMetadata()
426
432
  ).unchecked
427
- TypeQualifierValidation(
433
+ TypeModifierValidation(
428
434
  skip_validation=self._interpreter.skip_type_modifier_validation
429
- ).run(func_def.port_declarations, func_def.body, unchecked)
435
+ ).run(func_def, unchecked)
430
436
 
431
437
  @staticmethod
432
- def _should_override_type_qualifiers(func_context: FunctionContext) -> bool:
438
+ def _should_override_type_modifiers(func_context: FunctionContext) -> bool:
433
439
  """
434
- The type qualifier can be changed according to the operand passed to the
440
+ The type modifier can be changed according to the operand passed to the
435
441
  function. For example,
436
- apply_to_all(X, q) --> q will be QFree after expansion
442
+ apply_to_all(X, q) --> q will be Permutable after expansion
437
443
  apply_to_all(H, q) --> q will be Quantum after expansion
438
444
  This also holds for the intermediate lambda created during the expansion.
439
445
 
440
- We don't override the type qualifier if it's explicitly specified (QFree or
446
+ We don't override the type modifier if it's explicitly specified (Permutable or
441
447
  Const), neither in the function declaration nor in the operand declaration.
442
448
  """
443
449
 
@@ -461,8 +467,8 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
461
467
  )
462
468
 
463
469
  @staticmethod
464
- def _override_type_qualifiers(func_def: NativeFunctionDefinition) -> None:
465
- # only override the qualifier if it's unspecified (not QFree or Const)
470
+ def _override_type_modifiers(func_def: NativeFunctionDefinition) -> None:
471
+ # only override the modifier if it's unspecified (not Permutable or Const)
466
472
  for port in func_def.port_declarations:
467
- if port.type_qualifier is TypeQualifier.Quantum:
468
- port.type_qualifier = TypeQualifier.Inferred
473
+ if port.type_modifier is TypeModifier.Mutable:
474
+ port.type_modifier = TypeModifier.Inferred
@@ -4,7 +4,7 @@ from classiq.interface.model.variable_declaration_statement import (
4
4
  VariableDeclarationStatement,
5
5
  )
6
6
 
7
- from classiq.model_expansions.evaluators.parameter_types import (
7
+ from classiq.evaluators.parameter_types import (
8
8
  evaluate_type_in_quantum_symbol,
9
9
  )
10
10
  from classiq.model_expansions.quantum_operations.emitter import Emitter
@@ -11,13 +11,13 @@ from classiq.interface.model.native_function_definition import NativeFunctionDef
11
11
  from classiq.interface.model.port_declaration import PortDeclaration
12
12
  from classiq.interface.model.quantum_function_declaration import PositionalArg
13
13
 
14
- from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
15
- from classiq.model_expansions.evaluators.classical_expression import (
14
+ from classiq.evaluators.classical_expression import (
16
15
  evaluate_classical_expression,
17
16
  )
18
- from classiq.model_expansions.evaluators.parameter_types import (
17
+ from classiq.evaluators.parameter_types import (
19
18
  evaluate_type_in_quantum_symbol,
20
19
  )
20
+ from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
21
21
  from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
22
22
  from classiq.qmod.builtins import BUILTIN_CONSTANTS
23
23
  from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
@@ -6,7 +6,13 @@ from functools import cmp_to_key
6
6
  from typing import TypeVar, cast
7
7
 
8
8
  from classiq.interface.exceptions import ClassiqInternalExpansionError
9
+ from classiq.interface.generator.expressions.evaluated_expression import (
10
+ EvaluatedExpression,
11
+ )
9
12
  from classiq.interface.generator.expressions.expression import Expression
13
+ from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
14
+ AnyClassicalValue,
15
+ )
10
16
  from classiq.interface.generator.visitor import NodeType
11
17
  from classiq.interface.model.handle_binding import HandleBinding
12
18
  from classiq.interface.model.model_visitor import ModelTransformer
@@ -71,7 +77,7 @@ class HandleRenaming:
71
77
  SymbolRenaming = Mapping[HandleBinding, Sequence[HandleRenaming]]
72
78
 
73
79
 
74
- def _rewrite_expression(
80
+ def rewrite_expression(
75
81
  symbol_mapping: SymbolRenaming, expression: Expression
76
82
  ) -> Expression:
77
83
  normalized_expr = ExprNormalizer().visit(ast.parse(expression.expr))
@@ -82,7 +88,8 @@ def _rewrite_expression(
82
88
 
83
89
  handle_names = {
84
90
  part.source_handle: part.target_var_handle
85
- for parts in symbol_mapping.values()
91
+ for source, parts in symbol_mapping.items()
92
+ if source.name in expression.expr
86
93
  for part in parts
87
94
  }
88
95
  new_expr_str = ast.unparse(normalized_expr)
@@ -95,11 +102,15 @@ def _rewrite_expression(
95
102
  for handle in sorted_handles:
96
103
  new_handle = handle.collapse()
97
104
  for handle_to_replace, replacement in handle_names.items():
98
- new_handle = new_handle.replace_prefix(handle_to_replace, replacement)
105
+ if new_handle.name == handle_to_replace.name:
106
+ new_handle = new_handle.replace_prefix(handle_to_replace, replacement)
99
107
  new_expr_str = _replace_full_word(str(handle), str(new_handle), new_expr_str)
100
108
 
101
109
  new_expr = Expression(expr=new_expr_str)
102
- new_expr._evaluated_expr = expression._evaluated_expr
110
+ if not new_expr.is_evaluated():
111
+ new_expr._evaluated_expr = EvaluatedExpression(
112
+ value=AnyClassicalValue(new_expr_str)
113
+ )
103
114
  return new_expr
104
115
 
105
116
 
@@ -123,7 +134,7 @@ class _ReplaceSplitVarsExpressions(ModelTransformer):
123
134
  self._symbol_mapping = symbol_mapping
124
135
 
125
136
  def visit_Expression(self, expr: Expression) -> Expression:
126
- return _rewrite_expression(self._symbol_mapping, expr)
137
+ return rewrite_expression(self._symbol_mapping, expr)
127
138
 
128
139
  def visit_QuantumExpressionOperation(
129
140
  self, op: QuantumExpressionOperation