Algorithm Search⌘K

Proofs: Myers diff algorithm

These are the human proofs of Myers diff algorithm, at full length.

Myers' greedy search finds a shortest edit script full

This proof shows: correctness.

We use the pseudocode of the page. The search of lines L4 to L7 can produce points with x>mx > m or y>ny > n, so we work in an extended graph GG. Its vertices are all points (x,y)(x, y) with integers x,y≥0x, y \ge 0. Each point has a right edge to (x+1,y)(x + 1, y) and a down edge to (x,y+1)(x, y + 1), each of cost 1, and a diagonal edge to (x+1,y+1)(x + 1, y + 1) of cost 0 if x<mx < m, y<ny < n and ax+1=by+1a_{x+1} = b_{y+1}. The edit graph of the page is the part with x≤mx \le m and y≤ny \le n. Along each edge, xx and yy do not decrease. The diagonal of (x,y)(x, y) is k=x−yk = x - y; a right edge raises kk by 1, a down edge lowers it by 1, and a diagonal edge keeps it. The cost of a path is its number of right and down edges.

For a point P=(x,y)P = (x, y), let snake(P)\mathrm{snake}(P) be the end of the longest run of diagonal edges from PP: the point (x+t,y+t)(x + t, y + t) with t≥0t \ge 0 largest such that the tt diagonal edges exist. This is what line L7 computes.

Let RdR_d be the set of points that are the end of some path of cost exactly dd from (0,0)(0, 0), and for each kk let Fd[k]=max⁡{x:(x,x−k)∈Rd}F_d[k] = \max\{ x : (x, x - k) \in R_d \}, or undefined if no such point exists.

Lemma 1 (diagonals). If (x,y)∈Rd(x, y) \in R_d, then ∣x−y∣≤d|x - y| \le d and x−y≡d(mod2)x - y \equiv d \pmod 2. For each k∈{−d,−d+2,…,d}k \in \{-d, -d + 2, \ldots, d\}, Fd[k]F_d[k] is defined and finite.

Proof. A path of cost dd with rr right and d−rd - r down edges ends on diagonal r−(d−r)=2r−dr - (d - r) = 2r - d, which has the parity of dd and lies in [−d,d][-d, d]. For a given k=2r−dk = 2r - d, the path of rr right edges then d−rd - r down edges reaches diagonal kk, so Fd[k]F_d[k] is defined. It is finite, since a path of cost dd has at most dd right edges and at most min⁡(m,n)\min(m, n) diagonal edges, so x≤d+min⁡(m,n)x \le d + \min(m, n). □\square

Lemma 2 (later is better). Let P=(x,y)P = (x, y) and P′=(x′,y′)P' = (x', y') be on the same diagonal with x≤x′x \le x'. Then each point QQ on this diagonal that can be reached from PP by diagonal edges only has first coordinate at most that of snake(P′)\mathrm{snake}(P').

Proof. The diagonal edges from PP go through the points (x+s,y+s)(x + s, y + s), s=0,1,…s = 0, 1, \ldots If the run from PP stops before x′x', then QQ has first coordinate below x′≤x' \le the first coordinate of snake(P′)\mathrm{snake}(P'). Otherwise the run passes through P′P', and from there it uses the same edges as the run from P′P', so it ends at snake(P′)\mathrm{snake}(P'), and QQ is on this run. □\square

Lemma 3 (the recurrence, Myers' Lemma 2). F0[0]F_0[0] is the first coordinate of snake((0,0))\mathrm{snake}((0, 0)). For d≥1d \ge 1 and k∈{−d,−d+2,…,d}k \in \{-d, -d + 2, \ldots, d\}, let

x0={Fd−1[k+1]if k=−d,Fd−1[k−1]+1if k=d,max⁡(Fd−1[k−1]+1, Fd−1[k+1])otherwise.x_0 = \begin{cases} F_{d-1}[k + 1] & \text{if } k = -d, \\ F_{d-1}[k - 1] + 1 & \text{if } k = d, \\ \max(F_{d-1}[k - 1] + 1,\ F_{d-1}[k + 1]) & \text{otherwise}. \end{cases}

Then Fd[k]F_d[k] is the first coordinate of snake((x0,x0−k))\mathrm{snake}((x_0, x_0 - k)).

Proof. For d=0d = 0, the paths of cost 0 are runs of diagonal edges from (0,0)(0, 0), and the furthest one ends at snake((0,0))\mathrm{snake}((0, 0)).

Let d≥1d \ge 1. (≥\ge) The point of diagonal k+1k + 1 at x=Fd−1[k+1]x = F_{d-1}[k + 1] is in Rd−1R_{d-1}; a down edge takes it to (x,x−k)(x, x - k) on diagonal kk, at cost dd; then the snake keeps cost dd. In the same way, the point of diagonal k−1k - 1 at Fd−1[k−1]F_{d-1}[k - 1] and a right edge reach x=Fd−1[k−1]+1x = F_{d-1}[k - 1] + 1 on diagonal kk. These points exist when k+1≤d−1k + 1 \le d - 1 and k−1≥−(d−1)k - 1 \ge -(d - 1) respectively, by Lemma 1, which are the cases of x0x_0. So snake((x0,x0−k))∈Rd\mathrm{snake}((x_0, x_0 - k)) \in R_d.

(≤\le) Let Q∈RdQ \in R_d be on diagonal kk, at the end of a path of cost d≥1d \ge 1. Cut the path after its last right or down edge, at the point SS. Then QQ is reached from SS by diagonal edges only. The point before this last edge is in Rd−1R_{d-1}. If the edge is a down edge, that point is on diagonal k+1k + 1 with first coordinate at most Fd−1[k+1]F_{d-1}[k + 1], and SS has the same first coordinate. If it is a right edge, the point is on diagonal k−1k - 1 with first coordinate at most Fd−1[k−1]F_{d-1}[k - 1], and SS has one more. In both cases SS is on diagonal kk with first coordinate at most x0x_0. By Lemma 2 with P=SP = S and P′=(x0,x0−k)P' = (x_0, x_0 - k), the first coordinate of QQ is at most that of snake((x0,x0−k))\mathrm{snake}((x_0, x_0 - k)). □\square

Lemma 4 (the loop computes FF). After round dd of the loop of line L2, V[k]=Fd[k]V[k] = F_d[k] for each k∈{−d,−d+2,…,d}k \in \{-d, -d + 2, \ldots, d\}, and these values are saved as VdV_d.

Proof. Induction on dd. In round 0, k=0=−dk = 0 = -d, so line L4 sets x=V[1]=0x = V[1] = 0 (line L1), and lines L6 to L8 store the snake from (0,0)(0, 0); this is F0[0]F_0[0] by Lemma 3. In round d≥1d \ge 1, the entries V[k±1]V[k \pm 1] read in lines L4 and L5 are on diagonals of the parity of d−1d - 1, which round dd does not write, so they hold Fd−1[k±1]F_{d-1}[k \pm 1] by the induction hypothesis. If k=−dk = -d, line L4 takes x=Fd−1[k+1]x = F_{d-1}[k + 1]. If k=dk = d, the test of line L4 fails and line L5 takes Fd−1[k−1]+1F_{d-1}[k - 1] + 1. Otherwise line L4 takes Fd−1[k+1]F_{d-1}[k + 1] when Fd−1[k−1]<Fd−1[k+1]F_{d-1}[k - 1] < F_{d-1}[k + 1], that is, when Fd−1[k+1]≥Fd−1[k−1]+1F_{d-1}[k + 1] \ge F_{d-1}[k - 1] + 1, and line L5 takes Fd−1[k−1]+1F_{d-1}[k - 1] + 1 otherwise; in both cases x=x0x = x_0. Line L7 follows the snake: its test is exactly the condition for a diagonal edge of GG. By Lemma 3, line L8 stores Fd[k]F_d[k]. □\square

Lemma 5 (the stop). Let DD be the cost of a cheapest path from (0,0)(0, 0) to (m,n)(m, n), and call a point final if x≥mx \ge m and y≥ny \ge n. If a final point is in RdR_d, then d≥Dd \ge D, and if d=Dd = D the point is (m,n)(m, n).

Proof. Let a path of cost dd end at a final point (x,y)(x, y). Along the path the coordinates grow by at most 1 per edge, from (0,0)(0, 0), so there is a first point S=(s,t)S = (s, t) of the path with s=ms = m or t=nt = n; then s≤ms \le m and t≤nt \le n. After SS the path has no diagonal edges, since these need x<mx < m and y<ny < n, so the rest of the path costs (x−s)+(y−t)(x - s) + (y - t). The path from (0,0)(0, 0) to SS, followed by m−sm - s right edges and n−tn - t down edges (one of the two numbers is 0), reaches (m,n)(m, n) at cost

d−(x−s)−(y−t)+(m−s)+(n−t)=d−(x−m)−(y−n)≤d.d - (x - s) - (y - t) + (m - s) + (n - t) = d - (x - m) - (y - n) \le d.

So D≤dD \le d, with equality only if x=mx = m and y=ny = n. □\square

Theorem. MYERS returns d=Dd = D, and TRACEBACK outputs a shortest edit script from AA to BB.

Proof. The point (m,n)(m, n) is reached by a path of cost DD, so it is in RDR_D on diagonal m−nm - n, and FD[m−n]≥mF_D[m - n] \ge m, with y=FD[m−n]−(m−n)≥ny = F_D[m - n] - (m - n) \ge n; so round DD finds a final point. By Lemma 5, no earlier round does, since a final point of round dd is in RdR_d by Lemma 4. So the loop stops at round DD (and D≤m+nD \le m + n, so line L2 runs far enough). In round DD, each final point that line L9 finds is (m,n)(m, n), again by Lemma 5.

TRACEBACK starts at (m,n)=(FD[k],FD[k]−k)(m, n) = (F_D[k], F_D[k] - k) with k=m−nk = m - n. In step dd, it is at the point (Fd[k],Fd[k]−k)(F_d[k], F_d[k] - k) for the current kk. Line L12 repeats the choice of line L4 in round dd, with the same values Vd−1V_{d-1}, so (px,py)(px, py) is the point of round d−1d - 1 from which round dd started, (sx,sy)(sx, sy) is (x0,x0−k)(x_0, x_0 - k) after one down or right edge, and (x,y)(x, y) is the end of the snake from it (Lemma 4). So the steps of the traceback walk back a path of GG: a snake, one right or down edge, then the same for d−1d - 1, down to round 0, whose snake starts at (0,0)(0, 0). This path has cost DD and ends at (m,n)(m, n). A path of GG that ends at (m,n)(m, n) stays in the edit graph, since coordinates do not decrease. Its right edges are deletions, its down edges are insertions, and its diagonal edges are kept items, so the output is an edit script of DD operations. By the theorem of the shortest edit script page, the edit scripts correspond to the paths of the edit graph, so no script is shorter. ■\blacksquare

Cost. Round dd visits d+1d + 1 diagonals with O(1)O(1) work outside line L7, so O(D2)O(D^2) in all. For line L7, consider a diagonal kk and rounds d−2d - 2 and dd with ∣k∣≤d−2|k| \le d - 2. The point of round d−2d - 2 on diagonal kk, followed by a right edge, gives Fd−1[k+1]≥Fd−2[k]+1F_{d-1}[k + 1] \ge F_{d-2}[k] + 1, so x0>Fd−2[k]x_0 > F_{d-2}[k] in round dd: the snake of round dd starts after the end of the snake of round d−2d - 2. So each diagonal edge on diagonal kk is walked at most once, and diagonal kk has at most min⁡(m,n)\min(m, n) diagonal edges. With at most 2D+12D + 1 diagonals, line L7 takes O(Dmin⁡(m,n))O(D \min(m, n)) steps, and the total is O((m+n)D)O((m + n) D).

Back to Myers diff algorithm