Algorithm Search⌘K

Proofs: Catenable deque

These are the human proofs of Catenable deque, at full length.

The catenable deque operations keep the invariant, compute the right sequences and run in the stated time full

This proof shows: correctness, termination, complexity.

We use the definitions of the page. For an element xx of level kk, items(x)\text{items}(x) is ⟨x⟩\langle x \rangle if k=0k = 0, and the concatenation of the items of its children otherwise. For a tuple tt of elements, items(t)\text{items}(t) is the concatenation of the items of its elements. For a c-deque, seq(Shallow(d))=items(d)\text{seq}(\text{Shallow}(d)) = \text{items}(d) and seq(Deep(f,m,r))=items(f)⋅seq(m)⋅items(r)\text{seq}(\text{Deep}(f, m, r)) = \text{items}(f) \cdot \text{seq}(m) \cdot \text{items}(r). A valid c-deque of level kk is a c-deque of level kk that satisfies (C1) to (C3). Its depth is the number of Deep levels on its spine: 0 for Shallow, and 1+depth(m)1 + \text{depth}(m) for Deep(f,m,r)\text{Deep}(f, m, r). A valid c-deque is empty exactly when it is Shallow()\text{Shallow}(), because a Deep one has at least 2 elements in its front.

No line of the pseudocode writes into a tuple or a node that exists before the call: every result is a new node whose parts are new or old. So every earlier version keeps its sequence, and it suffices to prove the claims about the results.

Lemma 1 (CONS). If qq is a valid c-deque of level kk and xx an element of level kk, then CONS(x,q)(x, q) returns a valid c-deque of level kk with sequence items(x)⋅seq(q)\text{items}(x) \cdot \text{seq}(q), after at most depth(q)+1\text{depth}(q) + 1 calls of CONS.

Proof. By induction on depth(q)\text{depth}(q). Line L1 returns a Shallow tuple of at most 4 elements. Line L2 returns a Deep c-deque with a front of 2 and a rear of 3 elements and an empty middle, which is valid, and its sequence is items(x,a)⋅items(b,c,e)\text{items}(x, a) \cdot \text{items}(b, c, e), as required. Otherwise q=Deep(f,m,r)q = \text{Deep}(f, m, r). If ∣f∣<4|f| < 4, line L4 makes a front of 3 or 4 elements. If f=(a,b,c,e)f = (a, b, c, e), the tuple (b,c,e)(b, c, e) is an element of level k+1k + 1 by (C1), and mm is a valid c-deque of level k+1k + 1 of depth depth(q)−1\text{depth}(q) - 1. By the hypothesis, the call of line L6 returns a valid c-deque m′m' of level k+1k + 1 with seq(m′)=items(b,c,e)⋅seq(m)\text{seq}(m') = \text{items}(b, c, e) \cdot \text{seq}(m), after at most depth(q)\text{depth}(q) calls. The new front (x,a)(x, a) has 2 elements, and the sequence is items(x,a)⋅items(b,c,e)⋅seq(m)⋅items(r)=items(x)⋅seq(q)\text{items}(x, a) \cdot \text{items}(b, c, e) \cdot \text{seq}(m) \cdot \text{items}(r) = \text{items}(x) \cdot \text{seq}(q). □\square

By symmetry, SNOC(q,x)(q, x) returns a valid c-deque with sequence seq(q)⋅items(x)\text{seq}(q) \cdot \text{items}(x) after at most depth(q)+1\text{depth}(q) + 1 calls.

Lemma 2 (HEAD and TAIL). If qq is a non-empty valid c-deque of level kk, then HEAD(q)(q) is an element of level kk, TAIL(q)(q) is a valid c-deque of level kk, items(HEAD(q))⋅seq(TAIL(q))=seq(q)\text{items}(\text{HEAD}(q)) \cdot \text{seq}(\text{TAIL}(q)) = \text{seq}(q), and TAIL makes at most depth(q)+1\text{depth}(q) + 1 calls of TAIL.

Proof. By induction on depth(q)\text{depth}(q). HEAD returns the first element of dd or of ff. Line L7 drops the first element of a non-empty Shallow tuple. Otherwise q=Deep(f,m,r)q = \text{Deep}(f, m, r) and HEAD(q)(q) is the first element aa of ff. If ∣f∣>2|f| > 2, line L9 leaves a front of 2 or 3 elements. Otherwise f=(a,b)f = (a, b) (line L10). If mm is not empty, the hypothesis applies to mm, of smaller depth: g=HEAD(m)g = \text{HEAD}(m) is an element of level k+1k + 1, a tuple of 2 or 3 elements of level kk by (C1), and TAIL(m)(m) is valid with items(g)⋅seq(TAIL(m))=seq(m)\text{items}(g) \cdot \text{seq}(\text{TAIL}(m)) = \text{seq}(m). The front b⋅gb \cdot g of line L11 has 3 or 4 elements, and the sequence of the result is items(b)⋅items(g)⋅seq(TAIL(m))⋅items(r)=items(b)⋅seq(m)⋅items(r)\text{items}(b) \cdot \text{items}(g) \cdot \text{seq}(\text{TAIL}(m)) \cdot \text{items}(r) = \text{items}(b) \cdot \text{seq}(m) \cdot \text{items}(r), which is seq(q)\text{seq}(q) without items(a)\text{items}(a). If mm is empty, seq(q)=items(a)⋅items(b)⋅items(r)\text{seq}(q) = \text{items}(a) \cdot \text{items}(b) \cdot \text{items}(r), and s=b⋅rs = b \cdot r has 1+∣r∣1 + |r| elements, from 3 to 5. Line L13 returns it as a Shallow tuple if it has at most 4, and line L14 splits 5 elements into a front of 2 and a rear of 3. In both cases the sequence is items(s)\text{items}(s). □\square

By symmetry, LAST and INIT satisfy the mirror statement.

Lemma 3 (PUSH-FRONT and PUSH-BACK). If dd is a tuple of 2 to 4 elements of level kk and mm a valid c-deque of level k+1k + 1, then PUSH-FRONT(d,m)(d, m) is a valid c-deque of level k+1k + 1 with sequence items(d)⋅seq(m)\text{items}(d) \cdot \text{seq}(m), and PUSH-BACK(m,d)(m, d) is one with sequence seq(m)⋅items(d)\text{seq}(m) \cdot \text{items}(d). Each makes at most two calls of CONS or SNOC at the top, and the c-deques they apply to have depth at most depth(m)+1\text{depth}(m) + 1.

Proof. If ∣d∣≤3|d| \le 3, dd is itself an element of level k+1k + 1, and line L15 is Lemma 1. If d=(d1,d2,d3,d4)d = (d_1, d_2, d_3, d_4), the pairs (d1,d2)(d_1, d_2) and (d3,d4)(d_3, d_4) are elements of level k+1k + 1, and two uses of Lemma 1 give the sequence items(d1,d2)⋅items(d3,d4)⋅seq(m)\text{items}(d_1, d_2) \cdot \text{items}(d_3, d_4) \cdot \text{seq}(m). A CONS adds at most one Deep level, since only line L2 turns a Shallow c-deque into a Deep one, at the bottom of the spine. PUSH-BACK is symmetric. □\square

Lemma 4 (FROM-TUPLE). For a tuple ss of at most 8 elements of level kk, FROM-TUPLE(s)(s) is a valid c-deque of level kk with sequence items(s)\text{items}(s).

Proof. If ∣s∣≤4|s| \le 4, it is a Shallow tuple. If 5≤∣s∣≤85 \le |s| \le 8, the front has ⌊∣s∣/2⌋\lfloor |s|/2 \rfloor and the rear ⌈∣s∣/2⌉\lceil |s|/2 \rceil elements, both between 2 and 4, and the middle is empty. □\square

Lemma 5 (CAT). If q1q_1 and q2q_2 are valid c-deques of level kk, then CAT(q1,q2)(q_1, q_2) returns a valid c-deque of level kk with sequence seq(q1)⋅seq(q2)\text{seq}(q_1) \cdot \text{seq}(q_2).

Proof. By induction on ∣seq(q1)∣|\text{seq}(q_1)|, the number of items in q1q_1. Line L17: ∣d1∣+∣d2∣≤8|d_1| + |d_2| \le 8, so Lemma 4 applies. Lines L18 to L20: q2=Deep(f2,m2,r2)q_2 = \text{Deep}(f_2, m_2, r_2). If ∣d∣=0|d| = 0, the result is q2q_2; if ∣d∣=1|d| = 1, it is CONS of the one element onto q2q_2, by Lemma 1. If 2≤∣d∣≤42 \le |d| \le 4, dd is a valid front, and by Lemma 3 PUSH-FRONT(f2,m2)(f_2, m_2) is a valid c-deque of level k+1k + 1 with sequence items(f2)⋅seq(m2)\text{items}(f_2) \cdot \text{seq}(m_2). The sequence of the result is items(d)⋅items(f2)⋅seq(m2)⋅items(r2)=seq(q1)⋅seq(q2)\text{items}(d) \cdot \text{items}(f_2) \cdot \text{seq}(m_2) \cdot \text{items}(r_2) = \text{seq}(q_1) \cdot \text{seq}(q_2). Lines L21 to L23 are symmetric. Line L24: both are Deep. By Lemma 3, p1=PUSH-BACK(m1,r1)p_1 = \text{PUSH-BACK}(m_1, r_1) and p2=PUSH-FRONT(f2,m2)p_2 = \text{PUSH-FRONT}(f_2, m_2) are valid of level k+1k + 1, with sequences seq(m1)⋅items(r1)\text{seq}(m_1) \cdot \text{items}(r_1) and items(f2)⋅seq(m2)\text{items}(f_2) \cdot \text{seq}(m_2). The c-deque p1p_1 holds the items of q1q_1 except those of f1f_1, and f1f_1 is not empty, so ∣seq(p1)∣<∣seq(q1)∣|\text{seq}(p_1)| < |\text{seq}(q_1)|, and the hypothesis applies to CAT(p1,p2)(p_1, p_2). The result has sequence items(f1)⋅seq(m1)⋅items(r1)⋅items(f2)⋅seq(m2)⋅items(r2)\text{items}(f_1) \cdot \text{seq}(m_1) \cdot \text{items}(r_1) \cdot \text{items}(f_2) \cdot \text{seq}(m_2) \cdot \text{items}(r_2), which is seq(q1)⋅seq(q2)\text{seq}(q_1) \cdot \text{seq}(q_2). □\square

The induction also proves that every call terminates: each recursive call of CONS and TAIL is on a c-deque of smaller depth, and each recursive call of CAT is on a first argument with fewer items.

Lemma 6 (depth). A valid c-deque of level 0 with n≥1n \ge 1 items has depth at most lg⁡n−1\lg n - 1 when it is Deep. More generally, if a valid c-deque of level kk with NN items is Deep, then N≥2k+2N \ge 2^{k+2}.

Proof. An element of level jj holds at least 2j2^j items, by induction on jj with (C1). A Deep c-deque of level kk has at least 4 elements of level kk in its front and rear, so N≥4⋅2kN \ge 4 \cdot 2^k. If a c-deque of level 0 has depth D≥1D \ge 1, the c-deque at the bottom of its spine of Deep levels is Deep of level D−1D - 1 and holds at most nn items, so n≥2D+1n \ge 2^{D+1}. □\square

Theorem. On valid c-deques with at most nn items, CONS, SNOC, TAIL and INIT take O(log⁡n)O(\log n) time in the worst case, HEAD and LAST O(1)O(1), and CAT(q1,q2)(q_1, q_2) takes O((1+log⁡min⁡(n1,n2))⋅(1+log⁡(n1+n2)))O\big((1 + \log \min(n_1, n_2)) \cdot (1 + \log(n_1 + n_2))\big), where n1n_1 and n2n_2 are the sizes of q1q_1 and q2q_2. Each operation builds O(1)O(1) new nodes and tuples of O(1)O(1) size per unit of time, so the space of mm operations is O(n0+their total time)O(n_0 + \text{their total time}).

Proof. Every line except the recursive calls does O(1)O(1) work, because tuples have at most 8 elements. By Lemmas 1 and 2, CONS and TAIL make at most depth(q)+1\text{depth}(q) + 1 calls, which is O(log⁡n)O(\log n) by Lemma 6. In CAT, consider the call at nesting level kk that reaches line L24. Its arguments are valid of level kk and hold at most n1n_1 and n2n_2 items, since every recursive argument holds a subset of the items of the argument above it. Both are Deep, so by Lemma 6 min⁡(n1,n2)≥2k+2\min(n_1, n_2) \ge 2^{k+2}, and there are at most 1+lg⁡min⁡(n1,n2)1 + \lg \min(n_1, n_2) levels of recursion. Each level does at most four calls of CONS or SNOC, inside PUSH-BACK and PUSH-FRONT, or in lines L19 and L22, on c-deques of at most n1+n2n_1 + n_2 items, each O(log⁡(n1+n2))O(\log(n_1 + n_2)) by Lemmas 1 and 6. ■\blacksquare

Back to Catenable deque