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
@@ -1,11 +1,9 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
1
|
import pydantic
|
4
2
|
|
5
|
-
from classiq.interface.model.quantum_function_call import ConcreteQuantumStatement
|
6
3
|
from classiq.interface.model.quantum_function_declaration import (
|
7
4
|
QuantumFunctionDeclaration,
|
8
5
|
)
|
6
|
+
from classiq.interface.model.statement_block import StatementBlock
|
9
7
|
from classiq.interface.model.validations.handles_validator import HandleValidator
|
10
8
|
from classiq.interface.model.variable_declaration_statement import (
|
11
9
|
VariableDeclarationStatement,
|
@@ -22,7 +20,7 @@ class NativeFunctionDefinition(QuantumFunctionDeclaration):
|
|
22
20
|
objects from other classes.
|
23
21
|
"""
|
24
22
|
|
25
|
-
body:
|
23
|
+
body: StatementBlock = pydantic.Field(
|
26
24
|
default_factory=list, description="List of function calls to perform."
|
27
25
|
)
|
28
26
|
|
@@ -33,6 +31,6 @@ class NativeFunctionDefinition(QuantumFunctionDeclaration):
|
|
33
31
|
if isinstance(statement, VariableDeclarationStatement):
|
34
32
|
handle_validator.handle_variable_declaration(statement)
|
35
33
|
else:
|
36
|
-
handle_validator.
|
34
|
+
handle_validator.handle_operation(statement)
|
37
35
|
|
38
36
|
handle_validator.report_errored_handles(ClassiqValueError)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
from typing import TYPE_CHECKING
|
2
|
+
|
3
|
+
from classiq.interface.generator.expressions.expression import Expression
|
4
|
+
from classiq.interface.model.quantum_statement import QuantumOperation
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from classiq.interface.model.statement_block import StatementBlock
|
8
|
+
|
9
|
+
|
10
|
+
class Power(QuantumOperation):
|
11
|
+
power: Expression
|
12
|
+
body: "StatementBlock"
|
@@ -36,9 +36,14 @@ class AmplitudeLoadingOperation(QuantumAssignmentOperation):
|
|
36
36
|
) -> Mapping[
|
37
37
|
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
38
38
|
]:
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
inouts = {self.result_name(): self.result_var}
|
40
|
+
if len(self.var_handles) == 1:
|
41
|
+
inouts[AMPLITUDE_IO_NAME] = self.var_handles[0]
|
42
|
+
return inouts
|
43
|
+
|
44
|
+
@property
|
45
|
+
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
46
|
+
return {}
|
42
47
|
|
43
48
|
def initialize_var_types(
|
44
49
|
self,
|
@@ -50,7 +55,7 @@ class AmplitudeLoadingOperation(QuantumAssignmentOperation):
|
|
50
55
|
var_type = var_types[self.var_handles[0].name]
|
51
56
|
if not (
|
52
57
|
isinstance(var_type, QuantumNumeric)
|
53
|
-
and var_type.
|
58
|
+
and var_type.fraction_digits_value == var_type.size_in_bits
|
54
59
|
):
|
55
60
|
raise ClassiqValueError(VAR_DOMAIN_ILLEGAL)
|
56
61
|
super().initialize_var_types(var_types, machine_precision)
|
@@ -4,7 +4,7 @@ from classiq.exceptions import ClassiqValueError
|
|
4
4
|
def min_unsigned_bit_length(number: int) -> int:
|
5
5
|
if number < 0:
|
6
6
|
raise ClassiqValueError(
|
7
|
-
f"Quantum register is not signed but control value "
|
7
|
+
f"Quantum register is not signed but control value "
|
8
8
|
f"'{number}' is negative"
|
9
9
|
)
|
10
10
|
return 1 if number == 0 else number.bit_length()
|
@@ -28,7 +28,7 @@ def to_twos_complement(value: int, bits: int, is_signed: bool) -> str:
|
|
28
28
|
required_bits = min_bit_length(value, is_signed)
|
29
29
|
if bits < required_bits:
|
30
30
|
raise ClassiqValueError(
|
31
|
-
f"Cannot express '{value}' using {bits} bits: "
|
31
|
+
f"Cannot express '{value}' using {bits} bits: "
|
32
32
|
f"at least {required_bits} bits are required"
|
33
33
|
)
|
34
34
|
if value >= 0:
|
@@ -1,49 +1,35 @@
|
|
1
1
|
import itertools
|
2
2
|
import re
|
3
|
-
from typing import Any, Dict, List, Mapping, Optional,
|
3
|
+
from typing import Any, Dict, List, Mapping, Optional, Set, Type, Union
|
4
4
|
|
5
5
|
import pydantic
|
6
|
-
from pydantic import BaseModel
|
7
6
|
|
7
|
+
from classiq.interface.ast_node import ASTNode
|
8
8
|
from classiq.interface.generator.expressions.expression import Expression
|
9
|
-
from classiq.interface.generator.
|
10
|
-
|
9
|
+
from classiq.interface.generator.functions.function_declaration import (
|
10
|
+
FunctionDeclaration,
|
11
|
+
)
|
11
12
|
from classiq.interface.generator.functions.port_declaration import (
|
12
13
|
PortDeclarationDirection,
|
13
14
|
)
|
14
|
-
from classiq.interface.
|
15
|
-
BAD_CALL_NAME_ERROR_MSG,
|
16
|
-
SUFFIX_MARKER,
|
17
|
-
randomize_suffix,
|
18
|
-
)
|
19
|
-
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
20
|
-
from classiq.interface.model.bind_operation import BindOperation
|
15
|
+
from classiq.interface.model.call_synthesis_data import CallSynthesisData
|
21
16
|
from classiq.interface.model.handle_binding import (
|
22
17
|
HandleBinding,
|
23
18
|
SlicedHandleBinding,
|
24
19
|
SubscriptHandleBinding,
|
25
20
|
)
|
26
|
-
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
27
|
-
from classiq.interface.model.numeric_reinterpretation import (
|
28
|
-
NumericReinterpretationOperation,
|
29
|
-
)
|
30
|
-
from classiq.interface.model.operator_synthesis_data import OperatorSynthesisData
|
31
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
32
|
-
AmplitudeLoadingOperation,
|
33
|
-
)
|
34
|
-
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
35
|
-
ArithmeticOperation,
|
36
|
-
)
|
37
21
|
from classiq.interface.model.quantum_function_declaration import (
|
38
22
|
QuantumFunctionDeclaration,
|
39
23
|
QuantumOperandDeclaration,
|
40
24
|
)
|
41
|
-
from classiq.interface.model.
|
25
|
+
from classiq.interface.model.quantum_lambda_function import (
|
26
|
+
LambdaListComprehension,
|
27
|
+
QuantumCallable,
|
28
|
+
QuantumLambdaFunction,
|
29
|
+
QuantumOperand,
|
30
|
+
)
|
42
31
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
43
32
|
from classiq.interface.model.validation_handle import get_unique_handle_names
|
44
|
-
from classiq.interface.model.variable_declaration_statement import (
|
45
|
-
VariableDeclarationStatement,
|
46
|
-
)
|
47
33
|
|
48
34
|
from classiq.exceptions import ClassiqError, ClassiqValueError
|
49
35
|
|
@@ -91,8 +77,13 @@ def _validate_no_duplicated_handles(
|
|
91
77
|
def _validate_no_mixing_sliced_and_whole_handles(
|
92
78
|
inouts: Mapping[str, HandleBinding],
|
93
79
|
) -> None:
|
80
|
+
def _treat_subscript_as_slice(type_: Type[HandleBinding]) -> Type[HandleBinding]:
|
81
|
+
if type_ == SubscriptHandleBinding:
|
82
|
+
return SlicedHandleBinding
|
83
|
+
return type_
|
84
|
+
|
94
85
|
inout_handle_names_to_types = {
|
95
|
-
handle_name: {type(handle) for handle in handles}
|
86
|
+
handle_name: {_treat_subscript_as_slice(type(handle)) for handle in handles}
|
96
87
|
for handle_name, handles in itertools.groupby(
|
97
88
|
inouts.values(), lambda handle: handle.name
|
98
89
|
)
|
@@ -108,10 +99,16 @@ def _validate_no_mixing_sliced_and_whole_handles(
|
|
108
99
|
)
|
109
100
|
|
110
101
|
|
111
|
-
ArgValue = Union[
|
102
|
+
ArgValue = Union[
|
103
|
+
Expression,
|
104
|
+
QuantumOperand,
|
105
|
+
SlicedHandleBinding,
|
106
|
+
SubscriptHandleBinding,
|
107
|
+
HandleBinding,
|
108
|
+
]
|
112
109
|
|
113
110
|
|
114
|
-
class OperandIdentifier(
|
111
|
+
class OperandIdentifier(ASTNode):
|
115
112
|
name: str
|
116
113
|
index: Expression
|
117
114
|
|
@@ -121,13 +118,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
121
118
|
description="The function that is called"
|
122
119
|
)
|
123
120
|
params: Dict[str, Expression] = pydantic.Field(default_factory=dict)
|
124
|
-
release_by_inverse: bool = pydantic.Field(
|
125
|
-
default=False, description="Release zero inputs in inverse call."
|
126
|
-
)
|
127
|
-
should_control: bool = pydantic.Field(
|
128
|
-
default=True,
|
129
|
-
description="False value indicates this call shouldn't be controlled even if the flow is controlled.",
|
130
|
-
)
|
131
121
|
inputs: Dict[str, HandleBinding] = pydantic.Field(
|
132
122
|
default_factory=dict,
|
133
123
|
description="A mapping from the input name to the wire it connects to",
|
@@ -142,12 +132,7 @@ class QuantumFunctionCall(QuantumOperation):
|
|
142
132
|
default_factory=dict,
|
143
133
|
description="A mapping from the output name to the wire it connects to",
|
144
134
|
)
|
145
|
-
|
146
|
-
default=None,
|
147
|
-
description="The name of the function instance. "
|
148
|
-
"If not set, determined automatically.",
|
149
|
-
)
|
150
|
-
operands: Dict[str, "QuantumOperand"] = pydantic.Field(
|
135
|
+
operands: Dict[str, QuantumOperand] = pydantic.Field(
|
151
136
|
description="Function calls passed to the operator",
|
152
137
|
default_factory=dict,
|
153
138
|
)
|
@@ -157,8 +142,8 @@ class QuantumFunctionCall(QuantumOperation):
|
|
157
142
|
default=None
|
158
143
|
)
|
159
144
|
|
160
|
-
|
161
|
-
default_factory=
|
145
|
+
_synthesis_data: CallSynthesisData = pydantic.PrivateAttr(
|
146
|
+
default_factory=CallSynthesisData
|
162
147
|
)
|
163
148
|
|
164
149
|
@property
|
@@ -207,33 +192,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
207
192
|
result.extend(self.outputs.values())
|
208
193
|
return result
|
209
194
|
|
210
|
-
def __eq__(self, other: Any) -> bool:
|
211
|
-
return isinstance(other, QuantumFunctionCall) and self.name == other.name
|
212
|
-
|
213
|
-
def __hash__(self) -> int:
|
214
|
-
return hash(self.name)
|
215
|
-
|
216
|
-
@pydantic.validator("name", pre=True, always=True)
|
217
|
-
def _create_name(cls, name: Optional[str], values: Dict[str, Any]) -> str:
|
218
|
-
"""
|
219
|
-
generates a name to a user defined-functions as follows:
|
220
|
-
<function_name>_<SUFFIX_MARKER>_<random_suffix>
|
221
|
-
"""
|
222
|
-
if name is not None:
|
223
|
-
match = re.fullmatch(pattern=NAME_REGEX, string=name)
|
224
|
-
if match is None:
|
225
|
-
raise ValueError(BAD_CALL_NAME_ERROR_MSG)
|
226
|
-
return name
|
227
|
-
|
228
|
-
function = values.get("function")
|
229
|
-
if isinstance(function, OperandIdentifier):
|
230
|
-
function = function.name
|
231
|
-
|
232
|
-
suffix = f"{SUFFIX_MARKER}_{randomize_suffix()}"
|
233
|
-
if not function:
|
234
|
-
return name if name else suffix
|
235
|
-
return f"{function}_{suffix}"
|
236
|
-
|
237
195
|
@property
|
238
196
|
def pos_param_args(self) -> Dict[str, Expression]:
|
239
197
|
return dict(
|
@@ -324,17 +282,11 @@ class QuantumFunctionCall(QuantumOperation):
|
|
324
282
|
qlambda.set_op_decl(op_decl)
|
325
283
|
|
326
284
|
@property
|
327
|
-
def
|
328
|
-
return self.
|
329
|
-
|
330
|
-
def set_operator_synthesis_data(
|
331
|
-
self, operator_synthesis_data: OperatorSynthesisData
|
332
|
-
) -> None:
|
333
|
-
self._operator_synthesis_data = operator_synthesis_data
|
285
|
+
def synthesis_data(self) -> CallSynthesisData:
|
286
|
+
return self._synthesis_data
|
334
287
|
|
335
|
-
|
336
|
-
|
337
|
-
return len(set(name_list)) < len(name_list)
|
288
|
+
def merge_synthesis_data(self, other: CallSynthesisData) -> None:
|
289
|
+
self._synthesis_data = self._synthesis_data.merge(other)
|
338
290
|
|
339
291
|
@pydantic.root_validator()
|
340
292
|
def validate_handles(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
@@ -349,67 +301,6 @@ class QuantumFunctionCall(QuantumOperation):
|
|
349
301
|
return values
|
350
302
|
|
351
303
|
|
352
|
-
ConcreteQuantumStatement = Union[
|
353
|
-
QuantumFunctionCall,
|
354
|
-
ArithmeticOperation,
|
355
|
-
AmplitudeLoadingOperation,
|
356
|
-
VariableDeclarationStatement,
|
357
|
-
BindOperation,
|
358
|
-
NumericReinterpretationOperation,
|
359
|
-
InplaceBinaryOperation,
|
360
|
-
QuantumIfOperation,
|
361
|
-
]
|
362
|
-
|
363
|
-
|
364
|
-
class QuantumLambdaFunction(BaseModel):
|
365
|
-
"""
|
366
|
-
The definition of an anonymous function passed as operand to higher-level functions
|
367
|
-
"""
|
368
|
-
|
369
|
-
rename_params: Dict[str, str] = pydantic.Field(
|
370
|
-
default_factory=dict,
|
371
|
-
description="Mapping of the declared param to the actual variable name used ",
|
372
|
-
)
|
373
|
-
|
374
|
-
body: List[ConcreteQuantumStatement] = pydantic.Field(
|
375
|
-
description="A list of function calls passed to the operator"
|
376
|
-
)
|
377
|
-
|
378
|
-
_func_decl: Optional[QuantumOperandDeclaration] = pydantic.PrivateAttr(default=None)
|
379
|
-
|
380
|
-
@property
|
381
|
-
def func_decl(self) -> Optional[QuantumOperandDeclaration]:
|
382
|
-
return self._func_decl
|
383
|
-
|
384
|
-
def set_op_decl(self, fd: QuantumOperandDeclaration) -> None:
|
385
|
-
self._func_decl = fd
|
386
|
-
|
387
|
-
|
388
|
-
class LambdaListComprehension(BaseModel):
|
389
|
-
"""
|
390
|
-
Specification of a list of lambda functions iteratively
|
391
|
-
"""
|
392
|
-
|
393
|
-
count: Expression = pydantic.Field(
|
394
|
-
description="The number of lambda functions in the list"
|
395
|
-
)
|
396
|
-
|
397
|
-
index_var: str = pydantic.Field(
|
398
|
-
description="The name of the integer variable holding the iteration index"
|
399
|
-
)
|
400
|
-
|
401
|
-
func: QuantumLambdaFunction = pydantic.Field(
|
402
|
-
description="A lambda function definition replicated for index values 0 to count-1"
|
403
|
-
)
|
404
|
-
|
405
|
-
|
406
|
-
QuantumCallable = Union[str, QuantumLambdaFunction]
|
407
|
-
QuantumOperand = Union[QuantumCallable, List[QuantumCallable], LambdaListComprehension]
|
408
|
-
|
409
|
-
QuantumFunctionCall.update_forward_refs()
|
410
|
-
QuantumIfOperation.update_forward_refs(QuantumOperand=QuantumOperand)
|
411
|
-
|
412
|
-
|
413
304
|
def get_lambda_defs(operand: QuantumOperand) -> List[QuantumCallable]:
|
414
305
|
if isinstance(operand, list):
|
415
306
|
return operand
|
@@ -108,6 +108,14 @@ class QuantumFunctionDeclaration(FunctionDeclaration):
|
|
108
108
|
) -> None:
|
109
109
|
pass
|
110
110
|
|
111
|
+
@property
|
112
|
+
def port_names(self) -> List[str]:
|
113
|
+
return list(self.port_declarations.keys())
|
114
|
+
|
115
|
+
@property
|
116
|
+
def operand_names(self) -> List[str]:
|
117
|
+
return list(self.operand_declarations.keys())
|
118
|
+
|
111
119
|
def ports_by_direction(
|
112
120
|
self, direction: PortDirection
|
113
121
|
) -> Mapping[str, PortDeclaration]:
|
@@ -5,7 +5,7 @@ from sympy import Equality
|
|
5
5
|
from sympy.core.numbers import Integer
|
6
6
|
|
7
7
|
from classiq.interface.generator.expressions.expression import Expression
|
8
|
-
from classiq.interface.generator.expressions.
|
8
|
+
from classiq.interface.generator.expressions.qmod_qscalar_proxy import QmodQNumProxy
|
9
9
|
from classiq.interface.model.quantum_expressions.control_state import (
|
10
10
|
min_bit_length,
|
11
11
|
to_twos_complement,
|
@@ -17,8 +17,7 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
17
17
|
from classiq.exceptions import ClassiqValueError
|
18
18
|
|
19
19
|
if TYPE_CHECKING:
|
20
|
-
from classiq.interface.model.
|
21
|
-
|
20
|
+
from classiq.interface.model.statement_block import StatementBlock
|
22
21
|
|
23
22
|
QUANTUM_IF_INOUT_NAME = "ctrl"
|
24
23
|
QUANTUM_IF_CONDITION_ARG_ERROR_MESSAGE_FORMAT = (
|
@@ -27,8 +26,8 @@ QUANTUM_IF_CONDITION_ARG_ERROR_MESSAGE_FORMAT = (
|
|
27
26
|
)
|
28
27
|
|
29
28
|
|
30
|
-
class
|
31
|
-
then: "
|
29
|
+
class QuantumIf(QuantumExpressionOperation):
|
30
|
+
then: "StatementBlock"
|
32
31
|
_ctrl: Optional[QmodQNumProxy] = pydantic.PrivateAttr(
|
33
32
|
default=None,
|
34
33
|
)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Union
|
2
|
+
|
3
|
+
import pydantic
|
4
|
+
|
5
|
+
from classiq.interface.ast_node import ASTNode
|
6
|
+
from classiq.interface.generator.expressions.expression import Expression
|
7
|
+
from classiq.interface.model.quantum_function_declaration import (
|
8
|
+
QuantumOperandDeclaration,
|
9
|
+
)
|
10
|
+
|
11
|
+
if TYPE_CHECKING:
|
12
|
+
from classiq.interface.model.statement_block import StatementBlock
|
13
|
+
|
14
|
+
|
15
|
+
class QuantumLambdaFunction(ASTNode):
|
16
|
+
"""
|
17
|
+
The definition of an anonymous function passed as operand to higher-level functions
|
18
|
+
"""
|
19
|
+
|
20
|
+
rename_params: Dict[str, str] = pydantic.Field(
|
21
|
+
default_factory=dict,
|
22
|
+
description="Mapping of the declared param to the actual variable name used ",
|
23
|
+
)
|
24
|
+
|
25
|
+
body: "StatementBlock" = pydantic.Field(
|
26
|
+
description="A list of function calls passed to the operator"
|
27
|
+
)
|
28
|
+
|
29
|
+
_func_decl: Optional[QuantumOperandDeclaration] = pydantic.PrivateAttr(default=None)
|
30
|
+
|
31
|
+
@property
|
32
|
+
def func_decl(self) -> Optional[QuantumOperandDeclaration]:
|
33
|
+
return self._func_decl
|
34
|
+
|
35
|
+
def set_op_decl(self, fd: QuantumOperandDeclaration) -> None:
|
36
|
+
self._func_decl = fd
|
37
|
+
|
38
|
+
|
39
|
+
class LambdaListComprehension(ASTNode):
|
40
|
+
"""
|
41
|
+
Specification of a list of lambda functions iteratively
|
42
|
+
"""
|
43
|
+
|
44
|
+
count: Expression = pydantic.Field(
|
45
|
+
description="The number of lambda functions in the list"
|
46
|
+
)
|
47
|
+
|
48
|
+
index_var: str = pydantic.Field(
|
49
|
+
description="The name of the integer variable holding the iteration index"
|
50
|
+
)
|
51
|
+
|
52
|
+
func: QuantumLambdaFunction = pydantic.Field(
|
53
|
+
description="A lambda function definition replicated for index values 0 to count-1"
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
QuantumCallable = Union[str, QuantumLambdaFunction]
|
58
|
+
QuantumOperand = Union[QuantumCallable, List[QuantumCallable], LambdaListComprehension]
|
@@ -1,7 +1,15 @@
|
|
1
1
|
import itertools
|
2
2
|
import sys
|
3
|
-
from typing import
|
4
|
-
|
3
|
+
from typing import ( # type: ignore[attr-defined]
|
4
|
+
Any,
|
5
|
+
Dict,
|
6
|
+
Iterator,
|
7
|
+
List,
|
8
|
+
Optional,
|
9
|
+
Type,
|
10
|
+
Union,
|
11
|
+
_GenericAlias,
|
12
|
+
)
|
5
13
|
|
6
14
|
from classiq.interface.generator.arith.register_user_input import (
|
7
15
|
RegisterArithmeticInfo,
|
@@ -19,7 +27,7 @@ if sys.version_info >= (3, 9):
|
|
19
27
|
# This class is used for QReg, to support type-hint initialization
|
20
28
|
# Due to the `size` property of QReg
|
21
29
|
class QRegGenericAlias(_GenericAlias, _root=True): # type: ignore[call-arg]
|
22
|
-
def __call__(self, *args, **kwargs):
|
30
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
23
31
|
arith_info = {}
|
24
32
|
if self.size is not None:
|
25
33
|
arith_info["size"] = self.size
|
@@ -48,13 +56,13 @@ class QRegGenericAlias(_GenericAlias, _root=True): # type: ignore[call-arg]
|
|
48
56
|
|
49
57
|
@property
|
50
58
|
def integer_places(self) -> Optional[int]:
|
51
|
-
if len(self.__args__) in (1, 2) and
|
59
|
+
if len(self.__args__) in (1, 2) and isinstance(self.__args__[0], int):
|
52
60
|
return self.__args__[0]
|
53
61
|
return None
|
54
62
|
|
55
63
|
@property
|
56
64
|
def fraction_places(self) -> Optional[int]:
|
57
|
-
if len(self.__args__) == 2 and
|
65
|
+
if len(self.__args__) == 2 and isinstance(self.__args__[1], int):
|
58
66
|
return self.__args__[1]
|
59
67
|
return None
|
60
68
|
|
@@ -102,7 +110,7 @@ class QReg:
|
|
102
110
|
)
|
103
111
|
self._qubits[key] = value._qubits[0] if isinstance(key, int) else value._qubits # type: ignore[call-overload]
|
104
112
|
|
105
|
-
def __iter__(self):
|
113
|
+
def __iter__(self) -> Iterator["QReg"]:
|
106
114
|
return iter([self[idx] for idx in range(len(self))])
|
107
115
|
|
108
116
|
def __eq__(self, other: Any) -> bool:
|
@@ -136,7 +144,7 @@ class QReg:
|
|
136
144
|
|
137
145
|
def __class_getitem__(cls, params: Any) -> QRegGenericAlias:
|
138
146
|
# Supporting python 3.7+, thus returning `typing._GenericAlias` instead of `types.GenericAlias`
|
139
|
-
if
|
147
|
+
if isinstance(params, int):
|
140
148
|
return QRegGenericAlias(cls, params)
|
141
149
|
|
142
150
|
raise ClassiqQRegError(f"Invalid size: {params} ; int required")
|
@@ -171,8 +179,8 @@ class QSFixed(QReg):
|
|
171
179
|
if (
|
172
180
|
type(params) is tuple
|
173
181
|
and len(params) == 2
|
174
|
-
and
|
175
|
-
and
|
182
|
+
and isinstance(params[0], int)
|
183
|
+
and isinstance(params[1], int)
|
176
184
|
):
|
177
185
|
return QRegGenericAlias(cls, params)
|
178
186
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from typing import Mapping, Union
|
2
2
|
|
3
|
-
from pydantic import
|
3
|
+
from pydantic import Extra
|
4
4
|
|
5
|
+
from classiq.interface.ast_node import ASTNode
|
5
6
|
from classiq.interface.model.handle_binding import (
|
6
7
|
HandleBinding,
|
7
8
|
SlicedHandleBinding,
|
@@ -9,7 +10,7 @@ from classiq.interface.model.handle_binding import (
|
|
9
10
|
)
|
10
11
|
|
11
12
|
|
12
|
-
class QuantumStatement(
|
13
|
+
class QuantumStatement(ASTNode):
|
13
14
|
class Config:
|
14
15
|
extra = Extra.forbid
|
15
16
|
|