classiq 0.69.0__py3-none-any.whl → 0.71.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/analyzer.py +0 -18
- classiq/analyzer/url_utils.py +9 -4
- classiq/applications/combinatorial_helpers/pyomo_utils.py +2 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +6 -0
- classiq/interface/chemistry/operator.py +1 -21
- classiq/interface/debug_info/debug_info.py +4 -0
- classiq/interface/executor/quantum_instruction_set.py +1 -0
- classiq/interface/generator/arith/arithmetic.py +21 -6
- classiq/interface/generator/circuit_code/circuit_code.py +4 -0
- classiq/interface/generator/circuit_code/types_and_constants.py +1 -0
- classiq/interface/generator/expressions/atomic_expression_functions.py +1 -2
- classiq/interface/generator/expressions/expression_constants.py +0 -3
- classiq/interface/generator/expressions/expression_types.py +12 -4
- classiq/interface/generator/expressions/proxies/__init__.py +0 -0
- classiq/interface/generator/expressions/proxies/classical/__init__.py +0 -0
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +79 -0
- classiq/interface/generator/expressions/proxies/classical/classical_proxy.py +26 -0
- classiq/interface/generator/expressions/proxies/classical/classical_scalar_proxy.py +32 -0
- classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +35 -0
- classiq/interface/generator/expressions/proxies/classical/utils.py +34 -0
- classiq/interface/generator/expressions/proxies/quantum/__init__.py +0 -0
- classiq/interface/generator/expressions/{qmod_qarray_proxy.py → proxies/quantum/qmod_qarray_proxy.py} +3 -1
- classiq/interface/generator/expressions/{qmod_qscalar_proxy.py → proxies/quantum/qmod_qscalar_proxy.py} +3 -1
- classiq/interface/generator/expressions/{qmod_qstruct_proxy.py → proxies/quantum/qmod_qstruct_proxy.py} +3 -1
- classiq/interface/generator/functions/classical_type.py +24 -30
- classiq/interface/generator/functions/type_name.py +42 -2
- classiq/interface/generator/functions/type_qualifier.py +7 -0
- classiq/interface/generator/generated_circuit_data.py +22 -4
- classiq/interface/generator/model/preferences/preferences.py +1 -0
- classiq/interface/generator/quantum_function_call.py +8 -1
- classiq/interface/generator/quantum_program.py +0 -1
- classiq/interface/generator/synthesis_execution_parameter.py +1 -0
- classiq/interface/generator/types/compilation_metadata.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/inplace_binary_operation.py +4 -0
- classiq/interface/model/model.py +3 -1
- classiq/interface/model/native_function_definition.py +0 -10
- 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 +37 -3
- 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/model_expansions/atomic_expression_functions_defs.py +9 -3
- classiq/model_expansions/capturing/captured_vars.py +156 -34
- classiq/model_expansions/evaluators/arg_type_match.py +4 -2
- classiq/model_expansions/evaluators/classical_expression.py +2 -2
- classiq/model_expansions/evaluators/classical_type_inference.py +70 -0
- classiq/model_expansions/evaluators/control.py +1 -1
- classiq/model_expansions/evaluators/parameter_types.py +72 -16
- classiq/model_expansions/evaluators/quantum_type_utils.py +7 -57
- classiq/model_expansions/expression_evaluator.py +3 -12
- classiq/model_expansions/function_builder.py +2 -8
- classiq/model_expansions/generative_functions.py +39 -3
- classiq/model_expansions/interpreters/base_interpreter.py +3 -4
- classiq/model_expansions/quantum_operations/arithmetic/__init__.py +0 -0
- classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +60 -0
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +9 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +46 -6
- classiq/model_expansions/quantum_operations/emitter.py +41 -0
- classiq/model_expansions/quantum_operations/expression_evaluator.py +4 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +0 -22
- classiq/model_expansions/scope.py +7 -14
- classiq/model_expansions/scope_initialization.py +32 -39
- classiq/model_expansions/transformers/model_renamer.py +13 -4
- classiq/model_expansions/visitors/variable_references.py +8 -4
- classiq/open_library/functions/__init__.py +2 -0
- classiq/open_library/functions/lookup_table.py +58 -0
- classiq/qmod/__init__.py +3 -1
- classiq/qmod/declaration_inferrer.py +55 -25
- 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_parameter.py +8 -0
- classiq/qmod/qmod_variable.py +189 -151
- classiq/qmod/quantum_function.py +3 -4
- classiq/qmod/semantics/annotation/call_annotation.py +0 -28
- classiq/qmod/semantics/annotation/qstruct_annotator.py +21 -1
- classiq/qmod/semantics/validation/main_validation.py +1 -1
- classiq/qmod/semantics/validation/type_hints.py +38 -0
- classiq/qmod/utilities.py +38 -1
- {classiq-0.69.0.dist-info → classiq-0.71.0.dist-info}/METADATA +10 -12
- {classiq-0.69.0.dist-info → classiq-0.71.0.dist-info}/RECORD +97 -82
- {classiq-0.69.0.dist-info → classiq-0.71.0.dist-info}/WHEEL +1 -1
- /classiq/interface/generator/expressions/{qmod_struct_instance.py → proxies/classical/qmod_struct_instance.py} +0 -0
- /classiq/interface/generator/expressions/{qmod_sized_proxy.py → proxies/quantum/qmod_sized_proxy.py} +0 -0
@@ -1,30 +1,31 @@
|
|
1
|
-
from typing import TYPE_CHECKING, Any, Literal
|
1
|
+
from typing import TYPE_CHECKING, Any, Literal
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
from pydantic import ConfigDict, PrivateAttr
|
5
|
-
from sympy import IndexedBase, Symbol
|
6
5
|
from typing_extensions import Self
|
7
6
|
|
8
7
|
from classiq.interface.ast_node import HashableASTNode
|
9
|
-
from classiq.interface.generator.expressions.
|
8
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_array_proxy import (
|
9
|
+
ClassicalArrayProxy,
|
10
|
+
)
|
11
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
12
|
+
ClassicalProxy,
|
13
|
+
)
|
14
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_scalar_proxy import (
|
15
|
+
ClassicalScalarProxy,
|
16
|
+
)
|
10
17
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
18
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
11
19
|
|
12
20
|
if TYPE_CHECKING:
|
13
21
|
from classiq.interface.generator.functions.concrete_types import (
|
14
22
|
ConcreteClassicalType,
|
15
23
|
)
|
16
24
|
|
17
|
-
CLASSICAL_ATTRIBUTES = {"len", "size", "is_signed", "fraction_digits"}
|
18
|
-
|
19
|
-
NamedSymbol = Union[IndexedBase, Symbol]
|
20
|
-
|
21
25
|
|
22
26
|
class ClassicalType(HashableASTNode):
|
23
27
|
_is_generative: bool = PrivateAttr(default=False)
|
24
28
|
|
25
|
-
def as_symbolic(self, name: str) -> Union[NamedSymbol, list[NamedSymbol]]:
|
26
|
-
return Symbol(name)
|
27
|
-
|
28
29
|
model_config = ConfigDict(extra="forbid")
|
29
30
|
|
30
31
|
def __str__(self) -> str:
|
@@ -38,13 +39,13 @@ class ClassicalType(HashableASTNode):
|
|
38
39
|
def is_generative(self) -> bool:
|
39
40
|
return self._is_generative
|
40
41
|
|
42
|
+
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
43
|
+
return ClassicalScalarProxy(handle, self)
|
44
|
+
|
41
45
|
|
42
46
|
class Integer(ClassicalType):
|
43
47
|
kind: Literal["int"]
|
44
48
|
|
45
|
-
def as_symbolic(self, name: str) -> Symbol:
|
46
|
-
return Symbol(name, integer=True)
|
47
|
-
|
48
49
|
@pydantic.model_validator(mode="before")
|
49
50
|
@classmethod
|
50
51
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
@@ -54,9 +55,6 @@ class Integer(ClassicalType):
|
|
54
55
|
class Real(ClassicalType):
|
55
56
|
kind: Literal["real"]
|
56
57
|
|
57
|
-
def as_symbolic(self, name: str) -> Symbol:
|
58
|
-
return Symbol(name, real=True)
|
59
|
-
|
60
58
|
@pydantic.model_validator(mode="before")
|
61
59
|
@classmethod
|
62
60
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
@@ -76,14 +74,14 @@ class ClassicalList(ClassicalType):
|
|
76
74
|
kind: Literal["list"]
|
77
75
|
element_type: "ConcreteClassicalType"
|
78
76
|
|
79
|
-
def as_symbolic(self, name: str) -> Symbol:
|
80
|
-
return IndexedBase(name)
|
81
|
-
|
82
77
|
@pydantic.model_validator(mode="before")
|
83
78
|
@classmethod
|
84
79
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
85
80
|
return values_with_discriminator(values, "kind", "list")
|
86
81
|
|
82
|
+
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
83
|
+
raise NotImplementedError
|
84
|
+
|
87
85
|
|
88
86
|
class StructMetaType(ClassicalType):
|
89
87
|
kind: Literal["type_proxy"]
|
@@ -93,20 +91,23 @@ class StructMetaType(ClassicalType):
|
|
93
91
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
94
92
|
return values_with_discriminator(values, "kind", "type_proxy")
|
95
93
|
|
94
|
+
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
95
|
+
raise NotImplementedError
|
96
|
+
|
96
97
|
|
97
98
|
class ClassicalArray(ClassicalType):
|
98
99
|
kind: Literal["array"]
|
99
100
|
element_type: "ConcreteClassicalType"
|
100
|
-
size:
|
101
|
-
|
102
|
-
def as_symbolic(self, name: str) -> list:
|
103
|
-
return [self.element_type.as_symbolic(f"{name}_{i}") for i in range(self.size)]
|
101
|
+
size: int
|
104
102
|
|
105
103
|
@pydantic.model_validator(mode="before")
|
106
104
|
@classmethod
|
107
105
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
108
106
|
return values_with_discriminator(values, "kind", "array")
|
109
107
|
|
108
|
+
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
109
|
+
return ClassicalArrayProxy(handle, self.element_type, self.size)
|
110
|
+
|
110
111
|
|
111
112
|
class OpaqueHandle(ClassicalType):
|
112
113
|
pass
|
@@ -148,12 +149,5 @@ class IQAERes(OpaqueHandle):
|
|
148
149
|
return values_with_discriminator(values, "kind", "iqae_result")
|
149
150
|
|
150
151
|
|
151
|
-
def as_symbolic(symbols: dict[str, ClassicalType]) -> dict[str, RuntimeExpression]:
|
152
|
-
return {
|
153
|
-
param_name: param_type.as_symbolic(param_name)
|
154
|
-
for param_name, param_type in symbols.items()
|
155
|
-
}
|
156
|
-
|
157
|
-
|
158
152
|
class QmodPyObject:
|
159
153
|
pass
|
@@ -1,10 +1,20 @@
|
|
1
1
|
from collections.abc import Mapping
|
2
|
+
from itertools import chain
|
2
3
|
from typing import TYPE_CHECKING, Any, Literal, Optional
|
3
4
|
|
4
5
|
import pydantic
|
5
6
|
|
6
7
|
from classiq.interface.exceptions import ClassiqExpansionError
|
7
|
-
from classiq.interface.generator.expressions.
|
8
|
+
from classiq.interface.generator.expressions.expression import Expression
|
9
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
10
|
+
ClassicalProxy,
|
11
|
+
)
|
12
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_struct_proxy import (
|
13
|
+
ClassicalStructProxy,
|
14
|
+
)
|
15
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_qstruct_proxy import (
|
16
|
+
QmodQStructProxy,
|
17
|
+
)
|
8
18
|
from classiq.interface.generator.functions.classical_type import (
|
9
19
|
ClassicalType,
|
10
20
|
)
|
@@ -16,6 +26,7 @@ from classiq.interface.model.quantum_type import (
|
|
16
26
|
|
17
27
|
if TYPE_CHECKING:
|
18
28
|
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
29
|
+
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
19
30
|
|
20
31
|
|
21
32
|
class TypeName(ClassicalType, QuantumType):
|
@@ -24,6 +35,9 @@ class TypeName(ClassicalType, QuantumType):
|
|
24
35
|
_assigned_fields: Optional[Mapping[str, "ConcreteQuantumType"]] = (
|
25
36
|
pydantic.PrivateAttr(default=None)
|
26
37
|
)
|
38
|
+
_classical_struct_decl: Optional["StructDeclaration"] = pydantic.PrivateAttr(
|
39
|
+
default=None
|
40
|
+
)
|
27
41
|
|
28
42
|
@pydantic.model_validator(mode="before")
|
29
43
|
@classmethod
|
@@ -40,7 +54,7 @@ class TypeName(ClassicalType, QuantumType):
|
|
40
54
|
)
|
41
55
|
|
42
56
|
def get_proxy(self, handle: "HandleBinding") -> "QmodQStructProxy":
|
43
|
-
from classiq.interface.generator.expressions.qmod_qstruct_proxy import (
|
57
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_qstruct_proxy import (
|
44
58
|
QmodQStructProxy,
|
45
59
|
)
|
46
60
|
|
@@ -81,6 +95,32 @@ class TypeName(ClassicalType, QuantumType):
|
|
81
95
|
field_type.is_evaluated for field_type in self.fields.values()
|
82
96
|
)
|
83
97
|
|
98
|
+
@property
|
99
|
+
def has_classical_struct_decl(self) -> bool:
|
100
|
+
return self._classical_struct_decl is not None
|
101
|
+
|
102
|
+
@property
|
103
|
+
def classical_struct_decl(self) -> "StructDeclaration":
|
104
|
+
if self._classical_struct_decl is None:
|
105
|
+
raise ClassiqExpansionError(f"Type {self.name!r} is undefined")
|
106
|
+
return self._classical_struct_decl
|
107
|
+
|
108
|
+
def set_classical_struct_decl(self, decl: "StructDeclaration") -> None:
|
109
|
+
self._classical_struct_decl = decl
|
110
|
+
|
111
|
+
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
112
|
+
if self._classical_struct_decl is None:
|
113
|
+
raise ClassiqExpansionError(f"Type {self.name!r} is undefined")
|
114
|
+
return ClassicalStructProxy(handle, self._classical_struct_decl)
|
115
|
+
|
116
|
+
@property
|
117
|
+
def expressions(self) -> list[Expression]:
|
118
|
+
return list(
|
119
|
+
chain.from_iterable(
|
120
|
+
field_type.expressions for field_type in self.fields.values()
|
121
|
+
)
|
122
|
+
)
|
123
|
+
|
84
124
|
|
85
125
|
class Enum(TypeName):
|
86
126
|
pass
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
import re
|
2
3
|
from typing import Literal, Optional, Union
|
3
4
|
|
4
5
|
import pydantic
|
@@ -7,6 +8,9 @@ from typing_extensions import TypeAlias
|
|
7
8
|
|
8
9
|
from classiq.interface.debug_info.back_ref_util import is_allocate_or_free_by_backref
|
9
10
|
from classiq.interface.enum_utils import StrEnum
|
11
|
+
from classiq.interface.generator.compiler_keywords import (
|
12
|
+
generate_original_function_name,
|
13
|
+
)
|
10
14
|
from classiq.interface.generator.control_state import ControlState
|
11
15
|
from classiq.interface.generator.register_role import RegisterRole
|
12
16
|
from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
|
@@ -32,6 +36,11 @@ ParameterName = str
|
|
32
36
|
IOQubitMapping: TypeAlias = dict[str, tuple[int, ...]]
|
33
37
|
|
34
38
|
CLASSIQ_HIERARCHY_SEPARATOR: Literal["__"] = "__"
|
39
|
+
QASM_SEPARATOR = "_"
|
40
|
+
SPLIT_MARKER: str = "part"
|
41
|
+
PART_SUFFIX_REGEX = re.compile(
|
42
|
+
rf".+{QASM_SEPARATOR}{SPLIT_MARKER}{QASM_SEPARATOR}(\d+)$"
|
43
|
+
)
|
35
44
|
|
36
45
|
VISUALIZATION_HIDE_LIST = [
|
37
46
|
"apply_to_all",
|
@@ -74,7 +83,7 @@ class GeneratedRegister(pydantic.BaseModel):
|
|
74
83
|
@staticmethod
|
75
84
|
def demangle_name(name: str) -> str:
|
76
85
|
if is_captured_var_name(name):
|
77
|
-
|
86
|
+
name = demangle_capture_name(name)
|
78
87
|
return demangle_name(name)
|
79
88
|
|
80
89
|
|
@@ -168,9 +177,18 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
|
|
168
177
|
|
169
178
|
@property
|
170
179
|
def name(self) -> str:
|
171
|
-
if self.generated_function
|
172
|
-
|
173
|
-
|
180
|
+
generated_name = self.generated_function.name if self.generated_function else ""
|
181
|
+
# Temp fix for currently "supported" statements (same as for level_ property)
|
182
|
+
if generated_name in {StatementType.CONTROL, StatementType.POWER}:
|
183
|
+
return generated_name
|
184
|
+
if self.first_back_ref and isinstance(self.first_back_ref, QuantumFunctionCall):
|
185
|
+
name = generate_original_function_name(self.first_back_ref.func_name)
|
186
|
+
if part_match := PART_SUFFIX_REGEX.match(generated_name):
|
187
|
+
suffix = f" [{part_match.group(1)}]"
|
188
|
+
else:
|
189
|
+
suffix = ""
|
190
|
+
return f"{name}{suffix}"
|
191
|
+
return generated_name
|
174
192
|
|
175
193
|
@property
|
176
194
|
def first_back_ref(self) -> Optional[ConcreteQuantumStatement]:
|
@@ -40,7 +40,10 @@ from classiq.interface.generator.slice_parsing_utils import (
|
|
40
40
|
SLICING,
|
41
41
|
parse_io_slicing,
|
42
42
|
)
|
43
|
-
from classiq.interface.generator.synthesis_execution_parameter import
|
43
|
+
from classiq.interface.generator.synthesis_execution_parameter import (
|
44
|
+
ClassicalArg,
|
45
|
+
PydanticPowerType,
|
46
|
+
)
|
44
47
|
from classiq.interface.generator.user_defined_function_params import CustomFunction
|
45
48
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
46
49
|
from classiq.interface.helpers.hashable_pydantic_base_model import (
|
@@ -148,6 +151,10 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
148
151
|
description="The name of the function instance. "
|
149
152
|
"If not set, determined automatically.",
|
150
153
|
)
|
154
|
+
caller_parameters: Optional[list[str]] = pydantic.Field(default=None)
|
155
|
+
parameter_assignments: Optional[dict[str, ClassicalArg]] = pydantic.Field(
|
156
|
+
default=None
|
157
|
+
)
|
151
158
|
source_id: Optional[UUID] = pydantic.Field(default=None)
|
152
159
|
arithmetic_id: Optional[str] = pydantic.Field(default=None)
|
153
160
|
inverse_op_id: Optional[UUID] = pydantic.Field(default=None)
|
@@ -117,7 +117,6 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
117
117
|
instruction_set: Optional[QuantumInstructionSet] = None,
|
118
118
|
) -> quantum_code.QuantumCode:
|
119
119
|
initial_values = initial_values or self.initial_values
|
120
|
-
|
121
120
|
if instruction_set is not None:
|
122
121
|
code, syntax = (
|
123
122
|
self.program_circuit.get_code(instruction_set),
|
@@ -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"
|
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:
|
@@ -10,13 +10,6 @@ if TYPE_CHECKING:
|
|
10
10
|
from classiq.interface.model.statement_block import StatementBlock
|
11
11
|
|
12
12
|
|
13
|
-
class FunctionSynthesisData(pydantic.BaseModel):
|
14
|
-
should_synthesize_separately: bool = pydantic.Field(
|
15
|
-
default=False,
|
16
|
-
description="Whether the function should be synthesized separately.",
|
17
|
-
)
|
18
|
-
|
19
|
-
|
20
13
|
class NativeFunctionDefinition(NamedParamsQuantumFunctionDeclaration):
|
21
14
|
"""
|
22
15
|
Facilitates the creation of a user-defined composite function
|
@@ -28,6 +21,3 @@ class NativeFunctionDefinition(NamedParamsQuantumFunctionDeclaration):
|
|
28
21
|
body: "StatementBlock" = pydantic.Field(
|
29
22
|
default_factory=list, description="List of function calls to perform."
|
30
23
|
)
|
31
|
-
synthesis_data: FunctionSynthesisData = pydantic.Field(
|
32
|
-
default_factory=FunctionSynthesisData, deprecated=True, exclude=True
|
33
|
-
)
|
@@ -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:
|
@@ -11,13 +11,17 @@ from classiq.interface.generator.arith.register_user_input import (
|
|
11
11
|
RegisterUserInput,
|
12
12
|
)
|
13
13
|
from classiq.interface.generator.expressions.expression import Expression
|
14
|
-
from classiq.interface.generator.expressions.qmod_qarray_proxy import
|
15
|
-
|
14
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_qarray_proxy import (
|
15
|
+
QmodQArrayProxy,
|
16
|
+
)
|
17
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_qscalar_proxy import (
|
16
18
|
QmodQBitProxy,
|
17
19
|
QmodQNumProxy,
|
18
20
|
QmodQScalarProxy,
|
19
21
|
)
|
20
|
-
from classiq.interface.generator.expressions.qmod_sized_proxy import
|
22
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_sized_proxy import (
|
23
|
+
QmodSizedProxy,
|
24
|
+
)
|
21
25
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
22
26
|
from classiq.interface.model.handle_binding import HandleBinding
|
23
27
|
|
@@ -67,6 +71,10 @@ class QuantumType(HashableASTNode):
|
|
67
71
|
def is_evaluated(self) -> bool:
|
68
72
|
raise NotImplementedError
|
69
73
|
|
74
|
+
@property
|
75
|
+
def expressions(self) -> list[Expression]:
|
76
|
+
return []
|
77
|
+
|
70
78
|
|
71
79
|
class QuantumScalar(QuantumType):
|
72
80
|
def get_proxy(self, handle: "HandleBinding") -> QmodQScalarProxy:
|
@@ -170,6 +178,13 @@ class QuantumBitvector(QuantumType):
|
|
170
178
|
and self.element_type.is_evaluated
|
171
179
|
)
|
172
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
|
+
|
173
188
|
|
174
189
|
class QuantumNumeric(QuantumScalar):
|
175
190
|
kind: Literal["qnum"]
|
@@ -213,6 +228,14 @@ class QuantumNumeric(QuantumScalar):
|
|
213
228
|
0 if self.fraction_digits is None else self.fraction_digits.to_int_value()
|
214
229
|
)
|
215
230
|
|
231
|
+
@property
|
232
|
+
def is_qbit(self) -> bool:
|
233
|
+
return (
|
234
|
+
self.size_in_bits == 1
|
235
|
+
and self.fraction_digits_value == 0
|
236
|
+
and not self.sign_value
|
237
|
+
)
|
238
|
+
|
216
239
|
def _update_size_in_bits_from_declaration(self) -> None:
|
217
240
|
if self.size is not None and self.size.is_evaluated():
|
218
241
|
self._size_in_bits = self.size.to_int_value()
|
@@ -253,6 +276,17 @@ class QuantumNumeric(QuantumScalar):
|
|
253
276
|
self.fraction_digits is not None and not self.fraction_digits.is_evaluated()
|
254
277
|
)
|
255
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
|
+
|
256
290
|
|
257
291
|
class RegisterQuantumType(BaseModel):
|
258
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
|
@@ -12,9 +12,15 @@ from classiq.interface.generator.expressions.expression_types import (
|
|
12
12
|
ExpressionValue,
|
13
13
|
QmodStructInstance,
|
14
14
|
)
|
15
|
-
from classiq.interface.generator.expressions.qmod_qscalar_proxy import
|
16
|
-
|
17
|
-
|
15
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_qscalar_proxy import (
|
16
|
+
QmodQNumProxy,
|
17
|
+
)
|
18
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_qstruct_proxy import (
|
19
|
+
QmodQStructProxy,
|
20
|
+
)
|
21
|
+
from classiq.interface.generator.expressions.proxies.quantum.qmod_sized_proxy import (
|
22
|
+
QmodSizedProxy,
|
23
|
+
)
|
18
24
|
from classiq.interface.generator.expressions.type_proxy import TypeProxy
|
19
25
|
from classiq.interface.generator.functions.classical_function_declaration import (
|
20
26
|
ClassicalFunctionDeclaration,
|