Algorithm Search⌘K

Proofs: de Bruijn graph

These are the human proofs of de Bruijn graph, at full length.

The tables of the de Bruijn graph are correct, and walks spell exactly the strings whose K-mers are edges full

This proof shows: correctness, termination.

Notation. Σ\Sigma is a finite alphabet, K≥2K \ge 2, and indices are 0-based. For a multiset XX of words of length KK, #X(x)\#_X(x) is the number of copies of xx in XX. The graph GK(X)G_K(X) has a vertex for each word x[0..K−2]x[0..K-2] and x[1..K−1]x[1..K-1] with x∈Xx \in X, and an edge x[0..K−2]→x[1..K−1]x[0..K-2] \to x[1..K-1] labeled xx for each distinct x∈Xx \in X, with multiplicity #X(x)\#_X(x). An absent key of a table counts as 0.

Invariant. After the calls ADD-KMER(x1),…,(x_1), \ldots, ADD-KMER(xr)(x_r), with X={x1,…,xr}X = \{x_1, \ldots, x_r\} as a multiset:

  • (T1) for every word uu of length K−1K - 1 and letter cc, out[u][c]=#X(u c)\mathrm{out}[u][c] = \#_X(u\,c);
  • (T2) for every word vv of length K−1K - 1 and letter aa, in[v][a]=#X(a v)\mathrm{in}[v][a] = \#_X(a\,v);
  • (T3) the keys of out\mathrm{out} and of in\mathrm{in} are both the vertex set of GK(X)G_K(X).

Proof. For r=0r = 0 all tables are empty, XX is empty and GK(X)G_K(X) has no vertex. Suppose the invariant holds for XX and let xx be added, X′=X+{x}X' = X + \{x\}. Line L1 sets u=x[0..K−2]u = x[0..K-2] and v=x[1..K−1]v = x[1..K-1]. Line L2 adds uu and vv as keys of both tables, which are the two vertices that xx adds to GK(X′)G_K(X'); no other key is added. Line L3 increases out[u][x[K−1]]\mathrm{out}[u][x[K-1]] by one, and u x[K−1]=xu\,x[K-1] = x, so (T1) holds for the pair (u,x[K−1])(u, x[K-1]); any other pair (u′,c)(u', c) has u′c≠xu'c \ne x, so #X′(u′c)=#X(u′c)\#_{X'}(u'c) = \#_X(u'c) and its entry is unchanged. Line L4 does the same for (T2), since x[0] v=xx[0]\,v = x. □\square

ADD-READ. Line L5 calls ADD-KMER on r[i..i+K−1]r[i..i+K-1] for 0≤i≤∣r∣−K0 \le i \le |r| - K, which are the KK-mers of rr, each occurrence once. If ∣r∣<K|r| < K, the range is empty. So after adding a set of reads, XX is the multiset of all their KK-mers.

SUCCESSORS and PREDECESSORS. An edge leaves uu exactly for the distinct x∈Xx \in X with x[0..K−2]=ux[0..K-2] = u, that is, x=u cx = u\,c with #X(u c)>0\#_X(u\,c) > 0, and it goes to x[1..K−1]=u[1..K−2] cx[1..K-1] = u[1..K-2]\,c. By (T1), these letters cc are the keys of out[u]\mathrm{out}[u] with positive count, which are all its keys, since counts only grow from 1. Line L6 returns these vertices. The same argument with (T2) gives line L7: an edge enters vv from a v[0..K−3]a\,v[0..K-3] exactly when a v∈Xa\,v \in X.

Spelling lemma. Let v0,…,vwv_0, \ldots, v_w be words of length K−1K - 1 such that vt[0..K−3]=vt−1[1..K−2]v_t[0..K-3] = v_{t-1}[1..K-2] for 1≤t≤w1 \le t \le w, and let ss be the output of lines L8 to L10. Then

  1. ∣s∣=K−1+w|s| = K - 1 + w and s[t..t+K−2]=vts[t..t+K-2] = v_t for 0≤t≤w0 \le t \le w;
  2. for 1≤t≤w1 \le t \le w, the KK-mer s[t−1..t+K−2]s[t-1..t+K-2] is vt−1v_{t-1} followed by the last letter of vtv_t, which is the label of an edge vt−1→vtv_{t-1} \to v_t if one exists.

Proof. Item 1 by induction on tt. For t=0t = 0, ss starts with v0v_0. Suppose s[t−1..t+K−3]=vt−1s[t-1..t+K-3] = v_{t-1}. The letter appended for tt is at index t+K−2t + K - 2 and equals vt[K−2]v_t[K-2]. The letters at t,…,t+K−3t, \ldots, t + K - 3 are vt−1[1..K−2]=vt[0..K−3]v_{t-1}[1..K-2] = v_t[0..K-3]. So s[t..t+K−2]=vts[t..t+K-2] = v_t. Each step appends one letter, which gives the length. For item 2, s[t−1..t+K−2]s[t-1..t+K-2] is s[t−1..t+K−3]=vt−1s[t-1..t+K-3] = v_{t-1} followed by s[t+K−2]=vt[K−2]s[t+K-2] = v_t[K-2]. An edge vt−1→vtv_{t-1} \to v_t has label vt−1 cv_{t-1}\,c with vt−1[1..K−2] c=vtv_{t-1}[1..K-2]\,c = v_t, so c=vt[K−2]c = v_t[K-2]. □\square

Converse. If ss is a string of length L≥KL \ge K whose KK-mers all lie in XX, then vt=s[t..t+K−2]v_t = s[t..t+K-2] for 0≤t≤L−K+10 \le t \le L - K + 1 is a walk, since s[t−1..t+K−2]s[t-1..t+K-2] is an edge from vt−1v_{t-1} to vtv_t, and SPELL returns ss by item 1 of the lemma.

Consequence. If a walk uses each edge of GK(X)G_K(X) exactly once, then by item 2 the KK-mers of its spelled string are the labels of the edges in the order of the walk, so they are the distinct KK-mers of XX, each exactly once.

Termination. Each operation is straight-line code or a loop over a finite range: line L5 runs max⁡(0,∣r∣−K+1)\max(0, |r| - K + 1) times, lines L6 and L7 run once per key, at most σ\sigma keys, and line L9 runs ww times. ■\blacksquare

Back to de Bruijn graph