- Review of NDFA-to-DFA conversion so far
-
Last class we introduced this amazing algorithm that converts
an NDFA without $\lambda$-transitions to a DFA that accepts the
same language. For review, here it is:
Algorithm: NDFA-to-DFA Conversion
Input: a nondeterministic finite automaton
$M = \left(Q,\Sigma,\Delta,s,W\right)$, which has no
$\lambda$-transitions
Output: a deterministic finite automaton $M'$
such that $L(M') = L(M)$.
$
M' = \left( 2^{Q}, \Sigma, \delta, \{s\}, \{ R \in 2^{Q}\ |\ R
\cap Q \neq \emptyset \} \right)
$, where
$\delta(H,x) = \{ q \in Q \ |\ \exists p \in
H\left[(p,x,q) \in \Delta\right] \}$
For further practice,
run the above algorithm on the machine M =
({q0,q1},{a,b,c},{(q0,a,q0},(q0,c,q0),(q0,c,q1),(q1,a,q1),(q1,b,q1)},q0,
{q1}).
- How do we know it works?
-
How do we know algorithm "Non-Deterministic (w/o λ-transitions) to
Deterministic FA" really works? I'll give the idea behind a
proof of correctness. Recall the following example $M$ and
$M'$ from last class:
What we're going to show is that a computation (as a sequence
of configurations) in $M'$ is essentially a summary of all
possible computational paths in $M$. Let's see this in
action in input $w = babc$:
all paths in $M$ |
$(q_0,babc)$ | $\Rightarrow_M$ |
$(q_0,abc)$ | $\Rightarrow_M$ |
$(q_0,bc)$ | $\Rightarrow_M$ |
$(q_0,c)$ | $\times$ |
|
| $(q_0,babc)$ | $\Rightarrow_M$ |
$(q_0,abc)$ | $\Rightarrow_M$ |
$(q_0,bc)$ | $\Rightarrow_M$ |
$(q_1,c)$ | $\Rightarrow_M$ |
$(q_1,\lambda)$ |
| $(q_0,babc)$ | $\Rightarrow_M$ |
$(q_1,abc)$ | $\times$ |
| |
| |
|
reachable states
|
$\{q_0\}$ | |
$\{q_0,q_1\}$ | |
$\{q_0\}$ | |
$\{q_0,q_1\}$ | |
$\{q_1\}$ | |
path in $M'$ |
$(\{q_0\},babc)$ | $\Rightarrow_M'$ |
$(\{q_0,q_1\},abc)$ | $\Rightarrow_M'$ |
$(\{q_0\},bc)$ | $\Rightarrow_M'$ |
$(\{q_0,q_1\},c)$ | $\Rightarrow_M'$ |
$(\{q_1\},\lambda)$ |
Hopefully that makes clear what I meant by saying that a
computation in $M'$ for $w$ is a summary of all possible
computations in $M$ for $w$. If we can establish that this
is indeed always the case, then it's clear that DFA $M'$ and
NDFA $M$ accept exactly the same strings — i.e. that
the conversion algorithm is correct. Formally, what we'd
like to prove is the following theorem:
If $M = (Q,\Sigma,\Delta,s,W)$ is an NDFA w/o
$\lambda$-transitions, and $M'$ is the DFA resulting from
the conversion algorithm, then for any string $w = w_1\cdots
w_n \in \Sigma$
$$
(\{s\},w) \Rightarrow_{M'}^* (H,\lambda)
\text{ if and only if }
H = \{ q\in Q\ |\ (s,w) \Rightarrow_M^* (q,\lambda) \}.
$$
Proof:
This really requires proof by induction — induction on
$n$, which is the length of $w$.
For the moment I'm not going to include this proof
- What about the λ-transitions?
-
Our algorithm for converting non-deterministic finite automata into
deterministic finite automata doesn't work if we
have λ-transitions. So, to round things out for us, we need
an algorithm that takes a nondeterministic machine
with λ-transitions and produces a new nondeterministic
machine that accepts the same language, but which
has no λ-transitions. The general idea is this: Suppose
state p has an λ-transition to
state q, and suppose that for character x you have
transitions from state q to states
r1, r2, ..., rk. Then essentially, if you're in state
p and x is the next character in the
input, you can either take any of p's x-transitions
or you can go to q and then take one of
q's x-transitions, which take you to r1, or
r2 or ... or rk. Thus,
we can replace the λ-transition (p,λ,q) with the
regular transitions
{(p,x,r) | x ∈ Σ and (q,x,r) ∈ Δ}.}
Now, this idea works fine if there are not, in turn,
λ-transitions out of q. The question is, if
a machine has λ-transitions, can we always find at least one
λ-transition to a state that has no
λ-transitions? Then we could keep eliminating
λ-transitions of that type until there weren't any
at all. Unfortunately, there is one way that we could be unable to
find an λ-transition to a state out of
which there are no λ-transitions: What if there is a loop (or
in graph parlance a cycle) of
λ-transitions? So, first we need to get rid of any cycles of
λ-transitions.
Well, if there is a cycle of λ-transitions, the states in the
cycle all form one big "super state", because
whenever you're in one of the states you can get to any other without
reading any input. So if there's a cycle, we'll
merge all the states along the cycle into one state, wiping out all the
λ-transitions between them in the process.
This can simply be repeated until we finally arrive at a machine that
has no cycles.
Algorithm: Lose λ-transition
Input: NDFA M = (Q,Σ,Δ,s,W) and
(p,λ,q) ∈ Δ, where there are no
λ-transitions out of q.
Output: NDFA M' such that $L(M) = L(M')$ and
$M'$ has one fewer $\lambda$-transitions than $M$
M' = (Q,Σ,Δ',s,W'), where
Δ' = Δ - {(p,λ,q)} ∪ { (p,x,r) ∈
QxΣxQ | (q,x,r) ∈ Δ }
W' = W ∪ {p} if q ∈ W, and
W otherwise
Claim:
Algorithm Lose λ-transition meets its
specification, i.e.
L(M') = L(M) and there is one fewer
λ-transition in M' than
in M.
Proof:
The fact that there is one fewer λ-transition in M' than
in M is obvious, so we concentrate on proving that L(M') = L(M).
We need to prove that for any string $w$,
$w \in L(M)$ if and only if $w \in L(M')$. This means that
$M$ and $M'$ accept the same strings and reject the same strings.
-
If $w \in L(M)$ then $w \in L(M')$:
Since $w \in L(M)$, we know that $(s,w) \Rightarrow_M^* (r,\lambda)$,
where $r \in W$. In other words, we have a
(potentially) long sequence
\[
(s,w) \Rightarrow_M \ldots \Rightarrow_M (r,\lambda)
\]
representing a valid, accepting computation in $M$. To
prove that $w$ is accepted by $M'$, I will give you an
algorithm that converts that sequence into a sequence
representing an accepting computation for string $w$ and
machine $M'$. Here it is:
-
if the sequence ends in $(p,\lambda) \Rightarrow_M (q,\lambda)$,
drop the "$\Rightarrow_M (q,\lambda)$".
Note: this removes any use of $(p,\lambda,q)$
as the last step in the computation.
-
moving left-to-right in the sequnce, replace any
$(p, xu) \Rightarrow_M (q,xu) \Rightarrow_M (r,u)$
with $(p, xu) \Rightarrow_M (r,u)$
Note: this removes any remaining use of $(p,\lambda,q)$
-
change any remaining $\Rightarrow_M$ to $\Rightarrow_{M'}$
The resulting sequence is a valid computation in $M'$,
and it either ends in the same state $r$, which is
accepting for $M'$, or the original ended in $q$ and the
new sequence ends in $p$. But in this case $q$ must
have been accepting for $M$, which means $p$ is
accepting in $M'$. In either case, $w$ is accepted by
$M'$, which is what we needed to show.
-
If $w \in L(M')$ then $w \in L(M)$:
I'll leave this up to you. You need an algorithm that
converts a sequence
\[
(s,w) \Rightarrow_{M'} \ldots \Rightarrow_{M'} (r,\lambda)
\]
where $r \in W'$ to a sequence representing an accepting
computation in $M$.
The only problem that remains is what to do if there are
$\lambda$-transitions, but all of them into states that
themselves have outgoing $\lambda$-transions. In this case,
we can't apply the above algorithm. The thing to note is
that this can only happen in the presence of cycles of
$\lambda$-transitions. The next algorithm removes such
cycles by merging all states in such a cycle into a single
state.
Algorithm: Lose λ-cycle
Input: NDFA M = (Q,Σ,Δ,s,W) and states
p1,p2,...,pk comprising a cycle of 2 or more
λ-transitions in M
Output: NDFA M' such that
$L(M') = L(M)$ and $M'$ has fewer $\lambda$-transitions than $M$
M' = (Q',Σ,Δ',s',W') where
Q' = Q - {p1,...,pk} ∪ {D}, where D is
a new state i.e. D ∉ Q
| Δ' = Δ |
| |
| - {p1,...,pk}x(Σ ∪
{λ})xQ
|
remove transitions out
of the cycle
|
| - Qx(Σ ∪ {λ})x{p1,...,pk} |
remove transitions into
the cycle |
| ∪ {(D,x,q) ∈ {D}x(Σ ∪
{λ})xQ' | for some pi, (pi,x,q) ∈ Δ} |
add transitions out of D |
| ∪ {(q,x,D) ∈ Q'x(Σ ∪
{λ})x{D} | for some pi, (q,x,pi) ∈ Δ} |
add transitions into D |
| ∪ {(D,x,D) ∈
{D}xΣx{D} |
for some pi and pj, (pi,x,pj) ∈ Δ} |
add D's loops |
s' = D if s ∈ {p1,...,pk}, and
s otherwise
W' = W if W ∩ {p1,...,pk} = ∅, and
W' = W ∪ {D} - {p1,...,pk} otherwise
Claim:
Algorithm: Lose λ-cycle meets its
specification, i.e.
L(M') = L(M) and there are fewer
λ-transitions in M' than in M.
Proof:
In this case we will rely on the in-class discussion to
convince you that this algorithm works.
- A full algorithm converting an NDFA into a DFA
-
Assume you're given a machine M =
(Q,Σ,Δ,s,W) which has no transitions of the
form (q,λ,q). This assumption is no real
restriction, since such transitions are pointless and can
simply be removed without affecting the language accepted by
the machine. Set M' = M and then:
- Apply Algorithm: Lose λ-cycle
repeatedly until there are no λ-cycles left in
M'. This will only require a finite number of
applications of the algorithm, since the number of
λ-transitions
decreases with every application of the algorithm.
- Repeatedly apply Algorithm Lose λ-transition
until there are no λ-transitions left. This can
only take a finite number of steps because the number of
λ-transitions is finite, and each application of
the algorithm reduces the number of
λ-transitions. We are assured that we can always
find a transition (p,λ,q) such that no
λ-transitions come out of q because the
machine has no λ-cycles. (Think about it!)
Moreover, since we don't add new λ-transitions with
this algorithm, no new cycles can appear.
-
Apply the algorithm from Class
14 to convert the resulting nondeterministic machine
(which now has no λ-transitions) into an
equivalent deterministic finite automaton.
The deterministic finite automaton that results from this
process accepts the same language as the original
nondeterministic machine!