Proofs: Set Horspool algorithm
These are the human proofs of Set Horspool algorithm, at full length.
Set Horspool outputs exactly the occurrences of the patterns full
This proof shows: correctness, termination.
Claim. For every text and patterns , SET-HORSPOOL stops and outputs each pair with and exactly once, and no other pair.
Notation. For a string , is its reverse. In the trie of line L3, each node spells a string (the labels read from the root), and . A pattern ends at if it occurs at . For a position , let be the text read backward from .
Lemma 1 (the trie). A string is for some node if and only if is a prefix of for some nonempty . Each node has at most one child per character.
Proof. Line L3 inserts each from the root, creating a child only when none exists for the next character. So the nodes are exactly the prefixes of the inserted strings, and children are unique per character.
Lemma 2 (one reading). Fix with . Lines L9 to L12 output exactly the pairs for the nonempty that end at , each once.
Proof. Let be the length of the longest prefix of that is a node. By Lemma 1 and induction on the iterations of line L10, after iterations is the node of and ; the loop continues as long as the next prefix is a node and , so it makes exactly iterations. The node reached after iterations has the string , so line L12 outputs for the with , that is, the patterns of length that end at .
Conversely, if a nonempty ends at , then is the prefix of of length , and every prefix of it is a node by Lemma 1, so and the iteration outputs . Each is visited once and each is in one list, so no pair is output twice.
Lemma 3 (the table). After line L6, for every character ,
In particular .
Proof. Line L5 sets every entry to . Line L6 visits, for each nonempty , the indices from to , which are exactly the indices for from to (all valid, since ), and lowers to when that is smaller. So each entry ends as the minimum of and the distances found.
Lemma 4 (safe shift). For every and every with , no nonempty pattern ends at .
Proof. Suppose ends at with . By Lemma 3, , so the occurrence contains , at the index of . Hence with , and Lemma 3 gives , a contradiction.
Theorem. The claim holds.
Proof. Empty patterns. Line L1 outputs for every and every empty , which are exactly their occurrences, once each; no later line outputs an empty pattern, since the trie has none. If all patterns are empty, line L2 stops here.
Termination. By Lemma 3, each pass of line L13 increases by at least 1, and the inner loop of line L10 runs at most times since decreases from and must stay . So the loop of line L8 ends.
Nonempty patterns. Let be the values of at line L9. A nonempty pattern ends at some with . If is not one of the , there is a with , or is beyond the last visited value , where ; in both cases Lemma 4 with and says that no pattern ends at . So every end position of a nonempty pattern is visited, each exactly once, and by Lemma 2 the readings at the visited positions output exactly the occurrences that end there, each once. Two different end positions give different pairs, so no pair is output twice.