classiq 0.67.0__py3-none-any.whl → 0.68.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 (56) hide show
  1. classiq/_internals/api_wrapper.py +5 -1
  2. classiq/_internals/async_utils.py +1 -1
  3. classiq/_internals/authentication/password_manager.py +1 -1
  4. classiq/_internals/client.py +1 -1
  5. classiq/execution/execution_session.py +7 -3
  6. classiq/executor.py +7 -2
  7. classiq/interface/_version.py +1 -1
  8. classiq/interface/ast_node.py +1 -1
  9. classiq/interface/chemistry/operator.py +1 -1
  10. classiq/interface/debug_info/debug_info.py +15 -0
  11. classiq/interface/generator/arith/arithmetic.py +96 -1
  12. classiq/interface/generator/arith/arithmetic_expression_parser.py +1 -1
  13. classiq/interface/generator/generated_circuit_data.py +4 -2
  14. classiq/interface/generator/quantum_program.py +18 -1
  15. classiq/interface/generator/types/enum_declaration.py +33 -2
  16. classiq/interface/model/classical_if.py +2 -2
  17. classiq/interface/model/control.py +2 -2
  18. classiq/interface/model/invert.py +2 -2
  19. classiq/interface/model/power.py +2 -2
  20. classiq/interface/model/quantum_function_call.py +4 -0
  21. classiq/interface/model/repeat.py +2 -2
  22. classiq/interface/model/statement_block.py +1 -1
  23. classiq/interface/model/within_apply_operation.py +2 -2
  24. classiq/model_expansions/interpreters/generative_interpreter.py +78 -18
  25. classiq/model_expansions/quantum_operations/allocate.py +3 -1
  26. classiq/model_expansions/quantum_operations/assignment_result_processor.py +52 -0
  27. classiq/model_expansions/quantum_operations/bind.py +2 -1
  28. classiq/model_expansions/quantum_operations/block_evaluator.py +76 -0
  29. classiq/model_expansions/quantum_operations/classicalif.py +5 -4
  30. classiq/model_expansions/quantum_operations/composite_emitter.py +27 -0
  31. classiq/model_expansions/quantum_operations/emitter.py +16 -2
  32. classiq/model_expansions/quantum_operations/expression_evaluator.py +33 -0
  33. classiq/model_expansions/quantum_operations/handle_evaluator.py +28 -0
  34. classiq/model_expansions/quantum_operations/quantum_function_call.py +3 -2
  35. classiq/model_expansions/quantum_operations/repeat.py +2 -1
  36. classiq/model_expansions/quantum_operations/variable_decleration.py +2 -1
  37. classiq/model_expansions/sympy_conversion/expression_to_sympy.py +1 -1
  38. classiq/open_library/functions/__init__.py +1 -2
  39. classiq/open_library/functions/amplitude_amplification.py +8 -5
  40. classiq/open_library/functions/discrete_sine_cosine_transform.py +16 -13
  41. classiq/open_library/functions/grover.py +6 -10
  42. classiq/open_library/functions/modular_exponentiation.py +7 -13
  43. classiq/open_library/functions/state_preparation.py +16 -17
  44. classiq/open_library/functions/swap_test.py +1 -1
  45. classiq/open_library/functions/utility_functions.py +10 -2
  46. classiq/qmod/builtins/functions/chemistry.py +6 -38
  47. classiq/qmod/quantum_expandable.py +30 -6
  48. classiq/qmod/semantics/validation/types_validation.py +1 -1
  49. classiq/qmod/symbolic.py +2 -1
  50. classiq/qmod/utilities.py +2 -1
  51. classiq/qmod/write_qmod.py +10 -7
  52. classiq/synthesis.py +20 -7
  53. {classiq-0.67.0.dist-info → classiq-0.68.0.dist-info}/METADATA +1 -1
  54. {classiq-0.67.0.dist-info → classiq-0.68.0.dist-info}/RECORD +55 -51
  55. classiq/model_expansions/quantum_operations/shallow_emitter.py +0 -166
  56. {classiq-0.67.0.dist-info → classiq-0.68.0.dist-info}/WHEEL +0 -0
@@ -3,6 +3,7 @@ from typing import Any, Optional, Protocol, TypeVar
3
3
 
4
4
  import httpx
5
5
  import pydantic
6
+ from pydantic.main import IncEx
6
7
 
7
8
  import classiq.interface.executor.execution_result
8
9
  import classiq.interface.pyomo_extension
@@ -72,11 +73,12 @@ class ApiWrapper:
72
73
  model: pydantic.BaseModel,
73
74
  use_versioned_url: bool = True,
74
75
  http_client: Optional[httpx.AsyncClient] = None,
76
+ exclude: Optional[IncEx] = None,
75
77
  ) -> dict:
76
78
  # TODO: we can't use model.dict() - it doesn't serialize complex class.
77
79
  # This was added because JSON serializer doesn't serialize complex type, and pydantic does.
78
80
  # We should add support for smarter json serialization.
79
- body = json.loads(model.model_dump_json())
81
+ body = json.loads(model.model_dump_json(exclude=exclude))
80
82
  return await cls._call_task(
81
83
  http_method,
82
84
  url,
@@ -135,6 +137,7 @@ class ApiWrapper:
135
137
  url=routes.EXECUTION_SESSIONS_PREFIX,
136
138
  model=circuit,
137
139
  http_client=http_client,
140
+ exclude={"debug_info"},
138
141
  )
139
142
  return raw_result["id"]
140
143
 
@@ -164,6 +167,7 @@ class ApiWrapper:
164
167
  url=routes.CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_FULL,
165
168
  model=circuit,
166
169
  http_client=http_client,
170
+ exclude={"debug_info"},
167
171
  )
168
172
 
169
173
  @classmethod
@@ -58,7 +58,7 @@ def enable_jupyter_notebook() -> None:
58
58
 
59
59
 
60
60
  def _make_iterable_interval(
61
- interval_sec: Union[SupportsFloat, Iterable[SupportsFloat]]
61
+ interval_sec: Union[SupportsFloat, Iterable[SupportsFloat]],
62
62
  ) -> Iterable[float]:
63
63
  if isinstance(interval_sec, Iterable):
64
64
  return map(float, interval_sec)
@@ -117,7 +117,7 @@ class DummyPasswordManager(PasswordManager):
117
117
 
118
118
  class FilePasswordManager(PasswordManager):
119
119
  _CLASSIQ_CREDENTIALS_FILE_PATH: str = "{}/.classiq-credentials".format(
120
- os.getenv("HOME")
120
+ os.getenv("CLASSIQ_DIR", os.getenv("HOME"))
121
121
  )
122
122
 
123
123
  def __init__(self) -> None:
@@ -89,7 +89,7 @@ P = ParamSpec("P")
89
89
 
90
90
 
91
91
  def try_again_on_failure(
92
- func: Callable[P, Awaitable[Ret]]
92
+ func: Callable[P, Awaitable[Ret]],
93
93
  ) -> Callable[P, Awaitable[Ret]]:
94
94
  def check_approved_api_error(error_message: str) -> bool:
95
95
  for approved_api_error in APPROVED_API_ERROR_MESSAGES_FOR_RESTART:
@@ -1,4 +1,3 @@
1
- import json
2
1
  import random
3
2
  from types import TracebackType
4
3
  from typing import Callable, Optional, Union, cast
@@ -16,7 +15,10 @@ from classiq.interface.executor.result import (
16
15
  )
17
16
  from classiq.interface.generator.arith import number_utils
18
17
  from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
19
- from classiq.interface.generator.quantum_program import QuantumProgram
18
+ from classiq.interface.generator.quantum_program import (
19
+ OMIT_DEBUG_INFO_FLAG,
20
+ QuantumProgram,
21
+ )
20
22
  from classiq.interface.model.quantum_type import QuantumBit, QuantumNumeric
21
23
 
22
24
  from classiq._internals import async_utils
@@ -46,7 +48,9 @@ def _deserialize_program(program: Program) -> QuantumProgram:
46
48
  return (
47
49
  program
48
50
  if isinstance(program, QuantumProgram)
49
- else QuantumProgram.model_validate(json.loads(program))
51
+ else QuantumProgram.model_validate_json(
52
+ program, context={OMIT_DEBUG_INFO_FLAG: True}
53
+ )
50
54
  )
51
55
 
52
56
 
classiq/executor.py CHANGED
@@ -10,7 +10,10 @@ from classiq.interface.executor.execution_preferences import ExecutionPreference
10
10
  from classiq.interface.executor.quantum_code import QuantumCode
11
11
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
12
12
  from classiq.interface.executor.result import ExecutionDetails
13
- from classiq.interface.generator.quantum_program import QuantumProgram
13
+ from classiq.interface.generator.quantum_program import (
14
+ OMIT_DEBUG_INFO_FLAG,
15
+ QuantumProgram,
16
+ )
14
17
 
15
18
  from classiq._internals import async_utils
16
19
  from classiq._internals.api_wrapper import ApiWrapper
@@ -27,7 +30,9 @@ BackendPreferencesAndResult: TypeAlias = tuple[
27
30
  def _parse_serialized_qprog(
28
31
  quantum_program: SerializedQuantumProgram,
29
32
  ) -> QuantumProgram:
30
- return QuantumProgram.model_validate_json(quantum_program)
33
+ return QuantumProgram.model_validate_json(
34
+ quantum_program, context={OMIT_DEBUG_INFO_FLAG: True}
35
+ )
31
36
 
32
37
 
33
38
  async def execute_async(quantum_program: SerializedQuantumProgram) -> ExecutionJob:
@@ -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.67.0'
6
+ SEMVER_VERSION = '0.68.0'
7
7
  VERSION = str(Version(SEMVER_VERSION))
@@ -20,7 +20,7 @@ class ASTNode(HashablePydanticBaseModel):
20
20
  return self
21
21
 
22
22
 
23
- def without_statement_blocks(
23
+ def reset_lists(
24
24
  ast_node: ASTNodeType, statement_block_fields: list[str]
25
25
  ) -> ASTNodeType:
26
26
  return ast_node.model_copy(update={field: [] for field in statement_block_fields})
@@ -69,7 +69,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
69
69
 
70
70
  @staticmethod
71
71
  def _validate_monomial_coefficient(
72
- coeff: Union[sympy.Expr, ParameterComplexType]
72
+ coeff: Union[sympy.Expr, ParameterComplexType],
73
73
  ) -> ParameterComplexType:
74
74
  if isinstance(coeff, str):
75
75
  validate_expression_str(coeff)
@@ -89,6 +89,21 @@ class DebugInfoCollection(BaseModel):
89
89
  return self.blackbox_data.get(debug_info.name)
90
90
 
91
91
 
92
+ def get_back_refs(
93
+ debug_info: FunctionDebugInfo, collected_debug_info: DebugInfoCollection
94
+ ) -> list[ConcreteQuantumStatement]:
95
+ back_refs: list[ConcreteQuantumStatement] = []
96
+ while (node := debug_info.node) is not None:
97
+ back_refs.insert(0, node)
98
+ if node.back_ref is None:
99
+ break
100
+ next_debug_info = collected_debug_info.get(node.back_ref)
101
+ if next_debug_info is None:
102
+ break
103
+ debug_info = next_debug_info
104
+ return back_refs
105
+
106
+
92
107
  def new_function_debug_info_by_node(
93
108
  node: ConcreteQuantumStatement,
94
109
  ) -> FunctionDebugInfo:
@@ -1,4 +1,5 @@
1
- from typing import Any, Final, Optional
1
+ import ast
2
+ from typing import Any, Final, Optional, cast
2
3
 
3
4
  import networkx as nx
4
5
  import pydantic
@@ -95,6 +96,9 @@ def get_arithmetic_params(
95
96
  machine_precision: int,
96
97
  enable_target: bool = False,
97
98
  ) -> Arithmetic:
99
+ expr_str, var_types = _substitute_quantum_subscripts(
100
+ expr_str, var_types, machine_precision
101
+ )
98
102
  return Arithmetic(
99
103
  expression=expr_str,
100
104
  definitions={
@@ -121,3 +125,94 @@ def compute_arithmetic_result_type(
121
125
  return register_info_to_quantum_type(
122
126
  arith_param.outputs[ARITHMETIC_EXPRESSION_RESULT_NAME]
123
127
  )
128
+
129
+
130
+ def aggregate_numeric_types(
131
+ numeric_types: list[QuantumNumeric],
132
+ ) -> RegisterArithmeticInfo:
133
+ if all(
134
+ numeric_type.size_in_bits == 1
135
+ and numeric_type.sign_value
136
+ and numeric_type.fraction_digits_value == 1
137
+ for numeric_type in numeric_types
138
+ ):
139
+ return RegisterArithmeticInfo(size=1, is_signed=True, fraction_places=1)
140
+ int_size = max(
141
+ numeric_type.size_in_bits
142
+ - int(numeric_type.sign_value)
143
+ - numeric_type.fraction_digits_value
144
+ for numeric_type in numeric_types
145
+ )
146
+ is_signed = any(numeric_type.sign_value for numeric_type in numeric_types)
147
+ frac_size = max(
148
+ numeric_type.fraction_digits_value for numeric_type in numeric_types
149
+ )
150
+ total_size = int_size + int(is_signed) + frac_size
151
+ return RegisterArithmeticInfo(
152
+ size=total_size, is_signed=is_signed, fraction_places=frac_size
153
+ )
154
+
155
+
156
+ class _QuantumSubscriptRemover(ast.NodeTransformer):
157
+ def __init__(self, machine_precision: int) -> None:
158
+ self._machine_precision = machine_precision
159
+ self.substitutions_types: dict[str, QuantumNumeric] = {}
160
+
161
+ def visit_Call(self, node: ast.Call) -> ast.expr:
162
+ if not isinstance(node.func, ast.Name) or node.func.id != "Piecewise":
163
+ return node
164
+ items = [
165
+ cast(float, cast(ast.Num, cast(ast.Tuple, arg).elts[0]).value)
166
+ for arg in node.args
167
+ ]
168
+ numeric_types = [
169
+ compute_arithmetic_result_type(str(num), {}, self._machine_precision)
170
+ for num in items
171
+ ]
172
+ unified_numeric_type = register_info_to_quantum_type(
173
+ aggregate_numeric_types(numeric_types)
174
+ )
175
+ substitution_var_name = f"__lut__{len(self.substitutions_types)}__"
176
+ self.substitutions_types[substitution_var_name] = unified_numeric_type
177
+ return ast.Name(id=substitution_var_name)
178
+
179
+
180
+ class _NameCollector(ast.NodeVisitor):
181
+ def __init__(self) -> None:
182
+ self.names: set[str] = set()
183
+
184
+ def visit_Name(self, node: ast.Name) -> None:
185
+ self.names.add(node.id)
186
+
187
+
188
+ def _substitute_quantum_subscripts(
189
+ expr_str: str, var_types: dict[str, QuantumType], machine_precision: int
190
+ ) -> tuple[str, dict[str, QuantumType]]:
191
+ """
192
+ Remove quantum lookup expressions ([1, 2, 3, 4][n]) from an arithmetic expression
193
+ for the purpose of calculating its numeric attributes.
194
+ Each quantum lookup expression is replaced by a numeric value with equivalent
195
+ numeric properties.
196
+
197
+ Args:
198
+ expr_str: arithmetic expression
199
+ var_types: quantum variable type mapping
200
+ machine_precision: global machine precision
201
+
202
+ Returns:
203
+ 1. the reduced expression
204
+ 2. updated type mapping
205
+ """
206
+ expr_ast = ast.parse(expr_str)
207
+ subscript_remover = _QuantumSubscriptRemover(machine_precision)
208
+ expr_ast = subscript_remover.visit(expr_ast)
209
+ var_types_substituted = var_types | subscript_remover.substitutions_types
210
+ expr_str_substituted = ast.unparse(expr_ast)
211
+ names_collector = _NameCollector()
212
+ names_collector.visit(ast.parse(expr_str_substituted))
213
+ var_types_substituted = {
214
+ var_name: var_type
215
+ for var_name, var_type in var_types_substituted.items()
216
+ if var_name in names_collector.names
217
+ }
218
+ return expr_str_substituted, var_types_substituted
@@ -91,7 +91,7 @@ class ExpressionVisitor(ExpressionValidator):
91
91
  class InDegreeLimiter:
92
92
  @staticmethod
93
93
  def _sort_in_edges(
94
- in_edges: Collection[tuple[Node, str]]
94
+ in_edges: Collection[tuple[Node, str]],
95
95
  ) -> list[tuple[Node, str]]:
96
96
  return sorted(
97
97
  in_edges,
@@ -11,6 +11,7 @@ from classiq.interface.generator.register_role import RegisterRole
11
11
  from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
12
12
  ExecutionData,
13
13
  )
14
+ from classiq.interface.model.statement_block import StatementBlock
14
15
 
15
16
  from classiq.model_expansions.capturing.mangling_utils import (
16
17
  demangle_capture_name,
@@ -22,7 +23,7 @@ _logger = logging.getLogger(__name__)
22
23
  ParameterName = str
23
24
  IOQubitMapping: TypeAlias = dict[str, tuple[int, ...]]
24
25
 
25
- CLASSIQ_HIERARCHY_SEPARATOR: Literal["."] = "."
26
+ CLASSIQ_HIERARCHY_SEPARATOR: Literal["__"] = "__"
26
27
 
27
28
  VISUALIZATION_HIDE_LIST = [
28
29
  "apply_to_all",
@@ -136,6 +137,7 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
136
137
  parameters: list[OperationParameter] = list()
137
138
  port_to_passed_variable_map: dict[str, str] = pydantic.Field(default={})
138
139
  release_by_inverse: bool = pydantic.Field(default=False)
140
+ back_refs: StatementBlock = pydantic.Field(default_factory=list)
139
141
 
140
142
  model_config = ConfigDict(extra="allow")
141
143
  # Temporary field to store the override debug info for parallel old/new visualization
@@ -167,7 +169,7 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
167
169
 
168
170
  @staticmethod
169
171
  def create_parameters_from_dict(
170
- parameters: dict[str, str]
172
+ parameters: dict[str, str],
171
173
  ) -> list[OperationParameter]:
172
174
  return [
173
175
  OperationParameter(label=key, value=value)
@@ -1,9 +1,11 @@
1
1
  import uuid
2
2
  from datetime import datetime, timezone
3
3
  from pathlib import Path
4
- from typing import Optional, Union
4
+ from typing import Any, Optional, Union
5
5
 
6
6
  import pydantic
7
+ from pydantic import model_validator
8
+ from pydantic_core.core_schema import ValidationInfo
7
9
  from typing_extensions import TypeAlias
8
10
 
9
11
  from classiq.interface.exceptions import (
@@ -36,6 +38,8 @@ from classiq.interface.ide.visual_model import CircuitMetrics
36
38
  RegisterName: TypeAlias = str
37
39
  InitialConditions: TypeAlias = dict[RegisterName, int]
38
40
 
41
+ OMIT_DEBUG_INFO_FLAG = "omit_debug_info"
42
+
39
43
 
40
44
  class TranspiledCircuitData(CircuitCodeInterface):
41
45
  depth: int
@@ -71,6 +75,19 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
71
75
  program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
72
76
  execution_primitives_input: Optional[PrimitivesInput] = pydantic.Field(default=None)
73
77
 
78
+ @model_validator(mode="before")
79
+ @classmethod
80
+ def remove_debug_info(
81
+ cls, data: dict[str, Any], info: ValidationInfo
82
+ ) -> dict[str, Any]:
83
+ if (
84
+ isinstance(data, dict)
85
+ and info.context is not None
86
+ and info.context.get(OMIT_DEBUG_INFO_FLAG, False)
87
+ ):
88
+ data.pop("debug_info", None)
89
+ return data
90
+
74
91
  def _hardware_agnostic_program_code(self) -> CodeAndSyntax:
75
92
  circuit_code = self.program_circuit.get_code_by_priority()
76
93
  if circuit_code is not None:
@@ -1,5 +1,6 @@
1
1
  from collections import Counter
2
2
  from enum import Enum, EnumMeta, IntEnum
3
+ from typing import Any, Callable
3
4
 
4
5
  import pydantic
5
6
 
@@ -7,6 +8,33 @@ from classiq.interface.ast_node import HashableASTNode
7
8
  from classiq.interface.exceptions import ClassiqValueError
8
9
 
9
10
 
11
+ def rebuild_dynamic_enum(name: str, members: dict[str, int]) -> type[IntEnum]:
12
+ """
13
+ Rebuilds the dynamic enum from its name and members.
14
+ Returns a new enum type.
15
+ """
16
+ new_enum = IntEnum(name, members) # type: ignore[misc]
17
+ setattr(new_enum, "__members_data__", members) # noqa: B010
18
+ setattr(new_enum, "__reduce_ex__", dynamic_enum_reduce_ex) # noqa: B010
19
+ return new_enum
20
+
21
+
22
+ def dynamic_enum_reduce_ex(
23
+ obj: Any, protocol: int
24
+ ) -> tuple[Callable[..., type[IntEnum]], tuple[str, dict[str, int]]]:
25
+ """
26
+ Custom __reduce_ex__ for dynamic enums.
27
+ This function will be used when pickling an enum type or one of its members.
28
+ """
29
+ # Get the enum type and its member data.
30
+ enum_type = type(obj)
31
+ members = getattr(enum_type, "__members_data__", None)
32
+ if members is None:
33
+ raise ValueError("Dynamic enum is missing __members_data__ attribute")
34
+ # Return the callable and arguments needed to rebuild the enum type.
35
+ return rebuild_dynamic_enum, (enum_type.__name__, members)
36
+
37
+
10
38
  class EnumDeclaration(HashableASTNode):
11
39
  name: str
12
40
 
@@ -39,8 +67,11 @@ class EnumDeclaration(HashableASTNode):
39
67
 
40
68
  return members
41
69
 
42
- def create_enum(self) -> IntEnum:
43
- return IntEnum(self.name, self.members)
70
+ def create_enum(self) -> type[IntEnum]:
71
+ dynamic_enum = IntEnum(self.name, self.members) # type: ignore[misc]
72
+ setattr(dynamic_enum, "__members_data__", self.members) # noqa: B010
73
+ setattr(dynamic_enum, "__reduce_ex__", dynamic_enum_reduce_ex) # noqa: B010
74
+ return dynamic_enum
44
75
 
45
76
 
46
77
  def declaration_from_enum(enum_type: EnumMeta) -> EnumDeclaration:
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Literal
2
2
 
3
- from classiq.interface.ast_node import ASTNodeType, without_statement_blocks
3
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
4
4
  from classiq.interface.generator.expressions.expression import Expression
5
5
  from classiq.interface.model.quantum_statement import QuantumOperation
6
6
 
@@ -16,4 +16,4 @@ class ClassicalIf(QuantumOperation):
16
16
  else_: "StatementBlock"
17
17
 
18
18
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
19
- return without_statement_blocks(self, ["then", "else_"])
19
+ return reset_lists(self, ["then", "else_"])
@@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Literal, Optional
2
2
 
3
3
  import pydantic
4
4
 
5
- from classiq.interface.ast_node import ASTNodeType, without_statement_blocks
5
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
6
6
  from classiq.interface.generator.arith.arithmetic import compute_arithmetic_result_type
7
7
  from classiq.interface.model.quantum_expressions.quantum_expression import (
8
8
  QuantumExpressionOperation,
@@ -46,4 +46,4 @@ class Control(QuantumExpressionOperation):
46
46
  )
47
47
 
48
48
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
49
- return without_statement_blocks(self, ["body", "else_block"])
49
+ return reset_lists(self, ["body", "else_block"])
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Literal
2
2
 
3
- from classiq.interface.ast_node import ASTNodeType, without_statement_blocks
3
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
4
4
  from classiq.interface.model.quantum_statement import QuantumOperation
5
5
 
6
6
  if TYPE_CHECKING:
@@ -13,4 +13,4 @@ class Invert(QuantumOperation):
13
13
  body: "StatementBlock"
14
14
 
15
15
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
16
- return without_statement_blocks(self, ["body"])
16
+ return reset_lists(self, ["body"])
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Literal
2
2
 
3
- from classiq.interface.ast_node import ASTNodeType, without_statement_blocks
3
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
4
4
  from classiq.interface.generator.expressions.expression import Expression
5
5
  from classiq.interface.model.quantum_statement import QuantumOperation
6
6
 
@@ -15,4 +15,4 @@ class Power(QuantumOperation):
15
15
  body: "StatementBlock"
16
16
 
17
17
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
18
- return without_statement_blocks(self, ["body"])
18
+ return reset_lists(self, ["body"])
@@ -7,6 +7,7 @@ from typing import (
7
7
 
8
8
  import pydantic
9
9
 
10
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
10
11
  from classiq.interface.exceptions import ClassiqError, ClassiqValueError
11
12
  from classiq.interface.generator.expressions.expression import Expression
12
13
  from classiq.interface.generator.functions.port_declaration import (
@@ -45,6 +46,9 @@ class QuantumFunctionCall(QuantumOperation):
45
46
  default=None
46
47
  )
47
48
 
49
+ def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
50
+ return reset_lists(self, ["positional_args"])
51
+
48
52
  @property
49
53
  def func_decl(self) -> QuantumFunctionDeclaration:
50
54
  if self._func_decl is None:
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Literal
2
2
 
3
- from classiq.interface.ast_node import ASTNodeType, without_statement_blocks
3
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
4
4
  from classiq.interface.generator.expressions.expression import Expression
5
5
  from classiq.interface.model.quantum_statement import QuantumOperation
6
6
 
@@ -16,4 +16,4 @@ class Repeat(QuantumOperation):
16
16
  body: "StatementBlock"
17
17
 
18
18
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
19
- return without_statement_blocks(self, ["body"])
19
+ return reset_lists(self, ["body"])
@@ -27,8 +27,8 @@ from classiq.interface.model.within_apply_operation import WithinApply
27
27
 
28
28
  ConcreteQuantumStatement = Annotated[
29
29
  Union[
30
- Allocate,
31
30
  QuantumFunctionCall,
31
+ Allocate,
32
32
  ArithmeticOperation,
33
33
  AmplitudeLoadingOperation,
34
34
  VariableDeclarationStatement,
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Literal
2
2
 
3
- from classiq.interface.ast_node import ASTNodeType, without_statement_blocks
3
+ from classiq.interface.ast_node import ASTNodeType, reset_lists
4
4
  from classiq.interface.model.quantum_statement import QuantumOperation
5
5
 
6
6
  if TYPE_CHECKING:
@@ -14,4 +14,4 @@ class WithinApply(QuantumOperation):
14
14
  action: "StatementBlock"
15
15
 
16
16
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
17
- return without_statement_blocks(self, ["compute", "action"])
17
+ return reset_lists(self, ["compute", "action"])