เครื่องกำเนิดแคลคูลัสแลมบ์ดา


10

ฉันไม่รู้จะถามคำถามนี้ที่ไหนฉันหวังว่าที่นี่เป็นสถานที่ที่ดี

ฉันแค่อยากรู้ว่าเป็นไปได้ที่จะสร้างแลมบ์ดาแคลคูลัส; เป็นหลักวงที่จะให้เวลาไม่ จำกัด สร้างฟังก์ชันแคลคูลัสแลมบ์ดาที่เป็นไปได้ทั้งหมด (เหมือนในรูปแบบของสตริง)

เนื่องจากแคลคูลัสแลมบ์ดานั้นเรียบง่ายมีเพียงไม่กี่องค์ประกอบในสัญกรณ์ของมันฉันคิดว่ามันอาจเป็นไปได้ (แม้ว่าไม่มีประโยชน์มาก) ในการสร้างชุดค่าผสมที่เป็นไปได้ทั้งหมดขององค์ประกอบสัญกรณ์นั้นเริ่มต้นด้วยชุดค่าผสมที่ง่ายที่สุด ฟังก์ชันแคลคูลัส

แน่นอนฉันไม่รู้อะไรเกี่ยวกับแลมบ์ดาแคลคูลัสดังนั้นฉันจึงไม่รู้ว่ามันเป็นไปได้จริงหรือ

ใช่ไหม? ถ้าเป็นเช่นนั้นมันค่อนข้างตรงไปตรงมาเหมือนที่ฉันจินตนาการไว้หรือเป็นไปได้ในทางเทคนิค แต่ก็ยากที่จะเป็นไปไม่ได้อย่างมีประสิทธิภาพ?

PS ฉันไม่ได้พูดถึงฟังก์ชั่นลดเบต้าฉันแค่พูดถึงเครื่องหมายที่ถูกต้องของฟังก์ชันแคลคูลัสแลมบ์ดาทุกอัน

คำตอบ:


19

แน่นอนว่านี่เป็นแบบฝึกหัดการเข้ารหัสมาตรฐาน

ก่อนอื่นให้ฟังก์ชันใด ๆ ที่คำนวณได้แบบ bijective เรียกว่าฟังก์ชันจับคู่ ตัวเลือกมาตรฐานคือp:N2N

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

หนึ่งสามารถพิสูจน์ได้ว่านี่คือ bijection ดังนั้นใดก็ตามธรรมชาติเราสามารถคำนวณดังกล่าวว่า kn , m p ( n , m ) = kkn,mp(n,m)=k

กับข้อตกลงแลมบ์ดาการระบุการแก้ไขปัญหาการแจงนับใด ๆ สำหรับชื่อตัวแปร: x_0,x0,x1,x2,

จากนั้นสำหรับจำนวนธรรมชาติแต่ละตัวให้พิมพ์กำหนดซ้ำดังนี้:l a m b d a ( i )ilambda(i)

  • หากเป็นให้และส่งคืนตัวแปรj = i / 2 x jij=i/2xj
  • ถ้าเป็นเลขคี่ให้j = ( i - 1 ) / 2ij=(i1)/2
    • ถ้าเป็นคู่ให้และหาเช่นนั้น ; คำนวณ ; แอปพลิเคชันส่งคืนk = j / 2 n , m p ( n , m ) = k N = l a m b d a ( n ) , M = l a m b d a ( m ) ( N M )jk=j/2n,mp(n,m)=kN=lambda(n),M=lambda(m)(NM)
    • ถ้าเป็นเลขคี่ให้และหาเช่นนั้น ; คำนวณ ; return abstractionk = ( j - 1 ) / 2 n , m p ( n , m ) = k M = l a m b d a ( m ) ( λ x n . M )jk=(j1)/2n,mp(n,m)=kM=lambda(m)(λxn. M)

โปรแกรมนี้เป็นธรรมโดย bijection "พีชคณิต" ต่อไปนี้ที่เกี่ยวข้องกับชุดของข้อกำหนด :Λ

ΛN+(Λ2+N×Λ)

ซึ่งถูกอ่านว่า "เงื่อนไขแลมบ์ดา, syntactically, เป็นข้อรวมของ 1) ตัวแปร (แสดงเป็นธรรมชาติ), 2) แอปพลิเคชัน (ทำโดยแลมบ์ดาสองคำ) และ 3) นามธรรม (ตัวแปรคู่ / คำ + แลมบ์ดาธรรมชาติ )"

ระบุว่าเราใช้ bijections ที่คำนวณได้ ( ) และ (มาตรฐาน / คู่คี่) เพื่อให้ได้อัลกอริธึมข้างต้น p N + N NN2NpN+NN

ขั้นตอนนี้เป็นเรื่องทั่วไปและจะทำงานกับเกือบทุกภาษาที่สร้างขึ้นผ่านไวยากรณ์ที่ไม่มีบริบท


ว้าวขอบคุณเป็นไปได้ไหมที่คุณสามารถแสดงว่านี่เป็นรหัสเทียม ฉันเข้าใจอย่างถ่องแท้ว่าดีขึ้นเพราะฉันไม่มีวุฒิ
Legit Stack

3
@LegitStack ดีข้างต้นเป็นนามแฝงรหัส :) คุณสามารถกำหนด recursive ฟังก์ชั่นและจากนั้นใช้ ขั้นตอนที่ไม่สำคัญเพียงอย่างเดียวคือการค้นหาเช่นนั้น : สิ่งนี้สามารถทำได้โดยการลองทุกคู่กับ (อัลกอริทึมที่เร็วกว่าเดิม)lambda(n)if n%2==0 ...n,mp(n,m)=kn,mn,mk
chi

1
แท้จริงตาม Wikipedia, ฟังก์ชันผกผันของการจับคู่นี้สามารถพบได้ผ่านn a=12(8k+11),b=12a(a+1),n=bk,m=an
LegionMammal978

12

ใช่. ใช้สิ่งที่ระบุสตริง ASCII ที่เป็นไปได้ทั้งหมด สำหรับแต่ละเอาต์พุตให้ตรวจสอบว่ามันเป็นไวยากรณ์แคลคูลัสแลมบ์ดาที่ถูกต้องที่กำหนดฟังก์ชั่นหรือไม่ ถ้าไม่ข้าม (สามารถทำการตรวจสอบนั้น) ระบุฟังก์ชันแคลคูลัสแลมบ์ดาทั้งหมด


5
โดยพื้นฐานแล้วปัญหาทั้งหมดนี้แก้ไขได้ด้วยการเรียกลิงพิมพ์ดีด ...
xuq01

5
หรือคุณสามารถระบุเงื่อนไขแคลคูลัสแลมบ์ดาโดยตรง เร็วกว่าสตริงแบบสุ่มเนื่องจากเอาต์พุตทุกอันเป็นคำที่จัดรูปแบบอย่างถูกต้อง นั่นจะเหมือนกับการแทนที่ลิงที่กำลังพิมพ์ด้วยเครื่องกำเนิดการเล่นของ Shakespeare
Dan D.

11

ดังที่ได้กล่าวมานี้เป็นเพียงการแจกแจงคำศัพท์จากภาษาฟรีบริบทดังนั้นทำได้แน่นอน แต่มีคณิตศาสตร์ที่น่าสนใจอยู่ข้างหลังเข้าไปในเขตข้อมูลของ combinatorics anlytical

กระดาษการนับและการสร้างคำศัพท์ในแคลคูลัสแลมบ์ดามีการรักษาปัญหาการแจงนับและอื่น ๆ อีกมากมาย เพื่อให้สิ่งต่าง ๆ ง่ายขึ้นพวกเขาใช้สิ่งที่เรียกว่าbinary lambda calulusซึ่งเป็นเพียงการเข้ารหัสศัพท์แลมบ์ดาโดยใช้ดัชนี De Bruijnดังนั้นคุณไม่ต้องตั้งชื่อตัวแปร

บทความนั้นยังมีรหัส Haskell ที่เป็นรูปธรรมที่ใช้อัลกอริทึมการสร้างของพวกเขา มันเป็นไปได้อย่างมีประสิทธิภาพแน่นอน

ฉันบังเอิญได้เขียนการใช้แนวทางของพวกเขาในจูเลีย


7

แน่ใจ เราสามารถสร้างมันโดยตรงตามคำจำกัดความของแลมบ์ดา

ใน Haskell เรากำหนดประเภทข้อมูลก่อน

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 ++ ")"

และจากนั้นมีการใช้อย่างเป็นธรรม (ER) 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)

เราแค่แจกแจงพวกมันเช่น

> 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)

fjoinเทียบเท่ากับโอเมก้า monaddiagonal 's


0

ผมเคยเจอหนึ่งเครื่องมือออนไลน์ที่สามารถสร้างสายตัวอย่างจากการแสดงออกปกติ: https://www.browserling.com/tools/text-from-regex คุณสามารถสร้างคำแลมบ์ดาตัวอย่างได้จำนวนมากโดยการป้อนข้อมูลดังนี้:

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

แน่นอนว่าคุณจะต้องทำข้อตกลงกับระดับการซ้อนโดยพลการคุณจำเป็นต้องใช้ไวยากรณ์ที่ไม่มีบริบทซึ่งเป็นเครื่องมืออธิบายเพิ่มเติมสำหรับการกำหนดภาษามากกว่าการแสดงออกปกติ ฉันไม่ได้เจอเครื่องมือที่มีอยู่สำหรับสร้างประโยคตัวอย่างภาษาตามคำนิยามของไวยากรณ์ที่ไม่มีบริบท แต่ไม่มีเหตุผลที่ไม่สามารถสร้างได้


2
-terms ไม่ได้แสดงออกปกติ (ตามที่คุณทราบ) มันเป็นอันตรายที่จะตอบคำถามของผู้เริ่มต้นด้วยวิธีนี้เพราะมันบดบังความแตกต่างที่สำคัญ (กล่าวคือระหว่างไวยากรณ์ที่ไม่มีบริบทและการแสดงออกปกติ) λ
Andrej Bauer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.