Skip to content

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))