Algorithm Search⌘K

Proofs: Sklansky adder

These are the human proofs of Sklansky adder, at full length.

The Sklansky adder computes the sum full

This proof shows: correctness, termination.

Let aa, bb, c0c_0, gig_i, pip_i and the carries ci+1=gi∨(pi∧ci)c_{i+1} = g_i \vee (p_i \wedge c_i) be as on the page of the Kogge-Stone adder, whose proof shows three facts that we use here.

  1. For a block k..ik..i of positions there is a pair (Gi:k,Pi:k)(G_{i:k}, P_{i:k}) such that the carry out of position ii is Gi:k∨(Pi:k∧x)G_{i:k} \vee (P_{i:k} \wedge x) when the carry into position kk is xx, and (Gk:k,Pk:k)=(gk,pk)(G_{k:k}, P_{k:k}) = (g_k, p_k).
  2. For adjacent blocks, (Gi:k,Pi:k)=(Gi:j+1,Pi:j+1)∘(Gj:k,Pj:k)(G_{i:k}, P_{i:k}) = (G_{i:j+1}, P_{i:j+1}) \circ (G_{j:k}, P_{j:k}) for k≤j<ik \le j < i.
  3. After line L2 replaces g0g_0 by g0∨(p0∧c0)g_0 \vee (p_0 \wedge c_0), the GG part of the block 0..i0..i equals ci+1c_{i+1}, and a+b+c0=∑i<n(pi⊕ci)2i+cn2na + b + c_0 = \sum_{i<n} (p_i \oplus c_i)2^i + c_n2^n.

Lemma. Let 0≤lo<hi≤n0 \le lo < hi \le n, and suppose that before the call PREFIX(lo,hi)(lo, hi), (G[i],P[i])=(gi,pi)(G[i], P[i]) = (g_i, p_i) for every i∈[lo,hi)i \in [lo, hi). Then the call terminates, it changes no position outside [lo,hi)[lo, hi), and afterwards (G[i],P[i])=(Gi:lo,Pi:lo)(G[i], P[i]) = (G_{i:lo}, P_{i:lo}) for every i∈[lo,hi)i \in [lo, hi). The depth of the recursion below the call is ⌈log⁡2(hi−lo)⌉\lceil \log_2 (hi - lo) \rceil.

Proof. By strong induction on ℓ=hi−lo≥1\ell = hi - lo \ge 1.

If ℓ=1\ell = 1, line L7 returns at once, and (G[lo],P[lo])=(glo,plo)=(Glo:lo,Plo:lo)(G[lo], P[lo]) = (g_{lo}, p_{lo}) = (G_{lo:lo}, P_{lo:lo}). The recursion depth is 0=⌈log⁡21⌉0 = \lceil \log_2 1 \rceil.

If ℓ≥2\ell \ge 2, line L8 sets mid=lo+⌈ℓ/2⌉mid = lo + \lceil \ell/2 \rceil, so lo<mid<hilo < mid < hi, and both ranges [lo,mid)[lo, mid) and [mid,hi)[mid, hi) are shorter than ℓ\ell and disjoint. By the induction hypothesis the two calls of line L9 terminate, each changes only its own range, and afterwards position ii holds (Gi:lo,Pi:lo)(G_{i:lo}, P_{i:lo}) for lo≤i<midlo \le i < mid and (Gi:mid,Pi:mid)(G_{i:mid}, P_{i:mid}) for mid≤i<himid \le i < hi. Since the ranges are disjoint, the order in which the two calls run does not matter, so they may run in parallel.

Line L10 reads the pair at mid−1mid - 1, which is (Gmid−1:lo,Pmid−1:lo)(G_{mid-1:lo}, P_{mid-1:lo}) and is not changed by line L10, since mid−1<midmid - 1 < mid. For each i∈[mid,hi)i \in [mid, hi) it sets the pair at ii to

(Gi:mid,Pi:mid)∘(Gmid−1:lo,Pmid−1:lo)=(Gi:lo,Pi:lo)(G_{i:mid}, P_{i:mid}) \circ (G_{mid-1:lo}, P_{mid-1:lo}) = (G_{i:lo}, P_{i:lo})

by fact 2 with j=mid−1j = mid - 1. So every position of [lo,hi)[lo, hi) holds the block starting at lolo, and nothing outside [lo,hi)[lo, hi) changed.

The two halves have lengths ⌈ℓ/2⌉\lceil \ell/2 \rceil and ⌊ℓ/2⌋\lfloor \ell/2 \rfloor, and ⌈log⁡2⌈ℓ/2⌉⌉=⌈log⁡2ℓ⌉−1\lceil \log_2 \lceil \ell/2 \rceil \rceil = \lceil \log_2 \ell \rceil - 1 for ℓ≥2\ell \ge 2, so the recursion depth below the call is 1+(⌈log⁡2ℓ⌉−1)=⌈log⁡2ℓ⌉1 + (\lceil \log_2 \ell \rceil - 1) = \lceil \log_2 \ell \rceil. □\square

Theorem. SKLANSKY-ADD terminates and returns the n+1n + 1 bits of a+b+c0a + b + c_0.

Proof. For n=0n = 0 the result is the single bit c0c_0. For n≥1n \ge 1, line L3 sets (G[i],P[i])=(gi,pi)(G[i], P[i]) = (g_i, p_i) for all ii, with g0g_0 already updated by line L2, so the lemma applies to PREFIX(0,n)(0, n): it terminates, with recursion depth ⌈log⁡2n⌉\lceil \log_2 n \rceil, and leaves (Gi:0,Pi:0)(G_{i:0}, P_{i:0}) at every position. By fact 3, G[i]=ci+1G[i] = c_{i+1}, so line L4 sets the true carries, and line L5 computes si=pi⊕cis_i = p_i \oplus c_i. By fact 3 again, ∑i<nsi2i+cn2n=a+b+c0\sum_{i<n} s_i2^i + c_n2^n = a + b + c_0. ■\blacksquare

Back to Sklansky adder