classiq 0.64.0__py3-none-any.whl → 0.65.1__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 +30 -0
- classiq/applications/chemistry/chemistry_model_constructor.py +8 -9
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +2 -5
- classiq/applications/finance/finance_model_constructor.py +7 -12
- classiq/applications/grover/grover_model_constructor.py +4 -6
- classiq/applications/qsvm/qsvm_model_constructor.py +6 -4
- classiq/execution/execution_session.py +14 -13
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +1 -9
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +11 -13
- classiq/interface/generator/functions/type_name.py +6 -0
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/quantum_type.py +26 -0
- classiq/interface/model/statement_block.py +2 -0
- classiq/interface/server/routes.py +1 -0
- classiq/model_expansions/evaluators/quantum_type_utils.py +10 -0
- classiq/model_expansions/function_builder.py +35 -11
- classiq/model_expansions/generative_functions.py +6 -4
- classiq/model_expansions/interpreters/base_interpreter.py +37 -138
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +144 -3
- classiq/model_expansions/quantum_operations/call_emitter.py +43 -91
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +5 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +9 -0
- classiq/model_expansions/quantum_operations/shallow_emitter.py +20 -1
- classiq/model_expansions/scope.py +15 -15
- classiq/model_expansions/scope_initialization.py +3 -5
- classiq/open_library/functions/discrete_sine_cosine_transform.py +8 -2
- classiq/open_library/functions/grover.py +1 -1
- classiq/open_library/functions/modular_exponentiation.py +8 -2
- classiq/open_library/functions/state_preparation.py +23 -13
- classiq/open_library/functions/swap_test.py +1 -2
- classiq/open_library/functions/variational.py +1 -2
- classiq/qmod/builtins/__init__.py +1 -1
- classiq/qmod/builtins/operations.py +51 -0
- classiq/qmod/native/pretty_printer.py +9 -1
- classiq/qmod/pretty_print/pretty_printer.py +12 -1
- classiq/qmod/qmod_variable.py +38 -38
- classiq/qmod/quantum_function.py +4 -4
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +8 -46
- classiq/qmod/utilities.py +16 -0
- {classiq-0.64.0.dist-info → classiq-0.65.1.dist-info}/METADATA +1 -1
- {classiq-0.64.0.dist-info → classiq-0.65.1.dist-info}/RECORD +50 -45
- classiq/qmod/semantics/annotation.py +0 -36
- /classiq/qmod/semantics/{qstruct_annotator.py → annotation/qstruct_annotator.py} +0 -0
- {classiq-0.64.0.dist-info → classiq-0.65.1.dist-info}/WHEEL +0 -0
classiq/qmod/qmod_variable.py
CHANGED
@@ -23,11 +23,8 @@ from typing_extensions import ParamSpec, Self, _AnnotatedAlias
|
|
23
23
|
from classiq.interface.exceptions import ClassiqValueError
|
24
24
|
from classiq.interface.generator.expressions.expression import Expression
|
25
25
|
from classiq.interface.generator.expressions.qmod_qarray_proxy import (
|
26
|
-
ILLEGAL_SLICE_BOUNDS_MSG,
|
27
26
|
ILLEGAL_SLICE_MSG,
|
28
27
|
ILLEGAL_SLICING_STEP_MSG,
|
29
|
-
SLICE_OUT_OF_BOUNDS_MSG,
|
30
|
-
SUBSCRIPT_OUT_OF_BOUNDS_MSG,
|
31
28
|
)
|
32
29
|
from classiq.interface.generator.functions.port_declaration import (
|
33
30
|
PortDeclarationDirection,
|
@@ -69,6 +66,7 @@ from classiq.qmod.symbolic_type import SymbolicTypes
|
|
69
66
|
from classiq.qmod.utilities import (
|
70
67
|
get_source_ref,
|
71
68
|
unwrap_forward_ref,
|
69
|
+
varname,
|
72
70
|
version_portable_get_args,
|
73
71
|
)
|
74
72
|
|
@@ -98,28 +96,42 @@ def _no_current_expandable() -> Iterator[None]:
|
|
98
96
|
QCallable.CURRENT_EXPANDABLE = current_expandable
|
99
97
|
|
100
98
|
|
99
|
+
def _infer_variable_name(name: Any, depth: int) -> Any:
|
100
|
+
if name is not None:
|
101
|
+
return name
|
102
|
+
name = varname(depth + 1)
|
103
|
+
if name is None:
|
104
|
+
raise ClassiqValueError(
|
105
|
+
"Could not infer variable name. Please specify the variable name explicitly"
|
106
|
+
)
|
107
|
+
return name
|
108
|
+
|
109
|
+
|
101
110
|
class QVar(Symbolic):
|
111
|
+
CONSTRUCTOR_DEPTH: int = 1
|
112
|
+
|
102
113
|
def __init__(
|
103
114
|
self,
|
104
|
-
origin: Union[str, HandleBinding],
|
115
|
+
origin: Union[None, str, HandleBinding] = None,
|
105
116
|
*,
|
106
117
|
expr_str: Optional[str] = None,
|
107
118
|
depth: int = 2,
|
108
119
|
) -> None:
|
109
|
-
|
120
|
+
name = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
121
|
+
super().__init__(str(name), True)
|
110
122
|
source_ref = (
|
111
123
|
get_source_ref(sys._getframe(depth))
|
112
|
-
if isinstance(
|
113
|
-
else
|
124
|
+
if isinstance(name, str)
|
125
|
+
else name.source_ref
|
114
126
|
)
|
115
127
|
self._base_handle: HandleBinding = (
|
116
|
-
HandleBinding(name=
|
128
|
+
HandleBinding(name=name) if isinstance(name, str) else name
|
117
129
|
)
|
118
|
-
if isinstance(
|
130
|
+
if isinstance(name, str) and QCallable.CURRENT_EXPANDABLE is not None:
|
119
131
|
QCallable.CURRENT_EXPANDABLE.add_local_handle(
|
120
|
-
|
132
|
+
name, self.get_qmod_type(), source_ref
|
121
133
|
)
|
122
|
-
self._expr_str = expr_str if expr_str is not None else str(
|
134
|
+
self._expr_str = expr_str if expr_str is not None else str(name)
|
123
135
|
|
124
136
|
def get_handle_binding(self) -> HandleBinding:
|
125
137
|
return self._base_handle
|
@@ -180,13 +192,16 @@ Input = Annotated[_Q, PortDeclarationDirection.Input]
|
|
180
192
|
|
181
193
|
|
182
194
|
class QScalar(QVar, SymbolicExpr):
|
195
|
+
CONSTRUCTOR_DEPTH: int = 2
|
196
|
+
|
183
197
|
def __init__(
|
184
198
|
self,
|
185
|
-
origin: Union[str, HandleBinding],
|
199
|
+
origin: Union[None, str, HandleBinding] = None,
|
186
200
|
*,
|
187
201
|
_expr_str: Optional[str] = None,
|
188
202
|
depth: int = 2,
|
189
203
|
) -> None:
|
204
|
+
origin = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
190
205
|
QVar.__init__(self, origin, expr_str=_expr_str, depth=depth)
|
191
206
|
SymbolicExpr.__init__(self, str(origin), True)
|
192
207
|
|
@@ -286,9 +301,11 @@ _P = ParamSpec("_P")
|
|
286
301
|
|
287
302
|
|
288
303
|
class QNum(Generic[_P], QScalar):
|
304
|
+
CONSTRUCTOR_DEPTH: int = 3
|
305
|
+
|
289
306
|
def __init__(
|
290
307
|
self,
|
291
|
-
name: Union[str, HandleBinding],
|
308
|
+
name: Union[None, str, HandleBinding] = None,
|
292
309
|
size: Union[int, CInt, Expression, SymbolicExpr, None] = None,
|
293
310
|
is_signed: Union[bool, Expression, SymbolicExpr, None] = None,
|
294
311
|
fraction_digits: Union[int, CInt, Expression, None] = None,
|
@@ -398,10 +415,12 @@ class QNum(Generic[_P], QScalar):
|
|
398
415
|
|
399
416
|
|
400
417
|
class QArray(ArrayBase[_P], QVar):
|
418
|
+
CONSTRUCTOR_DEPTH: int = 3
|
419
|
+
|
401
420
|
# TODO [CAD-18620]: improve type hints
|
402
421
|
def __init__(
|
403
422
|
self,
|
404
|
-
name: Union[str, HandleBinding],
|
423
|
+
name: Union[None, str, HandleBinding] = None,
|
405
424
|
element_type: Union[_GenericAlias, QuantumType] = QBit,
|
406
425
|
length: Optional[Union[int, SymbolicExpr, Expression]] = None,
|
407
426
|
_expr_str: Optional[str] = None,
|
@@ -425,14 +444,6 @@ class QArray(ArrayBase[_P], QVar):
|
|
425
444
|
def _get_subscript(self, index: Union[slice, int, SymbolicExpr]) -> Any:
|
426
445
|
if isinstance(index, SymbolicExpr) and index.is_quantum:
|
427
446
|
raise ClassiqValueError("Non-classical parameter for slicing")
|
428
|
-
if (
|
429
|
-
isinstance(index, int)
|
430
|
-
and self._length is not None
|
431
|
-
and self._length.is_evaluated()
|
432
|
-
):
|
433
|
-
length = self._length.to_int_value()
|
434
|
-
if index < 0 or index >= length:
|
435
|
-
raise ClassiqValueError(SUBSCRIPT_OUT_OF_BOUNDS_MSG)
|
436
447
|
|
437
448
|
return _create_qvar_for_qtype(
|
438
449
|
self.get_qmod_type().element_type,
|
@@ -450,20 +461,6 @@ class QArray(ArrayBase[_P], QVar):
|
|
450
461
|
slice_.stop, (int, SymbolicExpr)
|
451
462
|
):
|
452
463
|
raise ClassiqValueError(ILLEGAL_SLICE_MSG)
|
453
|
-
if (
|
454
|
-
isinstance(slice_.start, int)
|
455
|
-
and isinstance(slice_.stop, int)
|
456
|
-
and slice_.start >= slice_.stop
|
457
|
-
):
|
458
|
-
raise ClassiqValueError(
|
459
|
-
ILLEGAL_SLICE_BOUNDS_MSG.format(slice_.start, slice_.stop)
|
460
|
-
)
|
461
|
-
if self._length is not None and self._length.is_evaluated():
|
462
|
-
length = self._length.to_int_value()
|
463
|
-
if (isinstance(slice_.start, int) and slice_.start < 0) or (
|
464
|
-
isinstance(slice_.stop, int) and slice_.stop > length
|
465
|
-
):
|
466
|
-
raise ClassiqValueError(SLICE_OUT_OF_BOUNDS_MSG)
|
467
464
|
|
468
465
|
return QArray(
|
469
466
|
name=SlicedHandleBinding(
|
@@ -547,16 +544,19 @@ class QArray(ArrayBase[_P], QVar):
|
|
547
544
|
|
548
545
|
|
549
546
|
class QStruct(QVar):
|
547
|
+
CONSTRUCTOR_DEPTH: int = 2
|
548
|
+
|
550
549
|
_struct_name: str
|
551
550
|
_fields: Mapping[str, QVar]
|
552
551
|
|
553
552
|
def __init__(
|
554
553
|
self,
|
555
|
-
|
554
|
+
origin: Union[None, str, HandleBinding] = None,
|
556
555
|
_struct_name: Optional[str] = None,
|
557
556
|
_fields: Optional[Mapping[str, QVar]] = None,
|
558
557
|
_expr_str: Optional[str] = None,
|
559
558
|
) -> None:
|
559
|
+
name = _infer_variable_name(origin, self.CONSTRUCTOR_DEPTH)
|
560
560
|
if _struct_name is None or _fields is None:
|
561
561
|
with _no_current_expandable():
|
562
562
|
temp_var = QStruct.to_qvar(name, type(self), _expr_str)
|
@@ -611,7 +611,7 @@ class QStruct(QVar):
|
|
611
611
|
for field_name, (field_class, field_type) in field_types.items()
|
612
612
|
}
|
613
613
|
return QStruct(
|
614
|
-
|
614
|
+
origin,
|
615
615
|
_struct_name=type_hint.__name__,
|
616
616
|
_fields=field_vars,
|
617
617
|
_expr_str=expr_str,
|
classiq/qmod/quantum_function.py
CHANGED
@@ -153,10 +153,10 @@ 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.interpreters.
|
157
|
-
|
156
|
+
from classiq.model_expansions.interpreters.frontend_generative_interpreter import (
|
157
|
+
FrontendGenerativeInterpreter,
|
158
158
|
)
|
159
|
-
from classiq.qmod.semantics.
|
159
|
+
from classiq.qmod.semantics.annotation.call_annotation import (
|
160
160
|
resolve_function_calls,
|
161
161
|
)
|
162
162
|
|
@@ -169,7 +169,7 @@ class QFunc(BaseQFunc):
|
|
169
169
|
for gen_func in generative_functions
|
170
170
|
},
|
171
171
|
)
|
172
|
-
interpreter =
|
172
|
+
interpreter = FrontendGenerativeInterpreter(model_stub, generative_functions)
|
173
173
|
set_frontend_interpreter(interpreter)
|
174
174
|
return interpreter.expand()
|
175
175
|
|
File without changes
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from collections.abc import Iterator, Mapping
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from classiq.interface.exceptions import ClassiqError
|
6
|
+
from classiq.interface.generator.visitor import Visitor
|
7
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
8
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
9
|
+
from classiq.interface.model.quantum_function_declaration import (
|
10
|
+
AnonQuantumOperandDeclaration,
|
11
|
+
QuantumFunctionDeclaration,
|
12
|
+
QuantumOperandDeclaration,
|
13
|
+
)
|
14
|
+
from classiq.interface.model.quantum_lambda_function import (
|
15
|
+
QuantumLambdaFunction,
|
16
|
+
)
|
17
|
+
|
18
|
+
from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
|
19
|
+
from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
|
20
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
21
|
+
from classiq.qmod.semantics.lambdas import get_renamed_parameters
|
22
|
+
|
23
|
+
|
24
|
+
def _annotate_function_call_decl(
|
25
|
+
fc: QuantumFunctionCall,
|
26
|
+
function_dict: Mapping[str, QuantumFunctionDeclaration],
|
27
|
+
) -> None:
|
28
|
+
if fc._func_decl is None:
|
29
|
+
func_decl = function_dict.get(fc.func_name)
|
30
|
+
if func_decl is None:
|
31
|
+
raise ClassiqError(
|
32
|
+
f"Error resolving function {fc.func_name}, the function is not found in included library."
|
33
|
+
)
|
34
|
+
fc.set_func_decl(func_decl)
|
35
|
+
|
36
|
+
for arg, param in zip(fc.positional_args, fc.func_decl.positional_arg_declarations):
|
37
|
+
if not isinstance(param, AnonQuantumOperandDeclaration):
|
38
|
+
continue
|
39
|
+
args: list
|
40
|
+
if isinstance(arg, list):
|
41
|
+
args = arg
|
42
|
+
else:
|
43
|
+
args = [arg]
|
44
|
+
for qlambda in args:
|
45
|
+
if isinstance(qlambda, QuantumLambdaFunction):
|
46
|
+
qlambda.set_op_decl(param)
|
47
|
+
|
48
|
+
|
49
|
+
class _CallLambdaAnnotator(Visitor):
|
50
|
+
def __init__(
|
51
|
+
self, quantum_functions: Mapping[str, QuantumFunctionDeclaration]
|
52
|
+
) -> None:
|
53
|
+
self._quantum_functions = dict(quantum_functions)
|
54
|
+
self._current_operands: dict[str, QuantumOperandDeclaration] = {}
|
55
|
+
|
56
|
+
@contextmanager
|
57
|
+
def set_operands(
|
58
|
+
self, operands: dict[str, QuantumOperandDeclaration]
|
59
|
+
) -> Iterator[None]:
|
60
|
+
previous_operands = self._current_operands
|
61
|
+
self._current_operands = operands
|
62
|
+
yield
|
63
|
+
self._current_operands = previous_operands
|
64
|
+
|
65
|
+
def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
|
66
|
+
with self.set_operands(func.operand_declarations_dict):
|
67
|
+
self.generic_visit(func)
|
68
|
+
|
69
|
+
def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
|
70
|
+
lambda_operands = get_renamed_parameters(lambda_func)[1]
|
71
|
+
with self.set_operands(self._current_operands | lambda_operands):
|
72
|
+
self.generic_visit(lambda_func)
|
73
|
+
|
74
|
+
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
75
|
+
_annotate_function_call_decl(
|
76
|
+
call, self._quantum_functions | self._current_operands
|
77
|
+
)
|
78
|
+
self.generic_visit(call)
|
79
|
+
|
80
|
+
|
81
|
+
def resolve_function_calls(
|
82
|
+
root: Any,
|
83
|
+
quantum_function_dict: Mapping[str, QuantumFunctionDeclaration],
|
84
|
+
) -> None:
|
85
|
+
all_functions: Mapping[str, QuantumFunctionDeclaration] = {
|
86
|
+
**BUILTIN_FUNCTION_DECLARATIONS,
|
87
|
+
**quantum_function_dict,
|
88
|
+
}
|
89
|
+
with ErrorManager().ignore_errors_context():
|
90
|
+
QStructAnnotator().visit(quantum_function_dict)
|
91
|
+
QStructAnnotator().visit(root)
|
92
|
+
_CallLambdaAnnotator(all_functions).visit(root)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from classiq.interface.model.port_declaration import PortDeclaration
|
2
|
+
from classiq.interface.model.quantum_function_declaration import (
|
3
|
+
AnonQuantumOperandDeclaration,
|
4
|
+
QuantumOperandDeclaration,
|
5
|
+
)
|
6
|
+
from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
|
7
|
+
|
8
|
+
from classiq import AnonClassicalParameterDeclaration
|
9
|
+
|
10
|
+
|
11
|
+
def get_renamed_parameters(
|
12
|
+
lambda_func: QuantumLambdaFunction,
|
13
|
+
) -> tuple[list[str], dict[str, QuantumOperandDeclaration], list[PortDeclaration]]:
|
14
|
+
renamed_parameters: list[str] = []
|
15
|
+
renamed_operands: dict[str, QuantumOperandDeclaration] = {}
|
16
|
+
renamed_ports: list[PortDeclaration] = []
|
17
|
+
for idx, param in enumerate(lambda_func.func_decl.positional_arg_declarations):
|
18
|
+
param_name = lambda_func.pos_rename_params[idx]
|
19
|
+
if isinstance(param, AnonClassicalParameterDeclaration):
|
20
|
+
renamed_parameters.append(param_name)
|
21
|
+
elif isinstance(param, AnonQuantumOperandDeclaration):
|
22
|
+
renamed_operands[param_name] = param.rename(param_name)
|
23
|
+
else:
|
24
|
+
renamed_ports.append(param.rename(param_name))
|
25
|
+
return renamed_parameters, renamed_operands, renamed_ports
|
@@ -2,7 +2,6 @@ import ast
|
|
2
2
|
from collections.abc import Iterator, Mapping, Sequence
|
3
3
|
from contextlib import contextmanager
|
4
4
|
from typing import (
|
5
|
-
Any,
|
6
5
|
Optional,
|
7
6
|
)
|
8
7
|
|
@@ -15,9 +14,6 @@ from classiq.interface.generator.functions.port_declaration import (
|
|
15
14
|
PortDeclarationDirection,
|
16
15
|
)
|
17
16
|
from classiq.interface.generator.visitor import Visitor
|
18
|
-
from classiq.interface.model.classical_parameter_declaration import (
|
19
|
-
AnonClassicalParameterDeclaration,
|
20
|
-
)
|
21
17
|
from classiq.interface.model.handle_binding import (
|
22
18
|
FieldHandleBinding,
|
23
19
|
HandleBinding,
|
@@ -33,7 +29,6 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
33
29
|
)
|
34
30
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
35
31
|
from classiq.interface.model.quantum_function_declaration import (
|
36
|
-
AnonQuantumOperandDeclaration,
|
37
32
|
QuantumFunctionDeclaration,
|
38
33
|
QuantumOperandDeclaration,
|
39
34
|
)
|
@@ -51,9 +46,10 @@ from classiq.model_expansions.visitors.variable_references import VarRefCollecto
|
|
51
46
|
from classiq.qmod.builtins.functions import (
|
52
47
|
BUILTIN_FUNCTION_DECLARATIONS,
|
53
48
|
)
|
54
|
-
from classiq.qmod.semantics.annotation import
|
49
|
+
from classiq.qmod.semantics.annotation.call_annotation import resolve_function_calls
|
50
|
+
from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
|
55
51
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
56
|
-
from classiq.qmod.semantics.
|
52
|
+
from classiq.qmod.semantics.lambdas import get_renamed_parameters
|
57
53
|
from classiq.qmod.semantics.validation.constants_validation import (
|
58
54
|
check_duplicate_constants,
|
59
55
|
)
|
@@ -202,13 +198,6 @@ class StaticSemanticsVisitor(Visitor):
|
|
202
198
|
def visit_QuantumOperation(self, op: QuantumOperation) -> None:
|
203
199
|
with self._error_manager.node_context(op):
|
204
200
|
if isinstance(op, QuantumFunctionCall):
|
205
|
-
annotate_function_call_decl(
|
206
|
-
op,
|
207
|
-
{
|
208
|
-
**self._functions_dict,
|
209
|
-
**self.current_scope.operands,
|
210
|
-
},
|
211
|
-
)
|
212
201
|
validate_call_arguments(
|
213
202
|
op,
|
214
203
|
{
|
@@ -243,8 +232,8 @@ class StaticSemanticsVisitor(Visitor):
|
|
243
232
|
)
|
244
233
|
|
245
234
|
def visit_QuantumLambdaFunction(self, lambda_func: QuantumLambdaFunction) -> None:
|
246
|
-
renamed_parameters, renamed_operands, renamed_ports = (
|
247
|
-
|
235
|
+
renamed_parameters, renamed_operands, renamed_ports = get_renamed_parameters(
|
236
|
+
lambda_func
|
248
237
|
)
|
249
238
|
scope = StaticScope(
|
250
239
|
parameters=self.current_scope.parameters + renamed_parameters,
|
@@ -259,22 +248,6 @@ class StaticSemanticsVisitor(Visitor):
|
|
259
248
|
with self.scoped_visit(scope):
|
260
249
|
self.generic_visit(lambda_func)
|
261
250
|
|
262
|
-
def _get_renamed_parameters(
|
263
|
-
self, lambda_func: QuantumLambdaFunction
|
264
|
-
) -> tuple[list[str], dict[str, QuantumOperandDeclaration], list[PortDeclaration]]:
|
265
|
-
renamed_parameters: list[str] = []
|
266
|
-
renamed_operands: dict[str, QuantumOperandDeclaration] = {}
|
267
|
-
renamed_ports: list[PortDeclaration] = []
|
268
|
-
for idx, param in enumerate(lambda_func.func_decl.positional_arg_declarations):
|
269
|
-
param_name = lambda_func.pos_rename_params[idx]
|
270
|
-
if isinstance(param, AnonClassicalParameterDeclaration):
|
271
|
-
renamed_parameters.append(param_name)
|
272
|
-
elif isinstance(param, AnonQuantumOperandDeclaration):
|
273
|
-
renamed_operands[param_name] = param.rename(param_name)
|
274
|
-
else:
|
275
|
-
renamed_ports.append(param.rename(param_name))
|
276
|
-
return renamed_parameters, renamed_operands, renamed_ports
|
277
|
-
|
278
251
|
def visit_HandleBinding(self, handle: HandleBinding) -> None:
|
279
252
|
resolve_handle(self.current_scope, handle)
|
280
253
|
|
@@ -375,26 +348,15 @@ class StaticSemanticsVisitor(Visitor):
|
|
375
348
|
)
|
376
349
|
|
377
350
|
|
378
|
-
def resolve_function_calls(
|
379
|
-
root: Any,
|
380
|
-
quantum_function_dict: Mapping[str, QuantumFunctionDeclaration],
|
381
|
-
) -> None:
|
382
|
-
with ErrorManager().ignore_errors_context():
|
383
|
-
QStructAnnotator().visit(quantum_function_dict)
|
384
|
-
QStructAnnotator().visit(root)
|
385
|
-
StaticSemanticsVisitor(
|
386
|
-
{**BUILTIN_FUNCTION_DECLARATIONS, **quantum_function_dict},
|
387
|
-
[],
|
388
|
-
).visit(root)
|
389
|
-
|
390
|
-
|
391
351
|
def static_semantics_analysis_pass(
|
392
352
|
model: Model, error_type: Optional[type[Exception]] = ClassiqSemanticError
|
393
353
|
) -> None:
|
394
354
|
_check_function_name_collisions(model, error_type)
|
395
355
|
QStructAnnotator().visit(model)
|
356
|
+
functions = {**BUILTIN_FUNCTION_DECLARATIONS, **model.function_dict}
|
357
|
+
resolve_function_calls(model, functions)
|
396
358
|
StaticSemanticsVisitor(
|
397
|
-
|
359
|
+
functions,
|
398
360
|
[const.name for const in model.constants],
|
399
361
|
).visit(model)
|
400
362
|
if error_type is not None:
|
classiq/qmod/utilities.py
CHANGED
@@ -103,3 +103,19 @@ def unwrap_forward_ref(x: Any) -> Any:
|
|
103
103
|
if isinstance(x, ForwardRef):
|
104
104
|
return x.__forward_arg__
|
105
105
|
return x
|
106
|
+
|
107
|
+
|
108
|
+
def varname(depth: int) -> Optional[str]:
|
109
|
+
frame = sys._getframe(depth)
|
110
|
+
codes = inspect.getframeinfo(frame).code_context
|
111
|
+
if codes is None or len(codes) != 1:
|
112
|
+
return None
|
113
|
+
code = codes[0]
|
114
|
+
if "=" not in code:
|
115
|
+
return None
|
116
|
+
var_name = code.split("=")[0].strip()
|
117
|
+
if ":" in var_name:
|
118
|
+
var_name = var_name.split(":")[0].strip()
|
119
|
+
if not var_name.isidentifier():
|
120
|
+
return None
|
121
|
+
return var_name
|