Probably every mathematician is familiar with Cantor’s diagonal argument for proving that there are uncountably many real numbers, but less well-known is the proof of the existence of an undecidable problem in computer science, which also uses Cantor’s diagonal argument. I thought it was really cool when I first learned it last year.
To understand undecidability, you first have to know what a Turing machine is. A Turing machine is just a theoretical model of a computer, with a work tape, a tape head which points to a cell on the tape, and a set of states. These three things determine a configuration of the TM. In addition, the TM comes with a transition function which dictates how the TM changes its configuration. Lastly, one of its states is designated the initial state, which is the state that the TM starts in every time it runs on an input, and some of its states are designated accept states, while others are designated reject states. A precise definition of a Turing machine can be found in any textbook on theory of computation, but it’s not terribly important for our goal here. The thing to take away is that a TM is given an input (written on its tape), then its transition function dictates what it does (like an algorithm), and if the TM lands on an accept state, then it accepts the input, and if it lands on a reject state, then it rejects the input. Note that it is also possible for infinite loops to occur for certain inputs, in which case the TM is considered to not accept or reject.
I didn’t mention what kind of inputs are allowed for Turing machines. It can be any finite alphabet , but I like to think of the allowed alphabet as since that’s what we use in modern electronic computers, and two letters is enough to do everything you want to do, so from now on we’ll assume Turing machines take binary string inputs. A language is a set (possibly infinite) of binary strings. The language recognized by a Turing machine is the set of strings that it accepts. So, when we talk about “problems”, such as the primality problem (given an positive integer, determine if it’s prime) or the SAT problem (given a boolean formula, determine if it’s satisfiable), we are really talking about languages. For example, we can view the primality problem as the set of binary strings which represent prime numbers. Then the question of whether there exists an algorithm for deciding primality is actually whether there exists a Turing machine which decides the corresponding language.
I just used the term “decide” but I haven’t defined it yet. Whereas a machine recognizes a language if it accepts precisely those strings in it, a machine decides a language if it recognizes the language and halts on every input. The cool thing is that there are problems that are recognizable but not decidable, and showing that is the main goal of my post.
Consider the language
where just means a binary string encoding concatenated with the binary string , with a delimiter in between so the Turing machine knows where the encoding of ends. In other words, the problem is to determine if a given Turing machine accepts a given binary string . This problem is recognizable. You can design a Turing machine , called the “universal Turing machine”, which can simulate any other Turing machine. Then, given input , just simulate on and accept if accepts and reject if rejects . Clearly our machine will accept if and only if accepts , so it recognizes . It doesn’t decide , however, since if goes into an infinite loop on , then so does our machine, but we want our machine to reject when this happens.
To show that is undecidable, we prove it by contradiction. Suppose we had a machine which decides . Note that every Turing machine has some encoding as a finite length binary string, so we can enumerate them as and construct the following table:
where the entry in row , column is a if accepts and is a if not. I just made up the numbers for concreteness. We can construct this table since we have (to determine the value of an entry, just run on . Now, consider the Turing machine which, given input , does the opposite of what does on input (if the input happens to not be a proper encoding of any Turing machine, then it’s irrelevant what does). That is, accepts if the entry corresponding to in our table is a , and rejects if the corresponding entry is a . Now, ask yourself: which is ? For each , our machine differs from on the input , so it can’t be any of these. But we’ve enumerated all the Turing machines, so we have a contradiction! Therefore, is not decidable.
That ends the proof. I hope you found this as cool as I did when I first saw it. Anyway, feel free to leave comments if you have any questions about the proof, or corrections to it if I made a mistake.
P.S. It’s also straightforward to see that there are languages that aren’t even Turing-recognizable, since there are countably many Turing machines but uncountably many languages.