Algorithm Search⌘K

Proofs: Bit vector

These are the human proofs of Bit vector, at full length.

Each bit vector operation keeps the invariant and returns the right result full

This proof shows: correctness.

Setting. Fix the word size w≥1w \ge 1 and the universe size n≥0n \ge 0. Let m=⌈n/w⌉m = \lceil n / w \rceil. For 0≤i<n0 \le i < n write q(i)=⌊i/w⌋q(i) = \lfloor i / w \rfloor and r(i)=i mod wr(i) = i \bmod w, so i=q(i)w+r(i)i = q(i) w + r(i) with 0≤q(i)<m0 \le q(i) < m and 0≤r(i)<w0 \le r(i) < w. The map i↦(q(i),r(i))i \mapsto (q(i), r(i)) is one-to-one. A position (j,t)(j, t) with 0≤j<m0 \le j < m, 0≤t<w0 \le t < w is a padding position when jw+t≥njw + t \ge n; then j=m−1j = m - 1, because (m−1)w<n(m - 1) w < n by the choice of mm, so for j≤m−2j \le m - 2 every position satisfies jw+t≤(m−1)w−1<njw + t \le (m - 1) w - 1 < n. Write B[j]tB[j]_t for bit tt of word B[j]B[j].

Invariant for an array BB and a set S⊆{0,…,n−1}S \subseteq \{0, \dots, n - 1\}:

  • (I1) for every 0≤i<n0 \le i < n: i∈S  ⟺  B[q(i)]r(i)=1i \in S \iff B[q(i)]_{r(i)} = 1;
  • (I2) B[j]t=0B[j]_t = 0 for every padding position (j,t)(j, t).

Every position of the array is either the position (q(i),r(i))(q(i), r(i)) of exactly one i<ni < n or a padding position, because the positions (j,t)(j, t) with jw+t<njw + t < n are exactly the images of 0,…,n−10, \dots, n - 1. Hence (I1) and (I2) together say: B[j]t=1B[j]_t = 1 exactly when jw+t∈Sjw + t \in S.

Lemma (one-bit masks). For 0≤t<w0 \le t < w and a ww-bit word xx: (x∨2t)s=1(x \vee 2^t)_s = 1 for s=ts = t and =xs= x_s otherwise; (x∧¬2t)s=0(x \wedge \neg 2^t)_s = 0 for s=ts = t and =xs= x_s otherwise; ((x≫t)∧1)=xt((x \gg t) \wedge 1) = x_t.

Proof. The word 2t2^t has its only 1-bit at position tt, and ¬2t\neg 2^t has its only 0-bit there. OR with 0 and AND with 1 leave a bit unchanged; OR with 1 gives 1 and AND with 0 gives 0. The right shift by tt moves bit tt to bit 0, and AND with 1 keeps only bit 0. □\square

NEW. Line L1 makes all mm words 0. For S=∅S = \emptyset, (I1) says that every bit of a universe element is 0, and (I2) says the same of the padding: both hold.

INSERT(B,i)(B, i) with 0≤i<n0 \le i < n. Assume (I1) and (I2) for SS. Line L2 replaces B[q(i)]B[q(i)] by B[q(i)]∨2r(i)B[q(i)] \vee 2^{r(i)}. By the lemma only position (q(i),r(i))(q(i), r(i)) changes, and it becomes 1. That position belongs to ii and is not a padding position, so (I2) still holds. For k≠ik \ne i the bit of kk is unchanged and k∈S∪{i}  ⟺  k∈Sk \in S \cup \{i\} \iff k \in S, so (I1) holds for kk; for k=ik = i the bit is 1 and i∈S∪{i}i \in S \cup \{i\}. So the invariant holds for S∪{i}S \cup \{i\}.

DELETE(B,i)(B, i) with 0≤i<n0 \le i < n. The same argument with line L3 and the second part of the lemma: only the bit of ii changes, it becomes 0, and the invariant holds for S∖{i}S \setminus \{i\}.

CONTAINS(B,i)(B, i) with 0≤i<n0 \le i < n. By the lemma line L4 returns true exactly when B[q(i)]r(i)=1B[q(i)]_{r(i)} = 1, which by (I1) is i∈Si \in S. Nothing is written.

COUNT. Loop invariant: before the test of line C2 with index jj, c=∑j′<jν(B[j′])c = \sum_{j' < j} \nu(B[j']), where ν\nu is the number of 1-bits. It holds for j=0j = 0 with c=0c = 0 by line C1, and line C3 keeps it. At exit j=mj = m and cc is the number of 1-bits in the array. By (I1) and (I2) the 1-bits are exactly the positions of the members of SS, one per member, so c=∣S∣c = \lvert S \rvert.

NEXT(B,i)(B, i) with i≥0i \ge 0. Let gg be the least member of SS with g≥ig \ge i, or NIL if there is none. If q=⌊i/w⌋≥mq = \lfloor i / w \rfloor \ge m (line N2), then i≥mw≥ni \ge mw \ge n and no member is ≥i\ge i, so NIL is right. Otherwise line N3 sets xx to B[q]B[q] with the bits at positions <i mod w< i \bmod w cleared, because (1≪(i mod w))−1(1 \ll (i \bmod w)) - 1 has 1-bits exactly at those positions. Loop invariant for lines N4 to N7: xx is the word whose 1-bits are exactly the positions tt of word jj with jw+t≥ijw + t \ge i and jw+t∈Sjw + t \in S, and no member of SS lies in [i,jw)[i, jw). Initially j=qj = q and this holds by line N3 and by (I1) and (I2), and [i,qw)[i, qw) is empty since qw≤iqw \le i. If x=0x = 0, word jj has no member ≥i\ge i, so no member lies in [i,(j+1)w)[i, (j + 1) w); lines N5 to N7 move to j+1j + 1 and load the whole word, which is right because every position of word j+1j + 1 is ≥(j+1)w>i\ge (j + 1) w > i. If j+1=mj + 1 = m, then no member lies in [i,mw)⊇[i,n)[i, mw) \supseteq [i, n) and NIL is right. When the loop ends with x≠0x \ne 0, the lowest 1-bit of xx is at position CTZ(x)\mathrm{CTZ}(x), and jw+CTZ(x)j w + \mathrm{CTZ}(x) is the least member ≥i\ge i by the invariant. The loop stops because jj increases and is bounded by mm.

COMPLEMENT. After lines K1 and K2, every bit of the array is inverted. So for 0≤i<n0 \le i < n the bit of ii is 1 exactly when i∉Si \notin S, which is (I1) for {0,…,n−1}∖S\{0, \dots, n - 1\} \setminus S, and every padding bit is 1. If n mod w=0n \bmod w = 0 there are no padding positions, because then mw=nmw = n. Otherwise the padding positions are the bits t≥n mod wt \ge n \bmod w of B[m−1]B[m - 1], since (m−1)w+t≥n  ⟺  t≥n−(m−1)w=n mod w(m - 1) w + t \ge n \iff t \ge n - (m - 1) w = n \bmod w. Line K3 ANDs B[m−1]B[m - 1] with 2n mod w−12^{n \bmod w} - 1, which clears exactly these bits and keeps the others, so (I2) holds and (I1) is not affected.

UNION(A,B)(A, B). Both arrays satisfy the invariant over the same nn, for sets SS and TT. Lines K4 and K5 set each bit of AA to the OR of the bits at the same position. For 0≤i<n0 \le i < n the new bit is 1 exactly when i∈Si \in S or i∈Ti \in T, which is (I1) for S∪TS \cup T. A padding bit is the OR of two zeros by (I2), so it stays 0. Intersection and difference are the same argument with AND, and with AND of the complement; a padding bit of AA is 0 and stays 0.

Conclusion. NEW establishes the invariant, each operation that writes keeps it for the new set, and each operation that reads returns the value the abstract type asks for, given the invariant. By induction on the number of operations, every sequence of operations from NEW returns correct answers. ■\blacksquare

Back to Bit vector