Proofs: Backward DAWG matching
These are the human proofs of Backward DAWG matching, at full length.
Backward DAWG matching outputs exactly the valid shifts full
This proof shows: correctness, termination.
Claim. For a text and a pattern , BACKWARD-DAWG-MATCHING stops and outputs exactly the shifts , , with , in increasing order.
For , line L2 outputs every shift, so let . A shift is valid when and .
The automaton. We use the defining property of the suffix automaton of : for every string , is defined exactly when is a factor of , and then it lies in exactly when is a suffix of . Since reversal maps factors to factors and suffixes of to prefixes of , for and : is defined iff is a factor of , and it is in iff is a prefix of .
Lemma 1 (the scan). At window , after line L8 has run with the new value , , or nil if that string is not a factor of .
Proof. By induction on the number of steps: the characters are fed in the order , which spells , and once is nil the loop stops.
Let be the value of when the loop of line L7 ends. Either and nil, or $q = $ nil and is not a factor of .
Lemma 2 (occurrence). Line L10 outputs if and only if is valid.
Proof. Line L10 outputs when and , that is, by Lemma 1, when is a prefix of ; since its length is , this means it equals . Conversely, if is valid, every is a suffix of and hence a factor, so the scan never meets nil, reaches , and the whole window is a prefix of , so and is output.
Lemma 3 (safe shift). At line L11, , and no shift with is valid.
Proof. starts at and is only set to values , so . Moreover, at the end, is the smallest with , and a prefix of , or if there is none, because line L10 runs for each such in decreasing order.
Let be valid with . Then is a prefix of .
- If , the scan read position , the string is a prefix of , and , so line L10 set to at most , a contradiction.
- If , then , so the scan stopped with $q = $ nil and is not a factor of . But the occurrence at covers the text positions to , and , so is a factor of , a contradiction.
Proof of the claim. By Lemma 2, each tested window is output exactly when it is valid. By Lemma 3, increases by at least 1 at each iteration and no valid shift is skipped, so every valid shift is tested, and the output is in increasing order. The inner loop runs at most times per window and the outer loop at most times, so the algorithm stops.