classiq 0.37.1__py3-none-any.whl → 0.39.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 +23 -24
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +37 -17
- classiq/_internals/async_utils.py +1 -74
- classiq/_internals/authentication/device.py +9 -4
- classiq/_internals/authentication/password_manager.py +25 -10
- classiq/_internals/authentication/token_manager.py +2 -2
- classiq/_internals/client.py +24 -6
- classiq/_internals/jobs.py +10 -7
- classiq/analyzer/analyzer.py +29 -29
- classiq/analyzer/analyzer_utilities.py +5 -5
- classiq/analyzer/rb.py +4 -5
- classiq/analyzer/show_interactive_hack.py +6 -6
- classiq/applications/__init__.py +1 -8
- classiq/applications/chemistry/__init__.py +6 -0
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +9 -16
- classiq/applications/combinatorial_helpers/allowed_constraints.py +20 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +150 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +122 -0
- classiq/applications/combinatorial_helpers/memory.py +77 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +162 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +75 -0
- classiq/applications/combinatorial_helpers/py.typed +0 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +245 -0
- classiq/applications/combinatorial_helpers/solvers/__init__.py +0 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/__init__.py +0 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +187 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +142 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +122 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +32 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +75 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +88 -0
- classiq/applications/combinatorial_optimization/__init__.py +13 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +134 -0
- classiq/applications/finance/__init__.py +3 -2
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +27 -30
- classiq/applications/grover/__init__.py +11 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +20 -91
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +35 -0
- classiq/applications/qnn/circuit_utils.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/types.py +2 -2
- classiq/applications/qsvm/__init__.py +5 -1
- classiq/applications/qsvm/qsvm.py +4 -7
- classiq/applications/qsvm/qsvm_data_generation.py +2 -5
- classiq/exceptions.py +43 -1
- classiq/execution/all_hardware_devices.py +13 -0
- classiq/executor.py +12 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +6 -3
- classiq/interface/analyzer/result.py +12 -8
- classiq/interface/applications/qsvm.py +17 -3
- classiq/interface/ast_node.py +23 -0
- classiq/interface/backend/backend_preferences.py +4 -2
- classiq/interface/backend/pydantic_backend.py +3 -1
- classiq/interface/backend/quantum_backend_providers.py +1 -0
- classiq/interface/chemistry/fermionic_operator.py +15 -13
- classiq/interface/chemistry/ground_state_problem.py +18 -3
- classiq/interface/chemistry/molecule.py +8 -6
- classiq/interface/chemistry/operator.py +20 -14
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -1
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -2
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +8 -3
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/set_cover.py +2 -1
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +9 -3
- classiq/interface/executor/aws_execution_cost.py +4 -3
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +5 -34
- classiq/interface/executor/execution_request.py +15 -48
- classiq/interface/executor/optimizer_preferences.py +22 -13
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +21 -15
- classiq/interface/executor/quantum_instruction_set.py +2 -1
- classiq/interface/executor/register_initialization.py +1 -3
- classiq/interface/executor/result.py +41 -10
- classiq/interface/executor/vqe_result.py +2 -2
- classiq/interface/finance/function_input.py +17 -4
- classiq/interface/finance/gaussian_model_input.py +3 -1
- classiq/interface/finance/log_normal_model_input.py +3 -1
- classiq/interface/finance/model_input.py +2 -0
- classiq/interface/generator/amplitude_loading.py +6 -3
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +14 -0
- classiq/interface/generator/arith/argument_utils.py +14 -4
- classiq/interface/generator/arith/arithmetic.py +3 -1
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +12 -13
- classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -1
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -2
- classiq/interface/generator/arith/arithmetic_expression_validator.py +16 -2
- classiq/interface/generator/arith/arithmetic_operations.py +5 -10
- classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
- classiq/interface/generator/arith/binary_ops.py +202 -54
- classiq/interface/generator/arith/extremum_operations.py +5 -3
- classiq/interface/generator/arith/logical_ops.py +4 -2
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +34 -44
- classiq/interface/generator/arith/register_user_input.py +21 -1
- classiq/interface/generator/arith/unary_ops.py +16 -25
- classiq/interface/generator/builtin_api_builder.py +0 -5
- classiq/interface/generator/chemistry_function_params.py +4 -4
- classiq/interface/generator/commuting_pauli_exponentiation.py +3 -1
- classiq/interface/generator/compiler_keywords.py +4 -0
- classiq/interface/generator/complex_type.py +3 -10
- classiq/interface/generator/constant.py +2 -3
- classiq/interface/generator/control_state.py +5 -3
- classiq/interface/generator/credit_risk_example/linear_gci.py +10 -3
- classiq/interface/generator/credit_risk_example/weighted_adder.py +14 -4
- classiq/interface/generator/expressions/atomic_expression_functions.py +5 -3
- classiq/interface/generator/expressions/evaluated_expression.py +18 -4
- classiq/interface/generator/expressions/expression.py +3 -5
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +33 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/finance.py +1 -1
- classiq/interface/generator/function_params.py +7 -6
- classiq/interface/generator/functions/__init__.py +2 -2
- classiq/interface/generator/functions/builtins/__init__.py +15 -0
- classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
- classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
- classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +612 -219
- classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
- classiq/interface/generator/functions/classical_type.py +2 -4
- classiq/interface/generator/functions/foreign_function_definition.py +12 -4
- classiq/interface/generator/functions/function_declaration.py +2 -2
- classiq/interface/generator/functions/function_implementation.py +8 -4
- classiq/interface/generator/functions/native_function_definition.py +4 -2
- classiq/interface/generator/functions/register.py +4 -2
- classiq/interface/generator/functions/register_mapping_data.py +14 -10
- classiq/interface/generator/generated_circuit_data.py +2 -2
- classiq/interface/generator/grover_operator.py +5 -3
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +5 -1
- classiq/interface/generator/hardware/hardware_data.py +6 -4
- classiq/interface/generator/hardware_efficient_ansatz.py +25 -8
- classiq/interface/generator/hartree_fock.py +13 -3
- classiq/interface/generator/linear_pauli_rotations.py +3 -1
- classiq/interface/generator/mcu.py +5 -3
- classiq/interface/generator/mcx.py +7 -5
- classiq/interface/generator/model/classical_main_validator.py +1 -1
- classiq/interface/generator/model/constraints.py +2 -1
- classiq/interface/generator/model/model.py +12 -20
- classiq/interface/generator/model/preferences/preferences.py +4 -3
- classiq/interface/generator/oracles/custom_oracle.py +4 -2
- classiq/interface/generator/oracles/oracle_abc.py +2 -2
- classiq/interface/generator/qpe.py +6 -4
- classiq/interface/generator/qsvm.py +5 -8
- classiq/interface/generator/quantum_function_call.py +21 -16
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +10 -14
- classiq/interface/generator/range_types.py +3 -1
- classiq/interface/generator/slice_parsing_utils.py +8 -3
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +4 -2
- classiq/interface/generator/state_preparation/metrics.py +2 -1
- classiq/interface/generator/state_preparation/state_preparation.py +7 -5
- classiq/interface/generator/state_propagator.py +16 -5
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/struct_declaration.py +10 -7
- classiq/interface/generator/ucc.py +6 -4
- classiq/interface/generator/unitary_gate.py +7 -3
- classiq/interface/generator/validations/flow_graph.py +6 -4
- classiq/interface/generator/validations/validator_functions.py +6 -4
- classiq/interface/hardware.py +2 -2
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/pydantic_model_helpers.py +0 -6
- classiq/interface/helpers/validation_helpers.py +1 -1
- classiq/interface/helpers/versioned_model.py +4 -1
- classiq/interface/ide/show.py +2 -2
- classiq/interface/jobs.py +72 -3
- classiq/interface/model/bind_operation.py +18 -11
- classiq/interface/model/call_synthesis_data.py +68 -0
- classiq/interface/model/classical_if.py +13 -0
- classiq/interface/model/classical_parameter_declaration.py +2 -3
- classiq/interface/model/control.py +16 -0
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/invert.py +10 -0
- classiq/interface/model/model.py +29 -22
- classiq/interface/model/native_function_definition.py +3 -5
- classiq/interface/model/power.py +12 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +9 -4
- classiq/interface/model/quantum_expressions/control_state.py +2 -2
- classiq/interface/model/quantum_function_call.py +33 -142
- classiq/interface/model/quantum_function_declaration.py +8 -0
- classiq/interface/model/quantum_if_operation.py +4 -5
- classiq/interface/model/quantum_lambda_function.py +58 -0
- classiq/{quantum_register.py → interface/model/quantum_register.py} +17 -9
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/model/quantum_type.py +58 -59
- classiq/interface/model/quantum_variable_declaration.py +3 -3
- classiq/interface/model/repeat.py +13 -0
- classiq/interface/model/resolvers/function_call_resolver.py +26 -0
- classiq/interface/model/statement_block.py +49 -0
- classiq/interface/model/validations/handles_validator.py +16 -18
- classiq/interface/model/within_apply_operation.py +11 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/routes.py +5 -4
- classiq/qmod/__init__.py +13 -6
- classiq/qmod/builtins/classical_execution_primitives.py +27 -36
- classiq/qmod/builtins/classical_functions.py +22 -12
- classiq/qmod/builtins/functions.py +272 -328
- classiq/qmod/builtins/operations.py +171 -35
- classiq/qmod/builtins/structs.py +15 -15
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +6 -14
- classiq/qmod/declaration_inferrer.py +12 -21
- classiq/qmod/expression_query.py +23 -0
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/__init__.py +0 -0
- classiq/qmod/native/expression_to_qmod.py +189 -0
- classiq/qmod/native/pretty_printer.py +340 -0
- classiq/qmod/qfunc.py +27 -0
- classiq/qmod/qmod_constant.py +100 -0
- classiq/qmod/qmod_parameter.py +36 -13
- classiq/qmod/qmod_struct.py +3 -3
- classiq/qmod/qmod_variable.py +148 -31
- classiq/qmod/quantum_callable.py +1 -0
- classiq/qmod/quantum_expandable.py +18 -19
- classiq/qmod/quantum_function.py +41 -8
- classiq/qmod/symbolic.py +48 -5
- classiq/qmod/symbolic_expr.py +9 -0
- classiq/qmod/utilities.py +13 -0
- classiq/qmod/write_qmod.py +39 -0
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/METADATA +2 -1
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/RECORD +244 -225
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/WHEEL +1 -1
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/model/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/pauli_helpers/__init__.py} +0 -0
- /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
- /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
- /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
- /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
@@ -6,10 +6,10 @@ from classiq.interface.generator.arith.register_user_input import RegisterArithm
|
|
6
6
|
RegisterOrConst = Union[RegisterArithmeticInfo, float]
|
7
7
|
|
8
8
|
|
9
|
-
def fraction_places(argument: RegisterOrConst
|
9
|
+
def fraction_places(argument: RegisterOrConst) -> int:
|
10
10
|
if isinstance(argument, RegisterArithmeticInfo):
|
11
11
|
return argument.fraction_places
|
12
|
-
return number_utils.fraction_places(argument
|
12
|
+
return number_utils.fraction_places(argument)
|
13
13
|
|
14
14
|
|
15
15
|
def integer_part_size(argument: RegisterOrConst) -> int:
|
@@ -18,10 +18,10 @@ def integer_part_size(argument: RegisterOrConst) -> int:
|
|
18
18
|
return number_utils.integer_part_size(argument)
|
19
19
|
|
20
20
|
|
21
|
-
def size(argument: RegisterOrConst
|
21
|
+
def size(argument: RegisterOrConst) -> int:
|
22
22
|
if isinstance(argument, RegisterArithmeticInfo):
|
23
23
|
return argument.size
|
24
|
-
return number_utils.size(argument
|
24
|
+
return number_utils.size(argument)
|
25
25
|
|
26
26
|
|
27
27
|
def is_signed(argument: RegisterOrConst) -> bool:
|
@@ -46,3 +46,13 @@ def bounds(argument: RegisterOrConst) -> Tuple[float, float]:
|
|
46
46
|
if isinstance(argument, RegisterArithmeticInfo):
|
47
47
|
return argument.bounds
|
48
48
|
return argument, argument
|
49
|
+
|
50
|
+
|
51
|
+
def limit_fraction_places(
|
52
|
+
argument: RegisterOrConst, *, machine_precision: int
|
53
|
+
) -> RegisterOrConst:
|
54
|
+
if isinstance(argument, RegisterArithmeticInfo):
|
55
|
+
return argument.limit_fraction_places(machine_precision)
|
56
|
+
return number_utils.limit_fraction_places(
|
57
|
+
argument, machine_precision=machine_precision
|
58
|
+
)
|
@@ -21,6 +21,8 @@ from classiq.interface.model.quantum_type import (
|
|
21
21
|
register_info_to_quantum_type,
|
22
22
|
)
|
23
23
|
|
24
|
+
from classiq.exceptions import ClassiqValueError
|
25
|
+
|
24
26
|
ARITHMETIC_EXPRESSION_TARGET_NAME: str = "arithmetic_target"
|
25
27
|
ARITHMETIC_EXPRESSION_RESULT_NAME: str = "expression_result"
|
26
28
|
|
@@ -47,7 +49,7 @@ class Arithmetic(ArithmeticExpressionABC):
|
|
47
49
|
degree or operation_allows_target(id2op(node))
|
48
50
|
for node, degree in graph.out_degree
|
49
51
|
):
|
50
|
-
raise
|
52
|
+
raise ClassiqValueError("Expression does not support target assignment")
|
51
53
|
|
52
54
|
def _create_ios(self) -> None:
|
53
55
|
self._inputs = {
|
@@ -2,23 +2,16 @@ from typing import Callable, Dict, List
|
|
2
2
|
|
3
3
|
from typing_extensions import TypeAlias
|
4
4
|
|
5
|
-
from classiq.interface.generator.arith
|
6
|
-
RegisterOrConst,
|
7
|
-
fraction_places,
|
8
|
-
)
|
5
|
+
from classiq.interface.generator.arith import argument_utils
|
9
6
|
from classiq.interface.generator.arith.binary_ops import BOOLEAN_OP_WITH_FRACTIONS_ERROR
|
10
7
|
|
11
8
|
from classiq.exceptions import ClassiqArithmeticError
|
12
9
|
|
13
|
-
ArgTypeValidator: TypeAlias = Callable[[List[RegisterOrConst]
|
10
|
+
ArgTypeValidator: TypeAlias = Callable[[List[argument_utils.RegisterOrConst]], None]
|
14
11
|
|
15
12
|
|
16
|
-
def _validate_bitwise_op_args(
|
17
|
-
|
18
|
-
) -> None:
|
19
|
-
if any(
|
20
|
-
fraction_places(arg, machine_precision=machine_precision) > 0 for arg in args
|
21
|
-
):
|
13
|
+
def _validate_bitwise_op_args(args: List[argument_utils.RegisterOrConst]) -> None:
|
14
|
+
if any(argument_utils.fraction_places(arg) > 0 for arg in args):
|
22
15
|
raise ClassiqArithmeticError(BOOLEAN_OP_WITH_FRACTIONS_ERROR)
|
23
16
|
|
24
17
|
|
@@ -30,8 +23,14 @@ arg_type_validator_map: Dict[str, ArgTypeValidator] = dict(
|
|
30
23
|
|
31
24
|
|
32
25
|
def validate_operation_arg_types(
|
33
|
-
operation: str,
|
26
|
+
operation: str,
|
27
|
+
arguments: List[argument_utils.RegisterOrConst],
|
28
|
+
machine_precision: int,
|
34
29
|
) -> None:
|
35
30
|
if operation not in arg_type_validator_map:
|
36
31
|
return
|
37
|
-
|
32
|
+
limited_args = [
|
33
|
+
argument_utils.limit_fraction_places(arg, machine_precision=machine_precision)
|
34
|
+
for arg in arguments
|
35
|
+
]
|
36
|
+
arg_type_validator_map[operation](limited_args)
|
@@ -17,6 +17,9 @@ from classiq.interface.generator.arith.arithmetic_expression_validator import (
|
|
17
17
|
from classiq.interface.generator.arith.arithmetic_result_builder import (
|
18
18
|
validate_arithmetic_result_type,
|
19
19
|
)
|
20
|
+
from classiq.interface.generator.arith.machine_precision import (
|
21
|
+
DEFAULT_MACHINE_PRECISION,
|
22
|
+
)
|
20
23
|
from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
|
21
24
|
from classiq.interface.generator.arith.uncomputation_methods import UncomputationMethods
|
22
25
|
from classiq.interface.generator.expressions.expression_constants import (
|
@@ -36,7 +39,7 @@ ValidDefinitions: TypeAlias = Union[
|
|
36
39
|
|
37
40
|
class ArithmeticExpressionABC(abc.ABC, FunctionParams):
|
38
41
|
uncomputation_method: UncomputationMethods = UncomputationMethods.optimized
|
39
|
-
machine_precision: pydantic.NonNegativeInt =
|
42
|
+
machine_precision: pydantic.NonNegativeInt = DEFAULT_MACHINE_PRECISION
|
40
43
|
expression: PydanticExpressionStr
|
41
44
|
definitions: Dict[str, ValidDefinitions]
|
42
45
|
qubit_count: Optional[pydantic.NonNegativeInt] = None
|
@@ -19,7 +19,9 @@ from classiq.interface.generator.arith.ast_node_rewrite import (
|
|
19
19
|
from classiq.exceptions import ClassiqArithmeticError
|
20
20
|
|
21
21
|
_MULTIPLE_RESULTS_ERROR_MESSAGE: str = "Expression cannot contain multiple result"
|
22
|
-
|
22
|
+
_UNEXPECTED_ARITHMETIC_ERROR_MESSAGE: str = (
|
23
|
+
"Unexpected arithmetic error: trivial expression. Please contact support."
|
24
|
+
)
|
23
25
|
_ALLOWED_MULTI_ARGUMENT_FUNCTIONS = ("min", "max")
|
24
26
|
Node = Union[str, float, int]
|
25
27
|
|
@@ -34,6 +36,10 @@ class ExpressionVisitor(ExpressionValidator):
|
|
34
36
|
super().__init__(supported_nodes, expression_type, supported_functions)
|
35
37
|
self.graph = nx.DiGraph()
|
36
38
|
|
39
|
+
@classmethod
|
40
|
+
def rewrite_ast(cls, expression_ast: AST) -> AST:
|
41
|
+
return AstNodeRewrite().visit(expression_ast)
|
42
|
+
|
37
43
|
def visit_Compare(self, node: ast.Compare) -> None:
|
38
44
|
self.validate_Compare(node)
|
39
45
|
self.update_graph(node, node.left, node.comparators[0])
|
@@ -122,7 +128,7 @@ class InDegreeLimiter:
|
|
122
128
|
if num_results > 1:
|
123
129
|
raise ClassiqArithmeticError(_MULTIPLE_RESULTS_ERROR_MESSAGE)
|
124
130
|
elif num_results == 0:
|
125
|
-
raise ClassiqArithmeticError(
|
131
|
+
raise ClassiqArithmeticError(_UNEXPECTED_ARITHMETIC_ERROR_MESSAGE)
|
126
132
|
return graph
|
127
133
|
|
128
134
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import ast
|
2
2
|
import builtins
|
3
|
+
import re
|
3
4
|
from _ast import AST
|
4
5
|
from typing import Any, Optional, Set, Tuple, Type, Union
|
5
6
|
|
@@ -15,6 +16,7 @@ from classiq.exceptions import ClassiqArithmeticError, ClassiqValueError
|
|
15
16
|
DEFAULT_SUPPORTED_FUNC_NAMES: Set[str] = {"CLShift", "CRShift", "min", "max"}
|
16
17
|
|
17
18
|
DEFAULT_EXPRESSION_TYPE = "arithmetic"
|
19
|
+
IDENITIFIER_REGEX = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*")
|
18
20
|
|
19
21
|
_REPEATED_VARIABLES_ERROR_MESSAGE: str = (
|
20
22
|
"Repeated variables in the beginning of an arithmetic expression are not allowed."
|
@@ -75,17 +77,25 @@ class ExpressionValidator(ast.NodeVisitor):
|
|
75
77
|
|
76
78
|
def validate(self, expression: str) -> None:
|
77
79
|
try:
|
78
|
-
|
80
|
+
adjusted_expression = self._get_adjusted_expression(expression)
|
81
|
+
ast_expr = ast.parse(adjusted_expression, filename="", mode=self._mode)
|
79
82
|
except SyntaxError as e:
|
80
83
|
raise ClassiqValueError(f"Failed to parse expression {expression!r}") from e
|
81
84
|
try:
|
82
|
-
self._ast_obj =
|
85
|
+
self._ast_obj = self.rewrite_ast(ast_expr)
|
83
86
|
self.visit(self._ast_obj)
|
84
87
|
except RecursionError as e:
|
85
88
|
raise ClassiqValueError(
|
86
89
|
f"Failed to parse expression since it is too long: {expression}"
|
87
90
|
) from e
|
88
91
|
|
92
|
+
@staticmethod
|
93
|
+
def _get_adjusted_expression(expression: str) -> str:
|
94
|
+
# This works around the simplification of the trivial expressions such as a + 0, 1 * a, etc.
|
95
|
+
if IDENITIFIER_REGEX.fullmatch(expression):
|
96
|
+
return f"0 + {expression}"
|
97
|
+
return expression
|
98
|
+
|
89
99
|
@property
|
90
100
|
def ast_obj(self) -> ast.AST:
|
91
101
|
if not self._ast_obj:
|
@@ -182,6 +192,10 @@ class ExpressionValidator(ast.NodeVisitor):
|
|
182
192
|
self._supported_functions.add(node.name)
|
183
193
|
self.generic_visit(node)
|
184
194
|
|
195
|
+
@classmethod
|
196
|
+
def rewrite_ast(cls, expression_ast: AST) -> AST:
|
197
|
+
return expression_ast
|
198
|
+
|
185
199
|
|
186
200
|
def validate_expression(
|
187
201
|
expression: str,
|
@@ -1,11 +1,11 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
1
|
import abc
|
4
2
|
from typing import ClassVar, Iterable, Optional, Tuple
|
5
3
|
|
6
4
|
import pydantic
|
7
5
|
|
8
|
-
from classiq.interface.generator.arith import
|
6
|
+
from classiq.interface.generator.arith.machine_precision import (
|
7
|
+
DEFAULT_MACHINE_PRECISION,
|
8
|
+
)
|
9
9
|
from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
|
10
10
|
from classiq.interface.generator.function_params import FunctionParams
|
11
11
|
|
@@ -14,7 +14,7 @@ DEFAULT_GARBAGE_OUT_NAME: str = "extra_qubits"
|
|
14
14
|
|
15
15
|
class ArithmeticOperationParams(FunctionParams):
|
16
16
|
output_size: Optional[pydantic.PositiveInt]
|
17
|
-
machine_precision: pydantic.PositiveInt =
|
17
|
+
machine_precision: pydantic.PositiveInt = DEFAULT_MACHINE_PRECISION
|
18
18
|
output_name: ClassVar[str]
|
19
19
|
garbage_output_name: ClassVar[str] = DEFAULT_GARBAGE_OUT_NAME
|
20
20
|
_result_register: Optional[RegisterArithmeticInfo] = pydantic.PrivateAttr(
|
@@ -46,11 +46,6 @@ class ArithmeticOperationParams(FunctionParams):
|
|
46
46
|
return suggested_bounds
|
47
47
|
return None
|
48
48
|
|
49
|
-
def _compute_fraction_places(self, argument: argument_utils.RegisterOrConst) -> int:
|
50
|
-
return argument_utils.fraction_places(
|
51
|
-
argument, machine_precision=self.machine_precision
|
52
|
-
)
|
53
|
-
|
54
49
|
@abc.abstractmethod
|
55
|
-
def get_params_inplace_options(self) -> Iterable[ArithmeticOperationParams]:
|
50
|
+
def get_params_inplace_options(self) -> Iterable["ArithmeticOperationParams"]:
|
56
51
|
pass
|
@@ -30,7 +30,7 @@ class AstNodeRewrite(ast.NodeTransformer):
|
|
30
30
|
elif hasattr(node, "op"):
|
31
31
|
return type(node.op).__name__ + next(self.count_str_gen)
|
32
32
|
elif hasattr(node, "func"):
|
33
|
-
return node.func
|
33
|
+
return self.extract_node_id(node.func)
|
34
34
|
elif hasattr(node, "value"):
|
35
35
|
return node.value
|
36
36
|
elif hasattr(node, "ops"):
|