Algorithm Search⌘K

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 T[0…n−1]T[0 \ldots n-1] and a pattern P[0…m−1]P[0 \ldots m-1], BACKWARD-DAWG-MATCHING(T,P)(T, P) stops and outputs exactly the shifts ss, 0≤s≤n−m0 \le s \le n - m, with T[s…s+m−1]=PT[s \ldots s+m-1] = P, in increasing order.

For m=0m = 0, line L2 outputs every shift, so let m≥1m \ge 1. A shift s′s' is valid when 0≤s′≤n−m0 \le s' \le n - m and T[s′…s′+m−1]=PT[s' \ldots s'+m-1] = P.

The automaton. We use the defining property of the suffix automaton A\mathcal{A} of PRP^R: for every string xx, δ(q0,x)\delta(q_0, x) is defined exactly when xx is a factor of PRP^R, and then it lies in FF exactly when xx is a suffix of PRP^R. Since reversal maps factors to factors and suffixes of PRP^R to prefixes of PP, for y=T[s+j…s+m−1]y = T[s+j \ldots s+m-1] and x=yRx = y^R: δ(q0,x)\delta(q_0, x) is defined iff yy is a factor of PP, and it is in FF iff yy is a prefix of PP.

Lemma 1 (the scan). At window ss, after line L8 has run with the new value jj, q=δ(q0,(T[s+j…s+m−1])R)q = \delta(q_0, (T[s+j \ldots s+m-1])^R), or nil if that string is not a factor of PRP^R.

Proof. By induction on the number of steps: the characters are fed in the order T[s+m−1],T[s+m−2],…,T[s+j]T[s+m-1], T[s+m-2], \ldots, T[s+j], which spells (T[s+j…s+m−1])R(T[s+j \ldots s+m-1])^R, and once qq is nil the loop stops. □\square

Let j∗j^* be the value of jj when the loop of line L7 ends. Either j∗=0j^* = 0 and q≠q \ne nil, or $q = $ nil and T[s+j∗…s+m−1]T[s+j^* \ldots s+m-1] is not a factor of PP.

Lemma 2 (occurrence). Line L10 outputs ss if and only if ss is valid.

Proof. Line L10 outputs ss when j=0j = 0 and q∈Fq \in F, that is, by Lemma 1, when T[s…s+m−1]T[s \ldots s+m-1] is a prefix of PP; since its length is mm, this means it equals PP. Conversely, if ss is valid, every T[s+j…s+m−1]T[s+j \ldots s+m-1] is a suffix of PP and hence a factor, so the scan never meets nil, reaches j=0j = 0, and the whole window PP is a prefix of PP, so q∈Fq \in F and ss is output. □\square

Lemma 3 (safe shift). At line L11, 1≤shift≤m1 \le \mathit{shift} \le m, and no shift s+ds + d with 0<d<shift0 < d < \mathit{shift} is valid.

Proof. shift\mathit{shift} starts at mm and is only set to values j>0j > 0, so 1≤shift≤m1 \le \mathit{shift} \le m. Moreover, at the end, shift\mathit{shift} is the smallest jj with j∗≤jj^* \le j, 0<j<m0 < j < m and T[s+j…s+m−1]T[s+j \ldots s+m-1] a prefix of PP, or mm if there is none, because line L10 runs for each such jj in decreasing order.

Let s+ds + d be valid with 0<d<shift≤m0 < d < \mathit{shift} \le m. Then T[s+d…s+m−1]=P[0…m−d−1]T[s+d \ldots s+m-1] = P[0 \ldots m-d-1] is a prefix of PP.

  • If d≥j∗d \ge j^*, the scan read position s+ds + d, the string T[s+d…s+m−1]T[s+d \ldots s+m-1] is a prefix of PP, and 0<d<m0 < d < m, so line L10 set shift\mathit{shift} to at most dd, a contradiction.
  • If d<j∗d < j^*, then j∗>0j^* > 0, so the scan stopped with $q = $ nil and T[s+j∗…s+m−1]T[s+j^* \ldots s+m-1] is not a factor of PP. But the occurrence at s+ds + d covers the text positions s+ds + d to s+d+m−1≥s+m−1s + d + m - 1 \ge s + m - 1, and d<j∗d < j^*, so T[s+j∗…s+m−1]=P[j∗−d…m−1−d]T[s+j^* \ldots s+m-1] = P[j^* - d \ldots m - 1 - d] is a factor of PP, a contradiction. □\square

Proof of the claim. By Lemma 2, each tested window is output exactly when it is valid. By Lemma 3, ss increases by at least 1 at each iteration and no valid shift is skipped, so every valid shift ≤n−m\le n - m is tested, and the output is in increasing order. The inner loop runs at most mm times per window and the outer loop at most n−m+1n - m + 1 times, so the algorithm stops. ■\blacksquare

Back to Backward DAWG matching