classiq 0.51.0__py3-none-any.whl → 0.52.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/_internals/api_wrapper.py +41 -15
- classiq/_internals/authentication/auth0.py +20 -4
- classiq/_internals/authentication/password_manager.py +16 -4
- classiq/_internals/client.py +2 -2
- classiq/_internals/host_checker.py +5 -3
- classiq/_internals/jobs.py +3 -3
- classiq/analyzer/analyzer_utilities.py +1 -1
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/pyomo_utils.py +3 -1
- classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
- classiq/applications/qnn/qlayer.py +2 -2
- classiq/execution/__init__.py +3 -0
- classiq/execution/execution_session.py +2 -2
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +2 -2
- classiq/executor.py +2 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +19 -9
- classiq/interface/analyzer/cytoscape_graph.py +10 -3
- classiq/interface/analyzer/result.py +6 -5
- classiq/interface/applications/qsvm.py +13 -12
- classiq/interface/backend/backend_preferences.py +78 -105
- classiq/interface/backend/ionq/ionq_quantum_program.py +12 -19
- classiq/interface/backend/pydantic_backend.py +24 -12
- classiq/interface/backend/quantum_backend_providers.py +2 -0
- classiq/interface/chemistry/fermionic_operator.py +7 -7
- classiq/interface/chemistry/ground_state_problem.py +23 -18
- classiq/interface/chemistry/molecule.py +10 -5
- classiq/interface/chemistry/operator.py +71 -44
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +2 -1
- classiq/interface/debug_info/debug_info.py +3 -4
- classiq/interface/execution/iqcc.py +21 -0
- classiq/interface/execution/jobs.py +10 -10
- classiq/interface/executor/aws_execution_cost.py +37 -20
- classiq/interface/executor/execution_preferences.py +1 -2
- classiq/interface/executor/execution_request.py +2 -2
- classiq/interface/executor/execution_result.py +4 -2
- classiq/interface/executor/iqae_result.py +1 -1
- classiq/interface/executor/optimizer_preferences.py +14 -10
- classiq/interface/executor/quantum_code.py +21 -16
- classiq/interface/executor/register_initialization.py +10 -10
- classiq/interface/executor/result.py +19 -16
- classiq/interface/executor/vqe_result.py +1 -1
- classiq/interface/finance/function_input.py +27 -18
- classiq/interface/finance/log_normal_model_input.py +2 -2
- classiq/interface/finance/model_input.py +3 -2
- classiq/interface/generator/amplitude_loading.py +8 -6
- classiq/interface/generator/arith/argument_utils.py +24 -0
- classiq/interface/generator/arith/arithmetic.py +5 -3
- classiq/interface/generator/arith/arithmetic_expression_abc.py +36 -14
- classiq/interface/generator/arith/arithmetic_operations.py +6 -3
- classiq/interface/generator/arith/binary_ops.py +88 -63
- classiq/interface/generator/arith/extremum_operations.py +22 -13
- classiq/interface/generator/arith/logical_ops.py +6 -4
- classiq/interface/generator/arith/number_utils.py +3 -3
- classiq/interface/generator/arith/register_user_input.py +32 -17
- classiq/interface/generator/arith/unary_ops.py +5 -4
- classiq/interface/generator/chemistry_function_params.py +2 -1
- classiq/interface/generator/circuit_code/circuit_code.py +2 -1
- classiq/interface/generator/commuting_pauli_exponentiation.py +6 -5
- classiq/interface/generator/complex_type.py +14 -18
- classiq/interface/generator/control_state.py +32 -26
- classiq/interface/generator/expressions/expression.py +6 -5
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +3 -3
- classiq/interface/generator/function_params.py +22 -39
- classiq/interface/generator/functions/classical_function_declaration.py +1 -1
- classiq/interface/generator/functions/classical_type.py +32 -23
- classiq/interface/generator/functions/concrete_types.py +8 -7
- classiq/interface/generator/functions/function_declaration.py +4 -5
- classiq/interface/generator/functions/type_name.py +5 -4
- classiq/interface/generator/generated_circuit_data.py +9 -6
- classiq/interface/generator/grover_diffuser.py +26 -18
- classiq/interface/generator/grover_operator.py +32 -22
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +3 -4
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +8 -7
- classiq/interface/generator/hardware/hardware_data.py +27 -26
- classiq/interface/generator/hardware_efficient_ansatz.py +11 -6
- classiq/interface/generator/hartree_fock.py +2 -1
- classiq/interface/generator/identity.py +7 -2
- classiq/interface/generator/linear_pauli_rotations.py +27 -14
- classiq/interface/generator/mcu.py +15 -12
- classiq/interface/generator/mcx.py +18 -10
- classiq/interface/generator/model/constraints.py +4 -2
- classiq/interface/generator/model/model.py +2 -1
- classiq/interface/generator/model/preferences/preferences.py +30 -32
- classiq/interface/generator/oracles/custom_oracle.py +13 -10
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +37 -21
- classiq/interface/generator/qpe.py +38 -26
- classiq/interface/generator/qsvm.py +4 -4
- classiq/interface/generator/quantum_function_call.py +57 -44
- classiq/interface/generator/quantum_program.py +8 -6
- classiq/interface/generator/range_types.py +10 -11
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +9 -5
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +12 -12
- classiq/interface/generator/state_preparation/state_preparation.py +22 -16
- classiq/interface/generator/types/enum_declaration.py +2 -1
- classiq/interface/generator/ucc.py +2 -1
- classiq/interface/generator/unitary_gate.py +2 -1
- classiq/interface/generator/user_defined_function_params.py +3 -0
- classiq/interface/generator/visitor.py +1 -1
- classiq/interface/hardware.py +18 -3
- classiq/interface/helpers/custom_pydantic_types.py +38 -47
- classiq/interface/helpers/pydantic_model_helpers.py +3 -2
- classiq/interface/helpers/versioned_model.py +1 -4
- classiq/interface/ide/ide_data.py +5 -5
- classiq/interface/ide/visual_model.py +5 -5
- classiq/interface/interface_version.py +1 -1
- classiq/interface/jobs.py +12 -22
- classiq/interface/model/bind_operation.py +2 -1
- classiq/interface/model/classical_parameter_declaration.py +10 -4
- classiq/interface/model/handle_binding.py +20 -24
- classiq/interface/model/inplace_binary_operation.py +16 -9
- classiq/interface/model/model.py +21 -11
- classiq/interface/model/port_declaration.py +10 -7
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +6 -4
- classiq/interface/model/quantum_function_declaration.py +22 -11
- classiq/interface/model/quantum_statement.py +6 -7
- classiq/interface/model/quantum_type.py +22 -19
- classiq/interface/model/statement_block.py +9 -9
- classiq/interface/server/global_versions.py +4 -5
- classiq/interface/server/routes.py +8 -0
- classiq/model_expansions/evaluators/parameter_types.py +3 -3
- classiq/model_expansions/expression_renamer.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +11 -12
- classiq/model_expansions/quantum_operations/emitter.py +22 -0
- classiq/model_expansions/quantum_operations/expression_operation.py +2 -20
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +65 -14
- classiq/model_expansions/quantum_operations/invert.py +1 -1
- classiq/model_expansions/quantum_operations/phase.py +4 -5
- classiq/model_expansions/quantum_operations/power.py +1 -1
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +50 -9
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
- classiq/model_expansions/quantum_operations/within_apply.py +1 -1
- classiq/qmod/builtins/__init__.py +1 -3
- classiq/qmod/builtins/functions/__init__.py +4 -0
- classiq/qmod/builtins/functions/arithmetic.py +10 -0
- classiq/qmod/create_model_function.py +14 -8
- classiq/qmod/quantum_expandable.py +22 -9
- classiq/qmod/quantum_function.py +1 -1
- classiq/qmod/semantics/static_semantics_visitor.py +3 -1
- classiq/qmod/type_attribute_remover.py +1 -1
- classiq/qmod/write_qmod.py +2 -4
- classiq/synthesis.py +11 -13
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/METADATA +3 -2
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/RECORD +150 -148
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Any, Dict, List, Optional, Tuple
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic import ConfigDict
|
4
5
|
|
5
6
|
from classiq.interface.enum_utils import StrEnum
|
6
7
|
from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
|
@@ -23,7 +24,7 @@ class OperationType(StrEnum):
|
|
23
24
|
|
24
25
|
|
25
26
|
class OperationData(pydantic.BaseModel):
|
26
|
-
approximated_depth: Optional[int]
|
27
|
+
approximated_depth: Optional[int] = None
|
27
28
|
width: int
|
28
29
|
gate_count: Dict[str, int] = pydantic.Field(default_factory=dict)
|
29
30
|
|
@@ -34,7 +35,7 @@ class ProgramData(pydantic.BaseModel):
|
|
34
35
|
|
35
36
|
class OperationParameter(pydantic.BaseModel):
|
36
37
|
label: str
|
37
|
-
value: Optional[str]
|
38
|
+
value: Optional[str] = None
|
38
39
|
|
39
40
|
|
40
41
|
class OperationLink(pydantic.BaseModel):
|
@@ -43,8 +44,7 @@ class OperationLink(pydantic.BaseModel):
|
|
43
44
|
qubits: Tuple[int, ...]
|
44
45
|
type: str
|
45
46
|
|
46
|
-
|
47
|
-
allow_mutation = False
|
47
|
+
model_config = ConfigDict(frozen=True)
|
48
48
|
|
49
49
|
def __hash__(self) -> int:
|
50
50
|
return hash((type(self), self.label, self.qubits, self.type))
|
@@ -94,7 +94,7 @@ class AtomicGate(StrEnum):
|
|
94
94
|
class Operation(pydantic.BaseModel):
|
95
95
|
name: str
|
96
96
|
children: List["Operation"]
|
97
|
-
operation_data: Optional[OperationData]
|
97
|
+
operation_data: Optional[OperationData] = None
|
98
98
|
operation_links: OperationLinks
|
99
99
|
control_qubits: Tuple[int, ...] = pydantic.Field(default_factory=tuple)
|
100
100
|
auxiliary_qubits: Tuple[int, ...]
|
@@ -1 +1 @@
|
|
1
|
-
INTERFACE_VERSION = "
|
1
|
+
INTERFACE_VERSION = "4"
|
classiq/interface/jobs.py
CHANGED
@@ -2,7 +2,7 @@ from typing import Any, Dict, Generic, Optional, TypeVar, Union
|
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
from pydantic import BaseModel
|
5
|
-
from
|
5
|
+
from typing_extensions import Self
|
6
6
|
|
7
7
|
from classiq.interface.enum_utils import StrEnum
|
8
8
|
from classiq.interface.exceptions import ClassiqAPIError
|
@@ -41,33 +41,23 @@ For unsuccessful jobs, we expect failure_details to be a string and result to be
|
|
41
41
|
"""
|
42
42
|
|
43
43
|
|
44
|
-
class JobDescription(
|
44
|
+
class JobDescription(BaseModel, Generic[T], json_encoders=CUSTOM_ENCODERS):
|
45
45
|
status: JobStatus
|
46
|
-
failure_details: Optional[str]
|
47
|
-
result: Optional[T]
|
46
|
+
failure_details: Optional[str] = pydantic.Field(default=None)
|
47
|
+
result: Optional[T] = pydantic.Field(default=None)
|
48
48
|
|
49
|
-
@pydantic.
|
50
|
-
def validate_status_and_fields(
|
51
|
-
status
|
52
|
-
if status is None or "result" not in values or "failure_details" not in values:
|
53
|
-
# If any of the fields doesn't exist, then previous validations failed
|
54
|
-
# result and failure_details are Optional, so we explicitly check if they
|
55
|
-
# exist in the values dictionary
|
56
|
-
return values
|
57
|
-
|
58
|
-
result = values["result"]
|
59
|
-
failure_details = values["failure_details"]
|
60
|
-
|
61
|
-
if status is JobStatus.COMPLETED:
|
49
|
+
@pydantic.model_validator(mode="after")
|
50
|
+
def validate_status_and_fields(self) -> Self:
|
51
|
+
if self.status is JobStatus.COMPLETED:
|
62
52
|
# Completed job must return result and not have an error
|
63
|
-
if result is None or failure_details is not None:
|
53
|
+
if self.result is None or self.failure_details is not None:
|
64
54
|
raise ClassiqAPIError(INVALID_RESPONSE_ERROR_MSG)
|
65
|
-
elif status in (JobStatus.FAILED, JobStatus.CANCELLED):
|
55
|
+
elif self.status in (JobStatus.FAILED, JobStatus.CANCELLED):
|
66
56
|
# Failed job must return error and not have result
|
67
|
-
if result is not None or failure_details is None:
|
57
|
+
if self.result is not None or self.failure_details is None:
|
68
58
|
raise ClassiqAPIError(INVALID_RESPONSE_ERROR_MSG)
|
69
|
-
elif result is not None or failure_details is not None:
|
59
|
+
elif self.result is not None or self.failure_details is not None:
|
70
60
|
# Pending job must have no result and no error
|
71
61
|
raise ClassiqAPIError(INVALID_RESPONSE_ERROR_MSG)
|
72
62
|
|
73
|
-
return
|
63
|
+
return self
|
@@ -49,7 +49,8 @@ class BindOperation(QuantumOperation):
|
|
49
49
|
for handle in self.out_handles
|
50
50
|
]
|
51
51
|
|
52
|
-
@pydantic.
|
52
|
+
@pydantic.field_validator("in_handles", "out_handles")
|
53
|
+
@classmethod
|
53
54
|
def validate_handle(cls, handles: List[HandleBinding]) -> List[HandleBinding]:
|
54
55
|
for handle in handles:
|
55
56
|
if not handle.is_bindable():
|
@@ -10,11 +10,11 @@ from classiq.interface.model.parameter import Parameter
|
|
10
10
|
|
11
11
|
class AnonClassicalParameterDeclaration(Parameter):
|
12
12
|
kind: Literal["ClassicalParameterDeclaration"]
|
13
|
-
|
14
13
|
classical_type: ConcreteClassicalType
|
15
14
|
|
16
|
-
@pydantic.
|
17
|
-
|
15
|
+
@pydantic.model_validator(mode="before")
|
16
|
+
@classmethod
|
17
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
18
18
|
return values_with_discriminator(
|
19
19
|
values, "kind", "ClassicalParameterDeclaration"
|
20
20
|
)
|
@@ -25,7 +25,13 @@ class AnonClassicalParameterDeclaration(Parameter):
|
|
25
25
|
ClassicalParameterDeclaration,
|
26
26
|
):
|
27
27
|
raise ClassiqInternalError
|
28
|
-
return ClassicalParameterDeclaration(
|
28
|
+
return ClassicalParameterDeclaration(
|
29
|
+
**{
|
30
|
+
**self.__dict__,
|
31
|
+
"name": new_name,
|
32
|
+
"kind": "ClassicalParameterDeclaration",
|
33
|
+
}
|
34
|
+
)
|
29
35
|
|
30
36
|
|
31
37
|
class ClassicalParameterDeclaration(AnonClassicalParameterDeclaration):
|
@@ -2,7 +2,7 @@ from itertools import chain
|
|
2
2
|
from typing import TYPE_CHECKING, Any, Dict, Sequence, Union
|
3
3
|
|
4
4
|
import pydantic
|
5
|
-
from pydantic import
|
5
|
+
from pydantic import ConfigDict, Field
|
6
6
|
|
7
7
|
from classiq.interface.ast_node import ASTNode
|
8
8
|
from classiq.interface.generator.expressions.expression import Expression
|
@@ -12,10 +12,7 @@ HANDLE_ID_SEPARATOR = "___"
|
|
12
12
|
|
13
13
|
class HandleBinding(ASTNode):
|
14
14
|
name: str = Field(default=None)
|
15
|
-
|
16
|
-
class Config:
|
17
|
-
frozen = True
|
18
|
-
extra = Extra.forbid
|
15
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
19
16
|
|
20
17
|
def __str__(self) -> str:
|
21
18
|
return self.name
|
@@ -52,10 +49,18 @@ class HandleBinding(ASTNode):
|
|
52
49
|
class NestedHandleBinding(HandleBinding):
|
53
50
|
base_handle: "ConcreteHandleBinding"
|
54
51
|
|
55
|
-
@pydantic.
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
@pydantic.model_validator(mode="before")
|
53
|
+
@classmethod
|
54
|
+
def _set_name(cls, values: Any) -> Dict[str, Any]:
|
55
|
+
if isinstance(values, dict):
|
56
|
+
orig = values
|
57
|
+
while "base_handle" in values:
|
58
|
+
values = values["base_handle"]
|
59
|
+
orig["name"] = dict(values).get("name")
|
60
|
+
return orig
|
61
|
+
if isinstance(values, NestedHandleBinding):
|
62
|
+
values.name = values.base_handle.name
|
63
|
+
return values.model_dump()
|
59
64
|
return values
|
60
65
|
|
61
66
|
def is_bindable(self) -> bool:
|
@@ -67,10 +72,7 @@ class NestedHandleBinding(HandleBinding):
|
|
67
72
|
|
68
73
|
class SubscriptHandleBinding(NestedHandleBinding):
|
69
74
|
index: Expression
|
70
|
-
|
71
|
-
class Config:
|
72
|
-
frozen = True
|
73
|
-
extra = Extra.forbid
|
75
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
74
76
|
|
75
77
|
def __str__(self) -> str:
|
76
78
|
return f"{self.base_handle}[{self.index}]"
|
@@ -121,10 +123,7 @@ class SubscriptHandleBinding(NestedHandleBinding):
|
|
121
123
|
class SlicedHandleBinding(NestedHandleBinding):
|
122
124
|
start: Expression
|
123
125
|
end: Expression
|
124
|
-
|
125
|
-
class Config:
|
126
|
-
frozen = True
|
127
|
-
extra = Extra.forbid
|
126
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
128
127
|
|
129
128
|
def __str__(self) -> str:
|
130
129
|
return f"{self.base_handle}[{self.start}:{self.end}]"
|
@@ -191,10 +190,7 @@ class SlicedHandleBinding(NestedHandleBinding):
|
|
191
190
|
|
192
191
|
class FieldHandleBinding(NestedHandleBinding):
|
193
192
|
field: str
|
194
|
-
|
195
|
-
class Config:
|
196
|
-
frozen = True
|
197
|
-
extra = Extra.forbid
|
193
|
+
model_config = ConfigDict(frozen=True, extra="forbid")
|
198
194
|
|
199
195
|
def __str__(self) -> str:
|
200
196
|
return f"{self.base_handle}.{self.field}"
|
@@ -222,6 +218,6 @@ ConcreteHandleBinding = Union[
|
|
222
218
|
SlicedHandleBinding,
|
223
219
|
FieldHandleBinding,
|
224
220
|
]
|
225
|
-
SubscriptHandleBinding.
|
226
|
-
SlicedHandleBinding.
|
227
|
-
FieldHandleBinding.
|
221
|
+
SubscriptHandleBinding.model_rebuild()
|
222
|
+
SlicedHandleBinding.model_rebuild()
|
223
|
+
FieldHandleBinding.model_rebuild()
|
@@ -1,7 +1,7 @@
|
|
1
|
-
from typing import Literal, Mapping, Sequence
|
1
|
+
from typing import Literal, Mapping, Sequence, Union
|
2
2
|
|
3
3
|
from classiq.interface.enum_utils import StrEnum
|
4
|
-
from classiq.interface.
|
4
|
+
from classiq.interface.generator.expressions.expression import Expression
|
5
5
|
from classiq.interface.model.handle_binding import ConcreteHandleBinding, HandleBinding
|
6
6
|
from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
|
7
7
|
|
@@ -15,21 +15,28 @@ class InplaceBinaryOperation(QuantumOperation):
|
|
15
15
|
kind: Literal["InplaceBinaryOperation"]
|
16
16
|
|
17
17
|
target: ConcreteHandleBinding
|
18
|
-
value: ConcreteHandleBinding
|
18
|
+
value: Union[ConcreteHandleBinding, Expression]
|
19
19
|
operation: BinaryOperation
|
20
20
|
|
21
21
|
@property
|
22
22
|
def wiring_inouts(self) -> Mapping[str, HandleBinding]:
|
23
|
-
|
23
|
+
inouts = {self.target.name: self.target}
|
24
|
+
if isinstance(self.value, HandleBinding):
|
25
|
+
inouts[self.value.name] = self.value
|
26
|
+
return inouts
|
24
27
|
|
25
28
|
@property
|
26
29
|
def readable_inouts(self) -> Sequence[HandleMetadata]:
|
27
30
|
suffix = f" of an in-place {self.operation.name.lower()} statement"
|
28
|
-
|
31
|
+
readable_inouts = [
|
29
32
|
HandleMetadata(
|
30
33
|
handle=self.target, readable_location=f"as the target{suffix}"
|
31
|
-
)
|
32
|
-
HandleMetadata(
|
33
|
-
handle=self.value, readable_location=f"as the value{suffix}"
|
34
|
-
),
|
34
|
+
)
|
35
35
|
]
|
36
|
+
if isinstance(self.value, HandleBinding):
|
37
|
+
readable_inouts.append(
|
38
|
+
HandleMetadata(
|
39
|
+
handle=self.value, readable_location=f"as the value{suffix}"
|
40
|
+
)
|
41
|
+
)
|
42
|
+
return readable_inouts
|
classiq/interface/model/model.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from collections import Counter
|
2
|
-
from typing import List, Literal, Mapping, NewType
|
2
|
+
from typing import Any, List, Literal, Mapping, NewType
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
@@ -61,6 +61,7 @@ class Model(VersionedModel, ASTNode):
|
|
61
61
|
functions: List[NativeFunctionDefinition] = pydantic.Field(
|
62
62
|
default_factory=list,
|
63
63
|
description="The user-defined custom type library.",
|
64
|
+
validate_default=True,
|
64
65
|
)
|
65
66
|
|
66
67
|
enums: List[EnumDeclaration] = pydantic.Field(
|
@@ -105,9 +106,17 @@ class Model(VersionedModel, ASTNode):
|
|
105
106
|
def body(self) -> StatementBlock:
|
106
107
|
return self.main_func.body
|
107
108
|
|
108
|
-
@pydantic.
|
109
|
-
|
110
|
-
|
109
|
+
@pydantic.field_validator("preferences", mode="before")
|
110
|
+
@classmethod
|
111
|
+
def _seed_suffix_randomizer(cls, preferences: Any) -> Any:
|
112
|
+
if isinstance(preferences, dict):
|
113
|
+
SUFFIX_RANDOMIZER.seed(preferences.get("random_seed"))
|
114
|
+
elif isinstance(preferences, Preferences):
|
115
|
+
SUFFIX_RANDOMIZER.seed(preferences.random_seed)
|
116
|
+
else:
|
117
|
+
raise ClassiqValueError(
|
118
|
+
f"preferences must be either a dict or a Preferences object, not {type(preferences)}"
|
119
|
+
)
|
111
120
|
return preferences
|
112
121
|
|
113
122
|
def _get_qualified_direction(
|
@@ -121,7 +130,8 @@ class Model(VersionedModel, ASTNode):
|
|
121
130
|
def function_dict(self) -> Mapping[str, NamedParamsQuantumFunctionDeclaration]:
|
122
131
|
return nameables_to_dict(self.functions)
|
123
132
|
|
124
|
-
@pydantic.
|
133
|
+
@pydantic.field_validator("functions")
|
134
|
+
@classmethod
|
125
135
|
def _add_empty_main(
|
126
136
|
cls, functions: List[NativeFunctionDefinition]
|
127
137
|
) -> List[NativeFunctionDefinition]:
|
@@ -131,11 +141,10 @@ class Model(VersionedModel, ASTNode):
|
|
131
141
|
return functions
|
132
142
|
|
133
143
|
def get_model(self) -> SerializedModel:
|
134
|
-
return SerializedModel(
|
135
|
-
self.json(exclude_defaults=True, exclude_unset=True, indent=2)
|
136
|
-
)
|
144
|
+
return SerializedModel(self.model_dump_json(indent=2))
|
137
145
|
|
138
|
-
@pydantic.
|
146
|
+
@pydantic.field_validator("functions")
|
147
|
+
@classmethod
|
139
148
|
def _validate_entry_point(
|
140
149
|
cls, functions: List[NativeFunctionDefinition]
|
141
150
|
) -> List[NativeFunctionDefinition]:
|
@@ -150,7 +159,8 @@ class Model(VersionedModel, ASTNode):
|
|
150
159
|
|
151
160
|
return functions
|
152
161
|
|
153
|
-
@pydantic.
|
162
|
+
@pydantic.field_validator("constants")
|
163
|
+
@classmethod
|
154
164
|
def _validate_constants(cls, constants: List[Constant]) -> List[Constant]:
|
155
165
|
constant_definition_counts = Counter(
|
156
166
|
[constant.name for constant in constants]
|
@@ -166,7 +176,7 @@ class Model(VersionedModel, ASTNode):
|
|
166
176
|
return constants
|
167
177
|
|
168
178
|
def json_no_preferences_and_constraints(self) -> str:
|
169
|
-
return self.
|
179
|
+
return self.model_dump_json(
|
170
180
|
indent=2,
|
171
181
|
exclude={
|
172
182
|
"constraints",
|
@@ -1,6 +1,7 @@
|
|
1
|
-
from typing import Any, Dict, Literal
|
1
|
+
from typing import Any, Dict, Literal
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic_core.core_schema import ValidationInfo
|
4
5
|
|
5
6
|
from classiq.interface.exceptions import ClassiqInternalError, ClassiqValueError
|
6
7
|
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
@@ -12,19 +13,21 @@ from classiq.interface.model.parameter import Parameter
|
|
12
13
|
|
13
14
|
|
14
15
|
class AnonPortDeclaration(Parameter):
|
15
|
-
kind: Literal["PortDeclaration"]
|
16
|
-
|
17
16
|
quantum_type: ConcreteQuantumType
|
18
17
|
direction: PortDeclarationDirection
|
18
|
+
kind: Literal["PortDeclaration"]
|
19
19
|
|
20
|
-
@pydantic.
|
21
|
-
|
20
|
+
@pydantic.model_validator(mode="before")
|
21
|
+
@classmethod
|
22
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
22
23
|
return values_with_discriminator(values, "kind", "PortDeclaration")
|
23
24
|
|
24
|
-
@pydantic.
|
25
|
+
@pydantic.field_validator("direction", mode="before")
|
26
|
+
@classmethod
|
25
27
|
def _direction_validator(
|
26
|
-
cls, direction: PortDeclarationDirection,
|
28
|
+
cls, direction: PortDeclarationDirection, info: ValidationInfo
|
27
29
|
) -> PortDeclarationDirection:
|
30
|
+
values = info.data
|
28
31
|
if direction is PortDeclarationDirection.Output:
|
29
32
|
quantum_type = values.get("quantum_type")
|
30
33
|
if quantum_type is None:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Dict, Literal, Mapping, Optional, Sequence
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic_core.core_schema import ValidationInfo
|
4
5
|
|
5
6
|
from classiq.interface.enum_utils import StrEnum
|
6
7
|
from classiq.interface.generator.arith.arithmetic import (
|
@@ -34,17 +35,18 @@ class ArithmeticOperation(QuantumAssignmentOperation):
|
|
34
35
|
)
|
35
36
|
|
36
37
|
operation_kind: ArithmeticOperationKind = pydantic.Field(
|
37
|
-
default=None,
|
38
|
+
default=None, validate_default=True
|
38
39
|
)
|
39
40
|
|
40
|
-
@pydantic.
|
41
|
+
@pydantic.field_validator("operation_kind", mode="before")
|
42
|
+
@classmethod
|
41
43
|
def _propagate_inplace_result(
|
42
|
-
cls, operation_kind: Optional[ArithmeticOperationKind],
|
44
|
+
cls, operation_kind: Optional[ArithmeticOperationKind], info: ValidationInfo
|
43
45
|
) -> ArithmeticOperationKind:
|
44
46
|
if operation_kind is None:
|
45
47
|
operation_kind = (
|
46
48
|
ArithmeticOperationKind.InplaceXor
|
47
|
-
if
|
49
|
+
if info.data["inplace_result"]
|
48
50
|
else ArithmeticOperationKind.Assignment
|
49
51
|
)
|
50
52
|
return operation_kind
|
@@ -8,6 +8,8 @@ from typing import (
|
|
8
8
|
)
|
9
9
|
|
10
10
|
import pydantic
|
11
|
+
from pydantic import SerializeAsAny
|
12
|
+
from pydantic_core.core_schema import ValidationInfo
|
11
13
|
from typing_extensions import Annotated
|
12
14
|
|
13
15
|
from classiq.interface.exceptions import ClassiqInternalError
|
@@ -143,7 +145,7 @@ class AnonQuantumFunctionDeclaration(FunctionDeclaration):
|
|
143
145
|
**{
|
144
146
|
field_name: field_value
|
145
147
|
for field_name, field_value in self.__dict__.items()
|
146
|
-
if field_name in AnonQuantumFunctionDeclaration.
|
148
|
+
if field_name in AnonQuantumFunctionDeclaration.model_fields
|
147
149
|
},
|
148
150
|
"name": new_name,
|
149
151
|
}
|
@@ -158,17 +160,21 @@ class AnonQuantumOperandDeclaration(AnonQuantumFunctionDeclaration):
|
|
158
160
|
default=False,
|
159
161
|
)
|
160
162
|
|
161
|
-
@pydantic.
|
162
|
-
|
163
|
+
@pydantic.model_validator(mode="before")
|
164
|
+
@classmethod
|
165
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
163
166
|
return values_with_discriminator(values, "kind", "QuantumOperandDeclaration")
|
164
167
|
|
165
168
|
def rename(self, new_name: str) -> "QuantumOperandDeclaration":
|
166
169
|
if type(self) not in (AnonQuantumOperandDeclaration, QuantumOperandDeclaration):
|
167
170
|
raise ClassiqInternalError
|
168
|
-
|
171
|
+
new_instance_data = self.__dict__.copy()
|
172
|
+
new_instance_data["name"] = new_name
|
173
|
+
new_instance_data["kind"] = "QuantumOperandDeclaration"
|
174
|
+
return QuantumOperandDeclaration(**new_instance_data)
|
169
175
|
|
170
176
|
|
171
|
-
AnonQuantumFunctionDeclaration.
|
177
|
+
AnonQuantumFunctionDeclaration.model_rebuild()
|
172
178
|
|
173
179
|
|
174
180
|
class QuantumFunctionDeclaration(AnonQuantumFunctionDeclaration):
|
@@ -176,16 +182,21 @@ class QuantumFunctionDeclaration(AnonQuantumFunctionDeclaration):
|
|
176
182
|
|
177
183
|
|
178
184
|
class QuantumOperandDeclaration(
|
179
|
-
|
185
|
+
AnonQuantumOperandDeclaration, QuantumFunctionDeclaration
|
180
186
|
):
|
181
|
-
|
187
|
+
@pydantic.model_validator(mode="before")
|
188
|
+
@classmethod
|
189
|
+
def _set_none(cls, values: Any, info: ValidationInfo) -> Dict[str, Any]:
|
190
|
+
return values
|
182
191
|
|
183
192
|
|
184
193
|
PositionalArg = Annotated[
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
194
|
+
SerializeAsAny[
|
195
|
+
Union[
|
196
|
+
ClassicalParameterDeclaration,
|
197
|
+
QuantumOperandDeclaration,
|
198
|
+
PortDeclaration,
|
199
|
+
]
|
189
200
|
],
|
190
201
|
pydantic.Field(..., discriminator="kind"),
|
191
202
|
]
|
@@ -3,7 +3,7 @@ from typing import Any, Callable, Dict, Mapping, Optional, Sequence
|
|
3
3
|
from uuid import UUID, uuid4
|
4
4
|
|
5
5
|
import pydantic
|
6
|
-
from pydantic import
|
6
|
+
from pydantic import ConfigDict
|
7
7
|
|
8
8
|
from classiq.interface.ast_node import ASTNode
|
9
9
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
@@ -15,13 +15,12 @@ from classiq.interface.model.handle_binding import (
|
|
15
15
|
|
16
16
|
class QuantumStatement(ASTNode):
|
17
17
|
kind: str
|
18
|
+
model_config = ConfigDict(extra="forbid")
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
24
|
-
return values_with_discriminator(values, "kind", cls.__name__) # type: ignore[attr-defined]
|
20
|
+
@pydantic.model_validator(mode="before")
|
21
|
+
@classmethod
|
22
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
23
|
+
return values_with_discriminator(values, "kind", cls.__name__)
|
25
24
|
|
26
25
|
|
27
26
|
@dataclass
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from typing import TYPE_CHECKING, Any, Dict, Literal, Optional
|
2
2
|
|
3
3
|
import pydantic
|
4
|
-
from pydantic import BaseModel,
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field
|
5
|
+
from typing_extensions import Self
|
5
6
|
|
6
7
|
from classiq.interface.ast_node import HashableASTNode
|
7
8
|
from classiq.interface.exceptions import ClassiqValueError
|
@@ -25,8 +26,7 @@ if TYPE_CHECKING:
|
|
25
26
|
|
26
27
|
|
27
28
|
class QuantumType(HashableASTNode):
|
28
|
-
|
29
|
-
extra = Extra.forbid
|
29
|
+
model_config = ConfigDict(extra="forbid")
|
30
30
|
|
31
31
|
_size_in_bits: Optional[int] = pydantic.PrivateAttr(default=None)
|
32
32
|
|
@@ -72,8 +72,9 @@ class QuantumBit(QuantumScalar):
|
|
72
72
|
super().__init__(**kwargs)
|
73
73
|
self._size_in_bits = 1
|
74
74
|
|
75
|
-
@pydantic.
|
76
|
-
|
75
|
+
@pydantic.model_validator(mode="before")
|
76
|
+
@classmethod
|
77
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
77
78
|
return values_with_discriminator(values, "kind", "qbit")
|
78
79
|
|
79
80
|
@property
|
@@ -89,14 +90,15 @@ class QuantumBit(QuantumScalar):
|
|
89
90
|
|
90
91
|
|
91
92
|
class QuantumBitvector(QuantumType):
|
92
|
-
kind: Literal["qvec"]
|
93
93
|
element_type: "ConcreteQuantumType" = Field(
|
94
94
|
discriminator="kind", default_factory=QuantumBit
|
95
95
|
)
|
96
|
-
|
96
|
+
kind: Literal["qvec"]
|
97
|
+
length: Optional[Expression] = Field(default=None)
|
97
98
|
|
98
|
-
@pydantic.
|
99
|
-
|
99
|
+
@pydantic.model_validator(mode="before")
|
100
|
+
@classmethod
|
101
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
100
102
|
return values_with_discriminator(values, "kind", "qvec")
|
101
103
|
|
102
104
|
def _update_size_in_bits_from_declaration(self) -> None:
|
@@ -144,23 +146,24 @@ class QuantumBitvector(QuantumType):
|
|
144
146
|
class QuantumNumeric(QuantumScalar):
|
145
147
|
kind: Literal["qnum"]
|
146
148
|
|
147
|
-
size: Optional[Expression] = pydantic.Field()
|
148
|
-
is_signed: Optional[Expression] = pydantic.Field()
|
149
|
-
fraction_digits: Optional[Expression] = pydantic.Field()
|
149
|
+
size: Optional[Expression] = pydantic.Field(default=None)
|
150
|
+
is_signed: Optional[Expression] = pydantic.Field(default=None)
|
151
|
+
fraction_digits: Optional[Expression] = pydantic.Field(default=None)
|
150
152
|
|
151
|
-
@pydantic.
|
152
|
-
|
153
|
+
@pydantic.model_validator(mode="before")
|
154
|
+
@classmethod
|
155
|
+
def _set_kind(cls, values: Any) -> Dict[str, Any]:
|
153
156
|
return values_with_discriminator(values, "kind", "qnum")
|
154
157
|
|
155
|
-
@pydantic.
|
156
|
-
def _validate_fields(
|
157
|
-
has_sign =
|
158
|
-
has_fraction_digits =
|
158
|
+
@pydantic.model_validator(mode="after")
|
159
|
+
def _validate_fields(self) -> Self:
|
160
|
+
has_sign = self.is_signed is not None
|
161
|
+
has_fraction_digits = self.fraction_digits is not None
|
159
162
|
if has_sign and not has_fraction_digits or not has_sign and has_fraction_digits:
|
160
163
|
raise ClassiqValueError(
|
161
164
|
"Assign neither or both of is_signed and fraction_digits"
|
162
165
|
)
|
163
|
-
return
|
166
|
+
return self
|
164
167
|
|
165
168
|
@property
|
166
169
|
def has_sign(self) -> bool:
|
@@ -46,12 +46,12 @@ ConcreteQuantumStatement = Annotated[
|
|
46
46
|
|
47
47
|
StatementBlock = List[ConcreteQuantumStatement]
|
48
48
|
|
49
|
-
Control.
|
50
|
-
QuantumLambdaFunction.
|
51
|
-
Repeat.
|
52
|
-
Power.
|
53
|
-
Invert.
|
54
|
-
WithinApply.
|
55
|
-
ClassicalIf.
|
56
|
-
NativeFunctionDefinition.
|
57
|
-
PhaseOperation.
|
49
|
+
Control.model_rebuild()
|
50
|
+
QuantumLambdaFunction.model_rebuild()
|
51
|
+
Repeat.model_rebuild()
|
52
|
+
Power.model_rebuild()
|
53
|
+
Invert.model_rebuild()
|
54
|
+
WithinApply.model_rebuild()
|
55
|
+
ClassicalIf.model_rebuild()
|
56
|
+
NativeFunctionDefinition.model_rebuild()
|
57
|
+
PhaseOperation.model_rebuild()
|
@@ -1,15 +1,14 @@
|
|
1
1
|
from datetime import date
|
2
2
|
from typing import Any, Dict
|
3
3
|
|
4
|
-
import pydantic
|
5
4
|
from pydantic import BaseModel
|
6
5
|
|
7
6
|
|
8
7
|
class DeprecationInfo(BaseModel):
|
9
|
-
deprecation_date: date
|
10
|
-
removal_date: date
|
8
|
+
deprecation_date: date
|
9
|
+
removal_date: date
|
11
10
|
|
12
11
|
|
13
12
|
class GlobalVersions(BaseModel):
|
14
|
-
deprecated: Dict[str, DeprecationInfo]
|
15
|
-
deployed: Dict[str, Any]
|
13
|
+
deprecated: Dict[str, DeprecationInfo]
|
14
|
+
deployed: Dict[str, Any]
|