The set of primitive recursive (PR) functions is the smallest set of functions of several integer arguments satisfying five axioms:
- Constant functions are PR.
- The function that picks the ith element of a list of n arguments is PR.
- The successor function S(n) = n+1 is PR.
- PR functions are closed under composition.
- PR functions are closed under primitive recursion.
The last axiom obviously gives PR functions their name. So what is primitive recursion? Given a PR function f that takes k arguments, and another PR function g that takes k+2 arguments, the primitive recursion of f and g is a function h of k+1 arguments satisfying two properties:
- h(0, x1, …, xk) = f(x1, …, xk)
- h(S(y), x1, …, xk) = g(y, h(y, x1, … xk), x1, …, xk)
Not every computable function is primitive recursive. For example, Ackermann’s function is a general recursive function, but not a primitive recursive function. General recursive functions are Turing complete. Turing machines, lambda calculus, and general recursive functions are all equivalent models of computation, but the first two are better known.
For this post, the main thing about general recursive functions is that, as the name implies, they are more general than primitive recursive functions.
Now we switch from functions to sets. The characteristic function of a set A is the function that is 1 for elements of A and zero everywhere else. In other areas of math, there is a sort of duality between functions and sets via characteristic functions. For example, the indicator function of a measurable set is a measurable function. And the indicator function of a convex set is a convex function. But in recursive functions, there’s an unexpected wrinkle in this analogy.
A set of integers is recursively enumerable if it is either empty or the image of a general recursive function. But there’s a theorem, due to Alonzo Church, that a non-empty recursively enumerable set is actually the image of a primitive recursive function. So although general recursive functions are more general, you can’t tell that from looking at function images. For example, although the Ackermann function is not primitive recursive, there is a primitive recursive function with the same image.