classiq 0.53.0__py3-none-any.whl → 0.55.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 +1 -3
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +2 -1
- classiq/_internals/__init__.py +0 -20
- classiq/_internals/api_wrapper.py +8 -8
- classiq/_internals/async_utils.py +1 -3
- classiq/_internals/authentication/auth0.py +5 -5
- classiq/_internals/authentication/device.py +5 -4
- classiq/_internals/authentication/password_manager.py +3 -3
- classiq/_internals/authentication/token_manager.py +3 -2
- classiq/_internals/client.py +10 -12
- classiq/_internals/config.py +2 -2
- classiq/_internals/jobs.py +7 -6
- classiq/_internals/type_validation.py +9 -9
- classiq/analyzer/__init__.py +1 -3
- classiq/analyzer/analyzer.py +8 -7
- classiq/analyzer/analyzer_utilities.py +8 -8
- classiq/analyzer/rb.py +11 -11
- classiq/applications/__init__.py +1 -3
- classiq/applications/chemistry/__init__.py +1 -3
- classiq/applications/chemistry/ansatz_parameters.py +4 -4
- classiq/applications/chemistry/chemistry_model_constructor.py +10 -9
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +26 -9
- classiq/applications/combinatorial_helpers/encoding_mapping.py +10 -10
- classiq/applications/combinatorial_helpers/encoding_utils.py +4 -4
- classiq/applications/combinatorial_helpers/memory.py +5 -7
- classiq/applications/combinatorial_helpers/optimization_model.py +43 -24
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +4 -6
- classiq/applications/combinatorial_helpers/pyomo_utils.py +95 -24
- classiq/applications/combinatorial_helpers/sympy_utils.py +2 -2
- classiq/applications/combinatorial_helpers/transformations/encoding.py +8 -8
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +5 -5
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +7 -9
- classiq/applications/combinatorial_helpers/transformations/penalty.py +1 -2
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +1 -2
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +1 -2
- classiq/applications/combinatorial_optimization/__init__.py +1 -3
- classiq/applications/combinatorial_optimization/combinatorial_optimization_config.py +2 -2
- classiq/applications/combinatorial_optimization/examples/__init__.py +1 -3
- classiq/applications/finance/__init__.py +1 -3
- classiq/applications/grover/__init__.py +1 -3
- classiq/applications/grover/grover_model_constructor.py +7 -9
- classiq/applications/hamiltonian/pauli_decomposition.py +6 -6
- classiq/applications/qnn/__init__.py +1 -3
- classiq/applications/qnn/circuit_utils.py +5 -5
- classiq/applications/qnn/datasets/__init__.py +1 -3
- classiq/applications/qnn/datasets/dataset_base_classes.py +5 -4
- classiq/applications/qnn/datasets/dataset_parity.py +2 -2
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -1
- classiq/applications/qnn/qlayer.py +3 -3
- classiq/applications/qnn/torch_utils.py +2 -2
- classiq/applications/qnn/types.py +5 -5
- classiq/applications/qsvm/qsvm.py +1 -3
- classiq/applications/qsvm/qsvm_data_generation.py +3 -3
- classiq/applications/qsvm/qsvm_model_constructor.py +5 -5
- classiq/execution/__init__.py +1 -3
- classiq/execution/all_hardware_devices.py +1 -3
- classiq/execution/execution_session.py +16 -16
- classiq/execution/jobs.py +4 -4
- classiq/execution/qaoa.py +3 -3
- classiq/execution/qnn.py +3 -3
- classiq/executor.py +3 -3
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +9 -10
- classiq/interface/analyzer/cytoscape_graph.py +5 -5
- classiq/interface/analyzer/result.py +17 -17
- classiq/interface/applications/qsvm.py +6 -10
- classiq/interface/backend/backend_preferences.py +4 -3
- classiq/interface/backend/ionq/ionq_quantum_program.py +4 -5
- classiq/interface/backend/pydantic_backend.py +1 -2
- classiq/interface/chemistry/fermionic_operator.py +5 -5
- classiq/interface/chemistry/ground_state_problem.py +7 -8
- classiq/interface/chemistry/molecule.py +4 -4
- classiq/interface/chemistry/operator.py +11 -13
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -3
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -4
- classiq/interface/combinatorial_optimization/examples/knapsack.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mht.py +2 -3
- classiq/interface/combinatorial_optimization/examples/portfolio_variations.py +2 -2
- classiq/interface/combinatorial_optimization/examples/set_cover.py +1 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +5 -7
- classiq/interface/combinatorial_optimization/optimization_problem.py +2 -2
- classiq/interface/combinatorial_optimization/result.py +1 -3
- classiq/interface/debug_info/debug_info.py +8 -7
- classiq/interface/exceptions.py +8 -6
- classiq/interface/execution/jobs.py +2 -2
- classiq/interface/execution/primitives.py +3 -3
- classiq/interface/executor/aws_execution_cost.py +4 -4
- classiq/interface/executor/execution_request.py +2 -3
- classiq/interface/executor/execution_result.py +3 -3
- classiq/interface/executor/iqae_result.py +3 -5
- classiq/interface/executor/optimizer_preferences.py +2 -2
- classiq/interface/executor/quantum_code.py +6 -6
- classiq/interface/executor/register_initialization.py +2 -4
- classiq/interface/executor/result.py +23 -27
- classiq/interface/executor/vqe_result.py +8 -8
- classiq/interface/finance/function_input.py +2 -2
- classiq/interface/finance/gaussian_model_input.py +5 -5
- classiq/interface/finance/log_normal_model_input.py +2 -2
- classiq/interface/finance/model_input.py +1 -2
- classiq/interface/generator/adjacency.py +1 -3
- classiq/interface/generator/ansatz_library.py +4 -4
- classiq/interface/generator/application_apis/finance_declarations.py +1 -1
- classiq/interface/generator/arith/argument_utils.py +3 -3
- classiq/interface/generator/arith/arithmetic.py +7 -7
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +5 -5
- classiq/interface/generator/arith/arithmetic_expression_abc.py +11 -11
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
- classiq/interface/generator/arith/arithmetic_expression_validator.py +8 -8
- classiq/interface/generator/arith/arithmetic_operations.py +4 -3
- classiq/interface/generator/arith/arithmetic_param_getters.py +6 -6
- classiq/interface/generator/arith/arithmetic_result_builder.py +9 -9
- classiq/interface/generator/arith/ast_node_rewrite.py +2 -1
- classiq/interface/generator/arith/binary_ops.py +10 -13
- classiq/interface/generator/arith/extremum_operations.py +3 -2
- classiq/interface/generator/arith/logical_ops.py +7 -6
- classiq/interface/generator/arith/number_utils.py +4 -4
- classiq/interface/generator/arith/register_user_input.py +4 -4
- classiq/interface/generator/arith/unary_ops.py +2 -1
- classiq/interface/generator/builtin_api_builder.py +2 -1
- classiq/interface/generator/circuit_code/circuit_code.py +4 -4
- classiq/interface/generator/circuit_code/types_and_constants.py +3 -5
- classiq/interface/generator/complex_type.py +1 -2
- classiq/interface/generator/control_state.py +2 -2
- classiq/interface/generator/custom_ansatz.py +1 -3
- classiq/interface/generator/distance.py +3 -5
- classiq/interface/generator/excitations.py +3 -2
- classiq/interface/generator/expressions/enums/finance_functions.py +1 -3
- classiq/interface/generator/expressions/evaluated_expression.py +4 -3
- classiq/interface/generator/expressions/expression.py +4 -5
- classiq/interface/generator/expressions/expression_constants.py +4 -4
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -1
- classiq/interface/generator/expressions/qmod_struct_instance.py +2 -1
- classiq/interface/generator/expressions/sympy_supported_expressions.py +11 -13
- classiq/interface/generator/finance.py +2 -2
- classiq/interface/generator/function_param_library.py +6 -6
- classiq/interface/generator/function_params.py +13 -19
- classiq/interface/generator/functions/builtins/internal_operators.py +9 -1
- classiq/interface/generator/functions/classical_function_declaration.py +4 -3
- classiq/interface/generator/functions/classical_type.py +13 -13
- classiq/interface/generator/functions/concrete_types.py +1 -2
- classiq/interface/generator/functions/function_declaration.py +1 -1
- classiq/interface/generator/functions/qmod_python_interface.py +2 -1
- classiq/interface/generator/functions/type_name.py +3 -2
- classiq/interface/generator/generated_circuit_data.py +33 -22
- classiq/interface/generator/grover_diffuser.py +7 -7
- classiq/interface/generator/grover_operator.py +2 -2
- classiq/interface/generator/hardware/hardware_data.py +7 -6
- classiq/interface/generator/hardware_efficient_ansatz.py +8 -8
- classiq/interface/generator/identity.py +5 -6
- classiq/interface/generator/linear_pauli_rotations.py +6 -6
- classiq/interface/generator/mcu.py +2 -2
- classiq/interface/generator/mcx.py +6 -6
- classiq/interface/generator/model/__init__.py +1 -3
- classiq/interface/generator/model/constraints.py +2 -2
- classiq/interface/generator/model/model.py +5 -6
- classiq/interface/generator/model/preferences/preferences.py +11 -6
- classiq/interface/generator/model/quantum_register.py +6 -11
- classiq/interface/generator/oracles/arithmetic_oracle.py +1 -2
- classiq/interface/generator/oracles/custom_oracle.py +2 -2
- classiq/interface/generator/oracles/oracle_abc.py +6 -5
- classiq/interface/generator/partitioned_register.py +6 -5
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +8 -7
- classiq/interface/generator/qpe.py +4 -4
- classiq/interface/generator/qsvm.py +3 -3
- classiq/interface/generator/quantum_function_call.py +24 -29
- classiq/interface/generator/quantum_program.py +9 -9
- classiq/interface/generator/register_role.py +2 -4
- classiq/interface/generator/slice_parsing_utils.py +4 -3
- classiq/interface/generator/standard_gates/standard_gates.py +3 -3
- classiq/interface/generator/state_preparation/bell_state_preparation.py +3 -3
- classiq/interface/generator/state_preparation/distributions.py +6 -5
- classiq/interface/generator/state_preparation/metrics.py +2 -4
- classiq/interface/generator/state_preparation/state_preparation.py +4 -4
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -3
- classiq/interface/generator/transpiler_basis_gates.py +2 -2
- classiq/interface/generator/types/compilation_metadata.py +5 -0
- classiq/interface/generator/types/enum_declaration.py +2 -3
- classiq/interface/generator/types/qstruct_declaration.py +2 -1
- classiq/interface/generator/types/struct_declaration.py +3 -2
- classiq/interface/generator/ucc.py +2 -1
- classiq/interface/generator/unitary_gate.py +2 -2
- classiq/interface/generator/user_defined_function_params.py +1 -1
- classiq/interface/generator/validations/flow_graph.py +6 -5
- classiq/interface/generator/validations/validator_functions.py +3 -2
- classiq/interface/generator/visitor.py +9 -14
- classiq/interface/hardware.py +5 -6
- classiq/interface/helpers/custom_encoders.py +2 -2
- classiq/interface/helpers/custom_pydantic_types.py +8 -9
- classiq/interface/helpers/hashable_mixin.py +3 -2
- classiq/interface/helpers/hashable_pydantic_base_model.py +2 -1
- classiq/interface/helpers/pydantic_model_helpers.py +4 -3
- classiq/interface/helpers/validation_helpers.py +2 -2
- classiq/interface/ide/ide_data.py +11 -15
- classiq/interface/ide/visual_model.py +22 -22
- classiq/interface/jobs.py +2 -2
- classiq/interface/model/bind_operation.py +5 -4
- classiq/interface/model/classical_parameter_declaration.py +2 -2
- classiq/interface/model/control.py +22 -1
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/inplace_binary_operation.py +2 -1
- classiq/interface/model/model.py +16 -11
- classiq/interface/model/native_function_definition.py +1 -1
- classiq/interface/model/port_declaration.py +2 -2
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +3 -2
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +4 -27
- classiq/interface/model/quantum_expressions/quantum_expression.py +8 -7
- classiq/interface/model/quantum_function_call.py +9 -14
- classiq/interface/model/quantum_function_declaration.py +10 -12
- classiq/interface/model/quantum_lambda_function.py +3 -16
- classiq/interface/model/quantum_statement.py +7 -3
- classiq/interface/model/quantum_type.py +5 -5
- classiq/interface/model/statement_block.py +2 -3
- classiq/interface/model/validation_handle.py +5 -4
- classiq/interface/server/global_versions.py +3 -3
- classiq/model_expansions/atomic_expression_functions_defs.py +3 -2
- classiq/model_expansions/capturing/captured_var_manager.py +4 -6
- classiq/model_expansions/capturing/propagated_var_stack.py +7 -7
- classiq/model_expansions/closure.py +83 -12
- classiq/model_expansions/evaluators/arg_type_match.py +3 -2
- classiq/model_expansions/evaluators/argument_types.py +3 -3
- classiq/model_expansions/evaluators/control.py +3 -3
- classiq/model_expansions/evaluators/parameter_types.py +7 -7
- classiq/model_expansions/evaluators/quantum_type_utils.py +2 -1
- classiq/model_expansions/evaluators/type_type_match.py +1 -1
- classiq/model_expansions/expression_evaluator.py +10 -9
- classiq/model_expansions/expression_renamer.py +6 -6
- classiq/model_expansions/function_builder.py +13 -12
- classiq/model_expansions/generative_functions.py +5 -4
- classiq/model_expansions/interpreter.py +20 -11
- classiq/model_expansions/model_tables.py +14 -14
- classiq/model_expansions/quantum_operations/bind.py +2 -4
- classiq/model_expansions/quantum_operations/classicalif.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +81 -24
- classiq/model_expansions/quantum_operations/emitter.py +33 -20
- classiq/model_expansions/quantum_operations/expression_operation.py +47 -16
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +160 -35
- classiq/model_expansions/quantum_operations/phase.py +6 -6
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +28 -31
- classiq/model_expansions/quantum_operations/quantum_function_call.py +9 -0
- classiq/model_expansions/quantum_operations/repeat.py +1 -3
- classiq/model_expansions/quantum_operations/within_apply.py +0 -16
- classiq/model_expansions/scope.py +11 -10
- classiq/model_expansions/scope_initialization.py +5 -5
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +6 -6
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +2 -2
- classiq/model_expansions/visitors/variable_references.py +5 -4
- classiq/qmod/builtins/classical_execution_primitives.py +9 -9
- classiq/qmod/builtins/functions/__init__.py +72 -55
- classiq/qmod/builtins/functions/amplitude_estimation.py +4 -1
- classiq/qmod/builtins/functions/arithmetic.py +14 -1
- classiq/qmod/builtins/functions/discrete_sine_cosine_transform.py +86 -6
- classiq/qmod/builtins/functions/grover.py +41 -45
- classiq/qmod/builtins/functions/hea.py +60 -4
- classiq/qmod/builtins/functions/linear_pauli_rotation.py +26 -4
- classiq/qmod/builtins/functions/modular_exponentiation.py +90 -29
- classiq/qmod/builtins/functions/operators.py +1 -1
- classiq/qmod/builtins/functions/qaoa_penalty.py +14 -5
- classiq/qmod/builtins/functions/qft_functions.py +57 -0
- classiq/qmod/builtins/functions/qpe.py +20 -4
- classiq/qmod/builtins/functions/qsvt.py +49 -4
- classiq/qmod/builtins/functions/standard_gates.py +4 -4
- classiq/qmod/builtins/functions/state_preparation.py +92 -10
- classiq/qmod/builtins/functions/swap_test.py +7 -1
- classiq/qmod/builtins/functions/utility_functions.py +43 -0
- classiq/qmod/builtins/functions/variational.py +18 -2
- classiq/qmod/builtins/operations.py +117 -22
- classiq/qmod/cfunc.py +2 -2
- classiq/qmod/classical_function.py +3 -7
- classiq/qmod/create_model_function.py +16 -17
- classiq/qmod/declaration_inferrer.py +7 -10
- classiq/qmod/expression_query.py +3 -3
- classiq/qmod/generative.py +2 -1
- classiq/qmod/model_state_container.py +10 -8
- classiq/qmod/native/__init__.py +1 -3
- classiq/qmod/native/expression_to_qmod.py +9 -8
- classiq/qmod/native/pretty_printer.py +12 -6
- classiq/qmod/pretty_print/__init__.py +1 -3
- classiq/qmod/pretty_print/expression_to_python.py +13 -12
- classiq/qmod/pretty_print/pretty_printer.py +38 -23
- classiq/qmod/python_classical_type.py +8 -4
- classiq/qmod/qfunc.py +4 -4
- classiq/qmod/qmod_variable.py +11 -10
- classiq/qmod/quantum_expandable.py +12 -15
- classiq/qmod/quantum_function.py +35 -22
- classiq/qmod/semantics/annotation.py +1 -1
- classiq/qmod/semantics/error_manager.py +8 -7
- classiq/qmod/semantics/static_semantics_visitor.py +19 -24
- classiq/qmod/semantics/validation/constants_validation.py +1 -1
- classiq/qmod/semantics/validation/func_call_validation.py +2 -2
- classiq/qmod/semantics/validation/main_validation.py +33 -0
- classiq/qmod/semantics/validation/types_validation.py +2 -1
- classiq/qmod/symbolic.py +5 -8
- classiq/qmod/symbolic_type.py +2 -2
- classiq/qmod/synthesize_separately.py +1 -2
- {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/METADATA +1 -1
- {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/RECORD +300 -297
- classiq/qmod/builtins/functions/qft.py +0 -23
- {classiq-0.53.0.dist-info → classiq-0.55.0.dist-info}/WHEEL +0 -0
@@ -1,6 +1,7 @@
|
|
1
|
+
from collections.abc import Iterable, Iterator, Sequence
|
1
2
|
from contextlib import contextmanager
|
2
3
|
from dataclasses import dataclass, field
|
3
|
-
from typing import
|
4
|
+
from typing import Generic, Optional, TypeVar
|
4
5
|
|
5
6
|
from classiq.interface.exceptions import (
|
6
7
|
ClassiqExpansionError,
|
@@ -35,14 +36,14 @@ ClosureType = TypeVar("ClosureType", bound=Closure)
|
|
35
36
|
|
36
37
|
@dataclass
|
37
38
|
class Block:
|
38
|
-
statements:
|
39
|
-
captured_vars:
|
39
|
+
statements: list[QuantumStatement] = field(default_factory=list)
|
40
|
+
captured_vars: list[PortDeclaration] = field(default_factory=list)
|
40
41
|
|
41
42
|
|
42
43
|
@dataclass
|
43
44
|
class OperationContext(Generic[ClosureType]):
|
44
45
|
closure: ClosureType
|
45
|
-
blocks:
|
46
|
+
blocks: dict[str, Block] = field(default_factory=dict)
|
46
47
|
|
47
48
|
@property
|
48
49
|
def name(self) -> str:
|
@@ -52,7 +53,7 @@ class OperationContext(Generic[ClosureType]):
|
|
52
53
|
def positional_arg_declarations(self) -> Sequence[PositionalArg]:
|
53
54
|
return self.closure.positional_arg_declarations
|
54
55
|
|
55
|
-
def statements(self, block_name: str) ->
|
56
|
+
def statements(self, block_name: str) -> list[QuantumStatement]:
|
56
57
|
return self.blocks[block_name].statements
|
57
58
|
|
58
59
|
|
@@ -63,11 +64,11 @@ class FunctionContext(OperationContext[FunctionClosure]):
|
|
63
64
|
return cls(original_function, {"body": Block()})
|
64
65
|
|
65
66
|
@property
|
66
|
-
def body(self) ->
|
67
|
+
def body(self) -> list[QuantumStatement]:
|
67
68
|
return self.statements("body")
|
68
69
|
|
69
70
|
@property
|
70
|
-
def captured_vars(self) ->
|
71
|
+
def captured_vars(self) -> list[PortDeclaration]:
|
71
72
|
return self.blocks["body"].captured_vars
|
72
73
|
|
73
74
|
@property
|
@@ -77,8 +78,8 @@ class FunctionContext(OperationContext[FunctionClosure]):
|
|
77
78
|
|
78
79
|
class OperationBuilder:
|
79
80
|
def __init__(self) -> None:
|
80
|
-
self._operations:
|
81
|
-
self._blocks:
|
81
|
+
self._operations: list[OperationContext] = []
|
82
|
+
self._blocks: list[str] = []
|
82
83
|
self._counter = 0
|
83
84
|
|
84
85
|
@property
|
@@ -93,7 +94,7 @@ class OperationBuilder:
|
|
93
94
|
raise ClassiqInternalExpansionError("No function found")
|
94
95
|
|
95
96
|
@property
|
96
|
-
def _current_statements(self) ->
|
97
|
+
def _current_statements(self) -> list[QuantumStatement]:
|
97
98
|
return self._operations[-1].blocks[self._blocks[-1]].statements
|
98
99
|
|
99
100
|
def emit_statement(self, statement: QuantumStatement) -> None:
|
@@ -160,7 +161,7 @@ class OperationBuilder:
|
|
160
161
|
name = f"{name}_{LAMBDA_KEYWORD + '_0_0_' if function_context.is_lambda else ''}{EXPANDED_KEYWORD}_{self._counter}"
|
161
162
|
self._counter += 1
|
162
163
|
|
163
|
-
new_parameters:
|
164
|
+
new_parameters: list[PortDeclaration] = [
|
164
165
|
param
|
165
166
|
for param in function_context.positional_arg_declarations
|
166
167
|
if isinstance(param, PortDeclaration)
|
@@ -173,7 +174,7 @@ class OperationBuilder:
|
|
173
174
|
)
|
174
175
|
|
175
176
|
|
176
|
-
def validate_captured_vars(captured_vars:
|
177
|
+
def validate_captured_vars(captured_vars: list[PortDeclaration]) -> None:
|
177
178
|
if input_captured := [
|
178
179
|
demangle_name(var.name)
|
179
180
|
for var in captured_vars
|
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Mapping
|
2
|
+
from typing import TYPE_CHECKING, Any
|
2
3
|
|
3
4
|
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
4
5
|
from classiq.interface.generator.expressions.qmod_struct_instance import (
|
@@ -127,7 +128,7 @@ class _InterpreterExpandable(QFunc):
|
|
127
128
|
def emit_generative_statements(
|
128
129
|
interpreter: "Interpreter",
|
129
130
|
operation: GenerativeClosure,
|
130
|
-
args:
|
131
|
+
args: list[Evaluated],
|
131
132
|
) -> None:
|
132
133
|
python_qmod_args = [
|
133
134
|
translate_ast_arg_to_python_qmod(param, arg)
|
@@ -185,7 +186,7 @@ def _expand_operand_as_declarative(
|
|
185
186
|
|
186
187
|
|
187
188
|
def _register_declarative_function(interpreter: "Interpreter", func_name: str) -> None:
|
188
|
-
if func_name in nameables_to_dict(interpreter._expanded_functions):
|
189
|
+
if func_name in nameables_to_dict(list(interpreter._expanded_functions.values())):
|
189
190
|
return
|
190
191
|
|
191
192
|
for user_gen_func in interpreter._generative_functions:
|
@@ -198,7 +199,7 @@ def _register_declarative_function(interpreter: "Interpreter", func_name: str) -
|
|
198
199
|
dec_func = QFunc(user_gen_func._py_callable)
|
199
200
|
dec_func.expand()
|
200
201
|
dec_func_def = QMODULE.native_defs[func_name]
|
201
|
-
interpreter._expanded_functions
|
202
|
+
interpreter._expanded_functions[func_name] = dec_func_def
|
202
203
|
_DecFuncVisitor(interpreter).visit(dec_func_def)
|
203
204
|
|
204
205
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import copy
|
2
|
+
from collections.abc import Iterator, Sequence
|
2
3
|
from contextlib import contextmanager, nullcontext
|
3
4
|
from functools import singledispatchmethod
|
4
|
-
from typing import Any,
|
5
|
+
from typing import Any, Optional, cast
|
5
6
|
|
6
7
|
import numpy as np
|
7
8
|
from numpy.random import permutation
|
@@ -11,6 +12,7 @@ from classiq.interface.exceptions import (
|
|
11
12
|
ClassiqInternalExpansionError,
|
12
13
|
)
|
13
14
|
from classiq.interface.generator.expressions.expression import Expression
|
15
|
+
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
14
16
|
from classiq.interface.model.bind_operation import BindOperation
|
15
17
|
from classiq.interface.model.classical_if import ClassicalIf
|
16
18
|
from classiq.interface.model.control import Control
|
@@ -88,7 +90,7 @@ from classiq.qmod.builtins.functions import permute
|
|
88
90
|
from classiq.qmod.quantum_function import GenerativeQFunc
|
89
91
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
90
92
|
|
91
|
-
STATEMENT_TYPES_FOR_SOURCE_REFERENCE_PROPAGATION:
|
93
|
+
STATEMENT_TYPES_FOR_SOURCE_REFERENCE_PROPAGATION: tuple[type[QuantumStatement], ...] = (
|
92
94
|
QuantumFunctionCall,
|
93
95
|
VariableDeclarationStatement,
|
94
96
|
QuantumAssignmentOperation,
|
@@ -99,14 +101,14 @@ class Interpreter:
|
|
99
101
|
def __init__(
|
100
102
|
self,
|
101
103
|
model: Model,
|
102
|
-
generative_functions: Optional[
|
104
|
+
generative_functions: Optional[list[GenerativeQFunc]] = None,
|
103
105
|
is_frontend: bool = False,
|
104
106
|
) -> None:
|
105
107
|
self._is_frontend = is_frontend
|
106
108
|
self._model = model
|
107
109
|
self._current_scope = Scope()
|
108
110
|
self._builder = OperationBuilder()
|
109
|
-
self._expanded_functions:
|
111
|
+
self._expanded_functions: dict[str, NativeFunctionDefinition] = {}
|
110
112
|
self._propagated_var_stack = PropagatedVarStack(
|
111
113
|
self._current_scope, self._builder
|
112
114
|
)
|
@@ -117,7 +119,9 @@ class Interpreter:
|
|
117
119
|
generative_functions = []
|
118
120
|
self._generative_functions = generative_functions
|
119
121
|
init_top_level_scope(model, generative_functions, self._current_scope)
|
120
|
-
|
122
|
+
self._expanded_functions_compilation_metadata: dict[
|
123
|
+
str, CompilationMetadata
|
124
|
+
] = dict()
|
121
125
|
self._counted_name_allocator = CountedNameAllocator()
|
122
126
|
self._error_manager: ErrorManager = ErrorManager()
|
123
127
|
|
@@ -150,7 +154,7 @@ class Interpreter:
|
|
150
154
|
main_closure.positional_arg_declarations, main_closure
|
151
155
|
)
|
152
156
|
context = self._expand_operation(main_closure)
|
153
|
-
self._expanded_functions.
|
157
|
+
self._expanded_functions[main_closure.closure_id] = (
|
154
158
|
self._builder.create_definition(cast(FunctionContext, context))
|
155
159
|
)
|
156
160
|
|
@@ -173,12 +177,13 @@ class Interpreter:
|
|
173
177
|
preferences=self._model.preferences,
|
174
178
|
classical_execution_code=self._model.classical_execution_code,
|
175
179
|
execution_preferences=self._model.execution_preferences,
|
176
|
-
functions=self._expanded_functions,
|
180
|
+
functions=list(self._expanded_functions.values()),
|
177
181
|
constants=self._model.constants,
|
178
182
|
enums=self._model.enums,
|
179
183
|
types=self._model.types,
|
180
184
|
qstructs=self._model.qstructs,
|
181
185
|
debug_info=self._model.debug_info,
|
186
|
+
functions_compilation_metadata=self._expanded_functions_compilation_metadata,
|
182
187
|
)
|
183
188
|
|
184
189
|
@singledispatchmethod
|
@@ -196,7 +201,7 @@ class Interpreter:
|
|
196
201
|
@evaluate.register
|
197
202
|
def evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
|
198
203
|
renamed_params = [
|
199
|
-
param.rename(function.
|
204
|
+
param.rename(function.pos_rename_params[idx])
|
200
205
|
for idx, param in enumerate(function.func_decl.positional_arg_declarations)
|
201
206
|
]
|
202
207
|
func_decl = NamedParamsQuantumFunctionDeclaration(
|
@@ -204,7 +209,7 @@ class Interpreter:
|
|
204
209
|
positional_arg_declarations=renamed_params,
|
205
210
|
)
|
206
211
|
|
207
|
-
closure_class:
|
212
|
+
closure_class: type[FunctionClosure]
|
208
213
|
extra_args: dict[str, Any]
|
209
214
|
if function.is_generative():
|
210
215
|
closure_class = GenerativeFunctionClosure
|
@@ -339,7 +344,11 @@ class Interpreter:
|
|
339
344
|
|
340
345
|
def _expand_operation(self, operation: Closure) -> OperationContext:
|
341
346
|
with self._builder.operation_context(operation) as context:
|
342
|
-
if isinstance(operation, FunctionClosure) and
|
347
|
+
if isinstance(operation, FunctionClosure) and (
|
348
|
+
self._expanded_functions.get(operation.closure_id) is not None
|
349
|
+
):
|
350
|
+
pass
|
351
|
+
elif isinstance(operation, FunctionClosure) and operation.name == "permute":
|
343
352
|
# special expansion since permute is generative
|
344
353
|
with self._scope_guard(operation.scope):
|
345
354
|
self._expand_permute()
|
@@ -373,5 +382,5 @@ class Interpreter:
|
|
373
382
|
return (
|
374
383
|
self._model.functions
|
375
384
|
+ [gen_func.func_decl for gen_func in self._generative_functions]
|
376
|
-
+ self._expanded_functions
|
385
|
+
+ list(self._expanded_functions.values())
|
377
386
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
2
|
from enum import IntEnum
|
3
|
-
from typing import ClassVar,
|
3
|
+
from typing import ClassVar, Generic, Optional, TypeVar
|
4
4
|
|
5
5
|
from classiq.interface.generator.expressions.handle_identifier import HandleIdentifier
|
6
6
|
from classiq.interface.generator.functions.classical_type import QmodPyObject
|
@@ -18,15 +18,15 @@ DeclarationType = TypeVar(
|
|
18
18
|
|
19
19
|
|
20
20
|
class TypeTable(Generic[DeclarationType], ABC):
|
21
|
-
def __init__(self, user_types:
|
22
|
-
self._all_types:
|
21
|
+
def __init__(self, user_types: list[DeclarationType]) -> None:
|
22
|
+
self._all_types: dict[str, DeclarationType] = self.builtins.copy()
|
23
23
|
for t in user_types:
|
24
24
|
assert t.name not in self._all_types # FIXME: issue user error (CAD-7856)
|
25
25
|
self._all_types[t.name] = t
|
26
26
|
|
27
27
|
@property
|
28
28
|
@abstractmethod
|
29
|
-
def builtins(self) ->
|
29
|
+
def builtins(self) -> dict[str, DeclarationType]:
|
30
30
|
pass
|
31
31
|
|
32
32
|
def __getitem__(self, key: str) -> DeclarationType:
|
@@ -38,20 +38,20 @@ class TypeTable(Generic[DeclarationType], ABC):
|
|
38
38
|
def __contains__(self, key: str) -> bool:
|
39
39
|
return key in self._all_types
|
40
40
|
|
41
|
-
def all_types(self) ->
|
41
|
+
def all_types(self) -> dict[str, DeclarationType]:
|
42
42
|
return self._all_types
|
43
43
|
|
44
44
|
|
45
45
|
class EnumTable(TypeTable[EnumDeclaration]):
|
46
|
-
def __init__(self, user_types:
|
46
|
+
def __init__(self, user_types: list[EnumDeclaration]) -> None:
|
47
47
|
super().__init__(user_types)
|
48
48
|
|
49
49
|
@property
|
50
|
-
def builtins(self) ->
|
50
|
+
def builtins(self) -> dict[str, EnumDeclaration]:
|
51
51
|
return BUILTIN_ENUM_DECLARATIONS
|
52
52
|
|
53
53
|
@property
|
54
|
-
def enums(self) ->
|
54
|
+
def enums(self) -> dict[str, IntEnum]:
|
55
55
|
return {
|
56
56
|
enum_decl.name: enum_decl.create_enum()
|
57
57
|
for enum_decl in self.all_types().values()
|
@@ -60,13 +60,13 @@ class EnumTable(TypeTable[EnumDeclaration]):
|
|
60
60
|
|
61
61
|
class StructTable(TypeTable[StructDeclaration]):
|
62
62
|
@property
|
63
|
-
def builtins(self) ->
|
63
|
+
def builtins(self) -> dict[str, StructDeclaration]:
|
64
64
|
return BUILTIN_STRUCT_DECLARATIONS
|
65
65
|
|
66
66
|
|
67
67
|
class QStructTable(TypeTable[QStructDeclaration]):
|
68
68
|
@property
|
69
|
-
def builtins(self) ->
|
69
|
+
def builtins(self) -> dict[str, QStructDeclaration]:
|
70
70
|
return {}
|
71
71
|
|
72
72
|
|
@@ -76,15 +76,15 @@ class SymbolTable:
|
|
76
76
|
qstruct_table: ClassVar[QStructTable] = QStructTable([])
|
77
77
|
|
78
78
|
@classmethod
|
79
|
-
def init_user_enums(cls, user_enums:
|
79
|
+
def init_user_enums(cls, user_enums: list[EnumDeclaration]) -> None:
|
80
80
|
cls.enum_table = EnumTable(user_enums)
|
81
81
|
|
82
82
|
@classmethod
|
83
|
-
def init_user_types(cls, user_types:
|
83
|
+
def init_user_types(cls, user_types: list[StructDeclaration]) -> None:
|
84
84
|
cls.type_table = StructTable(user_types)
|
85
85
|
|
86
86
|
@classmethod
|
87
|
-
def init_user_qstructs(cls, user_qstructs:
|
87
|
+
def init_user_qstructs(cls, user_qstructs: list[QStructDeclaration]) -> None:
|
88
88
|
cls.qstruct_table = QStructTable(user_qstructs)
|
89
89
|
QMODULE.qstruct_decls = {
|
90
90
|
qstruct_decl.name: qstruct_decl for qstruct_decl in user_qstructs
|
@@ -92,7 +92,7 @@ class SymbolTable:
|
|
92
92
|
|
93
93
|
|
94
94
|
class HandleTable:
|
95
|
-
_handle_map:
|
95
|
+
_handle_map: dict[HandleIdentifier, QmodPyObject] = {}
|
96
96
|
|
97
97
|
@classmethod
|
98
98
|
def get_handle_object(cls, hid: HandleIdentifier) -> Optional[QmodPyObject]:
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
1
|
from classiq.interface.exceptions import ClassiqExpansionError
|
4
2
|
from classiq.interface.model.bind_operation import BindOperation
|
5
3
|
|
@@ -18,11 +16,11 @@ class BindEmitter(Emitter[BindOperation]):
|
|
18
16
|
def emit(self, bind: BindOperation, /) -> None:
|
19
17
|
with self._propagated_var_stack.capture_variables(bind):
|
20
18
|
pass
|
21
|
-
inputs:
|
19
|
+
inputs: list[QuantumSymbol] = [
|
22
20
|
self._interpreter.evaluate(arg).as_type(QuantumSymbol)
|
23
21
|
for arg in bind.in_handles
|
24
22
|
]
|
25
|
-
outputs:
|
23
|
+
outputs: list[QuantumSymbol] = [
|
26
24
|
self._interpreter.evaluate(arg).as_type(QuantumSymbol)
|
27
25
|
for arg in bind.out_handles
|
28
26
|
]
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import List, Tuple
|
2
|
-
|
3
1
|
from sympy import Equality
|
4
2
|
from sympy.logic.boolalg import Boolean
|
5
3
|
from typing_extensions import TypeGuard
|
@@ -11,6 +9,7 @@ from classiq.interface.exceptions import (
|
|
11
9
|
from classiq.interface.generator.compiler_keywords import INPLACE_ARITH_AUX_VAR_PREFIX
|
12
10
|
from classiq.interface.generator.expressions.expression import Expression
|
13
11
|
from classiq.interface.generator.expressions.expression_types import ExpressionValue
|
12
|
+
from classiq.interface.generator.expressions.qmod_qarray_proxy import QmodQArrayProxy
|
14
13
|
from classiq.interface.generator.expressions.qmod_qscalar_proxy import QmodQNumProxy
|
15
14
|
from classiq.interface.generator.expressions.qmod_sized_proxy import QmodSizedProxy
|
16
15
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
@@ -23,6 +22,7 @@ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
23
22
|
ArithmeticOperation,
|
24
23
|
ArithmeticOperationKind,
|
25
24
|
)
|
25
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
26
26
|
from classiq.interface.model.quantum_type import QuantumBit, QuantumBitvector
|
27
27
|
from classiq.interface.model.statement_block import ConcreteQuantumStatement
|
28
28
|
from classiq.interface.model.variable_declaration_statement import (
|
@@ -42,6 +42,7 @@ from classiq.model_expansions.quantum_operations.expression_operation import (
|
|
42
42
|
ExpressionOperationEmitter,
|
43
43
|
)
|
44
44
|
from classiq.model_expansions.scope import Scope
|
45
|
+
from classiq.qmod.builtins.functions.standard_gates import X
|
45
46
|
|
46
47
|
ARRAY_CAST_SUFFIX = HANDLE_ID_SEPARATOR + "array_cast"
|
47
48
|
|
@@ -49,22 +50,42 @@ ARRAY_CAST_SUFFIX = HANDLE_ID_SEPARATOR + "array_cast"
|
|
49
50
|
class ControlEmitter(ExpressionOperationEmitter[Control]):
|
50
51
|
def emit(self, control: Control, /) -> None:
|
51
52
|
condition = self._evaluate_op_expression(control)
|
52
|
-
control = control.model_copy(update=dict(expression=condition))
|
53
53
|
|
54
54
|
arrays_with_subscript = self._get_symbols_to_split(condition)
|
55
55
|
if len(arrays_with_subscript) > 0:
|
56
56
|
self._emit_with_split(control, condition, arrays_with_subscript)
|
57
57
|
return
|
58
58
|
|
59
|
+
control = self._evaluate_types_in_expression(control, condition)
|
59
60
|
condition_val = condition.value.value
|
60
61
|
if isinstance(condition_val, QmodSizedProxy):
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
if control.else_block is None:
|
63
|
+
self._validate_canonical_condition(condition_val)
|
64
|
+
self._emit_canonical_control(control)
|
65
|
+
return
|
66
|
+
else:
|
67
|
+
self._interpreter.emit_statement(
|
68
|
+
control.model_copy(
|
69
|
+
update=dict(
|
70
|
+
expression=self._uncanonize_condition(condition_val)
|
71
|
+
)
|
72
|
+
)
|
73
|
+
)
|
74
|
+
return
|
64
75
|
|
65
|
-
self._validate_condition(
|
76
|
+
self._validate_condition(control)
|
66
77
|
self._emit_with_boolean(control)
|
67
78
|
|
79
|
+
def _uncanonize_condition(self, condition_val: QmodSizedProxy) -> Expression:
|
80
|
+
lhs = (
|
81
|
+
" & ".join(
|
82
|
+
f"{condition_val.handle}[{idx}]" for idx in range(condition_val.size)
|
83
|
+
)
|
84
|
+
if isinstance(condition_val, QmodQArrayProxy)
|
85
|
+
else condition_val.handle
|
86
|
+
)
|
87
|
+
return Expression(expr=f"{lhs} == 1")
|
88
|
+
|
68
89
|
def _emit_canonical_control(self, control: Control) -> None:
|
69
90
|
# canonical means control(q, body) where q is a single quantum variable
|
70
91
|
control = self._evaluate_types_in_expression(control, control.expression)
|
@@ -131,9 +152,10 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
131
152
|
condition_val = control.expression.value.value
|
132
153
|
if self._is_simple_equality(condition_val):
|
133
154
|
ctrl, ctrl_state = resolve_num_condition(condition_val)
|
134
|
-
|
135
|
-
|
136
|
-
|
155
|
+
if control.else_block is None or ctrl.size == 1:
|
156
|
+
self._emit_with_x_gates(control, ctrl, ctrl_state)
|
157
|
+
return
|
158
|
+
self._emit_with_arithmetic(control)
|
137
159
|
|
138
160
|
@staticmethod
|
139
161
|
def _is_simple_equality(condition_val: ExpressionValue) -> TypeGuard[Equality]:
|
@@ -153,14 +175,38 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
153
175
|
|
154
176
|
def _create_canonical_control_op(
|
155
177
|
self, control: Control, handle_name: str
|
156
|
-
) ->
|
178
|
+
) -> list[ConcreteQuantumStatement]:
|
157
179
|
handle_expr = self._interpreter.evaluate(Expression(expr=handle_name)).emit()
|
158
|
-
|
180
|
+
control_then = control.model_copy(
|
181
|
+
update=dict(expression=handle_expr, else_block=None)
|
182
|
+
)
|
183
|
+
if control.else_block is None:
|
184
|
+
return [control_then]
|
185
|
+
else_compute_call = QuantumFunctionCall(
|
186
|
+
function="X", positional_args=[HandleBinding(name=handle_name)]
|
187
|
+
)
|
188
|
+
else_compute_call.set_func_decl(X.func_decl)
|
189
|
+
control_else_inner = control.model_copy(
|
190
|
+
update=dict(
|
191
|
+
expression=handle_expr, body=control.else_block, else_block=None
|
192
|
+
),
|
193
|
+
deep=True,
|
194
|
+
)
|
195
|
+
control_else = WithinApply(
|
196
|
+
compute=[else_compute_call],
|
197
|
+
action=[control_else_inner],
|
198
|
+
)
|
199
|
+
if control_else_inner.is_generative():
|
200
|
+
control_else_inner.set_generative_block(
|
201
|
+
"body", control_else_inner.get_generative_block("else_block")
|
202
|
+
)
|
203
|
+
control_else_inner.remove_generative_block("else_block")
|
204
|
+
return [control_then, control_else]
|
159
205
|
|
160
|
-
def
|
206
|
+
def _control_with_x_gates(
|
161
207
|
self, control: Control, ctrl: QmodSizedProxy, ctrl_state: str
|
162
|
-
) ->
|
163
|
-
compute_op:
|
208
|
+
) -> ConcreteQuantumStatement:
|
209
|
+
compute_op: list[ConcreteQuantumStatement] = []
|
164
210
|
|
165
211
|
x_gate_value = self._get_x_gate_value(ctrl_state)
|
166
212
|
if x_gate_value != 0:
|
@@ -177,12 +223,19 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
177
223
|
cast_decl, bind_op = self._get_array_cast_ops(ctrl)
|
178
224
|
self._interpreter.emit_statement(cast_decl)
|
179
225
|
compute_op.append(bind_op)
|
180
|
-
|
226
|
+
control_ops = self._create_canonical_control_op(
|
227
|
+
control, str(cast_decl.name)
|
228
|
+
)
|
181
229
|
else:
|
182
|
-
|
230
|
+
control_ops = self._create_canonical_control_op(control, str(ctrl.handle))
|
231
|
+
|
232
|
+
return WithinApply(compute=compute_op, action=control_ops)
|
183
233
|
|
234
|
+
def _emit_with_x_gates(
|
235
|
+
self, control: Control, ctrl: QmodSizedProxy, ctrl_state: str
|
236
|
+
) -> None:
|
184
237
|
self._interpreter.emit_statement(
|
185
|
-
|
238
|
+
self._control_with_x_gates(control, ctrl, ctrl_state)
|
186
239
|
)
|
187
240
|
|
188
241
|
@staticmethod
|
@@ -194,7 +247,7 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
194
247
|
|
195
248
|
def _get_array_cast_ops(
|
196
249
|
self, ctrl: QmodQNumProxy
|
197
|
-
) ->
|
250
|
+
) -> tuple[VariableDeclarationStatement, BindOperation]:
|
198
251
|
array_cast = self._counted_name_allocator.allocate(
|
199
252
|
f"{ctrl.handle}{ARRAY_CAST_SUFFIX}"
|
200
253
|
)
|
@@ -219,14 +272,18 @@ class ControlEmitter(ExpressionOperationEmitter[Control]):
|
|
219
272
|
self._interpreter.emit_statement(
|
220
273
|
WithinApply(
|
221
274
|
compute=[arith_expression],
|
222
|
-
action=
|
275
|
+
action=self._create_canonical_control_op(control, aux_var),
|
223
276
|
)
|
224
277
|
)
|
225
278
|
|
226
|
-
|
227
|
-
|
228
|
-
if not
|
229
|
-
|
279
|
+
def _validate_condition(self, control: Control) -> None:
|
280
|
+
condition_value = control.expression.value.value
|
281
|
+
if not (
|
282
|
+
isinstance(condition_value, Boolean)
|
283
|
+
or self._all_vars_boolean(control)
|
284
|
+
and self._is_res_boolean(control)
|
285
|
+
):
|
286
|
+
raise ClassiqExpansionError(_condition_err_msg(condition_value))
|
230
287
|
|
231
288
|
@staticmethod
|
232
289
|
def _validate_canonical_condition(condition_val: ExpressionValue) -> None:
|