Algorithm Search⌘K

Proofs: Rope

These are the human proofs of Rope, at full length.

The rope operations keep the invariant and compute concatenation, split and indexing full

This proof shows: correctness.

We use the representation, the invariant (R1) and (R2), and the pseudocode of the page. Write h(NIL)=−1h(\text{NIL}) = -1 and len(NIL)=0len(\text{NIL}) = 0, and text(NIL)=εtext(\text{NIL}) = \varepsilon.

Lemma 1 (rotations). Let uu be a node whose children are balanced trees (each satisfies (R1) and (R2)) with heights differing by at most 2. Then BALANCE(uu) returns a tree satisfying (R1) and (R2) with the same text, whose height is h(u)h(u) or h(u)−1h(u) - 1.

Proof. NODE computes lenlen and hh from the children, so (R1) holds for every node that BALANCE builds. A rotation replaces ((A B) C)((A\,B)\,C) by (A (B C))(A\,(B\,C)) or the reverse, which keeps the left-to-right order of the subtrees A,B,CA, B, C, so the text is the same. The rest is the standard case analysis of AVL rebalancing after an insertion: if the taller child, say the left one with height k+2k + 2 against kk for the right, has its left child of height k+1k + 1, one right rotation gives children of heights k+1k + 1 and k+1k + 1 or k+2k + 2 at the root, with all lower nodes balanced; if its left child has height kk and its right child height k+1k + 1, the double rotation gives a root with children of heights k+1k + 1 and k+1k + 1. If the children of uu differ by at most 1, BALANCE returns uu. □\square

Lemma 2 (CONCAT). If aa and bb satisfy (R1) and (R2), CONCAT(aa, bb) returns a tree cc that satisfies (R1) and (R2), with text(c)=text(a)⋅text(b)text(c) = text(a) \cdot text(b) and max⁡(h(a),h(b))≤h(c)≤max⁡(h(a),h(b))+1\max(h(a), h(b)) \le h(c) \le \max(h(a), h(b)) + 1, unless one of them is NIL, in which case cc is the other one.

Proof. By induction on ∣h(a)−h(b)∣\lvert h(a) - h(b) \rvert. Line L5 is clear. In line L6, the new node is balanced and has height max⁡+1\max + 1. (Merging two leaves into one leaf when their total length is at most LL is also correct: the text is the concatenation, and the height 0 is the maximum.) In line L7, h(a)≥h(b)+2h(a) \ge h(b) + 2, so aa is an inner node, and h(a.right)≥h(a)−2≥h(b)h(a.right) \ge h(a) - 2 \ge h(b); the difference h(a.right)−h(b)h(a.right) - h(b) is smaller than h(a)−h(b)h(a) - h(b), so by the induction hypothesis $c' = $ CONCAT(a.righta.right, bb) is balanced, has text text(a.right)⋅text(b)text(a.right) \cdot text(b), and has height h(a.right)h(a.right) or h(a.right)+1h(a.right) + 1. Since h(a.left)∈{h(a)−2,h(a)−1}h(a.left) \in \{h(a) - 2, h(a) - 1\} and h(a.right)∈{h(a)−2,h(a)−1}h(a.right) \in \{h(a) - 2, h(a) - 1\}, the heights of a.lefta.left and c′c' differ by at most 2, and Lemma 1 applies. The text of NODE(a.lefta.left, c′c') is text(a.left)⋅text(a.right)⋅text(b)=text(a)⋅text(b)text(a.left) \cdot text(a.right) \cdot text(b) = text(a) \cdot text(b). Its height is 1+max⁡(h(a.left),h(c′))≤h(a)+11 + \max(h(a.left), h(c')) \le h(a) + 1 and at least h(a)h(a), and BALANCE lowers it by at most 1 only when the node was unbalanced, which can happen only when h(c′)=h(a)h(c') = h(a), so the result has height at least h(a)h(a). Line L8 is symmetric. □\square

Lemma 3 (SPLIT). If tt satisfies (R1) and (R2) and 0≤i≤len(t)0 \le i \le len(t), SPLIT(tt, ii) returns (x,y)(x, y), both satisfying (R1) and (R2), with text(x)=text(t)[0..i−1]text(x) = text(t)[0 .. i-1] and text(y)=text(t)[i..]text(y) = text(t)[i ..].

Proof. By induction on the height of tt. For a leaf, line L9 cuts its string; the pieces are nonempty or dropped as NIL, and shorter than LL, so (R1) holds. For an inner node with i≤len(t.left)i \le len(t.left), the induction hypothesis splits text(t.left)text(t.left) into text(x)text(x) and text(y)text(y) at ii, and by Lemma 2, CONCAT(yy, t.rightt.right) is balanced with text text(t.left)[i..]⋅text(t.right)=text(t)[i..]text(t.left)[i ..] \cdot text(t.right) = text(t)[i ..]. The case i>len(t.left)i > len(t.left) is symmetric, with the offset i−len(t.left)i - len(t.left) into t.rightt.right, which is in range since i≤len(t)i \le len(t). □\square

CHAR-AT. The loop keeps the claim that the answer is character ii of text(t)text(t) and 0≤i<len(t)0 \le i < len(t). If i<len(t.left)i < len(t.left), character ii of text(t)=text(t.left)⋅text(t.right)text(t) = text(t.left) \cdot text(t.right) is character ii of text(t.left)text(t.left); otherwise it is character i−len(t.left)i - len(t.left) of text(t.right)text(t.right), which is less than len(t.right)len(t.right). By (R1) the stored lengths are correct. At a leaf, line L4 returns the character. The loop ends because the depth decreases.

INSERT and DELETE. By Lemma 3, line L12 gives xx and yy with text(x)⋅text(y)=text(t)text(x) \cdot text(y) = text(t) split at ii; BUILD(ss) is a perfectly balanced tree, where the two halves of each node differ by at most one leaf and so their heights differ by at most 1, with leaves of length at most LL; and by Lemma 2 the two concatenations give a balanced tree with text text(t)[0..i−1]⋅s⋅text(t)[i..]text(t)[0 .. i-1] \cdot s \cdot text(t)[i ..]. For DELETE, the two splits give xx with the first ii characters and zz with the characters from position jj on, and line L15 joins them. No operation modifies an existing node, so all earlier ropes keep their texts. ■\blacksquare

Back to Rope