Come posso enumerare (per dimensione di albero di espressioni, ad esempio) tutte le funzioni ricorsive primitive che mappano i numeri naturali ai numeri naturali in un linguaggio di programmazione tradizionale come C?
Ad esempio, in Mathematica, si possono esprimere le funzioni ricorsive primitive di base come segue :
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]]];
Quindi, ad esempio, gli alberi di espressione ricorsiva primitiva per addizione, predecessore e monus (sottrazione troncata) sono:
Idealmentedovrebbeesserepossibilevalutareeffettivamentequesteprimitivefunzioniricorsivesuinumerinaturali,inmodochesipossanoottenereglioutputdiquestefunzionisudiessi.
Modifica
Adesempio,quicisonolefunzioniricorsiveprimitivedibaseimplementateinPython:
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
Quindi possiamo implementare addizione, predecessore e monus (sottrazione troncata) come segue:
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)
Ho quindi costruito un modo per rappresentare (e analizzare / valutare) la struttura di diverse funzioni ricorsive primitive:
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
Ad esempio, la funzione predecessore può essere rappresentata come
predecessorExpression = Expression(
head=recursion,
arguments=(
zero,
Expression(
head=projection,
arguments=(
Expression(
head=successor,
arguments=(
Expression(
head=zero,
arguments=()
),
)
),
)
)
)
)
Il parser funziona correttamente quando si valuta l'espressione predecessore:
predecessorFunction = parse(predecessorExpression)
print predecessorFunction(42)
Ciò che rimane è costruire gli alberi di espressione che rappresentano le funzioni ricorsive primitive. Qualcuno sa quale sarebbe il modo migliore per avvicinarsi a questo?
EDIT 2: Ho appena trovato questo promettente articolo .