Λ-taşı veya lambda taşı, anonim fonksiyonlarına göre mantıksal bir sistemdir. Örneğin, bu bir λ ifadesi:
λf.(λx.xx)(λx.f(xx))
Ancak, bu zorluğun amaçları için gösterimi basitleştireceğiz:
- Değişim
λ
için\
(daha kolay yazmak için yapmak):\f.(\x.xx)(\x.f(xx))
.
Biz bırakın böylece lambda başlıklarda, gereksiz:\f(\xxx)(\xf(xx))
- İki işlevi birlikte yazmak yerine uygulama için Unlambda stili önek gösterimini kullanın
`
(bunun nasıl yapılacağına dair tam bir açıklama için bkz. Lambda Matematik Gösterimleri arasında dönüştürme ):\f`\x`xx\x`f`xx
- Bu en karmaşık ikamedir. Her değişkeni, değişkenin ait olduğu lambda başlığına göre ne kadar derinden yuvalandığına bağlı olarak parantez içindeki bir sayıyla değiştirin (yani 0 tabanlı De Bruijn dizinini kullanın ). Örneğin,
\xx
(kimlik fonksiyonu) 'x
nda, gövde içindeki ile değiştirilir[0]
, çünkü ifade değişkenden sonuna doğru giderken karşılaşılan ilk (0 tabanlı) başlığa aittir;\x\y``\x`xxxy
dönüştürülür\x\y``\x`[0][0][1][0]
. Şimdi değişkenleri başlıklara bırakabiliriz\\``\`[0][0][1][0]
.
Kombinatorik mantık temel olarak λ-hesabından yapılmış bir Turing Tarpit'tir (Aslında, önce geldi, ancak bu ilgisiz.)
"Kombine edici mantık, lambda hesabının bir varyantı olarak görülebilir, burada lambda ifadeleri (fonksiyonel soyutlamayı temsil eden), bağlı değişkenlerin bulunmadığı ilkel işlevlerin sınırlı bir birleştirici kümesiyle değiştirilir." 1
En yaygın birleştirici mantık türü , aşağıdaki ilkelleri kullanan SK birleştirici hesabıdır :
K = λx.λy.x
S = λx.λy.λz.xz(yz)
Bazen bir birleştirici I = λx.x
eklenir, ancak SKK
(veya SKx
herhangi x
biri için ) eşdeğer olduğu için gereksizdir I
.
Λ hesabında herhangi bir ifadeyi kodlayabilmek için tek ihtiyacınız olan K, S ve uygulama. Örnek olarak, işlevden λf.(λx.xx)(λx.f(xx))
birleştirici mantığa bir çeviri :
λf.(λx.xx)(λx.f(xx)) = S(K(λx.xx))(λf.λx.f(xx))
λx.f(xx) = S(Kf)(S(SKK)(SKK))
λf.λx.f(xx) = λf.S(Kf)(S(SKK)(SKK))
λf.S(Sf)(S(SKK)(SKK)) = S(λf.S(Sf))(K(S(SKK)(SKK)))
λf.S(Sf) = S(KS)S
λf.λx.f(xx) = S(S(KS)S)(K(S(SKK)(SKK)))
λx.xx = S(SKK)(SKK)
λf.(λx.xx)(λx.f(xx)) = S(K(S(SKK)(SKK)))(S(S(KS)S)(K(S(SKK)(SKK))))
Önek notasyonunu kullandığımız için, bu ```S`K``S``SKK``SKK``S``S`KSS`K``SKK`
.
1 Kaynak: Wikipedia
Meydan okuma
Şimdiye kadar, muhtemelen ne olduğunu tahmin ettiniz: SK-birleştirici hesabında yeniden yazılan geçerli bir λ ifadesi (yukarıda açıklanan gösterimde) giriş ve çıkışlar (veya döndürür) olarak aynı işlevi alan bir program yazın. Bunu yeniden yazmanın sonsuz sayıda yolu olduğunu unutmayın; sadece sonsuz yollardan birini çıkarmanız gerekir.
Bu kod golf , bu nedenle (bayt cinsinden ölçülen) en kısa geçerli gönderim kazanır.
Test Durumları
Her test durumu bir olası çıktı gösterir. Üstteki ifade eşdeğer λ-kalkülüs ifadesidir.
λx.x:
\[0] -> ``SKK
λx.xx:
\`[0][0] -> ```SKK``SKK
λx.λy.y:
\\[0] -> `SK
λx.λy.x:
\\[1] -> K
λx.λy.λz.xz(yz):
\\\``[2][0]`[1][0] -> S
λw.w(λx.λy.λz.xz(yz))(λx.λy.x):
\``[0]\\[1]\\\``[2][0]`[1][0] -> ``S``SI`KS`KK
λx.f(xx) = S(Kf)(SKK)
? Olmamalı mıydı λx.f(xx) = S(Kf)(SII) = S(Kf)(S(SKK)(SKK))
? Dönüştürürken λx.f(xx)
, S {λx.f} {λx.xx}
hangi azaltıldığını alıyorum S (Kf) {λx.xx}
ve parantez içindeki ifade ω=λx.xx
, bildiğimizden başka bir şey değil SII = S(SKK)(SKK)
, değil mi?
SII
, değil SKK
. O bir hataydı.