NFA to DFA converter: subset construction with steps
Convert a nondeterministic finite automaton into an equivalent deterministic one with the subset construction. Enter an NFA as a list of transitions, or a regular expression that is first turned into an NFA, then step through every ε-closure and every entry of the subset table. Tick “Minimise” to reduce the result to the smallest equivalent DFA.
On this page
NFA to DFA converterThe subset construction, one transition at a time.
NFA
DFA being built
Pseudocode
- A ← ε-closure({start}); mark A as unprocessed
- while some DFA state T is unprocessed:
- for each symbol c:
- U ← ε-closure(move(T, c))
- if U is empty: no transition (dead state)
- else if U is new: name it and add it, unprocessed
- δ(T, c) ← U
- accepting DFA states: those containing an accepting NFA state
This step
Result
Entering an NFA
Choose From an NFA table and write one transition per line as from symbol to. State names can be any words without spaces (q0, start, s1); symbols are single characters. Write eps, ε or - as the symbol for an ε-transition. One line start q0 names the start state and one line accept q2 q3 lists the accepting states. Anything after # is a comment. Nondeterminism is written by giving several lines with the same state and symbol, as in q0 1 q0 and q0 1 q1.
With From a regex, the expression is turned into an NFA by Thompson’s construction first (see the regex to NFA converter to step through that part), and the subset construction runs on the result.
How the subset construction works
An NFA can be in several states at once. The idea, due to Rabin and Scott, is to let one DFA state stand for the whole set of NFA states the NFA could be in. Two operations do all the work:
- : every state reachable from a state in using only ε-transitions, including the states of itself.
- : every state reachable from a state in by one transition on the symbol .
The DFA’s start state is the ε-closure of the NFA’s start state. Then, for each DFA state not yet processed and each symbol , compute . If is a set we have not seen, it becomes a new DFA state. Either way, . The construction stops when every DFA state has been processed, and a DFA state is accepting when its set contains at least one accepting NFA state.
If is empty, no NFA state can read , and the DFA moves to a dead state that rejects everything. The converter leaves the dead state out of the diagram and shows it as ∅ in the table, as the DFA simulator does.
Worked example: the second-last symbol is 1
The NFA preloaded under “From an NFA table” guesses, at some 1, that this is the second-last symbol: from q0 on 1 it may go to q1, then any symbol takes it to the accepting state q2. The subset construction gives 4 DFA states:
| DFA state | NFA states | on 0 | on 1 |
|---|---|---|---|
| →A | {q0} | A | B |
| B | {q0, q1} | C | D |
| *C | {q0, q2} | A | B |
| *D | {q0, q1, q2} | C | D |
Each DFA state remembers the last two symbols read: that is exactly the information the NFA was guessing about. The accepting states (marked *) are the sets containing q2.
The exponential blow-up
A set of NFA states has subsets, so the DFA can be exponentially larger than the NFA. The construction only creates the subsets that are actually reachable, which is usually far fewer, but some languages really do need them all. “The -th symbol from the end is 1” has an NFA with states, while any DFA for it must remember the last symbols, which takes states:
| k | NFA states | DFA states (subset construction) | after minimisation |
|---|---|---|---|
| 2 | 3 | 4 | 4 |
| 3 | 4 | 8 | 8 |
| 4 | 5 | 16 | 16 |
| 5 | 6 | 32 | 32 |
Minimisation does not help here: these DFAs are already minimal. That is the price of determinism, and it is why practical regex engines often simulate the NFA directly, or build DFA states lazily only as the input needs them.
Minimising the DFA
The subset construction rarely gives the smallest DFA. For (a|b)*abb it produces 5 states, and minimisation merges two of them, leaving 4. The converter uses Moore’s partition refinement:
- Make the DFA complete by adding a dead state for missing transitions, and drop states unreachable from the start.
- Split the states into two groups: accepting and non-accepting.
- Two states stay in the same group only if, on every symbol, they move into the same group. Split any group that breaks this, and repeat until nothing changes.
- Each final group becomes one state of the minimal DFA.
The minimal DFA is unique up to renaming states (the Myhill–Nerode theorem), so two regular expressions describe the same language exactly when their minimal DFAs are the same machine. That gives a mechanical way to check whether a simplified regex is still correct.
Background
The full story, from Kleene’s theorem to minimal DFAs, is in from regular expressions to automata. If DFAs are new to you, start with finite-state machines.
References
- M. O. Rabin and D. Scott, “Finite automata and their decision problems”, IBM Journal of Research and Development 3(2), 1959. doi:10.1147/rd.32.0114
- E. F. Moore, “Gedanken-experiments on sequential machines”, in Automata Studies, Princeton University Press, 1956.
- J. E. Hopcroft, R. Motwani and J. D. Ullman, Introduction to Automata Theory, Languages, and Computation, 3rd ed., Pearson, 2006. Sections 2.3 and 4.4.