Comme j'ai récemment enseigné les bases du λ-calcul, j'ai implémenté un évaluateur de λ-calcul simple en Common Lisp. Lorsque je demande la forme Y fac 3
normale de réduction dans l'ordre normal, cela prend 619 étapes, ce qui semblait un peu trop.
Bien sûr, chaque fois que je faisais des réductions similaires sur du papier, je n'utilisais jamais le λ-calcul non typé, mais j'y ajoutais des nombres et des fonctions. Dans ce cas, fac est défini comme tel:
fac = λfac.λn.if (= n 0) 1 (* n (fac (- n 1)))
Dans ce cas, compte tenu =
, *
et -
que les fonctions taitement, il prend seulement environ 50 étapes pour obtenir Y fac 3
sa forme normale 6
.
Mais dans mon évaluateur, j'ai utilisé ce qui suit:
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)
En 619 étapes, je passe Y fac ⌜3⌝
à la forme normale de ⌜6⌝
, à savoir λf.λx.f (f (f (f (f (f x)))))
.
D'après un survol rapide des nombreuses étapes, je suppose que c'est la définition pred
qui justifie une réduction si longue, mais je me demande toujours si ce n'est peut-être qu'un gros bogue méchant dans mon implémentation ...
EDIT: J'ai d'abord demandé environ un millier d'étapes, dont certaines ont en effet causé une mauvaise mise en œuvre de l'ordre normal, donc je suis descendu aux 2/3 du nombre initial d'étapes. Comme indiqué ci-dessous, avec mon implémentation actuelle, le passage de l'arithmétique Church à Peano augmente en fait le nombre d'étapes…
la source
Y
semble cruciale ici (en particulier pour les nombres Peano) pour obtenir de courtes réductions.Si je pense au nombre de choses qu'un processeur fait pour calculer la factorielle de 3, par exemple en Python, alors quelques centaines de réductions ne sont pas du tout un problème.
la source