Karena saya telah mengajarkan dasar kalkulus λ belakangan ini, saya telah menerapkan evaluator kalkulus λ sederhana di Common Lisp. Ketika saya bertanya bentuk normal Y fac 3
dalam reduksi urutan normal, dibutuhkan 619 langkah, yang sepertinya agak banyak.
Tentu saja, setiap kali saya melakukan pengurangan serupa di atas kertas, saya tidak pernah menggunakan λ-calculus yang tidak diketik, tetapi menambahkan angka dan fungsi yang beroperasi pada mereka. Dalam hal ini, fac didefinisikan sebagai:
fac = λfac.λn.if (= n 0) 1 (* n (fac (- n 1)))
Dalam hal ini, mempertimbangkan =
, *
dan -
sebagai fungsi kari, hanya dibutuhkan sekitar 50 langkah untuk mencapai Y fac 3
bentuk normalnya 6
.
Tetapi di evaluator saya, saya menggunakan yang berikut:
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)
Dalam 619 langkah, saya beralih dari Y fac ⌜3⌝
bentuk normal ⌜6⌝
, yaitu λf.λx.f (f (f (f (f (f x)))))
.
Dari sekilas cepat dari banyak langkah, saya kira itu definisi pred
yang menjamin pengurangan yang begitu lama, tapi saya masih bertanya-tanya apakah itu hanya bug besar yang jahat dalam implementasi saya ...
EDIT: Saya awalnya bertanya tentang seribu langkah, beberapa di antaranya memang menyebabkan penerapan urutan normal yang salah, jadi saya turun ke 2/3 dari jumlah langkah awal. Seperti yang dikomentari di bawah ini, dengan implementasi saya saat ini, beralih dari aritmatika Gereja ke Peano sebenarnya meningkatkan jumlah langkah ...