classiq 0.92.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 +6 -5
- classiq/applications/qsvm/qsvm_data_generation.py +1 -2
- classiq/evaluators/classical_expression.py +0 -4
- classiq/evaluators/parameter_types.py +17 -12
- 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 +6 -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 +8 -4
- classiq/model_expansions/quantum_operations/allocate.py +4 -4
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +8 -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 +61 -29
- 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 +19 -14
- 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 +43 -58
- classiq/qmod/builtins/structs.py +2 -58
- classiq/qmod/cfunc.py +3 -2
- classiq/qmod/classical_function.py +2 -1
- classiq/qmod/classical_variable.py +4 -2
- 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 +33 -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/symbolic_expr.py +12 -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.92.0.dist-info → classiq-0.94.0.dist-info}/METADATA +38 -37
- {classiq-0.92.0.dist-info → classiq-0.94.0.dist-info}/RECORD +240 -261
- classiq-0.94.0.dist-info/WHEEL +4 -0
- classiq-0.94.0.dist-info/licenses/LICENSE.txt +27 -0
- 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.92.0.dist-info/WHEEL +0 -4
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
ANALYZER_PREFIX = "/analyzer"
|
|
2
|
-
CHEMISTRY_PREFIX = "/chemistry"
|
|
3
2
|
EXECUTION_PREFIX = "/execution"
|
|
4
3
|
EXECUTION_SESSIONS_PREFIX = EXECUTION_PREFIX + "/sessions"
|
|
5
4
|
CONVERSION_PREFIX = "/conversion"
|
|
@@ -62,9 +61,6 @@ ANALYZER_RB_FULL_PATH = ANALYZER_PREFIX + TASK_RB_SUFFIX
|
|
|
62
61
|
|
|
63
62
|
TASKS_SOLVE_EXACT_SUFFIX = "/tasks/solve_exact"
|
|
64
63
|
|
|
65
|
-
GENERATE_HAMILTONIAN_SUFFIX = "/generate_hamiltonian"
|
|
66
|
-
GENERATE_HAMILTONIAN_FULL_PATH = CHEMISTRY_PREFIX + GENERATE_HAMILTONIAN_SUFFIX
|
|
67
|
-
|
|
68
64
|
CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX = "/execution_input"
|
|
69
65
|
CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_FULL = (
|
|
70
66
|
CONVERSION_PREFIX + CONVERSION_GENERATED_CIRCUIT_TO_EXECUTION_INPUT_SUFFIX
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import re
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
import pydantic
|
|
7
6
|
|
|
@@ -30,7 +29,7 @@ class SourceReference(HashablePydanticBaseModel):
|
|
|
30
29
|
start_column: int
|
|
31
30
|
end_line: int
|
|
32
31
|
end_column: int
|
|
33
|
-
file_name:
|
|
32
|
+
file_name: str | None = pydantic.Field(default=None)
|
|
34
33
|
|
|
35
34
|
def __str__(self) -> str:
|
|
36
35
|
return f"{self.file_string()}{self.ref_inside_file()}"
|
|
@@ -47,8 +46,8 @@ class SourceReference(HashablePydanticBaseModel):
|
|
|
47
46
|
|
|
48
47
|
class SourceReferencedError(pydantic.BaseModel):
|
|
49
48
|
error: str
|
|
50
|
-
source_ref:
|
|
51
|
-
function:
|
|
49
|
+
source_ref: SourceReference | None = None
|
|
50
|
+
function: str | None = None
|
|
52
51
|
|
|
53
52
|
def __str__(self) -> str:
|
|
54
53
|
source_referenced_error = (
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional, Union
|
|
3
2
|
|
|
4
3
|
from classiq.interface.generator.arith import number_utils
|
|
5
4
|
from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
|
|
@@ -23,7 +22,7 @@ class NumericAttributes:
|
|
|
23
22
|
size: int,
|
|
24
23
|
is_signed: bool,
|
|
25
24
|
fraction_digits: int,
|
|
26
|
-
bounds:
|
|
25
|
+
bounds: tuple[float, float] | None = None,
|
|
27
26
|
trim_bounds: bool = False,
|
|
28
27
|
) -> None:
|
|
29
28
|
self.size = size
|
|
@@ -108,7 +107,7 @@ class NumericAttributes:
|
|
|
108
107
|
def from_constant(
|
|
109
108
|
cls,
|
|
110
109
|
value: float,
|
|
111
|
-
machine_precision:
|
|
110
|
+
machine_precision: int | None = None,
|
|
112
111
|
) -> "NumericAttributes":
|
|
113
112
|
if machine_precision is not None:
|
|
114
113
|
value = number_utils.limit_fraction_places(value, machine_precision)
|
|
@@ -124,7 +123,7 @@ class NumericAttributes:
|
|
|
124
123
|
def from_quantum_scalar(
|
|
125
124
|
cls,
|
|
126
125
|
quantum_type: QuantumScalar,
|
|
127
|
-
machine_precision:
|
|
126
|
+
machine_precision: int | None = None,
|
|
128
127
|
) -> "NumericAttributes":
|
|
129
128
|
return cls(
|
|
130
129
|
size=quantum_type.size_in_bits,
|
|
@@ -137,7 +136,7 @@ class NumericAttributes:
|
|
|
137
136
|
def from_register_arithmetic_info(
|
|
138
137
|
cls,
|
|
139
138
|
register: RegisterArithmeticInfo,
|
|
140
|
-
machine_precision:
|
|
139
|
+
machine_precision: int | None = None,
|
|
141
140
|
) -> "NumericAttributes":
|
|
142
141
|
return cls.from_quantum_scalar(
|
|
143
142
|
quantum_type=register_info_to_quantum_type(register),
|
|
@@ -147,8 +146,8 @@ class NumericAttributes:
|
|
|
147
146
|
@classmethod
|
|
148
147
|
def from_type_or_constant(
|
|
149
148
|
cls,
|
|
150
|
-
from_:
|
|
151
|
-
machine_precision:
|
|
149
|
+
from_: float | QuantumScalar | RegisterArithmeticInfo,
|
|
150
|
+
machine_precision: int | None = None,
|
|
152
151
|
) -> "NumericAttributes":
|
|
153
152
|
if isinstance(from_, QuantumScalar):
|
|
154
153
|
return cls.from_quantum_scalar(from_, machine_precision)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import math
|
|
2
2
|
from collections.abc import Sequence
|
|
3
|
-
from typing import Union
|
|
4
3
|
|
|
5
4
|
from classiq.interface.exceptions import ClassiqValueError
|
|
6
5
|
|
|
@@ -153,7 +152,7 @@ def compute_result_attrs_multiply(
|
|
|
153
152
|
|
|
154
153
|
def compute_result_attrs_power(
|
|
155
154
|
left: NumericAttributes,
|
|
156
|
-
right:
|
|
155
|
+
right: int | float,
|
|
157
156
|
machine_precision: int,
|
|
158
157
|
) -> NumericAttributes:
|
|
159
158
|
if not float(right).is_integer() or right <= 0:
|
|
@@ -174,7 +173,7 @@ def compute_result_attrs_power(
|
|
|
174
173
|
|
|
175
174
|
def compute_result_attrs_lshift(
|
|
176
175
|
left: NumericAttributes,
|
|
177
|
-
right:
|
|
176
|
+
right: int | float,
|
|
178
177
|
machine_precision: int,
|
|
179
178
|
) -> NumericAttributes:
|
|
180
179
|
if not float(right).is_integer() or right < 0:
|
|
@@ -196,7 +195,7 @@ def compute_result_attrs_lshift(
|
|
|
196
195
|
|
|
197
196
|
def compute_result_attrs_rshift(
|
|
198
197
|
left: NumericAttributes,
|
|
199
|
-
right:
|
|
198
|
+
right: int | float,
|
|
200
199
|
machine_precision: int,
|
|
201
200
|
) -> NumericAttributes:
|
|
202
201
|
if not float(right).is_integer() or right < 0:
|
|
@@ -219,7 +218,7 @@ def compute_result_attrs_rshift(
|
|
|
219
218
|
|
|
220
219
|
def compute_result_attrs_modulo(
|
|
221
220
|
left: NumericAttributes,
|
|
222
|
-
right:
|
|
221
|
+
right: int | float,
|
|
223
222
|
machine_precision: int,
|
|
224
223
|
) -> NumericAttributes:
|
|
225
224
|
if not float(right).is_integer() or right < 2:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
import dataclasses
|
|
3
|
-
from collections.abc import Sequence
|
|
3
|
+
from collections.abc import Callable, Sequence
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import TYPE_CHECKING,
|
|
5
|
+
from typing import TYPE_CHECKING, cast
|
|
6
6
|
|
|
7
7
|
from typing_extensions import Self
|
|
8
8
|
|
|
@@ -297,7 +297,7 @@ class CapturedVars:
|
|
|
297
297
|
|
|
298
298
|
def _conjugate_direction(
|
|
299
299
|
self,
|
|
300
|
-
source_direction:
|
|
300
|
+
source_direction: PortDirection | bool,
|
|
301
301
|
target_direction: PortDirection,
|
|
302
302
|
var_name: str,
|
|
303
303
|
) -> PortDirection:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
3
|
from classiq.interface.generator.compiler_keywords import CAPTURE_SUFFIX
|
|
5
4
|
from classiq.interface.model.handle_binding import HANDLE_ID_SEPARATOR, HandleBinding
|
|
@@ -17,7 +16,7 @@ def mangle_captured_var_name(
|
|
|
17
16
|
return f"{var_name}{CAPTURE_SUFFIX}{function_name}__{function_depth}"
|
|
18
17
|
|
|
19
18
|
|
|
20
|
-
def _match_capture_pattern(name: str) ->
|
|
19
|
+
def _match_capture_pattern(name: str) -> re.Match[str] | None:
|
|
21
20
|
return re.match(CAPTURE_PATTERN, name)
|
|
22
21
|
|
|
23
22
|
|
|
@@ -2,7 +2,7 @@ import dataclasses
|
|
|
2
2
|
from collections.abc import Sequence
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
from typing_extensions import Self
|
|
8
8
|
|
|
@@ -47,7 +47,8 @@ class FunctionClosure(Closure):
|
|
|
47
47
|
is_lambda: bool = False
|
|
48
48
|
is_atomic: bool = False
|
|
49
49
|
signature_scope: Scope = field(default_factory=Scope)
|
|
50
|
-
|
|
50
|
+
permutation: bool = False
|
|
51
|
+
_depth: int | None = None
|
|
51
52
|
|
|
52
53
|
@property
|
|
53
54
|
def depth(self) -> int:
|
|
@@ -67,9 +68,9 @@ class FunctionClosure(Closure):
|
|
|
67
68
|
cls,
|
|
68
69
|
name: str,
|
|
69
70
|
scope: Scope,
|
|
70
|
-
body:
|
|
71
|
+
body: Sequence[QuantumStatement] | None = None,
|
|
71
72
|
positional_arg_declarations: Sequence[PositionalArg] = tuple(),
|
|
72
|
-
lambda_external_vars:
|
|
73
|
+
lambda_external_vars: CapturedVars | None = None,
|
|
73
74
|
is_atomic: bool = False,
|
|
74
75
|
**kwargs: Any,
|
|
75
76
|
) -> Self:
|
|
@@ -78,13 +79,13 @@ class FunctionClosure(Closure):
|
|
|
78
79
|
if lambda_external_vars is not None:
|
|
79
80
|
captured_vars.set_parent(lambda_external_vars)
|
|
80
81
|
return cls(
|
|
81
|
-
name,
|
|
82
|
-
blocks,
|
|
83
|
-
scope,
|
|
84
|
-
positional_arg_declarations,
|
|
85
|
-
captured_vars,
|
|
86
|
-
lambda_external_vars is not None,
|
|
87
|
-
is_atomic,
|
|
82
|
+
name=name,
|
|
83
|
+
blocks=blocks,
|
|
84
|
+
scope=scope,
|
|
85
|
+
positional_arg_declarations=positional_arg_declarations,
|
|
86
|
+
captured_vars=captured_vars,
|
|
87
|
+
is_lambda=lambda_external_vars is not None,
|
|
88
|
+
is_atomic=is_atomic,
|
|
88
89
|
**kwargs,
|
|
89
90
|
)
|
|
90
91
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from collections.abc import Iterator, Sequence
|
|
2
2
|
from contextlib import contextmanager
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Generic,
|
|
4
|
+
from typing import Generic, TypeVar
|
|
5
5
|
|
|
6
6
|
from classiq.interface.exceptions import (
|
|
7
7
|
ClassiqExpansionError,
|
|
@@ -13,6 +13,7 @@ from classiq.interface.generator.compiler_keywords import (
|
|
|
13
13
|
)
|
|
14
14
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
|
15
15
|
BLOCK_OPERATOR_NAME,
|
|
16
|
+
SKIP_CONTROL_OPERATOR_NAME,
|
|
16
17
|
WITHIN_APPLY_NAME,
|
|
17
18
|
)
|
|
18
19
|
from classiq.interface.model.model import MAIN_FUNCTION_NAME
|
|
@@ -39,7 +40,11 @@ from classiq.model_expansions.utils.counted_name_allocator import CountedNameAll
|
|
|
39
40
|
|
|
40
41
|
ClosureType = TypeVar("ClosureType", bound=Closure)
|
|
41
42
|
|
|
42
|
-
BLOCKS_ALLOWED_CAPTURING = (
|
|
43
|
+
BLOCKS_ALLOWED_CAPTURING = (
|
|
44
|
+
WITHIN_APPLY_NAME,
|
|
45
|
+
BLOCK_OPERATOR_NAME,
|
|
46
|
+
SKIP_CONTROL_OPERATOR_NAME,
|
|
47
|
+
)
|
|
43
48
|
|
|
44
49
|
|
|
45
50
|
@dataclass
|
|
@@ -87,6 +92,10 @@ class FunctionContext(OperationContext[FunctionClosure]):
|
|
|
87
92
|
def is_lambda(self) -> bool:
|
|
88
93
|
return self.closure.is_lambda
|
|
89
94
|
|
|
95
|
+
@property
|
|
96
|
+
def permutation(self) -> bool:
|
|
97
|
+
return self.closure.permutation
|
|
98
|
+
|
|
90
99
|
|
|
91
100
|
class OperationBuilder:
|
|
92
101
|
def __init__(
|
|
@@ -95,7 +104,7 @@ class OperationBuilder:
|
|
|
95
104
|
self._operations: list[OperationContext] = []
|
|
96
105
|
self._blocks: list[str] = []
|
|
97
106
|
self._functions_scope = functions_scope
|
|
98
|
-
self._current_source_ref:
|
|
107
|
+
self._current_source_ref: SourceReference | None = None
|
|
99
108
|
self._counted_name_allocator = counted_name_allocator
|
|
100
109
|
|
|
101
110
|
@property
|
|
@@ -201,9 +210,7 @@ class OperationBuilder:
|
|
|
201
210
|
parent_block.captured_vars.update(captured_vars)
|
|
202
211
|
|
|
203
212
|
@contextmanager
|
|
204
|
-
def source_ref_context(
|
|
205
|
-
self, source_ref: Optional[SourceReference]
|
|
206
|
-
) -> Iterator[None]:
|
|
213
|
+
def source_ref_context(self, source_ref: SourceReference | None) -> Iterator[None]:
|
|
207
214
|
previous_source_ref = self._current_source_ref
|
|
208
215
|
self._current_source_ref = source_ref
|
|
209
216
|
yield
|
|
@@ -218,6 +225,7 @@ class OperationBuilder:
|
|
|
218
225
|
name=name,
|
|
219
226
|
body=function_context.body,
|
|
220
227
|
positional_arg_declarations=params,
|
|
228
|
+
permutation=function_context.permutation,
|
|
221
229
|
)
|
|
222
230
|
|
|
223
231
|
def _get_expanded_function_name(self, function_context: FunctionContext) -> str:
|
|
@@ -113,10 +113,7 @@ def translate_ast_arg_to_python_qmod(param: PositionalArg, value: Any) -> Any:
|
|
|
113
113
|
if isinstance(param, PortDeclaration):
|
|
114
114
|
return _create_qvar_for_qtype(value.quantum_type, value.handle)
|
|
115
115
|
if isinstance(param, QuantumOperandDeclaration):
|
|
116
|
-
|
|
117
|
-
return QTerminalCallable(param)
|
|
118
|
-
inner_decl = param.model_copy(update={"is_list": False})
|
|
119
|
-
return [QTerminalCallable(inner_decl, index_=idx) for idx in range(len(value))]
|
|
116
|
+
return QTerminalCallable(param)
|
|
120
117
|
if (
|
|
121
118
|
isinstance(value, QmodStructInstance)
|
|
122
119
|
and not param.classical_type.is_purely_generative
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
from abc import abstractmethod
|
|
3
3
|
from collections import defaultdict
|
|
4
|
-
from collections.abc import Sequence
|
|
4
|
+
from collections.abc import Callable, Sequence
|
|
5
5
|
from contextlib import nullcontext
|
|
6
6
|
from functools import singledispatchmethod
|
|
7
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, cast
|
|
8
8
|
|
|
9
9
|
from pydantic import ValidationError
|
|
10
10
|
|
|
@@ -42,9 +42,6 @@ from classiq.interface.model.quantum_statement import QuantumStatement
|
|
|
42
42
|
|
|
43
43
|
from classiq.evaluators.classical_expression import process_scope_val
|
|
44
44
|
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
45
|
-
from classiq.evaluators.qmod_expression_visitors.qmod_expression_bwc import (
|
|
46
|
-
QmodExpressionBwc,
|
|
47
|
-
)
|
|
48
45
|
from classiq.evaluators.qmod_expression_visitors.qmod_expression_evaluator import (
|
|
49
46
|
evaluate_qmod_expression,
|
|
50
47
|
)
|
|
@@ -214,7 +211,6 @@ class BaseInterpreter:
|
|
|
214
211
|
if expression.is_evaluated():
|
|
215
212
|
return Evaluated(value=expression.value.value)
|
|
216
213
|
expr_ast = ast.parse(expression.expr, mode="eval").body
|
|
217
|
-
expr_ast = QmodExpressionBwc().visit(expr_ast)
|
|
218
214
|
expr_val = self._eval_expr(ast.unparse(expr_ast), treat_qnum_as_float)
|
|
219
215
|
if simplify and not expr_val.has_value(expr_val.root):
|
|
220
216
|
simplified_expr = simplify_qmod_expression(expr_val)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from functools import singledispatchmethod
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
from numpy.random import permutation
|
|
@@ -119,9 +119,9 @@ class GenerativeInterpreter(BaseInterpreter):
|
|
|
119
119
|
def infer_symbolic_parameters(
|
|
120
120
|
self,
|
|
121
121
|
functions: list[NativeFunctionDefinition],
|
|
122
|
-
additional_signatures:
|
|
122
|
+
additional_signatures: None | (
|
|
123
123
|
list[NamedParamsQuantumFunctionDeclaration]
|
|
124
|
-
|
|
124
|
+
) = None,
|
|
125
125
|
) -> None:
|
|
126
126
|
pass
|
|
127
127
|
|
|
@@ -134,6 +134,7 @@ class GenerativeInterpreter(BaseInterpreter):
|
|
|
134
134
|
function.func_decl.name or "<lambda>"
|
|
135
135
|
),
|
|
136
136
|
positional_arg_declarations=function.named_func_decl.positional_arg_declarations,
|
|
137
|
+
permutation=function.named_func_decl.permutation,
|
|
137
138
|
)
|
|
138
139
|
|
|
139
140
|
closure_class: type[FunctionClosure]
|
|
@@ -152,6 +153,7 @@ class GenerativeInterpreter(BaseInterpreter):
|
|
|
152
153
|
closure = closure_class.create(
|
|
153
154
|
name=func_decl.name,
|
|
154
155
|
positional_arg_declarations=func_decl.positional_arg_declarations,
|
|
156
|
+
permutation=func_decl.permutation,
|
|
155
157
|
body=function.body,
|
|
156
158
|
scope=Scope(parent=self._builder.current_scope),
|
|
157
159
|
lambda_external_vars=self._builder.current_block.captured_vars,
|
|
@@ -245,7 +247,9 @@ class GenerativeInterpreter(BaseInterpreter):
|
|
|
245
247
|
def emit_variable_declaration(
|
|
246
248
|
self, variable_declaration: VariableDeclarationStatement
|
|
247
249
|
) -> None:
|
|
248
|
-
VariableDeclarationStatementEmitter(
|
|
250
|
+
VariableDeclarationStatementEmitter(
|
|
251
|
+
self, allow_symbolic_vars=self._symbolic_parameters_switch
|
|
252
|
+
).emit(variable_declaration)
|
|
249
253
|
|
|
250
254
|
@emit.register
|
|
251
255
|
def emit_classical_if(self, classical_if: ClassicalIf) -> None:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, Any
|
|
1
|
+
from typing import TYPE_CHECKING, Any
|
|
2
2
|
|
|
3
3
|
import sympy
|
|
4
4
|
|
|
@@ -193,7 +193,7 @@ class AllocateEmitter(Emitter[Allocate]):
|
|
|
193
193
|
|
|
194
194
|
def _interpret_size(
|
|
195
195
|
self, size: Expression, var_name: str
|
|
196
|
-
) ->
|
|
196
|
+
) -> int | float | sympy.Basic | QmodAnnotatedExpression:
|
|
197
197
|
size_value = self._interpreter.evaluate(size).value
|
|
198
198
|
if not (
|
|
199
199
|
(
|
|
@@ -221,7 +221,7 @@ class AllocateEmitter(Emitter[Allocate]):
|
|
|
221
221
|
|
|
222
222
|
def _interpret_is_signed(
|
|
223
223
|
self, is_signed: Expression
|
|
224
|
-
) ->
|
|
224
|
+
) -> bool | sympy.Basic | QmodAnnotatedExpression:
|
|
225
225
|
is_signed_value = self._interpreter.evaluate(is_signed).value
|
|
226
226
|
if not self._allow_symbolic_attrs and not (
|
|
227
227
|
isinstance(is_signed_value, bool)
|
|
@@ -238,7 +238,7 @@ class AllocateEmitter(Emitter[Allocate]):
|
|
|
238
238
|
|
|
239
239
|
def _interpret_fraction_digits(
|
|
240
240
|
self, fraction_digits: Expression
|
|
241
|
-
) ->
|
|
241
|
+
) -> int | float | sympy.Expr | QmodAnnotatedExpression:
|
|
242
242
|
fraction_digits_value = self._interpreter.evaluate(fraction_digits).value
|
|
243
243
|
if not self._allow_symbolic_attrs and not (
|
|
244
244
|
isinstance(fraction_digits_value, (int, float))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from classiq.interface.exceptions import ClassiqExpansionError
|
|
4
4
|
from classiq.interface.generator.expressions.expression import Expression
|
|
@@ -62,6 +62,12 @@ class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
|
62
62
|
if isinstance(result_symbol, ClassicalSymbol):
|
|
63
63
|
return False
|
|
64
64
|
result_type = result_symbol.quantum_type
|
|
65
|
+
if not isinstance(result_type, QuantumScalar):
|
|
66
|
+
raise ClassiqExpansionError(
|
|
67
|
+
f"Cannot assign into a non-scalar quantum variable "
|
|
68
|
+
f"{str(result_symbol.handle)!r} of type "
|
|
69
|
+
f"{result_type.raw_qmod_type_name}"
|
|
70
|
+
)
|
|
65
71
|
|
|
66
72
|
if not (
|
|
67
73
|
isinstance(op, ArithmeticOperation)
|
|
@@ -105,9 +111,7 @@ class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
|
105
111
|
self._assign_to_inferred_var_and_bind(op, result_type, expression_type)
|
|
106
112
|
return True
|
|
107
113
|
|
|
108
|
-
def _infer_expression_type(
|
|
109
|
-
self, op: ArithmeticOperation
|
|
110
|
-
) -> Optional[QuantumScalar]:
|
|
114
|
+
def _infer_expression_type(self, op: ArithmeticOperation) -> QuantumScalar | None:
|
|
111
115
|
expr = self._evaluate_expression(op.expression)
|
|
112
116
|
expr_val = expr.value.value
|
|
113
117
|
if isinstance(expr_val, QmodAnnotatedExpression):
|
|
@@ -2,7 +2,6 @@ from collections.abc import Sequence
|
|
|
2
2
|
from itertools import chain, combinations
|
|
3
3
|
from typing import (
|
|
4
4
|
Generic,
|
|
5
|
-
Optional,
|
|
6
5
|
cast,
|
|
7
6
|
)
|
|
8
7
|
from uuid import UUID
|
|
@@ -16,9 +15,7 @@ from classiq.interface.exceptions import ClassiqExpansionError
|
|
|
16
15
|
from classiq.interface.generator.functions.port_declaration import (
|
|
17
16
|
PortDeclarationDirection,
|
|
18
17
|
)
|
|
19
|
-
from classiq.interface.generator.functions.type_modifier import TypeModifier
|
|
20
18
|
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
|
21
|
-
from classiq.interface.helpers.backward_compatibility import zip_strict
|
|
22
19
|
from classiq.interface.helpers.text_utils import are, readable_list, s
|
|
23
20
|
from classiq.interface.model.block import Block
|
|
24
21
|
from classiq.interface.model.classical_parameter_declaration import (
|
|
@@ -72,8 +69,8 @@ from classiq.model_expansions.scope import (
|
|
|
72
69
|
Scope,
|
|
73
70
|
)
|
|
74
71
|
from classiq.model_expansions.transformers.model_renamer import ModelRenamer
|
|
75
|
-
from classiq.model_expansions.
|
|
76
|
-
|
|
72
|
+
from classiq.model_expansions.visitors.uncomputation_signature_inference import (
|
|
73
|
+
infer_and_validate_uncomputation_signature,
|
|
77
74
|
)
|
|
78
75
|
from classiq.qmod.pretty_print.expression_to_python import transform_expression
|
|
79
76
|
from classiq.qmod.semantics.validation.signature_validation import (
|
|
@@ -106,7 +103,7 @@ def _validate_cloning(evaluated_args: list[Evaluated]) -> None:
|
|
|
106
103
|
def _validate_gen_args(
|
|
107
104
|
function: FunctionClosure, evaluated_args: list[Evaluated]
|
|
108
105
|
) -> None:
|
|
109
|
-
for param, arg in
|
|
106
|
+
for param, arg in zip(
|
|
110
107
|
function.positional_arg_declarations, evaluated_args, strict=True
|
|
111
108
|
):
|
|
112
109
|
if (
|
|
@@ -158,7 +155,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
158
155
|
self,
|
|
159
156
|
name: str,
|
|
160
157
|
body: Sequence[QuantumStatement],
|
|
161
|
-
debug_info:
|
|
158
|
+
debug_info: FunctionDebugInfo | None = None,
|
|
162
159
|
) -> QuantumFunctionCall:
|
|
163
160
|
wrapping_function = FunctionClosure.create(
|
|
164
161
|
name=self._counted_name_allocator.allocate(name),
|
|
@@ -172,7 +169,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
172
169
|
self,
|
|
173
170
|
function: FunctionClosure,
|
|
174
171
|
args: list[ArgValue],
|
|
175
|
-
propagated_debug_info:
|
|
172
|
+
propagated_debug_info: FunctionDebugInfo | None,
|
|
176
173
|
) -> QuantumFunctionCall:
|
|
177
174
|
call = self._create_quantum_function_call(
|
|
178
175
|
function, args, propagated_debug_info=propagated_debug_info
|
|
@@ -182,8 +179,8 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
182
179
|
|
|
183
180
|
@staticmethod
|
|
184
181
|
def _get_back_ref(
|
|
185
|
-
propagated_debug_info:
|
|
186
|
-
) ->
|
|
182
|
+
propagated_debug_info: FunctionDebugInfo | None,
|
|
183
|
+
) -> UUID | None:
|
|
187
184
|
if propagated_debug_info is None:
|
|
188
185
|
return None
|
|
189
186
|
if propagated_debug_info.node is None:
|
|
@@ -194,7 +191,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
194
191
|
self,
|
|
195
192
|
function: FunctionClosure,
|
|
196
193
|
args: list[ArgValue],
|
|
197
|
-
propagated_debug_info:
|
|
194
|
+
propagated_debug_info: FunctionDebugInfo | None,
|
|
198
195
|
) -> QuantumFunctionCall:
|
|
199
196
|
function = function.clone()
|
|
200
197
|
function = function.set_depth(self._builder.current_function.depth + 1)
|
|
@@ -218,7 +215,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
218
215
|
new_positional_arg_decls = new_declaration.positional_arg_declarations
|
|
219
216
|
evaluated_args = [
|
|
220
217
|
arg
|
|
221
|
-
for param, arg in
|
|
218
|
+
for param, arg in zip(
|
|
222
219
|
function.positional_arg_declarations, evaluated_args, strict=True
|
|
223
220
|
)
|
|
224
221
|
if isinstance(arg.value, QuantumVariable)
|
|
@@ -235,7 +232,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
235
232
|
)
|
|
236
233
|
new_positional_args = [
|
|
237
234
|
arg.emit(param)
|
|
238
|
-
for param, arg in
|
|
235
|
+
for param, arg in zip(
|
|
239
236
|
new_positional_arg_decls[
|
|
240
237
|
: len(new_positional_arg_decls) - len(captured_args)
|
|
241
238
|
],
|
|
@@ -394,6 +391,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
394
391
|
function,
|
|
395
392
|
evaluated_args,
|
|
396
393
|
),
|
|
394
|
+
permutation=function.permutation,
|
|
397
395
|
)
|
|
398
396
|
|
|
399
397
|
def _validate_call_args(
|
|
@@ -425,27 +423,30 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
425
423
|
def _validate_type_modifiers(
|
|
426
424
|
self, func_context: FunctionContext, func_def: NativeFunctionDefinition
|
|
427
425
|
) -> None:
|
|
428
|
-
|
|
429
|
-
self._override_type_modifiers(func_def)
|
|
430
|
-
|
|
431
|
-
unchecked = self._functions_compilation_metadata.get(
|
|
426
|
+
compilation_metadata = self._functions_compilation_metadata.get(
|
|
432
427
|
func_context.name, CompilationMetadata()
|
|
433
|
-
)
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
428
|
+
)
|
|
429
|
+
infer_and_validate_uncomputation_signature(
|
|
430
|
+
func_def,
|
|
431
|
+
disable_perm_check=self._interpreter.skip_type_modifier_validation
|
|
432
|
+
or compilation_metadata.disable_perm_check,
|
|
433
|
+
disable_const_checks=self._interpreter.skip_type_modifier_validation
|
|
434
|
+
or compilation_metadata.disable_const_checks,
|
|
435
|
+
tighten_signature=self._should_tighten_signature(func_context),
|
|
436
|
+
)
|
|
437
437
|
|
|
438
438
|
@staticmethod
|
|
439
|
-
def
|
|
439
|
+
def _should_tighten_signature(func_context: FunctionContext) -> bool:
|
|
440
440
|
"""
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
441
|
+
In some cases we want to tighten the function signature (adding "const" or
|
|
442
|
+
"permutation" modifiers) when possible:
|
|
443
|
+
- Lambda functions (which are defined without modifiers)
|
|
444
|
+
- Functions which receive operands and their modifiers depend on the operand
|
|
445
|
+
|
|
446
|
+
For example:
|
|
447
|
+
- apply_to_all(Z, q) --> q will become `const` and the function will become `permutation`
|
|
448
|
+
- apply_to_all(X, q) --> the function will become `permutation`
|
|
449
|
+
- apply_to_all(H, q) --> no change
|
|
449
450
|
"""
|
|
450
451
|
|
|
451
452
|
if func_context.is_lambda:
|
|
@@ -466,10 +467,3 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
466
467
|
for param_decl in orig_func.positional_arg_declarations
|
|
467
468
|
)
|
|
468
469
|
)
|
|
469
|
-
|
|
470
|
-
@staticmethod
|
|
471
|
-
def _override_type_modifiers(func_def: NativeFunctionDefinition) -> None:
|
|
472
|
-
# only override the modifier if it's unspecified (not Permutable or Const)
|
|
473
|
-
for port in func_def.port_declarations:
|
|
474
|
-
if port.type_modifier is TypeModifier.Mutable:
|
|
475
|
-
port.type_modifier = TypeModifier.Inferred
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from itertools import chain
|
|
2
|
-
from typing import TYPE_CHECKING, Generic
|
|
2
|
+
from typing import TYPE_CHECKING, Generic
|
|
3
3
|
|
|
4
4
|
from classiq.interface.generator.functions.port_declaration import (
|
|
5
5
|
PortDeclarationDirection,
|
|
@@ -41,7 +41,7 @@ class DeclarativeCallEmitter(
|
|
|
41
41
|
return True
|
|
42
42
|
|
|
43
43
|
def _is_function_purely_declarative(
|
|
44
|
-
self, function: FunctionClosure, seen_funcs:
|
|
44
|
+
self, function: FunctionClosure, seen_funcs: set[str] | None = None
|
|
45
45
|
) -> bool:
|
|
46
46
|
if seen_funcs is None:
|
|
47
47
|
seen_funcs = set()
|
|
@@ -3,9 +3,7 @@ from collections.abc import Sequence
|
|
|
3
3
|
from typing import (
|
|
4
4
|
TYPE_CHECKING,
|
|
5
5
|
Generic,
|
|
6
|
-
Optional,
|
|
7
6
|
TypeVar,
|
|
8
|
-
Union,
|
|
9
7
|
)
|
|
10
8
|
|
|
11
9
|
from classiq.interface.debug_info.debug_info import (
|
|
@@ -113,9 +111,9 @@ class Emitter(Generic[QuantumStatementT], ABC):
|
|
|
113
111
|
self,
|
|
114
112
|
op: QuantumOperation,
|
|
115
113
|
context_name: str,
|
|
116
|
-
block_names:
|
|
117
|
-
params:
|
|
118
|
-
scope:
|
|
114
|
+
block_names: None | str | list[str] = None,
|
|
115
|
+
params: Sequence[PositionalArg] | None = None,
|
|
116
|
+
scope: Scope | None = None,
|
|
119
117
|
) -> OperationContext:
|
|
120
118
|
if isinstance(block_names, str):
|
|
121
119
|
block_names = [block_names]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
3
|
from classiq.interface.exceptions import (
|
|
4
4
|
ClassiqExpansionError,
|
|
@@ -24,7 +24,7 @@ class ExpressionEvaluator(Emitter[QuantumOperation]):
|
|
|
24
24
|
interpreter: "BaseInterpreter",
|
|
25
25
|
expression_name: str,
|
|
26
26
|
*,
|
|
27
|
-
readable_expression_name:
|
|
27
|
+
readable_expression_name: str | None = None,
|
|
28
28
|
simplify: bool = False,
|
|
29
29
|
treat_qnum_as_float: bool = False,
|
|
30
30
|
allow_link_time_vars: bool = True,
|
|
@@ -73,7 +73,7 @@ class ExpressionEvaluator(Emitter[QuantumOperation]):
|
|
|
73
73
|
link_time_vars.append(var_name)
|
|
74
74
|
self._capture_classical_var(var_name, var_type)
|
|
75
75
|
if not self._allow_link_time_vars and len(link_time_vars) > 0:
|
|
76
|
-
link_time_message = f"
|
|
76
|
+
link_time_message = f"execution parameter{s(link_time_vars)} {readable_list(link_time_vars, quote=True)}"
|
|
77
77
|
else:
|
|
78
78
|
link_time_message = None
|
|
79
79
|
if not self._allow_runtime_vars and len(runtime_vars) > 0:
|