Introduction to the theory of computation

Sipser