Proofs: Fully persistent array
These are the human proofs of Fully persistent array, at full length.
The path-copying array returns the right value in every version and uses O(log n) time and space per write full
This proof shows: correctness, termination, complexity.
We use the definitions of the page, with . For integers , a tree for is a leaf if , and otherwise a node whose left child is a tree for and whose right child is a tree for , with . Since gives , both ranges are non-empty and shorter than . For a tree for and an index , let be the leaf reached from by going to the left child when and to the right child otherwise, and let be its value. The invariant of the page says that for every version and index .
Lemma 1 (BUILD). For , BUILD returns a tree for with for every , made of new nodes.
Proof. By induction on . If it is 1, line L1 returns a leaf for that holds . Otherwise, by the hypothesis, line L3 returns a node whose children are trees for and with the right values. For , is the leaf of in the left child, which holds , and likewise for on the right. The number of nodes is .
Lemma 2 (GET). If is a tree for and , GET returns after at most iterations.
Proof. At the start of each iteration of line L5, is the node for on the path to from the root , and . This holds at line L4. If , lines L6 and L7 move to the child whose range contains , which is the next node on the path by the definition of leaf, and keep . Each iteration replaces by or , so after iterations , and the loop stops after at most iterations with . Then is , and line L8 returns its value.
Lemma 3 (SET). If is a tree for and , then SET returns a tree for such that and for every with . It changes no existing node and builds one new node for each node on the path from to , which is at most nodes.
Proof. By induction on . If it is 1, then is impossible in , and line L9 returns a new leaf holding . Otherwise suppose ; the case is symmetric with line L12. By the hypothesis applied to the left child, which is a tree for that contains , the call returns a tree for with that agrees with the old left child on every other leaf. Line L11 returns a new node with children and the old right child, which is a tree for . For or , the path goes left and the claim follows from the hypothesis. For , the path goes right, into the old right child, so . Lines L9, L11 and L12 only build new nodes and read fields of old ones, so no existing node changes. The count of new nodes is one per level of the path, and the path has at most nodes by the halving argument of Lemma 2.
Theorem. After any sequence of UPDATE calls on any existing versions, the invariant holds: for every version and every . GET takes time, each UPDATE takes time and adds at most nodes, and after versions the structure holds at most nodes.
Proof. By induction on the number of updates. Version 0 satisfies the invariant by Lemma 1. Suppose it holds for versions , and UPDATE creates version , defined by and for . By Lemma 3, the new root of line L13 satisfies and for . No existing node changed, so for every older version , the leaves reached from hold the same values as before, and the invariant still holds for . Lemma 2 then gives the claim about GET. The time and the node counts follow from Lemmas 1 to 3, since every line does work besides the recursive calls.