classiq 0.83.0__py3-none-any.whl → 0.84.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/_internals/api_wrapper.py +27 -0
- classiq/applications/chemistry/chemistry_model_constructor.py +0 -2
- classiq/applications/chemistry/hartree_fock.py +68 -0
- classiq/applications/chemistry/mapping.py +85 -0
- classiq/applications/chemistry/op_utils.py +79 -0
- classiq/applications/chemistry/problems.py +195 -0
- classiq/applications/chemistry/ucc.py +109 -0
- classiq/applications/chemistry/z2_symmetries.py +368 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +30 -1
- classiq/{model_expansions/evaluators → evaluators}/arg_type_match.py +12 -4
- classiq/{model_expansions/evaluators → evaluators}/argument_types.py +1 -1
- classiq/{model_expansions/evaluators → evaluators}/classical_expression.py +1 -1
- classiq/{model_expansions/evaluators → evaluators}/classical_type_inference.py +3 -4
- classiq/{model_expansions/evaluators → evaluators}/parameter_types.py +17 -15
- classiq/execution/__init__.py +12 -1
- classiq/execution/execution_session.py +189 -43
- classiq/execution/jobs.py +26 -1
- classiq/execution/qnn.py +2 -2
- classiq/execution/user_budgets.py +39 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/constants.py +1 -0
- classiq/interface/execution/primitives.py +29 -1
- classiq/interface/executor/estimate_cost.py +35 -0
- classiq/interface/executor/execution_result.py +13 -0
- classiq/interface/executor/result.py +116 -1
- classiq/interface/executor/user_budget.py +26 -33
- classiq/interface/generator/expressions/atomic_expression_functions.py +5 -1
- classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +0 -6
- classiq/interface/generator/functions/classical_type.py +2 -35
- classiq/interface/generator/functions/concrete_types.py +0 -3
- classiq/interface/generator/functions/type_modifier.py +0 -19
- classiq/interface/generator/generated_circuit_data.py +0 -8
- classiq/interface/generator/types/compilation_metadata.py +0 -3
- classiq/interface/ide/visual_model.py +6 -2
- classiq/interface/model/model.py +12 -7
- classiq/interface/model/port_declaration.py +2 -24
- classiq/interface/pretty_print/__init__.py +0 -0
- classiq/{qmod/native → interface/pretty_print}/expression_to_qmod.py +18 -11
- classiq/interface/server/routes.py +4 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +42 -5
- classiq/model_expansions/interpreters/base_interpreter.py +3 -3
- classiq/model_expansions/quantum_operations/allocate.py +1 -1
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +1 -1
- classiq/model_expansions/quantum_operations/bind.py +2 -2
- classiq/model_expansions/quantum_operations/call_emitter.py +26 -20
- classiq/model_expansions/quantum_operations/variable_decleration.py +1 -1
- classiq/model_expansions/scope_initialization.py +3 -3
- classiq/model_expansions/transformers/model_renamer.py +6 -4
- classiq/model_expansions/transformers/type_modifier_inference.py +81 -43
- classiq/model_expansions/visitors/symbolic_param_inference.py +2 -3
- classiq/open_library/functions/__init__.py +3 -0
- classiq/open_library/functions/amplitude_amplification.py +10 -18
- classiq/open_library/functions/discrete_sine_cosine_transform.py +5 -5
- classiq/open_library/functions/grover.py +14 -6
- classiq/open_library/functions/modular_exponentiation.py +22 -20
- classiq/open_library/functions/state_preparation.py +17 -0
- classiq/qmod/builtins/enums.py +23 -0
- classiq/qmod/builtins/functions/__init__.py +2 -0
- classiq/qmod/builtins/functions/exponentiation.py +32 -4
- classiq/qmod/builtins/structs.py +55 -3
- classiq/qmod/declaration_inferrer.py +3 -2
- classiq/qmod/native/pretty_printer.py +2 -6
- classiq/qmod/pretty_print/expression_to_python.py +2 -1
- classiq/qmod/pretty_print/pretty_printer.py +1 -6
- classiq/qmod/python_classical_type.py +12 -5
- classiq/qmod/qmod_constant.py +2 -5
- classiq/qmod/qmod_parameter.py +2 -5
- classiq/qmod/qmod_variable.py +56 -15
- classiq/qmod/quantum_expandable.py +4 -2
- classiq/qmod/quantum_function.py +7 -2
- classiq/qmod/semantics/annotation/qstruct_annotator.py +1 -1
- classiq/qmod/semantics/validation/main_validation.py +1 -9
- classiq/qmod/utilities.py +0 -2
- classiq/qmod/write_qmod.py +1 -1
- {classiq-0.83.0.dist-info → classiq-0.84.0.dist-info}/METADATA +4 -1
- {classiq-0.83.0.dist-info → classiq-0.84.0.dist-info}/RECORD +82 -73
- /classiq/{model_expansions/evaluators → evaluators}/__init__.py +0 -0
- /classiq/{model_expansions/evaluators → evaluators}/control.py +0 -0
- /classiq/{model_expansions → evaluators}/expression_evaluator.py +0 -0
- /classiq/{model_expansions/evaluators → evaluators}/quantum_type_utils.py +0 -0
- /classiq/{model_expansions/evaluators → evaluators}/type_type_match.py +0 -0
- {classiq-0.83.0.dist-info → classiq-0.84.0.dist-info}/WHEEL +0 -0
@@ -50,19 +50,19 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
50
50
|
VariableDeclarationStatement,
|
51
51
|
)
|
52
52
|
|
53
|
+
from classiq.evaluators.argument_types import (
|
54
|
+
add_information_from_output_arguments,
|
55
|
+
handle_args_numeric_bounds,
|
56
|
+
)
|
57
|
+
from classiq.evaluators.parameter_types import (
|
58
|
+
evaluate_parameter_types_from_args,
|
59
|
+
)
|
53
60
|
from classiq.model_expansions.capturing.captured_vars import (
|
54
61
|
INITIALIZED_VAR_MESSAGE,
|
55
62
|
UNINITIALIZED_VAR_MESSAGE,
|
56
63
|
validate_args_are_not_propagated,
|
57
64
|
)
|
58
65
|
from classiq.model_expansions.closure import Closure, FunctionClosure
|
59
|
-
from classiq.model_expansions.evaluators.argument_types import (
|
60
|
-
add_information_from_output_arguments,
|
61
|
-
handle_args_numeric_bounds,
|
62
|
-
)
|
63
|
-
from classiq.model_expansions.evaluators.parameter_types import (
|
64
|
-
evaluate_parameter_types_from_args,
|
65
|
-
)
|
66
66
|
from classiq.model_expansions.function_builder import (
|
67
67
|
FunctionContext,
|
68
68
|
)
|
@@ -135,13 +135,13 @@ def _validate_gen_args(
|
|
135
135
|
):
|
136
136
|
if (
|
137
137
|
isinstance(param, ClassicalParameterDeclaration)
|
138
|
-
and param.classical_type.
|
138
|
+
and not param.classical_type.is_purely_declarative
|
139
139
|
and _is_symbolic(arg.value)
|
140
140
|
):
|
141
|
+
readable_expr = transform_expression(str(arg.value), {}, {}, one_line=True)
|
141
142
|
raise ClassiqExpansionError(
|
142
|
-
f"
|
143
|
-
f"
|
144
|
-
f"{transform_expression(str(arg.value), {}, {}, one_line=True)!r}"
|
143
|
+
f"Cannot pass symbolic expression {readable_expr!r} as Python-type "
|
144
|
+
f"parameter {param.name!r}"
|
145
145
|
)
|
146
146
|
|
147
147
|
|
@@ -209,17 +209,21 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
|
|
209
209
|
function.name, new_declaration
|
210
210
|
)
|
211
211
|
else:
|
212
|
-
|
213
|
-
if type(self._interpreter).__name__ == "FrontendGenerativeInterpreter":
|
214
|
-
_validate_gen_args(function, evaluated_args)
|
212
|
+
_validate_gen_args(function, evaluated_args)
|
215
213
|
new_declaration = self._expand_function(
|
216
214
|
evaluated_args, new_declaration, function
|
217
215
|
)
|
218
216
|
new_positional_arg_decls = new_declaration.positional_arg_declarations
|
219
217
|
evaluated_args = [
|
220
218
|
arg
|
221
|
-
for arg in
|
222
|
-
|
219
|
+
for param, arg in zip_strict(
|
220
|
+
function.positional_arg_declarations, evaluated_args, strict=True
|
221
|
+
)
|
222
|
+
if isinstance(arg.value, QuantumVariable)
|
223
|
+
or (
|
224
|
+
isinstance(param, ClassicalParameterDeclaration)
|
225
|
+
and param.classical_type.is_purely_declarative
|
226
|
+
)
|
223
227
|
]
|
224
228
|
|
225
229
|
add_information_from_output_arguments(new_positional_arg_decls, evaluated_args)
|
@@ -312,7 +316,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
|
|
312
316
|
if isinstance(param, PortDeclaration)
|
313
317
|
or (
|
314
318
|
isinstance(param, ClassicalParameterDeclaration)
|
315
|
-
and
|
319
|
+
and param.classical_type.is_purely_declarative
|
316
320
|
)
|
317
321
|
]
|
318
322
|
func_def = self._builder.create_definition(function_context, params)
|
@@ -350,8 +354,10 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
|
|
350
354
|
),
|
351
355
|
defining_function=closure,
|
352
356
|
)
|
353
|
-
elif
|
354
|
-
|
357
|
+
elif (
|
358
|
+
isinstance(parameter, ClassicalParameterDeclaration)
|
359
|
+
and parameter.classical_type.is_purely_declarative
|
360
|
+
):
|
355
361
|
inferred_arg = Evaluated(
|
356
362
|
value=parameter.classical_type.get_classical_proxy(param_handle),
|
357
363
|
defining_function=closure,
|
@@ -426,7 +432,7 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], VarSpl
|
|
426
432
|
).unchecked
|
427
433
|
TypeModifierValidation(
|
428
434
|
skip_validation=self._interpreter.skip_type_modifier_validation
|
429
|
-
).run(func_def
|
435
|
+
).run(func_def, unchecked)
|
430
436
|
|
431
437
|
@staticmethod
|
432
438
|
def _should_override_type_modifiers(func_context: FunctionContext) -> bool:
|
@@ -4,7 +4,7 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
4
4
|
VariableDeclarationStatement,
|
5
5
|
)
|
6
6
|
|
7
|
-
from classiq.
|
7
|
+
from classiq.evaluators.parameter_types import (
|
8
8
|
evaluate_type_in_quantum_symbol,
|
9
9
|
)
|
10
10
|
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
@@ -11,13 +11,13 @@ from classiq.interface.model.native_function_definition import NativeFunctionDef
|
|
11
11
|
from classiq.interface.model.port_declaration import PortDeclaration
|
12
12
|
from classiq.interface.model.quantum_function_declaration import PositionalArg
|
13
13
|
|
14
|
-
from classiq.
|
15
|
-
from classiq.model_expansions.evaluators.classical_expression import (
|
14
|
+
from classiq.evaluators.classical_expression import (
|
16
15
|
evaluate_classical_expression,
|
17
16
|
)
|
18
|
-
from classiq.
|
17
|
+
from classiq.evaluators.parameter_types import (
|
19
18
|
evaluate_type_in_quantum_symbol,
|
20
19
|
)
|
20
|
+
from classiq.model_expansions.closure import FunctionClosure, GenerativeFunctionClosure
|
21
21
|
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
22
22
|
from classiq.qmod.builtins import BUILTIN_CONSTANTS
|
23
23
|
from classiq.qmod.builtins.enums import BUILTIN_ENUM_DECLARATIONS
|
@@ -77,7 +77,7 @@ class HandleRenaming:
|
|
77
77
|
SymbolRenaming = Mapping[HandleBinding, Sequence[HandleRenaming]]
|
78
78
|
|
79
79
|
|
80
|
-
def
|
80
|
+
def rewrite_expression(
|
81
81
|
symbol_mapping: SymbolRenaming, expression: Expression
|
82
82
|
) -> Expression:
|
83
83
|
normalized_expr = ExprNormalizer().visit(ast.parse(expression.expr))
|
@@ -88,7 +88,8 @@ def _rewrite_expression(
|
|
88
88
|
|
89
89
|
handle_names = {
|
90
90
|
part.source_handle: part.target_var_handle
|
91
|
-
for parts in symbol_mapping.
|
91
|
+
for source, parts in symbol_mapping.items()
|
92
|
+
if source.name in expression.expr
|
92
93
|
for part in parts
|
93
94
|
}
|
94
95
|
new_expr_str = ast.unparse(normalized_expr)
|
@@ -101,7 +102,8 @@ def _rewrite_expression(
|
|
101
102
|
for handle in sorted_handles:
|
102
103
|
new_handle = handle.collapse()
|
103
104
|
for handle_to_replace, replacement in handle_names.items():
|
104
|
-
new_handle
|
105
|
+
if new_handle.name == handle_to_replace.name:
|
106
|
+
new_handle = new_handle.replace_prefix(handle_to_replace, replacement)
|
105
107
|
new_expr_str = _replace_full_word(str(handle), str(new_handle), new_expr_str)
|
106
108
|
|
107
109
|
new_expr = Expression(expr=new_expr_str)
|
@@ -132,7 +134,7 @@ class _ReplaceSplitVarsExpressions(ModelTransformer):
|
|
132
134
|
self._symbol_mapping = symbol_mapping
|
133
135
|
|
134
136
|
def visit_Expression(self, expr: Expression) -> Expression:
|
135
|
-
return
|
137
|
+
return rewrite_expression(self._symbol_mapping, expr)
|
136
138
|
|
137
139
|
def visit_QuantumExpressionOperation(
|
138
140
|
self, op: QuantumExpressionOperation
|
@@ -4,6 +4,7 @@ import itertools
|
|
4
4
|
import warnings
|
5
5
|
from collections.abc import Collection, Iterator, Sequence
|
6
6
|
from contextlib import contextmanager
|
7
|
+
from typing import Optional, Union
|
7
8
|
|
8
9
|
from classiq.interface.exceptions import (
|
9
10
|
ClassiqDeprecationWarning,
|
@@ -18,6 +19,7 @@ from classiq.interface.model.bind_operation import BindOperation
|
|
18
19
|
from classiq.interface.model.control import Control
|
19
20
|
from classiq.interface.model.invert import Invert
|
20
21
|
from classiq.interface.model.model_visitor import ModelVisitor
|
22
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
21
23
|
from classiq.interface.model.phase_operation import PhaseOperation
|
22
24
|
from classiq.interface.model.port_declaration import PortDeclaration
|
23
25
|
from classiq.interface.model.power import Power
|
@@ -31,34 +33,43 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
31
33
|
QuantumExpressionOperation,
|
32
34
|
)
|
33
35
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
34
|
-
from classiq.interface.model.quantum_statement import QuantumStatement
|
35
36
|
from classiq.interface.model.within_apply_operation import WithinApply
|
37
|
+
from classiq.interface.source_reference import SourceReference
|
36
38
|
|
37
39
|
from classiq.model_expansions.visitors.variable_references import VarRefCollector
|
38
40
|
|
39
41
|
|
40
42
|
def _inconsistent_type_modifier_error(
|
41
|
-
port_name: str,
|
43
|
+
port_name: str,
|
44
|
+
expected: TypeModifier,
|
45
|
+
actual: TypeModifier,
|
46
|
+
source_ref: Optional[Union[SourceReference, str]] = None,
|
42
47
|
) -> str:
|
48
|
+
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
43
49
|
return (
|
44
|
-
f"The
|
50
|
+
f"The use of variable '{port_name}' does not conform to its declared modifier: "
|
45
51
|
f"expected '{expected.name}', but found '{actual.name}'.\n"
|
46
|
-
f"Tip: If the
|
47
|
-
f"
|
48
|
-
|
52
|
+
f"Tip: If the cumulative use of the variable in the function matches '{expected.name}', "
|
53
|
+
f"use the `unchecked` flag to instruct the compiler to disregard individual operations."
|
54
|
+
f"{source_ref_str}\n"
|
55
|
+
"The deprecation warning will be elevated to an error starting July 23, 2025, at the earliest."
|
49
56
|
)
|
50
57
|
|
51
58
|
|
52
59
|
def _inconsistent_type_modifier_in_binding_error(
|
53
|
-
expected: TypeModifier,
|
60
|
+
expected: TypeModifier,
|
61
|
+
known_modifiers: dict[str, TypeModifier],
|
62
|
+
source_ref: Optional[Union[SourceReference, str]] = None,
|
54
63
|
) -> str:
|
55
64
|
actual = ", ".join(
|
56
65
|
f"{name}: {modifier.name}" for name, modifier in known_modifiers.items()
|
57
66
|
)
|
67
|
+
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
58
68
|
return (
|
59
|
-
f"
|
69
|
+
f"Inconsistent modifiers in variable binding: "
|
60
70
|
f"Expected modifier: {expected.name}, Actual modifiers: {actual}"
|
61
|
-
|
71
|
+
f"{source_ref_str}\n"
|
72
|
+
"The deprecation warning will be elevated to an error starting July 23, 2025, at the earliest."
|
62
73
|
)
|
63
74
|
|
64
75
|
|
@@ -85,6 +96,7 @@ class TypeModifierValidation(ModelVisitor):
|
|
85
96
|
support_unused_ports # could be turned off for debugging
|
86
97
|
)
|
87
98
|
self._skip_validation = skip_validation
|
99
|
+
self._source_ref: Optional[Union[SourceReference, str]] = None
|
88
100
|
|
89
101
|
@contextmanager
|
90
102
|
def validate_ports(
|
@@ -119,6 +131,17 @@ class TypeModifierValidation(ModelVisitor):
|
|
119
131
|
finally:
|
120
132
|
self._conjugation_context = previous_context
|
121
133
|
|
134
|
+
@contextmanager
|
135
|
+
def source_reference_context(
|
136
|
+
self, source_ref: Optional[Union[SourceReference, str]]
|
137
|
+
) -> Iterator[None]:
|
138
|
+
previous_source_ref = self._source_ref
|
139
|
+
self._source_ref = source_ref
|
140
|
+
try:
|
141
|
+
yield
|
142
|
+
finally:
|
143
|
+
self._source_ref = previous_source_ref
|
144
|
+
|
122
145
|
def _set_unused_as_const(self) -> None:
|
123
146
|
unresolved_ports = [
|
124
147
|
port
|
@@ -161,7 +184,7 @@ class TypeModifierValidation(ModelVisitor):
|
|
161
184
|
if signature_modifier is not TypeModifier.and_(signature_modifier, modifier):
|
162
185
|
warnings.warn(
|
163
186
|
_inconsistent_type_modifier_error(
|
164
|
-
candidate, signature_modifier, modifier
|
187
|
+
candidate, signature_modifier, modifier, self._source_ref
|
165
188
|
),
|
166
189
|
ClassiqDeprecationWarning,
|
167
190
|
stacklevel=1,
|
@@ -176,13 +199,17 @@ class TypeModifierValidation(ModelVisitor):
|
|
176
199
|
|
177
200
|
def run(
|
178
201
|
self,
|
179
|
-
|
180
|
-
body: Sequence[QuantumStatement],
|
202
|
+
func_def: NativeFunctionDefinition,
|
181
203
|
unchecked: Collection[str],
|
182
204
|
) -> None:
|
183
|
-
with
|
205
|
+
with (
|
206
|
+
self.validate_ports(
|
207
|
+
func_def.port_declarations, unchecked
|
208
|
+
) as should_validate,
|
209
|
+
self.source_reference_context(f"function '{func_def.name}'"),
|
210
|
+
):
|
184
211
|
if should_validate:
|
185
|
-
self.visit(body)
|
212
|
+
self.visit(func_def.body)
|
186
213
|
self._update_bound_vars()
|
187
214
|
|
188
215
|
def _update_bound_vars(self) -> None:
|
@@ -193,16 +220,18 @@ class TypeModifierValidation(ModelVisitor):
|
|
193
220
|
self._validate_modifier(var, reduced_modifier)
|
194
221
|
|
195
222
|
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
223
|
+
with self.source_reference_context(call.source_ref):
|
224
|
+
for handle, port in call.handles_with_params:
|
225
|
+
self._validate_modifier(handle.name, port.type_modifier)
|
226
|
+
if port.direction is PortDeclarationDirection.Output:
|
227
|
+
self._add_initialized_modifier(handle.name, port.type_modifier)
|
200
228
|
|
201
229
|
if self._has_inputs(call):
|
202
230
|
bound_vars = {
|
203
231
|
handle.name
|
204
232
|
for handle, port in call.handles_with_params
|
205
233
|
if port.direction is not PortDeclarationDirection.Inout
|
234
|
+
and handle.name not in self._unchecked
|
206
235
|
}
|
207
236
|
self._bound_vars.append(bound_vars)
|
208
237
|
|
@@ -214,13 +243,15 @@ class TypeModifierValidation(ModelVisitor):
|
|
214
243
|
)
|
215
244
|
|
216
245
|
def visit_Allocate(self, alloc: Allocate) -> None:
|
217
|
-
self.
|
218
|
-
|
246
|
+
with self.source_reference_context(alloc.source_ref):
|
247
|
+
self._validate_modifier(alloc.target.name, TypeModifier.Permutable)
|
248
|
+
self._add_initialized_modifier(alloc.target.name, TypeModifier.Permutable)
|
219
249
|
|
220
250
|
def visit_BindOperation(self, bind_op: BindOperation) -> None:
|
221
251
|
var_names = {
|
222
252
|
handle.name
|
223
253
|
for handle in itertools.chain(bind_op.in_handles, bind_op.out_handles)
|
254
|
+
if handle.name not in self._unchecked
|
224
255
|
}
|
225
256
|
self._bound_vars.append(var_names)
|
226
257
|
for handle in bind_op.out_handles:
|
@@ -251,7 +282,7 @@ class TypeModifierValidation(ModelVisitor):
|
|
251
282
|
):
|
252
283
|
warnings.warn(
|
253
284
|
_inconsistent_type_modifier_in_binding_error(
|
254
|
-
min_modifier, known_modifiers
|
285
|
+
min_modifier, known_modifiers, self._source_ref
|
255
286
|
),
|
256
287
|
ClassiqDeprecationWarning,
|
257
288
|
stacklevel=1,
|
@@ -277,42 +308,49 @@ class TypeModifierValidation(ModelVisitor):
|
|
277
308
|
return [handle.name for handle in vrc.var_handles]
|
278
309
|
|
279
310
|
def visit_ArithmeticOperation(self, arith: ArithmeticOperation) -> None:
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
self.
|
284
|
-
|
285
|
-
|
311
|
+
with self.source_reference_context(arith.source_ref):
|
312
|
+
result_var = arith.result_var.name
|
313
|
+
self._validate_modifier(result_var, TypeModifier.Permutable)
|
314
|
+
for expr_var in self._extract_expr_vars(arith):
|
315
|
+
self._validate_modifier(expr_var, TypeModifier.Const)
|
316
|
+
if not arith.is_inplace:
|
317
|
+
self._add_initialized_modifier(result_var, TypeModifier.Permutable)
|
286
318
|
|
287
319
|
def visit_AmplitudeLoadingOperation(
|
288
320
|
self, amp_load: AmplitudeLoadingOperation
|
289
321
|
) -> None:
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
self.
|
322
|
+
with self.source_reference_context(amp_load.source_ref):
|
323
|
+
result_var = amp_load.result_var.name
|
324
|
+
self._validate_modifier(result_var, TypeModifier.Mutable)
|
325
|
+
for expr_var in self._extract_expr_vars(amp_load):
|
326
|
+
self._validate_modifier(expr_var, TypeModifier.Const)
|
294
327
|
|
295
328
|
def visit_PhaseOperation(self, phase_op: PhaseOperation) -> None:
|
296
|
-
|
297
|
-
self.
|
329
|
+
with self.source_reference_context(phase_op.source_ref):
|
330
|
+
for expr_var in self._extract_expr_vars(phase_op):
|
331
|
+
self._validate_modifier(expr_var, TypeModifier.Const)
|
298
332
|
|
299
333
|
def visit_Control(self, control: Control) -> None:
|
300
|
-
|
301
|
-
self.
|
302
|
-
|
303
|
-
|
304
|
-
|
334
|
+
with self.source_reference_context(control.source_ref):
|
335
|
+
for control_var in self._extract_expr_vars(control):
|
336
|
+
self._validate_modifier(control_var, TypeModifier.Const)
|
337
|
+
self.visit(control.body)
|
338
|
+
if control.else_block is not None:
|
339
|
+
self.visit(control.else_block)
|
305
340
|
|
306
341
|
def visit_Invert(self, invert: Invert) -> None:
|
307
|
-
self.
|
342
|
+
with self.source_reference_context(invert.source_ref):
|
343
|
+
self.visit(invert.body)
|
308
344
|
|
309
345
|
def visit_Power(self, power: Power) -> None:
|
310
|
-
self.
|
346
|
+
with self.source_reference_context(power.source_ref):
|
347
|
+
self.visit(power.body)
|
311
348
|
|
312
349
|
def visit_WithinApply(self, within_apply: WithinApply) -> None:
|
313
|
-
with self.
|
314
|
-
self.
|
315
|
-
|
350
|
+
with self.source_reference_context(within_apply.source_ref):
|
351
|
+
with self.conjugation_context():
|
352
|
+
self.visit(within_apply.compute)
|
353
|
+
self.visit(within_apply.action)
|
316
354
|
|
317
355
|
|
318
356
|
def _merge_overlapping(bound_vars: Sequence[Collection[str]]) -> list[set[str]]:
|
@@ -10,7 +10,6 @@ from classiq.interface.generator.expressions.atomic_expression_functions import
|
|
10
10
|
from classiq.interface.generator.expressions.expression import Expression
|
11
11
|
from classiq.interface.generator.functions.classical_type import (
|
12
12
|
ClassicalArray,
|
13
|
-
ClassicalList,
|
14
13
|
ClassicalTuple,
|
15
14
|
ClassicalType,
|
16
15
|
)
|
@@ -53,7 +52,7 @@ def set_generative_recursively(classical_type: ClassicalType) -> None:
|
|
53
52
|
set_generative_recursively(field_type)
|
54
53
|
return
|
55
54
|
classical_type.set_generative()
|
56
|
-
if isinstance(classical_type,
|
55
|
+
if isinstance(classical_type, ClassicalArray):
|
57
56
|
set_generative_recursively(classical_type.element_type)
|
58
57
|
if isinstance(classical_type, ClassicalTuple):
|
59
58
|
for element_type in classical_type.element_types:
|
@@ -155,7 +154,7 @@ class SymbolicParamInference(ModelVisitor):
|
|
155
154
|
for param, arg in zip_longest(params, call.positional_args):
|
156
155
|
if (
|
157
156
|
not isinstance(param, AnonClassicalParameterDeclaration)
|
158
|
-
or param.classical_type.
|
157
|
+
or not param.classical_type.is_purely_declarative
|
159
158
|
):
|
160
159
|
self._process_compile_time_expressions(arg)
|
161
160
|
else:
|
@@ -6,6 +6,7 @@ from .amplitude_estimation import *
|
|
6
6
|
from .discrete_sine_cosine_transform import *
|
7
7
|
from .discrete_sine_cosine_transform import _qct_d_operator, _qct_pi_operator
|
8
8
|
from .grover import *
|
9
|
+
from .grover import _cond_phase_flip
|
9
10
|
from .hea import *
|
10
11
|
from .linear_pauli_rotation import *
|
11
12
|
from .linear_pauli_rotation import _single_pauli
|
@@ -79,6 +80,7 @@ OPEN_LIBRARY_FUNCTIONS = [
|
|
79
80
|
_check_msb,
|
80
81
|
encode_in_angle,
|
81
82
|
encode_on_bloch,
|
83
|
+
_cond_phase_flip,
|
82
84
|
]
|
83
85
|
|
84
86
|
__all__ = [
|
@@ -105,6 +107,7 @@ __all__ = [
|
|
105
107
|
"modular_increment",
|
106
108
|
"multiswap",
|
107
109
|
"phase_oracle",
|
110
|
+
"prepare_basis_state",
|
108
111
|
"prepare_bell_state",
|
109
112
|
"prepare_complex_amplitudes",
|
110
113
|
"prepare_dicke_state",
|
@@ -1,11 +1,10 @@
|
|
1
1
|
from classiq.open_library.functions.grover import grover_operator
|
2
|
+
from classiq.qmod.builtins.functions.allocation import free
|
2
3
|
from classiq.qmod.builtins.functions.standard_gates import RY
|
3
4
|
from classiq.qmod.builtins.operations import (
|
4
5
|
allocate,
|
5
|
-
bind,
|
6
6
|
control,
|
7
7
|
power,
|
8
|
-
within_apply,
|
9
8
|
)
|
10
9
|
from classiq.qmod.cparam import CInt, CReal
|
11
10
|
from classiq.qmod.qfunc import qfunc
|
@@ -71,21 +70,14 @@ def exact_amplitude_amplification(
|
|
71
70
|
theta = pi / (4 * k + 2)
|
72
71
|
rot_phase = 2 * acos(sin(theta) / amplitude)
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
73
|
+
allocate(aux)
|
74
|
+
amplitude_amplification(
|
75
|
+
k,
|
76
|
+
lambda qvars_: control(qvars_[0] == 0, lambda: oracle(qvars_[1 : qvars_.size])),
|
77
|
+
lambda qvars_: [
|
78
|
+
space_transform(qvars_[1 : qvars_.size]),
|
79
|
+
RY(rot_phase, qvars_[0]),
|
79
80
|
],
|
80
|
-
|
81
|
-
k,
|
82
|
-
lambda qvars_: control(
|
83
|
-
qvars_[0] == 0, lambda: oracle(qvars_[1 : qvars_.size])
|
84
|
-
),
|
85
|
-
lambda qvars_: [
|
86
|
-
space_transform(qvars_[1 : qvars_.size]),
|
87
|
-
RY(rot_phase, qvars_[0]),
|
88
|
-
],
|
89
|
-
extended_qvars,
|
90
|
-
),
|
81
|
+
[aux, packed_qvars],
|
91
82
|
)
|
83
|
+
free(aux)
|
@@ -11,7 +11,7 @@ from classiq.qmod.builtins.operations import (
|
|
11
11
|
within_apply,
|
12
12
|
)
|
13
13
|
from classiq.qmod.qfunc import qfunc
|
14
|
-
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
14
|
+
from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit, QNum
|
15
15
|
from classiq.qmod.symbolic import pi
|
16
16
|
|
17
17
|
|
@@ -21,13 +21,13 @@ def _b_operator(q: QBit) -> None:
|
|
21
21
|
|
22
22
|
|
23
23
|
@qfunc
|
24
|
-
def _qct_d_operator(x: QNum, q: QBit) -> None:
|
24
|
+
def _qct_d_operator(x: Const[QNum], q: QBit) -> None:
|
25
25
|
_b_operator(q)
|
26
26
|
control(x == 0, lambda: invert(lambda: _b_operator(q)))
|
27
27
|
|
28
28
|
|
29
29
|
@qfunc
|
30
|
-
def _qct_pi_operator(x: QArray[QBit], q: QBit) -> None:
|
30
|
+
def _qct_pi_operator(x: Permutable[QArray[QBit]], q: Const[QBit]) -> None:
|
31
31
|
control(
|
32
32
|
q == 1,
|
33
33
|
lambda: [
|
@@ -120,8 +120,8 @@ def qct_qst_type1(x: QArray[QBit]) -> None:
|
|
120
120
|
within_apply(lambda: _t_operator(x), lambda: qft(x))
|
121
121
|
|
122
122
|
|
123
|
-
@qfunc
|
124
|
-
def qct_qst_type2(x: QArray[QBit], q: QBit) -> None:
|
123
|
+
@qfunc(unchecked=["q"])
|
124
|
+
def qct_qst_type2(x: QArray[QBit], q: Const[QBit]) -> None:
|
125
125
|
"""
|
126
126
|
[Qmod Classiq-library function]
|
127
127
|
|
@@ -10,14 +10,22 @@ from classiq.qmod.builtins.operations import (
|
|
10
10
|
)
|
11
11
|
from classiq.qmod.qfunc import qfunc
|
12
12
|
from classiq.qmod.qmod_parameter import CInt
|
13
|
-
from classiq.qmod.qmod_variable import QArray, QBit, QNum
|
13
|
+
from classiq.qmod.qmod_variable import Const, Permutable, QArray, QBit, QNum
|
14
14
|
from classiq.qmod.quantum_callable import QCallable
|
15
15
|
from classiq.qmod.symbolic import pi
|
16
16
|
|
17
17
|
|
18
|
+
@qfunc(unchecked=["target"])
|
19
|
+
def _cond_phase_flip(
|
20
|
+
predicate: QCallable[Permutable[QBit]], target: Const[QBit]
|
21
|
+
) -> None:
|
22
|
+
within_apply(lambda: H(target), lambda: predicate(target))
|
23
|
+
|
24
|
+
|
18
25
|
@qfunc
|
19
26
|
def phase_oracle(
|
20
|
-
predicate: QCallable[QArray[QBit]
|
27
|
+
predicate: QCallable[Const[QArray[QBit]], Permutable[QBit]],
|
28
|
+
target: Const[QArray[QBit]],
|
21
29
|
) -> None:
|
22
30
|
"""
|
23
31
|
[Qmod Classiq-library function]
|
@@ -42,13 +50,13 @@ def phase_oracle(
|
|
42
50
|
"""
|
43
51
|
aux = QBit()
|
44
52
|
within_apply(
|
45
|
-
|
46
|
-
|
53
|
+
lambda: [allocate(aux), X(aux)],
|
54
|
+
lambda: _cond_phase_flip(lambda x: predicate(target, x), aux),
|
47
55
|
)
|
48
56
|
|
49
57
|
|
50
|
-
@qfunc
|
51
|
-
def reflect_about_zero(packed_vars: QArray[QBit]) -> None:
|
58
|
+
@qfunc(unchecked=["packed_vars"])
|
59
|
+
def reflect_about_zero(packed_vars: Const[QArray[QBit]]) -> None:
|
52
60
|
"""
|
53
61
|
[Qmod Classiq-library function]
|
54
62
|
|