Hello! Welcome back to our study of computation.
In our last lesson, we introduced the Nondeterministic Finite Automaton with ε-transitions (NFA-ε). We saw that while these "free moves" make designing automata more convenient, they don't add any fundamental power—any NFA-ε can be converted into an equivalent standard NFA.
Today, we'll see exactly why NFA-ε are so convenient. We will learn a cornerstone algorithm known as Thompson's construction, which provides a systematic, step-by-step method to convert any regular expression into an equivalent NFA-ε. This lesson is a constructive proof that any language that can be described by a regular expression is, in fact, a regular language.
Your experience in designing and building software systems, where you often translate high-level specifications into concrete implementations, provides a great parallel. Think of a regular expression as a high-level pattern specification and an NFA as a low-level, "executable" machine model. Thompson's construction is the compiler that bridges this gap.
The Algorithm: Building NFAs from Regular Expressions
Regular expressions are defined recursively. They have simple base cases (ε, ∅, and single symbols like a) and recursive cases that build larger expressions from smaller ones using operators (union, concatenation, and star).
Thompson's construction is an elegant algorithm that mirrors this recursive structure. We will:
- Define simple "atomic" NFAs for the base cases.
- Define rules for combining these atomic NFAs to handle the recursive cases.
A key feature of the NFAs produced by this algorithm is that they are highly composable: each NFA will have exactly one start state and exactly one final state, and the final state will have no outgoing transitions. This modularity is what makes the algorithm work so well.
The Building Blocks: Thompson's Construction Rules
Let's dive into the specific rules for the construction. We'll start with the base cases and then move to the operations that combine them.
The following Wikipedia article provides a concise summary of the rules for Thompson's construction, complete with clear diagrams for each case. These diagrams are the definitive visual guide for the algorithm.
Please read the section titled 'Rules'. Focus on the diagrams for each of the five cases: empty-expression (ε), symbol, union, concatenation, and Kleene star. Notice how each construction results in a machine with a single entry point (start state) and a single exit point (final state).
To reinforce this, let's watch a video that walks through these same constructions. The presenter links these constructions back to the closure properties we discussed for regular languages, which is a powerful insight.
2. Nondeterminism, Closure Properties, Conversion of Regular Expressions to FA
Professor Sipser's lecture from MIT OpenCourseWare demonstrates how to build up NFAs for complex regular expressions. He treats the construction as an automatic procedure built from the closure properties we've seen.
Watch the segment from 52:24 to 59:30. Pay close attention to how he starts with NFAs for the 'atomic' expressions 'a' and 'b' and then uses the constructions for concatenation and union to build the NFA for 'a union ab'. This perfectly illustrates the recursive nature of the algorithm.
Let's summarize the rules you've just reviewed. For any regular expression , we are building an NFA we can represent as a box with a start and final state: .
-
Base Cases:
- For
ε: A start state with an ε-transition to a final state.
start --ε--> final - For a symbol
ain Σ: A start state with ana-transition to a final state.
start --a--> final - For
∅: A start state and a final state with no path between them.
- For
-
Recursive Cases: (Assuming we have already constructed and )
- Union (
s | t): Create a new start state with ε-transitions to the start states of and . Create a new final state, and add ε-transitions from the final states of and to it. - Concatenation (
st): The start state of becomes the overall start state. The final state of becomes the overall final state. Connect the final state of to the start state of with an ε-transition. - Kleene Star (
s*): Create a new start and a new final state.- Add an ε-transition from the new start state to the new final state (this handles the "zero occurrences" case, i.e., the empty string).
- Add an ε-transition from the new start state to the start state of .
- Add an ε-transition from the final state of to the new final state.
- Add an ε-transition from the final state of back to the start state of (this allows for one or more repetitions).
- Union (
A Worked Example: (a|b)*abb
Now, let's apply these rules to a more complex regular expression: (a|b)*abb. The structure of this expression is CONCAT(CONCAT(CONCAT(STAR(UNION(a, b)), a), b), b). We build the NFA from the inside out.
-
NFA for
aandb: We start with the atomic NFAs foraandb.- N(a):
(q_a_start) --a--> (q_a_final) - N(b):
(q_b_start) --b--> (q_b_final)
- N(a):
-
NFA for
a|b: Apply the union rule to N(a) and N(b). We create a new start state with ε-moves toq_a_startandq_b_start, and a new final state that is the target of ε-moves fromq_a_finalandq_b_final. -
NFA for
(a|b)*: Apply the star rule to our NFA fora|b. This involves adding another new start and final state and the four required ε-transitions for looping and bypass. -
NFA for
(a|b)*a: Apply the concatenation rule. We connect the final state of N((a|b)*) to the start state of a new NFA forawith an ε-transition. -
NFA for
(a|b)*aband(a|b)*abb: We repeat the concatenation step twice more, first forb, and then for a finalb.
The final result is a large but systematic NFA-ε that accepts exactly the language described by (a|b)*abb.

Test your understanding!
Sketch the NFA-ε that results from applying Thompson's construction to the regular expression a(b*|c).
Show answer
Here's a breakdown of the construction:
-
Innermost part:
b*- Start with N(b):
(q1) --b--> (q2) - Apply star rule: Create new start
s1and finalf1.s1 --ε--> f1(for empty string)s1 --ε--> q1q2 --ε--> f1q2 --ε--> q1(for repetition)
- Start with N(b):
-
Next part:
b*|c- We have N(b*) from step 1 and N(c):
(q3) --c--> (q4). - Apply union rule: Create new start
s2and finalf2.s2 --ε--> s1(start of N(b*))s2 --ε--> q3(start of N(c))f1 --ε--> f2(from final of N(b*))q4 --ε--> f2(from final of N(c))
- We have N(b*) from step 1 and N(c):
-
Outermost part:
a(b*|c)- We have N(a):
(q5) --a--> (q6)and N(b*|c) from step 2. - Apply concatenation rule: The start state of N(a) (
q5) is the overall start state. The final state of N(b*|c) (f2) is the overall final state. - Connect them:
q6 --ε--> s2
- We have N(a):
The final machine starts at q5, reads an a to get to q6, takes a "free" ε-move to s2, and then nondeterministically chooses to process either a string from L(b*) or a c before reaching the final state f2.
Conclusion
Today we explored Thompson's construction, a powerful and systematic algorithm for converting any regular expression into an equivalent NFA-ε. This process is not just a theoretical exercise; it's the basis for how many real-world regular expression engines are implemented. By providing a constructive proof, we have solidified one direction of a major theorem in this field.
Key Takeaways:
- Thompson's construction is a recursive algorithm that builds an NFA-ε from a regular expression.
- The algorithm defines simple NFAs for the base cases (
ε,∅,a) and provides rules for combining them to handle the recursive cases (union, concatenation, Kleene star). - The NFAs produced are modular, each with a single start and final state, making them easy to compose into larger machines.
- This construction proves that every language describable by a regular expression is a regular language.
Preview of the Next Lesson:
We have successfully built a bridge from regular expressions to finite automata. But is the bridge a two-way street? Can we go in the other direction? In the next lesson, we will answer that question by learning the state elimination method, an algorithm for converting any DFA back into an equivalent regular expression. By proving this, we will complete the proof of Kleene's Theorem, which states that regular expressions and finite automata are equivalent in their descriptive power.