Generator Kalkulus Lambda

10

Saya tidak tahu harus bertanya ke mana lagi, saya harap ini tempat yang bagus.

Saya hanya ingin tahu apakah mungkin membuat generator kalkulus lambda; pada dasarnya, loop yang akan, diberikan waktu yang tak terbatas, menghasilkan setiap fungsi kalkulus lambda yang mungkin. (seperti dalam bentuk string).

Karena kalkulus lambda sangat sederhana, hanya memiliki beberapa elemen untuk notasinya, saya pikir itu mungkin (meskipun, tidak sangat berguna) untuk menghasilkan semua kombinasi yang mungkin dari elemen notasi itu, dimulai dengan kombinasi yang paling sederhana, dan dengan demikian menghasilkan setiap lambda yang mungkin. fungsi kalkulus.

Tentu saja, saya hampir tidak tahu apa-apa tentang kalkulus lambda jadi saya tidak tahu apakah ini benar-benar mungkin.

Apakah itu? Jika demikian, apakah ini cukup mudah seperti yang saya bayangkan, atau apakah secara teknis memungkinkan, tetapi begitu sulit sehingga secara efektif tidak mungkin?

PS. Saya tidak berbicara tentang fungsi yang dikurangi beta, saya hanya berbicara tentang setiap notasi yang valid dari setiap fungsi kalkulus lambda.

Tumpukan legal
sumber

Jawaban:

19

Tentu, ini adalah latihan pengkodean standar.

p:N2N

p(n,m)=(n+m)(n+m+1)2+n

kn,mp(n,m)=k

x0,x1,x2,

ilambda(i)

  • ij=i/2xj
  • ij=(i1)/2
    • jk=j/2n,mp(n,m)=kN=lambda(n),M=lambda(m)(NM)
    • jk=(j1)/2n,mp(n,m)=kM=lambda(m)(λxn. M)

Λ

ΛN+(Λ2+N×Λ)

yang dibaca sebagai "istilah lambda, secara sintaksis, adalah penyatuan terpisahkan dari 1) variabel (direpresentasikan sebagai alami), 2) aplikasi (dibuat oleh dua istilah lambda), dan 3) abstraksi (variabel pasangan / alami + istilah lambda ) ".

N2NpN+NN

Prosedur ini bersifat umum, dan akan bekerja pada hampir semua bahasa yang dihasilkan melalui tata bahasa bebas konteks, yang akan memberikan isomorfisme serupa dengan yang di atas.

chi
sumber
Wow, terima kasih, mungkinkah Anda dapat mewakili kode semu ini? Saya pasti akan mengerti itu lebih baik karena saya tidak memiliki gelar cs.
Legit Stack
3
lambda(n)if n%2==0 ...n,mp(n,m)=kn,mn,mk
1
a=12(8k+11),b=12a(a+1),n=bk,m=an
12

Iya. Ambil sesuatu yang menyebutkan semua string ASCII yang mungkin. Untuk setiap output, periksa apakah itu sintaks kalkulus lambda yang valid yang mendefinisikan fungsi; jika tidak, lewati saja. (Pemeriksaan itu bisa dilakukan.) Itu menyebutkan semua fungsi kalkulus lambda.

DW
sumber
5
Intinya, semua masalah seperti ini diselesaikan dengan memanggil monyet pengetikan ...
xuq01
5
Atau Anda bisa secara langsung menyebutkan istilah kalkulus lambda. Jauh lebih cepat daripada string acak karena setiap output adalah istilah yang diformat dengan benar. Itu akan seperti mengganti monyet mengetik dengan generator play Shakespeare.
Dan D.
11

Seperti yang telah disebutkan, ini hanya menyebutkan istilah dari konteks bahasa bebas, jadi pasti bisa dilakukan. Tapi ada matematika yang lebih menarik di baliknya, masuk ke bidang kombinatorik anlytical.

Makalah Menghitung dan menghasilkan istilah dalam kalkulus lambda biner berisi pengobatan masalah enumerasi, dan banyak lagi. Untuk mempermudah, mereka menggunakan sesuatu yang disebut biner lambda calulus , yang hanya merupakan pengkodean istilah lambda menggunakan indeks De Bruijn , jadi Anda tidak perlu menyebutkan variabel.

Makalah itu juga berisi kode Haskell konkret yang mengimplementasikan algoritma generasi mereka. Itu pasti secara efektif mungkin.

Saya kebetulan telah menulis implementasi dari pendekatan mereka di Julia.

phipsgabler
sumber
7

Tentu. Kita dapat langsung menghasilkannya sesuai dengan definisi istilah lambda.

Di Haskell, kita mendefinisikan tipe data terlebih dahulu,

data LC a  =  Var  a                -- Constructor <type> <type> ...
           |  App (LC a) (LC a)     --
           |  Lam  a     (LC a)     --  ... alternatives ...

instance Show a => Show (LC a)      -- `LC a` is in Show if `a` is in Show, and
  where
    show (Var i)    =  [c | c <- show i, c /= '\'']
    show (App m n)  =  "("  ++ show m       ++ " " ++ show n ++ ")"
    show (Lam v b)  =  "(^" ++ show (Var v) ++ "." ++ show b ++ ")"

dan kemudian dengan menggunakan adil join,

lambda :: [a] -> [LC a]
lambda vars  =  terms 
  where
  terms  =  fjoin [ map Var vars ,
                    fjoin [ [App t s | t <- terms] | s <- terms ] ,
                    fjoin [ [Lam v s | v <- vars ] | s <- terms ] ]

  fjoin :: [[a]] -> [a]
  fjoin xs  =  go [] xs             -- fairer join
      where 
      go [] []  =  []
      go a  b   =  reverse (concatMap (take 1) a) ++ go 
                       (take 1 b ++ [t | (_:t) <- a]) (drop 1 b)

kita hanya menyebutkannya, seperti misalnya

> take 20 $ lambda "xyz"
[x,y,(x x),z,(y x),(^x.x),(x y),(^y.x),((x x) x),(^x.y),(y y),(^z.x),(x (x x)),
 (^y.y),(z x),(^x.(x x)),((x x) y),(^z.y),(y (x x)),(^y.(x x))]

> take 5 $ drop 960 $ lambda "xyz"
[(((x x) y) (z x)),(^y.(^x.((x x) (x x)))),((^x.(x x)) (^x.(x x))),(^x.((^z.x) 
 y)),((z x) ((x x) y))]

Ω=(λx.xx)(λx.xx)

fjoinsetara dengan Omega monad 's diagonal.

Will Ness
sumber
0

Saya telah menemukan satu alat online yang dapat menghasilkan string sampel dari ekspresi reguler: https://www.browserling.com/tools/text-from-regex . Anda dapat menghasilkan banyak contoh istilah lambda dengan memasukkan sesuatu seperti ini:

(\( (lambda \w\. )* \w+ \))* 

Tentu saja untuk mendapatkan istilah dengan tingkat bersarang yang sewenang-wenang, Anda perlu menggunakan tata bahasa bebas konteks, yang merupakan alat yang lebih deskriptif untuk mendefinisikan bahasa daripada ekspresi reguler. Saya belum menemukan alat yang ada untuk menghasilkan kalimat bahasa sampel berdasarkan pada definisi tata bahasa bebas konteks, tetapi tidak ada alasan seseorang tidak dapat dibangun.

martin
sumber
2
λ