Поскольку в последнее время я преподавал основы λ-исчисления, я реализовал простой инструмент оценки λ-исчисления в Common Lisp. Когда я задаю нормальную форму Y fac 3
в обычном сокращении, требуется 619 шагов, что кажется немного большим.
Конечно, каждый раз, когда я делал подобные сокращения на бумаге, я никогда не использовал нетипизированное λ-исчисление, но добавлял числа и функции, действующие на них. В этом случае fac определяется как:
fac = λfac.λn.if (= n 0) 1 (* n (fac (- n 1)))
В этом случае, принимая во внимание =
, *
а -
также выделки функции, это займет всего около 50 шагов , чтобы получить Y fac 3
к своей нормальной форме 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
требует столь длительного сокращения, но я все еще задаюсь вопросом, может ли это быть большой неприятной ошибкой в моей реализации ...
РЕДАКТИРОВАТЬ: Первоначально я спросил о тысяче шагов, некоторые из которых действительно были вызваны неправильной реализацией нормального порядка, поэтому я сократил до 2/3 от первоначального количества шагов. Как прокомментировано ниже, с моей текущей реализацией, переключение с церковной арифметики на Пеано фактически увеличивает количество шагов ...