classiq 0.93.0__py3-none-any.whl → 0.94.1__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.1.dist-info}/METADATA +2 -3
- {classiq-0.93.0.dist-info → classiq-0.94.1.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.1.dist-info}/WHEEL +0 -0
- {classiq-0.93.0.dist-info → classiq-0.94.1.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
import itertools
|
|
3
|
-
import warnings
|
|
4
|
-
from collections.abc import Collection, Iterator, Sequence
|
|
5
|
-
from contextlib import contextmanager
|
|
6
|
-
from typing import Optional, Union
|
|
7
|
-
|
|
8
|
-
from classiq.interface.exceptions import (
|
|
9
|
-
ClassiqDeprecationWarning,
|
|
10
|
-
ClassiqInternalExpansionError,
|
|
11
|
-
)
|
|
12
|
-
from classiq.interface.generator.functions.port_declaration import (
|
|
13
|
-
PortDeclarationDirection,
|
|
14
|
-
)
|
|
15
|
-
from classiq.interface.generator.functions.type_modifier import TypeModifier
|
|
16
|
-
from classiq.interface.model.allocate import Allocate
|
|
17
|
-
from classiq.interface.model.bind_operation import BindOperation
|
|
18
|
-
from classiq.interface.model.block import Block
|
|
19
|
-
from classiq.interface.model.control import Control
|
|
20
|
-
from classiq.interface.model.invert import Invert
|
|
21
|
-
from classiq.interface.model.model_visitor import ModelVisitor
|
|
22
|
-
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
23
|
-
from classiq.interface.model.phase_operation import PhaseOperation
|
|
24
|
-
from classiq.interface.model.port_declaration import PortDeclaration
|
|
25
|
-
from classiq.interface.model.power import Power
|
|
26
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
27
|
-
AmplitudeLoadingOperation,
|
|
28
|
-
)
|
|
29
|
-
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
30
|
-
ArithmeticOperation,
|
|
31
|
-
)
|
|
32
|
-
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
33
|
-
QuantumExpressionOperation,
|
|
34
|
-
)
|
|
35
|
-
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
|
36
|
-
from classiq.interface.model.within_apply_operation import WithinApply
|
|
37
|
-
from classiq.interface.source_reference import SourceReference
|
|
38
|
-
|
|
39
|
-
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _inconsistent_type_modifier_error(
|
|
43
|
-
port_name: str,
|
|
44
|
-
expected: TypeModifier,
|
|
45
|
-
actual: TypeModifier,
|
|
46
|
-
source_ref: Optional[Union[SourceReference, str]] = None,
|
|
47
|
-
) -> str:
|
|
48
|
-
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
|
49
|
-
return (
|
|
50
|
-
f"The use of variable '{port_name}' does not conform to its declared modifier: "
|
|
51
|
-
f"expected '{expected.name}', but found '{actual.name}'.\n"
|
|
52
|
-
f"Tip: If the cumulative use of the variable in the function matches '{expected.name}', "
|
|
53
|
-
f"use the `unchecked` flag to instruct the compiler to disregard individual operations."
|
|
54
|
-
f"{source_ref_str}\n"
|
|
55
|
-
"The deprecation warning will be elevated to an error starting July 23, 2025, at the earliest."
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _inconsistent_type_modifier_in_binding_error(
|
|
60
|
-
expected: TypeModifier,
|
|
61
|
-
known_modifiers: dict[str, TypeModifier],
|
|
62
|
-
source_ref: Optional[Union[SourceReference, str]] = None,
|
|
63
|
-
) -> str:
|
|
64
|
-
actual = ", ".join(
|
|
65
|
-
f"{name}: {modifier.name}" for name, modifier in known_modifiers.items()
|
|
66
|
-
)
|
|
67
|
-
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
|
68
|
-
return (
|
|
69
|
-
f"Inconsistent modifiers in variable binding: "
|
|
70
|
-
f"Expected modifier: {expected.name}, Actual modifiers: {actual}"
|
|
71
|
-
f"{source_ref_str}\n"
|
|
72
|
-
"The deprecation warning will be elevated to an error starting July 23, 2025, at the earliest."
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class TypeModifierValidation(ModelVisitor):
|
|
77
|
-
"""
|
|
78
|
-
This class assumes that function calls are topologically sorted, so it traverses
|
|
79
|
-
the list of function calls and infers the type modifiers for each function call
|
|
80
|
-
without going recursively into the function calls.
|
|
81
|
-
The function definition ports are modified inplace.
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
def __init__(
|
|
85
|
-
self, *, skip_validation: bool = False, support_unused_ports: bool = True
|
|
86
|
-
) -> None:
|
|
87
|
-
self._signature_ports: dict[str, PortDeclaration] = dict()
|
|
88
|
-
self._inferred_ports: dict[str, PortDeclaration] = dict()
|
|
89
|
-
self._unchecked: set[str] = set()
|
|
90
|
-
|
|
91
|
-
self._initialized_vars: dict[str, TypeModifier] = dict()
|
|
92
|
-
self._bound_vars: list[set[str]] = []
|
|
93
|
-
|
|
94
|
-
self._conjugation_context: bool = False
|
|
95
|
-
self._support_unused_ports = (
|
|
96
|
-
support_unused_ports # could be turned off for debugging
|
|
97
|
-
)
|
|
98
|
-
self._skip_validation = skip_validation
|
|
99
|
-
self._source_ref: Optional[Union[SourceReference, str]] = None
|
|
100
|
-
|
|
101
|
-
@contextmanager
|
|
102
|
-
def validate_ports(
|
|
103
|
-
self, ports: Collection[PortDeclaration], unchecked: Collection[str]
|
|
104
|
-
) -> Iterator[bool]:
|
|
105
|
-
for port in ports:
|
|
106
|
-
if port.type_modifier is TypeModifier.Inferred:
|
|
107
|
-
self._inferred_ports[port.name] = port
|
|
108
|
-
else:
|
|
109
|
-
self._signature_ports[port.name] = port
|
|
110
|
-
self._unchecked.update(unchecked)
|
|
111
|
-
|
|
112
|
-
yield len(self._inferred_ports) > 0 or (
|
|
113
|
-
any(
|
|
114
|
-
port.type_modifier is not TypeModifier.Mutable
|
|
115
|
-
for port in self._signature_ports.values()
|
|
116
|
-
)
|
|
117
|
-
and not self._skip_validation
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
self._set_unused_as_const()
|
|
121
|
-
self._signature_ports.clear()
|
|
122
|
-
self._inferred_ports.clear()
|
|
123
|
-
self._unchecked.clear()
|
|
124
|
-
|
|
125
|
-
@contextmanager
|
|
126
|
-
def conjugation_context(self) -> Iterator[None]:
|
|
127
|
-
previous_context = self._conjugation_context
|
|
128
|
-
self._conjugation_context = True
|
|
129
|
-
try:
|
|
130
|
-
yield
|
|
131
|
-
finally:
|
|
132
|
-
self._conjugation_context = previous_context
|
|
133
|
-
|
|
134
|
-
@contextmanager
|
|
135
|
-
def source_reference_context(
|
|
136
|
-
self, source_ref: Optional[Union[SourceReference, str]]
|
|
137
|
-
) -> Iterator[None]:
|
|
138
|
-
previous_source_ref = self._source_ref
|
|
139
|
-
self._source_ref = source_ref
|
|
140
|
-
try:
|
|
141
|
-
yield
|
|
142
|
-
finally:
|
|
143
|
-
self._source_ref = previous_source_ref
|
|
144
|
-
|
|
145
|
-
def _set_unused_as_const(self) -> None:
|
|
146
|
-
unresolved_ports = [
|
|
147
|
-
port
|
|
148
|
-
for port in self._inferred_ports.values()
|
|
149
|
-
if port.type_modifier is TypeModifier.Inferred
|
|
150
|
-
]
|
|
151
|
-
if not self._support_unused_ports and len(unresolved_ports) > 0:
|
|
152
|
-
raise ClassiqInternalExpansionError(
|
|
153
|
-
f"Unresolved inferred ports detected: {', '.join(port.name for port in unresolved_ports)}. "
|
|
154
|
-
"All ports must have their type modifiers resolved."
|
|
155
|
-
)
|
|
156
|
-
for port in unresolved_ports:
|
|
157
|
-
port.type_modifier = TypeModifier.Const
|
|
158
|
-
|
|
159
|
-
def _validate_modifier(self, candidate: str, modifier: TypeModifier) -> None:
|
|
160
|
-
if self._conjugation_context and modifier is TypeModifier.Permutable:
|
|
161
|
-
modifier = TypeModifier.Const
|
|
162
|
-
|
|
163
|
-
if candidate in self._inferred_ports:
|
|
164
|
-
self._inferred_ports[candidate].type_modifier = TypeModifier.and_(
|
|
165
|
-
self._inferred_ports[candidate].type_modifier, modifier
|
|
166
|
-
)
|
|
167
|
-
return
|
|
168
|
-
|
|
169
|
-
if self._skip_validation or candidate in self._unchecked:
|
|
170
|
-
return
|
|
171
|
-
|
|
172
|
-
if candidate in self._signature_ports:
|
|
173
|
-
self._validate_signature_modifier(candidate, modifier)
|
|
174
|
-
|
|
175
|
-
elif candidate in self._initialized_vars:
|
|
176
|
-
self._initialized_vars[candidate] = TypeModifier.and_(
|
|
177
|
-
self._initialized_vars[candidate], modifier
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
def _validate_signature_modifier(
|
|
181
|
-
self, candidate: str, modifier: TypeModifier
|
|
182
|
-
) -> None:
|
|
183
|
-
signature_modifier = self._signature_ports[candidate].type_modifier
|
|
184
|
-
if signature_modifier is not TypeModifier.and_(signature_modifier, modifier):
|
|
185
|
-
warnings.warn(
|
|
186
|
-
_inconsistent_type_modifier_error(
|
|
187
|
-
candidate, signature_modifier, modifier, self._source_ref
|
|
188
|
-
),
|
|
189
|
-
ClassiqDeprecationWarning,
|
|
190
|
-
stacklevel=1,
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
def _add_initialized_modifier(self, var: str, modifier: TypeModifier) -> None:
|
|
194
|
-
if var in self._inferred_ports or var in self._signature_ports:
|
|
195
|
-
return
|
|
196
|
-
if self._conjugation_context and modifier is TypeModifier.Permutable:
|
|
197
|
-
modifier = TypeModifier.Const
|
|
198
|
-
self._initialized_vars[var] = modifier
|
|
199
|
-
|
|
200
|
-
def run(
|
|
201
|
-
self,
|
|
202
|
-
func_def: NativeFunctionDefinition,
|
|
203
|
-
unchecked: Collection[str],
|
|
204
|
-
) -> None:
|
|
205
|
-
with (
|
|
206
|
-
self.validate_ports(
|
|
207
|
-
func_def.port_declarations, unchecked
|
|
208
|
-
) as should_validate,
|
|
209
|
-
self.source_reference_context(f"function '{func_def.name}'"),
|
|
210
|
-
):
|
|
211
|
-
if should_validate:
|
|
212
|
-
self.visit(func_def.body)
|
|
213
|
-
self._update_bound_vars()
|
|
214
|
-
|
|
215
|
-
def _update_bound_vars(self) -> None:
|
|
216
|
-
merged_bound_vars = _merge_overlapping(self._bound_vars)
|
|
217
|
-
for bound_vars in merged_bound_vars:
|
|
218
|
-
reduced_modifier = self._get_reduced_modifier(bound_vars)
|
|
219
|
-
for var in bound_vars:
|
|
220
|
-
self._validate_modifier(var, reduced_modifier)
|
|
221
|
-
|
|
222
|
-
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
|
223
|
-
with self.source_reference_context(call.source_ref):
|
|
224
|
-
for handle, port in call.handles_with_params:
|
|
225
|
-
self._validate_modifier(handle.name, port.type_modifier)
|
|
226
|
-
if port.direction is PortDeclarationDirection.Output:
|
|
227
|
-
self._add_initialized_modifier(handle.name, port.type_modifier)
|
|
228
|
-
|
|
229
|
-
if self._has_inputs(call):
|
|
230
|
-
bound_vars = {
|
|
231
|
-
handle.name
|
|
232
|
-
for handle, port in call.handles_with_params
|
|
233
|
-
if port.direction is not PortDeclarationDirection.Inout
|
|
234
|
-
and handle.name not in self._unchecked
|
|
235
|
-
}
|
|
236
|
-
self._bound_vars.append(bound_vars)
|
|
237
|
-
|
|
238
|
-
@staticmethod
|
|
239
|
-
def _has_inputs(call: QuantumFunctionCall) -> bool:
|
|
240
|
-
return any(
|
|
241
|
-
port.direction is PortDeclarationDirection.Input
|
|
242
|
-
for _, port in call.handles_with_params
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
def visit_Allocate(self, alloc: Allocate) -> None:
|
|
246
|
-
with self.source_reference_context(alloc.source_ref):
|
|
247
|
-
self._validate_modifier(alloc.target.name, TypeModifier.Permutable)
|
|
248
|
-
self._add_initialized_modifier(alloc.target.name, TypeModifier.Permutable)
|
|
249
|
-
|
|
250
|
-
def visit_BindOperation(self, bind_op: BindOperation) -> None:
|
|
251
|
-
var_names = {
|
|
252
|
-
handle.name
|
|
253
|
-
for handle in itertools.chain(bind_op.in_handles, bind_op.out_handles)
|
|
254
|
-
if handle.name not in self._unchecked
|
|
255
|
-
}
|
|
256
|
-
self._bound_vars.append(var_names)
|
|
257
|
-
for handle in bind_op.out_handles:
|
|
258
|
-
self._add_initialized_modifier(handle.name, TypeModifier.Inferred)
|
|
259
|
-
|
|
260
|
-
def _get_reduced_modifier(self, bound_vars: set[str]) -> TypeModifier:
|
|
261
|
-
signature_modifiers = {
|
|
262
|
-
name: self._signature_ports[name].type_modifier
|
|
263
|
-
for name in bound_vars.intersection(self._signature_ports)
|
|
264
|
-
}
|
|
265
|
-
known_inferred_modifiers = {
|
|
266
|
-
name: self._inferred_ports[name].type_modifier
|
|
267
|
-
for name in bound_vars.intersection(self._inferred_ports)
|
|
268
|
-
if self._inferred_ports[name].type_modifier is not TypeModifier.Inferred
|
|
269
|
-
}
|
|
270
|
-
known_initialized_modifiers = {
|
|
271
|
-
name: self._initialized_vars[name]
|
|
272
|
-
for name in bound_vars.intersection(self._initialized_vars)
|
|
273
|
-
if self._initialized_vars[name] is not TypeModifier.Inferred
|
|
274
|
-
}
|
|
275
|
-
known_modifiers = (
|
|
276
|
-
signature_modifiers | known_inferred_modifiers | known_initialized_modifiers
|
|
277
|
-
)
|
|
278
|
-
min_modifier = self._get_min_modifier(list(known_modifiers.values()))
|
|
279
|
-
if not all(
|
|
280
|
-
type_modifier is min_modifier
|
|
281
|
-
for type_modifier in signature_modifiers.values()
|
|
282
|
-
):
|
|
283
|
-
warnings.warn(
|
|
284
|
-
_inconsistent_type_modifier_in_binding_error(
|
|
285
|
-
min_modifier, known_modifiers, self._source_ref
|
|
286
|
-
),
|
|
287
|
-
ClassiqDeprecationWarning,
|
|
288
|
-
stacklevel=1,
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
return min_modifier
|
|
292
|
-
|
|
293
|
-
@staticmethod
|
|
294
|
-
def _get_min_modifier(modifiers: list[TypeModifier]) -> TypeModifier:
|
|
295
|
-
if len(modifiers) == 0:
|
|
296
|
-
return TypeModifier.Const
|
|
297
|
-
elif len(modifiers) == 1:
|
|
298
|
-
return modifiers[0]
|
|
299
|
-
else:
|
|
300
|
-
return functools.reduce(TypeModifier.and_, modifiers)
|
|
301
|
-
|
|
302
|
-
@staticmethod
|
|
303
|
-
def _extract_expr_vars(expr_op: QuantumExpressionOperation) -> list[str]:
|
|
304
|
-
expr_val = expr_op.expression.value.value
|
|
305
|
-
if not isinstance(expr_val, QmodAnnotatedExpression):
|
|
306
|
-
return []
|
|
307
|
-
return list(
|
|
308
|
-
dict.fromkeys(var.name for var in expr_val.get_quantum_vars().values())
|
|
309
|
-
)
|
|
310
|
-
|
|
311
|
-
def visit_ArithmeticOperation(self, arith: ArithmeticOperation) -> None:
|
|
312
|
-
with self.source_reference_context(arith.source_ref):
|
|
313
|
-
result_var = arith.result_var.name
|
|
314
|
-
self._validate_modifier(result_var, TypeModifier.Permutable)
|
|
315
|
-
for expr_var in self._extract_expr_vars(arith):
|
|
316
|
-
self._validate_modifier(expr_var, TypeModifier.Const)
|
|
317
|
-
if not arith.is_inplace:
|
|
318
|
-
self._add_initialized_modifier(result_var, TypeModifier.Permutable)
|
|
319
|
-
|
|
320
|
-
def visit_AmplitudeLoadingOperation(
|
|
321
|
-
self, amp_load: AmplitudeLoadingOperation
|
|
322
|
-
) -> None:
|
|
323
|
-
with self.source_reference_context(amp_load.source_ref):
|
|
324
|
-
result_var = amp_load.result_var.name
|
|
325
|
-
self._validate_modifier(result_var, TypeModifier.Mutable)
|
|
326
|
-
for expr_var in self._extract_expr_vars(amp_load):
|
|
327
|
-
self._validate_modifier(expr_var, TypeModifier.Const)
|
|
328
|
-
|
|
329
|
-
def visit_PhaseOperation(self, phase_op: PhaseOperation) -> None:
|
|
330
|
-
with self.source_reference_context(phase_op.source_ref):
|
|
331
|
-
for expr_var in self._extract_expr_vars(phase_op):
|
|
332
|
-
self._validate_modifier(expr_var, TypeModifier.Const)
|
|
333
|
-
|
|
334
|
-
def visit_Control(self, control: Control) -> None:
|
|
335
|
-
with self.source_reference_context(control.source_ref):
|
|
336
|
-
for control_var in self._extract_expr_vars(control):
|
|
337
|
-
self._validate_modifier(control_var, TypeModifier.Const)
|
|
338
|
-
self.visit(control.body)
|
|
339
|
-
if control.else_block is not None:
|
|
340
|
-
self.visit(control.else_block)
|
|
341
|
-
|
|
342
|
-
def visit_Invert(self, invert: Invert) -> None:
|
|
343
|
-
with self.source_reference_context(invert.source_ref):
|
|
344
|
-
self.visit(invert.body)
|
|
345
|
-
|
|
346
|
-
def visit_Power(self, power: Power) -> None:
|
|
347
|
-
with self.source_reference_context(power.source_ref):
|
|
348
|
-
self.visit(power.body)
|
|
349
|
-
|
|
350
|
-
def visit_WithinApply(self, within_apply: WithinApply) -> None:
|
|
351
|
-
with self.source_reference_context(within_apply.source_ref):
|
|
352
|
-
with self.conjugation_context():
|
|
353
|
-
self.visit(within_apply.compute)
|
|
354
|
-
self.visit(within_apply.action)
|
|
355
|
-
|
|
356
|
-
def visit_Block(self, block: Block) -> None:
|
|
357
|
-
with self.source_reference_context(block.source_ref):
|
|
358
|
-
self.visit(block.statements)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
def _merge_overlapping(bound_vars: Sequence[Collection[str]]) -> list[set[str]]:
|
|
362
|
-
"""
|
|
363
|
-
Merges overlapping sets of bound variables.
|
|
364
|
-
Two sets overlap if they share at least one variable.
|
|
365
|
-
"""
|
|
366
|
-
all_bound_vars = bound_vars
|
|
367
|
-
merged_bound_vars: list[set[str]] = []
|
|
368
|
-
loop_guard: int = 10
|
|
369
|
-
idx: int = 0
|
|
370
|
-
|
|
371
|
-
for _ in range(loop_guard):
|
|
372
|
-
idx += 1
|
|
373
|
-
|
|
374
|
-
merged_bound_vars = []
|
|
375
|
-
modified: bool = False
|
|
376
|
-
for current_bound_vars in all_bound_vars:
|
|
377
|
-
for existing in merged_bound_vars:
|
|
378
|
-
if existing.intersection(current_bound_vars):
|
|
379
|
-
existing.update(current_bound_vars)
|
|
380
|
-
modified = True
|
|
381
|
-
break
|
|
382
|
-
else:
|
|
383
|
-
merged_bound_vars.append(set(current_bound_vars))
|
|
384
|
-
|
|
385
|
-
if not modified:
|
|
386
|
-
break
|
|
387
|
-
all_bound_vars = merged_bound_vars
|
|
388
|
-
|
|
389
|
-
if idx == loop_guard - 1:
|
|
390
|
-
raise ClassiqInternalExpansionError
|
|
391
|
-
|
|
392
|
-
return merged_bound_vars
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import warnings
|
|
2
|
-
|
|
3
|
-
from classiq.interface.exceptions import ClassiqDeprecationWarning
|
|
4
|
-
|
|
5
|
-
from classiq.qmod.builtins.structs import (
|
|
6
|
-
FockHamiltonianProblem,
|
|
7
|
-
MoleculeProblem,
|
|
8
|
-
)
|
|
9
|
-
from classiq.qmod.qfunc import qfunc
|
|
10
|
-
from classiq.qmod.qmod_parameter import CArray, CInt
|
|
11
|
-
from classiq.qmod.qmod_variable import QArray, QBit
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@qfunc(external=True)
|
|
15
|
-
def molecule_ucc(
|
|
16
|
-
molecule_problem: MoleculeProblem,
|
|
17
|
-
excitations: CArray[CInt],
|
|
18
|
-
qbv: QArray[QBit],
|
|
19
|
-
) -> None:
|
|
20
|
-
warnings.warn(
|
|
21
|
-
(
|
|
22
|
-
"The function `molecule_ucc` is deprecated and will no "
|
|
23
|
-
"longer be supported starting on 2025-09-18 at the earliest. "
|
|
24
|
-
"For more information on Classiq's chemistry application, see "
|
|
25
|
-
"https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
|
|
26
|
-
),
|
|
27
|
-
category=ClassiqDeprecationWarning,
|
|
28
|
-
stacklevel=2,
|
|
29
|
-
)
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@qfunc(external=True)
|
|
34
|
-
def molecule_hva(
|
|
35
|
-
molecule_problem: MoleculeProblem,
|
|
36
|
-
reps: CInt,
|
|
37
|
-
qbv: QArray[QBit],
|
|
38
|
-
) -> None:
|
|
39
|
-
warnings.warn(
|
|
40
|
-
(
|
|
41
|
-
"The function `molecule_hva` is deprecated and will no "
|
|
42
|
-
"longer be supported starting on 2025-09-18 at the earliest. "
|
|
43
|
-
"For more information on Classiq's chemistry application, see "
|
|
44
|
-
"https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
|
|
45
|
-
),
|
|
46
|
-
category=ClassiqDeprecationWarning,
|
|
47
|
-
stacklevel=2,
|
|
48
|
-
)
|
|
49
|
-
pass
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@qfunc(external=True)
|
|
53
|
-
def molecule_hartree_fock(
|
|
54
|
-
molecule_problem: MoleculeProblem,
|
|
55
|
-
qbv: QArray[QBit],
|
|
56
|
-
) -> None:
|
|
57
|
-
warnings.warn(
|
|
58
|
-
(
|
|
59
|
-
"The function `molecule_hartree_fock` is deprecated and will no "
|
|
60
|
-
"longer be supported starting on 2025-09-18 at the earliest. "
|
|
61
|
-
"For more information on Classiq's chemistry application, see "
|
|
62
|
-
"https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
|
|
63
|
-
),
|
|
64
|
-
category=ClassiqDeprecationWarning,
|
|
65
|
-
stacklevel=2,
|
|
66
|
-
)
|
|
67
|
-
pass
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@qfunc(external=True)
|
|
71
|
-
def fock_hamiltonian_ucc(
|
|
72
|
-
fock_hamiltonian_problem: FockHamiltonianProblem,
|
|
73
|
-
excitations: CArray[CInt],
|
|
74
|
-
qbv: QArray[QBit],
|
|
75
|
-
) -> None:
|
|
76
|
-
warnings.warn(
|
|
77
|
-
(
|
|
78
|
-
"The function `fock_hamiltonian_ucc` is deprecated and will no "
|
|
79
|
-
"longer be supported starting on 2025-09-18 at the earliest. "
|
|
80
|
-
"For more information on Classiq's chemistry application, see "
|
|
81
|
-
"https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
|
|
82
|
-
),
|
|
83
|
-
category=ClassiqDeprecationWarning,
|
|
84
|
-
stacklevel=2,
|
|
85
|
-
)
|
|
86
|
-
pass
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@qfunc(external=True)
|
|
90
|
-
def fock_hamiltonian_hva(
|
|
91
|
-
fock_hamiltonian_problem: FockHamiltonianProblem,
|
|
92
|
-
reps: CInt,
|
|
93
|
-
qbv: QArray[QBit],
|
|
94
|
-
) -> None:
|
|
95
|
-
warnings.warn(
|
|
96
|
-
(
|
|
97
|
-
"The function `fock_hamiltonian_hva` is deprecated and will no "
|
|
98
|
-
"longer be supported starting on 2025-09-18 at the earliest. "
|
|
99
|
-
"For more information on Classiq's chemistry application, see "
|
|
100
|
-
"https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
|
|
101
|
-
),
|
|
102
|
-
category=ClassiqDeprecationWarning,
|
|
103
|
-
stacklevel=2,
|
|
104
|
-
)
|
|
105
|
-
pass
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
@qfunc(external=True)
|
|
109
|
-
def fock_hamiltonian_hartree_fock(
|
|
110
|
-
fock_hamiltonian_problem: FockHamiltonianProblem,
|
|
111
|
-
qbv: QArray[QBit],
|
|
112
|
-
) -> None:
|
|
113
|
-
warnings.warn(
|
|
114
|
-
(
|
|
115
|
-
"The function `fock_hamiltonian_hartree_fock` is deprecated and will no "
|
|
116
|
-
"longer be supported starting on 2025-09-18 at the earliest. "
|
|
117
|
-
"For more information on Classiq's chemistry application, see "
|
|
118
|
-
"https://docs.classiq.io/latest/explore/applications/chemistry/classiq_chemistry_application/classiq_chemistry_application/."
|
|
119
|
-
),
|
|
120
|
-
category=ClassiqDeprecationWarning,
|
|
121
|
-
stacklevel=2,
|
|
122
|
-
)
|
|
123
|
-
pass
|
|
File without changes
|
|
File without changes
|