Intuition The big picture (WHY this matters)
A regular expression (regex) is a pattern you write down with symbols like a, |, *.
A finite automaton (FA) is a machine with states that reads input and accepts/rejects.
These look totally different — one is text, one is a diagram — yet they describe the exact same
class of languages : the regular languages . This is Kleene's Theorem . It's the bridge
that lets you go from "I can describe a pattern" to "I can build a machine that recognizes it"
and back again. That's why grep, lexers, and search engines work.
Definition Kleene's Theorem
A language L L L is described by some regular expression if and only if L L L is accepted by
some finite automaton (DFA or NFA). Symbolically:
L = L ( R ) for some regex R ⟺ L = L ( M ) for some FA M . L = L(R) \text{ for some regex } R \iff L = L(M) \text{ for some FA } M. L = L ( R ) for some regex R ⟺ L = L ( M ) for some FA M .
This is an iff , so we need two directions :
Regex → NFA (every pattern is buildable as a machine) — Thompson's construction .
FA → Regex (every machine's behavior is expressible as a pattern) — state elimination .
Because NFA ≡ DFA (subset construction, proven elsewhere), proving regex ↔ NFA is enough.
Intuition Why exactly these operators?
They mirror the three ways NFAs combine : running one machine then another (concatenation),
choosing between machines (ε \varepsilon ε -branch = union), and looping back (ε \varepsilon ε -loop = star).
The operators were designed to match what ε \varepsilon ε -transitions can do — that's the secret
of why the equivalence is so clean.
For each regex we build a tiny NFA with exactly one start state and one accept state ,
and we glue these tiny machines together using ==ε \varepsilon ε -transitions==. Keeping a single
start/accept makes gluing trivial.
Worked example Build an NFA for
(a|b)*a — Why each step?
a gadget: → a → \to a \to → a → . Why: base case for a single symbol.
b gadget: → b → \to b \to → b → . Why: base case.
a|b : new start ε \varepsilon ε -branches to the a and b gadgets, new accept collects both.
Why: union = "either branch."
(a|b)* : wrap step 3 with the star gadget (skip-edge for zero, loop-back for repeat).
Why: star = "zero or more of the inside."
(a|b)*a : concatenate the star-NFA's accept via ε \varepsilon ε to a fresh a gadget.
Why: concatenation = "do the star, then read one final a."
Result accepts any string of a's/b's that ends in a . Sanity check: "ba" ✓, "b" ✗.
Common mistake Steel-man: "I'll merge start/accept states to save space."
Why it feels right: fewer states looks simpler, and it often seems to work on small cases.
Why it's wrong: in the star gadget, if you reuse N R N_R N R 's start as the new start without the
fresh accept, a partial loop can leak an accepting path you never intended (e.g. accepting a
string that's not a clean repetition). Fix: always add fresh start/accept states for
union and star. The clean invariant (1 start, 1 accept, no edges into start, none out of accept)
is what makes induction correct.
Intuition WHAT a GNFA is and WHY we use it
Normal NFA edges are labeled with single symbols. A Generalized NFA (GNFA) allows edges
labeled with whole regexes . We rip out states one by one; each time we delete a state we
re-label the surviving edges with bigger regexes that "remember" the deleted paths. When only
the start and accept remain, the single edge between them is the answer.
Worked example FA → Regex, tiny machine — Why each step?
States { 1 , 2 } \{1,2\} { 1 , 2 } , start 1 1 1 , accept 2 2 2 . Edges: 1 → a 2 1\xrightarrow{a}2 1 a 2 , 2 → b 2 2\xrightarrow{b}2 2 b 2 (self-loop).
Add s → ε 1 s\xrightarrow{\varepsilon}1 s ε 1 and 2 → ε f 2\xrightarrow{\varepsilon}f 2 ε f . Why: normalize so start has
no incoming, accept has no outgoing.
Eliminate state 1 1 1 : only path s → 1 → 2 s\to 1\to 2 s → 1 → 2 with labels ε , a \varepsilon, a ε , a , no self-loop on 1, so
new edge s → ε a 2 = s → a 2 s\xrightarrow{\varepsilon\,a}2 = s\xrightarrow{a}2 s ε a 2 = s a 2 . Why: R q q ∗ = ∅ ∗ = ε R_{qq}^*=\varnothing^*=\varepsilon R q q ∗ = ∅ ∗ = ε .
Eliminate state 2 2 2 : path s → 2 → f s\to 2\to f s → 2 → f with 2 2 2 's self-loop b b b . New edge
s → a b ∗ ε f = a b ∗ s\xrightarrow{a\,b^{*}\,\varepsilon}f = a b^{*} s a b ∗ ε f = a b ∗ . Why: the rule R i q R q q ∗ R q j = a ⋅ b ∗ ⋅ ε R_{iq}R_{qq}^*R_{qj}=a\cdot b^*\cdot\varepsilon R i q R q q ∗ R q j = a ⋅ b ∗ ⋅ ε .
Answer: a b ∗ \boxed{ab^{*}} a b ∗ — "an a then any number of bs." Check: "a" ✓, "abbb" ✓, "b" ✗.
Common mistake Steel-man: "Order of elimination changes the language."
Why it feels right: different elimination orders give different-looking regexes, so it seems
the result depends on order. Why it's wrong: they're equivalent regexes (same language),
just written differently — like 2 + 3 2+3 2 + 3 vs 3 + 2 3+2 3 + 2 . Fix: any order is correct; pick the order that
keeps regexes small. Verify by testing a few strings, not by string-matching the regex text.
Intuition Why "iff" finishes the job
Direction 1 shows regex ⊆ FA-languages . Direction 2 shows FA-languages ⊆ regex . Two
containments = equality. Plus NFA ≡ DFA means we can freely say "FA" without worrying which kind.
So regex, NFA, DFA all carve out the same set: the regular languages.
Recall Feynman: explain to a 12-year-old
Imagine a regex is a recipe written in words ("first an apple, then any number of bananas").
A finite automaton is a little robot that walks through rooms as it eats each fruit and lights
up green if the meal matches. Kleene's theorem says: any recipe you can write, a robot can be
built to check it — and any robot's behavior can be written back as a recipe. They're two
languages for the same idea , so you can always translate one into the other.
Mnemonic Remember the two directions
"Thompson Builds, Elimination Reads."
T hompson = regex B uild machine (glue with ε).
E limination = machine R ead off as regex (rip states, R i q R q q ∗ R q j R_{iq}R_{qq}^*R_{qj} R i q R q q ∗ R q j ).
Cover answers. (1) What two constructions prove Kleene's theorem? (2) What does R q q ∗ R_{qq}^* R q q ∗ mean in
state elimination? (3) Why fresh states in the star gadget? (4) Is ∅ ∗ \varnothing^* ∅ ∗ equal to ε \varepsilon ε ?
Kleene's Theorem states A language is regular (regex-describable) iff it is accepted by a finite automaton (DFA/NFA).
The two constructions proving the equivalence Regex→NFA via Thompson's construction; FA→Regex via state elimination (GNFA).
Thompson gadget for union R ∣ S R\mid S R ∣ S New start ε-branches into
N R N_R N R and
N S N_S N S ; new accept reached by ε from both old accepts.
Thompson gadget for concatenation R S RS R S ε-edge from
N R N_R N R 's accept to
N S N_S N S 's start; accept =
N S N_S N S 's accept.
Thompson gadget for star R ∗ R^* R ∗ New start ε to new accept (zero) and to
N R N_R N R 's start;
N R N_R N R 's accept ε back to its start (loop) and to new accept (stop).
State-elimination relabeling rule R i j n e w = R i j ∣ R i q R q q ∗ R q j R_{ij}^{new} = R_{ij} \mid R_{iq} R_{qq}^{*} R_{qj} R ij n e w = R ij ∣ R i q R q q ∗ R q j .
Meaning of R q q ∗ R_{qq}^{*} R q q ∗ in elimination Loop on the state being deleted zero or more times before leaving.
Why add fresh start/accept before elimination So start has no incoming and accept no outgoing edges, making the rip rule always applicable.
Value of ∅ ∗ \varnothing^{*} ∅ ∗ ε \varepsilon ε — "zero or more of nothing" is the empty string.
Why NFA proof suffices (not DFA directly) NFA ≡ DFA by subset construction, so regex↔NFA gives regex↔DFA for free.
Does elimination order change the language No — different orders give equivalent regexes (same language), only differing in form.
Regex for FA: 1 → a 2 1\xrightarrow{a}2 1 a 2 , 2 → b 2 2\xrightarrow{b}2 2 b 2 loop, accept 2
Regular expression pattern
Operators union concat star
Intuition Hinglish mein samjho
Dekho, regular expression ek pattern hai jo tum likhte ho — jaise (a|b)*a, matlab "kitne bhi
a ya b, last me ek a". Aur finite automaton ek machine hai states ke saath jo string padh kar
batati hai accept ya reject. Dono bilkul alag lagte hain, par Kleene's Theorem kehta hai ki dono
exactly same languages describe karte hain — yahi regular languages hain. Isi wajah se grep,
search bars, aur compiler ke lexers kaam karte hain.
Do directions prove karni padti hain. Pehli: regex se NFA banao — ye hai Thompson's
construction . Har chhote pattern ka ek mini-machine banao jisme ek hi start aur ek hi accept ho,
phir unhe epsilon-transitions (khali move, bina input padhe) se jod do. Union ke liye dono machine
me branch karo, concatenation me ek ke baad doosri chalao, star me ek loop lagao aur "zero copies"
ka skip edge bhi.
Doosri direction: FA se regex — ye hai state elimination . Ek-ek karke states hatao, aur jo
edges bachte hain unpe pura regex likh do, formula se: R i j n e w = R i j ∣ R i q R q q ∗ R q j R_{ij}^{new}=R_{ij}\mid R_{iq}R_{qq}^{*}R_{qj} R ij n e w = R ij ∣ R i q R q q ∗ R q j .
Yahan R q q ∗ R_{qq}^{*} R q q ∗ ka matlab hai "delete hone wali state pe jitni baar chahe ghoom lo". Jab sirf
start aur accept bache, beech ka label hi tumhara answer hai. Yaad rakhna: elimination ka order
badalne se language nahi badalti , sirf regex ka likhne ka tareeka badalta hai — 2 + 3 2+3 2 + 3 aur 3 + 2 3+2 3 + 2
jaisa. Dono directions milke "iff" complete karti hain, isliye regex, NFA, DFA — teeno same regular
languages hain.