classiq 0.43.3__py3-none-any.whl → 0.44.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 +7 -1
- classiq/_internals/client.py +4 -7
- classiq/_internals/host_checker.py +34 -12
- classiq/_internals/jobs.py +2 -2
- classiq/applications/chemistry/chemistry_model_constructor.py +12 -6
- classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
- classiq/applications/finance/finance_model_constructor.py +3 -2
- classiq/applications/grover/grover_model_constructor.py +7 -5
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/qnn/qlayer.py +1 -1
- classiq/exceptions.py +4 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/ast_node.py +1 -18
- classiq/interface/backend/backend_preferences.py +10 -16
- classiq/interface/backend/ionq/ionq_quantum_program.py +1 -1
- classiq/interface/backend/pydantic_backend.py +0 -5
- classiq/interface/backend/quantum_backend_providers.py +3 -2
- classiq/interface/chemistry/operator.py +5 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +32 -0
- classiq/interface/executor/execution_preferences.py +1 -45
- classiq/interface/executor/result.py +25 -12
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- classiq/interface/generator/application_apis/chemistry_declarations.py +78 -60
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +19 -10
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +36 -22
- classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
- classiq/interface/generator/arith/arithmetic_expression_abc.py +21 -1
- classiq/interface/generator/arith/binary_ops.py +5 -4
- classiq/interface/generator/arith/extremum_operations.py +43 -19
- classiq/interface/generator/constant.py +1 -1
- classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
- classiq/interface/generator/expressions/expression_constants.py +3 -1
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -66
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/functions/builtins/core_library/__init__.py +4 -2
- classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +41 -41
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +52 -42
- classiq/interface/generator/functions/builtins/open_lib_functions.py +1095 -3347
- classiq/interface/generator/functions/builtins/quantum_operators.py +9 -22
- classiq/interface/generator/functions/classical_function_declaration.py +14 -6
- classiq/interface/generator/functions/classical_type.py +7 -76
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +10 -10
- classiq/interface/generator/functions/type_name.py +104 -0
- classiq/interface/generator/generated_circuit_data.py +3 -3
- classiq/interface/generator/model/model.py +11 -0
- classiq/interface/generator/model/preferences/preferences.py +5 -0
- classiq/interface/generator/quantum_function_call.py +3 -0
- classiq/interface/generator/quantum_program.py +2 -2
- classiq/interface/generator/register_role.py +7 -1
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
- classiq/interface/generator/types/qstruct_declaration.py +17 -0
- classiq/interface/generator/types/struct_declaration.py +1 -1
- classiq/interface/helpers/validation_helpers.py +1 -17
- classiq/interface/ide/visual_model.py +9 -2
- classiq/interface/interface_version.py +1 -0
- classiq/interface/model/bind_operation.py +25 -5
- classiq/interface/model/classical_parameter_declaration.py +8 -5
- classiq/interface/model/control.py +5 -5
- classiq/interface/model/handle_binding.py +185 -12
- classiq/interface/model/inplace_binary_operation.py +16 -4
- classiq/interface/model/model.py +28 -5
- classiq/interface/model/native_function_definition.py +8 -4
- classiq/interface/model/parameter.py +14 -0
- classiq/interface/model/port_declaration.py +20 -2
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +21 -6
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +30 -6
- classiq/interface/model/quantum_expressions/quantum_expression.py +4 -9
- classiq/interface/model/quantum_function_call.py +135 -192
- classiq/interface/model/quantum_function_declaration.py +147 -165
- classiq/interface/model/quantum_lambda_function.py +24 -6
- classiq/interface/model/quantum_statement.py +34 -8
- classiq/interface/model/quantum_type.py +61 -10
- classiq/interface/model/quantum_variable_declaration.py +1 -1
- classiq/interface/model/statement_block.py +2 -0
- classiq/interface/model/validation_handle.py +7 -0
- classiq/interface/server/global_versions.py +4 -4
- classiq/interface/server/routes.py +2 -0
- classiq/interface/source_reference.py +59 -0
- classiq/qmod/__init__.py +2 -3
- classiq/qmod/builtins/functions.py +39 -11
- classiq/qmod/builtins/operations.py +171 -40
- classiq/qmod/declaration_inferrer.py +99 -56
- classiq/qmod/expression_query.py +1 -1
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/pretty_printer.py +71 -53
- classiq/qmod/pretty_print/pretty_printer.py +98 -52
- classiq/qmod/qfunc.py +11 -5
- classiq/qmod/qmod_parameter.py +1 -2
- classiq/qmod/qmod_variable.py +364 -172
- classiq/qmod/quantum_callable.py +3 -3
- classiq/qmod/quantum_expandable.py +119 -65
- classiq/qmod/quantum_function.py +15 -3
- classiq/qmod/semantics/annotation.py +12 -13
- classiq/qmod/semantics/error_manager.py +36 -10
- classiq/qmod/semantics/static_semantics_visitor.py +163 -75
- classiq/qmod/semantics/validation/func_call_validation.py +42 -96
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/types_validation.py +108 -1
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +26 -5
- {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/METADATA +3 -3
- {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/RECORD +111 -99
- classiq/qmod/qmod_struct.py +0 -13
- /classiq/{interface/ide/show.py → show.py} +0 -0
- {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/WHEEL +0 -0
@@ -1,15 +1,18 @@
|
|
1
1
|
import dataclasses
|
2
2
|
import inspect
|
3
|
+
import sys
|
3
4
|
from enum import EnumMeta
|
4
5
|
from typing import (
|
5
6
|
Any,
|
6
7
|
Callable,
|
7
|
-
Dict,
|
8
8
|
List,
|
9
9
|
Optional,
|
10
|
+
Sequence,
|
11
|
+
Tuple,
|
10
12
|
Type,
|
11
13
|
get_args,
|
12
14
|
get_origin,
|
15
|
+
overload,
|
13
16
|
)
|
14
17
|
|
15
18
|
from typing_extensions import _AnnotatedAlias
|
@@ -18,51 +21,55 @@ from classiq.interface.generator.functions.classical_type import (
|
|
18
21
|
Bool,
|
19
22
|
ClassicalArray,
|
20
23
|
ClassicalList,
|
21
|
-
ConcreteClassicalType,
|
22
|
-
Enum,
|
23
24
|
Integer,
|
24
25
|
Real,
|
25
|
-
Struct,
|
26
26
|
)
|
27
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
28
|
+
from classiq.interface.generator.functions.port_declaration import (
|
29
|
+
PortDeclarationDirection,
|
30
|
+
)
|
31
|
+
from classiq.interface.generator.functions.type_name import Enum
|
27
32
|
from classiq.interface.generator.types.enum_declaration import (
|
28
33
|
EnumDeclaration,
|
29
34
|
declaration_from_enum,
|
30
35
|
)
|
31
36
|
from classiq.interface.model.classical_parameter_declaration import (
|
32
|
-
|
37
|
+
AnonClassicalParameterDeclaration,
|
33
38
|
)
|
34
|
-
from classiq.interface.model.port_declaration import
|
39
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
35
40
|
from classiq.interface.model.quantum_function_declaration import (
|
41
|
+
AnonPositionalArg,
|
42
|
+
AnonQuantumOperandDeclaration,
|
43
|
+
NamedParamsQuantumFunctionDeclaration,
|
36
44
|
PositionalArg,
|
37
|
-
QuantumFunctionDeclaration,
|
38
|
-
QuantumOperandDeclaration,
|
39
45
|
)
|
40
46
|
|
41
|
-
from classiq import StructDeclaration
|
47
|
+
from classiq import Struct, StructDeclaration
|
42
48
|
from classiq.exceptions import ClassiqValueError
|
43
49
|
from classiq.qmod.model_state_container import ModelStateContainer
|
44
|
-
from classiq.qmod.qmod_parameter import CArray, CBool, CInt,
|
50
|
+
from classiq.qmod.qmod_parameter import CArray, CBool, CInt, CReal
|
45
51
|
from classiq.qmod.qmod_variable import QVar, get_type_hint_expr
|
46
|
-
from classiq.qmod.quantum_callable import
|
52
|
+
from classiq.qmod.quantum_callable import QCallableList
|
47
53
|
from classiq.qmod.utilities import unmangle_keyword, version_portable_get_args
|
48
54
|
|
49
|
-
|
55
|
+
if sys.version_info[0:2] >= (3, 9):
|
56
|
+
from typing import Annotated
|
50
57
|
|
51
58
|
|
52
59
|
def python_type_to_qmod(
|
53
60
|
py_type: type, *, qmodule: ModelStateContainer
|
54
61
|
) -> Optional[ConcreteClassicalType]:
|
55
|
-
if py_type
|
62
|
+
if py_type is int or py_type is CInt:
|
56
63
|
return Integer()
|
57
|
-
elif py_type
|
64
|
+
elif py_type in (float, complex) or py_type is CReal:
|
58
65
|
return Real()
|
59
|
-
elif py_type
|
66
|
+
elif py_type is bool or py_type is CBool:
|
60
67
|
return Bool()
|
61
|
-
elif get_origin(py_type)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
elif get_origin(py_type)
|
68
|
+
elif get_origin(py_type) is list:
|
69
|
+
element_type = python_type_to_qmod(get_args(py_type)[0], qmodule=qmodule)
|
70
|
+
if element_type is not None:
|
71
|
+
return ClassicalList(element_type=element_type)
|
72
|
+
elif get_origin(py_type) is CArray:
|
66
73
|
array_args = version_portable_get_args(py_type)
|
67
74
|
if len(array_args) == 1:
|
68
75
|
return ClassicalList(
|
@@ -112,72 +119,108 @@ def _add_qmod_struct(py_type: Type, *, qmodule: ModelStateContainer) -> None:
|
|
112
119
|
)
|
113
120
|
|
114
121
|
|
115
|
-
def _extract_port_decl(name: str, py_type: Any) ->
|
122
|
+
def _extract_port_decl(name: Optional[str], py_type: Any) -> AnonPortDeclaration:
|
116
123
|
# FIXME: CAD-13409
|
117
124
|
qtype: Type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
|
118
125
|
direction = qtype.port_direction(py_type)
|
119
126
|
if isinstance(py_type, _AnnotatedAlias):
|
120
127
|
py_type = py_type.__args__[0]
|
121
|
-
|
122
|
-
name=
|
128
|
+
param = AnonPortDeclaration(
|
129
|
+
name=None,
|
123
130
|
direction=direction,
|
124
131
|
quantum_type=qtype.to_qmod_quantum_type(py_type),
|
125
132
|
)
|
133
|
+
if name is not None:
|
134
|
+
param = param.rename(name)
|
135
|
+
return param
|
126
136
|
|
127
137
|
|
128
138
|
def _extract_operand_decl(
|
129
|
-
name: str, py_type: Any, qmodule: ModelStateContainer
|
130
|
-
) ->
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
139
|
+
name: Optional[str], py_type: Any, qmodule: ModelStateContainer
|
140
|
+
) -> AnonQuantumOperandDeclaration:
|
141
|
+
is_list = (get_origin(py_type) or py_type) is QCallableList
|
142
|
+
if get_origin(py_type) is list:
|
143
|
+
is_list = True
|
144
|
+
py_type = version_portable_get_args(py_type)
|
145
|
+
type_args = version_portable_get_args(py_type)
|
146
|
+
param_decls = [_extract_operand_param(arg_type) for arg_type in type_args]
|
147
|
+
param = AnonQuantumOperandDeclaration(
|
136
148
|
name=name,
|
137
|
-
positional_arg_declarations=_extract_positional_args(
|
138
|
-
|
149
|
+
positional_arg_declarations=_extract_positional_args(
|
150
|
+
param_decls, qmodule=qmodule
|
151
|
+
),
|
152
|
+
is_list=is_list,
|
153
|
+
)
|
154
|
+
if name is not None:
|
155
|
+
param = param.rename(name)
|
156
|
+
return param
|
157
|
+
|
158
|
+
|
159
|
+
def _extract_operand_param(py_type: Any) -> Tuple[Optional[str], Any]:
|
160
|
+
if sys.version_info[0:2] < (3, 9) or get_origin(py_type) is not Annotated:
|
161
|
+
return None, py_type
|
162
|
+
args = get_args(py_type)
|
163
|
+
if len(args) == 2:
|
164
|
+
if isinstance(args[1], PortDeclarationDirection):
|
165
|
+
return None, py_type
|
166
|
+
elif isinstance(args[1], str):
|
167
|
+
return args[1], args[0]
|
168
|
+
elif (
|
169
|
+
len(args) == 3
|
170
|
+
and isinstance(args[1], PortDeclarationDirection)
|
171
|
+
and isinstance(args[2], str)
|
172
|
+
):
|
173
|
+
return args[2], Annotated[args[0], args[1]]
|
174
|
+
raise ClassiqValueError(
|
175
|
+
f"Operand parameter declaration must be of the form <param-type> or "
|
176
|
+
f"Annotated[<param-type>, <param-name>]. Got {py_type}"
|
139
177
|
)
|
140
178
|
|
141
179
|
|
180
|
+
@overload
|
142
181
|
def _extract_positional_args(
|
143
|
-
args:
|
144
|
-
) ->
|
145
|
-
|
146
|
-
|
182
|
+
args: Sequence[Tuple[str, Any]], qmodule: ModelStateContainer
|
183
|
+
) -> Sequence[PositionalArg]:
|
184
|
+
pass
|
185
|
+
|
186
|
+
|
187
|
+
@overload
|
188
|
+
def _extract_positional_args(
|
189
|
+
args: Sequence[Tuple[Optional[str], Any]], qmodule: ModelStateContainer
|
190
|
+
) -> Sequence[AnonPositionalArg]:
|
191
|
+
pass
|
192
|
+
|
193
|
+
|
194
|
+
def _extract_positional_args(
|
195
|
+
args: Sequence[Tuple[Optional[str], Any]], qmodule: ModelStateContainer
|
196
|
+
) -> Sequence[AnonPositionalArg]:
|
197
|
+
result: List[AnonPositionalArg] = []
|
198
|
+
for name, py_type in args:
|
147
199
|
if name == "return":
|
148
200
|
continue
|
149
201
|
name = unmangle_keyword(name)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
or isinstance(py_type, EnumMeta)
|
156
|
-
)
|
157
|
-
or get_origin(py_type) == CArray
|
158
|
-
):
|
159
|
-
result.append(
|
160
|
-
ClassicalParameterDeclaration(
|
161
|
-
name=name,
|
162
|
-
classical_type=python_type_to_qmod(py_type, qmodule=qmodule),
|
163
|
-
)
|
202
|
+
classical_type = python_type_to_qmod(py_type, qmodule=qmodule)
|
203
|
+
if classical_type is not None:
|
204
|
+
param = AnonClassicalParameterDeclaration(
|
205
|
+
name=None,
|
206
|
+
classical_type=classical_type,
|
164
207
|
)
|
208
|
+
if name is not None:
|
209
|
+
param = param.rename(name)
|
210
|
+
result.append(param)
|
165
211
|
elif QVar.from_type_hint(py_type) is not None:
|
166
212
|
result.append(_extract_port_decl(name, py_type))
|
167
213
|
else:
|
168
|
-
assert (get_origin(py_type) or py_type) is QCallable or (
|
169
|
-
get_origin(py_type) or py_type
|
170
|
-
) is QCallableList
|
171
214
|
result.append(_extract_operand_decl(name, py_type, qmodule=qmodule))
|
172
215
|
return result
|
173
216
|
|
174
217
|
|
175
218
|
def infer_func_decl(
|
176
219
|
py_func: Callable, qmodule: ModelStateContainer
|
177
|
-
) ->
|
178
|
-
return
|
220
|
+
) -> NamedParamsQuantumFunctionDeclaration:
|
221
|
+
return NamedParamsQuantumFunctionDeclaration(
|
179
222
|
name=unmangle_keyword(py_func.__name__),
|
180
223
|
positional_arg_declarations=_extract_positional_args(
|
181
|
-
py_func.__annotations__, qmodule=qmodule
|
224
|
+
list(py_func.__annotations__.items()), qmodule=qmodule
|
182
225
|
),
|
183
226
|
)
|
classiq/qmod/expression_query.py
CHANGED
@@ -15,7 +15,7 @@ def get_expression_numeric_attributes(
|
|
15
15
|
) -> Tuple[int, bool, int]:
|
16
16
|
res_type = compute_arithmetic_result_type(
|
17
17
|
expr_str=str(expr),
|
18
|
-
var_types={var.
|
18
|
+
var_types={str(var.get_handle_binding()): var.get_qmod_type() for var in vars},
|
19
19
|
machine_precision=machine_precision,
|
20
20
|
)
|
21
21
|
if TYPE_CHECKING:
|
@@ -2,6 +2,7 @@ from typing import Dict
|
|
2
2
|
|
3
3
|
from classiq.interface.generator.constant import Constant
|
4
4
|
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
5
|
+
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
5
6
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
6
7
|
|
7
8
|
from classiq import StructDeclaration
|
@@ -10,6 +11,7 @@ from classiq import StructDeclaration
|
|
10
11
|
class ModelStateContainer:
|
11
12
|
enum_decls: Dict[str, EnumDeclaration]
|
12
13
|
type_decls: Dict[str, StructDeclaration]
|
14
|
+
qstruct_decls: Dict[str, QStructDeclaration]
|
13
15
|
native_defs: Dict[str, NativeFunctionDefinition]
|
14
16
|
constants: Dict[str, Constant]
|
15
17
|
|
@@ -1,24 +1,29 @@
|
|
1
|
-
from typing import Dict, List, Optional
|
1
|
+
from typing import Dict, List, Mapping, Optional, Union
|
2
2
|
|
3
3
|
from classiq.interface.generator.constant import Constant
|
4
4
|
from classiq.interface.generator.expressions.expression import Expression
|
5
5
|
from classiq.interface.generator.functions.classical_type import (
|
6
6
|
ClassicalArray,
|
7
|
+
)
|
8
|
+
from classiq.interface.generator.functions.concrete_types import (
|
7
9
|
ConcreteClassicalType,
|
8
|
-
|
10
|
+
ConcreteQuantumType,
|
9
11
|
)
|
10
12
|
from classiq.interface.generator.functions.port_declaration import (
|
11
13
|
PortDeclarationDirection,
|
12
14
|
)
|
15
|
+
from classiq.interface.generator.functions.type_name import TypeName
|
13
16
|
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
17
|
+
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
14
18
|
from classiq.interface.generator.visitor import NodeType, Visitor
|
15
19
|
from classiq.interface.model.bind_operation import BindOperation
|
16
20
|
from classiq.interface.model.classical_if import ClassicalIf
|
17
21
|
from classiq.interface.model.classical_parameter_declaration import (
|
18
|
-
|
22
|
+
AnonClassicalParameterDeclaration,
|
19
23
|
)
|
20
24
|
from classiq.interface.model.control import Control
|
21
25
|
from classiq.interface.model.handle_binding import (
|
26
|
+
FieldHandleBinding,
|
22
27
|
HandleBinding,
|
23
28
|
SlicedHandleBinding,
|
24
29
|
SubscriptHandleBinding,
|
@@ -27,7 +32,9 @@ from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperat
|
|
27
32
|
from classiq.interface.model.invert import Invert
|
28
33
|
from classiq.interface.model.model import Model
|
29
34
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
30
|
-
from classiq.interface.model.port_declaration import
|
35
|
+
from classiq.interface.model.port_declaration import (
|
36
|
+
AnonPortDeclaration,
|
37
|
+
)
|
31
38
|
from classiq.interface.model.power import Power
|
32
39
|
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
33
40
|
AmplitudeLoadingOperation,
|
@@ -40,6 +47,8 @@ from classiq.interface.model.quantum_function_call import (
|
|
40
47
|
QuantumFunctionCall,
|
41
48
|
)
|
42
49
|
from classiq.interface.model.quantum_function_declaration import (
|
50
|
+
AnonQuantumFunctionDeclaration,
|
51
|
+
AnonQuantumOperandDeclaration,
|
43
52
|
QuantumFunctionDeclaration,
|
44
53
|
QuantumOperandDeclaration,
|
45
54
|
)
|
@@ -59,7 +68,13 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
59
68
|
)
|
60
69
|
from classiq.interface.model.within_apply_operation import WithinApply
|
61
70
|
|
62
|
-
from classiq import
|
71
|
+
from classiq import (
|
72
|
+
Bool,
|
73
|
+
ClassicalList,
|
74
|
+
Integer,
|
75
|
+
Real,
|
76
|
+
StructDeclaration,
|
77
|
+
)
|
63
78
|
from classiq.qmod.native.expression_to_qmod import transform_expression
|
64
79
|
from classiq.qmod.semantics.static_semantics_visitor import (
|
65
80
|
static_semantics_analysis_pass,
|
@@ -82,36 +97,37 @@ class DSLPrettyPrinter(Visitor):
|
|
82
97
|
|
83
98
|
def visit_Model(self, model: Model) -> str:
|
84
99
|
# FIXME - CAD-20149: Remove this line once the froggies are removed, and the visit of lambdas can be done without accessing the func_decl property (with rename_params values only).
|
85
|
-
static_semantics_analysis_pass(model)
|
100
|
+
static_semantics_analysis_pass(model, None)
|
86
101
|
enum_decls = [self.visit(enum_decl) for enum_decl in model.enums]
|
87
102
|
struct_decls = [self.visit(struct_decl) for struct_decl in model.types]
|
103
|
+
qstruct_decls = [self.visit(qstruct_decl) for qstruct_decl in model.qstructs]
|
88
104
|
func_defs = [self.visit(func_def) for func_def in model.functions]
|
89
105
|
constants = [self.visit(constant) for constant in model.constants]
|
90
106
|
classical_code = (
|
91
|
-
f"cscope ```\n{model.classical_execution_code}\n
|
107
|
+
[f"cscope ```\n{model.classical_execution_code}\n```\n"]
|
92
108
|
if model.classical_execution_code
|
93
|
-
else
|
109
|
+
else []
|
94
110
|
)
|
111
|
+
|
95
112
|
return "\n".join(
|
96
|
-
[
|
113
|
+
[
|
114
|
+
*constants,
|
115
|
+
*enum_decls,
|
116
|
+
*struct_decls,
|
117
|
+
*qstruct_decls,
|
118
|
+
*func_defs,
|
119
|
+
*classical_code,
|
120
|
+
]
|
97
121
|
)
|
98
122
|
|
99
123
|
def visit_Constant(self, constant: Constant) -> str:
|
100
124
|
return f"{self._indent}{self.visit(constant.name)}: {self.visit(constant.const_type)} = {self.visit(constant.value)};\n"
|
101
125
|
|
102
|
-
def _visit_arg_decls(self, func_def:
|
103
|
-
|
104
|
-
self.visit(arg_decl)
|
105
|
-
for arg_decl in func_def.get_positional_arg_decls()
|
106
|
-
if not isinstance(arg_decl, PortDeclaration)
|
107
|
-
)
|
108
|
-
quantum_args = ", ".join(
|
109
|
-
self.visit(arg_decl)
|
110
|
-
for arg_decl in func_def.get_positional_arg_decls()
|
111
|
-
if isinstance(arg_decl, PortDeclaration)
|
126
|
+
def _visit_arg_decls(self, func_def: AnonQuantumFunctionDeclaration) -> str:
|
127
|
+
positional_args = ", ".join(
|
128
|
+
self.visit(arg_decl) for arg_decl in func_def.positional_arg_declarations
|
112
129
|
)
|
113
|
-
|
114
|
-
return f"{gen_time_arg_list}({quantum_args})"
|
130
|
+
return f"({positional_args})"
|
115
131
|
|
116
132
|
def visit_QuantumFunctionDeclaration(
|
117
133
|
self, func_decl: QuantumFunctionDeclaration
|
@@ -133,7 +149,12 @@ class DSLPrettyPrinter(Visitor):
|
|
133
149
|
def visit_StructDeclaration(self, struct_decl: StructDeclaration) -> str:
|
134
150
|
return f"struct {struct_decl.name} {{\n{self._visit_variables(struct_decl.variables)}}}\n"
|
135
151
|
|
136
|
-
def
|
152
|
+
def visit_QStructDeclaration(self, qstruct_decl: QStructDeclaration) -> str:
|
153
|
+
return f"qstruct {qstruct_decl.name} {{\n{self._visit_variables(qstruct_decl.fields)}}}\n"
|
154
|
+
|
155
|
+
def _visit_variables(
|
156
|
+
self, variables: Mapping[str, Union[ConcreteClassicalType, ConcreteQuantumType]]
|
157
|
+
) -> str:
|
137
158
|
self._level += 1
|
138
159
|
variables_str = "".join(
|
139
160
|
f"{self._indent}{self.visit(field_name)}: {self.visit(var_decl)};\n"
|
@@ -147,13 +168,14 @@ class DSLPrettyPrinter(Visitor):
|
|
147
168
|
) -> str:
|
148
169
|
return f"{var_decl.name}: {self.visit(var_decl.quantum_type)}"
|
149
170
|
|
150
|
-
def
|
171
|
+
def visit_AnonPortDeclaration(self, port_decl: AnonPortDeclaration) -> str:
|
151
172
|
dir_str = (
|
152
173
|
f"{port_decl.direction} "
|
153
174
|
if port_decl.direction != PortDeclarationDirection.Inout
|
154
175
|
else ""
|
155
176
|
)
|
156
|
-
|
177
|
+
param_name = f"{port_decl.name}: " if port_decl.name is not None else ""
|
178
|
+
return f"{dir_str}{param_name}{self.visit(port_decl.quantum_type)}"
|
157
179
|
|
158
180
|
def visit_QuantumBit(self, qtype: QuantumBit) -> str:
|
159
181
|
return "qbit"
|
@@ -179,10 +201,11 @@ class DSLPrettyPrinter(Visitor):
|
|
179
201
|
|
180
202
|
return f"qnum{params}"
|
181
203
|
|
182
|
-
def
|
183
|
-
self, cparam:
|
204
|
+
def visit_AnonClassicalParameterDeclaration(
|
205
|
+
self, cparam: AnonClassicalParameterDeclaration
|
184
206
|
) -> str:
|
185
|
-
|
207
|
+
param_name = f"{cparam.name}: " if cparam.name is not None else ""
|
208
|
+
return f"{param_name}{self.visit(cparam.classical_type)}"
|
186
209
|
|
187
210
|
def visit_Integer(self, ctint: Integer) -> str:
|
188
211
|
return "int"
|
@@ -207,10 +230,16 @@ class DSLPrettyPrinter(Visitor):
|
|
207
230
|
) -> str:
|
208
231
|
return f"{self._indent}{self.visit_QuantumVariableDeclaration(local_decl)};\n"
|
209
232
|
|
233
|
+
def visit_AnonQuantumOperandDeclaration(
|
234
|
+
self, op_decl: AnonQuantumOperandDeclaration
|
235
|
+
) -> str:
|
236
|
+
param_name = f"{op_decl.name}: " if op_decl.name is not None else ""
|
237
|
+
return f"{param_name}qfunc{[] if op_decl.is_list else ''} {self._visit_arg_decls(op_decl)}"
|
238
|
+
|
210
239
|
def visit_QuantumOperandDeclaration(
|
211
240
|
self, op_decl: QuantumOperandDeclaration
|
212
241
|
) -> str:
|
213
|
-
return
|
242
|
+
return self.visit_AnonQuantumOperandDeclaration(op_decl)
|
214
243
|
|
215
244
|
def visit_NativeFunctionDefinition(self, func_def: NativeFunctionDefinition) -> str:
|
216
245
|
self._level += 1
|
@@ -219,18 +248,10 @@ class DSLPrettyPrinter(Visitor):
|
|
219
248
|
return f"{self.visit_QuantumFunctionDeclaration(func_def)} {{\n{body}}}\n"
|
220
249
|
|
221
250
|
def visit_QuantumFunctionCall(self, func_call: QuantumFunctionCall) -> str:
|
222
|
-
|
223
|
-
self.visit(arg_decl)
|
224
|
-
for arg_decl in func_call.get_positional_args()
|
225
|
-
if not isinstance(arg_decl, HandleBinding)
|
226
|
-
)
|
227
|
-
gen_time_arg_list = f"<{gen_time_args}>" if gen_time_args else ""
|
228
|
-
quantum_args = ", ".join(
|
229
|
-
self.visit(arg_decl)
|
230
|
-
for arg_decl in func_call.get_positional_args()
|
231
|
-
if isinstance(arg_decl, HandleBinding)
|
251
|
+
positional_args = ", ".join(
|
252
|
+
self.visit(arg_decl) for arg_decl in func_call.positional_args
|
232
253
|
)
|
233
|
-
return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}
|
254
|
+
return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}({positional_args});\n"
|
234
255
|
|
235
256
|
def visit_Control(self, op: Control) -> str:
|
236
257
|
control = f"{self._indent}control ({self.visit(op.expression)}) {{\n"
|
@@ -301,29 +322,26 @@ class DSLPrettyPrinter(Visitor):
|
|
301
322
|
)
|
302
323
|
|
303
324
|
def visit_QuantumLambdaFunction(self, qlambda: QuantumLambdaFunction) -> str:
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
)
|
310
|
-
quantum_args = ", ".join(
|
311
|
-
qlambda.rename_params.get(arg_decl.name, arg_decl.name)
|
312
|
-
for arg_decl in qlambda.func_decl.get_positional_arg_decls()
|
313
|
-
if isinstance(arg_decl, PortDeclaration)
|
325
|
+
positional_args = ", ".join(
|
326
|
+
qlambda.get_rename_params()[idx]
|
327
|
+
for idx, arg_decl in enumerate(
|
328
|
+
qlambda.func_decl.positional_arg_declarations
|
329
|
+
)
|
314
330
|
)
|
315
|
-
gen_time_arg_list = f"<{gen_time_args}>" if gen_time_args else ""
|
316
331
|
body = self._visit_body(qlambda.body)
|
317
|
-
return f"lambda
|
332
|
+
return f"lambda({positional_args}) {{\n{body}{self._indent}}}"
|
318
333
|
|
319
334
|
def visit_HandleBinding(self, var_ref: HandleBinding) -> str:
|
320
335
|
return var_ref.name
|
321
336
|
|
322
337
|
def visit_SlicedHandleBinding(self, var_ref: SlicedHandleBinding) -> str:
|
323
|
-
return f"{var_ref.
|
338
|
+
return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
|
324
339
|
|
325
340
|
def visit_SubscriptHandleBinding(self, var_ref: SubscriptHandleBinding) -> str:
|
326
|
-
return f"{var_ref.
|
341
|
+
return f"{self.visit(var_ref.base_handle)}[{self.visit(var_ref.index)}]"
|
342
|
+
|
343
|
+
def visit_FieldHandleBinding(self, var_ref: FieldHandleBinding) -> str:
|
344
|
+
return f"{self.visit(var_ref.base_handle)}.{self.visit(var_ref.field)}"
|
327
345
|
|
328
346
|
def visit_ArithmeticOperation(self, arith_op: ArithmeticOperation) -> str:
|
329
347
|
op = "^=" if arith_op.inplace_result else "="
|