The de Bruijn bit scan returns the index of the lowest 1-bit full
This proof shows: correctness.
Fix n≥1 and the word size w=2n. Words are integers in [0,2w), bit t of a word a is ⌊a/2t⌋mod2, and −a means (2w−a)mod2w. For x=0 let ρ(x) be the least t with bit t of x equal to 1.
Lemma 1 (isolation). For 0<x<2w with k=ρ(x), x∧(−x)=2k.
Proof. Write x=h⋅2k+1+2k with 0≤h<2w−k−1; this is possible because bits 0 to k−1 of x are 0 and bit k is 1. Then x=(2w−1)−x has bits 0 to k−1 equal to 1, bit k equal to 0, and bits above k equal to the complements of those of x. Adding 1 to x turns its k low 1-bits into 0-bits with a carry into bit k, which becomes 1, and the carry stops there. So −x=x+1mod2w has bits 0 to k−1 equal to 0, bit k equal to 1, and each bit above k the complement of the same bit of x. In x∧(−x) the bits below k are 0, bit k is 1, and each bit above k is a∧a=0. So x∧(−x)=2k. □
Windows. For a word D and 0≤k<w, let wink(D)=((2kD)mod2w)≫(w−n), an integer in [0,2n). Write d0d1…dw−1 for the bits of D read from the top, so dj is bit w−1−j of D. Extend the indices cyclically: dj=djmodw.
Lemma 2 (window). For 0≤k<w, the n bits of wink(D), from the top, are ck,ck+1,…,ck+n−1, where cj=dj for j<w and cj=0 for j≥w.
Proof. Multiplying by 2k moves bit t of D to bit t+k, and the reduction modulo 2w deletes the bits that reach position w or more; positions 0 to k−1 become 0. The shift by w−n keeps positions w−1 down to w−n of the product, as the top n bits of the result in the same order. Position w−1−m of the product, for 0≤m<n, holds bit w−1−m−k of D if w−1−m−k≥0, which is dk+m, and holds 0 otherwise, that is when k+m≥w. So the bit at place m from the top of wink(D) is ck+m. □
Lemma 3 (distinct windows). Let the cyclic sequence d0…dw−1 be a binary de Bruijn sequence of order n, that is, the w cyclic windows (dk,dk+1,…,dk+n−1) for 0≤k<w are the 2n binary words of length n, each once. Suppose also d0=d1=⋯=dn−1=0. Then win0(D),…,winw−1(D) are pairwise distinct.
Proof. By Lemma 2, wink(D) has bits ck,…,ck+n−1. For an index j=k+m with k<w and m<n, if j<w then cj=dj, and if j≥w then j−w<n, so dj=dj−w=0=cj by the hypothesis on the top n bits. Hence cj=dj for every index used, and wink(D) is the k-th cyclic window of the de Bruijn sequence. These w windows are pairwise distinct by definition. □
The hypothesis can always be met: a de Bruijn sequence contains the window 0n once, and its rotation that starts there has n leading zeros and is again a de Bruijn sequence.
Table. Under the condition of Lemma 3 the map k↦wink(D) is injective from {0,…,w−1} into {0,…,2n−1}, a set with 2n=w elements, so it is a bijection. The table filled by T[wink(D)]←k for k=0,…,w−1 therefore writes each entry exactly once and satisfies T[wink(D)]=k for every k.
Theorem. Let D and T be as above and 0<x<2w. Then DE-BRUIJN-SCAN(x) returns ρ(x).
Proof. Let k=ρ(x). By Lemma 1, line L1 sets b=2k. Line L2 sets p=(2kD)mod2w, and line L3 sets i=p≫(w−n)=wink(D). Line L4 returns T[wink(D)]=k by the property of the table. □
Remark (zero). For x=0, x∧(−x)=0, so i=0 and the procedure returns T[0]=T[win0(D)]=0, which is ρ(1). The precondition x=0 is needed.
Termination. The procedure has four lines and no loop, and the table is built by a loop of w iterations, so both stop. ■