Algorithm Search⌘K

Proofs: Fully indexable dictionary

These are the human proofs of Fully indexable dictionary, at full length.

The queries of the fully indexable dictionary are correct full

This proof shows: correctness.

Let S⊆U={0,…,u−1}S \subseteq U = \{0, \ldots, u-1\} with ∣S∣=n|S| = n, and let BB be its characteristic vector. Write s1<s2<⋯<sns_1 < s_2 < \cdots < s_n for the elements of SS. We assume that the primitives are correct: ACCESS(x)=B[x](x) = B[x], RANK1(r)=∣{y<r:B[y]=1}∣(r) = |\{y < r : B[y] = 1\}|, SELECT1(i)=si(i) = s_i and SELECT0(k)(k) is the kk-th smallest element of U∖SU \setminus S. These are the queries of the rank and select problem on BB.

MEMBER, RANK, SELECT (lines L1 to L3). x∈Sx \in S if and only if B[x]=1B[x] = 1, so line L1 is correct. RANK1(r)\text{RANK1}(r) counts the y<ry < r with B[y]=1B[y] = 1, which are the elements of SS less than rr, so line L2 is correct. Line L3 returns sis_i by assumption.

PRED (lines L4 to L6). Let 0≤x<u0 \le x < u and r=RANK1(x+1)=∣{y∈S:y≤x}∣r = \text{RANK1}(x + 1) = |\{y \in S : y \le x\}|. The elements of SS that are ≤x\le x are exactly s1,…,srs_1, \ldots, s_r: they are the rr smallest elements of SS, because if si≤xs_i \le x then si′≤xs_{i'} \le x for each i′<ii' < i. If r=0r = 0, no element is ≤x\le x, and line L5 returns none, which is right. If r≥1r \ge 1, the largest of them is srs_r, and line L6 returns SELECT1(r)=sr(r) = s_r.

SUCC (lines L7 to L9). Let r=RANK1(x)=∣{y∈S:y<x}∣r = \text{RANK1}(x) = |\{y \in S : y < x\}|. By the same argument, the elements less than xx are s1,…,srs_1, \ldots, s_r, so the elements ≥x\ge x are sr+1,…,sns_{r+1}, \ldots, s_n. If r=nr = n, there is none, and line L8 returns none. Otherwise the smallest is sr+1s_{r+1}, which line L9 returns; SELECT1(r+1)(r + 1) is defined because 1≤r+1≤n1 \le r + 1 \le n.

RANK-OUT (line L10). Each yy with 0≤y<r0 \le y < r is in exactly one of SS and U∖SU \setminus S, so ∣{y∉S:y<r}∣=r−∣{y∈S:y<r}∣=r−RANK1(r)|\{y \notin S : y < r\}| = r - |\{y \in S : y < r\}| = r - \text{RANK1}(r).

SELECT-OUT (line L11). The kk-th smallest element of U∖SU \setminus S is the position of the kk-th 0 of BB, which SELECT0(k)(k) returns by assumption.

The primitives of the implementation. The Python code keeps BB in packed words with the count RS[q]RS[q] of 1s before superblock qq of 88 words. Its rank adds RS[q]RS[q], the counts of the full words of the superblock before word ⌊r/w⌋\lfloor r/w \rfloor, and the count of the low r mod wr \bmod w bits of that word, which together cover {0,…,r−1}\{0, \ldots, r-1\} exactly. Its select first finds by binary search the last superblock qq with fewer than jj wanted bits before it. Such a qq exists since superblock 0 has none before it, and the wanted bit is in superblock qq or later; it is not later, because the next superblock already has at least jj wanted bits before it, or does not exist. It then scans words from the start of superblock qq as in the SELECT1 of the bit vector, with the padding of the last word masked off for 0s. ■\blacksquare

Back to Fully indexable dictionary