Building CFG from Push Down Automata
1. Goal of NPDA → CFG Conversion
For every context-free language (CFL) there exists a CFG that generates it, and vice versa. To prove this formally, he provides a method to convert an NPDA into an equivalent CFG .
-
NPDA:
-
= set of states
-
= input alphabet
-
= stack alphabet
-
= transition function
-
= initial state
-
= initial stack symbol
-
= set of final states
-
-
CFG:
-
= set of non-terminals
-
= terminal alphabet (same as NPDA input)
-
= set of productions
-
= start symbol
-
2. Simplifying Assumptions
For ease of conversion (as Linz recommends), assume:
-
Single final state .
-
Acceptance by empty stack when reaching . That is, the NPDA accepts a string if starting from .
-
Every transition into the final state must empty the stack, i.e.,
These assumptions do not change the language accepted, and they make the CFG construction systematic.
3. Core Idea
We want to define CFG non-terminals that describe how the NPDA processes input while manipulating the stack.
-
Non-terminal:
Meaning: “The NPDA can go from state to state , popping from the stack and leaving the rest of the stack unchanged, while reading some input string.” -
These non-terminals capture NPDA computations over segments of input, corresponding to popping or pushing stack symbols.
4. CFG Components
(a) Non-terminals
-
Each represents consuming input that removes X from the stack while moving from to .
-
This allows the CFG to mimic the NPDA’s stack behavior using productions.
(b) Start Symbol
-
Start symbol simulates the NPDA starting in with stack .
-
Any represents the state after the NPDA finishes processing (final acceptance).
(c) Production Rules
For each NPDA transition:
-
= current state
-
= input symbol read
-
= stack top symbol
-
= next state
-
= symbols pushed onto the stack (may be empty, )
Cases
Case 1: Pop operation (m=0)
-
Pop X and read input a (or λ).
-
No intermediate stack symbols; the NPDA goes directly from to .
Case 2: Push one symbol (m=1)
-
NPDA replaces X with one stack symbol .
-
Intermediate state represents where we finish after consuming Y₁.
Case 3: Push multiple symbols (m ≥ 2)
-
NPDA replaces X with (stack growth).
-
Intermediate states represent intermediate computation points.
-
Number of rules:
Important: This is why NPDA → CFG conversion can produce very large grammars.
5. Example from Linz:
NPDA
-
States:
-
Input:
-
Stack:
-
Initial:
-
Accept: by empty stack
Transitions:
δ | Meaning |
---|---|
δ(q₀, a, z) = (q₀, Az) | push A over z |
δ(q₀, a, A) = (q₀, AA) | push A over A |
δ(q₀, b, A) = (q₁, λ) | pop A on b |
δ(q₁, b, A) = (q₁, λ) | pop A on b |
δ(q₁, λ, z) = (q₁, λ) | pop z at end |
CFG Non-terminals
,
Start Symbol
Productions
NPDA Transition | CFG Rule |
---|---|
δ(q₀, a, z) → (q₀, Az) | [q₀ z q₀] → a [q₀ A q₀][q₀ z q₀] [q₀ z q₀] → a [q₀ A q₁][q₁ z q₀] [q₀ z q₁] → a [q₀ A q₀][q₀ z q₁] [q₀ z q₁] → a [q₀ A q₁][q₁ z q₁] |
δ(q₀, a, A) → (q₀, AA) | [q₀ A q₀] → a [q₀ A q₀][q₀ A q₀] [q₀ A q₀] → a [q₀ A q₁][q₁ A q₀] [q₀ A q₁] → a [q₀ A q₀][q₀ A q₁] [q₀ A q₁] → a [q₀ A q₁][q₁ A q₁] |
δ(q₀, b, A) → (q₁, λ) | [q₀ A q₁] → b |
δ(q₁, b, A) → (q₁, λ) | [q₁ A q₁] → b |
δ(q₁, λ, z) → (q₁, λ) | [q₁ z q₁] → λ |
-
This grammar generates exactly strings
-
The complexity arises from multiple intermediate states , but conceptually, every non-terminal represents a computation segment in the NPDA.
6. Summary of Steps
-
Start from NPDA (simplified: single final state, acceptance by empty stack).
-
Create non-terminals for all states and stack symbols.
-
Start symbol: S → [q₀ z q_j].
-
Add productions according to transitions:
-
Pop only → direct terminal
-
Push one symbol → one intermediate non-terminal
-
Push multiple symbols → sequence of non-terminals for all possible intermediate states
-
-
Resulting CFG generates the same language as NPDA.
✅ Key Idea: Each CFG non-terminal simulates the effect of NPDA transitions on stack and input. This shows formally that every NPDA-recognizable language is context-free, proving the equivalence.
Comments
Post a Comment