classiq 0.63.1__py3-none-any.whl → 0.64.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/analyzer/url_utils.py +2 -3
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/result.py +1 -2
- classiq/interface/executor/result.py +6 -3
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/handle_binding.py +11 -3
- classiq/interface/server/routes.py +4 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +6 -6
- classiq/model_expansions/capturing/captured_vars.py +27 -10
- classiq/model_expansions/evaluators/arg_type_match.py +4 -7
- classiq/model_expansions/evaluators/quantum_type_utils.py +15 -8
- classiq/model_expansions/expression_evaluator.py +8 -2
- classiq/model_expansions/generative_functions.py +3 -3
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/{interpreter.py → interpreters/base_interpreter.py} +26 -137
- classiq/model_expansions/interpreters/generative_interpreter.py +108 -0
- classiq/model_expansions/model_tables.py +1 -92
- classiq/model_expansions/quantum_operations/__init__.py +0 -10
- classiq/model_expansions/quantum_operations/call_emitter.py +3 -3
- classiq/model_expansions/quantum_operations/emitter.py +2 -2
- classiq/model_expansions/quantum_operations/quantum_function_call.py +2 -2
- classiq/model_expansions/quantum_operations/shallow_emitter.py +2 -2
- classiq/model_expansions/scope_initialization.py +8 -0
- classiq/qmod/declaration_inferrer.py +0 -3
- classiq/qmod/generative.py +4 -4
- classiq/qmod/qfunc.py +4 -2
- classiq/qmod/qmod_variable.py +17 -10
- classiq/qmod/quantum_function.py +6 -4
- classiq/qmod/utilities.py +7 -1
- {classiq-0.63.1.dist-info → classiq-0.64.0.dist-info}/METADATA +1 -1
- {classiq-0.63.1.dist-info → classiq-0.64.0.dist-info}/RECORD +33 -39
- classiq/interface/helpers/dotdict.py +0 -18
- classiq/model_expansions/quantum_operations/control.py +0 -290
- classiq/model_expansions/quantum_operations/expression_operation.py +0 -103
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +0 -535
- classiq/model_expansions/quantum_operations/invert.py +0 -36
- classiq/model_expansions/quantum_operations/phase.py +0 -187
- classiq/model_expansions/quantum_operations/power.py +0 -71
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +0 -230
- classiq/model_expansions/quantum_operations/within_apply.py +0 -25
- {classiq-0.63.1.dist-info → classiq-0.64.0.dist-info}/WHEEL +0 -0
classiq/analyzer/url_utils.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import urllib
|
2
2
|
from urllib.parse import urljoin
|
3
|
-
from uuid import UUID
|
4
3
|
|
5
4
|
from classiq.interface.server import routes
|
6
5
|
|
@@ -21,7 +20,7 @@ def versioned_url_params(circuit_version: str) -> str:
|
|
21
20
|
)
|
22
21
|
|
23
22
|
|
24
|
-
def circuit_page_uri(circuit_id:
|
25
|
-
url = urljoin(f"{routes.ANALYZER_CIRCUIT_PAGE}/",
|
23
|
+
def circuit_page_uri(circuit_id: str, circuit_version: str) -> str:
|
24
|
+
url = urljoin(f"{routes.ANALYZER_CIRCUIT_PAGE}/", circuit_id)
|
26
25
|
url += versioned_url_params(circuit_version=circuit_version)
|
27
26
|
return url
|
classiq/interface/_version.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
from typing import Annotated, Literal, Optional, Union
|
2
|
-
from uuid import UUID
|
3
2
|
|
4
3
|
import pydantic
|
5
4
|
from pydantic import Field
|
@@ -34,7 +33,7 @@ class RbResults(VersionedModel):
|
|
34
33
|
|
35
34
|
|
36
35
|
class DataID(pydantic.BaseModel):
|
37
|
-
id:
|
36
|
+
id: str
|
38
37
|
|
39
38
|
|
40
39
|
class QasmCode(pydantic.BaseModel):
|
@@ -20,7 +20,7 @@ from classiq.interface.generator.arith import number_utils
|
|
20
20
|
from classiq.interface.generator.complex_type import Complex
|
21
21
|
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
22
22
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
|
23
|
-
from classiq.interface.helpers.
|
23
|
+
from classiq.interface.helpers.datastructures import get_sdk_compatible_python_object
|
24
24
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
25
25
|
|
26
26
|
_ILLEGAL_QUBIT_ERROR_MSG: str = "Illegal qubit index requested"
|
@@ -51,8 +51,11 @@ class SampledState(BaseModel):
|
|
51
51
|
|
52
52
|
@pydantic.field_validator("state", mode="after")
|
53
53
|
@classmethod
|
54
|
-
def
|
55
|
-
return {
|
54
|
+
def _make_state_sdk_compatible(cls, state: ParsedState) -> DotAccessParsedState:
|
55
|
+
return {
|
56
|
+
name: get_sdk_compatible_python_object(value)
|
57
|
+
for name, value in state.items()
|
58
|
+
}
|
56
59
|
|
57
60
|
|
58
61
|
ParsedCounts: TypeAlias = list[SampledState]
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
|
4
|
+
class DotDict(dict):
|
5
|
+
def __getattr__(self, key: str) -> Any:
|
6
|
+
return super().get(key)
|
7
|
+
|
8
|
+
def __setattr__(self, key: str, value: Any) -> None:
|
9
|
+
super().__setitem__(key, value)
|
10
|
+
|
11
|
+
def __delattr__(self, key: str) -> None:
|
12
|
+
super().__delitem__(key)
|
13
|
+
|
14
|
+
|
15
|
+
class LenList(list):
|
16
|
+
@property
|
17
|
+
def len(self) -> int:
|
18
|
+
return len(self)
|
19
|
+
|
20
|
+
|
21
|
+
def get_sdk_compatible_python_object(obj: Any) -> Any:
|
22
|
+
if isinstance(obj, list):
|
23
|
+
return LenList([get_sdk_compatible_python_object(item) for item in obj])
|
24
|
+
if isinstance(obj, dict):
|
25
|
+
return DotDict({k: get_sdk_compatible_python_object(v) for k, v in obj.items()})
|
26
|
+
return obj
|
@@ -1 +1 @@
|
|
1
|
-
INTERFACE_VERSION = "
|
1
|
+
INTERFACE_VERSION = "7"
|
@@ -243,15 +243,23 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
243
243
|
def _get_collapsed_stop(self) -> Expression:
|
244
244
|
if TYPE_CHECKING:
|
245
245
|
assert isinstance(self.base_handle, SlicedHandleBinding)
|
246
|
-
if self.
|
246
|
+
if self._is_evaluated() and self.base_handle.start.is_evaluated():
|
247
247
|
return Expression(
|
248
|
-
expr=str(
|
248
|
+
expr=str(
|
249
|
+
self.end.to_int_value()
|
250
|
+
- self.start.to_int_value()
|
251
|
+
+ self.base_handle.start.to_int_value()
|
252
|
+
)
|
249
253
|
)
|
250
|
-
return Expression(
|
254
|
+
return Expression(
|
255
|
+
expr=f"({self.end})-({self.start})+({self.base_handle.start})"
|
256
|
+
)
|
251
257
|
|
252
258
|
def replace_prefix(
|
253
259
|
self, prefix: HandleBinding, replacement: HandleBinding
|
254
260
|
) -> HandleBinding:
|
261
|
+
if self == prefix:
|
262
|
+
return replacement
|
255
263
|
if (
|
256
264
|
isinstance(prefix, SlicedHandleBinding)
|
257
265
|
and self.base_handle == prefix.base_handle
|
@@ -24,12 +24,16 @@ TASKS_SUFFIX = "/tasks"
|
|
24
24
|
RB = "/rb"
|
25
25
|
ANALYZER_DATA_TASK = f"{TASKS_SUFFIX}/data"
|
26
26
|
ANALYZER_QASM_TASK = f"{TASKS_SUFFIX}/qasm"
|
27
|
+
ANALYZER_GET_VISUAL_MODEL = "/get_visual_model"
|
28
|
+
ANALYZER_GET_IDE_DATA = "/get_ide_data"
|
27
29
|
IDE_EVENT_TASK = f"{TASKS_SUFFIX}/event"
|
28
30
|
DATA_DOG_EVENT_TASK = f"{TASKS_SUFFIX}/data_dog_event"
|
29
31
|
|
30
32
|
ANALYZER_DATA_TASK_UPLOAD_FILE = f"{TASKS_SUFFIX}/data/file_upload"
|
31
33
|
ANALYZER_DATA_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_DATA_TASK}"
|
32
34
|
ANALYZER_QASM_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_QASM_TASK}"
|
35
|
+
ANALYZER_GET_VISUAL_MODEL_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_GET_VISUAL_MODEL}"
|
36
|
+
ANALYZER_GET_IDE_DATA_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_GET_IDE_DATA}"
|
33
37
|
IDE_EVENT_TASK_FULL_PATH = f"{ANALYZER_PREFIX}{IDE_EVENT_TASK}"
|
34
38
|
DATA_DOG_EVENT_TASK_FULL_PATH = f"{ANALYZER_PREFIX}{DATA_DOG_EVENT_TASK}"
|
35
39
|
|
@@ -33,7 +33,6 @@ from classiq.interface.generator.functions.type_name import TypeName
|
|
33
33
|
from classiq.model_expansions.model_tables import (
|
34
34
|
HandleIdentifier,
|
35
35
|
HandleTable,
|
36
|
-
SymbolTable,
|
37
36
|
)
|
38
37
|
from classiq.model_expansions.sympy_conversion.arithmetics import (
|
39
38
|
BitwiseAnd,
|
@@ -48,13 +47,14 @@ from classiq.model_expansions.sympy_conversion.expression_to_sympy import (
|
|
48
47
|
from classiq.model_expansions.sympy_conversion.sympy_to_python import (
|
49
48
|
sympy_to_python,
|
50
49
|
)
|
50
|
+
from classiq.qmod.model_state_container import QMODULE
|
51
51
|
|
52
52
|
|
53
53
|
def qmod_val_to_python(val: ExpressionValue, qmod_type: ClassicalType) -> Any:
|
54
54
|
if isinstance(qmod_type, TypeName):
|
55
55
|
if (
|
56
56
|
isinstance(val, QmodStructInstance)
|
57
|
-
and val.struct_declaration ==
|
57
|
+
and val.struct_declaration == QMODULE.type_decls[qmod_type.name]
|
58
58
|
):
|
59
59
|
return {
|
60
60
|
field_name: qmod_val_to_python(val.fields[field_name], field_type)
|
@@ -97,10 +97,10 @@ def qmod_val_to_python(val: ExpressionValue, qmod_type: ClassicalType) -> Any:
|
|
97
97
|
|
98
98
|
def python_val_to_qmod(val: Any, qmod_type: ClassicalType) -> ExpressionValue:
|
99
99
|
if isinstance(qmod_type, TypeName):
|
100
|
-
if qmod_type.name in
|
100
|
+
if qmod_type.name in QMODULE.enum_decls:
|
101
101
|
return val
|
102
102
|
|
103
|
-
struct_decl =
|
103
|
+
struct_decl = QMODULE.type_decls[qmod_type.name]
|
104
104
|
if not isinstance(val, Mapping):
|
105
105
|
raise ClassiqInternalExpansionError(
|
106
106
|
f"Bad value for struct {struct_decl.name}"
|
@@ -138,7 +138,7 @@ def python_call_wrapper(func: Callable, *args: ExpressionValue) -> Any:
|
|
138
138
|
|
139
139
|
def struct_literal(struct_type_symbol: Symbol, **kwargs: Any) -> QmodStructInstance:
|
140
140
|
return QmodStructInstance(
|
141
|
-
|
141
|
+
QMODULE.type_decls[struct_type_symbol.name],
|
142
142
|
{field: sympy_to_python(field_value) for field, field_value in kwargs.items()},
|
143
143
|
)
|
144
144
|
|
@@ -179,7 +179,7 @@ def get_field(
|
|
179
179
|
|
180
180
|
|
181
181
|
def get_type(struct_type: Symbol) -> TypeProxy:
|
182
|
-
return TypeProxy(
|
182
|
+
return TypeProxy(QMODULE.type_decls[struct_type.name])
|
183
183
|
|
184
184
|
|
185
185
|
def _unwrap_sympy_numeric(n: Any) -> Any:
|
@@ -34,6 +34,10 @@ if TYPE_CHECKING:
|
|
34
34
|
from classiq.model_expansions.closure import FunctionClosure
|
35
35
|
|
36
36
|
|
37
|
+
ALREADY_ALLOCATED_MESSAGE = "Cannot allocate variable '{}', it is already initialized"
|
38
|
+
ALREADY_FREED_MESSAGE = "Cannot free variable '{}', it is already uninitialized"
|
39
|
+
|
40
|
+
|
37
41
|
class PortDirection(StrEnum):
|
38
42
|
Input = "input"
|
39
43
|
Inout = "inout"
|
@@ -141,7 +145,14 @@ class CapturedVars:
|
|
141
145
|
isinstance(captured_handle.handle, NestedHandleBinding)
|
142
146
|
and captured_handle.direction != PortDirection.Inout
|
143
147
|
):
|
144
|
-
|
148
|
+
verb = (
|
149
|
+
"free"
|
150
|
+
if captured_handle.direction == PortDirection.Input
|
151
|
+
else "allocate"
|
152
|
+
)
|
153
|
+
raise ClassiqExpansionError(
|
154
|
+
f"Cannot partially {verb} variable {captured_handle.handle.name}"
|
155
|
+
)
|
145
156
|
|
146
157
|
new_captured_handles = []
|
147
158
|
for existing_captured_handle in self._captured_handles:
|
@@ -174,7 +185,9 @@ class CapturedVars:
|
|
174
185
|
return captured_handle.change_direction(PortDirection.Inout)
|
175
186
|
if captured_handle.direction == PortDirection.Outin:
|
176
187
|
return captured_handle.change_direction(PortDirection.Input)
|
177
|
-
raise
|
188
|
+
raise ClassiqExpansionError(
|
189
|
+
ALREADY_FREED_MESSAGE.format(captured_handle.handle)
|
190
|
+
)
|
178
191
|
if existing_captured_handle.direction == PortDirection.Output:
|
179
192
|
if captured_handle.direction == PortDirection.Input:
|
180
193
|
return captured_handle.change_direction(PortDirection.Outin)
|
@@ -182,8 +195,8 @@ class CapturedVars:
|
|
182
195
|
PortDirection.Output,
|
183
196
|
PortDirection.Outin,
|
184
197
|
):
|
185
|
-
raise
|
186
|
-
|
198
|
+
raise ClassiqExpansionError(
|
199
|
+
ALREADY_ALLOCATED_MESSAGE.format(captured_handle.handle)
|
187
200
|
)
|
188
201
|
return captured_handle.change_direction(PortDirection.Output)
|
189
202
|
if existing_captured_handle.direction == PortDirection.Inout:
|
@@ -191,14 +204,16 @@ class CapturedVars:
|
|
191
204
|
PortDirection.Output,
|
192
205
|
PortDirection.Outin,
|
193
206
|
):
|
194
|
-
raise
|
195
|
-
|
207
|
+
raise ClassiqExpansionError(
|
208
|
+
ALREADY_ALLOCATED_MESSAGE.format(captured_handle.handle)
|
196
209
|
)
|
197
210
|
elif captured_handle.direction in (
|
198
211
|
PortDirection.Input,
|
199
212
|
PortDirection.Inout,
|
200
213
|
):
|
201
|
-
raise
|
214
|
+
raise ClassiqExpansionError(
|
215
|
+
ALREADY_FREED_MESSAGE.format(captured_handle.handle)
|
216
|
+
)
|
202
217
|
return captured_handle
|
203
218
|
|
204
219
|
def _intersect_handles(
|
@@ -211,7 +226,9 @@ class CapturedVars:
|
|
211
226
|
PortDirection.Input,
|
212
227
|
PortDirection.Outin,
|
213
228
|
):
|
214
|
-
raise
|
229
|
+
raise ClassiqExpansionError(
|
230
|
+
ALREADY_FREED_MESSAGE.format(captured_handle.handle)
|
231
|
+
)
|
215
232
|
return existing_captured_handle
|
216
233
|
|
217
234
|
if existing_captured_handle.handle in captured_handle.handle:
|
@@ -219,8 +236,8 @@ class CapturedVars:
|
|
219
236
|
PortDirection.Output,
|
220
237
|
PortDirection.Outin,
|
221
238
|
):
|
222
|
-
raise
|
223
|
-
|
239
|
+
raise ClassiqExpansionError(
|
240
|
+
ALREADY_ALLOCATED_MESSAGE.format(captured_handle.handle)
|
224
241
|
)
|
225
242
|
return captured_handle
|
226
243
|
|
@@ -25,8 +25,8 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
25
25
|
|
26
26
|
from classiq.model_expansions.closure import FunctionClosure
|
27
27
|
from classiq.model_expansions.evaluators.type_type_match import check_signature_match
|
28
|
-
from classiq.model_expansions.model_tables import SymbolTable
|
29
28
|
from classiq.model_expansions.scope import Evaluated, QuantumSymbol
|
29
|
+
from classiq.qmod.model_state_container import QMODULE
|
30
30
|
from classiq.qmod.qmod_parameter import CInt, get_qmod_type
|
31
31
|
|
32
32
|
|
@@ -122,11 +122,11 @@ def _check_classical_type_match(
|
|
122
122
|
type_name = _resolve_type_name(classical_type)
|
123
123
|
type_is_struct = (
|
124
124
|
isinstance(classical_type, TypeName)
|
125
|
-
and classical_type.name in
|
125
|
+
and classical_type.name in QMODULE.type_decls
|
126
126
|
)
|
127
127
|
type_is_enum = (
|
128
128
|
isinstance(classical_type, TypeName)
|
129
|
-
and classical_type.name in
|
129
|
+
and classical_type.name in QMODULE.enum_decls
|
130
130
|
)
|
131
131
|
arg_is_qvar = isinstance(argument, QmodSizedProxy)
|
132
132
|
arg_is_builtin = argument.__class__.__module__ == "builtins"
|
@@ -153,9 +153,6 @@ def _resolve_type_name(classical_type: ConcreteClassicalType) -> str:
|
|
153
153
|
type_name = get_qmod_type(classical_type).__name__
|
154
154
|
if not isinstance(classical_type, TypeName):
|
155
155
|
return type_name
|
156
|
-
if
|
157
|
-
type_name not in SymbolTable.type_table
|
158
|
-
and type_name not in SymbolTable.enum_table
|
159
|
-
):
|
156
|
+
if type_name not in QMODULE.type_decls and type_name not in QMODULE.enum_decls:
|
160
157
|
raise ClassiqExpansionError(f"Undefined type {type_name}")
|
161
158
|
return type_name
|
@@ -10,10 +10,12 @@ from classiq.interface.generator.functions.type_name import (
|
|
10
10
|
TypeName,
|
11
11
|
)
|
12
12
|
from classiq.interface.model.bind_operation import BindOperation
|
13
|
+
from classiq.interface.model.inplace_binary_operation import BinaryOperation
|
13
14
|
from classiq.interface.model.quantum_type import (
|
14
15
|
QuantumBit,
|
15
16
|
QuantumBitvector,
|
16
17
|
QuantumNumeric,
|
18
|
+
QuantumScalar,
|
17
19
|
QuantumType,
|
18
20
|
)
|
19
21
|
|
@@ -209,14 +211,19 @@ def validate_bind_targets(bind: BindOperation, scope: Scope) -> None:
|
|
209
211
|
)
|
210
212
|
|
211
213
|
|
212
|
-
def
|
213
|
-
|
214
|
-
) ->
|
215
|
-
if not isinstance(
|
214
|
+
def get_inplace_op_scalar_as_numeric(
|
215
|
+
var: QuantumSymbol, operation: BinaryOperation, var_kind: str
|
216
|
+
) -> QuantumNumeric:
|
217
|
+
if not isinstance(var.quantum_type, QuantumScalar):
|
216
218
|
raise ClassiqExpansionError(
|
217
|
-
f"Cannot perform
|
219
|
+
f"Cannot perform inplace {operation.name.lower()} with non-scalar {var_kind} {var.handle}"
|
218
220
|
)
|
219
|
-
if
|
220
|
-
|
221
|
-
|
221
|
+
if isinstance(var.quantum_type, QuantumNumeric):
|
222
|
+
return var.quantum_type
|
223
|
+
if isinstance(var.quantum_type, QuantumBit):
|
224
|
+
return QuantumNumeric(
|
225
|
+
size=Expression(expr="1"),
|
226
|
+
is_signed=Expression(expr="False"),
|
227
|
+
fraction_digits=Expression(expr="0"),
|
222
228
|
)
|
229
|
+
raise ClassiqInternalExpansionError(f"Unexpected scalar type {var.quantum_type}")
|
@@ -24,12 +24,13 @@ from classiq.model_expansions.atomic_expression_functions_defs import (
|
|
24
24
|
ATOMIC_EXPRESSION_FUNCTIONS,
|
25
25
|
qmod_val_to_python,
|
26
26
|
)
|
27
|
-
from classiq.model_expansions.model_tables import SymbolTable
|
28
27
|
from classiq.model_expansions.sympy_conversion.expression_to_sympy import (
|
29
28
|
translate_to_sympy,
|
30
29
|
)
|
31
30
|
from classiq.model_expansions.sympy_conversion.sympy_to_python import sympy_to_python
|
32
31
|
from classiq.qmod import symbolic
|
32
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
33
|
+
from classiq.qmod.model_state_container import QMODULE
|
33
34
|
|
34
35
|
|
35
36
|
def evaluate_constants(constants: list[Constant]) -> dict[str, EvaluatedExpression]:
|
@@ -56,7 +57,12 @@ def evaluate(
|
|
56
57
|
) -> EvaluatedExpression:
|
57
58
|
model_locals: dict[str, ExpressionValue] = {}
|
58
59
|
model_locals.update(ATOMIC_EXPRESSION_FUNCTIONS)
|
59
|
-
model_locals.update(
|
60
|
+
model_locals.update(
|
61
|
+
{
|
62
|
+
enum_decl.name: enum_decl.create_enum()
|
63
|
+
for enum_decl in (QMODULE.enum_decls | BUILTIN_ENUM_DECLARATIONS).values()
|
64
|
+
}
|
65
|
+
)
|
60
66
|
# locals override builtin-functions
|
61
67
|
model_locals.update({name: expr.value for name, expr in locals_dict.items()})
|
62
68
|
uninitialized_locals = uninitialized_locals or set()
|
@@ -34,7 +34,7 @@ from classiq.qmod.semantics.static_semantics_visitor import resolve_function_cal
|
|
34
34
|
from classiq.qmod.symbolic_expr import SymbolicExpr
|
35
35
|
|
36
36
|
if TYPE_CHECKING:
|
37
|
-
from classiq.model_expansions.
|
37
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
38
38
|
|
39
39
|
|
40
40
|
class LenList(list):
|
@@ -94,7 +94,7 @@ def translate_ast_arg_to_python_qmod(param: PositionalArg, evaluated: Evaluated)
|
|
94
94
|
|
95
95
|
|
96
96
|
class _InterpreterExpandable(QFunc):
|
97
|
-
def __init__(self, interpreter: "
|
97
|
+
def __init__(self, interpreter: "BaseInterpreter"):
|
98
98
|
super().__init__(lambda: None)
|
99
99
|
self._interpreter = interpreter
|
100
100
|
|
@@ -137,7 +137,7 @@ class _InterpreterExpandable(QFunc):
|
|
137
137
|
|
138
138
|
|
139
139
|
def emit_generative_statements(
|
140
|
-
interpreter: "
|
140
|
+
interpreter: "BaseInterpreter",
|
141
141
|
operation: GenerativeClosure,
|
142
142
|
args: list[Evaluated],
|
143
143
|
) -> None:
|
File without changes
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from abc import abstractmethod
|
1
2
|
from collections import defaultdict
|
2
3
|
from collections.abc import Sequence
|
3
4
|
from contextlib import nullcontext
|
@@ -15,30 +16,15 @@ from classiq.interface.exceptions import (
|
|
15
16
|
)
|
16
17
|
from classiq.interface.generator.constant import Constant
|
17
18
|
from classiq.interface.generator.expressions.expression import Expression
|
18
|
-
from classiq.interface.generator.functions.builtins.internal_operators import (
|
19
|
-
CONTROL_OPERATOR_NAME,
|
20
|
-
INVERT_OPERATOR_NAME,
|
21
|
-
WITHIN_APPLY_NAME,
|
22
|
-
)
|
23
19
|
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
24
|
-
from classiq.interface.model.bind_operation import BindOperation
|
25
|
-
from classiq.interface.model.classical_if import ClassicalIf
|
26
|
-
from classiq.interface.model.control import Control
|
27
20
|
from classiq.interface.model.handle_binding import (
|
28
21
|
FieldHandleBinding,
|
29
22
|
HandleBinding,
|
30
23
|
SlicedHandleBinding,
|
31
24
|
SubscriptHandleBinding,
|
32
25
|
)
|
33
|
-
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
34
|
-
from classiq.interface.model.invert import Invert
|
35
26
|
from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
|
36
27
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
37
|
-
from classiq.interface.model.phase_operation import PhaseOperation
|
38
|
-
from classiq.interface.model.power import Power
|
39
|
-
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
40
|
-
QuantumAssignmentOperation,
|
41
|
-
)
|
42
28
|
from classiq.interface.model.quantum_function_call import (
|
43
29
|
QuantumFunctionCall,
|
44
30
|
)
|
@@ -51,11 +37,6 @@ from classiq.interface.model.quantum_lambda_function import (
|
|
51
37
|
QuantumLambdaFunction,
|
52
38
|
)
|
53
39
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
54
|
-
from classiq.interface.model.repeat import Repeat
|
55
|
-
from classiq.interface.model.variable_declaration_statement import (
|
56
|
-
VariableDeclarationStatement,
|
57
|
-
)
|
58
|
-
from classiq.interface.model.within_apply_operation import WithinApply
|
59
40
|
|
60
41
|
from classiq.model_expansions.closure import (
|
61
42
|
Closure,
|
@@ -74,21 +55,6 @@ from classiq.model_expansions.function_builder import (
|
|
74
55
|
OperationContext,
|
75
56
|
)
|
76
57
|
from classiq.model_expansions.generative_functions import emit_generative_statements
|
77
|
-
from classiq.model_expansions.quantum_operations import (
|
78
|
-
BindEmitter,
|
79
|
-
ClassicalIfEmitter,
|
80
|
-
ControlEmitter,
|
81
|
-
InplaceBinaryOperationEmitter,
|
82
|
-
InvertEmitter,
|
83
|
-
PowerEmitter,
|
84
|
-
QuantumAssignmentOperationEmitter,
|
85
|
-
QuantumFunctionCallEmitter,
|
86
|
-
RepeatEmitter,
|
87
|
-
VariableDeclarationStatementEmitter,
|
88
|
-
WithinApplyEmitter,
|
89
|
-
)
|
90
|
-
from classiq.model_expansions.quantum_operations.phase import PhaseEmitter
|
91
|
-
from classiq.model_expansions.quantum_operations.shallow_emitter import ShallowEmitter
|
92
58
|
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
93
59
|
from classiq.model_expansions.scope_initialization import (
|
94
60
|
add_constants_to_scope,
|
@@ -96,25 +62,24 @@ from classiq.model_expansions.scope_initialization import (
|
|
96
62
|
add_functions_to_scope,
|
97
63
|
add_generative_functions_to_scope,
|
98
64
|
get_main_renamer,
|
65
|
+
init_builtin_types,
|
99
66
|
init_top_level_scope,
|
100
67
|
)
|
101
68
|
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
69
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
102
70
|
from classiq.qmod.builtins.functions import permute
|
71
|
+
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
103
72
|
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
104
73
|
from classiq.qmod.quantum_function import GenerativeQFunc
|
105
74
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
106
75
|
|
107
76
|
|
108
|
-
class
|
77
|
+
class BaseInterpreter:
|
109
78
|
def __init__(
|
110
79
|
self,
|
111
80
|
model: Model,
|
112
81
|
generative_functions: Optional[list[GenerativeQFunc]] = None,
|
113
|
-
is_normalizer: bool = False,
|
114
|
-
is_shallow: bool = False,
|
115
82
|
) -> None:
|
116
|
-
self._is_normalizer = is_normalizer
|
117
|
-
self._is_shallow = is_shallow
|
118
83
|
self._model = model
|
119
84
|
self._top_level_scope = Scope()
|
120
85
|
self._counted_name_allocator = CountedNameAllocator()
|
@@ -123,12 +88,8 @@ class Interpreter:
|
|
123
88
|
)
|
124
89
|
self._expanded_functions: dict[str, NativeFunctionDefinition] = {}
|
125
90
|
|
91
|
+
init_builtin_types()
|
126
92
|
init_top_level_scope(model, generative_functions or [], self._top_level_scope)
|
127
|
-
self._main_renamer: Optional[ExpressionRenamer] = (
|
128
|
-
get_main_renamer(self._get_function_declarations())
|
129
|
-
if self._is_normalizer
|
130
|
-
else None
|
131
|
-
)
|
132
93
|
self._functions_compilation_metadata: dict[str, CompilationMetadata] = dict(
|
133
94
|
self._model.functions_compilation_metadata
|
134
95
|
)
|
@@ -138,6 +99,13 @@ class Interpreter:
|
|
138
99
|
self._counted_name_allocator = CountedNameAllocator()
|
139
100
|
self._error_manager: ErrorManager = ErrorManager()
|
140
101
|
|
102
|
+
@property
|
103
|
+
def is_shallow(self) -> bool:
|
104
|
+
return False
|
105
|
+
|
106
|
+
def get_main_renamer(self) -> Optional[ExpressionRenamer]:
|
107
|
+
return get_main_renamer(self._get_function_declarations())
|
108
|
+
|
141
109
|
def _expand_main_func(self) -> None:
|
142
110
|
main_func = self._top_level_scope[MAIN_FUNCTION_NAME].value
|
143
111
|
closure_constructor: Any
|
@@ -153,7 +121,7 @@ class Interpreter:
|
|
153
121
|
name=main_func.name,
|
154
122
|
positional_arg_declarations=main_func.positional_arg_declarations,
|
155
123
|
scope=Scope(parent=self._top_level_scope),
|
156
|
-
expr_renamer=self.
|
124
|
+
expr_renamer=self.get_main_renamer(),
|
157
125
|
_depth=0,
|
158
126
|
**extra_args,
|
159
127
|
)
|
@@ -189,8 +157,16 @@ class Interpreter:
|
|
189
157
|
execution_preferences=self._model.execution_preferences,
|
190
158
|
functions=list(self._expanded_functions.values()),
|
191
159
|
constants=self._model.constants,
|
192
|
-
enums=
|
193
|
-
|
160
|
+
enums=[
|
161
|
+
enum_decl
|
162
|
+
for name, enum_decl in QMODULE.enum_decls.items()
|
163
|
+
if name not in BUILTIN_ENUM_DECLARATIONS
|
164
|
+
],
|
165
|
+
types=[
|
166
|
+
struct_decl
|
167
|
+
for name, struct_decl in QMODULE.type_decls.items()
|
168
|
+
if name not in BUILTIN_STRUCT_DECLARATIONS
|
169
|
+
],
|
194
170
|
qstructs=list(QMODULE.qstruct_decls.values()),
|
195
171
|
debug_info=self._model.debug_info,
|
196
172
|
functions_compilation_metadata=self._expanded_functions_compilation_metadata,
|
@@ -282,96 +258,9 @@ class Interpreter:
|
|
282
258
|
base_value = self.evaluate(field_access.base_handle)
|
283
259
|
return Evaluated(value=base_value.value.fields[field_access.field])
|
284
260
|
|
285
|
-
@
|
261
|
+
@abstractmethod
|
286
262
|
def emit(self, statement: QuantumStatement) -> None:
|
287
|
-
|
288
|
-
|
289
|
-
@emit.register
|
290
|
-
def emit_quantum_function_call(self, call: QuantumFunctionCall) -> None:
|
291
|
-
QuantumFunctionCallEmitter(self).emit(call)
|
292
|
-
|
293
|
-
@emit.register
|
294
|
-
def emit_bind(self, bind: BindOperation) -> None:
|
295
|
-
BindEmitter(self).emit(bind)
|
296
|
-
|
297
|
-
@emit.register
|
298
|
-
def emit_quantum_assignment_operation(self, op: QuantumAssignmentOperation) -> None:
|
299
|
-
if self._is_normalizer:
|
300
|
-
ShallowEmitter(
|
301
|
-
self, "assignment_operation", components=["expression", "result_var"]
|
302
|
-
).emit(op)
|
303
|
-
else:
|
304
|
-
QuantumAssignmentOperationEmitter(self).emit(op)
|
305
|
-
|
306
|
-
@emit.register
|
307
|
-
def emit_inplace_binary_operation(self, op: InplaceBinaryOperation) -> None:
|
308
|
-
if self._is_normalizer:
|
309
|
-
ShallowEmitter(
|
310
|
-
self, "inplace_binary_operation", components=["target", "value"]
|
311
|
-
).emit(op)
|
312
|
-
else:
|
313
|
-
InplaceBinaryOperationEmitter(self).emit(op)
|
314
|
-
|
315
|
-
@emit.register
|
316
|
-
def emit_variable_declaration(
|
317
|
-
self, variable_declaration: VariableDeclarationStatement
|
318
|
-
) -> None:
|
319
|
-
VariableDeclarationStatementEmitter(self).emit(variable_declaration)
|
320
|
-
|
321
|
-
@emit.register
|
322
|
-
def emit_classical_if(self, classical_if: ClassicalIf) -> None:
|
323
|
-
ClassicalIfEmitter(self).emit(classical_if)
|
324
|
-
|
325
|
-
@emit.register
|
326
|
-
def emit_within_apply(self, within_apply: WithinApply) -> None:
|
327
|
-
if self._is_normalizer:
|
328
|
-
ShallowEmitter(
|
329
|
-
self,
|
330
|
-
WITHIN_APPLY_NAME,
|
331
|
-
components=["within", "apply", "compute", "action"],
|
332
|
-
).emit(within_apply)
|
333
|
-
else:
|
334
|
-
WithinApplyEmitter(self).emit(within_apply)
|
335
|
-
|
336
|
-
@emit.register
|
337
|
-
def emit_invert(self, invert: Invert) -> None:
|
338
|
-
if self._is_normalizer:
|
339
|
-
ShallowEmitter(self, INVERT_OPERATOR_NAME, components=["body"]).emit(invert)
|
340
|
-
else:
|
341
|
-
InvertEmitter(self).emit(invert)
|
342
|
-
|
343
|
-
@emit.register
|
344
|
-
def emit_repeat(self, repeat: Repeat) -> None:
|
345
|
-
RepeatEmitter(self).emit(repeat)
|
346
|
-
|
347
|
-
@emit.register
|
348
|
-
def emit_control(self, control: Control) -> None:
|
349
|
-
if self._is_normalizer:
|
350
|
-
ShallowEmitter(
|
351
|
-
self,
|
352
|
-
CONTROL_OPERATOR_NAME,
|
353
|
-
components=["expression", "body", "else_block"],
|
354
|
-
).emit(control)
|
355
|
-
else:
|
356
|
-
ControlEmitter(self).emit(control)
|
357
|
-
|
358
|
-
@emit.register
|
359
|
-
def emit_power(self, power: Power) -> None:
|
360
|
-
if self._is_normalizer:
|
361
|
-
ShallowEmitter(
|
362
|
-
self, CONTROL_OPERATOR_NAME, components=["power", "body"]
|
363
|
-
).emit(power)
|
364
|
-
else:
|
365
|
-
PowerEmitter(self).emit(power)
|
366
|
-
|
367
|
-
@emit.register
|
368
|
-
def emit_phase(self, phase: PhaseOperation) -> None:
|
369
|
-
if self._is_normalizer:
|
370
|
-
ShallowEmitter(self, "phase", components=["expression", "theta"]).emit(
|
371
|
-
phase
|
372
|
-
)
|
373
|
-
else:
|
374
|
-
PhaseEmitter(self).emit(phase)
|
263
|
+
pass
|
375
264
|
|
376
265
|
def _expand_block(self, block: Sequence[QuantumStatement], block_name: str) -> None:
|
377
266
|
with self._builder.block_context(block_name):
|