classiq 0.53.0__py3-none-any.whl → 0.55.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/builtins/internal_operators.py +9 -1
- 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 +33 -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 +11 -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/compilation_metadata.py +5 -0
- 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 +22 -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/control.py +22 -1
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/inplace_binary_operation.py +2 -1
- classiq/interface/model/model.py +16 -11
- classiq/interface/model/native_function_definition.py +1 -1
- 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 +4 -27
- 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 +7 -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/capturing/captured_var_manager.py +4 -6
- classiq/model_expansions/capturing/propagated_var_stack.py +7 -7
- classiq/model_expansions/closure.py +83 -12
- 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 +13 -12
- classiq/model_expansions/generative_functions.py +5 -4
- classiq/model_expansions/interpreter.py +20 -11
- 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 +81 -24
- classiq/model_expansions/quantum_operations/emitter.py +33 -20
- classiq/model_expansions/quantum_operations/expression_operation.py +47 -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 +28 -31
- classiq/model_expansions/quantum_operations/quantum_function_call.py +9 -0
- classiq/model_expansions/quantum_operations/repeat.py +1 -3
- classiq/model_expansions/quantum_operations/within_apply.py +0 -16
- classiq/model_expansions/scope.py +11 -10
- classiq/model_expansions/scope_initialization.py +5 -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 +117 -22
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +3 -7
- classiq/qmod/create_model_function.py +16 -17
- 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 +10 -8
- classiq/qmod/native/__init__.py +1 -3
- classiq/qmod/native/expression_to_qmod.py +9 -8
- classiq/qmod/native/pretty_printer.py +12 -6
- 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 +38 -23
- 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 +35 -22
- 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/qmod/synthesize_separately.py +1 -2
- {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/METADATA +1 -1
- {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/RECORD +300 -297
- classiq/qmod/builtins/functions/qft.py +0 -23
- {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/WHEEL +0 -0
@@ -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
|
|
@@ -73,8 +70,13 @@ class Emitter(Generic[QuantumStatementT]):
|
|
73
70
|
|
74
71
|
self._scope_guard = self._interpreter._scope_guard
|
75
72
|
self._machine_precision = self._interpreter._model.preferences.machine_precision
|
76
|
-
|
77
|
-
|
73
|
+
self._expanded_functions_compilation_metadata = (
|
74
|
+
self._interpreter._expanded_functions_compilation_metadata
|
75
|
+
)
|
76
|
+
self._functions_compilation_metadata = (
|
77
|
+
self._interpreter._model.functions_compilation_metadata
|
78
|
+
)
|
79
|
+
self._generative_contexts: dict[str, OperationContext] = {}
|
78
80
|
|
79
81
|
@abstractmethod
|
80
82
|
def emit(self, statement: QuantumStatementT, /) -> None:
|
@@ -103,7 +105,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
103
105
|
return self._interpreter._current_scope
|
104
106
|
|
105
107
|
@property
|
106
|
-
def _expanded_functions(self) ->
|
108
|
+
def _expanded_functions(self) -> dict[str, NativeFunctionDefinition]:
|
107
109
|
return self._interpreter._expanded_functions
|
108
110
|
|
109
111
|
@property
|
@@ -125,14 +127,14 @@ class Emitter(Generic[QuantumStatementT]):
|
|
125
127
|
return self._create_quantum_function_call(wrapping_function, list())
|
126
128
|
|
127
129
|
def _emit_quantum_function_call(
|
128
|
-
self, function: FunctionClosure, args:
|
130
|
+
self, function: FunctionClosure, args: list[ArgValue]
|
129
131
|
) -> QuantumFunctionCall:
|
130
132
|
call = self._create_quantum_function_call(function, args)
|
131
133
|
self._builder.emit_statement(call)
|
132
134
|
return call
|
133
135
|
|
134
136
|
def _create_quantum_function_call(
|
135
|
-
self, function: FunctionClosure, args:
|
137
|
+
self, function: FunctionClosure, args: list[ArgValue]
|
136
138
|
) -> QuantumFunctionCall:
|
137
139
|
evaluated_args = [self._interpreter.evaluate(arg) for arg in args]
|
138
140
|
new_declaration = self._prepare_fully_typed_declaration(
|
@@ -140,23 +142,34 @@ class Emitter(Generic[QuantumStatementT]):
|
|
140
142
|
)
|
141
143
|
new_positional_arg_decls = new_declaration.positional_arg_declarations
|
142
144
|
is_atomic = function.is_atomic
|
143
|
-
|
145
|
+
new_function_name = function.name
|
146
|
+
if not is_atomic: # perform monomorphization per interpreted parameters set
|
144
147
|
self._add_params_to_scope(
|
145
148
|
new_positional_arg_decls, evaluated_args, function
|
146
149
|
)
|
147
150
|
context = self._expand_operation(
|
148
151
|
function.with_new_declaration(new_declaration)
|
149
152
|
)
|
150
|
-
|
151
|
-
|
153
|
+
function_context = cast(FunctionContext, context)
|
154
|
+
closure_id = function_context.closure.closure_id
|
155
|
+
function_def = self._expanded_functions.get(closure_id)
|
156
|
+
if function_def is None:
|
157
|
+
function_def = self._builder.create_definition(function_context)
|
158
|
+
self._expanded_functions[closure_id] = function_def
|
159
|
+
new_function_name = function_def.name
|
160
|
+
compilation_metadata = self._functions_compilation_metadata.get(
|
161
|
+
function.name
|
152
162
|
)
|
163
|
+
if compilation_metadata is not None:
|
164
|
+
self._expanded_functions_compilation_metadata[new_function_name] = (
|
165
|
+
compilation_metadata
|
166
|
+
)
|
167
|
+
|
153
168
|
new_positional_args = self._get_new_positional_args(
|
154
169
|
evaluated_args, is_atomic, new_positional_arg_decls
|
155
170
|
)
|
156
171
|
new_call = QuantumFunctionCall(
|
157
|
-
function=
|
158
|
-
new_declaration.name if is_atomic else self._expanded_functions[-1].name
|
159
|
-
),
|
172
|
+
function=new_function_name,
|
160
173
|
positional_args=new_positional_args,
|
161
174
|
)
|
162
175
|
is_allocate_or_free = (
|
@@ -206,10 +219,10 @@ class Emitter(Generic[QuantumStatementT]):
|
|
206
219
|
|
207
220
|
def _get_new_positional_args(
|
208
221
|
self,
|
209
|
-
evaluated_args:
|
222
|
+
evaluated_args: list[Evaluated],
|
210
223
|
is_atomic: bool,
|
211
224
|
new_positional_arg_decls: Sequence[PositionalArg],
|
212
|
-
) ->
|
225
|
+
) -> list[ArgValue]:
|
213
226
|
evaluated_args = add_information_from_output_arguments(
|
214
227
|
new_positional_arg_decls, evaluated_args
|
215
228
|
)
|
@@ -230,7 +243,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
230
243
|
return positional_args
|
231
244
|
|
232
245
|
def _prepare_fully_typed_declaration(
|
233
|
-
self, function: FunctionClosure, evaluated_args:
|
246
|
+
self, function: FunctionClosure, evaluated_args: list[Evaluated]
|
234
247
|
) -> NamedParamsQuantumFunctionDeclaration:
|
235
248
|
"""
|
236
249
|
Given, for example,
|
@@ -260,7 +273,7 @@ class Emitter(Generic[QuantumStatementT]):
|
|
260
273
|
self,
|
261
274
|
op: QuantumOperation,
|
262
275
|
context_name: str,
|
263
|
-
block_names: Union[None, str,
|
276
|
+
block_names: Union[None, str, list[str]] = None,
|
264
277
|
func_decl: Optional[NamedParamsQuantumFunctionDeclaration] = None,
|
265
278
|
) -> OperationContext:
|
266
279
|
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, Union
|
5
5
|
|
6
6
|
from classiq.interface.exceptions import (
|
7
7
|
ClassiqExpansionError,
|
@@ -13,6 +13,7 @@ from classiq.interface.generator.expressions.evaluated_expression import (
|
|
13
13
|
from classiq.interface.generator.expressions.expression import Expression
|
14
14
|
from classiq.interface.generator.functions.type_name import TypeName
|
15
15
|
from classiq.interface.model.bind_operation import BindOperation
|
16
|
+
from classiq.interface.model.control import Control
|
16
17
|
from classiq.interface.model.handle_binding import (
|
17
18
|
FieldHandleBinding,
|
18
19
|
HandleBinding,
|
@@ -20,12 +21,14 @@ from classiq.interface.model.handle_binding import (
|
|
20
21
|
SubscriptHandleBinding,
|
21
22
|
)
|
22
23
|
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
24
|
+
QuantumAssignmentOperation,
|
23
25
|
QuantumExpressionOperation,
|
24
26
|
)
|
25
27
|
from classiq.interface.model.quantum_type import (
|
26
28
|
QuantumBit,
|
27
29
|
QuantumBitvector,
|
28
30
|
QuantumNumeric,
|
31
|
+
QuantumType,
|
29
32
|
)
|
30
33
|
from classiq.interface.model.variable_declaration_statement import (
|
31
34
|
VariableDeclarationStatement,
|
@@ -48,7 +51,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
48
51
|
self,
|
49
52
|
op: ExpressionOperationT,
|
50
53
|
expression: Expression,
|
51
|
-
symbols_to_split:
|
54
|
+
symbols_to_split: list[QuantumSymbol],
|
52
55
|
) -> None:
|
53
56
|
symbols_parts, bind_ops = self._get_bind_ops(symbols_to_split)
|
54
57
|
|
@@ -62,14 +65,13 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
62
65
|
)
|
63
66
|
)
|
64
67
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
expression,
|
71
|
-
)
|
68
|
+
symbol_mapping = {
|
69
|
+
symbol.handle: (symbol_part_var_name, symbol.quantum_type)
|
70
|
+
for symbol, symbol_part_var_name in chain.from_iterable(symbols_parts)
|
71
|
+
}
|
72
|
+
new_expression = self._update_op_expression(symbol_mapping, expression)
|
72
73
|
new_op = op.model_copy(update=dict(expression=new_expression))
|
74
|
+
new_op = self._get_updated_op_split_symbols(new_op, symbol_mapping)
|
73
75
|
|
74
76
|
self._interpreter.emit_statement(
|
75
77
|
WithinApply(
|
@@ -79,9 +81,16 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
79
81
|
)
|
80
82
|
)
|
81
83
|
|
84
|
+
@staticmethod
|
85
|
+
def _get_updated_op_split_symbols(
|
86
|
+
op: ExpressionOperationT,
|
87
|
+
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
88
|
+
) -> ExpressionOperationT:
|
89
|
+
return op
|
90
|
+
|
82
91
|
def _update_op_expression(
|
83
92
|
self,
|
84
|
-
|
93
|
+
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
85
94
|
expression: Expression,
|
86
95
|
) -> Expression:
|
87
96
|
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
@@ -90,9 +99,9 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
90
99
|
new_expr_str = expression.expr
|
91
100
|
for handle in vrc.var_handles:
|
92
101
|
collapsed_handle = handle.collapse()
|
93
|
-
if collapsed_handle in
|
102
|
+
if collapsed_handle in symbol_mapping:
|
94
103
|
new_expr_str = new_expr_str.replace(
|
95
|
-
str(handle),
|
104
|
+
str(handle), symbol_mapping[collapsed_handle][0]
|
96
105
|
)
|
97
106
|
self._check_all_handles_were_replaced(new_expr_str)
|
98
107
|
|
@@ -115,8 +124,8 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
115
124
|
|
116
125
|
def _get_bind_ops(
|
117
126
|
self,
|
118
|
-
symbols_to_split:
|
119
|
-
) ->
|
127
|
+
symbols_to_split: list[QuantumSymbol],
|
128
|
+
) -> tuple[list[list[tuple[QuantumSymbol, str]]], list[BindOperation]]:
|
120
129
|
bind_ops = []
|
121
130
|
symbols_parts = []
|
122
131
|
for symbol in symbols_to_split:
|
@@ -135,7 +144,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
135
144
|
|
136
145
|
def _get_symbol_parts(
|
137
146
|
self, symbol: QuantumSymbol
|
138
|
-
) ->
|
147
|
+
) -> list[tuple[QuantumSymbol, str]]:
|
139
148
|
quantum_type = symbol.quantum_type
|
140
149
|
|
141
150
|
if isinstance(quantum_type, (QuantumBit, QuantumNumeric)):
|
@@ -169,7 +178,7 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
169
178
|
)
|
170
179
|
)
|
171
180
|
|
172
|
-
def _get_symbols_to_split(self, expression: Expression) ->
|
181
|
+
def _get_symbols_to_split(self, expression: Expression) -> list[QuantumSymbol]:
|
173
182
|
vrc = VarRefCollector(ignore_duplicated_handles=True)
|
174
183
|
vrc.visit(ast.parse(expression.expr))
|
175
184
|
symbol_names_to_split = dict.fromkeys(
|
@@ -207,3 +216,25 @@ class ExpressionOperationEmitter(Emitter[ExpressionOperationT]):
|
|
207
216
|
self._machine_precision,
|
208
217
|
)
|
209
218
|
return op_with_evaluated_types
|
219
|
+
|
220
|
+
@staticmethod
|
221
|
+
def _all_vars_boolean(op: QuantumExpressionOperation) -> bool:
|
222
|
+
if not all(
|
223
|
+
var_type.has_size_in_bits and var_type.size_in_bits == 1
|
224
|
+
for var_type in op.var_types.values()
|
225
|
+
):
|
226
|
+
return False
|
227
|
+
return not any(
|
228
|
+
isinstance(var_type, QuantumNumeric)
|
229
|
+
and (var_type.sign_value or var_type.fraction_digits_value > 0)
|
230
|
+
for var_type in op.var_types.values()
|
231
|
+
)
|
232
|
+
|
233
|
+
@staticmethod
|
234
|
+
def _is_res_boolean(op: Union[QuantumAssignmentOperation, Control]) -> bool:
|
235
|
+
if not (op.result_type.has_size_in_bits and op.result_type.size_in_bits == 1):
|
236
|
+
return False
|
237
|
+
return not (
|
238
|
+
isinstance(op.result_type, QuantumNumeric)
|
239
|
+
and (op.result_type.sign_value or op.result_type.fraction_digits_value > 0)
|
240
|
+
)
|
@@ -1,10 +1,12 @@
|
|
1
|
-
from typing import TYPE_CHECKING,
|
1
|
+
from typing import TYPE_CHECKING, Optional, Union
|
2
2
|
|
3
|
+
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
3
4
|
from classiq.interface.generator.expressions.expression import Expression
|
4
5
|
from classiq.interface.generator.functions.port_declaration import (
|
5
6
|
PortDeclarationDirection,
|
6
7
|
)
|
7
8
|
from classiq.interface.model.bind_operation import BindOperation
|
9
|
+
from classiq.interface.model.control import Control
|
8
10
|
from classiq.interface.model.handle_binding import HandleBinding
|
9
11
|
from classiq.interface.model.inplace_binary_operation import (
|
10
12
|
BinaryOperation,
|
@@ -16,11 +18,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
16
18
|
NamedParamsQuantumFunctionDeclaration,
|
17
19
|
)
|
18
20
|
from classiq.interface.model.quantum_statement import QuantumStatement
|
19
|
-
from classiq.interface.model.quantum_type import
|
20
|
-
QuantumBit,
|
21
|
-
QuantumBitvector,
|
22
|
-
QuantumNumeric,
|
23
|
-
)
|
21
|
+
from classiq.interface.model.quantum_type import QuantumBitvector, QuantumNumeric
|
24
22
|
from classiq.interface.model.variable_declaration_statement import (
|
25
23
|
VariableDeclarationStatement,
|
26
24
|
)
|
@@ -38,6 +36,7 @@ from classiq.model_expansions.scope import QuantumSymbol, Scope
|
|
38
36
|
from classiq.qmod.builtins.functions import (
|
39
37
|
CX,
|
40
38
|
allocate,
|
39
|
+
apply_to_all,
|
41
40
|
integer_xor,
|
42
41
|
modular_add,
|
43
42
|
modular_add_constant,
|
@@ -94,6 +93,18 @@ class InplaceBinaryOperationEmitter(Emitter[InplaceBinaryOperation]):
|
|
94
93
|
handle=HandleBinding(name="target"),
|
95
94
|
quantum_type=target_var.quantum_type,
|
96
95
|
)
|
96
|
+
internal_func_decl = _binary_function_declaration(op.operation, constant=False)
|
97
|
+
if op.operation == BinaryOperation.Xor:
|
98
|
+
body = _build_inplace_xor_operation(
|
99
|
+
value_var=value_var,
|
100
|
+
target_var=target_var,
|
101
|
+
)
|
102
|
+
else:
|
103
|
+
body = _build_inplace_binary_operation(
|
104
|
+
value_var=value_var,
|
105
|
+
target_var=target_var,
|
106
|
+
internal_function_declaration=internal_func_decl,
|
107
|
+
)
|
97
108
|
inplace_binary_op_function = FunctionClosure.create(
|
98
109
|
name=op.operation.value,
|
99
110
|
positional_arg_declarations=[
|
@@ -108,13 +119,7 @@ class InplaceBinaryOperationEmitter(Emitter[InplaceBinaryOperation]):
|
|
108
119
|
direction=PortDeclarationDirection.Inout,
|
109
120
|
),
|
110
121
|
],
|
111
|
-
body=
|
112
|
-
value_var=value_var,
|
113
|
-
target_var=target_var,
|
114
|
-
internal_function_declaration=_binary_function_declaration(
|
115
|
-
op.operation, constant=False
|
116
|
-
),
|
117
|
-
),
|
122
|
+
body=body,
|
118
123
|
scope=Scope(parent=self._current_scope),
|
119
124
|
)
|
120
125
|
with self._propagated_var_stack.capture_variables(op):
|
@@ -139,7 +144,7 @@ def _build_inplace_binary_operation(
|
|
139
144
|
value_var: QuantumSymbol,
|
140
145
|
target_var: QuantumSymbol,
|
141
146
|
internal_function_declaration: NamedParamsQuantumFunctionDeclaration,
|
142
|
-
) ->
|
147
|
+
) -> list[QuantumStatement]:
|
143
148
|
if TYPE_CHECKING:
|
144
149
|
assert isinstance(value_var.quantum_type, QuantumNumeric)
|
145
150
|
assert isinstance(target_var.quantum_type, QuantumNumeric)
|
@@ -192,6 +197,54 @@ def _build_inplace_binary_operation(
|
|
192
197
|
]
|
193
198
|
|
194
199
|
|
200
|
+
def _build_inplace_xor_operation(
|
201
|
+
value_var: QuantumSymbol, target_var: QuantumSymbol
|
202
|
+
) -> list[QuantumStatement]:
|
203
|
+
if TYPE_CHECKING:
|
204
|
+
assert isinstance(value_var.quantum_type, QuantumNumeric)
|
205
|
+
assert isinstance(target_var.quantum_type, QuantumNumeric)
|
206
|
+
|
207
|
+
frac_digits_diff = (
|
208
|
+
value_var.quantum_type.fraction_digits_value
|
209
|
+
- target_var.quantum_type.fraction_digits_value
|
210
|
+
)
|
211
|
+
|
212
|
+
target_overlap_var, target_var_decls, target_bind_ops = (
|
213
|
+
_trim_superfluous_fraction_digits("target", target_var, -frac_digits_diff)
|
214
|
+
)
|
215
|
+
value_overlap_var, value_trim_var_decls, value_bind_ops = (
|
216
|
+
_trim_superfluous_fraction_digits("value", value_var, frac_digits_diff)
|
217
|
+
)
|
218
|
+
target_left_var, value_left_var, sign_var_decls, sign_bind_ops, sign_xor = (
|
219
|
+
_split_and_xor_sign(target_overlap_var, value_overlap_var)
|
220
|
+
)
|
221
|
+
|
222
|
+
action: list[QuantumStatement] = []
|
223
|
+
if target_left_var is not None and value_left_var is not None:
|
224
|
+
action.append(
|
225
|
+
_internal_inplace_binary_operation_function_call(
|
226
|
+
integer_xor.func_decl,
|
227
|
+
value_left_var.handle,
|
228
|
+
target_left_var.handle,
|
229
|
+
)
|
230
|
+
)
|
231
|
+
action.extend(sign_xor)
|
232
|
+
|
233
|
+
return [
|
234
|
+
*target_var_decls,
|
235
|
+
*value_trim_var_decls,
|
236
|
+
*sign_var_decls,
|
237
|
+
WithinApply(
|
238
|
+
compute=[
|
239
|
+
*target_bind_ops,
|
240
|
+
*value_bind_ops,
|
241
|
+
*sign_bind_ops,
|
242
|
+
],
|
243
|
+
action=action,
|
244
|
+
),
|
245
|
+
]
|
246
|
+
|
247
|
+
|
195
248
|
def _internal_inplace_binary_operation_function_call(
|
196
249
|
internal_function_declaration: NamedParamsQuantumFunctionDeclaration,
|
197
250
|
value: Union[HandleBinding, Expression],
|
@@ -207,7 +260,7 @@ def _internal_inplace_binary_operation_function_call(
|
|
207
260
|
|
208
261
|
def _trim_superfluous_fraction_digits(
|
209
262
|
kind: str, var: QuantumSymbol, frac_digits_diff: int
|
210
|
-
) ->
|
263
|
+
) -> tuple[QuantumSymbol, list[VariableDeclarationStatement], list[BindOperation]]:
|
211
264
|
if frac_digits_diff <= 0:
|
212
265
|
return var, [], []
|
213
266
|
|
@@ -246,12 +299,12 @@ def _trim_superfluous_fraction_digits(
|
|
246
299
|
return overlap_var, split_var_declarations, [bind_op]
|
247
300
|
|
248
301
|
|
249
|
-
def _pad_with_sign_bit(kind: str, var: QuantumSymbol, size_diff: int) ->
|
302
|
+
def _pad_with_sign_bit(kind: str, var: QuantumSymbol, size_diff: int) -> tuple[
|
250
303
|
QuantumSymbol,
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
304
|
+
list[VariableDeclarationStatement],
|
305
|
+
list[QuantumStatement],
|
306
|
+
list[QuantumFunctionCall],
|
307
|
+
list[BindOperation],
|
255
308
|
]:
|
256
309
|
quantum_type = var.quantum_type
|
257
310
|
if TYPE_CHECKING:
|
@@ -291,7 +344,7 @@ def _pad_with_sign_bit(kind: str, var: QuantumSymbol, size_diff: int) -> Tuple[
|
|
291
344
|
[padding_rebind],
|
292
345
|
)
|
293
346
|
|
294
|
-
significand_var, sign_var, sign_split_bind =
|
347
|
+
significand_var, sign_var, sign_split_bind = _split_var(kind, var, 1)
|
295
348
|
padding_init_ops = _init_padding(sign_var, padding_var, size_diff)
|
296
349
|
|
297
350
|
padding_rebind = BindOperation(
|
@@ -318,7 +371,7 @@ def _pad_with_sign_bit(kind: str, var: QuantumSymbol, size_diff: int) -> Tuple[
|
|
318
371
|
|
319
372
|
def _init_padding(
|
320
373
|
sign_var: QuantumSymbol, padding_var: QuantumSymbol, size_diff: int
|
321
|
-
) ->
|
374
|
+
) -> list[QuantumFunctionCall]:
|
322
375
|
padding_init_ops = [
|
323
376
|
QuantumFunctionCall(
|
324
377
|
function=CX.func_decl.name,
|
@@ -333,7 +386,7 @@ def _init_padding(
|
|
333
386
|
|
334
387
|
def _allocate_padding(
|
335
388
|
kind: str, size_diff: int
|
336
|
-
) ->
|
389
|
+
) -> tuple[QuantumSymbol, QuantumFunctionCall]:
|
337
390
|
padding_var = QuantumSymbol(
|
338
391
|
handle=HandleBinding(name=f"{kind}_sign_padding"),
|
339
392
|
quantum_type=QuantumBitvector(
|
@@ -348,23 +401,95 @@ def _allocate_padding(
|
|
348
401
|
return padding_var, padding_allocation
|
349
402
|
|
350
403
|
|
351
|
-
def
|
352
|
-
kind: str, var: QuantumSymbol
|
353
|
-
) ->
|
354
|
-
|
355
|
-
handle=HandleBinding(name=f"{kind}
|
404
|
+
def _split_var(
|
405
|
+
kind: str, var: QuantumSymbol, right_size: int
|
406
|
+
) -> tuple[QuantumSymbol, QuantumSymbol, BindOperation]:
|
407
|
+
left_var = QuantumSymbol(
|
408
|
+
handle=HandleBinding(name=f"{kind}_left"),
|
356
409
|
quantum_type=QuantumNumeric(
|
357
|
-
size=Expression(expr=str(var.quantum_type.size_in_bits -
|
410
|
+
size=Expression(expr=str(var.quantum_type.size_in_bits - right_size)),
|
358
411
|
is_signed=Expression(expr="False"),
|
359
412
|
fraction_digits=Expression(expr="0"),
|
360
413
|
),
|
361
414
|
)
|
362
|
-
|
363
|
-
handle=HandleBinding(name=f"{kind}
|
364
|
-
quantum_type=
|
415
|
+
right_var = QuantumSymbol(
|
416
|
+
handle=HandleBinding(name=f"{kind}_right"),
|
417
|
+
quantum_type=QuantumNumeric(
|
418
|
+
size=Expression(expr=str(right_size)),
|
419
|
+
is_signed=Expression(expr="False"),
|
420
|
+
fraction_digits=Expression(expr="0"),
|
421
|
+
),
|
365
422
|
)
|
366
|
-
|
423
|
+
split_bind = BindOperation(
|
367
424
|
in_handles=[var.handle],
|
368
|
-
out_handles=[
|
425
|
+
out_handles=[left_var.handle, right_var.handle],
|
426
|
+
)
|
427
|
+
return left_var, right_var, split_bind
|
428
|
+
|
429
|
+
|
430
|
+
def _split_and_xor_sign(target_var: QuantumSymbol, value_var: QuantumSymbol) -> tuple[
|
431
|
+
Optional[QuantumSymbol],
|
432
|
+
Optional[QuantumSymbol],
|
433
|
+
list[VariableDeclarationStatement],
|
434
|
+
list[BindOperation],
|
435
|
+
list[Control],
|
436
|
+
]:
|
437
|
+
if TYPE_CHECKING:
|
438
|
+
assert isinstance(value_var.quantum_type, QuantumNumeric)
|
439
|
+
assert isinstance(target_var.quantum_type, QuantumNumeric)
|
440
|
+
size_diff = (
|
441
|
+
value_var.quantum_type.size_in_bits - target_var.quantum_type.size_in_bits
|
442
|
+
)
|
443
|
+
if not value_var.quantum_type.sign_value or size_diff >= 0:
|
444
|
+
return target_var, value_var, [], [], []
|
445
|
+
|
446
|
+
if value_var.quantum_type.size_in_bits == 1:
|
447
|
+
return None, None, [], [], [_xor_sign(target_var, value_var)]
|
448
|
+
|
449
|
+
value_rest_var, value_sign_var, value_split_bind = _split_var("value", value_var, 1)
|
450
|
+
target_left_var, target_right_var, target_split_bind = _split_var(
|
451
|
+
"target", target_var, -size_diff + 1
|
452
|
+
)
|
453
|
+
var_decls = [
|
454
|
+
VariableDeclarationStatement(
|
455
|
+
name=var.handle.name,
|
456
|
+
quantum_type=var.quantum_type,
|
457
|
+
)
|
458
|
+
for var in (value_rest_var, value_sign_var, target_left_var, target_right_var)
|
459
|
+
]
|
460
|
+
bind_ops = [value_split_bind, target_split_bind]
|
461
|
+
sign_xor = _xor_sign(target_right_var, value_sign_var)
|
462
|
+
return target_left_var, value_rest_var, var_decls, bind_ops, [sign_xor]
|
463
|
+
|
464
|
+
|
465
|
+
def _xor_sign(target_var: QuantumSymbol, value_var: QuantumSymbol) -> Control:
|
466
|
+
quantum_type = value_var.quantum_type
|
467
|
+
if TYPE_CHECKING:
|
468
|
+
assert isinstance(quantum_type, QuantumNumeric)
|
469
|
+
if quantum_type.size_in_bits != 1 or quantum_type.fraction_digits_value not in (
|
470
|
+
0,
|
471
|
+
1,
|
472
|
+
):
|
473
|
+
raise ClassiqInternalExpansionError
|
474
|
+
|
475
|
+
inner_xor = QuantumFunctionCall(
|
476
|
+
function=apply_to_all.func_decl.name,
|
477
|
+
positional_args=["X", target_var.handle],
|
478
|
+
)
|
479
|
+
inner_xor.set_func_decl(apply_to_all.func_decl)
|
480
|
+
|
481
|
+
if quantum_type.sign_value:
|
482
|
+
if quantum_type.fraction_digits_value == 1:
|
483
|
+
ctrl_value = -0.5
|
484
|
+
else:
|
485
|
+
ctrl_value = -1
|
486
|
+
else:
|
487
|
+
if quantum_type.fraction_digits_value == 1:
|
488
|
+
ctrl_value = 0.5
|
489
|
+
else:
|
490
|
+
ctrl_value = 1
|
491
|
+
|
492
|
+
return Control(
|
493
|
+
expression=Expression(expr=f"{value_var.handle} == {ctrl_value}"),
|
494
|
+
body=[inner_xor],
|
369
495
|
)
|
370
|
-
return significand_var, sign_var, sign_split_bind
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import TYPE_CHECKING
|
1
|
+
from typing import TYPE_CHECKING
|
2
2
|
|
3
3
|
import sympy
|
4
4
|
from sympy import sympify
|
@@ -108,8 +108,8 @@ class PhaseEmitter(ExpressionOperationEmitter[PhaseOperation]):
|
|
108
108
|
|
109
109
|
|
110
110
|
def _get_single_bit_vars_expression(
|
111
|
-
expr: sympy.Expr, vars_info:
|
112
|
-
) ->
|
111
|
+
expr: sympy.Expr, vars_info: dict[str, QuantumScalar]
|
112
|
+
) -> tuple[sympy.Expr, list[sympy.Symbol]]:
|
113
113
|
bit_vars = []
|
114
114
|
for var_name, var_info in vars_info.items():
|
115
115
|
size = var_info.size_in_bits
|
@@ -139,9 +139,9 @@ def _get_single_bit_vars_expression(
|
|
139
139
|
|
140
140
|
|
141
141
|
def _convert_ising_sympy_to_pauli_terms(
|
142
|
-
ising_expr: sympy.Expr, ordered_sympy_vars:
|
142
|
+
ising_expr: sympy.Expr, ordered_sympy_vars: list[sympy.Symbol]
|
143
143
|
) -> str:
|
144
|
-
pauli_terms:
|
144
|
+
pauli_terms: list[str] = []
|
145
145
|
coefficients = ising_expr.as_coefficients_dict(*ordered_sympy_vars)
|
146
146
|
for expr_term in ising_expr.args:
|
147
147
|
expr_vars = _get_vars(expr_term)
|
@@ -171,7 +171,7 @@ def _convert_ising_sympy_to_pauli_terms(
|
|
171
171
|
|
172
172
|
def _convert_cost_expression_to_hamiltonian(
|
173
173
|
expr: str,
|
174
|
-
vars:
|
174
|
+
vars: dict[str, QuantumScalar],
|
175
175
|
) -> Expression:
|
176
176
|
sympy_expr = sympify(expr)
|
177
177
|
single_bit_vars_expression, single_bit_vars = _get_single_bit_vars_expression(
|