classiq 0.72.1__py3-none-any.whl → 0.73.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/interface/_version.py +1 -1
- classiq/interface/generator/generated_circuit_data.py +42 -11
- classiq/interface/model/quantum_function_declaration.py +13 -1
- classiq/model_expansions/atomic_expression_functions_defs.py +10 -1
- classiq/model_expansions/capturing/captured_vars.py +21 -15
- classiq/model_expansions/generative_functions.py +31 -54
- classiq/model_expansions/quantum_operations/call_emitter.py +6 -1
- classiq/model_expansions/utils/text_utils.py +16 -0
- classiq/qmod/declaration_inferrer.py +4 -0
- classiq/qmod/quantum_function.py +1 -1
- classiq/qmod/symbolic.py +16 -3
- {classiq-0.72.1.dist-info → classiq-0.73.0.dist-info}/METADATA +1 -1
- {classiq-0.72.1.dist-info → classiq-0.73.0.dist-info}/RECORD +14 -13
- {classiq-0.72.1.dist-info → classiq-0.73.0.dist-info}/WHEEL +0 -0
classiq/interface/_version.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import logging
|
2
2
|
import re
|
3
3
|
from typing import Literal, Optional, Union
|
4
|
+
from uuid import UUID
|
4
5
|
|
5
6
|
import pydantic
|
6
7
|
from pydantic import ConfigDict, Field
|
@@ -16,10 +17,11 @@ from classiq.interface.generator.register_role import RegisterRole
|
|
16
17
|
from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
|
17
18
|
ExecutionData,
|
18
19
|
)
|
19
|
-
from classiq.interface.model.quantum_expressions.
|
20
|
-
|
20
|
+
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
21
|
+
ArithmeticOperationKind,
|
21
22
|
)
|
22
23
|
from classiq.interface.model.statement_block import (
|
24
|
+
ArithmeticOperation,
|
23
25
|
ConcreteQuantumStatement,
|
24
26
|
QuantumFunctionCall,
|
25
27
|
StatementBlock,
|
@@ -141,11 +143,33 @@ class StatementType(StrEnum):
|
|
141
143
|
CONTROL = "control"
|
142
144
|
POWER = "power"
|
143
145
|
INVERT = "invert"
|
144
|
-
WITHIN_APPLY = "
|
145
|
-
|
146
|
+
WITHIN_APPLY = "within apply"
|
147
|
+
ASSIGN = "assign"
|
148
|
+
ASSIGN_AMPLITUDE = "assign amplitude"
|
149
|
+
PHASE = "phase"
|
150
|
+
INPLACE_XOR = "inplace xor"
|
151
|
+
INPLACE_ADD = "inplace add"
|
146
152
|
REPEAT = "repeat"
|
147
153
|
|
148
154
|
|
155
|
+
# Mapping between statement kind (or sub-kind) and statement type (visualization name)
|
156
|
+
# Keys (statement kind) are taken from the `kind` field of the statement models,
|
157
|
+
# which cannot be used directly because they're instance fields of `Literal` type.
|
158
|
+
STATEMENTS_NAME: dict[str, StatementType] = {
|
159
|
+
"Control": StatementType.CONTROL,
|
160
|
+
"Power": StatementType.POWER,
|
161
|
+
"Invert": StatementType.INVERT,
|
162
|
+
"WithinApply": StatementType.WITHIN_APPLY,
|
163
|
+
ArithmeticOperationKind.Assignment.value: StatementType.ASSIGN,
|
164
|
+
"InplaceBinaryOperation": StatementType.ASSIGN,
|
165
|
+
"AmplitudeLoadingOperation": StatementType.ASSIGN_AMPLITUDE,
|
166
|
+
"PhaseOperation": StatementType.PHASE,
|
167
|
+
ArithmeticOperationKind.InplaceXor.value: StatementType.INPLACE_XOR,
|
168
|
+
ArithmeticOperationKind.InplaceAdd.value: StatementType.INPLACE_ADD,
|
169
|
+
"Repeat": StatementType.REPEAT,
|
170
|
+
}
|
171
|
+
|
172
|
+
|
149
173
|
class FunctionDebugInfoInterface(pydantic.BaseModel):
|
150
174
|
generated_function: Optional[GeneratedFunction] = Field(default=None)
|
151
175
|
children: list["FunctionDebugInfoInterface"]
|
@@ -154,6 +178,8 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
|
|
154
178
|
is_basis_gate: Optional[bool] = Field(default=None)
|
155
179
|
is_inverse: bool = Field(default=False)
|
156
180
|
is_allocate_or_free: bool = Field(default=False)
|
181
|
+
is_unitary: bool = Field(default=True, exclude=True)
|
182
|
+
uuid: Optional[UUID] = Field(default=None, exclude=True)
|
157
183
|
level: OperationLevel = Field(default=OperationLevel.UNKNOWN)
|
158
184
|
port_to_passed_variable_map: dict[str, str] = Field(default={})
|
159
185
|
release_by_inverse: bool = Field(default=False)
|
@@ -181,14 +207,23 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
|
|
181
207
|
# Temp fix for currently "supported" statements (same as for level_ property)
|
182
208
|
if generated_name in {StatementType.CONTROL, StatementType.POWER}:
|
183
209
|
return generated_name
|
184
|
-
|
185
|
-
|
210
|
+
|
211
|
+
back_ref = self.first_back_ref
|
212
|
+
if back_ref is None:
|
213
|
+
return generated_name
|
214
|
+
|
215
|
+
if isinstance(back_ref, QuantumFunctionCall):
|
216
|
+
name = generate_original_function_name(back_ref.func_name)
|
186
217
|
if part_match := PART_SUFFIX_REGEX.match(generated_name):
|
187
218
|
suffix = f" [{part_match.group(1)}]"
|
188
219
|
else:
|
189
220
|
suffix = ""
|
190
221
|
return f"{name}{suffix}"
|
191
|
-
|
222
|
+
|
223
|
+
statement_kind: str = back_ref.kind
|
224
|
+
if isinstance(back_ref, ArithmeticOperation):
|
225
|
+
statement_kind = back_ref.operation_kind.value
|
226
|
+
return STATEMENTS_NAME[statement_kind]
|
192
227
|
|
193
228
|
@property
|
194
229
|
def first_back_ref(self) -> Optional[ConcreteQuantumStatement]:
|
@@ -209,10 +244,6 @@ class FunctionDebugInfoInterface(pydantic.BaseModel):
|
|
209
244
|
return self.level
|
210
245
|
if isinstance(back_ref, QuantumFunctionCall):
|
211
246
|
return OperationLevel.QMOD_FUNCTION_CALL
|
212
|
-
# Temp "fix" for assignment statements until we have a way to fully
|
213
|
-
# distinguish them and to properly display them
|
214
|
-
if isinstance(back_ref, QuantumExpressionOperation):
|
215
|
-
return OperationLevel.ENGINE_FUNCTION_CALL
|
216
247
|
return OperationLevel.QMOD_STATEMENT
|
217
248
|
|
218
249
|
@property
|
@@ -158,6 +158,7 @@ class AnonQuantumOperandDeclaration(AnonQuantumFunctionDeclaration):
|
|
158
158
|
description="Indicate whether the operand expects an unnamed list of lambdas",
|
159
159
|
default=False,
|
160
160
|
)
|
161
|
+
_is_generative: bool = pydantic.PrivateAttr(default=False)
|
161
162
|
|
162
163
|
@pydantic.model_validator(mode="before")
|
163
164
|
@classmethod
|
@@ -170,7 +171,10 @@ class AnonQuantumOperandDeclaration(AnonQuantumFunctionDeclaration):
|
|
170
171
|
new_instance_data = self.__dict__.copy()
|
171
172
|
new_instance_data["name"] = new_name
|
172
173
|
new_instance_data["kind"] = "QuantumOperandDeclaration"
|
173
|
-
|
174
|
+
new_decl = QuantumOperandDeclaration(**new_instance_data)
|
175
|
+
if self._is_generative:
|
176
|
+
new_decl.set_generative()
|
177
|
+
return new_decl
|
174
178
|
|
175
179
|
@property
|
176
180
|
def element_declaration(self) -> Self:
|
@@ -178,6 +182,14 @@ class AnonQuantumOperandDeclaration(AnonQuantumFunctionDeclaration):
|
|
178
182
|
raise ClassiqInternalError
|
179
183
|
return self.model_copy(update={"is_list": False})
|
180
184
|
|
185
|
+
def set_generative(self) -> Self:
|
186
|
+
self._is_generative = True
|
187
|
+
return self
|
188
|
+
|
189
|
+
@property
|
190
|
+
def is_generative(self) -> bool:
|
191
|
+
return self._is_generative
|
192
|
+
|
181
193
|
|
182
194
|
AnonQuantumFunctionDeclaration.model_rebuild()
|
183
195
|
|
@@ -15,6 +15,9 @@ from classiq.interface.generator.expressions.expression_types import (
|
|
15
15
|
from classiq.interface.generator.expressions.proxies.classical.any_classical_value import (
|
16
16
|
AnyClassicalValue,
|
17
17
|
)
|
18
|
+
from classiq.interface.generator.expressions.proxies.classical.classical_proxy import (
|
19
|
+
ClassicalProxy,
|
20
|
+
)
|
18
21
|
from classiq.interface.generator.expressions.proxies.quantum.qmod_qscalar_proxy import (
|
19
22
|
QmodQNumProxy,
|
20
23
|
)
|
@@ -159,7 +162,7 @@ def struct_literal(struct_type_symbol: Symbol, **kwargs: Any) -> QmodStructInsta
|
|
159
162
|
|
160
163
|
def get_field(
|
161
164
|
proxy: Union[
|
162
|
-
QmodSizedProxy, QmodStructInstance,
|
165
|
+
QmodSizedProxy, QmodStructInstance, list, ClassicalProxy, AnyClassicalValue
|
163
166
|
],
|
164
167
|
field: str,
|
165
168
|
) -> ExpressionValue:
|
@@ -179,6 +182,12 @@ def get_field(
|
|
179
182
|
f"Available attributes: len"
|
180
183
|
)
|
181
184
|
return len(proxy)
|
185
|
+
if not isinstance(
|
186
|
+
proxy, (QmodSizedProxy, QmodStructInstance, ClassicalProxy, AnyClassicalValue)
|
187
|
+
):
|
188
|
+
raise ClassiqExpansionError(
|
189
|
+
f"Object {str(proxy)!r} has not attribute {field!r}"
|
190
|
+
)
|
182
191
|
if field not in proxy.fields:
|
183
192
|
if isinstance(proxy, (QmodStructInstance, QmodQStructProxy)):
|
184
193
|
property_name = "field"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import dataclasses
|
2
2
|
from collections.abc import Sequence
|
3
3
|
from dataclasses import dataclass, field
|
4
|
-
from typing import TYPE_CHECKING
|
4
|
+
from typing import TYPE_CHECKING, Callable
|
5
5
|
|
6
6
|
from typing_extensions import Self
|
7
7
|
|
@@ -40,6 +40,7 @@ from classiq.model_expansions.transformers.model_renamer import (
|
|
40
40
|
SymbolRenaming,
|
41
41
|
)
|
42
42
|
from classiq.model_expansions.transformers.var_splitter import SymbolPart
|
43
|
+
from classiq.model_expansions.utils.text_utils import are, readable_list, s, they
|
43
44
|
|
44
45
|
if TYPE_CHECKING:
|
45
46
|
from classiq.model_expansions.closure import FunctionClosure
|
@@ -617,7 +618,9 @@ def _same_closure(closure_1: "FunctionClosure", closure_2: "FunctionClosure") ->
|
|
617
618
|
|
618
619
|
|
619
620
|
def validate_args_are_not_propagated(
|
620
|
-
args: Sequence[ArgValue],
|
621
|
+
args: Sequence[ArgValue],
|
622
|
+
captured_vars: Sequence[ArgValue],
|
623
|
+
error_message: Callable[[list[str]], str],
|
621
624
|
) -> None:
|
622
625
|
if not captured_vars:
|
623
626
|
return
|
@@ -629,17 +632,16 @@ def validate_args_are_not_propagated(
|
|
629
632
|
arg_handles = {
|
630
633
|
demangle_handle(arg) for arg in args if isinstance(arg, HandleBinding)
|
631
634
|
}
|
632
|
-
|
633
|
-
arg_handle
|
635
|
+
violating_handles = [
|
636
|
+
f"{str(arg_handle)!r}"
|
634
637
|
for arg_handle in arg_handles
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
638
|
+
if any(
|
639
|
+
arg_handle.overlaps(captured_handle) for captured_handle in captured_handles
|
640
|
+
)
|
641
|
+
]
|
642
|
+
if len(violating_handles) > 0:
|
640
643
|
raise ClassiqExpansionError(
|
641
|
-
f"
|
642
|
-
f"{vars_msg}"
|
644
|
+
f"Quantum cloning violation: {error_message(violating_handles)}"
|
643
645
|
)
|
644
646
|
|
645
647
|
|
@@ -647,12 +649,12 @@ def validate_captured_directions(
|
|
647
649
|
captured_vars: CapturedVars, report_outin: bool = True
|
648
650
|
) -> None:
|
649
651
|
captured_inputs = [
|
650
|
-
captured_handle.handle.name
|
652
|
+
f"{captured_handle.handle.name!r}"
|
651
653
|
for captured_handle in captured_vars._captured_handles
|
652
654
|
if captured_handle.direction == PortDirection.Input
|
653
655
|
]
|
654
656
|
captured_outputs = [
|
655
|
-
captured_handle.handle.name
|
657
|
+
f"{captured_handle.handle.name!r}"
|
656
658
|
for captured_handle in captured_vars._captured_handles
|
657
659
|
if captured_handle.direction
|
658
660
|
in (
|
@@ -663,11 +665,15 @@ def validate_captured_directions(
|
|
663
665
|
]
|
664
666
|
if len(captured_inputs) > 0:
|
665
667
|
raise ClassiqExpansionError(
|
666
|
-
f"
|
668
|
+
f"Variable{s(captured_inputs)} {readable_list(captured_inputs)} "
|
669
|
+
f"{are(captured_inputs)} defined in an outer block, so "
|
670
|
+
f"{they(captured_inputs)} cannot be freed here"
|
667
671
|
)
|
668
672
|
if len(captured_outputs) > 0:
|
669
673
|
raise ClassiqExpansionError(
|
670
|
-
f"
|
674
|
+
f"Variable{s(captured_outputs)} {readable_list(captured_outputs)} "
|
675
|
+
f"{are(captured_outputs)} defined in an outer block, so "
|
676
|
+
f"{they(captured_outputs)} cannot be initialized here"
|
671
677
|
)
|
672
678
|
|
673
679
|
|
@@ -16,6 +16,7 @@ from classiq.interface.generator.expressions.proxies.classical.utils import (
|
|
16
16
|
get_proxy_type,
|
17
17
|
)
|
18
18
|
from classiq.interface.generator.functions.type_name import Struct
|
19
|
+
from classiq.interface.helpers.datastructures import get_sdk_compatible_python_object
|
19
20
|
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
20
21
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
21
22
|
from classiq.interface.model.port_declaration import PortDeclaration
|
@@ -34,13 +35,12 @@ from classiq.model_expansions.scope import Evaluated, QuantumSymbol
|
|
34
35
|
from classiq.qmod.generative import generative_mode_context, set_frontend_interpreter
|
35
36
|
from classiq.qmod.model_state_container import QMODULE
|
36
37
|
from classiq.qmod.qmod_parameter import CParamStruct, create_param
|
37
|
-
from classiq.qmod.qmod_variable import
|
38
|
+
from classiq.qmod.qmod_variable import _create_qvar_for_qtype
|
38
39
|
from classiq.qmod.quantum_expandable import (
|
39
40
|
QTerminalCallable,
|
40
41
|
)
|
41
42
|
from classiq.qmod.quantum_function import QFunc
|
42
43
|
from classiq.qmod.semantics.annotation.call_annotation import resolve_function_calls
|
43
|
-
from classiq.qmod.symbolic_expr import SymbolicExpr
|
44
44
|
|
45
45
|
if TYPE_CHECKING:
|
46
46
|
from classiq.model_expansions.interpreters.generative_interpreter import (
|
@@ -65,26 +65,6 @@ def _unwrap_traceback_frame(e: Exception) -> Exception:
|
|
65
65
|
return e.with_traceback(back_tb)
|
66
66
|
|
67
67
|
|
68
|
-
class LenList(list):
|
69
|
-
@property
|
70
|
-
def len(self) -> int:
|
71
|
-
return len(self)
|
72
|
-
|
73
|
-
def __getitem__(self, item: Any) -> Any:
|
74
|
-
if isinstance(item, QNum):
|
75
|
-
return SymbolicExpr(f"{self}[{item}]", True)
|
76
|
-
try:
|
77
|
-
return super().__getitem__(item)
|
78
|
-
except (IndexError, TypeError) as e:
|
79
|
-
raise _unwrap_traceback_frame(e) from None
|
80
|
-
|
81
|
-
@classmethod
|
82
|
-
def wrap(cls, obj: Any) -> Any:
|
83
|
-
if not isinstance(obj, list):
|
84
|
-
return obj
|
85
|
-
return LenList([cls.wrap(item) for item in obj])
|
86
|
-
|
87
|
-
|
88
68
|
def translate_ast_arg_to_python_qmod(param: PositionalArg, evaluated: Evaluated) -> Any:
|
89
69
|
if isinstance(param, PortDeclaration):
|
90
70
|
quantum_symbol = evaluated.as_type(QuantumSymbol)
|
@@ -92,28 +72,13 @@ def translate_ast_arg_to_python_qmod(param: PositionalArg, evaluated: Evaluated)
|
|
92
72
|
quantum_symbol.quantum_type, quantum_symbol.handle
|
93
73
|
)
|
94
74
|
if isinstance(param, QuantumOperandDeclaration):
|
95
|
-
if param.is_list:
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
positional_arg_declarations=param.positional_arg_declarations,
|
103
|
-
),
|
104
|
-
index_=idx,
|
105
|
-
)
|
106
|
-
for idx in range(len(func_list))
|
107
|
-
]
|
108
|
-
)
|
109
|
-
else:
|
110
|
-
func = evaluated.as_type(FunctionClosure)
|
111
|
-
return QTerminalCallable(
|
112
|
-
QuantumFunctionDeclaration(
|
113
|
-
name=param.name if func.is_lambda else func.name,
|
114
|
-
positional_arg_declarations=func.positional_arg_declarations,
|
115
|
-
),
|
116
|
-
)
|
75
|
+
if not param.is_list or not param.is_generative:
|
76
|
+
return QTerminalCallable(param)
|
77
|
+
inner_decl = param.model_copy(update={"is_list": False})
|
78
|
+
func_list: list[FunctionClosure] = evaluated.as_type(list)
|
79
|
+
return [
|
80
|
+
QTerminalCallable(inner_decl, index_=idx) for idx in range(len(func_list))
|
81
|
+
]
|
117
82
|
classical_value = evaluated.value
|
118
83
|
if isinstance(classical_value, QmodStructInstance):
|
119
84
|
return CParamStruct(
|
@@ -126,7 +91,7 @@ def translate_ast_arg_to_python_qmod(param: PositionalArg, evaluated: Evaluated)
|
|
126
91
|
str(classical_value.handle), get_proxy_type(classical_value), QMODULE
|
127
92
|
)
|
128
93
|
|
129
|
-
return
|
94
|
+
return get_sdk_compatible_python_object(classical_value)
|
130
95
|
|
131
96
|
|
132
97
|
class _InterpreterExpandable(QFunc):
|
@@ -161,15 +126,27 @@ class _InterpreterExpandable(QFunc):
|
|
161
126
|
self._interpreter.emit_statement(stmt)
|
162
127
|
|
163
128
|
def _get_function_declarations(self) -> Mapping[str, QuantumFunctionDeclaration]:
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
129
|
+
scope_func_decls: dict[str, QuantumFunctionDeclaration] = {}
|
130
|
+
for name, evaluated in self._interpreter._builder.current_scope.items():
|
131
|
+
value = evaluated.value
|
132
|
+
if isinstance(value, FunctionClosure):
|
133
|
+
scope_func_decls[name] = QuantumFunctionDeclaration(
|
134
|
+
name=name,
|
135
|
+
positional_arg_declarations=value.positional_arg_declarations,
|
136
|
+
)
|
137
|
+
elif (
|
138
|
+
isinstance(value, list)
|
139
|
+
and len(value) > 0
|
140
|
+
and isinstance(value[0], FunctionClosure)
|
141
|
+
):
|
142
|
+
scope_func_decls[name] = QuantumFunctionDeclaration(
|
143
|
+
name=name,
|
144
|
+
positional_arg_declarations=value[0].positional_arg_declarations,
|
145
|
+
)
|
146
|
+
return (
|
147
|
+
nameables_to_dict(self._interpreter._get_function_declarations())
|
148
|
+
| scope_func_decls
|
149
|
+
)
|
173
150
|
|
174
151
|
|
175
152
|
def emit_generative_statements(
|
@@ -62,6 +62,7 @@ from classiq.model_expansions.quantum_operations.emitter import (
|
|
62
62
|
)
|
63
63
|
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
64
64
|
from classiq.model_expansions.transformers.var_splitter import VarSplitter
|
65
|
+
from classiq.model_expansions.utils.text_utils import are, readable_list, s
|
65
66
|
from classiq.qmod.builtins.functions import free
|
66
67
|
from classiq.qmod.semantics.validation.signature_validation import (
|
67
68
|
validate_function_signature,
|
@@ -176,7 +177,11 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
|
|
176
177
|
captured_args = function.captured_vars.filter_vars(function).get_captured_args(
|
177
178
|
self._builder.current_function
|
178
179
|
)
|
179
|
-
validate_args_are_not_propagated(
|
180
|
+
validate_args_are_not_propagated(
|
181
|
+
new_positional_args,
|
182
|
+
captured_args,
|
183
|
+
lambda vars: f"Argument{s(vars)} {readable_list(vars)} {are(vars)} used in adjacent lambda functions",
|
184
|
+
)
|
180
185
|
new_positional_args.extend(captured_args)
|
181
186
|
new_call = QuantumFunctionCall(
|
182
187
|
function=new_declaration.name,
|
@@ -0,0 +1,16 @@
|
|
1
|
+
def s(items: list) -> str:
|
2
|
+
return "" if len(items) == 1 else "s"
|
3
|
+
|
4
|
+
|
5
|
+
def are(items: list) -> str:
|
6
|
+
return "is" if len(items) == 1 else "are"
|
7
|
+
|
8
|
+
|
9
|
+
def they(items: list) -> str:
|
10
|
+
return "it" if len(items) == 1 else "they"
|
11
|
+
|
12
|
+
|
13
|
+
def readable_list(items: list) -> str:
|
14
|
+
if len(items) == 1:
|
15
|
+
return str(items[0])
|
16
|
+
return f"{', '.join(items[:-1])} and {items[-1]}"
|
@@ -102,8 +102,10 @@ def _extract_operand_decl(
|
|
102
102
|
name: Optional[str], py_type: Any, qmodule: Optional[ModelStateContainer]
|
103
103
|
) -> AnonQuantumOperandDeclaration:
|
104
104
|
is_list = (get_origin(py_type) or py_type) is QCallableList
|
105
|
+
is_generative = False
|
105
106
|
if get_origin(py_type) is list:
|
106
107
|
is_list = True
|
108
|
+
is_generative = True
|
107
109
|
py_type = version_portable_get_args(py_type)[0]
|
108
110
|
type_args = version_portable_get_args(py_type)
|
109
111
|
if len(type_args) > 0 and isinstance(type_args[0], list): # Callable support
|
@@ -116,6 +118,8 @@ def _extract_operand_decl(
|
|
116
118
|
),
|
117
119
|
is_list=is_list,
|
118
120
|
)
|
121
|
+
if is_generative:
|
122
|
+
param = param.set_generative()
|
119
123
|
if name is not None:
|
120
124
|
param = param.rename(name)
|
121
125
|
return param
|
classiq/qmod/quantum_function.py
CHANGED
@@ -42,6 +42,7 @@ class BaseQFunc(QExpandable):
|
|
42
42
|
compilation_metadata: Optional[CompilationMetadata] = None,
|
43
43
|
) -> None:
|
44
44
|
super().__init__(py_callable)
|
45
|
+
functools.update_wrapper(self, py_callable)
|
45
46
|
self.compilation_metadata = compilation_metadata
|
46
47
|
|
47
48
|
@property
|
@@ -87,7 +88,6 @@ class QFunc(BaseQFunc):
|
|
87
88
|
) -> None:
|
88
89
|
_validate_no_gen_params(py_callable.__annotations__)
|
89
90
|
super().__init__(py_callable, compilation_metadata)
|
90
|
-
functools.update_wrapper(self, py_callable)
|
91
91
|
self.compilation_metadata: Optional[CompilationMetadata] = None
|
92
92
|
|
93
93
|
@property
|
classiq/qmod/symbolic.py
CHANGED
@@ -9,6 +9,8 @@ from typing import (
|
|
9
9
|
overload,
|
10
10
|
)
|
11
11
|
|
12
|
+
import numpy as np
|
13
|
+
|
12
14
|
from classiq.interface.exceptions import ClassiqValueError
|
13
15
|
|
14
16
|
from classiq.qmod import model_state_container
|
@@ -30,6 +32,15 @@ GoldenRatio = SymbolicExpr("GoldenRatio", False)
|
|
30
32
|
EulerGamma = SymbolicExpr("EulerGamma", False)
|
31
33
|
Catalan = SymbolicExpr("Catalan", False)
|
32
34
|
|
35
|
+
|
36
|
+
def _unwrap_numpy(x: Any) -> Any:
|
37
|
+
if isinstance(x, np.ndarray):
|
38
|
+
return x.tolist()
|
39
|
+
if isinstance(x, list):
|
40
|
+
return list(map(_unwrap_numpy, x))
|
41
|
+
return x
|
42
|
+
|
43
|
+
|
33
44
|
T = TypeVar("T", bound=CParam)
|
34
45
|
|
35
46
|
|
@@ -45,7 +56,7 @@ def symbolic_function(*args: Any, return_type: Optional[type[T]] = None) -> CPar
|
|
45
56
|
qmodule = (
|
46
57
|
model_state_container.QMODULE
|
47
58
|
) # FIXME: https://classiq.atlassian.net/browse/CAD-15126
|
48
|
-
str_args = [str(x) for x in args]
|
59
|
+
str_args = [str(_unwrap_numpy(x)) for x in args]
|
49
60
|
expr = f"{sys._getframe(1).f_code.co_name}({','.join(str_args)})"
|
50
61
|
|
51
62
|
if return_type is None:
|
@@ -310,10 +321,12 @@ def _subscript_to_str(index: Any) -> str:
|
|
310
321
|
|
311
322
|
|
312
323
|
def subscript(
|
313
|
-
|
324
|
+
array: Union[
|
325
|
+
Sequence[Union[float, CReal, CParamScalar]], CArray[CReal], np.ndarray
|
326
|
+
],
|
314
327
|
index: Any,
|
315
328
|
) -> CParamScalar:
|
316
|
-
return CParamScalar(expr=f"{
|
329
|
+
return CParamScalar(expr=f"{_unwrap_numpy(array)}[{_subscript_to_str(index)}]")
|
317
330
|
|
318
331
|
|
319
332
|
__all__ = [
|
@@ -89,7 +89,7 @@ classiq/execution/jobs.py,sha256=h_aki-Q7RDbG7fyMYdc-kTRNgtq1gX9W5LDub_7J2UM,108
|
|
89
89
|
classiq/execution/qnn.py,sha256=WGPvncz5uS2WxSY3-yBWt2LFiCk6Ug8WKWF-Kp-f7TM,2403
|
90
90
|
classiq/executor.py,sha256=9mae_QMGZYT8CJ5QlS4XH7063OYrrDUnt8gAFV-OhRc,2773
|
91
91
|
classiq/interface/__init__.py,sha256=cg7hD_XVu1_jJ1fgwmT0rMIoZHopNVeB8xtlmMx-E_A,83
|
92
|
-
classiq/interface/_version.py,sha256=
|
92
|
+
classiq/interface/_version.py,sha256=Lc9aqZPOiBQdlmuqFuanaz8FdcjwfMpBSvc-WsDGjkM,197
|
93
93
|
classiq/interface/analyzer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
94
94
|
classiq/interface/analyzer/analysis_params.py,sha256=dM5rwSks798cxk4FWe4_X5ToRYtgZQh34F1u0XrFkK8,3881
|
95
95
|
classiq/interface/analyzer/cytoscape_graph.py,sha256=MpeRBIYS1TfwYwiFpgTO51IE0KoxhY510pmEM3S0rbw,2361
|
@@ -254,7 +254,7 @@ classiq/interface/generator/functions/port_declaration.py,sha256=ESJE_19jOg_zS1r
|
|
254
254
|
classiq/interface/generator/functions/qmod_python_interface.py,sha256=x8GA4Cr6YyfC6prGXv0A0I9G9GSnLHNito2nfN1GZDI,93
|
255
255
|
classiq/interface/generator/functions/type_name.py,sha256=2HiPejk-WZJy8PkWyYXcpuhGgecVZCUf9mpPWFuYty8,4443
|
256
256
|
classiq/interface/generator/functions/type_qualifier.py,sha256=PGiNm_3bczA3TB7ulSemry8zXDB5s4HUIuxdFaVdU_Y,145
|
257
|
-
classiq/interface/generator/generated_circuit_data.py,sha256=
|
257
|
+
classiq/interface/generator/generated_circuit_data.py,sha256=S3V2KwGeEG-JaQW0ySUxEDKXEgidfHbeh9WuXZrJFFU,13792
|
258
258
|
classiq/interface/generator/grover_diffuser.py,sha256=c52p2_hpjBO0qUDsqFMQ_xffBIDPJlrfz3kIy2Mh2Gk,3750
|
259
259
|
classiq/interface/generator/grover_operator.py,sha256=_VzBJ3qO0O0MJzsHf8LF7_ooXnsz1p_I5rjQQFf1Ptg,4119
|
260
260
|
classiq/interface/generator/hadamard_transform.py,sha256=NI4oZBpDCGfaw2OTb5SL3iSGI_nDtyUgElTCO4pEKnk,673
|
@@ -377,7 +377,7 @@ classiq/interface/model/quantum_expressions/amplitude_loading_operation.py,sha25
|
|
377
377
|
classiq/interface/model/quantum_expressions/arithmetic_operation.py,sha256=kqABvyr-niat293lHqBmPhV0Ks3WUgHJ3mevmyD1zD8,2732
|
378
378
|
classiq/interface/model/quantum_expressions/quantum_expression.py,sha256=hSWdSJmsEYaZZ62dWI8ueIl_-lqn7FBnwadsqozzZOI,2228
|
379
379
|
classiq/interface/model/quantum_function_call.py,sha256=fKDQwYBg8v_WvDsl9QDAA-RBVsW4GOn-zOnpqlhamPg,7384
|
380
|
-
classiq/interface/model/quantum_function_declaration.py,sha256=
|
380
|
+
classiq/interface/model/quantum_function_declaration.py,sha256=Er0RfxfpcVO5-ufMkBqSFxKz0BHtu7zCMKnTWOwU_ZM,8675
|
381
381
|
classiq/interface/model/quantum_lambda_function.py,sha256=cATqykbArV6c9qmSNtqRgDQjjvCfRvYeC3-S5gJW-wg,1930
|
382
382
|
classiq/interface/model/quantum_statement.py,sha256=XthtcTISbdRIv4NW-fckV4jB-dkvYotAZnphMIiK-Ww,3359
|
383
383
|
classiq/interface/model/quantum_type.py,sha256=KcwykkbjctiQsMc7XaM3EugKYNE2wVmyPYcclH8K3Lc,10311
|
@@ -397,9 +397,9 @@ classiq/interface/server/global_versions.py,sha256=EyUtBCoGHjgS4jybiHI8wOZq3WOqv
|
|
397
397
|
classiq/interface/server/routes.py,sha256=9UKBb5c_DWzqM1QBzU1v2I_W0Y__6NnYfjqRFa1FI3g,3400
|
398
398
|
classiq/interface/source_reference.py,sha256=a-4Vdc511ux-0lDPDTRGAzouRWWtu4A3MPAfiZe_YPE,1764
|
399
399
|
classiq/model_expansions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
400
|
-
classiq/model_expansions/atomic_expression_functions_defs.py,sha256=
|
400
|
+
classiq/model_expansions/atomic_expression_functions_defs.py,sha256=68iOZfdN_WHPbrdChoMgdElokBqp97mLscMNwmUE82U,9841
|
401
401
|
classiq/model_expansions/capturing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
402
|
-
classiq/model_expansions/capturing/captured_vars.py,sha256=
|
402
|
+
classiq/model_expansions/capturing/captured_vars.py,sha256=KWgLGqt3aE_8Z7EjWsT1huNzSDYW3sBPt0Un902iiZM,26268
|
403
403
|
classiq/model_expansions/capturing/mangling_utils.py,sha256=wfCsjP0pScZv9YP6JXq3oVhkS-lCFyUoZ9IROBHS3Ek,1858
|
404
404
|
classiq/model_expansions/closure.py,sha256=vCNdYyn_pzoyNGIs4w-ZEm_Vj9925mfu64TDnTdHkys,4975
|
405
405
|
classiq/model_expansions/debug_flag.py,sha256=JWzl9FFq2CLcvTg_sh-K8Dp_xXvewsTuFKhPjTCrsrs,107
|
@@ -414,7 +414,7 @@ classiq/model_expansions/evaluators/quantum_type_utils.py,sha256=s2kqPenO3qaJsiV
|
|
414
414
|
classiq/model_expansions/evaluators/type_type_match.py,sha256=3akZR86TAFKUyM5c5knCPSlraI3LQeWZXxXMTtmu0BI,3220
|
415
415
|
classiq/model_expansions/expression_evaluator.py,sha256=Yn_bzK-qtO99XPC3GgbRyn3bMGHy1WoqxYovVjUEOgk,4780
|
416
416
|
classiq/model_expansions/function_builder.py,sha256=oVmXhyEu6wr8Ru8LSxIqxwn9gdDoQ26SAPlNnYWCGMI,8697
|
417
|
-
classiq/model_expansions/generative_functions.py,sha256=
|
417
|
+
classiq/model_expansions/generative_functions.py,sha256=pBOE9gBXDK8CDRwJdTHFOJo0nvBiCMYqUmWyrvYebJY,6714
|
418
418
|
classiq/model_expansions/interpreters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
419
419
|
classiq/model_expansions/interpreters/base_interpreter.py,sha256=tvs7Q0LEfzZEUOhcn0gcYXf8obeGbFgyDO7BeN-OxUs,11411
|
420
420
|
classiq/model_expansions/interpreters/frontend_generative_interpreter.py,sha256=db1BKh-MDWqLTK8WCXpbNYxxQM4mjqWIhwFtDil7Vd0,3768
|
@@ -427,7 +427,7 @@ classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressi
|
|
427
427
|
classiq/model_expansions/quantum_operations/assignment_result_processor.py,sha256=OtiqKU6-KxrMBNigSyX4jqohUPzg9qOFa2I-d0DZDK0,2671
|
428
428
|
classiq/model_expansions/quantum_operations/bind.py,sha256=KCX_J94-m3taogRGQN7d9sphJyM0XTYaGW_ssBlwIe4,4557
|
429
429
|
classiq/model_expansions/quantum_operations/block_evaluator.py,sha256=bESmqOLibwosu4KUh7UdAluwX3ICwO2hbLB7l4x2GYo,3083
|
430
|
-
classiq/model_expansions/quantum_operations/call_emitter.py,sha256=
|
430
|
+
classiq/model_expansions/quantum_operations/call_emitter.py,sha256=ZCWbQ8mRyzazzv2orCdX0DwuLX9jtQHM4GiEUMWw93A,14842
|
431
431
|
classiq/model_expansions/quantum_operations/composite_emitter.py,sha256=B09YGldhWcqdNiyhNzQQU-85mJ_9cRrtNgruDvuyEUE,824
|
432
432
|
classiq/model_expansions/quantum_operations/declarative_call_emitter.py,sha256=BlcjV0AG05qpKyWFD2-GJQKqTDWcFfRl7y1z3yIpllc,3209
|
433
433
|
classiq/model_expansions/quantum_operations/emitter.py,sha256=jArt-eMikrGbR9fOzY9mP1Vc11Zmkn1UkGcHQWy5sIQ,9700
|
@@ -450,6 +450,7 @@ classiq/model_expansions/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
|
|
450
450
|
classiq/model_expansions/utils/counted_name_allocator.py,sha256=9LPLBm-4ZrpC_0r1rbogyF11FnLaGCUyzwWpcBJoSmA,297
|
451
451
|
classiq/model_expansions/utils/handles_collector.py,sha256=4RfPsiKjVZkTq2tuS-nvo5OG5gGT_HEALf52SuzJ4Dg,1164
|
452
452
|
classiq/model_expansions/utils/sympy_utils.py,sha256=nfmAj2r5NawLlANA5M2IkN3PmQoxNAYYPdaxz79uoEE,682
|
453
|
+
classiq/model_expansions/utils/text_utils.py,sha256=rVYVPHLmnmEhsDXwn-90AEaznDyuYRf1kBhD0TMHuls,373
|
453
454
|
classiq/model_expansions/visitors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
454
455
|
classiq/model_expansions/visitors/boolean_expression_transformers.py,sha256=a8ITXY48uROZFd9MF8tXdXs14Uxh8XbBpuvRXvRehjY,8067
|
455
456
|
classiq/model_expansions/visitors/variable_references.py,sha256=HBgzONJujH8hbtRoqBkT8kBGgE2wDErtfAF_BJXcZC8,5299
|
@@ -495,7 +496,7 @@ classiq/qmod/cfunc.py,sha256=e3zWNEloBBPy-wJaGI1K5cdNFbd3oq0o4TUY2YDr6ks,1087
|
|
495
496
|
classiq/qmod/classical_function.py,sha256=iHm6T719PUZQPwuNSkouaMA8J9yHrrHUpP-2AQjsA5g,1088
|
496
497
|
classiq/qmod/cparam.py,sha256=WqWG_XLYU4SVYDHHXsZNFu0QcE4dfaEM-0C_Q1OOFs0,2007
|
497
498
|
classiq/qmod/create_model_function.py,sha256=JhPFmI-_K4Yv-RFcKwWLLhFMpcs35K651ItojXwHolk,2245
|
498
|
-
classiq/qmod/declaration_inferrer.py,sha256=
|
499
|
+
classiq/qmod/declaration_inferrer.py,sha256=mcqUrrMfolphtNeCn7B0uT4TVAYdx481v6jebmmiRcc,7749
|
499
500
|
classiq/qmod/expression_query.py,sha256=24gsE5hJ1o9ZuqPILH7aaoOzKRQY2RZtvIK35xuubGA,1629
|
500
501
|
classiq/qmod/generative.py,sha256=MSy-LUsmxteVm3sQSTSWPiYgAskBfYcRHm5EJCYBVZo,1255
|
501
502
|
classiq/qmod/model_state_container.py,sha256=yTaowwd468oEntRQAOAhFFgM3cznR9c6ijqrm6U1SBg,1349
|
@@ -512,7 +513,7 @@ classiq/qmod/qmod_parameter.py,sha256=3WYO11-F8dmbZKqTokmKxzehLdb-aEPYwyiDcAFbbQ
|
|
512
513
|
classiq/qmod/qmod_variable.py,sha256=_Wbg7FyrpBYSLnySJhHt96hWkH0EOwDaHoQJhq1x2ow,24806
|
513
514
|
classiq/qmod/quantum_callable.py,sha256=RifbkZEmZ4COOHfluPD2jfd-qYSda2ytW173diR3tI4,2501
|
514
515
|
classiq/qmod/quantum_expandable.py,sha256=3GjFdIP7rDv5SMG9scE3_niu04tWELS6u7it2zpRZUg,17640
|
515
|
-
classiq/qmod/quantum_function.py,sha256=
|
516
|
+
classiq/qmod/quantum_function.py,sha256=a43xlDi3Lb1qVl4xTVXcJfVgPuwDIzAcN-UwpmxzI_c,12819
|
516
517
|
classiq/qmod/semantics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
517
518
|
classiq/qmod/semantics/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
518
519
|
classiq/qmod/semantics/annotation/call_annotation.py,sha256=I94YDffDP-PDx3-r8XRFtg7D8B07OyuwnWOGwJVOOOA,3804
|
@@ -529,13 +530,13 @@ classiq/qmod/semantics/validation/model_validation.py,sha256=BMeleBpQ7WkEi2LNh4j
|
|
529
530
|
classiq/qmod/semantics/validation/signature_validation.py,sha256=WZerCfEwgbCPmXD34iHhXGVATMhJ86sg-dfdOHFZNGg,922
|
530
531
|
classiq/qmod/semantics/validation/type_hints.py,sha256=xXhneZhzxXYq40LvZPc4jqNabQGxItKraN91-GWkCDU,1354
|
531
532
|
classiq/qmod/semantics/validation/types_validation.py,sha256=uVyW1WlDvUQU7emzHT75QTS0huIlFZr9DgUXLQ7s7vQ,4856
|
532
|
-
classiq/qmod/symbolic.py,sha256=
|
533
|
+
classiq/qmod/symbolic.py,sha256=z5aMUf66pSobTozJif6STWDRJ4YlZv1bxHubbJqecAQ,8209
|
533
534
|
classiq/qmod/symbolic_expr.py,sha256=LJoa9c6puMvUu4d5oU0SNzc7VXzSFBUNLf19ADzktLs,6133
|
534
535
|
classiq/qmod/symbolic_type.py,sha256=ded7bVfWmHFw8MoyivVDJsG5vZZVRQontOZYb1kCrTQ,162
|
535
536
|
classiq/qmod/type_attribute_remover.py,sha256=NZmTXAsngWqthXjE8n-n6yE72fiWTFM12-TXXJ1kJ-Q,1242
|
536
537
|
classiq/qmod/utilities.py,sha256=XoB9JU6Vn4p8ZirrUUaP-UpOInm3jwuuYjB6R_V3XLo,5467
|
537
538
|
classiq/qmod/write_qmod.py,sha256=Q3TWQU9p_Uy42STmX5GA_4Ts2TTOgYjt7I8LTRxTbb0,2047
|
538
539
|
classiq/synthesis.py,sha256=_1W-_shxXEmlhNFKuYz3npiv6P3pWonVn55B0qKRYSo,9052
|
539
|
-
classiq-0.
|
540
|
-
classiq-0.
|
541
|
-
classiq-0.
|
540
|
+
classiq-0.73.0.dist-info/METADATA,sha256=3oGZ8EY-94dU4TXW1ZYTssEdTew52vp91GEB1YMLoTo,3338
|
541
|
+
classiq-0.73.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
542
|
+
classiq-0.73.0.dist-info/RECORD,,
|
File without changes
|