Theory of computation :an introduction