Algorithm Search⌘K

Proofs: Lengauer-Tarjan algorithm

These are the human proofs of Lengauer-Tarjan algorithm, at full length.

The Lengauer-Tarjan algorithm computes the immediate dominators full

This proof shows: correctness, termination.

Setting. GG is a directed graph with start vertex rr. Only the vertices reachable from rr matter: an edge from an unreachable vertex lies on no path from rr, so dropping such edges, as line L4 does, changes no dominator. After line L1 the reachable vertices are identified with their preorder numbers 0,…,k−10, \ldots, k - 1 in a depth-first search from rr, so r=0r = 0. TT is the DFS tree. We write x→∗yx \to^* y if xx is an ancestor of yy in TT (possibly x=yx = y) and x→+yx \to^+ y for a proper ancestor. All paths start where stated; "dominates" refers to paths from rr. Dominance is a partial order whose strict dominators of a vertex form a chain, and idom(w)\mathrm{idom}(w) is the lowest of them; this is proved on the page of the dominator tree. The semidominator sdom(w)\mathrm{sdom}(w) for w≠rw \ne r is the least vv such that some path v=v0,…,vj=wv = v_0, \ldots, v_j = w has vi>wv_i > w for 0<i<j0 < i < j; we call such a path an sdom path for ww. Removing a cycle from an sdom path gives an sdom path, so we may take them simple.

Lemma 0 (preorder intervals). The descendants of xx in TT are exactly the numbers x,x+1,…,x+s(x)−1x, x + 1, \ldots, x + s(x) - 1, where s(x)s(x) is the size of the subtree of xx. The ancestors of a vertex yy form the tree path from rr to yy, with numbers increasing downward.

Proof. The DFS numbers xx when it first reaches it and then numbers all vertices reached before it leaves xx, which are exactly the descendants of xx, so they get the next s(x)−1s(x) - 1 numbers. A parent is numbered before its child. □\square

Lemma 1 (DFS edges). If (v,w)(v, w) is an edge with v<wv < w, then v→∗wv \to^* w.

Proof. When the DFS examines the edge (v,w)(v, w), vv is on the stack. If ww is unvisited, it becomes a child of vv. Otherwise ww was numbered after vv and before this moment, that is, while vv was on the stack, so ww is a descendant of vv. □\square

Lemma 2 (path lemma). If v≤wv \le w, every path from vv to ww contains a common ancestor of vv and ww.

Proof. Let xx be the vertex of least number on the path. By induction along the path, every vertex yy after xx is a descendant of xx: for an edge (y,z)(y, z) with yy a descendant of xx, either z>yz > y, and zz is a descendant of yy by Lemma 1, or x≤z<yx \le z < y, and zz lies in the interval of xx by Lemma 0. So ww is a descendant of xx, and x≤v≤wx \le v \le w places vv in the interval of xx as well. □\square

Lemma 3 (positions). For w≠rw \ne r: idom(w)→+w\mathrm{idom}(w) \to^+ w, sdom(w)→+w\mathrm{sdom}(w) \to^+ w, and idom(w)→∗sdom(w)\mathrm{idom}(w) \to^* \mathrm{sdom}(w).

Proof. The tree path from rr to ww is a path in GG, so every dominator of ww is on it, and the strict ones are proper ancestors. The edge from the parent of ww is an sdom path, so sdom(w)≤parent(w)<w\mathrm{sdom}(w) \le parent(w) < w. Take an sdom path from v0=sdom(w)v_0 = \mathrm{sdom}(w) to ww. By Lemma 2 it contains a common ancestor xx of v0v_0 and ww, so x≤v0<wx \le v_0 < w; internal vertices are >w> w and ww itself is not an ancestor of v0<wv_0 < w, so x=v0x = v_0, and v0→+wv_0 \to^+ w. Finally, the tree path from rr to sdom(w)\mathrm{sdom}(w) followed by the sdom path is a path to ww whose vertices are ancestors of sdom(w)\mathrm{sdom}(w), numbers >w> w, or ww. A proper ancestor yy of ww with sdom(w)→+y\mathrm{sdom}(w) \to^+ y has sdom(w)<y<w\mathrm{sdom}(w) < y < w and lies on neither part, so it does not dominate ww. Hence idom(w)\mathrm{idom}(w), a proper ancestor of ww, is an ancestor of sdom(w)\mathrm{sdom}(w). □\square

Lemma 4 (nesting). If v→∗wv \to^* w and v≠rv \ne r, then v→∗idom(w)v \to^* \mathrm{idom}(w) or idom(w)→∗idom(v)\mathrm{idom}(w) \to^* \mathrm{idom}(v).

Proof. Let xx satisfy idom(v)→+x→+v\mathrm{idom}(v) \to^+ x \to^+ v. Then xx does not dominate vv, since the dominators of vv are vv and the ancestors of idom(v)\mathrm{idom}(v). So some path from rr to vv avoids xx; followed by the tree path from vv to ww, whose vertices are descendants of vv and hence not xx, it reaches ww avoiding xx. So idom(w)\mathrm{idom}(w), which is on the tree path to ww, is not strictly between idom(v)\mathrm{idom}(v) and vv: it is either a descendant of vv or an ancestor of idom(v)\mathrm{idom}(v). □\square

Theorem 1 (semidominator formula). For w≠rw \ne r, sdom(w)=min⁡(A∪B)\mathrm{sdom}(w) = \min(A \cup B), where A={v:(v,w)∈E,v<w}A = \{v : (v, w) \in E, v < w\} and B={sdom(u):u>w and u→∗v for some edge (v,w)∈E}B = \{\mathrm{sdom}(u) : u > w \text{ and } u \to^* v \text{ for some edge } (v, w) \in E\}.

Proof. Let x=min⁡(A∪B)x = \min(A \cup B); AA contains parent(w)parent(w), so it is not empty. sdom(w)≤x\mathrm{sdom}(w) \le x. An element v∈Av \in A is the start of the sdom path v,wv, w. For an element sdom(u)∈B\mathrm{sdom}(u) \in B, take an sdom path for uu, then the tree path from uu to vv, then the edge (v,w)(v, w). The internal vertices of the first part are >u>w> u > w, uu itself is >w> w, and the tree path from uu consists of descendants of uu, numbered ≥u>w\ge u > w. So this is an sdom path for ww from sdom(u)\mathrm{sdom}(u).

x≤sdom(w)x \le \mathrm{sdom}(w). Let v0=sdom(w),v1,…,vj=wv_0 = \mathrm{sdom}(w), v_1, \ldots, v_j = w be a simple sdom path. If j=1j = 1, then v0∈Av_0 \in A. If j>1j > 1, let i≥1i \ge 1 be the least index with vi→∗vj−1v_i \to^* v_{j-1}; it exists because i=j−1i = j - 1 qualifies. We claim vt>viv_t > v_i for 0<t<i0 < t < i. Otherwise let vtv_t be the least of v1,…,vi−1v_1, \ldots, v_{i-1}, with vt<viv_t < v_i (equality is excluded because the path is simple). By Lemma 2 the subpath from vtv_t to viv_i contains a common ancestor vsv_s of both, with t≤s≤it \le s \le i. Then vs≤vtv_s \le v_t, so s=ts = t or s=is = i by the choice of tt. If s=ts = t, vt→∗vi→∗vj−1v_t \to^* v_i \to^* v_{j-1} with 1≤t<i1 \le t < i, contradicting the choice of ii; if s=is = i, viv_i is an ancestor of vtv_t and vi≤vtv_i \le v_t, a contradiction. So v0,…,viv_0, \ldots, v_i is an sdom path for viv_i, and sdom(vi)≤v0\mathrm{sdom}(v_i) \le v_0. Also vi>wv_i > w because it is an internal vertex, and vi→∗vj−1v_i \to^* v_{j-1} with (vj−1,w)∈E(v_{j-1}, w) \in E. So sdom(vi)∈B\mathrm{sdom}(v_i) \in B and x≤sdom(vi)≤v0x \le \mathrm{sdom}(v_i) \le v_0. □\square

Theorem 2 (immediate dominator rule). For w≠rw \ne r, let uu be a vertex of least sdom(u)\mathrm{sdom}(u) among the vertices yy with sdom(w)→+y→∗w\mathrm{sdom}(w) \to^+ y \to^* w. Then sdom(u)≤sdom(w)\mathrm{sdom}(u) \le \mathrm{sdom}(w), and idom(w)=sdom(w)\mathrm{idom}(w) = \mathrm{sdom}(w) if sdom(u)=sdom(w)\mathrm{sdom}(u) = \mathrm{sdom}(w), while idom(w)=idom(u)\mathrm{idom}(w) = \mathrm{idom}(u) if sdom(u)<sdom(w)\mathrm{sdom}(u) < \mathrm{sdom}(w).

Proof. The set contains ww, so sdom(u)≤sdom(w)\mathrm{sdom}(u) \le \mathrm{sdom}(w). We use one claim twice.

Claim. Let z≠rz \ne r be a proper ancestor of ww and PP a path from rr to ww that avoids zz. Let xx be the last vertex of PP with x<zx < z (it exists because r<zr < z), and yy the first vertex after xx on PP with z→+y→∗wz \to^+ y \to^* w (it exists because ww qualifies). Then sdom(y)≤x<z\mathrm{sdom}(y) \le x < z.

Proof of the claim. Let x=x0,x1,…,xq=yx = x_0, x_1, \ldots, x_q = y be the part of PP between them, made simple. Suppose some internal xtx_t has xt<yx_t < y, and take the least such xtx_t. By Lemma 2 the subpath from xtx_t to yy contains a common ancestor xsx_s of xtx_t and yy; as before s=ts = t, so xt→∗y→∗wx_t \to^* y \to^* w. Since xtx_t comes after xx on PP, xt≥zx_t \ge z, and xt≠zx_t \ne z because PP avoids zz; an ancestor of ww numbered above the ancestor zz of ww is a proper descendant of zz (Lemma 0). So z→+xt→∗wz \to^+ x_t \to^* w, and xtx_t comes before yy, against the choice of yy. So all internal vertices exceed yy, the part is an sdom path for yy, and sdom(y)≤x\mathrm{sdom}(y) \le x. □\square

Case sdom(u)=sdom(w)\mathrm{sdom}(u) = \mathrm{sdom}(w). Then sdom(y)≥sdom(w)\mathrm{sdom}(y) \ge \mathrm{sdom}(w) for every yy with sdom(w)→+y→∗w\mathrm{sdom}(w) \to^+ y \to^* w. If sdom(w)=r\mathrm{sdom}(w) = r, it dominates ww. Otherwise suppose a path PP avoids z=sdom(w)z = \mathrm{sdom}(w); the claim gives such a yy with sdom(y)<sdom(w)\mathrm{sdom}(y) < \mathrm{sdom}(w), a contradiction. So sdom(w)\mathrm{sdom}(w) dominates ww; it is a proper ancestor of ww and, by Lemma 3, a descendant of idom(w)\mathrm{idom}(w). As idom(w)\mathrm{idom}(w) is the lowest strict dominator, idom(w)=sdom(w)\mathrm{idom}(w) = \mathrm{sdom}(w).

Case sdom(u)<sdom(w)\mathrm{sdom}(u) < \mathrm{sdom}(w). Here u≠ru \ne r, since u>sdom(w)≥ru > \mathrm{sdom}(w) \ge r. By Lemma 3, idom(u)→∗sdom(u)\mathrm{idom}(u) \to^* \mathrm{sdom}(u), and sdom(u)\mathrm{sdom}(u) is an ancestor of uu numbered below sdom(w)\mathrm{sdom}(w), hence sdom(u)→+sdom(w)\mathrm{sdom}(u) \to^+ \mathrm{sdom}(w). So idom(u)→+sdom(w)→+u→∗w\mathrm{idom}(u) \to^+ \mathrm{sdom}(w) \to^+ u \to^* w. By Lemma 4 applied to u→∗wu \to^* w, either u→∗idom(w)u \to^* \mathrm{idom}(w), which is impossible because idom(w)→∗sdom(w)→+u\mathrm{idom}(w) \to^* \mathrm{sdom}(w) \to^+ u (Lemma 3), or idom(w)→∗idom(u)\mathrm{idom}(w) \to^* \mathrm{idom}(u).

It remains to show that z=idom(u)z = \mathrm{idom}(u) dominates ww; then zz is a strict dominator of ww, hence an ancestor of idom(w)\mathrm{idom}(w), and the two are equal. If z=rz = r this is clear. Otherwise suppose a path PP to ww avoids zz and take xx and yy from the claim, with sdom(y)≤x<z\mathrm{sdom}(y) \le x < z. If sdom(w)→+y\mathrm{sdom}(w) \to^+ y, then yy is in the set that defines uu, and sdom(y)<z≤sdom(u)\mathrm{sdom}(y) < z \le \mathrm{sdom}(u) (by Lemma 3, z→∗sdom(u)z \to^* \mathrm{sdom}(u)) contradicts the choice of uu. Otherwise z→+y→∗sdom(w)→+uz \to^+ y \to^* \mathrm{sdom}(w) \to^+ u, so yy is strictly between zz and uu on the tree path. Now sdom(y)\mathrm{sdom}(y) is an ancestor of yy (Lemma 3) numbered below zz, so it is a proper ancestor of zz. The tree path from rr to sdom(y)\mathrm{sdom}(y) (ancestors of sdom(y)\mathrm{sdom}(y), all numbered below zz), an sdom path from sdom(y)\mathrm{sdom}(y) to yy (internal vertices above y>zy > z), and the tree path from yy to uu (descendants of yy) form a path from rr to uu that avoids z=idom(u)z = \mathrm{idom}(u), a contradiction. □\square

Lemma 5 (the forest). Consider the moment just before EVAL is called. Every vertex xx with ancestor[x]≠ancestor[x] \ne none has been linked, ancestor[x]→+xancestor[x] \to^+ x, every vertex on the tree path from ancestor[x]ancestor[x], exclusive, down to xx has been linked, and label[x]label[x] is a vertex of least semisemi on that path. Moreover semisemi of a linked vertex no longer changes. Then EVAL(v)(v) returns vv if vv is unlinked, and otherwise a vertex of least semisemi on the tree path from the highest unlinked ancestor of vv, exclusive, down to vv; and it preserves the invariant.

Proof. The invariant holds after line L6 links ww, since label[w]=wlabel[w] = w and the path from parent(w)parent(w), exclusive, to ww is {w}\{w\}; semi[w]semi[w] is final at that point and is not written again. If vv is unlinked, line L12 returns vv. Otherwise line L14 collects v=x1,x2=ancestor[x1],…v = x_1, x_2 = ancestor[x_1], \ldots as long as ancestor[ancestor[x]]ancestor[ancestor[x]] exists, so it stops at a vertex xj+1x_{j+1} whose ancestor zz is unlinked: zz is the root of the forest tree, and the highest unlinked ancestor of vv, because all vertices strictly below zz on the path are linked by the invariant, and zz is unlinked. Line L15 processes xj,…,x1x_j, \ldots, x_1. When it reaches xtx_t, ancestor[xt+1]=zancestor[x_{t+1}] = z already holds and label[xt+1]label[x_{t+1}] is a minimum on the path from zz, exclusive, to xt+1x_{t+1} (for t=jt = j this is the invariant for xj+1x_{j+1}, whose ancestor is zz). Combining with label[xt]label[x_t], a minimum on the path from xt+1x_{t+1}, exclusive, to xtx_t, gives a minimum on the path from zz, exclusive, to xtx_t, and ancestor[xt]ancestor[x_t] becomes zz. So the invariant holds after the update, and label[v]label[v] is the required minimum. □\square

Theorem 3. The algorithm terminates and returns idom(w)\mathrm{idom}(w) for every w≠rw \ne r reachable from rr.

Proof. Termination. The DFS pushes each vertex once. Each loop of lines L3 to L11 runs over a finite set, and the loop of line L14 climbs strictly upward in TT (by Lemma 5, ancestor[x]→+xancestor[x] \to^+ x).

Semidominators. We show that when ww is processed, line L5 sets semi[w]=sdom(w)semi[w] = \mathrm{sdom}(w). At that time the linked vertices are exactly those numbered above ww, with their final semisemi by induction. For a predecessor v<wv < w: vv is unlinked, semi[v]=vsemi[v] = v, and EVAL returns vv: these are the elements of AA. For a predecessor v>wv > w: the ancestors of vv numbered above ww are linked, and the highest unlinked ancestor zz of vv has z≤wz \le w, so the tree path from zz, exclusive, to vv is exactly the set of ancestors uu of vv with u>wu > w, by Lemma 0. EVAL returns one of them with least semi=sdomsemi = \mathrm{sdom}. These give the elements of BB, and semi[w]semi[w] starts at $w > $ every element of A∪BA \cup B, so line L5 computes min⁡(A∪B)=sdom(w)\min(A \cup B) = \mathrm{sdom}(w) by Theorem 1.

Buckets. Vertex vv enters bucket[sdom(v)]bucket[\mathrm{sdom}(v)] when it is processed. Let cc be the child of p=sdom(v)p = \mathrm{sdom}(v) on the tree path to vv. The vertices processed after vv and before cc are numbered between cc and vv, hence lie in the subtree of cc (Lemma 0), and none of them is a child of pp. So vv stays in bucket[p]bucket[p] until cc is processed, and is handled in line L8 at w=cw = c, after cc is linked. At that moment the linked vertices are those numbered ≥c\ge c, so the whole tree path from cc to vv is linked and pp is not, and by Lemma 5 EVAL(v)(v) returns a vertex uu of least sdom\mathrm{sdom} among yy with p→+y→∗vp \to^+ y \to^* v, which is the vertex of Theorem 2. If semi[u]≥semi[v]semi[u] \ge semi[v], then sdom(u)=sdom(v)\mathrm{sdom}(u) = \mathrm{sdom}(v) and line L8 sets idom[v]=p=idom(v)idom[v] = p = \mathrm{idom}(v). Otherwise it sets idom[v]=uidom[v] = u with idom(v)=idom(u)\mathrm{idom}(v) = \mathrm{idom}(u) and p<u<vp < u < v.

Final pass. Line L11 changes idom[w]idom[w] exactly when idom[w]=u≠semi[w]=pidom[w] = u \ne semi[w] = p, that is, in the second case; there u<wu < w, so in increasing order idom[u]idom[u] is already final, and idom[w]←idom[u]=idom(u)=idom(w)idom[w] \leftarrow idom[u] = \mathrm{idom}(u) = \mathrm{idom}(w). In the first case idom[w]=semi[w]idom[w] = semi[w] and nothing changes. Renaming back to the original labels preserves all answers. ■\blacksquare

Back to Lengauer-Tarjan algorithm