classiq 0.70.0__py3-none-any.whl → 0.72.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.
- classiq/__init__.py +0 -6
- classiq/_internals/client.py +11 -1
- classiq/applications/chemistry/chemistry_model_constructor.py +18 -16
- classiq/applications/combinatorial_helpers/optimization_model.py +9 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +6 -1
- classiq/applications/finance/__init__.py +0 -3
- classiq/applications/qsvm/__init__.py +0 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +22 -0
- classiq/interface/backend/quantum_backend_providers.py +2 -0
- classiq/interface/debug_info/debug_info.py +4 -0
- classiq/interface/generator/expressions/expression_constants.py +0 -3
- classiq/interface/generator/expressions/expression_types.py +8 -3
- classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +135 -0
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -0
- classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +5 -1
- classiq/interface/generator/expressions/proxies/classical/utils.py +34 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +1 -0
- classiq/interface/generator/functions/classical_type.py +1 -1
- classiq/interface/generator/functions/type_name.py +16 -0
- classiq/interface/generator/functions/type_qualifier.py +7 -0
- classiq/interface/generator/generated_circuit_data.py +14 -1
- classiq/interface/generator/hardware/hardware_data.py +3 -1
- classiq/interface/generator/quantum_function_call.py +8 -1
- classiq/interface/generator/synthesis_execution_parameter.py +1 -0
- classiq/interface/generator/transpiler_basis_gates.py +3 -1
- classiq/interface/generator/types/compilation_metadata.py +1 -0
- classiq/interface/hardware.py +1 -0
- classiq/interface/ide/visual_model.py +1 -0
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/allocate.py +7 -0
- classiq/interface/model/block.py +12 -0
- classiq/interface/model/classical_if.py +4 -0
- classiq/interface/model/handle_binding.py +21 -0
- classiq/interface/model/inplace_binary_operation.py +4 -0
- classiq/interface/model/model.py +3 -1
- classiq/interface/model/phase_operation.py +4 -0
- classiq/interface/model/port_declaration.py +3 -0
- classiq/interface/model/power.py +4 -0
- classiq/interface/model/quantum_expressions/quantum_expression.py +4 -0
- classiq/interface/model/quantum_function_call.py +4 -0
- classiq/interface/model/quantum_function_declaration.py +1 -1
- classiq/interface/model/quantum_statement.py +5 -0
- classiq/interface/model/quantum_type.py +22 -0
- classiq/interface/model/repeat.py +4 -0
- classiq/interface/model/statement_block.py +3 -0
- classiq/interface/model/variable_declaration_statement.py +5 -0
- classiq/interface/server/routes.py +0 -2
- classiq/model_expansions/atomic_expression_functions_defs.py +35 -13
- classiq/model_expansions/capturing/captured_vars.py +156 -34
- classiq/model_expansions/closure.py +0 -9
- classiq/model_expansions/evaluators/classical_type_inference.py +70 -0
- classiq/model_expansions/evaluators/parameter_types.py +20 -10
- classiq/model_expansions/expression_evaluator.py +0 -11
- classiq/model_expansions/function_builder.py +2 -8
- classiq/model_expansions/generative_functions.py +7 -30
- classiq/model_expansions/interpreters/base_interpreter.py +7 -8
- classiq/model_expansions/interpreters/generative_interpreter.py +33 -5
- classiq/model_expansions/quantum_operations/__init__.py +0 -2
- classiq/model_expansions/quantum_operations/block_evaluator.py +16 -2
- classiq/model_expansions/quantum_operations/call_emitter.py +49 -6
- classiq/model_expansions/quantum_operations/emitter.py +64 -6
- classiq/model_expansions/quantum_operations/expression_evaluator.py +4 -0
- classiq/model_expansions/quantum_operations/handle_evaluator.py +1 -1
- classiq/model_expansions/quantum_operations/quantum_function_call.py +49 -0
- classiq/model_expansions/quantum_operations/repeat_block_evaluator.py +34 -0
- classiq/model_expansions/scope.py +33 -21
- classiq/model_expansions/scope_initialization.py +28 -32
- classiq/model_expansions/transformers/model_renamer.py +69 -63
- classiq/model_expansions/utils/sympy_utils.py +24 -0
- classiq/model_expansions/visitors/variable_references.py +1 -0
- classiq/qmod/__init__.py +3 -1
- classiq/qmod/builtins/functions/__init__.py +8 -0
- classiq/qmod/builtins/functions/allocation.py +36 -0
- classiq/qmod/builtins/functions/arithmetic.py +10 -5
- classiq/qmod/builtins/functions/mid_circuit_measurement.py +3 -0
- classiq/qmod/builtins/operations.py +2 -2
- classiq/qmod/declaration_inferrer.py +52 -24
- classiq/qmod/model_state_container.py +9 -0
- classiq/qmod/native/pretty_printer.py +25 -3
- classiq/qmod/pretty_print/pretty_printer.py +31 -14
- classiq/qmod/python_classical_type.py +12 -1
- classiq/qmod/qfunc.py +33 -8
- classiq/qmod/qmod_variable.py +188 -147
- classiq/qmod/quantum_function.py +3 -4
- classiq/qmod/semantics/validation/type_hints.py +19 -10
- classiq/qmod/symbolic.py +16 -3
- {classiq-0.70.0.dist-info → classiq-0.72.0.dist-info}/METADATA +1 -1
- {classiq-0.70.0.dist-info → classiq-0.72.0.dist-info}/RECORD +90 -91
- classiq/applications/finance/finance_model_constructor.py +0 -137
- classiq/applications/grover/__init__.py +0 -9
- classiq/applications/grover/grover_model_constructor.py +0 -167
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +0 -22
- classiq/applications/qsvm/qsvm_model_constructor.py +0 -131
- classiq/model_expansions/quantum_operations/classicalif.py +0 -57
- classiq/model_expansions/quantum_operations/repeat.py +0 -62
- {classiq-0.70.0.dist-info → classiq-0.72.0.dist-info}/WHEEL +0 -0
@@ -63,7 +63,9 @@ THREE_QUBIT_GATES: BasisGates = frozenset(("ccx", "cswap"))
|
|
63
63
|
DEFAULT_BASIS_GATES: BasisGates = SINGLE_QUBIT_GATES | BASIC_TWO_QUBIT_GATES
|
64
64
|
ALL_GATES: BasisGates = SINGLE_QUBIT_GATES | TWO_QUBIT_GATES | THREE_QUBIT_GATES
|
65
65
|
|
66
|
-
ROUTING_TWO_QUBIT_BASIS_GATES: BasisGates = frozenset(
|
66
|
+
ROUTING_TWO_QUBIT_BASIS_GATES: BasisGates = frozenset(
|
67
|
+
("cx", "ecr", "rzx", "ryy", "rxx", "rzz", "cy", "cz", "cp", "swap")
|
68
|
+
)
|
67
69
|
DEFAULT_ROUTING_BASIS_GATES: BasisGates = SINGLE_QUBIT_GATES | frozenset(("cx",))
|
68
70
|
# The Enum names are capitalized per recommendation in https://docs.python.org/3/library/enum.html#module-enum
|
69
71
|
# The Enum values are lowered to keep consistency
|
classiq/interface/hardware.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
INTERFACE_VERSION = "
|
1
|
+
INTERFACE_VERSION = "9"
|
@@ -14,3 +14,10 @@ class Allocate(QuantumOperation):
|
|
14
14
|
@property
|
15
15
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
16
16
|
return {"out": self.target}
|
17
|
+
|
18
|
+
@property
|
19
|
+
def expressions(self) -> list[Expression]:
|
20
|
+
exprs = []
|
21
|
+
if self.size is not None:
|
22
|
+
exprs.append(self.size)
|
23
|
+
return exprs
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Literal
|
2
|
+
|
3
|
+
from classiq.interface.model.quantum_statement import QuantumOperation
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from classiq.interface.model.statement_block import StatementBlock
|
7
|
+
|
8
|
+
|
9
|
+
class Block(QuantumOperation):
|
10
|
+
kind: Literal["Block"]
|
11
|
+
|
12
|
+
statements: "StatementBlock"
|
@@ -64,6 +64,9 @@ class HandleBinding(ASTNode):
|
|
64
64
|
def __contains__(self, other_handle: "HandleBinding") -> bool:
|
65
65
|
return self.collapse() in other_handle.collapse().prefixes()
|
66
66
|
|
67
|
+
def is_constant(self) -> bool:
|
68
|
+
return True
|
69
|
+
|
67
70
|
|
68
71
|
class NestedHandleBinding(HandleBinding):
|
69
72
|
base_handle: "ConcreteHandleBinding"
|
@@ -105,6 +108,9 @@ class NestedHandleBinding(HandleBinding):
|
|
105
108
|
)
|
106
109
|
return self
|
107
110
|
|
111
|
+
def is_constant(self) -> bool:
|
112
|
+
return self.base_handle.is_constant()
|
113
|
+
|
108
114
|
|
109
115
|
class SubscriptHandleBinding(NestedHandleBinding):
|
110
116
|
index: Expression
|
@@ -178,6 +184,13 @@ class SubscriptHandleBinding(NestedHandleBinding):
|
|
178
184
|
)
|
179
185
|
return super().replace_prefix(prefix, replacement)
|
180
186
|
|
187
|
+
def is_constant(self) -> bool:
|
188
|
+
return (
|
189
|
+
super().is_constant()
|
190
|
+
and self.index.is_evaluated()
|
191
|
+
and self.index.is_constant()
|
192
|
+
)
|
193
|
+
|
181
194
|
|
182
195
|
class SlicedHandleBinding(NestedHandleBinding):
|
183
196
|
start: Expression
|
@@ -284,6 +297,14 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
284
297
|
def _is_evaluated(self) -> bool:
|
285
298
|
return self.start.is_evaluated() and self.end.is_evaluated()
|
286
299
|
|
300
|
+
def is_constant(self) -> bool:
|
301
|
+
return (
|
302
|
+
super().is_constant()
|
303
|
+
and self._is_evaluated()
|
304
|
+
and self.start.is_constant()
|
305
|
+
and self.end.is_constant()
|
306
|
+
)
|
307
|
+
|
287
308
|
|
288
309
|
class FieldHandleBinding(NestedHandleBinding):
|
289
310
|
field: str
|
classiq/interface/model/model.py
CHANGED
@@ -103,7 +103,9 @@ class Model(VersionedModel, ASTNode):
|
|
103
103
|
functions_compilation_metadata: dict[str, CompilationMetadata] = pydantic.Field(
|
104
104
|
default_factory=dict
|
105
105
|
)
|
106
|
-
execution_parameters: Optional[dict[str, ConcreteClassicalType]] =
|
106
|
+
execution_parameters: Optional[dict[str, ConcreteClassicalType]] = pydantic.Field(
|
107
|
+
default=None, exclude=True
|
108
|
+
)
|
107
109
|
|
108
110
|
@property
|
109
111
|
def main_func(self) -> NativeFunctionDefinition:
|
@@ -9,3 +9,7 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
9
9
|
class PhaseOperation(QuantumExpressionOperation):
|
10
10
|
kind: Literal["PhaseOperation"]
|
11
11
|
theta: Expression
|
12
|
+
|
13
|
+
@property
|
14
|
+
def expressions(self) -> list[Expression]:
|
15
|
+
return super().expressions + [self.theta]
|
@@ -8,6 +8,7 @@ from classiq.interface.generator.functions.concrete_types import ConcreteQuantum
|
|
8
8
|
from classiq.interface.generator.functions.port_declaration import (
|
9
9
|
PortDeclarationDirection,
|
10
10
|
)
|
11
|
+
from classiq.interface.generator.functions.type_qualifier import TypeQualifier
|
11
12
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
12
13
|
from classiq.interface.model.parameter import Parameter
|
13
14
|
|
@@ -15,6 +16,8 @@ from classiq.interface.model.parameter import Parameter
|
|
15
16
|
class AnonPortDeclaration(Parameter):
|
16
17
|
quantum_type: ConcreteQuantumType
|
17
18
|
direction: PortDeclarationDirection
|
19
|
+
# TODO remove default after BWC-breaking version
|
20
|
+
type_qualifier: TypeQualifier = pydantic.Field(default=TypeQualifier.Quantum)
|
18
21
|
kind: Literal["PortDeclaration"]
|
19
22
|
|
20
23
|
@pydantic.model_validator(mode="before")
|
classiq/interface/model/power.py
CHANGED
@@ -46,6 +46,10 @@ class QuantumExpressionOperation(QuantumOperation):
|
|
46
46
|
def wiring_inouts(self) -> Mapping[str, ConcreteHandleBinding]:
|
47
47
|
return nameables_to_dict(self.var_handles)
|
48
48
|
|
49
|
+
@property
|
50
|
+
def expressions(self) -> list[Expression]:
|
51
|
+
return [self.expression]
|
52
|
+
|
49
53
|
|
50
54
|
class QuantumAssignmentOperation(QuantumExpressionOperation):
|
51
55
|
result_var: ConcreteHandleBinding = pydantic.Field(
|
@@ -170,6 +170,10 @@ class QuantumFunctionCall(QuantumOperation):
|
|
170
170
|
param for param in self.positional_args if isinstance(param, HandleBinding)
|
171
171
|
]
|
172
172
|
|
173
|
+
@property
|
174
|
+
def expressions(self) -> list[Expression]:
|
175
|
+
return [arg for arg in self.positional_args if isinstance(arg, Expression)]
|
176
|
+
|
173
177
|
def _get_handles_by_direction(
|
174
178
|
self, direction: PortDeclarationDirection
|
175
179
|
) -> list[tuple[int, AnonPortDeclaration, HandleBinding]]:
|
@@ -8,6 +8,7 @@ from pydantic import ConfigDict
|
|
8
8
|
from typing_extensions import Self
|
9
9
|
|
10
10
|
from classiq.interface.ast_node import ASTNode
|
11
|
+
from classiq.interface.generator.expressions.expression import Expression
|
11
12
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
12
13
|
from classiq.interface.model.handle_binding import (
|
13
14
|
ConcreteHandleBinding,
|
@@ -39,6 +40,10 @@ class QuantumStatement(ASTNode):
|
|
39
40
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
40
41
|
return values_with_discriminator(values, "kind", cls.__name__)
|
41
42
|
|
43
|
+
@property
|
44
|
+
def expressions(self) -> list[Expression]:
|
45
|
+
return []
|
46
|
+
|
42
47
|
|
43
48
|
@dataclass
|
44
49
|
class HandleMetadata:
|
@@ -71,6 +71,10 @@ class QuantumType(HashableASTNode):
|
|
71
71
|
def is_evaluated(self) -> bool:
|
72
72
|
raise NotImplementedError
|
73
73
|
|
74
|
+
@property
|
75
|
+
def expressions(self) -> list[Expression]:
|
76
|
+
return []
|
77
|
+
|
74
78
|
|
75
79
|
class QuantumScalar(QuantumType):
|
76
80
|
def get_proxy(self, handle: "HandleBinding") -> QmodQScalarProxy:
|
@@ -174,6 +178,13 @@ class QuantumBitvector(QuantumType):
|
|
174
178
|
and self.element_type.is_evaluated
|
175
179
|
)
|
176
180
|
|
181
|
+
@property
|
182
|
+
def expressions(self) -> list[Expression]:
|
183
|
+
exprs = self.element_type.expressions
|
184
|
+
if self.length is not None:
|
185
|
+
exprs.append(self.length)
|
186
|
+
return exprs
|
187
|
+
|
177
188
|
|
178
189
|
class QuantumNumeric(QuantumScalar):
|
179
190
|
kind: Literal["qnum"]
|
@@ -265,6 +276,17 @@ class QuantumNumeric(QuantumScalar):
|
|
265
276
|
self.fraction_digits is not None and not self.fraction_digits.is_evaluated()
|
266
277
|
)
|
267
278
|
|
279
|
+
@property
|
280
|
+
def expressions(self) -> list[Expression]:
|
281
|
+
exprs = []
|
282
|
+
if self.size is not None:
|
283
|
+
exprs.append(self.size)
|
284
|
+
if self.is_signed is not None:
|
285
|
+
exprs.append(self.is_signed)
|
286
|
+
if self.fraction_digits is not None:
|
287
|
+
exprs.append(self.fraction_digits)
|
288
|
+
return exprs
|
289
|
+
|
268
290
|
|
269
291
|
class RegisterQuantumType(BaseModel):
|
270
292
|
quantum_types: "ConcreteQuantumType"
|
@@ -4,6 +4,7 @@ from pydantic import Field
|
|
4
4
|
|
5
5
|
from classiq.interface.model.allocate import Allocate
|
6
6
|
from classiq.interface.model.bind_operation import BindOperation
|
7
|
+
from classiq.interface.model.block import Block
|
7
8
|
from classiq.interface.model.classical_if import ClassicalIf
|
8
9
|
from classiq.interface.model.control import Control
|
9
10
|
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
@@ -41,12 +42,14 @@ ConcreteQuantumStatement = Annotated[
|
|
41
42
|
Control,
|
42
43
|
WithinApply,
|
43
44
|
PhaseOperation,
|
45
|
+
Block,
|
44
46
|
],
|
45
47
|
Field(..., discriminator="kind"),
|
46
48
|
]
|
47
49
|
|
48
50
|
StatementBlock = list[ConcreteQuantumStatement]
|
49
51
|
|
52
|
+
Block.model_rebuild()
|
50
53
|
Control.model_rebuild()
|
51
54
|
QuantumLambdaFunction.model_rebuild()
|
52
55
|
Repeat.model_rebuild()
|
@@ -1,5 +1,6 @@
|
|
1
1
|
from typing import Literal
|
2
2
|
|
3
|
+
from classiq.interface.generator.expressions.expression import Expression
|
3
4
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
4
5
|
from classiq.interface.model.quantum_variable_declaration import (
|
5
6
|
QuantumVariableDeclaration,
|
@@ -8,3 +9,7 @@ from classiq.interface.model.quantum_variable_declaration import (
|
|
8
9
|
|
9
10
|
class VariableDeclarationStatement(QuantumStatement, QuantumVariableDeclaration):
|
10
11
|
kind: Literal["VariableDeclarationStatement"]
|
12
|
+
|
13
|
+
@property
|
14
|
+
def expressions(self) -> list[Expression]:
|
15
|
+
return self.quantum_type.expressions
|
@@ -43,8 +43,6 @@ TASKS_VISUAL_MODEL_SUFFIX = TASKS_SUFFIX + "/visual_model"
|
|
43
43
|
TASKS_SOLVE_SUFFIX = "/tasks/solve"
|
44
44
|
|
45
45
|
CHEMISTRY_QMOD_PATH = "/generate_model/chemistry/qmod"
|
46
|
-
GROVER_QMOD_PATH = "/generate_model/grover/qmod"
|
47
|
-
FINANCE_QMOD_PATH = "/generate_model/finance/qmod"
|
48
46
|
|
49
47
|
|
50
48
|
TASK_TRAIN_SUFFIX = TASKS_SUFFIX + "/train"
|
@@ -1,8 +1,8 @@
|
|
1
1
|
from collections.abc import Mapping
|
2
2
|
from enum import Enum
|
3
|
-
from typing import Any, Callable, Union
|
3
|
+
from typing import Any, Callable, Union, get_args
|
4
4
|
|
5
|
-
from sympy import Eq, Expr,
|
5
|
+
from sympy import Eq, Expr, Piecewise, Symbol
|
6
6
|
|
7
7
|
from classiq.interface.exceptions import (
|
8
8
|
ClassiqExpansionError,
|
@@ -12,6 +12,9 @@ from classiq.interface.generator.expressions.expression_types import (
|
|
12
12
|
ExpressionValue,
|
13
13
|
QmodStructInstance,
|
14
14
|
)
|
15
|
+
from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
|
16
|
+
AnyClassicalValue,
|
17
|
+
)
|
15
18
|
from classiq.interface.generator.expressions.proxies.quantum.qmod_qscalar_proxy import (
|
16
19
|
QmodQNumProxy,
|
17
20
|
)
|
@@ -54,6 +57,10 @@ from classiq.model_expansions.sympy_conversion.expression_to_sympy import (
|
|
54
57
|
from classiq.model_expansions.sympy_conversion.sympy_to_python import (
|
55
58
|
sympy_to_python,
|
56
59
|
)
|
60
|
+
from classiq.model_expansions.utils.sympy_utils import (
|
61
|
+
is_constant_subscript,
|
62
|
+
unwrap_sympy_numeric,
|
63
|
+
)
|
57
64
|
from classiq.qmod.model_state_container import QMODULE
|
58
65
|
|
59
66
|
|
@@ -151,9 +158,13 @@ def struct_literal(struct_type_symbol: Symbol, **kwargs: Any) -> QmodStructInsta
|
|
151
158
|
|
152
159
|
|
153
160
|
def get_field(
|
154
|
-
proxy: Union[
|
161
|
+
proxy: Union[
|
162
|
+
QmodSizedProxy, QmodStructInstance, QmodQStructProxy, list, AnyClassicalValue
|
163
|
+
],
|
155
164
|
field: str,
|
156
165
|
) -> ExpressionValue:
|
166
|
+
if isinstance(proxy, AnyClassicalValue):
|
167
|
+
return AnyClassicalValue(f"({proxy}).{field}")
|
157
168
|
if isinstance(proxy, type) and issubclass(proxy, Enum):
|
158
169
|
return getattr(proxy, field)
|
159
170
|
if isinstance(proxy, Symbol) and not isinstance(proxy, QmodSizedProxy):
|
@@ -189,20 +200,25 @@ def get_type(struct_type: Symbol) -> TypeProxy:
|
|
189
200
|
return TypeProxy(QMODULE.type_decls[struct_type.name])
|
190
201
|
|
191
202
|
|
192
|
-
def _unwrap_sympy_numeric(n: Any) -> Any:
|
193
|
-
if not isinstance(n, Number) or not n.is_constant():
|
194
|
-
return n
|
195
|
-
if n.is_Integer:
|
196
|
-
return int(n)
|
197
|
-
return float(n)
|
198
|
-
|
199
|
-
|
200
203
|
def do_div(lhs: Any, rhs: Any) -> Any:
|
201
|
-
lhs =
|
202
|
-
rhs =
|
204
|
+
lhs = unwrap_sympy_numeric(lhs)
|
205
|
+
rhs = unwrap_sympy_numeric(rhs)
|
203
206
|
return lhs / rhs
|
204
207
|
|
205
208
|
|
209
|
+
_EXPRESSION_TYPES = get_args(ExpressionValue)
|
210
|
+
|
211
|
+
|
212
|
+
def _is_qmod_value(val: Any) -> bool:
|
213
|
+
if not isinstance(val, slice):
|
214
|
+
return isinstance(val, _EXPRESSION_TYPES)
|
215
|
+
if val.start is not None and not isinstance(val.start, _EXPRESSION_TYPES):
|
216
|
+
return False
|
217
|
+
if val.stop is not None and not isinstance(val.stop, _EXPRESSION_TYPES):
|
218
|
+
return False
|
219
|
+
return val.step is None or isinstance(val.step, _EXPRESSION_TYPES)
|
220
|
+
|
221
|
+
|
206
222
|
def do_subscript(value: Any, index: Any) -> Any:
|
207
223
|
if not isinstance(value, list) or not isinstance(index, QmodQNumProxy):
|
208
224
|
if isinstance(index, (QmodSizedProxy, QmodStructInstance)):
|
@@ -214,6 +230,12 @@ def do_subscript(value: Any, index: Any) -> Any:
|
|
214
230
|
f"\t2. `l[n]`, where `l` is a list of classical real numbers and `n` "
|
215
231
|
f"is a classical or quantum integer."
|
216
232
|
)
|
233
|
+
if (
|
234
|
+
isinstance(value, list)
|
235
|
+
and not is_constant_subscript(index)
|
236
|
+
and _is_qmod_value(index)
|
237
|
+
):
|
238
|
+
return AnyClassicalValue(str(value))[index]
|
217
239
|
return value[index]
|
218
240
|
if index.is_signed or index.fraction_digits > 0:
|
219
241
|
raise ClassiqExpansionError(
|