Source code for guppyft.code.steane.logical

"""Guppy functions for the logical operations and types for the Steane QEC architecture.

This module contains bindings for the fundamental ops in the HUGR extensions, as well
as composite operations that comprise multiple logical operations.

The physical implementation for these ops is provided in
:py:mod:`~guppyft.code.steane.primitives`.
"""

from typing import no_type_check

from guppylang import guppy
from guppylang.std.angles import angle
from guppylang.std.lang import owned
from guppylang_internals.decorator import custom_function, custom_type, hugr_op
from guppylang_internals.tys import Effect

from guppyft.code._logical import _logical_op
from guppyft.extensions import steane_ops, steane_types
from guppyft.std._rotation import _RotationCompiler

_OPS_EXTN = steane_ops()


[docs] @custom_type(steane_types.steane_measurement(), copyable=True, droppable=True) class Measurement: """A measurement outcome of a logical Steane qubit."""
[docs] @hugr_op(_logical_op("decode", _OPS_EXTN)) @no_type_check def decode(self: "Measurement") -> bool: """Return the decoded logical measurement outcome."""
[docs] @custom_type(steane_types.steane_qubit(), copyable=False, droppable=False) class Qubit: """A logical qubit encoded in the Steane code. Constructing a ``Qubit`` instance prepares it in the logical zero state. """
[docs] @hugr_op(_logical_op("prep_zero", _OPS_EXTN), effects=[Effect.ANY]) @no_type_check def __new__() -> "Qubit": """Prepare a logical qubit in the zero state."""
[docs] @guppy @no_type_check def free(self: "Qubit" @ owned) -> None: """Free the qubit.""" free(self)
[docs] @guppy @no_type_check def measure_z(self: "Qubit" @ owned) -> Measurement: """Destructive measurement of the qubit in the Z basis.""" return measure_z(self)
[docs] @guppy @no_type_check def qec_cycle(self: "Qubit") -> None: """Perform a QEC cycle on the logical qubit.""" qec_cycle(self)
[docs] @guppy @no_type_check def x(self: "Qubit") -> None: """X gate.""" x(self)
[docs] @guppy @no_type_check def y(self: "Qubit") -> None: """Y gate.""" y(self)
[docs] @guppy @no_type_check def z(self: "Qubit") -> None: """Z gate.""" z(self)
[docs] @guppy @no_type_check def h(self: "Qubit") -> None: """H gate.""" h(self)
[docs] @guppy @no_type_check def s(self: "Qubit") -> None: """S gate.""" s(self)
[docs] @guppy @no_type_check def sdg(self: "Qubit") -> None: """Sdg gate.""" sdg(self)
[docs] @guppy def t(self: "Qubit") -> None: r"""Apply a logical :math:`T` gate using magic-state injection.""" t(self)
[docs] @guppy def tdg(self: "Qubit") -> None: r"""Apply a logical :math:`T^\dagger` gate using magic-state injection.""" tdg(self)
[docs] @hugr_op(_logical_op("free", _OPS_EXTN), effects=[Effect.ANY]) @no_type_check def free(qubit: "Qubit" @ owned) -> None: """Free a qubit."""
[docs] @hugr_op(_logical_op("measure_z", _OPS_EXTN), effects=[Effect.ANY]) @no_type_check def measure_z(qubit: "Qubit" @ owned) -> Measurement: """Destructive measurement of the qubit in the Z basis."""
[docs] @hugr_op(_logical_op("qec_cycle", _OPS_EXTN)) @no_type_check def qec_cycle(qubit: Qubit) -> None: """Perform a QEC cycle on the logical qubit."""
[docs] @hugr_op(_logical_op("x", _OPS_EXTN)) @no_type_check def x(qubit: Qubit) -> None: """X gate."""
[docs] @hugr_op(_logical_op("y", _OPS_EXTN)) @no_type_check def y(qubit: Qubit) -> None: """Y gate."""
[docs] @hugr_op(_logical_op("z", _OPS_EXTN)) @no_type_check def z(qubit: "Qubit") -> None: """Z gate."""
[docs] @hugr_op(_logical_op("h", _OPS_EXTN)) @no_type_check def h(qubit: "Qubit") -> None: """H gate."""
[docs] @hugr_op(_logical_op("s", _OPS_EXTN)) @no_type_check def s(qubit: "Qubit") -> None: """S gate."""
[docs] @hugr_op(_logical_op("sdg", _OPS_EXTN)) @no_type_check def sdg(qubit: "Qubit") -> None: """Sdg gate."""
[docs] @custom_function(_RotationCompiler("rz", _OPS_EXTN)) def rz(qubit: "Qubit", angle: angle) -> None: """Rz gate."""
[docs] @hugr_op(_logical_op("prep_t_state", _OPS_EXTN), effects=[Effect.ANY]) @no_type_check def prep_t_state() -> "Qubit": r"""Prepare a logical :math:`T\ket{+}` magic state for :math:`T` and :math:`T^\dagger` injection."""
[docs] @hugr_op(_logical_op("inject_t", _OPS_EXTN)) @no_type_check def inject_t(qubit: "Qubit", magic: "Qubit" @ owned) -> None: """Apply a logical :math:`T` gate by consuming a magic-state qubit."""
[docs] @hugr_op(_logical_op("inject_tdg", _OPS_EXTN)) @no_type_check def inject_tdg(qubit: "Qubit", magic: "Qubit" @ owned) -> None: r"""Apply a logical :math:`T^\dagger` gate by consuming a magic-state qubit."""
[docs] @hugr_op(_logical_op("cx", _OPS_EXTN)) @no_type_check def cx(q0: "Qubit", q1: "Qubit") -> None: """CX gate."""
[docs] @hugr_op(_logical_op("cz", _OPS_EXTN)) @no_type_check def cz(q0: "Qubit", q1: "Qubit") -> None: """CZ gate."""
[docs] @hugr_op(_logical_op("swap", _OPS_EXTN)) @no_type_check def swap(q0: "Qubit", q1: "Qubit") -> None: """SWAP gate."""
[docs] @guppy def t(q: Qubit) -> None: r"""Apply a logical :math:`T` gate using magic-state injection.""" a = prep_t_state() inject_t(q, a)
[docs] @guppy def tdg(q: Qubit) -> None: r"""Apply a logical :math:`T^\dagger` gate using magic-state injection.""" a = prep_t_state() inject_tdg(q, a)