4.6.9Theory of Computation

Chomsky Normal Form (CNF) — conversion

2,525 words11 min readdifficulty · medium3 backlinks

WHAT is CNF?


HOW to convert — the 5-step pipeline (Sipser order!)

In Sipser's textbook the order is START → DEL → UNIT → TERM → BIN. Remove the messy ε and unit rules first, then clean up terminals and binarize last.

  1. START — add a fresh start symbol S0SS_0 \rightarrow S (so the start never appears on a right-hand side).
  2. DEL — eliminate ==ε\varepsilon-productions== (nullable variables).
  3. UNIT — eliminate unit productions (ABA \rightarrow B).
  4. TERM — replace terminals inside long rules with new variables.
  5. BIN — break right-hand sides longer than 2 into chains of length-2 rules.

Step 0 (START): new start symbol

WHY: CNF lets the start symbol have ε\varepsilon. If SS also appears on the right of some rule, deleting/transforming gets tangled. A fresh S0S_0 that only points to old SS keeps the start "clean."

Step 1 (DEL): remove ε\varepsilon-productions

WHY: AεA \rightarrow \varepsilon (for non-start AA) is illegal. HOW: find all nullable variables (those that can derive ε\varepsilon), then for every rule, add versions with each subset of the nullable occurrences omitted (but never delete the entire RHS down to nothing — that would re-create an ε-rule).

Step 2 (UNIT): remove renames ABA \rightarrow B

WHY: ABA \rightarrow B produces no terminal and no branching — it just renames. HOW: for every unit pair (A,B)(A,B) (meaning ABA \Rightarrow^* B using only unit rules), and every non-unit rule BγB \rightarrow \gamma, add AγA \rightarrow \gamma. Then drop all unit rules.

Step 3 (TERM): isolate terminals

WHY: In AaCA \rightarrow aC, the terminal aa is illegally mixed with variable CC. Introduce TaaT_a \rightarrow a and rewrite ATaCA \rightarrow T_a C. (A standalone AaA\to a is already fine.)

Step 4 (BIN): chop long rules

WHY: AB1B2B3B4A \rightarrow B_1 B_2 B_3 B_4 is too long. Replace by AB1X1,X1B2X2,X2B3B4.A \rightarrow B_1 X_1,\quad X_1 \rightarrow B_2 X_2,\quad X_2 \rightarrow B_3 B_4. Each new XiX_i is a fresh variable holding "the rest of the chain."

Figure — Chomsky Normal Form (CNF) — conversion

Worked Example 1 — full conversion (Sipser order)

Grammar: SASAaB,ABS,BbεS \rightarrow ASA \mid aB,\quad A \rightarrow B \mid S,\quad B \rightarrow b \mid \varepsilon

START. Add S0SS_0 \rightarrow S. Why this step? So the start never sits on a right side. Rules: S0SS_0\to S; SASAaBS \to ASA \mid aB; ABSA \to B \mid S; BbεB \to b \mid \varepsilon.

DEL. Nullable set: BεBB \to \varepsilon \Rightarrow B nullable. ABA \to B with BB nullable A\Rightarrow A nullable. No other all-nullable RHS. So N={A,B}N=\{A,B\}. Patch each rule over all subsets of nullable positions (never down to empty):

  • SASAS \to ASA: nullable positions are the two AA's. Drop subsets ⟹ add SSAASSS\to SA \mid AS \mid S. So SASASAASSS \to ASA \mid SA \mid AS \mid S.
  • SaBS \to aB: BB nullable ⟹ add SaS\to a. So SaBaS \to aB \mid a.
  • ABA \to B: BB nullable ⟹ would add AεA\to\varepsilon — drop it (not S0S_0). Keep ABA\to B.
  • ASA \to S: keep (no nullable symbol).
  • BbB \to b: keep. Delete BεB\to\varepsilon.

After DEL: S0SS_0\to S; SASASAASSaBaS \to ASA \mid SA \mid AS \mid S \mid aB \mid a; ABSA \to B \mid S; BbB \to b.

UNIT. Find unit pairs (reflexive + transitive closure over unit rules SSS\to S, ABA\to B, ASA\to S, S0SS_0\to S):

  • (S0,S)(S_0,S), and via SS none further (S's only unit rule is SSS\to S). SSS\to S is a trivial self-unit, removed.
  • (A,S)(A,S), (A,B)(A,B).

Now, for each variable, collect non-unit bodies of every variable it reaches:

  • Non-unit bodies of SS: {ASA,SA,AS,aB,a}\{ASA, SA, AS, aB, a\}.
  • Non-unit bodies of AA: from ABA\Rightarrow^* B gives {b}\{b\}; from ASA\Rightarrow^* S gives {ASA,SA,AS,aB,a}\{ASA, SA, AS, aB, a\}.
  • Non-unit bodies of BB: {b}\{b\}.

Result (unit rules dropped):

S0ASASAASaBaSASASAASaBaAASASAASaBabBb\begin{aligned} S_0 &\to ASA \mid SA \mid AS \mid aB \mid a\\ S &\to ASA \mid SA \mid AS \mid aB \mid a\\ A &\to ASA \mid SA \mid AS \mid aB \mid a \mid b\\ B &\to b \end{aligned}

Why this step? Every rename is replaced by the actual productive bodies it could reach.

TERM. Terminal aa appears mixed in aBaB: add TaaT_a\to a, rewrite aBTaBaB \to T_a B. (Standalone a\to a and b\to b stay.)

S0,SASASAASTaBaAASASAASTaBabBb,Taa\begin{aligned} S_0,S &\to ASA \mid SA \mid AS \mid T_a B \mid a\\ A &\to ASA \mid SA \mid AS \mid T_a B \mid a \mid b\\ B &\to b,\quad T_a \to a \end{aligned}

BIN. Only ASAASA (length 3) is too long. Add A1SAA_1 \to SA, rewrite ASAAA1ASA \to A\,A_1:

S0,SAA1SAASTaBaAAA1SAASTaBabA1SA,Bb,Taa\begin{aligned} S_0,S &\to A A_1 \mid SA \mid AS \mid T_a B \mid a\\ A &\to A A_1 \mid SA \mid AS \mid T_a B \mid a \mid b\\ A_1 &\to SA,\quad B \to b,\quad T_a \to a \end{aligned}

Why this step? Now every rule is ABCA\to BC or AaA\to aCNF achieved.


Worked Example 2 — small & clean

Grammar: SaSbabS \rightarrow aSb \mid ab. (No ε, no unit rules — DEL and UNIT do nothing.)

TERM: TaaT_a \to a, TbbT_b \to b. Rules: STaSTbTaTbS \to T_a S T_b \mid T_a T_b. Why? Isolate a,ba,b.

BIN: STaSTbS \to T_a S T_b (length 3): STaX1S \to T_a X_1, X1STbX_1 \to S T_b. Why? Cut length-3 into two length-2 rules.

Final CNF: STaX1TaTb,X1STb,Taa,Tbb.S \to T_a X_1 \mid T_a T_b,\quad X_1 \to S T_b,\quad T_a \to a,\quad T_b \to b. Language ={anbn:n1}= \{a^n b^n : n\ge 1\}, unchanged. ✓


Forecast-then-Verify


Common mistakes


Flashcards

What two production forms are allowed in CNF (ignoring start-ε)?
ABCA \to BC (two variables) and AaA \to a (one terminal).
Which single rule may legally produce ε in CNF?
Only the start symbol: S0εS_0 \to \varepsilon, and only if ε is in the language.
What is Sipser's order of the 5 CNF conversion steps?
START, DEL, UNIT, TERM, BIN.
Why does DEL/UNIT come before TERM/BIN in Sipser?
ε- and unit-removal only shrink/rename RHSs, so doing them first means TERM/BIN never get undone.
Define a nullable variable.
A variable AA with AεA \Rightarrow^* \varepsilon (derives the empty string).
In DEL, how do you patch AXYZA\to XYZ where X,ZX,Z are nullable?
Add a rule for every subset of {X,Z}\{X,Z\} omitted: AXYZYZXYYA\to XYZ\mid YZ\mid XY\mid Y (never empty).
What is a unit production and how is it removed?
A rule ABA\to B (B a variable); remove by adding AγA\to\gamma for every non-unit body γ\gamma reachable as a unit pair (A,B)(A,B).
Why is CNF useful?
Parse trees become binary ⟹ enables CYK O(n3)O(n^3) membership and the CFL pumping lemma.
In BIN, converting AB1B2B3A\to B_1B_2B_3, what do you get?
AB1X1A\to B_1 X_1, X1B2B3X_1\to B_2 B_3 (one fresh variable).
Why add a new start symbol S0S_0 first?
So the start symbol never appears on any right-hand side, keeping later steps clean.

Recall Feynman: explain to a 12-year-old

Imagine LEGO instructions where each step can only do ONE of two things: snap two big blocks together, or place one single colored tile. No giant complicated steps allowed. CNF rewrites a messy building manual into this baby-simple style. The finished tower is exactly the same — but now a robot can follow the steps super fast and even check whether a given tower is buildable. We clean up by: giving a fresh "start" block, removing "build nothing" steps, removing lazy "call this block by another name" steps, then swapping loose colored tiles for named blocks, and finally chopping long steps into pairs.

Concept Map

tidied into

rule form

rule form

start only

yields

enables

enables

built by

1

2

3

4

5

must precede

Messy CFG

CNF grammar

A to BC two variables

A to a one terminal

S to empty

Binary parse tree 2n-1 nodes

CYK membership O of n cubed

CFL pumping lemma

5-step pipeline

START new S0

DEL remove empty rules

UNIT remove renames

TERM isolate terminals

BIN split long rules

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, Chomsky Normal Form ka matlab hai grammar ko ek bilkul fixed "saaf-suthri" shape me laana. Isme har rule sirf do tarah ka ho sakta hai: ya toh ek variable se do variables (ABCA \to BC), ya ek variable se ek terminal (AaA \to a). Bas. Mixed cheezein jaise AaBA\to aB, lambi rules ABCDA\to BCD, khaali wali AεA\to\varepsilon, aur rename wali ABA\to B — sab ban hain (start symbol ka chhota exception chhod ke).

Faayda kya hai? Jab har rule do hisson me todta hai, toh parse tree ek binary tree ban jaata hai. Isse CYK algorithm se hum O(n3)O(n^3) me check kar sakte hain ki koi string language me hai ya nahi, aur CFL ka pumping lemma bhi clean prove hota hai. Isliye CNF ko grammar ka "assembly language" bolte hain.

Conversion ka Sipser order yaad rakhna zaruri hai: START, DEL, UNIT, TERM, BIN (mnemonic: "Some Dogs Understand Tricky Behaviour"). Pehle naya start symbol S0S_0, phir nullable (khaali derive karne wale) variables hatao (DEL), phir unit/rename rules hatao (UNIT), phir terminals ko alag variable me daalo (TERM), aur aakhir me lambi rules ko do-do me chop karo (BIN). DEL aur UNIT pehle isliye, kyunki ye sirf RHS chhota ya rename karte hain — agar baad me kiya toh TERM/BIN ka kaam dobara karna pad jaata hai.

Ek important point DEL me: agar ek rule me kai nullable symbols hain, toh har subset ko drop karke alag-alag rule banao.

Go deeper — visual, from zero

Test yourself — Theory of Computation

Connections