Оскільки я останнім часом викладаю основи λ-числення, я запровадив просту оцінку λ-числення в Common Lisp. Коли я запитую нормальну форму зменшення Y fac 3
нормального порядку, вона займає 619 кроків, що здавалося небагато.
Звичайно, щоразу, коли я робив подібні скорочення на папері, я ніколи не використовував нетипізовані λ-обчислення, але додавав числа та функції, що діють на них. У цьому випадку fac визначається як такий:
fac = λfac.λn.if (= n 0) 1 (* n (fac (- n 1)))
У цьому випадку, враховуючи =
, *
і -
як функцію каррінгу, для досягнення Y fac 3
нормальної форми потрібно лише приблизно 50 кроків 6
.
Але в своєму оцінювачі я використав наступне:
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)
За 619 кроків я переходжу Y fac ⌜3⌝
до нормальної форми ⌜6⌝
, а саме λf.λx.f (f (f (f (f (f x)))))
.
Зі швидкого проскакування багатьох кроків, я думаю, саме таке визначення pred
вимагає такого тривалого скорочення, але мені все одно цікаво, чи це просто може бути великою неприємною помилкою в моєму виконанні ...
EDIT: Спочатку я просив близько тисячі кроків, деякі з яких справді були спричинені неправильним виконанням звичайного замовлення, тому я знизився до 2/3 початкової кількості кроків. Як коментується нижче, при моїй теперішній реалізації перехід від церкви до арифметики Пеано фактично збільшує кількість кроків ...