Proofs: Blumer et al. suffix automaton algorithm
These are the human proofs of Blumer et al. suffix automaton algorithm, at full length.
EXTEND turns the suffix automaton of t into that of tc, in amortized constant steps full
This proof shows: correctness, complexity.
We use the pseudocode and the notation of the page. For a text of length and a substring , is the set of end positions of the occurrences of , with . A class is a set of substrings with the same end set, and is the class of .
Facts on classes. (F1) If is a suffix of , then . If two substrings and end at a common position, one is a suffix of the other. Hence the strings of a class are the suffixes of its longest string with lengths in an interval, and if is a substring with , , then is a suffix of . (F2) , so depends only on and . (F3) If is the longest suffix of the longest string of a class that is not in , then is the longest string of its class: a longer would end at each end of (since ), so by (F1) would be a suffix of longer than outside , or would be a suffix of and then all three end sets are equal and .
The invariant (A). For the current text : the states other than 0 are the classes of nonempty substrings, and 0 is the class of ; is the length of the longest string of ; is the class of the longest suffix of that string outside ; for when is a substring, and undefined otherwise; . By (F1) the link path from visits, in order of decreasing length, classes that together contain each suffix of once. (A) holds for the empty text.
What changes when is appended. Let and let be the longest suffix of that is a substring of ( if there is none). For a substring of , is , plus if is a suffix of .
- The suffixes of longer than are new and end only at : they form one class , with longest string and suffix link , by (F3) applied in .
- The classes of whose strings are all suffixes of , or all not, keep the same strings.
- At most one class of splits, the class when is not its longest string. Indeed, let be a class of with a suffix of and a string that is not, so by (F1) and , so is a suffix of . Then ends at each end of ; if , would be a suffix of and of , so is a suffix of and , so . Then splits into , its strings of length at most (all suffixes of , which gain ), and , the longer ones.
The walk of line L2. For a state on the link path of , all its strings have a substring of or none do, by (F2); and if is a substring so is for each suffix of . So the walk passes exactly the states of the suffixes of for which is new, that is , and setting is the transition of (A) in . It stops at the state whose longest string is the longest suffix of with a substring, so and ; or it runs off the path, and then and line L3 sets . Line L1 sets , the length of .
Line L4. Here . If , then is the longest string of , all strings of are suffixes of , and no class splits. The link of is , as item 1 requires. No other state changes its strings, so their lengths, links and transitions stay right; a transition into comes from a state of a string with a suffix of longer than , which is a state passed by the walk; and has no transitions, since its strings end only at the last position.
Lines L5 to L7. If , splits. The clone is : its longest string is , so its length is ; its link is the class of the longest suffix of below , which is the old ; and becomes , with the same length and the link . Transitions out of the two parts: a transition from never led to itself, since an end set is not its own shift by one (compare the largest elements), so the targets are classes other than , which keep their identity, and the targets of and are those of , by (F2) in applied to strings that had the same targets in . So copying the transitions of to the clone is right. Transitions into : a state with must now go to if its strings have in , which means is a suffix of , so and is a suffix of ; so is on the link path of the old . Along that path, the targets on are the classes of for suffixes of decreasing length, and the in have lengths in an interval, so these states are and its consecutive link ancestors up to the first one whose -transition goes elsewhere. Line L6 redirects exactly these. The link of is , set at line L7. A state whose old link was had as link the longest string of (by (F3)), which lies in , so its link stays . The rest is as in the case of line L4.
So (A) holds for , and line L8 sets . By induction, after the whole text the automaton is the automaton of the classes. With the states on the link path from as accepting states, the automaton accepts the suffixes of , and it is the minimal automaton of this language: two strings and are right-equivalent for it if and only if they are both non-substrings or have the same end set, since the strings with a suffix of are exactly the for , and these determine . So by the Myhill-Nerode theorem the automaton is minimal. (For the language of all substrings, two strings are right-equivalent as soon as their first occurrences end at the same place, so that minimal automaton can have fewer states.)
The running time. Let be the number of links from to state 0. First, for each transition , : fix ; each state on the link path of contains a suffix of , and is a suffix of , so is on the link path of ; two different give different classes by (F2); so the path of has at most one more state than that of .
Consider a call with iterations of line L2 and of line L6. The state after line L2 has , and its path is not changed by the call, since only and the new states get new links and . In case L3, . In case L4, . In the clone case, the last state redirected in line L6 has depth and a -transition to the clone, so . In all cases . Summing over the calls, with , the total number of iterations of lines L2 and L6 is at most . With the at most transitions copied in line L5, the number of transition operations is , and the time is times the cost of one transition operation.