Reading preferences
Optional display controls need JavaScript. All reading content and navigation work without it.
Source file content/computability/recursive-functions/recursive-functions.tex
Editorial
These are Jeremy Avigad's notes on recursive functions, revised and expanded by Richard Zach. This chapter does contain some exercises, and can be included independently to provide the basis for a discussion of arithmetization of syntax.
Source file content/computability/recursive-functions/introduction.tex
Introduction
In order to develop a mathematical theory of computability, one has to, first of all, develop a model of computability. We now think of computability as the kind of thing that computers do, and computers work with symbols. But at the beginning of the development of theories of computability, the paradigmatic example of computation was numerical computation. Mathematicians were always interested in number-theoretic functions, i.e., functions source that can be computed. So it is not surprising that at the beginning of the theory of computability, it was such functions that were studied. The most familiar examples of computable numerical functions, such as addition, multiplication, exponentiation (of natural numbers) share an interesting feature: they can be defined recursively. It is thus quite natural to attempt a general definition of computable function on the basis of recursive definitions. Among the many possible ways to define number-theoretic functions recursively, one particularly simple pattern of definition here becomes central: so-called primitive recursion.
In addition to computable functions, we might be interested in computable sets and relations. A set is computable if we can compute the answer to whether or not a given number is an element of the set, and a relation is computable iff we can compute whether or not a tuple source is an element of the relation. By considering the characteristic function of a set or relation, discussion of computable sets and relations can be subsumed under that of computable functions. Thus we can define primitive recursive relations as well, e.g., the relation “source evenly divides source” is a primitive recursive relation.
Primitive recursive functions---those that can be defined using just primitive recursion---are not, however, the only computable number-theoretic functions. Many generalizations of primitive recursion have been considered, but the most powerful and widely-accepted additional way of computing functions is by unbounded search. This leads to the definition of partial recursive functions, and a related definition to general recursive functions. General recursive functions are computable and total, and the definition characterizes exactly the partial recursive functions that happen to be total. Recursive functions can simulate every other model of computation (Turing machines, lambda calculus, etc.) and so represent one of the many accepted models of computation.
Source file content/computability/recursive-functions/primitive-recursion.tex
Primitive Recursion
A characteristic of the natural numbers is that every natural number can be reached from source by applying the successor operation source finitely many times---any natural number is either source or the successor of dots the successor of source. One way to specify a function source that makes use of this fact is this: (a) specify what the value of source is for argument source, and (b) also specify how to, given the value of source, compute the value of source. For (a) tells us directly what source is, so source is defined for source. Now, using the instruction given by (b) for source, we can compute source from source. Using the same instructions for source, we compute source from source, and so on. For every natural number source, we'll eventually reach the step where we define source from source, and so source is defined for all source.
For instance, suppose we specify source by the following two equations:
If we already know how to multiply, then these equations give us the information required for (a) and (b) above. By successively applying the second equation, we get that
We see that the function source we have specified is source.
The characteristic feature of the natural numbers guarantees that there is only one function source that meets these two criteria. A pair of equations like these is called a definition by primitive recursion of the function source. It is so-called because we define source “recursively,” i.e., the definition, specifically the second equation, involves source itself on the right-hand-side. It is “primitive” because in defining source we only use the value source, i.e., the immediately preceding value. This is the simplest way of defining a function on source recursively.
We can define even more fundamental functions like addition and multiplication by primitive recursion. In these cases, however, the functions in question are source-place. We fix one of the argument places, and use the other for the recursion. E.g, to define source we can fix source and define the value first for source and then for source in terms of source. Since source is fixed, it will appear on the left and on the right side of the defining equations.
These equations specify the value of source for all source and source. To find source, for instance, we apply the defining equations for source, using the first to find source, then using the second to successively find source, source, source.
In the definition of source we used source on the right-hand-side of the second equation, but only to add source. In other words, we used the successor function source and applied it to the previous value source to define source. So we can think of the recursive definition as given in terms of a single function which we apply to the previous value. However, it doesn't hurt---and sometimes is necessary---to allow the function to depend not just on the previous value but also on source and source. Consider:
This is a primitive recursive definition of a function source by applying the function source to both the preceding value source and the first argument source. It also defines the function source for all arguments source and source. For instance, source is determined by successively computing source, source, source, and source:
The general pattern then is this: to give a primitive recursive definition of a function source, we provide two equations. The first defines the value of source without reference to source. The second defines the value of source in terms of source, the other arguments source, dots, source, and source. Only the immediately preceding value of source may be used in that second equation. If we think of the operations given by the right-hand-sides of these two equations as themselves being functions source and source, then the general pattern to define a new function source by primitive recursion is this:
In the case of source, we have source and source (the identity function), and source (the source-place function that returns the successor of its third argument):
In the case of source, we have source (the constant function always returning source) and source (the source-place function that returns the sum of its last and first argument):
Source file content/computability/recursive-functions/composition.tex
Composition
If source and source are two one-place functions of natural numbers, we can compose them: source. The new function source is then defined by composition from the functions source and source. We'd like to generalize this to functions of more than one argument.
Here's one way of doing this: suppose source is a source-place function, and source, dots, source are source functions which are all source-place. Then we can define a new source-place function source as follows:
If source and all source are computable, so is source: To compute source, first compute the values source for each source, dots, source. Then feed these values into source to compute source.
This may seem like an overly restrictive characterization of what happens when we compute a new function using some existing ones. For one thing, sometimes we do not use all the arguments of a function, as when we defined source for use in the primitive recursive definition of source. Suppose we are allowed use of the following functions:
The functions source are called projection functions: source is an source-place function. Then source can be defined by
Here the role of source is played by the source-place function source, so source. And we have one source-place function source which plays the role of source. The result is a source-place function that returns the successor of the third argument.
The projection functions also allow us to define new functions by reordering or identifying arguments. For instance, the function source can be defined by
Here source, source, the role of source is played by source, and the roles of source and source are both played by source, the one-place projection function (aka the identity function).
If source is a function we already have, we can define the function source by
Here source, source, and the roles of source and source are played by source and source, respectively.
You may also worry that source, dots, source are all required to have the same arity source. (Remember that the arity of a function is the number of arguments; an source-place function has arity source.) But adding the projection functions provides the desired flexibility. For example, suppose source and source are source-place functions and source is the source-place function defined by
The definition of source can be rewritten with the projection functions, as
Then source is the composition of source with source, source, and source, where
i.e., source is the composition of source with source, source, and source.
Source file content/computability/recursive-functions/pr-functions.tex
Primitive Recursion Functions
Let us record again how we can define new functions from existing ones using primitive recursion and composition.
Definition of primitive recursion
Suppose source is a source-place function (source) and source is a source-place function. The function defined by primitive recursion from source and source is the source-place function source defined by the equations
Definition of composition
Suppose source is a source-place function, and source, dots, source are source functions which are all source-place. The function defined by composition from source and source, dots, source is the source-place function source defined by
In addition to source and the projection functions
for each natural number source and source, we will include among the primitive recursive functions the function source.
Definition of primitive recursive functions
The set of primitive recursive functions is the set of functions from source to source, defined inductively by the following clauses:
source is primitive recursive.
source is primitive recursive.
Each projection function source is primitive recursive.
If source is a source-place primitive recursive function and source, dots, source are source-place primitive recursive functions, then the composition of source with source, dots, source is primitive recursive.
If source is a source-place primitive recursive function and source is a source-place primitive recursive function, then the function defined by primitive recursion from source and source is primitive recursive.
Explain
Put more concisely, the set of primitive recursive functions is the smallest set containing source, source, and the projection functions source, and which is closed under composition and primitive recursion.
Another way of describing the set of primitive recursive functions is by defining it in terms of “stages.” Let source denote the set of starting functions: source, source, and the projections. These are the primitive recursive functions of stage source. Once a stage source has been defined, let source be the set of all functions you get by applying a single instance of composition or primitive recursion to functions already in source. Then
is the set of all primitive recursive functions
Let us verify that source is a primitive recursive function.
Addition is primitive recursive proposition
The addition function source is primitive recursive.
Proof
We already have a primitive recursive definition of source in terms of two functions source and source which matches the format of Addition construction reference to primitive recursion:
So source is primitive recursive provided source and source are as well. source, and the projection functions count as primitive recursive, so source is primitive recursive. The function source is the three-place function source defined by
This does not yet tell us that source is primitive recursive, since source and source are not quite the same function: source is one-place, and source has to be three-place. But we can define source “officially” by composition as
Since source and source count as primitive recursive functions, source does as well, since it can be defined by composition from primitive recursive functions.
Multiplication is primitive recursive proposition
The multiplication function source is primitive recursive.
Proof
Exercise.
Multiplication proof exercise
Prove Multiplication exercise reference to multiplication proposition by showing that the primitive recursive definition of source can be put into the form required by Multiplication exercise reference to primitive recursion and showing that the corresponding functions source and source are primitive recursive.
First primitive recursion example
Here's our very first example of a primitive recursive definition:
This function cannot fit into the form required by First example obstacle reference to primitive recursion, since source. The definition also involves the constants source and source. To get around the first problem, let's introduce a dummy argument and define the function source:
The function source can be defined from source and source by composition: source. The function source can be defined by composition from source and projections:
where source is as above: source. Now that we have source, we can use composition again to let source. This shows that source can be defined from the basic functions using a sequence of compositions and primitive recursions, so source is primitive recursive.
Source file content/computability/recursive-functions/notation-pr-functions.tex
Primitive Recursion Notations
One advantage to having the precise inductive description of the primitive recursive functions is that we can be systematic in describing them. For example, we can assign a “notation” to each such function, as follows. Use symbols source, source, and source for zero, successor, and the projections. Now suppose source is defined by composition from a source-place function source and source-place functions source, dots, source, and we have assigned notations source, source, dots, source to the latter functions. Then, using a new symbol source, we can denote the function source by source.
For functions defined by primitive recursion, we can use analogous notations. Suppose the source-ary function source is defined by primitive recursion from the source-ary function source and the source-ary function source, and the notations assigned to source and source are source and source, respectively. Then the notation assigned to source is source.
Recall that the addition function is defined by primitive recursion as
Here the role of source is played by source, and the role of source is played by source, which is assigned the notation source as it is the result of defining a function by composition from the source-ary function source and the source-ary function source. With this setup, we can denote the addition function by
Having these notations sometimes proves useful, e.g., when enumerating primitive recursive functions.
Multiplication notation exercise
Give the complete primitive recursive notation for source.
Source file content/computability/recursive-functions/pr-functions-computable.tex
Primitive Recursive Functions are Computable
Suppose a function source is defined by primitive recursion
and suppose the functions source and source are computable. (We use source to abbreviate source, dots, source.) Then source can obviously be computed, since it is just source which we assume is computable. source can then also be computed, since source and so source is just
Thus, to compute source in general, successively compute source, source, dots, until we reach source.
Thus, a primitive recursive definition yields a new computable function if the functions source and source are computable. Composition of functions also results in a computable function if the functions source and source are computable.
Since the basic functions source, source, and source are computable, and composition and primitive recursion yield computable functions from computable functions, this means that every primitive recursive function is computable.
Source file content/computability/recursive-functions/examples.tex
Examples of Primitive Recursive Functions
We already have some examples of primitive recursive functions: the addition and multiplication functions source and source. The identity function source is primitive recursive, since it is just source. The constant functions source are primitive recursive since they can be defined from source and source by successive composition. This is useful when we want to use constants in primitive recursive definitions, e.g., if we want to define the function source can obtain it by composition from source and multiplication as source. We'll make use of this trick from now on.
Exponentiation is primitive recursive proposition
The exponentiation function source is primitive recursive.
Proof
We can define source primitive recursively as
and so source and source are defined from primitive recursive functions by composition.
Predecessor is primitive recursive proposition
The predecessor function source defined by
is primitive recursive.
Proof
Note that
This is almost a primitive recursive definition. It does not, strictly speaking, fit into the pattern of definition by primitive recursion, since that pattern requires at least one extra argument source. It is also odd in that it does not actually use source in the definition of source. But we can first define source by
and then define source from it by composition, e.g., as source.
Factorial is primitive recursive proposition
The factorial function source is primitive recursive.
Proof
The obvious primitive recursive definition is
From now on we'll be a bit more laissez-faire and not give the official definitions by composition and primitive recursion.
Truncated subtraction is primitive recursive proposition
Truncated subtraction, source, defined by
is primitive recursive.
Proof
We have:
Distance is primitive recursive proposition
The distance between source and source, source, is primitive recursive.
Proof
We have source, so the distance can be defined by composition from source and source, which are primitive recursive.
Maximum is primitive recursive proposition
The maximum of source and source, source, is primitive recursive.
Proof
We can define source by composition from source and source by
If source is the maximum, i.e., source, then source, so source. If source is the maximum, then source, and so source.
Minimum is primitive recursive proposition
The minimum of source and source, source, is primitive recursive.
Proof
Exercise.
Minimum proof exercise
Exponent tower exercise
Show that
is primitive recursive.
Integer division construction exercise
Show that integer division source (i.e., division, where you disregard everything after the decimal point) is primitive recursive. When source, we stipulate source. Give an explicit definition of source using primitive recursion and composition.
Finite sums and products closure proposition
The set of primitive recursive functions is closed under the following two operations:
Proof
For example, finite sums are defined recursively by the equations
Source file content/computability/recursive-functions/pr-relations.tex
Primitive Recursive Relations
Definition of primitive recursive relations
A relation source is said to be primitive recursive if its characteristic function,
is primitive recursive.
In other words, when one speaks of a primitive recursive relation source, one is referring to a relation of the form source, where source is a primitive recursive function which, on any input, returns either 1 or 0. For example, the relation source, which holds if and only if source, corresponds to the function source, defined using primitive recursion by
It should be clear that one can compose relations with other primitive recursive functions. So the following are also primitive recursive:
Boolean closure proposition for relations
The set of primitive recursive relations is closed under Boolean operations, that is, if source and source are primitive recursive, so are
Proof
Suppose source and source are primitive recursive, i.e., their characteristic functions source and source are. We have to show that the characteristic functions of source, etc., are also primitive recursive.
Bounded quantification closure proposition
The set of primitive recursive relations is closed under bounded quantification, i.e., if source is a primitive recursive relation, then so are the relations
source holds of source and source if and only if source holds for every source less than source, and similarly for source.
Proof
By convention, we take source to be true (for the trivial reason that there are no source less than source) and source to be false. A bounded universal quantifier functions just like a finite product or iterated minimum, i.e., if source then source can be defined by
Bounded existential quantification can similarly be defined using source. Alternatively, it can be defined from bounded universal quantification, using the equivalence source. Note that, for example, a bounded quantifier of the form source is equivalent to source.
Congruence relation exercise
Show that the three place relation source (congruence modulo source) is primitive recursive.
Another useful primitive recursive function is the conditional function, source, defined by
One can use this to justify definitions of primitive recursive functions by cases from primitive recursive relations:
Piecewise primitive recursion proposition
If source, dots, source are primitive recursive functions, and source, dots, source are primitive recursive relations, then the function source defined by
is also primitive recursive.
Proof
When source, this is just the function defined by
For source greater than source, one can just compose definitions of this form.
Source file content/computability/recursive-functions/bounded-minimization.tex
Bounded Minimization
Explain
It is often useful to define a function as the least number satisfying some property or relation source. If source is decidable, we can compute this function simply by trying out all the possible numbers, source, source, source, dots, until we find the least one satisfying source. This kind of unbounded search takes us out of the realm of primitive recursive functions. However, if we're only interested in the least number less than some independently given bound, we stay primitive recursive. In other words, and a bit more generally, suppose we have a primitive recursive relation source. Consider the function that maps source and source to the least source such that source. It, too, can be computed, by testing whether source, source, dots, source. But why is it primitive recursive?
Bounded minimization proposition
If source is primitive recursive, so is the function source which returns the least source less than source such that source holds, if there is one, and source otherwise. We will write the function source as
Proof
Note than there can be no source such that source since there is no source at all. So source.
In case the bound is of the form source we have three cases:
So we can define source by primitive recursion as follows:
Alternative bounded search exercise
Suppose source is primitive recursive. Define the function source which returns the least source less than source such that source holds, if there is one, and source otherwise, by primitive recursion from source.
Source file content/computability/recursive-functions/primes.tex
Primes
Bounded quantification and bounded minimization provide us with a good deal of machinery to show that natural functions and relations are primitive recursive. For example, consider the relation “source divides source”, written source. The relation source holds if division of source by source is possible without remainder, i.e., if source is an integer multiple of source. (If it doesn't hold, i.e., the remainder when dividing source by source is source, we write source.) In other words, source iff for some source, source. Obviously, any such source, if it exists, must be source. So, we have that source iff for some source, source. We can define the relation source by bounded existential quantification from source and multiplication by
We've thus shown that source is primitive recursive.
A natural number source is prime if it is neither source nor source and is only divisible by source and itself. In other words, prime numbers are such that, whenever source, either source or source. To test if source is prime, we only have to check if source for all source, since if source, then automatically source. So, the relation source, which holds iff source is prime, can be defined by
and is thus primitive recursive.
The primes are source, source, source, source, source, etc. Consider the function source which returns the sourceth prime in that sequence, i.e., source, source, source, etc. (For convenience we will often write source as source (source, source, etc.)
If we had a function source, which returns the first prime number larger than source, source can be easily defined using primitive recursion:
Since source is the least source such that source and source is prime, it can be easily computed by unbounded search. But it can also be defined by bounded minimization, thanks to a result due to Euclid: there is always a prime number between source and source.
This shows, that source and hence source are (not just computable but) primitive recursive.
(If you're curious, here's a quick proof of Euclid's theorem. Suppose source is the largest prime source and consider the product source of all primes source. Either source is prime or there is a prime between source and source. Why? Suppose source is not prime. Then some prime number source where source. None of the primes source divide source. (By definition of source, each of the primes source divides source, i.e., with remainder source. So, each of the primes source divides source with remainder source, and so source.) Hence, source is a prime source and source. And source, so there is a prime source and source.)
Bounded minimization division exercise
Define integer division source using bounded minimization.
Source file content/computability/recursive-functions/sequences.tex
Sequences
The set of primitive recursive functions is remarkably robust. But we will be able to do even more once we have developed a adequate means of handling sequences. We will identify finite sequences of natural numbers with natural numbers in the following way: the sequence source corresponds to the number
We add one to the exponents to guarantee that, for example, the sequences source and source have distinct numeric codes. We can take both source and source to code the empty sequence; for concreteness, let source denote source.
The reason that this coding of sequences works is the so-called Fundamental Theorem of Arithmetic: every natural number source can be written in one and only one way in the form
with source. This guarantees that the mapping source is injective: different sequences are mapped to different numbers; to each number only at most one sequence corresponds.
We'll now show that the operations of determining the length of a sequence, determining its sourceth element, appending an element to a sequence, and concatenating two sequences, are all primitive recursive.
Sequence length proposition
The function source, which returns the length of the sequence source, is primitive recursive.
Proof
Let source be the relation defined by
source is clearly primitive recursive. Whenever source is the code of a non-empty sequence, i.e.,
source holds if source is the largest prime such that source, i.e., source. The length of source thus is source iff source is the largest prime that divides source, so we can let
We can use bounded minimization here, since there is only one source that satisfies source when source is a code of a sequence, and if source exists it is less than source itself.
Sequence append proposition
The function source, which returns the result of appending source to the sequence source, is primitive recursive.
Proof
source can be defined by:
Sequence element proposition
The function source, which returns the sourceth element of source (where the initial element is called the sourceth), or source if source is greater than or equal to the length of source, is primitive recursive.
Proof
Note that source is the sourceth element of source iff source is the largest power of source that divides source, i.e., source but source. So:
Instead of using the official names for the functions defined above, we introduce a more compact notation. We will use source instead of source, and source to abbreviate
Note that if source has length source, the elements of source are source, dots, source.
Sequence concatenation proposition
The function source, which concatenates two sequences, is primitive recursive.
Proof
We want a function source with the property that
We'll use a “helper” function source which concatenates the first source symbols of source to source. This function can be defined by primitive recursion as follows:
We will write source instead of source.
It will be useful for us to be able to bound the numeric code of a sequence in terms of its length and its largest element. Suppose source is a sequence of length source, each element of which is less than or equal to some number source. Then source has at most source prime factors, each at most source, and each raised to at most source in the prime factorization of source. In other words, if we define
then the numeric code of the sequence source described above is at most source.
Having such a bound on sequences gives us a way of defining new functions using bounded search. For example, we can define source using bounded search. All we need to do is write down a primitive recursive specification of the object (number of the concatenated sequence) we are looking for, and a bound on how far to look. The following works:
Sequence list concatenation exercise
Show that there is a primitive recursive function source with the property that
Sequence tail exercise
Show that there is a primitive recursive function source with the property that
Subsequence is primitive recursive proposition
The function source which returns the subsequence of source of length source beginning at the sourceth element, is primitive recursive.
Proof
Exercise.
Subsequence proof exercise
Prove Subsequence exercise reference to subsequence proposition.
Source file content/computability/recursive-functions/trees.tex
Trees
Sometimes it is useful to represent trees as natural numbers, just like we can represent sequences by numbers and properties of and operations on them by primitive recursive relations and functions on their codes. We'll use sequences and their codes to do this. A tree can be either a single node (possibly with a label) or else a node (possibly with a label) connected to a number of subtrees. The node is called the root of the tree, and the subtrees it is connected to its immediate subtrees.
We code trees recursively as a sequence source, where source is the number of immediate subtrees and source, dots, source the codes of the immediate subtrees. If the nodes have labels, they can be included after the immediate subtrees. So a tree consisting just of a single node with label source would be coded by source, and a tree consisting of a root (labelled source) connected to two single nodes (labelled source, source) would be coded by source.
Subtree sequence is primitive recursive proposition
The function source, which returns the code of a sequence the elements of which are the codes of all subtrees of the tree with code source, is primitive recursive.
Proof
First note that source is primitive recursive and returns the codes of the immediate subtrees of a tree source. Now we can define a helper function source which computes the sequence of all subtrees which are source nodes removed from the root. The sequence of subtrees of source which is source nodes removed from the root---in other words, begins at the root of source---is the sequence consisting just of source. To obtain a sequence of all level source subtrees of source, we concatenate the level source subtrees with a sequence consisting of all immediate subtrees of the level source subtrees. To get a list of all these, note that if source is a primitive recursive function returning codes of sequences, then source is also primitive recursive:
For instance, if source is a sequence of trees, then source gives the sequence of the immediate subtrees of the elements of source. We can use it to define source by
The maximum level of subtrees in a tree coded by source, i.e., the maximum distance between the root and a leaf node, is bounded by the code source. So a sequence of codes of all subtrees of the tree coded by source is given by source.
Duplicate free subtree exercise
The definition of source in the proof of Duplicate free subtree exercise reference in general includes repetitions. Give an alternative definition which guarantees that the code of a subtree occurs only once in the resulting list.
Source file content/computability/recursive-functions/other-recursions.tex
Other Recursions
Using pairing and sequencing, we can justify more exotic (and useful) forms of primitive recursion. For example, it is often useful to define two functions simultaneously, such as in the following definition:
This is an instance of simultaneous recursion. Another useful way of defining functions is to give the value of source in terms of all the values source, dots, source, as in the following definition:
The following schema captures this idea more succinctly:
with the understanding that the last argument to source is just the empty sequence when source is source. In either formulation, the idea is that in computing the “successor step,” the function source can make use of the entire sequence of values computed so far. This is known as a course-of-values recursion. For a particular example, it can be used to justify the following type of definition:
In other words, the value of source at source can be computed in terms of the value of source at any previous value, given by source.
Remainder by course of values exercise
Define the remainder function source by course-of-values recursion. (If source, source are natural numbers and source, source is the number less than source such that source for some source. For definiteness, let's say that if source, source.)
You should think about how to obtain these functions using ordinary primitive recursion. One final version of primitive recursion is more flexible in that one is allowed to change the parameters (side values) along the way:
This, too, can be simulated with ordinary primitive recursion. (Doing so is tricky. For a hint, try unwinding the computation by hand.)
Source file content/computability/recursive-functions/non-pr-functions.tex
Non-Primitive Recursive Functions
The primitive recursive functions do not exhaust the intuitively computable functions. It should be intuitively clear that we can make a list of all the unary primitive recursive functions, source, source, source, dots such that we can effectively compute the value of source on input source; in other words, the function source, defined by
is computable. But then so is the function
For each primitive recursive function source, the value of source and source differ at source. So source is computable, but not primitive recursive; and one can say the same about source. This is an “effective” version of Cantor's diagonalization argument.
One can provide more explicit examples of computable functions that are not primitive recursive. For example, let the notation source denote source, with source source's in all; and define a sequence source of functions by
You can confirm that each function source is primitive recursive. Each successive function grows much faster than the one before; source is equal to source, source is equal to source, and source grows roughly like an exponential stack of source source's. The Ackermann--P\'eter function is essentially the function source, and one can show that this grows faster than any primitive recursive function.
Let us return to the issue of enumerating the primitive recursive functions. Remember that we have assigned symbolic notations to each primitive recursive function; so it suffices to enumerate notations. We can assign a natural number source to each notation source, recursively, as follows:
Here we are using the fact that every sequence of numbers can be viewed as a natural number, using the codes from the last section. The upshot is that every code is assigned a natural number. Of course, some sequences (and hence some numbers) do not correspond to notations; but we can let source be the unary primitive recursive function with notation coded as source, if source codes such a notation; and the constant source function otherwise. The net result is that we have an explicit way of enumerating the unary primitive recursive functions.
(In fact, some functions, like the constant zero function, will appear more than once on the list. This is not just an artifact of our coding, but also a result of the fact that the constant zero function has more than one notation. We will later see that one can not computably avoid these repetitions; for example, there is no computable function that decides whether or not a given notation represents the constant zero function.)
We can now take the function source to be given by source, where source refers to the enumeration we have just described. How do we know that source is computable? Intuitively, this is clear: to compute source, first “unpack” source, and see if it is a notation for a unary function. If it is, compute the value of that function on input source.
Digress
You may already be convinced that (with some work!) one can write a program (say, in Java or C++) that does this; and now we can appeal to the Church--Turing thesis, which says that anything that, intuitively, is computable can be computed by a Turing machine.
Of course, a more direct way to show that source is computable is to describe a Turing machine that computes it, explicitly. This would, in particular, avoid the Church--Turing thesis and appeals to intuition. Soon we will have built up enough machinery to show that source is computable, appealing to a model of computation that can be simulated on a Turing machine: namely, the recursive functions.
Source file content/computability/recursive-functions/partial-functions.tex
Partial Recursive Functions
To motivate the definition of the recursive functions, note that our proof that there are computable functions that are not primitive recursive actually establishes much more. The argument was simple: all we used was the fact that it is possible to enumerate functions source such that, as a function of source and source, source is computable. So the argument applies to any class of functions that can be enumerated in such a way. This puts us in a bind: we would like to describe the computable functions explicitly; but any explicit description of a collection of computable functions cannot be exhaustive!
The way out is to allow partial functions to come into play. We will see that it is possible to enumerate the partial computable functions. In fact, we already pretty much know that this is the case, since it is possible to enumerate Turing machines in a systematic way. We will come back to our diagonal argument later, and explore why it does not go through when partial functions are included.
The question is now this: what do we need to add to the primitive recursive functions to obtain all the partial recursive functions? We need to do two things:
Modify our definition of the primitive recursive functions to allow for partial functions as well.
Add something to the definition, so that some new partial functions are included.
The first is easy. As before, we will start with zero, successor, and projections, and close under composition and primitive recursion. The only difference is that we have to modify the definitions of composition and primitive recursion to allow for the possibility that some of the terms in the definition are not defined. If source and source are partial functions, we will write source to mean that source is defined at source, i.e., source is in the domain of source; and source to mean the opposite, i.e., that source is not defined at source. We will use source to mean that either source and source are both undefined, or they are both defined and equal. We will use these notations for more complicated terms as well. We will adopt the convention that if source and source, dots, source all are partial functions, then
is defined if and only if each source is defined at source, and source is defined at source, dots, source. With this understanding, the definitions of composition and primitive recursion for partial functions is just as above, except that we have to replace “source” by “source”.
What we will add to the definition of the primitive recursive functions to obtain partial functions is the unbounded search operator. If source is any partial function on the natural numbers, define source to be
with the understanding that source is undefined otherwise. This defines source uniquely.
Explain
Note that our definition makes no reference to Turing machines, or algorithms, or any specific computational model. But like composition and primitive recursion, there is an operational, computational intuition behind unbounded search. When it comes to the computability of a partial function, arguments where the function is undefined correspond to inputs for which the computation does not halt. The procedure for computing source will amount to this: compute source until a value of 0 is returned. If any of the intermediate computations do not halt, however, neither does the computation of source.
If source is any relation, source is defined to be source. In other words, source returns the least value of source such that source holds. So, if source is a total function, source is the same as source. But note that our original definition is more general, since it allows for the possibility that source is not everywhere defined (whereas, in contrast, the characteristic function of a relation is always total).
Definition of partial recursive functions
The set of partial recursive functions is the smallest set of partial functions from the natural numbers to the natural numbers (of various arities) containing zero, successor, and projections, and closed under composition, primitive recursion, and unbounded search.
Of course, some of the partial recursive functions will happen to be total, i.e., defined for every argument.
Definition of recursive functions
The set of recursive functions is the set of partial recursive functions that are total.
A recursive function is sometimes called “total recursive” to emphasize that it is defined everywhere.
Source file content/computability/recursive-functions/normal-form.tex
The Normal Form Theorem
Kleene normal form theorem
[Kleene's Normal Form Theorem] There is a primitive recursive relation source and a primitive recursive function source, with the following property: if source is any partial recursive function, then for some source,
for every source.
Explain
The proof of the normal form theorem is involved, but the basic idea is simple. Every partial recursive function has an index source, intuitively, a number coding its program or definition. If source, the computation can be recorded systematically and coded by some number source, and the fact that source codes the computation of source on input source can be checked primitive recursively using only source and the definition source. Consequently, the relation source, “the function with index source has a computation for input source, and source codes this computation,” is primitive recursive. Given the full record of the computation source, the “upshot” of source is the value of source, and it can be obtained from source primitive recursively as well.
The normal form theorem shows that only a single unbounded search is required for the definition of any partial recursive function. Basically, we can search through all numbers until we find one that codes a computation of the function with index source for input source. We can use the numbers source as “names” of partial recursive functions, and write source for the function source defined by the equation in the theorem. Note that any partial recursive function can have more than one index---in fact, every partial recursive function has infinitely many indices.
Source file content/computability/recursive-functions/halting-problem.tex
The Halting Problem
The halting problem in general is the problem of deciding, given the specification source (e.g., program) of a computable function and a number source, whether the computation of the function on input source halts, i.e., produces a result. Famously, Alan Turing proved that this problem itself cannot be solved by a computable function, i.e., the function
is not computable.
In the context of partial recursive functions, the role of the specification of a program may be played by the index source given in Kleene's normal form theorem. If source is a partial recursive function, any source for which the equation in the normal form theorem holds, is an index of source. Given a number source, the normal form theorem states that
is partial recursive, and for every partial recursive source, there is an source such that source for all source. In fact, for each such source there is not just one, but infinitely many such source. The halting function source is defined by
Note that source if source, but also when source is not the index of a partial recursive function at all.
Halting function nonrecursiveness theorem
The halting function source is not partial recursive.
Proof
If source were partial recursive, we could define
Since no number source satisfies source, there is no source, and so source iff source. From this definition it follows that
If source were partial recursive, then source would be partial recursive as well. Thus, by the Kleene normal form theorem, it has an index source. Consider the value of source. There are two possible cases, source and source.
If source then source. But source, and source is defined iff source. So source.
If source then either source is not the index of a partial recursive function, or it is and source. But again, source, and source is undefined iff source.
The upshot is that source cannot, after all, be the index of a partial recursive function. But if source were partial recursive, source would be too, and so our definition of source as an index of it would be admissible. We must conclude that source cannot be partial recursive.
Source file content/computability/recursive-functions/general-recursive-functions.tex
General Recursive Functions
There is another way to obtain a set of total functions. Say a total function source is regular if for every sequence of natural numbers source, there is an source such that source. In other words, the regular functions are exactly those functions to which one can apply unbounded search, and end up with a total function. One can, conservatively, restrict unbounded search to regular functions:
Definition of general recursive functions
The set of general recursive functions is the smallest set of functions from the natural numbers to the natural numbers (of various arities) containing zero, successor, and projections, and closed under composition, primitive recursion, and unbounded search applied to regular functions.
Clearly every general recursive function is total. The difference between Initial comparison reference to general recursion definition and Initial comparison reference to recursive function definition is that in the latter one is allowed to use partial recursive functions along the way; the only requirement is that the function you end up with at the end is total. So the word “general,” a historic relic, is a misnomer; on the surface, Misnomer comparison reference to general recursion definition is less general than Equivalence comparison reference to recursive function definition. But, fortunately, the difference is illusory; though the definitions are different, the set of general recursive functions and the set of recursive functions are one and the same.
Source disclosures
- TR030-SOURCE-001: The frozen source reverses the dependency in its concluding sentence. The reader restores the direction used in the preceding examples; the source remains available unchanged. source
- TR030-SOURCE-002: The frozen source changes h's n input variables to k input variables in the final computation sentence. The reader restores n on h's argument list. source
- TR030-SOURCE-003: The frozen source switches from n to k when naming the just-defined projection family. The reader consistently uses n. source
- TR030-SOURCE-009: The reader corrects the adjective in the section title; the frozen title is retained in source replay. source
- TR030-SOURCE-010: The reader supplies the missing subject and names the constant-two function used by the displayed composition. source
- TR030-SOURCE-017: The reader names the displayed non-strict relation accurately; its formula and characteristic function are unchanged. source
- TR030-SOURCE-011: The reader changes 'than' to 'that'; the mathematics and source formulas are unchanged. source
- TR030-SOURCE-004: The frozen source changes the fixed parameter vector from x to z in the third case. The reader restores vector x. source
- TR030-SOURCE-005: The frozen parenthetical reverses divisor and dividend. The reader follows the surrounding definition: divide y by x. source
- TR030-SOURCE-012: The reader restores the missing closing parenthesis in this prose sentence. source
- TR030-SOURCE-013: The reader separates the function name from its argument so MathML and speech expose application structure. source
- TR030-SOURCE-014: The reader corrects the indefinite article. source
- TR030-SOURCE-006: The frozen concatenation display has a misplaced empty minimization argument and does not handle two empty inputs. The reader supplies an explicit empty case and gives bounded minimization the intended three-part predicate; the original display remains available. source
- TR030-SOURCE-015: The reader supplies the missing verb in the definition of immediate subtrees. source
- TR030-SOURCE-007: The frozen helper counts through index k but is called with the sequence length. The reader uses a length-counting recursion that visits exactly the valid entries. source
- TR030-SOURCE-016: The reader restores the direction described by the preceding coding equations; some numbers still do not code notations. source
- TR030-SOURCE-008: The frozen proof mixes two indexing conventions. The reader follows the convention stated immediately above the halting function, under which every natural e determines a partial recursive function. The diagonal contradiction for the known index e sub d is unchanged. source