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 ...
sumber
Y
tampaknya penting di sini (terutama untuk angka Peano) untuk mendapatkan reduksi singkat.Jika saya berpikir tentang berapa banyak hal yang dilakukan CPU untuk menghitung faktorial 3, katakanlah dengan Python, maka beberapa ratus pengurangan bukanlah masalah besar sama sekali.
sumber