Undecidability by Reduction

We already know one problem that no program can ever solve: the halting problem — deciding, for an arbitrary program and input, whether it eventually stops or loops forever. Turing proved it is undecidable: no algorithm can answer it correctly for every case.

That single hard fact is a seed. Once you have one undecidable problem, you can grow a whole forest of them without ever re-doing the diagonal argument. The tool is a reduction: a way of saying "problem B is at least as hard as the halting problem." If B were decidable, the halting problem would be too — and it isn't. So B is undecidable. This page teaches that one move, richly, because it is the master key to almost every undecidability result there is.

The reduction idea in one breath

Suppose a friend claims to have a perfect decider D_B for some problem B — a program that always halts and always answers "yes" or "no" correctly. We don't build D_B; we just assume it exists and then use it as a subroutine to do something we know is impossible: decide halting.

A mapping reduction from the halting problem \mathrm{HALT} to B is a computable function f that turns any halting-problem instance (M, w) into a B-instance f(M, w) such that

(M, w) \in \mathrm{HALT} \iff f(M, w) \in B.

We write this \mathrm{HALT} \le_m B. The arrow of hardness points from the thing we already know is hard into the new problem. If such an f exists and B is decidable, then "D_B(f(M,w))" is a decider for \mathrm{HALT} — a contradiction. Hence B is undecidable.

Worked example: "Does M halt on empty input?"

Call this problem \mathrm{HALT}_\varepsilon: given a Turing machine M, does it halt when started on a blank tape? It feels easier than the general halting problem — no input to worry about — but it is exactly as impossible. Here is the reduction, laid out as a proof by contradiction.

  1. Assume the decider exists. Suppose D decides \mathrm{HALT}_\varepsilon: D(P) always halts and returns "yes" iff program P halts on empty input.
  2. Build the transformation f. Given an arbitrary halting instance (M, w), construct a new machine M_{w} that ignores its own input, hard-codes w inside itself, and simply simulates M on w. Writing out the source of M_{w} from (M, w) is plain text-manipulation — clearly computable.
  3. Note the equivalence. By construction, M_{w} halts on empty input \iff M halts on w. So f(M,w) = M_w satisfies (M,w)\in\mathrm{HALT} \iff M_w \in \mathrm{HALT}_\varepsilon.
  4. Decide halting — impossibly. Now run D(M_{w}). Its answer is exactly whether M halts on w. We have built a decider for the general halting problem out of D.
  5. Contradiction. The halting problem is undecidable, so no such D can exist. Therefore \mathrm{HALT}_\varepsilon is undecidable. \blacksquare

The same three moving parts recur every time: assume a decider, wrap the halting instance into a gadget machine, read the decider's answer as a halting verdict. Only the gadget changes from problem to problem.

Watch the arrows: a picture of the reduction

The whole argument is one directed chain. Reveal it step by step: a halting instance flows through the computable transformation f into a B-instance, the hypothetical decider D_B answers it, and that answer is a halting verdict — which cannot exist.

The sweeping generalisation: Rice's theorem

Reducing from \mathrm{HALT} one problem at a time is powerful — but there is a single theorem that condemns an entire universe of problems in one stroke.

"Does this program ever output 42?", "Is the language it recognises empty?", "Does it compute the same function as this other program?", "Does it accept at least one string?" — all semantic, all non-trivial, all undecidable, instantly, by Rice. The proof is itself a reduction from the halting problem, run once in full generality. It is the reason the dream of a tool that verifies "this program has no bugs" for every program is mathematically hopeless.

Rice's theorem kills only the fully general, always-correct decider for a semantic property. Two escape hatches remain, and industry lives in them. First, syntactic properties are fair game: "does the source contain a goto?", "does it have exactly 100 lines?", "is this valid grammar?" — these are about the text, not the computed function, so Rice says nothing and they are perfectly decidable. Second, real tools accept approximation: a type-checker or static analyser may answer "don't know / rejected to be safe" and still be enormously useful. Undecidability forbids perfect answers, not helpful ones.

Get the direction of the reduction right — it is the single most common mistake. To prove a new problem B is undecidable, you reduce the known-hard problem into it: \mathrm{HALT} \le_m B. You take an arbitrary halting instance, transform it into a B-instance, and use a hypothetical decider for B to settle halting. Reducing the other way — B \le_m \mathrm{HALT} — proves nothing about B's hardness; it would only show B is no harder than halting.

It is worth contrasting with hardness proofs in complexity. In NP-hardness you also reduce from a known-hard problem into the target (SAT \le_p B) — the direction is the same. The rule to memorise for both settings: to show a target is hard, reduce a known-hard problem TO it, never FROM it.

A gallery of undecidable problems

Every one of these is proved undecidable by a reduction from the halting problem (or, faster, straight from Rice's theorem):

By contrast, plenty of questions are decidable — anything syntactic, and semantic questions about weaker models like finite automata (emptiness and equivalence of DFAs are decidable). Undecidability is the price of Turing-complete power.