Proofs: XOR linked list
These are the human proofs of XOR linked list, at full length.
The XOR linked list keeps its invariant and returns the right keys full
This proof shows: correctness.
Claim. Assume the invariant (X) before an operation. Then each of PUSH-FRONT, POP-FRONT (on a list that is not empty), REVERSE, PUSH-BACK, POP-BACK and INSERT-BETWEEN (on two adjacent nodes before ) leaves a list that satisfies (X) and holds the right sequence of keys; the two pops return the key that the deque asks for; and TRAVERSE visits the keys from the front to the back and stops.
Setup. The list holds the nodes in order, with keys , and . No node has address 0, and distinct nodes have distinct addresses. The invariant is
(X) for ; and when ; when .
We use that is associative and commutative, and . Hence (cancellation). To prove (X) for a new sequence it is enough to check the link of each node whose predecessor or successor differs from before, since the link of every other node is not written and its neighbours are the same.
Lemma 1 (PUSH-FRONT). The new sequence is , where is the new node, with key . Line L1 gives an address that is not 0 and not in use. Line L2 sets . If , then , so , which is (X) for the one node ; line L4 sets and line L5 sets . If , then , as (X) asks for . The node now has predecessor instead of 0. Line L3 sets , as (X) asks for . No other node has a new neighbour. Line L5 sets , and is still the last node.
Lemma 2 (POP-FRONT). Here , and the new sequence is . Line L6 sets and, by (X), . If , then , line L8 sets and line L9 sets , which is (X) for the empty list. If , the node now has predecessor 0 instead of , and line L7 sets , as (X) asks. Line L9 sets , and the tail is unchanged. No other node has a new neighbour. Line L10 returns , the front key, and frees , which is no longer in the list.
Lemma 3 (TRAVERSE). We show by induction on that at the -th test of line L12, for , and . For , line L11 sets and (which is 0 when ). Assume the statement for some . Then , so the body runs, line L13 visits , and line L14 sets by (X) and cancellation. Line L15 sets and , which is the statement for . So the loop visits in this order. At the test number , and the loop stops; it cannot stop earlier because for .
Lemma 4 (REVERSE, PUSH-BACK, POP-BACK). Let , so and . For , by commutativity. After line R1, and (both 0 when ). So the list satisfies (X) for the reversed sequence: REVERSE reverses the list. PUSH-BACK reverses, inserts at the front by Lemma 1, and reverses again; the result is the sequence followed by the new node, and it satisfies (X) by Lemmas 1 and 4. POP-BACK reverses, removes and returns the front key of the reversed list by Lemma 2, which is , and reverses again; the result is and satisfies (X).
Lemma 5 (INSERT-BETWEEN). Let and with . The new sequence is . Line B2 sets , which is (X) for . The node has the new successor instead of ; line B3 sets . The node has the new predecessor instead of ; line B4 sets . No other node has a new neighbour, and and are not the ends of the new list, so head and tail stay right.
Conclusion. The empty list (, no node) satisfies (X). By Lemmas 1, 2, 4 and 5, each update keeps (X) and changes the key sequence as the deque operations require, and by Lemmas 2 and 4 each pop returns the key at its end. By Lemma 3, TRAVERSE reads the keys in order. By induction on the number of operations, every sequence of operations from the empty list gives the same results as an abstract deque.