Lukas' Notes

Prologue

  • Purpose of formal languages
    • Syntax specifies which expressions and proofs are allowed; semantics assigns meaning and determines truth in an interpretation.
    • This separation lets us ask whether formal derivations capture semantic consequences.
  • Hilbert’s programme
    • Seek a formal theory in a language that formalises all mathematics, with a finitistic proof of its consistency. The broader foundational ambition also asks for completeness:
      • Consistency: does not prove both a sentence and its negation .
      • Completeness of the theory: for every sentence of , either or .
    • Frege developed a formal logical language; Zermelo’s axiomatic set theory contributed to the foundations later developed as ZF and ZFC.
  • Gödel’s results
    • Completeness theorem (1929; published 1930): first-order logic has a complete proof calculus: implies . Every consequence of that holds in all models of can be formally derived. This applies to first-order theories such as ZFC, but does not mean that ZFC decides every sentence.
    • First incompleteness theorem (1931): every consistent, effectively axiomatised theory with enough arithmetic leaves some sentence undecided: neither nor .
    • Second incompleteness theorem (1931): under the usual arithmetical conditions, such a theory cannot prove its own consistency. This blocks the original unrestricted ambition of Hilbert’s programme; it does not rule out every relative consistency proof.

Chapter 1: Computability

  • Decidable Predicate
  • There are more uncomputable functions than computable functions.
    • Finite programs can be listed as . Let be the unary partial function computed by . Every computable unary function occurs in this list, possibly more than once.
    • Put programs in rows and inputs in columns. Entry is the output of on input ; means that the computation does not halt. For example, a row might read . Boxed entries form the diagonal:

Misplaced & \begin{array}{c|ccccc} & 0 & 1 & 2 & 3 & \cdots \\ \hline f_0 & \boxed{f_0(0)} & f_0(1) & f_0(2) & f_0(3) & \cdots \\ f_1 & f_1(0) & \boxed{f_1(1)} & f_1(2) & f_1(3) & \cdots \\ f_2 & f_2(0) & f_2(1) & \boxed{f_2(2)} & f_2(3) & \cdots \\ f_3 & f_3(0) & f_3(1) & f_3(2) & \boxed{f_3(3)} & \cdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \ddots \end{array} <span class="math-indent" aria-hidden="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

- Define a [[Knowledge/Total Function|total function]] $g:\mathbb{N}\to\mathbb{N}$ by changing every diagonal entry:

Misplaced & g(n):= \begin{cases} f_n(n)+1 & \text{if }f_n(n)\text{ is defined},\\ 1 & \text{otherwise}. \end{cases} <span class="math-indent" aria-hidden="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

- For every $n$, $g$ differs from $f_n$ on input $n$: if $f_n(n)$ is defined, then $g(n)=f_n(n)+1\neq f_n(n)$; otherwise $g(n)=1$ is defined while $f_n(n)$ is not. Thus $g\neq f_n$ for every $n$, so no [[Knowledge/Program|program]] in the list computes $g$.
- This defines $g$ mathematically, not algorithmically: to choose the second case, we would need to determine that $P_n$ never halts on input $n$. Waiting for its output cannot establish this.
- There are only countably many finite programs, but uncountably many total functions $\mathbb{N}\to\mathbb{N}$ (already the functions $\mathbb{N}\to\{0,1\}$ correspond to all [[Knowledge/Subset|subsets]] of $\mathbb{N}$). Hence [[Knowledge/Uncomputable Function|uncomputable functions]] outnumber computable ones; the diagonal construction exhibits one total uncomputable function.

Misplaced & \begin{aligned} i^*(\langle\rangle)&=0,\\ i^*(\langle n_1,\ldots,n_m\rangle) &=\left(\prod_{k=1}^{m-1}p_k^{n_k}\right)p_m^{n_m+1}-1 \qquad(m\geq1). \end{aligned} <span class="math-indent" aria-hidden="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

- **Preserving the length:** an exponent $0$ contributes a factor $p^0=1$, so an ordinary prime-power product cannot distinguish a sequence from the same sequence with trailing zeros. For instance, $\langle1\rangle$ and $\langle1,0\rangle$ would both give $2$.
	- Increasing only the final exponent to $n_m+1\geq1$ forces the last [[Knowledge/Prime Number|prime]] $p_m$ to appear. Its position $m$ in the prime list then records the sequence length, even if the last component is $0$.
	- For $m=1$, the product before the final factor is empty and equals $1$, so the formula becomes $i^*(\langle n_1\rangle)=2^{n_1+1}-1$.
- **Recovering the sequence:** given a code $a>0$, use [[Knowledge/Prime Factorisation|unique prime factorisation]] to write

Misplaced & a+1=p_1^{e_1}\cdots p_m^{e_m},\qquad e_m>0. <span class="math-indent" aria-hidden="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

	- The largest prime factor is $p_m$, so the sequence has length $m$. A prime $p_k$ that is absent has exponent $e_k=0$ and therefore records a zero component.
	- Read $n_k=e_k$ for $k<m$, and undo the final increment with $n_m=e_m-1$.
	- Every integer $a+1>1$ has exactly one such factorisation, so every code $a>0$ represents exactly one non-empty sequence. The remaining code $a=0$ represents the empty sequence, since $a+1=1$ has no prime factors. Thus the shift by $-1$ turns the positive-integer representations into codes covering all of $\mathbb{N}$, giving a [[Knowledge/Bijective Relation|bijection]].
- The length function $\ell^*$ and component functions $c^{*,k}$ act on the code, not directly on the sequence:

Misplaced & \begin{aligned} \ell^*\bigl(i^*(\langle n_1,\ldots,n_m\rangle)\bigr)&=m,\\ c^{*,k}\bigl(i^*(\langle n_1,\ldots,n_m\rangle)\bigr)&=n_k \qquad(1\leq k\leq m). \end{aligned} <span class="math-indent" aria-hidden="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

  • Mu-Recursive Function
    • Extend the basic functions, composition, and primitive recursion with unbounded minimisation. Unlike primitive-recursive functions, mu-recursive functions may be partial.
    • Composition propagates undefinedness: for , if any is undefined, then is undefined—even if ignores that argument. The same holds if is undefined at the resulting tuple.
    • The mu-zero operator searches the first argument of for the least value yielding . For total ,

Misplaced & (\mu_0 g)(x)=\min\{y\in\mathbb{N}\mid g(y,x)=0\}. <span class="math-indent" aria-hidden="true">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>

	- Evaluate $g(0,x),g(1,x),g(2,x),\ldots$ in order and return the first index $y$ with $g(y,x)=0$. If no such index exists, the search never terminates and the result is undefined.
	- For partial $g$, an undefined value encountered before a zero also makes the search undefined: execution cannot skip a computation that never halts.
- Every mu-recursive function is [[Knowledge/Computable Function|computable]]: construct [[Knowledge/Unrestricted Register Machine Program|URM programs]] for the basic functions, combine them for composition and primitive recursion, and implement minimisation by a loop that tests successive candidates $y$. This construction preserves both returned values and non-termination.