classiq 0.93.0__py3-none-any.whl → 0.94.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of classiq might be problematic. Click here for more details.
- classiq/__init__.py +6 -19
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
- classiq/_analyzer_extras/interactive_hardware.py +19 -12
- classiq/_internals/api_wrapper.py +38 -52
- classiq/_internals/async_utils.py +4 -7
- classiq/_internals/authentication/auth0.py +3 -3
- classiq/_internals/authentication/device.py +4 -4
- classiq/_internals/authentication/password_manager.py +13 -13
- classiq/_internals/authentication/token_manager.py +4 -5
- classiq/_internals/client.py +17 -44
- classiq/_internals/config.py +1 -2
- classiq/_internals/help.py +1 -2
- classiq/_internals/host_checker.py +3 -3
- classiq/_internals/jobs.py +14 -14
- classiq/_internals/type_validation.py +3 -3
- classiq/analyzer/analyzer.py +18 -18
- classiq/analyzer/rb.py +17 -8
- classiq/applications/chemistry/__init__.py +0 -30
- classiq/applications/chemistry/op_utils.py +4 -4
- classiq/applications/chemistry/problems.py +3 -3
- classiq/applications/chemistry/ucc.py +1 -2
- classiq/applications/chemistry/z2_symmetries.py +4 -4
- classiq/applications/combinatorial_helpers/allowed_constraints.py +1 -3
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +2 -1
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +2 -2
- classiq/applications/combinatorial_helpers/encoding_mapping.py +2 -3
- classiq/applications/combinatorial_helpers/encoding_utils.py +2 -2
- classiq/applications/combinatorial_helpers/optimization_model.py +3 -4
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +2 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +8 -8
- classiq/applications/combinatorial_helpers/sympy_utils.py +1 -3
- classiq/applications/combinatorial_helpers/transformations/encoding.py +3 -3
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +1 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -3
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +15 -10
- classiq/applications/hamiltonian/pauli_decomposition.py +6 -4
- classiq/applications/iqae/iqae.py +8 -8
- classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
- classiq/applications/qnn/datasets/dataset_parity.py +6 -6
- classiq/applications/qnn/qlayer.py +8 -7
- classiq/applications/qnn/torch_utils.py +3 -4
- classiq/applications/qnn/types.py +2 -1
- classiq/applications/qsp/qsp.py +5 -4
- classiq/applications/qsvm/qsvm_data_generation.py +1 -2
- classiq/evaluators/classical_expression.py +0 -4
- classiq/evaluators/parameter_types.py +7 -8
- classiq/evaluators/qmod_annotated_expression.py +24 -26
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +14 -14
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +2 -1
- classiq/evaluators/qmod_expression_visitors/sympy_wrappers.py +8 -8
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +4 -4
- classiq/evaluators/qmod_node_evaluators/list_evaluation.py +2 -2
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +3 -3
- classiq/evaluators/qmod_node_evaluators/subscript_evaluation.py +9 -9
- classiq/evaluators/qmod_node_evaluators/utils.py +6 -6
- classiq/evaluators/qmod_type_inference/classical_type_inference.py +9 -10
- classiq/evaluators/qmod_type_inference/quantum_type_inference.py +5 -5
- classiq/execution/execution_session.py +18 -19
- classiq/execution/jobs.py +26 -26
- classiq/execution/qnn.py +1 -2
- classiq/execution/user_budgets.py +52 -7
- classiq/executor.py +1 -3
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +4 -4
- classiq/interface/analyzer/cytoscape_graph.py +3 -3
- classiq/interface/analyzer/result.py +4 -4
- classiq/interface/applications/qsvm.py +5 -8
- classiq/interface/ast_node.py +3 -3
- classiq/interface/backend/backend_preferences.py +16 -16
- classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
- classiq/interface/chemistry/ansatz_library.py +3 -5
- classiq/interface/chemistry/operator.py +3 -3
- classiq/interface/combinatorial_optimization/examples/knapsack.py +2 -4
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +1 -2
- classiq/interface/compression_utils.py +2 -3
- classiq/interface/debug_info/debug_info.py +7 -7
- classiq/interface/exceptions.py +2 -3
- classiq/interface/execution/iqcc.py +1 -3
- classiq/interface/execution/primitives.py +6 -6
- classiq/interface/executor/estimate_cost.py +1 -1
- classiq/interface/executor/execution_preferences.py +3 -5
- classiq/interface/executor/execution_request.py +10 -10
- classiq/interface/executor/execution_result.py +1 -2
- classiq/interface/executor/quantum_code.py +8 -8
- classiq/interface/executor/result.py +28 -18
- classiq/interface/executor/user_budget.py +2 -3
- classiq/interface/executor/vqe_result.py +5 -6
- classiq/interface/generator/ansatz_library.py +6 -8
- classiq/interface/generator/application_apis/__init__.py +0 -2
- classiq/interface/generator/arith/arithmetic.py +2 -2
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +2 -3
- classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -5
- classiq/interface/generator/arith/arithmetic_expression_parser.py +11 -4
- classiq/interface/generator/arith/arithmetic_expression_validator.py +12 -15
- classiq/interface/generator/arith/arithmetic_operations.py +4 -6
- classiq/interface/generator/arith/arithmetic_param_getters.py +70 -107
- classiq/interface/generator/arith/arithmetic_result_builder.py +4 -4
- classiq/interface/generator/arith/ast_node_rewrite.py +8 -4
- classiq/interface/generator/arith/binary_ops.py +7 -36
- classiq/interface/generator/arith/logical_ops.py +2 -3
- classiq/interface/generator/arith/number_utils.py +2 -2
- classiq/interface/generator/arith/register_user_input.py +2 -2
- classiq/interface/generator/arith/unary_ops.py +2 -2
- classiq/interface/generator/circuit_code/circuit_code.py +8 -10
- classiq/interface/generator/circuit_code/types_and_constants.py +1 -1
- classiq/interface/generator/complex_type.py +2 -2
- classiq/interface/generator/copy.py +1 -3
- classiq/interface/generator/expressions/atomic_expression_functions.py +0 -5
- classiq/interface/generator/expressions/evaluated_expression.py +2 -3
- classiq/interface/generator/expressions/expression.py +2 -2
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +4 -7
- classiq/interface/generator/function_param_list.py +0 -20
- classiq/interface/generator/function_params.py +5 -6
- classiq/interface/generator/functions/classical_function_declaration.py +2 -2
- classiq/interface/generator/functions/classical_type.py +3 -3
- classiq/interface/generator/functions/type_modifier.py +0 -14
- classiq/interface/generator/functions/type_name.py +2 -2
- classiq/interface/generator/generated_circuit_data.py +12 -13
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +2 -4
- classiq/interface/generator/hardware/hardware_data.py +8 -8
- classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
- classiq/interface/generator/mcu.py +3 -3
- classiq/interface/generator/mcx.py +3 -3
- classiq/interface/generator/model/constraints.py +34 -5
- classiq/interface/generator/model/preferences/preferences.py +15 -21
- classiq/interface/generator/model/quantum_register.py +7 -10
- classiq/interface/generator/noise_properties.py +3 -7
- classiq/interface/generator/parameters.py +1 -1
- classiq/interface/generator/partitioned_register.py +1 -2
- classiq/interface/generator/preferences/qasm_to_qmod_params.py +11 -0
- classiq/interface/generator/qsvm.py +2 -2
- classiq/interface/generator/quantum_function_call.py +8 -11
- classiq/interface/generator/quantum_program.py +12 -15
- classiq/interface/generator/range_types.py +3 -3
- classiq/interface/generator/slice_parsing_utils.py +4 -5
- classiq/interface/generator/standard_gates/standard_gates.py +2 -4
- classiq/interface/generator/state_preparation/state_preparation.py +6 -8
- classiq/interface/generator/synthesis_execution_parameter.py +1 -3
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
- classiq/interface/generator/transpiler_basis_gates.py +2 -4
- classiq/interface/generator/types/builtin_enum_declarations.py +0 -136
- classiq/interface/generator/types/compilation_metadata.py +12 -1
- classiq/interface/generator/types/enum_declaration.py +2 -1
- classiq/interface/generator/validations/flow_graph.py +3 -3
- classiq/interface/generator/visitor.py +10 -12
- classiq/interface/hardware.py +2 -2
- classiq/interface/helpers/classproperty.py +2 -2
- classiq/interface/helpers/custom_encoders.py +2 -1
- classiq/interface/helpers/custom_pydantic_types.py +1 -1
- classiq/interface/helpers/text_utils.py +1 -4
- classiq/interface/ide/visual_model.py +5 -5
- classiq/interface/jobs.py +3 -3
- classiq/interface/model/allocate.py +4 -4
- classiq/interface/model/block.py +2 -2
- classiq/interface/model/bounds.py +3 -3
- classiq/interface/model/control.py +1 -1
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/model.py +4 -4
- classiq/interface/model/parameter.py +1 -3
- classiq/interface/model/port_declaration.py +1 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +1 -2
- classiq/interface/model/quantum_function_call.py +3 -6
- classiq/interface/model/quantum_function_declaration.py +1 -0
- classiq/interface/model/quantum_lambda_function.py +4 -4
- classiq/interface/model/quantum_statement.py +4 -4
- classiq/interface/model/quantum_type.py +14 -14
- classiq/interface/model/validation_handle.py +2 -3
- classiq/interface/model/variable_declaration_statement.py +2 -2
- classiq/interface/pretty_print/expression_to_qmod.py +3 -4
- classiq/interface/server/routes.py +0 -4
- classiq/interface/source_reference.py +3 -4
- classiq/model_expansions/arithmetic.py +6 -7
- classiq/model_expansions/arithmetic_compute_result_attrs.py +4 -5
- classiq/model_expansions/capturing/captured_vars.py +3 -3
- classiq/model_expansions/capturing/mangling_utils.py +1 -2
- classiq/model_expansions/closure.py +12 -11
- classiq/model_expansions/function_builder.py +14 -6
- classiq/model_expansions/generative_functions.py +1 -4
- classiq/model_expansions/interpreters/base_interpreter.py +2 -6
- classiq/model_expansions/interpreters/generative_interpreter.py +5 -3
- classiq/model_expansions/quantum_operations/allocate.py +4 -4
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +2 -4
- classiq/model_expansions/quantum_operations/call_emitter.py +31 -37
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +2 -2
- classiq/model_expansions/quantum_operations/emitter.py +3 -5
- classiq/model_expansions/quantum_operations/expression_evaluator.py +3 -3
- classiq/model_expansions/quantum_operations/skip_control_verifier.py +1 -2
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
- classiq/model_expansions/scope.py +7 -7
- classiq/model_expansions/scope_initialization.py +4 -0
- classiq/model_expansions/visitors/symbolic_param_inference.py +3 -3
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +317 -0
- classiq/model_expansions/visitors/variable_references.py +15 -14
- classiq/open_library/functions/__init__.py +6 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
- classiq/open_library/functions/grover.py +8 -10
- classiq/open_library/functions/modular_exponentiation.py +96 -8
- classiq/qmod/__init__.py +5 -2
- classiq/qmod/builtins/classical_execution_primitives.py +4 -11
- classiq/qmod/builtins/classical_functions.py +1 -42
- classiq/qmod/builtins/enums.py +0 -136
- classiq/qmod/builtins/functions/__init__.py +0 -13
- classiq/qmod/builtins/functions/allocation.py +4 -4
- classiq/qmod/builtins/functions/arithmetic.py +22 -27
- classiq/qmod/builtins/functions/standard_gates.py +27 -27
- classiq/qmod/builtins/operations.py +35 -58
- classiq/qmod/builtins/structs.py +2 -58
- classiq/qmod/cfunc.py +3 -2
- classiq/qmod/classical_function.py +2 -1
- classiq/qmod/cparam.py +2 -8
- classiq/qmod/create_model_function.py +7 -7
- classiq/qmod/declaration_inferrer.py +33 -30
- classiq/qmod/model_state_container.py +2 -2
- classiq/qmod/native/pretty_printer.py +25 -14
- classiq/qmod/pretty_print/expression_to_python.py +5 -3
- classiq/qmod/pretty_print/pretty_printer.py +39 -17
- classiq/qmod/python_classical_type.py +40 -13
- classiq/qmod/qfunc.py +139 -16
- classiq/qmod/qmod_constant.py +2 -2
- classiq/qmod/qmod_parameter.py +5 -2
- classiq/qmod/qmod_variable.py +47 -43
- classiq/qmod/quantum_callable.py +18 -13
- classiq/qmod/quantum_expandable.py +31 -26
- classiq/qmod/quantum_function.py +51 -32
- classiq/qmod/semantics/annotation/call_annotation.py +2 -2
- classiq/qmod/semantics/error_manager.py +5 -6
- classiq/qmod/semantics/lambdas.py +1 -2
- classiq/qmod/semantics/validation/types_validation.py +1 -2
- classiq/qmod/symbolic.py +2 -4
- classiq/qmod/utilities.py +13 -10
- classiq/qmod/write_qmod.py +3 -4
- classiq/quantum_program.py +1 -3
- classiq/synthesis.py +11 -7
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/METADATA +2 -3
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/RECORD +238 -260
- classiq/applications/chemistry/ansatz_parameters.py +0 -29
- classiq/applications/chemistry/chemistry_execution_parameters.py +0 -16
- classiq/applications/chemistry/chemistry_model_constructor.py +0 -532
- classiq/applications/chemistry/ground_state_problem.py +0 -42
- classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
- classiq/interface/chemistry/elements.py +0 -120
- classiq/interface/chemistry/fermionic_operator.py +0 -208
- classiq/interface/chemistry/ground_state_problem.py +0 -132
- classiq/interface/chemistry/ground_state_result.py +0 -8
- classiq/interface/chemistry/molecule.py +0 -71
- classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
- classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
- classiq/interface/generator/chemistry_function_params.py +0 -50
- classiq/interface/generator/entangler_params.py +0 -72
- classiq/interface/generator/entanglers.py +0 -14
- classiq/interface/generator/hartree_fock.py +0 -26
- classiq/interface/generator/hva.py +0 -22
- classiq/interface/generator/linear_pauli_rotations.py +0 -92
- classiq/interface/generator/qft.py +0 -37
- classiq/interface/generator/ucc.py +0 -74
- classiq/interface/helpers/backward_compatibility.py +0 -9
- classiq/model_expansions/transformers/type_modifier_inference.py +0 -392
- classiq/qmod/builtins/functions/chemistry.py +0 -123
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/WHEEL +0 -0
- {classiq-0.93.0.dist-info → classiq-0.94.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import datetime
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
import pydantic
|
|
5
4
|
from pydantic import ConfigDict, Field
|
|
@@ -11,11 +10,11 @@ from classiq.interface.helpers.versioned_model import VersionedModel
|
|
|
11
10
|
class UserBudget(VersionedModel):
|
|
12
11
|
provider: str
|
|
13
12
|
currency_code: str
|
|
14
|
-
organization:
|
|
13
|
+
organization: str | None = Field(default=None)
|
|
15
14
|
available_budget: float
|
|
16
15
|
used_budget: float
|
|
17
16
|
last_allocation_date: datetime.datetime
|
|
18
|
-
budget_limit:
|
|
17
|
+
budget_limit: float | None = Field(default=None)
|
|
19
18
|
|
|
20
19
|
model_config = ConfigDict(extra="ignore")
|
|
21
20
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import io
|
|
3
3
|
from datetime import datetime
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
import pydantic
|
|
7
6
|
from PIL import Image
|
|
@@ -18,8 +17,8 @@ Solution = tuple[int, ...]
|
|
|
18
17
|
class SolverResult(BaseModel):
|
|
19
18
|
energy: float
|
|
20
19
|
# TODO: add time units (like seconds)
|
|
21
|
-
time:
|
|
22
|
-
solution:
|
|
20
|
+
time: float | None = None
|
|
21
|
+
solution: Solution | None = None
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
class SolutionData(BaseModel):
|
|
@@ -37,7 +36,7 @@ class VQEIntermediateData(BaseModel):
|
|
|
37
36
|
parameters: list[float] = pydantic.Field(
|
|
38
37
|
description="The optimizer parameters for the variational form"
|
|
39
38
|
)
|
|
40
|
-
mean_all_solutions:
|
|
39
|
+
mean_all_solutions: float | None = pydantic.Field(
|
|
41
40
|
default=None, description="The mean score of all solutions in this iteration"
|
|
42
41
|
)
|
|
43
42
|
solutions: list[SolutionData] = pydantic.Field(
|
|
@@ -51,12 +50,12 @@ class VQEIntermediateData(BaseModel):
|
|
|
51
50
|
|
|
52
51
|
class VQESolverResult(SolverResult, QmodPyObject):
|
|
53
52
|
eigenstate: dict[str, Complex]
|
|
54
|
-
reduced_probabilities:
|
|
53
|
+
reduced_probabilities: dict[str, float] | None = None
|
|
55
54
|
optimized_circuit_sample_results: ExecutionDetails
|
|
56
55
|
intermediate_results: list[VQEIntermediateData]
|
|
57
56
|
optimal_parameters: dict[str, float]
|
|
58
57
|
convergence_graph_str: str
|
|
59
|
-
num_solutions:
|
|
58
|
+
num_solutions: int | None = None
|
|
60
59
|
num_shots: int
|
|
61
60
|
|
|
62
61
|
def show_convergence_graph(self) -> None:
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional, Union
|
|
2
|
-
|
|
3
1
|
from pydantic import BaseModel
|
|
4
2
|
|
|
5
3
|
from classiq.interface.enum_utils import StrEnum
|
|
@@ -43,20 +41,20 @@ class EntanglingLayersArgs(CustomAnsatzArgs):
|
|
|
43
41
|
class RandomArgs(CustomAnsatzArgs):
|
|
44
42
|
gate_count: int = 100
|
|
45
43
|
gate_probabilities: dict[str, float] = {"cx": 0.5, "u": 0.5}
|
|
46
|
-
random_seed:
|
|
44
|
+
random_seed: int | None = None
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
class RandomTwoQubitGatesArgs(CustomAnsatzArgs):
|
|
50
48
|
random_two_qubit_gate_count_factor: float = 1.0
|
|
51
|
-
random_seed:
|
|
49
|
+
random_seed: int | None = None
|
|
52
50
|
|
|
53
51
|
|
|
54
52
|
class TwoLocalArgs(CustomAnsatzArgs):
|
|
55
|
-
rotation_blocks:
|
|
53
|
+
rotation_blocks: RotationBlocksType | list[RotationBlocksType] | None = (
|
|
56
54
|
RotationBlocksType.ry
|
|
57
55
|
)
|
|
58
|
-
entanglement_blocks:
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
entanglement_blocks: None | (
|
|
57
|
+
EntanglementBlocksType | list[EntanglementBlocksType]
|
|
58
|
+
) = EntanglementBlocksType.cx
|
|
61
59
|
entanglement: EntanglementStructureType = EntanglementStructureType.full
|
|
62
60
|
reps: int = 3
|
|
@@ -3,9 +3,7 @@ from classiq.interface.generator.builtin_api_builder import (
|
|
|
3
3
|
)
|
|
4
4
|
|
|
5
5
|
from .arithmetic_declarations import * # noqa: F403
|
|
6
|
-
from .chemistry_declarations import * # noqa: F403
|
|
7
6
|
from .combinatorial_optimization_declarations import * # noqa: F403
|
|
8
|
-
from .entangler_declarations import * # noqa: F403
|
|
9
7
|
from .qsvm_declarations import * # noqa: F403
|
|
10
8
|
|
|
11
9
|
populate_builtin_declarations(vars().values())
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
|
-
from typing import Any, Final,
|
|
2
|
+
from typing import Any, Final, cast
|
|
3
3
|
|
|
4
4
|
import networkx as nx
|
|
5
5
|
import pydantic
|
|
@@ -48,7 +48,7 @@ def is_bool(expr: str) -> bool:
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class Arithmetic(ArithmeticExpressionABC):
|
|
51
|
-
target:
|
|
51
|
+
target: RegisterArithmeticInfo | None = None
|
|
52
52
|
inputs_to_save: set[str] = pydantic.Field(default_factory=set)
|
|
53
53
|
|
|
54
54
|
@pydantic.field_validator("inputs_to_save")
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from typing_extensions import TypeAlias
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import TypeAlias
|
|
4
3
|
|
|
5
4
|
from classiq.interface.exceptions import ClassiqArithmeticError
|
|
6
5
|
from classiq.interface.generator.arith import argument_utils
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import ast
|
|
3
3
|
import re
|
|
4
|
-
from typing import Any, Optional, Union
|
|
4
|
+
from typing import Any, Optional, TypeAlias, Union
|
|
5
5
|
|
|
6
6
|
import networkx as nx
|
|
7
7
|
import pydantic
|
|
8
8
|
from pydantic import TypeAdapter
|
|
9
|
-
from typing_extensions import TypeAlias
|
|
10
9
|
|
|
11
10
|
from classiq.interface.exceptions import ClassiqValueError
|
|
12
11
|
from classiq.interface.generator.arith import number_utils
|
|
@@ -42,7 +41,7 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
|
|
|
42
41
|
machine_precision: pydantic.NonNegativeInt = DEFAULT_MACHINE_PRECISION
|
|
43
42
|
expression: PydanticExpressionStr
|
|
44
43
|
definitions: dict[str, ValidDefinitions]
|
|
45
|
-
qubit_count:
|
|
44
|
+
qubit_count: pydantic.NonNegativeInt | None = None
|
|
46
45
|
|
|
47
46
|
def _get_literal_set(self) -> set[str]:
|
|
48
47
|
return _extract_literals(self.expression)
|
|
@@ -85,7 +84,7 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
|
|
|
85
84
|
):
|
|
86
85
|
definition_dict = dict(definition_dict)
|
|
87
86
|
definitions = definitions_adapter.validate_python(definition_dict)
|
|
88
|
-
machine_precision:
|
|
87
|
+
machine_precision: int | None = values.get(
|
|
89
88
|
"machine_precision", DEFAULT_MACHINE_PRECISION
|
|
90
89
|
)
|
|
91
90
|
if (
|
|
@@ -173,7 +172,7 @@ class ArithmeticExpressionABC(abc.ABC, FunctionParams):
|
|
|
173
172
|
|
|
174
173
|
@staticmethod
|
|
175
174
|
def _replace_numeric_value_in_expression(
|
|
176
|
-
expression: str, var: str, value:
|
|
175
|
+
expression: str, var: str, value: int | float, machine_precision: int
|
|
177
176
|
) -> str:
|
|
178
177
|
if isinstance(value, float):
|
|
179
178
|
value = number_utils.limit_fraction_places(
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import ast
|
|
2
|
+
import re
|
|
2
3
|
from _ast import AST
|
|
3
4
|
from collections.abc import Collection
|
|
4
|
-
from typing import
|
|
5
|
+
from typing import Union, cast
|
|
5
6
|
|
|
6
7
|
import networkx as nx
|
|
7
8
|
|
|
@@ -23,6 +24,9 @@ _UNEXPECTED_ARITHMETIC_ERROR_MESSAGE: str = (
|
|
|
23
24
|
"Quantum expressions that evaluate to a classical value are not supported"
|
|
24
25
|
)
|
|
25
26
|
_ALLOWED_MULTI_ARGUMENT_FUNCTIONS = ("min", "max")
|
|
27
|
+
_ALLOWED_MULTI_ARGUMENT_PATTEN = re.compile(
|
|
28
|
+
rf"(({')|('.join(_ALLOWED_MULTI_ARGUMENT_FUNCTIONS)}))_[0-9]+"
|
|
29
|
+
)
|
|
26
30
|
Node = Union[str, float, int]
|
|
27
31
|
|
|
28
32
|
|
|
@@ -31,7 +35,7 @@ class ExpressionVisitor(ExpressionValidator):
|
|
|
31
35
|
self,
|
|
32
36
|
supported_nodes: tuple[type[AST], ...],
|
|
33
37
|
expression_type: str = DEFAULT_EXPRESSION_TYPE,
|
|
34
|
-
supported_functions:
|
|
38
|
+
supported_functions: set[str] | None = None,
|
|
35
39
|
) -> None:
|
|
36
40
|
super().__init__(supported_nodes, expression_type, supported_functions)
|
|
37
41
|
self.graph = nx.DiGraph()
|
|
@@ -101,7 +105,10 @@ class InDegreeLimiter:
|
|
|
101
105
|
|
|
102
106
|
@staticmethod
|
|
103
107
|
def _condition(graph: nx.DiGraph, node: str) -> bool:
|
|
104
|
-
return
|
|
108
|
+
return (
|
|
109
|
+
graph.in_degree[node] > 2
|
|
110
|
+
and _ALLOWED_MULTI_ARGUMENT_PATTEN.fullmatch(node) is not None
|
|
111
|
+
)
|
|
105
112
|
|
|
106
113
|
@classmethod
|
|
107
114
|
def _node_conversion(cls, graph: nx.DiGraph, node: str) -> nx.DiGraph:
|
|
@@ -137,7 +144,7 @@ def parse_expression(
|
|
|
137
144
|
*,
|
|
138
145
|
supported_nodes: tuple[type[AST], ...] = DEFAULT_SUPPORTED_NODE_TYPES,
|
|
139
146
|
expression_type: str = DEFAULT_EXPRESSION_TYPE,
|
|
140
|
-
supported_functions:
|
|
147
|
+
supported_functions: set[str] | None = None,
|
|
141
148
|
) -> nx.DiGraph:
|
|
142
149
|
supported_functions = supported_functions or DEFAULT_SUPPORTED_FUNC_NAMES
|
|
143
150
|
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
import re
|
|
3
3
|
from _ast import AST
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, TypeAlias, Union, get_args
|
|
5
5
|
|
|
6
6
|
from sympy import Expr
|
|
7
|
-
from typing_extensions import TypeAlias, get_args
|
|
8
7
|
|
|
9
8
|
from classiq.interface.exceptions import ClassiqArithmeticError, ClassiqValueError
|
|
10
|
-
from classiq.interface.generator.arith.ast_node_rewrite import AstNodeRewrite
|
|
11
9
|
from classiq.interface.generator.expressions.sympy_supported_expressions import (
|
|
12
10
|
SYMPY_SUPPORTED_EXPRESSIONS,
|
|
13
11
|
)
|
|
14
12
|
|
|
15
|
-
DEFAULT_SUPPORTED_FUNC_NAMES: set[str] = {"
|
|
13
|
+
DEFAULT_SUPPORTED_FUNC_NAMES: set[str] = {"min", "max"}
|
|
16
14
|
|
|
17
15
|
DEFAULT_EXPRESSION_TYPE = "arithmetic"
|
|
18
16
|
IDENITIFIER_REGEX = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*")
|
|
@@ -55,7 +53,7 @@ SupportedNodesTypes = Union[
|
|
|
55
53
|
DEFAULT_SUPPORTED_NODE_TYPES = get_args(SupportedNodesTypes)
|
|
56
54
|
|
|
57
55
|
|
|
58
|
-
def is_constant(expr:
|
|
56
|
+
def is_constant(expr: str | Expr) -> bool:
|
|
59
57
|
try:
|
|
60
58
|
float(expr)
|
|
61
59
|
return True
|
|
@@ -72,7 +70,7 @@ class ExpressionValidator(ast.NodeVisitor):
|
|
|
72
70
|
self,
|
|
73
71
|
supported_nodes: tuple[type[AST], ...],
|
|
74
72
|
expression_type: str = DEFAULT_EXPRESSION_TYPE,
|
|
75
|
-
supported_functions:
|
|
73
|
+
supported_functions: set[str] | None = None,
|
|
76
74
|
mode: str = "eval",
|
|
77
75
|
) -> None:
|
|
78
76
|
super().__init__()
|
|
@@ -80,7 +78,7 @@ class ExpressionValidator(ast.NodeVisitor):
|
|
|
80
78
|
self._expression_type = expression_type
|
|
81
79
|
self._supported_functions = supported_functions or DEFAULT_SUPPORTED_FUNC_NAMES
|
|
82
80
|
self._mode = mode
|
|
83
|
-
self._ast_obj:
|
|
81
|
+
self._ast_obj: ast.AST | None = None
|
|
84
82
|
|
|
85
83
|
def validate(self, expression: str) -> None:
|
|
86
84
|
try:
|
|
@@ -171,14 +169,13 @@ class ExpressionValidator(ast.NodeVisitor):
|
|
|
171
169
|
node,
|
|
172
170
|
"the first two call arguments are identical",
|
|
173
171
|
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if node_id in ("CLShift", "CRShift") and (
|
|
179
|
-
len(node.args) != 2 or not isinstance(node.args[1], ast.Constant)
|
|
172
|
+
if (
|
|
173
|
+
not isinstance(node.func, ast.Name)
|
|
174
|
+
or node.func.id not in self._supported_functions
|
|
180
175
|
):
|
|
181
|
-
raise ClassiqValueError(
|
|
176
|
+
raise ClassiqValueError(
|
|
177
|
+
f"{ast.unparse(node.func)} not in supported functions"
|
|
178
|
+
)
|
|
182
179
|
|
|
183
180
|
def visit_Call(self, node: ast.Call) -> None:
|
|
184
181
|
self.validate_Call(node)
|
|
@@ -207,7 +204,7 @@ def validate_expression(
|
|
|
207
204
|
*,
|
|
208
205
|
supported_nodes: tuple[type[AST], ...] = DEFAULT_SUPPORTED_NODE_TYPES,
|
|
209
206
|
expression_type: str = DEFAULT_EXPRESSION_TYPE,
|
|
210
|
-
supported_functions:
|
|
207
|
+
supported_functions: set[str] | None = None,
|
|
211
208
|
mode: str = "eval",
|
|
212
209
|
) -> ast.AST:
|
|
213
210
|
supported_functions = supported_functions or set(SYMPY_SUPPORTED_EXPRESSIONS).union(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
from collections.abc import Iterable
|
|
3
|
-
from typing import ClassVar, Final
|
|
3
|
+
from typing import ClassVar, Final
|
|
4
4
|
|
|
5
5
|
import pydantic
|
|
6
6
|
|
|
@@ -18,13 +18,11 @@ MODULO_WITH_FRACTION_PLACES_ERROR_MSG: Final[str] = (
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class ArithmeticOperationParams(FunctionParams):
|
|
21
|
-
output_size:
|
|
21
|
+
output_size: pydantic.PositiveInt | None = pydantic.Field(default=None)
|
|
22
22
|
machine_precision: pydantic.PositiveInt = DEFAULT_MACHINE_PRECISION
|
|
23
23
|
output_name: ClassVar[str]
|
|
24
24
|
garbage_output_name: ClassVar[str] = DEFAULT_GARBAGE_OUT_NAME
|
|
25
|
-
_result_register:
|
|
26
|
-
default=None
|
|
27
|
-
)
|
|
25
|
+
_result_register: RegisterArithmeticInfo | None = pydantic.PrivateAttr(default=None)
|
|
28
26
|
|
|
29
27
|
@abc.abstractmethod
|
|
30
28
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
|
@@ -46,7 +44,7 @@ class ArithmeticOperationParams(FunctionParams):
|
|
|
46
44
|
|
|
47
45
|
def _legal_bounds(
|
|
48
46
|
self, suggested_bounds: tuple[float, float], max_bounds: tuple[float, float]
|
|
49
|
-
) ->
|
|
47
|
+
) -> tuple[float, float] | None:
|
|
50
48
|
if self.output_size is None or (
|
|
51
49
|
suggested_bounds[0] >= max_bounds[0]
|
|
52
50
|
and suggested_bounds[1] <= max_bounds[1]
|