4.6.18Theory of Computation

Halting problem — undecidability proof by diagonalization

2,037 words9 min readdifficulty · medium6 backlinks

WHAT is the Halting Problem?

WHY do we care? Many real questions — "does this loop terminate?", "is this code dead?", "are these two programs equivalent?" — reduce to halting. If halting is unsolvable, those are too. It marks the hard limit of what mechanical computation can ever achieve.


HOW the proof works — derivation from scratch

We use proof by contradiction + diagonalization (Cantor's trick that there are "more" reals than integers, repurposed for programs).

Step 1 — Assume the decider exists

Suppose a program H solves halting. Define it precisely:

H(P,w)={HALTif P halts on wLOOPif P runs forever on wH(P, w) = \begin{cases} \texttt{HALT} & \text{if } P \text{ halts on } w \\ \texttt{LOOP} & \text{if } P \text{ runs forever on } w \end{cases}

Why this step? We want to disprove "H exists." The cleanest route is to assume it does and squeeze a contradiction out — that forces the assumption to be false.

Key fact we rely on: a program is just a string, so we can feed a program its own code as input. (This is what "self-reference" means here.)

Step 2 — Build a troublemaker program D (the diagonal)

Using H as a subroutine, construct:

D(P):                # P is the source code of a program
    if H(P, P) == HALT:   # would P halt when given its own code?
        loop forever
    else:                 # H says P loops on itself
        halt

Why this step? D is engineered to do the opposite of what H predicts about a program running on itself. This deliberate flip is the diagonalization: we'll later place D on the "diagonal" against itself.

Step 3 — Feed D its own code: run D(D)

Ask: does D halt on input D? Two cases, both fatal.

  • Case A: Suppose D(D) halts. Then inside D, the branch taken must have been the else (the "halt" branch). That branch runs only when H(D, D) == LOOP, i.e. H claims D(D) runs forever. But we assumed it halts. Contradiction.

  • Case B: Suppose D(D) loops forever. Then the if-branch was taken, which happens only when H(D, D) == HALT, i.e. H claims D(D) halts. But we assumed it loops. Contradiction.

D(D) halts    H(D,D)=LOOP    D(D) loopsD(D)\text{ halts} \iff H(D,D)=\texttt{LOOP} \iff D(D)\text{ loops}

A statement equivalent to its own negation is impossible.

Step 4 — Conclude

Every consistent answer leads to contradiction, so our only assumption — that H exists — must be false.

Figure — Halting problem — undecidability proof by diagonalization

WHY it's called diagonalization


Worked examples


Common mistakes (steel-manned)


Flashcards

What language does the halting problem ask us to decide?
HALT={P,wP halts on w}HALT=\{\langle P,w\rangle \mid P \text{ halts on } w\}
Is HALTHALT decidable or undecidable?
Undecidable (no total algorithm decides it).
What proof technique establishes undecidability of halting?
Proof by contradiction using diagonalization (self-reference).
How is program D defined from a supposed decider H?
D(P): if H(P,P)=HALT then loop forever, else halt.
What contradiction appears when running D(D)?
D(D)D(D) halts     H(D,D)=\iff H(D,D)=LOOP     D(D)\iff D(D) loops — a statement equal to its own negation.
Why can we feed a program its own code as input?
Because a program is itself just a string/data.
Why is "simulate and watch" not a decider?
If PP loops forever, the simulation never halts, so it never outputs LOOP; a decider must always halt.
What property does HALTHALT have if not decidable?
It is semi-decidable / recognizable (can confirm halting, can't confirm looping).
What is a reduction used for here?
To transfer undecidability: if problem A reduces to B and A is undecidable, then B is too.
Which cell does D disagree with in the program×input table?
The diagonal cell (i,i)(i,i) — whether PiP_i halts on itself.

Recall Feynman: explain to a 12-year-old

Imagine a magic box that, for any video game, tells you "this game will end" or "this game runs forever." Now I build a sneaky game called Trickster. Trickster looks at a game's instructions and asks the magic box about that game playing against itself. If the box says "ends," Trickster decides to run forever. If the box says "runs forever," Trickster ends. Now I make Trickster look at itself. Whatever the box predicts, Trickster does the opposite — so the box is wrong. Since I could always build a Trickster, the magic box can never have existed. That's why no program can predict halting for all programs.


Connections

  • Turing Machines — the formal model in which "program" and "decide" are defined.
  • Decidable vs Recognizable LanguagesHALTHALT separates these two classes.
  • Reductions and Mapping Reducibility — how undecidability propagates (Example 2).
  • Rice's Theorem — generalizes: every nontrivial semantic property of programs is undecidable.
  • Cantor's Diagonal Argument — the set-theory ancestor of this proof.
  • Universal Turing Machine — why a program can run another program (and itself).
  • Church–Turing Thesis — why "no program" means "no possible algorithm at all."

Concept Map

asks if

claim tested on

technique for

assume

enables

used as subroutine to build

does opposite of H prediction

feed own code

Case A halts

Case B loops

refutes

therefore

Halting Problem HALT language

Does P halt on w?

Decidable = total algorithm exists

Proof by contradiction + diagonalization

Decider H exists

Program is a string, self-reference

Troublemaker program D

Flips halt/loop

Run D on D

Contradiction

HALT is undecidable

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Halting problem ka matlab simple hai: kya koi aisa ek hi program H ban sakta hai jo har program P aur input w ke liye sahi-sahi bata de ki "yeh halt hoga ya hamesha loop karega"? Theory of Computation kehti hai — nahi, aisa universal program ban hi nahi sakta. Isko hum diagonalization aur contradiction se prove karte hain.

Idea yeh hai: maan lo H exist karta hai. Ab ek shaitan program D banao jo H ko ulta chidhaye. D(P) kya karta hai? Pehle puchta hai H(P,P) — yaani P apne aap pe halt karega ya nahi. Agar H bole "HALT", to D jaan-bujh ke infinite loop me chala jaata hai. Agar H bole "LOOP", to D turant halt kar deta hai. Matlab D hamesha H ki prediction ka opposite karta hai.

Ab masti yahan hai: D(D) chalao — D ko khud D ka code de do (program bhi to bas ek string hai, isliye yeh allowed hai). Ab dekho: agar D(D) halt karta hai, to iska matlab H(D,D) ne "LOOP" bola tha — yaani galat. Agar D(D) loop karta hai, to H(D,D) ne "HALT" bola tha — phir bhi galat. Dono case me H galat. To H jaisa perfect decider exist hi nahi kar sakta. Bas yahi proof hai.

Yeh important kyun hai? Kyunki bahut saare real questions — "kya yeh loop terminate hoga", "kya yeh do programs same hain" — sabhi halting pe reduce ho jaate hain. Iska matlab computing ki ek fundamental limit hai: kuch cheezein machine kabhi bhi general tareeke se solve nahi kar sakti, chahe kitna bhi smart algorithm bana lo. Yeh cleverness ki kami nahi, yeh logic ki deewar hai.

Go deeper — visual, from zero

Test yourself — Theory of Computation

Connections