classiq 0.92.0__py3-none-any.whl → 0.99.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 +11 -19
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +7 -7
- classiq/_analyzer_extras/interactive_hardware.py +19 -12
- classiq/_internals/api_wrapper.py +31 -142
- classiq/_internals/async_utils.py +4 -7
- classiq/_internals/authentication/auth0.py +41 -15
- classiq/_internals/authentication/authorization_code.py +9 -0
- classiq/_internals/authentication/authorization_flow.py +41 -0
- classiq/_internals/authentication/device.py +33 -52
- classiq/_internals/authentication/hybrid_flow.py +19 -0
- classiq/_internals/authentication/password_manager.py +13 -13
- classiq/_internals/authentication/token_manager.py +9 -9
- classiq/_internals/client.py +17 -44
- classiq/_internals/config.py +19 -5
- 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/analyzer/show_interactive_hack.py +1 -1
- classiq/applications/__init__.py +2 -2
- 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 +14 -11
- classiq/applications/qnn/datasets/dataset_base_classes.py +6 -6
- classiq/applications/qnn/datasets/dataset_parity.py +6 -6
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
- classiq/applications/qnn/qlayer.py +9 -8
- classiq/applications/qnn/torch_utils.py +5 -6
- classiq/applications/qnn/types.py +2 -1
- classiq/applications/qsp/__init__.py +20 -2
- classiq/applications/qsp/qsp.py +239 -11
- classiq/applications/qsvm/qsvm_data_generation.py +1 -2
- classiq/evaluators/classical_expression.py +0 -4
- classiq/evaluators/parameter_types.py +20 -12
- classiq/evaluators/qmod_annotated_expression.py +31 -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/binary_op_evaluation.py +4 -4
- classiq/evaluators/qmod_node_evaluators/classical_function_evaluation.py +14 -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/__init__.py +0 -3
- classiq/execution/execution_session.py +28 -21
- classiq/execution/jobs.py +26 -26
- classiq/execution/qnn.py +1 -2
- classiq/execution/user_budgets.py +71 -37
- 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/ast_node.py +3 -3
- classiq/interface/backend/backend_preferences.py +26 -50
- classiq/interface/backend/ionq/ionq_quantum_program.py +5 -5
- classiq/interface/backend/provider_config/__init__.py +0 -0
- classiq/interface/backend/provider_config/provider_config.py +8 -0
- classiq/interface/backend/provider_config/providers/__init__.py +0 -0
- classiq/interface/backend/provider_config/providers/alice_bob.py +47 -0
- classiq/interface/backend/provider_config/providers/aqt.py +16 -0
- classiq/interface/backend/provider_config/providers/azure.py +37 -0
- classiq/interface/backend/provider_config/providers/braket.py +39 -0
- classiq/interface/backend/provider_config/providers/ibm.py +26 -0
- classiq/interface/backend/provider_config/providers/ionq.py +22 -0
- classiq/interface/backend/quantum_backend_providers.py +20 -2
- 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 +8 -7
- classiq/interface/exceptions.py +10 -7
- 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 +25 -17
- classiq/interface/executor/vqe_result.py +5 -6
- classiq/interface/generator/ansatz_library.py +6 -8
- classiq/interface/generator/application_apis/__init__.py +0 -3
- 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 +15 -40
- 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 +3 -3
- 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 -40
- 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 -15
- classiq/interface/generator/functions/type_name.py +2 -2
- classiq/interface/generator/generated_circuit_data.py +14 -18
- 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 +9 -9
- 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/quantum_function_call.py +9 -12
- classiq/interface/generator/quantum_program.py +10 -23
- 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/synthesis_execution_parameter.py +1 -3
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +9 -0
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +2 -3
- classiq/interface/generator/transpiler_basis_gates.py +12 -4
- classiq/interface/generator/types/builtin_enum_declarations.py +0 -145
- 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 -3
- 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 +6 -5
- classiq/interface/interface_version.py +1 -1
- classiq/interface/jobs.py +3 -3
- classiq/interface/model/allocate.py +4 -4
- classiq/interface/model/block.py +6 -2
- classiq/interface/model/bounds.py +3 -3
- classiq/interface/model/classical_if.py +4 -0
- classiq/interface/model/control.py +8 -1
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/invert.py +4 -0
- classiq/interface/model/model.py +4 -4
- classiq/interface/model/model_visitor.py +40 -1
- classiq/interface/model/parameter.py +1 -3
- classiq/interface/model/port_declaration.py +1 -1
- classiq/interface/model/power.py +4 -0
- 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 +11 -4
- classiq/interface/model/quantum_type.py +14 -14
- classiq/interface/model/repeat.py +4 -0
- classiq/interface/model/skip_control.py +4 -0
- classiq/interface/model/validation_handle.py +2 -3
- classiq/interface/model/variable_declaration_statement.py +2 -2
- classiq/interface/model/within_apply_operation.py +4 -0
- classiq/interface/pretty_print/expression_to_qmod.py +3 -4
- classiq/interface/server/routes.py +0 -16
- classiq/interface/source_reference.py +3 -4
- classiq/model_expansions/arithmetic.py +11 -7
- classiq/model_expansions/arithmetic_compute_result_attrs.py +30 -27
- 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 +7 -12
- classiq/model_expansions/interpreters/base_interpreter.py +3 -7
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +2 -1
- 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 +6 -6
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +328 -0
- classiq/model_expansions/visitors/variable_references.py +15 -14
- classiq/open_library/functions/__init__.py +28 -11
- classiq/open_library/functions/amplitude_loading.py +81 -0
- classiq/open_library/functions/discrete_sine_cosine_transform.py +19 -14
- classiq/open_library/functions/grover.py +8 -10
- classiq/open_library/functions/lcu.py +47 -18
- classiq/open_library/functions/modular_exponentiation.py +93 -8
- classiq/open_library/functions/qsvt.py +66 -79
- classiq/open_library/functions/qsvt_temp.py +536 -0
- classiq/open_library/functions/state_preparation.py +130 -27
- classiq/qmod/__init__.py +6 -4
- classiq/qmod/builtins/classical_execution_primitives.py +4 -23
- classiq/qmod/builtins/classical_functions.py +1 -42
- classiq/qmod/builtins/enums.py +15 -153
- classiq/qmod/builtins/functions/__init__.py +9 -18
- classiq/qmod/builtins/functions/allocation.py +25 -4
- classiq/qmod/builtins/functions/arithmetic.py +22 -27
- classiq/qmod/builtins/functions/exponentiation.py +51 -2
- classiq/qmod/builtins/functions/mcx_func.py +7 -0
- classiq/qmod/builtins/functions/standard_gates.py +46 -27
- classiq/qmod/builtins/operations.py +173 -79
- classiq/qmod/builtins/structs.py +24 -91
- 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/expression_query.py +7 -4
- 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 +124 -19
- classiq/qmod/qmod_constant.py +2 -2
- classiq/qmod/qmod_parameter.py +5 -2
- classiq/qmod/qmod_variable.py +47 -46
- classiq/qmod/quantum_callable.py +18 -13
- classiq/qmod/quantum_expandable.py +33 -26
- classiq/qmod/quantum_function.py +84 -36
- classiq/qmod/semantics/annotation/call_annotation.py +5 -5
- classiq/qmod/semantics/error_manager.py +12 -14
- 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 -20
- 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.99.0.dist-info}/METADATA +38 -37
- {classiq-0.92.0.dist-info → classiq-0.99.0.dist-info}/RECORD +273 -300
- classiq-0.99.0.dist-info/WHEEL +4 -0
- classiq-0.99.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/applications/qsvm/__init__.py +0 -8
- classiq/applications/qsvm/qsvm.py +0 -11
- classiq/evaluators/qmod_expression_visitors/qmod_expression_bwc.py +0 -129
- classiq/execution/iqcc.py +0 -128
- classiq/interface/applications/qsvm.py +0 -117
- 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/execution/iqcc.py +0 -44
- classiq/interface/generator/application_apis/chemistry_declarations.py +0 -69
- classiq/interface/generator/application_apis/entangler_declarations.py +0 -29
- classiq/interface/generator/application_apis/qsvm_declarations.py +0 -6
- 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/hamiltonian_evolution/qdrift.py +0 -27
- 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/qsvm.py +0 -96
- classiq/interface/generator/state_preparation/__init__.py +0 -14
- classiq/interface/generator/state_preparation/bell_state_preparation.py +0 -27
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +0 -28
- classiq/interface/generator/state_preparation/distributions.py +0 -53
- classiq/interface/generator/state_preparation/exponential_state_preparation.py +0 -14
- classiq/interface/generator/state_preparation/ghz_state_preparation.py +0 -14
- classiq/interface/generator/state_preparation/metrics.py +0 -41
- classiq/interface/generator/state_preparation/state_preparation.py +0 -113
- classiq/interface/generator/state_preparation/state_preparation_abc.py +0 -24
- classiq/interface/generator/state_preparation/uniform_distibution_state_preparation.py +0 -13
- classiq/interface/generator/state_preparation/w_state_preparation.py +0 -13
- 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/open_library/functions/lookup_table.py +0 -58
- classiq/qmod/builtins/functions/chemistry.py +0 -123
- classiq/qmod/builtins/functions/qsvm.py +0 -24
- classiq-0.92.0.dist-info/WHEEL +0 -4
|
@@ -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
|
|
@@ -175,20 +172,18 @@ class _InterpreterExpandable(QFunc):
|
|
|
175
172
|
scope_func_decls: dict[str, QuantumFunctionDeclaration] = {}
|
|
176
173
|
for name, evaluated in self._interpreter._builder.current_scope.items():
|
|
177
174
|
value = evaluated.value
|
|
175
|
+
if (
|
|
176
|
+
isinstance(value, list)
|
|
177
|
+
and len(value) > 0
|
|
178
|
+
and isinstance(value[0], FunctionClosure)
|
|
179
|
+
):
|
|
180
|
+
value = value[0]
|
|
178
181
|
if isinstance(value, FunctionClosure):
|
|
179
182
|
scope_func_decls[name] = QuantumFunctionDeclaration(
|
|
180
183
|
name=name,
|
|
181
184
|
positional_arg_declarations=value.positional_arg_declarations,
|
|
182
185
|
)
|
|
183
186
|
continue
|
|
184
|
-
op_param = self._interpreter._builder.current_function.parameters_dict.get(
|
|
185
|
-
name
|
|
186
|
-
)
|
|
187
|
-
if isinstance(op_param, QuantumOperandDeclaration):
|
|
188
|
-
scope_func_decls[name] = QuantumFunctionDeclaration(
|
|
189
|
-
name=name,
|
|
190
|
-
positional_arg_declarations=op_param.positional_arg_declarations,
|
|
191
|
-
)
|
|
192
187
|
return (
|
|
193
188
|
nameables_to_dict(self._interpreter._get_function_declarations())
|
|
194
189
|
| scope_func_decls
|
|
@@ -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)
|
|
@@ -328,7 +324,7 @@ class BaseInterpreter:
|
|
|
328
324
|
def emit_statement(self, statement: QuantumStatement) -> None:
|
|
329
325
|
source_ref = statement.source_ref
|
|
330
326
|
error_context = (
|
|
331
|
-
self._error_manager.
|
|
327
|
+
self._error_manager.source_ref_context(statement.source_ref)
|
|
332
328
|
if source_ref is not None
|
|
333
329
|
else nullcontext()
|
|
334
330
|
)
|
|
@@ -41,7 +41,8 @@ class FrontendGenerativeInterpreter(GenerativeInterpreter):
|
|
|
41
41
|
if module is None or not module.__name__.startswith("classiq."):
|
|
42
42
|
file_name = os.path.split(frame.filename)[-1]
|
|
43
43
|
if (
|
|
44
|
-
frame
|
|
44
|
+
hasattr(frame, "positions")
|
|
45
|
+
and frame.positions is not None
|
|
45
46
|
and frame.positions.lineno is not None
|
|
46
47
|
and frame.positions.col_offset is not None
|
|
47
48
|
and frame.positions.end_lineno is not None
|
|
@@ -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:
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from classiq.interface.exceptions import ClassiqExpansionError
|
|
2
|
-
from classiq.interface.helpers.backward_compatibility import zip_strict
|
|
3
2
|
from classiq.interface.model.skip_control import SkipControl
|
|
4
3
|
|
|
5
4
|
from classiq.model_expansions.function_builder import FunctionContext
|
|
@@ -9,7 +8,7 @@ from classiq.model_expansions.quantum_operations.emitter import Emitter
|
|
|
9
8
|
class SkipControlVerifier(Emitter[SkipControl]):
|
|
10
9
|
def emit(self, skip_control: SkipControl, /) -> bool:
|
|
11
10
|
for op, block in list(
|
|
12
|
-
|
|
11
|
+
zip(self._builder._operations, self._builder._blocks, strict=True)
|
|
13
12
|
)[::-1]:
|
|
14
13
|
if isinstance(op, FunctionContext):
|
|
15
14
|
break
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING,
|
|
1
|
+
from typing import TYPE_CHECKING, cast
|
|
2
2
|
|
|
3
3
|
from classiq.interface.exceptions import ClassiqExpansionError
|
|
4
4
|
from classiq.interface.generator.functions.classical_type import ClassicalType
|
|
5
5
|
from classiq.interface.generator.functions.concrete_types import ConcreteType
|
|
6
|
+
from classiq.interface.helpers.text_utils import readable_list, s
|
|
6
7
|
from classiq.interface.model.handle_binding import HandleBinding
|
|
7
8
|
from classiq.interface.model.quantum_type import QuantumType
|
|
8
9
|
from classiq.interface.model.variable_declaration_statement import (
|
|
@@ -13,11 +14,21 @@ from classiq.evaluators.parameter_types import (
|
|
|
13
14
|
evaluate_type_in_classical_symbol,
|
|
14
15
|
evaluate_type_in_quantum_symbol,
|
|
15
16
|
)
|
|
17
|
+
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
16
18
|
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
|
17
19
|
from classiq.model_expansions.scope import ClassicalSymbol, Evaluated, QuantumSymbol
|
|
18
20
|
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
|
23
|
+
|
|
19
24
|
|
|
20
25
|
class VariableDeclarationStatementEmitter(Emitter[VariableDeclarationStatement]):
|
|
26
|
+
def __init__(
|
|
27
|
+
self, interpreter: "BaseInterpreter", allow_symbolic_vars: bool = False
|
|
28
|
+
) -> None:
|
|
29
|
+
super().__init__(interpreter)
|
|
30
|
+
self._allow_symbolic_vars = allow_symbolic_vars
|
|
31
|
+
|
|
21
32
|
def emit(self, variable_declaration: VariableDeclarationStatement, /) -> bool:
|
|
22
33
|
var_decl = variable_declaration.model_copy(
|
|
23
34
|
update=dict(back_ref=variable_declaration.uuid)
|
|
@@ -27,38 +38,59 @@ class VariableDeclarationStatementEmitter(Emitter[VariableDeclarationStatement])
|
|
|
27
38
|
raise ClassiqExpansionError(
|
|
28
39
|
f"Variable {variable_declaration.name!r} is already defined"
|
|
29
40
|
)
|
|
30
|
-
var_value:
|
|
41
|
+
var_value: QuantumSymbol | ClassicalSymbol
|
|
31
42
|
if variable_declaration.is_quantum:
|
|
32
|
-
|
|
33
|
-
assert isinstance(var_decl.qmod_type, QuantumType)
|
|
34
|
-
updated_quantum_type = evaluate_type_in_quantum_symbol(
|
|
35
|
-
var_decl.qmod_type,
|
|
36
|
-
self._current_scope,
|
|
37
|
-
var_decl.name,
|
|
38
|
-
)
|
|
39
|
-
var_decl.qmod_type = updated_quantum_type
|
|
40
|
-
var_value = QuantumSymbol(
|
|
41
|
-
handle=HandleBinding(name=var_decl.name),
|
|
42
|
-
quantum_type=updated_quantum_type,
|
|
43
|
-
)
|
|
44
|
-
self._builder.current_block.captured_vars.init_var(
|
|
45
|
-
var_decl.name, self._builder.current_function
|
|
46
|
-
)
|
|
43
|
+
var_value = self._get_quantum_var(var_decl)
|
|
47
44
|
else:
|
|
48
|
-
|
|
49
|
-
assert isinstance(var_decl.qmod_type, ClassicalType)
|
|
50
|
-
updated_classical_type = evaluate_type_in_classical_symbol(
|
|
51
|
-
var_decl.qmod_type,
|
|
52
|
-
self._current_scope,
|
|
53
|
-
var_decl.name,
|
|
54
|
-
)
|
|
55
|
-
var_decl.qmod_type = cast(ConcreteType, updated_classical_type)
|
|
56
|
-
var_value = ClassicalSymbol(
|
|
57
|
-
handle=HandleBinding(name=var_decl.name),
|
|
58
|
-
classical_type=updated_classical_type,
|
|
59
|
-
)
|
|
45
|
+
var_value = self._get_classical_var(var_decl)
|
|
60
46
|
self._current_scope[variable_declaration.name] = Evaluated(
|
|
61
47
|
value=var_value, defining_function=self._builder.current_function
|
|
62
48
|
)
|
|
63
49
|
self.emit_statement(var_decl)
|
|
64
50
|
return True
|
|
51
|
+
|
|
52
|
+
def _get_quantum_var(self, var_decl: VariableDeclarationStatement) -> QuantumSymbol:
|
|
53
|
+
updated_quantum_type = evaluate_type_in_quantum_symbol(
|
|
54
|
+
cast(QuantumType, var_decl.qmod_type),
|
|
55
|
+
self._current_scope,
|
|
56
|
+
var_decl.name,
|
|
57
|
+
)
|
|
58
|
+
if not self._allow_symbolic_vars:
|
|
59
|
+
symbolic_variables = list(
|
|
60
|
+
dict.fromkeys(
|
|
61
|
+
classical_var.name
|
|
62
|
+
for expr in updated_quantum_type.expressions
|
|
63
|
+
if isinstance(expr_val := expr.value.value, QmodAnnotatedExpression)
|
|
64
|
+
for classical_var in expr_val.get_classical_vars().values()
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
if len(symbolic_variables) > 0:
|
|
68
|
+
raise ClassiqExpansionError(
|
|
69
|
+
f"Variable type is instantiated with non-compile-time "
|
|
70
|
+
f"variable{s(symbolic_variables)} "
|
|
71
|
+
f"{readable_list(symbolic_variables, quote=True)}"
|
|
72
|
+
)
|
|
73
|
+
var_decl.qmod_type = updated_quantum_type
|
|
74
|
+
var_value = QuantumSymbol(
|
|
75
|
+
handle=HandleBinding(name=var_decl.name),
|
|
76
|
+
quantum_type=updated_quantum_type,
|
|
77
|
+
)
|
|
78
|
+
self._builder.current_block.captured_vars.init_var(
|
|
79
|
+
var_decl.name, self._builder.current_function
|
|
80
|
+
)
|
|
81
|
+
return var_value
|
|
82
|
+
|
|
83
|
+
def _get_classical_var(
|
|
84
|
+
self, var_decl: VariableDeclarationStatement
|
|
85
|
+
) -> ClassicalSymbol:
|
|
86
|
+
updated_classical_type = evaluate_type_in_classical_symbol(
|
|
87
|
+
cast(ClassicalType, var_decl.qmod_type),
|
|
88
|
+
self._current_scope,
|
|
89
|
+
var_decl.name,
|
|
90
|
+
)
|
|
91
|
+
var_decl.qmod_type = cast(ConcreteType, updated_classical_type)
|
|
92
|
+
var_value = ClassicalSymbol(
|
|
93
|
+
handle=HandleBinding(name=var_decl.name),
|
|
94
|
+
classical_type=updated_classical_type,
|
|
95
|
+
)
|
|
96
|
+
return var_value
|