classiq 0.102.0__py3-none-any.whl → 0.104.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/applications/chemistry/op_utils.py +32 -0
- classiq/evaluators/qmod_annotated_expression.py +1 -1
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +1 -8
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +1 -1
- classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +2 -2
- classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +18 -29
- classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +1 -6
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +1 -7
- classiq/evaluators/qmod_type_inference/quantum_type_comparison.py +52 -0
- classiq/execution/execution_session.py +1 -1
- classiq/execution/functions/__init__.py +3 -0
- classiq/execution/functions/_logging.py +19 -0
- classiq/execution/functions/constants.py +9 -0
- classiq/execution/functions/parse_provider_backend.py +90 -0
- classiq/execution/functions/sample.py +257 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +15 -0
- classiq/interface/backend/provider_config/providers/aqt.py +1 -1
- classiq/interface/backend/provider_config/providers/azure.py +1 -2
- classiq/interface/backend/provider_config/providers/ibm.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +3 -0
- classiq/interface/executor/result.py +9 -5
- classiq/interface/generator/arith/binary_ops.py +38 -2
- classiq/interface/generator/function_param_list.py +4 -2
- classiq/interface/generator/functions/builtins/internal_operators.py +5 -9
- classiq/interface/generator/functions/classical_type.py +45 -0
- classiq/interface/generator/functions/type_name.py +23 -0
- classiq/interface/generator/generated_circuit_data.py +0 -2
- classiq/interface/generator/types/compilation_metadata.py +9 -0
- classiq/interface/hardware.py +1 -0
- classiq/interface/helpers/model_normalizer.py +42 -6
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/invert.py +8 -0
- classiq/interface/model/model_visitor.py +4 -2
- classiq/interface/model/quantum_type.py +21 -0
- classiq/interface/model/statement_block.py +0 -4
- classiq/model_expansions/capturing/captured_vars.py +16 -12
- classiq/model_expansions/function_builder.py +9 -1
- classiq/model_expansions/interpreters/base_interpreter.py +9 -8
- classiq/model_expansions/interpreters/generative_interpreter.py +9 -24
- classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -0
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +132 -28
- classiq/model_expansions/quantum_operations/bind.py +4 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +5 -35
- classiq/model_expansions/quantum_operations/emitter.py +1 -4
- classiq/model_expansions/quantum_operations/expression_evaluator.py +0 -3
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +0 -9
- classiq/qmod/builtins/functions/__init__.py +9 -0
- classiq/qmod/builtins/functions/arithmetic.py +131 -0
- classiq/qmod/builtins/functions/exponentiation.py +32 -2
- classiq/qmod/builtins/operations.py +2 -38
- classiq/qmod/native/pretty_printer.py +1 -12
- classiq/qmod/pretty_print/pretty_printer.py +1 -17
- classiq/qmod/qmod_parameter.py +4 -0
- classiq/qmod/qmod_variable.py +38 -63
- classiq/qmod/quantum_function.py +43 -7
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +7 -4
- classiq/qmod/semantics/validation/model_validation.py +7 -2
- classiq/qmod/symbolic_type.py +4 -2
- {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/METADATA +1 -1
- {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/RECORD +63 -59
- classiq/interface/generator/amplitude_loading.py +0 -103
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +0 -77
- {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/WHEEL +0 -0
- {classiq-0.102.0.dist-info → classiq-0.104.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -5,6 +5,7 @@ class CompilationMetadata(BaseModel):
|
|
|
5
5
|
should_synthesize_separately: bool = Field(default=False)
|
|
6
6
|
occurrences_number: NonNegativeInt = Field(default=0)
|
|
7
7
|
_occupation_number: NonNegativeInt = PrivateAttr(default=0)
|
|
8
|
+
_required_clean_qubit: NonNegativeInt = PrivateAttr(default=0)
|
|
8
9
|
disable_perm_check: bool = Field(default=False)
|
|
9
10
|
disable_const_checks: list[str] | bool = Field(default=False)
|
|
10
11
|
|
|
@@ -16,6 +17,14 @@ class CompilationMetadata(BaseModel):
|
|
|
16
17
|
def occupation_number(self, value: NonNegativeInt) -> None:
|
|
17
18
|
self._occupation_number = value
|
|
18
19
|
|
|
20
|
+
@property
|
|
21
|
+
def required_clean_qubit(self) -> NonNegativeInt:
|
|
22
|
+
return self._required_clean_qubit
|
|
23
|
+
|
|
24
|
+
@required_clean_qubit.setter
|
|
25
|
+
def required_clean_qubit(self, value: NonNegativeInt) -> None:
|
|
26
|
+
self._required_clean_qubit = value
|
|
27
|
+
|
|
19
28
|
@property
|
|
20
29
|
def has_user_directives(self) -> bool:
|
|
21
30
|
return bool(self.disable_perm_check or self.disable_const_checks)
|
classiq/interface/hardware.py
CHANGED
|
@@ -6,16 +6,31 @@ from classiq.interface.generator.expressions.expression import Expression
|
|
|
6
6
|
from classiq.interface.generator.functions.classical_type import ClassicalType
|
|
7
7
|
from classiq.interface.generator.functions.type_modifier import TypeModifier
|
|
8
8
|
from classiq.interface.generator.visitor import Transformer, Visitor
|
|
9
|
+
from classiq.interface.model.handle_binding import HandleBinding
|
|
9
10
|
from classiq.interface.model.model import Model
|
|
10
11
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
11
|
-
from classiq.interface.model.port_declaration import
|
|
12
|
+
from classiq.interface.model.port_declaration import (
|
|
13
|
+
PortDeclaration,
|
|
14
|
+
)
|
|
12
15
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
|
16
|
+
from classiq.interface.model.variable_declaration_statement import (
|
|
17
|
+
VariableDeclarationStatement,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
|
13
21
|
|
|
14
22
|
|
|
15
23
|
class ModelNormalizer(Visitor):
|
|
16
|
-
def __init__(
|
|
17
|
-
self
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
normalize_func_names: bool = False,
|
|
27
|
+
normalize_quantum_var_names: bool = False,
|
|
28
|
+
) -> None:
|
|
29
|
+
self._normalize_func_names = normalize_func_names
|
|
30
|
+
self._normalize_quantum_var_names = normalize_quantum_var_names
|
|
18
31
|
self._funcs_renames: dict[str, str] = {}
|
|
32
|
+
self._count_name = CountedNameAllocator()
|
|
33
|
+
self.original_names: dict[str, str] = {}
|
|
19
34
|
|
|
20
35
|
def visit(self, node: Any) -> None:
|
|
21
36
|
if isinstance(node, ASTNode):
|
|
@@ -35,12 +50,12 @@ class ModelNormalizer(Visitor):
|
|
|
35
50
|
self.generic_visit(model)
|
|
36
51
|
|
|
37
52
|
def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
|
|
38
|
-
if self.
|
|
53
|
+
if self._normalize_func_names:
|
|
39
54
|
func.name = self._funcs_renames[func.name]
|
|
40
55
|
self.generic_visit(func)
|
|
41
56
|
|
|
42
57
|
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
|
43
|
-
if self.
|
|
58
|
+
if self._normalize_func_names:
|
|
44
59
|
if isinstance(call.function, str):
|
|
45
60
|
if call.function in self._funcs_renames:
|
|
46
61
|
call.function = self._funcs_renames[call.function]
|
|
@@ -49,8 +64,29 @@ class ModelNormalizer(Visitor):
|
|
|
49
64
|
call.function.name = self._funcs_renames[call.function.name]
|
|
50
65
|
self.generic_visit(call)
|
|
51
66
|
|
|
52
|
-
def
|
|
67
|
+
def visit_PortDeclaration(self, decl: PortDeclaration) -> None:
|
|
53
68
|
decl.type_modifier = TypeModifier.Mutable
|
|
69
|
+
self._rename_quantum_var(decl, "_port")
|
|
70
|
+
|
|
71
|
+
def visit_VariableDeclarationStatement(
|
|
72
|
+
self, var: VariableDeclarationStatement
|
|
73
|
+
) -> None:
|
|
74
|
+
self._rename_quantum_var(var, "_var")
|
|
75
|
+
|
|
76
|
+
def _rename_quantum_var(
|
|
77
|
+
self, var: VariableDeclarationStatement | PortDeclaration, new_name_prefix: str
|
|
78
|
+
) -> None:
|
|
79
|
+
if self._normalize_quantum_var_names:
|
|
80
|
+
old_name = var.name
|
|
81
|
+
var.name = self._count_name.allocate(new_name_prefix)
|
|
82
|
+
self.original_names[old_name] = var.name
|
|
83
|
+
|
|
84
|
+
def visit_HandleBinding(self, handle: HandleBinding) -> None:
|
|
85
|
+
if self._normalize_quantum_var_names:
|
|
86
|
+
# this is a hack use just for testing, do not use in production
|
|
87
|
+
object.__setattr__(
|
|
88
|
+
handle, "name", self.original_names.get(handle.name, handle.name)
|
|
89
|
+
)
|
|
54
90
|
|
|
55
91
|
|
|
56
92
|
class ClearModelInternals(Transformer):
|
|
@@ -1 +1 @@
|
|
|
1
|
-
INTERFACE_VERSION = "
|
|
1
|
+
INTERFACE_VERSION = "16"
|
|
@@ -2,6 +2,8 @@ from typing import TYPE_CHECKING, Literal
|
|
|
2
2
|
|
|
3
3
|
from classiq.interface.ast_node import ASTNodeType, reset_lists
|
|
4
4
|
from classiq.interface.enum_utils import StrEnum
|
|
5
|
+
from classiq.interface.exceptions import ClassiqInternalExpansionError
|
|
6
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
|
5
7
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
|
6
8
|
|
|
7
9
|
if TYPE_CHECKING:
|
|
@@ -25,3 +27,9 @@ class Invert(QuantumOperation):
|
|
|
25
27
|
@property
|
|
26
28
|
def blocks(self) -> dict[str, "StatementBlock"]:
|
|
27
29
|
return {"body": self.body}
|
|
30
|
+
|
|
31
|
+
def validate_node(self) -> None:
|
|
32
|
+
if self.block_kind == BlockKind.SingleCall and (
|
|
33
|
+
len(self.body) != 1 or not isinstance(self.body[0], QuantumFunctionCall)
|
|
34
|
+
):
|
|
35
|
+
raise ClassiqInternalExpansionError("Malformed single-call invert")
|
|
@@ -10,8 +10,10 @@ from classiq.interface.model.quantum_statement import QuantumStatement
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class ModelVisitor(Visitor):
|
|
13
|
-
def visit_DebugInfoCollection(
|
|
14
|
-
|
|
13
|
+
def visit_DebugInfoCollection(
|
|
14
|
+
self, debug_info: DebugInfoCollection
|
|
15
|
+
) -> RetType | None:
|
|
16
|
+
return None
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class ModelStatementsVisitor(ModelVisitor):
|
|
@@ -78,6 +78,9 @@ class QuantumType(HashableASTNode):
|
|
|
78
78
|
def without_symbolic_attributes(self) -> Self:
|
|
79
79
|
return self
|
|
80
80
|
|
|
81
|
+
def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
|
|
82
|
+
return {}
|
|
83
|
+
|
|
81
84
|
|
|
82
85
|
class QuantumScalar(QuantumType):
|
|
83
86
|
@property
|
|
@@ -262,6 +265,14 @@ class QuantumBitvector(QuantumType):
|
|
|
262
265
|
length = 1
|
|
263
266
|
return length * self.element_type.minimal_size_in_bits
|
|
264
267
|
|
|
268
|
+
def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
|
|
269
|
+
attrs: dict[str, Any] = {}
|
|
270
|
+
if self.has_constant_length:
|
|
271
|
+
attrs[f"{path_expr_prefix}.len"] = self.length_value
|
|
272
|
+
return attrs | self.element_type.get_compile_time_attributes(
|
|
273
|
+
f"{path_expr_prefix}[0]"
|
|
274
|
+
)
|
|
275
|
+
|
|
265
276
|
def without_symbolic_attributes(self) -> "QuantumBitvector":
|
|
266
277
|
length = (
|
|
267
278
|
None
|
|
@@ -301,6 +312,16 @@ class QuantumNumeric(QuantumScalar):
|
|
|
301
312
|
)
|
|
302
313
|
return self
|
|
303
314
|
|
|
315
|
+
def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
|
|
316
|
+
attrs: dict[str, Any] = {}
|
|
317
|
+
if self.has_size_in_bits:
|
|
318
|
+
attrs[f"{path_expr_prefix}.size"] = self.size_in_bits
|
|
319
|
+
if self.has_constant_sign:
|
|
320
|
+
attrs[f"{path_expr_prefix}.is_signed"] = self.sign_value
|
|
321
|
+
if self.has_constant_fraction_digits:
|
|
322
|
+
attrs[f"{path_expr_prefix}.fraction_digits"] = self.fraction_digits_value
|
|
323
|
+
return attrs
|
|
324
|
+
|
|
304
325
|
def set_size_in_bits(self, val: int) -> None:
|
|
305
326
|
super().set_size_in_bits(val)
|
|
306
327
|
if self.size is not None:
|
|
@@ -13,9 +13,6 @@ from classiq.interface.model.invert import Invert
|
|
|
13
13
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
14
14
|
from classiq.interface.model.phase_operation import PhaseOperation
|
|
15
15
|
from classiq.interface.model.power import Power
|
|
16
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
17
|
-
AmplitudeLoadingOperation,
|
|
18
|
-
)
|
|
19
16
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
20
17
|
ArithmeticOperation,
|
|
21
18
|
)
|
|
@@ -38,7 +35,6 @@ ConcreteQuantumStatement = Annotated[
|
|
|
38
35
|
QuantumFunctionCall,
|
|
39
36
|
Allocate,
|
|
40
37
|
ArithmeticOperation,
|
|
41
|
-
AmplitudeLoadingOperation,
|
|
42
38
|
VariableDeclarationStatement,
|
|
43
39
|
BindOperation,
|
|
44
40
|
InplaceBinaryOperation,
|
|
@@ -56,8 +56,8 @@ if TYPE_CHECKING:
|
|
|
56
56
|
from classiq.model_expansions.closure import FunctionClosure
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
_INITIALIZED_VAR_MESSAGE = "Variable '{}' should be uninitialized here"
|
|
60
|
+
_UNINITIALIZED_VAR_MESSAGE = "Variable '{}' should be initialized here"
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def _get_symbol_expr(symbol: str, classical_type: ClassicalType) -> Expression:
|
|
@@ -311,7 +311,7 @@ class CapturedVars:
|
|
|
311
311
|
return PortDirection.Inout
|
|
312
312
|
if target_direction == PortDirection.Outin:
|
|
313
313
|
return PortDirection.Input
|
|
314
|
-
raise ClassiqExpansionError(
|
|
314
|
+
raise ClassiqExpansionError(_UNINITIALIZED_VAR_MESSAGE.format(var_name))
|
|
315
315
|
|
|
316
316
|
if source_direction == PortDirection.Output:
|
|
317
317
|
if target_direction == PortDirection.Input:
|
|
@@ -320,18 +320,18 @@ class CapturedVars:
|
|
|
320
320
|
PortDirection.Output,
|
|
321
321
|
PortDirection.Outin,
|
|
322
322
|
):
|
|
323
|
-
raise ClassiqExpansionError(
|
|
323
|
+
raise ClassiqExpansionError(_INITIALIZED_VAR_MESSAGE.format(var_name))
|
|
324
324
|
return PortDirection.Output
|
|
325
325
|
|
|
326
326
|
if source_direction == PortDirection.Inout:
|
|
327
327
|
if target_direction in (PortDirection.Input, PortDirection.Inout):
|
|
328
328
|
return target_direction
|
|
329
|
-
raise ClassiqExpansionError(
|
|
329
|
+
raise ClassiqExpansionError(_INITIALIZED_VAR_MESSAGE.format(var_name))
|
|
330
330
|
|
|
331
331
|
if source_direction == PortDirection.Outin:
|
|
332
332
|
if target_direction in (PortDirection.Output, PortDirection.Outin):
|
|
333
333
|
return target_direction
|
|
334
|
-
raise ClassiqExpansionError(
|
|
334
|
+
raise ClassiqExpansionError(_UNINITIALIZED_VAR_MESSAGE.format(var_name))
|
|
335
335
|
|
|
336
336
|
raise ClassiqInternalExpansionError(f"Unexpected direction {source_direction}")
|
|
337
337
|
|
|
@@ -346,7 +346,7 @@ class CapturedVars:
|
|
|
346
346
|
PortDirection.Outin,
|
|
347
347
|
):
|
|
348
348
|
raise ClassiqExpansionError(
|
|
349
|
-
|
|
349
|
+
_UNINITIALIZED_VAR_MESSAGE.format(captured_handle.handle)
|
|
350
350
|
)
|
|
351
351
|
return existing_captured_handle
|
|
352
352
|
|
|
@@ -356,7 +356,7 @@ class CapturedVars:
|
|
|
356
356
|
PortDirection.Outin,
|
|
357
357
|
):
|
|
358
358
|
raise ClassiqExpansionError(
|
|
359
|
-
|
|
359
|
+
_INITIALIZED_VAR_MESSAGE.format(captured_handle.handle)
|
|
360
360
|
)
|
|
361
361
|
return captured_handle
|
|
362
362
|
|
|
@@ -705,7 +705,9 @@ class CapturedVars:
|
|
|
705
705
|
def set_parent(self, parent: "CapturedVars") -> None:
|
|
706
706
|
self._handle_states += parent._get_handle_states()
|
|
707
707
|
|
|
708
|
-
def get_state(
|
|
708
|
+
def get_state(
|
|
709
|
+
self, var_name: str, defining_function: "FunctionClosure"
|
|
710
|
+
) -> bool | None:
|
|
709
711
|
for name, func, state in self._handle_states:
|
|
710
712
|
if name == var_name and _same_closure(func, defining_function):
|
|
711
713
|
return state
|
|
@@ -717,9 +719,7 @@ class CapturedVars:
|
|
|
717
719
|
PortDirection.Output,
|
|
718
720
|
PortDirection.Inout,
|
|
719
721
|
)
|
|
720
|
-
|
|
721
|
-
f"Cannot find {var_name!r} from {defining_function.name!r}"
|
|
722
|
-
)
|
|
722
|
+
return None
|
|
723
723
|
|
|
724
724
|
def clone(self) -> "CapturedVars":
|
|
725
725
|
return CapturedVars(
|
|
@@ -846,6 +846,10 @@ def validate_end_state(func: "FunctionClosure", captured_vars: CapturedVars) ->
|
|
|
846
846
|
for param in func.positional_arg_declarations:
|
|
847
847
|
if isinstance(param, PortDeclaration):
|
|
848
848
|
state = captured_vars.get_state(param.name, func)
|
|
849
|
+
if state is None:
|
|
850
|
+
raise ClassiqInternalExpansionError(
|
|
851
|
+
f"Cannot find {param.name!r} from {func.name!r}"
|
|
852
|
+
)
|
|
849
853
|
expected_state = param.direction in (
|
|
850
854
|
PortDeclarationDirection.Output,
|
|
851
855
|
PortDeclarationDirection.Inout,
|
|
@@ -13,6 +13,8 @@ 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
|
+
INVERT_OPERATOR_NAMES,
|
|
17
|
+
SINGLE_CALL_INVERT_OPERATOR_NAME,
|
|
16
18
|
SKIP_CONTROL_OPERATOR_NAME,
|
|
17
19
|
WITHIN_APPLY_NAME,
|
|
18
20
|
)
|
|
@@ -44,6 +46,7 @@ BLOCKS_ALLOWED_CAPTURING = (
|
|
|
44
46
|
WITHIN_APPLY_NAME,
|
|
45
47
|
BLOCK_OPERATOR_NAME,
|
|
46
48
|
SKIP_CONTROL_OPERATOR_NAME,
|
|
49
|
+
SINGLE_CALL_INVERT_OPERATOR_NAME,
|
|
47
50
|
)
|
|
48
51
|
|
|
49
52
|
|
|
@@ -155,6 +158,8 @@ class OperationBuilder:
|
|
|
155
158
|
self._operations[-1].blocks[block_name] = block
|
|
156
159
|
yield
|
|
157
160
|
captured_vars = self.current_block.captured_vars
|
|
161
|
+
if self.current_operation.name in INVERT_OPERATOR_NAMES:
|
|
162
|
+
captured_vars = captured_vars.negate()
|
|
158
163
|
if (
|
|
159
164
|
not isinstance(self.current_operation, FunctionClosure)
|
|
160
165
|
and self.current_operation.name not in BLOCKS_ALLOWED_CAPTURING
|
|
@@ -178,7 +183,10 @@ class OperationBuilder:
|
|
|
178
183
|
context.closure.captured_vars.init_params(original_operation)
|
|
179
184
|
else:
|
|
180
185
|
context = OperationContext(closure=original_operation)
|
|
181
|
-
context.
|
|
186
|
+
if context.name != SINGLE_CALL_INVERT_OPERATOR_NAME:
|
|
187
|
+
context.closure.captured_vars.set_parent(
|
|
188
|
+
self.current_block.captured_vars
|
|
189
|
+
)
|
|
182
190
|
self._operations.append(context)
|
|
183
191
|
yield context
|
|
184
192
|
self._finalize_within_apply()
|
|
@@ -32,6 +32,7 @@ from classiq.interface.model.handle_binding import (
|
|
|
32
32
|
from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
|
|
33
33
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
34
34
|
from classiq.interface.model.quantum_function_declaration import (
|
|
35
|
+
NamedParamsQuantumFunctionDeclaration,
|
|
35
36
|
QuantumFunctionDeclaration,
|
|
36
37
|
)
|
|
37
38
|
from classiq.interface.model.quantum_lambda_function import (
|
|
@@ -76,6 +77,7 @@ from classiq.model_expansions.scope_initialization import (
|
|
|
76
77
|
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
|
77
78
|
from classiq.qmod.builtins.constants import __all__ as builtin_constants
|
|
78
79
|
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
|
80
|
+
from classiq.qmod.builtins.functions import CORE_LIB_DECLS
|
|
79
81
|
from classiq.qmod.builtins.structs import BUILTIN_STRUCT_DECLARATIONS
|
|
80
82
|
from classiq.qmod.model_state_container import QMODULE
|
|
81
83
|
from classiq.qmod.semantics.annotation.qstruct_annotator import QStructAnnotator
|
|
@@ -98,7 +100,7 @@ class BaseInterpreter:
|
|
|
98
100
|
skip_type_modifier_validation: bool = False
|
|
99
101
|
|
|
100
102
|
def __init__(self, model: Model) -> None:
|
|
101
|
-
validate_model(model)
|
|
103
|
+
validate_model(model, self.get_builtin_functions())
|
|
102
104
|
self._model = model
|
|
103
105
|
self._top_level_scope = Scope()
|
|
104
106
|
self._counted_name_allocator = CountedNameAllocator()
|
|
@@ -121,6 +123,9 @@ class BaseInterpreter:
|
|
|
121
123
|
self._counted_name_allocator = CountedNameAllocator()
|
|
122
124
|
self._error_manager: ErrorManager = ErrorManager()
|
|
123
125
|
|
|
126
|
+
def get_builtin_functions(self) -> list[NamedParamsQuantumFunctionDeclaration]:
|
|
127
|
+
return CORE_LIB_DECLS
|
|
128
|
+
|
|
124
129
|
def _expand_main_func(self) -> None:
|
|
125
130
|
main_closure = self._get_main_closure(
|
|
126
131
|
self._top_level_scope[MAIN_FUNCTION_NAME].value
|
|
@@ -207,15 +212,14 @@ class BaseInterpreter:
|
|
|
207
212
|
expression: Expression,
|
|
208
213
|
*,
|
|
209
214
|
simplify: bool = False,
|
|
210
|
-
treat_qnum_as_float: bool = False,
|
|
211
215
|
) -> Evaluated:
|
|
212
216
|
if expression.is_evaluated():
|
|
213
217
|
return Evaluated(value=expression.value.value)
|
|
214
218
|
expr_ast = ast.parse(expression.expr, mode="eval").body
|
|
215
|
-
expr_val = self._eval_expr(ast.unparse(expr_ast)
|
|
219
|
+
expr_val = self._eval_expr(ast.unparse(expr_ast))
|
|
216
220
|
if simplify and not expr_val.has_value(expr_val.root):
|
|
217
221
|
simplified_expr = simplify_qmod_expression(expr_val)
|
|
218
|
-
expr_val = self._eval_expr(simplified_expr
|
|
222
|
+
expr_val = self._eval_expr(simplified_expr)
|
|
219
223
|
if expr_val.has_value(expr_val.root):
|
|
220
224
|
value = expr_val.get_value(expr_val.root)
|
|
221
225
|
else:
|
|
@@ -223,12 +227,9 @@ class BaseInterpreter:
|
|
|
223
227
|
|
|
224
228
|
return Evaluated(value=value)
|
|
225
229
|
|
|
226
|
-
def _eval_expr(
|
|
227
|
-
self, expr: str, treat_qnum_as_float: bool
|
|
228
|
-
) -> QmodAnnotatedExpression:
|
|
230
|
+
def _eval_expr(self, expr: str) -> QmodAnnotatedExpression:
|
|
229
231
|
return evaluate_qmod_expression(
|
|
230
232
|
expr,
|
|
231
|
-
treat_qnum_as_float=treat_qnum_as_float,
|
|
232
233
|
machine_precision=self._model.preferences.machine_precision,
|
|
233
234
|
classical_struct_declarations=list(QMODULE.type_decls.values()),
|
|
234
235
|
enum_declarations=list(QMODULE.enum_decls.values()),
|
|
@@ -9,10 +9,11 @@ from classiq.interface.generator.expressions.expression import Expression
|
|
|
9
9
|
from classiq.interface.generator.functions.builtins.internal_operators import (
|
|
10
10
|
BLOCK_OPERATOR_NAME,
|
|
11
11
|
CLASSICAL_IF_OPERATOR_NAME,
|
|
12
|
+
COMPOUND_INVERT_OPERATOR_NAME,
|
|
12
13
|
CONTROL_OPERATOR_NAME,
|
|
13
|
-
INVERT_OPERATOR_NAME,
|
|
14
14
|
POWER_OPERATOR_NAME,
|
|
15
15
|
REPEAT_OPERATOR_NAME,
|
|
16
|
+
SINGLE_CALL_INVERT_OPERATOR_NAME,
|
|
16
17
|
SKIP_CONTROL_OPERATOR_NAME,
|
|
17
18
|
WITHIN_APPLY_NAME,
|
|
18
19
|
)
|
|
@@ -23,14 +24,11 @@ from classiq.interface.model.bounds import SetBoundsStatement
|
|
|
23
24
|
from classiq.interface.model.classical_if import ClassicalIf
|
|
24
25
|
from classiq.interface.model.control import Control
|
|
25
26
|
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
|
26
|
-
from classiq.interface.model.invert import Invert
|
|
27
|
+
from classiq.interface.model.invert import BlockKind, Invert
|
|
27
28
|
from classiq.interface.model.model import Model
|
|
28
29
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
29
30
|
from classiq.interface.model.phase_operation import PhaseOperation
|
|
30
31
|
from classiq.interface.model.power import Power
|
|
31
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
32
|
-
AmplitudeLoadingOperation,
|
|
33
|
-
)
|
|
34
32
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
35
33
|
ArithmeticOperation,
|
|
36
34
|
)
|
|
@@ -199,24 +197,6 @@ class GenerativeInterpreter(BaseInterpreter):
|
|
|
199
197
|
bind
|
|
200
198
|
)
|
|
201
199
|
|
|
202
|
-
@emit.register
|
|
203
|
-
def emit_amplitude_loading_operation(self, op: AmplitudeLoadingOperation) -> None:
|
|
204
|
-
CompositeEmitter[AmplitudeLoadingOperation](
|
|
205
|
-
self,
|
|
206
|
-
[
|
|
207
|
-
HandleEvaluator(self, "result_var"),
|
|
208
|
-
ExpressionEvaluator(
|
|
209
|
-
self,
|
|
210
|
-
"expression",
|
|
211
|
-
readable_expression_name="amplitude-encoding expression",
|
|
212
|
-
simplify=True,
|
|
213
|
-
treat_qnum_as_float=True,
|
|
214
|
-
allow_runtime_vars=self._symbolic_parameters_switch,
|
|
215
|
-
),
|
|
216
|
-
AssignmentResultProcessor(self),
|
|
217
|
-
],
|
|
218
|
-
).emit(op)
|
|
219
|
-
|
|
220
200
|
@emit.register
|
|
221
201
|
def _emit_arithmetic_operation(self, op: ArithmeticOperation) -> None:
|
|
222
202
|
self.emit_arithmetic_operation(op)
|
|
@@ -285,7 +265,12 @@ class GenerativeInterpreter(BaseInterpreter):
|
|
|
285
265
|
|
|
286
266
|
@emit.register
|
|
287
267
|
def emit_invert(self, invert: Invert) -> None:
|
|
288
|
-
|
|
268
|
+
match invert.block_kind:
|
|
269
|
+
case BlockKind.SingleCall:
|
|
270
|
+
op_name = SINGLE_CALL_INVERT_OPERATOR_NAME
|
|
271
|
+
case BlockKind.Compound:
|
|
272
|
+
op_name = COMPOUND_INVERT_OPERATOR_NAME
|
|
273
|
+
BlockEvaluator(self, op_name, "body").emit(invert)
|
|
289
274
|
|
|
290
275
|
@emit.register
|
|
291
276
|
def emit_skip_control(self, skip_control: SkipControl) -> None:
|