Algorithm Search⌘K

Proofs: Boyer-Moore-Horspool algorithm

These are the human proofs of Boyer-Moore-Horspool algorithm, at full length.

Horspool 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], HORSPOOL(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. Let m≥1m \ge 1. After lines L3 and L4, for every character cc,

shift[c]=min⁡({m}∪{ m−1−k:0≤k≤m−2, P[k]=c }),\mathrm{shift}[c] = \min\big(\{m\} \cup \{\, m - 1 - k : 0 \le k \le m - 2,\ P[k] = c \,\}\big),

because line L4 visits kk in increasing order and the last write for cc is its largest k≤m−2k \le m - 2, which gives the smallest value m−1−km - 1 - k. In particular 1≤shift[c]≤m1 \le \mathrm{shift}[c] \le m.

Lemma (safe shift). Let s≤n−ms \le n - m and c=T[s+m−1]c = T[s + m - 1]. No shift s′s' with s<s′<s+shift[c]s < s' < s + \mathrm{shift}[c] is valid.

Proof. Let s′=s+ds' = s + d with 1≤d<shift[c]≤m1 \le d < \mathrm{shift}[c] \le m be valid. The text position s+m−1s + m - 1 lies in the window at s′s', because s′≤s+m−1≤s′+m−1s' \le s + m - 1 \le s' + m - 1. It is aligned with the pattern position k=m−1−dk = m - 1 - d, and 0≤k≤m−20 \le k \le m - 2. Validity gives P[k]=T[s+m−1]=cP[k] = T[s + m - 1] = c, so m−1−k=dm - 1 - k = d belongs to the set in the definition of shift[c]\mathrm{shift}[c], and shift[c]≤d\mathrm{shift}[c] \le d, a contradiction. □\square

Theorem. The claim holds.

Proof. Invariant at line L6: the output is the increasing list of the valid shifts smaller than ss. It holds for s=0s = 0. In an iteration with s≤n−ms \le n - m, lines L7 and L8 end with j<0j < 0 exactly when P[i]=T[s+i]P[i] = T[s+i] for all 0≤i<m0 \le i < m, so line L9 outputs ss exactly when it is valid, after all smaller outputs. By the lemma, no valid shift lies strictly between ss and the new value s+shift[c]s + \mathrm{shift}[c], so the invariant holds again. Each iteration increases ss by at least 1, so the loop stops after at most n−m+1n - m + 1 iterations, with s>n−ms > n - m; then all valid shifts are smaller than ss and have been output. ■\blacksquare

Back to Boyer-Moore-Horspool algorithm