Algorithm Search⌘K

Proofs: Skew binary random-access list

These are the human proofs of Skew binary random-access list, at full length.

The skew binary random-access list implements a persistent list full

This proof shows: correctness.

Setting. A version is a list of pairs (w1,t1),…,(wm,tm)(w_1, t_1), \ldots, (w_m, t_m). For a complete tree tt let pre(t)\text{pre}(t) be its items in preorder, and let the items of the version be pre(t1)⋯pre(tm)\text{pre}(t_1) \cdots \text{pre}(t_m). The version is good if (I1) each wj=2kj−1w_j = 2^{k_j} - 1 with kj≥1k_j \ge 1 and tjt_j is a complete tree with wjw_j nodes, (I2) w1≤w2<w3<⋯<wmw_1 \le w_2 < w_3 < \cdots < w_m, and (I3) ∑jwj=n\sum_j w_j = n.

Lemma 1 (cons). If ss is good with items XX, then CONS(x,s)(x, s) is good with items ⟨x⟩⋅X\langle x \rangle \cdot X.

Proof. Case m≥2m \ge 2 and w1=w2=w=2k−1w_1 = w_2 = w = 2^k - 1 (lines L1 and L2). The new tree Node(x,t1,t2)\text{Node}(x, t_1, t_2) is complete with 1+2w=2k+1−11 + 2w = 2^{k+1} - 1 nodes, and its preorder is ⟨x⟩⋅pre(t1)⋅pre(t2)\langle x \rangle \cdot \text{pre}(t_1) \cdot \text{pre}(t_2), so the items are right. By (I2), w3>ww_3 > w, and w3w_3 is of the form 2k′−12^{k'} - 1 with k′>kk' > k, so w3≥2k+1−1w_3 \ge 2^{k+1} - 1. If w3=2k+1−1w_3 = 2^{k+1} - 1, the new list starts with two equal weights, which (I2) allows; any later weights are larger than w3w_3. So (I2) holds, and (I3) holds with n+1n + 1. Otherwise (line L3), the new first weight is 1. If m≥1m \ge 1 and w1=1w_1 = 1, then w2>1w_2 > 1 (because the first case did not apply), so after the new weight 1 the sequence is 1,1,w2,…1, 1, w_2, \ldots with w2>1w_2 > 1, and (I2) holds. If w1>1w_1 > 1 or m=0m = 0, (I2) is clear. The items are ⟨x⟩⋅X\langle x \rangle \cdot X. □\square

Lemma 2 (head and tail). If ss is good and not empty, HEAD(s)(s) is its first item, and TAIL(s)(s) is good with the other items.

Proof. The first item is the first item of pre(t1)\text{pre}(t_1), which is the root of t1t_1 (line L4). If w1=1w_1 = 1 (line L6), dropping t1t_1 removes exactly that item, and a suffix of a sequence that satisfies (I2) satisfies it. Otherwise t1=Node(x,l,r)t_1 = \text{Node}(x, l, r) with ll and rr complete of weight h=(w1−1)/2=2k−1−1≥1h = (w_1 - 1)/2 = 2^{k-1} - 1 \ge 1 (line L7), and pre(t1)=⟨x⟩⋅pre(l)⋅pre(r)\text{pre}(t_1) = \langle x \rangle \cdot \text{pre}(l) \cdot \text{pre}(r), so the new items are right. The new weights are h,h,w2,…h, h, w_2, \ldots; since w2≥w1>hw_2 \ge w_1 > h, (I2) holds. (I3) holds with n−1n - 1. □\square

Lemma 3 (tree walk). Let tt be complete with weight ww and 0≤i<w0 \le i < w. The loop of lines L10 to L12 ends at the node that holds item ii of pre(t)\text{pre}(t).

Proof. By induction on ww. If i=0i = 0 the item is the root. Otherwise t=Node(x,l,r)t = \text{Node}(x, l, r) with ll and rr of weight h=⌊w/2⌋h = \lfloor w/2 \rfloor. In preorder, positions 1,…,h1, \ldots, h are the items of ll, at positions 0,…,h−10, \ldots, h - 1 of pre(l)\text{pre}(l), and positions h+1,…,w−1h + 1, \ldots, w - 1 are the items of rr, at positions 0,…,h−10, \ldots, h - 1 of pre(r)\text{pre}(r). Line L12 goes to ll with i−1i - 1 when i≤hi \le h, and to rr with i−1−hi - 1 - h otherwise, and both are in range for a tree of weight hh. The claim follows by induction. □\square

Lemma 4 (lookup and update). If ss is good and 0≤i<n0 \le i < n, LOOKUP(s,i)(s, i) returns item ii, and UPDATE(s,i,y)(s, i, y) returns a good version whose items are those of ss with item ii set to yy, while ss is unchanged.

Proof. Line L8 keeps the item of the current index the same: skipping the tree tjt_j removes its wjw_j items from the front, and lowers ii by wjw_j. It stops at the first tree with i<wji < w_j, which exists by (I3) because i<ni < n. Lemma 3 finishes LOOKUP. UPDATE follows the same walk (line L14), makes a new node with item yy and the same children (line L15), and copies each node on the path with the new child in place of the old one (line L16). The new tree has the same shape, so it is complete of weight wjw_j, and its preorder differs from the old one only at item ii. Line L17 rebuilds the cells in front with the same weights and trees. So the new version is good and has the right items. No line writes to an existing node or cell, so ss is unchanged. □\square

Theorem. Every version made by the operations is good, every operation returns the result of the abstract persistent list on its argument, and no operation changes an existing version.

Proof. The empty list is good, with no items. By Lemmas 1, 2 and 4 and induction on the number of operations, every version is good and has the items of the abstract list. All operations build new cells and nodes that point to old ones and never write to existing memory, so each old version keeps its items. ■\blacksquare

Back to Skew binary random-access list