4.6.4 · D2Theory of Computation

Visual walkthrough — NFA to DFA conversion — subset construction

1,986 words9 min readBack to topic

Step 1 — Two machines, one difference

WHAT. Look at the two little machines in the figure. On the left, a Non-deterministic Finite Automaton (NFA): from one room, one letter, you can be sent to several rooms — or slide for free along a dashed -edge (an edge you cross without reading any letter). On the right, a Deterministic Finite Automaton (DFA): one room, one letter, exactly one destination, no dashed edges.

WHY. Everything on this page exists to bridge this one gap. The NFA is allowed to be in a set of rooms; the DFA is forced to be in a single room. The whole trick will be: make the DFA's single room stand for the NFA's whole set of rooms.

PICTURE. The NFA (left) shows room firing into on the letter — two arrows from one letter. The DFA (right) shows one arrow per letter. That fan-out on the left is the "many at once" we must tame.

Figure — NFA to DFA conversion — subset construction

Step 2 — The notebook idea: one DFA room = a SET of NFA rooms

WHAT. We declare, once and for all: a single state of the DFA is a set of NFA rooms. If the NFA might be standing in rooms and simultaneously, the DFA has one state literally named .

WHY. A DFA cannot split. But a set is a single object. So "the collection of all rooms the NFA could be in" is itself one thing — and we let the DFA hold that one thing. Because these sets are drawn from the power set of all subsets, this is the subset construction.

PICTURE. The figure boxes up the NFA's three rooms and then draws a few sets of them (, , ) as new single tiles. Each tile is one future DFA room.

Figure — NFA to DFA conversion — subset construction

Term by term: is the DFA state we are naming; the braces hold the NFA rooms it stands for; is the shelf of every subset — with rooms there are shelves, though we will only ever visit the reachable ones.


Step 3 — Before reading anything: the free slide (ε-closure)

WHAT. We compute where the NFA can be before it reads a single letter. Start room is . But room has a dashed -edge to room — a free slide. So the NFA is already possibly in both and . We bundle those: .

WHY. The dashed edges cost no input. So the instant the machine is switched on, it has silently drifted everywhere those free edges reach. If the DFA started at just it would forget room was reachable — and miss strings the NFA accepts. The ε-closure is the fix.

PICTURE. Watch the green flood: it starts on room , then walks the dashed edge to , and stops (room has no outgoing dashed edge). The green blob is our DFA start state, call it .

Figure — NFA to DFA conversion — subset construction

= every room reachable from using only -edges, including itself. Here closes up to .


Step 4 — Reading a letter: MOVE, then close again

WHAT. From state we read the letter . Two sub-steps, in strict order:

  1. MOVE — take a real -step from every room in . Room has no -edge; room has . So .
  2. ECLOSE — now let the result drift along free edges. Room has a dashed edge to , so .

Combine: . Call this new state .

WHY this order. Reading a letter is one honest step followed by any number of free slides. If you closed before moving but forgot to close after, you would land in and forget that the NFA immediately slides to as well — losing the -step that room later enables. MOVE-then-CLOSE, every time.

PICTURE. Orange arrow = the real -step (). Green flood again = the ε-closure that pulls in room . The final blob is a new tile, so we add it to the notebook as unprocessed.

Figure — NFA to DFA conversion — subset construction

— the union sign says "collect the targets from each room in and pool them." Then ECLOSE wraps free slides around that pool.


Step 5 — Repeat until the notebook stops growing

WHAT. State is unprocessed, so read from it. MOVE: room gives , room has no -edge, so . ECLOSE gives again. So — a self-loop. No new state appears.

WHY it terminates. Every DFA state is a subset of , and there are only subsets. Each round either produces an old set (stop expanding down that branch) or a genuinely new one. You cannot invent new subsets forever, so the process must halt. (This is why the DFA is finite.)

PICTURE. The growing notebook: tile , arrow to tile , and looping to itself. There are no fresh tiles left to process — we are done exploring.

Figure — NFA to DFA conversion — subset construction
DFA state reachable? on
(start) yes
yes

We never listed the other subsets — they are unreachable from the start, so they simply do not exist in our DFA. (Trap: don't generate all up front.)


Step 6 — Which tiles are accepting?

WHAT. A DFA state is accepting exactly when its set contains at least one NFA accepting room. Our final room is .

  • : does it contain ? No — reject.
  • : does it contain ? Yes — accept.

WHY "contains", not "equals". The NFA succeeds if any single one of its parallel paths ends in a final room. So the notebook state succeeds as soon as it touches — one accepting room on the list is enough. Demanding the whole set equal would wrongly reject the accepting state .

PICTURE. Room glows as the NFA's exit. Any tile whose set overlaps that glow gets a double-ring (accepting). lights up; stays plain.

Figure — NFA to DFA conversion — subset construction

is the overlap of a DFA-tile with the NFA's finals; the condition ("is not empty") is the "touches" test.


Step 7 — The degenerate case: the empty tile

WHAT. Suppose MOVE ever returns nothing — say we read a letter no live room can handle. Then , the empty set. This is a legitimate DFA state: the notebook is blank, no NFA room is alive.

WHY it matters. A DFA's transition function must be total — defined for every state and every letter. If we left it undefined, the machine would jam. Instead is the dead/trap state: once empty, every letter keeps it empty (), and since it is never accepting. It swallows all doomed strings.

PICTURE. A grey empty tile with self-loops on every letter, marked "reject forever." (In our example every MOVE stayed non-empty, so is unreachable and we may omit it — but you must know it exists.)

Figure — NFA to DFA conversion — subset construction

The one-picture summary

WHAT. One diagram, whole derivation: NFA on the left, the pipeline (ECLOSE start → MOVE-then-ECLOSE per letter → touch-test for accept) in the middle, the finished DFA on the right.

Figure — NFA to DFA conversion — subset construction

ECLOSE

MOVE then ECLOSE on a

MOVE then ECLOSE on a

touches final 2

misses final

Start room q0

DFA start = A

new tile B

B is accepting

A rejects

Recall Feynman: the whole walkthrough in plain words

A magic robot can stand in many rooms at once and slip through free doorways without spending a letter. A plain robot can't split — so we hand it a notebook.

First, before reading anything, the plain robot writes down every room the magic robot could already be in after slipping through free doorways — that's the start page ( of the start room). Then each time it reads a letter, it does the same two things: take one honest step from every room on the current page (MOVE), then slip through all the free doorways again (ECLOSE). That gives the next page. It keeps discovering pages until no new page appears — which must happen, because there are only finitely many possible lists of rooms. Finally, it circles every page that mentions an exit room: if any listed room is an exit, that page means "Accepted." And if a page ever goes blank, that's the dead-end page that just says "no" forever. That filled notebook is the DFA.


Connections