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 MM into an equivalent CFG GG.

  • NPDA: M=(Q,Σ,Γ,δ,q0,z,F)

    • QQ = set of states

    • Σ\Sigma = input alphabet

    • Γ\Gamma = stack alphabet

    • δ\delta = transition function

    • q0q_0 = initial state

    • zz = initial stack symbol

    • FF = set of final states

  • CFG: G=(V,Σ,P,S)G = (V, \Sigma, P, S)

    • VV = set of non-terminals

    • Σ\Sigma = terminal alphabet (same as NPDA input)

    • PP = set of productions

    • SS = start symbol


2. Simplifying Assumptions

For ease of conversion (as Linz recommends), assume:

  1. Single final state qfq_f.

  2. Acceptance by empty stack when reaching qfq_f. That is, the NPDA accepts a string ww if starting from (q0,w,z) it can reach (qf,λ,λ)(q_f, \lambda, \lambda).

  3. Every transition into the final state must empty the stack, i.e., δ(q,a,X)(qf,λ)\delta(q, a, X) \ni (q_f, \lambda)

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: [qiXqj][q_i X q_j]
    Meaning: “The NPDA can go from state qiq_i to state qjq_j, popping XX 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 VV

V={[qiXqj]qi,qjQ,XΓ}V = \{ [q_i X q_j] \mid q_i, q_j \in Q, X \in \Gamma \}
  • Each [qiXqj][q_i X q_j] represents consuming input that removes X from the stack while moving from qiq_i to qjq_j.

  • This allows the CFG to mimic the NPDA’s stack behavior using productions.


(b) Start Symbol SS

S[q0zqj]for all qjQS \rightarrow [q_0 z q_j] \quad \text{for all } q_j \in Q
  • Start symbol simulates the NPDA starting in q0q_0with stack zz.

  • Any qjq_j represents the state after the NPDA finishes processing zz (final acceptance).


(c) Production Rules PP

For each NPDA transition:

δ(qi,a,X)(qk,Y1Y2Ym)\delta(q_i, a, X) \ni (q_k, Y_1 Y_2 \dots Y_m)
  • qiq_i= current state

  • aΣ{λ}a \in \Sigma \cup \{\lambda\} = input symbol read

  • XX = stack top symbol

  • qkq_k = next state

  • Y1YmY_1 \dots Y_m= symbols pushed onto the stack (may be empty, m=0m=0)

Cases

Case 1: Pop operation (m=0)

δ(qi,a,X)(qk,λ)[qiXqk]a\delta(q_i, a, X) \ni (q_k, \lambda) \quad\Rightarrow\quad [q_i X q_k] \rightarrow a
  • Pop X and read input a (or λ).

  • No intermediate stack symbols; the NPDA goes directly from qiq_ito qkq_k.

Case 2: Push one symbol (m=1)

δ(qi,a,X)(qk,Y1)[qiXqj]a[qkY1qj]qjQ\delta(q_i, a, X) \ni (q_k, Y_1) \quad\Rightarrow\quad [q_i X q_j] \rightarrow a [q_k Y_1 q_j] \quad\forall q_j \in Q
  • NPDA replaces X with one stack symbol Y1Y_1.

  • Intermediate state qjq_j represents where we finish after consuming Y₁.

Case 3: Push multiple symbols (m ≥ 2)

[qiXqj]a[qkY1ql1][ql1Y2ql2][qlm1Ymqj][q_i X q_j] \rightarrow a [q_k Y_1 q_{l_1}] [q_{l_1} Y_2 q_{l_2}] \dots [q_{l_{m-1}} Y_m q_j]
  • NPDA replaces X with Y1YmY_1 \dots Y_m (stack growth).

  • Intermediate states ql1,,qlm1q_{l_1}, \dots, q_{l_{m-1}} represent intermediate computation points.

  • Number of rules: Qm1 for each NPDA transition.

Important: This is why NPDA → CFG conversion can produce very large grammars.


5. Example from Linz: L={anbn}

NPDA

  • States: Q={q0,q1}Q = \{q_0, q_1\}

  • Input: Σ={a,b}\Sigma = \{a, b\}

  • Stack: Γ={z,A}\Gamma = \{z, A\}

  • Initial: q0,zq_0, z

  • 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

[qiXqj][q_i X q_j], qi,qj{q0,q1},X{z,A}q_i,q_j \in \{q_0,q_1\}, X \in \{z,A\}

Start Symbol

S[q0zq1]S \rightarrow [q_0 z q_1]

Productions

NPDA TransitionCFG 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 anbna^n b^n

  • The complexity arises from multiple intermediate states ql1,,qlm1q_{l_1}, …, q_{l_{m-1}}, but conceptually, every non-terminal represents a computation segment in the NPDA.


6. Summary of Steps

  1. Start from NPDA (simplified: single final state, acceptance by empty stack).

  2. Create non-terminals [qiXqj][q_i X q_j] for all states and stack symbols.

  3. Start symbol: S → [q₀ z q_j].

  4. 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

  5. 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

Popular posts from this blog

Theory Of Computation PCCST302 KTU Semester 3 BTech 2024 Scheme

Non deterministic Finite Automata NFA

Formal Definition - Turing Machine