classiq 0.39.0__py3-none-any.whl → 0.41.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 +5 -2
- classiq/_internals/api_wrapper.py +3 -21
- classiq/applications/chemistry/chemistry_model_constructor.py +87 -101
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +7 -26
- classiq/applications/combinatorial_helpers/optimization_model.py +7 -6
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +33 -55
- classiq/applications/combinatorial_optimization/__init__.py +4 -0
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +29 -26
- classiq/applications/finance/finance_model_constructor.py +23 -26
- classiq/applications/grover/grover_model_constructor.py +37 -38
- classiq/applications/qsvm/qsvm.py +1 -2
- classiq/applications/qsvm/qsvm_model_constructor.py +15 -16
- classiq/execution/__init__.py +4 -0
- classiq/execution/execution_session.py +151 -0
- classiq/execution/qnn.py +80 -0
- classiq/executor.py +2 -109
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +11 -0
- classiq/interface/applications/qsvm.py +0 -8
- classiq/interface/ast_node.py +12 -2
- classiq/interface/backend/backend_preferences.py +30 -6
- classiq/interface/backend/quantum_backend_providers.py +11 -11
- classiq/interface/executor/execution_preferences.py +7 -67
- classiq/interface/executor/execution_result.py +22 -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/binary_ops.py +88 -25
- classiq/interface/generator/arith/unary_ops.py +28 -19
- classiq/interface/generator/expressions/atomic_expression_functions.py +6 -2
- classiq/interface/generator/expressions/enums/__init__.py +10 -0
- classiq/interface/generator/expressions/enums/classical_enum.py +5 -1
- classiq/interface/generator/expressions/expression.py +9 -2
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +89 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +20 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +22 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +10 -1
- classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +8 -6
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +10 -4
- classiq/interface/generator/functions/builtins/internal_operators.py +7 -62
- classiq/interface/generator/functions/builtins/open_lib_functions.py +1627 -271
- classiq/interface/generator/functions/classical_type.py +27 -17
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/model/bind_operation.py +3 -1
- classiq/interface/model/call_synthesis_data.py +2 -13
- classiq/interface/model/classical_if.py +3 -1
- classiq/interface/model/classical_parameter_declaration.py +13 -0
- classiq/interface/model/control.py +6 -8
- classiq/interface/model/inplace_binary_operation.py +3 -1
- classiq/interface/model/invert.py +3 -1
- classiq/interface/model/port_declaration.py +8 -1
- classiq/interface/model/power.py +3 -1
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +4 -2
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +11 -1
- classiq/interface/model/quantum_function_call.py +4 -10
- classiq/interface/model/quantum_function_declaration.py +26 -4
- classiq/interface/model/quantum_lambda_function.py +1 -20
- classiq/interface/model/quantum_statement.py +9 -2
- classiq/interface/model/quantum_type.py +6 -5
- classiq/interface/model/repeat.py +3 -1
- classiq/interface/model/resolvers/function_call_resolver.py +0 -5
- classiq/interface/model/statement_block.py +19 -16
- classiq/interface/model/validations/handles_validator.py +8 -2
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +3 -1
- classiq/interface/server/routes.py +0 -5
- classiq/qmod/__init__.py +5 -2
- classiq/qmod/builtins/classical_execution_primitives.py +22 -2
- classiq/qmod/builtins/classical_functions.py +30 -35
- classiq/qmod/builtins/functions.py +263 -153
- classiq/qmod/builtins/operations.py +50 -26
- classiq/qmod/builtins/structs.py +50 -48
- classiq/qmod/declaration_inferrer.py +32 -27
- classiq/qmod/native/__init__.py +9 -0
- classiq/qmod/native/expression_to_qmod.py +8 -4
- classiq/qmod/native/pretty_printer.py +11 -18
- classiq/qmod/pretty_print/__init__.py +9 -0
- classiq/qmod/pretty_print/expression_to_python.py +221 -0
- classiq/qmod/pretty_print/pretty_printer.py +421 -0
- classiq/qmod/qmod_constant.py +7 -7
- classiq/qmod/qmod_parameter.py +57 -33
- classiq/qmod/qmod_struct.py +2 -2
- classiq/qmod/qmod_variable.py +40 -29
- classiq/qmod/quantum_callable.py +8 -4
- classiq/qmod/quantum_expandable.py +22 -15
- classiq/qmod/quantum_function.py +15 -4
- classiq/qmod/symbolic.py +73 -68
- classiq/qmod/symbolic_expr.py +1 -1
- classiq/qmod/symbolic_type.py +1 -4
- classiq/qmod/utilities.py +29 -0
- classiq/synthesis.py +15 -16
- {classiq-0.39.0.dist-info → classiq-0.41.0.dist-info}/METADATA +5 -4
- {classiq-0.39.0.dist-info → classiq-0.41.0.dist-info}/RECORD +95 -94
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- {classiq-0.39.0.dist-info → classiq-0.41.0.dist-info}/WHEEL +0 -0
@@ -1,10 +1,11 @@
|
|
1
1
|
import inspect
|
2
|
+
import sys
|
2
3
|
from types import FrameType
|
3
|
-
from typing import Any, Callable, Final, List, Mapping, Union
|
4
|
+
from typing import Any, Callable, Final, List, Mapping, Union, overload
|
4
5
|
|
5
6
|
from classiq.interface.generator.expressions.expression import Expression
|
6
7
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
7
|
-
|
8
|
+
REPEAT_OPERATOR_NAME,
|
8
9
|
)
|
9
10
|
from classiq.interface.model.bind_operation import BindOperation
|
10
11
|
from classiq.interface.model.classical_if import ClassicalIf
|
@@ -19,17 +20,18 @@ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
|
19
20
|
from classiq.interface.model.quantum_function_declaration import (
|
20
21
|
QuantumOperandDeclaration,
|
21
22
|
)
|
22
|
-
from classiq.interface.model.quantum_if_operation import QuantumIf
|
23
23
|
from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
|
24
24
|
from classiq.interface.model.repeat import Repeat
|
25
25
|
from classiq.interface.model.statement_block import StatementBlock
|
26
26
|
from classiq.interface.model.within_apply_operation import WithinApply
|
27
27
|
|
28
|
+
from classiq import Integer
|
28
29
|
from classiq.exceptions import ClassiqValueError
|
29
30
|
from classiq.qmod.qmod_variable import Input, Output, QArray, QBit, QNum, QVar
|
30
31
|
from classiq.qmod.quantum_callable import QCallable
|
31
32
|
from classiq.qmod.quantum_expandable import prepare_arg
|
32
33
|
from classiq.qmod.symbolic_expr import SymbolicExpr
|
34
|
+
from classiq.qmod.utilities import get_source_ref
|
33
35
|
|
34
36
|
_MISSING_VALUE: Final[int] = -1
|
35
37
|
|
@@ -39,6 +41,7 @@ def bind(
|
|
39
41
|
destination: Union[Output[QVar], List[Output[QVar]]],
|
40
42
|
) -> None:
|
41
43
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
44
|
+
source_ref = get_source_ref(sys._getframe(1))
|
42
45
|
if not isinstance(source, list):
|
43
46
|
source = [source]
|
44
47
|
if not isinstance(destination, list):
|
@@ -47,19 +50,7 @@ def bind(
|
|
47
50
|
BindOperation(
|
48
51
|
in_handles=[src_var.get_handle_binding() for src_var in source],
|
49
52
|
out_handles=[dst_var.get_handle_binding() for dst_var in destination],
|
50
|
-
|
51
|
-
)
|
52
|
-
|
53
|
-
|
54
|
-
def control(
|
55
|
-
operand: Union[QCallable, Callable[[], None]], ctrl: Union[QBit, QArray[QBit]]
|
56
|
-
) -> None:
|
57
|
-
_validate_operand(operand)
|
58
|
-
assert QCallable.CURRENT_EXPANDABLE is not None
|
59
|
-
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
60
|
-
Control(
|
61
|
-
control=ctrl.get_handle_binding(),
|
62
|
-
body=_operand_to_body(operand),
|
53
|
+
source_ref=source_ref,
|
63
54
|
)
|
64
55
|
)
|
65
56
|
|
@@ -73,24 +64,41 @@ def if_(
|
|
73
64
|
if else_ != _MISSING_VALUE:
|
74
65
|
_validate_operand(else_)
|
75
66
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
67
|
+
source_ref = get_source_ref(sys._getframe(1))
|
76
68
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
77
69
|
ClassicalIf(
|
78
70
|
condition=Expression(expr=str(condition)),
|
79
71
|
then=_operand_to_body(then),
|
80
72
|
else_=_operand_to_body(else_) if else_ != _MISSING_VALUE else [], # type: ignore[arg-type]
|
73
|
+
source_ref=source_ref,
|
81
74
|
)
|
82
75
|
)
|
83
76
|
|
84
77
|
|
85
|
-
|
86
|
-
|
78
|
+
@overload
|
79
|
+
def control(
|
80
|
+
ctrl: Union[QBit, QArray[QBit]], operand: Union[QCallable, Callable[[], None]]
|
87
81
|
) -> None:
|
88
|
-
|
82
|
+
pass
|
83
|
+
|
84
|
+
|
85
|
+
@overload
|
86
|
+
def control(ctrl: SymbolicExpr, operand: Union[QCallable, Callable[[], None]]) -> None:
|
87
|
+
pass
|
88
|
+
|
89
|
+
|
90
|
+
def control(
|
91
|
+
ctrl: Union[SymbolicExpr, QBit, QArray[QBit]],
|
92
|
+
operand: Union[QCallable, Callable[[], None]],
|
93
|
+
) -> None:
|
94
|
+
_validate_operand(operand)
|
89
95
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
96
|
+
source_ref = get_source_ref(sys._getframe(1))
|
90
97
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
91
|
-
|
92
|
-
expression=Expression(expr=str(
|
93
|
-
|
98
|
+
Control(
|
99
|
+
expression=Expression(expr=str(ctrl)),
|
100
|
+
body=_operand_to_body(operand),
|
101
|
+
source_ref=source_ref,
|
94
102
|
)
|
95
103
|
)
|
96
104
|
|
@@ -100,11 +108,13 @@ def inplace_add(
|
|
100
108
|
target: QNum,
|
101
109
|
) -> None:
|
102
110
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
111
|
+
source_ref = get_source_ref(sys._getframe(1))
|
103
112
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
104
113
|
InplaceBinaryOperation(
|
105
114
|
target=target.get_handle_binding(),
|
106
115
|
value=value.get_handle_binding(),
|
107
116
|
operation=BinaryOperation.Addition,
|
117
|
+
source_ref=source_ref,
|
108
118
|
)
|
109
119
|
)
|
110
120
|
|
@@ -114,11 +124,13 @@ def inplace_xor(
|
|
114
124
|
target: QNum,
|
115
125
|
) -> None:
|
116
126
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
127
|
+
source_ref = get_source_ref(sys._getframe(1))
|
117
128
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
118
129
|
InplaceBinaryOperation(
|
119
130
|
target=target.get_handle_binding(),
|
120
131
|
value=value.get_handle_binding(),
|
121
132
|
operation=BinaryOperation.Xor,
|
133
|
+
source_ref=source_ref,
|
122
134
|
)
|
123
135
|
)
|
124
136
|
|
@@ -130,10 +142,12 @@ def within_apply(
|
|
130
142
|
_validate_operand(compute)
|
131
143
|
_validate_operand(action)
|
132
144
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
145
|
+
source_ref = get_source_ref(sys._getframe(1))
|
133
146
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
134
147
|
WithinApply(
|
135
148
|
compute=_operand_to_body(compute),
|
136
149
|
action=_operand_to_body(action),
|
150
|
+
source_ref=source_ref,
|
137
151
|
)
|
138
152
|
)
|
139
153
|
|
@@ -141,14 +155,19 @@ def within_apply(
|
|
141
155
|
def repeat(count: Union[SymbolicExpr, int], iteration: Callable[[int], None]) -> None:
|
142
156
|
_validate_operand(iteration)
|
143
157
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
158
|
+
source_ref = get_source_ref(sys._getframe(1))
|
144
159
|
iteration_operand = prepare_arg(
|
145
|
-
|
160
|
+
QuantumOperandDeclaration(
|
161
|
+
name=REPEAT_OPERATOR_NAME, param_decls={"index": Integer()}
|
162
|
+
),
|
163
|
+
iteration,
|
146
164
|
)
|
147
165
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
148
166
|
Repeat(
|
149
167
|
iter_var=inspect.getfullargspec(iteration).args[0],
|
150
168
|
count=Expression(expr=str(count)),
|
151
169
|
body=iteration_operand.body,
|
170
|
+
source_ref=source_ref,
|
152
171
|
)
|
153
172
|
)
|
154
173
|
|
@@ -159,8 +178,13 @@ def power(
|
|
159
178
|
) -> None:
|
160
179
|
_validate_operand(operand)
|
161
180
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
181
|
+
source_ref = get_source_ref(sys._getframe(1))
|
162
182
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
163
|
-
Power(
|
183
|
+
Power(
|
184
|
+
power=Expression(expr=str(power)),
|
185
|
+
body=_operand_to_body(operand),
|
186
|
+
source_ref=source_ref,
|
187
|
+
)
|
164
188
|
)
|
165
189
|
|
166
190
|
|
@@ -169,8 +193,9 @@ def invert(
|
|
169
193
|
) -> None:
|
170
194
|
_validate_operand(operand)
|
171
195
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
196
|
+
source_ref = get_source_ref(sys._getframe(1))
|
172
197
|
QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
|
173
|
-
Invert(body=_operand_to_body(operand))
|
198
|
+
Invert(body=_operand_to_body(operand), source_ref=source_ref)
|
174
199
|
)
|
175
200
|
|
176
201
|
|
@@ -240,7 +265,6 @@ __all__ = [
|
|
240
265
|
"control",
|
241
266
|
"invert",
|
242
267
|
"if_",
|
243
|
-
"quantum_if",
|
244
268
|
"inplace_add",
|
245
269
|
"inplace_xor",
|
246
270
|
"power",
|
classiq/qmod/builtins/structs.py
CHANGED
@@ -1,113 +1,115 @@
|
|
1
1
|
# This file was generated automatically - do not edit manually
|
2
2
|
|
3
|
-
from
|
3
|
+
from classiq.interface.generator.expressions.enums.ladder_operator import LadderOperator
|
4
|
+
from classiq.interface.generator.expressions.enums.pauli import Pauli
|
4
5
|
|
6
|
+
from classiq.qmod.qmod_parameter import CArray, CBool, CInt, CReal
|
5
7
|
from classiq.qmod.qmod_struct import struct
|
6
8
|
|
7
9
|
|
8
10
|
@struct
|
9
11
|
class PauliTerm:
|
10
|
-
pauli:
|
11
|
-
coefficient:
|
12
|
+
pauli: CArray[Pauli]
|
13
|
+
coefficient: CReal
|
12
14
|
|
13
15
|
|
14
16
|
@struct
|
15
17
|
class MoleculeProblem:
|
16
|
-
mapping:
|
17
|
-
z2_symmetries:
|
18
|
+
mapping: CInt
|
19
|
+
z2_symmetries: CBool
|
18
20
|
molecule: "Molecule"
|
19
|
-
freeze_core:
|
20
|
-
remove_orbitals:
|
21
|
+
freeze_core: CBool
|
22
|
+
remove_orbitals: CArray[CInt]
|
21
23
|
|
22
24
|
|
23
25
|
@struct
|
24
26
|
class Molecule:
|
25
|
-
atoms:
|
26
|
-
spin:
|
27
|
-
charge:
|
27
|
+
atoms: CArray["ChemistryAtom"]
|
28
|
+
spin: CInt
|
29
|
+
charge: CInt
|
28
30
|
|
29
31
|
|
30
32
|
@struct
|
31
33
|
class ChemistryAtom:
|
32
|
-
element:
|
34
|
+
element: CInt
|
33
35
|
position: "Position"
|
34
36
|
|
35
37
|
|
36
38
|
@struct
|
37
39
|
class Position:
|
38
|
-
x:
|
39
|
-
y:
|
40
|
-
z:
|
40
|
+
x: CReal
|
41
|
+
y: CReal
|
42
|
+
z: CReal
|
41
43
|
|
42
44
|
|
43
45
|
@struct
|
44
46
|
class FockHamiltonianProblem:
|
45
|
-
mapping:
|
46
|
-
z2_symmetries:
|
47
|
-
terms:
|
48
|
-
num_particles:
|
47
|
+
mapping: CInt
|
48
|
+
z2_symmetries: CBool
|
49
|
+
terms: CArray["LadderTerm"]
|
50
|
+
num_particles: CArray[CInt]
|
49
51
|
|
50
52
|
|
51
53
|
@struct
|
52
54
|
class LadderTerm:
|
53
|
-
coefficient:
|
54
|
-
ops:
|
55
|
+
coefficient: CReal
|
56
|
+
ops: CArray["LadderOp"]
|
55
57
|
|
56
58
|
|
57
59
|
@struct
|
58
60
|
class LadderOp:
|
59
|
-
op:
|
60
|
-
index:
|
61
|
+
op: LadderOperator
|
62
|
+
index: CInt
|
61
63
|
|
62
64
|
|
63
65
|
@struct
|
64
66
|
class CombinatorialOptimizationSolution:
|
65
|
-
probability:
|
66
|
-
cost:
|
67
|
-
solution:
|
68
|
-
count:
|
67
|
+
probability: CReal
|
68
|
+
cost: CReal
|
69
|
+
solution: CArray[CInt]
|
70
|
+
count: CInt
|
69
71
|
|
70
72
|
|
71
73
|
@struct
|
72
74
|
class GaussianModel:
|
73
|
-
num_qubits:
|
74
|
-
normal_max_value:
|
75
|
-
default_probabilities:
|
76
|
-
rhos:
|
77
|
-
loss:
|
78
|
-
min_loss:
|
75
|
+
num_qubits: CInt
|
76
|
+
normal_max_value: CReal
|
77
|
+
default_probabilities: CArray[CReal]
|
78
|
+
rhos: CArray[CReal]
|
79
|
+
loss: CArray[CInt]
|
80
|
+
min_loss: CInt
|
79
81
|
|
80
82
|
|
81
83
|
@struct
|
82
84
|
class LogNormalModel:
|
83
|
-
num_qubits:
|
84
|
-
mu:
|
85
|
-
sigma:
|
85
|
+
num_qubits: CInt
|
86
|
+
mu: CReal
|
87
|
+
sigma: CReal
|
86
88
|
|
87
89
|
|
88
90
|
@struct
|
89
91
|
class FinanceFunction:
|
90
|
-
f:
|
91
|
-
threshold:
|
92
|
-
larger:
|
93
|
-
polynomial_degree:
|
94
|
-
use_chebyshev_polynomial_approximation:
|
95
|
-
tail_probability:
|
92
|
+
f: CInt
|
93
|
+
threshold: CReal
|
94
|
+
larger: CBool
|
95
|
+
polynomial_degree: CInt
|
96
|
+
use_chebyshev_polynomial_approximation: CBool
|
97
|
+
tail_probability: CReal
|
96
98
|
|
97
99
|
|
98
100
|
@struct
|
99
101
|
class QsvmResult:
|
100
|
-
test_score:
|
101
|
-
predicted_labels:
|
102
|
+
test_score: CReal
|
103
|
+
predicted_labels: CArray[CReal]
|
102
104
|
|
103
105
|
|
104
106
|
@struct
|
105
107
|
class QSVMFeatureMapPauli:
|
106
|
-
feature_dimension:
|
107
|
-
reps:
|
108
|
-
entanglement:
|
109
|
-
alpha:
|
110
|
-
paulis:
|
108
|
+
feature_dimension: CInt
|
109
|
+
reps: CInt
|
110
|
+
entanglement: CInt
|
111
|
+
alpha: CReal
|
112
|
+
paulis: CArray[CArray[Pauli]]
|
111
113
|
|
112
114
|
|
113
115
|
__all__ = [
|
@@ -9,8 +9,8 @@ from classiq.interface.generator.functions.classical_type import (
|
|
9
9
|
ClassicalArray,
|
10
10
|
ClassicalList,
|
11
11
|
ConcreteClassicalType,
|
12
|
+
CStructBase,
|
12
13
|
Integer,
|
13
|
-
QStructBase,
|
14
14
|
Real,
|
15
15
|
Struct,
|
16
16
|
)
|
@@ -27,7 +27,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
27
27
|
from classiq import StructDeclaration
|
28
28
|
from classiq.exceptions import ClassiqValueError
|
29
29
|
from classiq.qmod.model_state_container import ModelStateContainer
|
30
|
-
from classiq.qmod.qmod_parameter import
|
30
|
+
from classiq.qmod.qmod_parameter import CArray, CBool, CInt, CParam, CReal
|
31
31
|
from classiq.qmod.qmod_variable import QVar, get_type_hint_expr
|
32
32
|
from classiq.qmod.quantum_callable import QCallable, QCallableList
|
33
33
|
from classiq.qmod.utilities import unmangle_keyword, version_portable_get_args
|
@@ -38,34 +38,39 @@ OPERAND_ARG_NAME = "arg{i}"
|
|
38
38
|
def python_type_to_qmod(
|
39
39
|
py_type: type, *, qmodule: ModelStateContainer
|
40
40
|
) -> Optional[ConcreteClassicalType]:
|
41
|
-
if py_type == int:
|
41
|
+
if py_type == int or py_type is CInt:
|
42
42
|
return Integer()
|
43
|
-
elif py_type == float:
|
43
|
+
elif py_type == float or py_type is CReal:
|
44
44
|
return Real()
|
45
|
-
elif py_type == bool:
|
45
|
+
elif py_type == bool or py_type is CBool:
|
46
46
|
return Bool()
|
47
47
|
elif get_origin(py_type) == list:
|
48
48
|
return ClassicalList(
|
49
49
|
element_type=python_type_to_qmod(get_args(py_type)[0], qmodule=qmodule)
|
50
50
|
)
|
51
|
-
elif get_origin(py_type) ==
|
51
|
+
elif get_origin(py_type) == CArray:
|
52
52
|
array_args = version_portable_get_args(py_type)
|
53
|
-
if len(array_args)
|
54
|
-
|
55
|
-
|
53
|
+
if len(array_args) == 1:
|
54
|
+
return ClassicalList(
|
55
|
+
element_type=python_type_to_qmod(array_args[0], qmodule=qmodule)
|
56
56
|
)
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
elif len(array_args) == 2:
|
58
|
+
return ClassicalArray(
|
59
|
+
element_type=python_type_to_qmod(array_args[0], qmodule=qmodule),
|
60
|
+
size=get_type_hint_expr(array_args[1]),
|
61
|
+
)
|
62
|
+
raise ClassiqValueError(
|
63
|
+
"CArray accepts one or two generic parameters in the form "
|
64
|
+
"`CArray[<element-type>]` or `CArray[<element-type>, <size>]`"
|
60
65
|
)
|
61
|
-
elif inspect.isclass(py_type) and issubclass(py_type,
|
66
|
+
elif inspect.isclass(py_type) and issubclass(py_type, CStructBase):
|
62
67
|
_add_qmod_struct(py_type, qmodule=qmodule)
|
63
68
|
return Struct(name=py_type.__name__)
|
64
69
|
return None
|
65
70
|
|
66
71
|
|
67
72
|
def _add_qmod_struct(
|
68
|
-
py_type: Type[
|
73
|
+
py_type: Type[CStructBase], *, qmodule: ModelStateContainer
|
69
74
|
) -> None:
|
70
75
|
if (
|
71
76
|
py_type.__name__ in StructDeclaration.BUILTIN_STRUCT_DECLARATIONS
|
@@ -82,17 +87,6 @@ def _add_qmod_struct(
|
|
82
87
|
)
|
83
88
|
|
84
89
|
|
85
|
-
def _extract_param_decl(
|
86
|
-
name: str, py_type: Any, *, qmodule: ModelStateContainer
|
87
|
-
) -> ClassicalParameterDeclaration:
|
88
|
-
if len(get_args(py_type)) != 1:
|
89
|
-
raise ClassiqValueError("QParam takes exactly one generic argument")
|
90
|
-
py_type = get_args(py_type)[0]
|
91
|
-
return ClassicalParameterDeclaration(
|
92
|
-
name=name, classical_type=python_type_to_qmod(py_type, qmodule=qmodule)
|
93
|
-
)
|
94
|
-
|
95
|
-
|
96
90
|
def _extract_port_decl(name: str, py_type: Any) -> PortDeclaration:
|
97
91
|
# FIXME: CAD-13409
|
98
92
|
qtype: Type[QVar] = QVar.from_type_hint(py_type) # type:ignore[assignment]
|
@@ -128,8 +122,19 @@ def _extract_positional_args(
|
|
128
122
|
if name == "return":
|
129
123
|
continue
|
130
124
|
name = unmangle_keyword(name)
|
131
|
-
if
|
132
|
-
|
125
|
+
if (
|
126
|
+
inspect.isclass(py_type)
|
127
|
+
and issubclass(py_type, CParam)
|
128
|
+
or inspect.isclass(py_type)
|
129
|
+
and issubclass(py_type, CStructBase)
|
130
|
+
or get_origin(py_type) == CArray
|
131
|
+
):
|
132
|
+
result.append(
|
133
|
+
ClassicalParameterDeclaration(
|
134
|
+
name=name,
|
135
|
+
classical_type=python_type_to_qmod(py_type, qmodule=qmodule),
|
136
|
+
)
|
137
|
+
)
|
133
138
|
elif QVar.from_type_hint(py_type) is not None:
|
134
139
|
result.append(_extract_port_decl(name, py_type))
|
135
140
|
else:
|
classiq/qmod/native/__init__.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import ast
|
2
2
|
import re
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Callable, Dict, List, Mapping, Type
|
4
|
+
from typing import Callable, Dict, List, Mapping, Optional, Type
|
5
5
|
|
6
6
|
import numpy as np
|
7
7
|
|
@@ -42,7 +42,7 @@ LIST_FORMAT_CHAR_LIMIT = 20
|
|
42
42
|
@dataclass
|
43
43
|
class ASTToQMODCode:
|
44
44
|
level: int
|
45
|
-
decimal_precision: int
|
45
|
+
decimal_precision: Optional[int]
|
46
46
|
indent_seq: str = " "
|
47
47
|
|
48
48
|
@property
|
@@ -65,6 +65,8 @@ class ASTToQMODCode:
|
|
65
65
|
elif isinstance(node, ast.Name):
|
66
66
|
return node.id
|
67
67
|
elif isinstance(node, ast.Num):
|
68
|
+
if self.decimal_precision is None:
|
69
|
+
return str(node.n)
|
68
70
|
return str(np.round(node.n, self.decimal_precision))
|
69
71
|
elif isinstance(node, ast.Str):
|
70
72
|
return repr(node.s)
|
@@ -122,7 +124,7 @@ class ASTToQMODCode:
|
|
122
124
|
keywords = node.keywords
|
123
125
|
initializer_list = self.indent_items(
|
124
126
|
lambda: [
|
125
|
-
f"{keyword.arg}
|
127
|
+
f"{keyword.arg}={self._cleaned_ast_to_code(keyword.value)}"
|
126
128
|
for keyword in keywords
|
127
129
|
if keyword.arg is not None
|
128
130
|
]
|
@@ -182,7 +184,9 @@ def _remove_redundant_parentheses(expr: str) -> str:
|
|
182
184
|
|
183
185
|
|
184
186
|
def transform_expression(
|
185
|
-
expr: str,
|
187
|
+
expr: str,
|
188
|
+
level: int = 0,
|
189
|
+
decimal_precision: Optional[int] = DEFAULT_DECIMAL_PRECISION,
|
186
190
|
) -> str:
|
187
191
|
return ASTToQMODCode(level=level, decimal_precision=decimal_precision).visit(
|
188
192
|
ast.parse(expr)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Dict, List
|
1
|
+
from typing import Dict, List, Optional
|
2
2
|
|
3
3
|
from classiq.interface.generator.constant import Constant
|
4
4
|
from classiq.interface.generator.expressions.expression import Expression
|
@@ -41,7 +41,6 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
41
41
|
QuantumFunctionDeclaration,
|
42
42
|
QuantumOperandDeclaration,
|
43
43
|
)
|
44
|
-
from classiq.interface.model.quantum_if_operation import QuantumIf
|
45
44
|
from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
|
46
45
|
from classiq.interface.model.quantum_type import (
|
47
46
|
QuantumBit,
|
@@ -64,7 +63,9 @@ from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
|
|
64
63
|
|
65
64
|
|
66
65
|
class DSLPrettyPrinter(Visitor):
|
67
|
-
def __init__(
|
66
|
+
def __init__(
|
67
|
+
self, decimal_precision: Optional[int] = DEFAULT_DECIMAL_PRECISION
|
68
|
+
) -> None:
|
68
69
|
self._level = 0
|
69
70
|
self._decimal_precision = decimal_precision
|
70
71
|
|
@@ -137,8 +138,6 @@ class DSLPrettyPrinter(Visitor):
|
|
137
138
|
|
138
139
|
def visit_QuantumBitvector(self, qtype: QuantumBitvector) -> str:
|
139
140
|
if qtype.length is not None:
|
140
|
-
if qtype.length.is_evaluated() and qtype.length.to_int_value() == 1:
|
141
|
-
return "qbit"
|
142
141
|
return f"qbit[{self.visit(qtype.length)}]"
|
143
142
|
return "qbit[]"
|
144
143
|
|
@@ -213,17 +212,11 @@ class DSLPrettyPrinter(Visitor):
|
|
213
212
|
)
|
214
213
|
return f"{self._indent}{func_call.func_name}{f'[{self.visit(func_call.function.index)}]' if isinstance(func_call.function, OperandIdentifier) else ''}{gen_time_arg_list}({quantum_args});\n"
|
215
214
|
|
216
|
-
def visit_Control(self,
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
return
|
221
|
-
|
222
|
-
def visit_QuantumIf(self, op: QuantumIf) -> str:
|
223
|
-
quantum_if = f"{self._indent}quantum_if ({self.visit(op.expression)}) {{\n"
|
224
|
-
quantum_if += self._visit_body(op.then)
|
225
|
-
quantum_if += f"{self._indent}}}\n"
|
226
|
-
return quantum_if
|
215
|
+
def visit_Control(self, op: Control) -> str:
|
216
|
+
control = f"{self._indent}control ({self.visit(op.expression)}) {{\n"
|
217
|
+
control += self._visit_body(op.body)
|
218
|
+
control += f"{self._indent}}}\n"
|
219
|
+
return control
|
227
220
|
|
228
221
|
def visit_ClassicalIf(self, op: ClassicalIf) -> str:
|
229
222
|
classical_if = f"{self._indent}if ({self.visit(op.condition)}) {{\n"
|
@@ -309,10 +302,10 @@ class DSLPrettyPrinter(Visitor):
|
|
309
302
|
return var_ref.name
|
310
303
|
|
311
304
|
def visit_SlicedHandleBinding(self, var_ref: SlicedHandleBinding) -> str:
|
312
|
-
return
|
305
|
+
return f"{var_ref.name}[{self.visit(var_ref.start)}:{self.visit(var_ref.end)}]"
|
313
306
|
|
314
307
|
def visit_SubscriptHandleBinding(self, var_ref: SubscriptHandleBinding) -> str:
|
315
|
-
return
|
308
|
+
return f"{var_ref.name}[{self.visit(var_ref.index)}]"
|
316
309
|
|
317
310
|
def visit_ArithmeticOperation(self, arith_op: ArithmeticOperation) -> str:
|
318
311
|
op = "^=" if arith_op.inplace_result else "="
|