Algorithm Search⌘K

Proofs: Turbo-BM algorithm

These are the human proofs of Turbo-BM algorithm, at full length.

Turbo-BM 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], TURBO-BOYER-MOORE(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, which is correct, so let m≥1m \ge 1. A shift s′s' is valid when s′+m≤ns' + m \le n and T[s′…s′+m−1]=PT[s' \ldots s'+m-1] = P. We use the tables as defined on the page: gs[i]\mathrm{gs}[i] is the smallest d≥1d \ge 1 with (G1) P[k−d]=P[k]P[k-d] = P[k] for all kk with i<k<mi < k < m and k≥dk \ge d, and (G2) i−d<0i - d < 0 or P[i−d]≠P[i]P[i-d] \ne P[i]; gs[0]\mathrm{gs}[0] is the smallest period pp of PP (the boyer-moore page proves this and that GOOD-SUFFIX computes the table); λ(c)\lambda(c) is the largest k≤m−2k \le m - 2 with P[k]=cP[k] = c, or −1-1.

Invariant. At the start of each iteration of line L5 with window ss, write sh\mathit{sh} for the value of shift\mathit{shift} and L=m−sh−uL = m - \mathit{sh} - u, R=m−sh−1R = m - \mathit{sh} - 1. Then:

(I1) no valid shift lies in [0,s)[0, s) other than those already output, and every shift output so far is valid;

(I2) if u>0u > 0, then 0≤L0 \le L, and T[s+k]=P[k]T[s + k] = P[k] for L≤k≤RL \le k \le R; moreover the factor w=T[s+L…s+R]w = T[s+L \ldots s+R] equals the suffix P[m−u…m−1]P[m-u \ldots m-1] of length uu.

Initially s=0s = 0 and u=0u = 0, so both hold.

Lemma 1 (the scan). Under (I2), the loop of lines L7 and L8 stops with i<0i < 0 exactly when ss is valid, and otherwise with i≥0i \ge 0, P[i]≠T[s+i]P[i] \ne T[s+i] and P[k]=T[s+k]P[k] = T[s+k] for i<k<mi < k < m.

Proof. The loop compares positions from m−1m - 1 down. Line L8 skips positions only when u≠0u \ne 0 and ii has just become RR; it then sets ii to L−1L - 1, so the skipped positions are L,…,RL, \ldots, R, where T[s+k]=P[k]T[s+k] = P[k] by (I2). So the invariant "P[k]=T[s+k]P[k] = T[s+k] for i<k<mi < k < m" holds throughout, and the loop stops either at i<0i < 0, when all positions match, or at a compared position ii with P[i]≠T[s+i]P[i] \ne T[s+i]. □\square

Line L10 therefore outputs ss exactly when ss is valid. It remains to show that the shift added at line L19 skips no valid shift, that it is at least 1, and that (I2) holds for the next window.

Lemma 2 (shift after a match). If ss is valid, no shift s+ds + d with 1≤d<p1 \le d < p is valid, and (I2) holds at s+ps + p with u=m−pu = m - p.

Proof. If ss and s+ds + d are both valid with d<p≤md < p \le m, then for d≤k<md \le k < m, P[k]=T[s+k]=P[k−d]P[k] = T[s + k] = P[k - d], so dd is a period of PP smaller than pp, which is impossible. For (I2): the new L=m−p−(m−p)=0L = m - p - (m - p) = 0 and R=m−p−1R = m - p - 1. For 0≤k≤R0 \le k \le R, T[s+p+k]=P[p+k]T[s + p + k] = P[p + k] since ss is valid, and P[p+k]=P[k]P[p + k] = P[k] since pp is a period. The factor is P[p…m−1]P[p \ldots m-1], the suffix of length m−pm - p. □\square

Now let the scan stop at i≥0i \ge 0 with a=T[s+i]≠P[i]=ba = T[s+i] \ne P[i] = b, and v=m−1−iv = m - 1 - i, so the text matches the suffix z=P[i+1…m−1]z = P[i+1 \ldots m-1] of length vv.

Lemma 3 (bad character and good suffix). No shift s+ds + d with 1≤d<max⁡(gs[i],i−λ(a))1 \le d < \max(\mathrm{gs}[i], i - \lambda(a)) is valid.

Proof. Let s+ds + d be valid with d≥1d \ge 1. For i<k<mi < k < m with k≥dk \ge d, P[k−d]=T[s+k]=P[k]P[k - d] = T[s + k] = P[k], which is (G1). If i−d≥0i - d \ge 0, then P[i−d]=T[s+i]=a≠b=P[i]P[i - d] = T[s + i] = a \ne b = P[i], which is (G2). So d≥gs[i]d \ge \mathrm{gs}[i] by minimality. Also, if i−d≥0i - d \ge 0 then P[i−d]=aP[i-d] = a with i−d≤m−2i - d \le m - 2, so λ(a)≥i−d\lambda(a) \ge i - d, that is d≥i−λ(a)d \ge i - \lambda(a); if i−d<0i - d < 0 then d≥i+1≥i−λ(a)d \ge i + 1 \ge i - \lambda(a) since λ(a)≥−1\lambda(a) \ge -1. □\square

Lemma 4 (turbo shift). If u>0u > 0 and v<uv < u, no shift s+ds + d with 1≤d<u−v1 \le d < u - v is valid.

Proof. Let s+ds + d be valid with 1≤d<u−v1 \le d < u - v; then d<ud < u. By (I2), T[s+k]=P[k]T[s+k] = P[k] for L≤k≤RL \le k \le R, and since s+ds + d is valid, T[s+k]=P[k−d]T[s + k] = P[k - d] for k≥dk \ge d. So P[k]=P[k−d]P[k] = P[k - d] for max⁡(L,d)≤k≤R\max(L, d) \le k \le R, and in particular for L+d≤k≤RL + d \le k \le R. As P[L…R]=wP[L \ldots R] = w by (I2), this says w[j]=w[j+d]w[j] = w[j + d] for 0≤j<u−d0 \le j < u - d: ww has period dd.

The occurrence at s+ds + d ends at text position s+m−1+ds + m - 1 + d, and its suffix of length uu, which is ww, occupies the text positions s+m+d−us + m + d - u to s+m−1+ds + m - 1 + d. Since d<u−vd < u - v, the position s+i=s+m−1−vs + i = s + m - 1 - v lies in this range, at index j=u−1−v−d≥0j = u - 1 - v - d \ge 0 of ww. So w[u−1−v−d]=aw[u - 1 - v - d] = a. By the period dd, w[u−1−v]=aw[u - 1 - v] = a. But ww is the suffix of PP of length u>vu > v, so w[u−1−v]=P[m−1−v]=P[i]=b≠aw[u - 1 - v] = P[m - 1 - v] = P[i] = b \ne a, a contradiction. □\square

If v≥uv \ge u or u=0u = 0, the value u−v≤0u - v \le 0 excludes nothing, so in all cases Lemmas 3 and 4 show that no shift s+ds + d with 1≤d<max⁡(u−v,i−λ(a),gs[i])1 \le d < \max(u - v, i - \lambda(a), \mathrm{gs}[i]) is valid. Line L15 sets shift\mathit{shift} to this maximum, which is at least gs[i]≥1\mathrm{gs}[i] \ge 1.

Lemma 5 (the new memory). If line L17 runs, (I2) holds at s+shifts + \mathit{shift} with u′=min⁡(m−shift,v)u' = \min(m - \mathit{shift}, v); if line L18 runs, (I2) holds trivially with u′=0u' = 0.

Proof. Let d=shift=gs[i]d = \mathit{shift} = \mathrm{gs}[i] and u′=min⁡(m−d,v)u' = \min(m - d, v); if u′=0u' = 0 there is nothing to show. The new values are L′=m−d−u′≥0L' = m - d - u' \ge 0 and R′=m−d−1R' = m - d - 1. For L′≤k≤R′L' \le k \le R', the text position s+d+ks + d + k is position k+dk + d of the old window, with k+d≥m−u′≥m−v=i+1k + d \ge m - u' \ge m - v = i + 1, so T[s+d+k]=P[k+d]T[s + d + k] = P[k + d] by Lemma 1. By (G1) for dd, applied to the index k+dk + d, which satisfies i<k+d<mi < k + d < m and k+d≥dk + d \ge d, we get P[k+d]=P[k]P[k + d] = P[k]. So T[s+d+k]=P[k]T[s + d + k] = P[k], and the factor is P[m−u′…m−1]P[m - u' \ldots m - 1], the suffix of length u′u'. □\square

Proof of the claim. By Lemmas 2 to 5, each iteration moves ss by at least 1, outputs ss exactly when it is valid, skips no valid shift, and keeps (I2). By induction, (I1) holds at every iteration. The loop stops when s>n−ms > n - m; there are at most n−m+1n - m + 1 iterations, and each inner scan stops after at most mm steps because ii decreases at each step. At the end, (I1) gives that the output is exactly the set of valid shifts, in increasing order because ss only increases. ■\blacksquare

Back to Turbo-BM algorithm