Sikau

Theory of computation · Day 9 · about 40 min

The limits of computation

Diagonalisation and the halting problem.

Problems no program can solve

Wouldn't it be useful to have a tool that reads any program and its input and tells you whether it will ever finish? Your editor could warn about infinite loops before you run anything. Turing proved in 1936 that no such tool can exist — not because we haven't been clever enough, but because the idea contradicts itself. That's the halting problem, and it was one of the first results in computer science.

A problem is decidable if some Turing machine always halts with the right yes-or-no answer. Everything from Unit 1 is decidable. The halting problem is not, and neither are many questions about programs that follow from it.

The diagonal argument

The proof uses a trick from Georg Cantor (1891). Write a list of binary strings, one per row. Build a new string by taking the i-th character of row i and flipping it. The new string differs from row 0 at position 0, from row 1 at position 1, and so on — so it can't equal any row. Whatever list you start with, the diagonal argument builds something missing from it.

diagonal(["000", "111", "010"])
// row 0, char 0: 0 → 1
// row 1, char 1: 1 → 0
// row 2, char 2: 0 → 1
// "101" — not in the list

Cantor used this to show there are more real numbers than whole numbers. Turing used it on programs: list every program, and build one that disagrees with each of them.

The rest of this lesson

  • Why halting is undecidableexplain
  • Flip the diagonalpredict
  • Decidable or not?match
  • The contradictionorder
  • Diagonals and honest haltingwrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 10 lessons of Theory of computation