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,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(
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import ast
|
2
2
|
import re
|
3
|
-
from typing import Tuple
|
4
3
|
|
5
4
|
from classiq.interface.exceptions import (
|
6
5
|
ClassiqExpansionError,
|
@@ -23,6 +22,7 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
23
22
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
24
23
|
from classiq.interface.model.quantum_type import (
|
25
24
|
QuantumNumeric,
|
25
|
+
QuantumType,
|
26
26
|
)
|
27
27
|
from classiq.interface.model.variable_declaration_statement import (
|
28
28
|
VariableDeclarationStatement,
|
@@ -41,6 +41,10 @@ from classiq.model_expansions.visitors.boolean_expression_transformers import (
|
|
41
41
|
from classiq.qmod import builtins
|
42
42
|
from classiq.qmod.builtins.functions import X, allocate
|
43
43
|
|
44
|
+
HANDLE_ERROR_MESSAGE = (
|
45
|
+
"Quantum variable '{handle_str}' cannot appear on both sides of the assignment"
|
46
|
+
)
|
47
|
+
|
44
48
|
|
45
49
|
def _is_constant(expr: str) -> bool:
|
46
50
|
try:
|
@@ -129,7 +133,7 @@ class QuantumAssignmentOperationEmitter(
|
|
129
133
|
|
130
134
|
def _optimize_boolean_expression(
|
131
135
|
self, op: ArithmeticOperation, expression: Expression
|
132
|
-
) ->
|
136
|
+
) -> tuple[ArithmeticOperation, Expression, bool]:
|
133
137
|
if (
|
134
138
|
self._interpreter._is_frontend
|
135
139
|
or op.operation_kind
|
@@ -150,7 +154,7 @@ class QuantumAssignmentOperationEmitter(
|
|
150
154
|
|
151
155
|
def _adapt_boolean_inplace(
|
152
156
|
self, op: ArithmeticOperation, expression: Expression, is_bool_opt: bool
|
153
|
-
) ->
|
157
|
+
) -> tuple[ArithmeticOperation, Expression, bool]:
|
154
158
|
adapter = BooleanExpressionFuncLibAdapter(is_bool_opt)
|
155
159
|
adapted_expression = self._evaluate_expression(
|
156
160
|
Expression(expr=ast.unparse(adapter.visit(ast.parse(expression.expr))))
|
@@ -223,12 +227,28 @@ class QuantumAssignmentOperationEmitter(
|
|
223
227
|
self._interpreter.emit_statement(allocate_call)
|
224
228
|
return True
|
225
229
|
|
230
|
+
@staticmethod
|
231
|
+
def _get_updated_op_split_symbols(
|
232
|
+
op: QuantumAssignmentOperation,
|
233
|
+
symbol_mapping: dict[HandleBinding, tuple[str, QuantumType]],
|
234
|
+
) -> QuantumAssignmentOperation:
|
235
|
+
if op.result_var not in symbol_mapping:
|
236
|
+
return op
|
237
|
+
handle_str, quantum_type = symbol_mapping[op.result_var]
|
238
|
+
if handle_str in op.expression.expr:
|
239
|
+
raise ClassiqExpansionError(
|
240
|
+
HANDLE_ERROR_MESSAGE.format(handle_str=str(op.result_var))
|
241
|
+
)
|
242
|
+
new_result_handle = HandleBinding(name=handle_str)
|
243
|
+
return op.model_copy(
|
244
|
+
update=dict(result_var=new_result_handle, _result_type=quantum_type)
|
245
|
+
)
|
246
|
+
|
226
247
|
|
227
248
|
def _validate_naive_inplace_handles(qe: ArithmeticOperation) -> None:
|
228
249
|
if qe.result_var in qe.var_handles:
|
229
250
|
raise ClassiqExpansionError(
|
230
|
-
|
231
|
-
f"the ^= assignment"
|
251
|
+
HANDLE_ERROR_MESSAGE.format(handle_str=str(qe.result_var))
|
232
252
|
)
|
233
253
|
|
234
254
|
|
@@ -1,15 +1,54 @@
|
|
1
|
+
from typing import TYPE_CHECKING
|
2
|
+
|
1
3
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
2
4
|
|
5
|
+
from classiq.model_expansions.call_to_model_converter import (
|
6
|
+
BlockFunctionInfo,
|
7
|
+
CallToModelConverter,
|
8
|
+
)
|
3
9
|
from classiq.model_expansions.closure import FunctionClosure
|
4
10
|
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
5
11
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
6
12
|
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from classiq.model_expansions.interpreter import Interpreter
|
15
|
+
|
7
16
|
|
8
17
|
class QuantumFunctionCallEmitter(Emitter[QuantumFunctionCall]):
|
18
|
+
def __init__(self, interpreter: "Interpreter") -> None:
|
19
|
+
super().__init__(interpreter)
|
20
|
+
self._model = self._interpreter._model
|
21
|
+
self._synthesized_separately_blocks = (
|
22
|
+
self._interpreter._synthesized_separately_blocks
|
23
|
+
)
|
24
|
+
|
9
25
|
def emit(self, call: QuantumFunctionCall, /) -> None:
|
10
|
-
function = self._interpreter.evaluate(call.function).as_type(
|
26
|
+
function: FunctionClosure = self._interpreter.evaluate(call.function).as_type(
|
27
|
+
FunctionClosure
|
28
|
+
)
|
11
29
|
args = call.positional_args
|
12
30
|
with ErrorManager().call(
|
13
31
|
function.name
|
14
32
|
), function.scope.freeze(), self._propagated_var_stack.capture_variables(call):
|
15
|
-
self._emit_quantum_function_call(function, args)
|
33
|
+
new_call = self._emit_quantum_function_call(function, args)
|
34
|
+
if function.synthesis_data.should_synthesize_separately:
|
35
|
+
interpreted_call_converter = CallToModelConverter(
|
36
|
+
call,
|
37
|
+
function.positional_arg_declarations,
|
38
|
+
function.scope.data,
|
39
|
+
self._model,
|
40
|
+
)
|
41
|
+
self._update_synthesized_separately_models(
|
42
|
+
interpreted_call_converter, new_call.func_name
|
43
|
+
)
|
44
|
+
|
45
|
+
def _update_synthesized_separately_models(
|
46
|
+
self, call_converter: CallToModelConverter, call_name: str
|
47
|
+
) -> None:
|
48
|
+
synthesized_separately_blocks = self._synthesized_separately_blocks
|
49
|
+
block_id = call_converter.block_id
|
50
|
+
block_function = synthesized_separately_blocks.get(block_id)
|
51
|
+
if block_function is None:
|
52
|
+
block_function = BlockFunctionInfo.from_call_converter(call_converter)
|
53
|
+
synthesized_separately_blocks[block_id] = block_function
|
54
|
+
block_function.calls.add(call_name)
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import Type
|
2
|
-
|
3
1
|
from classiq.interface.generator.expressions.expression import Expression
|
4
2
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
5
3
|
REPEAT_OPERATOR_NAME,
|
@@ -24,7 +22,7 @@ class RepeatEmitter(Emitter[Repeat]):
|
|
24
22
|
self._emit_propagated(repeat, i)
|
25
23
|
|
26
24
|
def _emit_propagated(self, repeat: Repeat, i: int) -> None:
|
27
|
-
closure_constructor:
|
25
|
+
closure_constructor: type[FunctionClosure]
|
28
26
|
extra_args: dict
|
29
27
|
if repeat.is_generative():
|
30
28
|
closure_constructor = GenerativeFunctionClosure
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import itertools
|
2
2
|
from collections import UserDict
|
3
|
+
from collections.abc import Iterator
|
3
4
|
from contextlib import contextmanager
|
4
5
|
from dataclasses import dataclass
|
5
6
|
from functools import singledispatch
|
6
|
-
from typing import TYPE_CHECKING, Any,
|
7
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
|
7
8
|
|
8
9
|
from classiq.interface.exceptions import (
|
9
10
|
ClassiqExpansionError,
|
@@ -104,7 +105,7 @@ class QuantumSymbol:
|
|
104
105
|
)
|
105
106
|
|
106
107
|
@property
|
107
|
-
def fields(self) ->
|
108
|
+
def fields(self) -> dict[str, "QuantumSymbol"]:
|
108
109
|
quantum_type = self.quantum_type
|
109
110
|
if not isinstance(quantum_type, TypeName):
|
110
111
|
raise ClassiqExpansionError(
|
@@ -120,18 +121,18 @@ class QuantumSymbol:
|
|
120
121
|
|
121
122
|
|
122
123
|
@singledispatch
|
123
|
-
def
|
124
|
+
def evaluated_to_str(value: Any) -> str:
|
124
125
|
return str(value)
|
125
126
|
|
126
127
|
|
127
|
-
@
|
128
|
+
@evaluated_to_str.register
|
128
129
|
def _evaluated_to_str_list(value: list) -> str:
|
129
|
-
return f"[{', '.join(
|
130
|
+
return f"[{', '.join(evaluated_to_str(x) for x in value)}]"
|
130
131
|
|
131
132
|
|
132
|
-
@
|
133
|
+
@evaluated_to_str.register
|
133
134
|
def _evaluated_to_str_struct_literal(value: QmodStructInstance) -> str:
|
134
|
-
return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={
|
135
|
+
return f"struct_literal({value.struct_declaration.name}, {', '.join(f'{k}={evaluated_to_str(v)}' for k, v in value.fields.items())})"
|
135
136
|
|
136
137
|
|
137
138
|
@dataclass(frozen=True)
|
@@ -139,7 +140,7 @@ class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
|
|
139
140
|
value: Any
|
140
141
|
defining_function: Optional["Closure"] = None
|
141
142
|
|
142
|
-
def as_type(self, t:
|
143
|
+
def as_type(self, t: type[T]) -> T:
|
143
144
|
if t is int:
|
144
145
|
return self._as_int() # type: ignore[return-value]
|
145
146
|
|
@@ -162,7 +163,7 @@ class Evaluated: # FIXME: Merge with EvaluatedExpression if possible
|
|
162
163
|
if isinstance(self.value, QuantumSymbol):
|
163
164
|
return self.value.emit()
|
164
165
|
|
165
|
-
ret = Expression(expr=
|
166
|
+
ret = Expression(expr=evaluated_to_str(self.value))
|
166
167
|
ret._evaluated_expr = EvaluatedExpression(value=self.value)
|
167
168
|
return ret
|
168
169
|
|
@@ -176,7 +177,7 @@ else:
|
|
176
177
|
class Scope(EvaluatedUserDict):
|
177
178
|
def __init__(
|
178
179
|
self,
|
179
|
-
data: Optional[
|
180
|
+
data: Optional[dict[str, Evaluated]] = None,
|
180
181
|
/,
|
181
182
|
*,
|
182
183
|
parent: Optional["Scope"] = None,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Sequence
|
2
2
|
|
3
3
|
from classiq.interface.exceptions import ClassiqError
|
4
4
|
from classiq.interface.generator.constant import Constant
|
@@ -43,7 +43,7 @@ def get_main_renamer(
|
|
43
43
|
return ExpressionRenamer(var_mapping={})
|
44
44
|
|
45
45
|
|
46
|
-
def _add_constants_to_scope(constants:
|
46
|
+
def _add_constants_to_scope(constants: list[Constant], scope: Scope) -> None:
|
47
47
|
for constant in constants:
|
48
48
|
scope[constant.name] = Evaluated(
|
49
49
|
value=evaluate_classical_expression(constant.value, scope).value
|
@@ -51,7 +51,7 @@ def _add_constants_to_scope(constants: List[Constant], scope: Scope) -> None:
|
|
51
51
|
|
52
52
|
|
53
53
|
def _add_functions_to_scope(
|
54
|
-
functions:
|
54
|
+
functions: list[NativeFunctionDefinition], scope: Scope
|
55
55
|
) -> None:
|
56
56
|
for function in functions:
|
57
57
|
scope[function.name] = Evaluated(
|
@@ -60,12 +60,13 @@ def _add_functions_to_scope(
|
|
60
60
|
positional_arg_declarations=function.positional_arg_declarations,
|
61
61
|
body=function.body,
|
62
62
|
scope=Scope(parent=scope),
|
63
|
+
synthesis_data=function.synthesis_data,
|
63
64
|
)
|
64
65
|
)
|
65
66
|
|
66
67
|
|
67
68
|
def _add_generative_functions_to_scope(
|
68
|
-
functions:
|
69
|
+
functions: list[GenerativeQFunc], scope: Scope
|
69
70
|
) -> None:
|
70
71
|
for function in functions:
|
71
72
|
scope[function.func_decl.name] = Evaluated(
|
@@ -138,7 +139,7 @@ def add_entry_point_params_to_scope(
|
|
138
139
|
|
139
140
|
|
140
141
|
def init_top_level_scope(
|
141
|
-
model: Model, generative_functions:
|
142
|
+
model: Model, generative_functions: list[GenerativeQFunc], scope: Scope
|
142
143
|
) -> None:
|
143
144
|
_add_functions_to_scope(model.functions, scope)
|
144
145
|
_add_generative_functions_to_scope(generative_functions, scope)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import ast
|
2
|
-
from typing import TYPE_CHECKING,
|
2
|
+
from typing import TYPE_CHECKING, cast
|
3
3
|
|
4
4
|
from classiq.interface.exceptions import ClassiqExpansionError
|
5
5
|
|
@@ -18,29 +18,29 @@ def translate_to_sympy(expr: str) -> str:
|
|
18
18
|
|
19
19
|
|
20
20
|
class ExpressionSympyTranslator(ast.NodeTransformer):
|
21
|
-
BINARY_OPERATORS:
|
21
|
+
BINARY_OPERATORS: dict[type[ast.AST], str] = {
|
22
22
|
ast.BitOr: "BitwiseOr",
|
23
23
|
ast.BitAnd: "BitwiseAnd",
|
24
24
|
ast.BitXor: "BitwiseXor",
|
25
25
|
ast.Div: "do_div",
|
26
26
|
}
|
27
27
|
|
28
|
-
UNARY_OPERATORS:
|
28
|
+
UNARY_OPERATORS: dict[type[ast.AST], str] = {
|
29
29
|
ast.Invert: "BitwiseNot",
|
30
30
|
ast.Not: "Not",
|
31
31
|
}
|
32
32
|
|
33
|
-
BOOLEAN_OPERATORS:
|
33
|
+
BOOLEAN_OPERATORS: dict[type[ast.AST], str] = {
|
34
34
|
ast.Or: "Or",
|
35
35
|
ast.And: "And",
|
36
36
|
}
|
37
37
|
|
38
|
-
COMPARE_OPERATORS:
|
38
|
+
COMPARE_OPERATORS: dict[type[ast.AST], str] = {
|
39
39
|
ast.Eq: "Eq",
|
40
40
|
ast.NotEq: "Ne",
|
41
41
|
}
|
42
42
|
|
43
|
-
SPECIAL_FUNCTIONS:
|
43
|
+
SPECIAL_FUNCTIONS: dict[str, str] = {
|
44
44
|
"max": "Max",
|
45
45
|
"min": "Min",
|
46
46
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import functools
|
2
|
-
from typing import Any,
|
2
|
+
from typing import Any, Optional, get_args
|
3
3
|
|
4
4
|
from sympy import (
|
5
5
|
Array,
|
@@ -22,7 +22,7 @@ from classiq.model_expansions.sympy_conversion.arithmetics import LogicalXor
|
|
22
22
|
|
23
23
|
|
24
24
|
def sympy_to_python(
|
25
|
-
value: Any, locals: Optional[
|
25
|
+
value: Any, locals: Optional[dict[str, ExpressionValue]] = None
|
26
26
|
) -> ExpressionValue:
|
27
27
|
if isinstance(value, Integer):
|
28
28
|
value = int(value)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import ast
|
2
|
+
from collections.abc import Iterator
|
2
3
|
from contextlib import contextmanager
|
3
|
-
from typing import
|
4
|
+
from typing import Optional, Union
|
4
5
|
|
5
6
|
from classiq.interface.exceptions import (
|
6
7
|
ClassiqExpansionError,
|
@@ -23,12 +24,12 @@ from classiq.interface.model.handle_binding import (
|
|
23
24
|
|
24
25
|
class VarRefCollector(ast.NodeVisitor):
|
25
26
|
def __init__(self, ignore_duplicated_handles: bool = False) -> None:
|
26
|
-
self._var_handles:
|
27
|
+
self._var_handles: dict[HandleBinding, bool] = {}
|
27
28
|
self._ignore_duplicated_handles = ignore_duplicated_handles
|
28
29
|
self._is_nested = False
|
29
30
|
|
30
31
|
@property
|
31
|
-
def var_handles(self) ->
|
32
|
+
def var_handles(self) -> list[HandleBinding]:
|
32
33
|
return list(self._var_handles)
|
33
34
|
|
34
35
|
def visit(self, node: ast.AST) -> Union[
|
@@ -110,7 +111,7 @@ class VarRefCollector(ast.NodeVisitor):
|
|
110
111
|
|
111
112
|
|
112
113
|
class VarRefTransformer(ast.NodeTransformer):
|
113
|
-
def __init__(self, var_mapping:
|
114
|
+
def __init__(self, var_mapping: dict[str, str]) -> None:
|
114
115
|
self.var_mapping = var_mapping
|
115
116
|
|
116
117
|
def visit_Name(self, node: ast.Name) -> ast.Name:
|