classiq 0.89.0__py3-none-any.whl → 0.91.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.
Potentially problematic release.
This version of classiq might be problematic. Click here for more details.
- classiq/__init__.py +1 -0
- classiq/_internals/api_wrapper.py +16 -32
- classiq/analyzer/show_interactive_hack.py +26 -1
- classiq/applications/chemistry/chemistry_model_constructor.py +14 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +9 -6
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -2
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +16 -8
- classiq/evaluators/classical_expression.py +63 -41
- classiq/evaluators/control.py +31 -52
- classiq/evaluators/expression_evaluator.py +31 -127
- classiq/evaluators/parameter_types.py +200 -104
- classiq/evaluators/qmod_annotated_expression.py +3 -1
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +10 -3
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +12 -37
- classiq/evaluators/qmod_node_evaluators/constant_evaluation.py +8 -17
- classiq/evaluators/qmod_node_evaluators/measurement_evaluation.py +1 -1
- classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +7 -1
- classiq/evaluators/qmod_node_evaluators/name_evaluation.py +0 -1
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +9 -1
- classiq/evaluators/qmod_node_evaluators/utils.py +33 -8
- classiq/evaluators/qmod_type_inference/classical_type_inference.py +4 -7
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +1 -25
- classiq/interface/analyzer/result.py +4 -0
- classiq/interface/chemistry/ground_state_problem.py +16 -2
- classiq/interface/executor/optimizer_preferences.py +0 -112
- classiq/interface/executor/result.py +22 -3
- classiq/interface/generator/application_apis/chemistry_declarations.py +3 -1
- classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -7
- classiq/interface/generator/expressions/evaluated_expression.py +3 -13
- classiq/interface/generator/expressions/expression_types.py +10 -22
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +3 -8
- classiq/interface/generator/expressions/proxies/classical/classical_proxy.py +2 -2
- classiq/interface/generator/expressions/proxies/classical/classical_struct_proxy.py +1 -2
- classiq/interface/generator/functions/classical_type.py +2 -5
- classiq/interface/generator/functions/concrete_types.py +1 -1
- classiq/interface/generator/functions/type_name.py +0 -12
- classiq/interface/generator/generated_circuit_data.py +4 -0
- classiq/interface/generator/preferences/qasm_to_qmod_params.py +14 -0
- classiq/interface/helpers/model_normalizer.py +0 -6
- classiq/interface/ide/visual_model.py +1 -0
- classiq/interface/model/handle_binding.py +1 -1
- classiq/interface/model/port_declaration.py +2 -1
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +16 -12
- classiq/interface/model/quantum_type.py +1 -40
- classiq/interface/server/routes.py +2 -3
- classiq/model_expansions/capturing/captured_vars.py +10 -3
- classiq/model_expansions/closure.py +8 -0
- classiq/model_expansions/function_builder.py +18 -2
- classiq/model_expansions/interpreters/base_interpreter.py +84 -22
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +1 -11
- classiq/model_expansions/interpreters/generative_interpreter.py +67 -20
- classiq/model_expansions/quantum_operations/allocate.py +92 -21
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +28 -27
- classiq/model_expansions/quantum_operations/call_emitter.py +32 -26
- classiq/model_expansions/quantum_operations/classical_var_emitter.py +6 -2
- classiq/model_expansions/quantum_operations/emitter.py +50 -70
- classiq/model_expansions/quantum_operations/expression_evaluator.py +62 -7
- classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -5
- classiq/model_expansions/quantum_operations/variable_decleration.py +16 -11
- classiq/model_expansions/scope.py +39 -41
- classiq/model_expansions/scope_initialization.py +3 -6
- classiq/model_expansions/transformers/model_renamer.py +35 -64
- classiq/model_expansions/transformers/type_modifier_inference.py +6 -6
- classiq/model_expansions/utils/handles_collector.py +7 -0
- classiq/model_expansions/visitors/boolean_expression_transformers.py +7 -31
- classiq/model_expansions/visitors/symbolic_param_inference.py +9 -3
- classiq/open_library/functions/state_preparation.py +3 -3
- classiq/qmod/builtins/functions/allocation.py +8 -8
- classiq/qmod/builtins/functions/arithmetic.py +1 -1
- classiq/qmod/builtins/functions/chemistry.py +64 -0
- classiq/qmod/builtins/functions/exponentiation.py +7 -13
- classiq/qmod/builtins/functions/qsvm.py +1 -1
- classiq/qmod/builtins/operations.py +42 -10
- classiq/qmod/generative.py +2 -4
- classiq/qmod/native/pretty_printer.py +1 -1
- classiq/qmod/pretty_print/pretty_printer.py +1 -1
- classiq/qmod/qmod_constant.py +1 -1
- classiq/qmod/qmod_parameter.py +2 -2
- classiq/qmod/qmod_variable.py +18 -19
- classiq/qmod/quantum_expandable.py +1 -1
- classiq/qmod/semantics/error_manager.py +34 -15
- classiq/qmod/symbolic.py +15 -4
- classiq/qmod/utilities.py +4 -1
- classiq/synthesis.py +38 -3
- classiq/visualization.py +1 -1
- {classiq-0.89.0.dist-info → classiq-0.91.0.dist-info}/METADATA +1 -1
- {classiq-0.89.0.dist-info → classiq-0.91.0.dist-info}/RECORD +89 -107
- classiq/evaluators/arg_type_match.py +0 -168
- classiq/evaluators/classical_type_inference.py +0 -121
- classiq/interface/combinatorial_optimization/optimization_problem.py +0 -17
- classiq/interface/combinatorial_optimization/result.py +0 -9
- classiq/interface/generator/expressions/handle_identifier.py +0 -6
- classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +0 -41
- classiq/interface/generator/expressions/proxies/quantum/__init__.py +0 -0
- classiq/interface/generator/expressions/proxies/quantum/qmod_qarray_proxy.py +0 -80
- classiq/interface/generator/expressions/proxies/quantum/qmod_qscalar_proxy.py +0 -77
- classiq/interface/generator/expressions/proxies/quantum/qmod_qstruct_proxy.py +0 -38
- classiq/interface/generator/expressions/proxies/quantum/qmod_sized_proxy.py +0 -39
- classiq/interface/generator/expressions/type_proxy.py +0 -10
- classiq/model_expansions/atomic_expression_functions_defs.py +0 -413
- classiq/model_expansions/model_tables.py +0 -18
- classiq/model_expansions/sympy_conversion/__init__.py +0 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +0 -181
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +0 -132
- classiq/model_expansions/transformers/ast_renamer.py +0 -26
- classiq/model_expansions/utils/sympy_utils.py +0 -24
- {classiq-0.89.0.dist-info → classiq-0.91.0.dist-info}/WHEEL +0 -0
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
from
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
from typing import TYPE_CHECKING, Union
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
from sympy.logic.boolalg import Boolean
|
|
4
|
+
import sympy
|
|
5
5
|
|
|
6
|
-
from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
|
|
7
|
-
from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
|
|
8
|
-
AnyClassicalValue,
|
|
9
|
-
)
|
|
10
|
-
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
|
11
|
-
ClassicalProxy,
|
|
12
|
-
)
|
|
13
6
|
from classiq.interface.generator.expressions.proxies.classical.qmod_struct_instance import (
|
|
14
7
|
QmodStructInstance,
|
|
15
8
|
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
from classiq.interface.generator.expressions.type_proxy import TypeProxy
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
20
12
|
|
|
21
13
|
RuntimeConstant = Union[
|
|
22
14
|
int,
|
|
23
15
|
float,
|
|
24
16
|
list,
|
|
25
17
|
bool,
|
|
18
|
+
complex,
|
|
19
|
+
IntEnum,
|
|
26
20
|
QmodStructInstance,
|
|
27
|
-
|
|
28
|
-
HandleIdentifier,
|
|
29
|
-
]
|
|
30
|
-
Proxies = Union[
|
|
31
|
-
QmodSizedProxy,
|
|
32
|
-
ClassicalProxy,
|
|
21
|
+
sympy.Basic,
|
|
33
22
|
]
|
|
34
|
-
|
|
35
|
-
ExpressionValue = Union[RuntimeConstant, Proxies, RuntimeExpression]
|
|
23
|
+
ExpressionValue = Union[RuntimeConstant, "QmodAnnotatedExpression"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from collections.abc import Mapping
|
|
2
|
-
from typing import TYPE_CHECKING, Any, Union
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
3
3
|
|
|
4
4
|
import sympy
|
|
5
5
|
from sympy import Integer
|
|
@@ -8,9 +8,6 @@ from typing_extensions import TypeGuard
|
|
|
8
8
|
from classiq.interface.exceptions import ClassiqIndexError
|
|
9
9
|
from classiq.interface.generator.expressions.expression import Expression
|
|
10
10
|
from classiq.interface.generator.expressions.non_symbolic_expr import NonSymbolicExpr
|
|
11
|
-
from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
|
|
12
|
-
AnyClassicalValue,
|
|
13
|
-
)
|
|
14
11
|
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
|
15
12
|
ClassicalProxy,
|
|
16
13
|
)
|
|
@@ -28,8 +25,6 @@ if TYPE_CHECKING:
|
|
|
28
25
|
|
|
29
26
|
|
|
30
27
|
def _is_int(val: Any) -> TypeGuard[Union[int, sympy.Basic]]:
|
|
31
|
-
if isinstance(val, AnyClassicalValue):
|
|
32
|
-
return False
|
|
33
28
|
if isinstance(val, sympy.Basic):
|
|
34
29
|
return val.is_Number
|
|
35
30
|
return isinstance(val, int)
|
|
@@ -99,7 +94,7 @@ class ClassicalArrayProxy(ClassicalSequenceProxy):
|
|
|
99
94
|
self,
|
|
100
95
|
handle: HandleBinding,
|
|
101
96
|
element_type: "ConcreteClassicalType",
|
|
102
|
-
length: "ExpressionValue",
|
|
97
|
+
length: Optional["ExpressionValue"],
|
|
103
98
|
) -> None:
|
|
104
99
|
super().__init__(handle)
|
|
105
100
|
self._element_type = element_type
|
|
@@ -108,7 +103,7 @@ class ClassicalArrayProxy(ClassicalSequenceProxy):
|
|
|
108
103
|
self._length = length
|
|
109
104
|
|
|
110
105
|
@property
|
|
111
|
-
def length(self) -> "ExpressionValue":
|
|
106
|
+
def length(self) -> Optional["ExpressionValue"]:
|
|
112
107
|
return self._length
|
|
113
108
|
|
|
114
109
|
def get_slice_at(self, start: Any, stop: Any) -> ClassicalProxy:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from collections.abc import Mapping
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
2
|
+
from typing import TYPE_CHECKING, Union
|
|
3
3
|
|
|
4
4
|
if TYPE_CHECKING:
|
|
5
5
|
from classiq.interface.generator.expressions.expression_types import ExpressionValue
|
|
@@ -18,7 +18,7 @@ class ClassicalProxy:
|
|
|
18
18
|
return str(self.handle)
|
|
19
19
|
|
|
20
20
|
@property
|
|
21
|
-
def fields(self) -> Mapping[str, "ExpressionValue"]:
|
|
21
|
+
def fields(self) -> Mapping[str, Union["ExpressionValue", "ClassicalProxy"]]:
|
|
22
22
|
raise NotImplementedError
|
|
23
23
|
|
|
24
24
|
@property
|
|
@@ -8,7 +8,6 @@ from classiq.interface.generator.expressions.proxies.classical.classical_proxy i
|
|
|
8
8
|
from classiq.interface.model.handle_binding import FieldHandleBinding, HandleBinding
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
-
from classiq.interface.generator.expressions.expression_types import ExpressionValue
|
|
12
11
|
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
|
13
12
|
|
|
14
13
|
|
|
@@ -22,7 +21,7 @@ class ClassicalStructProxy(NonSymbolicExpr, ClassicalProxy):
|
|
|
22
21
|
return self._decl
|
|
23
22
|
|
|
24
23
|
@property
|
|
25
|
-
def fields(self) -> Mapping[str,
|
|
24
|
+
def fields(self) -> Mapping[str, ClassicalProxy]:
|
|
26
25
|
return {
|
|
27
26
|
field_name: field_type.get_classical_proxy(
|
|
28
27
|
FieldHandleBinding(base_handle=self.handle, field=field_name)
|
|
@@ -9,9 +9,6 @@ from classiq.interface.ast_node import HashableASTNode
|
|
|
9
9
|
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
|
10
10
|
from classiq.interface.generator.expressions.expression import Expression
|
|
11
11
|
from classiq.interface.generator.expressions.expression_types import ExpressionValue
|
|
12
|
-
from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
|
|
13
|
-
AnyClassicalValue,
|
|
14
|
-
)
|
|
15
12
|
from classiq.interface.generator.expressions.proxies.classical.classical_array_proxy import (
|
|
16
13
|
ClassicalArrayProxy,
|
|
17
14
|
ClassicalTupleProxy,
|
|
@@ -163,9 +160,9 @@ class ClassicalArray(ClassicalType):
|
|
|
163
160
|
return self.length.to_int_value()
|
|
164
161
|
|
|
165
162
|
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
|
166
|
-
length: ExpressionValue
|
|
163
|
+
length: Optional[ExpressionValue]
|
|
167
164
|
if self.length is None:
|
|
168
|
-
length =
|
|
165
|
+
length = None
|
|
169
166
|
elif not self.length.is_evaluated():
|
|
170
167
|
raise ClassiqInternalExpansionError(
|
|
171
168
|
"Classical list length is not evaluated"
|
|
@@ -47,7 +47,7 @@ PythonClassicalPydanticTypes = (Enum,)
|
|
|
47
47
|
|
|
48
48
|
ConcreteQuantumType = Annotated[
|
|
49
49
|
Union[QuantumBit, QuantumBitvector, QuantumNumeric, TypeName],
|
|
50
|
-
Field(discriminator="kind"
|
|
50
|
+
Field(discriminator="kind"),
|
|
51
51
|
]
|
|
52
52
|
QuantumBitvector.model_rebuild()
|
|
53
53
|
TypeName.model_rebuild()
|
|
@@ -15,9 +15,6 @@ from classiq.interface.generator.expressions.proxies.classical.classical_scalar_
|
|
|
15
15
|
from classiq.interface.generator.expressions.proxies.classical.classical_struct_proxy import (
|
|
16
16
|
ClassicalStructProxy,
|
|
17
17
|
)
|
|
18
|
-
from classiq.interface.generator.expressions.proxies.quantum.qmod_qstruct_proxy import (
|
|
19
|
-
QmodQStructProxy,
|
|
20
|
-
)
|
|
21
18
|
from classiq.interface.generator.functions.classical_type import (
|
|
22
19
|
ClassicalType,
|
|
23
20
|
)
|
|
@@ -59,15 +56,6 @@ class TypeName(ClassicalType, QuantumType):
|
|
|
59
56
|
field_type.size_in_bits for field_type in fields_types
|
|
60
57
|
)
|
|
61
58
|
|
|
62
|
-
def get_proxy(self, handle: "HandleBinding") -> "QmodQStructProxy":
|
|
63
|
-
from classiq.interface.generator.expressions.proxies.quantum.qmod_qstruct_proxy import (
|
|
64
|
-
QmodQStructProxy,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
return QmodQStructProxy(
|
|
68
|
-
handle=handle, struct_name=self.name, fields=self.fields
|
|
69
|
-
)
|
|
70
|
-
|
|
71
59
|
@property
|
|
72
60
|
def qmod_type_name(self) -> str:
|
|
73
61
|
return self.name
|
|
@@ -17,6 +17,7 @@ from classiq.interface.generator.register_role import RegisterRole
|
|
|
17
17
|
from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
|
|
18
18
|
ExecutionData,
|
|
19
19
|
)
|
|
20
|
+
from classiq.interface.model.block import Block
|
|
20
21
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
21
22
|
ArithmeticOperationKind,
|
|
22
23
|
)
|
|
@@ -210,10 +211,13 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
|
|
|
210
211
|
)
|
|
211
212
|
name_with_suffix = self.add_suffix_from_generated_name(generated_name, name)
|
|
212
213
|
return name_with_suffix
|
|
214
|
+
if isinstance(back_ref, Block) and back_ref.label is not None:
|
|
215
|
+
return back_ref.label
|
|
213
216
|
|
|
214
217
|
statement_kind: str = back_ref.kind
|
|
215
218
|
if isinstance(back_ref, ArithmeticOperation):
|
|
216
219
|
statement_kind = back_ref.operation_kind.value
|
|
220
|
+
|
|
217
221
|
return self.add_suffix_from_generated_name(
|
|
218
222
|
generated_name, STATEMENTS_NAME[statement_kind]
|
|
219
223
|
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
from classiq.interface.analyzer.result import QasmCode
|
|
4
|
+
from classiq.interface.enum_utils import StrEnum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class QmodFormat(StrEnum):
|
|
8
|
+
NATIVE = "native"
|
|
9
|
+
PYTHON = "python"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class QasmToQmodParams(BaseModel):
|
|
13
|
+
qasm: QasmCode
|
|
14
|
+
qmod_format: QmodFormat
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import ast
|
|
2
1
|
from typing import Any
|
|
3
2
|
|
|
4
3
|
from classiq.interface.ast_node import ASTNode
|
|
@@ -10,8 +9,6 @@ from classiq.interface.generator.visitor import Transformer, Visitor
|
|
|
10
9
|
from classiq.interface.model.model import Model
|
|
11
10
|
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
|
12
11
|
|
|
13
|
-
from classiq.model_expansions.transformers.model_renamer import ExprNormalizer
|
|
14
|
-
|
|
15
12
|
|
|
16
13
|
class ModelNormalizer(Visitor):
|
|
17
14
|
def visit(self, node: Any) -> None:
|
|
@@ -28,9 +25,6 @@ class ModelNormalizer(Visitor):
|
|
|
28
25
|
model.functions.sort(key=lambda x: x.name)
|
|
29
26
|
self.generic_visit(model)
|
|
30
27
|
|
|
31
|
-
def visit_Expression(self, expr: Expression) -> None:
|
|
32
|
-
expr.expr = ast.unparse(ExprNormalizer().visit(ast.parse(expr.expr)))
|
|
33
|
-
|
|
34
28
|
def visit_AnonPortDeclaration(self, decl: AnonPortDeclaration) -> None:
|
|
35
29
|
decl.type_modifier = TypeModifier.Mutable
|
|
36
30
|
|
|
@@ -171,6 +171,7 @@ class Operation(pydantic.BaseModel):
|
|
|
171
171
|
expanded: bool = pydantic.Field(default=False)
|
|
172
172
|
show_expanded_label: bool = pydantic.Field(default=False)
|
|
173
173
|
is_low_level_fallback: bool = pydantic.Field(default=False)
|
|
174
|
+
is_measurement: bool = pydantic.Field(default=False)
|
|
174
175
|
|
|
175
176
|
model_config = ConfigDict(frozen=True)
|
|
176
177
|
|
|
@@ -349,7 +349,7 @@ class FieldHandleBinding(NestedHandleBinding):
|
|
|
349
349
|
|
|
350
350
|
@property
|
|
351
351
|
def qmod_expr(self) -> str:
|
|
352
|
-
return f"
|
|
352
|
+
return f"{self.base_handle.qmod_expr}.{self.field}"
|
|
353
353
|
|
|
354
354
|
@property
|
|
355
355
|
def identifier(self) -> str:
|
|
@@ -13,10 +13,11 @@ from classiq.interface.generator.functions.type_modifier import (
|
|
|
13
13
|
)
|
|
14
14
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
|
15
15
|
from classiq.interface.model.parameter import Parameter
|
|
16
|
+
from classiq.interface.model.quantum_type import QuantumBitvector
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class AnonPortDeclaration(Parameter):
|
|
19
|
-
quantum_type: ConcreteQuantumType
|
|
20
|
+
quantum_type: ConcreteQuantumType = pydantic.Field(default_factory=QuantumBitvector)
|
|
20
21
|
direction: PortDeclarationDirection
|
|
21
22
|
kind: Literal["PortDeclaration"]
|
|
22
23
|
type_modifier: TypeModifier
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
from collections.abc import Mapping, Sequence
|
|
2
|
-
from typing import Literal
|
|
3
|
-
|
|
4
|
-
from pydantic import PrivateAttr
|
|
2
|
+
from typing import Literal, cast
|
|
5
3
|
|
|
6
4
|
from classiq.interface.enum_utils import StrEnum
|
|
7
5
|
from classiq.interface.generator.arith.arithmetic import (
|
|
8
6
|
ARITHMETIC_EXPRESSION_RESULT_NAME,
|
|
9
|
-
compute_arithmetic_result_type,
|
|
10
7
|
)
|
|
11
8
|
from classiq.interface.model.handle_binding import (
|
|
12
9
|
ConcreteHandleBinding,
|
|
@@ -18,6 +15,9 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
|
18
15
|
from classiq.interface.model.quantum_statement import HandleMetadata
|
|
19
16
|
from classiq.interface.model.quantum_type import QuantumType
|
|
20
17
|
|
|
18
|
+
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
19
|
+
from classiq.model_expansions.arithmetic import NumericAttributes
|
|
20
|
+
|
|
21
21
|
|
|
22
22
|
class ArithmeticOperationKind(StrEnum):
|
|
23
23
|
InplaceAdd = "inplace_add"
|
|
@@ -29,7 +29,7 @@ class ArithmeticOperation(QuantumAssignmentOperation):
|
|
|
29
29
|
kind: Literal["ArithmeticOperation"]
|
|
30
30
|
|
|
31
31
|
operation_kind: ArithmeticOperationKind
|
|
32
|
-
|
|
32
|
+
classical_assignment: bool = False
|
|
33
33
|
|
|
34
34
|
@property
|
|
35
35
|
def is_inplace(self) -> bool:
|
|
@@ -44,16 +44,20 @@ class ArithmeticOperation(QuantumAssignmentOperation):
|
|
|
44
44
|
machine_precision: int,
|
|
45
45
|
) -> None:
|
|
46
46
|
super().initialize_var_types(var_types, machine_precision)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
expr_val = self.expression.value.value
|
|
48
|
+
if isinstance(expr_val, QmodAnnotatedExpression):
|
|
49
|
+
self._result_type = expr_val.get_quantum_type(expr_val.root)
|
|
50
|
+
else:
|
|
51
|
+
self._result_type = NumericAttributes.from_constant(
|
|
52
|
+
cast(float, expr_val), machine_precision
|
|
53
|
+
).to_quantum_numeric()
|
|
50
54
|
|
|
51
55
|
@property
|
|
52
56
|
def wiring_inouts(
|
|
53
57
|
self,
|
|
54
58
|
) -> Mapping[str, ConcreteHandleBinding]:
|
|
55
59
|
inouts = dict(super().wiring_inouts)
|
|
56
|
-
if self.is_inplace and not self.
|
|
60
|
+
if self.is_inplace and not self.classical_assignment:
|
|
57
61
|
inouts[self.result_name()] = self.result_var
|
|
58
62
|
return inouts
|
|
59
63
|
|
|
@@ -63,7 +67,7 @@ class ArithmeticOperation(QuantumAssignmentOperation):
|
|
|
63
67
|
HandleMetadata(handle=handle, readable_location="in an expression")
|
|
64
68
|
for handle in self.var_handles
|
|
65
69
|
]
|
|
66
|
-
if self.is_inplace and not self.
|
|
70
|
+
if self.is_inplace and not self.classical_assignment:
|
|
67
71
|
inouts.append(
|
|
68
72
|
HandleMetadata(
|
|
69
73
|
handle=self.result_var,
|
|
@@ -74,13 +78,13 @@ class ArithmeticOperation(QuantumAssignmentOperation):
|
|
|
74
78
|
|
|
75
79
|
@property
|
|
76
80
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
|
77
|
-
if self.is_inplace or self.
|
|
81
|
+
if self.is_inplace or self.classical_assignment:
|
|
78
82
|
return {}
|
|
79
83
|
return super().wiring_outputs
|
|
80
84
|
|
|
81
85
|
@property
|
|
82
86
|
def readable_outputs(self) -> Sequence[HandleMetadata]:
|
|
83
|
-
if self.is_inplace or self.
|
|
87
|
+
if self.is_inplace or self.classical_assignment:
|
|
84
88
|
return []
|
|
85
89
|
return [
|
|
86
90
|
HandleMetadata(
|
|
@@ -15,20 +15,8 @@ from classiq.interface.generator.arith.register_user_input import (
|
|
|
15
15
|
RegisterUserInput,
|
|
16
16
|
)
|
|
17
17
|
from classiq.interface.generator.expressions.expression import Expression
|
|
18
|
-
from classiq.interface.generator.expressions.proxies.quantum.qmod_qarray_proxy import (
|
|
19
|
-
QmodQArrayProxy,
|
|
20
|
-
)
|
|
21
|
-
from classiq.interface.generator.expressions.proxies.quantum.qmod_qscalar_proxy import (
|
|
22
|
-
QmodQBitProxy,
|
|
23
|
-
QmodQNumProxy,
|
|
24
|
-
QmodQScalarProxy,
|
|
25
|
-
)
|
|
26
|
-
from classiq.interface.generator.expressions.proxies.quantum.qmod_sized_proxy import (
|
|
27
|
-
QmodSizedProxy,
|
|
28
|
-
)
|
|
29
18
|
from classiq.interface.helpers.custom_pydantic_types import PydanticFloatTuple
|
|
30
19
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
|
31
|
-
from classiq.interface.model.handle_binding import HandleBinding
|
|
32
20
|
|
|
33
21
|
if TYPE_CHECKING:
|
|
34
22
|
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
|
@@ -59,9 +47,6 @@ class QuantumType(HashableASTNode):
|
|
|
59
47
|
def minimal_size_in_bits(self) -> int:
|
|
60
48
|
raise NotImplementedError
|
|
61
49
|
|
|
62
|
-
def get_proxy(self, handle: "HandleBinding") -> QmodSizedProxy:
|
|
63
|
-
return QmodSizedProxy(handle=handle, size=self.size_in_bits)
|
|
64
|
-
|
|
65
50
|
@property
|
|
66
51
|
def qmod_type_name(self) -> str:
|
|
67
52
|
raise NotImplementedError
|
|
@@ -95,9 +80,6 @@ class QuantumType(HashableASTNode):
|
|
|
95
80
|
|
|
96
81
|
|
|
97
82
|
class QuantumScalar(QuantumType):
|
|
98
|
-
def get_proxy(self, handle: "HandleBinding") -> QmodQScalarProxy:
|
|
99
|
-
return QmodQScalarProxy(handle, size=self.size_in_bits)
|
|
100
|
-
|
|
101
83
|
@property
|
|
102
84
|
def has_sign(self) -> bool:
|
|
103
85
|
raise NotImplementedError
|
|
@@ -147,9 +129,6 @@ class QuantumBit(QuantumScalar):
|
|
|
147
129
|
def qmod_type_name(self) -> str:
|
|
148
130
|
return "QBit"
|
|
149
131
|
|
|
150
|
-
def get_proxy(self, handle: "HandleBinding") -> QmodQBitProxy:
|
|
151
|
-
return QmodQBitProxy(handle)
|
|
152
|
-
|
|
153
132
|
@property
|
|
154
133
|
def type_name(self) -> str:
|
|
155
134
|
return "Quantum bit"
|
|
@@ -233,16 +212,6 @@ class QuantumBitvector(QuantumType):
|
|
|
233
212
|
assert self.length is not None
|
|
234
213
|
return self.length.to_int_value()
|
|
235
214
|
|
|
236
|
-
def get_proxy(self, handle: "HandleBinding") -> QmodQArrayProxy:
|
|
237
|
-
element_size = self.element_type.size_in_bits
|
|
238
|
-
assert self.size_in_bits % element_size == 0
|
|
239
|
-
return QmodQArrayProxy(
|
|
240
|
-
handle,
|
|
241
|
-
self.element_type,
|
|
242
|
-
element_size,
|
|
243
|
-
self.size_in_bits // element_size,
|
|
244
|
-
)
|
|
245
|
-
|
|
246
215
|
@property
|
|
247
216
|
def qmod_type_name(self) -> str:
|
|
248
217
|
element_type = [self.element_type.qmod_type_name]
|
|
@@ -382,14 +351,6 @@ class QuantumNumeric(QuantumScalar):
|
|
|
382
351
|
):
|
|
383
352
|
self._size_in_bits = self.size.to_int_value()
|
|
384
353
|
|
|
385
|
-
def get_proxy(self, handle: "HandleBinding") -> QmodQNumProxy:
|
|
386
|
-
return QmodQNumProxy(
|
|
387
|
-
handle,
|
|
388
|
-
size=self.size_in_bits,
|
|
389
|
-
fraction_digits=self.fraction_digits_value,
|
|
390
|
-
is_signed=self.sign_value,
|
|
391
|
-
)
|
|
392
|
-
|
|
393
354
|
@property
|
|
394
355
|
def qmod_type_name(self) -> str:
|
|
395
356
|
if (
|
|
@@ -532,7 +493,7 @@ class QuantumNumeric(QuantumScalar):
|
|
|
532
493
|
|
|
533
494
|
|
|
534
495
|
class RegisterQuantumType(BaseModel):
|
|
535
|
-
quantum_types: "ConcreteQuantumType"
|
|
496
|
+
quantum_types: "ConcreteQuantumType" = Field(default_factory=QuantumBitvector)
|
|
536
497
|
size: int = Field(default=1)
|
|
537
498
|
|
|
538
499
|
@property
|
|
@@ -44,9 +44,6 @@ TASKS_VISUALIZE_SUFFIX = TASKS_SUFFIX + "/visualize"
|
|
|
44
44
|
TASKS_VISUAL_MODEL_SUFFIX = TASKS_SUFFIX + "/visual_model"
|
|
45
45
|
TASKS_SOLVE_SUFFIX = "/tasks/solve"
|
|
46
46
|
|
|
47
|
-
CHEMISTRY_QMOD_PATH = "/generate_model/chemistry/qmod"
|
|
48
|
-
|
|
49
|
-
|
|
50
47
|
TASK_TRAIN_SUFFIX = TASKS_SUFFIX + "/train"
|
|
51
48
|
TASK_TEST_SUFFIX = TASKS_SUFFIX + "/test"
|
|
52
49
|
TASK_PREDICT_SUFFIX = TASKS_SUFFIX + "/predict"
|
|
@@ -75,6 +72,8 @@ CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX = "/execution_input"
|
|
|
75
72
|
CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_FULL = (
|
|
76
73
|
CONVERSION_PREFIX + CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX
|
|
77
74
|
)
|
|
75
|
+
QASM_TO_QMOD_SUFFIX = "/qasm_to_qmod"
|
|
76
|
+
QASM_TO_QMOD_FULL_PATH = CONVERSION_PREFIX + QASM_TO_QMOD_SUFFIX
|
|
78
77
|
|
|
79
78
|
STATIC_SEMANTICS_VALIDATION_PATH = "/validate_static_semantics"
|
|
80
79
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ast
|
|
1
2
|
import dataclasses
|
|
2
3
|
from collections.abc import Sequence
|
|
3
4
|
from dataclasses import dataclass, field
|
|
@@ -41,6 +42,7 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
|
41
42
|
VariableDeclarationStatement,
|
|
42
43
|
)
|
|
43
44
|
|
|
45
|
+
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
44
46
|
from classiq.model_expansions.capturing.mangling_utils import (
|
|
45
47
|
demangle_handle,
|
|
46
48
|
mangle_captured_var_name,
|
|
@@ -60,9 +62,11 @@ UNINITIALIZED_VAR_MESSAGE = "Variable '{}' should be initialized here"
|
|
|
60
62
|
|
|
61
63
|
def _get_symbol_expr(symbol: str, classical_type: ClassicalType) -> Expression:
|
|
62
64
|
expr = Expression(expr=symbol)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
65
|
+
expr_val = QmodAnnotatedExpression(ast.Name(id=symbol))
|
|
66
|
+
expr_val.set_type(expr_val.root, classical_type)
|
|
67
|
+
expr_val.set_var(expr_val.root, HandleBinding(name=symbol))
|
|
68
|
+
expr_val.lock()
|
|
69
|
+
expr._evaluated_expr = EvaluatedExpression(value=expr_val)
|
|
66
70
|
return expr
|
|
67
71
|
|
|
68
72
|
|
|
@@ -550,6 +554,9 @@ class CapturedVars:
|
|
|
550
554
|
],
|
|
551
555
|
)
|
|
552
556
|
|
|
557
|
+
def get_captured_classical_vars(self) -> list[str]:
|
|
558
|
+
return [var.name for var in self._captured_classical_vars]
|
|
559
|
+
|
|
553
560
|
def get_captured_parameters(self) -> list[PositionalArg]:
|
|
554
561
|
decls: list[PositionalArg]
|
|
555
562
|
decls = [
|
|
@@ -11,6 +11,7 @@ from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
|
|
11
11
|
from classiq.interface.model.quantum_function_declaration import (
|
|
12
12
|
NamedParamsQuantumFunctionDeclaration,
|
|
13
13
|
PositionalArg,
|
|
14
|
+
QuantumOperandDeclaration,
|
|
14
15
|
)
|
|
15
16
|
from classiq.interface.model.quantum_lambda_function import QuantumCallable
|
|
16
17
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
|
@@ -111,6 +112,13 @@ class FunctionClosure(Closure):
|
|
|
111
112
|
def emit(self) -> QuantumCallable:
|
|
112
113
|
return self.name
|
|
113
114
|
|
|
115
|
+
def as_operand_declaration(self, is_list: bool) -> QuantumOperandDeclaration:
|
|
116
|
+
return QuantumOperandDeclaration(
|
|
117
|
+
name=self.name,
|
|
118
|
+
positional_arg_declarations=self.positional_arg_declarations,
|
|
119
|
+
is_list=is_list,
|
|
120
|
+
)
|
|
121
|
+
|
|
114
122
|
|
|
115
123
|
@dataclass(frozen=True)
|
|
116
124
|
class GenerativeFunctionClosure(GenerativeClosure, FunctionClosure):
|
|
@@ -3,7 +3,10 @@ from contextlib import contextmanager
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from typing import Generic, Optional, TypeVar
|
|
5
5
|
|
|
6
|
-
from classiq.interface.exceptions import
|
|
6
|
+
from classiq.interface.exceptions import (
|
|
7
|
+
ClassiqExpansionError,
|
|
8
|
+
ClassiqInternalExpansionError,
|
|
9
|
+
)
|
|
7
10
|
from classiq.interface.generator.compiler_keywords import (
|
|
8
11
|
EXPANDED_KEYWORD,
|
|
9
12
|
LAMBDA_KEYWORD,
|
|
@@ -31,7 +34,7 @@ from classiq.model_expansions.capturing.captured_vars import (
|
|
|
31
34
|
validate_end_state,
|
|
32
35
|
)
|
|
33
36
|
from classiq.model_expansions.closure import Closure, FunctionClosure
|
|
34
|
-
from classiq.model_expansions.scope import Scope
|
|
37
|
+
from classiq.model_expansions.scope import ClassicalSymbol, Scope
|
|
35
38
|
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
|
36
39
|
|
|
37
40
|
ClosureType = TypeVar("ClosureType", bound=Closure)
|
|
@@ -190,6 +193,8 @@ class OperationBuilder:
|
|
|
190
193
|
self.current_function
|
|
191
194
|
).set_propagated()
|
|
192
195
|
validate_captured_directions(captured_vars)
|
|
196
|
+
else:
|
|
197
|
+
self._validate_no_captured_runtime_params(captured_vars)
|
|
193
198
|
if len(self._operations) < 2:
|
|
194
199
|
return
|
|
195
200
|
parent_block = self._operations[-2].blocks[self._blocks[-1]]
|
|
@@ -231,3 +236,14 @@ class OperationBuilder:
|
|
|
231
236
|
raise ClassiqInternalExpansionError("Could not allocate function name")
|
|
232
237
|
|
|
233
238
|
return name
|
|
239
|
+
|
|
240
|
+
def _validate_no_captured_runtime_params(self, captured_vars: CapturedVars) -> None:
|
|
241
|
+
if any(
|
|
242
|
+
var in self.current_scope
|
|
243
|
+
and isinstance(self.current_scope[var].value, ClassicalSymbol)
|
|
244
|
+
for var in captured_vars.get_captured_classical_vars()
|
|
245
|
+
):
|
|
246
|
+
raise ClassiqExpansionError(
|
|
247
|
+
"Runtime classical variables can only be declared and used at the "
|
|
248
|
+
"function's top scope"
|
|
249
|
+
)
|