Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

GATE CS & DA Preparation Guide  Module 7 – Theory of computation and compiler design (CS sections 6-7)

Context-free languages, PDAs, Turing machines

Design grammars and PDAs, use CNF, CYK and the pumping lemma for CFLs, and decide which problems are undecidable with reductions and Rice's theorem.

  • Advanced
  • 20 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 7 of 20 minutes free
Free: Each machine adds one resource, and each class is strictly larger · A stack lets a PDA check what a grammar generates · Normal forms fix the length of every derivation · 2 more sections. With a pass: 3 in-depth parts and 3 interview answers, about 13 minutes.

What you will learn

  • Design CFGs and PDAs, detect ambiguity and convert grammars to normal forms
  • Apply CFL closure properties and the pumping lemma for context-free languages
  • Classify problems as decidable, semi-decidable or undecidable using known results and reductions
  • Identify the level of a language in the Chomsky hierarchy

Before you start

A pushdown automaton (PDA), a finite automaton with a stack, checks that aabbbb has twice as many b’s as a’s in 7 moves: one push of two symbols for each a, one pop for each b, and a last move that reads nothing. A context-free grammar (CFG) generates strings by rewriting one variable at a time, whatever surrounds it, with rules such as S → aSb | ε, and the languages that grammars generate are the context-free languages (CFLs). Nondeterministic PDAs accept exactly the context-free languages, while deterministic PDAs accept fewer of them.

A Turing machine has an unbounded tape that it can read, write and move along in both directions. Turing machines compute everything that any computer can, and they define two classes: a language is decidable language: A language for which some Turing machine halts on every input and accepts exactly the strings of the language. Decidable and recursive mean the same., or recursive, when a machine halts on every input with the right answer, and recursively enumerable language: A language that some Turing machine accepts exactly, possibly running forever on strings outside it. Every decidable language is one; the halting problem is one that is not decidable. when a machine accepts exactly its strings but may run forever on the others. Each idea below comes with a program you can run.

Each machine adds one resource, and each class is strictly larger

Nested boxes: regular inside deterministic context-free, inside context-free, context-sensitive, recursive and recursively enumerable.Not recursively enumerableexample: the complement of HALTRecursively enumerable: Turing machineexample: HALT, the halting problemRecursive, or decidable:a Turing machine that always haltsContext-sensitive: linear-bounded automatonexample: aⁿbⁿcⁿContext-free: nondeterministic PDAexample: even palindromes, ww^RDeterministic context-free: DPDAexample: aⁿbⁿRegular: finite automatonexample: a*b*

The Chomsky hierarchy, with the machine and one example language at each level

Text description of the diagram

The diagram is a set of nested boxes. From the innermost box outwards:

1. Regular languages, recognised by finite automata; example: a*b*. 2. Deterministic context-free languages, recognised by deterministic pushdown automata; example: aⁿbⁿ. 3. Context-free languages, recognised by nondeterministic pushdown automata; example: the even palindromes ww^R. 4. Context-sensitive languages, recognised by linear-bounded automata; example: aⁿbⁿcⁿ. 5. Recursive (decidable) languages, recognised by Turing machines that halt on every input. 6. Recursively enumerable languages, recognised by Turing machines that may run forever on inputs they do not accept; example: HALT, the halting problem.

Outside all of them are the languages that are not recursively enumerable, for example the complement of HALT. Each box contains every box inside it, and every inclusion is strict.

Each class contains the classes drawn inside it, and each machine adds one resource. A finite automaton has only its states. A PDA adds a stack, which can match one count against another or a string against its reversal. A linear-bounded automaton may rewrite the tape cells of its input but no others, and Turing machines have an unbounded tape. Every inclusion is strict, and the examples show why: anbna^n b^n needs the stack, the even palindromes need a guess of the middle, anbncna^n b^n c^n needs more than one stack can do, and HALT is recognised but never decided.

Checkpoint

Check: The Chomsky hierarchy

  1. Question 1 of 2 What does a pushdown automaton add to a finite automaton?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: A stack

    Each machine of the hierarchy adds one resource: a PDA adds a stack to the finite control, a linear-bounded automaton may rewrite its input cells, and a Turing machine has an unbounded tape.

  2. Question 2 of 2 What is the smallest class of the hierarchy that contains the even palindromes over {a, b}?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The context-free languages

    The even palindromes sit in the context-free ring of the diagram, outside the deterministic ring: a PDA must guess where the middle is, which only a nondeterministic PDA can do.

A stack lets a PDA check what a grammar generates

The grammar S → aSbb | ε generates anb2na^n b^{2n}: each use of the first rule adds one a on the left and two b’s on the right. The PDA does the same work with its stack. It pushes two X’s for every a and pops one for every b, and the bottom marker Z tells it that every b has been matched. Step through its run on aabbbb:

Interactive · step by step A PDA for aⁿb²ⁿ checks aabbbb Step through the run. The box in focus is the current state; its second line is the stack, top first, then the input still to read.
A PDA for aⁿb²ⁿ checks aabbbb, step 9 of 9. Showing q0 (start, accepting), q1 (push XX per a), q2 (pop one X per b), q3 (accepting).a, Z → XXZb, X → εε, Z → Zq0start, acceptingq1push XX per aq2pop one X per bq3accepting

The drawing shows the whole scene; its 9 steps are listed below.

Every step as text
  1. Start. The PDA starts in q0 with only the bottom marker Z on its stack and all of aabbbb to read. q0 accepts too, so the empty string, the case n = 0, is accepted without a move.
  2. The first a. Reading a with Z on top, the move a, Z → XXZ replaces Z by XXZ, two X's above the marker, and goes to q1.
  3. The second a. In q1, every further a with X on top pushes two more X's, so the stack grows to four X's.
  4. The first b. Reading b with X on top pops one X and moves to q2. From now on an a has no move, so an a after a b is rejected.
  5. The second b. Each b pops one X. Two X's are left for the two b's still to read, and the run stays in q2.
  6. The third and fourth b. Two more pops leave only the marker Z, and the input is used up. Four b's have matched the four X's that two a's pushed.
  7. Accept. With Z on top, the move ε, Z → Z reads nothing and goes to q3, which accepts, so aabbbb is accepted after 7 moves.
  8. One b short. On aabbb the input runs out in q2 with XZ still on the stack. Only a move on Z could lead to q3, and X is on top, so no move applies and the PDA rejects.
  9. Deterministic. In every configuration at most one move applies, and the move that reads nothing is never offered beside one that reads a symbol. So this PDA is deterministic.

The program prints the same configurations, then the run on aabbb, which uses up its input with an X still on the stack:

A deterministic PDA for aⁿb²ⁿ, move by move Python · pda_trace.py
"""A deterministic PDA for a^n b^(2n), traced move by move and checked against the definition."""
from itertools import product

# (state, symbol read, top of stack) -> (next state, what replaces the top).
# A symbol of "" reads nothing; Z marks the bottom of the stack.
MOVES = {
    ("q0", "a", "Z"): ("q1", "XXZ"),  # the first a pushes two X's
    ("q1", "a", "X"): ("q1", "XXX"),  # every further a pushes two more
    ("q1", "b", "X"): ("q2", ""),     # each b pops one X
    ("q2", "b", "X"): ("q2", ""),
    ("q2", "", "Z"): ("q3", "Z"),     # every X matched: move to the accepting state
}
ACCEPTING = {"q0", "q3"}  # q0 accepts the empty string


def run(word, show=False):
    state, rest, stack = "q0", word, "Z"  # the top of the stack is its first character
    while True:
        if show:
            print(f"  {state}  input {rest or '-':7}  stack {stack}")
        top = stack[:1]
        if rest and (state, rest[0], top) in MOVES:
            state, push = MOVES[state, rest[0], top]
            rest, stack = rest[1:], push + stack[1:]
        elif (state, "", top) in MOVES:
            state, push = MOVES[state, "", top]
            stack = push + stack[1:]
        else:
            return not rest and state in ACCEPTING


for word in ("aabbbb", "aabbb"):
    print(f"{word}:")
    print("  accepted" if run(word, show=True) else "  rejected: no move left")

words = ["".join(w) for n in range(10) for w in product("ab", repeat=n)]
same = all(run(w) == (w == "a" * (len(w) // 3) + "b" * (2 * len(w) // 3)) for w in words)
print(f"agrees with a^n b^(2n) on all {len(words)} strings up to length 9: {same}")

Output

aabbbb:
  q0  input aabbbb   stack Z
  q1  input abbbb    stack XXZ
  q1  input bbbb     stack XXXXZ
  q2  input bbb      stack XXXZ
  q2  input bb       stack XXZ
  q2  input b        stack XZ
  q2  input -        stack Z
  q3  input -        stack Z
  accepted
aabbb:
  q0  input aabbb    stack Z
  q1  input abbb     stack XXZ
  q1  input bbb      stack XXXXZ
  q2  input bb       stack XXXZ
  q2  input b        stack XXZ
  q2  input -        stack XZ
  rejected: no move left
agrees with a^n b^(2n) on all 1023 strings up to length 9: True

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 pda_trace.py

This PDA is deterministic: in every configuration at most one move applies. Deterministic PDAs accept exactly the deterministic CFLs, which include anb2na^n b^{2n} but not the even palindromes, where a machine would have to guess where the middle is.

Checkpoint

Check: Grammars and PDAs for one language

  1. Question 1 of 2 Why does the PDA for aⁿb²ⁿ reject aabbb?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The input runs out with an X still on the stack, and no move applies

    Two a's push four X's, and three b's pop only three, so the run ends in q2 with XZ on the stack and the input used up. No move applies, so the PDA rejects.

  2. Question 2 of 2 The PDA for aⁿb²ⁿ reads aaabbbbbb. How many X's are on its stack after it has read the three a's?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 6 X's

    The first a replaces Z by XXZ, and each further a pushes two more X's: 2 × 3 = 6 X's above the marker, one for each of the six b's that must follow.

Normal forms fix the length of every derivation

A grammar in Chomsky normal form: A grammar form that allows only rules A → BC and A → a, plus S → ε when the language contains ε. A derivation of a string of length n then takes exactly 2n − 1 steps. derives aabb in exactly 7 steps, in whatever order it applies its rules:

Interactive · stage by stage Deriving aabb in Chomsky normal form takes 7 steps Step through the leftmost derivation. Each step applies one rule to the leftmost variable and names the kind of rule.
Deriving aabb in Chomsky normal form takes 7 steps, step 8 of 8. Showing S, A C, a C, a S B, a A B B, a a B B, a a b B, a a b b. In focus: a a b b.Sthe start variableA CS → AC: one variable morea CA → a: one terminala S BC → SB: one variable morea A B BS → AB: one variable morea a B BA → a: one terminala a b BB → b: one terminala a b bB → b: done, 7 steps

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. The start variable. The grammar S → AB | AC, C → SB, A → a, B → b is in Chomsky normal form and generates aⁿbⁿ for n ≥ 1. A derivation of aabb starts from S.
  2. S → AC. A rule of the form A → BC replaces one variable by two, so the sentential form grows from one variable to two.
  3. A → a. A rule of the form A → a turns the leftmost variable into a terminal, which no later step changes.
  4. C → SB. C becomes S B, the second rule of the form A → BC. The S in the middle will produce the inner ab.
  5. S → AB. The third and last rule of the form A → BC. The form now has four symbols, the a already made and three variables, one for each terminal of aabb, so n − 1 = 3 such rules were needed.
  6. A → a. From here every step turns one variable into one terminal. The three variables left need three such steps, which with the earlier A → a make four, one per terminal.
  7. B → b. The third terminal rule. Only one variable is left.
  8. 7 steps in all. The last B becomes b. The derivation used 3 rules of the form A → BC and 4 of the form A → a, 2n − 1 = 7 steps for a string of length n = 4, whatever the order of the steps.

  • Chomsky normal form (CNF) allows only rules A → BC and A → a, so a derivation of a string of length n takes exactly 2n − 1 steps.
  • Greibach normal form (GNF) starts every right-hand side with a terminal, A → aα, so a string of length n takes exactly n steps.
  • The CYK algorithm decides whether a grammar in CNF generates a string of length n in O(n3)O(n^3) time, by filling a triangle of cells, one for each substring.
  • The pumping lemma for CFLs splits every long enough string as uvxyz, with |vxy| ≤ p and |vy| ≥ 1, and pumps v and y together. anbncna^n b^n c^n fails it.
  • Closure: CFLs are closed under union, concatenation, star and intersection with a regular language, but not under intersection or complement.
  • Ambiguity: a grammar is ambiguous when some string has two parse trees, and no algorithm decides ambiguity for every grammar. A language is inherently ambiguous when every grammar for it is ambiguous.

Counting a CNF derivation as n steps

A derivation of aabb in Chomsky normal form takes 7 steps, not 4: three steps of the form A → BC grow one variable into four, and four steps of the form A → a turn them into terminals. Only Greibach normal form takes n steps.

Checkpoint

Check: Normal forms, CYK, pumping and closure

  1. Question 1 of 2 A grammar in Chomsky normal form derives a string of length 10. How many steps does the derivation take?

    Type a number.

    Show the answer: Question 1 of 2

    Answer: 19 steps

    n − 1 = 9 rules of the form A → BC grow one variable into ten, and n = 10 rules of the form A → a turn them into terminals: 2n − 1 = 19 steps, as the derivation of aabb took 7.

  2. Question 2 of 2 L₁ and L₂ are context-free and R is regular. Which of these must be context-free?

    Choose every answer that is right.

    Show the answer: Question 2 of 2

    Answer:

    • L₁ ∪ L₂
    • L₁ ∩ R

    Context-free languages are closed under union, concatenation, star and intersection with a regular language, but not under intersection or complement.

Decidability shrinks as the machines grow stronger

A problem is decidable when one Turing machine answers it correctly for every input and always halts. The table gives the standard results for each class; the input is a description of the language, such as a DFA, a grammar or a Turing machine.

Which questions are decidable for each class of languages
Criterion RegularDCFLCFLRecursiveRE
Is a given string in L? DecidableDecidableDecidableDecidableUndecidable, semi-decidable
Is L empty? DecidableDecidableDecidableUndecidableUndecidable
Is L finite? DecidableDecidableDecidableUndecidableUndecidable
Is L every string? DecidableDecidableUndecidableUndecidableUndecidable
Are two such languages equal? DecidableDecidableUndecidableUndecidableUndecidable
Closed under complement? YesYesNoYesNo

Two results explain most of the undecidable cells. Turing proved that no machine decides whether a given machine halts on a given input, the halting problem. Other problems are shown undecidable by reduction: if a decider for a problem P could be used to decide halting, P is undecidable. Rice’s theorem makes this general: every non-trivial property of the language that a Turing machine accepts is undecidable. Diagonalisation explains why such problems must exist: Turing machines can be listed one after another, while languages cannot.

Key idea

A reduction runs from the halting problem to P: if a decider for P would decide halting, no decider for P exists.

Checkpoint

Check: Decidable questions for each class

  1. Question 1 of 2 Is it decidable whether a context-free grammar generates every string over its alphabet?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: No, it is undecidable for context-free grammars

    Universality is decidable for regular and deterministic context-free languages but not for context-free ones in general, and so is equivalence. Membership, emptiness and finiteness stay decidable for CFLs.

  2. Question 2 of 2 You have shown that a decider for HALT would also decide a problem P. What does that prove about P?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Nothing about whether P is decidable

    A reduction proves undecidability only from a known undecidable problem to the new one: if a decider for P would decide HALT, P is undecidable. The opposite direction says that HALT is at least as hard as P, which every decidable P satisfies too.

Practise: membership, closure and decidability

Exercise · Medium · Python

Decide membership with the CYK table

Write derives(binary, unit, start, word), which says whether a grammar in Chomsky normal form derives word from the variable start.

  • binary lists the rules of the form A → BC as triples, such as ("S", "A", "C").
  • unit maps each terminal to the set of variables with a rule A → a, such as {"a": {"A"}, "b": {"B"}}.

Use the CYK algorithm. For every substring, from length 1 up to the whole word, work out the set of variables that derive it. A variable derives a substring of length 1 when it has a rule for that terminal. It derives a longer substring when one of its rules A → BC can split the substring into a first part that B derives and a rest that C derives. The word is in the language when start is in the set for the whole word. The empty word is never derived.

ANBN = [("S", "A", "B"), ("S", "A", "C"), ("C", "S", "B")]
derives(ANBN, {"a": {"A"}, "b": {"B"}}, "S", "aabb")   # True
derives(ANBN, {"a": {"A"}, "b": {"B"}}, "S", "abab")   # False

Starter code · membership.py

def derives(binary, unit, start, word):
    """True when the grammar in Chomsky normal form derives `word` from `start`.

    `binary` lists the rules A -> BC as triples ("A", "B", "C"); `unit` maps each terminal
    to the set of variables that produce it (A -> a). The grammar has no rule for the empty
    string, so the empty word is never derived.
    """
    # Replace this line with your code.
    return False
The sample tests · test_membership.py
from itertools import product

from membership import derives

# a^n b^n, n >= 1: S -> AB | AC, C -> SB, A -> a, B -> b.
ANBN = [("S", "A", "B"), ("S", "A", "C"), ("C", "S", "B")]
ANBN_UNIT = {"a": {"A"}, "b": {"B"}}

# Balanced brackets: S -> SS | LR | LT, T -> SR, L -> (, R -> ).
BRACKETS = [("S", "S", "S"), ("S", "L", "R"), ("S", "L", "T"), ("T", "S", "R")]
BRACKETS_UNIT = {"(": {"L"}, ")": {"R"}}


def test_anbn_members():
    """ab, aabb and aaabbb are derived"""
    assert [derives(ANBN, ANBN_UNIT, "S", w) for w in ("ab", "aabb", "aaabbb")] == [True, True, True]


def test_anbn_non_members():
    """aab, abab and ba are not derived"""
    assert [derives(ANBN, ANBN_UNIT, "S", w) for w in ("aab", "abab", "ba")] == [False, False, False]


def test_empty_word():
    """a grammar in Chomsky normal form without an empty rule never derives the empty word"""
    assert derives(ANBN, ANBN_UNIT, "S", "") is False


def test_unknown_symbol():
    """a symbol that no rule produces makes the word underivable"""
    assert derives(ANBN, ANBN_UNIT, "S", "acb") is False


def test_brackets():
    """balanced brackets are derived, unbalanced ones are not"""
    words = ["()", "(())()", "(()", ")(", "()()()"]
    assert [derives(BRACKETS, BRACKETS_UNIT, "S", w) for w in words] == [True, True, False, False, True]


def test_anbn_against_definition():
    """the same answer as the definition on every string up to length 8"""
    for n in range(9):
        for w in map("".join, product("ab", repeat=n)):
            k = len(w) // 2
            assert derives(ANBN, ANBN_UNIT, "S", w) == (k > 0 and w == "a" * k + "b" * k), w
A hint

Keep a dictionary from (start position, length) to a set of variables. Fill all the cells of length 1 from unit, then the cells of length 2, 3 and so on: for each cell try every split point and every rule A → BC, and add A when B is in the left cell and C is in the right one. The answer is whether start is in the cell (0, len(word)).

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Practice that adapts to you

Practise this lesson

10 questions about 10 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 10 Which machine accepts exactly the context-free languages?

    Choose one answer.

    Show the answer: Question 1 of 10

    Answer: A nondeterministic pushdown automaton

    Nondeterministic PDAs accept exactly the context-free languages. Deterministic PDAs accept only the deterministic ones, a proper subset; two stacks can simulate a Turing machine's tape; linear-bounded automata accept the context-sensitive languages.

  2. Question 2 of 10 Which string does the PDA for aⁿb²ⁿ accept?

    Choose one answer.

    Show the answer: Question 2 of 10

    Answer: abb

    The PDA accepts when the b's pop exactly the X's the a's pushed, two per a, and then moves on Z to q3. Of the four strings only abb has twice as many b's as a's, in the right order.

  3. Question 3 of 10 Which of these languages are context-free?

    Choose every answer that is right.

    Show the answer: Question 3 of 10

    Answer:

    • aⁿbᵐcᵐ for n, m ≥ 0
    • aⁿb²ⁿ for n ≥ 0
    • ww^R for w in {a, b}*, the even palindromes

    aⁿbᵐcᵐ is a* followed by bᵐcᵐ, the even palindromes are generated by S → aSa | bSb | ε, and aⁿb²ⁿ by S → aSbb | ε. aⁿbⁿcⁿ fails the pumping lemma for context-free languages: a stack can match one pair of counts, not three.

  4. Question 4 of 10 A grammar in Greibach normal form derives a string of length 9. How many steps does the derivation take?

    Type a number.

    Show the answer: Question 4 of 10

    Answer: 9 steps

    Every rule in Greibach normal form has the form A → aα: it produces exactly one terminal, followed by variables. A string of 9 terminals therefore needs exactly 9 steps.

  5. Question 5 of 10 A grammar in Chomsky normal form derives a string of length 7. How many steps does the derivation take?

    Type a number.

    Show the answer: Question 5 of 10

    Answer: 13 steps

    A derivation in Chomsky normal form uses n − 1 rules of the form A → BC, to grow from one variable to n of them, and n rules of the form A → a, one per terminal: 2n − 1 = 13 steps for n = 7.

  6. Question 6 of 10 Under which operations are the context-free languages closed?

    Choose every answer that is right.

    Show the answer: Question 6 of 10

    Answer:

    • Star
    • Union

    Union and star are built with a new start rule: S → S₁ | S₂ and S → SS₁ | ε. Intersection fails: aⁿbⁿcᵐ and aᵐbⁿcⁿ are context-free, and their intersection aⁿbⁿcⁿ is not. Complement fails too, because with union it would give intersection by De Morgan's law.

  7. Question 7 of 10 L is context-free and R is regular. What is L ∩ R?

    Choose one answer.

    Show the answer: Question 7 of 10

    Answer: Always context-free

    A PDA for L and a DFA for R can run side by side, the DFA's state kept in the PDA's control, so the intersection is always context-free. It need not be regular: take R as every string.

  8. Question 8 of 10 Which questions about context-free grammars are decidable?

    Choose every answer that is right.

    Show the answer: Question 8 of 10

    Answer:

    • Does the grammar generate any string at all?
    • Does the grammar generate a given string w?
    • Does the grammar generate infinitely many strings?

    Emptiness is decided by marking the variables that generate a terminal string, finiteness by looking for a cycle among the useful variables of a grammar in Chomsky normal form, and membership by the CYK algorithm. Equivalence of two context-free grammars is undecidable.

  9. Question 9 of 10 A language L and its complement are both recursively enumerable. What follows?

    Choose one answer.

    Show the answer: Question 9 of 10

    Answer: L is recursive

    Run the two recognisers side by side, one step each in turn. Every string is accepted by exactly one of them, so this combined machine always halts and decides L.

  10. Question 10 of 10 Rice's theorem shows that many questions about a Turing machine M are undecidable. Which question does it not apply to?

    Choose one answer.

    Show the answer: Question 10 of 10

    Answer: Does M have at most 100 states?

    Rice's theorem covers non-trivial properties of the language a machine accepts. The number of states is a property of the machine's description, not of its language, and reading the description decides it.

Grammars in depth: CYK, ambiguity and normal forms, worked Pro: opens with a Pro, Premium or Ultimate pass

Membership, ambiguity and normal forms each come with a count that is easy to get wrong. This part runs the CYK algorithm cell by cell, counts the parse trees of an ambiguous grammar, and works out what each normal form fixes about a derivation.

In this part:

  • The CYK table, filled cell by cell
  • Ambiguity reproduced: two trees and two values
  • Normal forms by the numbers

2 runnable examples (Python) · about 4 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Closure, pumping and deterministic PDAs, with the traps reproduced Pro: opens with a Pro, Premium or Ultimate pass

Closure properties and the pumping lemma settle most “is this context-free?” questions, and the gap between deterministic and nondeterministic PDAs settles the rest. This part tabulates closure with a counterexample for every failure, runs the pumping lemma on every split, and measures what nondeterminism costs a simulation.

In this part:

  • Closure of CFLs and DCFLs, every “no” with its counterexample
  • The pumping lemma for CFLs, checked on every split
  • What nondeterminism costs, measured

2 runnable examples (Python) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Turing machines and undecidability, with reductions worked Pro: opens with a Pro, Premium or Ultimate pass

Decidability is settled by proofs, not runs, but a Turing machine you can trace makes the definitions concrete. This part runs a machine for anbncna^n b^n c^n, proves the halting problem undecidable by diagonalisation, and applies reductions and Rice’s theorem to eight typical properties.

In this part:

  • A Turing machine for equal runs of a, b and c, traced and measured
  • Why undecidable problems exist: a diagonal proof
  • Reductions and Rice’s theorem, applied to eight properties

1 runnable example (Python) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Interview questions

  1. Fresher · Warm-up

    What is the difference between a recursive and a recursively enumerable language?

    A language is recursive, or decidable, when some Turing machine halts on every input and accepts exactly the strings of the language: it always answers yes or no. It is recursively enumerable when some Turing machine accepts exactly its strings but may run forever on a string outside it, so a no may never come. Every recursive language is recursively enumerable, but not the other way round: the halting problem is recursively enumerable and not recursive. The two classes meet in a useful theorem: when a language and its complement are both recursively enumerable, the language is recursive, because running the two machines in turns always ends. Recursive languages are closed under complement, and recursively enumerable ones are not.

  2. Fresher to mid

    Your team's expression grammar gives two parse trees for some inputs, and one input evaluates differently under each tree. Is there a tool that decides, for every context-free grammar, whether it is ambiguous? What do you do instead to make sure your grammar is not?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  3. Fresher

    The languages of the strings aⁿbⁿcᵐ and of the strings aᵐbⁿcⁿ, for n, m ≥ 0, are both context-free. Show that their intersection is not, and explain what this proves about closure of the context-free languages under intersection and under complement.

    Model answer, Pro. First step and follow-ups

  4. Fresher to mid

    For a Turing machine M, which of these are decidable: (a) M has more than 10 states; (b) L(M) contains the string gate; (c) M halts on the blank tape within 100 steps; (d) L(M) is regular? Justify each one with Rice's theorem or a direct argument.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • CFGs and nondeterministic PDAs describe the same languages; deterministic PDAs describe fewer, without the even palindromes.
  • A derivation in Chomsky normal form takes 2n − 1 steps, one in Greibach normal form n steps, and CYK decides membership in O(n3)O(n^3) time.
  • CFLs are closed under union, concatenation and star and under intersection with a regular language, but not under intersection or complement.
  • Membership, emptiness and finiteness are decidable for CFLs; equivalence and universality are not, and Rice’s theorem makes every non-trivial question about a Turing machine’s language undecidable.

Terms in this lesson

Chomsky normal form
A grammar form that allows only rules A → BC and A → a, plus S → ε when the language contains ε. A derivation of a string of length n then takes exactly 2n − 1 steps.
context-free grammar (CFG)
A grammar whose rules rewrite one variable at a time, whatever surrounds it, such as S → aSb | ε. The languages such grammars generate are the context-free languages.
decidable language
A language for which some Turing machine halts on every input and accepts exactly the strings of the language. Decidable and recursive mean the same.
pushdown automaton (PDA)
A finite automaton with a stack it can push and pop. Nondeterministic PDAs accept exactly the context-free languages; deterministic ones accept fewer of them.
recursively enumerable language
A language that some Turing machine accepts exactly, possibly running forever on strings outside it. Every decidable language is one; the halting problem is one that is not decidable.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.