classiq 0.38.0__py3-none-any.whl → 0.40.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/__init__.py +22 -22
- classiq/_internals/api_wrapper.py +13 -1
- classiq/_internals/client.py +12 -2
- classiq/analyzer/analyzer.py +3 -1
- classiq/applications/__init__.py +1 -8
- classiq/applications/chemistry/__init__.py +6 -0
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/arithmetic_expression.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/combinatorial_problem_utils.py +25 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_mapping.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/encoding_utils.py +1 -1
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/memory.py +2 -4
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/optimization_model.py +13 -16
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/pyomo_utils.py +4 -2
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/encoding.py +3 -10
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/fixed_variables.py +4 -6
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/ising_converter.py +3 -5
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty_support.py +3 -7
- classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/slack_variables.py +4 -6
- classiq/applications/combinatorial_optimization/__init__.py +11 -3
- classiq/{applications_model_constructors → applications/combinatorial_optimization}/combinatorial_optimization_model_constructor.py +9 -10
- classiq/applications/finance/__init__.py +3 -2
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +24 -14
- classiq/applications/grover/__init__.py +11 -0
- classiq/applications/libraries/qmci_library.py +35 -0
- classiq/applications/qsvm/__init__.py +5 -1
- classiq/execution/all_hardware_devices.py +13 -0
- classiq/executor.py +2 -1
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/result.py +1 -5
- classiq/interface/applications/qsvm.py +4 -2
- classiq/interface/ast_node.py +23 -0
- classiq/interface/backend/backend_preferences.py +5 -5
- classiq/interface/backend/quantum_backend_providers.py +7 -7
- classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
- classiq/interface/executor/execution_preferences.py +4 -9
- classiq/interface/executor/execution_request.py +2 -37
- classiq/interface/executor/vqe_result.py +1 -1
- classiq/interface/generator/application_apis/chemistry_declarations.py +2 -4
- classiq/interface/generator/application_apis/finance_declarations.py +1 -1
- classiq/interface/generator/arith/arithmetic_expression_validator.py +2 -0
- classiq/interface/generator/builtin_api_builder.py +0 -5
- classiq/interface/generator/constant.py +2 -3
- classiq/interface/generator/expressions/expression.py +2 -4
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +82 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +22 -1
- classiq/interface/generator/expressions/qmod_sized_proxy.py +22 -0
- classiq/interface/generator/functions/__init__.py +2 -2
- classiq/interface/generator/functions/builtins/__init__.py +15 -0
- classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
- classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +8 -6
- classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +10 -4
- classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
- classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +893 -319
- classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
- classiq/interface/generator/functions/classical_type.py +31 -21
- classiq/interface/generator/functions/function_declaration.py +2 -2
- classiq/interface/generator/hartree_fock.py +10 -2
- classiq/interface/generator/model/classical_main_validator.py +1 -1
- classiq/interface/generator/model/model.py +1 -1
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/generator/quantum_function_call.py +1 -1
- classiq/interface/generator/types/struct_declaration.py +2 -4
- classiq/interface/model/call_synthesis_data.py +3 -3
- classiq/interface/model/classical_if.py +13 -0
- classiq/interface/model/classical_parameter_declaration.py +2 -3
- classiq/interface/model/{quantum_if_operation.py → control.py} +39 -21
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/invert.py +10 -0
- classiq/interface/model/model.py +2 -1
- classiq/interface/model/power.py +12 -0
- classiq/interface/model/quantum_function_call.py +9 -4
- classiq/interface/model/quantum_lambda_function.py +3 -9
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/model/quantum_type.py +8 -9
- classiq/interface/model/quantum_variable_declaration.py +2 -2
- classiq/interface/model/repeat.py +13 -0
- classiq/interface/model/resolvers/function_call_resolver.py +21 -0
- classiq/interface/model/statement_block.py +18 -4
- classiq/interface/model/validations/handles_validator.py +8 -12
- classiq/interface/model/within_apply_operation.py +4 -4
- classiq/interface/server/routes.py +0 -4
- classiq/qmod/__init__.py +6 -2
- classiq/qmod/builtins/classical_functions.py +34 -39
- classiq/qmod/builtins/functions.py +287 -300
- classiq/qmod/builtins/operations.py +217 -16
- classiq/qmod/builtins/structs.py +50 -48
- classiq/qmod/declaration_inferrer.py +30 -18
- classiq/qmod/native/expression_to_qmod.py +5 -4
- classiq/qmod/native/pretty_printer.py +48 -26
- classiq/qmod/qmod_constant.py +29 -5
- classiq/qmod/qmod_parameter.py +56 -34
- classiq/qmod/qmod_struct.py +2 -2
- classiq/qmod/qmod_variable.py +87 -43
- classiq/qmod/quantum_callable.py +8 -4
- classiq/qmod/quantum_expandable.py +25 -20
- classiq/qmod/quantum_function.py +29 -2
- classiq/qmod/symbolic.py +79 -69
- classiq/qmod/symbolic_expr.py +1 -1
- classiq/qmod/symbolic_type.py +1 -4
- classiq/qmod/utilities.py +29 -0
- {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/METADATA +1 -1
- {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/RECORD +122 -141
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -70
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -25
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +0 -34
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -107
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py +0 -0
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -95
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -462
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -229
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -205
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/allowed_constraints.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/arithmetic/isolation.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/pauli_helpers/pauli_utils.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/py.typed +0 -0
- /classiq/{applications_model_constructors/combinatorial_helpers/transformations → applications/combinatorial_helpers/solvers}/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/sympy_utils.py +0 -0
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers/transformations}/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/penalty.py +0 -0
- /classiq/{applications_model_constructors → applications}/combinatorial_helpers/transformations/sign_seperation.py +0 -0
- /classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/libraries}/__init__.py +0 -0
- /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
- /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
- /classiq/{quantum_register.py → interface/model/quantum_register.py} +0 -0
- {classiq-0.38.0.dist-info → classiq-0.40.0.dist-info}/WHEEL +0 -0
classiq/qmod/quantum_callable.py
CHANGED
@@ -12,6 +12,7 @@ from typing import ( # type: ignore[attr-defined]
|
|
12
12
|
|
13
13
|
from typing_extensions import ParamSpec
|
14
14
|
|
15
|
+
from classiq.interface.ast_node import SourceReference
|
15
16
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
16
17
|
from classiq.interface.model.quantum_function_declaration import (
|
17
18
|
QuantumFunctionDeclaration,
|
@@ -19,7 +20,8 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
19
20
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
20
21
|
from classiq.interface.model.quantum_type import QuantumType
|
21
22
|
|
22
|
-
from classiq.qmod.qmod_parameter import
|
23
|
+
from classiq.qmod.qmod_parameter import CInt
|
24
|
+
from classiq.qmod.utilities import get_source_ref
|
23
25
|
|
24
26
|
if TYPE_CHECKING:
|
25
27
|
from classiq.qmod.quantum_expandable import QTerminalCallable
|
@@ -42,8 +44,9 @@ class QCallable(Generic[P], ABC):
|
|
42
44
|
|
43
45
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
44
46
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
47
|
+
source_ref = get_source_ref(sys._getframe(1))
|
45
48
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
46
|
-
self.create_quantum_function_call(*args, **kwargs)
|
49
|
+
self.create_quantum_function_call(source_ref, *args, **kwargs)
|
47
50
|
)
|
48
51
|
return
|
49
52
|
|
@@ -60,7 +63,7 @@ class QCallable(Generic[P], ABC):
|
|
60
63
|
|
61
64
|
@abstractmethod
|
62
65
|
def create_quantum_function_call(
|
63
|
-
self, *args: Any, **kwargs: Any
|
66
|
+
self, source_ref_: SourceReference, *args: Any, **kwargs: Any
|
64
67
|
) -> QuantumFunctionCall:
|
65
68
|
raise NotImplementedError()
|
66
69
|
|
@@ -68,7 +71,8 @@ class QCallable(Generic[P], ABC):
|
|
68
71
|
class QCallableList(QCallable, Generic[P], ABC):
|
69
72
|
if TYPE_CHECKING:
|
70
73
|
|
74
|
+
@property
|
71
75
|
def len(self) -> int: ...
|
72
76
|
|
73
|
-
def __getitem__(self, key: Union[slice, int,
|
77
|
+
def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
|
74
78
|
raise NotImplementedError()
|
@@ -17,6 +17,7 @@ from typing import (
|
|
17
17
|
|
18
18
|
from typing_extensions import Self
|
19
19
|
|
20
|
+
from classiq.interface.ast_node import SourceReference
|
20
21
|
from classiq.interface.generator.expressions.expression import Expression
|
21
22
|
from classiq.interface.model.classical_parameter_declaration import (
|
22
23
|
ClassicalParameterDeclaration,
|
@@ -32,10 +33,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
32
33
|
QuantumFunctionDeclaration,
|
33
34
|
QuantumOperandDeclaration,
|
34
35
|
)
|
35
|
-
from classiq.interface.model.quantum_lambda_function import
|
36
|
-
QuantumLambdaFunction,
|
37
|
-
QuantumOperand,
|
38
|
-
)
|
36
|
+
from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
|
39
37
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
40
38
|
from classiq.interface.model.quantum_type import QuantumType
|
41
39
|
from classiq.interface.model.variable_declaration_statement import (
|
@@ -45,12 +43,12 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
45
43
|
from classiq.exceptions import ClassiqValueError
|
46
44
|
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
47
45
|
from classiq.qmod.qmod_constant import QConstant
|
48
|
-
from classiq.qmod.qmod_parameter import
|
46
|
+
from classiq.qmod.qmod_parameter import CInt, CParam, CParamScalar, create_param
|
49
47
|
from classiq.qmod.qmod_variable import QVar, create_qvar_for_port_decl
|
50
48
|
from classiq.qmod.quantum_callable import QCallable, QExpandableInterface
|
51
49
|
from classiq.qmod.utilities import mangle_keyword
|
52
50
|
|
53
|
-
ArgType = Union[
|
51
|
+
ArgType = Union[CParam, QVar, QCallable]
|
54
52
|
|
55
53
|
|
56
54
|
class QExpandable(QCallable, QExpandableInterface, ABC):
|
@@ -112,9 +110,11 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
112
110
|
return result
|
113
111
|
|
114
112
|
def create_quantum_function_call(
|
115
|
-
self, *args: Any, **kwargs: Any
|
113
|
+
self, source_ref_: SourceReference, *args: Any, **kwargs: Any
|
116
114
|
) -> QuantumFunctionCall:
|
117
|
-
return _create_quantum_function_call(
|
115
|
+
return _create_quantum_function_call(
|
116
|
+
self.func_decl, None, source_ref_, *args, **kwargs
|
117
|
+
)
|
118
118
|
|
119
119
|
|
120
120
|
class QLambdaFunction(QExpandable):
|
@@ -141,7 +141,7 @@ class QTerminalCallable(QCallable):
|
|
141
141
|
def __init__(
|
142
142
|
self,
|
143
143
|
decl: QuantumFunctionDeclaration,
|
144
|
-
index_: Optional[Union[int,
|
144
|
+
index_: Optional[Union[int, CParamScalar]] = None,
|
145
145
|
) -> None:
|
146
146
|
self._decl = decl
|
147
147
|
self._index = index_
|
@@ -150,51 +150,53 @@ class QTerminalCallable(QCallable):
|
|
150
150
|
def is_list(self) -> bool:
|
151
151
|
return isinstance(self._decl, QuantumOperandDeclaration) and self._decl.is_list
|
152
152
|
|
153
|
-
def __getitem__(self, key: Union[slice, int,
|
153
|
+
def __getitem__(self, key: Union[slice, int, CInt]) -> "QTerminalCallable":
|
154
154
|
if not self.is_list:
|
155
155
|
raise ClassiqValueError("Cannot index a non-list operand")
|
156
156
|
if isinstance(key, slice):
|
157
157
|
raise NotImplementedError("Operand lists don't support slicing")
|
158
|
-
if isinstance(key,
|
158
|
+
if isinstance(key, CParam) and not isinstance(key, CParamScalar):
|
159
159
|
raise ClassiqValueError("Non-classical parameter for slicing")
|
160
160
|
return QTerminalCallable(self._decl, key)
|
161
161
|
|
162
162
|
def __len__(self) -> int:
|
163
163
|
raise ClassiqValueError(
|
164
|
-
"len(<func>) is not supported for quantum callables - use <func>.len
|
164
|
+
"len(<func>) is not supported for quantum callables - use <func>.len instead (Only if it is an operand list)"
|
165
165
|
)
|
166
166
|
|
167
167
|
if TYPE_CHECKING:
|
168
168
|
|
169
|
+
@property
|
169
170
|
def len(self) -> int: ...
|
170
171
|
|
171
172
|
else:
|
172
173
|
|
173
|
-
|
174
|
+
@property
|
175
|
+
def len(self) -> CParamScalar:
|
174
176
|
if not self.is_list:
|
175
177
|
raise ClassiqValueError("Cannot get length of a non-list operand")
|
176
|
-
return
|
178
|
+
return CParamScalar(f"{self.func_decl.name}.len")
|
177
179
|
|
178
180
|
@property
|
179
181
|
def func_decl(self) -> QuantumFunctionDeclaration:
|
180
182
|
return self._decl
|
181
183
|
|
182
184
|
def create_quantum_function_call(
|
183
|
-
self, *args: Any, **kwargs: Any
|
185
|
+
self, source_ref_: SourceReference, *args: Any, **kwargs: Any
|
184
186
|
) -> QuantumFunctionCall:
|
185
187
|
if self.is_list and self._index is None:
|
186
188
|
raise ClassiqValueError(
|
187
189
|
f"Quantum operand {self.func_decl.name!r} is a list and must be indexed"
|
188
190
|
)
|
189
191
|
return _create_quantum_function_call(
|
190
|
-
self.func_decl, self._index, *args, **kwargs
|
192
|
+
self.func_decl, self._index, source_ref_, *args, **kwargs
|
191
193
|
)
|
192
194
|
|
193
195
|
|
194
196
|
@overload
|
195
197
|
def prepare_arg(
|
196
|
-
arg_decl: PositionalArg, val: Union[QCallable, Callable[
|
197
|
-
) ->
|
198
|
+
arg_decl: PositionalArg, val: Union[QCallable, Callable[..., None]]
|
199
|
+
) -> QuantumLambdaFunction: ...
|
198
200
|
|
199
201
|
|
200
202
|
@overload
|
@@ -279,7 +281,8 @@ def _prepare_args(
|
|
279
281
|
|
280
282
|
def _create_quantum_function_call(
|
281
283
|
decl_: QuantumFunctionDeclaration,
|
282
|
-
index_: Optional[Union[
|
284
|
+
index_: Optional[Union[CParamScalar, int]] = None,
|
285
|
+
source_ref_: Optional[SourceReference] = None,
|
283
286
|
*args: Any,
|
284
287
|
**kwargs: Any,
|
285
288
|
) -> QuantumFunctionCall:
|
@@ -307,4 +310,6 @@ def _create_quantum_function_call(
|
|
307
310
|
index=Expression(expr=str(index_)), name=function_ident
|
308
311
|
)
|
309
312
|
|
310
|
-
return QuantumFunctionCall(
|
313
|
+
return QuantumFunctionCall(
|
314
|
+
function=function_ident, positional_args=prepared_args, source_ref=source_ref_
|
315
|
+
)
|
classiq/qmod/quantum_function.py
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
import ast
|
2
2
|
import functools
|
3
|
+
import warnings
|
4
|
+
from inspect import isclass
|
3
5
|
from typing import Any, Callable, Dict, List, Optional, Tuple, get_origin
|
4
6
|
|
5
7
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
8
|
+
from classiq.interface.generator.functions.classical_type import CStructBase
|
6
9
|
from classiq.interface.generator.model.constraints import Constraints
|
7
10
|
from classiq.interface.generator.model.preferences.preferences import Preferences
|
8
11
|
from classiq.interface.model.model import Model, SerializedModel
|
@@ -15,7 +18,7 @@ from classiq.exceptions import ClassiqError
|
|
15
18
|
from classiq.qmod.classical_function import CFunc
|
16
19
|
from classiq.qmod.declaration_inferrer import infer_func_decl
|
17
20
|
from classiq.qmod.qmod_constant import QConstant
|
18
|
-
from classiq.qmod.qmod_parameter import QParam
|
21
|
+
from classiq.qmod.qmod_parameter import CArray, CParam, QParam
|
19
22
|
from classiq.qmod.qmod_variable import QVar
|
20
23
|
from classiq.qmod.quantum_callable import QCallable, QCallableList
|
21
24
|
from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
|
@@ -34,6 +37,10 @@ def create_model(
|
|
34
37
|
preferences: Optional[Preferences] = None,
|
35
38
|
classical_execution_function: Optional[CFunc] = None,
|
36
39
|
) -> SerializedModel:
|
40
|
+
if entry_point.func_decl.name != "main":
|
41
|
+
raise ClassiqError(
|
42
|
+
f"The entry point function must be named 'main', got '{entry_point.func_decl.name}'"
|
43
|
+
)
|
37
44
|
return entry_point.create_model(
|
38
45
|
constraints, execution_preferences, preferences, classical_execution_function
|
39
46
|
).get_model()
|
@@ -42,6 +49,18 @@ def create_model(
|
|
42
49
|
class QFunc(QExpandable):
|
43
50
|
def __init__(self, py_callable: Callable) -> None:
|
44
51
|
_validate_no_gen_params(py_callable.__annotations__)
|
52
|
+
if any(
|
53
|
+
get_origin(annotation) == QParam
|
54
|
+
for annotation in py_callable.__annotations__.values()
|
55
|
+
):
|
56
|
+
warnings.warn(
|
57
|
+
"QParam is deprecated and will be removed in a future release. Use the "
|
58
|
+
"new classical parameter types instead:\n * QParam[int] -> CInt\n * QParam[float] "
|
59
|
+
"-> CReal\n * QParam[bool] -> CBool\n * QParam[list[int]] -> "
|
60
|
+
"CArray[CInt]",
|
61
|
+
category=DeprecationWarning,
|
62
|
+
stacklevel=4,
|
63
|
+
)
|
45
64
|
super().__init__(py_callable)
|
46
65
|
functools.update_wrapper(self, py_callable)
|
47
66
|
|
@@ -140,7 +159,10 @@ ILLEGAL_PARAM_ERROR = "Unsupported type hint '{annotation}' for argument '{name}
|
|
140
159
|
|
141
160
|
|
142
161
|
class IllegalParamsError(ClassiqError):
|
143
|
-
_HINT =
|
162
|
+
_HINT = (
|
163
|
+
"\nNote - QMOD functions can declare classical parameters using the type hints "
|
164
|
+
"'CInt', 'CReal', 'CBool', and 'CArray'."
|
165
|
+
)
|
144
166
|
|
145
167
|
def __init__(self, message: str) -> None:
|
146
168
|
super().__init__(message + self._HINT)
|
@@ -153,6 +175,11 @@ def _validate_no_gen_params(annotations: Dict[str, Any]) -> None:
|
|
153
175
|
if not (
|
154
176
|
name == "return"
|
155
177
|
or get_origin(annotation) is QParam
|
178
|
+
or isclass(annotation)
|
179
|
+
and issubclass(annotation, CParam)
|
180
|
+
or isclass(annotation)
|
181
|
+
and issubclass(annotation, CStructBase)
|
182
|
+
or get_origin(annotation) is CArray
|
156
183
|
or (get_origin(annotation) or annotation) is QCallable
|
157
184
|
or (get_origin(annotation) or annotation) is QCallableList
|
158
185
|
or QVar.from_type_hint(annotation) is not None
|
classiq/qmod/symbolic.py
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
import sys
|
2
|
-
from typing import
|
2
|
+
from typing import (
|
3
|
+
TYPE_CHECKING,
|
4
|
+
Any,
|
5
|
+
List,
|
6
|
+
Optional,
|
7
|
+
Tuple,
|
8
|
+
Type,
|
9
|
+
TypeVar,
|
10
|
+
get_args,
|
11
|
+
get_origin,
|
12
|
+
overload,
|
13
|
+
)
|
3
14
|
|
4
15
|
from classiq.exceptions import ClassiqValueError
|
5
16
|
from classiq.qmod import model_state_container
|
6
17
|
from classiq.qmod.declaration_inferrer import python_type_to_qmod
|
7
|
-
from classiq.qmod.qmod_parameter import
|
18
|
+
from classiq.qmod.qmod_parameter import CParam, CParamScalar, QParam, create_param
|
8
19
|
from classiq.qmod.symbolic_expr import SymbolicExpr
|
9
20
|
from classiq.qmod.symbolic_type import SymbolicTypes
|
10
21
|
|
@@ -15,20 +26,18 @@ GoldenRatio = SymbolicExpr("GoldenRatio")
|
|
15
26
|
EulerGamma = SymbolicExpr("EulerGamma")
|
16
27
|
Catalan = SymbolicExpr("Catalan")
|
17
28
|
|
29
|
+
T = TypeVar("T", bound=CParam)
|
30
|
+
|
18
31
|
|
19
32
|
@overload
|
20
|
-
def symbolic_function(
|
21
|
-
*args: SymbolicTypes, return_type: None = None
|
22
|
-
) -> QParamScalar: ...
|
33
|
+
def symbolic_function(*args: Any, return_type: None = None) -> CParamScalar: ...
|
23
34
|
|
24
35
|
|
25
36
|
@overload
|
26
|
-
def symbolic_function(*args:
|
37
|
+
def symbolic_function(*args: Any, return_type: Type[T]) -> T: ...
|
27
38
|
|
28
39
|
|
29
|
-
def symbolic_function(
|
30
|
-
*args: SymbolicTypes, return_type: Optional[Type[QParam]] = None
|
31
|
-
) -> QParam:
|
40
|
+
def symbolic_function(*args: Any, return_type: Optional[Type[T]] = None) -> CParam:
|
32
41
|
qmodule = (
|
33
42
|
model_state_container.QMODULE
|
34
43
|
) # FIXME: https://classiq.atlassian.net/browse/CAD-15126
|
@@ -36,14 +45,15 @@ def symbolic_function(
|
|
36
45
|
expr = f"{sys._getframe(1).f_code.co_name}({','.join(str_args)})"
|
37
46
|
|
38
47
|
if return_type is None:
|
39
|
-
return
|
48
|
+
return CParamScalar(expr)
|
40
49
|
|
41
|
-
if get_origin(return_type) is
|
42
|
-
|
43
|
-
|
44
|
-
|
50
|
+
if get_origin(return_type) is QParam:
|
51
|
+
return_type = get_args(return_type)[0]
|
52
|
+
|
53
|
+
if TYPE_CHECKING:
|
54
|
+
assert return_type is not None
|
45
55
|
|
46
|
-
qmod_type = python_type_to_qmod(
|
56
|
+
qmod_type = python_type_to_qmod(return_type, qmodule=qmodule)
|
47
57
|
if qmod_type is None:
|
48
58
|
raise ClassiqValueError(
|
49
59
|
f"Unsupported return type for symbolic function: {return_type}"
|
@@ -56,211 +66,211 @@ def symbolic_function(
|
|
56
66
|
)
|
57
67
|
|
58
68
|
|
59
|
-
def sin(x: SymbolicTypes) ->
|
69
|
+
def sin(x: SymbolicTypes) -> CParamScalar:
|
60
70
|
return symbolic_function(x)
|
61
71
|
|
62
72
|
|
63
|
-
def cos(x: SymbolicTypes) ->
|
73
|
+
def cos(x: SymbolicTypes) -> CParamScalar:
|
64
74
|
return symbolic_function(x)
|
65
75
|
|
66
76
|
|
67
|
-
def tan(x: SymbolicTypes) ->
|
77
|
+
def tan(x: SymbolicTypes) -> CParamScalar:
|
68
78
|
return symbolic_function(x)
|
69
79
|
|
70
80
|
|
71
|
-
def cot(x: SymbolicTypes) ->
|
81
|
+
def cot(x: SymbolicTypes) -> CParamScalar:
|
72
82
|
return symbolic_function(x)
|
73
83
|
|
74
84
|
|
75
|
-
def sec(x: SymbolicTypes) ->
|
85
|
+
def sec(x: SymbolicTypes) -> CParamScalar:
|
76
86
|
return symbolic_function(x)
|
77
87
|
|
78
88
|
|
79
|
-
def csc(x: SymbolicTypes) ->
|
89
|
+
def csc(x: SymbolicTypes) -> CParamScalar:
|
80
90
|
return symbolic_function(x)
|
81
91
|
|
82
92
|
|
83
|
-
def asin(x: SymbolicTypes) ->
|
93
|
+
def asin(x: SymbolicTypes) -> CParamScalar:
|
84
94
|
return symbolic_function(x)
|
85
95
|
|
86
96
|
|
87
|
-
def acos(x: SymbolicTypes) ->
|
97
|
+
def acos(x: SymbolicTypes) -> CParamScalar:
|
88
98
|
return symbolic_function(x)
|
89
99
|
|
90
100
|
|
91
|
-
def atan(x: SymbolicTypes) ->
|
101
|
+
def atan(x: SymbolicTypes) -> CParamScalar:
|
92
102
|
return symbolic_function(x)
|
93
103
|
|
94
104
|
|
95
|
-
def acot(x: SymbolicTypes) ->
|
105
|
+
def acot(x: SymbolicTypes) -> CParamScalar:
|
96
106
|
return symbolic_function(x)
|
97
107
|
|
98
108
|
|
99
|
-
def asec(x: SymbolicTypes) ->
|
109
|
+
def asec(x: SymbolicTypes) -> CParamScalar:
|
100
110
|
return symbolic_function(x)
|
101
111
|
|
102
112
|
|
103
|
-
def acsc(x: SymbolicTypes) ->
|
113
|
+
def acsc(x: SymbolicTypes) -> CParamScalar:
|
104
114
|
return symbolic_function(x)
|
105
115
|
|
106
116
|
|
107
|
-
def sinh(x: SymbolicTypes) ->
|
117
|
+
def sinh(x: SymbolicTypes) -> CParamScalar:
|
108
118
|
return symbolic_function(x)
|
109
119
|
|
110
120
|
|
111
|
-
def cosh(x: SymbolicTypes) ->
|
121
|
+
def cosh(x: SymbolicTypes) -> CParamScalar:
|
112
122
|
return symbolic_function(x)
|
113
123
|
|
114
124
|
|
115
|
-
def tanh(x: SymbolicTypes) ->
|
125
|
+
def tanh(x: SymbolicTypes) -> CParamScalar:
|
116
126
|
return symbolic_function(x)
|
117
127
|
|
118
128
|
|
119
|
-
def coth(x: SymbolicTypes) ->
|
129
|
+
def coth(x: SymbolicTypes) -> CParamScalar:
|
120
130
|
return symbolic_function(x)
|
121
131
|
|
122
132
|
|
123
|
-
def sech(x: SymbolicTypes) ->
|
133
|
+
def sech(x: SymbolicTypes) -> CParamScalar:
|
124
134
|
return symbolic_function(x)
|
125
135
|
|
126
136
|
|
127
|
-
def csch(x: SymbolicTypes) ->
|
137
|
+
def csch(x: SymbolicTypes) -> CParamScalar:
|
128
138
|
return symbolic_function(x)
|
129
139
|
|
130
140
|
|
131
|
-
def asinh(x: SymbolicTypes) ->
|
141
|
+
def asinh(x: SymbolicTypes) -> CParamScalar:
|
132
142
|
return symbolic_function(x)
|
133
143
|
|
134
144
|
|
135
|
-
def acosh(x: SymbolicTypes) ->
|
145
|
+
def acosh(x: SymbolicTypes) -> CParamScalar:
|
136
146
|
return symbolic_function(x)
|
137
147
|
|
138
148
|
|
139
|
-
def atanh(x: SymbolicTypes) ->
|
149
|
+
def atanh(x: SymbolicTypes) -> CParamScalar:
|
140
150
|
return symbolic_function(x)
|
141
151
|
|
142
152
|
|
143
|
-
def acoth(x: SymbolicTypes) ->
|
153
|
+
def acoth(x: SymbolicTypes) -> CParamScalar:
|
144
154
|
return symbolic_function(x)
|
145
155
|
|
146
156
|
|
147
|
-
def asech(x: SymbolicTypes) ->
|
157
|
+
def asech(x: SymbolicTypes) -> CParamScalar:
|
148
158
|
return symbolic_function(x)
|
149
159
|
|
150
160
|
|
151
|
-
def exp(x: SymbolicTypes) ->
|
161
|
+
def exp(x: SymbolicTypes) -> CParamScalar:
|
152
162
|
return symbolic_function(x)
|
153
163
|
|
154
164
|
|
155
|
-
def log(x: SymbolicTypes, base: SymbolicTypes = E) ->
|
165
|
+
def log(x: SymbolicTypes, base: SymbolicTypes = E) -> CParamScalar:
|
156
166
|
return symbolic_function(x, base)
|
157
167
|
|
158
168
|
|
159
|
-
def ln(x: SymbolicTypes) ->
|
169
|
+
def ln(x: SymbolicTypes) -> CParamScalar:
|
160
170
|
return symbolic_function(x)
|
161
171
|
|
162
172
|
|
163
|
-
def sqrt(x: SymbolicTypes) ->
|
173
|
+
def sqrt(x: SymbolicTypes) -> CParamScalar:
|
164
174
|
return symbolic_function(x)
|
165
175
|
|
166
176
|
|
167
|
-
def abs(x: SymbolicTypes) ->
|
177
|
+
def abs(x: SymbolicTypes) -> CParamScalar:
|
168
178
|
return symbolic_function(x)
|
169
179
|
|
170
180
|
|
171
|
-
def floor(x: SymbolicTypes) ->
|
181
|
+
def floor(x: SymbolicTypes) -> CParamScalar:
|
172
182
|
return symbolic_function(x)
|
173
183
|
|
174
184
|
|
175
|
-
def ceiling(x: SymbolicTypes) ->
|
185
|
+
def ceiling(x: SymbolicTypes) -> CParamScalar:
|
176
186
|
return symbolic_function(x)
|
177
187
|
|
178
188
|
|
179
|
-
def erf(x: SymbolicTypes) ->
|
189
|
+
def erf(x: SymbolicTypes) -> CParamScalar:
|
180
190
|
return symbolic_function(x)
|
181
191
|
|
182
192
|
|
183
|
-
def erfc(x: SymbolicTypes) ->
|
193
|
+
def erfc(x: SymbolicTypes) -> CParamScalar:
|
184
194
|
return symbolic_function(x)
|
185
195
|
|
186
196
|
|
187
|
-
def gamma(x: SymbolicTypes) ->
|
197
|
+
def gamma(x: SymbolicTypes) -> CParamScalar:
|
188
198
|
return symbolic_function(x)
|
189
199
|
|
190
200
|
|
191
|
-
def beta(x: SymbolicTypes) ->
|
201
|
+
def beta(x: SymbolicTypes) -> CParamScalar:
|
192
202
|
return symbolic_function(x)
|
193
203
|
|
194
204
|
|
195
|
-
def besselj(x: SymbolicTypes) ->
|
205
|
+
def besselj(x: SymbolicTypes) -> CParamScalar:
|
196
206
|
return symbolic_function(x)
|
197
207
|
|
198
208
|
|
199
|
-
def bessely(x: SymbolicTypes) ->
|
209
|
+
def bessely(x: SymbolicTypes) -> CParamScalar:
|
200
210
|
return symbolic_function(x)
|
201
211
|
|
202
212
|
|
203
|
-
def besseli(x: SymbolicTypes) ->
|
213
|
+
def besseli(x: SymbolicTypes) -> CParamScalar:
|
204
214
|
return symbolic_function(x)
|
205
215
|
|
206
216
|
|
207
|
-
def besselk(x: SymbolicTypes) ->
|
217
|
+
def besselk(x: SymbolicTypes) -> CParamScalar:
|
208
218
|
return symbolic_function(x)
|
209
219
|
|
210
220
|
|
211
|
-
def dirichlet_eta(x: SymbolicTypes) ->
|
221
|
+
def dirichlet_eta(x: SymbolicTypes) -> CParamScalar:
|
212
222
|
return symbolic_function(x)
|
213
223
|
|
214
224
|
|
215
|
-
def polygamma(x: SymbolicTypes) ->
|
225
|
+
def polygamma(x: SymbolicTypes) -> CParamScalar:
|
216
226
|
return symbolic_function(x)
|
217
227
|
|
218
228
|
|
219
|
-
def loggamma(x: SymbolicTypes) ->
|
229
|
+
def loggamma(x: SymbolicTypes) -> CParamScalar:
|
220
230
|
return symbolic_function(x)
|
221
231
|
|
222
232
|
|
223
|
-
def factorial(x: SymbolicTypes) ->
|
233
|
+
def factorial(x: SymbolicTypes) -> CParamScalar:
|
224
234
|
return symbolic_function(x)
|
225
235
|
|
226
236
|
|
227
|
-
def binomial(x: SymbolicTypes) ->
|
237
|
+
def binomial(x: SymbolicTypes) -> CParamScalar:
|
228
238
|
return symbolic_function(x)
|
229
239
|
|
230
240
|
|
231
|
-
def subfactorial(x: SymbolicTypes) ->
|
241
|
+
def subfactorial(x: SymbolicTypes) -> CParamScalar:
|
232
242
|
return symbolic_function(x)
|
233
243
|
|
234
244
|
|
235
|
-
def primorial(x: SymbolicTypes) ->
|
245
|
+
def primorial(x: SymbolicTypes) -> CParamScalar:
|
236
246
|
return symbolic_function(x)
|
237
247
|
|
238
248
|
|
239
|
-
def bell(x: SymbolicTypes) ->
|
249
|
+
def bell(x: SymbolicTypes) -> CParamScalar:
|
240
250
|
return symbolic_function(x)
|
241
251
|
|
242
252
|
|
243
|
-
def bernoulli(x: SymbolicTypes) ->
|
253
|
+
def bernoulli(x: SymbolicTypes) -> CParamScalar:
|
244
254
|
return symbolic_function(x)
|
245
255
|
|
246
256
|
|
247
|
-
def euler(x: SymbolicTypes) ->
|
257
|
+
def euler(x: SymbolicTypes) -> CParamScalar:
|
248
258
|
return symbolic_function(x)
|
249
259
|
|
250
260
|
|
251
|
-
def catalan(x: SymbolicTypes) ->
|
261
|
+
def catalan(x: SymbolicTypes) -> CParamScalar:
|
252
262
|
return symbolic_function(x)
|
253
263
|
|
254
264
|
|
255
|
-
def Piecewise(*args: Tuple[SymbolicTypes, SymbolicTypes]) ->
|
265
|
+
def Piecewise(*args: Tuple[SymbolicTypes, SymbolicTypes]) -> CParamScalar: # noqa: N802
|
256
266
|
return symbolic_function(*args)
|
257
267
|
|
258
268
|
|
259
|
-
def max(x: SymbolicTypes, y: SymbolicTypes) ->
|
269
|
+
def max(x: SymbolicTypes, y: SymbolicTypes) -> CParamScalar:
|
260
270
|
return symbolic_function(x, y)
|
261
271
|
|
262
272
|
|
263
|
-
def min(x: SymbolicTypes, y: SymbolicTypes) ->
|
273
|
+
def min(x: SymbolicTypes, y: SymbolicTypes) -> CParamScalar:
|
264
274
|
return symbolic_function(x, y)
|
265
275
|
|
266
276
|
|
@@ -276,7 +286,7 @@ def logical_not(x: SymbolicTypes) -> SymbolicExpr:
|
|
276
286
|
return SymbolicExpr._unary_op(x, "not")
|
277
287
|
|
278
288
|
|
279
|
-
def mod_inverse(a: SymbolicTypes, m: SymbolicTypes) ->
|
289
|
+
def mod_inverse(a: SymbolicTypes, m: SymbolicTypes) -> CParamScalar:
|
280
290
|
return symbolic_function(a, m)
|
281
291
|
|
282
292
|
|
@@ -346,5 +356,5 @@ __all__ = [
|
|
346
356
|
]
|
347
357
|
|
348
358
|
|
349
|
-
def __dir__():
|
359
|
+
def __dir__() -> List[str]:
|
350
360
|
return __all__
|
classiq/qmod/symbolic_expr.py
CHANGED
classiq/qmod/symbolic_type.py
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
from typing import Tuple, Union
|
2
2
|
|
3
|
-
from classiq.qmod.qmod_parameter import QParam
|
4
3
|
from classiq.qmod.symbolic_expr import SymbolicExpr
|
5
4
|
|
6
|
-
SymbolicTypes = Union[
|
7
|
-
QParam, SymbolicExpr, int, float, bool, Tuple["SymbolicTypes", ...]
|
8
|
-
]
|
5
|
+
SymbolicTypes = Union[SymbolicExpr, int, float, bool, Tuple["SymbolicTypes", ...]]
|
classiq/qmod/utilities.py
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
import inspect
|
2
|
+
import itertools
|
1
3
|
import keyword
|
2
4
|
import sys
|
5
|
+
from types import FrameType
|
3
6
|
from typing import get_args, get_origin
|
4
7
|
|
8
|
+
from classiq.interface.ast_node import SourceReference
|
9
|
+
|
5
10
|
DEFAULT_DECIMAL_PRECISION = 4
|
6
11
|
|
7
12
|
|
@@ -25,3 +30,27 @@ def version_portable_get_args(py_type: type) -> tuple:
|
|
25
30
|
return get_args(py_type) # The result of __class_getitem__
|
26
31
|
else:
|
27
32
|
return get_args(py_type)[0]
|
33
|
+
|
34
|
+
|
35
|
+
def get_source_ref(frame: FrameType) -> SourceReference:
|
36
|
+
filename = inspect.getfile(frame)
|
37
|
+
lineno = frame.f_lineno
|
38
|
+
if sys.version_info[0:2] < (3, 11) or frame.f_lasti < 0:
|
39
|
+
source_ref = SourceReference(
|
40
|
+
file_name=filename,
|
41
|
+
start_line=lineno,
|
42
|
+
start_column=-1,
|
43
|
+
end_line=-1,
|
44
|
+
end_column=-1,
|
45
|
+
)
|
46
|
+
else:
|
47
|
+
positions_gen = frame.f_code.co_positions()
|
48
|
+
positions = next(itertools.islice(positions_gen, frame.f_lasti // 2, None))
|
49
|
+
source_ref = SourceReference(
|
50
|
+
file_name=filename,
|
51
|
+
start_line=positions[0],
|
52
|
+
start_column=positions[2],
|
53
|
+
end_line=positions[1],
|
54
|
+
end_column=positions[3],
|
55
|
+
)
|
56
|
+
return source_ref
|