classiq 0.53.0__py3-none-any.whl → 0.54.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 +1 -3
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/__init__.py +0 -20
- classiq/_internals/api_wrapper.py +8 -8
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +5 -5
- classiq/_internals/authentication/device.py +5 -4
- classiq/_internals/authentication/password_manager.py +3 -3
- classiq/_internals/authentication/token_manager.py +3 -2
- classiq/_internals/client.py +10 -12
- classiq/_internals/config.py +2 -2
- classiq/_internals/jobs.py +7 -6
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +8 -7
- classiq/analyzer/analyzer_utilities.py +8 -8
- classiq/analyzer/rb.py +11 -11
- classiq/applications/__init__.py +1 -3
- classiq/applications/chemistry/__init__.py +1 -3
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/applications/chemistry/chemistry_model_constructor.py +10 -9
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +26 -9
- classiq/applications/combinatorial_helpers/encoding_mapping.py +10 -10
- classiq/applications/combinatorial_helpers/encoding_utils.py +4 -4
- classiq/applications/combinatorial_helpers/memory.py +5 -7
- classiq/applications/combinatorial_helpers/optimization_model.py +43 -24
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +4 -6
- classiq/applications/combinatorial_helpers/pyomo_utils.py +95 -24
- classiq/applications/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/applications/combinatorial_helpers/transformations/encoding.py +8 -8
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -5
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +7 -9
- classiq/applications/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -2
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +1 -2
- classiq/applications/combinatorial_optimization/__init__.py +1 -3
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +1 -3
- classiq/applications/grover/__init__.py +1 -3
- classiq/applications/grover/grover_model_constructor.py +7 -9
- classiq/applications/hamiltonian/pauli_decomposition.py +6 -6
- classiq/applications/qnn/__init__.py +1 -3
- classiq/applications/qnn/circuit_utils.py +5 -5
- classiq/applications/qnn/datasets/__init__.py +1 -3
- classiq/applications/qnn/datasets/dataset_base_classes.py +5 -4
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +3 -3
- classiq/applications/qnn/torch_utils.py +2 -2
- classiq/applications/qnn/types.py +5 -5
- classiq/applications/qsvm/qsvm.py +1 -3
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- classiq/applications/qsvm/qsvm_model_constructor.py +5 -5
- classiq/execution/__init__.py +1 -3
- classiq/execution/all_hardware_devices.py +1 -3
- classiq/execution/execution_session.py +16 -16
- classiq/execution/jobs.py +4 -4
- classiq/execution/qaoa.py +3 -3
- classiq/execution/qnn.py +3 -3
- classiq/executor.py +3 -3
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +9 -10
- classiq/interface/analyzer/cytoscape_graph.py +5 -5
- classiq/interface/analyzer/result.py +17 -17
- classiq/interface/applications/qsvm.py +6 -10
- classiq/interface/backend/backend_preferences.py +4 -3
- classiq/interface/backend/ionq/ionq_quantum_program.py +4 -5
- classiq/interface/backend/pydantic_backend.py +1 -2
- classiq/interface/chemistry/fermionic_operator.py +5 -5
- classiq/interface/chemistry/ground_state_problem.py +7 -8
- classiq/interface/chemistry/molecule.py +4 -4
- classiq/interface/chemistry/operator.py +11 -13
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mht.py +2 -3
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +5 -7
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/debug_info/debug_info.py +8 -7
- classiq/interface/exceptions.py +8 -6
- classiq/interface/execution/jobs.py +2 -2
- classiq/interface/execution/primitives.py +3 -3
- classiq/interface/executor/aws_execution_cost.py +4 -4
- classiq/interface/executor/execution_request.py +2 -3
- classiq/interface/executor/execution_result.py +3 -3
- classiq/interface/executor/iqae_result.py +3 -5
- classiq/interface/executor/optimizer_preferences.py +2 -2
- classiq/interface/executor/quantum_code.py +6 -6
- classiq/interface/executor/register_initialization.py +2 -4
- classiq/interface/executor/result.py +23 -27
- classiq/interface/executor/vqe_result.py +8 -8
- classiq/interface/finance/function_input.py +2 -2
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +2 -2
- classiq/interface/finance/model_input.py +1 -2
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/ansatz_library.py +4 -4
- classiq/interface/generator/application_apis/finance_declarations.py +1 -1
- classiq/interface/generator/arith/argument_utils.py +3 -3
- classiq/interface/generator/arith/arithmetic.py +7 -7
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +5 -5
- classiq/interface/generator/arith/arithmetic_expression_abc.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
- classiq/interface/generator/arith/arithmetic_expression_validator.py +8 -8
- classiq/interface/generator/arith/arithmetic_operations.py +4 -3
- classiq/interface/generator/arith/arithmetic_param_getters.py +6 -6
- classiq/interface/generator/arith/arithmetic_result_builder.py +9 -9
- classiq/interface/generator/arith/ast_node_rewrite.py +2 -1
- classiq/interface/generator/arith/binary_ops.py +10 -13
- classiq/interface/generator/arith/extremum_operations.py +3 -2
- classiq/interface/generator/arith/logical_ops.py +7 -6
- classiq/interface/generator/arith/number_utils.py +4 -4
- classiq/interface/generator/arith/register_user_input.py +4 -4
- classiq/interface/generator/arith/unary_ops.py +2 -1
- classiq/interface/generator/builtin_api_builder.py +2 -1
- classiq/interface/generator/circuit_code/circuit_code.py +4 -4
- classiq/interface/generator/circuit_code/types_and_constants.py +3 -5
- classiq/interface/generator/complex_type.py +1 -2
- classiq/interface/generator/control_state.py +2 -2
- classiq/interface/generator/custom_ansatz.py +1 -3
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/enums/finance_functions.py +1 -3
- classiq/interface/generator/expressions/evaluated_expression.py +4 -3
- classiq/interface/generator/expressions/expression.py +4 -5
- classiq/interface/generator/expressions/expression_constants.py +4 -4
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_struct_instance.py +2 -1
- classiq/interface/generator/expressions/sympy_supported_expressions.py +11 -13
- classiq/interface/generator/finance.py +2 -2
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_params.py +13 -19
- classiq/interface/generator/functions/classical_function_declaration.py +4 -3
- classiq/interface/generator/functions/classical_type.py +13 -13
- classiq/interface/generator/functions/concrete_types.py +1 -2
- classiq/interface/generator/functions/function_declaration.py +1 -1
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +3 -2
- classiq/interface/generator/generated_circuit_data.py +34 -22
- classiq/interface/generator/grover_diffuser.py +7 -7
- classiq/interface/generator/grover_operator.py +2 -2
- classiq/interface/generator/hardware/hardware_data.py +7 -6
- classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
- classiq/interface/generator/identity.py +5 -6
- classiq/interface/generator/linear_pauli_rotations.py +6 -6
- classiq/interface/generator/mcu.py +2 -2
- classiq/interface/generator/mcx.py +6 -6
- classiq/interface/generator/model/__init__.py +1 -3
- classiq/interface/generator/model/constraints.py +2 -2
- classiq/interface/generator/model/model.py +5 -6
- classiq/interface/generator/model/preferences/preferences.py +7 -6
- classiq/interface/generator/model/quantum_register.py +6 -11
- classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
- classiq/interface/generator/oracles/custom_oracle.py +2 -2
- classiq/interface/generator/oracles/oracle_abc.py +6 -5
- classiq/interface/generator/partitioned_register.py +6 -5
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +8 -7
- classiq/interface/generator/qpe.py +4 -4
- classiq/interface/generator/qsvm.py +3 -3
- classiq/interface/generator/quantum_function_call.py +24 -29
- classiq/interface/generator/quantum_program.py +9 -9
- classiq/interface/generator/register_role.py +2 -4
- classiq/interface/generator/slice_parsing_utils.py +4 -3
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/distributions.py +6 -5
- classiq/interface/generator/state_preparation/metrics.py +2 -4
- classiq/interface/generator/state_preparation/state_preparation.py +4 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -3
- classiq/interface/generator/transpiler_basis_gates.py +2 -2
- classiq/interface/generator/types/enum_declaration.py +2 -3
- classiq/interface/generator/types/qstruct_declaration.py +2 -1
- classiq/interface/generator/types/struct_declaration.py +3 -2
- classiq/interface/generator/ucc.py +2 -1
- classiq/interface/generator/unitary_gate.py +2 -2
- classiq/interface/generator/user_defined_function_params.py +1 -1
- classiq/interface/generator/validations/flow_graph.py +6 -5
- classiq/interface/generator/validations/validator_functions.py +3 -2
- classiq/interface/generator/visitor.py +9 -14
- classiq/interface/hardware.py +5 -6
- classiq/interface/helpers/custom_encoders.py +2 -2
- classiq/interface/helpers/custom_pydantic_types.py +8 -9
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +4 -3
- classiq/interface/helpers/validation_helpers.py +2 -2
- classiq/interface/ide/ide_data.py +11 -15
- classiq/interface/ide/visual_model.py +20 -22
- classiq/interface/jobs.py +2 -2
- classiq/interface/model/bind_operation.py +5 -4
- classiq/interface/model/classical_parameter_declaration.py +2 -2
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/inplace_binary_operation.py +2 -1
- classiq/interface/model/model.py +12 -11
- classiq/interface/model/port_declaration.py +2 -2
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +3 -2
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -2
- classiq/interface/model/quantum_expressions/quantum_expression.py +8 -7
- classiq/interface/model/quantum_function_call.py +9 -14
- classiq/interface/model/quantum_function_declaration.py +10 -12
- classiq/interface/model/quantum_lambda_function.py +3 -16
- classiq/interface/model/quantum_statement.py +4 -3
- classiq/interface/model/quantum_type.py +5 -5
- classiq/interface/model/statement_block.py +2 -3
- classiq/interface/model/validation_handle.py +5 -4
- classiq/interface/server/global_versions.py +3 -3
- classiq/model_expansions/atomic_expression_functions_defs.py +3 -2
- classiq/model_expansions/call_to_model_converter.py +190 -0
- classiq/model_expansions/capturing/captured_var_manager.py +4 -6
- classiq/model_expansions/capturing/propagated_var_stack.py +7 -7
- classiq/model_expansions/closure.py +17 -9
- classiq/model_expansions/evaluators/arg_type_match.py +3 -2
- classiq/model_expansions/evaluators/argument_types.py +3 -3
- classiq/model_expansions/evaluators/control.py +3 -3
- classiq/model_expansions/evaluators/parameter_types.py +7 -7
- classiq/model_expansions/evaluators/quantum_type_utils.py +2 -1
- classiq/model_expansions/evaluators/type_type_match.py +1 -1
- classiq/model_expansions/expression_evaluator.py +10 -9
- classiq/model_expansions/expression_renamer.py +6 -6
- classiq/model_expansions/function_builder.py +19 -12
- classiq/model_expansions/generative_functions.py +3 -2
- classiq/model_expansions/interpreter.py +31 -19
- classiq/model_expansions/model_tables.py +14 -14
- classiq/model_expansions/quantum_operations/bind.py +2 -4
- classiq/model_expansions/quantum_operations/classicalif.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +2 -4
- classiq/model_expansions/quantum_operations/emitter.py +10 -13
- classiq/model_expansions/quantum_operations/expression_operation.py +23 -16
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +160 -35
- classiq/model_expansions/quantum_operations/phase.py +6 -6
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +25 -5
- classiq/model_expansions/quantum_operations/quantum_function_call.py +41 -2
- classiq/model_expansions/quantum_operations/repeat.py +1 -3
- classiq/model_expansions/scope.py +11 -10
- classiq/model_expansions/scope_initialization.py +6 -5
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +6 -6
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +2 -2
- classiq/model_expansions/visitors/variable_references.py +5 -4
- classiq/qmod/builtins/classical_execution_primitives.py +9 -9
- classiq/qmod/builtins/functions/__init__.py +72 -55
- classiq/qmod/builtins/functions/amplitude_estimation.py +4 -1
- classiq/qmod/builtins/functions/arithmetic.py +14 -1
- classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +86 -6
- classiq/qmod/builtins/functions/grover.py +41 -45
- classiq/qmod/builtins/functions/hea.py +60 -4
- classiq/qmod/builtins/functions/linear_pauli_rotation.py +26 -4
- classiq/qmod/builtins/functions/modular_exponentiation.py +90 -29
- classiq/qmod/builtins/functions/operators.py +1 -1
- classiq/qmod/builtins/functions/qaoa_penalty.py +14 -5
- classiq/qmod/builtins/functions/qft_functions.py +57 -0
- classiq/qmod/builtins/functions/qpe.py +20 -4
- classiq/qmod/builtins/functions/qsvt.py +49 -4
- classiq/qmod/builtins/functions/standard_gates.py +4 -4
- classiq/qmod/builtins/functions/state_preparation.py +92 -10
- classiq/qmod/builtins/functions/swap_test.py +7 -1
- classiq/qmod/builtins/functions/utility_functions.py +43 -0
- classiq/qmod/builtins/functions/variational.py +18 -2
- classiq/qmod/builtins/operations.py +4 -5
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +3 -7
- classiq/qmod/create_model_function.py +7 -6
- classiq/qmod/declaration_inferrer.py +7 -10
- classiq/qmod/expression_query.py +3 -3
- classiq/qmod/generative.py +2 -1
- classiq/qmod/model_state_container.py +5 -7
- classiq/qmod/native/__init__.py +1 -3
- classiq/qmod/native/expression_to_qmod.py +9 -8
- classiq/qmod/native/pretty_printer.py +6 -5
- classiq/qmod/pretty_print/__init__.py +1 -3
- classiq/qmod/pretty_print/expression_to_python.py +13 -12
- classiq/qmod/pretty_print/pretty_printer.py +13 -12
- classiq/qmod/python_classical_type.py +8 -4
- classiq/qmod/qfunc.py +4 -4
- classiq/qmod/qmod_variable.py +11 -10
- classiq/qmod/quantum_expandable.py +12 -15
- classiq/qmod/quantum_function.py +10 -3
- classiq/qmod/semantics/annotation.py +1 -1
- classiq/qmod/semantics/error_manager.py +8 -7
- classiq/qmod/semantics/static_semantics_visitor.py +19 -24
- classiq/qmod/semantics/validation/constants_validation.py +1 -1
- classiq/qmod/semantics/validation/func_call_validation.py +2 -2
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +2 -1
- classiq/qmod/symbolic.py +5 -8
- classiq/qmod/symbolic_type.py +2 -2
- {classiq-0.53.0.dist-info → classiq-0.54.0.dist-info}/METADATA +1 -1
- {classiq-0.53.0.dist-info → classiq-0.54.0.dist-info}/RECORD +295 -292
- classiq/qmod/builtins/functions/qft.py +0 -23
- {classiq-0.53.0.dist-info → classiq-0.54.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,7 @@
|
|
1
|
+
from collections.abc import Iterable, Iterator, Sequence
|
1
2
|
from contextlib import contextmanager
|
2
3
|
from dataclasses import dataclass, field
|
3
|
-
from typing import
|
4
|
+
from typing import Generic, Optional, TypeVar
|
4
5
|
|
5
6
|
from classiq.interface.exceptions import (
|
6
7
|
ClassiqExpansionError,
|
@@ -18,6 +19,7 @@ from classiq.interface.generator.functions.port_declaration import (
|
|
18
19
|
)
|
19
20
|
from classiq.interface.model.model import MAIN_FUNCTION_NAME
|
20
21
|
from classiq.interface.model.native_function_definition import (
|
22
|
+
FunctionSynthesisData,
|
21
23
|
NativeFunctionDefinition,
|
22
24
|
)
|
23
25
|
from classiq.interface.model.port_declaration import PortDeclaration
|
@@ -35,14 +37,14 @@ ClosureType = TypeVar("ClosureType", bound=Closure)
|
|
35
37
|
|
36
38
|
@dataclass
|
37
39
|
class Block:
|
38
|
-
statements:
|
39
|
-
captured_vars:
|
40
|
+
statements: list[QuantumStatement] = field(default_factory=list)
|
41
|
+
captured_vars: list[PortDeclaration] = field(default_factory=list)
|
40
42
|
|
41
43
|
|
42
44
|
@dataclass
|
43
45
|
class OperationContext(Generic[ClosureType]):
|
44
46
|
closure: ClosureType
|
45
|
-
blocks:
|
47
|
+
blocks: dict[str, Block] = field(default_factory=dict)
|
46
48
|
|
47
49
|
@property
|
48
50
|
def name(self) -> str:
|
@@ -52,7 +54,7 @@ class OperationContext(Generic[ClosureType]):
|
|
52
54
|
def positional_arg_declarations(self) -> Sequence[PositionalArg]:
|
53
55
|
return self.closure.positional_arg_declarations
|
54
56
|
|
55
|
-
def statements(self, block_name: str) ->
|
57
|
+
def statements(self, block_name: str) -> list[QuantumStatement]:
|
56
58
|
return self.blocks[block_name].statements
|
57
59
|
|
58
60
|
|
@@ -63,22 +65,26 @@ class FunctionContext(OperationContext[FunctionClosure]):
|
|
63
65
|
return cls(original_function, {"body": Block()})
|
64
66
|
|
65
67
|
@property
|
66
|
-
def body(self) ->
|
68
|
+
def body(self) -> list[QuantumStatement]:
|
67
69
|
return self.statements("body")
|
68
70
|
|
69
71
|
@property
|
70
|
-
def captured_vars(self) ->
|
72
|
+
def captured_vars(self) -> list[PortDeclaration]:
|
71
73
|
return self.blocks["body"].captured_vars
|
72
74
|
|
73
75
|
@property
|
74
76
|
def is_lambda(self) -> bool:
|
75
77
|
return self.closure.is_lambda
|
76
78
|
|
79
|
+
@property
|
80
|
+
def synthesis_data(self) -> FunctionSynthesisData:
|
81
|
+
return self.closure.synthesis_data
|
82
|
+
|
77
83
|
|
78
84
|
class OperationBuilder:
|
79
85
|
def __init__(self) -> None:
|
80
|
-
self._operations:
|
81
|
-
self._blocks:
|
86
|
+
self._operations: list[OperationContext] = []
|
87
|
+
self._blocks: list[str] = []
|
82
88
|
self._counter = 0
|
83
89
|
|
84
90
|
@property
|
@@ -93,7 +99,7 @@ class OperationBuilder:
|
|
93
99
|
raise ClassiqInternalExpansionError("No function found")
|
94
100
|
|
95
101
|
@property
|
96
|
-
def _current_statements(self) ->
|
102
|
+
def _current_statements(self) -> list[QuantumStatement]:
|
97
103
|
return self._operations[-1].blocks[self._blocks[-1]].statements
|
98
104
|
|
99
105
|
def emit_statement(self, statement: QuantumStatement) -> None:
|
@@ -160,7 +166,7 @@ class OperationBuilder:
|
|
160
166
|
name = f"{name}_{LAMBDA_KEYWORD + '_0_0_' if function_context.is_lambda else ''}{EXPANDED_KEYWORD}_{self._counter}"
|
161
167
|
self._counter += 1
|
162
168
|
|
163
|
-
new_parameters:
|
169
|
+
new_parameters: list[PortDeclaration] = [
|
164
170
|
param
|
165
171
|
for param in function_context.positional_arg_declarations
|
166
172
|
if isinstance(param, PortDeclaration)
|
@@ -170,10 +176,11 @@ class OperationBuilder:
|
|
170
176
|
name=name,
|
171
177
|
body=function_context.body,
|
172
178
|
positional_arg_declarations=new_parameters,
|
179
|
+
synthesis_data=function_context.synthesis_data,
|
173
180
|
)
|
174
181
|
|
175
182
|
|
176
|
-
def validate_captured_vars(captured_vars:
|
183
|
+
def validate_captured_vars(captured_vars: list[PortDeclaration]) -> None:
|
177
184
|
if input_captured := [
|
178
185
|
demangle_name(var.name)
|
179
186
|
for var in captured_vars
|
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Mapping
|
2
|
+
from typing import TYPE_CHECKING, Any
|
2
3
|
|
3
4
|
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
4
5
|
from classiq.interface.generator.expressions.qmod_struct_instance import (
|
@@ -127,7 +128,7 @@ class _InterpreterExpandable(QFunc):
|
|
127
128
|
def emit_generative_statements(
|
128
129
|
interpreter: "Interpreter",
|
129
130
|
operation: GenerativeClosure,
|
130
|
-
args:
|
131
|
+
args: list[Evaluated],
|
131
132
|
) -> None:
|
132
133
|
python_qmod_args = [
|
133
134
|
translate_ast_arg_to_python_qmod(param, arg)
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import copy
|
2
|
+
from collections.abc import Iterator, Sequence
|
2
3
|
from contextlib import contextmanager, nullcontext
|
3
4
|
from functools import singledispatchmethod
|
4
|
-
from typing import Any,
|
5
|
+
from typing import Any, Optional, cast
|
5
6
|
|
6
7
|
import numpy as np
|
7
8
|
from numpy.random import permutation
|
@@ -45,6 +46,7 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
45
46
|
)
|
46
47
|
from classiq.interface.model.within_apply_operation import WithinApply
|
47
48
|
|
49
|
+
from classiq.model_expansions.call_to_model_converter import BlockFunctionInfo
|
48
50
|
from classiq.model_expansions.capturing.propagated_var_stack import PropagatedVarStack
|
49
51
|
from classiq.model_expansions.closure import (
|
50
52
|
Closure,
|
@@ -88,7 +90,7 @@ from classiq.qmod.builtins.functions import permute
|
|
88
90
|
from classiq.qmod.quantum_function import GenerativeQFunc
|
89
91
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
90
92
|
|
91
|
-
STATEMENT_TYPES_FOR_SOURCE_REFERENCE_PROPAGATION:
|
93
|
+
STATEMENT_TYPES_FOR_SOURCE_REFERENCE_PROPAGATION: tuple[type[QuantumStatement], ...] = (
|
92
94
|
QuantumFunctionCall,
|
93
95
|
VariableDeclarationStatement,
|
94
96
|
QuantumAssignmentOperation,
|
@@ -99,14 +101,14 @@ class Interpreter:
|
|
99
101
|
def __init__(
|
100
102
|
self,
|
101
103
|
model: Model,
|
102
|
-
generative_functions: Optional[
|
104
|
+
generative_functions: Optional[list[GenerativeQFunc]] = None,
|
103
105
|
is_frontend: bool = False,
|
104
106
|
) -> None:
|
105
107
|
self._is_frontend = is_frontend
|
106
108
|
self._model = model
|
107
109
|
self._current_scope = Scope()
|
108
110
|
self._builder = OperationBuilder()
|
109
|
-
self._expanded_functions:
|
111
|
+
self._expanded_functions: list[NativeFunctionDefinition] = []
|
110
112
|
self._propagated_var_stack = PropagatedVarStack(
|
111
113
|
self._current_scope, self._builder
|
112
114
|
)
|
@@ -120,6 +122,7 @@ class Interpreter:
|
|
120
122
|
|
121
123
|
self._counted_name_allocator = CountedNameAllocator()
|
122
124
|
self._error_manager: ErrorManager = ErrorManager()
|
125
|
+
self._synthesized_separately_blocks: dict[str, BlockFunctionInfo] = {}
|
123
126
|
|
124
127
|
@contextmanager
|
125
128
|
def _scope_guard(self, scope: Scope) -> Iterator[None]:
|
@@ -154,9 +157,10 @@ class Interpreter:
|
|
154
157
|
self._builder.create_definition(cast(FunctionContext, context))
|
155
158
|
)
|
156
159
|
|
157
|
-
def expand(self) -> Model:
|
160
|
+
def expand(self) -> tuple[Model, dict[str, BlockFunctionInfo]]:
|
158
161
|
try:
|
159
162
|
with self._error_manager.call("main"):
|
163
|
+
self._synthesized_separately_blocks = {}
|
160
164
|
self._expand_main_func()
|
161
165
|
except Exception as e:
|
162
166
|
if isinstance(e, ClassiqInternalExpansionError) or debug_mode.get():
|
@@ -168,17 +172,20 @@ class Interpreter:
|
|
168
172
|
finally:
|
169
173
|
self._error_manager.report_errors(ClassiqExpansionError)
|
170
174
|
|
171
|
-
return
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
175
|
+
return (
|
176
|
+
Model(
|
177
|
+
constraints=self._model.constraints,
|
178
|
+
preferences=self._model.preferences,
|
179
|
+
classical_execution_code=self._model.classical_execution_code,
|
180
|
+
execution_preferences=self._model.execution_preferences,
|
181
|
+
functions=self._expanded_functions,
|
182
|
+
constants=self._model.constants,
|
183
|
+
enums=self._model.enums,
|
184
|
+
types=self._model.types,
|
185
|
+
qstructs=self._model.qstructs,
|
186
|
+
debug_info=self._model.debug_info,
|
187
|
+
),
|
188
|
+
self._synthesized_separately_blocks,
|
182
189
|
)
|
183
190
|
|
184
191
|
@singledispatchmethod
|
@@ -196,7 +203,7 @@ class Interpreter:
|
|
196
203
|
@evaluate.register
|
197
204
|
def evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
|
198
205
|
renamed_params = [
|
199
|
-
param.rename(function.
|
206
|
+
param.rename(function.pos_rename_params[idx])
|
200
207
|
for idx, param in enumerate(function.func_decl.positional_arg_declarations)
|
201
208
|
]
|
202
209
|
func_decl = NamedParamsQuantumFunctionDeclaration(
|
@@ -204,7 +211,7 @@ class Interpreter:
|
|
204
211
|
positional_arg_declarations=renamed_params,
|
205
212
|
)
|
206
213
|
|
207
|
-
closure_class:
|
214
|
+
closure_class: type[FunctionClosure]
|
208
215
|
extra_args: dict[str, Any]
|
209
216
|
if function.is_generative():
|
210
217
|
closure_class = GenerativeFunctionClosure
|
@@ -339,7 +346,12 @@ class Interpreter:
|
|
339
346
|
|
340
347
|
def _expand_operation(self, operation: Closure) -> OperationContext:
|
341
348
|
with self._builder.operation_context(operation) as context:
|
342
|
-
if
|
349
|
+
if (
|
350
|
+
isinstance(operation, FunctionClosure)
|
351
|
+
and operation.synthesis_data.should_synthesize_separately
|
352
|
+
):
|
353
|
+
pass
|
354
|
+
elif isinstance(operation, FunctionClosure) and operation.name == "permute":
|
343
355
|
# special expansion since permute is generative
|
344
356
|
with self._scope_guard(operation.scope):
|
345
357
|
self._expand_permute()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
from enum import IntEnum
|
3
|
-
from typing import ClassVar,
|
3
|
+
from typing import ClassVar, Generic, Optional, TypeVar
|
4
4
|
|
5
5
|
from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
|
6
6
|
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
@@ -18,15 +18,15 @@ DeclarationType = TypeVar(
|
|
18
18
|
|
19
19
|
|
20
20
|
class TypeTable(Generic[DeclarationType], ABC):
|
21
|
-
def __init__(self, user_types:
|
22
|
-
self._all_types:
|
21
|
+
def __init__(self, user_types: list[DeclarationType]) -> None:
|
22
|
+
self._all_types: dict[str, DeclarationType] = self.builtins.copy()
|
23
23
|
for t in user_types:
|
24
24
|
assert t.name not in self._all_types # FIXME: issue user error (CAD-7856)
|
25
25
|
self._all_types[t.name] = t
|
26
26
|
|
27
27
|
@property
|
28
28
|
@abstractmethod
|
29
|
-
def builtins(self) ->
|
29
|
+
def builtins(self) -> dict[str, DeclarationType]:
|
30
30
|
pass
|
31
31
|
|
32
32
|
def __getitem__(self, key: str) -> DeclarationType:
|
@@ -38,20 +38,20 @@ class TypeTable(Generic[DeclarationType], ABC):
|
|
38
38
|
def __contains__(self, key: str) -> bool:
|
39
39
|
return key in self._all_types
|
40
40
|
|
41
|
-
def all_types(self) ->
|
41
|
+
def all_types(self) -> dict[str, DeclarationType]:
|
42
42
|
return self._all_types
|
43
43
|
|
44
44
|
|
45
45
|
class EnumTable(TypeTable[EnumDeclaration]):
|
46
|
-
def __init__(self, user_types:
|
46
|
+
def __init__(self, user_types: list[EnumDeclaration]) -> None:
|
47
47
|
super().__init__(user_types)
|
48
48
|
|
49
49
|
@property
|
50
|
-
def builtins(self) ->
|
50
|
+
def builtins(self) -> dict[str, EnumDeclaration]:
|
51
51
|
return BUILTIN_ENUM_DECLARATIONS
|
52
52
|
|
53
53
|
@property
|
54
|
-
def enums(self) ->
|
54
|
+
def enums(self) -> dict[str, IntEnum]:
|
55
55
|
return {
|
56
56
|
enum_decl.name: enum_decl.create_enum()
|
57
57
|
for enum_decl in self.all_types().values()
|
@@ -60,13 +60,13 @@ class EnumTable(TypeTable[EnumDeclaration]):
|
|
60
60
|
|
61
61
|
class StructTable(TypeTable[StructDeclaration]):
|
62
62
|
@property
|
63
|
-
def builtins(self) ->
|
63
|
+
def builtins(self) -> dict[str, StructDeclaration]:
|
64
64
|
return BUILTIN_STRUCT_DECLARATIONS
|
65
65
|
|
66
66
|
|
67
67
|
class QStructTable(TypeTable[QStructDeclaration]):
|
68
68
|
@property
|
69
|
-
def builtins(self) ->
|
69
|
+
def builtins(self) -> dict[str, QStructDeclaration]:
|
70
70
|
return {}
|
71
71
|
|
72
72
|
|
@@ -76,15 +76,15 @@ class SymbolTable:
|
|
76
76
|
qstruct_table: ClassVar[QStructTable] = QStructTable([])
|
77
77
|
|
78
78
|
@classmethod
|
79
|
-
def init_user_enums(cls, user_enums:
|
79
|
+
def init_user_enums(cls, user_enums: list[EnumDeclaration]) -> None:
|
80
80
|
cls.enum_table = EnumTable(user_enums)
|
81
81
|
|
82
82
|
@classmethod
|
83
|
-
def init_user_types(cls, user_types:
|
83
|
+
def init_user_types(cls, user_types: list[StructDeclaration]) -> None:
|
84
84
|
cls.type_table = StructTable(user_types)
|
85
85
|
|
86
86
|
@classmethod
|
87
|
-
def init_user_qstructs(cls, user_qstructs:
|
87
|
+
def init_user_qstructs(cls, user_qstructs: list[QStructDeclaration]) -> None:
|
88
88
|
cls.qstruct_table = QStructTable(user_qstructs)
|
89
89
|
QMODULE.qstruct_decls = {
|
90
90
|
qstruct_decl.name: qstruct_decl for qstruct_decl in user_qstructs
|
@@ -92,7 +92,7 @@ class SymbolTable:
|
|
92
92
|
|
93
93
|
|
94
94
|
class HandleTable:
|
95
|
-
_handle_map:
|
95
|
+
_handle_map: dict[HandleIdentifier, QmodPyObject] = {}
|
96
96
|
|
97
97
|
@classmethod
|
98
98
|
def get_handle_object(cls, hid: HandleIdentifier) -> Optional[QmodPyObject]:
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
1
|
from classiq.interface.exceptions import ClassiqExpansionError
|
4
2
|
from classiq.interface.model.bind_operation import BindOperation
|
5
3
|
|
@@ -18,11 +16,11 @@ class BindEmitter(Emitter[BindOperation]):
|
|
18
16
|
def emit(self, bind: BindOperation, /) -> None:
|
19
17
|
with self._propagated_var_stack.capture_variables(bind):
|
20
18
|
pass
|
21
|
-
inputs:
|
19
|
+
inputs: list[QuantumSymbol] = [
|
22
20
|
self._interpreter.evaluate(arg).as_type(QuantumSymbol)
|
23
21
|
for arg in bind.in_handles
|
24
22
|
]
|
25
|
-
outputs:
|
23
|
+
outputs: list[QuantumSymbol] = [
|
26
24
|
self._interpreter.evaluate(arg).as_type(QuantumSymbol)
|
27
25
|
for arg in bind.out_handles
|
28
26
|
]
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import List, Tuple
|
2
|
-
|
3
1
|
from sympy import Equality
|
4
2
|
from sympy.logic.boolalg import Boolean
|
5
3
|
from typing_extensions import TypeGuard
|
@@ -160,7 +158,7 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
160
158
|
def _emit_with_x_gates(
|
161
159
|
self, control: Control, ctrl: QmodSizedProxy, ctrl_state: str
|
162
160
|
) -> None:
|
163
|
-
compute_op:
|
161
|
+
compute_op: list[ConcreteQuantumStatement] = []
|
164
162
|
|
165
163
|
x_gate_value = self._get_x_gate_value(ctrl_state)
|
166
164
|
if x_gate_value != 0:
|
@@ -194,7 +192,7 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
194
192
|
|
195
193
|
def _get_array_cast_ops(
|
196
194
|
self, ctrl: QmodQNumProxy
|
197
|
-
) ->
|
195
|
+
) -> tuple[VariableDeclarationStatement, BindOperation]:
|
198
196
|
array_cast = self._counted_name_allocator.allocate(
|
199
197
|
f"{ctrl.handle}{ARRAY_CAST_SUFFIX}"
|
200
198
|
)
|
@@ -1,11 +1,9 @@
|
|
1
1
|
from abc import abstractmethod
|
2
|
+
from collections.abc import Sequence
|
2
3
|
from typing import (
|
3
4
|
TYPE_CHECKING,
|
4
|
-
Dict,
|
5
5
|
Generic,
|
6
|
-
List,
|
7
6
|
Optional,
|
8
|
-
Sequence,
|
9
7
|
TypeVar,
|
10
8
|
Union,
|
11
9
|
cast,
|
@@ -18,7 +16,7 @@ from classiq.interface.generator.expressions.evaluated_expression import (
|
|
18
16
|
EvaluatedExpression,
|
19
17
|
)
|
20
18
|
from classiq.interface.generator.expressions.expression import Expression
|
21
|
-
from classiq.interface.
|
19
|
+
from classiq.interface.generator.generated_circuit_data import OperationLevel
|
22
20
|
from classiq.interface.model.classical_parameter_declaration import (
|
23
21
|
ClassicalParameterDeclaration,
|
24
22
|
)
|
@@ -63,7 +61,6 @@ from classiq.qmod.quantum_function import GenerativeQFunc
|
|
63
61
|
if TYPE_CHECKING:
|
64
62
|
from classiq.model_expansions.interpreter import Interpreter
|
65
63
|
|
66
|
-
|
67
64
|
QuantumStatementT = TypeVar("QuantumStatementT", bound=QuantumStatement)
|
68
65
|
|
69
66
|
|
@@ -74,7 +71,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
74
71
|
self._scope_guard = self._interpreter._scope_guard
|
75
72
|
self._machine_precision = self._interpreter._model.preferences.machine_precision
|
76
73
|
|
77
|
-
self._generative_contexts:
|
74
|
+
self._generative_contexts: dict[str, OperationContext] = {}
|
78
75
|
|
79
76
|
@abstractmethod
|
80
77
|
def emit(self, statement: QuantumStatementT, /) -> None:
|
@@ -103,7 +100,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
103
100
|
return self._interpreter._current_scope
|
104
101
|
|
105
102
|
@property
|
106
|
-
def _expanded_functions(self) ->
|
103
|
+
def _expanded_functions(self) -> list[NativeFunctionDefinition]:
|
107
104
|
return self._interpreter._expanded_functions
|
108
105
|
|
109
106
|
@property
|
@@ -125,14 +122,14 @@ class Emitter(Generic[QuantumStatementT]):
|
|
125
122
|
return self._create_quantum_function_call(wrapping_function, list())
|
126
123
|
|
127
124
|
def _emit_quantum_function_call(
|
128
|
-
self, function: FunctionClosure, args:
|
125
|
+
self, function: FunctionClosure, args: list[ArgValue]
|
129
126
|
) -> QuantumFunctionCall:
|
130
127
|
call = self._create_quantum_function_call(function, args)
|
131
128
|
self._builder.emit_statement(call)
|
132
129
|
return call
|
133
130
|
|
134
131
|
def _create_quantum_function_call(
|
135
|
-
self, function: FunctionClosure, args:
|
132
|
+
self, function: FunctionClosure, args: list[ArgValue]
|
136
133
|
) -> QuantumFunctionCall:
|
137
134
|
evaluated_args = [self._interpreter.evaluate(arg) for arg in args]
|
138
135
|
new_declaration = self._prepare_fully_typed_declaration(
|
@@ -206,10 +203,10 @@ class Emitter(Generic[QuantumStatementT]):
|
|
206
203
|
|
207
204
|
def _get_new_positional_args(
|
208
205
|
self,
|
209
|
-
evaluated_args:
|
206
|
+
evaluated_args: list[Evaluated],
|
210
207
|
is_atomic: bool,
|
211
208
|
new_positional_arg_decls: Sequence[PositionalArg],
|
212
|
-
) ->
|
209
|
+
) -> list[ArgValue]:
|
213
210
|
evaluated_args = add_information_from_output_arguments(
|
214
211
|
new_positional_arg_decls, evaluated_args
|
215
212
|
)
|
@@ -230,7 +227,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
230
227
|
return positional_args
|
231
228
|
|
232
229
|
def _prepare_fully_typed_declaration(
|
233
|
-
self, function: FunctionClosure, evaluated_args:
|
230
|
+
self, function: FunctionClosure, evaluated_args: list[Evaluated]
|
234
231
|
) -> NamedParamsQuantumFunctionDeclaration:
|
235
232
|
"""
|
236
233
|
Given, for example,
|
@@ -260,7 +257,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
260
257
|
self,
|
261
258
|
op: QuantumOperation,
|
262
259
|
context_name: str,
|
263
|
-
block_names: Union[None, str,
|
260
|
+
block_names: Union[None, str, list[str]] = None,
|
264
261
|
func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
|
265
262
|
) -> OperationContext:
|
266
263
|
if isinstance(block_names, str):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import ast
|
2
2
|
from abc import abstractmethod
|
3
3
|
from itertools import chain
|
4
|
-
from typing import TYPE_CHECKING,
|
4
|
+
from typing import TYPE_CHECKING, TypeVar
|
5
5
|
|
6
6
|
from classiq.interface.exceptions import (
|
7
7
|
ClassiqExpansionError,
|
@@ -26,6 +26,7 @@ from classiq.interface.model.quantum_type import (
|
|
26
26
|
QuantumBit,
|
27
27
|
QuantumBitvector,
|
28
28
|
QuantumNumeric,
|
29
|
+
QuantumType,
|
29
30
|
)
|
30
31
|
from classiq.interface.model.variable_declaration_statement import (
|
31
32
|
VariableDeclarationStatement,
|
@@ -48,7 +49,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
48
49
|
self,
|
49
50
|
op: ExpressionOperationT,
|
50
51
|
expression: Expression,
|
51
|
-
symbols_to_split:
|
52
|
+
symbols_to_split: list[QuantumSymbol],
|
52
53
|
) -> None:
|
53
54
|
symbols_parts, bind_ops = self._get_bind_ops(symbols_to_split)
|
54
55
|
|
@@ -62,14 +63,13 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
62
63
|
)
|
63
64
|
)
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
expression,
|
71
|
-
)
|
66
|
+
symbol_mapping = {
|
67
|
+
symbol.handle: (symbol_part_var_name, symbol.quantum_type)
|
68
|
+
for symbol, symbol_part_var_name in chain.from_iterable(symbols_parts)
|
69
|
+
}
|
70
|
+
new_expression = self._update_op_expression(symbol_mapping, expression)
|
72
71
|
new_op = op.model_copy(update=dict(expression=new_expression))
|
72
|
+
new_op = self._get_updated_op_split_symbols(new_op, symbol_mapping)
|
73
73
|
|
74
74
|
self._interpreter.emit_statement(
|
75
75
|
WithinApply(
|
@@ -79,9 +79,16 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
79
79
|
)
|
80
80
|
)
|
81
81
|
|
82
|
+
@staticmethod
|
83
|
+
def _get_updated_op_split_symbols(
|
84
|
+
op: ExpressionOperationT,
|
85
|
+
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
86
|
+
) -> ExpressionOperationT:
|
87
|
+
return op
|
88
|
+
|
82
89
|
def _update_op_expression(
|
83
90
|
self,
|
84
|
-
|
91
|
+
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
85
92
|
expression: Expression,
|
86
93
|
) -> Expression:
|
87
94
|
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
@@ -90,9 +97,9 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
90
97
|
new_expr_str = expression.expr
|
91
98
|
for handle in vrc.var_handles:
|
92
99
|
collapsed_handle = handle.collapse()
|
93
|
-
if collapsed_handle in
|
100
|
+
if collapsed_handle in symbol_mapping:
|
94
101
|
new_expr_str = new_expr_str.replace(
|
95
|
-
str(handle),
|
102
|
+
str(handle), symbol_mapping[collapsed_handle][0]
|
96
103
|
)
|
97
104
|
self._check_all_handles_were_replaced(new_expr_str)
|
98
105
|
|
@@ -115,8 +122,8 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
115
122
|
|
116
123
|
def _get_bind_ops(
|
117
124
|
self,
|
118
|
-
symbols_to_split:
|
119
|
-
) ->
|
125
|
+
symbols_to_split: list[QuantumSymbol],
|
126
|
+
) -> tuple[list[list[tuple[QuantumSymbol, str]]], list[BindOperation]]:
|
120
127
|
bind_ops = []
|
121
128
|
symbols_parts = []
|
122
129
|
for symbol in symbols_to_split:
|
@@ -135,7 +142,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
135
142
|
|
136
143
|
def _get_symbol_parts(
|
137
144
|
self, symbol: QuantumSymbol
|
138
|
-
) ->
|
145
|
+
) -> list[tuple[QuantumSymbol, str]]:
|
139
146
|
quantum_type = symbol.quantum_type
|
140
147
|
|
141
148
|
if isinstance(quantum_type, (QuantumBit, QuantumNumeric)):
|
@@ -169,7 +176,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
169
176
|
)
|
170
177
|
)
|
171
178
|
|
172
|
-
def _get_symbols_to_split(self, expression: Expression) ->
|
179
|
+
def _get_symbols_to_split(self, expression: Expression) -> list[QuantumSymbol]:
|
173
180
|
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
174
181
|
vrc.visit(ast.parse(expression.expr))
|
175
182
|
symbol_names_to_split = dict.fromkeys(
|