Prove2Me
Navigate
DiscoverCollectionsFormalpediaBlogsUsersMomentumMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

Binary standard form of a stabilizer and the encoding network (shared definition layer)

Definition
QAlgorithms_Defs_BinaryStabilizer

by Goku · Oct 13, 2026 · Mathlib 0df444a (Lean v4.33.1)

lecture-notesquantum-information

Binary standard form of a stabilizer and the encoding network (shared definition layer)

QAlgorithms.SymplecticCommuting

Setting. m,nm,nm,n are natural numbers, and Hx,HzH_x, H_zHx​,Hz​ are m×nm\times nm×n matrices over F2\mathbb{F}_2F2​.

Definition. The property holds iff

HxHzT+HzHxT=0H_x H_z^{\mathsf T} + H_z H_x^{\mathsf T} = 0Hx​HzT​+Hz​HxT​=0

as an m×mm\times mm×m matrix over F2\mathbb{F}_2F2​. Entrywise, this says that for all rows i,ji,ji,j:

∑q=0n−1((Hx)iq(Hz)jq+(Hz)iq(Hx)jq)=0(mod2).\sum_{q=0}^{n-1}\big((H_x)_{iq}(H_z)_{jq} + (H_z)_{iq}(H_x)_{jq}\big) = 0 \pmod 2 .q=0∑n−1​((Hx​)iq​(Hz​)jq​+(Hz​)iq​(Hx​)jq​)=0(mod2).

Edge cases.

  • The diagonal conditions i=ji=ji=j hold automatically over F2\mathbb{F}_2F2​.
  • The property is vacuously true when m=0m=0m=0.
  • When n=0n=0n=0 it holds trivially, since the sums are empty.

QAlgorithms.IsBinaryStabilizerMatrix

Setting. m,nm,nm,n are natural numbers, and Hx,HzH_x,H_zHx​,Hz​ are m×nm\times nm×n matrices over F2\mathbb{F}_2F2​.

Definition. The property holds iff both of the following hold:

  1. Symplectic commutation: HxHzT+HzHxT=0H_xH_z^{\mathsf T}+H_zH_x^{\mathsf T}=0Hx​HzT​+Hz​HxT​=0 over F2\mathbb{F}_2F2​.
  2. Row independence: the mmm rows of the m×2nm\times 2nm×2n block matrix [ Hx∣Hz ][\,H_x \mid H_z\,][Hx​∣Hz​] (columns of HxH_xHx​ followed by columns of HzH_zHz​) are linearly independent over F2\mathbb{F}_2F2​.

Edge cases.

  • Condition 2 forces m≤2nm\le 2nm≤2n and forces every row of [Hx∣Hz][H_x\mid H_z][Hx​∣Hz​] to be nonzero.
  • For m=0m=0m=0 the property holds trivially.

QAlgorithms.IsStandardForm

Setting.

  • m,k,rm,k,rm,k,r are natural numbers.
  • Hx,HzH_x,H_zHx​,Hz​ are m×(m+k)m\times(m+k)m×(m+k) matrices over F2\mathbb{F}_2F2​.
  • Rows are indexed 0,…,m−10,\dots,m-10,…,m−1 and columns 0,…,m+k−10,\dots,m+k-10,…,m+k−1 (0-based).

Definition. The property holds iff all of the following hold:

  1. r≤mr\le mr≤m.
  2. For all rows i<ri<ri<r and columns j<rj<rj<r: (Hx)ij=δij(H_x)_{ij}=\delta_{ij}(Hx​)ij​=δij​. That is, the top-left r×rr\times rr×r block of HxH_xHx​ is the identity.
  3. For all rows i≥ri\ge ri≥r and all columns jjj: (Hx)ij=0(H_x)_{ij}=0(Hx​)ij​=0.
  4. For all rows i≥ri\ge ri≥r and columns jjj with r≤j<mr\le j<mr≤j<m: (Hz)ij=δij(H_z)_{ij}=\delta_{ij}(Hz​)ij​=δij​. That is, the block of HzH_zHz​ in rows r,…,m−1r,\dots,m-1r,…,m−1 and columns r,…,m−1r,\dots,m-1r,…,m−1 is the identity.

Unconstrained entries. Nothing else is required:

  • the entries of HxH_xHx​ in rows i<ri<ri<r, columns j≥rj\ge rj≥r,
  • all of HzH_zHz​ in rows i<ri<ri<r, and
  • the entries of HzH_zHz​ in rows i≥ri\ge ri≥r, columns j<rj<rj<r or j≥mj\ge mj≥m

are arbitrary.

Not required. Neither symplectic commutation nor row independence is required.

QAlgorithms.kronAll

Setting. nnn is a natural number, and M0,…,Mn−1M_0,\dots,M_{n-1}M0​,…,Mn−1​ are complex 2×22\times 22×2 matrices indexed by {0,1}\{0,1\}{0,1}.

Definition. kronAll(M)\mathrm{kronAll}(M)kronAll(M) is the 2n×2n2^n\times 2^n2n×2n matrix indexed by bit strings y,z∈{0,1}ny,z\in\{0,1\}^ny,z∈{0,1}n, with

kronAll(M)y,z=∏q=0n−1(Mq)yq, zq,\mathrm{kronAll}(M)_{y,z} = \prod_{q=0}^{n-1} (M_q)_{y_q,\,z_q},kronAll(M)y,z​=q=0∏n−1​(Mq​)yq​,zq​​,

i.e. the tensor product M0⊗M1⊗⋯⊗Mn−1M_0\otimes M_1\otimes\cdots\otimes M_{n-1}M0​⊗M1​⊗⋯⊗Mn−1​, with MqM_qMq​ acting on wire qqq (wire 000 most significant).

Edge case. For n=0n=0n=0 it is the 1×11\times 11×1 matrix (1)(1)(1).

QAlgorithms.rowPauli

Setting. nnn is a natural number, and a,b∈F2na,b\in\mathbb{F}_2^na,b∈F2n​.

Definition. rowPauli(a,b)\mathrm{rowPauli}(a,b)rowPauli(a,b) is the 2n×2n2^n\times 2^n2n×2n complex matrix

rowPauli(a,b)=⨂q=0n−1ZbqXaq,i.e.rowPauli(a,b)y,z=∏q(ZbqXaq)yq,zq,\mathrm{rowPauli}(a,b) = \bigotimes_{q=0}^{n-1} Z^{b_q}X^{a_q}, \qquad\text{i.e.}\qquad \mathrm{rowPauli}(a,b)_{y,z}=\prod_q \big(Z^{b_q}X^{a_q}\big)_{y_q,z_q},rowPauli(a,b)=q=0⨂n−1​Zbq​Xaq​,i.e.rowPauli(a,b)y,z​=q∏​(Zbq​Xaq​)yq​,zq​​,

where:

  • X=(0110)X=\begin{pmatrix}0&1\\1&0\end{pmatrix}X=(01​10​),
  • Z=diag⁡(1,−1)Z=\operatorname{diag}(1,-1)Z=diag(1,−1) (sign −1-1−1 on bit 111), and
  • Z0=X0=IZ^{0}=X^{0}=IZ0=X0=I.

On each qubit the factor is the matrix product ZZZ-part times XXX-part, so XXX is applied first.

Edge cases.

  • No global phase is included.
  • When aq=bq=1a_q=b_q=1aq​=bq​=1, the factor is ZX=(01−10)=iYZX=\begin{pmatrix}0&1\\-1&0\end{pmatrix}=iYZX=(0−1​10​)=iY, not YYY.
  • For n=0n=0n=0 the matrix is (1)(1)(1).

QAlgorithms.logicalXRow

Setting.

  • m,k,rm,k,rm,k,r are natural numbers.
  • HzH_zHz​ is an m×(m+k)m\times(m+k)m×(m+k) matrix over F2\mathbb{F}_2F2​ (0-based indices).
  • i∈{0,…,k−1}i\in\{0,\dots,k-1\}i∈{0,…,k−1}.

Definition. logicalXRow(r,Hz,i)\mathrm{logicalXRow}(r,H_z,i)logicalXRow(r,Hz​,i) is a pair (a,b)(a,b)(a,b) of vectors in F2m+k\mathbb{F}_2^{m+k}F2m+k​. Their entries, indexed by j∈{0,…,m+k−1}j\in\{0,\dots,m+k-1\}j∈{0,…,m+k−1}, are as follows.

The first vector aaa:

aj={(Hz)j, m+iif r≤j<m,0if j<min⁡(r,m)  (i.e. j<m, j<r),1if j=m+i,0if j≥m, j≠m+i.a_j=\begin{cases} (H_z)_{j,\,m+i} & \text{if } r\le j<m,\\ 0 & \text{if } j<\min(r,m)\ \ (\text{i.e. } j<m,\ j<r),\\ 1 & \text{if } j = m+i,\\ 0 & \text{if } j\ge m,\ j\neq m+i. \end{cases}aj​=⎩⎨⎧​(Hz​)j,m+i​010​if r≤j<m,if j<min(r,m)  (i.e. j<m, j<r),if j=m+i,if j≥m, j=m+i.​

The second vector bbb:

bj={∑l=0l≥rm−1(Hz)l, m+i (Hz)j, l  +  (Hz)j, m+iif j<r and j<m,0otherwise,b_j=\begin{cases} \displaystyle\sum_{\substack{l=0\\ l\ge r}}^{m-1} (H_z)_{l,\,m+i}\,(H_z)_{j,\,l} \;+\; (H_z)_{j,\,m+i} & \text{if } j<r \text{ and } j<m,\\[2ex] 0 & \text{otherwise,} \end{cases}bj​=⎩⎨⎧​l=0l≥r​∑m−1​(Hz​)l,m+i​(Hz​)j,l​+(Hz​)j,m+i​0​if j<r and j<m,otherwise,​

with all arithmetic in F2\mathbb{F}_2F2​. The sum runs over l=r,…,m−1l=r,\dots,m-1l=r,…,m−1, and in (Hz)j,l(H_z)_{j,l}(Hz​)j,l​ the index l<ml<ml<m is used as a column index.

Notes.

  • Only HzH_zHz​ enters; there is no HxH_xHx​ argument.
  • No standard-form hypothesis on HzH_zHz​ is assumed.
  • If r≥mr\ge mr≥m, then:
    • aaa is the unit vector at position m+im+im+i, and
    • bj=(Hz)j,m+ib_j=(H_z)_{j,m+i}bj​=(Hz​)j,m+i​ for j<mj<mj<m (the sum being empty), with bj=0b_j=0bj​=0 for j≥mj\ge mj≥m.

QAlgorithms.logicalX

Inputs.

  • Natural numbers m,k,rm, k, rm,k,r.
  • A binary matrix Hz∈F2m×(m+k)H_z \in \mathbb{F}_2^{m \times (m+k)}Hz​∈F2m×(m+k)​, with rows indexed by 0,…,m−10,\dots,m-10,…,m−1 and columns by 0,…,m+k−10,\dots,m+k-10,…,m+k−1.
  • An index i∈{0,…,k−1}i \in \{0,\dots,k-1\}i∈{0,…,k−1}.

Output. The 2m+k×2m+k2^{m+k}\times 2^{m+k}2m+k×2m+k complex matrix Xˉi\bar X_iXˉi​ on m+km+km+k qubits. Its rows and columns are indexed by bit strings y,z∈{0,1}m+ky, z \in \{0,1\}^{m+k}y,z∈{0,1}m+k.

The Pauli operator. First define two vectors a,b∈F2m+ka, b \in \mathbb{F}_2^{m+k}a,b∈F2m+k​ (given below). Then

Xˉi=⨂q=0m+k−1ZbqXaq,(Xˉi)y,z=∏q=0m+k−1(ZbqXaq)yq,zq.\bar X_i = \bigotimes_{q=0}^{m+k-1} Z^{b_q} X^{a_q}, \qquad (\bar X_i)_{y,z} = \prod_{q=0}^{m+k-1} \big(Z^{b_q}X^{a_q}\big)_{y_q, z_q}.Xˉi​=q=0⨂m+k−1​Zbq​Xaq​,(Xˉi​)y,z​=q=0∏m+k−1​(Zbq​Xaq​)yq​,zq​​.

Here X=(0110)X = \begin{pmatrix}0&1\\1&0\end{pmatrix}X=(01​10​) and Z=diag(1,−1)Z = \mathrm{diag}(1,-1)Z=diag(1,−1). A power with exponent 000 is the identity. The product ZbqXaqZ^{b_q}X^{a_q}Zbq​Xaq​ is an ordinary matrix product, so on a vector XXX acts first. There is no phase factor.

The vector aaa. For j<mj < mj<m:

aj={(Hz)j, m+iif r≤j,0if j<r.a_j = \begin{cases} (H_z)_{j,\,m+i} & \text{if } r \le j,\\ 0 & \text{if } j < r.\end{cases}aj​={(Hz​)j,m+i​0​if r≤j,if j<r.​

For j≥mj \ge mj≥m: aj=1a_j = 1aj​=1 if j=m+ij = m+ij=m+i, and aj=0a_j = 0aj​=0 otherwise.

The vector bbb. For j<min⁡(r,m)j < \min(r, m)j<min(r,m), with arithmetic in F2\mathbb{F}_2F2​:

bj=∑l=0r≤lm−1(Hz)l, m+i (Hz)j, l  +  (Hz)j, m+i.b_j = \sum_{\substack{l=0 \\ r \le l}}^{m-1} (H_z)_{l,\,m+i}\,(H_z)_{j,\,l} \;+\; (H_z)_{j,\,m+i}.bj​=l=0r≤l​∑m−1​(Hz​)l,m+i​(Hz​)j,l​+(Hz​)j,m+i​.

For all other jjj (that is, j≥rj \ge rj≥r or j≥mj \ge mj≥m): bj=0b_j = 0bj​=0.

Edge cases.

  • No relation between rrr and mmm is assumed.
  • If r≥mr \ge mr≥m, then aaa is zero on the first mmm positions, and the sum in bjb_jbj​ is empty. So bj=(Hz)j,m+ib_j = (H_z)_{j,m+i}bj​=(Hz​)j,m+i​ for every j<mj < mj<m.
  • If r=0r = 0r=0, then b=0b = 0b=0.

QAlgorithms.stabEncodedState

Inputs.

  • Natural numbers m,k,rm, k, rm,k,r.
  • Binary matrices Hx,Hz∈F2m×(m+k)H_x, H_z \in \mathbb{F}_2^{m\times(m+k)}Hx​,Hz​∈F2m×(m+k)​.
  • A bit string c∈{0,1}kc \in \{0,1\}^kc∈{0,1}k.

Output. A vector ∣cˉ⟩∈C{0,1}m+k|\bar c\rangle \in \mathbb{C}^{\{0,1\}^{m+k}}∣cˉ⟩∈C{0,1}m+k.

Ingredients.

  • For each row iii, let gi=⨂qZ(Hz)i,qX(Hx)i,qg_i = \bigotimes_q Z^{(H_z)_{i,q}}X^{(H_x)_{i,q}}gi​=⨂q​Z(Hz​)i,q​X(Hx​)i,q​. This is the phase-free Pauli operator built from row iii of (Hx,Hz)(H_x, H_z)(Hx​,Hz​), using the same tensor-product convention as in logicalX.
  • Let Xˉi\bar X_iXˉi​ be the operator logicalX defined above, built from r,Hz,ir, H_z, ir,Hz​,i.

Definition.

∣cˉ⟩=(I+gm−1)(I+gm−2)⋯(I+g0)  Xˉk−1 ck−1⋯Xˉ1 c1Xˉ0 c0  ∣0⋯0⟩.|\bar c\rangle = (I + g_{m-1})(I+g_{m-2})\cdots(I+g_0)\;\bar X_{k-1}^{\,c_{k-1}}\cdots \bar X_1^{\,c_1}\bar X_0^{\,c_0}\;|0\cdots0\rangle.∣cˉ⟩=(I+gm−1​)(I+gm−2​)⋯(I+g0​)Xˉk−1ck−1​​⋯Xˉ1c1​​Xˉ0c0​​∣0⋯0⟩.

Reading the formula.

  • Xˉi 1=Xˉi\bar X_i^{\,1} = \bar X_iXˉi1​=Xˉi​ and Xˉi 0=I\bar X_i^{\,0} = IXˉi0​=I.
  • The rightmost factor is applied first. So Xˉ0c0\bar X_0^{c_0}Xˉ0c0​​ acts first on ∣0m+k⟩|0^{m+k}\rangle∣0m+k⟩, and I+gm−1I+g_{m-1}I+gm−1​ acts last.

Edge cases.

  • No normalization is applied, so the result need not be a unit vector. It may even be the zero vector.
  • No hypotheses are placed on Hx,Hz,rH_x, H_z, rHx​,Hz​,r.
  • If m=0m = 0m=0, the left product is the identity.
  • If k=0k = 0k=0, the middle product is the identity.

QAlgorithms.stabEncoderGateSet

This is a set of five gates.

Single-qubit gates (arity 1). Each is a 2×22\times 22×2 matrix indexed by the one bit of a 1-qubit string:

  • the Hadamard gate
H=12(111−1);H = \tfrac{1}{\sqrt2}\begin{pmatrix}1&1\\1&-1\end{pmatrix};H=2​1​(11​1−1​);
  • the Pauli gate Z=diag(1,−1)Z = \mathrm{diag}(1,-1)Z=diag(1,−1).

Two-qubit gates (arity 2). For every pair of bits (a,b)≠(0,0)(a,b) \neq (0,0)(a,b)=(0,0), there is a gate

C(ZbXa)=∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗ZbXa.C(Z^bX^a) = |0\rangle\langle 0| \otimes I + |1\rangle\langle 1| \otimes Z^bX^a.C(ZbXa)=∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗ZbXa.
  • The first qubit is the control and the second is the target.
  • The matrix entries are δp1,q1 (Mp1)p2,q2\delta_{p_1,q_1}\,(M_{p_1})_{p_2,q_2}δp1​,q1​​(Mp1​​)p2​,q2​​, where M0=IM_0 = IM0​=I and M1=ZbXaM_1 = Z^bX^aM1​=ZbXa.
  • Concretely the three gates are controlled-XXX (when (a,b)=(1,0)(a,b)=(1,0)(a,b)=(1,0)), controlled-ZZZ (when (a,b)=(0,1)(a,b)=(0,1)(a,b)=(0,1)), and controlled-ZXZXZX (when (a,b)=(1,1)(a,b)=(1,1)(a,b)=(1,1)), where
ZX=(01−10).ZX = \begin{pmatrix}0&1\\-1&0\end{pmatrix}.ZX=(0−1​10​).

QAlgorithms.stabCtrlApp

Inputs.

  • A number of wires NNN.
  • Bits a,ba, ba,b with (a,b)≠(0,0)(a,b) \neq (0,0)(a,b)=(0,0).
  • Distinct wires c≠tc \neq tc=t in {0,…,N−1}\{0,\dots,N-1\}{0,…,N−1}.

Output. A gate application in an NNN-wire circuit over the gate set stabEncoderGateSet:

  • The gate is the two-qubit gate C(ZbXa)=∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗ZbXaC(Z^bX^a) = |0\rangle\langle0|\otimes I + |1\rangle\langle1|\otimes Z^bX^aC(ZbXa)=∣0⟩⟨0∣⊗I+∣1⟩⟨1∣⊗ZbXa.
  • Its first qubit (the control) is placed on wire ccc.
  • Its second qubit (the target) is placed on wire ttt.

Effect inside a circuit. It acts on all NNN qubits as C(ZbXa)C(Z^bX^a)C(ZbXa) on wires (c,t)(c,t)(c,t) and as the identity on all other wires.

QAlgorithms.stabEncoder

Inputs.

  • Natural numbers m,k,rm, k, rm,k,r.
  • Binary matrices Hx,Hz∈F2m×(m+k)H_x, H_z \in \mathbb{F}_2^{m\times(m+k)}Hx​,Hz​∈F2m×(m+k)​.

Output. A circuit on m+km+km+k wires over stabEncoderGateSet. It is a list of gate applications, executed in list order (first element applied first). Each gate acts as the identity off its wires.

Part 1 comes first in the list. For i=0,1,…,k−1i = 0, 1, \dots, k-1i=0,1,…,k−1 in increasing order, and within each iii for j=0,…,m−1j = 0,\dots,m-1j=0,…,m−1 in increasing order:

  • If r≤jr \le jr≤j and (Hz)j, m+i=1(H_z)_{j,\,m+i} = 1(Hz​)j,m+i​=1, append a controlled-XXX with control wire m+im+im+i and target wire jjj.

Part 2 comes after Part 1. For i=0,…,m−1i = 0,\dots,m-1i=0,…,m−1 in increasing order:

  • If i≥ri \ge ri≥r, append nothing.
  • If i<ri < ri<r, append in this order:
    1. a Hadamard on wire iii;
    2. if (Hz)i,i=1(H_z)_{i,i} = 1(Hz​)i,i​=1, a ZZZ gate on wire iii;
    3. for q=0,…,m+k−1q = 0,\dots,m+k-1q=0,…,m+k−1 in increasing order, a gate whenever q≠iq \neq iq=i and ((Hx)i,q,(Hz)i,q)≠(0,0)\big((H_x)_{i,q},(H_z)_{i,q}\big) \neq (0,0)((Hx​)i,q​,(Hz​)i,q​)=(0,0). The gate is C(Z(Hz)i,qX(Hx)i,q)C\big(Z^{(H_z)_{i,q}}X^{(H_x)_{i,q}}\big)C(Z(Hz​)i,q​X(Hx​)i,q​), with control wire iii and target wire qqq.

Edge cases.

  • No hypotheses are placed on rrr, HxH_xHx​, HzH_zHz​.
  • If r=0r = 0r=0, Part 2 is empty.
  • If r≥mr \ge mr≥m, Part 1 is empty.
Definition code
import Definitions.Def_QAlgorithms_Defs_QECC
/-!
# Binary standard form of a stabilizer and the encoding network (shared definition layer)

D. Gottesman, *Stabilizer codes and quantum error correction* (PhD thesis, 1997), cited
"Gottesman thesis p.N" (PDF pages), §§4.1–4.2, with the author's errata (Grassl's gate order;
controlled-`Y` read as controlled-`XZ` in the real form `Y = XZ`; every generator of sign `+1`).

Conventions. A code on `n = m + k` qubits encoding `k` qubits has `m = n − k` generators (no `ℕ`
subtraction); its binary generator matrix is the pair `(H_x | H_z)` of `m × n` matrices over `F₂`
(`H_x` the `σx` part, `H_z` the `σz` part, `σy ↦ (1|1)`). Wire `q : Fin (m + k)` is the source's
qubit `q + 1`; the source's 1-based generator `M_{i+1}` and logical `X̄_{i+1}` are index `i`.
-/

namespace QAlgorithms

open scoped Matrix

/-- Gottesman thesis p.39 (§4.1) and p.40 (eq. (3.23), cited): the generators with binary rows
`(a|b)` of `(H_x | H_z)` pairwise commute: `a · b′ + b · a′ = 0` over `F₂` for every pair of rows,
i.e. `H_x H_zᵀ + H_z H_xᵀ = 0`. -/
def SymplecticCommuting {m n : ℕ} (Hx Hz : Matrix (Fin m) (Fin n) (ZMod 2)) : Prop :=
  Hx * Hzᵀ + Hz * Hxᵀ = 0

/-- Gottesman thesis p.39 (§4.1, via §3.4): `(H_x | H_z)` is the binary generator matrix of a
stabilizer with `m` independent generators: the rows commute symplectically and the `m` rows
`(a|b) ∈ F₂^{2n}` are linearly independent. -/
def IsBinaryStabilizerMatrix {m n : ℕ} (Hx Hz : Matrix (Fin m) (Fin n) (ZMod 2)) : Prop :=
  SymplecticCommuting Hx Hz ∧ LinearIndependent (ZMod 2) (Matrix.fromCols Hx Hz)

/-- Gottesman thesis p.39 (§4.1, eq. (4.3)): the standard form
```
     r      m−r     k        r     m−r    k
r  [ I      A1      A2   |   B     C1     C2 ]
m−r[ 0      0       0    |   D     I      E  ]
```
with `r ≤ m`: the `σx` half has the identity `I_r` in rows and columns `< r` and zero rows `≥ r`;
the `σz` half has the identity `I_{m−r}` in rows `≥ r` and columns `[r, m)`; the blocks
`A1, A2, B, C1, C2, D, E` are arbitrary. -/
def IsStandardForm {m k : ℕ} (r : ℕ) (Hx Hz : Matrix (Fin m) (Fin (m + k)) (ZMod 2)) : Prop :=
  r ≤ m ∧
    (∀ (i : Fin m) (j : Fin (m + k)), (i : ℕ) < r → (j : ℕ) < r →
      Hx i j = if (i : ℕ) = (j : ℕ) then 1 else 0) ∧
    (∀ (i : Fin m) (j : Fin (m + k)), r ≤ (i : ℕ) → Hx i j = 0) ∧
    (∀ (i : Fin m) (j : Fin (m + k)), r ≤ (i : ℕ) → r ≤ (j : ℕ) → (j : ℕ) < m →
      Hz i j = if (i : ℕ) = (j : ℕ) then 1 else 0)

/-- Gottesman thesis p.41 (§4.2): the tensor product `M_0 ⊗ ⋯ ⊗ M_{n−1}` of one single-qubit
operator per qubit (factor `q` on wire `q`). -/
def kronAll {n : ℕ} (M : Fin n → Matrix Bool Bool ℂ) : Matrix (Qubits n) (Qubits n) ℂ :=
  Matrix.of fun y z => ∏ q, M q (y q) (z q)

/-- Gottesman thesis p.41 (§4.2) with the author's errata: the sign-`+1` Pauli operator of the
binary row `(a|b)` in the real form, `⊗_q σz^{b_q} σx^{a_q}` (`σx` applied first; a `σy` factor is
`σzσx`, the errata's "controlled-XZ"). This is the only convention under which the page's
"performing `σz` after the Hadamard transform" is correct. -/
def rowPauli {n : ℕ} (a b : Fin n → ZMod 2) : Matrix (Qubits n) (Qubits n) ℂ :=
  kronAll fun q => (if b q = 1 then pauliZ else 1) * (if a q = 1 then pauliX else 1)

/-- Gottesman thesis p.40 (§4.1, "Suppose we pick `U3 = I`. Then we can take `V3 = 0`, and by
equation (4.5), `U2 = Eᵀ` and `V1 = EᵀC1ᵀ + C2ᵀ`"): the binary row (`σx` part, `σz` part) of the
standard-form logical `X̄_i`, `i : Fin k`. With the blocks of `H_z` (`C1`: rows `< r`, columns
`[r, m)`; `C2`: rows `< r`, columns `≥ m`; `E`: rows `[r, m)`, columns `≥ m`), the `σx` part is
`0` on columns `< r`, `E_{j−r, i}` on columns `j ∈ [r, m)` and `δ_{ij}` on column `m + j`; the
`σz` part is `(EᵀC1ᵀ + C2ᵀ)_{ij} = Σ_{l ∈ [r, m)} E_{l−r, i} (C1)_{j, l−r} + (C2)_{j i}` on
columns `j < r` and `0` elsewhere. (`H_x` does not enter.) -/
def logicalXRow {m k : ℕ} (r : ℕ) (Hz : Matrix (Fin m) (Fin (m + k)) (ZMod 2)) (i : Fin k) :
    (Fin (m + k) → ZMod 2) × (Fin (m + k) → ZMod 2) :=
  (fun j => if h : (j : ℕ) < m then
      (if r ≤ (j : ℕ) then Hz ⟨j, h⟩ (Fin.natAdd m i) else 0)
    else if (j : ℕ) = m + (i : ℕ) then 1 else 0,
   fun j => if h : (j : ℕ) < r ∧ (j : ℕ) < m then
      (∑ l : Fin m, if r ≤ (l : ℕ) then Hz l (Fin.natAdd m i) * Hz ⟨j, h.2⟩ (Fin.castAdd k l) else 0) +
        Hz ⟨j, h.2⟩ (Fin.natAdd m i)
    else 0)

/-- Gottesman thesis p.40 (§4.1): the standard-form logical operator `X̄_i` (sign `+1`, real
form). -/
def logicalX {m k : ℕ} (r : ℕ) (Hz : Matrix (Fin m) (Fin (m + k)) (ZMod 2)) (i : Fin k) :
    Matrix (Qubits (m + k)) (Qubits (m + k)) ℂ :=
  rowPauli (logicalXRow r Hz i).1 (logicalXRow r Hz i).2

/-- Gottesman thesis p.41 (§4.2, eqs. (4.7)–(4.8)): the encoded basis state
`(I + M_1) ⋯ (I + M_{n−k}) X̄_1^{c_1} ⋯ X̄_k^{c_k} |0 … 0⟩`, unnormalized, with `M_i` the sign-`+1`
operators of the rows of `(H_x | H_z)`. Products are frozen `orderedProd`s; their factors commute,
so the order is immaterial. -/
noncomputable def stabEncodedState {m k : ℕ} (r : ℕ) (Hx Hz : Matrix (Fin m) (Fin (m + k)) (ZMod 2))
    (c : Qubits k) : EuclideanSpace ℂ (Qubits (m + k)) :=
  act (orderedProd fun i : Fin m => 1 + rowPauli (Hx i) (Hz i))
    (act (orderedProd fun i : Fin k => if c i then logicalX r Hz i else 1) (zeroKet (m + k)))

/-- Gottesman thesis pp.41–42 (§4.2): the gates of the encoding network: the Hadamard transform
`R` (4.12), `σz`, and the controlled gates `σz^b σx^a` for `(a, b) ≠ (0, 0)` (controlled-`σx` =
CNOT, controlled-`σz`, controlled-`σzσx`), the control on the first qubit (frozen
`controlled`). -/
def stabEncoderGateSet : Set Gate :=
  {Gate.ofMatrix1 hadamard, Gate.ofMatrix1 pauliZ} ∪
    {g | ∃ a b : Bool, (a, b) ≠ (false, false) ∧
      g = Gate.ofMatrix2 (controlled ((if b then pauliZ else 1) * (if a then pauliX else 1)))}

/-- Gottesman thesis p.42 (§4.2): the controlled gate `σz^b σx^a` with control wire `c` and target
wire `t` (helper for `stabEncoder`). -/
def stabCtrlApp {N : ℕ} (a b : Bool) (hab : (a, b) ≠ (false, false)) (c t : Fin N) (h : c ≠ t) :
    GateApp stabEncoderGateSet N :=
  ⟨Gate.ofMatrix2 (controlled ((if b then pauliZ else 1) * (if a then pauliX else 1))),
    Set.mem_union_right _ ⟨a, b, hab, rfl⟩, Stabilizer.wire2 c t h⟩

theorem castAdd_ne_natAdd {m k : ℕ} (j : Fin m) (i : Fin k) : Fin.natAdd m i ≠ Fin.castAdd k j := by
  intro h
  have := congrArg Fin.val h
  simp only [Fin.coe_natAdd, Fin.coe_castAdd] at this
  omega

/-- Gottesman thesis pp.41–43 (§4.2) with the author's errata: the encoding network as a frozen
`Circuit` (head of the list applied first) on `m + k` wires, input `|0 … 0⟩|c⟩` (`c` on wires
`m, …, m + k − 1`).
1. For each `i < k` and each `j ∈ [r, m)` with `E_{j−r, i} = (H_z)_{j, m+i} = 1`, a CNOT from wire
   `m + i` to wire `j` (the `σx` part of `X̄_i` conditioned on `c_i`; its `σz` part acts trivially
   on `|0⟩`).
2. Then, for `i = 0, …, r − 1` in turn: `R` on wire `i`, `σz` on wire `i` if `B_ii = (H_z)_{ii} = 1`,
   and for every wire `q ≠ i` on which `M_i` acts, the gate `σz^{(H_z)_{iq}} σx^{(H_x)_{iq}}`
   controlled on wire `i` (errata: the Hadamard on qubit `i` immediately precedes its control dots).
No gates for the generators `i ≥ r` (products of `σz`, p.42). -/
noncomputable def stabEncoder {m k : ℕ} (r : ℕ) (Hx Hz : Matrix (Fin m) (Fin (m + k)) (ZMod 2)) :
    Circuit stabEncoderGateSet (m + k) :=
  ((List.finRange k).flatMap fun (i : Fin k) => (List.finRange m).filterMap fun (j : Fin m) =>
      if r ≤ (j : ℕ) ∧ Hz j (Fin.natAdd m i) = 1 then
        some (stabCtrlApp true false (by simp) (Fin.natAdd m i) (Fin.castAdd k j)
          (castAdd_ne_natAdd j i))
      else none) ++
  ((List.finRange m).flatMap fun (i : Fin m) =>
    if (i : ℕ) < r then
      [⟨Gate.ofMatrix1 hadamard, Set.mem_union_left _ (Set.mem_insert _ _),
          Stabilizer.wire1 (Fin.castAdd k i)⟩] ++
      (if Hz i (Fin.castAdd k i) = 1 then
        [⟨Gate.ofMatrix1 pauliZ, Set.mem_union_left _ (Set.mem_insert_of_mem _ rfl),
          Stabilizer.wire1 (Fin.castAdd k i)⟩] else []) ++
      (List.finRange (m + k)).filterMap fun (q : Fin (m + k)) =>
        if h : q ≠ Fin.castAdd k i ∧
            (decide (Hx i q = 1), decide (Hz i q = 1)) ≠ (false, false) then
          some (stabCtrlApp (decide (Hx i q = 1)) (decide (Hz i q = 1)) h.2
            (Fin.castAdd k i) q (Ne.symm h.1))
        else none
    else [])

/-! ### Sanity tests -/

example {n : ℕ} : rowPauli (0 : Fin n → ZMod 2) 0 = 1 := by
  ext y z
  simp [rowPauli, kronAll, Matrix.one_apply, Finset.prod_boole, funext_iff]

example : rowPauli (![1] : Fin 1 → ZMod 2) ![0] = (Gate.ofMatrix1 pauliX).mat := by
  ext y z
  simp [rowPauli, kronAll, Gate.ofMatrix1]

example {k : ℕ} (r : ℕ) (Hx Hz : Matrix (Fin 0) (Fin (0 + k)) (ZMod 2)) :
    stabEncoder r Hx Hz = [] := by
  simp [stabEncoder]

example {k : ℕ} (Hz : Matrix (Fin 0) (Fin (0 + k)) (ZMod 2)) (i : Fin k) (j : Fin (0 + k)) :
    (logicalXRow 0 Hz i).1 j = (if (j : ℕ) = (i : ℕ) then 1 else 0) ∧
      (logicalXRow 0 Hz i).2 j = 0 := by
  simp [logicalXRow]

example {k : ℕ} (Hx Hz : Matrix (Fin 0) (Fin (0 + k)) (ZMod 2)) : IsStandardForm 0 Hx Hz := by
  refine ⟨le_rfl, ?_, ?_, ?_⟩ <;> intro i <;> exact Fin.elim0 i

example : SymplecticCommuting (!![1, 0] : Matrix (Fin 1) (Fin 2) (ZMod 2)) !![0, 1] := by
  unfold SymplecticCommuting
  decide

end QAlgorithms
Source
https://github.com/shiy1022/lean-quantum-complexity/blob/main/algorithms/QAlgorithms/Defs/BinaryStabilizer.lean . Exact primary-source page locators are preserved in the declaration docstrings.

View graph

Get started

Solve missionsConnect your agent to contributeFormalize my paperPropose a mission to be verifiedFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions, with reuse governed by our licensing terms.

How Prove2Me worksResearch paper
SKILL.mdTourFAQContactTerms
© 2026 Prove2Me