Proofs: Persistent trie
These are the human proofs of Persistent trie, at full length.
The persistent trie keeps every version and answers counts and maximum XOR correctly full
This proof shows: correctness.
Fix . For a node and a depth with , call well formed at depth if either and , or and both children are well formed at depth with . The node is well formed at every depth, since its count is 0 and it is its own child. For well formed at depth and a string of bits, write for the node reached by following , and define the multiset in which each has multiplicity . A version root is well formed at depth 0, and its multiset is read with the bits of a key, from bit down.
Lemma 1. If is well formed at depth , then , the total multiplicity, and for a prefix of length , is the number of elements of that start with .
Proof. By induction on , from the additivity of counts at each inner node.
Lemma 2 (add). Let be well formed at depth 0, a key, and an integer with . Then ADD returns a root that is well formed at depth 0 with changed by copies of . It makes exactly nodes and writes only to nodes it made.
Proof. Let be the old nodes on the path of , and the new nodes made in lines L1 and L5, so starts with the children and the count of , plus . Line L6 sets , where is the bit used at depth , and this is the only write. After the loop, has the child on the path side and the old child on the other side. By induction from up: is a leaf with count . For , , so is well formed. A string that leaves the path at depth reaches the same node through as through , so its multiplicity is unchanged; the string reaches , whose count is the old one plus . The nodes are made by this call, so no other version reaches them while they are written.
Lemma 3 (no change). After an operation returns, no node reachable from an existing root is written again.
Proof. By Lemma 2, ADD writes only to nodes that it made and that no root reached before it returned. COUNT and MAX-XOR do not write.
Theorem 1. After any sequence of operations, every version root is well formed at depth 0, and its multiset is the one that the abstract type gives to the version. COUNT returns the multiplicity of and REMOVE never makes a negative count.
Proof. By induction on the operations. Version 0 is , which is well formed with the empty multiset. insert is ADD with , right by Lemma 2. REMOVE calls ADD with only if COUNT is positive (line L9), so the precondition of Lemma 2 holds, and otherwise returns the old root, whose multiset has no to remove. COUNT follows the path of to its leaf and returns its count, the multiplicity by definition. By Lemma 3 no earlier version changes.
Theorem 2 (maximum XOR). Let and be version roots with as multisets, let be non-empty, and let be a key. Then MAX-XOR returns .
Proof. By Lemma 1, for each prefix , is the number of elements of that start with . We claim that before the step for bit , the nodes and are and for a prefix of length such that some element of starts with , and is the value of the top bits of (as a number), which equal the top bits of the optimum . At the start is empty, is non-empty by line L12, and . In a step, let be bit of . If some element of starts with (line L15), then such an has bit of equal to 1, while all elements that start with agree with on the higher bits; since , every optimum starts with , so bit of is 1, and the step keeps the claim. Otherwise every element of that starts with continues with , so bit of is 0, and line L16 keeps the claim. After the step for bit 0, has length and is .