classiq 0.43.3__py3-none-any.whl → 0.45.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +8 -3
- classiq/_internals/api_wrapper.py +2 -2
- classiq/_internals/authentication/auth0.py +1 -1
- classiq/_internals/authentication/device.py +5 -1
- classiq/_internals/authentication/token_manager.py +5 -4
- classiq/_internals/client.py +5 -8
- classiq/_internals/config.py +1 -2
- classiq/_internals/host_checker.py +34 -13
- classiq/_internals/jobs.py +3 -3
- classiq/analyzer/analyzer.py +1 -1
- classiq/analyzer/analyzer_utilities.py +1 -1
- classiq/analyzer/rb.py +1 -1
- classiq/applications/chemistry/chemistry_model_constructor.py +13 -7
- classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +1 -1
- classiq/applications/combinatorial_helpers/encoding_mapping.py +1 -1
- classiq/applications/combinatorial_helpers/encoding_utils.py +2 -1
- classiq/applications/combinatorial_helpers/optimization_model.py +1 -1
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +1 -1
- classiq/applications/combinatorial_helpers/pyomo_utils.py +1 -2
- classiq/applications/combinatorial_helpers/transformations/encoding.py +1 -1
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -4
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +1 -1
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -1
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
- classiq/applications/finance/finance_model_constructor.py +4 -3
- classiq/applications/grover/grover_model_constructor.py +7 -5
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/qnn/circuit_utils.py +1 -1
- classiq/applications/qnn/datasets/dataset_base_classes.py +2 -1
- classiq/applications/qnn/datasets/dataset_not.py +2 -1
- classiq/applications/qnn/qlayer.py +3 -2
- classiq/applications/qnn/torch_utils.py +2 -1
- classiq/applications/qsvm/qsvm_model_constructor.py +1 -1
- classiq/execution/execution_session.py +1 -1
- classiq/execution/jobs.py +5 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/cytoscape_graph.py +1 -2
- classiq/interface/analyzer/result.py +2 -3
- classiq/interface/ast_node.py +1 -18
- classiq/interface/backend/backend_preferences.py +11 -18
- classiq/interface/backend/ionq/ionq_quantum_program.py +1 -1
- classiq/interface/backend/pydantic_backend.py +0 -5
- classiq/interface/backend/quantum_backend_providers.py +4 -3
- classiq/interface/chemistry/fermionic_operator.py +1 -2
- classiq/interface/chemistry/ground_state_problem.py +2 -3
- classiq/interface/chemistry/molecule.py +1 -2
- classiq/interface/chemistry/operator.py +8 -10
- classiq/interface/combinatorial_optimization/encoding_types.py +1 -1
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +1 -1
- classiq/interface/combinatorial_optimization/solver_types.py +1 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +32 -0
- classiq/{exceptions.py → interface/exceptions.py} +4 -0
- classiq/interface/executor/aws_execution_cost.py +2 -2
- classiq/interface/executor/execution_preferences.py +2 -47
- classiq/interface/executor/execution_result.py +1 -2
- classiq/interface/executor/optimizer_preferences.py +2 -3
- classiq/interface/executor/quantum_code.py +1 -2
- classiq/interface/executor/quantum_instruction_set.py +2 -2
- classiq/interface/executor/register_initialization.py +1 -2
- classiq/interface/executor/result.py +29 -14
- classiq/interface/finance/function_input.py +6 -11
- classiq/interface/generator/amplitude_loading.py +2 -3
- classiq/interface/generator/ansatz_library.py +1 -1
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- classiq/interface/generator/application_apis/chemistry_declarations.py +78 -60
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +19 -10
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +37 -44
- classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
- classiq/interface/generator/arith/arithmetic.py +10 -8
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +1 -2
- classiq/interface/generator/arith/arithmetic_expression_abc.py +22 -3
- classiq/interface/generator/arith/arithmetic_expression_parser.py +3 -4
- classiq/interface/generator/arith/arithmetic_expression_validator.py +1 -2
- classiq/interface/generator/arith/arithmetic_param_getters.py +1 -2
- classiq/interface/generator/arith/arithmetic_result_builder.py +15 -11
- classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
- classiq/interface/generator/arith/binary_ops.py +7 -7
- classiq/interface/generator/arith/endianness.py +1 -1
- classiq/interface/generator/arith/extremum_operations.py +44 -21
- classiq/interface/generator/arith/logical_ops.py +1 -2
- classiq/interface/generator/arith/register_user_input.py +1 -2
- classiq/interface/generator/arith/unary_ops.py +1 -2
- classiq/interface/generator/arith/uncomputation_methods.py +1 -1
- classiq/interface/generator/chemistry_function_params.py +1 -2
- classiq/interface/generator/circuit_code/circuit_code.py +1 -2
- classiq/interface/generator/circuit_code/types_and_constants.py +1 -2
- classiq/interface/generator/commuting_pauli_exponentiation.py +1 -2
- classiq/interface/generator/constant.py +1 -1
- classiq/interface/generator/control_state.py +1 -2
- classiq/interface/generator/custom_ansatz.py +1 -2
- classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
- classiq/interface/generator/expressions/enums/finance_functions.py +4 -5
- classiq/interface/generator/expressions/evaluated_expression.py +1 -2
- classiq/interface/generator/expressions/expression.py +1 -2
- classiq/interface/generator/expressions/expression_constants.py +3 -1
- classiq/interface/generator/expressions/non_symbolic_expr.py +1 -1
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +53 -70
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -7
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +1 -1
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/function_params.py +2 -3
- classiq/interface/generator/functions/builtins/core_library/__init__.py +4 -2
- classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +41 -41
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +52 -42
- classiq/interface/generator/functions/builtins/open_lib_functions.py +1095 -3347
- classiq/interface/generator/functions/builtins/quantum_operators.py +9 -22
- classiq/interface/generator/functions/classical_function_declaration.py +14 -6
- classiq/interface/generator/functions/classical_type.py +7 -114
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +10 -10
- classiq/interface/generator/functions/port_declaration.py +1 -2
- classiq/interface/generator/functions/type_name.py +80 -0
- classiq/interface/generator/generated_circuit_data.py +3 -3
- classiq/interface/generator/grover_diffuser.py +1 -2
- classiq/interface/generator/grover_operator.py +1 -2
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +1 -2
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +1 -2
- classiq/interface/generator/hardware/hardware_data.py +1 -2
- classiq/interface/generator/hardware_efficient_ansatz.py +2 -3
- classiq/interface/generator/hartree_fock.py +1 -2
- classiq/interface/generator/linear_pauli_rotations.py +1 -2
- classiq/interface/generator/mcmt_method.py +1 -1
- classiq/interface/generator/mcu.py +1 -2
- classiq/interface/generator/mcx.py +1 -2
- classiq/interface/generator/model/constraints.py +2 -3
- classiq/interface/generator/model/model.py +12 -2
- classiq/interface/generator/model/preferences/preferences.py +7 -3
- classiq/interface/generator/model/quantum_register.py +1 -2
- classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
- classiq/interface/generator/oracles/custom_oracle.py +1 -2
- classiq/interface/generator/oracles/oracle_abc.py +1 -2
- classiq/interface/generator/partitioned_register.py +1 -2
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +1 -2
- classiq/interface/generator/preferences/optimization.py +1 -2
- classiq/interface/generator/qpe.py +1 -2
- classiq/interface/generator/qsvm.py +2 -3
- classiq/interface/generator/quantum_function_call.py +4 -2
- classiq/interface/generator/quantum_program.py +6 -7
- classiq/interface/generator/range_types.py +1 -1
- classiq/interface/generator/register_role.py +8 -2
- classiq/interface/generator/slice_parsing_utils.py +1 -2
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +1 -2
- classiq/interface/generator/state_preparation/metrics.py +2 -3
- classiq/interface/generator/state_preparation/state_preparation.py +1 -2
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
- classiq/interface/generator/transpiler_basis_gates.py +1 -1
- classiq/interface/generator/types/builtin_enum_declarations.py +38 -45
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
- classiq/interface/generator/types/enum_declaration.py +1 -2
- classiq/interface/generator/types/qstruct_declaration.py +17 -0
- classiq/interface/generator/types/struct_declaration.py +2 -3
- classiq/interface/generator/ucc.py +1 -2
- classiq/interface/generator/unitary_gate.py +1 -2
- classiq/interface/generator/validations/flow_graph.py +1 -2
- classiq/interface/generator/validations/validator_functions.py +1 -2
- classiq/interface/hardware.py +1 -1
- classiq/interface/helpers/validation_helpers.py +2 -19
- classiq/interface/ide/visual_model.py +10 -4
- classiq/interface/interface_version.py +1 -0
- classiq/interface/jobs.py +2 -3
- classiq/interface/model/bind_operation.py +26 -7
- classiq/interface/model/classical_parameter_declaration.py +8 -5
- classiq/interface/model/control.py +5 -5
- classiq/interface/model/handle_binding.py +185 -12
- classiq/interface/model/inplace_binary_operation.py +17 -6
- classiq/interface/model/model.py +29 -7
- classiq/interface/model/native_function_definition.py +8 -4
- classiq/interface/model/parameter.py +13 -0
- classiq/interface/model/port_declaration.py +21 -4
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +22 -8
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +30 -6
- classiq/interface/model/quantum_expressions/quantum_expression.py +4 -9
- classiq/interface/model/quantum_function_call.py +136 -194
- classiq/interface/model/quantum_function_declaration.py +147 -165
- classiq/interface/model/quantum_lambda_function.py +23 -6
- classiq/interface/model/quantum_statement.py +34 -8
- classiq/interface/model/quantum_type.py +41 -11
- classiq/interface/model/quantum_variable_declaration.py +1 -1
- classiq/interface/model/statement_block.py +2 -0
- classiq/interface/model/validation_handle.py +8 -2
- classiq/interface/server/global_versions.py +4 -4
- classiq/interface/server/routes.py +2 -0
- classiq/interface/source_reference.py +59 -0
- classiq/qmod/__init__.py +2 -3
- classiq/qmod/builtins/classical_execution_primitives.py +1 -1
- classiq/qmod/builtins/functions.py +39 -11
- classiq/qmod/builtins/operations.py +172 -41
- classiq/qmod/classical_function.py +1 -1
- classiq/qmod/declaration_inferrer.py +102 -57
- classiq/qmod/expression_query.py +1 -1
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/pretty_printer.py +71 -53
- classiq/qmod/pretty_print/pretty_printer.py +98 -52
- classiq/qmod/qfunc.py +11 -5
- classiq/qmod/qmod_constant.py +1 -1
- classiq/qmod/qmod_parameter.py +27 -4
- classiq/qmod/qmod_variable.py +405 -174
- classiq/qmod/quantum_callable.py +3 -3
- classiq/qmod/quantum_expandable.py +128 -68
- classiq/qmod/quantum_function.py +24 -5
- classiq/qmod/semantics/annotation.py +13 -15
- classiq/qmod/semantics/error_manager.py +36 -10
- classiq/qmod/semantics/static_semantics_visitor.py +164 -76
- classiq/qmod/semantics/validation/func_call_validation.py +43 -97
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/types_validation.py +108 -1
- classiq/qmod/symbolic.py +2 -1
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +26 -5
- classiq/{interface/ide/show.py → show.py} +1 -1
- {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/METADATA +3 -3
- {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/RECORD +219 -207
- classiq/qmod/qmod_struct.py +0 -13
- /classiq/{_internals → interface}/enum_utils.py +0 -0
- {classiq-0.43.3.dist-info → classiq-0.45.0.dist-info}/WHEEL +0 -0
@@ -1,23 +1,22 @@
|
|
1
|
-
from typing import Dict, Literal, Mapping,
|
1
|
+
from typing import Dict, Literal, Mapping, Sequence
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
|
+
from classiq.interface.exceptions import ClassiqValueError
|
5
6
|
from classiq.interface.generator.amplitude_loading import (
|
6
7
|
AMPLITUDE_IO_NAME,
|
7
8
|
TARGET_OUTPUT_NAME,
|
8
9
|
)
|
9
10
|
from classiq.interface.model.handle_binding import (
|
11
|
+
ConcreteHandleBinding,
|
10
12
|
HandleBinding,
|
11
|
-
SlicedHandleBinding,
|
12
|
-
SubscriptHandleBinding,
|
13
13
|
)
|
14
14
|
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
15
15
|
QuantumAssignmentOperation,
|
16
16
|
)
|
17
|
+
from classiq.interface.model.quantum_statement import HandleMetadata
|
17
18
|
from classiq.interface.model.quantum_type import QuantumBit, QuantumNumeric, QuantumType
|
18
19
|
|
19
|
-
from classiq.exceptions import ClassiqValueError
|
20
|
-
|
21
20
|
MULTI_VARS_UNSUPPORTED_ERROR = (
|
22
21
|
"Amplitude Loading with more than one input variable is unsupported."
|
23
22
|
)
|
@@ -33,14 +32,29 @@ class AmplitudeLoadingOperation(QuantumAssignmentOperation):
|
|
33
32
|
@property
|
34
33
|
def wiring_inouts(
|
35
34
|
self,
|
36
|
-
) -> Mapping[
|
37
|
-
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
38
|
-
]:
|
35
|
+
) -> Mapping[str, ConcreteHandleBinding]:
|
39
36
|
inouts = {self.result_name(): self.result_var}
|
40
37
|
if len(self.var_handles) == 1:
|
41
38
|
inouts[AMPLITUDE_IO_NAME] = self.var_handles[0]
|
42
39
|
return inouts
|
43
40
|
|
41
|
+
@property
|
42
|
+
def readable_inouts(self) -> Sequence[HandleMetadata]:
|
43
|
+
inouts = [
|
44
|
+
HandleMetadata(
|
45
|
+
handle=self.result_var,
|
46
|
+
readable_location="on the left-hand side of an in-place assignment",
|
47
|
+
)
|
48
|
+
]
|
49
|
+
if len(self.var_handles) == 1:
|
50
|
+
inouts.append(
|
51
|
+
HandleMetadata(
|
52
|
+
handle=self.var_handles[0],
|
53
|
+
readable_location="in an expression",
|
54
|
+
)
|
55
|
+
)
|
56
|
+
return inouts
|
57
|
+
|
44
58
|
@property
|
45
59
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
46
60
|
return {}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Dict, Literal, Mapping,
|
1
|
+
from typing import Dict, Literal, Mapping, Sequence
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
@@ -7,13 +7,13 @@ from classiq.interface.generator.arith.arithmetic import (
|
|
7
7
|
compute_arithmetic_result_type,
|
8
8
|
)
|
9
9
|
from classiq.interface.model.handle_binding import (
|
10
|
+
ConcreteHandleBinding,
|
10
11
|
HandleBinding,
|
11
|
-
SlicedHandleBinding,
|
12
|
-
SubscriptHandleBinding,
|
13
12
|
)
|
14
13
|
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
15
14
|
QuantumAssignmentOperation,
|
16
15
|
)
|
16
|
+
from classiq.interface.model.quantum_statement import HandleMetadata
|
17
17
|
from classiq.interface.model.quantum_type import QuantumType
|
18
18
|
|
19
19
|
|
@@ -37,20 +37,44 @@ class ArithmeticOperation(QuantumAssignmentOperation):
|
|
37
37
|
@property
|
38
38
|
def wiring_inouts(
|
39
39
|
self,
|
40
|
-
) -> Mapping[
|
41
|
-
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
42
|
-
]:
|
40
|
+
) -> Mapping[str, ConcreteHandleBinding]:
|
43
41
|
inouts = dict(super().wiring_inouts)
|
44
42
|
if self.inplace_result:
|
45
43
|
inouts[self.result_name()] = self.result_var
|
46
44
|
return inouts
|
47
45
|
|
46
|
+
@property
|
47
|
+
def readable_inouts(self) -> Sequence[HandleMetadata]:
|
48
|
+
inouts = [
|
49
|
+
HandleMetadata(handle=handle, readable_location="in an expression")
|
50
|
+
for handle in self.var_handles
|
51
|
+
]
|
52
|
+
if self.inplace_result:
|
53
|
+
inouts.append(
|
54
|
+
HandleMetadata(
|
55
|
+
handle=self.result_var,
|
56
|
+
readable_location="on the left-hand side of an in-place assignment",
|
57
|
+
)
|
58
|
+
)
|
59
|
+
return inouts
|
60
|
+
|
48
61
|
@property
|
49
62
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
50
63
|
if self.inplace_result:
|
51
64
|
return {}
|
52
65
|
return super().wiring_outputs
|
53
66
|
|
67
|
+
@property
|
68
|
+
def readable_outputs(self) -> Sequence[HandleMetadata]:
|
69
|
+
if self.inplace_result:
|
70
|
+
return []
|
71
|
+
return [
|
72
|
+
HandleMetadata(
|
73
|
+
handle=self.result_var,
|
74
|
+
readable_location="on the left-hand side of an assignment",
|
75
|
+
)
|
76
|
+
]
|
77
|
+
|
54
78
|
@classmethod
|
55
79
|
def result_name(cls) -> str:
|
56
80
|
return ARITHMETIC_EXPRESSION_RESULT_NAME
|
@@ -1,14 +1,13 @@
|
|
1
1
|
import abc
|
2
|
-
from typing import Dict, List, Mapping, Optional
|
2
|
+
from typing import Dict, List, Mapping, Optional
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
6
6
|
from classiq.interface.generator.expressions.expression import Expression
|
7
7
|
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
8
8
|
from classiq.interface.model.handle_binding import (
|
9
|
+
ConcreteHandleBinding,
|
9
10
|
HandleBinding,
|
10
|
-
SlicedHandleBinding,
|
11
|
-
SubscriptHandleBinding,
|
12
11
|
)
|
13
12
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
14
13
|
from classiq.interface.model.quantum_type import QuantumType
|
@@ -43,16 +42,12 @@ class QuantumExpressionOperation(QuantumOperation):
|
|
43
42
|
self._var_types = var_types
|
44
43
|
|
45
44
|
@property
|
46
|
-
def wiring_inouts(
|
47
|
-
self,
|
48
|
-
) -> Mapping[
|
49
|
-
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
50
|
-
]:
|
45
|
+
def wiring_inouts(self) -> Mapping[str, ConcreteHandleBinding]:
|
51
46
|
return nameables_to_dict(self.var_handles)
|
52
47
|
|
53
48
|
|
54
49
|
class QuantumAssignmentOperation(QuantumExpressionOperation):
|
55
|
-
result_var:
|
50
|
+
result_var: ConcreteHandleBinding = pydantic.Field(
|
56
51
|
description="The variable storing the expression result"
|
57
52
|
)
|
58
53
|
_result_type: Optional[QuantumType] = pydantic.PrivateAttr(
|
@@ -1,104 +1,39 @@
|
|
1
|
-
import
|
2
|
-
|
1
|
+
from typing import (
|
2
|
+
Dict,
|
3
|
+
Iterable,
|
4
|
+
List,
|
5
|
+
Literal,
|
6
|
+
Mapping,
|
7
|
+
Optional,
|
8
|
+
Sequence,
|
9
|
+
Tuple,
|
10
|
+
Union,
|
11
|
+
)
|
12
|
+
from uuid import UUID, uuid4
|
3
13
|
|
4
14
|
import pydantic
|
5
15
|
|
6
16
|
from classiq.interface.ast_node import ASTNode
|
17
|
+
from classiq.interface.exceptions import ClassiqError, ClassiqValueError
|
7
18
|
from classiq.interface.generator.expressions.expression import Expression
|
8
|
-
from classiq.interface.generator.functions.function_declaration import (
|
9
|
-
FunctionDeclaration,
|
10
|
-
)
|
11
19
|
from classiq.interface.generator.functions.port_declaration import (
|
12
20
|
PortDeclarationDirection,
|
13
21
|
)
|
14
22
|
from classiq.interface.model.handle_binding import (
|
23
|
+
ConcreteHandleBinding,
|
15
24
|
HandleBinding,
|
16
|
-
SlicedHandleBinding,
|
17
|
-
SubscriptHandleBinding,
|
18
25
|
)
|
26
|
+
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
19
27
|
from classiq.interface.model.quantum_function_declaration import (
|
20
28
|
QuantumFunctionDeclaration,
|
21
29
|
)
|
22
|
-
from classiq.interface.model.quantum_lambda_function import
|
23
|
-
|
24
|
-
)
|
25
|
-
from classiq.interface.model.quantum_statement import QuantumOperation
|
26
|
-
from classiq.interface.model.validation_handle import get_unique_handle_names
|
27
|
-
|
28
|
-
from classiq.exceptions import ClassiqError, ClassiqValueError
|
29
|
-
|
30
|
-
|
31
|
-
def _validate_no_duplicated_ports(
|
32
|
-
inputs: Mapping[str, HandleBinding],
|
33
|
-
outputs: Mapping[str, HandleBinding],
|
34
|
-
inouts: Mapping[str, HandleBinding],
|
35
|
-
) -> None:
|
36
|
-
inputs_and_inouts = inputs.keys() & inouts.keys()
|
37
|
-
if inputs_and_inouts:
|
38
|
-
raise ClassiqValueError(
|
39
|
-
f"{inputs_and_inouts} are used as ports in both inputs and inouts"
|
40
|
-
)
|
41
|
-
|
42
|
-
outputs_and_inouts = outputs.keys() & inouts.keys()
|
43
|
-
if outputs_and_inouts:
|
44
|
-
raise ClassiqValueError(
|
45
|
-
f"{outputs_and_inouts} are used as ports in both outputs and inouts"
|
46
|
-
)
|
47
|
-
|
48
|
-
|
49
|
-
def _validate_no_duplicated_handles(
|
50
|
-
inputs: Mapping[str, HandleBinding],
|
51
|
-
outputs: Mapping[str, HandleBinding],
|
52
|
-
inouts: Mapping[str, HandleBinding],
|
53
|
-
) -> None:
|
54
|
-
inputs_and_inouts = get_unique_handle_names(inputs) & get_unique_handle_names(
|
55
|
-
inouts
|
56
|
-
)
|
57
|
-
if inputs_and_inouts:
|
58
|
-
raise ClassiqValueError(
|
59
|
-
f"{inputs_and_inouts} are used as handles in both inputs and inouts"
|
60
|
-
)
|
61
|
-
|
62
|
-
outputs_and_inouts = get_unique_handle_names(outputs) & get_unique_handle_names(
|
63
|
-
inouts
|
64
|
-
)
|
65
|
-
if outputs_and_inouts:
|
66
|
-
raise ClassiqValueError(
|
67
|
-
f"{outputs_and_inouts} are used as handles in both outputs and inouts"
|
68
|
-
)
|
69
|
-
|
70
|
-
|
71
|
-
def _validate_no_mixing_sliced_and_whole_handles(
|
72
|
-
inouts: Mapping[str, HandleBinding],
|
73
|
-
) -> None:
|
74
|
-
def _treat_subscript_as_slice(type_: Type[HandleBinding]) -> Type[HandleBinding]:
|
75
|
-
if type_ == SubscriptHandleBinding:
|
76
|
-
return SlicedHandleBinding
|
77
|
-
return type_
|
78
|
-
|
79
|
-
inout_handle_names_to_types = {
|
80
|
-
handle_name: {_treat_subscript_as_slice(type(handle)) for handle in handles}
|
81
|
-
for handle_name, handles in itertools.groupby(
|
82
|
-
inouts.values(), lambda handle: handle.name
|
83
|
-
)
|
84
|
-
}
|
85
|
-
invalid_handles = [
|
86
|
-
handle
|
87
|
-
for handle, types in inout_handle_names_to_types.items()
|
88
|
-
if len(types) > 1
|
89
|
-
]
|
90
|
-
if invalid_handles:
|
91
|
-
raise ClassiqValueError(
|
92
|
-
f"Inout handles {', '.join(invalid_handles)} mix sliced and whole handles"
|
93
|
-
)
|
94
|
-
|
30
|
+
from classiq.interface.model.quantum_lambda_function import QuantumOperand
|
31
|
+
from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
|
95
32
|
|
96
33
|
ArgValue = Union[
|
97
34
|
Expression,
|
98
35
|
QuantumOperand,
|
99
|
-
|
100
|
-
SubscriptHandleBinding,
|
101
|
-
HandleBinding,
|
36
|
+
ConcreteHandleBinding,
|
102
37
|
]
|
103
38
|
|
104
39
|
|
@@ -113,26 +48,10 @@ class QuantumFunctionCall(QuantumOperation):
|
|
113
48
|
function: Union[str, OperandIdentifier] = pydantic.Field(
|
114
49
|
description="The function that is called"
|
115
50
|
)
|
116
|
-
designated_params: Dict[str, Expression] = pydantic.Field(default_factory=dict)
|
117
|
-
designated_inputs: Dict[str, HandleBinding] = pydantic.Field(
|
118
|
-
default_factory=dict,
|
119
|
-
description="A mapping from the input name to the wire it connects to",
|
120
|
-
)
|
121
|
-
designated_inouts: Dict[
|
122
|
-
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
123
|
-
] = pydantic.Field(
|
124
|
-
default_factory=dict,
|
125
|
-
description="A mapping from in/out name to the wires that connect to it",
|
126
|
-
)
|
127
|
-
designated_outputs: Dict[str, HandleBinding] = pydantic.Field(
|
128
|
-
default_factory=dict,
|
129
|
-
description="A mapping from the output name to the wire it connects to",
|
130
|
-
)
|
131
|
-
designated_operands: Dict[str, QuantumOperand] = pydantic.Field(
|
132
|
-
description="Function calls passed to the operator",
|
133
|
-
default_factory=dict,
|
134
|
-
)
|
135
51
|
positional_args: List[ArgValue] = pydantic.Field(default_factory=list)
|
52
|
+
uuid: UUID = pydantic.Field(
|
53
|
+
description="A unique identifier for this call", default_factory=uuid4
|
54
|
+
)
|
136
55
|
|
137
56
|
_func_decl: Optional[QuantumFunctionDeclaration] = pydantic.PrivateAttr(
|
138
57
|
default=None
|
@@ -145,7 +64,7 @@ class QuantumFunctionCall(QuantumOperation):
|
|
145
64
|
|
146
65
|
return self._func_decl
|
147
66
|
|
148
|
-
def set_func_decl(self, fd: Optional[
|
67
|
+
def set_func_decl(self, fd: Optional[QuantumFunctionDeclaration]) -> None:
|
149
68
|
if fd is not None and not isinstance(fd, QuantumFunctionDeclaration):
|
150
69
|
raise ClassiqValueError(
|
151
70
|
"the declaration of a quantum function call cannot be set to a non-quantum function declaration."
|
@@ -160,76 +79,113 @@ class QuantumFunctionCall(QuantumOperation):
|
|
160
79
|
|
161
80
|
@property
|
162
81
|
def wiring_inputs(self) -> Mapping[str, HandleBinding]:
|
163
|
-
return self.
|
82
|
+
return self._get_pos_port_args_by_direction(PortDeclarationDirection.Input)
|
83
|
+
|
84
|
+
@property
|
85
|
+
def inputs(self) -> Sequence[HandleBinding]:
|
86
|
+
return [
|
87
|
+
handle
|
88
|
+
for _, _, handle in self._get_handles_by_direction(
|
89
|
+
PortDeclarationDirection.Input
|
90
|
+
)
|
91
|
+
]
|
92
|
+
|
93
|
+
@property
|
94
|
+
def readable_inputs(self) -> Sequence[HandleMetadata]:
|
95
|
+
return [
|
96
|
+
HandleMetadata(
|
97
|
+
handle=handle,
|
98
|
+
readable_location=self._get_readable_location(param_idx, param),
|
99
|
+
)
|
100
|
+
for param_idx, param, handle in self._get_handles_by_direction(
|
101
|
+
PortDeclarationDirection.Input
|
102
|
+
)
|
103
|
+
]
|
164
104
|
|
165
105
|
@property
|
166
106
|
def wiring_inouts(
|
167
107
|
self,
|
168
|
-
) -> Mapping[
|
169
|
-
|
170
|
-
|
171
|
-
|
108
|
+
) -> Mapping[str, ConcreteHandleBinding]:
|
109
|
+
return self._get_pos_port_args_by_direction(PortDeclarationDirection.Inout)
|
110
|
+
|
111
|
+
@property
|
112
|
+
def inouts(self) -> Sequence[HandleBinding]:
|
113
|
+
return [
|
114
|
+
handle
|
115
|
+
for _, _, handle in self._get_handles_by_direction(
|
116
|
+
PortDeclarationDirection.Inout
|
117
|
+
)
|
118
|
+
]
|
119
|
+
|
120
|
+
@property
|
121
|
+
def readable_inouts(self) -> Sequence[HandleMetadata]:
|
122
|
+
return [
|
123
|
+
HandleMetadata(
|
124
|
+
handle=handle,
|
125
|
+
readable_location=self._get_readable_location(param_idx, param),
|
126
|
+
)
|
127
|
+
for param_idx, param, handle in self._get_handles_by_direction(
|
128
|
+
PortDeclarationDirection.Inout
|
129
|
+
)
|
130
|
+
]
|
172
131
|
|
173
132
|
@property
|
174
133
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
175
|
-
return self.
|
134
|
+
return self._get_pos_port_args_by_direction(PortDeclarationDirection.Output)
|
176
135
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
return result
|
136
|
+
@property
|
137
|
+
def outputs(self) -> Sequence[HandleBinding]:
|
138
|
+
return [
|
139
|
+
handle
|
140
|
+
for _, _, handle in self._get_handles_by_direction(
|
141
|
+
PortDeclarationDirection.Output
|
142
|
+
)
|
143
|
+
]
|
186
144
|
|
187
145
|
@property
|
188
|
-
def
|
189
|
-
return
|
190
|
-
|
191
|
-
|
192
|
-
(
|
193
|
-
param
|
194
|
-
for param in self.positional_args
|
195
|
-
if isinstance(param, Expression)
|
196
|
-
),
|
146
|
+
def readable_outputs(self) -> Sequence[HandleMetadata]:
|
147
|
+
return [
|
148
|
+
HandleMetadata(
|
149
|
+
handle=handle,
|
150
|
+
readable_location=self._get_readable_location(param_idx, param),
|
197
151
|
)
|
198
|
-
|
152
|
+
for param_idx, param, handle in self._get_handles_by_direction(
|
153
|
+
PortDeclarationDirection.Output
|
154
|
+
)
|
155
|
+
]
|
199
156
|
|
200
157
|
@property
|
201
|
-
def params(self) ->
|
202
|
-
return
|
158
|
+
def params(self) -> List[Expression]:
|
159
|
+
return [
|
160
|
+
param for param in self.positional_args if isinstance(param, Expression)
|
161
|
+
]
|
203
162
|
|
204
163
|
@property
|
205
|
-
def
|
206
|
-
return dict(
|
207
|
-
zip(
|
208
|
-
self.func_decl.operand_declarations.keys(),
|
209
|
-
(
|
210
|
-
param
|
211
|
-
for param in self.positional_args
|
212
|
-
if not isinstance(param, (Expression, HandleBinding))
|
213
|
-
),
|
214
|
-
)
|
215
|
-
)
|
164
|
+
def params_dict(self) -> Dict[str, Expression]:
|
165
|
+
return dict(zip(self.func_decl.param_names, self.params))
|
216
166
|
|
217
167
|
@property
|
218
|
-
def operands(self) ->
|
219
|
-
return
|
168
|
+
def operands(self) -> List["QuantumOperand"]:
|
169
|
+
return [
|
170
|
+
param
|
171
|
+
for param in self.positional_args
|
172
|
+
if not isinstance(param, (Expression, HandleBinding))
|
173
|
+
]
|
220
174
|
|
221
175
|
@property
|
222
|
-
def
|
223
|
-
return
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
)
|
232
|
-
|
176
|
+
def ports(self) -> List[HandleBinding]:
|
177
|
+
return [
|
178
|
+
param for param in self.positional_args if isinstance(param, HandleBinding)
|
179
|
+
]
|
180
|
+
|
181
|
+
def _get_handles_by_direction(
|
182
|
+
self, direction: PortDeclarationDirection
|
183
|
+
) -> List[Tuple[int, AnonPortDeclaration, HandleBinding]]:
|
184
|
+
return [
|
185
|
+
(idx, port_decl, handle)
|
186
|
+
for idx, port_decl, handle in self._get_handles_with_declarations()
|
187
|
+
if direction == port_decl.direction
|
188
|
+
]
|
233
189
|
|
234
190
|
def _get_pos_port_args_by_direction(
|
235
191
|
self, direction: PortDeclarationDirection
|
@@ -240,49 +196,35 @@ class QuantumFunctionCall(QuantumOperation):
|
|
240
196
|
if self._func_decl is None:
|
241
197
|
return dict()
|
242
198
|
return {
|
243
|
-
port_decl.
|
244
|
-
for port_decl,
|
245
|
-
self.func_decl.port_declarations.values(),
|
246
|
-
(
|
247
|
-
param
|
248
|
-
for param in self.positional_args
|
249
|
-
if isinstance(param, HandleBinding)
|
250
|
-
),
|
251
|
-
)
|
199
|
+
port_decl.get_name(): handle
|
200
|
+
for _, port_decl, handle in self._get_handles_with_declarations()
|
252
201
|
if direction == port_decl.direction
|
253
202
|
}
|
254
203
|
|
255
|
-
|
256
|
-
def inputs(self) -> Dict[str, HandleBinding]:
|
257
|
-
return (
|
258
|
-
self._get_pos_port_args_by_direction(PortDeclarationDirection.Input)
|
259
|
-
or self.designated_inputs
|
260
|
-
)
|
261
|
-
|
262
|
-
@property
|
263
|
-
def inouts(
|
204
|
+
def _get_handles_with_declarations(
|
264
205
|
self,
|
265
|
-
) ->
|
266
|
-
return
|
267
|
-
|
268
|
-
|
269
|
-
|
206
|
+
) -> Iterable[Tuple[int, AnonPortDeclaration, HandleBinding]]:
|
207
|
+
return [
|
208
|
+
(idx, port, handle)
|
209
|
+
for idx, (port, handle) in enumerate(
|
210
|
+
zip(
|
211
|
+
(port_decl for port_decl in self.func_decl.port_declarations),
|
212
|
+
(
|
213
|
+
param
|
214
|
+
for param in self.positional_args
|
215
|
+
if isinstance(param, HandleBinding)
|
216
|
+
),
|
217
|
+
)
|
218
|
+
)
|
219
|
+
]
|
270
220
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
221
|
+
def _get_readable_location(
|
222
|
+
self, param_index: int, param_decl: AnonPortDeclaration
|
223
|
+
) -> str:
|
224
|
+
param_name = (
|
225
|
+
repr(param_decl.name) if param_decl.name is not None else f"#{param_index}"
|
276
226
|
)
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
outputs = values.get("designated_outputs", dict())
|
282
|
-
inouts = values.get("designated_inouts", dict())
|
283
|
-
|
284
|
-
_validate_no_duplicated_ports(inputs, outputs, inouts)
|
285
|
-
_validate_no_duplicated_handles(inputs, outputs, inouts)
|
286
|
-
_validate_no_mixing_sliced_and_whole_handles(inouts)
|
287
|
-
|
288
|
-
return values
|
227
|
+
param_text = (
|
228
|
+
f" for parameter {param_name}" if len(self.positional_args) > 1 else ""
|
229
|
+
)
|
230
|
+
return f"as an argument{param_text} of function {self.func_name!r}"
|