Algorithm Search⌘K

Proofs: XOR swap

These are the human proofs of XOR swap, at full length.

The XOR swap exchanges two distinct cells and leaves one cell unchanged full

This proof shows: correctness.

Fix a word size w≥1w \ge 1 and let W={0,1}wW = \{0,1\}^w. For a,b∈Wa, b \in W, a⊕ba \oplus b is the word whose bit tt is at+bt mod 2a_t + b_t \bmod 2, for 0≤t<w0 \le t < w.

Lemma (laws of XOR). For all a,b,c∈Wa, b, c \in W: (1) (a⊕b)⊕c=a⊕(b⊕c)(a \oplus b) \oplus c = a \oplus (b \oplus c); (2) a⊕b=b⊕aa \oplus b = b \oplus a; (3) a⊕0=aa \oplus 0 = a; (4) a⊕a=0a \oplus a = 0.

Proof. Each law is an equation between two words, so it is enough to check it at each bit position tt. At position tt the operation is addition modulo 2 on {0,1}\{0, 1\}. Addition modulo 2 is associative and commutative, at+0=ata_t + 0 = a_t, and at+at=2at≡0(mod2)a_t + a_t = 2a_t \equiv 0 \pmod 2. □\square

The laws hold for any reading of the words, signed or unsigned, because they are about bit patterns.

Theorem. Let AA be a memory of ww-bit cells. Let x=A[i]x = A[i] and y=A[j]y = A[j] before the call XOR-SWAP(A,i,j)(A, i, j). After the call, A[i]=yA[i] = y and A[j]=xA[j] = x when i≠ji \ne j, A[i]=xA[i] = x when i=ji = j, and no other cell changes.

Proof. Lines L2 to L4 write only to A[i]A[i] and A[j]A[j], and line L1 writes nothing, so no other cell changes.

Case i=ji = j. Line L1 returns before any write, so A[i]=xA[i] = x.

Case i≠ji \ne j. Then A[i]A[i] and A[j]A[j] are different cells, and a write to one does not change the other. We follow the two cells.

  1. Line L2 sets A[i]=x⊕yA[i] = x \oplus y. The cell A[j]A[j] still holds yy.
  2. Line L3 sets A[j]=(x⊕y)⊕yA[j] = (x \oplus y) \oplus y. By (1), this is x⊕(y⊕y)x \oplus (y \oplus y); by (4), it is x⊕0x \oplus 0; by (3), it is xx. The cell A[i]A[i] still holds x⊕yx \oplus y.
  3. Line L4 sets A[i]=(x⊕y)⊕xA[i] = (x \oplus y) \oplus x. By (2) and (1), this is y⊕(x⊕x)y \oplus (x \oplus x); by (4) and (3), it is yy. The cell A[j]A[j] still holds xx.

So A[i]=yA[i] = y and A[j]=xA[j] = x. □\square

Why line L1 is needed. Remove line L1 and let i=ji = j, with A[i]=xA[i] = x. Line L2 sets A[i]=x⊕x=0A[i] = x \oplus x = 0 by (4). Line L3 then sets A[i]=0⊕0=0A[i] = 0 \oplus 0 = 0, and line L4 does the same. So the cell ends with 0, and the result is wrong for each x≠0x \ne 0. For x=0x = 0 the result happens to be right.

Termination and cost. There is no loop. The procedure runs at most one comparison and three XOR assignments, so it stops after a constant number of steps. ■\blacksquare

Back to XOR swap