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
@@ -2,18 +2,16 @@ from typing import (
|
|
2
2
|
Any,
|
3
3
|
ClassVar,
|
4
4
|
Dict,
|
5
|
-
List,
|
6
5
|
Literal,
|
7
|
-
Mapping,
|
8
6
|
Sequence,
|
9
7
|
Set,
|
10
|
-
Type,
|
11
8
|
Union,
|
12
9
|
)
|
13
10
|
|
14
11
|
import pydantic
|
15
12
|
from typing_extensions import Annotated
|
16
13
|
|
14
|
+
from classiq.interface.generator.arith.register_user_input import RegisterUserInput
|
17
15
|
from classiq.interface.generator.function_params import ArithmeticIODict, PortDirection
|
18
16
|
from classiq.interface.generator.functions.function_declaration import (
|
19
17
|
FunctionDeclaration,
|
@@ -22,218 +20,122 @@ from classiq.interface.generator.functions.port_declaration import (
|
|
22
20
|
PortDeclarationDirection,
|
23
21
|
)
|
24
22
|
from classiq.interface.helpers.pydantic_model_helpers import (
|
25
|
-
Nameable,
|
26
23
|
values_with_discriminator,
|
27
24
|
)
|
28
|
-
from classiq.interface.helpers.validation_helpers import (
|
29
|
-
validate_nameables_mapping,
|
30
|
-
validate_nameables_no_overlap,
|
31
|
-
)
|
32
25
|
from classiq.interface.model.classical_parameter_declaration import (
|
26
|
+
AnonClassicalParameterDeclaration,
|
33
27
|
ClassicalParameterDeclaration,
|
34
28
|
)
|
35
|
-
from classiq.interface.model.port_declaration import
|
29
|
+
from classiq.interface.model.port_declaration import (
|
30
|
+
AnonPortDeclaration,
|
31
|
+
PortDeclaration,
|
32
|
+
)
|
36
33
|
from classiq.interface.model.quantum_type import quantum_var_to_register
|
37
34
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
return pos_decl == kw_decl
|
45
|
-
|
46
|
-
|
47
|
-
def _populate_declaration_dicts_with_positional_lists(
|
48
|
-
pos_decls: Sequence[Nameable],
|
49
|
-
kw_decls: Dict[str, Nameable],
|
50
|
-
param_type: Type[Nameable],
|
51
|
-
) -> None:
|
52
|
-
for pos_decl in pos_decls:
|
53
|
-
if not isinstance(pos_decl, param_type):
|
54
|
-
continue
|
55
|
-
kw_decl = kw_decls.get(pos_decl.name)
|
56
|
-
if kw_decl is not None and not _is_equiv_kw_and_pos_decl(kw_decl, pos_decl):
|
57
|
-
raise ClassiqValueError(
|
58
|
-
f"{param_type.__name__} parameter with name {pos_decl.name} already declared"
|
59
|
-
)
|
60
|
-
kw_decls[pos_decl.name] = (
|
61
|
-
pos_decl.classical_type # type:ignore[assignment]
|
62
|
-
if isinstance(pos_decl, ClassicalParameterDeclaration)
|
63
|
-
else pos_decl
|
64
|
-
)
|
65
|
-
|
66
|
-
|
67
|
-
PositionalArg = Annotated[
|
68
|
-
Union[ClassicalParameterDeclaration, "QuantumOperandDeclaration", PortDeclaration],
|
35
|
+
AnonPositionalArg = Annotated[
|
36
|
+
Union[
|
37
|
+
AnonClassicalParameterDeclaration,
|
38
|
+
"AnonQuantumOperandDeclaration",
|
39
|
+
AnonPortDeclaration,
|
40
|
+
],
|
69
41
|
pydantic.Field(..., discriminator="kind"),
|
70
42
|
]
|
71
43
|
|
72
44
|
|
73
45
|
def _ports_to_registers(
|
74
|
-
port_declarations:
|
75
|
-
) ->
|
76
|
-
return
|
77
|
-
|
78
|
-
for
|
46
|
+
port_declarations: Sequence[AnonPortDeclaration], direction: PortDirection
|
47
|
+
) -> Sequence[RegisterUserInput]:
|
48
|
+
return [
|
49
|
+
quantum_var_to_register(port_decl.get_name(), port_decl.quantum_type)
|
50
|
+
for port_decl in port_declarations
|
79
51
|
if port_decl.direction.includes_port_direction(direction)
|
80
|
-
|
52
|
+
]
|
81
53
|
|
82
54
|
|
83
|
-
class
|
55
|
+
class AnonQuantumFunctionDeclaration(FunctionDeclaration):
|
84
56
|
"""
|
85
57
|
Facilitates the creation of a common quantum function interface object.
|
86
58
|
"""
|
87
59
|
|
88
|
-
|
89
|
-
|
90
|
-
default_factory=dict,
|
60
|
+
positional_arg_declarations: Sequence[AnonPositionalArg] = pydantic.Field(
|
61
|
+
default_factory=list
|
91
62
|
)
|
92
63
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
64
|
+
@property
|
65
|
+
def port_declarations(self) -> Sequence[AnonPortDeclaration]:
|
66
|
+
return [
|
67
|
+
arg
|
68
|
+
for arg in self.positional_arg_declarations
|
69
|
+
if isinstance(arg, AnonPortDeclaration)
|
70
|
+
]
|
97
71
|
|
98
|
-
|
99
|
-
|
100
|
-
|
72
|
+
@property
|
73
|
+
def operand_declarations(self) -> Sequence["AnonQuantumOperandDeclaration"]:
|
74
|
+
return [
|
75
|
+
arg
|
76
|
+
for arg in self.positional_arg_declarations
|
77
|
+
if isinstance(arg, AnonQuantumOperandDeclaration)
|
78
|
+
]
|
101
79
|
|
102
|
-
|
103
|
-
|
104
|
-
|
80
|
+
@property
|
81
|
+
def param_decls(self) -> Sequence[AnonClassicalParameterDeclaration]:
|
82
|
+
return [
|
83
|
+
arg
|
84
|
+
for arg in self.positional_arg_declarations
|
85
|
+
if isinstance(arg, AnonClassicalParameterDeclaration)
|
86
|
+
]
|
87
|
+
|
88
|
+
@property
|
89
|
+
def param_names(self) -> Sequence[str]:
|
90
|
+
return [param.get_name() for param in self.param_decls]
|
105
91
|
|
106
92
|
@property
|
107
93
|
def input_set(self) -> Set[str]:
|
108
|
-
return
|
94
|
+
return {inp.name for inp in self.inputs}
|
109
95
|
|
110
96
|
@property
|
111
97
|
def output_set(self) -> Set[str]:
|
112
|
-
return
|
98
|
+
return {output.name for output in self.outputs}
|
113
99
|
|
114
100
|
@property
|
115
|
-
def inputs(self) ->
|
101
|
+
def inputs(self) -> Sequence[RegisterUserInput]:
|
116
102
|
return _ports_to_registers(self.port_declarations, PortDirection.Input)
|
117
103
|
|
118
104
|
@property
|
119
|
-
def outputs(self) ->
|
105
|
+
def outputs(self) -> Sequence[RegisterUserInput]:
|
120
106
|
return _ports_to_registers(self.port_declarations, PortDirection.Output)
|
121
107
|
|
122
|
-
def update_logic_flow(
|
123
|
-
self, function_dict: Mapping[str, "QuantumFunctionDeclaration"]
|
124
|
-
) -> None:
|
125
|
-
pass
|
126
|
-
|
127
108
|
@property
|
128
|
-
def port_names(self) ->
|
129
|
-
return
|
109
|
+
def port_names(self) -> Sequence[str]:
|
110
|
+
return [port.get_name() for port in self.port_declarations]
|
130
111
|
|
131
112
|
@property
|
132
|
-
def operand_names(self) ->
|
133
|
-
return
|
113
|
+
def operand_names(self) -> Sequence[str]:
|
114
|
+
return [operand.get_name() for operand in self.operand_declarations]
|
134
115
|
|
135
116
|
def ports_by_direction(
|
136
117
|
self, direction: PortDirection
|
137
|
-
) ->
|
138
|
-
return
|
139
|
-
|
140
|
-
for
|
118
|
+
) -> Sequence[AnonPortDeclaration]:
|
119
|
+
return [
|
120
|
+
port
|
121
|
+
for port in self.port_declarations
|
141
122
|
if port.direction.includes_port_direction(direction)
|
142
|
-
|
123
|
+
]
|
143
124
|
|
144
125
|
def ports_by_declaration_direction(
|
145
126
|
self, direction: PortDeclarationDirection
|
146
127
|
) -> Set[str]:
|
147
128
|
return {
|
148
|
-
|
149
|
-
for
|
129
|
+
port.get_name()
|
130
|
+
for port in self.port_declarations
|
150
131
|
if port.direction == direction
|
151
132
|
}
|
152
133
|
|
153
|
-
def
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
for name, ctype in self.param_decls.items()
|
159
|
-
]
|
160
|
-
result.extend(self.operand_declarations.values())
|
161
|
-
result.extend(self.port_declarations.values())
|
162
|
-
return result
|
163
|
-
|
164
|
-
@pydantic.validator("operand_declarations")
|
165
|
-
def _validate_operand_declarations_names(
|
166
|
-
cls, operand_declarations: Dict[str, "QuantumOperandDeclaration"]
|
167
|
-
) -> Dict[str, "QuantumOperandDeclaration"]:
|
168
|
-
validate_nameables_mapping(operand_declarations, "Operand")
|
169
|
-
return operand_declarations
|
170
|
-
|
171
|
-
@pydantic.validator("port_declarations")
|
172
|
-
def _validate_port_declarations_names(
|
173
|
-
cls, port_declarations: Dict[str, PortDeclaration]
|
174
|
-
) -> Dict[str, PortDeclaration]:
|
175
|
-
validate_nameables_mapping(port_declarations, "Port")
|
176
|
-
return port_declarations
|
177
|
-
|
178
|
-
@pydantic.root_validator()
|
179
|
-
def _validate_params_and_operands_uniqueness(
|
180
|
-
cls, values: Dict[str, Any]
|
181
|
-
) -> Dict[str, Any]:
|
182
|
-
operand_declarations = values.get("operand_declarations")
|
183
|
-
parameter_declarations = values.get("param_decls")
|
184
|
-
port_declarations = values.get("port_declarations")
|
185
|
-
operand_parameter = validate_nameables_no_overlap(
|
186
|
-
operand_declarations, parameter_declarations, "operand", "parameter"
|
187
|
-
)
|
188
|
-
operand_port = validate_nameables_no_overlap(
|
189
|
-
operand_declarations, port_declarations, "operand", "port"
|
190
|
-
)
|
191
|
-
parameter_port = validate_nameables_no_overlap(
|
192
|
-
parameter_declarations, port_declarations, "parameter", "port"
|
193
|
-
)
|
194
|
-
error_message = ",".join(
|
195
|
-
msg
|
196
|
-
for msg in [operand_parameter, operand_port, parameter_port]
|
197
|
-
if msg is not None
|
198
|
-
)
|
199
|
-
|
200
|
-
if error_message:
|
201
|
-
raise ClassiqValueError(error_message)
|
202
|
-
|
203
|
-
return values
|
204
|
-
|
205
|
-
@pydantic.root_validator()
|
206
|
-
def _reduce_positional_declarations_to_keyword(
|
207
|
-
cls, values: Dict[str, Any]
|
208
|
-
) -> Dict[str, Any]:
|
209
|
-
operand_declarations = values.get("operand_declarations", dict())
|
210
|
-
parameter_declarations = values.get("param_decls", dict())
|
211
|
-
port_declarations = values.get("port_declarations", dict())
|
212
|
-
|
213
|
-
positional_arg_declarations = values.get("positional_arg_declarations", list())
|
214
|
-
|
215
|
-
_populate_declaration_dicts_with_positional_lists(
|
216
|
-
positional_arg_declarations,
|
217
|
-
parameter_declarations,
|
218
|
-
ClassicalParameterDeclaration,
|
219
|
-
)
|
220
|
-
_populate_declaration_dicts_with_positional_lists(
|
221
|
-
positional_arg_declarations,
|
222
|
-
operand_declarations,
|
223
|
-
QuantumOperandDeclaration,
|
224
|
-
)
|
225
|
-
_populate_declaration_dicts_with_positional_lists(
|
226
|
-
positional_arg_declarations, port_declarations, PortDeclaration
|
227
|
-
)
|
228
|
-
|
229
|
-
values["operand_declarations"] = operand_declarations
|
230
|
-
values["param_decls"] = parameter_declarations
|
231
|
-
values["port_declarations"] = port_declarations
|
232
|
-
|
233
|
-
return values
|
234
|
-
|
235
|
-
|
236
|
-
class QuantumOperandDeclaration(QuantumFunctionDeclaration):
|
134
|
+
def rename(self, new_name: str) -> "QuantumFunctionDeclaration":
|
135
|
+
return QuantumFunctionDeclaration(**{**self.__dict__, "name": new_name})
|
136
|
+
|
137
|
+
|
138
|
+
class AnonQuantumOperandDeclaration(AnonQuantumFunctionDeclaration):
|
237
139
|
kind: Literal["QuantumOperandDeclaration"]
|
238
140
|
|
239
141
|
is_list: bool = pydantic.Field(
|
@@ -245,5 +147,85 @@ class QuantumOperandDeclaration(QuantumFunctionDeclaration):
|
|
245
147
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
246
148
|
return values_with_discriminator(values, "kind", "QuantumOperandDeclaration")
|
247
149
|
|
150
|
+
def rename(self, new_name: str) -> "QuantumOperandDeclaration":
|
151
|
+
return QuantumOperandDeclaration(**{**self.__dict__, "name": new_name})
|
152
|
+
|
153
|
+
|
154
|
+
AnonQuantumFunctionDeclaration.update_forward_refs()
|
155
|
+
|
156
|
+
|
157
|
+
class QuantumFunctionDeclaration(AnonQuantumFunctionDeclaration):
|
158
|
+
name: str
|
159
|
+
|
160
|
+
BUILTIN_FUNCTION_DECLARATIONS: ClassVar[
|
161
|
+
Dict[str, "NamedParamsQuantumFunctionDeclaration"]
|
162
|
+
] = {}
|
163
|
+
|
164
|
+
|
165
|
+
class QuantumOperandDeclaration(
|
166
|
+
QuantumFunctionDeclaration, AnonQuantumOperandDeclaration
|
167
|
+
):
|
168
|
+
pass
|
248
169
|
|
249
|
-
|
170
|
+
|
171
|
+
PositionalArg = Annotated[
|
172
|
+
Union[
|
173
|
+
ClassicalParameterDeclaration,
|
174
|
+
QuantumOperandDeclaration,
|
175
|
+
PortDeclaration,
|
176
|
+
],
|
177
|
+
pydantic.Field(..., discriminator="kind"),
|
178
|
+
]
|
179
|
+
|
180
|
+
|
181
|
+
class NamedParamsQuantumFunctionDeclaration(QuantumFunctionDeclaration):
|
182
|
+
|
183
|
+
positional_arg_declarations: Sequence[PositionalArg] = pydantic.Field(
|
184
|
+
default_factory=list
|
185
|
+
)
|
186
|
+
|
187
|
+
@property
|
188
|
+
def port_declarations_dict(self) -> Dict[str, PortDeclaration]:
|
189
|
+
return {port.name: port for port in self.port_declarations}
|
190
|
+
|
191
|
+
@property
|
192
|
+
def operand_declarations_dict(self) -> Dict[str, QuantumOperandDeclaration]:
|
193
|
+
return {op.name: op for op in self.operand_declarations}
|
194
|
+
|
195
|
+
@property
|
196
|
+
def param_decls_dict(self) -> Dict[str, ClassicalParameterDeclaration]:
|
197
|
+
return {param.name: param for param in self.param_decls}
|
198
|
+
|
199
|
+
@property
|
200
|
+
def inputs_dict(self) -> ArithmeticIODict:
|
201
|
+
return _ports_to_registers_dict(self.port_declarations, PortDirection.Input)
|
202
|
+
|
203
|
+
@property
|
204
|
+
def inouts_dict(self) -> ArithmeticIODict:
|
205
|
+
return _ports_to_registers_dict(self.port_declarations, PortDirection.Inout)
|
206
|
+
|
207
|
+
@property
|
208
|
+
def outputs_dict(self) -> ArithmeticIODict:
|
209
|
+
return _ports_to_registers_dict(self.port_declarations, PortDirection.Output)
|
210
|
+
|
211
|
+
@property
|
212
|
+
def port_declarations(self) -> Sequence[PortDeclaration]:
|
213
|
+
return super().port_declarations # type:ignore[return-value]
|
214
|
+
|
215
|
+
@property
|
216
|
+
def operand_declarations(self) -> Sequence[QuantumOperandDeclaration]:
|
217
|
+
return super().operand_declarations # type:ignore[return-value]
|
218
|
+
|
219
|
+
@property
|
220
|
+
def param_decls(self) -> Sequence[ClassicalParameterDeclaration]:
|
221
|
+
return super().param_decls # type:ignore[return-value]
|
222
|
+
|
223
|
+
|
224
|
+
def _ports_to_registers_dict(
|
225
|
+
port_declarations: Sequence[PortDeclaration], direction: PortDirection
|
226
|
+
) -> ArithmeticIODict:
|
227
|
+
return {
|
228
|
+
port_decl.name: quantum_var_to_register(port_decl.name, port_decl.quantum_type)
|
229
|
+
for port_decl in port_declarations
|
230
|
+
if port_decl.direction.includes_port_direction(direction)
|
231
|
+
}
|
@@ -1,10 +1,11 @@
|
|
1
|
-
from typing import TYPE_CHECKING, Dict, List, Optional, Union
|
1
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Union, cast
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
5
|
from classiq.interface.ast_node import ASTNode
|
6
|
+
from classiq.interface.exceptions import ClassiqError
|
6
7
|
from classiq.interface.model.quantum_function_declaration import (
|
7
|
-
|
8
|
+
AnonQuantumOperandDeclaration,
|
8
9
|
)
|
9
10
|
|
10
11
|
if TYPE_CHECKING:
|
@@ -18,22 +19,38 @@ class QuantumLambdaFunction(ASTNode):
|
|
18
19
|
|
19
20
|
rename_params: Dict[str, str] = pydantic.Field(
|
20
21
|
default_factory=dict,
|
21
|
-
|
22
|
+
)
|
23
|
+
|
24
|
+
pos_rename_params: List[str] = pydantic.Field(
|
25
|
+
default_factory=list,
|
26
|
+
description="Mapping of the declared param to the actual variable name used",
|
22
27
|
)
|
23
28
|
|
24
29
|
body: "StatementBlock" = pydantic.Field(
|
25
30
|
description="A list of function calls passed to the operator"
|
26
31
|
)
|
27
32
|
|
28
|
-
_func_decl: Optional[
|
33
|
+
_func_decl: Optional[AnonQuantumOperandDeclaration] = pydantic.PrivateAttr(
|
34
|
+
default=None
|
35
|
+
)
|
29
36
|
|
30
37
|
@property
|
31
|
-
def func_decl(self) ->
|
38
|
+
def func_decl(self) -> AnonQuantumOperandDeclaration:
|
39
|
+
if self._func_decl is None:
|
40
|
+
raise ClassiqError("Could not resolve lambda signature.")
|
32
41
|
return self._func_decl
|
33
42
|
|
34
|
-
def set_op_decl(self, fd:
|
43
|
+
def set_op_decl(self, fd: AnonQuantumOperandDeclaration) -> None:
|
35
44
|
self._func_decl = fd
|
36
45
|
|
46
|
+
def get_rename_params(self) -> List[str]:
|
47
|
+
if self.pos_rename_params:
|
48
|
+
return self.pos_rename_params
|
49
|
+
return [
|
50
|
+
self.rename_params.get(cast(str, param.name), cast(str, param.name))
|
51
|
+
for param in self.func_decl.positional_arg_declarations
|
52
|
+
]
|
53
|
+
|
37
54
|
|
38
55
|
QuantumCallable = Union[str, QuantumLambdaFunction]
|
39
56
|
QuantumOperand = Union[QuantumCallable, List[QuantumCallable]]
|
@@ -1,13 +1,13 @@
|
|
1
|
-
from
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Any, Dict, Mapping, Optional, Sequence
|
2
3
|
|
3
4
|
from pydantic import Extra, root_validator
|
4
5
|
|
5
6
|
from classiq.interface.ast_node import ASTNode
|
6
7
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
7
8
|
from classiq.interface.model.handle_binding import (
|
9
|
+
ConcreteHandleBinding,
|
8
10
|
HandleBinding,
|
9
|
-
SlicedHandleBinding,
|
10
|
-
SubscriptHandleBinding,
|
11
11
|
)
|
12
12
|
|
13
13
|
|
@@ -22,19 +22,45 @@ class QuantumStatement(ASTNode):
|
|
22
22
|
return values_with_discriminator(values, "kind", cls.__name__) # type: ignore[attr-defined]
|
23
23
|
|
24
24
|
|
25
|
+
@dataclass
|
26
|
+
class HandleMetadata:
|
27
|
+
handle: HandleBinding
|
28
|
+
readable_location: Optional[str] = None
|
29
|
+
|
30
|
+
|
25
31
|
class QuantumOperation(QuantumStatement):
|
26
32
|
@property
|
27
33
|
def wiring_inputs(self) -> Mapping[str, HandleBinding]:
|
28
34
|
return dict()
|
29
35
|
|
30
36
|
@property
|
31
|
-
def
|
32
|
-
self
|
33
|
-
|
34
|
-
|
35
|
-
]:
|
37
|
+
def inputs(self) -> Sequence[HandleBinding]:
|
38
|
+
return list(self.wiring_inputs.values())
|
39
|
+
|
40
|
+
@property
|
41
|
+
def wiring_inouts(self) -> Mapping[str, ConcreteHandleBinding]:
|
36
42
|
return dict()
|
37
43
|
|
44
|
+
@property
|
45
|
+
def inouts(self) -> Sequence[HandleBinding]:
|
46
|
+
return list(self.wiring_inouts.values())
|
47
|
+
|
38
48
|
@property
|
39
49
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
40
50
|
return dict()
|
51
|
+
|
52
|
+
@property
|
53
|
+
def outputs(self) -> Sequence[HandleBinding]:
|
54
|
+
return list(self.wiring_outputs.values())
|
55
|
+
|
56
|
+
@property
|
57
|
+
def readable_inputs(self) -> Sequence[HandleMetadata]:
|
58
|
+
return [HandleMetadata(handle=handle) for handle in self.inputs]
|
59
|
+
|
60
|
+
@property
|
61
|
+
def readable_inouts(self) -> Sequence[HandleMetadata]:
|
62
|
+
return [HandleMetadata(handle=handle) for handle in self.inouts]
|
63
|
+
|
64
|
+
@property
|
65
|
+
def readable_outputs(self) -> Sequence[HandleMetadata]:
|
66
|
+
return [HandleMetadata(handle=handle) for handle in self.outputs]
|
@@ -1,10 +1,10 @@
|
|
1
|
-
from typing import Any, Dict, Literal, Optional
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, Literal, Optional
|
2
2
|
|
3
3
|
import pydantic
|
4
|
-
from pydantic import Extra, Field
|
5
|
-
from typing_extensions import Annotated
|
4
|
+
from pydantic import BaseModel, Extra, Field
|
6
5
|
|
7
6
|
from classiq.interface.ast_node import HashableASTNode
|
7
|
+
from classiq.interface.exceptions import ClassiqValueError
|
8
8
|
from classiq.interface.generator.arith.register_user_input import (
|
9
9
|
RegisterArithmeticInfo,
|
10
10
|
RegisterUserInput,
|
@@ -20,7 +20,8 @@ from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedPr
|
|
20
20
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
21
21
|
from classiq.interface.model.handle_binding import HandleBinding
|
22
22
|
|
23
|
-
|
23
|
+
if TYPE_CHECKING:
|
24
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
24
25
|
|
25
26
|
|
26
27
|
class QuantumType(HashableASTNode):
|
@@ -56,7 +57,7 @@ class QuantumType(HashableASTNode):
|
|
56
57
|
|
57
58
|
@property
|
58
59
|
def type_name(self) -> str:
|
59
|
-
|
60
|
+
raise NotImplementedError
|
60
61
|
|
61
62
|
|
62
63
|
class QuantumScalar(QuantumType):
|
@@ -82,6 +83,10 @@ class QuantumBit(QuantumScalar):
|
|
82
83
|
def get_proxy(self, handle: "HandleBinding") -> QmodQBitProxy:
|
83
84
|
return QmodQBitProxy(handle)
|
84
85
|
|
86
|
+
@property
|
87
|
+
def type_name(self) -> str:
|
88
|
+
return "Quantum bit"
|
89
|
+
|
85
90
|
|
86
91
|
class QuantumBitvector(QuantumType):
|
87
92
|
kind: Literal["qvec"]
|
@@ -120,7 +125,7 @@ class QuantumBitvector(QuantumType):
|
|
120
125
|
assert self.size_in_bits % element_size == 0
|
121
126
|
return QmodQArrayProxy(
|
122
127
|
handle,
|
123
|
-
self.element_type
|
128
|
+
self.element_type,
|
124
129
|
element_size,
|
125
130
|
self.size_in_bits // element_size,
|
126
131
|
)
|
@@ -131,6 +136,10 @@ class QuantumBitvector(QuantumType):
|
|
131
136
|
length = [self.length.expr] if self.length is not None else []
|
132
137
|
return f"QArray[{', '.join(element_type + length)}]"
|
133
138
|
|
139
|
+
@property
|
140
|
+
def type_name(self) -> str:
|
141
|
+
return "Quantum array"
|
142
|
+
|
134
143
|
|
135
144
|
class QuantumNumeric(QuantumScalar):
|
136
145
|
kind: Literal["qnum"]
|
@@ -193,12 +202,24 @@ class QuantumNumeric(QuantumScalar):
|
|
193
202
|
return f"QNum[{self.size.expr}, {self.is_signed.expr}, {self.fraction_digits.expr}]"
|
194
203
|
return "QNum"
|
195
204
|
|
205
|
+
@property
|
206
|
+
def type_name(self) -> str:
|
207
|
+
return "Quantum numeric"
|
208
|
+
|
209
|
+
|
210
|
+
class RegisterQuantumType(BaseModel):
|
211
|
+
quantum_types: "ConcreteQuantumType"
|
212
|
+
size: int = Field(default=1)
|
213
|
+
|
214
|
+
@property
|
215
|
+
def qmod_type_name(self) -> str:
|
216
|
+
try:
|
217
|
+
return self.quantum_types.qmod_type_name.split("[")[0]
|
218
|
+
except AttributeError:
|
219
|
+
return "default"
|
196
220
|
|
197
|
-
|
198
|
-
|
199
|
-
Field(discriminator="kind", default_factory=QuantumBitvector),
|
200
|
-
]
|
201
|
-
QuantumBitvector.update_forward_refs()
|
221
|
+
|
222
|
+
RegisterQuantumTypeDict = Dict[str, RegisterQuantumType]
|
202
223
|
|
203
224
|
|
204
225
|
def register_info_to_quantum_type(reg_info: RegisterArithmeticInfo) -> QuantumNumeric:
|
@@ -225,3 +246,12 @@ def quantum_var_to_register(name: str, qtype: QuantumType) -> RegisterUserInput:
|
|
225
246
|
is_signed=signed,
|
226
247
|
fraction_places=fraction_places,
|
227
248
|
)
|
249
|
+
|
250
|
+
|
251
|
+
def quantum_type_to_register_quantum_type(
|
252
|
+
qtype: QuantumType, size: int
|
253
|
+
) -> RegisterQuantumType:
|
254
|
+
return RegisterQuantumType(
|
255
|
+
quantum_types=qtype,
|
256
|
+
size=size,
|
257
|
+
)
|
@@ -4,8 +4,8 @@ import pydantic
|
|
4
4
|
|
5
5
|
from classiq.interface.ast_node import ASTNode
|
6
6
|
from classiq.interface.generator.expressions.expression import Expression
|
7
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
7
8
|
from classiq.interface.model.quantum_type import (
|
8
|
-
ConcreteQuantumType,
|
9
9
|
QuantumBitvector,
|
10
10
|
QuantumNumeric,
|
11
11
|
)
|
@@ -8,6 +8,7 @@ from classiq.interface.model.classical_if import ClassicalIf
|
|
8
8
|
from classiq.interface.model.control import Control
|
9
9
|
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
10
10
|
from classiq.interface.model.invert import Invert
|
11
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
11
12
|
from classiq.interface.model.power import Power
|
12
13
|
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
13
14
|
AmplitudeLoadingOperation,
|
@@ -50,3 +51,4 @@ Power.update_forward_refs(StatementBlock=StatementBlock)
|
|
50
51
|
Invert.update_forward_refs(StatementBlock=StatementBlock)
|
51
52
|
WithinApply.update_forward_refs(StatementBlock=StatementBlock)
|
52
53
|
ClassicalIf.update_forward_refs(StatementBlock=StatementBlock)
|
54
|
+
NativeFunctionDefinition.update_forward_refs(StatementBlock=StatementBlock)
|
@@ -2,16 +2,22 @@ import dataclasses
|
|
2
2
|
from enum import Enum
|
3
3
|
from typing import List, Mapping, Optional, Set
|
4
4
|
|
5
|
+
from classiq.interface.exceptions import ClassiqError
|
5
6
|
from classiq.interface.model.handle_binding import HandleBinding
|
6
7
|
|
7
|
-
from classiq.exceptions import ClassiqError
|
8
|
-
|
9
8
|
|
10
9
|
class HandleState(Enum):
|
11
10
|
INITIALIZED = 0
|
12
11
|
UNINITIALIZED = 1
|
13
12
|
ERRORED = 2
|
14
13
|
|
14
|
+
def __invert__(self) -> "HandleState":
|
15
|
+
if self == HandleState.INITIALIZED:
|
16
|
+
return HandleState.UNINITIALIZED
|
17
|
+
if self == HandleState.UNINITIALIZED:
|
18
|
+
return HandleState.INITIALIZED
|
19
|
+
return self
|
20
|
+
|
15
21
|
|
16
22
|
@dataclasses.dataclass
|
17
23
|
class ValidationHandle:
|
@@ -1,13 +1,13 @@
|
|
1
|
-
from datetime import datetime
|
2
|
-
from typing import Any, Dict
|
1
|
+
from datetime import date, datetime
|
2
|
+
from typing import Any, Dict, Union
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
from pydantic import BaseModel
|
6
6
|
|
7
7
|
|
8
8
|
class DeprecationInfo(BaseModel):
|
9
|
-
deprecation_date: datetime = pydantic.Field()
|
10
|
-
removal_date: datetime = pydantic.Field()
|
9
|
+
deprecation_date: Union[datetime, date] = pydantic.Field()
|
10
|
+
removal_date: Union[datetime, date] = pydantic.Field()
|
11
11
|
|
12
12
|
|
13
13
|
class GlobalVersions(BaseModel):
|