Dato che ultimamente ho insegnato le basi del calcolo λ, ho implementato un semplice valutatore del calcolo λ in Common Lisp. Quando chiedo la forma Y fac 3
normale di riduzione di ordine normale, ci vogliono 619 passaggi, il che sembrava un po 'troppo.
Naturalmente, ogni volta che ho fatto riduzioni simili sulla carta, non ho mai usato il calcolo λ non tipizzato, ma ho aggiunto numeri e funzioni operanti su di essi. In questo caso, fac è definito come tale:
fac = λfac.λn.if (= n 0) 1 (* n (fac (- n 1)))
In questo caso, tenendo conto =
, *
e -
come funzioni strigliare, esso soltanto circa 50 passi per arrivare Y fac 3
alla sua forma normale 6
.
Ma nel mio valutatore, ho usato quanto segue:
true = λx.λy.x
false = λx.λy.y
⌜0⌝ = λf.λx.x
succ = λn.λf.λx.f n f x
⌜n+1⌝ = succ ⌜n⌝
zero? = λn.n (λx.false) true
mult = λm.λn.λf.m (n f)
pred = λn.λf.λx.n (λg.λh.h (g f)) (λu.x) (λu.u)
fac = λfac.λn.(zero? n) ⌜1⌝ (* n (fac (pred n)))
Y = λf.(λf.λx.f (x x)) f ((λf.λx.f (x x)) f)
In 619 passaggi, ottengo dalla Y fac ⌜3⌝
forma normale di ⌜6⌝
, vale a dire λf.λx.f (f (f (f (f (f x)))))
.
Da una rapida scrematura dei molti passaggi, immagino sia la definizione di pred
ciò che merita una riduzione così lunga, ma mi chiedo ancora se potrebbe essere solo un grosso brutto bug nella mia implementazione ...
EDIT: inizialmente ho chiesto circa un migliaio di passaggi, alcuni dei quali hanno causato un'implementazione errata dell'ordine normale, quindi sono sceso a 2/3 del numero iniziale di passaggi. Come commentato di seguito, con la mia attuale implementazione, il passaggio dalla chiesa all'aritmetica di Peano in realtà aumenta il numero di passaggi ...