classiq 0.93.0__py3-none-any.whl → 0.94.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.
Potentially problematic release.
This version of classiq might be problematic. Click here for more details.
- classiq/__init__.py +6 -19
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
- classiq/_analyzer_extras/interactive_hardware.py +19 -12
- classiq/_internals/api_wrapper.py +38 -52
- classiq/_internals/async_utils.py +4 -7
- classiq/_internals/authentication/auth0.py +3 -3
- classiq/_internals/authentication/device.py +4 -4
- classiq/_internals/authentication/password_manager.py +13 -13
- classiq/_internals/authentication/token_manager.py +4 -5
- classiq/_internals/client.py +17 -44
- classiq/_internals/config.py +1 -2
- classiq/_internals/help.py +1 -2
- classiq/_internals/host_checker.py +3 -3
- classiq/_internals/jobs.py +14 -14
- classiq/_internals/type_validation.py +3 -3
- classiq/analyzer/analyzer.py +18 -18
- classiq/analyzer/rb.py +17 -8
- classiq/applications/chemistry/__init__.py +0 -30
- classiq/applications/chemistry/op_utils.py +4 -4
- classiq/applications/chemistry/problems.py +3 -3
- classiq/applications/chemistry/ucc.py +1 -2
- classiq/applications/chemistry/z2_symmetries.py +4 -4
- classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
- classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
- classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
- classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
- classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
- classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
- classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
- classiq/applications/iqae/iqae.py +8 -8
- classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
- classiq/applications/qnn/datasets/dataset_parity.py +6 -6
- classiq/applications/qnn/qlayer.py +8 -7
- classiq/applications/qnn/torch_utils.py +3 -4
- classiq/applications/qnn/types.py +2 -1
- classiq/applications/qsp/qsp.py +5 -4
- classiq/applications/qsvm/qsvm_data_generation.py +1 -2
- classiq/evaluators/classical_expression.py +0 -4
- classiq/evaluators/parameter_types.py +7 -8
- classiq/evaluators/qmod_annotated_expression.py +24 -26
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
- classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +4 -4
- classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
- classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
- classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
- classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
- classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
- classiq/execution/execution_session.py +18 -19
- classiq/execution/jobs.py +26 -26
- classiq/execution/qnn.py +1 -2
- classiq/execution/user_budgets.py +52 -7
- classiq/executor.py +1 -3
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +4 -4
- classiq/interface/analyzer/cytoscape_graph.py +3 -3
- classiq/interface/analyzer/result.py +4 -4
- classiq/interface/applications/qsvm.py +5 -8
- classiq/interface/ast_node.py +3 -3
- classiq/interface/backend/backend_preferences.py +16 -16
- classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
- classiq/interface/chemistry/ansatz_library.py +3 -5
- classiq/interface/chemistry/operator.py +3 -3
- classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
- classiq/interface/compression_utils.py +2 -3
- classiq/interface/debug_info/debug_info.py +7 -7
- classiq/interface/exceptions.py +2 -3
- classiq/interface/execution/iqcc.py +1 -3
- classiq/interface/execution/primitives.py +6 -6
- classiq/interface/executor/estimate_cost.py +1 -1
- classiq/interface/executor/execution_preferences.py +3 -5
- classiq/interface/executor/execution_request.py +10 -10
- classiq/interface/executor/execution_result.py +1 -2
- classiq/interface/executor/quantum_code.py +8 -8
- classiq/interface/executor/result.py +28 -18
- classiq/interface/executor/user_budget.py +2 -3
- classiq/interface/executor/vqe_result.py +5 -6
- classiq/interface/generator/ansatz_library.py +6 -8
- classiq/interface/generator/application_apis/__init__.py +0 -2
- classiq/interface/generator/arith/arithmetic.py +2 -2
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
- classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
- classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
- classiq/interface/generator/arith/arithmetic_operations.py +4 -6
- classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
- classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
- classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
- classiq/interface/generator/arith/binary_ops.py +7 -36
- classiq/interface/generator/arith/logical_ops.py +2 -3
- classiq/interface/generator/arith/number_utils.py +2 -2
- classiq/interface/generator/arith/register_user_input.py +2 -2
- classiq/interface/generator/arith/unary_ops.py +2 -2
- classiq/interface/generator/circuit_code/circuit_code.py +8 -10
- classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
- classiq/interface/generator/complex_type.py +2 -2
- classiq/interface/generator/copy.py +1 -3
- classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
- classiq/interface/generator/expressions/evaluated_expression.py +2 -3
- classiq/interface/generator/expressions/expression.py +2 -2
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
- classiq/interface/generator/function_param_list.py +0 -20
- classiq/interface/generator/function_params.py +5 -6
- classiq/interface/generator/functions/classical_function_declaration.py +2 -2
- classiq/interface/generator/functions/classical_type.py +3 -3
- classiq/interface/generator/functions/type_modifier.py +0 -14
- classiq/interface/generator/functions/type_name.py +2 -2
- classiq/interface/generator/generated_circuit_data.py +12 -13
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
- classiq/interface/generator/hardware/hardware_data.py +8 -8
- classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
- classiq/interface/generator/mcu.py +3 -3
- classiq/interface/generator/mcx.py +3 -3
- classiq/interface/generator/model/constraints.py +34 -5
- classiq/interface/generator/model/preferences/preferences.py +15 -21
- classiq/interface/generator/model/quantum_register.py +7 -10
- classiq/interface/generator/noise_properties.py +3 -7
- classiq/interface/generator/parameters.py +1 -1
- classiq/interface/generator/partitioned_register.py +1 -2
- classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
- classiq/interface/generator/qsvm.py +2 -2
- classiq/interface/generator/quantum_function_call.py +8 -11
- classiq/interface/generator/quantum_program.py +12 -15
- classiq/interface/generator/range_types.py +3 -3
- classiq/interface/generator/slice_parsing_utils.py +4 -5
- classiq/interface/generator/standard_gates/standard_gates.py +2 -4
- classiq/interface/generator/state_preparation/state_preparation.py +6 -8
- classiq/interface/generator/synthesis_execution_parameter.py +1 -3
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
- classiq/interface/generator/transpiler_basis_gates.py +2 -4
- classiq/interface/generator/types/builtin_enum_declarations.py +0 -136
- classiq/interface/generator/types/compilation_metadata.py +12 -1
- classiq/interface/generator/types/enum_declaration.py +2 -1
- classiq/interface/generator/validations/flow_graph.py +3 -3
- classiq/interface/generator/visitor.py +10 -12
- classiq/interface/hardware.py +2 -2
- classiq/interface/helpers/classproperty.py +2 -2
- classiq/interface/helpers/custom_encoders.py +2 -1
- classiq/interface/helpers/custom_pydantic_types.py +1 -1
- classiq/interface/helpers/text_utils.py +1 -4
- classiq/interface/ide/visual_model.py +5 -5
- classiq/interface/jobs.py +3 -3
- classiq/interface/model/allocate.py +4 -4
- classiq/interface/model/block.py +2 -2
- classiq/interface/model/bounds.py +3 -3
- classiq/interface/model/control.py +1 -1
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/model.py +4 -4
- classiq/interface/model/parameter.py +1 -3
- classiq/interface/model/port_declaration.py +1 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
- classiq/interface/model/quantum_function_call.py +3 -6
- classiq/interface/model/quantum_function_declaration.py +1 -0
- classiq/interface/model/quantum_lambda_function.py +4 -4
- classiq/interface/model/quantum_statement.py +4 -4
- classiq/interface/model/quantum_type.py +14 -14
- classiq/interface/model/validation_handle.py +2 -3
- classiq/interface/model/variable_declaration_statement.py +2 -2
- classiq/interface/pretty_print/expression_to_qmod.py +3 -4
- classiq/interface/server/routes.py +0 -4
- classiq/interface/source_reference.py +3 -4
- classiq/model_expansions/arithmetic.py +6 -7
- classiq/model_expansions/arithmetic_compute_result_attrs.py +4 -5
- classiq/model_expansions/capturing/captured_vars.py +3 -3
- classiq/model_expansions/capturing/mangling_utils.py +1 -2
- classiq/model_expansions/closure.py +12 -11
- classiq/model_expansions/function_builder.py +14 -6
- classiq/model_expansions/generative_functions.py +1 -4
- classiq/model_expansions/interpreters/base_interpreter.py +2 -6
- classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
- classiq/model_expansions/quantum_operations/allocate.py +4 -4
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
- classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
- classiq/model_expansions/quantum_operations/emitter.py +3 -5
- classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
- classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
- classiq/model_expansions/scope.py +7 -7
- classiq/model_expansions/scope_initialization.py +4 -0
- classiq/model_expansions/visitors/symbolic_param_inference.py +3 -3
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +317 -0
- classiq/model_expansions/visitors/variable_references.py +15 -14
- classiq/open_library/functions/__init__.py +6 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
- classiq/open_library/functions/grover.py +8 -10
- classiq/open_library/functions/modular_exponentiation.py +96 -8
- classiq/qmod/__init__.py +5 -2
- classiq/qmod/builtins/classical_execution_primitives.py +4 -11
- classiq/qmod/builtins/classical_functions.py +1 -42
- classiq/qmod/builtins/enums.py +0 -136
- classiq/qmod/builtins/functions/__init__.py +0 -13
- classiq/qmod/builtins/functions/allocation.py +4 -4
- classiq/qmod/builtins/functions/arithmetic.py +22 -27
- classiq/qmod/builtins/functions/standard_gates.py +27 -27
- classiq/qmod/builtins/operations.py +35 -58
- classiq/qmod/builtins/structs.py +2 -58
- classiq/qmod/cfunc.py +3 -2
- classiq/qmod/classical_function.py +2 -1
- classiq/qmod/cparam.py +2 -8
- classiq/qmod/create_model_function.py +7 -7
- classiq/qmod/declaration_inferrer.py +33 -30
- classiq/qmod/model_state_container.py +2 -2
- classiq/qmod/native/pretty_printer.py +25 -14
- classiq/qmod/pretty_print/expression_to_python.py +5 -3
- classiq/qmod/pretty_print/pretty_printer.py +39 -17
- classiq/qmod/python_classical_type.py +40 -13
- classiq/qmod/qfunc.py +139 -16
- classiq/qmod/qmod_constant.py +2 -2
- classiq/qmod/qmod_parameter.py +5 -2
- classiq/qmod/qmod_variable.py +47 -43
- classiq/qmod/quantum_callable.py +18 -13
- classiq/qmod/quantum_expandable.py +31 -26
- classiq/qmod/quantum_function.py +51 -32
- classiq/qmod/semantics/annotation/call_annotation.py +2 -2
- classiq/qmod/semantics/error_manager.py +5 -6
- classiq/qmod/semantics/lambdas.py +1 -2
- classiq/qmod/semantics/validation/types_validation.py +1 -2
- classiq/qmod/symbolic.py +2 -4
- classiq/qmod/utilities.py +13 -10
- classiq/qmod/write_qmod.py +3 -4
- classiq/quantum_program.py +1 -3
- classiq/synthesis.py +11 -7
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/METADATA +2 -3
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/RECORD +238 -260
- classiq/applications/chemistry/ansatz_parameters.py +0 -29
- classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
- classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
- classiq/applications/chemistry/ground_state_problem.py +0 -42
- classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
- classiq/interface/chemistry/elements.py +0 -120
- classiq/interface/chemistry/fermionic_operator.py +0 -208
- classiq/interface/chemistry/ground_state_problem.py +0 -132
- classiq/interface/chemistry/ground_state_result.py +0 -8
- classiq/interface/chemistry/molecule.py +0 -71
- classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
- classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
- classiq/interface/generator/chemistry_function_params.py +0 -50
- classiq/interface/generator/entangler_params.py +0 -72
- classiq/interface/generator/entanglers.py +0 -14
- classiq/interface/generator/hartree_fock.py +0 -26
- classiq/interface/generator/hva.py +0 -22
- classiq/interface/generator/linear_pauli_rotations.py +0 -92
- classiq/interface/generator/qft.py +0 -37
- classiq/interface/generator/ucc.py +0 -74
- classiq/interface/helpers/backward_compatibility.py +0 -9
- classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
- classiq/qmod/builtins/functions/chemistry.py +0 -123
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/WHEEL +0 -0
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from collections.abc import Sized
|
|
2
2
|
from functools import reduce
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
import torch
|
|
6
5
|
import torch.nn as nn
|
|
@@ -52,8 +51,8 @@ def _result_to_tensor(
|
|
|
52
51
|
all_results: list,
|
|
53
52
|
inputs: Tensor,
|
|
54
53
|
weights: Tensor,
|
|
55
|
-
expected_shape:
|
|
56
|
-
requires_grad:
|
|
54
|
+
expected_shape: Shape | None = None,
|
|
55
|
+
requires_grad: bool | None = None,
|
|
57
56
|
) -> Tensor:
|
|
58
57
|
default_shape = (
|
|
59
58
|
torch.Size([inputs.shape[0]])
|
|
@@ -94,7 +93,7 @@ def iter_inputs_weights(
|
|
|
94
93
|
post_process: PostProcessFunction,
|
|
95
94
|
*,
|
|
96
95
|
expected_shape: Shape = (),
|
|
97
|
-
requires_grad:
|
|
96
|
+
requires_grad: bool | None = None,
|
|
98
97
|
) -> Tensor:
|
|
99
98
|
if is_single_layer_circuit(weights):
|
|
100
99
|
iter_weights = torch.reshape(weights, (1, weights.shape[0]))
|
classiq/applications/qsp/qsp.py
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import builtins
|
|
2
2
|
import importlib.util
|
|
3
|
+
from collections.abc import Callable
|
|
3
4
|
from functools import wraps
|
|
4
|
-
from typing import Callable, Optional
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
|
-
from matplotlib import pyplot as plt
|
|
8
7
|
from numpy.polynomial import Chebyshev, Polynomial
|
|
9
8
|
from numpy.polynomial.chebyshev import cheb2poly, poly2cheb
|
|
10
9
|
|
|
@@ -122,6 +121,8 @@ def _plot_qsp_approx(
|
|
|
122
121
|
f_target: Callable[[np.ndarray], np.ndarray],
|
|
123
122
|
interval: tuple[float, float] = (-1, 1),
|
|
124
123
|
) -> None:
|
|
124
|
+
from matplotlib import pyplot as plt
|
|
125
|
+
|
|
125
126
|
grid_full = np.linspace(-1, 1, 3000)
|
|
126
127
|
grid_interval = np.linspace(interval[0], interval[1], 3000)
|
|
127
128
|
|
|
@@ -154,10 +155,10 @@ def _plot_qsp_approx(
|
|
|
154
155
|
def qsp_approximate(
|
|
155
156
|
f_target: Callable[[np.ndarray], np.ndarray],
|
|
156
157
|
degree: int,
|
|
157
|
-
parity:
|
|
158
|
+
parity: int | None = None,
|
|
158
159
|
interval: tuple[float, float] = (-1, 1),
|
|
159
160
|
bound: float = 0.99,
|
|
160
|
-
num_grid_points:
|
|
161
|
+
num_grid_points: int | None = None,
|
|
161
162
|
plot: bool = False,
|
|
162
163
|
) -> tuple[np.ndarray, float]:
|
|
163
164
|
"""
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections import defaultdict
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
4
|
import numpy as np
|
|
6
5
|
|
|
@@ -14,7 +13,7 @@ def generate_data(
|
|
|
14
13
|
range_min: float = 0,
|
|
15
14
|
range_max: float = 2 * np.pi,
|
|
16
15
|
std: float = 0.5,
|
|
17
|
-
sources:
|
|
16
|
+
sources: np.ndarray | None = None,
|
|
18
17
|
) -> dict[int, np.ndarray]:
|
|
19
18
|
if sources is None:
|
|
20
19
|
sources = np.random.uniform(
|
|
@@ -17,9 +17,6 @@ from classiq.interface.generator.expressions.proxies.classical.utils import (
|
|
|
17
17
|
from classiq.interface.generator.functions.classical_type import ClassicalArray, Integer
|
|
18
18
|
|
|
19
19
|
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
20
|
-
from classiq.evaluators.qmod_expression_visitors.qmod_expression_bwc import (
|
|
21
|
-
QmodExpressionBwc,
|
|
22
|
-
)
|
|
23
20
|
from classiq.evaluators.qmod_expression_visitors.qmod_expression_evaluator import (
|
|
24
21
|
evaluate_qmod_expression,
|
|
25
22
|
)
|
|
@@ -59,7 +56,6 @@ def evaluate_classical_expression(expr: Expression, scope: Scope) -> Evaluated:
|
|
|
59
56
|
if expr.is_evaluated():
|
|
60
57
|
return Evaluated(value=expr.value.value)
|
|
61
58
|
expr_ast = ast.parse(expr.expr)
|
|
62
|
-
expr_ast = QmodExpressionBwc().visit(expr_ast)
|
|
63
59
|
expr_val = evaluate_qmod_expression(
|
|
64
60
|
ast.unparse(expr_ast),
|
|
65
61
|
classical_struct_declarations=list(QMODULE.type_decls.values()),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, Any, NoReturn,
|
|
1
|
+
from typing import TYPE_CHECKING, Any, NoReturn, TypeVar, Union
|
|
2
2
|
|
|
3
3
|
import sympy
|
|
4
4
|
|
|
@@ -25,7 +25,6 @@ from classiq.interface.generator.functions.port_declaration import (
|
|
|
25
25
|
from classiq.interface.generator.functions.type_name import (
|
|
26
26
|
TypeName,
|
|
27
27
|
)
|
|
28
|
-
from classiq.interface.helpers.backward_compatibility import zip_strict
|
|
29
28
|
from classiq.interface.model.classical_parameter_declaration import (
|
|
30
29
|
ClassicalParameterDeclaration,
|
|
31
30
|
)
|
|
@@ -80,7 +79,7 @@ def evaluate_parameter_types_from_args(
|
|
|
80
79
|
f"{len(arguments)} were given"
|
|
81
80
|
)
|
|
82
81
|
|
|
83
|
-
for parameter, argument in
|
|
82
|
+
for parameter, argument in zip(parameters, arguments, strict=True):
|
|
84
83
|
if isinstance(parameter, ClassicalParameterDeclaration):
|
|
85
84
|
arg_val = argument.value
|
|
86
85
|
if not isinstance(arg_val, QmodAnnotatedExpression):
|
|
@@ -88,11 +87,11 @@ def evaluate_parameter_types_from_args(
|
|
|
88
87
|
|
|
89
88
|
evaluated_params = [
|
|
90
89
|
_evaluate_type_from_arg(parameter, argument, closure)
|
|
91
|
-
for parameter, argument in
|
|
90
|
+
for parameter, argument in zip(parameters, arguments, strict=True)
|
|
92
91
|
]
|
|
93
92
|
|
|
94
93
|
parameter_names = {parameter.name for parameter in parameters}
|
|
95
|
-
for parameter, argument in
|
|
94
|
+
for parameter, argument in zip(parameters, arguments, strict=True):
|
|
96
95
|
if isinstance(parameter, QuantumOperandDeclaration):
|
|
97
96
|
_update_operand_signature_environment(
|
|
98
97
|
argument.value, parameter_names, closure
|
|
@@ -271,9 +270,9 @@ def _evaluate_op_type_from_arg(
|
|
|
271
270
|
|
|
272
271
|
def _raise_argument_type_error(
|
|
273
272
|
arg_val: Any,
|
|
274
|
-
arg_type:
|
|
273
|
+
arg_type: QmodType | AnonQuantumOperandDeclaration,
|
|
275
274
|
param_name: str,
|
|
276
|
-
param_type:
|
|
275
|
+
param_type: QmodType | AnonQuantumOperandDeclaration,
|
|
277
276
|
) -> NoReturn:
|
|
278
277
|
raise ClassiqExpansionError(
|
|
279
278
|
f"Argument {str(arg_val)!r} of type "
|
|
@@ -378,7 +377,7 @@ def _eval_expr(
|
|
|
378
377
|
if expected_type is int and isinstance(val, float) and int(val) == val:
|
|
379
378
|
val = int(val)
|
|
380
379
|
|
|
381
|
-
failing_type:
|
|
380
|
+
failing_type: str | None = None
|
|
382
381
|
if isinstance(val, QmodAnnotatedExpression):
|
|
383
382
|
val_type = val.get_type(val.root)
|
|
384
383
|
if not isinstance(val_type, expected_qmod_type):
|
|
@@ -2,7 +2,7 @@ import ast
|
|
|
2
2
|
from collections.abc import Mapping, Sequence
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from enum import Enum
|
|
5
|
-
from typing import Any,
|
|
5
|
+
from typing import Any, cast
|
|
6
6
|
|
|
7
7
|
import sympy
|
|
8
8
|
|
|
@@ -98,26 +98,24 @@ class QmodAnnotatedExpression:
|
|
|
98
98
|
def get_node(self, node_id: QmodExprNodeId) -> ast.AST:
|
|
99
99
|
return self._node_mapping[node_id]
|
|
100
100
|
|
|
101
|
-
def set_value(self, node:
|
|
101
|
+
def set_value(self, node: ast.AST | QmodExprNodeId, value: Any) -> None:
|
|
102
102
|
if self._locked:
|
|
103
103
|
raise ClassiqInternalExpansionError("QAE is locked")
|
|
104
104
|
if isinstance(node, ast.AST):
|
|
105
105
|
node = id(node)
|
|
106
106
|
self._values[node] = value
|
|
107
107
|
|
|
108
|
-
def get_value(self, node:
|
|
108
|
+
def get_value(self, node: ast.AST | QmodExprNodeId) -> Any:
|
|
109
109
|
if isinstance(node, ast.AST):
|
|
110
110
|
node = id(node)
|
|
111
111
|
return self._values[node]
|
|
112
112
|
|
|
113
|
-
def has_value(self, node:
|
|
113
|
+
def has_value(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
114
114
|
if isinstance(node, ast.AST):
|
|
115
115
|
node = id(node)
|
|
116
116
|
return node in self._values
|
|
117
117
|
|
|
118
|
-
def set_type(
|
|
119
|
-
self, node: Union[ast.AST, QmodExprNodeId], qmod_type: QmodType
|
|
120
|
-
) -> None:
|
|
118
|
+
def set_type(self, node: ast.AST | QmodExprNodeId, qmod_type: QmodType) -> None:
|
|
121
119
|
if self._locked:
|
|
122
120
|
raise ClassiqInternalExpansionError("QAE is locked")
|
|
123
121
|
if isinstance(node, ast.AST):
|
|
@@ -126,12 +124,12 @@ class QmodAnnotatedExpression:
|
|
|
126
124
|
node = id(node)
|
|
127
125
|
self._types[node] = qmod_type
|
|
128
126
|
|
|
129
|
-
def get_type(self, node:
|
|
127
|
+
def get_type(self, node: ast.AST | QmodExprNodeId) -> QmodType:
|
|
130
128
|
if isinstance(node, ast.AST):
|
|
131
129
|
node = id(node)
|
|
132
130
|
return self._types[node]
|
|
133
131
|
|
|
134
|
-
def get_quantum_type(self, node:
|
|
132
|
+
def get_quantum_type(self, node: ast.AST | QmodExprNodeId) -> QuantumType:
|
|
135
133
|
if isinstance(node, ast.AST):
|
|
136
134
|
node = id(node)
|
|
137
135
|
qmod_type = self._types[node]
|
|
@@ -139,7 +137,7 @@ class QmodAnnotatedExpression:
|
|
|
139
137
|
raise ClassiqInternalExpansionError
|
|
140
138
|
return cast(QuantumType, qmod_type)
|
|
141
139
|
|
|
142
|
-
def get_classical_type(self, node:
|
|
140
|
+
def get_classical_type(self, node: ast.AST | QmodExprNodeId) -> ClassicalType:
|
|
143
141
|
if isinstance(node, ast.AST):
|
|
144
142
|
node = id(node)
|
|
145
143
|
qmod_type = self._types[node]
|
|
@@ -147,7 +145,7 @@ class QmodAnnotatedExpression:
|
|
|
147
145
|
raise ClassiqInternalExpansionError
|
|
148
146
|
return cast(ClassicalType, qmod_type)
|
|
149
147
|
|
|
150
|
-
def set_var(self, node:
|
|
148
|
+
def set_var(self, node: ast.AST | QmodExprNodeId, var: HandleBinding) -> None:
|
|
151
149
|
if self._locked:
|
|
152
150
|
raise ClassiqInternalExpansionError("QAE is locked")
|
|
153
151
|
var = var.collapse()
|
|
@@ -158,25 +156,25 @@ class QmodAnnotatedExpression:
|
|
|
158
156
|
else:
|
|
159
157
|
self._quantum_vars[node] = var
|
|
160
158
|
|
|
161
|
-
def get_var(self, node:
|
|
159
|
+
def get_var(self, node: ast.AST | QmodExprNodeId) -> HandleBinding:
|
|
162
160
|
if isinstance(node, ast.AST):
|
|
163
161
|
node = id(node)
|
|
164
162
|
return (self._classical_vars | self._quantum_vars)[node]
|
|
165
163
|
|
|
166
|
-
def has_var(self, node:
|
|
164
|
+
def has_var(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
167
165
|
return self.has_classical_var(node) or self.has_quantum_var(node)
|
|
168
166
|
|
|
169
|
-
def has_classical_var(self, node:
|
|
167
|
+
def has_classical_var(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
170
168
|
if isinstance(node, ast.AST):
|
|
171
169
|
node = id(node)
|
|
172
170
|
return node in self._classical_vars
|
|
173
171
|
|
|
174
|
-
def has_quantum_var(self, node:
|
|
172
|
+
def has_quantum_var(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
175
173
|
if isinstance(node, ast.AST):
|
|
176
174
|
node = id(node)
|
|
177
175
|
return node in self._quantum_vars
|
|
178
176
|
|
|
179
|
-
def remove_var(self, node:
|
|
177
|
+
def remove_var(self, node: ast.AST | QmodExprNodeId) -> None:
|
|
180
178
|
if self._locked:
|
|
181
179
|
raise ClassiqInternalExpansionError("QAE is locked")
|
|
182
180
|
if isinstance(node, ast.AST):
|
|
@@ -188,9 +186,9 @@ class QmodAnnotatedExpression:
|
|
|
188
186
|
|
|
189
187
|
def set_quantum_subscript(
|
|
190
188
|
self,
|
|
191
|
-
node:
|
|
192
|
-
value:
|
|
193
|
-
index:
|
|
189
|
+
node: ast.AST | QmodExprNodeId,
|
|
190
|
+
value: ast.AST | QmodExprNodeId,
|
|
191
|
+
index: ast.AST | QmodExprNodeId,
|
|
194
192
|
) -> None:
|
|
195
193
|
if self._locked:
|
|
196
194
|
raise ClassiqInternalExpansionError("QAE is locked")
|
|
@@ -204,7 +202,7 @@ class QmodAnnotatedExpression:
|
|
|
204
202
|
value=value, index=index
|
|
205
203
|
)
|
|
206
204
|
|
|
207
|
-
def has_quantum_subscript(self, node:
|
|
205
|
+
def has_quantum_subscript(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
208
206
|
if isinstance(node, ast.AST):
|
|
209
207
|
node = id(node)
|
|
210
208
|
return node in self._quantum_subscripts
|
|
@@ -216,7 +214,7 @@ class QmodAnnotatedExpression:
|
|
|
216
214
|
|
|
217
215
|
def set_quantum_type_attr(
|
|
218
216
|
self,
|
|
219
|
-
node:
|
|
217
|
+
node: ast.AST | QmodExprNodeId,
|
|
220
218
|
value: HandleBinding,
|
|
221
219
|
attr: str,
|
|
222
220
|
) -> None:
|
|
@@ -228,7 +226,7 @@ class QmodAnnotatedExpression:
|
|
|
228
226
|
value=value, attr=attr
|
|
229
227
|
)
|
|
230
228
|
|
|
231
|
-
def has_quantum_type_attribute(self, node:
|
|
229
|
+
def has_quantum_type_attribute(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
232
230
|
if isinstance(node, ast.AST):
|
|
233
231
|
node = id(node)
|
|
234
232
|
return node in self._quantum_type_attrs
|
|
@@ -240,8 +238,8 @@ class QmodAnnotatedExpression:
|
|
|
240
238
|
|
|
241
239
|
def set_concatenation(
|
|
242
240
|
self,
|
|
243
|
-
node:
|
|
244
|
-
elements: Sequence[
|
|
241
|
+
node: ast.AST | QmodExprNodeId,
|
|
242
|
+
elements: Sequence[ast.AST | QmodExprNodeId],
|
|
245
243
|
) -> None:
|
|
246
244
|
if self._locked:
|
|
247
245
|
raise ClassiqInternalExpansionError("QAE is locked")
|
|
@@ -257,7 +255,7 @@ class QmodAnnotatedExpression:
|
|
|
257
255
|
inlined_elements.extend(self._concatenations.pop(element).elements)
|
|
258
256
|
self._concatenations[node] = ConcatenationAnnotation(elements=inlined_elements)
|
|
259
257
|
|
|
260
|
-
def has_concatenation(self, node:
|
|
258
|
+
def has_concatenation(self, node: ast.AST | QmodExprNodeId) -> bool:
|
|
261
259
|
if isinstance(node, ast.AST):
|
|
262
260
|
node = id(node)
|
|
263
261
|
return node in self._concatenations
|
|
@@ -271,7 +269,7 @@ class QmodAnnotatedExpression:
|
|
|
271
269
|
def get_quantum_vars(self) -> Mapping[QmodExprNodeId, HandleBinding]:
|
|
272
270
|
return self._quantum_vars
|
|
273
271
|
|
|
274
|
-
def clear_node_data(self, node:
|
|
272
|
+
def clear_node_data(self, node: ast.AST | QmodExprNodeId) -> None:
|
|
275
273
|
if isinstance(node, ast.AST):
|
|
276
274
|
node = id(node)
|
|
277
275
|
self._node_mapping.pop(node, None)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ast
|
|
2
|
-
from collections.abc import Mapping, Sequence
|
|
2
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
3
3
|
from enum import IntEnum
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, cast
|
|
5
5
|
|
|
6
6
|
from classiq.interface.exceptions import (
|
|
7
7
|
ClassiqExpansionError,
|
|
@@ -79,13 +79,13 @@ class QmodExpressionEvaluator(ast.NodeVisitor):
|
|
|
79
79
|
*,
|
|
80
80
|
treat_qnum_as_float: bool = False,
|
|
81
81
|
machine_precision: int = DEFAULT_MACHINE_PRECISION,
|
|
82
|
-
classical_struct_declarations:
|
|
83
|
-
enum_declarations:
|
|
84
|
-
classical_function_declarations:
|
|
82
|
+
classical_struct_declarations: Sequence[StructDeclaration] | None = None,
|
|
83
|
+
enum_declarations: Sequence[EnumDeclaration] | None = None,
|
|
84
|
+
classical_function_declarations: None | (
|
|
85
85
|
Sequence[ClassicalFunctionDeclaration]
|
|
86
|
-
|
|
87
|
-
classical_function_callables:
|
|
88
|
-
scope:
|
|
86
|
+
) = None,
|
|
87
|
+
classical_function_callables: Mapping[str, Callable] | None = None,
|
|
88
|
+
scope: Mapping[str, Any] | None = None,
|
|
89
89
|
) -> None:
|
|
90
90
|
self._expr_val = expr_val
|
|
91
91
|
self._treat_qnum_as_float = treat_qnum_as_float
|
|
@@ -258,13 +258,13 @@ def evaluate_qmod_expression(
|
|
|
258
258
|
*,
|
|
259
259
|
treat_qnum_as_float: bool = False,
|
|
260
260
|
machine_precision: int = DEFAULT_MACHINE_PRECISION,
|
|
261
|
-
classical_struct_declarations:
|
|
262
|
-
enum_declarations:
|
|
263
|
-
classical_function_declarations:
|
|
261
|
+
classical_struct_declarations: Sequence[StructDeclaration] | None = None,
|
|
262
|
+
enum_declarations: Sequence[EnumDeclaration] | None = None,
|
|
263
|
+
classical_function_declarations: None | (
|
|
264
264
|
Sequence[ClassicalFunctionDeclaration]
|
|
265
|
-
|
|
266
|
-
classical_function_callables:
|
|
267
|
-
scope:
|
|
265
|
+
) = None,
|
|
266
|
+
classical_function_callables: Mapping[str, Callable] | None = None,
|
|
267
|
+
scope: Mapping[str, Any] | None = None,
|
|
268
268
|
) -> QmodAnnotatedExpression:
|
|
269
269
|
expr_ast = ast.parse(expr, mode="eval").body
|
|
270
270
|
expr_value = QmodAnnotatedExpression(expr_ast)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
from sympy import Function, Integer
|
|
4
4
|
from sympy.logic.boolalg import BooleanFunction
|
|
@@ -6,7 +6,7 @@ from sympy.logic.boolalg import BooleanFunction
|
|
|
6
6
|
|
|
7
7
|
class BitwiseAnd(Function):
|
|
8
8
|
@classmethod
|
|
9
|
-
def eval(cls, a: Any, b: Any) ->
|
|
9
|
+
def eval(cls, a: Any, b: Any) -> int | None:
|
|
10
10
|
if isinstance(a, Integer) and isinstance(b, Integer):
|
|
11
11
|
return a & b
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ class BitwiseAnd(Function):
|
|
|
15
15
|
|
|
16
16
|
class BitwiseXor(Function):
|
|
17
17
|
@classmethod
|
|
18
|
-
def eval(cls, a: Any, b: Any) ->
|
|
18
|
+
def eval(cls, a: Any, b: Any) -> int | None:
|
|
19
19
|
if isinstance(a, Integer) and isinstance(b, Integer):
|
|
20
20
|
return a ^ b
|
|
21
21
|
|
|
@@ -24,7 +24,7 @@ class BitwiseXor(Function):
|
|
|
24
24
|
|
|
25
25
|
class LogicalXor(BooleanFunction):
|
|
26
26
|
@classmethod
|
|
27
|
-
def eval(cls, a: Any, b: Any) ->
|
|
27
|
+
def eval(cls, a: Any, b: Any) -> bool | None:
|
|
28
28
|
if isinstance(a, bool) and isinstance(b, bool):
|
|
29
29
|
return a ^ b
|
|
30
30
|
|
|
@@ -33,7 +33,7 @@ class LogicalXor(BooleanFunction):
|
|
|
33
33
|
|
|
34
34
|
class BitwiseOr(Function):
|
|
35
35
|
@classmethod
|
|
36
|
-
def eval(cls, a: Any, b: Any) ->
|
|
36
|
+
def eval(cls, a: Any, b: Any) -> int | None:
|
|
37
37
|
if isinstance(a, Integer) and isinstance(b, Integer):
|
|
38
38
|
return a | b
|
|
39
39
|
|
|
@@ -42,7 +42,7 @@ class BitwiseOr(Function):
|
|
|
42
42
|
|
|
43
43
|
class BitwiseNot(Function):
|
|
44
44
|
@classmethod
|
|
45
|
-
def eval(cls, a: Any) ->
|
|
45
|
+
def eval(cls, a: Any) -> int | None:
|
|
46
46
|
if isinstance(a, Integer):
|
|
47
47
|
return ~a
|
|
48
48
|
|
|
@@ -51,7 +51,7 @@ class BitwiseNot(Function):
|
|
|
51
51
|
|
|
52
52
|
class RShift(Function):
|
|
53
53
|
@classmethod
|
|
54
|
-
def eval(cls, a: Any, b: Any) ->
|
|
54
|
+
def eval(cls, a: Any, b: Any) -> int | None:
|
|
55
55
|
if isinstance(a, Integer) and isinstance(b, Integer):
|
|
56
56
|
return a >> b
|
|
57
57
|
|
|
@@ -60,7 +60,7 @@ class RShift(Function):
|
|
|
60
60
|
|
|
61
61
|
class LShift(Function):
|
|
62
62
|
@classmethod
|
|
63
|
-
def eval(cls, a: Any, b: Any) ->
|
|
63
|
+
def eval(cls, a: Any, b: Any) -> int | None:
|
|
64
64
|
if isinstance(a, Integer) and isinstance(b, Integer):
|
|
65
65
|
return a << b
|
|
66
66
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ast
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import cast
|
|
3
4
|
|
|
4
5
|
import sympy
|
|
5
6
|
|
|
@@ -19,7 +20,6 @@ from classiq.interface.generator.functions.classical_type import (
|
|
|
19
20
|
Real,
|
|
20
21
|
)
|
|
21
22
|
from classiq.interface.generator.functions.type_name import TypeName
|
|
22
|
-
from classiq.interface.helpers.backward_compatibility import zip_strict
|
|
23
23
|
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
|
24
24
|
|
|
25
25
|
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
@@ -39,7 +39,7 @@ INTEGER_FUNCTION_OVERRIDE = {"floor", "ceiling"}
|
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _check_classical_array_arg_type(
|
|
42
|
-
param_type:
|
|
42
|
+
param_type: ClassicalArray | ClassicalTuple, arg_type: ClassicalType
|
|
43
43
|
) -> bool:
|
|
44
44
|
if not isinstance(arg_type, (ClassicalArray, ClassicalTuple)):
|
|
45
45
|
return False
|
|
@@ -63,7 +63,7 @@ def _check_classical_array_arg_type(
|
|
|
63
63
|
)
|
|
64
64
|
return all(
|
|
65
65
|
check_classical_arg_type(param_element_type, arg_element_type)
|
|
66
|
-
for param_element_type, arg_element_type in
|
|
66
|
+
for param_element_type, arg_element_type in zip(
|
|
67
67
|
param_type.element_types, arg_type.element_types, strict=True
|
|
68
68
|
)
|
|
69
69
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import cast
|
|
3
3
|
|
|
4
4
|
from classiq.interface.exceptions import (
|
|
5
5
|
ClassiqExpansionError,
|
|
@@ -57,7 +57,7 @@ def list_allowed(classical_types: list[ClassicalType]) -> bool:
|
|
|
57
57
|
if len(classical_types) < 2:
|
|
58
58
|
return True
|
|
59
59
|
|
|
60
|
-
element_without_empty_tuple:
|
|
60
|
+
element_without_empty_tuple: ClassicalType | None = None
|
|
61
61
|
for classical_type in classical_types:
|
|
62
62
|
if not _has_empty_tuple(classical_type):
|
|
63
63
|
element_without_empty_tuple = classical_type
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
import sympy
|
|
5
5
|
|
|
@@ -22,7 +22,7 @@ def get_numeric_attrs(
|
|
|
22
22
|
qmod_type: QmodType,
|
|
23
23
|
machine_precision: int,
|
|
24
24
|
treat_qnum_as_float: bool,
|
|
25
|
-
) ->
|
|
25
|
+
) -> NumericAttributes | None:
|
|
26
26
|
if isinstance(qmod_type, Bool):
|
|
27
27
|
return NumericAttributes.from_bounds(0, 1, 0, machine_precision)
|
|
28
28
|
if is_classical_type(qmod_type):
|
|
@@ -45,7 +45,7 @@ def get_classical_value_for_arithmetic(
|
|
|
45
45
|
node: ast.AST,
|
|
46
46
|
qmod_type: QmodType,
|
|
47
47
|
treat_qnum_as_float: bool,
|
|
48
|
-
) ->
|
|
48
|
+
) -> float | None:
|
|
49
49
|
if not is_classical_type(qmod_type):
|
|
50
50
|
return None
|
|
51
51
|
if not expr_val.has_value(node):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import cast
|
|
3
3
|
|
|
4
4
|
from classiq.interface.exceptions import (
|
|
5
5
|
ClassiqExpansionError,
|
|
@@ -53,12 +53,12 @@ def _eval_slice(expr_val: QmodAnnotatedExpression, node: ast.Subscript) -> None:
|
|
|
53
53
|
f"Slice indices must be integers, not {index_type.raw_qmod_type_name}"
|
|
54
54
|
)
|
|
55
55
|
|
|
56
|
-
start_val:
|
|
56
|
+
start_val: int | None = None
|
|
57
57
|
if expr_val.has_value(start):
|
|
58
58
|
start_val = cast(int, expr_val.get_value(start))
|
|
59
59
|
if start_val < 0:
|
|
60
60
|
raise ClassiqExpansionError("Slice indices must be positive integers")
|
|
61
|
-
stop_val:
|
|
61
|
+
stop_val: int | None = None
|
|
62
62
|
if expr_val.has_value(stop):
|
|
63
63
|
stop_val = cast(int, expr_val.get_value(stop))
|
|
64
64
|
if start_val is not None and stop_val < start_val:
|
|
@@ -74,7 +74,7 @@ def _eval_slice(expr_val: QmodAnnotatedExpression, node: ast.Subscript) -> None:
|
|
|
74
74
|
or (stop_val is not None and stop_val > subject_type.length_value)
|
|
75
75
|
):
|
|
76
76
|
raise ClassiqExpansionError("Array index out of range")
|
|
77
|
-
length_expr:
|
|
77
|
+
length_expr: Expression | None = None
|
|
78
78
|
if start_val is not None and stop_val is not None:
|
|
79
79
|
length_expr = Expression(expr=str(stop_val - start_val))
|
|
80
80
|
slice_type = ClassicalArray(
|
|
@@ -139,7 +139,7 @@ def _eval_subscript(expr_val: QmodAnnotatedExpression, node: ast.Subscript) -> N
|
|
|
139
139
|
f"{index_type.raw_qmod_type_name}"
|
|
140
140
|
)
|
|
141
141
|
|
|
142
|
-
sub_val:
|
|
142
|
+
sub_val: int | None = None
|
|
143
143
|
if expr_val.has_value(subscript):
|
|
144
144
|
sub_val = cast(int, expr_val.get_value(subscript))
|
|
145
145
|
if sub_val < 0:
|
|
@@ -195,10 +195,10 @@ def eval_subscript(expr_val: QmodAnnotatedExpression, node: ast.Subscript) -> No
|
|
|
195
195
|
|
|
196
196
|
|
|
197
197
|
def validate_quantum_subscript_index_properties(
|
|
198
|
-
index_size:
|
|
199
|
-
index_sign:
|
|
200
|
-
index_fraction_digits:
|
|
201
|
-
array_len:
|
|
198
|
+
index_size: int | None,
|
|
199
|
+
index_sign: bool | None,
|
|
200
|
+
index_fraction_digits: int | None,
|
|
201
|
+
array_len: int | None,
|
|
202
202
|
) -> None:
|
|
203
203
|
if index_sign or (index_fraction_digits is not None and index_fraction_digits > 0):
|
|
204
204
|
raise ClassiqValueError("Quantum index must be an unsigned integer")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Union, cast
|
|
2
2
|
|
|
3
3
|
import sympy
|
|
4
4
|
|
|
@@ -42,7 +42,7 @@ def qnum_is_qbit(qmod_type: QuantumNumeric) -> bool:
|
|
|
42
42
|
|
|
43
43
|
def get_numeric_properties(
|
|
44
44
|
qmod_type: QuantumScalar,
|
|
45
|
-
) -> tuple[
|
|
45
|
+
) -> tuple[int | None, bool | None, int | None]:
|
|
46
46
|
if isinstance(qmod_type, QuantumBit):
|
|
47
47
|
return 1, False, 0
|
|
48
48
|
if not isinstance(qmod_type, QuantumNumeric):
|
|
@@ -66,7 +66,7 @@ def get_numeric_properties(
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def element_types(
|
|
69
|
-
classical_type:
|
|
69
|
+
classical_type: ClassicalArray | ClassicalTuple,
|
|
70
70
|
) -> list[ClassicalType]:
|
|
71
71
|
if isinstance(classical_type, ClassicalArray):
|
|
72
72
|
return [classical_type.element_type]
|
|
@@ -74,8 +74,8 @@ def element_types(
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
def array_len(
|
|
77
|
-
classical_type:
|
|
78
|
-
) ->
|
|
77
|
+
classical_type: ClassicalArray | ClassicalTuple,
|
|
78
|
+
) -> int | None:
|
|
79
79
|
if isinstance(classical_type, ClassicalTuple):
|
|
80
80
|
return len(classical_type.element_types)
|
|
81
81
|
if classical_type.has_constant_length:
|
|
@@ -95,7 +95,7 @@ def is_classical_integer(qmod_type: QmodType) -> bool:
|
|
|
95
95
|
)
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
def get_sympy_val(val: sympy.Basic) ->
|
|
98
|
+
def get_sympy_val(val: sympy.Basic) -> bool | int | float | complex:
|
|
99
99
|
if hasattr(val, "is_Boolean") and val.is_Boolean:
|
|
100
100
|
return bool(val)
|
|
101
101
|
if (hasattr(val, "is_integer") and val.is_integer) or (
|