Notes on the Halting Problem

2023-12-07 · 4 min read


  • computability
  • math
  • turing

The computability of the HALT\mathrm{HALT} class is a simple problem to solve, which provides a very powerful result. Mainly, that we cannot prove that arbitrary Turing machines halt or not.

Except that this is not accurate. The undecidable nature of HALT\mathrm{HALT} merely says that no singular Turing machine (i.e., a single algorithm) can compute whether any Turing machine halts or not.

Proving this is a fun little exercise, and the proof is similar to proving Russel’s paradox.

Proving HALT\mathrm{HALT} is undecidable

We begin by assuming that there is some Turing machine, HH, which can decide whether a given input M,x\langle M, x \rangle halts or not (running MM with input xx). Then, construct a Turing machine CC as follows:

  • Given input xx:
    • If x,x\langle x, x \rangle halts, then loop forever.
    • Otherwise, halt.

Where checking if x,x\langle x, x \rangle halts is done using HH. Now, consider what happens when we run CC with the input CC (i.e., feed CC to itself):

  • If C,C\langle C, C\rangle halts, then by the construction of CC, CC doesn’t halt.
  • If C,C\langle C, C\rangle doesn’t halt, then again by the construction, CC should halt.

This results in a contradiction, with the contradiction being the existence of HH itself.

While this proof is simple and effective, it does not give much insight to this problem. In fact, here is an algorithm which supposedly contradicts this proof:

  • Given input M,x\langle M, x \rangle:
    • Enumerate on all proofs of M,x\langle M, x \rangle, alternating between proving halting, and proving non-halting (infinite loop)
    • Because MM must either halt or loop forever, eventually some proof will be found. Via this proof, report back “YES”/“NO”, depending on what proof we found.

Because proofs are always finite, this means that the algorithm above must stop sometime, and report a result. Yet, this contradicts what we’ve just proved: HALT\mathrm{HALT} is undecidable, but here is an algorithm which decides it.

Gödel’s Incompleteness Theorems

In 1931, Gödel published an article showcasing two incredible results in mathematical logic. Of those two, the first is relevant to us. The result, also known as Gödel’s first incompleteness theorem, states:

Theorem. (Gödel’s first incompleteness theorem) Given any formal system FF, there exist some statement GG (also known as Gödel’s sentence) which cannot be proven or disproven under FF.

The connection between Gödel’s theorem and the halting problem is striking. Given any supposed algorithm HH which decides HALT\mathrm{HALT}, we can find some Turing machine for which HH simply cannot decide whether it halts or not. However, this time no clever constructions are needed.

Because we assume HH to be correct (that is, answer correctly and not randomly), this means that HH must perform a sequence of logical conclusions, in order to arrive at the answer of whether a given machine halts or not. This is essentially the formal system, FHF_H, under which HH is working. From Gödel’s first incompleteness theorem we can draw the conclusion that there is some statement GHG_H, which is unprovable under FHF_H. Finally, it is possible to turn GHG_H into a Turing machine, by halting iff GHG_H is true, and looping forever if it is false.

The algorithm above fails in deciding HALT\mathrm{HALT}, because such proof might not exist, hence causing the algorithm to loop forever. For the sake of completeness: such algorithm cannot exist, because for any algorithm we can encode it as a proof under some formal system FF, and for each such system there is an unprovable statement.

Gödel’s incompleteness theorems were published before the consideration of the halting problems. At the time of publishing, this created a huge shock, as it implied that some statements simply cannot be proved (roughly speaking). For me, using these theorems in the context of computability is as shocking: it essentially implies that there exist Turing machine on which we cannot prove anything.

Of course, looking at this from a higher-level standpoint is not very impressive; Turing machines can be thought of as just proof enumerations, and in that regard indeed the two results are exactly the same.

Computability vs Decidability

Finally, a word on search problems. A similar construction can build uncomputable functions. That is, functions f:NNf : \mathbb{N} \to \mathbb{N} for which no Turing machine can compute f(x)f(x), for sufficient xx. To do this, we utilize unprovable statements, yet again. Let ff be some function, and GG some Gödel statement. We construct the uncomputable function fG:NN{}f_G : \mathbb{N} \to \mathbb{N} \cup \{ \perp \} by:

fG(x)={f(x)G is provableotherwisef_G(x) = \begin{cases} f(x) && G \text{ is provable} \\ \perp && \text{otherwise} \end{cases}

Thus, for example, being able to compute any value of fGf_G would be equivalent to the Turing machine proving GG. In other words, any output of an evaluation of fGf_G at any input would require either proving or disproving GG.

fGf_G might perhaps be cheating, as the existence of GG is dependent on the machine itself, yet we require the machine in order to construct the function. Instead, let us construct a function in two parts. First, let gF:N×Stmt(F)N{}g_F : \mathbb{N} \times \mathsf{Stmt}(F) \to \mathbb{N} \cup \{ \perp \} be defined as:

gF(x,φ)={xφ is provableotherwiseg_F(x, \varphi) = \begin{cases} x && \varphi \text{ is provable} \\ \perp && \text{otherwise} \end{cases}

It is clear that gFg_F is computable for some inputs, such as xNx \in \mathbb{N} and φ=true\varphi = \mathbf{true}, yet not computable for all inputs. Indeed, for φ=G\varphi = G the function g(x)=gF(x,G)g^{\prime} (x) = g_F(x, G) is not computable by the same machine that might compute some of gFg_F. Instead, construct a function hh which is not computable at all, by:

h(x)=φStmt(F)φxgF(x,φ)h(x) = \sum_{\substack{\varphi \in \mathsf{Stmt}(F) \\ \lvert \varphi \rvert \le x}} g_F(x, \varphi)

Which by itself is partially computable, yet h(x)=h(x+G)h^{\prime} (x) = h(x + \lvert G \rvert) with GG being the shortest Gödel statement under FF. hh^\prime is not computable under any input.