classiq 0.86.0__py3-none-any.whl → 0.87.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 +2 -0
- classiq/applications/chemistry/hartree_fock.py +5 -1
- classiq/applications/chemistry/op_utils.py +2 -2
- classiq/applications/combinatorial_helpers/encoding_mapping.py +11 -15
- classiq/applications/combinatorial_helpers/encoding_utils.py +6 -6
- classiq/applications/combinatorial_helpers/memory.py +4 -4
- classiq/applications/combinatorial_helpers/optimization_model.py +5 -5
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +6 -10
- classiq/applications/combinatorial_helpers/pyomo_utils.py +27 -26
- classiq/applications/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/applications/combinatorial_helpers/transformations/encoding.py +4 -6
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +4 -4
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +2 -2
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +3 -3
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +4 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +33 -1
- classiq/evaluators/argument_types.py +15 -6
- classiq/evaluators/parameter_types.py +43 -39
- classiq/evaluators/qmod_annotated_expression.py +88 -11
- classiq/evaluators/qmod_expression_visitors/out_of_place_node_transformer.py +19 -0
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +54 -11
- classiq/evaluators/qmod_expression_visitors/qmod_expression_renamer.py +40 -25
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +29 -59
- classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +12 -5
- classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +175 -28
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +21 -14
- classiq/evaluators/qmod_node_evaluators/compare_evaluation.py +9 -5
- classiq/evaluators/qmod_node_evaluators/constant_evaluation.py +20 -1
- classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +97 -0
- classiq/evaluators/qmod_node_evaluators/name_evaluation.py +11 -26
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +56 -0
- classiq/evaluators/qmod_node_evaluators/piecewise_evaluation.py +40 -0
- classiq/evaluators/qmod_node_evaluators/struct_instantiation_evaluation.py +2 -3
- classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +48 -21
- classiq/evaluators/qmod_node_evaluators/unary_op_evaluation.py +53 -9
- classiq/evaluators/qmod_node_evaluators/utils.py +27 -5
- classiq/evaluators/qmod_type_inference/classical_type_inference.py +188 -0
- classiq/evaluators/qmod_type_inference/quantum_type_inference.py +292 -0
- classiq/evaluators/quantum_type_utils.py +0 -131
- classiq/execution/execution_session.py +1 -1
- classiq/execution/qnn.py +4 -1
- classiq/execution/user_budgets.py +1 -1
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +10 -30
- classiq/interface/backend/quantum_backend_providers.py +63 -52
- classiq/interface/generator/arith/binary_ops.py +107 -115
- classiq/interface/generator/arith/extremum_operations.py +33 -45
- classiq/interface/generator/arith/number_utils.py +4 -1
- classiq/interface/generator/circuit_code/types_and_constants.py +0 -9
- classiq/interface/generator/compiler_keywords.py +2 -0
- classiq/interface/generator/function_param_list.py +133 -5
- classiq/interface/generator/functions/classical_type.py +59 -2
- classiq/interface/generator/functions/qmod_python_interface.py +15 -0
- classiq/interface/generator/functions/type_name.py +6 -0
- classiq/interface/generator/model/preferences/preferences.py +1 -17
- classiq/interface/generator/quantum_program.py +1 -13
- classiq/interface/helpers/model_normalizer.py +2 -2
- classiq/interface/helpers/text_utils.py +7 -2
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/classical_if.py +40 -0
- classiq/interface/model/handle_binding.py +28 -16
- classiq/interface/model/quantum_type.py +61 -2
- classiq/interface/pretty_print/expression_to_qmod.py +24 -11
- classiq/interface/pyomo_extension/__init__.py +0 -4
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +2 -2
- classiq/model_expansions/arithmetic.py +43 -1
- classiq/model_expansions/arithmetic_compute_result_attrs.py +255 -0
- classiq/model_expansions/capturing/captured_vars.py +2 -5
- classiq/model_expansions/quantum_operations/allocate.py +22 -15
- classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -3
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +52 -71
- classiq/model_expansions/quantum_operations/bind.py +15 -7
- classiq/model_expansions/quantum_operations/call_emitter.py +2 -10
- classiq/model_expansions/quantum_operations/classical_var_emitter.py +6 -0
- classiq/open_library/functions/__init__.py +3 -0
- classiq/open_library/functions/lcu.py +117 -0
- classiq/qmod/builtins/enums.py +2 -2
- classiq/qmod/builtins/structs.py +33 -18
- classiq/qmod/pretty_print/expression_to_python.py +7 -9
- {classiq-0.86.0.dist-info → classiq-0.87.0.dist-info}/METADATA +3 -3
- {classiq-0.86.0.dist-info → classiq-0.87.0.dist-info}/RECORD +83 -89
- classiq/interface/generator/amplitude_estimation.py +0 -34
- classiq/interface/generator/function_param_list_without_self_reference.py +0 -160
- classiq/interface/generator/grover_diffuser.py +0 -93
- classiq/interface/generator/grover_operator.py +0 -106
- classiq/interface/generator/oracles/__init__.py +0 -3
- classiq/interface/generator/oracles/arithmetic_oracle.py +0 -82
- classiq/interface/generator/oracles/custom_oracle.py +0 -65
- classiq/interface/generator/oracles/oracle_abc.py +0 -76
- classiq/interface/generator/oracles/oracle_function_param_list.py +0 -6
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +0 -165
- classiq/interface/generator/qpe.py +0 -169
- classiq/interface/grover/grover_modelling_params.py +0 -13
- classiq/model_expansions/transformers/var_splitter.py +0 -224
- /classiq/{interface/grover → evaluators/qmod_type_inference}/__init__.py +0 -0
- {classiq-0.86.0.dist-info → classiq-0.87.0.dist-info}/WHEEL +0 -0
@@ -3,7 +3,6 @@ from typing_extensions import TypeAlias
|
|
3
3
|
from classiq.interface.enum_utils import StrEnum
|
4
4
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
5
5
|
from classiq.interface.generator.model.preferences.preferences import QuantumFormat
|
6
|
-
from classiq.interface.hardware import Provider
|
7
6
|
|
8
7
|
Code: TypeAlias = str
|
9
8
|
CodeAndSyntax: TypeAlias = tuple[Code, QuantumInstructionSet]
|
@@ -14,14 +13,6 @@ INSTRUCTION_SET_TO_FORMAT: dict[QuantumInstructionSet, QuantumFormat] = {
|
|
14
13
|
QuantumInstructionSet.IONQ: QuantumFormat.IONQ,
|
15
14
|
QuantumInstructionSet.INTERNAL: QuantumFormat.EXECUTION_SERIALIZATION,
|
16
15
|
}
|
17
|
-
VENDOR_TO_INSTRUCTION_SET: dict[Provider, QuantumInstructionSet] = {
|
18
|
-
Provider.CLASSIQ: QuantumInstructionSet.QASM,
|
19
|
-
Provider.IONQ: QuantumInstructionSet.IONQ,
|
20
|
-
Provider.AZURE_QUANTUM: QuantumInstructionSet.QSHARP,
|
21
|
-
Provider.IBM_QUANTUM: QuantumInstructionSet.QASM,
|
22
|
-
Provider.AMAZON_BRAKET: QuantumInstructionSet.QASM,
|
23
|
-
}
|
24
|
-
DEFAULT_INSTRUCTION_SET = QuantumInstructionSet.QASM
|
25
16
|
_MAXIMUM_STRING_LENGTH = 250
|
26
17
|
|
27
18
|
|
@@ -1,14 +1,142 @@
|
|
1
1
|
import itertools
|
2
2
|
|
3
|
+
from classiq.interface.generator.amplitude_loading import AmplitudeLoading
|
4
|
+
from classiq.interface.generator.arith.arithmetic import Arithmetic
|
5
|
+
from classiq.interface.generator.arith.binary_ops import (
|
6
|
+
Adder,
|
7
|
+
BitwiseAnd,
|
8
|
+
BitwiseOr,
|
9
|
+
BitwiseXor,
|
10
|
+
CyclicShift,
|
11
|
+
Equal,
|
12
|
+
GreaterEqual,
|
13
|
+
GreaterThan,
|
14
|
+
LessEqual,
|
15
|
+
LessThan,
|
16
|
+
LShift,
|
17
|
+
Modulo,
|
18
|
+
Multiplier,
|
19
|
+
NotEqual,
|
20
|
+
Power,
|
21
|
+
RShift,
|
22
|
+
Subtractor,
|
23
|
+
)
|
24
|
+
from classiq.interface.generator.arith.extremum_operations import Max, Min
|
25
|
+
from classiq.interface.generator.arith.logical_ops import LogicalAnd, LogicalOr
|
26
|
+
from classiq.interface.generator.arith.unary_ops import BitwiseInvert, Negation, Sign
|
27
|
+
from classiq.interface.generator.commuting_pauli_exponentiation import (
|
28
|
+
CommutingPauliExponentiation,
|
29
|
+
)
|
30
|
+
from classiq.interface.generator.copy import Copy
|
31
|
+
from classiq.interface.generator.entangler_params import (
|
32
|
+
GridEntangler,
|
33
|
+
HypercubeEntangler,
|
34
|
+
TwoDimensionalEntangler,
|
35
|
+
)
|
36
|
+
from classiq.interface.generator.finance import Finance, FinanceModels, FinancePayoff
|
3
37
|
from classiq.interface.generator.function_param_library import FunctionParamLibrary
|
4
|
-
from classiq.interface.generator.
|
5
|
-
|
38
|
+
from classiq.interface.generator.hadamard_transform import HadamardTransform
|
39
|
+
from classiq.interface.generator.hamiltonian_evolution.exponentiation import (
|
40
|
+
Exponentiation,
|
41
|
+
)
|
42
|
+
from classiq.interface.generator.hamiltonian_evolution.qdrift import QDrift
|
43
|
+
from classiq.interface.generator.hamiltonian_evolution.suzuki_trotter import (
|
44
|
+
SuzukiTrotter,
|
45
|
+
)
|
46
|
+
from classiq.interface.generator.hardware_efficient_ansatz import (
|
47
|
+
HardwareEfficientAnsatz,
|
48
|
+
)
|
49
|
+
from classiq.interface.generator.hartree_fock import HartreeFock
|
50
|
+
from classiq.interface.generator.hva import HVA
|
51
|
+
from classiq.interface.generator.identity import Identity
|
52
|
+
from classiq.interface.generator.linear_pauli_rotations import LinearPauliRotations
|
53
|
+
from classiq.interface.generator.mcu import Mcu
|
54
|
+
from classiq.interface.generator.mcx import Mcx
|
55
|
+
from classiq.interface.generator.qft import QFT
|
56
|
+
from classiq.interface.generator.qsvm import QSVMFeatureMap
|
57
|
+
from classiq.interface.generator.randomized_benchmarking import RandomizedBenchmarking
|
58
|
+
from classiq.interface.generator.reset import Reset
|
59
|
+
from classiq.interface.generator.standard_gates.standard_gates_param_list import (
|
60
|
+
standard_gate_function_param_library,
|
61
|
+
)
|
62
|
+
from classiq.interface.generator.standard_gates.u_gate import UGate
|
63
|
+
from classiq.interface.generator.state_preparation import (
|
64
|
+
BellStatePreparation,
|
65
|
+
ComputationalBasisStatePreparation,
|
66
|
+
ExponentialStatePreparation,
|
67
|
+
GHZStatePreparation,
|
68
|
+
StatePreparation,
|
69
|
+
UniformDistributionStatePreparation,
|
70
|
+
WStatePreparation,
|
6
71
|
)
|
7
|
-
from classiq.interface.generator.
|
72
|
+
from classiq.interface.generator.ucc import UCC
|
73
|
+
from classiq.interface.generator.unitary_gate import UnitaryGate
|
74
|
+
from classiq.interface.generator.user_defined_function_params import CustomFunction
|
8
75
|
|
9
76
|
function_param_library: FunctionParamLibrary = FunctionParamLibrary(
|
10
77
|
param_list=itertools.chain(
|
11
|
-
|
12
|
-
|
78
|
+
{
|
79
|
+
StatePreparation,
|
80
|
+
ComputationalBasisStatePreparation,
|
81
|
+
UniformDistributionStatePreparation,
|
82
|
+
BellStatePreparation,
|
83
|
+
GHZStatePreparation,
|
84
|
+
WStatePreparation,
|
85
|
+
ExponentialStatePreparation,
|
86
|
+
QFT,
|
87
|
+
BitwiseAnd,
|
88
|
+
BitwiseOr,
|
89
|
+
BitwiseXor,
|
90
|
+
BitwiseInvert,
|
91
|
+
Adder,
|
92
|
+
Arithmetic,
|
93
|
+
Sign,
|
94
|
+
Equal,
|
95
|
+
NotEqual,
|
96
|
+
GreaterThan,
|
97
|
+
GreaterEqual,
|
98
|
+
LessThan,
|
99
|
+
LessEqual,
|
100
|
+
Negation,
|
101
|
+
LogicalAnd,
|
102
|
+
LogicalOr,
|
103
|
+
Subtractor,
|
104
|
+
RShift,
|
105
|
+
LShift,
|
106
|
+
CyclicShift,
|
107
|
+
Modulo,
|
108
|
+
TwoDimensionalEntangler,
|
109
|
+
Finance,
|
110
|
+
FinanceModels,
|
111
|
+
FinancePayoff,
|
112
|
+
HypercubeEntangler,
|
113
|
+
GridEntangler,
|
114
|
+
Mcx,
|
115
|
+
Mcu,
|
116
|
+
CustomFunction,
|
117
|
+
HardwareEfficientAnsatz,
|
118
|
+
UnitaryGate,
|
119
|
+
LinearPauliRotations,
|
120
|
+
Multiplier,
|
121
|
+
Power,
|
122
|
+
HartreeFock,
|
123
|
+
UCC,
|
124
|
+
Min,
|
125
|
+
Max,
|
126
|
+
Exponentiation,
|
127
|
+
CommutingPauliExponentiation,
|
128
|
+
SuzukiTrotter,
|
129
|
+
QDrift,
|
130
|
+
Identity,
|
131
|
+
RandomizedBenchmarking,
|
132
|
+
HVA,
|
133
|
+
UGate,
|
134
|
+
AmplitudeLoading,
|
135
|
+
QSVMFeatureMap,
|
136
|
+
HadamardTransform,
|
137
|
+
Copy,
|
138
|
+
Reset,
|
139
|
+
},
|
140
|
+
standard_gate_function_param_library.param_list,
|
13
141
|
)
|
14
142
|
)
|
@@ -58,6 +58,14 @@ class ClassicalType(HashableASTNode):
|
|
58
58
|
def get_classical_proxy(self, handle: HandleBinding) -> ClassicalProxy:
|
59
59
|
return ClassicalScalarProxy(handle, self)
|
60
60
|
|
61
|
+
@property
|
62
|
+
def qmod_type_name(self) -> str:
|
63
|
+
raise NotImplementedError
|
64
|
+
|
65
|
+
@property
|
66
|
+
def raw_qmod_type_name(self) -> str:
|
67
|
+
return self.qmod_type_name
|
68
|
+
|
61
69
|
@property
|
62
70
|
def expressions(self) -> list[Expression]:
|
63
71
|
return []
|
@@ -79,6 +87,10 @@ class Integer(ClassicalType):
|
|
79
87
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
80
88
|
return values_with_discriminator(values, "kind", "int")
|
81
89
|
|
90
|
+
@property
|
91
|
+
def qmod_type_name(self) -> str:
|
92
|
+
return "CInt"
|
93
|
+
|
82
94
|
|
83
95
|
class Real(ClassicalType):
|
84
96
|
kind: Literal["real"]
|
@@ -88,6 +100,10 @@ class Real(ClassicalType):
|
|
88
100
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
89
101
|
return values_with_discriminator(values, "kind", "real")
|
90
102
|
|
103
|
+
@property
|
104
|
+
def qmod_type_name(self) -> str:
|
105
|
+
return "CReal"
|
106
|
+
|
91
107
|
|
92
108
|
class Bool(ClassicalType):
|
93
109
|
kind: Literal["bool"]
|
@@ -97,6 +113,10 @@ class Bool(ClassicalType):
|
|
97
113
|
def _set_kind(cls, values: Any) -> dict[str, Any]:
|
98
114
|
return values_with_discriminator(values, "kind", "bool")
|
99
115
|
|
116
|
+
@property
|
117
|
+
def qmod_type_name(self) -> str:
|
118
|
+
return "CBool"
|
119
|
+
|
100
120
|
|
101
121
|
class StructMetaType(ClassicalType):
|
102
122
|
kind: Literal["type_proxy"]
|
@@ -163,6 +183,18 @@ class ClassicalArray(ClassicalType):
|
|
163
183
|
raw_type.set_generative()
|
164
184
|
return raw_type
|
165
185
|
|
186
|
+
@property
|
187
|
+
def qmod_type_name(self) -> str:
|
188
|
+
if self.length is None:
|
189
|
+
length = ""
|
190
|
+
else:
|
191
|
+
length = f", {self.length.expr}"
|
192
|
+
return f"CArray[{self.element_type.qmod_type_name}{length}]"
|
193
|
+
|
194
|
+
@property
|
195
|
+
def raw_qmod_type_name(self) -> str:
|
196
|
+
return "CArray"
|
197
|
+
|
166
198
|
|
167
199
|
class ClassicalTuple(ClassicalType):
|
168
200
|
kind: Literal["tuple"]
|
@@ -196,10 +228,24 @@ class ClassicalTuple(ClassicalType):
|
|
196
228
|
element_type.is_purely_generative for element_type in self.element_types
|
197
229
|
)
|
198
230
|
|
199
|
-
def get_raw_type(self) -> "ConcreteClassicalType":
|
231
|
+
def get_raw_type(self, *, preserve_length: bool = False) -> "ConcreteClassicalType":
|
200
232
|
if len(self.element_types) == 0:
|
201
233
|
return self
|
202
|
-
|
234
|
+
chosen_element = self.element_types[0]
|
235
|
+
for element in self.element_types:
|
236
|
+
if (
|
237
|
+
not isinstance(element, ClassicalTuple)
|
238
|
+
or len(element.element_types) > 0
|
239
|
+
):
|
240
|
+
chosen_element = element
|
241
|
+
break
|
242
|
+
if preserve_length:
|
243
|
+
length = Expression(expr=str(len(self.element_types)))
|
244
|
+
else:
|
245
|
+
length = None
|
246
|
+
raw_type = ClassicalArray(
|
247
|
+
element_type=chosen_element.get_raw_type(), length=length
|
248
|
+
)
|
203
249
|
if self._is_generative:
|
204
250
|
raw_type.set_generative()
|
205
251
|
return raw_type
|
@@ -208,6 +254,17 @@ class ClassicalTuple(ClassicalType):
|
|
208
254
|
def length(self) -> int:
|
209
255
|
return len(self.element_types)
|
210
256
|
|
257
|
+
@property
|
258
|
+
def qmod_type_name(self) -> str:
|
259
|
+
raw_type = self.get_raw_type(preserve_length=True)
|
260
|
+
if isinstance(raw_type, ClassicalTuple):
|
261
|
+
return "CArray[0]"
|
262
|
+
return raw_type.qmod_type_name
|
263
|
+
|
264
|
+
@property
|
265
|
+
def raw_qmod_type_name(self) -> str:
|
266
|
+
return "CArray"
|
267
|
+
|
211
268
|
|
212
269
|
class OpaqueHandle(ClassicalType):
|
213
270
|
pass
|
@@ -1,4 +1,19 @@
|
|
1
1
|
from collections.abc import Mapping
|
2
2
|
from typing import Any
|
3
3
|
|
4
|
+
from classiq.interface.generator.expressions.proxies.classical.qmod_struct_instance import (
|
5
|
+
QmodStructInstance,
|
6
|
+
)
|
7
|
+
|
4
8
|
QmodPyStruct = Mapping[str, Any]
|
9
|
+
|
10
|
+
|
11
|
+
def qmod_value_to_dict(qmod_value: Any) -> Any:
|
12
|
+
if isinstance(qmod_value, QmodStructInstance):
|
13
|
+
return {
|
14
|
+
field_name: qmod_value_to_dict(field_value)
|
15
|
+
for field_name, field_value in qmod_value.fields.items()
|
16
|
+
}
|
17
|
+
if isinstance(qmod_value, list):
|
18
|
+
return [qmod_value_to_dict(item) for item in qmod_value]
|
19
|
+
return qmod_value
|
@@ -177,6 +177,12 @@ class TypeName(ClassicalType, QuantumType):
|
|
177
177
|
raw_type.set_classical_struct_decl(raw_decl)
|
178
178
|
return raw_type
|
179
179
|
|
180
|
+
@property
|
181
|
+
def minimal_size_in_bits(self) -> int:
|
182
|
+
return sum(
|
183
|
+
field_type.minimal_size_in_bits for field_type in self.fields.values()
|
184
|
+
)
|
185
|
+
|
180
186
|
|
181
187
|
class Enum(TypeName):
|
182
188
|
pass
|
@@ -50,14 +50,6 @@ class QuantumFormat(StrEnum):
|
|
50
50
|
EXECUTION_SERIALIZATION = "_execution_serialization"
|
51
51
|
|
52
52
|
|
53
|
-
_SERVICE_PROVIDER_TO_FORMAT: dict[Provider, QuantumFormat] = {
|
54
|
-
Provider.CLASSIQ: QuantumFormat.QASM,
|
55
|
-
Provider.IONQ: QuantumFormat.IONQ,
|
56
|
-
Provider.AZURE_QUANTUM: QuantumFormat.QSHARP,
|
57
|
-
Provider.IBM_QUANTUM: QuantumFormat.QASM,
|
58
|
-
Provider.AMAZON_BRAKET: QuantumFormat.QASM,
|
59
|
-
}
|
60
|
-
|
61
53
|
if TYPE_CHECKING:
|
62
54
|
PydanticConstrainedQuantumFormatList = list[QuantumFormat]
|
63
55
|
else:
|
@@ -176,7 +168,7 @@ class Preferences(pydantic.BaseModel, extra="forbid"):
|
|
176
168
|
deprecated=True,
|
177
169
|
)
|
178
170
|
optimization_level: OptimizationLevel = pydantic.Field(
|
179
|
-
default=OptimizationLevel.
|
171
|
+
default=OptimizationLevel.LIGHT,
|
180
172
|
description="The optimization level used during synthesis; determines the trade-off between synthesis speed and the quality of the results",
|
181
173
|
)
|
182
174
|
output_format: PydanticConstrainedQuantumFormatList = pydantic.Field(
|
@@ -260,14 +252,6 @@ class Preferences(pydantic.BaseModel, extra="forbid"):
|
|
260
252
|
"has at least one format that appears twice or more"
|
261
253
|
)
|
262
254
|
|
263
|
-
service_provider = info.data.get("backend_service_provider")
|
264
|
-
if service_provider is None:
|
265
|
-
return output_format
|
266
|
-
|
267
|
-
provider_format = _SERVICE_PROVIDER_TO_FORMAT.get(service_provider)
|
268
|
-
if provider_format is not None and provider_format not in output_format:
|
269
|
-
output_format.append(provider_format)
|
270
|
-
|
271
255
|
return output_format
|
272
256
|
|
273
257
|
@pydantic.field_validator("backend_name")
|
@@ -19,9 +19,7 @@ from classiq.interface.executor.quantum_instruction_set import QuantumInstructio
|
|
19
19
|
from classiq.interface.executor.register_initialization import RegisterInitialization
|
20
20
|
from classiq.interface.generator.circuit_code.circuit_code import CircuitCodeInterface
|
21
21
|
from classiq.interface.generator.circuit_code.types_and_constants import (
|
22
|
-
DEFAULT_INSTRUCTION_SET,
|
23
22
|
INSTRUCTION_SET_TO_FORMAT,
|
24
|
-
VENDOR_TO_INSTRUCTION_SET,
|
25
23
|
CodeAndSyntax,
|
26
24
|
)
|
27
25
|
from classiq.interface.generator.generated_circuit_data import (
|
@@ -82,7 +80,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
82
80
|
def __str__(self) -> str:
|
83
81
|
return self.model_dump_json(indent=2)
|
84
82
|
|
85
|
-
def
|
83
|
+
def _default_program_code(self) -> CodeAndSyntax:
|
86
84
|
circuit_code = self.program_circuit.get_code_by_priority()
|
87
85
|
if circuit_code is not None:
|
88
86
|
return circuit_code
|
@@ -91,16 +89,6 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
91
89
|
missing_formats=list(INSTRUCTION_SET_TO_FORMAT.values())
|
92
90
|
)
|
93
91
|
|
94
|
-
def _default_program_code(self) -> CodeAndSyntax:
|
95
|
-
if self.hardware_data.backend_data is None:
|
96
|
-
return self._hardware_agnostic_program_code()
|
97
|
-
|
98
|
-
backend_provider = self.hardware_data.backend_data.hw_provider
|
99
|
-
instruction_set: QuantumInstructionSet = VENDOR_TO_INSTRUCTION_SET.get(
|
100
|
-
backend_provider, DEFAULT_INSTRUCTION_SET
|
101
|
-
)
|
102
|
-
return self.program_circuit.get_code(instruction_set), instruction_set
|
103
|
-
|
104
92
|
def to_base_program(self) -> quantum_code.QuantumBaseCode:
|
105
93
|
code, syntax = self._default_program_code()
|
106
94
|
return quantum_code.QuantumBaseCode(code=code, syntax=syntax)
|
@@ -37,8 +37,8 @@ class ModelNormalizer(Visitor):
|
|
37
37
|
|
38
38
|
class ClearModelInternals(Transformer):
|
39
39
|
def visit_Expression(self, expr: Expression) -> Expression:
|
40
|
-
|
41
|
-
|
40
|
+
expr._evaluated_expr = None
|
41
|
+
expr._try_to_immediate_evaluate()
|
42
42
|
return expr
|
43
43
|
|
44
44
|
def visit_ClassicalType(self, classical_type: ClassicalType) -> ClassicalType:
|
@@ -1,5 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
from typing import Union
|
2
|
+
|
3
|
+
|
4
|
+
def s(items: Union[list, int]) -> str:
|
5
|
+
if isinstance(items, list):
|
6
|
+
items = len(items)
|
7
|
+
return "" if items == 1 else "s"
|
3
8
|
|
4
9
|
|
5
10
|
def are(items: list) -> str:
|
@@ -1 +1 @@
|
|
1
|
-
INTERFACE_VERSION = "
|
1
|
+
INTERFACE_VERSION = "12"
|
@@ -1,7 +1,11 @@
|
|
1
|
+
import functools
|
2
|
+
import operator
|
3
|
+
from collections.abc import Mapping
|
1
4
|
from typing import TYPE_CHECKING, Literal
|
2
5
|
|
3
6
|
from classiq.interface.ast_node import ASTNodeType, reset_lists
|
4
7
|
from classiq.interface.generator.expressions.expression import Expression
|
8
|
+
from classiq.interface.model.handle_binding import ConcreteHandleBinding, HandleBinding
|
5
9
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
6
10
|
|
7
11
|
if TYPE_CHECKING:
|
@@ -21,3 +25,39 @@ class ClassicalIf(QuantumOperation):
|
|
21
25
|
@property
|
22
26
|
def expressions(self) -> list[Expression]:
|
23
27
|
return [self.condition]
|
28
|
+
|
29
|
+
@property
|
30
|
+
def wiring_inputs(self) -> Mapping[str, HandleBinding]:
|
31
|
+
return functools.reduce(
|
32
|
+
operator.ior,
|
33
|
+
(
|
34
|
+
op.wiring_inputs
|
35
|
+
for op in (*self.then, *self.else_)
|
36
|
+
if isinstance(op, QuantumOperation)
|
37
|
+
),
|
38
|
+
dict(),
|
39
|
+
)
|
40
|
+
|
41
|
+
@property
|
42
|
+
def wiring_inouts(self) -> Mapping[str, ConcreteHandleBinding]:
|
43
|
+
return functools.reduce(
|
44
|
+
operator.ior,
|
45
|
+
(
|
46
|
+
op.wiring_inouts
|
47
|
+
for op in (*self.then, *self.else_)
|
48
|
+
if isinstance(op, QuantumOperation)
|
49
|
+
),
|
50
|
+
dict(),
|
51
|
+
)
|
52
|
+
|
53
|
+
@property
|
54
|
+
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
55
|
+
return functools.reduce(
|
56
|
+
operator.ior,
|
57
|
+
(
|
58
|
+
op.wiring_outputs
|
59
|
+
for op in (*self.then, *self.else_)
|
60
|
+
if isinstance(op, QuantumOperation)
|
61
|
+
),
|
62
|
+
dict(),
|
63
|
+
)
|
@@ -156,7 +156,12 @@ class SubscriptHandleBinding(NestedHandleBinding):
|
|
156
156
|
def _get_collapsed_index(self) -> Expression:
|
157
157
|
if TYPE_CHECKING:
|
158
158
|
assert isinstance(self.base_handle, SlicedHandleBinding)
|
159
|
-
if
|
159
|
+
if (
|
160
|
+
self.index.is_evaluated()
|
161
|
+
and self.index.is_constant()
|
162
|
+
and self.base_handle.start.is_evaluated()
|
163
|
+
and self.base_handle.start.is_constant()
|
164
|
+
):
|
160
165
|
return Expression(
|
161
166
|
expr=str(
|
162
167
|
self.base_handle.start.to_int_value() + self.index.to_int_value()
|
@@ -170,7 +175,8 @@ class SubscriptHandleBinding(NestedHandleBinding):
|
|
170
175
|
if (
|
171
176
|
isinstance(other_handle, SlicedHandleBinding)
|
172
177
|
and self.index.is_evaluated()
|
173
|
-
and
|
178
|
+
and self.index.is_constant()
|
179
|
+
and other_handle.is_constant()
|
174
180
|
):
|
175
181
|
return (
|
176
182
|
other_handle.start.to_int_value()
|
@@ -186,7 +192,8 @@ class SubscriptHandleBinding(NestedHandleBinding):
|
|
186
192
|
isinstance(prefix, SlicedHandleBinding)
|
187
193
|
and self.base_handle == prefix.base_handle
|
188
194
|
and self.index.is_evaluated()
|
189
|
-
and
|
195
|
+
and self.index.is_constant()
|
196
|
+
and prefix.is_constant()
|
190
197
|
and prefix.start.to_int_value()
|
191
198
|
<= self.index.to_int_value()
|
192
199
|
< prefix.end.to_int_value()
|
@@ -243,19 +250,17 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
243
250
|
)
|
244
251
|
|
245
252
|
def _tail_overlaps(self, other_handle: "HandleBinding") -> bool:
|
246
|
-
if not self.
|
253
|
+
if not self.is_constant():
|
247
254
|
return False
|
248
255
|
start = self.start.to_int_value()
|
249
256
|
end = self.end.to_int_value()
|
250
257
|
if (
|
251
258
|
isinstance(other_handle, SubscriptHandleBinding)
|
252
259
|
and other_handle.index.is_evaluated()
|
260
|
+
and other_handle.index.is_constant()
|
253
261
|
):
|
254
262
|
return start <= other_handle.index.to_int_value() < end
|
255
|
-
if (
|
256
|
-
isinstance(other_handle, SlicedHandleBinding)
|
257
|
-
and other_handle._is_evaluated()
|
258
|
-
):
|
263
|
+
if isinstance(other_handle, SlicedHandleBinding) and other_handle.is_constant():
|
259
264
|
other_start = other_handle.start.to_int_value()
|
260
265
|
other_end = other_handle.end.to_int_value()
|
261
266
|
return start <= other_start < end or other_start <= start < other_end
|
@@ -264,7 +269,12 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
264
269
|
def _get_collapsed_start(self) -> Expression:
|
265
270
|
if TYPE_CHECKING:
|
266
271
|
assert isinstance(self.base_handle, SlicedHandleBinding)
|
267
|
-
if
|
272
|
+
if (
|
273
|
+
self.start.is_evaluated()
|
274
|
+
and self.start.is_constant()
|
275
|
+
and self.base_handle.start.is_evaluated()
|
276
|
+
and self.base_handle.start.is_constant()
|
277
|
+
):
|
268
278
|
return Expression(
|
269
279
|
expr=str(
|
270
280
|
self.base_handle.start.to_int_value() + self.start.to_int_value()
|
@@ -275,7 +285,11 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
275
285
|
def _get_collapsed_stop(self) -> Expression:
|
276
286
|
if TYPE_CHECKING:
|
277
287
|
assert isinstance(self.base_handle, SlicedHandleBinding)
|
278
|
-
if
|
288
|
+
if (
|
289
|
+
self.is_constant()
|
290
|
+
and self.base_handle.start.is_evaluated()
|
291
|
+
and self.base_handle.start.is_constant()
|
292
|
+
):
|
279
293
|
return Expression(
|
280
294
|
expr=str(
|
281
295
|
self.end.to_int_value()
|
@@ -295,8 +309,8 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
295
309
|
if (
|
296
310
|
isinstance(prefix, SlicedHandleBinding)
|
297
311
|
and self.base_handle == prefix.base_handle
|
298
|
-
and self.
|
299
|
-
and prefix.
|
312
|
+
and self.is_constant()
|
313
|
+
and prefix.is_constant()
|
300
314
|
):
|
301
315
|
prefix_start = prefix.start.to_int_value()
|
302
316
|
prefix_end = prefix.end.to_int_value()
|
@@ -313,14 +327,12 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
313
327
|
)
|
314
328
|
return super().replace_prefix(prefix, replacement)
|
315
329
|
|
316
|
-
def _is_evaluated(self) -> bool:
|
317
|
-
return self.start.is_evaluated() and self.end.is_evaluated()
|
318
|
-
|
319
330
|
def is_constant(self) -> bool:
|
320
331
|
return (
|
321
332
|
super().is_constant()
|
322
|
-
and self.
|
333
|
+
and self.start.is_evaluated()
|
323
334
|
and self.start.is_constant()
|
335
|
+
and self.end.is_evaluated()
|
324
336
|
and self.end.is_constant()
|
325
337
|
)
|
326
338
|
|