Algorithm Search⌘K

Proofs: Lazy DFA construction

These are the human proofs of Lazy DFA construction, at full length.

The lazy DFA accepts exactly the words that the NFA accepts full

This proof shows: correctness, termination.

Let NN have the finite set of states QQ, start state q0q_0 and accepting states FF. For S⊆QS \subseteq Q and a symbol cc, MOVE(S,c)\mathrm{MOVE}(S, c) is the set of targets of the moves on cc that leave SS, and CLOSURE(S)\mathrm{CLOSURE}(S) is the set of states reachable from SS by zero or more ε\varepsilon-moves. Define δ^(ε)=CLOSURE({q0})\hat\delta(\varepsilon) = \mathrm{CLOSURE}(\{q_0\}) and δ^(ua)=CLOSURE(MOVE(δ^(u),a))\hat\delta(ua) = \mathrm{CLOSURE}(\mathrm{MOVE}(\hat\delta(u), a)).

Lemma 1. For every word uu, δ^(u)\hat\delta(u) is the set of states qq such that some path from q0q_0 to qq reads uu, where a path may use ε\varepsilon-moves anywhere.

Proof. By induction on uu. For u=εu = \varepsilon, a path that reads ε\varepsilon uses only ε\varepsilon-moves, so its end is in CLOSURE({q0})\mathrm{CLOSURE}(\{q_0\}), and every state of the closure is the end of such a path. For uaua, a path that reads uaua splits at its last move on a symbol, which reads aa: before it, a path that reads uu, ending in some p∈δ^(u)p \in \hat\delta(u) by induction; then a move on aa from pp to some p′p', so p′∈MOVE(δ^(u),a)p' \in \mathrm{MOVE}(\hat\delta(u), a); then only ε\varepsilon-moves, so the end is in the closure. Conversely, each state of CLOSURE(MOVE(δ^(u),a))\mathrm{CLOSURE}(\mathrm{MOVE}(\hat\delta(u), a)) is the end of a path built from these three parts. □\square

So NN accepts uu if and only if δ^(u)∩F≠∅\hat\delta(u) \cap F \ne \emptyset.

Lemma 2 (stored moves). At all times, every DFA state object XX satisfies: X.accepting=(X.set∩F≠∅)X.\mathrm{accepting} = (X.\mathrm{set} \cap F \ne \emptyset), and for every symbol cc with X.next[c]=YX.\mathrm{next}[c] = Y defined, Y.set=CLOSURE(MOVE(X.set,c))Y.\mathrm{set} = \mathrm{CLOSURE}(\mathrm{MOVE}(X.\mathrm{set}, c)).

Proof. Objects are made only at line L12, with the right accepting bit and an empty table. The fields set and accepting of an object never change afterwards. A table entry is written only at line L9, as S.next[c]←TS.\mathrm{next}[c] \gets T, where TT was returned by STATE(U)(U) at line L8 with U=CLOSURE(MOVE(S.set,c))U = \mathrm{CLOSURE}(\mathrm{MOVE}(S.\mathrm{set}, c)) from line L6, and STATE(U)(U) returns an object whose set is UU: either the one already stored under the key UU, or a new one with set UU. Clearing the map at line L7 removes keys but changes no object. So the property holds after every line. □\square

Lemma 3 (loop invariant). After ii rounds of the loop at lines L3 to L10, S.set=δ^(a1⋯ai)S.\mathrm{set} = \hat\delta(a_1 \cdots a_i).

Proof. Before the loop, line L2 sets SS to an object with set CLOSURE({q0})=δ^(ε)\mathrm{CLOSURE}(\{q_0\}) = \hat\delta(\varepsilon). In round ii, with c=aic = a_i and S.set=δ^(a1⋯ai−1)S.\mathrm{set} = \hat\delta(a_1 \cdots a_{i-1}): if S.next[c]S.\mathrm{next}[c] is defined, line L4 reads TT, and by Lemma 2 T.set=CLOSURE(MOVE(S.set,c))T.\mathrm{set} = \mathrm{CLOSURE}(\mathrm{MOVE}(S.\mathrm{set}, c)). Otherwise lines L6 to L8 make TT with the same set. Either way, after line L10, S.set=CLOSURE(MOVE(δ^(a1⋯ai−1),ai))=δ^(a1⋯ai)S.\mathrm{set} = \mathrm{CLOSURE}(\mathrm{MOVE}(\hat\delta(a_1 \cdots a_{i-1}), a_i)) = \hat\delta(a_1 \cdots a_i). □\square

Termination. The loop runs once for each of the nn symbols of ww. In each round, MOVE scans the finitely many moves that leave S.setS.\mathrm{set}, and CLOSURE is a graph search that adds each state of QQ at most once. Lines L7 to L9, L12 and L13 do finitely many map operations. So the algorithm stops.

Theorem. LAZY-DFA-MATCH(N,w,k)(N, w, k) returns true if and only if NN accepts ww, for every capacity k≥1k \ge 1.

Proof. By Lemma 3, after the loop S.set=δ^(w)S.\mathrm{set} = \hat\delta(w). By Lemma 2, line L11 returns δ^(w)∩F≠∅\hat\delta(w) \cap F \ne \emptyset, which by Lemma 1 holds exactly when NN accepts ww. The capacity enters only through line L7, which by Lemma 2 never makes a stored set or move wrong. ■\blacksquare

Search. With q0q_0 added to the result of MOVE before the closure, the same argument with δ^′(ua)=CLOSURE(MOVE(δ^′(u),a)∪{q0})\hat\delta'(ua) = \mathrm{CLOSURE}(\mathrm{MOVE}(\hat\delta'(u), a) \cup \{q_0\}) shows, by the induction of Lemma 1, that δ^′(u)\hat\delta'(u) is the set of states reachable from q0q_0 by a path that reads some suffix of uu. So the state after a1⋯aia_1 \cdots a_i is accepting if and only if some substring of ww that ends at position ii is accepted.

Back to Lazy DFA construction