ชัดเจนและเป็นธรรมชาติของ combinator จุดคงที่ (Y combinator)


28

แก้ไข combinator จุดคงที่ (aka combinator Y) ในแคลคูลัสแลมบ์ดา (untyped) ( ) ถูกกำหนดเป็น:λ

FIXλf.(λx.f (λy.x x y)) (λx.f (λy.x x y))

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

นี่คือเท่าที่ฉันได้รับเมื่อฉันพยายามที่จะได้รับมันด้วยตนเอง:

  1. FIX เป็นฟังก์ชั่น: FIX λ
  2. การแก้ไขใช้ฟังก์ชันอื่นfเพื่อทำให้เกิดการเรียกซ้ำ: FIX λf.
  3. อาร์กิวเมนต์แรกของฟังก์ชั่นfคือ "ชื่อ" ของฟังก์ชั่นซึ่งใช้ในกรณีที่แอปพลิเคชันแบบเรียกซ้ำมีวัตถุประสงค์ ดังนั้นสิ่งที่ปรากฏทั้งหมดของอาร์กิวเมนต์แรกเป็นfควรถูกแทนที่ด้วยฟังก์ชันและฟังก์ชันนี้ควรคาดหวังว่าอาร์กิวเมนต์ที่เหลือของf (สมมติว่าfใช้อาร์กิวเมนต์หนึ่งข้อ): FIX λf.f (λy.y)

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

ฉันได้อ่านประเภทและภาษาการเขียนโปรแกรมแล้วซึ่งไม่ได้พยายามหามาโดยตรงและอ้างถึงผู้อ่านถึงThe Little Schemerแทน ฉันได้อ่านแล้วเช่นกันและ "การสืบทอด" ของมันก็ไม่เป็นประโยชน์ นอกจากนี้ยังเป็นน้อยของมาโดยตรงและมากขึ้นของการใช้งานของตัวอย่างที่เฉพาะเจาะจงมากและความพยายามเฉพาะกิจการเขียน recursive ฟังก์ชันที่เหมาะสมใน\λ


1
โพสต์นี้อาจมีประโยชน์ โดยทั่วไปแล้วฉันคิดว่าการดำเนินการและการคำนวณซ้ำหลายครั้งของ combinator นั้นมีประโยชน์ในการหาสาเหตุที่มันใช้งานได้
Xodarap

2
มี combinators จุดคงที่ที่แตกต่างกันหลายประการ บางทีผู้คนอาจจะเล่นกับ combinators จนกว่าพวกเขาจะสะดุดกับพวกเขา
Yuval Filmus

@YuvalFilmus นั่นคือสิ่งที่การวิจัยของฉันและการตอบสนองต่อคำถามนี้เริ่มที่จะทำให้ฉันคิดว่า แต่ฉันก็ยังคิดว่ามันจะเป็นคำแนะนำที่ "เห็น" ว่า combinator (s) จะเกิดขึ้นในเชิงตรรกะทักษะที่จะเป็นประโยชน์โดยเฉพาะอย่างยิ่งเมื่อเช่นพยายามสร้าง combinator ใหม่
BlueBomber

อ่านบทที่ 9 ใน "The Little Lisper" โดย Daniel P. Friedman (หรือ "The Little Schemer")
user18199

2
ดูเหมือนว่า OP จะระบุว่าพวกเขาได้อ่านแล้ว
ราฟาเอล

คำตอบ:


29

ฉันไม่ได้อ่านสิ่งนี้ทุกที่ แต่นี่เป็นวิธีที่ฉันเชื่อว่าจะได้รับ:Y

ลองมีฟังก์ชันแบบเรียกซ้ำ , อาจเป็นแฟกทอเรียลหรืออย่างอื่นก็ได้ อย่างไม่เป็นทางการเราให้คำจำกัดความfเป็นคำว่าหลอกหลอกโดยที่fเกิดขึ้นในคำนิยามของมันเอง:fff

f=ff

ก่อนอื่นเราทราบว่าการเรียกซ้ำสามารถแยกออกเป็นพารามิเตอร์:

f=(λr.(rr))Mf

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

f=(λr.(rr))M(λr.(rr))M

อย่างไรก็ตามนี่ไม่ถูกต้องสมบูรณ์ ก่อนได้แทนสำหรับRภายในM แต่ตอนนี้เราผ่านMแทน เราต้องแก้ไขสถานที่ทั้งหมดที่เราใช้rเพื่อให้พวกมันสร้างfจากMขึ้นมาใหม่ จริงนี้ไม่ยากเลย: ตอนนี้เรารู้ว่าF = M M , ทุกที่ที่เราใช้rเราก็เปลี่ยนไป( R R )frMMrfMf=MMr(rr)

f=(λr.((rr)(rr)))M(λr.((rr)(rr)))M

วิธีนี้ดี แต่เราต้องเปลี่ยนข้างใน สิ่งนี้ไม่สะดวก เราสามารถทำเช่นนี้มากขึ้นอย่างหรูหราโดยไม่ต้องแก้ไขMโดยการแนะนำอีกλที่ส่งไปยังMอาร์กิวเมนต์นำไปใช้กับตัวเอง: โดยการแสดงM 'เป็นλ x เราได้รับM ( x x )MMλMMλx.M(xx)

f=(λx.(λr.(rr))M(xx))(λx.(λr.(rr))M(xx))

วิธีนี้เมื่อแทนสำหรับx , M MแทนสำหรับRซึ่งเป็นโดยความหมายเท่ากับฉ สิ่งนี้ให้คำจำกัดความแบบไม่เรียกซ้ำของfซึ่งแสดงเป็นคำแลมบ์ดาที่ถูกต้อง!MxMMrff

การเปลี่ยนเป็นเป็นเรื่องง่าย เราสามารถใช้คำแลมบ์ดาโดยพลการแทนเอ็มและทำตามขั้นตอนนี้ได้ ดังนั้นเราสามารถแยกMออกและกำหนดYMM

Y=λm.(λx.m(xx))(λx.m(xx))

แท้จริงแล้วลดลงถึงfตามที่เรานิยามไว้YMf


หมายเหตุ:ฉันได้รับตามที่กำหนดไว้ในวรรณคดี Combinator ที่คุณอธิบายเป็นตัวแปรของYสำหรับการโทรโดยค่าภาษาบางครั้งเรียกว่าZ ดูบทความวิกิพีเดียนี้YYZ


1
สัญชาตญาณที่ขาดหายไป แต่ดูเหมือนชัดเจนว่าการตอบสนองที่ยอดเยี่ยมของคุณให้ฉันคือฟังก์ชั่นแบบเรียกซ้ำต้องการตัวเองเป็นอาร์กิวเมนต์ดังนั้นเราเริ่มด้วยสมมติฐานว่าฟังก์ชันจะมีรูปแบบสำหรับXบางตัว จากนั้นในขณะที่เราสร้างXเราทำให้การใช้งานของการยืนยันว่าถูกกำหนดให้เป็นแอพลิเคชันของบางสิ่งบางอย่างกับตัวเองภายในในXเช่นใช้xเพื่อxในคำตอบของคุณซึ่งเป็นโดยความหมายเท่ากับฉ ที่น่าสนใจ! =X(X)XXXxx
BlueBomber

11

ในฐานะที่เป็น Yuval ได้ชี้ให้เห็นว่ามีไม่เพียงหนึ่งผู้ประกอบการจุดคงที่ มีหลายคน กล่าวอีกนัยหนึ่งสมการสำหรับทฤษฎีบทจุดคงที่ไม่มีคำตอบเดียว ดังนั้นคุณจะไม่สามารถหาตัวดำเนินการจากพวกมันได้

มันก็เหมือนถามว่าคนที่ได้รับมาเป็นวิธีแก้ปัญหาสำหรับx = Y พวกเขาทำไม่ได้! สมการนี้ไม่มีคำตอบที่เป็นเอกลักษณ์(x,y)=(0,0)x=y


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

เท่าที่ฉันจำได้ว่าทฤษฎีบทเดิมเกิดจาก SC Kleene Kleene เกิดขึ้นกับทฤษฎีบทจุดคงที่เดิมโดยกู้หลักฐานการไม่สอดคล้องกันของแคลคูลัสแลมบ์ดาดั้งเดิมของโบสถ์ แคลคูลัสแลมบ์ดาของโบสถ์ดั้งเดิมได้รับความทุกข์ทรมานจากความขัดแย้งประเภทรัสเซล แคลคูลัสแลมบ์ดาที่ถูกแก้ไขหลีกเลี่ยงปัญหา Kleene ศึกษาการพิสูจน์ความไม่สอดคล้องกันอาจจะดูว่าแคลคูลัสแลมบ์ดาที่ถูกแก้ไขจะประสบปัญหาที่คล้ายกันและเปลี่ยนการพิสูจน์ความไม่ลงรอยกันเป็นทฤษฎีบทที่มีประโยชน์ในแคลคูลัสแลมบ์ดา ผ่านงานของเขาเกี่ยวกับความสมดุลของแคลคูลัส lambada กับการคำนวณแบบอื่น (เครื่องจักรทัวริง, ฟังก์ชันแบบเรียกซ้ำ, ฯลฯ ) เขาย้ายมันไปยังการคำนวณแบบอื่น


วิธีการรับผู้ประกอบการที่คุณอาจถาม? นี่คือวิธีที่ฉันเก็บไว้ในใจ ทฤษฎีบทจุดคงที่เกี่ยวกับการลบการอ้างอิงตนเอง

ทุกคนรู้จักคนโกหกคนโกหก:

ฉันเป็นถ้ำ

หรือในรูปแบบของภาษาอื่น ๆ :

ประโยคนี้เป็นเท็จ

ตอนนี้คนส่วนใหญ่คิดว่าปัญหาของประโยคนี้คือการอ้างอิงตนเอง มันไม่ใช่! การอ้างอิงตนเองสามารถกำจัดได้ (ปัญหาอยู่ที่ความจริงภาษาไม่สามารถพูดเกี่ยวกับความจริงของประโยคของตัวเองโดยทั่วไปได้ดูทฤษฎีความจริงที่ไม่สามารถแก้ไขได้ของ Tarski ) แบบฟอร์มที่ลบการอ้างอิงตนเองนั้นเป็นดังนี้:

ถ้าคุณเขียนอัญประกาศต่อไปนี้สองครั้งครั้งที่สองภายในอัญประกาศประโยคผลลัพธ์เป็นเท็จ: "ถ้าคุณเขียนอัญประกาศต่อไปนี้สองครั้งครั้งที่สองภายในอัญประกาศประโยคผลลัพธ์เป็นเท็จ:"

ไม่มีการอ้างอิงตนเองเรามีคำแนะนำเกี่ยวกับวิธีสร้างประโยคและทำอะไรกับมัน และประโยคที่ถูกสร้างขึ้นเท่ากับคำแนะนำ ทราบว่าในแคลคูลัสเราไม่จำเป็นต้องราคาเพราะมีความแตกต่างระหว่างข้อมูลและคำแนะนำไม่มีλ

ตอนนี้ถ้าเราวิเคราะห์สิ่งนี้เรามีโดยที่M xคือคำแนะนำในการสร้างx xและทำบางสิ่งกับมันMMMxxx

Mx=(xx)

ดังนั้นคือλ x f ( x x )และเรามีMλx.f(xx)

MM=(λx.f(xx))(λx.f(xx))

นี้สำหรับการแก้ไขฉหากคุณต้องการทำให้มันเป็นโอเปอเรเตอร์เราเพิ่งบวกλ fแล้วเราได้Y :λY

Y=λ.(MM)=λ.((λx.(xx))(λx.(xx)))

ดังนั้นฉันจึงจำความขัดแย้งโดยไม่มีการอ้างอิงตนเองและช่วยให้ฉันเข้าใจว่าเกี่ยวกับอะไรY


3

ดังนั้นคุณต้องกำหนด combinator จุดคงที่

fix f = f (fix f)
      = f (f (fix f))
      = f (f (f ... ))

แต่ไม่มีการเรียกซ้ำที่ชัดเจน เริ่มต้นด้วย combinator ที่ลดทอนได้ง่ายที่สุด

omega = (\x. x x) (\x. x x)
      = (\x. x x) (\x. x x)
      = ...

xในแลมบ์ดาครั้งแรกถูกแทนที่ซ้ำแลมบ์ดาที่สอง การแปลงอัลฟ่าอย่างง่ายทำให้กระบวนการนี้ชัดเจนยิ่งขึ้น:

omega =  (\x. x x) (\x. x x)
      =α (\x. x x) (\y. y y)
      =β (\y. y y) (\y. y y)
      =α (\y. y y) (\z. z z)
      =β (\z. z z) (\z. z z)

นั่นคือตัวแปรในแลมบ์ดาแรกจะหายไปเสมอ ดังนั้นถ้าเราเพิ่มfเข้าไปในแลมบ์ดาแรก

(\x. f (x x)) (\y. y y)

ความfประสงค์จะ Bob ขึ้น

f ((\y. y y) (\y. y y))

เราomegaกลับมาแล้ว ตอนนี้มันควรจะชัดเจนว่าถ้าเราเพิ่มfแลมบ์ดาที่สองจากนั้นก็fจะปรากฏในแลมบ์ดาแรกและจากนั้นมันจะหายไป:

Y f = (\x. x x)     (\x. f (x x))
      (\x. f (x x)) (\x. f (x x)) -- the classical definition of Y

ตั้งแต่

(\x. s t) z = s ((\x. t) z), if `x' doesn't occur free in `s'

เราสามารถเขียนนิพจน์เป็น

f ((\x. x x) (\x. f (x x))

ซึ่งเป็นเพียง

f (Y f)

Y f = f (Y f)และเราได้มีสมการของเรา ดังนั้นผู้Yรวมเป็นหลัก

  1. สองเท่าของ f
  2. ทำให้fผมบ๊อบคนแรก
  3. ทำซ้ำ

2

คุณอาจเห็นตัวอย่างคลาสสิกของสมการโดยไม่มีรูปแบบปกติ:

(λx.xx)(λx.xx)(λx.xx)(λx.xx)

แนะนำให้ใช้สมการที่คล้ายกันสำหรับการเรียกซ้ำทั่วไป:

(A)(λx.R(xx))(λx.R(xx)) R( (λx.R(xx))(λx.R(xx)) )R(R( (λx.R(xx))(λx.R(xx)) ))...

Y=(Y)R

Y=(λx.(xx))(λx.(xx))
Y=λ.(λx.(xx))(λx.(xx))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.