This file covers selected topics from lecture 4:
- definition of an NFA, the run of an NFA and the language accepted by an NFA
- how to turn an NFA into a DFA using the powerset construction
- proof that the languages of an NFA and the resulting powerset DFA are equal
- how to turn a total DFA into an NFA and the proof that the accepted language stays the same
Slides are available at: https://iccl.inf.tu-dresden.de/w/images/c/c9/FS2025-Vorlesung-04-print.pdf
An NFA (Nondeterministic Finite Automaton) is a structure depending on two types Q and Sigma both of which are finite. The transition function δ now has potentially many different values so it maps a state and a symbol to a list of states. That means when reading a symbol σ in a state q the NFA will end up in one of the states from the list. The reason why this definition uses a list instead of a set is that defining finite sets is not as easy as one might think. A list is always finite so it works just as well.
Instances For
Transition function for words mapping a word w ∈ Σ* and a list of states R to another list of states.
- w = ε: the NFA remains in one of the states from R so δ_word(R,ε) = R
- w = av: δ_word(R,av) = δ_word(R',v) where R' is the list of states reachable from some state R with a
Equations
Instances For
A run of an NFA on a word w is a sequence of states. We can express this using an inductive definition:
- For every state q, the sequence q is a run on the empty word ε.
- If an NFA has a run q2...qf on v and q2 is reachable with a from q1, then q1...qf is a run on av.
- self {Q : Type u} {Sigma : Type v} [Fintype Q] [Fintype Sigma] {nfa : NFA Q Sigma} (q : Q) : nfa.Run q q []
- step {Q : Type u} {Sigma : Type v} [Fintype Q] [Fintype Sigma] {nfa : NFA Q Sigma} {q1 q2 qf : Q} {a : Sigma} {v : Word Sigma} (r : nfa.Run q2 qf v) (q2_mem : q2 ∈ nfa.δ q1 a) : nfa.Run q1 qf (a :: v)
Instances For
The language of an NFA consists of all words w that have an accepting run beginning with some state q0 ∈ Q0 and ending in a state qf ∈ F.
Instances For
In lecture 3 we defined the language of a DFA M as the set of words w satisfying δ_word(q0,w) ∈ F. We can do something similar for NFAs (using δ_word with a the list of starting states as an input) and prove that this is equal to the previous definition using the run of an NFA. The corresponding proof in lecture 4 can be found starting from slide 18 - feel free to compare it to the Lean version!
Using the two previous results, we can show that the two different definitions for the language accepted by an NFA are equal: An NFA has an accepting run q0...qf on a word w iff the set of states reachable from q0 ∈ Q0 contains a qf ∈ F.
The following section deals with the conversion from DFA to NFA. We proceed in a similar manner as we did for the proof of totalDFA_eq_DFA in lecture3 by first showing that the transition functions of M and M.to_NFA are (almost) equal and then using this to prove the equality of M.Language and M.to_NFA.Language.
Every NFA can be turned into a total DFA using the powerset construction. Since we defined the states Q as some type with a Fintype instance, computing the "powerset" of Q is a bit tricky. A Fintype is simply a type with finitely many elements. This can be expressed by requiring the existence of a list with all elements of Q. The Powertype of Q is the list of all possible subsets of this list. We use subsets instead of lists because the powertype needs to be finite. If you are interested in the details have a look at Powertype.lean. It is not required to understand the definitions and proofs concerning Powertype to understand the section toDFA.
Equations
- powerset_δ M = Quotient.lift (fun (R : Finset' Q) (a : Sigma) => Finset.mk (List.flatMap (fun (q : Q) => M.δ q a) R)) ⋯
Instances For
Equations
- M.to_TotalDFA = { δ := fun (R : Powertype Q) (a : Sigma) => powerset_δ M R a, q0 := Finset.mk M.Q0, F := List.filter (fun (x : Powertype Q) => Finset.mk M.F ∩ x != ∅) Fintype.elems }