How can I enumerate (by expression tree size, for example) all of the primitive recursive functions that map natural numbers to natural numbers in a traditional programming language like C?
For example, in Mathematica, one can express the basic primitive recursive functions as follows:
zero = Function[0];
succ = Function[# + 1];
proj[n_Integer] = Function[Part[{##}, n]];
comp[f_, gs__] = Function[Apply[f, Through[{gs}[##]]]];
prec[f_, g_] =
Function[If[#1 == 0, f[##2], g[#1 - 1, #0[#1 - 1, ##2], ##2]]];
Hence, for example, the primitive recursive expression trees for addition, predecessor, and monus (truncated subtraction) are:
Ideally it should be possible to actually evaluate these primitive recursive functions on the natural numbers, so that one can obtain the outputs of these functions on them.
EDIT:
For example, here are the basic primitive recursive functions implemented in Python:
def zero():
# Takes no arguments
# Returns zero
return 0
def successor(x):
# Takes a natural number
# Returns its successor
return x + 1
def projection(n):
# Takes at least n+1 arguments
# Returns the nth argument
def f(*x):
return x[n]
return f
def composition(g, *h):
# Takes a k-ary function and k m-ary functions
# Returns an m-ary function
def f(*x):
return g(*map(lambda h_: h_(*x), h))
return f
def recursion(g, h):
# Takes a k-ary function and a (k+2)-ary function
# Returns a (k+1)-ary function
def f(n, *x):
if n == 0:
return g(*x)
else:
return h(f(n - 1, *x), n - 1, *x)
return f
Hence we can implement addition, predecessor, and monus (truncated subtraction) as follows:
addition = recursion(projection(0), composition(successor, projection(0)))
predecessor = recursion(zero, projection(1))
monus = recursion(projection(0), composition(predecessor, projection(0)))
print addition(12, 6)
print predecessor(16)
print monus(10, 19)
I then constructed a way to represent (and parse/evaluate) the structure of different primitive recursive functions:
Expression = collections.namedtuple('Expression', ['head', 'arguments'])
def parse(expression):
if isinstance(expression, Expression):
return expression.head(*map(lambda argument: parse(argument), expression.arguments))
else:
return expression
For example, the predecessor function can be represented as
predecessorExpression = Expression(
head=recursion,
arguments=(
zero,
Expression(
head=projection,
arguments=(
Expression(
head=successor,
arguments=(
Expression(
head=zero,
arguments=()
),
)
),
)
)
)
)
The parser works successfully when evaluating the predecessor expression:
predecessorFunction = parse(predecessorExpression)
print predecessorFunction(42)
What remains is to construct the expression trees that represent the primitive recursive functions. Does anyone know what the best way to approach this would be?
EDIT 2: Just came across this promising paper.