Proofs: Unrolled linked list
These are the human proofs of Unrolled linked list, at full length.
The unrolled linked list keeps its invariant and implements the list type full
This proof shows: correctness.
Claim. Let and . If the invariant (U1) to (U3) holds before an operation, then GET for returns ; INSERT for leaves the sequence ; DELETE for returns and leaves ; and the invariant holds afterwards.
Setup. The nodes are with counts , and is the number of items before node . By (U1), node holds the positions to at its offsets 0 to . The invariant is:
(U1) the arrays of , read in order, form ; (U2) for each ; (U3) if then for each .
Since , , and .
Lemma 1 (FIND). Let and . FIND returns with (nil for ) and , where if , and , if .
Proof. The loop of lines L2 and L3 keeps: , , , and . This holds at the start with , . A step runs only when , and it sets and moves to , so the statement holds for . Each step increases by 1 and the loop stops at the latest when , since then ; so it stops after at most steps. At the exit, either , so satisfies ; or and , so , hence and . If , the second case is impossible, so . If , the first case would give , a contradiction, so and .
GET and SET. For , Lemma 1 gives the node and an offset with , which by (U1) is the cell of . Line L5 returns it. Neither changes the structure of the nodes, so the invariant holds.
Lemma 2 (INSERT). If the list is empty, line L6 makes one node holding , which satisfies (U1) to (U3) with . Else let FIND return with and (by Lemma 1).
Case 1, . Line L11 shifts the items at offsets to up by one and writes at offset . Read in order, the arrays now give , which is the new sequence. The count becomes , and no count drops, so (U2) and (U3) hold.
Case 2, . Line L9 moves the last items of to a new node placed after , so keeps items and the order of (U1) is unchanged. Both new counts and are at least . If , position is at offset of , which now has items. If , position is at offset of , and ; line L10 selects this node. Then line L11 inserts as in Case 1, and the chosen node gets or items (because and ). The nodes and now hold between and items. Every other node keeps its old count, which is between and by (U2) and (U3), since the old list had and at least one more node; when the old was 1 there is no other node. So (U2) and (U3) hold with nodes.
Lemma 3 (DELETE). Let FIND return , with , , and . Line L13 returns by (U1) and shifts the later items of down, so the arrays read in order give the new sequence, and the count of is .
Case 1, , or . If , all counts are still between and . If (that is, and ) and , (U3) does not apply. If and , line L14 removes the node and the list is empty with . In each case the invariant holds.
Case 2, and . Since by (U3), the count of is exactly . Line L15 picks two adjacent nodes before , one of them : the successor of if it exists, else the predecessor , which exists since . Let be the other node of the pair; by (U3), has items.
If , line L16 appends the items of to . Since follows , the order of (U1) is unchanged. The merged node has items (as ) and at most . The list now has nodes; if every count is still at least , and if (U3) does not apply. So the invariant holds.
If , then , because . Line L17 moves one item from to : the first item of to the end of when , or the last item of to the front of when . In both cases the moved item stays between the items of and the items of , so the order of (U1) is unchanged. Now has items and has items, both at most , so (U2) and (U3) hold.
Conclusion. The empty list (no node, ) satisfies the invariant. By Lemmas 2 and 3 and the paragraph on GET, every operation returns the value the list type asks for and keeps the invariant. By induction on the number of operations, any sequence of operations from the empty list behaves as the abstract list.