Pushdown Automata (PDA)

Pushdown Automata (PDA) Visually

Learn Pushdown Automata with interactive visual simulations. Understand stack operations, context-free languages, and PDA transitions with dynamic animations.

Visual Simulation Step Execution PDA Constructor Performance Analysis

What is a Pushdown Automaton?

A Pushdown Automaton (PDA) is a finite automaton equipped with a stack (LIFO memory). PDAs are more powerful than finite automata and can recognize context-free languages, which include nested structures like balanced parentheses, palindromes, and programming language constructs.

Formal Definition: A PDA is a 7-tuple M = (Q, Σ, Γ, δ, q₀, Z₀, F) where:
  • Q: Finite set of states
  • Σ: Input alphabet
  • Γ: Stack alphabet
  • δ: Transition function δ: Q × (Σ ∪ @{ε@}) × Γ → P(Q × Γ*)
  • q₀: Initial state
  • Z₀: Initial stack symbol
  • F: Set of final states
Example Language: L = @{a^n b^n | n ≥ 1@} = @{ab, aabb, aaabbb, ...@}

Interactive PDA Tester

Test strings with the PDA for L = @{a^n b^n | n ≥ 1@}

Visual PDA Simulator

Interactive simulation of a PDA that accepts L = @{a^n b^n | n ≥ 1@}

PDA for L = @{a^n b^n | n ≥ 1@}
Input Tape
Position: 0
Stack
Z₀
Top: Z₀
Current State
q₀
Status: Running
1000ms

Transition Table

PDA transitions for L = @{a^n b^n | n ≥ 1@}

State Input Stack Top Next State Stack Operation
q₀ a Z₀ q₁ Push A
q₁ a A q₁ Push A
q₁ b A q₂ Pop A
q₂ b A q₂ Pop A
q₂ ε Z₀ q₃ -

PDA Implementation

class PushdownAutomaton: def __init__(self, states, input_alphabet, stack_alphabet, transitions, start_state, start_stack, final_states): self.states = states self.input_alphabet = input_alphabet self.stack_alphabet = stack_alphabet self.transitions = transitions self.start_state = start_state self.start_stack = start_stack self.final_states = final_states def process_string(self, input_string): stack = [self.start_stack] current_state = self.start_state position = 0 trace = [] while position <= len(input_string): if position == len(input_string): symbol = 'ε' # End of input else: symbol = input_string[position] stack_top = stack[-1] if stack else None transition_key = (current_state, symbol, stack_top) if transition_key in self.transitions: next_state, stack_ops = self.transitions[transition_key] # Apply stack operations if stack_ops == 'pop': stack.pop() elif stack_ops.startswith('push_'): stack.append(stack_ops[5:]) trace.append(@{ 'state': current_state, 'input': symbol, 'stack_before': stack[:], 'stack_after': stack[:], 'next_state': next_state @}) current_state = next_state if symbol != 'ε': position += 1 else: break accepted = (current_state in self.final_states and len(stack) == 1 and stack[0] == self.start_stack) return accepted, trace # Example PDA for @{a^n b^n | n >= 1@} pda = PushdownAutomaton( states=@{'q0', 'q1', 'q2', 'q3'@}, input_alphabet=@{'a', 'b'@}, stack_alphabet=@{'A', 'Z0'@}, transitions=@{ ('q0', 'a', 'Z0'): ('q1', 'push_A'), ('q1', 'a', 'A'): ('q1', 'push_A'), ('q1', 'b', 'A'): ('q2', 'pop'), ('q2', 'b', 'A'): ('q2', 'pop'), ('q2', 'ε', 'Z0'): ('q3', '') @}, start_state='q0', start_stack='Z0', final_states=@{'q3'@} )