แปลงλ-expressions เป็น SK-expressions


20

λแคลคูลัสหรือแลมบ์ดาแคลคูลัสเป็นระบบตรรกะขึ้นอยู่กับฟังก์ชั่นที่ไม่ระบุชื่อ ตัวอย่างเช่นนี่เป็นนิพจน์::

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

อย่างไรก็ตามสำหรับจุดประสงค์ของการท้าทายนี้เราจะทำให้สัญลักษณ์ง่ายขึ้น:

  • เปลี่ยนλเป็น\(เพื่อให้พิมพ์ง่ายขึ้น):\f.(\x.xx)(\x.f(xx))
  • .ในส่วนหัวของแลมบ์ดาไม่จำเป็นเพื่อให้เราสามารถวาง:\f(\xxx)(\xf(xx))
  • ใช้Unlambdaสไตล์คำนำหน้าโน้ตด้วย`สำหรับการประยุกต์ใช้มากกว่าการเขียนทั้งสองฟังก์ชั่นด้วยกัน (สำหรับคำอธิบายเต็มรูปแบบของวิธีการทำเช่นนี้ดูแปลงระหว่างแลมบ์ดาแคลคูลัสสัญลักษณ์ ):\f`\x`xx\x`f`xx
  • นี่เป็นการทดแทนที่ซับซ้อนที่สุด แทนที่ตัวแปรแต่ละตัวด้วยตัวเลขในวงเล็บตามความลึกของตัวแปรที่สัมพันธ์กับส่วนหัวแลมบ์ดาที่เป็นของมัน (เช่นใช้การทำดัชนี De Bruijn ที่ใช้ 0 ) ตัวอย่างเช่นใน\xx(ฟังก์ชั่นเอกลักษณ์), xในร่างกายจะถูกแทนที่ด้วย[0]เพราะมันเป็นของส่วนหัว (ตามพื้นฐาน 0) พบเมื่อสำรวจภายในการแสดงออกจากตัวแปรไปยังจุดสิ้นสุด; จะถูกแปลงเป็น\x\y``\x`xxxy ตอนนี้เราสามารถวางตัวแปรในส่วนหัวออก\x\y``\x`[0][0][1][0]\\``\`[0][0][1][0]

ตรรกะเชิงผสมนั้นเป็นทัวริงทาร์พิทที่ทำจากcalcul-แคลคูลัส (จริง ๆ แล้วมันมาก่อน แต่มันไม่เกี่ยวข้องเลย)

"Combinatory ตรรกศาสตร์สามารถถูกมองว่าเป็นตัวแปรของแลมบ์ดาแคลคูลัสซึ่งแลมบ์ดานิพจน์ (แทนการทำหน้าที่เป็นนามธรรม) จะถูกแทนที่ด้วยชุด จำกัด combinators ฟังก์ชั่นดั้งเดิมที่ไม่มีขอบเขต จำกัด ตัวแปร" 1

ตรรกะที่พบได้บ่อยที่สุดคือแคลคูลัสของSK combinatorซึ่งใช้หลักการพื้นฐานต่อไปนี้:

K = λx.λy.x
S = λx.λy.λz.xz(yz)

บางครั้ง Combinator I = λx.xคือเพิ่ม แต่มันจะซ้ำซ้อนเช่นSKK(หรือแน่นอนSKxสำหรับการใด ๆx) Iเทียบเท่ากับ

สิ่งที่คุณต้องมีคือ K, S และแอปพลิเคชันเพื่อให้สามารถเข้ารหัสนิพจน์ใด ๆ ในλ-แคลคูลัส ดังตัวอย่างต่อไปนี้เป็นคำแปลจากฟังก์ชั่นλf.(λx.xx)(λx.f(xx))เป็นตรรกะเชิงการรวม:

λf.(λx.xx)(λx.f(xx)) = S(K(λx.xx))(λf.λx.f(xx))
λx.f(xx) = S(Kf)(S(SKK)(SKK))
λf.λx.f(xx) = λf.S(Kf)(S(SKK)(SKK))
λf.S(Sf)(S(SKK)(SKK)) = S(λf.S(Sf))(K(S(SKK)(SKK)))
λf.S(Sf) = S(KS)S
λf.λx.f(xx) = S(S(KS)S)(K(S(SKK)(SKK)))
λx.xx = S(SKK)(SKK)
λf.(λx.xx)(λx.f(xx)) = S(K(S(SKK)(SKK)))(S(S(KS)S)(K(S(SKK)(SKK))))

```S`K``S``SKK``SKK``S``S`KSS`K``SKK`เนื่องจากเรามีการใช้คำนำหน้าเอกสารนี้เป็น

1ที่มา: Wikipedia

ความท้าทาย

ถึงตอนนี้คุณอาจเดาได้ว่าคืออะไร: เขียนโปรแกรมที่ใช้ expression-expression ที่ถูกต้อง (ในสัญลักษณ์ที่อธิบายด้านบน) เป็นอินพุตและเอาต์พุต (หรือส่งคืน) ฟังก์ชันเดียวกันเขียนใหม่ในแคลคูลัส SK-combinator โปรดทราบว่ามีวิธีการเขียนนี้จำนวนอนันต์ คุณต้องการส่งออกหนึ่งในวิธีที่ไม่มีที่สิ้นสุด

นี่คือดังนั้นการส่งที่ถูกต้องที่สั้นที่สุด (วัดเป็นไบต์) ชนะ

กรณีทดสอบ

แต่ละกรณีทดสอบแสดงผลลัพธ์ที่เป็นไปได้หนึ่งรายการ นิพจน์ด้านบนเป็นนิพจน์ calcul-แคลคูลัสที่เทียบเท่า

λx.x:
\[0]                        -> ``SKK
λx.xx:
\`[0][0]                    -> ```SKK``SKK
λx.λy.y:
\\[0]                       -> `SK
λx.λy.x:
\\[1]                       -> K
λx.λy.λz.xz(yz):
\\\``[2][0]`[1][0]          -> S
λw.w(λx.λy.λz.xz(yz))(λx.λy.x):
\``[0]\\[1]\\\``[2][0]`[1][0] -> ``S``SI`KS`KK

1
ที่เกี่ยวข้อง: codegolf.stackexchange.com/q/105991/56725
Christian Sievers

1
ฉันคิดว่ากรณีทดสอบที่สองของคุณไม่ถูกต้อง สุดท้ายมีตัวเลขที่ไม่ได้อยู่ในวงเล็บ
Christian Sievers

ที่เกี่ยวข้อง: codegolf.stackexchange.com/q/53250/134
FUZxxl

คุณได้λx.f(xx) = S(Kf)(SKK)อย่างไร มันไม่ควรจะเป็นอย่างนั้นλx.f(xx) = S(Kf)(SII) = S(Kf)(S(SKK)(SKK))หรือ เมื่อแปลงλx.f(xx)ฉันจะได้รับS {λx.f} {λx.xx}สิ่งที่ลดลงS (Kf) {λx.xx}และการแสดงออกในวงเล็บไม่ได้เป็นอย่างอื่นω=λx.xxที่เรารู้ว่ามันแสดงออกSII = S(SKK)(SKK)มาใช่ไหม?
BarbaraKwarc

@BarbaraKwarc ขวาฉันหมายถึงไม่ได้SII SKKนั่นเป็นความผิดพลาด
แยกผลไม้

คำตอบ:


9

Haskell, 251 237 222 214 ไบต์

บันทึก 15 ไบต์ด้วย @ Ørjan_Johansen (ดูลิงค์ของ TIO ในหมายเหตุ)!

มีการบันทึกอีก 8 ไบต์ขอบคุณ @nimi!

data E=S|K|E:>E|V Int
p(h:s)|h>'_',(u,a)<-p s,(v,b)<-p u=(v,a:>b)|h>'['=a<$>p s|[(n,_:t)]<-reads s=(t,V n)
a(e:>f)=S:>a e:>a f
a(V 0)=S:>K:>K
a(V n)=K:>V(n-1)
a x=K:>x
o(e:>f)='`':o e++o f
o S="S"
o K="K"
f=o.snd.p

pแยกวิเคราะห์อินพุตส่งคืนส่วนที่ไม่ได้แยกวิเคราะห์ที่เหลืออยู่ในองค์ประกอบแรกของคู่ผลลัพธ์ อักขระตัวแรกของอาร์กิวเมนต์ต้องเป็น backtick, แบ็กสแลชหรือเครื่องหมายวงเล็บเปิด ยามรูปแบบของการpตรวจสอบกรณีเหล่านี้ในลำดับนี้ ในกรณีแรกที่แสดงถึงการประยุกต์ใช้อีกสองสำนวนที่มีการแยกวิเคราะห์และรวมกับองค์ประกอบของที่ชนิดของข้อมูลที่มีคอนสตรัคมัดE :>ในกรณีแลมบ์ดานิพจน์ต่อไปนี้จะถูกวิเคราะห์และกำหนดให้กับaฟังก์ชันทันที มิฉะนั้นจะเป็นตัวแปรที่เราได้รับจำนวนที่มีreadsฟังก์ชั่น (ซึ่งจะส่งกลับรายการ) (_:t)และวางวงเล็บปิดโดยการจับคู่รูปแบบด้วย

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

oเปลี่ยนผลลัพธ์เป็นสตริงสำหรับเอาต์พุต fเป็นฟังก์ชั่นที่สมบูรณ์

ในหลาย ๆ ภาษาแบ็กสแลชเป็นอักขระยกเว้นดังนั้นจะต้องมีสองครั้งในตัวอักษรสตริง:

*Main> f "\\[0]"
"``SKK"
*Main> f "\\`[0][0]"
"``S``SKK``SKK"
*Main> f "\\\\[0]"
"``S``S`KS`KK`KK"
*Main> f "\\\\[1]"
"``S`KK``SKK"
*Main> f "\\\\\\``[2][0]`[1][0]"
"``S``S`KS``S``S`KS``S`KK`KS``S``S`KS``S``S`KS``S`KK`KS``S``S`KS``S`KK`KK``S`KK``SKK``S``S`KS``S``S`KS``S`KK`KS``S`KK`KK``S`KK`KK``S``S`KS``S``S`KS``S`KK`KS``S``S`KS``S`KK`KK``S``S`KS`KK`KK``S``S`KS``S``S`KS``S`KK`KS``S`KK`KK``S`KK`KK"

1
1. (a,(b,v))<-p<$>p sในบรรทัดที่สองคุณสามารถใช้ 2. '\\'สามารถเป็นได้_ถ้าคุณย้ายการแข่งขันที่ผ่านมา
Ørjan Johansen

1
จริง ๆ แล้วเกาส่วนแรก: มันสั้นกว่าเพื่อสลับลำดับ tuple และใช้p(_:s)=a<$>p sสำหรับ'\\'บรรทัด(ย้าย)
Ørjan Johansen

1
ลองออนไลน์! สำหรับเวอร์ชันปัจจุบันของคุณ ซึ่งวิธีนี้มีขนาดเพียง 236 ไบต์คุณสามารถลบบรรทัดใหม่ได้
Ørjan Johansen

2
@ Challenger5 ฉันคิดว่ามันเป็นส่วนใหญ่เนื่องจากความจริงที่ว่า Haskell จะขึ้นอยู่กับแลมบ์ดาแคลคูลัสเพื่อให้คนที่มีความเชี่ยวชาญใน Haskell มีแนวโน้มที่จะดึงดูดให้ชนิดของคำถามนี้ :)
สิงห์

2
คุณสามารถกำหนดpด้วยสีหน้าเดียวกับสามยามจัดเรียงกรณีและวางคู่ฟุ่มเฟือยของ:() p(h:s)|h>'_',(u,a)<-p s,(v,b)<-p u=(v,a:>b)|h>'['=a<$>p s|[(n,_:t)]<-reads s=(t,V n)
nimi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.