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
@@ -0,0 +1,108 @@
|
|
1
|
+
from functools import singledispatchmethod
|
2
|
+
|
3
|
+
from classiq.interface.generator.functions.builtins.internal_operators import (
|
4
|
+
CONTROL_OPERATOR_NAME,
|
5
|
+
INVERT_OPERATOR_NAME,
|
6
|
+
WITHIN_APPLY_NAME,
|
7
|
+
)
|
8
|
+
from classiq.interface.model.bind_operation import BindOperation
|
9
|
+
from classiq.interface.model.classical_if import ClassicalIf
|
10
|
+
from classiq.interface.model.control import Control
|
11
|
+
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
12
|
+
from classiq.interface.model.invert import Invert
|
13
|
+
from classiq.interface.model.phase_operation import PhaseOperation
|
14
|
+
from classiq.interface.model.power import Power
|
15
|
+
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
16
|
+
QuantumAssignmentOperation,
|
17
|
+
)
|
18
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
19
|
+
from classiq.interface.model.quantum_statement import QuantumStatement
|
20
|
+
from classiq.interface.model.repeat import Repeat
|
21
|
+
from classiq.interface.model.variable_declaration_statement import (
|
22
|
+
VariableDeclarationStatement,
|
23
|
+
)
|
24
|
+
from classiq.interface.model.within_apply_operation import WithinApply
|
25
|
+
|
26
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
27
|
+
from classiq.model_expansions.quantum_operations import (
|
28
|
+
BindEmitter,
|
29
|
+
ClassicalIfEmitter,
|
30
|
+
QuantumFunctionCallEmitter,
|
31
|
+
RepeatEmitter,
|
32
|
+
VariableDeclarationStatementEmitter,
|
33
|
+
)
|
34
|
+
from classiq.model_expansions.quantum_operations.shallow_emitter import ShallowEmitter
|
35
|
+
|
36
|
+
|
37
|
+
class GenerativeInterpreter(BaseInterpreter):
|
38
|
+
@property
|
39
|
+
def is_shallow(self) -> bool:
|
40
|
+
return True
|
41
|
+
|
42
|
+
@singledispatchmethod
|
43
|
+
def emit(self, statement: QuantumStatement) -> None: # type:ignore[override]
|
44
|
+
raise NotImplementedError(f"Cannot emit {statement!r}")
|
45
|
+
|
46
|
+
@emit.register
|
47
|
+
def emit_quantum_function_call(self, call: QuantumFunctionCall) -> None:
|
48
|
+
QuantumFunctionCallEmitter(self).emit(call)
|
49
|
+
|
50
|
+
@emit.register
|
51
|
+
def emit_bind(self, bind: BindOperation) -> None:
|
52
|
+
BindEmitter(self).emit(bind)
|
53
|
+
|
54
|
+
@emit.register
|
55
|
+
def emit_quantum_assignment_operation(self, op: QuantumAssignmentOperation) -> None:
|
56
|
+
ShallowEmitter(
|
57
|
+
self, "assignment_operation", components=["expression", "result_var"]
|
58
|
+
).emit(op)
|
59
|
+
|
60
|
+
@emit.register
|
61
|
+
def emit_inplace_binary_operation(self, op: InplaceBinaryOperation) -> None:
|
62
|
+
ShallowEmitter(
|
63
|
+
self, "inplace_binary_operation", components=["target", "value"]
|
64
|
+
).emit(op)
|
65
|
+
|
66
|
+
@emit.register
|
67
|
+
def emit_variable_declaration(
|
68
|
+
self, variable_declaration: VariableDeclarationStatement
|
69
|
+
) -> None:
|
70
|
+
VariableDeclarationStatementEmitter(self).emit(variable_declaration)
|
71
|
+
|
72
|
+
@emit.register
|
73
|
+
def emit_classical_if(self, classical_if: ClassicalIf) -> None:
|
74
|
+
ClassicalIfEmitter(self).emit(classical_if)
|
75
|
+
|
76
|
+
@emit.register
|
77
|
+
def emit_within_apply(self, within_apply: WithinApply) -> None:
|
78
|
+
ShallowEmitter(
|
79
|
+
self,
|
80
|
+
WITHIN_APPLY_NAME,
|
81
|
+
components=["within", "apply", "compute", "action"],
|
82
|
+
).emit(within_apply)
|
83
|
+
|
84
|
+
@emit.register
|
85
|
+
def emit_invert(self, invert: Invert) -> None:
|
86
|
+
ShallowEmitter(self, INVERT_OPERATOR_NAME, components=["body"]).emit(invert)
|
87
|
+
|
88
|
+
@emit.register
|
89
|
+
def emit_repeat(self, repeat: Repeat) -> None:
|
90
|
+
RepeatEmitter(self).emit(repeat)
|
91
|
+
|
92
|
+
@emit.register
|
93
|
+
def emit_control(self, control: Control) -> None:
|
94
|
+
ShallowEmitter(
|
95
|
+
self,
|
96
|
+
CONTROL_OPERATOR_NAME,
|
97
|
+
components=["expression", "body", "else_block"],
|
98
|
+
).emit(control)
|
99
|
+
|
100
|
+
@emit.register
|
101
|
+
def emit_power(self, power: Power) -> None:
|
102
|
+
ShallowEmitter(self, CONTROL_OPERATOR_NAME, components=["power", "body"]).emit(
|
103
|
+
power
|
104
|
+
)
|
105
|
+
|
106
|
+
@emit.register
|
107
|
+
def emit_phase(self, phase: PhaseOperation) -> None:
|
108
|
+
ShallowEmitter(self, "phase", components=["expression", "theta"]).emit(phase)
|
@@ -1,98 +1,7 @@
|
|
1
|
-
from
|
2
|
-
from enum import IntEnum
|
3
|
-
from typing import ClassVar, Generic, Optional, TypeVar
|
1
|
+
from typing import Optional
|
4
2
|
|
5
3
|
from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
|
6
4
|
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
7
|
-
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
8
|
-
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
9
|
-
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
10
|
-
|
11
|
-
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
12
|
-
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
13
|
-
from classiq.qmod.model_state_container import QMODULE
|
14
|
-
|
15
|
-
DeclarationType = TypeVar(
|
16
|
-
"DeclarationType", EnumDeclaration, StructDeclaration, QStructDeclaration
|
17
|
-
)
|
18
|
-
|
19
|
-
|
20
|
-
class TypeTable(Generic[DeclarationType], ABC):
|
21
|
-
def __init__(self, user_types: list[DeclarationType]) -> None:
|
22
|
-
self._all_types: dict[str, DeclarationType] = self.builtins.copy()
|
23
|
-
for t in user_types:
|
24
|
-
assert t.name not in self._all_types # FIXME: issue user error (CAD-7856)
|
25
|
-
self._all_types[t.name] = t
|
26
|
-
|
27
|
-
@property
|
28
|
-
@abstractmethod
|
29
|
-
def builtins(self) -> dict[str, DeclarationType]:
|
30
|
-
pass
|
31
|
-
|
32
|
-
def __getitem__(self, key: str) -> DeclarationType:
|
33
|
-
return self._all_types[key]
|
34
|
-
|
35
|
-
def __setitem__(self, key: str, value: DeclarationType) -> None:
|
36
|
-
self._all_types[key] = value
|
37
|
-
|
38
|
-
def __contains__(self, key: str) -> bool:
|
39
|
-
return key in self._all_types
|
40
|
-
|
41
|
-
def all_types(self) -> dict[str, DeclarationType]:
|
42
|
-
return self._all_types
|
43
|
-
|
44
|
-
|
45
|
-
class EnumTable(TypeTable[EnumDeclaration]):
|
46
|
-
def __init__(self, user_types: list[EnumDeclaration]) -> None:
|
47
|
-
super().__init__(user_types)
|
48
|
-
|
49
|
-
@property
|
50
|
-
def builtins(self) -> dict[str, EnumDeclaration]:
|
51
|
-
return BUILTIN_ENUM_DECLARATIONS
|
52
|
-
|
53
|
-
@property
|
54
|
-
def enums(self) -> dict[str, IntEnum]:
|
55
|
-
return {
|
56
|
-
enum_decl.name: enum_decl.create_enum()
|
57
|
-
for enum_decl in self.all_types().values()
|
58
|
-
}
|
59
|
-
|
60
|
-
|
61
|
-
class StructTable(TypeTable[StructDeclaration]):
|
62
|
-
@property
|
63
|
-
def builtins(self) -> dict[str, StructDeclaration]:
|
64
|
-
return BUILTIN_STRUCT_DECLARATIONS
|
65
|
-
|
66
|
-
|
67
|
-
class QStructTable(TypeTable[QStructDeclaration]):
|
68
|
-
@property
|
69
|
-
def builtins(self) -> dict[str, QStructDeclaration]:
|
70
|
-
return {}
|
71
|
-
|
72
|
-
|
73
|
-
class SymbolTable:
|
74
|
-
enum_table: ClassVar[EnumTable] = EnumTable([])
|
75
|
-
type_table: ClassVar[StructTable] = StructTable([])
|
76
|
-
qstruct_table: ClassVar[QStructTable] = QStructTable([])
|
77
|
-
|
78
|
-
@classmethod
|
79
|
-
def init_user_enums(cls, user_enums: list[EnumDeclaration]) -> None:
|
80
|
-
cls.enum_table = EnumTable(user_enums)
|
81
|
-
QMODULE.enum_decls = {enum_decl.name: enum_decl for enum_decl in user_enums}
|
82
|
-
|
83
|
-
@classmethod
|
84
|
-
def init_user_types(cls, user_types: list[StructDeclaration]) -> None:
|
85
|
-
cls.type_table = StructTable(user_types)
|
86
|
-
QMODULE.type_decls = {
|
87
|
-
struct_decl.name: struct_decl for struct_decl in user_types
|
88
|
-
}
|
89
|
-
|
90
|
-
@classmethod
|
91
|
-
def init_user_qstructs(cls, user_qstructs: list[QStructDeclaration]) -> None:
|
92
|
-
cls.qstruct_table = QStructTable(user_qstructs)
|
93
|
-
QMODULE.qstruct_decls = {
|
94
|
-
qstruct_decl.name: qstruct_decl for qstruct_decl in user_qstructs
|
95
|
-
}
|
96
5
|
|
97
6
|
|
98
7
|
class HandleTable:
|
@@ -1,14 +1,5 @@
|
|
1
1
|
from classiq.model_expansions.quantum_operations.bind import BindEmitter
|
2
2
|
from classiq.model_expansions.quantum_operations.classicalif import ClassicalIfEmitter
|
3
|
-
from classiq.model_expansions.quantum_operations.control import ControlEmitter
|
4
|
-
from classiq.model_expansions.quantum_operations.inplace_binary_operation import (
|
5
|
-
InplaceBinaryOperationEmitter,
|
6
|
-
)
|
7
|
-
from classiq.model_expansions.quantum_operations.invert import InvertEmitter
|
8
|
-
from classiq.model_expansions.quantum_operations.power import PowerEmitter
|
9
|
-
from classiq.model_expansions.quantum_operations.quantum_assignment_operation import (
|
10
|
-
QuantumAssignmentOperationEmitter,
|
11
|
-
)
|
12
3
|
from classiq.model_expansions.quantum_operations.quantum_function_call import (
|
13
4
|
QuantumFunctionCallEmitter,
|
14
5
|
)
|
@@ -16,4 +7,3 @@ from classiq.model_expansions.quantum_operations.repeat import RepeatEmitter
|
|
16
7
|
from classiq.model_expansions.quantum_operations.variable_decleration import (
|
17
8
|
VariableDeclarationStatementEmitter,
|
18
9
|
)
|
19
|
-
from classiq.model_expansions.quantum_operations.within_apply import WithinApplyEmitter
|
@@ -55,11 +55,11 @@ from classiq.qmod.builtins.functions import allocate, free
|
|
55
55
|
from classiq.qmod.model_state_container import QMODULE
|
56
56
|
|
57
57
|
if TYPE_CHECKING:
|
58
|
-
from classiq.model_expansions.
|
58
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
59
59
|
|
60
60
|
|
61
61
|
class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSplitter):
|
62
|
-
def __init__(self, interpreter: "
|
62
|
+
def __init__(self, interpreter: "BaseInterpreter") -> None:
|
63
63
|
Emitter.__init__(self, interpreter)
|
64
64
|
VarSplitter.__init__(self, interpreter._builder.current_scope)
|
65
65
|
|
@@ -107,7 +107,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
|
|
107
107
|
new_positional_arg_decls = new_declaration.positional_arg_declarations
|
108
108
|
is_atomic = function.is_atomic
|
109
109
|
if (
|
110
|
-
self._interpreter.
|
110
|
+
self._interpreter.is_shallow
|
111
111
|
and self._is_function_purely_declarative(function)
|
112
112
|
and self._are_args_purely_declarative(args)
|
113
113
|
):
|
@@ -40,13 +40,13 @@ from classiq.model_expansions.visitors.variable_references import VarRefCollecto
|
|
40
40
|
from classiq.qmod.quantum_function import GenerativeQFunc
|
41
41
|
|
42
42
|
if TYPE_CHECKING:
|
43
|
-
from classiq.model_expansions.
|
43
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
44
44
|
|
45
45
|
QuantumStatementT = TypeVar("QuantumStatementT", bound=QuantumStatement)
|
46
46
|
|
47
47
|
|
48
48
|
class Emitter(Generic[QuantumStatementT]):
|
49
|
-
def __init__(self, interpreter: "
|
49
|
+
def __init__(self, interpreter: "BaseInterpreter") -> None:
|
50
50
|
self._interpreter = interpreter
|
51
51
|
|
52
52
|
self._machine_precision = self._interpreter._model.preferences.machine_precision
|
@@ -7,11 +7,11 @@ from classiq.model_expansions.quantum_operations.call_emitter import CallEmitter
|
|
7
7
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
8
8
|
|
9
9
|
if TYPE_CHECKING:
|
10
|
-
from classiq.model_expansions.
|
10
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
11
11
|
|
12
12
|
|
13
13
|
class QuantumFunctionCallEmitter(CallEmitter[QuantumFunctionCall]):
|
14
|
-
def __init__(self, interpreter: "
|
14
|
+
def __init__(self, interpreter: "BaseInterpreter") -> None:
|
15
15
|
super().__init__(interpreter)
|
16
16
|
self._model = self._interpreter._model
|
17
17
|
|
@@ -24,7 +24,7 @@ from classiq.model_expansions.transformers.ast_renamer import rename_variables
|
|
24
24
|
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
25
25
|
|
26
26
|
if TYPE_CHECKING:
|
27
|
-
from classiq.model_expansions.
|
27
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
28
28
|
|
29
29
|
|
30
30
|
QuantumOperationT = TypeVar("QuantumOperationT", bound=QuantumOperation)
|
@@ -38,7 +38,7 @@ _REVERSE_BLOCK_RENAMES = {rename: name for name, rename in _BLOCK_RENAMES.items(
|
|
38
38
|
class ShallowEmitter(Emitter[QuantumOperation]):
|
39
39
|
def __init__(
|
40
40
|
self,
|
41
|
-
interpreter: "
|
41
|
+
interpreter: "BaseInterpreter",
|
42
42
|
operation_name: str,
|
43
43
|
*,
|
44
44
|
components: Optional[list[str]] = None,
|
@@ -29,10 +29,13 @@ from classiq.model_expansions.evaluators.parameter_types import (
|
|
29
29
|
from classiq.model_expansions.expression_renamer import ExpressionRenamer
|
30
30
|
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
31
31
|
from classiq.qmod.builtins import BUILTIN_CONSTANTS
|
32
|
+
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
32
33
|
from classiq.qmod.builtins.functions import (
|
33
34
|
CORE_LIB_DECLS,
|
34
35
|
STD_QMOD_OPERATORS,
|
35
36
|
)
|
37
|
+
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
38
|
+
from classiq.qmod.model_state_container import QMODULE
|
36
39
|
from classiq.qmod.quantum_function import GenerativeQFunc
|
37
40
|
|
38
41
|
|
@@ -142,3 +145,8 @@ def init_top_level_scope(
|
|
142
145
|
add_functions_to_scope(model.functions, scope)
|
143
146
|
add_constants_to_scope(model.constants, scope)
|
144
147
|
_init_builtins_scope(scope)
|
148
|
+
|
149
|
+
|
150
|
+
def init_builtin_types() -> None:
|
151
|
+
QMODULE.enum_decls |= BUILTIN_ENUM_DECLARATIONS
|
152
|
+
QMODULE.type_decls |= BUILTIN_STRUCT_DECLARATIONS
|
@@ -32,7 +32,6 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
32
32
|
PositionalArg,
|
33
33
|
)
|
34
34
|
|
35
|
-
from classiq.model_expansions.model_tables import SymbolTable
|
36
35
|
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
37
36
|
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
38
37
|
from classiq.qmod.model_state_container import ModelStateContainer
|
@@ -60,7 +59,6 @@ class _PythonClassicalType(PythonClassicalType):
|
|
60
59
|
|
61
60
|
enum_decl = declaration_from_enum(py_type)
|
62
61
|
self.qmodule.enum_decls[py_type.__name__] = enum_decl
|
63
|
-
SymbolTable.enum_table[py_type.__name__] = enum_decl
|
64
62
|
|
65
63
|
def register_struct(self, py_type: type) -> None:
|
66
64
|
if (
|
@@ -77,7 +75,6 @@ class _PythonClassicalType(PythonClassicalType):
|
|
77
75
|
},
|
78
76
|
)
|
79
77
|
self.qmodule.type_decls[py_type.__name__] = struct_decl
|
80
|
-
SymbolTable.type_table[py_type.__name__] = struct_decl
|
81
78
|
|
82
79
|
|
83
80
|
def python_type_to_qmod(
|
classiq/qmod/generative.py
CHANGED
@@ -6,10 +6,10 @@ from classiq.interface.exceptions import ClassiqError
|
|
6
6
|
from classiq.interface.generator.expressions.expression import Expression
|
7
7
|
|
8
8
|
if TYPE_CHECKING:
|
9
|
-
from classiq.model_expansions.
|
9
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
10
10
|
|
11
11
|
_GENERATIVE_MODE: bool = False
|
12
|
-
_FRONTEND_INTERPRETER: Optional["
|
12
|
+
_FRONTEND_INTERPRETER: Optional["BaseInterpreter"] = None
|
13
13
|
|
14
14
|
|
15
15
|
def is_generative_mode() -> bool:
|
@@ -27,12 +27,12 @@ def generative_mode_context(generative: bool) -> Iterator[None]:
|
|
27
27
|
_GENERATIVE_MODE = previous
|
28
28
|
|
29
29
|
|
30
|
-
def set_frontend_interpreter(interpreter: "
|
30
|
+
def set_frontend_interpreter(interpreter: "BaseInterpreter") -> None:
|
31
31
|
global _FRONTEND_INTERPRETER
|
32
32
|
_FRONTEND_INTERPRETER = interpreter
|
33
33
|
|
34
34
|
|
35
|
-
def get_frontend_interpreter() -> "
|
35
|
+
def get_frontend_interpreter() -> "BaseInterpreter":
|
36
36
|
if _FRONTEND_INTERPRETER is None:
|
37
37
|
raise ClassiqError("Interpreter was not set")
|
38
38
|
return _FRONTEND_INTERPRETER
|
classiq/qmod/qfunc.py
CHANGED
@@ -20,8 +20,10 @@ def set_global_generative_switch() -> Iterator[None]:
|
|
20
20
|
global _GENERATIVE_SWITCH
|
21
21
|
previous = _GENERATIVE_SWITCH
|
22
22
|
_GENERATIVE_SWITCH = True
|
23
|
-
|
24
|
-
|
23
|
+
try:
|
24
|
+
yield
|
25
|
+
finally:
|
26
|
+
_GENERATIVE_SWITCH = previous
|
25
27
|
|
26
28
|
|
27
29
|
@overload
|
classiq/qmod/qmod_variable.py
CHANGED
@@ -66,7 +66,11 @@ from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
|
66
66
|
from classiq.qmod.quantum_callable import QCallable
|
67
67
|
from classiq.qmod.symbolic_expr import Symbolic, SymbolicExpr
|
68
68
|
from classiq.qmod.symbolic_type import SymbolicTypes
|
69
|
-
from classiq.qmod.utilities import
|
69
|
+
from classiq.qmod.utilities import (
|
70
|
+
get_source_ref,
|
71
|
+
unwrap_forward_ref,
|
72
|
+
version_portable_get_args,
|
73
|
+
)
|
70
74
|
|
71
75
|
|
72
76
|
def _is_input_output_typehint(type_hint: Any) -> bool:
|
@@ -330,8 +334,12 @@ class QNum(Generic[_P], QScalar):
|
|
330
334
|
"is_signed: bool | CBool, fraction_digits: int | CInt]"
|
331
335
|
)
|
332
336
|
if len(type_args) == 1:
|
333
|
-
return type_args[0], None, None
|
334
|
-
return
|
337
|
+
return unwrap_forward_ref(type_args[0]), None, None
|
338
|
+
return (
|
339
|
+
unwrap_forward_ref(type_args[0]),
|
340
|
+
unwrap_forward_ref(type_args[1]),
|
341
|
+
unwrap_forward_ref(type_args[2]),
|
342
|
+
)
|
335
343
|
|
336
344
|
@classmethod
|
337
345
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
@@ -492,16 +500,18 @@ class QArray(ArrayBase[_P], QVar):
|
|
492
500
|
type_args = version_portable_get_args(type_hint)
|
493
501
|
if len(type_args) == 0:
|
494
502
|
return QBit, None
|
503
|
+
first_arg = unwrap_forward_ref(type_args[0])
|
495
504
|
if len(type_args) == 1:
|
496
|
-
if isinstance(
|
497
|
-
return QBit,
|
498
|
-
return
|
505
|
+
if isinstance(first_arg, (str, int)):
|
506
|
+
return QBit, first_arg
|
507
|
+
return first_arg, None
|
499
508
|
if len(type_args) != 2:
|
500
509
|
raise ClassiqValueError(
|
501
510
|
"QArray receives two type arguments: QArray[element_type: QVar, "
|
502
511
|
"length: int | CInt]"
|
503
512
|
)
|
504
|
-
|
513
|
+
second_arg = unwrap_forward_ref(type_args[1])
|
514
|
+
return cast(tuple[type[QVar], Any], (first_arg, second_arg))
|
505
515
|
|
506
516
|
@classmethod
|
507
517
|
def to_qmod_quantum_type(cls, type_hint: Any) -> QuantumType:
|
@@ -608,8 +618,6 @@ class QStruct(QVar):
|
|
608
618
|
)
|
609
619
|
|
610
620
|
def _add_qmod_qstruct(self, *, qmodule: ModelStateContainer) -> None:
|
611
|
-
from classiq.model_expansions.model_tables import SymbolTable
|
612
|
-
|
613
621
|
if self._struct_name in qmodule.qstruct_decls:
|
614
622
|
return
|
615
623
|
|
@@ -618,7 +626,6 @@ class QStruct(QVar):
|
|
618
626
|
fields={name: qvar.get_qmod_type() for name, qvar in self._fields.items()},
|
619
627
|
)
|
620
628
|
qmodule.qstruct_decls[self._struct_name] = struct_decl
|
621
|
-
SymbolTable.qstruct_table[self._struct_name] = struct_decl
|
622
629
|
|
623
630
|
|
624
631
|
def create_qvar_for_port_decl(port: AnonPortDeclaration, name: str) -> QVar:
|
classiq/qmod/quantum_function.py
CHANGED
@@ -153,7 +153,9 @@ class QFunc(BaseQFunc):
|
|
153
153
|
return model
|
154
154
|
|
155
155
|
def _create_generative_model(self, model_stub: Model) -> Model:
|
156
|
-
from classiq.model_expansions.
|
156
|
+
from classiq.model_expansions.interpreters.generative_interpreter import (
|
157
|
+
GenerativeInterpreter,
|
158
|
+
)
|
157
159
|
from classiq.qmod.semantics.static_semantics_visitor import (
|
158
160
|
resolve_function_calls,
|
159
161
|
)
|
@@ -167,9 +169,7 @@ class QFunc(BaseQFunc):
|
|
167
169
|
for gen_func in generative_functions
|
168
170
|
},
|
169
171
|
)
|
170
|
-
interpreter =
|
171
|
-
model_stub, generative_functions, is_normalizer=True, is_shallow=True
|
172
|
-
)
|
172
|
+
interpreter = GenerativeInterpreter(model_stub, generative_functions)
|
173
173
|
set_frontend_interpreter(interpreter)
|
174
174
|
return interpreter.expand()
|
175
175
|
|
@@ -244,6 +244,8 @@ class ExternalQFunc(QTerminalCallable):
|
|
244
244
|
|
245
245
|
|
246
246
|
class GenerativeQFunc(BaseQFunc):
|
247
|
+
FRAME_DEPTH = 3
|
248
|
+
|
247
249
|
def __init__(
|
248
250
|
self,
|
249
251
|
py_callable: Callable,
|
classiq/qmod/utilities.py
CHANGED
@@ -5,7 +5,7 @@ import keyword
|
|
5
5
|
import sys
|
6
6
|
from enum import Enum as PythonEnum
|
7
7
|
from types import FrameType
|
8
|
-
from typing import Any, Literal, Optional, get_args, get_origin, overload
|
8
|
+
from typing import Any, ForwardRef, Literal, Optional, get_args, get_origin, overload
|
9
9
|
|
10
10
|
from classiq.interface.source_reference import SourceReference
|
11
11
|
|
@@ -97,3 +97,9 @@ def qmod_val_to_expr_str(val: Any) -> str:
|
|
97
97
|
return f"{type(val).__name__}.{val.name}"
|
98
98
|
|
99
99
|
return str(val)
|
100
|
+
|
101
|
+
|
102
|
+
def unwrap_forward_ref(x: Any) -> Any:
|
103
|
+
if isinstance(x, ForwardRef):
|
104
|
+
return x.__forward_arg__
|
105
|
+
return x
|