classiq 0.70.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/interface/_version.py +1 -1
- 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 +4 -2
- 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/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 +1 -1
- classiq/interface/generator/quantum_function_call.py +8 -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/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/model_expansions/capturing/captured_vars.py +156 -34
- classiq/model_expansions/evaluators/classical_type_inference.py +70 -0
- classiq/model_expansions/evaluators/parameter_types.py +14 -0
- 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 +3 -4
- 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/scope.py +0 -8
- classiq/model_expansions/scope_initialization.py +20 -28
- classiq/qmod/__init__.py +3 -1
- classiq/qmod/declaration_inferrer.py +52 -24
- 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-0.70.0.dist-info → classiq-0.71.0.dist-info}/METADATA +1 -1
- {classiq-0.70.0.dist-info → classiq-0.71.0.dist-info}/RECORD +56 -52
- {classiq-0.70.0.dist-info → classiq-0.71.0.dist-info}/WHEEL +0 -0
classiq/interface/_version.py
CHANGED
@@ -10,6 +10,7 @@ from classiq.interface.generator.generated_circuit_data import (
|
|
10
10
|
OperationLevel,
|
11
11
|
StatementType,
|
12
12
|
)
|
13
|
+
from classiq.interface.model.block import Block
|
13
14
|
from classiq.interface.model.statement_block import ConcreteQuantumStatement
|
14
15
|
|
15
16
|
ParameterValue = Union[float, int, str, None]
|
@@ -84,6 +85,9 @@ def get_back_refs(
|
|
84
85
|
) -> list[ConcreteQuantumStatement]:
|
85
86
|
back_refs: list[ConcreteQuantumStatement] = []
|
86
87
|
while (node := debug_info.node) is not None:
|
88
|
+
# For backwards compatibility, we make sure that the back_ref is not a block
|
89
|
+
# Remove this check when we start saving blocks in the debug info collection.
|
90
|
+
assert not isinstance(node, Block)
|
87
91
|
back_refs.insert(0, node)
|
88
92
|
if node.back_ref is None:
|
89
93
|
break
|
@@ -20,6 +20,3 @@ BOOLEAN_LITERALS = {"True", "False"}
|
|
20
20
|
FORBIDDEN_LITERALS: set[str] = set(keyword.kwlist) - SUPPORTED_FUNC_NAMES
|
21
21
|
CPARAM_EXECUTION_SUFFIX: Final[str] = "_param"
|
22
22
|
RESERVED_EXPRESSIONS: frozenset[str] = frozenset({"i"})
|
23
|
-
CPARAM_EXECUTION_SUFFIX_PATTERN = (
|
24
|
-
rf"({CPARAM_EXECUTION_SUFFIX}|^({'|'.join(RESERVED_EXPRESSIONS)}))(_\d+)*$"
|
25
|
-
)
|
@@ -21,10 +21,12 @@ RuntimeConstant = Union[
|
|
21
21
|
list,
|
22
22
|
bool,
|
23
23
|
QmodStructInstance,
|
24
|
-
QmodSizedProxy,
|
25
24
|
TypeProxy,
|
26
25
|
HandleIdentifier,
|
26
|
+
]
|
27
|
+
Proxies = Union[
|
28
|
+
QmodSizedProxy,
|
27
29
|
ClassicalProxy,
|
28
30
|
]
|
29
31
|
RuntimeExpression = Union[Expr, Boolean]
|
30
|
-
ExpressionValue = Union[RuntimeConstant, RuntimeExpression]
|
32
|
+
ExpressionValue = Union[RuntimeConstant, Proxies, RuntimeExpression]
|
@@ -38,6 +38,10 @@ class ClassicalArrayProxy(NonSymbolicExpr, ClassicalProxy):
|
|
38
38
|
def type_name(self) -> str:
|
39
39
|
return "Array"
|
40
40
|
|
41
|
+
@property
|
42
|
+
def length(self) -> int:
|
43
|
+
return self._length
|
44
|
+
|
41
45
|
def __getitem__(self, key: Union[slice, int, Integer]) -> ClassicalProxy:
|
42
46
|
return (
|
43
47
|
self._get_slice(key) if isinstance(key, slice) else self._get_subscript(key)
|
@@ -17,11 +17,15 @@ class ClassicalStructProxy(NonSymbolicExpr, ClassicalProxy):
|
|
17
17
|
super().__init__(handle)
|
18
18
|
self._decl = decl
|
19
19
|
|
20
|
+
@property
|
21
|
+
def struct_declaration(self) -> "StructDeclaration":
|
22
|
+
return self._decl
|
23
|
+
|
20
24
|
@property
|
21
25
|
def fields(self) -> Mapping[str, "ExpressionValue"]:
|
22
26
|
return {
|
23
27
|
field_name: field_type.get_classical_proxy(
|
24
|
-
FieldHandleBinding(base_handle=self.handle,
|
28
|
+
FieldHandleBinding(base_handle=self.handle, field=field_name)
|
25
29
|
)
|
26
30
|
for field_name, field_type in self._decl.variables.items()
|
27
31
|
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
2
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_array_proxy import (
|
3
|
+
ClassicalArrayProxy,
|
4
|
+
)
|
5
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
6
|
+
ClassicalProxy,
|
7
|
+
)
|
8
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_scalar_proxy import (
|
9
|
+
ClassicalScalarProxy,
|
10
|
+
)
|
11
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_struct_proxy import (
|
12
|
+
ClassicalStructProxy,
|
13
|
+
)
|
14
|
+
from classiq.interface.generator.functions.classical_type import (
|
15
|
+
ClassicalArray,
|
16
|
+
ClassicalType,
|
17
|
+
)
|
18
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
19
|
+
|
20
|
+
|
21
|
+
def get_proxy_type(proxy: ClassicalProxy) -> ClassicalType:
|
22
|
+
if isinstance(proxy, ClassicalScalarProxy):
|
23
|
+
classical_type = proxy._classical_type
|
24
|
+
elif isinstance(proxy, ClassicalArrayProxy):
|
25
|
+
classical_type = ClassicalArray(
|
26
|
+
element_type=proxy._element_type, size=proxy.length
|
27
|
+
)
|
28
|
+
elif isinstance(proxy, ClassicalStructProxy):
|
29
|
+
classical_type = TypeName(name=proxy._decl.name)
|
30
|
+
else:
|
31
|
+
raise ClassiqInternalExpansionError(
|
32
|
+
f"Unrecognized classical proxy {type(proxy).__name__}"
|
33
|
+
)
|
34
|
+
return classical_type
|
@@ -1,9 +1,11 @@
|
|
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
|
8
|
+
from classiq.interface.generator.expressions.expression import Expression
|
7
9
|
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
8
10
|
ClassicalProxy,
|
9
11
|
)
|
@@ -97,6 +99,12 @@ class TypeName(ClassicalType, QuantumType):
|
|
97
99
|
def has_classical_struct_decl(self) -> bool:
|
98
100
|
return self._classical_struct_decl is not None
|
99
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
|
+
|
100
108
|
def set_classical_struct_decl(self, decl: "StructDeclaration") -> None:
|
101
109
|
self._classical_struct_decl = decl
|
102
110
|
|
@@ -105,6 +113,14 @@ class TypeName(ClassicalType, QuantumType):
|
|
105
113
|
raise ClassiqExpansionError(f"Type {self.name!r} is undefined")
|
106
114
|
return ClassicalStructProxy(handle, self._classical_struct_decl)
|
107
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
|
+
|
108
124
|
|
109
125
|
class Enum(TypeName):
|
110
126
|
pass
|
@@ -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)
|
@@ -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:
|
@@ -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
|