Why GF(2) Gaussian Elimination / XOR Basis Matters
Imagine switches that toggle lights. Pressing a switch twice cancels its effect, and only the parity of the press count matters. Each light's final state becomes an equation in bits. Gaussian elimination over the two-element field $\mathrm{GF}(2)$ finds whether the target state is reachable, one valid switch selection, and every alternative selection.
A related question starts with integer bit masks: which values can be formed by XORing a subset of them? An XOR basis keeps only independent masks. It supports exact membership tests, rank, and maximum subset XOR without enumerating every subset. Both algorithms are linear algebra over the same field, organized for different queries.
We will trace a binary system with a necessary row swap and one free variable, then build an XOR basis from its row masks. The programs implement both approaches in Python, C++, and Java, using exact checks rather than floating-point tolerances. They also distinguish dependence from inconsistency, a distinction that matters whenever right-hand sides are present.
Over $\mathrm{GF}(2)$, addition and subtraction are XOR, and the only nonzero pivot is $1$. Elimination solves parity equations; an XOR basis compresses a set of bit vectors while preserving every subset XOR that can be formed.
Core Concepts and Terminology
The field $\mathrm{GF}(2)=\{0,1\}$ uses arithmetic modulo $2$. Its addition table is XOR: $1+1=0$. Multiplication of bits is AND. There are no carries, approximate zeros, or numerical conditioning decisions. Every nonzero pivot is already $1$, so pivot normalization requires no division.
For an $m\times n$ binary matrix $A$ and bit vector $b$, the system $Ax=b$ means
$$ \bigoplus_{j=0}^{n-1}(A_{ij}\mathbin{\land}x_j)=b_i \quad\text{for every row }i. $$
The coefficient rank $r$ is the number of independent pivot rows. If the system is consistent, there are $d=n-r$ free variables and exactly $2^d$ solutions. A particular solution $x^{(0)}$ and a nullspace basis $h_1,\ldots,h_d$ describe them all:
$$ x=x^{(0)}\oplus t_1h_1\oplus\cdots\oplus t_dh_d, \qquad t_i\in\{0,1\}. $$
A row with all-zero coefficients and right side $0$ is redundant. The same coefficient row with right side $1$ is a contradiction. The nullspace depends only on $A$ and still exists even when the affine system is inconsistent.
An integer mask is a vector of bits. In an XOR basis, slots[k] is either zero, meaning empty, or a mask whose highest set bit is $k$. Distinct leading bits ensure independence. With rank $r$, the span has exactly $2^r$ distinct values, including zero from the empty subset.
For the same row masks, the XOR basis spans the row space of $A$, whereas solving $Ax=0$ finds its nullspace. These are different spaces. To recover which source masks XOR to a target, place the source vectors as columns of a separate system, or track selection witnesses during basis insertion.
The SageMath GF(2) matrix reference documents exact augmented binary matrices and reduced elimination, including classical and optimized M4RI-based algorithms. Our code uses simple arrays to expose each row operation.
| Term | Meaning | Sample role |
|---|---|---|
| GF(2) addition | XOR, written $\oplus$ | $1\oplus1=0$ |
| GF(2) multiplication | AND for individual bits | A zero coefficient removes a variable from the parity |
| Pivot column | Column with a selected leading $1$ | Sample coefficient pivots are columns $0$ and $1$ |
| Rank $r$ | Number of independent coefficient rows | Sample rank is $2$ |
| Free variable | Variable without a coefficient pivot | Sample $x_2$ may be $0$ or $1$ |
| Nullspace basis | Independent vectors satisfying $Ah=0$ | One sample basis vector is $(1,1,1)^T$ |
| Inconsistent row | Zero coefficients with right side $1$ | Represents the impossible equation $0=1$ |
| XOR basis slot | Stored vector keyed by its highest set bit | Slot $2$ stores binary $110$; slot $1$ stores $011$ |
| Dependent mask | Reduces to zero using stored vectors | $101\oplus110\oplus011=000$ |
| Reachable XORs | All XOR combinations of basis vectors | $\{000,011,101,110\}$ |
| Distinct values versus subsets | $2^r$ different results, possibly with repeated representations | Three rank-two inputs have eight subsets but only four results |
How GF(2) Gaussian Elimination / XOR Basis Works, Step by Step
Binary Gauss–Jordan elimination. Copy the augmented rows $[A\mid b]$. Maintain a pivot-row index initially equal to zero, and scan coefficient columns from left to right:
- Search the remaining rows for a $1$ in the current column. If none exists, skip that column; it will be a free variable.
- Swap the selected row into the pivot position. Swap the entire augmented row, including its right-hand side.
- For every other row containing a $1$ in that pivot column, XOR the entire pivot row into it. The pivot entry cancels because $1\oplus1=0$.
- Record the pivot column and advance the pivot row. Earlier pivot columns remain identity columns because the new pivot row is zero in those columns.
- After coefficient elimination, reject consistency if any zero coefficient row has right side $1$. The algorithm does not use the right-hand-side column as a coefficient pivot.
- If consistent, set all free variables to zero and read the pivot variables from their right sides. To build a nullspace basis vector for free column $f$, set its coordinate to $1$, all other free coordinates to zero, and each pivot coordinate to that pivot row's coefficient in column $f$. In characteristic two, subtraction equals addition.
The returned rows have a reduced coefficient block with the right side carried along. For an inconsistent input, they need not be the full reduced row echelon form obtained by also pivoting on the augmented column; the contradiction test is what matters.
Incremental XOR basis. For a new mask $x$, scan bits from high to low. If its current bit is set and a basis vector exists there, XOR that vector into $x$ to clear the bit. If the slot is empty, store the reduced $x$ there and increase rank. If every bit is cleared, the input was already in the span and adds no independent direction.
Membership applies the same reduction without modifying the basis. An unmatched highest bit proves nonmembership. A reduction to zero proves membership. The query $0$ is always reachable, even for an empty basis.
For maximum subset XOR, start with zero and scan the slots high to low. Replace the answer by its XOR with the current basis vector only when that increases its numeric value. A lower-pivot vector cannot change an already decided higher bit, so the greedy decision is valid for nonnegative fixed-width masks.
flowchart TD
A["Validate exact binary inputs"] --> B{"Task?"}
B -->|System| C["Search remaining rows for next coefficient pivot"]
C --> D{"Pivot found?"}
D -->|Yes| E["Swap entire augmented rows; XOR pivot into other rows"]
D -->|No| F["Skip column"]
E --> G{"More coefficient columns and rows?"}
F --> G
G -->|Yes| C
G -->|No| H["Check contradictions; construct particular and nullspace"]
B -->|Basis insertion| I["Inspect next highest bit"]
I --> J{"Current bit set?"}
J -->|No| O{"More lower bits?"}
J -->|Yes| P{"Slot occupied?"}
P -->|Yes| K["XOR stored vector to clear bit"]
K --> O
P -->|No| L["Store reduced vector; increase rank; finish"]
O -->|Yes| I
O -->|No| M["Zero remainder: dependent input"]
Worked Example with a Full Trace
Use variables $x_0,x_1,x_2$ and
$$ A=\begin{pmatrix}0&1&1\\1&1&0\\1&0&1\end{pmatrix}, \qquad b=\begin{pmatrix}1\\1\\0\end{pmatrix}. $$
The equations are $x_1\oplus x_2=1$, $x_0\oplus x_1=1$, and $x_0\oplus x_2=0$. The leftmost displayed coefficient maps to the highest bit when these rows are viewed as three-bit masks.
Initial augmented state:
$$ \left(\begin{array}{ccc|c}0&1&1&1\\1&1&0&1\\1&0&1&0\end{array}\right). $$
Column $0$: choose and swap a pivot. Row $0$ has a zero in this column, so choose row $1$ and swap them:
$$ \left(\begin{array}{ccc|c}1&1&0&1\\0&1&1&1\\1&0&1&0\end{array}\right). $$
Clear the bottom row's leading $1$ by $R_2\leftarrow R_2\oplus R_0$. Its full augmented contents become $(1,0,1,0)\oplus(1,1,0,1)=(0,1,1,1)$:
$$ \left(\begin{array}{ccc|c}1&1&0&1\\0&1&1&1\\0&1&1&1\end{array}\right). $$
Column $1$: use row $1$ as pivot. First clear it from row $0$ using $R_0\leftarrow R_0\oplus R_1$:
$$ \left(\begin{array}{ccc|c}1&0&1&0\\0&1&1&1\\0&1&1&1\end{array}\right). $$
Then clear it from row $2$ using $R_2\leftarrow R_2\oplus R_1$:
$$ \left(\begin{array}{ccc|c}1&0&1&0\\0&1&1&1\\0&0&0&0\end{array}\right). $$
Column $2$: no remaining pivot. The only unused row is zero, so this column is free. There is no contradiction. Rank is $2$, and $x_2=t$ gives $x_0=t$, $x_1=1\oplus t$. The two solutions are
$$ x^{(0)}=(0,1,0)^T, \qquad x^{(0)}\oplus(1,1,1)^T=(1,0,1)^T. $$
The nullspace is spanned by $(1,1,1)^T$, and the solution count is $2^{3-2}=2$. Substituting either solution into the original three equations yields residual zero.
XOR basis from the coefficient row masks. Read the same rows as the stream $011_2=3$, $110_2=6$, $101_2=5$:
| Input | Exact reductions | Result | Occupied slots after insertion |
|---|---|---|---|
| $011$ | Highest bit is $1$ and slot $1$ is empty | Store $011$; rank $1$ | $B_1=011$ |
| $110$ | Highest bit is $2$ and slot $2$ is empty | Store $110$; rank $2$ | $B_2=110$, $B_1=011$ |
| $101$ | $101\oplus110=011$, then $011\oplus011=000$ | Dependent; rank stays $2$ | $B_2=110$, $B_1=011$ |
The span is $\{000,011,101,110\}$, so there are $2^2=4$ distinct values. To test $101$, XOR $110$ and then $011$, reaching zero. To test $111$, XOR $110$ to get $001$; slot $0$ is empty, so $111$ is unreachable.
For the maximum, start at $000$, use slot $2$ to reach $110=6$, then decline the slot-$1$ change because $110\oplus011=101=5$ is smaller. The maximum is $6$.
A single changed right side. Replace only the third right-hand side by $1$. The same coefficient operations produce a last row $[0,0,0\mid1]$, so there are no solutions. The coefficient rank and coefficient XOR basis remain $2$; knowing their rank alone cannot decide consistency.
Trace It by Hand
After the first pivot, the bottom two augmented rows are both $[0,1,1\mid1]$. Predict their XOR. Reveal: every entry cancels, giving $[0,0,0\mid0]$, a redundant equation.
Now change the bottom right-hand side to zero before that XOR. Check: the coefficient bits still cancel, but the right sides produce $1$, yielding a contradiction. Explain why an XOR basis of coefficient masks alone cannot distinguish these outcomes.
For the stream $3,6,5$, how many subsets produce each reachable value? Answer: $2^{3-2}=2$. This counts selections of the three input positions, whereas the four distinct XOR values count outputs. The empty subset and the full subset both produce zero.
Implementation in Python, C++, and Java
Each panel is a complete program implementing both a binary Gauss–Jordan solver and an XOR basis. Run Python 3, compile C++14 or newer, or save Java as Main.java. The system solver accepts a nonempty rectangular matrix of integer bits and a matching right side, preserves both inputs, and returns coefficient rank, consistency, a particular solution, a nullspace basis, and the transformed augmented rows. For an inconsistent system, the particular-solution array is empty, while the nullspace basis still describes $Ax=0$.
All pivot and residual checks are exact. A floating-point tolerance is inappropriate for this field: a bit is either zero or one. Inputs outside the bit domain are rejected instead of being silently reduced modulo two. The sample verifies the particular solution against original $A,b$ and checks every returned nullspace vector against a zero right side.
The XOR basis supports widths from $1$ to $62$ and nonnegative values smaller than $2^W$. This shared range avoids signed-order and sign-bit differences between C++ and Java. C++ uses uint64_t; Java uses long with 1L shifts; Python enforces the same range despite its larger integers. The matrix solver does not share this $62$-variable bound, since its rows use separate bit entries.
Insertion returns whether rank increased. Membership and maximum queries do not modify the basis. Inserting zero or a dependent mask returns false. The sample prints counts as powers of two, avoiding an overflowing fixed-width count when a system has many free variables. The residual helper assumes compatible binary inputs and is called only on returned solutions or nullspace vectors.
All three programs print the same twelve lines:
system rank = 2status = multipleparticular = [0, 1, 0]nullspace = [[1, 1, 1]]solution count = 2^1GF(2) residual = 0basis rank = 2contains 5 = truecontains 7 = falsemaximum subset XOR = 6distinct subset XORs = 2^2check = PASS
Complexity, Correctness, and Invariants
Let the system have $m$ equations, $n$ variables, coefficient rank $r$, and nullity $d=n-r$. Validation and copying take $O(mn)$. The code searches for pivots and, for each pivot, may XOR a complete augmented row into up to $m-1$ other rows. Elimination therefore costs $O(mn+rmn)$. Explicitly returning the $d$ length-$n$ nullspace vectors adds $O(nd)$ time and storage. Total storage is $O(mn+nd)$ for transformed rows and output vectors.
For square $n\times n$ input, best cases such as the identity take $\Theta(n^2)$ because the XOR updates are skipped when a pivot column is already clear. The worst case is $\Theta(n^3)$. Uniformly random dense binary square matrices have expected cubic work for this elementary representation; sparse or structured inputs need their own analysis. Even the all-zero system returns a length-$n$ basis of $n$ vectors, so its output alone occupies $\Theta(n^2)$ space.
For a $W$-bit XOR basis, insertion and membership take $O(W)$ word operations, and maximum takes $\Theta(W)$. An insertion can finish immediately if its top bit finds an empty slot; dependent or zero values may scan all slots. Building from $N$ masks costs $O(NW)$ and stores $O(W)$ words. These word-operation bounds apply to the bounded masks used here; arbitrary-width big integers have costs that grow with their represented size.
| Approach | Time pattern | Space | Best fit and limitation |
|---|---|---|---|
| Unpacked binary Gauss–Jordan here | $O(mn+rmn+nd)$ including explicit nullspace output | $O(mn+nd)$ | Particular solutions, contradictions, and full solution families |
| Packed-bit elimination | Row XOR touches $\lceil(n+1)/w\rceil$ machine words for word size $w$ | Packed rows plus requested outputs | Same algebra with parallel bit operations |
| XOR basis here | $O(NW)$ build; $O(W)$ membership or maximum | $O(W)$ words | Span queries on masks; no automatic affine consistency or source witness |
| Exhaustive variable assignments | $O(2^nmn)$ for direct checking | Small working state if streamed | Independent oracle for small systems; exponential growth |
| Exhaustive subset XORs | $O(N2^N)$ naive word XORs, or $O(2^N)$ incremental XORs plus set costs | Up to $2^r$ stored results | Small-input checking; unnecessary when only rank, membership, or maximum is needed |
For elimination, row swapping is invertible, and XORing one row into another is its own inverse. Applying these operations to the entire augmented matrix preserves exactly the set of solutions. After each pivot, completed pivot columns are identity columns; a new row operation preserves them because the new pivot row is zero there. At termination, each free assignment determines every pivot variable, unless a contradiction exists.
The nullspace construction sets a distinct free coordinate to one for each basis vector, so these vectors are independent. Any homogeneous solution is determined by its free coordinates and is the XOR combination of the corresponding basis vectors. Adding a particular solution translates this homogeneous space into the full affine solution family, establishing the count $2^{n-r}$ for consistent systems.
For the XOR basis, each reduction $x\leftarrow x\oplus B_k$ preserves the span of the old basis together with $x$. If the remainder is zero, the input was already in the span. If it has a leading bit with an empty slot, no old combination can equal it, so insertion adds one independent direction. Distinct leading bits also justify membership reduction and imply exactly $2^r$ distinct combinations.
Finally, in the maximum query, a pivot vector's highest bit is the first bit it can change. All lower-pivot vectors leave that bit unchanged. Choosing the larger current value fixes the best attainable value of that bit while preserving the already chosen higher prefix, proving the greedy maximum.
Whole augmented-row operations preserve the system's solution set, while XOR-basis reductions preserve the span of the inserted masks. Distinct pivot positions supply independence; free coordinates describe all system solutions, and highest-bit pivots support exact membership and greedy maximum queries.
Variants, Pitfalls, and Optimizations
XOR is not OR or ordinary addition. Binary $011\oplus110=101$, whereas $011\mathbin{\lor}110=111$. OR does not cancel a shared pivot bit and can invent an unreachable value. Ordinary integer addition introduces carries and also computes a different operation. Use AND to multiply individual coefficient bits, then XOR to combine their contributions.
The right side must follow the row. Swapping or XORing only coefficients changes the affine system. Redundant coefficients can accompany either a redundant equation or a contradiction, depending on the right side. The solver's rank is coefficient rank, not augmented rank; with one right-hand-side column, an inconsistent system has augmented rank $r+1$.
A basis is not a list of original vectors or witnesses. A stored pivot can be the XOR of several inputs. To recover a subset, attach a selection mask to each vector and XOR those masks during the same reductions. To find a witness for a target from scratch, solve the system with source masks as columns. Extra provenance changes storage costs, especially for many source positions.
Representation order matters. The system solver scans columns left to right, while the packed basis scans highest numeric bits first. The sample maps the leftmost coefficient to the highest bit. Other conventions work if used consistently. The slot array is an echelon basis rather than a fully reduced canonical basis; different insertion orders may store different vectors with the same span. The descending greedy maximum needs only the distinct-highest-bit property used here.
Counts answer different questions. Rank $r$ gives $2^r$ distinct subset XORs. If $N$ indexed inputs were inserted, every reachable value has $2^{N-r}$ subset representations, including effects of duplicates and zero inputs. System solutions instead use the nullity of their coefficient matrix. Do not use any of these counts as a consistency test.
Scale the implementation with the problem. Pack augmented rows into bitsets for faster XOR, carrying the RHS bit too. Dense libraries use blocked methods such as M4RI; sparse elimination can still create fill-in. A static basis supports merging by inserting another basis's vectors, but deleting an arbitrary original value is not supported by this simple structure. Dynamic settings may need rollback, timestamps, or offline processing. A $k$-th sorted subset-XOR query requires additional ordering or reduction logic; the maximum routine alone does not provide it.
Use XOR cancellation, carry the right side through every row operation, and check for $0=1$ before counting solutions. Keep variable and bit ordering explicit, distinguish subset counts from distinct values, and respect the chosen integer width when shifting or comparing masks.
Practice Problems and Real-World Use
For small systems, enumerate every binary assignment independently and compare that set with the returned particular solution plus all nullspace combinations. Test unique, multiple, and inconsistent outcomes; include zero rows, duplicate equations with opposite right sides, and a pivot requiring a swap. For small streams, enumerate all indexed subsets and compare the distinct XOR set, maximum, and membership results.
For larger masks, test the top supported bit and boundary values explicitly. Preserve the system inputs and verify that queries leave the basis unchanged. A useful bridge test converts each coefficient row to a mask and confirms that its XOR-basis rank equals the matrix coefficient rank, while remembering that span membership and affine consistency are different queries.
| Exercise or application | Concrete task or checkpoint | Main idea | Difficulty |
|---|---|---|---|
| Full hand trace | Recover the two sample solutions $(0,1,0)^T$ and $(1,0,1)^T$ | Row swap, XOR elimination, and one free variable | Beginner |
| Contradictory duplicate | Solve $x_0=0$ and $x_0=1$ and return no solution | Zero coefficient row with right side one | Beginner |
| Subset-XOR stream | Insert $3,6,5$; obtain rank $2$, maximum $6$, and four distinct values | Incremental dependence and greedy maximum | Intermediate |
| Source-subset witness | Recover which masks produce target $5$ | Provenance tracking or a system with source vectors as columns | Intermediate |
| Toggle puzzle | Model switch effects as columns and target changes as the right side | Linear parity modeling and alternative solutions | Applied |
| Binary-code syndrome | Solve $He=s$ over GF(2), then impose any additional decoding objective | Parity-check constraints; elimination alone does not minimize error weight | Advanced |
| Graph cycle space | Build independent cycles using edge-incidence bit vectors | XOR combinations and cycle-space rank | Intermediate |
| XOR constraints | Solve a collection of parity clauses and count satisfying assignments | Linear XORSAT rather than general Boolean SAT | Applied |