Introduction to the mathematical theory of computation