Proofs: Discrimination tree
These are the human proofs of Discrimination tree, at full length.
Discrimination tree retrieval returns exactly the patterns whose linear form matches the query full
This proof shows: correctness.
We use the pseudocode of the page and the notation of the term rewriting pages: a signature , variables , terms , and substitutions . A function symbol of arity is written when it is a symbol of a key. For a pattern , is its preorder sequence of symbols with each variable replaced by . For a term , is with each occurrence of a variable replaced by a new variable, all distinct. A term matches if for some ; the variables of are treated as constants.
For a node of the tree, is the sequence of edge symbols on the path from the root to . The edges out of a node carry distinct symbols, because is a map. The tree stores the entry at a node with .
Invariant. (D1) An entry is in the set if and only if it is in for the node with . (D2) Each node other than the root has an entry or a child. (D3) is the number of entries.
Insert and delete keep the invariant
INSERT walks from the root along , creates each missing node as the only child for its symbol (line L3), and adds the entry at the last node , which has (line L5). Other nodes keep their entries, so (D1) holds. Each new node is on the path to , so it has a child on that path or it is , which has an entry, and (D2) holds.
DELETE walks along (lines L18 to L20). If an edge is missing, no node has , so by (D1) the entry is not in the set, and DELETE returns false without a change. Else it reaches the node with , and by (D1) the entry is in the set iff it is in ; line L21 removes one copy, or returns false. Lines L22 to L24 then go up from and remove each node that has no entry and no child, and stop at the first node that has one. A removed node has no entry, so (D1) still holds. A node that stays either was not changed, or is the node where the loop stopped, which has an entry or a child, so (D2) holds. (D3) is kept by the counter.
Retrieval
Let be the query, with preorder symbols (line L6). Each starts one subterm of , and the subterm ends just before ; a variable of gives the symbol , which is not and not a function symbol. If , then , starts at , and starts at the end of , the last one ending at . This is the definition of preorder.
Walk. For a sequence of key symbols and an index , define the walk of from : start at ; for each symbol of in turn, if and , set ; if and is a function symbol, set ; else the walk fails. The walk is deterministic, so it fails or ends at one index.
Lemma 1 (forest). Let be terms, and let . Let be an index. The walk of from ends at if and only if there are indices with and for , such that matches for each , and . (The term must exist, so , and is part of the claim.)
Proof. Induction on the total size . If , is empty and the walk ends at ; take . Let .
- If is a variable, . The walk does its first step iff , and then it moves to . The term is a variable, which matches . The claim follows from the induction hypothesis for from .
- If , . The first step succeeds iff and , that is, , and then the walk continues from with , a forest of smaller total size. By the induction hypothesis, this walk ends at iff match the consecutive subterms starting at , which are and end at , and then match consecutive subterms from , ending at . Because has distinct variables, the variables of are disjoint, so the matchers combine into one, and up to renaming matches iff each matches . If is another function symbol or a query variable, the walk fails, and , whose root is , does not match , whose root is not .
Lemma 2 (search). The loop of lines L8 to L12 pops the pair if and only if the walk of from ends at . Each node is popped at most once.
Proof. If: induction on the length of . The root is pushed with at line L7. Let be a child of by the symbol , and let the walk of end at . Then the walk of ends at some , so by the induction hypothesis is popped, and , so lines L11 and L12 run. If , line L11 pushes and . If is a function symbol, then , line L12 pushes and . Every pushed pair is popped, since the loop runs until the stack is empty.
Only if: each push at lines L11 and L12 extends the walk by one step of its definition, so by induction on the number of pushes, every pushed has a walk of that ends at . The walk is deterministic, and each node has one parent, so each node is pushed at most once.
Theorem. RETRIEVE returns each entry of such that matches , once, and no other entry. MATCH returns each entry such that matches , once, with its matcher.
Proof. Line L10 outputs the entries of when is popped with . Let be an entry and its node, by (D1). By Lemma 2, is popped iff the walk of from ends at . By Lemma 1 with , this holds iff matches and , and is always true. Lemma 2 also says that is popped at most once, so the entry is output at most once.
For MATCH: if matches with , then matches (map each new variable to the image of its old variable), so the entry is a candidate, and line L16 accepts it. Line L16 rejects every candidate that does not match.
Remark. The converse of " matches implies matches " is false for non-linear : is a candidate for , but it does not match. For linear , is up to renaming, so RETRIEVE alone is exact.