4.6.3 · D3Theory of Computation

Worked examples — NFA — formal definition, epsilon transitions

2,303 words10 min readBack to topic

The scenario matrix

Before any examples, let us enumerate the classes of situations an NFA computation can land in. Each row is one distinct behaviour; the examples below are labelled with the cell they cover.

# Case class What is special about it Covered by
A All branches survive, one is final Multiple guesses alive at once, acceptance is existential Ex 1
B A branch dies ( on part of the set) A guess becomes invalid but others continue Ex 1, Ex 2
C Every branch dies (empty set) Whole computation collapses → reject Ex 2
D ε-move BEFORE reading any symbol ε-closure of the start decides the empty string Ex 3
E ε-move AFTER a symbol reaches a final state Skipping closure would wrongly reject Ex 4
F The empty string itself Degenerate input, length-zero Ex 3
G A chain of ε-moves ( for free) ε-closure must be transitive, not one hop Ex 4
H Real-world word problem Modelling a spec as an NFA Ex 5
I Exam twist: "some path" vs "all paths" The classic trap of universal vs existential accept Ex 6
J Limiting / longest-guess behaviour A guess that must be delayed as long as possible Ex 7

Example 1 — all branches alive, then one dies (cells A, B)

Forecast: it ends in 1, so I expect... accept. But watch which branches live and die.

Look at the machine and the trace of state-sets below.

Figure — NFA — formal definition, epsilon transitions
  1. Start set . Why this step? Before reading anything we sit at , and there are no ε-arrows, so nothing is reachable for free.
  2. Read 1: . Set . Why this step? This is the nondeterministic guess (cell A): the machine keeps both possibilities — "this 1 is the last symbol" () and "it is not" ().
  3. Read 1: from , from . Union . Why this step? The old guess dies (cell B) because has no outgoing edge — but a fresh guess is born from .
  4. Read 0: from , from . Union . Why this step? A 0 can never be the ending 1, so the branch dies again; only the "not yet finished" branch survives.
  5. Read 1: from . Set . Why this step? Final symbol; the guess "this is the end" is reborn as .

Verify: final set , and accept ✅. Sanity check: 1101 does end in 1, matching the forecast.


Example 2 — the whole set empties out (cell C)

Forecast: it ends in 0, so I expect reject — and I bet the state-set becomes empty.

  1. Start . Why? Same reason as before.
  2. Read 1: . Why? Guess spawned.
  3. Read 1: . Why? Old dies, new one born.
  4. Read 0: from , . Why? The end-guess dies on a 0.
  5. Read 0: from . Why? loops on 0.

Verify: final set , and reject ✅.


Example 3 — the empty string, decided by ε-closure of the start (cells D, F)

Forecast: includes zero copies of 0, i.e. the empty string — so I expect accept, purely from the start's ε-closure.

Figure — NFA — formal definition, epsilon transitions
  1. Apply the base case: . Why this step? The extended transition for the empty string is defined as the ε-closure of the start — that is literally rule "before reading anything, slide along all free arrows."
  2. Compute : start with , follow ε to and . Why this step? ε-closure collects everything reachable by zero or more ε-moves, including itself (cell D).

Verify: accept ✅. This confirms cell F: the empty string's fate is settled entirely by — no symbol is ever read.


Example 4 — ε-chain reached only AFTER a symbol (cells E, G)

Forecast: after reading a I land on , which is not final — a careless reader would say reject. Let's not be careless.

Figure — NFA — formal definition, epsilon transitions
  1. Start set . has no ε-edge, so . Why this step? Base case again.
  2. Read a: collect . Why this step? Consume the symbol from every current state.
  3. Now take ε-closure of the result (this is the step people skip — cell E): : from , so the closure is . Why this step? ε-moves are free; after consuming a the machine may silently slide forward, and it must be allowed to do so transitively through the whole chain (cell G), not just one hop.

Verify: final set , and accept ✅. Had we forgotten the post-symbol closure (stopping at ) we would have wrongly rejected. And had we taken only one ε-hop (stopping at ) we'd still be fine here — but a machine whose only final state was reachable via two ε-hops would break. Always close fully.


Example 5 — real-world word problem (cell H)

Forecast: 0123 contains 123, so the machine should accept. Substring-detection is the textbook place where NFAs shine, because you get to guess where the pattern starts.

Machine: , start , .

  • loops on every symbol: for all ; plus .
  • , .
  • loops on every symbol: .

Why this design? "waits and guesses" — on a 1 it may either keep waiting () or bet that this is the start of 123 (). then checks the exact sequence. is a sink that stays accepting.

  1. Start .
  2. Read 0: . Why? No pattern yet; keep waiting.
  3. Read 1: . Why? Guess "the pattern starts here" spawns , while hedges.
  4. Read 2: , . Why? The bet is paying off — advances to .
  5. Read 3: , . Why? Pattern completed on the winning branch.

Verify: final set , accept ✅. Cross-check: 0123 literally contains 123, matching the forecast.


Example 6 — exam twist: "some path" vs "all paths" (cell I)

Forecast: 0110 does not contain 123, so the correct answer is reject — regardless of how many branches stay alive.

  1. Start .
  2. Read 0: .
  3. Read 1: . Why? Guess spawned.
  4. Read 1: , (there is no ). Union . Why? The old dies (it needed a 2), a new is born.
  5. Read 0: , . Union . Why? End-of-pattern guesses all fail.

Verify: final set , reject ✅.


Example 7 — limiting behaviour: the guess that must be delayed (cell J)

Forecast: the third-from-last symbol of 1 1 0 0 is the 1 at position 2 → so accept. The interesting part: the machine must delay its guess to exactly the right 1.

Why this design (cell J)? loops forever, so it can absorb any prefix. The branch counts exactly three more symbols. The nondeterminism guesses "the 1 I am reading right now sits three-from-the-end" — the machine must hold all such guesses simultaneously and let the wrong ones die at the end.

  1. Start .
  2. Read 1: . Why? First guess: "this 1 is 3-from-end."
  3. Read 1: , . Why? Old guess advances (); a fresh guess spawns from the second 1.
  4. Read 0: , , . Why? Each pending count steps forward; one guess reaches the accepting .
  5. Read 0: , , . Why? has no outgoing edge, so that guess dies — but another guess just completed its count of three and lands in .

Verify: final set , accept ✅. Cross-check by hand: 1100, three from the end = the symbol before the last two = the second 1 = 1. ✅


How the cells connect back

These behaviours are exactly what makes the Subset Construction (NFA to DFA) necessary: each set of states you saw above (, , ...) becomes a single DFA state. The empty set becomes the DFA's dead state. Because every NFA reduces this way, they accept precisely the Regular Languages, the same class captured by Regular Expressions and preserved under Closure Properties of Regular Languages — no more, no less than a DFA.

Recall Which cell was which? (hide answers)
  • Where does an empty final set come from? ::: All branches died (Ex 2 / Ex 6) — a clean reject, not a crash.
  • What single step do people skip, and where? ::: ε-closure after reading a symbol (Ex 4, cell E).
  • What decides acceptance of ? ::: (Ex 3, cells D/F).
  • Why must ε-closure be transitive? ::: ε-chains (Ex 4, cell G): for free.
  • "A branch stayed alive so accept" — true? ::: No; only a branch ending in counts (Ex 6, cell I).
Trace of "ends in 1" NFA on 1101 — final state-set?
, which meets , so accept.
Does the NFA accept the empty string, and why?
Yes — contains the final state .
In the ε-chain NFA ( free), does a accept?
Yes — after reading a you reach , whose ε-closure contains .
"Some branch stayed alive, so the NFA accepts." True or false?
False — acceptance needs a branch that ends in a final state, i.e. .