In computability theory, course-of-values recursion is a technique for defining number-theoretic functions by recursion. In a definition of a function f by course-of-values recursion, the value of f(n) is computed from the sequence
\langlef(0),f(1),\ldots,f(n-1)\rangle
The fact that such definitions can be converted into definitions using a simpler form of recursion is often used to prove that functions defined by course-of-values recursion are primitive recursive. Contrary to course-of-values recursion, in primitive recursion the computation of a value of a function requires only the previous value; for example, for a 1-ary primitive recursive function g the value of g(n+1) is computed only from g(n) and n.
The factorial function n! is recursively defined by the rules
0!=1,
(n+1)!=n!(n+1).
Fib(0)=0,
Fib(1)=1,
Fib(n+2)=Fib(n+1)+Fib(n).
g(0)=0,
g(n+1)=
n | |
\sum | |
i=0 |
g(i)n-i.
In general, a function f is defined by course-of-values recursion if there is a fixed primitive recursive function h such that for all n,
f(n)=h(n,\langlef(0),f(1),\ldots,f(n-1)\rangle)
\langlef(0),f(1),\ldots,f(n-1)\rangle
f(0)=h(0,\langle\rangle)
h(n,s)=\begin{cases}n&ifn<2\ s[n-2]+s[n-1]&ifn\geq2\end{cases}
In order to convert a definition by course-of-values recursion into a primitive recursion, an auxiliary (helper) function is used. Suppose that one wants to have
f(n)=h(n,\langlef(0),f(1),\ldots,f(n-1)\rangle)
\bar{f}(n)=\langlef(0),f(1),\ldots,f(n-1)\rangle
Thus
\bar{f}(n)
\bar{f}
\bar{f}(n+1)
\bar{f}(n)
h(n,\bar{f}(n))
\bar{f}(0)=\langle\rangle
\bar{f}(n+1)=append(n,\bar{f}(n),h(n,\bar{f}(n))),
\bar{f}(n+1)=g(n,\bar{f}(n))
g(i,j)=append(i,j,h(i,j)),
Given
\bar{f}
f(n)=\bar{f}(n+1)[n]
In the context of primitive recursive functions, it is convenient to have a means to represent finite sequences of natural numbers as single natural numbers. One such method, Gödel's encoding, represents a sequence of positive integers
\langlen0,n1,n2,\ldots,nk\rangle
k | |
\prod | |
i=0 |
ni | |
p | |
i |
Using this representation of sequences, it can be seen that if h(m) is primitive recursive then the function
f(n)=h(\langlef(0),f(1),f(2),\ldots,f(n-1)\rangle)
When the sequence
\langlen0,n1,n2,\ldots,nk\rangle
k | |
\prod | |
i=0 |
(ni+1) | |
p | |
i |
\langle0\rangle
\langle0,0\rangle
Not every recursive definition can be transformed into a primitive recursive definition. One known example is Ackermann's function, which is of the form A(m,n) and is provably not primitive recursive.
Indeed, every new value A(m+1, n) depends on the sequence of previously defined values A(i, j), but the i-s and j-s for which values should be included in this sequence depend themselves on previously computed values of the function; namely (i, j) = (m, A(m+1, n)). Thus one cannot encode the previously computed sequence of values in a primitive recursive way in the manner suggested above (or at all, as it turns out this function is not primitive recursive).