Lambda Analizini Kullanarak Negatif ve Karmaşık Sayıları Gösterme


Yanıtlar:


18

İlk olarak jmad tarafından açıklandığı gibi doğal sayıları ve çiftleri kodlayın.

K tamsayı k = a - b olacakk şekilde bir çift doğal sayı (a,b) edilir . Sonra tamsayılar üzerinde olağan işlemleri şöyle tanımlayabilirsiniz ( \ lambda -calculus için Haskell gösterimini kullanarak ):k=abλ

neg = \k -> (snd k, fst k)
add = \k m -> (fst k + fst m, snd k + snd m)
sub = \k m -> add k (neg m)
mul = \k m -> (fst k * fst m + snd k * snd m, fst k * snd m + snd k * fst m)

Karmaşık sayılar söz konusu olduğunda, karmaşık sayının bir çift real olarak kodlanması anlamında benzerdir. Ancak daha karmaşık bir soru, gerçeklerin nasıl kodlanacağıdır. Burada daha fazla iş yapmanız gerekiyor:

  1. Rasyonel bir sayı bir çift olarak kodlayın; burada bir tamsayıdır, doğaldır ve .( k , a ) k a q = k / ( 1 + a )q(k,a)kaq=k/(1+a)
  2. Gerçek bir değerini bir fonksiyonu ile kodlayın, böylece her doğal , rasyonel bir sayısını şekilde . Başka bir deyişle, bir gerçek, hızında ona yaklaşan dizisi olarak kodlanır .f k N f k q | x - q | < 2 - k k 2 - kxfkNfkq|xq|<2kk2k

Gerçekleri kodlamak çok iştir ve aslında -culculus içinde yapmak istemezsiniz. Ancak saf Haskell'deki gerçeklerin basit bir uygulaması için Marshall'ın alt dizinine bakınız . Bu prensip olarak saf hesabına çevrilebilir.λλetc/haskellλ


1
Vay canına =) Bunun ne anlama geldiğini merak ediyorum ... örneğin, kilise sayılarını kodlayarak ... yani. bir kilise sayısı n tamsayı değeri n, n değerine bir işlev uygulayan bir işlevle temsil edilir. Çiftler ve negatif lambda değerleri onlar hakkında benzer sezgisel hislere sahip mi?
zcaudate

1
Kilise kodlaması , , , doğal sayıları kodlar ... Negatif sayıları kodlamaz. Yukarıdaki cevapta, doğal sayıların kodlanmasını zaten bildiğinizi varsaydım, bu yüzden tamsayıların nasıl elde edileceğini açıkladım. Onları kodladığım tamsayılar, hesabı ile daha karmaşık bir şekilde bağlantılı olan Kilise rakamlarının aksine, daha resmi bir yapıdır. "Negatif lambda değerleri" nin anlamlı bir ifade olduğunu düşünmüyorum. 1 2 λ012λ
Andrej Bauer

@zcaudate [Tür açıklamalar: i:ℤ, x:a, f,u,s:a→a, p:(a→a,a→a)] siz ℤ kodlarsanız (Sign,ℕ)fonksiyonların bir çift göz önüne alındığında, daha sonra (s,f)şekilde pterimi λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)üretecek ya f(…f(x)…)veya s(f(…f(x)…))(sonuç negatif olduğu takdirde). Eğer ℤ olarak kodlamak varsa (ℕ,ℕ), bir ters olan bir işlev gerekir - bir çift verildi (f,u)ve xfonksiyon λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)üretecek u(…u(f(…f(x)…))…)bırakacak olan fuygulamalı ikez x. Her ikisi de farklı bağlamlarda çalışır (sonuç "ters fçevrilebilir " || tersine çevrilebilir).
kimse

@zcaudate Ekstra fonksiyonlar, Kilise tarafından kodlanmış numaralar "kendi başlarına geri çekme" olarak gereklidir, ancak çiftler size sadece bileşenlerini verir. Yardımcı fonksiyonlar sadece bileşenleri "doğru" sırayla yapıştırır (nats için otomatik olarak gerçekleşir.) Ayrıca bakınız: en.wikipedia.org/wiki/… - Kilise kodlaması temelde fold . ctorherhangi bir kurucu ve bu tip fold( r) için. (Bu nedenle, özyinelemeli türler için veriler "kendi başına geri çekilecektir". Özyinelemeli olmayan türler için bu daha çok bir case/ model eşleşmesi gibidir.)
kimse

13

Lambda hesabı çoğu veri yapısını ve temel türleri kodlayabilir. Örneğin, genellikle negatif olmayan tamsayıları ve boolean'ı kodlamak için gördüğünüz aynı Church kodlamasını kullanarak lambda hesabında bir çift mevcut terimi kodlayabilirsiniz:

pair=λxyz.zxy
fst=λp.p(λxy.x)
snd=λp.p(λxy.y)

Sonra çifti olan ve geri almak istiyorsanız ve yapabileceğiniz ve .(a,b)p=(pair ab)ab(fst p)(snd p)

Bu, bir çiftle pozitif ve negatif tam sayıları kolayca temsil edebileceğiniz anlamına gelir: soldaki işaret ve sağdaki mutlak değer. İşaret, sayının pozitif olup olmadığını belirten bir mantıksaldır. Sağ, Kilise kodlamasını kullanan doğal bir sayıdır.

(sign,n)

Ve şimdi göreceli tamsayılarınız var. Çarpmanın tanımlanması kolaydır, sadece işlevini işarete ve doğal sayılardaki çarpımı mutlak değere uygulamanız :xor

mult=λab.pair  (xor(fst a)(fst b))  (mult(snd a)(snd b))

Eklemeyi tanımlamak için, iki doğal sayıyı karşılaştırmanız ve işaretler farklı olduğunda çıkarma kullanmanız gerekir, bu nedenle bu bir λ terimi değildir, ancak gerçekten istiyorsanız:

add=λab.{(true,add(snd a)(snd b))if a0b0(false,add(snd a)(snd b))if a<0b<0(true,sub(snd a)(snd b))if a0b<0|a||b|(false,sub(snd b)(snd a))if a0b<0|a|<|b|(true,sub(snd b)(snd a))if a<0b0|a|<|b|(false,sub(snd a)(snd b))if a<0b0|a||b|

ancak çıkarmanın tanımlanması gerçekten kolaydır:

minus=λa.pair(not(fst a))(snd a)
sub=λab.add(a)(minusb)

Pozitif ve negatif tamsayılarınız olduğunda karmaşık tam sayıları çok kolay bir şekilde tanımlayabilirsiniz : temsil iki tamsayıdan sadece bir çifttir . Sonra ekleme nokta-bilge ve çarpma her zamanki gibi , ama ben yazmayacağım, kolay olmalı:(a,b)a+bi

add[i]=λz1z2.pair(add(fst z1)(fst z2))(add(snd z1)(snd z2))

7
Bunun yerine tamsayısını bir çift doğal sayı olarak temsil ediyorsanız , olacak şekilde durum ayrımlarından kaçınabilirsiniz . k(a,b)k=ab
Andrej Bauer

Karmaşık tamsayılar iyi, ama karmaşık sayılar istiyordu. Sonra tekrar, elbette temsil edilemez olduğu için asla temsil edilemezler.
HDM

@AndrejBauer: çok güzel hile (belki de o kadar basit değil) HdM: hepsinde olmasa bile emin olabilirler. Ancak Kilise kodlaması ile λ hesabında bir şeyler oluşturma yönteminin burada daha önemli / uygun olduğunu düşündüm.
jmad

Keşke iki doğru cevap verebilsem =) Karmaşık sayılar hakkında sorduğumda gerçeklerin temsil edilebileceğini düşünmüyordum ama işte gidiyorsunuz!
zcaudate
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.