Introduction to Automata Theory, Languages and Computation