ส่วนใดของ Hindley-Milner ที่คุณไม่เข้าใจ


851

ฉันสาบานว่าเคยเป็นเสื้อยืดขายที่มีคำอมตะ:


ส่วนไหนของ

Hindley-มิลเนอร์

คุณไม่เข้าใจเหรอ


ในกรณีของฉันคำตอบก็คือ ... ทั้งหมด!

โดยเฉพาะอย่างยิ่งฉันมักเห็นสัญกรณ์แบบนี้ในเอกสาร Haskell แต่ฉันก็ไม่รู้ว่ามันหมายถึงอะไร ฉันไม่รู้ว่ามันควรจะเป็นสาขาวิชาคณิตศาสตร์

ฉันรู้จักตัวอักษรของตัวอักษรกรีกแน่นอนและสัญลักษณ์เช่น "∉" (ซึ่งโดยปกติจะหมายถึงสิ่งที่ไม่ใช่องค์ประกอบของชุด)

ในทางกลับกันฉันไม่เคยเห็น "⊢" มาก่อน ( Wikipedia อ้างว่าอาจหมายถึง "พาร์ติชัน" ) ฉันไม่คุ้นเคยกับการใช้ vinculum ที่นี่ (มักจะหมายถึงส่วน แต่ที่ไม่ปรากฏจะเป็นกรณีที่นี่.)

ถ้าอย่างน้อยก็มีคนบอกฉันได้ว่าจะเริ่มมองหาที่ใดเพื่อเข้าใจความหมายของสัญลักษณ์ทะเลนี้นั่นจะเป็นประโยชน์


8
หากคุณกำลังมองหาคำอธิบายที่ดีเกี่ยวกับอัลกอริทึมสิ่งที่ดีที่สุดที่ฉันเคยพบคือในบทที่ 30 ของภาษาโปรแกรมของ Shriram Krishnamurthi ภาษา: การประยุกต์ใช้และการตีความ (ใบอนุญาต CC!)
laslowh

2
@laslowh ขอบคุณ! ฉันอ่านมัน รุ่นที่ใหม่กว่า: cs.brown.edu/courses/cs173/2012/book/book.pdf
SnowOnion

คำตอบ:


652
  • แนวนอนบาร์หมายถึงว่า "[เหนือ] หมายถึง [ด้านล่าง]"
  • หากมีการแสดงออกหลายใน [เหนือ] จากนั้นพิจารณาให้ANDedกัน ทั้งหมด [ข้างต้น] จะต้องเป็นจริงเพื่อรับประกัน [ด้านล่าง]
  • :หมายถึงมีประเภท
  • หมายถึงการอยู่ใน (เช่นเดียวกันหมายความว่า "ไม่ได้อยู่ใน")
  • Γมักใช้เพื่ออ้างถึงสภาพแวดล้อมหรือบริบท ในกรณีนี้มันอาจเป็นชุดของคำอธิบายประกอบประเภทจับคู่ตัวระบุกับประเภทของมัน ดังนั้นx : σ ∈ Γหมายความว่าสภาพแวดล้อมΓรวมถึงความจริงที่ว่ามีประเภทxσ
  • สามารถอ่านได้ตามที่พิสูจน์หรือกำหนด Γ ⊢ x : σหมายถึงว่าสภาพแวดล้อมΓเป็นตัวกำหนดว่ามีประเภทxσ
  • ,เป็นวิธีการรวมทั้งΓสมมติฐานเพิ่มเติมที่เฉพาะเจาะจงลงไปในสภาพแวดล้อม
    ดังนั้นΓ, x : τ ⊢ e : τ'หมายความว่าสภาพแวดล้อมΓ, มีเพิ่มเติมสมมติฐานเอาชนะที่xมีประเภทτ , พิสูจน์ให้เห็นว่ามีประเภทeτ'

ตามที่ได้รับการร้องขอ: ลำดับความสำคัญของผู้ให้บริการจากมากไปน้อย

  • เฉพาะภาษามัดและ mixfix ผู้ประกอบการเช่นλ x . e, ∀ α . σและτ → τ', let x = e0 in e1และช่องว่างสำหรับการใช้งานฟังก์ชั่น
  • :
  • และ
  • , (ซ้ายเชื่อมโยง)
  • ช่องว่างแยกข้อเสนอหลายรายการ (เชื่อมโยง)
  • แถบแนวนอน

19
กฎสำคัญของผู้ประกอบการคืออะไร?
Randomblue

:และมีความคล้ายคลึงกันมากซึ่งหมายความว่าสิ่งหนึ่งมีอยู่ในอีกสิ่งหนึ่ง - ชุดประกอบด้วยองค์ประกอบและประเภทมีค่าในแง่หนึ่ง ความแตกต่างที่สำคัญคือว่าx ∈ Sหมายความว่าชุดที่Sแท้จริงมีองค์ประกอบxในขณะที่Γ ⊢ x : Tวิธีการที่xจะสามารถสรุปได้ชนิดอาศัยอยู่ในบริบทT Γเมื่อพิจารณาถึงสิ่งนี้กฎ Var จะอ่าน: »ถ้า x มีอยู่จริงในบริบทมันสามารถอนุมานจากเล็กน้อยได้ (เล็กน้อย) «
David

@Randomblue ฉันทำอย่างชัดเจนความสำคัญของสัญลักษณ์โดยการเพิ่มวงเล็บทุกที่เช่น(Γ,(x:τ))⊢(x:σ)ดูoverleaf.com/read/ddmnkzjtnqbd#/61990222
SnowOnion

327

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

สัญลักษณ์

สิ่งที่ควรทราบก็คือตัวอักษรบางตัวมีความหมายดั้งเดิม โดยเฉพาะอย่างยิ่งΓแสดงถึง "บริบท" ที่คุณอยู่ - นั่นคือประเภทของสิ่งอื่น ๆ ที่คุณเห็นคืออะไร ดังนั้นสิ่งที่ต้องการΓ ⊢ ...หมายถึง "การแสดงออกเมื่อคุณรู้ประเภทของทุกการแสดงออกใน...Γ

สัญลักษณ์หลักหมายความว่าคุณสามารถพิสูจน์อะไรบางอย่าง ดังนั้นΓ ⊢ ...คำกล่าวที่ว่า "ฉันสามารถพิสูจน์ได้...ในบริบทΓข้อความเหล่านี้เรียกว่าการตัดสินประเภท

สิ่งที่จะต้องเก็บไว้ในใจ: ในวิชาคณิตศาสตร์เช่นเดียว ML และสกาล่าx : σหมายความว่ามีประเภทx σคุณสามารถอ่านได้เช่นเดียวกับ x :: σHaskell

แต่ละกฎมีความหมายว่าอย่างไร

ดังนั้นการรู้นี้การแสดงออกครั้งแรกกลายเป็นเรื่องง่ายที่จะเข้าใจ: ถ้าเรารู้ว่าx : σ ∈ Γ(นั่นคือxมีบางชนิดσในบางบริบทΓ) แล้วเรารู้ว่าΓ ⊢ x : σ(นั่นคือในΓ, xมีประเภทσ) ดังนั้นนี่ไม่ได้บอกอะไรคุณเลยที่น่าสนใจสุด ๆ มันแค่บอกวิธีใช้บริบทของคุณ

กฎอื่น ๆ ก็ง่าย [App]ตัวอย่างเช่นใช้ กฎข้อนี้มีสองเงื่อนไขe₀คือฟังก์ชั่นจากชนิดบางτชนิดบางτ'และเป็นค่าของชนิดe₁ τตอนนี้คุณรู้ว่าสิ่งที่พิมพ์คุณจะได้รับโดยการใช้e₀การe₁! หวังว่านี่จะไม่แปลกใจ :)

กฎต่อไปมีไวยากรณ์ใหม่เพิ่มเติม โดยเฉพาะอย่างยิ่งΓ, x : τก็หมายความว่าบริบทที่สร้างขึ้นจากและการตัดสินΓ x : τดังนั้นถ้าเรารู้ว่าตัวแปรxมีประเภทของτและการแสดงออกeมีชนิดτ'เรายังไม่ทราบชนิดของฟังก์ชั่นที่ใช้เวลาที่และผลตอบแทนx eนี่แค่บอกเราว่าต้องทำอย่างไรถ้าเรารู้ว่าฟังก์ชั่นประเภทใดที่ใช้และฟังก์ชั่นนั้นกลับมาดังนั้นมันจึงไม่น่าแปลกใจเลย

อันถัดไปจะบอกวิธีจัดการกับletข้อความ ถ้าคุณรู้ว่าการแสดงออกบางอย่างe₁มีประเภทτตราบใดที่xมีการพิมพ์σแล้วletแสดงออกซึ่งในประเทศที่ผูกxกับค่าของชนิดσจะทำให้มีประเภทe₁ τที่จริงนี่แค่บอกคุณว่าคำสั่ง let เป็นหลักช่วยให้คุณขยายบริบทด้วยการโยงใหม่ - ซึ่งเป็นสิ่งที่letทำ!

[Inst]กฎเกี่ยวกับการย่อยการพิมพ์ มันบอกว่าถ้าคุณมีค่าของชนิดσ'และเป็นชนิดย่อยของσ( แสดงให้เห็นถึงความสัมพันธ์ที่สั่งซื้อบางส่วน) แล้วว่าการแสดงออกเป็นยังσประเภท

กฎสุดท้ายเกี่ยวข้องกับประเภททั่วไป การกันอย่างรวดเร็ว: ตัวแปรอิสระคือตัวแปรที่ไม่ได้ถูกนำเสนอโดยคำสั่ง let หรือ lambda ภายในนิพจน์บางตัว; ตอนนี้การแสดงออกนี้ขึ้นอยู่กับมูลค่าของตัวแปรอิสระจากบริบทของมันกฎบอกว่าถ้ามีตัวแปรบางอย่างαที่ไม่ "ฟรี" ในทุกสิ่งในบริบทของคุณแล้วมันจะปลอดภัยที่จะพูดว่าการแสดงออกใด ๆ ที่คุณรู้e : σจะมีประเภทที่ใด ๆαค่าของ

วิธีใช้กฎ

ดังนั้นเมื่อคุณเข้าใจสัญลักษณ์แล้วคุณจะทำอย่างไรกับกฎเหล่านี้ ทีนี้คุณสามารถใช้กฎเหล่านี้เพื่อหาประเภทของค่าต่าง ๆ เมื่อต้องการทำสิ่งนี้ดูที่นิพจน์ของคุณ (พูดf x y) และค้นหากฎที่มีข้อสรุป (ส่วนล่าง) ที่ตรงกับคำสั่งของคุณ ลองเรียกสิ่งที่คุณพยายามค้นหา "เป้าหมาย" ของคุณ ในกรณีนี้คุณจะดูกฎที่ลงท้ายe₀ e₁ด้วย เมื่อคุณพบสิ่งนี้ตอนนี้คุณต้องค้นหากฎที่พิสูจน์ทุกอย่างเหนือบรรทัดของกฎนี้ โดยทั่วไปสิ่งเหล่านี้สอดคล้องกับประเภทของนิพจน์ย่อยดังนั้นคุณจะต้องแสดงซ้ำในบางส่วนของการแสดงออก คุณเพียงทำเช่นนี้จนกว่าคุณจะเสร็จสิ้นการพิสูจน์ต้นไม้ซึ่งจะช่วยให้คุณพิสูจน์ประเภทของการแสดงออกของคุณ

ดังนั้นกฎเหล่านี้ทั้งหมดจึงมีการระบุอย่างชัดเจนและในรายละเอียดทางคณิตศาสตร์ตามปกติ: P - วิธีการหาประเภทของการแสดงออก

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

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


5
\ alpha เป็นตัวแปรประเภทที่ไม่มีอิสระไม่ใช่ตัวแปรปกติ ดังนั้นในการอธิบายกฎทั่วไปจะต้องอธิบายให้มากขึ้น
nponeccop

2
@ nponeccop: อืมจุดดี ฉันไม่เคยเห็นกฎเฉพาะนั้นมาก่อน คุณช่วยอธิบายให้ถูกต้องได้มั้ย
Tikhon Jelvis

8
@TikhonJelvis: มันเป็นจริงตรงไปตรงมาสวยก็ช่วยให้คุณสามารถพูดคุย (สมมติΓ = {x : τ}) λy.x : σ → τไป∀ σ. σ → τแต่ไม่ถึง∀ τ. σ → τเพราะเป็นตัวแปรอิสระในτ Γบทความ Wikipedia เกี่ยวกับHMอธิบายได้ค่อนข้างดี
Vitus

7
ฉันเชื่อว่าส่วนหนึ่งของคำตอบที่เกี่ยวข้อง[Inst]นั้นไม่ถูกต้อง นี้เป็นเพียงความเข้าใจของฉันเพื่อให้ห่างไกล แต่ sigmas ในที่[Inst]และ[Gen]กฎระเบียบที่ไม่ได้หมายถึงประเภท แต่ประเภทรูปแบบ ดังนั้นโอเปอเรเตอร์คือการสั่งซื้อบางส่วนที่ไม่เกี่ยวข้องกับการพิมพ์ย่อยตามที่เราทราบจากภาษา OO มันเกี่ยวข้องกับค่า polymorphic id = λx. xเช่น id = ∀x. λx. xไวยากรณ์เต็มรูปแบบสำหรับฟังก์ชั่นดังกล่าวจะเป็น ตอนนี้เราสามารถเห็นได้ชัดว่าไม่มีid2 = ∀xy. λx. xที่ไหนyใช้ จากนั้นid2 ⊑ idซึ่งเป็นสิ่งที่[Inst]กฎกล่าว
Ionuț G. Stan

71

ถ้าอย่างน้อยก็มีคนบอกฉันได้ว่าจะเริ่มมองหาที่ไหนเพื่อเข้าใจความหมายของสัญลักษณ์ทะเลนี้

ดู " พื้นฐานการปฏิบัติของภาษาโปรแกรม " บทที่ 2 และ 3 ในรูปแบบของตรรกะผ่านการตัดสินและการพิสูจน์ หนังสือเล่มนี้มีวางจำหน่ายแล้วใน Amazon

บทที่ 2

คำจำกัดความอุปนัย

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

2.1 การตัดสิน

เราเริ่มต้นด้วยความคิดของการตัดสินหรือยืนยันเกี่ยวกับวัตถุวากยสัมพันธ์ เราจะใช้ประโยชน์จากการตัดสินหลายรูปแบบรวมถึงตัวอย่างเช่นสิ่งเหล่านี้:

  • n nat - nเป็นจำนวนธรรมชาติ
  • n = n1 + n2 - nคือผลรวมของn1และn2
  • τ type - τเป็นประเภท
  • e : τ - นิพจน์eมีประเภทτ
  • ev - นิพจน์eมีค่าv

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


53

ฉันจะเข้าใจกฎ Hindley-Milner ได้อย่างไร

Hindley-Milner เป็นชุดของกฎในรูปแบบของแคลคูลัสตามลำดับ (ไม่ใช่การหักตามธรรมชาติ) ที่แสดงให้เห็นว่าเราสามารถอนุมานประเภท (ทั่วไป) ของโปรแกรมจากการสร้างโปรแกรมโดยไม่ต้องมีการประกาศอย่างชัดเจน

สัญลักษณ์และสัญลักษณ์

อันดับแรกให้อธิบายสัญลักษณ์และหารือเกี่ยวกับลำดับความสำคัญของโอเปอเรเตอร์

  • 𝑥คือตัวระบุ (อย่างไม่เป็นทางการชื่อตัวแปร)
  • :หมายถึงประเภทของ (อย่างไม่เป็นทางการตัวอย่างของหรือ "is-a")
  • 𝜎 (sigma) เป็นนิพจน์ที่เป็นตัวแปรหรือฟังก์ชัน
  • ดังนั้น𝑥: 𝜎อ่าน " 𝑥 is-a 𝜎 "
  • ∈หมายถึง "เป็นองค์ประกอบของ"
  • 𝚪 (Gamma) คือสภาพแวดล้อม
  • (เครื่องหมายยืนยัน) หมายถึงการยืนยัน (หรือพิสูจน์ แต่บริบท "การยืนยัน" อ่านได้ดีขึ้น)
  • ⊦Γ 𝑥 : σจึงอ่าน "Γอ้าง𝑥ว่าเป็น-A σ "
  • 𝑒เป็นตัวอย่างที่เกิดขึ้นจริง (องค์ประกอบ) ประเภทσ
  • 𝜏 (tau) เป็นประเภท: พื้นฐาน, ตัวแปร ( 𝛼 ), ฟังก์ชัน𝜏 → 𝜏 ' , หรือผลิตภัณฑ์𝜏 × 𝜏' (ไม่ได้ใช้ผลิตภัณฑ์ที่นี่)
  • 𝜏 → 𝜏 'เป็นประเภทการทำงานที่ 𝜏และ𝜏'เป็นประเภทที่อาจแตกต่างกัน
  • λ𝑥.𝑒วิธีλ (แลมบ์ดา) เป็นฟังก์ชั่นที่ไม่ระบุชื่อที่ใช้อาร์กิวเมนต์𝑥และผลตอบแทนการแสดงออก, 𝑒

  • ให้ 𝑥 = 𝑒₀ ใน 𝑒₁วิธีการในการแสดงออก𝑒₁แทน𝑒₀ใดก็ตามที่𝑥ปรากฏ

  • หมายถึงองค์ประกอบก่อนหน้าเป็นประเภทย่อย (ทางการ - คลาสย่อย) ขององค์ประกอบหลัง

  • 𝛼เป็นตัวแปรชนิด
  • 𝛼.𝜎เป็นชนิดตัวแปรอาร์กิวเมนต์∀ (สำหรับทั้งหมด), 𝛼 , ส่งคืน𝜎นิพจน์
  • free (𝚪)หมายถึงไม่ได้เป็นองค์ประกอบของตัวแปรประเภทอิสระของ 𝚪 ที่กำหนดไว้ในบริบทด้านนอก (ตัวแปรที่ถูกผูกไว้สามารถทดแทนได้)

ทุกอย่างที่อยู่เหนือเส้นคือหลักฐานทุกอย่างด้านล่างคือข้อสรุป ( Per Martin-Löf )

ลำดับความสำคัญตามตัวอย่าง

ฉันได้นำตัวอย่างที่ซับซ้อนมากขึ้นบางส่วนจากกฎและใส่วงเล็บที่ซ้ำซ้อนที่แสดงความสำคัญกว่า:

  • 𝑥: 𝜎 ∈ 𝚪 สามารถเขียนได้(𝑥: 𝜎) ∈ 𝚪
  • Γ⊦ 𝑥 : σสามารถเขียนΓ⊦ ( 𝑥 : σ )

  • ⊦⊦ ให้ 𝑥 = 𝑒₀ ใน 𝑒₁ : 𝜏 เทียบเท่ากัน 𝚪 ⊦ (( อนุญาต ( 𝑥 = 𝑒₀ ) ใน 𝑒₁ ): 𝜏 )

  • 𝚪 ⊦ 𝜆𝑥.𝑒 : 𝜏 → 𝜏 'เทียบเท่ากัน 𝚪 ⊦ (( 𝜆𝑥.𝑒 ): ( 𝜏 → 𝜏' ))

จากนั้นช่องว่างขนาดใหญ่ที่แยกคำแถลงยืนยันและเงื่อนไขอื่น ๆ ระบุชุดของเงื่อนไขเบื้องต้นและในที่สุดเส้นแนวนอนที่แยกหลักฐานจากข้อสรุปนำมาซึ่งจุดสิ้นสุดของลำดับความสำคัญ

กฎระเบียบ

สิ่งที่ตามมาที่นี่คือการตีความกฎภาษาอังกฤษแต่ละข้อตามด้วยการพูดซ้ำอย่างหลวม ๆ และคำอธิบาย

ตัวแปร

ไดอะแกรมลอจิก VAR

รับ𝑥เป็นประเภทของ 𝜎 (sigma), องค์ประกอบของ 𝚪 (แกมมา),
สรุป 𝚪 ยืนยัน𝑥คือ 𝜎

ใส่อีกวิธีหนึ่งใน 𝚪 เรารู้ว่า𝑥เป็นประเภท 𝜎 เพราะ𝑥เป็นประเภท 𝜎 ใน 𝚪

นี่คือพื้นซ้ำซาก ชื่อตัวระบุเป็นตัวแปรหรือฟังก์ชั่น

ฟังก์ชั่นการใช้งาน

APP ลอจิกไดอะแกรม

กำหนด 𝚪 asserts 𝑒₀เป็นประเภทการใช้งานและ 𝚪 asserts 𝑒₁คือ 𝜏
สรุป 𝚪 ยืนยันการใช้ฟังก์ชัน𝑒₀ถึง𝑒₁เป็นประเภท 𝜏 '

ในการย้ำกฎเรารู้ว่าฟังก์ชั่นการใช้งานส่งคืนประเภท type 'เพราะฟังก์ชั่นมีประเภท 𝜏 → 𝜏' และได้รับการโต้แย้งประเภท 𝜏

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

ฟังก์ชั่นนามธรรม

ABS Logic Diagram

รับ 𝚪 และ𝑥ของประเภท 𝜏 asserts 𝑒เป็นประเภท conclud '
สรุป 𝚪 ยืนยันฟังก์ชั่นที่ไม่ระบุชื่อ 𝜆 ของ𝑥การแสดงออกกลับ𝑒เป็นประเภท 𝜏 → 𝜏'

อีกครั้งเมื่อเราเห็นฟังก์ชั่นที่รับ𝑥และส่งคืนนิพจน์𝑒เรารู้ว่ามันเป็นประเภท 𝜏 → 𝜏 'เพราะ𝑥 (a 𝜏) ยืนยันว่า𝑒คือ 𝜏'

หากเรารู้ว่า𝑥เป็นประเภท 𝜏 ดังนั้นนิพจน์𝑒เป็นประเภท 𝜏 'ดังนั้นฟังก์ชันของ𝑥นิพจน์ที่กลับมา𝑒เป็นประเภท𝑒→ 𝜏'

ขอประกาศตัวแปร

LET ลอจิกไดอะแกรม

รับ 𝚪 asserts 𝑒₀, ของประเภท 𝜎, และ 𝚪 และ𝑥, ของประเภท 𝜎, asserts 𝑒₁ของประเภท 𝜏
สรุป 𝚪 asserts let𝑥 = in𝑒₀𝑒₁ของประเภท 𝜏

อย่างหลวม ๆ bound ถูกผูกไว้กับ𝑒₀ in 𝑒₁ (a 𝜏) เพราะ𝑒₀คือ 𝜎 และ𝑥เป็น 𝜎 ที่อ้างว่า𝑒₁คือ 𝜏

นี่หมายความว่าถ้าเรามีนิพจน์𝑒₀นั่นคือ 𝜎 (เป็นตัวแปรหรือฟังก์ชั่น) และชื่อบางชื่อ𝑥, ยัง 𝜎 และการแสดงออกของ 𝜏 ประเภท 𝜏 แล้วเราสามารถแทนที่𝑒₀สำหรับ𝑥ทุกที่ที่ปรากฏภายใน ของ𝑒₁

instantiation

INST Logic Diagram

รับ 𝚪 asserts 𝑒ของ type 𝜎 'และ 𝜎' เป็น subtype ของ 𝜎
summe 𝚪 asserts 𝑒เป็น type 𝜎

การแสดงออก𝑒เป็นประเภทผู้ปกครอง 𝜎 เพราะการแสดงออก𝑒เป็นประเภทย่อย 𝜎 'และ 𝜎 เป็นประเภทผู้ปกครองของ 𝜎'

หากอินสแตนซ์เป็นประเภทที่เป็นประเภทย่อยของประเภทอื่นแล้วมันก็เป็นอินสแตนซ์ของประเภทซุปเปอร์ที่ - ประเภททั่วไปมากขึ้น

ลักษณะทั่วไป

ไดอะแกรมลอจิก GEN

รับ 𝚪 asserts 𝑒คือ 𝜎 และ 𝛼 ไม่ได้เป็นองค์ประกอบของตัวแปรอิสระของ 𝚪,
สรุป 𝚪 asserts type, พิมพ์สำหรับนิพจน์อาร์กิวเมนต์ทั้งหมด 𝛼 คืนค่า 𝜎 expression

ดังนั้นโดยทั่วไป𝑒ถูกพิมพ์ 𝜎 สำหรับตัวแปรอาร์กิวเมนต์ทั้งหมด (𝛼) ที่ส่งคืน because เพราะเรารู้ว่า𝑒คือ 𝜎 และ 𝛼 ไม่ใช่ตัวแปรอิสระ

ซึ่งหมายความว่าเราสามารถทำให้โปรแกรมทั่วไปยอมรับทุกประเภทสำหรับข้อโต้แย้งที่ไม่ได้ถูกผูกไว้ในขอบเขตที่มีอยู่ (ตัวแปรที่ไม่ใช่ของท้องถิ่น) ตัวแปรที่ผูกไว้เหล่านี้สามารถทดแทนได้

วางมันทั้งหมดเข้าด้วยกัน

ด้วยสมมติฐานบางประการ (เช่นไม่มีตัวแปรอิสระ / ไม่ได้กำหนดสภาวะแวดล้อมที่รู้จัก) เรารู้ประเภทของ:

  • องค์ประกอบอะตอมของโปรแกรมของเรา (ตัวแปร)
  • ค่าที่ส่งคืนโดยฟังก์ชั่น (Function Application)
  • ฟังก์ชั่นสร้าง (ฟังก์ชั่นนามธรรม),
  • let bindings (ให้ประกาศตัวแปร)
  • ประเภทหลักของอินสแตนซ์ (การสร้างอินสแตนซ์) และ
  • นิพจน์ทั้งหมด (ทั่วไป)

ข้อสรุป

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


1
บทสรุปที่ดีของ Aaron!
bhurlow

48

สัญกรณ์มาจากการหักธรรมชาติ

⊢สัญลักษณ์ที่เรียกว่าประตูหมุน

กฎ 6 ข้อนั้นง่ายมาก

Var กฎเป็นกฎที่ค่อนข้างไม่สำคัญ - มันบอกว่าถ้าประเภทสำหรับตัวระบุมีอยู่ในสภาพแวดล้อมประเภทของคุณแล้วให้อนุมานประเภทที่คุณเพิ่งนำมาจากสภาพแวดล้อมที่เป็นอยู่

Appกฎกล่าวว่าหากคุณมีตัวระบุสองตัวe0และe1สามารถอนุมานประเภทของพวกเขาได้คุณสามารถอนุมานประเภทของแอปพลิเคชันe0 e1ได้ กฎอ่านเช่นนี้ถ้าคุณรู้ว่าe0 :: t0 -> t1และe1 :: t0(คน t0 เดียวกัน!) t1แล้วโปรแกรมเป็นอย่างดีพิมพ์และประเภทคือ

AbsและLetเป็นกฎในการอนุมานประเภทของ lambda-abstraction และ let-in

Inst กฎบอกว่าคุณสามารถแทนที่ประเภทด้วยประเภทที่น้อยกว่าทั่วไป


4
นี่คือแคลคูลัสต่อเนื่องไม่ใช่การหักตามธรรมชาติ
Roman Cheplyaka

12
@ RomanCheplyaka ดีสัญกรณ์มากเหมือนกัน บทความวิกิพีเดียมีการเปรียบเทียบที่น่าสนใจของทั้งสองเทคนิค: en.wikipedia.org/wiki/Natural_deduction#Sequent_calculus แคลคูลัสตามลำดับเกิดขึ้นเพื่อตอบสนองโดยตรงต่อความล้มเหลวของการหักตามธรรมชาติดังนั้นหากคำถามคือ "สัญกรณ์นี้มาจากไหน" จากนั้น "การหักตามธรรมชาติ" เป็นคำตอบที่ถูกต้องทางเทคนิคมากขึ้น
Dan Burton

2
@ RomanCheplyaka ข้อควรพิจารณาอีกประการหนึ่งคือแคลคูลัสที่ต่อเนื่องนั้นเป็นวากยสัมพันธ์อย่างแท้จริง กฎข้อแรกสมมติว่าบริบทเป็นเซตในขณะที่อยู่ในแคลคูลัสตามลำดับมันเป็นโครงสร้างประโยคที่ง่ายกว่า
nponeccop

@Cheplyaka จริงๆแล้วไม่มีมันมีบางอย่างที่ดูเหมือนว่า "ต่อเนื่อง" แต่ไม่ใช่แคลคูลัสตามลำดับ Haper พัฒนาความเข้าใจในเรื่องนี้ในหนังสือเรียนของเขาว่าเป็น นี่คือการหักตามธรรมชาติ
Philip JF

15

มีสองวิธีในการคิด e: σ หนึ่งคือ "นิพจน์ e มีประเภทσ" อีกอย่างคือ "คู่ที่สั่งซื้อของการแสดงออก e และประเภทσ"

ดูΓเป็นความรู้เกี่ยวกับประเภทของนิพจน์ที่นำมาใช้เป็นชุดของการแสดงออกและประเภทคู่ e: σ

ประตูหมุน⊢หมายความว่าจากความรู้ทางด้านซ้ายเราสามารถสรุปสิ่งที่ถูกต้องได้

กฎข้อแรก [Var] สามารถอ่านได้:
หากความรู้ของเราΓมีคู่ e: σดังนั้นเราสามารถอนุมานจากΓที่ e มีประเภทσ

สามารถอ่านกฎที่สอง [แอป]:
หากเราจากΓสามารถอนุมานได้ว่า e_0 มีประเภทτ→τ 'และเราจากΓสามารถอนุมานได้ว่า e_1 มีประเภทτดังนั้นเราจากΓสามารถอนุมานว่า e_0 e_1 มี พิมพ์τ '

เป็นเรื่องปกติที่จะเขียนΓ, e: σแทนที่จะเป็นΓ∪ {e: σ}

กฎข้อที่สาม [Abs] สามารถอ่านได้:
หากเราจากΓที่ขยายด้วย x: τสามารถอนุมานได้ว่า e มีประเภทτ 'ดังนั้นเราจากΓสามารถอนุมานได้ว่าλx.eมีประเภทτ→τ'

กฎข้อที่สี่ [ให้] ถูกปล่อยให้เป็นแบบฝึกหัด :-)

กฎข้อที่ห้า [Inst] สามารถอ่านได้:
หากเราจากΓสามารถอนุมานได้ว่า e มีประเภทσ 'และσ' เป็นประเภทย่อยของσดังนั้นเราจากΓสามารถอนุมานว่า e มีประเภทσ

กฎข้อที่หกและสุดท้าย [Gen] สามารถอ่านได้:
ถ้าเราจากΓสามารถอนุมานได้ว่า e มีประเภทσและαไม่ใช่ตัวแปรประเภทอิสระในประเภทใด ๆ ในΓจากนั้นเราจากΓสามารถอนุมานว่า e มีประเภท ∀ασ

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