skip to content

A pushdown automaton is a finite-state control plus one unbounded stack; what does that stack let it recognise that finite state alone cannot?

level: middleimportance: must knowfreq 66%

answer

  1. finite control plus one extra store
  2. memory that grows with the input
  3. only the top symbol is visible
  4. push on opener, pop on closer
  5. exhausted store means every opener matched

basics

~20 s

The stack is memory that grows with the input, so the machine can match nesting of any depth: push a marker on every opener, pop and compare on every closer, and accept a run whose store ends exhausted.

solid answer

~50 s

A finite-state control has nothing to remember with except its current state, and the set of states is fixed before any input arrives, so it can tell depths apart only up to some built-in bound. Adding one stack gives it a store that grows with the input and is read last-in-first-out: a step is a function of the current state, the next input symbol (or none), and the **top** stack symbol only, and it replaces that top with a string of symbols. A depth reader falls straight out of that shape - push a marker for each opener, pop and compare on each closer, reject a closer that arrives on an empty store, and treat an exhausted store at end of input as balanced. Machines of this shape that may guess accept exactly the context-free languages.

code

pseudocode · 13 lines
pseudocode
store <- empty
for each symbol s in input:
    if s is an opener:
        push(kind_of(s))
    else if s is a closer:
        if store is empty:
            reject          # closed something never opened
        if pop() != kind_of(s):
            reject          # closer of the wrong kind
if store is empty:
    accept
else:
    reject                  # input ended mid-envelope

go deeper

for a junior

Recall the shape: states plus one stack, an opener pushes and a closer pops, and balanced input is input whose pushes and pops cancel out exactly.

for a middle

Explain that one step reads state, input symbol and the top stack symbol only, and that a store growing with the input is what buys unbounded depth. Name both rejection cases: a closer on an empty store, and openers left over at the end.

for a senior

Show where a real reader stops being this machine. The moment it needs something it already popped, or a second unbounded count, it is outside the model, and saying so beats patching the reader until a counterexample arrives.

for a principal

The judgement worth having is which checks stay inside a one-stack reader, because those remain single-pass and streamable, and which get pushed into a separate validation stage that costs another pass or a buffer.

Nesting is the first structure a finite-state recogniser cannot handle, and one stack is the smallest addition that fixes it. That is why a validator for a format with nested envelopes is written as a reader with a store rather than as a pattern, and why the two are not interchangeable no matter how elaborate the pattern gets. ## The machine, precisely A pushdown automaton has four moving parts: - a **finite control**: a finite set of states, exactly as a finite-state recogniser has; - a **one-way input**, read left to right, each symbol consumed once, never revisited; - a **stack**: an unbounded store with last-in-first-out discipline, over its own alphabet, which need not be the input alphabet; - a **transition relation** over the triple `(state, input symbol or nothing, top stack symbol)`, producing a new state and a string of symbols that replaces the top. Two details in that list do all the work. The store is **unbounded**, so the amount the machine can remember is a function of the input it has seen rather than a constant chosen in advance. And only the **top** symbol takes part in a step, so the store is a disciplined counter-with-labels, not an addressable memory. ## Why a fixed state set runs out A machine whose entire memory is its state must, to track nesting, distinguish being inside 1 open envelope from 2, from 3, and so on without limit. The state set is chosen once, before any input exists, and it is finite; beyond some depth two different depths have to be represented by the same state, and from that point the machine can no longer tell them apart. The formal argument that no finite-state machine accepts a balanced-nesting language is a separate piece of reasoning; the intuition above is what an interviewer wants spoken aloud. ## What the store buys, and what it does not | | finite control alone | finite control plus one stack | |---|---|---| | memory | a fixed set of states | states plus an unbounded LIFO store | | how far it can count | up to a bound fixed in advance | one count, to any depth | | readable in one step | state and current input symbol | those, plus the **top** stack symbol only | | languages accepted | the regular languages | the context-free languages (guessing model) | What it does not buy matters just as much: - **Only the top is visible.** A symbol buried under others cannot be consulted without popping everything above it, and popping destroys what it removes. - **One live count.** The store can carry one running quantity at a time; spending it against a later block leaves nothing for a third. - **One pass.** The input is consumed left to right once; there is no rewind. ## The reader that falls out of the model 1. Start with the store empty, or with a private bottom marker that the input alphabet never contains. 2. On an opener, push a symbol that records **which kind** of opener it was. 3. On a closer, pop; if the popped symbol is the wrong kind, the input is malformed. 4. On a closer that arrives with the store already empty, the input closed something it never opened. 5. At end of input, an exhausted store means every opener was matched; anything left means the input ended mid-envelope. Both rejection cases in steps 4 and 5 are load-bearing, and a candidate who names only one of them has described half a validator. Step 2 is the reason the store has its own alphabet: a machine that pushed an anonymous token could count depth but could not tell a square closer from a curly one. ## Where the model connects to rule systems The class of languages this machine accepts is exactly the class that context-free production rules generate. One direction builds a machine that keeps the not-yet-derived part of a sentence on its store, replacing a nonterminal on top with a rule's right-hand side and cancelling terminals against the input; the other turns a machine's moves back into rules. The equivalence is about the **class of languages**, not about how any practical reader is organised - an engineer should be able to say that the rule set and the machine describe the same power without claiming that one is compiled into the other in a real tool. ## The payoff in an interview The usable form of all this is a sentence: a pattern language over a fixed machine cannot check nesting because its memory does not grow with the input, so anything with nested structure needs a reader with a store. That single claim explains why hand-written nesting checks over a pattern always end in a counterexample, and it is the reason the answer to 'can I validate this with a pattern?' is decided by whether the structure nests.

  • Why does a step look only at the top of the stack rather than anywhere inside it?
    Because the store is defined as last-in-first-out and the control is finite: a step is a function of state, input symbol or nothing, and top symbol. Anything buried is unreachable until everything above it is popped, and popping destroys it. That restriction is exactly what holds the model at this level of power; a store with indexed access would be a different and stronger machine.
  • Where do context-free production rules fit into this picture?
    They describe the same class of languages. From a rule set you can build a machine that keeps the part of the sentence still to be derived on its store, expanding a nonterminal into a rule's right-hand side and cancelling terminals against the input; the other direction turns the machine's moves back into rules. The equivalence is about power, not about how a practical reader is built.
  • Does checking balanced nesting require the machine to guess?
    No. Matching openers against closers is fully determined by the current input symbol and the top of the store, so a machine with one forced move per configuration does it. Guessing is needed only for languages where the machine must commit to something the input has not yet revealed.

A cloakroom clerk with one spike for tickets: every coat handed in puts a ticket on the spike, every coat handed back must match the ticket on top, and the rail is clear only when the spike is bare. The clerk can never read a ticket buried under another one.

saying these in an interview costs you the question

  • Claims a finite-state machine handles nesting if given enough states
  • Says the machine can inspect symbols buried inside the stack
  • Thinks any extra memory works, ignoring the last-in-first-out restriction
  • Forgets that a closer arriving on an empty store must be rejected
  • Accepts a run that consumed all input while openers remain unmatched
  • Believes the model's stack has a fixed maximum size