Cite

This course has no released version yet: the text at this address may change. Cite a released version when one exists.

/courses/fundamentals/universal-program-smn
@misc{fundamentals-universal-program-smn,
  title = {{The universal function and the SMN theorem}},
  howpublished = {Lesson 2 of \emph{Fundamentals of computability}, Computability Theory course notes},
  url = {/courses/fundamentals/universal-program-smn},
  note = {Unreleased working version}
}

To cite a single statement, use the # link that appears next to its heading.

Lesson 2 of 6

The universal function and the SMN theorem

The universal partial computable function, the SMN theorem and its use with parameters, the padding lemma, and acceptable numberings.

40 min5 questions
Before this lesson:Programs as numbers · Diagonalization and computation (Countability and diagonalization)
Fundamentals of computability · lesson 2 of 6
  1. Programs as numbers
  2. The universal function and the SMN theorem
  3. The halting problem
  4. Computably enumerable sets
  5. Kleene's fixed point theorem
  6. Rice's theorem

Two properties of the enumeration (Φe)(\Phi_e) make it the right framework for computability theory. The first is that it is itself computable: a single algorithm evaluates Φe(x)\Phi_e(x) from ee and xx. The second is that indices can be manipulated computably: from an index of a function of two arguments and a value xx of the first argument, one can compute an index of the function of the second argument obtained by fixing xx. The first property is the universal function theorem, the second is the SMN theorem. Together they allow one to treat programs as data, which is what the rest of the course does.

2.1 The universal function

Theorem 2.1 (Universal function).#

For every k≥1k \geq 1, there is an index uu such that for all ee and x⃗=(x1,…,xk)\vec x = (x_1, \dots, x_k),

Φu(k+1)(e,x⃗)≃Φe(k)(x⃗).\Phi^{(k+1)}_u(e, \vec x) \simeq \Phi^{(k)}_e(\vec x).
Proof of Theorem 2.1.

By Universal function, the function (e,x⃗)↦U(μs Tk(e,x⃗,s))(e, \vec x) \mapsto U(\mu s\ T_k(e, \vec x, s)) is partial computable. Any of its indices is suitable.

A machine of index uu is an interpreter: it receives the code of a machine and an input, decodes the machine, and simulates it step by step. The theorem justifies definitions such as

f(x,y)≃Φx+1(y+2)org(e)≃Φe(e)+1,f(x, y) \simeq \Phi_{x+1}(y + 2) \qquad\text{or}\qquad g(e) \simeq \Phi_e(e) + 1,

which are partial computable as compositions of the universal function with computable functions. By contrast, no total computable function enumerates the total computable functions (Theorem 6.4 of “Diagonalization and computation”): the universal function is necessarily partial.

2.2 The SMN theorem

Theorem 2.2 (SMN theorem).#

For all m,n≥1m, n \geq 1, there is a primitive recursive function Snm:Nm+1→NS^m_n : \nat^{m+1} \to \nat such that for all ee, x⃗=(x1,…,xm)\vec x = (x_1, \dots, x_m) and y⃗=(y1,…,yn)\vec y = (y_1, \dots, y_n),

ΦSnm(e,x⃗)(n)(y⃗)≃Φe(m+n)(x⃗,y⃗).\Phi^{(n)}_{S^m_n(e, \vec x)}(\vec y) \simeq \Phi^{(m+n)}_e(\vec x, \vec y).

The name comes from Kleene’s notation SnmS^m_n. The function SnmS^m_n does not run the machine ee: it transforms its code into the code of another machine, which first writes x⃗\vec x on the tape in front of its input, then behaves as the machine ee. Computing this new code is a finite manipulation of a finite table.

Proof of Theorem 2.2.

We treat m=n=1m = n = 1; the general case is identical, with mm blocks to write in front of nn blocks. Recall the input convention (Definition 2.4 of “Turing machines”): the input yy is the block ⌜y⌝=1y+1\ulcorner y \urcorner = 1^{y+1} written from cell 00, and the input (x,y)(x, y) is ⌜x⌝⊔⌜y⌝\ulcorner x \urcorner \sqcup \ulcorner y \urcorner.

For x∈Nx \in \nat, let PxP_x be a machine which, started on the tape ⌜y⌝\ulcorner y \urcorner with the head on cell 00, halts with the tape ⌜x⌝⊔⌜y⌝\ulcorner x \urcorner \sqcup \ulcorner y \urcorner written from some cell hh, with the head on cell hh and in its halting state. For instance, PxP_x moves left from cell 00, writes a blank separator on cell −1-1 (already blank), then writes x+1x + 1 ones on the cells −2,−3,…,−x−2-2, -3, \dots, -x - 2, moving left after each of them, and finally moves one cell back to the right, halting on cell h=−x−2h = -x - 2. This takes x+O(1)x + O(1) states, and the transition table of PxP_x is obtained from xx by a primitive recursive function: it is a fixed table with a chain of x+1x + 1 writing states inserted.

Let MeM_e be the machine of code ee. The machine Px;MeP_x ; M_e is obtained by renaming the states of MeM_e so that they are distinct from those of PxP_x, and by identifying the halting state of PxP_x with the initial state of MeM_e. Started on ⌜y⌝\ulcorner y \urcorner, it runs PxP_x, reaching the configuration in the initial state of MeM_e with tape ⌜x⌝⊔⌜y⌝\ulcorner x \urcorner \sqcup \ulcorner y \urcorner written from cell hh and head on hh. This is the initial configuration of MeM_e on input (x,y)(x, y), translated by hh. By Lemma 3.2 of “Programming Turing machines”, the subsequent computation is the translate of the computation of MeM_e on (x,y)(x, y): it halts in a standard final configuration with output zz if and only if Φe(2)(x,y) ⁣ ⁣↓=z\Phi^{(2)}_e(x, y)\converge = z. Hence Px;MeP_x ; M_e computes y↦Φe(2)(x,y)y \mapsto \Phi^{(2)}_e(x, y).

Let S11(e,x)S^1_1(e, x) be the code of Px;MeP_x ; M_e. Renaming states and merging two tables are operations on finite sequences of integers, and with the coding of machines by sequence codes they are primitive recursive (Proposition 6.2 of “Coding finite sequences”). So S11S^1_1 is primitive recursive.

The SMN theorem is mostly used in the following form, which states that a family of partial computable functions, defined uniformly from a parameter, has indices computable from the parameter.

Corollary 2.3 (Parameter form).#

Let f:N1+n⇀Nf : \nat^{1+n} \rightharpoonup \nat be partial computable. There is a primitive recursive function s:N→Ns : \nat \to \nat such that for all xx and y⃗\vec y,

Φs(x)(n)(y⃗)≃f(x,y⃗).\Phi^{(n)}_{s(x)}(\vec y) \simeq f(x, \vec y).
Proof of Corollary 2.3.

Let ii be an index of ff, and let s(x)=Sn1(i,x)s(x) = S^1_n(i, x).

In proofs, the corollary is invoked by sentences such as: “for every xx, let s(x)s(x) be an index of the program which, on input yy, does … (something depending on xx and yy)”, it being understood that the description defines a partial computable function of (x,y)(x, y), and that ss is then total computable. We also say that s(x)s(x) is obtained uniformly in xx.

Example 2.4.#
  1. Composition of indices. There is a total computable cc with Φc(a,b)=Φa∘Φb\Phi_{c(a, b)} = \Phi_a \circ \Phi_b for all a,ba, b: apply the corollary to f(⟨a,b⟩,y)≃Φa(Φb(y))f(\langle a, b \rangle, y) \simeq \Phi_a(\Phi_b(y)), which is partial computable by the universal function, and compose with the pairing function.
  2. Constant functions. There is a total computable κ\kappa such that Φκ(x)\Phi_{\kappa(x)} is the constant function with value xx.
  3. Programs that ignore their input. There is a total computable zz such that Φz(e,x)(y)≃Φe(x)\Phi_{z(e, x)}(y) \simeq \Phi_e(x) for all yy: the program z(e,x)z(e, x) ignores its input and runs Φe\Phi_e on xx. So Φz(e,x)\Phi_{z(e, x)} is total if Φe(x) ⁣ ⁣↓\Phi_e(x)\converge, and nowhere defined otherwise. This construction is used in many reductions.

2.3 The padding lemma

Every partial computable function has infinitely many indices: adding to a machine states that are never entered does not change what it computes. The indices can moreover be found computably, and above any given bound.

Lemma 2.5 (Padding lemma).#

There is a primitive recursive function p:N2→Np : \nat^2 \to \nat such that for all ee and nn, p(e,n)≥np(e, n) \geq n and Φp(e,n)(k)=Φe(k)\Phi^{(k)}_{p(e, n)} = \Phi^{(k)}_e for every kk.

Proof of Lemma 2.5.

Let MeM_e be the machine of code ee (the fixed never-halting machine if ee is not a code). For j∈Nj \in \nat, let Me,jM_{e, j} be MeM_e with jj additional states, which are never entered and whose transitions are arbitrary, say “write a blank, move right, stay in the same state”. Its computations are those of MeM_e, so it computes the same functions. The machines Me,0,Me,1,…M_{e, 0}, M_{e, 1}, \dots have different numbers of states, so their codes c(e,j)c(e, j) are pairwise distinct, and cc is primitive recursive. Among the n+1n + 1 distinct values c(e,0),…,c(e,n)c(e, 0), \dots, c(e, n), at most nn lie below nn, so one of them is at least nn. Let p(e,n)=c(e,j)p(e, n) = c(e, j) for the least j≤nj \leq n with c(e,j)≥nc(e, j) \geq n, a bounded search.

Corollary 2.6.#

Every partial computable function has infinitely many indices. Consequently, the set of indices of a given partial computable function is never finite, and for every ee the function n↦p(e,n)n \mapsto p(e, n) enumerates infinitely many of the indices of Φe\Phi_e.

Proof of Corollary 2.6.

If f=Φef = \Phi_e, the indices p(e,n)p(e, n), for n∈Nn \in \nat, are unbounded since p(e,n)≥np(e, n) \geq n, hence infinitely many.

2.4 Acceptable numberings

The results of this course depend on the enumeration (Φe)(\Phi_e) only through a few properties. It is useful to know which ones.

Definition 2.7.#

A numbering of the unary partial computable functions is a sequence (ψe)e∈N(\psi_e)_{e \in \nat} in which every unary partial computable function appears. It is acceptable if

  1. the function (e,x)↦ψe(x)(e, x) \mapsto \psi_e(x) is partial computable, and
  2. there is a total computable tt with ψt(e)=Φe\psi_{t(e)} = \Phi_e for every ee.
Proposition 2.8.#

The numbering (Φe)(\Phi_e) is acceptable. If (ψe)(\psi_e) is acceptable, there is a total computable rr with Φr(e)=ψe\Phi_{r(e)} = \psi_e for every ee, and (ψe)(\psi_e) satisfies the SMN theorem: there is a total computable σ\sigma such that ψσ(e,x)(y)≃ψe(⟨x,y⟩)\psi_{\sigma(e, x)}(y) \simeq \psi_e(\langle x, y \rangle).

Proof of Proposition 2.8.

For (Φe)(\Phi_e), take the universal function and tt the identity. Let (ψe)(\psi_e) be acceptable. By Corollary 2.3 applied to (e,x)↦ψe(x)(e, x) \mapsto \psi_e(x), there is a total computable rr with Φr(e)(x)≃ψe(x)\Phi_{r(e)}(x) \simeq \psi_e(x). For SMN, apply Corollary 2.3 to (⟨e,x⟩,y)↦ψe(⟨x,y⟩)(\langle e, x \rangle, y) \mapsto \psi_e(\langle x, y \rangle), giving a total computable ss with Φs(⟨e,x⟩)(y)≃ψe(⟨x,y⟩)\Phi_{s(\langle e, x \rangle)}(y) \simeq \psi_e(\langle x, y \rangle), and let σ(e,x)=t(s(⟨e,x⟩))\sigma(e, x) = t(s(\langle e, x \rangle)).

Rogers proved that any two acceptable numberings differ by a computable permutation of the indices: if (ψe)(\psi_e) is acceptable, there is a computable bijection π:N→N\pi : \nat \to \nat with ψe=Φπ(e)\psi_e = \Phi_{\pi(e)}. We admit this isomorphism theorem, proved in Rogers’ paper of 1958 cited below; its proof is a computable back-and-forth argument using the padding lemma. It shows that every result of this course that is stated in terms of indices holds for every acceptable numbering. Not every numbering is acceptable: Friedberg constructed a numbering satisfying the first condition in which each partial computable function appears exactly once. Such a numbering cannot be acceptable: by the isomorphism theorem, the indices of a function in an acceptable numbering are in bijection with its indices in (Φe)(\Phi_e), which are infinitely many by Corollary 2.6.

2.5 Exercises

Exercise 2.9 ★.

Show that there is a total computable function gg such that Φg(e)(x)≃2⋅Φe(x)\Phi_{g(e)}(x) \simeq 2 \cdot \Phi_e(x) for all ee and xx, and that gg can be chosen injective.

Solution

Apply Corollary 2.3 to f(e,x)≃2⋅Φe(x)f(e, x) \simeq 2 \cdot \Phi_e(x), to get ss with Φs(e)=2⋅Φe\Phi_{s(e)} = 2 \cdot \Phi_e. To make it injective, let g(0)=s(0)g(0) = s(0) and g(e+1)=p(s(e+1),g(e)+1)g(e+1) = p(s(e+1), g(e) + 1), where pp is the padding function. Then g(e+1)≥g(e)+1g(e+1) \geq g(e) + 1, so gg is strictly increasing, hence injective, and Φg(e)=Φs(e)\Phi_{g(e)} = \Phi_{s(e)}.

Exercise 2.10 ★★.

Show that there is no total computable function ff such that, for every ee, Φf(e)\Phi_{f(e)} is total, and Φf(e)=Φe\Phi_{f(e)} = \Phi_e whenever Φe\Phi_e is total.

Solution

Suppose ff exists. Then Φf(0),Φf(1),…\Phi_{f(0)}, \Phi_{f(1)}, \dots is a sequence of total functions, uniformly computable since (e,x)↦Φf(e)(x)(e, x) \mapsto \Phi_{f(e)}(x) is partial computable and total. It contains every total computable function Φe\Phi_e, as Φf(e)\Phi_{f(e)}. This contradicts Theorem 6.4 of “Diagonalization and computation”.

2.6 Notes and references

The universal function is Turing’s universal machine (1936), and the SMN theorem is due to Kleene (1938). Acceptable numberings and the isomorphism theorem are due to Rogers (1958); Friedberg’s numbering without repetitions appeared the same year.

  • A. M. Turing, On computable numbers, with an application to the Entscheidungsproblem, Proceedings of the London Mathematical Society (2) 42 (1936), 230–265.
  • S. C. Kleene, On notation for ordinal numbers, Journal of Symbolic Logic 3 (1938), 150–155.
  • H. Rogers, Gödel numberings of partial recursive functions, Journal of Symbolic Logic 23 (1958), 331–341.
  • R. M. Friedberg, Three theorems on recursive enumeration, Journal of Symbolic Logic 23 (1958), 309–316.