Computation and Turing Machines · v2.2.3
2026-09-25 23:14:10
Halting: nothing forces a stop. Universality: \(U\) simulates, does not decide.
Are Turing machines powerful enough to model any conceivable algorithm?
Each technique is stronger than the one before.
An algorithm is an effective, systematic, mechanical method for a given problem.
Every result in this unit depends on termination in finitely many steps.
Decision problems
Input \(w\), output yes or no.
Yes means \(w \in L\).
Given a chess configuration, can the player to move win?
Function computation
Input \(w\), output \(f(w)\).
Given a social graph, what is the shortest chain between two people?
Two definitions follow: one for languages, one for functions.
\(M\) decides \(L \subseteq \Sigma^*\) iff for all \(w \in \Sigma^*\):
\[\begin{cases} M \text{ accepts } w, & \text{if } w \in L, \\ M \text{ rejects } w, & \text{if } w \notin L. \end{cases}\]
For \(f : \Sigma^* \to \Sigma^*\), a machine computes \(f\) iff for all \(w \in \Sigma^*\):
\[(q_0, \triangleright w) \vdash^{*} (q_{\text{acc}}, \triangleright f(w))\]
\(M\) semidecides \(L\) iff for all \(w \in \Sigma^*\):
\[\begin{cases} M \text{ accepts } w, & \text{if } w \in L, \\ M \text{ rejects } w \text{ or runs forever}, & \text{if } w \notin L. \end{cases}\]
The asymmetry is what separates semideciding from deciding.
| Type of computation | Always halt? |
|---|---|
| TMs for decidable languages | ✓ |
| TMs for computable functions | ✓ |
| TMs for semidecidable languages | ✗ |
If the machine has not accepted yet, nothing has been learned.
The Church-Turing thesis, in four phrasings:
For \(L \subseteq \Sigma^*\):
\[\overline{L} = \{\, w \in \Sigma^* \mid w \notin L \,\}\]
If \(L\) is Turing-decidable, then \(\overline{L}\) is Turing-decidable.
DECIDE_NOT_L(w)
1. result <- DECIDE_L(w)
2. if result = accept then
3. reject
4. else
5. accept
DECIDE_L halts on every input, so this does tooOne decider serves both, with the answers exchanged.
If \(L\) is semidecidable and undecidable, \(\overline{L}\) is not semidecidable.
DECIDE_L(w)
1. run SEMI_L(w) and SEMI_NOT_L(w)
in parallel
2. if SEMI_L accepts then
3. accept
4. elseif SEMI_NOT_L accepts then
5. reject
It would decide \(L\) — contradicting the assumption that \(L\) is undecidable.
There are strictly more decision problems than there are Turing machines.
Every program in every language appears somewhere on it.
Each machine semidecides at most one language, and problems outnumber machines.
The solvable problems form a vanishingly small part of the whole.
Showing a list incomplete requires one object it cannot contain.
Each entry is excluded at the cost of a single disagreement.
| TM | \(w_1\) | \(w_2\) | \(w_3\) | \(w_4\) | \(w_5\) |
|---|---|---|---|---|---|
| \(M_1\) | 1 | 0 | 0 | 1 | 0 |
| \(M_2\) | 0 | 0 | 1 | 0 | 0 |
| \(M_3\) | 0 | 1 | 1 | 1 | 1 |
| \(M_4\) | 1 | 1 | 0 | 1 | 0 |
| \(M_5\) | 0 | 1 | 0 | 0 | 0 |
A 1 where the machine accepts. Every semidecidable language is a row.
\[L_d = \{w_i \mid w_i \notin L(M_i)\}\]
\[d_i = \begin{cases} 1 & \text{if } \text{table}_{ii} = 0, \\ 0 & \text{if } \text{table}_{ii} = 1. \end{cases}\]
Suppose \(L_d = L(M_k)\) for some \(M_k\). Ask whether \(M_k\) accepts \(w_k\).
Case 1 — \(M_k\) accepts \(w_k\)
\[\begin{eqnarray} &\implies& w_k \notin L_d \\ &\implies& w_k \notin L(M_k) \\ &\implies& M_k \text{ does not accept } w_k \end{eqnarray}\]
Case 2 — \(M_k\) does not accept \(w_k\)
\[\begin{eqnarray} &\implies& w_k \in L_d \\ &\implies& w_k \in L(M_k) \\ &\implies& M_k \text{ accepts } w_k \end{eqnarray}\]
Each branch concludes the opposite of its own assumption.
\[\text{HALT} = \{\, \langle M, w \rangle \mid M \text{ halts on } w \,\}\]
\(\text{HALT}\) is the problem; HALT is a hypothetical algorithm deciding it.
Three machines over \(\Sigma = \{a\}\), one state each, none halting.
| \(\triangleright\) | \(a\) | \(\square\) | |
|---|---|---|---|
| \(M_1\): \(q_0\) | \((q_0, \rightarrow)\) | \((q_0, \rightarrow)\) | \((q_0, \rightarrow)\) |
| \(M_2\): \(q_0\) | \((q_0, \rightarrow)\) | \((q_0, a)\) | \((q_0, \square)\) |
| \(M_3\): \(q_0\) | \((q_0, \rightarrow)\) | \((q_0, \leftarrow)\) | \((q_0, \leftarrow)\) |
Undecidability is not caused by complexity.
\[\text{ACCEPT} = \{\, \langle M, w \rangle \mid M \text{ accepts } w \,\}\]
SIMULATE(<M, w>)
1. Simulate TM M on input string w
2. if M accepts w then
3. accept
4. elseif M rejects w then
5. reject
This procedure exists: it is what a universal machine does.
SIMULATE(<M, w>)
1. Simulate TM M on input string w
2. if M accepts w then
3. accept
4. else
5. reject
elseif M rejects w has become elseWhere the first version runs forever alongside \(M\), this one rejects.
The else branch must establish that \(M\) does not accept \(w\).
PARADOX(<M>)
1. result <- SIMULATE(<M, <M>>)
2. if result = accept then
3. reject
4. elseif result = reject then
5. accept
Then invoke PARADOX(<PARADOX>) — the machine is handed its own encoding.
Case 1
\[\begin{eqnarray} & & \texttt{PARADOX} \text{ accepts} \\ &\implies& \texttt{SIMULATE} \text{ rejects} \\ &\implies& \texttt{PARADOX} \text{ rejects} \\ &\implies& \text{Contradiction} \end{eqnarray}\]
Case 2
\[\begin{eqnarray} & & \texttt{PARADOX} \text{ rejects} \\ &\implies& \texttt{SIMULATE} \text{ accepts} \\ &\implies& \texttt{PARADOX} \text{ accepts} \\ &\implies& \text{Contradiction} \end{eqnarray}\]
ACCEPT is semidecidable, not decidable. Simulation stays possible.
HALT(<M, w>)
1. if M halts on w then
2. accept
3. else
4. reject
Rejecting requires establishing that \(M\) never halts.
PARADOX(<M>)
1. result <- HALT(<M, <M>>)
2. if result = accept then
3. run forever
4. elseif result = reject then
5. accept
\[\small \begin{eqnarray} & & \texttt{PARADOX} \text{ accepts} \\ &\implies& \texttt{HALT} \text{ rejects} \\ &\implies& \texttt{PARADOX} \text{ runs forever} \\ &\implies& \text{Contradiction} \end{eqnarray}\]
\[\small \begin{eqnarray} & & \texttt{PARADOX} \text{ runs forever} \\ &\implies& \texttt{HALT} \text{ accepts} \\ &\implies& \texttt{PARADOX} \text{ accepts} \\ &\implies& \text{Contradiction} \end{eqnarray}\]

PARADOX on SIMULATE: the outputs are crossed over.

PARADOX on HALT: accept becomes run-forever.
Identical construction; the middle box and one label change.
\[L_{\text{old}} \leq_m L_{\text{new}}\]
if there exists a computable function \(f\) such that for all \(x \in \Sigma^*\):
\[x \in L_{\text{old}} \iff f(x) \in L_{\text{new}}\]
\(f\) must be computable, or the argument carries nothing.

If \(L_{\text{old}} \leq_m L_{\text{new}}\):
SIMULATE(<M, w>)
1. result <- HALT(<M, w>)
2. if result = reject then
3. reject
4. elseif result = accept then
5. Simulate M on w
6. if M accepts w then
7. accept
8. elseif M rejects w then
9. reject
Lines 2–3 are what make this terminate.
This is the most common error in the topic.
Each carries a bound: simulate for 482 steps and look.
Each quantifies over all inputs; no finite simulation settles it.
Ask whether a finite amount of simulation could settle it.
A finite check settles it: decidable. Behaviour on all inputs: generally not.
Each is stronger than the one before.
The limit of computation: no hardware or language moves it.