Algorithm Search⌘K

Proofs: Product construction

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

The product construction accepts exactly the strings on which the Boolean operation of the two languages is true full

This proof shows: correctness, termination.

Let M1=(Q1,Σ,δ1,s1,F1)M_1 = (Q_1, \Sigma, \delta_1, s_1, F_1) and M2=(Q2,Σ,δ2,s2,F2)M_2 = (Q_2, \Sigma, \delta_2, s_2, F_2) be complete DFAs over the same alphabet, with δi:Qi×Σ→Qi\delta_i : Q_i \times \Sigma \to Q_i, and let op:{0,1}2→{0,1}\mathrm{op} : \{0, 1\}^2 \to \{0, 1\} be a Boolean function. Let P=(Q,Σ,δ,s,F)P = (Q, \Sigma, \delta, s, F) be the output of PRODUCT(M1,M2,op)(M_1, M_2, \mathrm{op}). Write δi∗\delta_i^* for the extension to strings: δi∗(q,ε)=q\delta_i^*(q, \varepsilon) = q and δi∗(q,va)=δi(δi∗(q,v),a)\delta_i^*(q, va) = \delta_i(\delta_i^*(q, v), a).

Lemma 1 (termination and reachability). The algorithm stops. Its set QQ is the set of pairs (δ1∗(s1,w),δ2∗(s2,w))(\delta_1^*(s_1, w), \delta_2^*(s_2, w)) for w∈Σ∗w \in \Sigma^*, and δ\delta is defined on each pair of QQ and each symbol.

Proof. A pair enters WW only when it enters QQ, at line L2 or line L7, and never leaves QQ. So each pair of Q1×Q2Q_1 \times Q_2 enters WW at most once, the loop makes at most ∣Q1∣∣Q2∣|Q_1| |Q_2| passes, and each pass does ∣Σ∣|\Sigma| steps. Each pair that enters QQ is removed from WW later, and then line L8 defines its move on each symbol.

Each pair of QQ has the stated form: s=(δ1∗(s1,ε),δ2∗(s2,ε))s = (\delta_1^*(s_1, \varepsilon), \delta_2^*(s_2, \varepsilon)), and if (p,q)=(δ1∗(s1,w),δ2∗(s2,w))(p, q) = (\delta_1^*(s_1, w), \delta_2^*(s_2, w)), then line L6 adds (δ1(p,a),δ2(q,a))=(δ1∗(s1,wa),δ2∗(s2,wa))(\delta_1(p, a), \delta_2(q, a)) = (\delta_1^*(s_1, wa), \delta_2^*(s_2, wa)). Conversely, by induction on ∣w∣|w|, the pair of ww is in QQ: true for ε\varepsilon, and if the pair of ww is in QQ, it is removed from WW at some time, and line L7 puts the pair of wawa in QQ. □\square

Lemma 2 (the run of the product). For each w∈Σ∗w \in \Sigma^*, δ∗(s,w)=(δ1∗(s1,w),δ2∗(s2,w))\delta^*(s, w) = (\delta_1^*(s_1, w), \delta_2^*(s_2, w)).

Proof. By induction on ∣w∣|w|. For w=εw = \varepsilon both sides are s=(s1,s2)s = (s_1, s_2). If the claim holds for ww, with the pair (p,q)(p, q), then δ∗(s,wa)=δ((p,q),a)=(δ1(p,a),δ2(q,a))\delta^*(s, wa) = \delta((p, q), a) = (\delta_1(p, a), \delta_2(q, a)) by line L6 and line L8, and this is (δ1∗(s1,wa),δ2∗(s2,wa))(\delta_1^*(s_1, wa), \delta_2^*(s_2, wa)). □\square

Theorem. PP is a complete DFA on its states, and for each w∈Σ∗w \in \Sigma^*,

w∈L(P)  ⟺  op(w∈L(M1), w∈L(M2)).w \in L(P) \iff \mathrm{op}\big(w \in L(M_1),\ w \in L(M_2)\big).

In particular, op = and gives L(M1)∩L(M2)L(M_1) \cap L(M_2), op = or gives L(M1)∪L(M2)L(M_1) \cup L(M_2), op(x,y)=x∧¬y\mathrm{op}(x, y) = x \wedge \neg y gives L(M1)∖L(M2)L(M_1) \setminus L(M_2), and op = xor gives the symmetric difference.

Proof. By Lemma 1, each state of PP has a move on each symbol, and the move is one pair of QQ. By Lemma 2 and line L9, δ∗(s,w)∈F\delta^*(s, w) \in F if and only if op(δ1∗(s1,w)∈F1,δ2∗(s2,w)∈F2)\mathrm{op}(\delta_1^*(s_1, w) \in F_1, \delta_2^*(s_2, w) \in F_2), and δi∗(si,w)∈Fi\delta_i^*(s_i, w) \in F_i if and only if w∈L(Mi)w \in L(M_i). ■\blacksquare

Why completeness is needed. If M2M_2 has no move on (q,a)(q, a), then line L6 has no pair to build, and each string ww that drives M2M_2 into this gap is rejected by PP, whatever the value of op. For op = or, a string in L(M1)L(M_1) that falls into the gap of M2M_2 must be accepted, so the result is wrong. For op = and it is still correct, because such a string is not in L(M2)L(M_2). To use any other op, first add a dead state to each input.

Running time. By Lemma 1 there are N≤∣Q1∣∣Q2∣N \le |Q_1| |Q_2| passes, each with ∣Σ∣|\Sigma| lookups and one dictionary test per symbol, so the time is O(N∣Σ∣)O(N |\Sigma|) with hashing, and O(∣Q1∣∣Q2∣∣Σ∣)O(|Q_1| |Q_2| |\Sigma|) in the worst case. The table has N∣Σ∣N |\Sigma| entries.

Back to Product construction