classiq 0.33.0__py3-none-any.whl → 0.35.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/_internals/api_wrapper.py +61 -23
- classiq/_internals/client.py +4 -1
- classiq/_internals/jobs.py +9 -2
- classiq/applications_model_constructors/grover_model_constructor.py +1 -1
- classiq/execution/__init__.py +9 -2
- classiq/execution/jobs.py +84 -11
- classiq/executor.py +3 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +17 -0
- classiq/interface/backend/pydantic_backend.py +8 -0
- classiq/interface/backend/quantum_backend_providers.py +15 -1
- classiq/interface/chemistry/ground_state_problem.py +1 -1
- classiq/interface/chemistry/operator.py +198 -0
- classiq/interface/execution/jobs.py +28 -0
- classiq/interface/executor/execution_request.py +2 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +1 -0
- classiq/interface/generator/arith/arithmetic_param_getters.py +12 -0
- classiq/interface/generator/arith/binary_ops.py +34 -0
- classiq/interface/generator/expressions/expression.py +3 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +12 -2
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -0
- classiq/interface/generator/function_params.py +4 -0
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +2 -2
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +42 -105
- classiq/interface/generator/generated_circuit.py +8 -44
- classiq/interface/generator/generated_circuit_data.py +2 -11
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/generator/quantum_function_call.py +1 -1
- classiq/interface/hardware.py +2 -0
- classiq/interface/ide/show.py +1 -14
- classiq/interface/model/bind_operation.py +10 -0
- classiq/interface/model/handle_binding.py +18 -0
- classiq/interface/model/model.py +12 -3
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +2 -1
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +9 -6
- classiq/interface/model/quantum_function_call.py +9 -339
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/server/routes.py +8 -6
- classiq/model/function_handler.pyi +86 -85
- classiq/qmod/__init__.py +2 -2
- classiq/qmod/builtins/__init__.py +8 -0
- classiq/{interface/model/clients/qmod/qmod_builtins.py → qmod/builtins/functions.py} +46 -165
- classiq/qmod/builtins/operations.py +19 -0
- classiq/qmod/builtins/structs.py +128 -0
- classiq/qmod/declaration_inferrer.py +34 -17
- classiq/qmod/model_state_container.py +6 -3
- classiq/qmod/qmod_parameter.py +24 -8
- classiq/qmod/qmod_variable.py +4 -4
- classiq/qmod/quantum_callable.py +2 -2
- classiq/qmod/quantum_expandable.py +7 -3
- classiq/qmod/quantum_function.py +9 -9
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/METADATA +1 -1
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/RECORD +56 -55
- classiq/interface/model/clients/qmod/__init__.py +0 -0
- classiq/interface/model/semantics.py +0 -15
- classiq/qmod/qmod_builtins.py +0 -4
- /classiq/interface/{model/clients → execution}/__init__.py +0 -0
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
# This file was generated automatically - do not edit manually
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from classiq.qmod.qmod_struct import QStruct
|
6
|
+
|
7
|
+
|
8
|
+
@QStruct
|
9
|
+
class PauliTerm:
|
10
|
+
pauli: List[int]
|
11
|
+
coefficient: float
|
12
|
+
|
13
|
+
|
14
|
+
@QStruct
|
15
|
+
class MoleculeProblem:
|
16
|
+
mapping: int
|
17
|
+
z2_symmetries: bool
|
18
|
+
molecule: "Molecule"
|
19
|
+
freeze_core: bool
|
20
|
+
remove_orbitals: List[int]
|
21
|
+
|
22
|
+
|
23
|
+
@QStruct
|
24
|
+
class Molecule:
|
25
|
+
atoms: List["ChemistryAtom"]
|
26
|
+
spin: int
|
27
|
+
charge: int
|
28
|
+
|
29
|
+
|
30
|
+
@QStruct
|
31
|
+
class ChemistryAtom:
|
32
|
+
element: int
|
33
|
+
position: "Position"
|
34
|
+
|
35
|
+
|
36
|
+
@QStruct
|
37
|
+
class Position:
|
38
|
+
x: float
|
39
|
+
y: float
|
40
|
+
z: float
|
41
|
+
|
42
|
+
|
43
|
+
@QStruct
|
44
|
+
class FockHamiltonianProblem:
|
45
|
+
mapping: int
|
46
|
+
z2_symmetries: bool
|
47
|
+
terms: List["LadderTerm"]
|
48
|
+
num_particles: List[int]
|
49
|
+
|
50
|
+
|
51
|
+
@QStruct
|
52
|
+
class LadderTerm:
|
53
|
+
coefficient: float
|
54
|
+
ops: List["LadderOp"]
|
55
|
+
|
56
|
+
|
57
|
+
@QStruct
|
58
|
+
class LadderOp:
|
59
|
+
op: int
|
60
|
+
index: int
|
61
|
+
|
62
|
+
|
63
|
+
@QStruct
|
64
|
+
class CombinatorialOptimizationSolution:
|
65
|
+
probability: float
|
66
|
+
cost: float
|
67
|
+
solution: List[int]
|
68
|
+
count: int
|
69
|
+
|
70
|
+
|
71
|
+
@QStruct
|
72
|
+
class GaussianModel:
|
73
|
+
num_qubits: int
|
74
|
+
normal_max_value: float
|
75
|
+
default_probabilities: List[float]
|
76
|
+
rhos: List[float]
|
77
|
+
loss: List[int]
|
78
|
+
min_loss: int
|
79
|
+
|
80
|
+
|
81
|
+
@QStruct
|
82
|
+
class LogNormalModel:
|
83
|
+
num_qubits: int
|
84
|
+
mu: float
|
85
|
+
sigma: float
|
86
|
+
|
87
|
+
|
88
|
+
@QStruct
|
89
|
+
class FinanceFunction:
|
90
|
+
f: int
|
91
|
+
threshold: float
|
92
|
+
larger: bool
|
93
|
+
polynomial_degree: int
|
94
|
+
use_chebyshev_polynomial_approximation: bool
|
95
|
+
tail_probability: float
|
96
|
+
|
97
|
+
|
98
|
+
@QStruct
|
99
|
+
class QsvmResult:
|
100
|
+
test_score: float
|
101
|
+
predicted_labels: List[float]
|
102
|
+
|
103
|
+
|
104
|
+
@QStruct
|
105
|
+
class QSVMFeatureMapPauli:
|
106
|
+
feature_dimension: int
|
107
|
+
reps: int
|
108
|
+
entanglement: int
|
109
|
+
alpha: float
|
110
|
+
paulis: List[List[int]]
|
111
|
+
|
112
|
+
|
113
|
+
__all__ = [
|
114
|
+
"PauliTerm",
|
115
|
+
"MoleculeProblem",
|
116
|
+
"Molecule",
|
117
|
+
"ChemistryAtom",
|
118
|
+
"Position",
|
119
|
+
"FockHamiltonianProblem",
|
120
|
+
"LadderTerm",
|
121
|
+
"LadderOp",
|
122
|
+
"CombinatorialOptimizationSolution",
|
123
|
+
"GaussianModel",
|
124
|
+
"LogNormalModel",
|
125
|
+
"FinanceFunction",
|
126
|
+
"QsvmResult",
|
127
|
+
"QSVMFeatureMapPauli",
|
128
|
+
]
|
@@ -44,7 +44,9 @@ def _version_portable_get_args(py_type: type) -> tuple:
|
|
44
44
|
return get_args(py_type)[0]
|
45
45
|
|
46
46
|
|
47
|
-
def _python_type_to_qmod(
|
47
|
+
def _python_type_to_qmod(
|
48
|
+
py_type: type, *, qmodule: ModelStateContainer
|
49
|
+
) -> Optional[ConcreteClassicalType]:
|
48
50
|
if py_type == int:
|
49
51
|
return Integer()
|
50
52
|
elif py_type == float:
|
@@ -52,7 +54,9 @@ def _python_type_to_qmod(py_type: type) -> Optional[ConcreteClassicalType]:
|
|
52
54
|
elif py_type == bool:
|
53
55
|
return Bool()
|
54
56
|
elif get_origin(py_type) == list:
|
55
|
-
return ClassicalList(
|
57
|
+
return ClassicalList(
|
58
|
+
element_type=_python_type_to_qmod(get_args(py_type)[0], qmodule=qmodule)
|
59
|
+
)
|
56
60
|
elif get_origin(py_type) == Array:
|
57
61
|
array_args = _version_portable_get_args(py_type)
|
58
62
|
if len(array_args) != 2:
|
@@ -60,36 +64,41 @@ def _python_type_to_qmod(py_type: type) -> Optional[ConcreteClassicalType]:
|
|
60
64
|
"Array accepts two generic parameters in the form 'Array[<element-type>, <size>]'"
|
61
65
|
)
|
62
66
|
return ClassicalArray(
|
63
|
-
element_type=_python_type_to_qmod(array_args[0]),
|
67
|
+
element_type=_python_type_to_qmod(array_args[0], qmodule=qmodule),
|
64
68
|
size=get_type_hint_expr(array_args[1]),
|
65
69
|
)
|
66
70
|
elif inspect.isclass(py_type) and issubclass(py_type, QStructBase):
|
67
|
-
_add_qmod_struct(py_type)
|
71
|
+
_add_qmod_struct(py_type, qmodule=qmodule)
|
68
72
|
return Struct(name=py_type.__name__)
|
69
73
|
return None
|
70
74
|
|
71
75
|
|
72
|
-
def _add_qmod_struct(
|
76
|
+
def _add_qmod_struct(
|
77
|
+
py_type: Type[QStructBase], *, qmodule: ModelStateContainer
|
78
|
+
) -> None:
|
73
79
|
if (
|
74
80
|
py_type.__name__ in StructDeclaration.BUILTIN_STRUCT_DECLARATIONS
|
75
|
-
or py_type.__name__ in
|
81
|
+
or py_type.__name__ in qmodule.type_decls.keys()
|
76
82
|
):
|
77
83
|
return
|
78
84
|
|
79
|
-
|
85
|
+
qmodule.type_decls[py_type.__name__] = StructDeclaration(
|
80
86
|
name=py_type.__name__,
|
81
87
|
variables={
|
82
|
-
f.name: _python_type_to_qmod(f.type
|
88
|
+
f.name: _python_type_to_qmod(f.type, qmodule=qmodule)
|
89
|
+
for f in dataclasses.fields(py_type)
|
83
90
|
},
|
84
91
|
)
|
85
92
|
|
86
93
|
|
87
|
-
def _extract_param_decl(
|
94
|
+
def _extract_param_decl(
|
95
|
+
name: str, py_type: Any, *, qmodule: ModelStateContainer
|
96
|
+
) -> ClassicalParameterDeclaration:
|
88
97
|
if len(get_args(py_type)) != 1:
|
89
98
|
raise ValueError("QParam takes exactly one generic argument")
|
90
99
|
py_type = get_args(py_type)[0]
|
91
100
|
return ClassicalParameterDeclaration(
|
92
|
-
name=name, classical_type=_python_type_to_qmod(py_type)
|
101
|
+
name=name, classical_type=_python_type_to_qmod(py_type, qmodule=qmodule)
|
93
102
|
)
|
94
103
|
|
95
104
|
|
@@ -106,35 +115,43 @@ def _extract_port_decl(name: str, py_type: Any) -> PortDeclaration:
|
|
106
115
|
)
|
107
116
|
|
108
117
|
|
109
|
-
def _extract_operand_decl(
|
118
|
+
def _extract_operand_decl(
|
119
|
+
name: str, py_type: Any, qmodule: ModelStateContainer
|
120
|
+
) -> QuantumOperandDeclaration:
|
110
121
|
qc_args = _version_portable_get_args(py_type)
|
111
122
|
arg_dict = {
|
112
123
|
OPERAND_ARG_NAME.format(i=i): arg_type for i, arg_type in enumerate(qc_args)
|
113
124
|
}
|
114
125
|
return QuantumOperandDeclaration(
|
115
126
|
name=name,
|
116
|
-
positional_arg_declarations=_extract_positional_args(arg_dict),
|
127
|
+
positional_arg_declarations=_extract_positional_args(arg_dict, qmodule=qmodule),
|
117
128
|
)
|
118
129
|
|
119
130
|
|
120
|
-
def _extract_positional_args(
|
131
|
+
def _extract_positional_args(
|
132
|
+
args: Dict[str, Any], qmodule: ModelStateContainer
|
133
|
+
) -> List[PositionalArg]:
|
121
134
|
result: List[PositionalArg] = []
|
122
135
|
for name, py_type in args.items():
|
123
136
|
if name == "return":
|
124
137
|
continue
|
125
138
|
name = unmangle_keyword(name)
|
126
139
|
if get_origin(py_type) is QParam:
|
127
|
-
result.append(_extract_param_decl(name, py_type))
|
140
|
+
result.append(_extract_param_decl(name, py_type, qmodule=qmodule))
|
128
141
|
elif QVar.from_type_hint(py_type) is not None:
|
129
142
|
result.append(_extract_port_decl(name, py_type))
|
130
143
|
else:
|
131
144
|
assert get_origin(py_type) or py_type is QCallable
|
132
|
-
result.append(_extract_operand_decl(name, py_type))
|
145
|
+
result.append(_extract_operand_decl(name, py_type, qmodule=qmodule))
|
133
146
|
return result
|
134
147
|
|
135
148
|
|
136
|
-
def infer_func_decl(
|
149
|
+
def infer_func_decl(
|
150
|
+
py_func: Callable, qmodule: ModelStateContainer
|
151
|
+
) -> QuantumFunctionDeclaration:
|
137
152
|
return QuantumFunctionDeclaration(
|
138
153
|
name=unmangle_keyword(py_func.__name__),
|
139
|
-
positional_arg_declarations=_extract_positional_args(
|
154
|
+
positional_arg_declarations=_extract_positional_args(
|
155
|
+
py_func.__annotations__, qmodule=qmodule
|
156
|
+
),
|
140
157
|
)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Dict
|
2
2
|
|
3
3
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
4
4
|
|
@@ -6,5 +6,8 @@ from classiq import StructDeclaration
|
|
6
6
|
|
7
7
|
|
8
8
|
class ModelStateContainer:
|
9
|
-
|
10
|
-
|
9
|
+
type_decls: Dict[str, StructDeclaration]
|
10
|
+
native_defs: Dict[str, NativeFunctionDefinition]
|
11
|
+
|
12
|
+
|
13
|
+
QMODULE = ModelStateContainer()
|
classiq/qmod/qmod_parameter.py
CHANGED
@@ -34,8 +34,13 @@ class QParamScalar(QParam, Symbol):
|
|
34
34
|
|
35
35
|
class QParamList(QParam):
|
36
36
|
def __init__(
|
37
|
-
self,
|
37
|
+
self,
|
38
|
+
expr_str: str,
|
39
|
+
list_type: Union[ClassicalList, ClassicalArray],
|
40
|
+
*,
|
41
|
+
qmodule: ModelStateContainer,
|
38
42
|
) -> None:
|
43
|
+
self._qmodule = qmodule
|
39
44
|
self._expr_str = expr_str
|
40
45
|
self._list_type = list_type
|
41
46
|
|
@@ -44,7 +49,9 @@ class QParamList(QParam):
|
|
44
49
|
|
45
50
|
def __getitem__(self, key: Any) -> QParam:
|
46
51
|
return create_param(
|
47
|
-
f"{self._expr_str}[{str(key)}]",
|
52
|
+
f"{self._expr_str}[{str(key)}]",
|
53
|
+
self._list_type.element_type,
|
54
|
+
qmodule=self._qmodule,
|
48
55
|
)
|
49
56
|
|
50
57
|
def __len__(self) -> int:
|
@@ -57,7 +64,10 @@ class QParamList(QParam):
|
|
57
64
|
|
58
65
|
|
59
66
|
class QParamStruct(QParam):
|
60
|
-
def __init__(
|
67
|
+
def __init__(
|
68
|
+
self, expr_str: str, struct_type: Struct, *, qmodule: ModelStateContainer
|
69
|
+
) -> None:
|
70
|
+
self._qmodule = qmodule
|
61
71
|
self._expr_str = expr_str
|
62
72
|
self._struct_type = struct_type
|
63
73
|
|
@@ -69,7 +79,7 @@ class QParamStruct(QParam):
|
|
69
79
|
self._struct_type.name
|
70
80
|
)
|
71
81
|
if struct_decl is None:
|
72
|
-
struct_decl =
|
82
|
+
struct_decl = self._qmodule.type_decls.get(self._struct_type.name)
|
73
83
|
assert struct_decl is not None
|
74
84
|
field_type = struct_decl.variables.get(field_name)
|
75
85
|
if field_type is None:
|
@@ -77,7 +87,11 @@ class QParamStruct(QParam):
|
|
77
87
|
f"Struct {self._struct_type.name!r} doesn't have field {field_name!r}"
|
78
88
|
)
|
79
89
|
|
80
|
-
return create_param(
|
90
|
+
return create_param(
|
91
|
+
f"get_field({self._expr_str},{field_name!r})",
|
92
|
+
field_type,
|
93
|
+
qmodule=self._qmodule,
|
94
|
+
)
|
81
95
|
|
82
96
|
|
83
97
|
_P = ParamSpec("_P")
|
@@ -95,10 +109,12 @@ class Array(ArrayBase[_P]):
|
|
95
109
|
pass
|
96
110
|
|
97
111
|
|
98
|
-
def create_param(
|
112
|
+
def create_param(
|
113
|
+
expr_str: str, ctype: ClassicalType, qmodule: ModelStateContainer
|
114
|
+
) -> QParam:
|
99
115
|
if isinstance(ctype, ClassicalList) or isinstance(ctype, ClassicalArray):
|
100
|
-
return QParamList(expr_str, ctype)
|
116
|
+
return QParamList(expr_str, ctype, qmodule=qmodule)
|
101
117
|
elif isinstance(ctype, Struct):
|
102
|
-
return QParamStruct(expr_str, ctype)
|
118
|
+
return QParamStruct(expr_str, ctype, qmodule=qmodule)
|
103
119
|
else:
|
104
120
|
return QParamScalar(expr_str)
|
classiq/qmod/qmod_variable.py
CHANGED
@@ -134,9 +134,9 @@ class QScalar(QVar, Symbol):
|
|
134
134
|
# Fixme: Arithmetic operations are not yet supported on slices (see CAD-12670)
|
135
135
|
if TYPE_CHECKING:
|
136
136
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
137
|
-
QCallable.CURRENT_EXPANDABLE.
|
137
|
+
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
138
138
|
ArithmeticOperation(
|
139
|
-
|
139
|
+
expression=Expression(expr=_python_expr(expr)),
|
140
140
|
result_var=self.get_handle_binding(),
|
141
141
|
inplace_result=inplace,
|
142
142
|
)
|
@@ -145,9 +145,9 @@ class QScalar(QVar, Symbol):
|
|
145
145
|
def _insert_amplitude_loading(self, expr: Basic) -> None:
|
146
146
|
if TYPE_CHECKING:
|
147
147
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
148
|
-
QCallable.CURRENT_EXPANDABLE.
|
148
|
+
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
149
149
|
AmplitudeLoadingOperation(
|
150
|
-
|
150
|
+
expression=Expression(expr=_python_expr(expr)),
|
151
151
|
result_var=self.get_handle_binding(),
|
152
152
|
)
|
153
153
|
)
|
classiq/qmod/quantum_callable.py
CHANGED
@@ -17,7 +17,7 @@ P = ParamSpec("P")
|
|
17
17
|
|
18
18
|
class QExpandableInterface(ABC):
|
19
19
|
@abstractmethod
|
20
|
-
def
|
20
|
+
def append_statement_to_body(self, stmt: QuantumStatement) -> None:
|
21
21
|
raise NotImplementedError()
|
22
22
|
|
23
23
|
@abstractmethod
|
@@ -30,7 +30,7 @@ class QCallable(Generic[P]):
|
|
30
30
|
|
31
31
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
32
32
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
33
|
-
QCallable.CURRENT_EXPANDABLE.
|
33
|
+
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
34
34
|
self.create_quantum_function_call(*args, **kwargs)
|
35
35
|
)
|
36
36
|
return
|
@@ -23,6 +23,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
23
23
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
24
24
|
from classiq.interface.model.quantum_type import QuantumType
|
25
25
|
|
26
|
+
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
26
27
|
from classiq.qmod.qmod_parameter import QParam, create_param
|
27
28
|
from classiq.qmod.qmod_variable import QVar, create_qvar_for_port_decl
|
28
29
|
from classiq.qmod.quantum_callable import QCallable, QExpandableInterface
|
@@ -35,7 +36,8 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
35
36
|
STACK: ClassVar[List["QExpandable"]] = list()
|
36
37
|
|
37
38
|
def __init__(self, py_callable: Callable) -> None:
|
38
|
-
self.
|
39
|
+
self._qmodule: ModelStateContainer = QMODULE
|
40
|
+
self._py_callable: Callable = py_callable
|
39
41
|
self._local_handles: List[LocalVariableDeclaration] = list()
|
40
42
|
self._body: List[QuantumStatement] = list()
|
41
43
|
|
@@ -77,7 +79,7 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
77
79
|
LocalVariableDeclaration(name=name, quantum_type=qtype)
|
78
80
|
)
|
79
81
|
|
80
|
-
def
|
82
|
+
def append_statement_to_body(self, stmt: QuantumStatement) -> None:
|
81
83
|
self._body.append(stmt)
|
82
84
|
|
83
85
|
def _get_positional_args(self) -> List[ArgType]:
|
@@ -88,7 +90,9 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
88
90
|
actual_name = (
|
89
91
|
rename_dict[arg.name] if arg.name in rename_dict else arg.name
|
90
92
|
)
|
91
|
-
result.append(
|
93
|
+
result.append(
|
94
|
+
create_param(actual_name, arg.classical_type, qmodule=self._qmodule)
|
95
|
+
)
|
92
96
|
elif isinstance(arg, PortDeclaration):
|
93
97
|
result.append(create_qvar_for_port_decl(arg))
|
94
98
|
else:
|
classiq/qmod/quantum_function.py
CHANGED
@@ -12,7 +12,6 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
12
12
|
|
13
13
|
from classiq.exceptions import ClassiqError
|
14
14
|
from classiq.qmod.declaration_inferrer import infer_func_decl
|
15
|
-
from classiq.qmod.model_state_container import ModelStateContainer
|
16
15
|
from classiq.qmod.qmod_parameter import QParam
|
17
16
|
from classiq.qmod.qmod_variable import QVar
|
18
17
|
from classiq.qmod.quantum_callable import QCallable
|
@@ -55,8 +54,9 @@ class QFunc(QExpandable):
|
|
55
54
|
|
56
55
|
@property
|
57
56
|
def func_decl(self) -> QuantumFunctionDeclaration:
|
58
|
-
return
|
59
|
-
self._py_callable.__name__,
|
57
|
+
return self._qmodule.native_defs.get(
|
58
|
+
self._py_callable.__name__,
|
59
|
+
infer_func_decl(self._py_callable, qmodule=self._qmodule),
|
60
60
|
)
|
61
61
|
|
62
62
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
@@ -69,8 +69,8 @@ class QFunc(QExpandable):
|
|
69
69
|
execution_preferences: Optional[ExecutionPreferences] = None,
|
70
70
|
preferences: Optional[Preferences] = None,
|
71
71
|
) -> Model:
|
72
|
-
|
73
|
-
|
72
|
+
self._qmodule.type_decls = dict()
|
73
|
+
self._qmodule.native_defs = dict()
|
74
74
|
self._add_native_func_def()
|
75
75
|
model_extra_settings: List[Tuple[str, Any]] = [
|
76
76
|
("constraints", constraints),
|
@@ -78,16 +78,16 @@ class QFunc(QExpandable):
|
|
78
78
|
("preferences", preferences),
|
79
79
|
]
|
80
80
|
return Model(
|
81
|
-
functions=list(
|
82
|
-
types=list(
|
81
|
+
functions=list(self._qmodule.native_defs.values()),
|
82
|
+
types=list(self._qmodule.type_decls.values()),
|
83
83
|
**{key: value for key, value in model_extra_settings if value},
|
84
84
|
)
|
85
85
|
|
86
86
|
def _add_native_func_def(self) -> None:
|
87
|
-
if self.func_decl.name in
|
87
|
+
if self.func_decl.name in self._qmodule.native_defs:
|
88
88
|
return
|
89
89
|
self.expand()
|
90
|
-
|
90
|
+
self._qmodule.native_defs[self.func_decl.name] = NativeFunctionDefinition(
|
91
91
|
**self.func_decl.__dict__, local_handles=self.local_handles, body=self.body
|
92
92
|
)
|
93
93
|
|