classiq 0.43.3__py3-none-any.whl → 0.45.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 +8 -3
- classiq/_internals/api_wrapper.py +2 -2
- classiq/_internals/authentication/auth0.py +1 -1
- classiq/_internals/authentication/device.py +5 -1
- classiq/_internals/authentication/token_manager.py +5 -4
- classiq/_internals/client.py +5 -8
- classiq/_internals/config.py +1 -2
- classiq/_internals/host_checker.py +34 -13
- classiq/_internals/jobs.py +3 -3
- classiq/analyzer/analyzer.py +1 -1
- classiq/analyzer/analyzer_utilities.py +1 -1
- classiq/analyzer/rb.py +1 -1
- classiq/applications/chemistry/chemistry_model_constructor.py +13 -7
- classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/applications/combinatorial_helpers/encoding_mapping.py +1 -1
- classiq/applications/combinatorial_helpers/encoding_utils.py +2 -1
- classiq/applications/combinatorial_helpers/optimization_model.py +1 -1
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +1 -1
- classiq/applications/combinatorial_helpers/pyomo_utils.py +1 -2
- classiq/applications/combinatorial_helpers/transformations/encoding.py +1 -1
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -4
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +1 -1
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -1
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
- classiq/applications/finance/finance_model_constructor.py +4 -3
- 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/circuit_utils.py +1 -1
- classiq/applications/qnn/datasets/dataset_base_classes.py +2 -1
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/qlayer.py +3 -2
- classiq/applications/qnn/torch_utils.py +2 -1
- classiq/applications/qsvm/qsvm_model_constructor.py +1 -1
- classiq/execution/execution_session.py +1 -1
- classiq/execution/jobs.py +5 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/cytoscape_graph.py +1 -2
- classiq/interface/analyzer/result.py +2 -3
- classiq/interface/ast_node.py +1 -18
- classiq/interface/backend/backend_preferences.py +11 -18
- 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 +4 -3
- classiq/interface/chemistry/fermionic_operator.py +1 -2
- classiq/interface/chemistry/ground_state_problem.py +2 -3
- classiq/interface/chemistry/molecule.py +1 -2
- classiq/interface/chemistry/operator.py +8 -10
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +1 -1
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +32 -0
- classiq/{exceptions.py → interface/exceptions.py} +4 -0
- classiq/interface/executor/aws_execution_cost.py +2 -2
- classiq/interface/executor/execution_preferences.py +2 -47
- classiq/interface/executor/execution_result.py +1 -2
- classiq/interface/executor/optimizer_preferences.py +2 -3
- classiq/interface/executor/quantum_code.py +1 -2
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +1 -2
- classiq/interface/executor/result.py +29 -14
- classiq/interface/finance/function_input.py +6 -11
- classiq/interface/generator/amplitude_loading.py +2 -3
- classiq/interface/generator/ansatz_library.py +1 -1
- 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 +37 -44
- classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
- classiq/interface/generator/arith/arithmetic.py +10 -8
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +1 -2
- classiq/interface/generator/arith/arithmetic_expression_abc.py +22 -3
- classiq/interface/generator/arith/arithmetic_expression_parser.py +3 -4
- classiq/interface/generator/arith/arithmetic_expression_validator.py +1 -2
- classiq/interface/generator/arith/arithmetic_param_getters.py +1 -2
- classiq/interface/generator/arith/arithmetic_result_builder.py +15 -11
- classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
- classiq/interface/generator/arith/binary_ops.py +7 -7
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +44 -21
- classiq/interface/generator/arith/logical_ops.py +1 -2
- classiq/interface/generator/arith/register_user_input.py +1 -2
- classiq/interface/generator/arith/unary_ops.py +1 -2
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/chemistry_function_params.py +1 -2
- classiq/interface/generator/circuit_code/circuit_code.py +1 -2
- classiq/interface/generator/circuit_code/types_and_constants.py +1 -2
- classiq/interface/generator/commuting_pauli_exponentiation.py +1 -2
- classiq/interface/generator/constant.py +1 -1
- classiq/interface/generator/control_state.py +1 -2
- classiq/interface/generator/custom_ansatz.py +1 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
- classiq/interface/generator/expressions/enums/finance_functions.py +4 -5
- classiq/interface/generator/expressions/evaluated_expression.py +1 -2
- classiq/interface/generator/expressions/expression.py +1 -2
- classiq/interface/generator/expressions/expression_constants.py +3 -1
- classiq/interface/generator/expressions/non_symbolic_expr.py +1 -1
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +53 -70
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -7
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +1 -1
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/function_params.py +2 -3
- 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 -114
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +10 -10
- classiq/interface/generator/functions/port_declaration.py +1 -2
- classiq/interface/generator/functions/type_name.py +80 -0
- classiq/interface/generator/generated_circuit_data.py +3 -3
- classiq/interface/generator/grover_diffuser.py +1 -2
- classiq/interface/generator/grover_operator.py +1 -2
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +1 -2
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +1 -2
- classiq/interface/generator/hardware/hardware_data.py +1 -2
- classiq/interface/generator/hardware_efficient_ansatz.py +2 -3
- classiq/interface/generator/hartree_fock.py +1 -2
- classiq/interface/generator/linear_pauli_rotations.py +1 -2
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +1 -2
- classiq/interface/generator/mcx.py +1 -2
- classiq/interface/generator/model/constraints.py +2 -3
- classiq/interface/generator/model/model.py +12 -2
- classiq/interface/generator/model/preferences/preferences.py +7 -3
- classiq/interface/generator/model/quantum_register.py +1 -2
- classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
- classiq/interface/generator/oracles/custom_oracle.py +1 -2
- classiq/interface/generator/oracles/oracle_abc.py +1 -2
- classiq/interface/generator/partitioned_register.py +1 -2
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +1 -2
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +1 -2
- classiq/interface/generator/qsvm.py +2 -3
- classiq/interface/generator/quantum_function_call.py +4 -2
- classiq/interface/generator/quantum_program.py +6 -7
- classiq/interface/generator/range_types.py +1 -1
- classiq/interface/generator/register_role.py +8 -2
- classiq/interface/generator/slice_parsing_utils.py +1 -2
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +1 -2
- classiq/interface/generator/state_preparation/metrics.py +2 -3
- classiq/interface/generator/state_preparation/state_preparation.py +1 -2
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
- classiq/interface/generator/transpiler_basis_gates.py +1 -1
- classiq/interface/generator/types/builtin_enum_declarations.py +38 -45
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
- classiq/interface/generator/types/enum_declaration.py +1 -2
- classiq/interface/generator/types/qstruct_declaration.py +17 -0
- classiq/interface/generator/types/struct_declaration.py +2 -3
- classiq/interface/generator/ucc.py +1 -2
- classiq/interface/generator/unitary_gate.py +1 -2
- classiq/interface/generator/validations/flow_graph.py +1 -2
- classiq/interface/generator/validations/validator_functions.py +1 -2
- classiq/interface/hardware.py +1 -1
- classiq/interface/helpers/validation_helpers.py +2 -19
- classiq/interface/ide/visual_model.py +10 -4
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +2 -3
- classiq/interface/model/bind_operation.py +26 -7
- 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 +17 -6
- classiq/interface/model/model.py +29 -7
- classiq/interface/model/native_function_definition.py +8 -4
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/port_declaration.py +21 -4
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +22 -8
- 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 +136 -194
- classiq/interface/model/quantum_function_declaration.py +147 -165
- classiq/interface/model/quantum_lambda_function.py +23 -6
- classiq/interface/model/quantum_statement.py +34 -8
- classiq/interface/model/quantum_type.py +41 -11
- classiq/interface/model/quantum_variable_declaration.py +1 -1
- classiq/interface/model/statement_block.py +2 -0
- classiq/interface/model/validation_handle.py +8 -2
- 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/classical_execution_primitives.py +1 -1
- classiq/qmod/builtins/functions.py +39 -11
- classiq/qmod/builtins/operations.py +172 -41
- classiq/qmod/classical_function.py +1 -1
- classiq/qmod/declaration_inferrer.py +102 -57
- 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_constant.py +1 -1
- classiq/qmod/qmod_parameter.py +27 -4
- classiq/qmod/qmod_variable.py +405 -174
- classiq/qmod/quantum_callable.py +3 -3
- classiq/qmod/quantum_expandable.py +128 -68
- classiq/qmod/quantum_function.py +24 -5
- classiq/qmod/semantics/annotation.py +13 -15
- classiq/qmod/semantics/error_manager.py +36 -10
- classiq/qmod/semantics/static_semantics_visitor.py +164 -76
- classiq/qmod/semantics/validation/func_call_validation.py +43 -97
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/types_validation.py +108 -1
- classiq/qmod/symbolic.py +2 -1
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +26 -5
- classiq/{interface/ide/show.py → show.py} +1 -1
- {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/METADATA +3 -3
- {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/RECORD +219 -207
- classiq/qmod/qmod_struct.py +0 -13
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/WHEEL +0 -0
@@ -1,68 +1,76 @@
|
|
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
|
+
Literal,
|
9
10
|
Optional,
|
11
|
+
Sequence,
|
12
|
+
Tuple,
|
10
13
|
Type,
|
11
14
|
get_args,
|
12
15
|
get_origin,
|
16
|
+
overload,
|
13
17
|
)
|
14
18
|
|
15
19
|
from typing_extensions import _AnnotatedAlias
|
16
20
|
|
21
|
+
from classiq.interface.exceptions import ClassiqValueError
|
17
22
|
from classiq.interface.generator.functions.classical_type import (
|
18
23
|
Bool,
|
19
24
|
ClassicalArray,
|
20
25
|
ClassicalList,
|
21
|
-
ConcreteClassicalType,
|
22
|
-
Enum,
|
23
26
|
Integer,
|
24
27
|
Real,
|
25
|
-
Struct,
|
26
28
|
)
|
29
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
30
|
+
from classiq.interface.generator.functions.port_declaration import (
|
31
|
+
PortDeclarationDirection,
|
32
|
+
)
|
33
|
+
from classiq.interface.generator.functions.type_name import Enum
|
27
34
|
from classiq.interface.generator.types.enum_declaration import (
|
28
35
|
EnumDeclaration,
|
29
36
|
declaration_from_enum,
|
30
37
|
)
|
31
38
|
from classiq.interface.model.classical_parameter_declaration import (
|
32
|
-
|
39
|
+
AnonClassicalParameterDeclaration,
|
33
40
|
)
|
34
|
-
from classiq.interface.model.port_declaration import
|
41
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
35
42
|
from classiq.interface.model.quantum_function_declaration import (
|
43
|
+
AnonPositionalArg,
|
44
|
+
AnonQuantumOperandDeclaration,
|
45
|
+
NamedParamsQuantumFunctionDeclaration,
|
36
46
|
PositionalArg,
|
37
|
-
QuantumFunctionDeclaration,
|
38
|
-
QuantumOperandDeclaration,
|
39
47
|
)
|
40
48
|
|
41
|
-
from classiq import StructDeclaration
|
42
|
-
from classiq.exceptions import ClassiqValueError
|
49
|
+
from classiq import Struct, StructDeclaration
|
43
50
|
from classiq.qmod.model_state_container import ModelStateContainer
|
44
|
-
from classiq.qmod.qmod_parameter import CArray, CBool, CInt,
|
51
|
+
from classiq.qmod.qmod_parameter import CArray, CBool, CInt, CReal
|
45
52
|
from classiq.qmod.qmod_variable import QVar, get_type_hint_expr
|
46
|
-
from classiq.qmod.quantum_callable import
|
53
|
+
from classiq.qmod.quantum_callable import QCallableList
|
47
54
|
from classiq.qmod.utilities import unmangle_keyword, version_portable_get_args
|
48
55
|
|
49
|
-
|
56
|
+
if sys.version_info[0:2] >= (3, 9):
|
57
|
+
from typing import Annotated
|
50
58
|
|
51
59
|
|
52
60
|
def python_type_to_qmod(
|
53
61
|
py_type: type, *, qmodule: ModelStateContainer
|
54
62
|
) -> Optional[ConcreteClassicalType]:
|
55
|
-
if py_type
|
63
|
+
if py_type is int or py_type is CInt:
|
56
64
|
return Integer()
|
57
|
-
elif py_type
|
65
|
+
elif py_type in (float, complex) or py_type is CReal:
|
58
66
|
return Real()
|
59
|
-
elif py_type
|
67
|
+
elif py_type is bool or py_type is CBool:
|
60
68
|
return Bool()
|
61
|
-
elif get_origin(py_type)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
elif get_origin(py_type)
|
69
|
+
elif get_origin(py_type) is list:
|
70
|
+
element_type = python_type_to_qmod(get_args(py_type)[0], qmodule=qmodule)
|
71
|
+
if element_type is not None:
|
72
|
+
return ClassicalList(element_type=element_type)
|
73
|
+
elif get_origin(py_type) is CArray:
|
66
74
|
array_args = version_portable_get_args(py_type)
|
67
75
|
if len(array_args) == 1:
|
68
76
|
return ClassicalList(
|
@@ -112,72 +120,109 @@ def _add_qmod_struct(py_type: Type, *, qmodule: ModelStateContainer) -> None:
|
|
112
120
|
)
|
113
121
|
|
114
122
|
|
115
|
-
def _extract_port_decl(name: str, py_type: Any) ->
|
123
|
+
def _extract_port_decl(name: Optional[str], py_type: Any) -> AnonPortDeclaration:
|
116
124
|
# FIXME: CAD-13409
|
117
125
|
qtype: Type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
|
118
126
|
direction = qtype.port_direction(py_type)
|
119
127
|
if isinstance(py_type, _AnnotatedAlias):
|
120
128
|
py_type = py_type.__args__[0]
|
121
|
-
|
122
|
-
name=
|
129
|
+
param = AnonPortDeclaration(
|
130
|
+
name=None,
|
123
131
|
direction=direction,
|
124
132
|
quantum_type=qtype.to_qmod_quantum_type(py_type),
|
125
133
|
)
|
134
|
+
if name is not None:
|
135
|
+
param = param.rename(name)
|
136
|
+
return param
|
126
137
|
|
127
138
|
|
128
139
|
def _extract_operand_decl(
|
129
|
-
name: str, py_type: Any, qmodule: ModelStateContainer
|
130
|
-
) ->
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
140
|
+
name: Optional[str], py_type: Any, qmodule: ModelStateContainer
|
141
|
+
) -> AnonQuantumOperandDeclaration:
|
142
|
+
is_list = (get_origin(py_type) or py_type) is QCallableList
|
143
|
+
if get_origin(py_type) is list:
|
144
|
+
is_list = True
|
145
|
+
py_type = version_portable_get_args(py_type)
|
146
|
+
type_args = version_portable_get_args(py_type)
|
147
|
+
param_decls = [_extract_operand_param(arg_type) for arg_type in type_args]
|
148
|
+
param = AnonQuantumOperandDeclaration(
|
136
149
|
name=name,
|
137
|
-
positional_arg_declarations=_extract_positional_args(
|
138
|
-
|
150
|
+
positional_arg_declarations=_extract_positional_args(
|
151
|
+
param_decls, qmodule=qmodule
|
152
|
+
),
|
153
|
+
is_list=is_list,
|
154
|
+
)
|
155
|
+
if name is not None:
|
156
|
+
param = param.rename(name)
|
157
|
+
return param
|
158
|
+
|
159
|
+
|
160
|
+
def _extract_operand_param(py_type: Any) -> Tuple[Optional[str], Any]:
|
161
|
+
if sys.version_info[0:2] < (3, 9) or get_origin(py_type) is not Annotated:
|
162
|
+
return None, py_type
|
163
|
+
args = get_args(py_type)
|
164
|
+
if len(args) == 2:
|
165
|
+
if isinstance(args[1], PortDeclarationDirection):
|
166
|
+
return None, py_type
|
167
|
+
elif isinstance(args[1], str):
|
168
|
+
return args[1], args[0]
|
169
|
+
elif get_origin(args[1]) is Literal:
|
170
|
+
return version_portable_get_args(args[1])[0], args[0]
|
171
|
+
elif len(args) == 3 and isinstance(args[1], PortDeclarationDirection):
|
172
|
+
if isinstance(args[2], str):
|
173
|
+
return args[2], Annotated[args[0], args[1]]
|
174
|
+
elif get_origin(args[2]) is Literal:
|
175
|
+
return version_portable_get_args(args[2])[0], Annotated[args[0], args[1]]
|
176
|
+
raise ClassiqValueError(
|
177
|
+
f"Operand parameter declaration must be of the form <param-type> or "
|
178
|
+
f"Annotated[<param-type>, <param-name>]. Got {py_type}"
|
139
179
|
)
|
140
180
|
|
141
181
|
|
182
|
+
@overload
|
142
183
|
def _extract_positional_args(
|
143
|
-
args:
|
144
|
-
) ->
|
145
|
-
|
146
|
-
|
184
|
+
args: Sequence[Tuple[str, Any]], qmodule: ModelStateContainer
|
185
|
+
) -> Sequence[PositionalArg]:
|
186
|
+
pass
|
187
|
+
|
188
|
+
|
189
|
+
@overload
|
190
|
+
def _extract_positional_args(
|
191
|
+
args: Sequence[Tuple[Optional[str], Any]], qmodule: ModelStateContainer
|
192
|
+
) -> Sequence[AnonPositionalArg]:
|
193
|
+
pass
|
194
|
+
|
195
|
+
|
196
|
+
def _extract_positional_args(
|
197
|
+
args: Sequence[Tuple[Optional[str], Any]], qmodule: ModelStateContainer
|
198
|
+
) -> Sequence[AnonPositionalArg]:
|
199
|
+
result: List[AnonPositionalArg] = []
|
200
|
+
for name, py_type in args:
|
147
201
|
if name == "return":
|
148
202
|
continue
|
149
203
|
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
|
-
)
|
204
|
+
classical_type = python_type_to_qmod(py_type, qmodule=qmodule)
|
205
|
+
if classical_type is not None:
|
206
|
+
param = AnonClassicalParameterDeclaration(
|
207
|
+
name=None,
|
208
|
+
classical_type=classical_type,
|
164
209
|
)
|
210
|
+
if name is not None:
|
211
|
+
param = param.rename(name)
|
212
|
+
result.append(param)
|
165
213
|
elif QVar.from_type_hint(py_type) is not None:
|
166
214
|
result.append(_extract_port_decl(name, py_type))
|
167
215
|
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
216
|
result.append(_extract_operand_decl(name, py_type, qmodule=qmodule))
|
172
217
|
return result
|
173
218
|
|
174
219
|
|
175
220
|
def infer_func_decl(
|
176
221
|
py_func: Callable, qmodule: ModelStateContainer
|
177
|
-
) ->
|
178
|
-
return
|
222
|
+
) -> NamedParamsQuantumFunctionDeclaration:
|
223
|
+
return NamedParamsQuantumFunctionDeclaration(
|
179
224
|
name=unmangle_keyword(py_func.__name__),
|
180
225
|
positional_arg_declarations=_extract_positional_args(
|
181
|
-
py_func.__annotations__, qmodule=qmodule
|
226
|
+
list(py_func.__annotations__.items()), qmodule=qmodule
|
182
227
|
),
|
183
228
|
)
|
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 "="
|