These notes are a bit sparse - see the book for a much more thorough presentation
Where regular languages are defined as those accepted by a DFA, we defined context-free languages in terms of their describing grammars. There is, however, an automaton whose power is equivalent to context free languages: a pushdown automaton (PDA). Informally, a PDA is more or less an NDA that has the additional capability to keep notes on a stack.
Let \(M = (\Sigma, \Gamma, Q, \delta, q)\), where
Decoding the \(\delta\) gibberish, our transition function takes:
The machine starts with:
A step of computation takes as input the current state, current tape symbol, and the symbol on the top of the stack. In response, the transition function provides:
Termination: The machine terminates when the stack is empty.
Acceptance: The machine accepts a string if the tape head is on the \(\square\) symbol at the time of termination.
Rejection: The machine rejects a string if the tape head is not on the \(\square\) symbol on termination or the machine never terminates.
Here’s a PDA that accepts strings with properly nested parentheses; for example, it should:
For typographic clarity, we’ll replace \((\) with \(a\) and \()\) with \(b\). So the above accepted examples would be:
Let \(M = (\Sigma, \Gamma, Q, \delta, q)\), where
and \(\delta\) is defined as follows:
\(q_{in}\) | Tape in | Stack in | \(q_{out}\) | Move? | Stack out | Commentary |
---|---|---|---|---|---|---|
\(q\) | \(\square\) | \(\$\) | \(q\) | N | \(\epsilon\) | Input is empty; accept |
\(q\) | \(a\) | \(\$\) | \(q\) | Y | \(S\) | First character is an \(a\) |
\(q\) | \(b\) | \(\$\) | \(q\) | N | \(\$\) | First character is a \(b\); reject by never terminating |
\(q\) | \(a\) | \(S\) | \(q\) | Y | \(SS\) | Open paren, increase nesting level |
\(q\) | \(b\) | \(S\) | \(q\) | Y | \(\epsilon\) | Close paren, decrese nesting level |
\(q\) | \(\square\) | \(S\) | \(q\) | N | \(S\) | End of string with nonzero nesting; reject by never terminating |
As above, except \(\delta : Q \times (\Sigma \cup \square) \times \Gamma \rightarrow \mathcal{P_f}\left( Q \times \{R, N\} \times \Gamma^*\right)\), where \(\mathcal{P_f}\) denotes all finite subsets of its argument.
As with NFAs, if there is any way to reach the accepting configuration
Example: A PDA accepting odd length strings with \(b\) in the middle position.
The basic idea here is like the \(a^nb^n\) machine, except that there needs to be a point where we see a \(b\) and switch from the start state (representing “we are in the first half of the string”) to a second state (representing “we are in the second half of the string”). By making the machine nondeterministic, we can have a rule that sees a \(b\) and either switches states, or continues reading input in “first half” mode. Then, th