Skip Control
The skip-control statement designates a statement block that should be applied unconditionally, even when the enclosing function is subject directly or indirectly to a quantum control operator. This construct is typically applied when the enclosing function involves intermediate computation and uncomputation blocks in ways that cannot be formulated using a simple conjunction (i.e., using the within-apply statement).
Syntax
skip_control { statements }
def skip_control(stmt_block: QCallable) -> None:
pass
Semantics
- All statements nested under a skip-control statement are applied
unconditionally, including in states where a control condition from above is
evaluated to
False
. It is the user's responsibility to ensure that the combined effect of the skip-control blocks in the enclosing function is functionally equivalent to NOP (identity). - Using skip-control inside the within block of a within-apply statement is redundant, since the within block is itself designated as a skip-control block.
- Using skip-control directly inside the apply block of a within-apply statement is not allowed.
Example
The following example demonstrates the use of skip_control
. Function foo
rotates a qubit in steps, applying a controlled flip of other qubits at each
step. The controlling qubit ultimately returns to its original state. The
rotations are marked with skip_control
because they can be safely applied even
for states where the whole function is under a negative control condition, as
demonstrated by function main
.
Note that the computation of qarr[0]
within foo
cannot be encapsulated in an
apply block of a within-apply statement.
qfunc foo(qarr: qbit[5]) {
repeat (i: 4) {
CX(qarr[0], qarr[i+1]);
skip_control {
RX(pi/2, qarr[0]);
}
}
}
qfunc main(output ctrl: qbit, output qarr: qbit[5]) {
allocate(qarr);
hadamard_transform(qarr[0]);
allocate(ctrl);
hadamard_transform(ctrl);
control(ctrl) {
foo(qarr);
}
}
from classiq import *
from classiq.qmod.symbolic import pi
@qfunc
def foo(qarr: QArray[QBit, 5]) -> None:
repeat(
4,
lambda i: [
CX(qarr[0], qarr[i + 1]),
skip_control(lambda: RX(pi / 2, qarr[0])),
],
)
@qfunc
def main(ctrl: Output[QBit], qarr: Output[QArray[QBit, 5]]) -> None:
allocate(qarr)
hadamard_transform(qarr[0])
allocate(ctrl)
hadamard_transform(ctrl)
control(ctrl, lambda: foo(qarr))