Đại diện cho số âm và số phức sử dụng tính toán Lambda


Câu trả lời:


18

Đầu tiên mã hóa các số và cặp tự nhiên, như được mô tả bởi jmad.

Biểu diễn một số nguyên là một cặp số tự nhiên ( a , b ) sao cho k = a - b . Sau đó, bạn có thể xác định hoạt động bình thường trên các số nguyên như (sử dụng ký hiệu Haskell cho λk(a,b)k=abλ -calculus):

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)

Trường hợp số phức tương tự theo nghĩa là số phức được mã hóa thành một cặp số thực. Nhưng một câu hỏi phức tạp hơn là làm thế nào để mã hóa thực tế. Ở đây bạn phải làm nhiều việc hơn:

  1. Mã hóa số hữu tỉ là một cặp ( k , a ) trong đó k là số nguyên, a là tự nhiên và q = k / ( 1 + a ) .q(k,a)kaq=k/(1+a)
  2. Mã hóa một số thực bằng một hàm f sao cho với mọi k N tự nhiên , f k mã hóa một số hữu tỷ q sao cho | x - q | < 2 - k . Nói cách khác, một thực được mã hóa như là một chuỗi của rationals hội tụ để nó ở mức k 2 - k .xfkNfkq|xq|<2kk2k

Encoding số thực là rất nhiều công việc và bạn không muốn thực sự làm điều đó trong -calculus. Nhưng hãy xem ví dụ thư mục con của Marshall để thực hiện đơn giản các thực tế trong Haskell thuần túy. Điều này có thể về nguyên tắc được dịch sang tinh khiết λ -calculus.λetc/haskellλ


1
Wow =) Tôi đang tự hỏi trực giác điều đó có nghĩa là gì ... ví dụ, sử dụng mã hóa số nhà thờ ... tức là. một số nhà thờ có giá trị nguyên n được biểu diễn bằng hàm áp dụng hàm cho giá trị n lần. Các cặp và giá trị lambda âm có cảm giác trực quan tương tự về chúng không?
zcaudate

1
Mã hóa nhà thờ mã hóa các số tự nhiên , 1 , 2 , ... Nó không mã hóa các số âm. Trong câu trả lời ở trên, tôi giả sử bạn đã biết về mã hóa số tự nhiên, vì vậy tôi đã giải thích cách lấy số nguyên. Các số nguyên như tôi mã hóa đó là một cấu trúc chính thức hơn, không giống như các chữ số Giáo Hội, được phức tạp hơn kết nối với λ -calculus. Tôi không nghĩ "giá trị lambda tiêu cực" là một cụm từ có ý nghĩa. 012λ
Andrej Bauer

@zcaudate [Loại chú thích: i:ℤ, x:a, f,u,s:a→a, p:(a→a,a→a)] Nếu bạn mã hóa ℤ như (Sign,ℕ)sau đó, cho một cặp của các chức năng (s,f)như p, thuật ngữ này λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)sẽ tạo ra một trong hai f(…f(x)…)hoặc s(f(…f(x)…))(nếu kết quả là âm tính). Nếu bạn mã hóa ℤ như (ℕ,ℕ), bạn cần một hàm có nghịch đảo - được cho một cặp (f,u)x, hàm λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)sẽ tạo ra u(…u(f(…f(x)…))…)sẽ để lại thời gian fáp dụng . Cả hai hoạt động trong các bối cảnh khác nhau (kết quả có thể "lật" | | là không thể đảo ngược). ixf
không ai

@zcaudate Các chức năng bổ sung là cần thiết vì các số được mã hóa của Giáo hội "tự lặp lại", nhưng các cặp sẽ chỉ trao cho bạn các thành phần của chúng. Các hàm trợ giúp chỉ kết dính các thành phần lại với nhau theo thứ tự "đúng" (điều này sẽ tự động xảy ra đối với các nats.) Xem thêm: en.wikipedia.org/wiki/iêu - Mã hóa nhà thờ về cơ bản fold . ctorcho bất kỳ nhà xây dựng nào và kiểu đó fold( r). (Đó là lý do tại sao, đối với các loại đệ quy, dữ liệu sẽ "tự lặp lại". Đối với các loại không đệ quy, nó giống như một casetrận đấu / mẫu.)
không ai là

13

Lambda-tính toán có thể mã hóa hầu hết các cấu trúc dữ liệu và các loại cơ bản. Ví dụ: bạn có thể mã hóa một cặp thuật ngữ hiện có trong phép tính lambda, sử dụng cùng một mã hóa Church mà bạn thường thấy để mã hóa các số nguyên không âm và boolean:

fst = λ p . p ( λ x y . x ) snd = λ p . p ( λ x y . y )

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

Khi đó cặp p = ( cặp  a b ) và nếu bạn muốn lấy lại ab, bạn có thể làm ( fst  p )( snd  p ) .(a,b)p=(pair ab)ab(fst p)(snd p)

Điều đó có nghĩa là bạn có thể dễ dàng biểu diễn các số nguyên dương và âm bằng một cặp: dấu bên trái và giá trị tuyệt đối ở bên phải. Dấu hiệu là một boolean xác định xem số đó có dương không. Bên phải là một số tự nhiên sử dụng mã hóa Church.

(sign,n)

Và bây giờ bạn có số nguyên tương đối. Phép nhân rất dễ xác định, bạn chỉ cần áp dụng hàm xor trên dấu và phép nhân trên số tự nhiên trên giá trị tuyệt đối:

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

Để xác định phép cộng, bạn phải so sánh hai số tự nhiên và sử dụng phép trừ khi các dấu hiệu khác nhau, vì vậy đây không phải là thuật ngữ but nhưng bạn có thể điều chỉnh nó nếu bạn thực sự muốn:

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|

but then subtraction is really easy to define:

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

Once you have positive and negative integers you can define complex integers very easily: it is just a pair of two integers (a,b) which represents a+bi. Then addition is point-wise and multiplication is as usual, but I won't write it, it should be easy:

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

6
You can avoid the case distinctions if instead you represent the integer k as a pair of natural numbers (a,b) such that k=ab.
Andrej Bauer

Complex integers alright, but he was asking for complex numbers. Then again, they of course can never be represented since there are uncountable.
HdM

@AndrejBauer: very nice trick (maybe not that simpler) HdM: sure they can, even in not all of them. But I figured that the method for building stuff in the λ-calculus with Church encoding was more important/appropriate here.
jmad

I wish I could give two correct answers =) I wasn't even thinking that reals could be represented when I asked about complex numbers but there you go!.
zcaudate
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.