Proofs: Double-array trie
These are the human proofs of Double-array trie, at full length.
The double-array trie build establishes the invariant and lookups follow the trie full
This proof shows: correctness.
We use the pseudocode, the codes and the invariant (D1) to (D3) of the page. Let be the ordinary trie of the key set built at line L7, with an extra child on code 0 at each node whose path is a key. Write for the cell given to a node of .
Lemma 1 (the build gives each node of one cell, and no cell to two nodes). When the queue empties, each node of has a cell, the cells of distinct nodes are distinct, for each non-root , and where is the code of the edge into .
Proof. The root gets cell 0, with a reserved check. A node is dequeued once, because it is enqueued once, by its parent. When is dequeued at line L9, its children have no cells yet, and line L10 picks a base for which every cell , for in the codes of the children, is free. Line L11 marks these cells with the check , so they are no longer free, and line L12 gives the cell to the child on . Cells that are taken are never freed, so no later node gets one of them. Each node of other than the root is the child of exactly one node, so it gets exactly one cell, at the offset of its code from the base of its parent. Such a base exists: the arrays grow, and a base past the last used cell has all its cells free. Each node's base is set once, when it is dequeued, before any of its children's cells are read.
Lemma 2 (D1). For each node of and each code , DA-NEXT returns if has a child on , and NIL otherwise.
Proof. If exists, by Lemma 1 the cell is and its check is , so lines L1 and L2 return . If does not exist and is in range, the cell is free (check ), or the cell of a node whose parent is not , or the root. In the first case the check is . In the second, , and by Lemma 1. The root cannot be , since bases are at least 1 and codes are nonnegative. So line L2 fails and line L3 returns NIL. If is out of range, line L3 returns NIL too.
Lemma 1 also gives (D2): each cell other than the root is free or the cell of exactly one node, the one whose parent's cell is named by the check.
Lemma 3 (D3 and DA-GET). DA-GET returns the value of if and NIL otherwise.
Proof. By Lemma 2 and induction on the symbols of , after line L4 has read symbols, is the cell of the node of whose path is the first symbols of , or the walk has returned NIL because no such node exists. In the second case is not a prefix of a path of , so . In the first case, after all symbols, for the node with path . By the construction of , has a child on code 0 if and only if , so by Lemma 2 line L5 finds the leaf cell exactly when is a key. Line L12 stored the value of there when the leaf was placed, so line L6 returns it.
Prefix searches. The common prefix search of a text is the walk of Lemma 3 on the symbols of with a test of code 0 after each step. By Lemma 3 applied to each prefix of , it reports exactly the keys that are prefixes of , and it stops at the first prefix that is not a path of , after which no longer prefix can be a key. Listing the keys below a node tests the codes at each node reached, and by Lemma 2 this finds exactly its children in ; visiting them in increasing code order lists the keys in the order of the codes.