A Turing machine

As proved in the last chapter, the language consisting of strings with a positive number of x’s followed by the same number of y’s followed by the same number of zs is not context free and so cannot be recognised by a pushdown automaton. We can construct a Turing machine which recognises it though.

There are two stacks, one of which initially holds the input and the other of which is initially empty. I’ll refer to these as Stack I and Stack E, respectively. While only x’s y’s and zs appear on the stacks initially it’s convenient to allow the machine to push and pop X’s, Y’s and Z’s as well.

There are two phases to the computation. In the first phase we perform the following action repeatedly:

The second stage is simpler.

Conceptually this is fairly simple. In the first stage we replace the first x by an X, the first y by a Y and the first z by a Z, then the second x by an X, the second y by a Y and the second z by a Z, etc. If the input was in the languages then at this point we should have with a positive number of X’s followed by the same number of Y’s followed by the same number of Zs. If it’s not in the language then either we have too few y’s or z’s in the input or too many. If we have too few then the machine will already have halted unsuccessfully when it empties Stack I while scanning for a y or a z. If we have too many then there will be some y’s which didn’t get changed to Y’s or some z’s which didn’t get changed to Z’s. In that case the machine will halt unsuccessfully during the second stage. Otherwise it will halt successfully after the second stage.

This Turing machine has the rather nice property that no matter what input we give it it will eventually halt, either successfully or unsuccessfully. This is not true of Turing machines in general. A recogniser is required to halt successfully on any input in the language and only on inputs in the language but it is allowed to halt unsuccessfully or run forever on inputs which are not in the language. A Turing machine which always halts unsuccessfully on inputs which are not in the language, like this one does, is called a decider for the language. Every decider is a recogniser, but not vice versa. In fact there are languages for which it’s possible to construct a recogniser but impossible to construct a decider.