इस जीएचसी कोर "सबूत" को कैसे पढ़ें?


84

मैंने Haskell के इस छोटे से हिस्से को यह पता लगाने के लिए लिखा कि GHC यह कैसे साबित करता है कि प्राकृतिक संख्या के लिए, आप केवल यहां तक ​​कि आधा कर सकते हैं:

{-# LANGUAGE DataKinds, GADTs, KindSignatures, TypeFamilies #-}
module Nat where

data Nat = Z | S Nat

data Parity = Even | Odd

type family Flip (x :: Parity) :: Parity where
  Flip Even = Odd
  Flip Odd  = Even

data ParNat :: Parity -> * where
  PZ :: ParNat Even
  PS :: (x ~ Flip y, y ~ Flip x) => ParNat x -> ParNat (Flip x)

halve :: ParNat Even -> Nat
halve PZ     = Z
halve (PS a) = helper a
  where helper :: ParNat Odd -> Nat
        helper (PS b) = S (halve b)

कोर के प्रासंगिक हिस्से बन जाते हैं:

Nat.$WPZ :: Nat.ParNat 'Nat.Even
Nat.$WPZ = Nat.PZ @ 'Nat.Even @~ <'Nat.Even>_N

Nat.$WPS
  :: forall (x_apH :: Nat.Parity) (y_apI :: Nat.Parity).
     (x_apH ~ Nat.Flip y_apI, y_apI ~ Nat.Flip x_apH) =>
     Nat.ParNat x_apH -> Nat.ParNat (Nat.Flip x_apH)
Nat.$WPS =
  \ (@ (x_apH :: Nat.Parity))
    (@ (y_apI :: Nat.Parity))
    (dt_aqR :: x_apH ~ Nat.Flip y_apI)
    (dt_aqS :: y_apI ~ Nat.Flip x_apH)
    (dt_aqT :: Nat.ParNat x_apH) ->
    case dt_aqR of _ { GHC.Types.Eq# dt_aqU ->
    case dt_aqS of _ { GHC.Types.Eq# dt_aqV ->
    Nat.PS
      @ (Nat.Flip x_apH)
      @ x_apH
      @ y_apI
      @~ <Nat.Flip x_apH>_N
      @~ dt_aqU
      @~ dt_aqV
      dt_aqT
    }
    }

Rec {
Nat.halve :: Nat.ParNat 'Nat.Even -> Nat.Nat
Nat.halve =
  \ (ds_dJB :: Nat.ParNat 'Nat.Even) ->
    case ds_dJB of _ {
      Nat.PZ dt_dKD -> Nat.Z;
      Nat.PS @ x_aIX @ y_aIY dt_dK6 dt1_dK7 dt2_dK8 a_apK ->
        case a_apK
             `cast` ((Nat.ParNat
                        (dt1_dK7
                         ; (Nat.Flip (dt2_dK8 ; Sym dt_dK6))_N
                         ; Nat.TFCo:R:Flip[0]))_R
                     :: Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd)
        of _
        { Nat.PS @ x1_aJ4 @ y1_aJ5 dt3_dKa dt4_dKb dt5_dKc b_apM ->
        Nat.S
          (Nat.halve
             (b_apM
              `cast` ((Nat.ParNat
                         (dt4_dKb
                          ; (Nat.Flip
                               (dt5_dKc
                                ; Sym dt3_dKa
                                ; Sym Nat.TFCo:R:Flip[0]
                                ; (Nat.Flip (dt_dK6 ; Sym dt2_dK8))_N
                                ; Sym dt1_dK7))_N
                          ; Sym dt_dK6))_R
                      :: Nat.ParNat x1_aJ4 ~# Nat.ParNat 'Nat.Even)))
        }
    }
end Rec }

मुझे पता है कि फ्लिप प्रकार के परिवार के उदाहरणों के माध्यम से प्रकारों को कास्टिंग करने का सामान्य प्रवाह है, लेकिन कुछ चीजें हैं जो मैं पूरी तरह से पालन नहीं कर सकता हूं:

  • का मतलब क्या है @~ <Nat.Flip x_apH>_N? क्या यह एक्स के लिए फ्लिप उदाहरण है? इससे अलग कैसे होता है @ (Nat.Flip x_apH)? मुझे दोनों में दिलचस्पी है < >और_N

पहली कास्ट के बारे में halve:

  • क्या करते हैं dt_dK6, dt1_dK7और dt2_dK8खड़े रहते हैं? मैं समझता हूं कि वे कुछ प्रकार के तुल्यता प्रमाण हैं, लेकिन कौन सा है?
  • मैं समझता हूं कि यह Symएक समतुल्यता के पीछे से चलता है
  • क्या करते ;हैं? क्या तुल्यता प्रमाण केवल क्रमिक रूप से लागू होते हैं?
  • ये क्या हैं _Nऔर _Rप्रत्यय हैं?
  • कर रहे हैं TFCo:R:Flip[0]और TFCo:R:Flip[1]फ्लिप के उदाहरण?

6
मुझे कोई पता नहीं है, लेकिन मेरा अनुमान है कि _N और _R नाममात्र और प्रतिनिधित्व वाली भूमिकाएं हैं: haskell.org/ghc/docs/latest/html/users_guide/…
chi

यात्रा stackoverflow.com/questions/6121146/reading-ghc-core उम्मीद है कि आपको एक विचार मिलेगा ..
हेमंत रामफुल

जवाबों:


6

@~ जबरदस्ती आवेदन है।

कोण कोष्ठक अंडरस्क्राइब किए गए अक्षर द्वारा दी गई भूमिका के साथ उनके निहित प्रकार के एक रिफ्लेक्टिव जबरदस्ती को दर्शाते हैं।

इस प्रकार <Nat.Flip x_ap0H>_Nएक समानता प्रमाण है जो नाममात्र के Nat.Flip x_apHबराबर है Nat.Flip x_apH(जैसा कि समान प्रकार न केवल समान प्रतिनिधित्व है)।

PS के पास बहुत सारे तर्क हैं। हम स्मार्ट कंस्ट्रक्टर $WPSको देखते हैं और हम देख सकते हैं कि पहले दो क्रमशः x और y के प्रकार हैं। हमारे पास प्रमाण है कि कंस्ट्रक्टर का तर्क है Flip x(इस मामले में हमारे पास है Flip x ~ Even। हमारे पास फिर साक्ष्य हैं x ~ Flip yऔर y ~ Flip xअंतिम तर्क का एक मूल्य है ParNat x

अब मैं पहले प्रकार के कलाकारों के माध्यम से चलूंगा Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd

हम शुरुआत करते हैं (Nat.ParNat ...)_R। यह एक प्रकार का कंस्ट्रक्टर एप्लिकेशन है। इसका प्रमाण देता x_aIX ~# 'Nat.Oddहै Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd। इसका Rमतलब यह है कि यह प्रतिनिधित्वात्मक रूप से करता है कि प्रकार समरूप हैं लेकिन समान नहीं हैं (इस मामले में वे समान हैं लेकिन हमें कलाकारों के प्रदर्शन के लिए उस ज्ञान की आवश्यकता नहीं है)।

अब हम सबूत के मुख्य शरीर को देखते हैं (dt1_dK7 ; (Nat.Flip (dt2_dK8 ; Sym dt_dK6))_N; Nat.TFCo:R:Flip[0]);का अर्थ है पारगमन यानी क्रम में इन साक्ष्यों को लागू करना।

dt1_dK7का एक प्रमाण है x_aIX ~# Nat.Flip y_aIY

अगर हम देखें (dt2_dK8 ; Sym dt_dK6)dt2_dK8दिखाता है y_aIY ~# Nat.Flip x_aIXdt_dK6प्रकार का है 'Nat.Even ~# Nat.Flip x_aIX। तो Sym dt_dK6प्रकार Nat.Flip x_aIX ~# 'Nat.Evenका (dt2_dK8 ; Sym dt_dK6)है और प्रकार का हैy_aIY ~# 'Nat.Even

इस प्रकार (Nat.Flip (dt2_dK8 ; Sym dt_dK6))_Nका सबूत है कि है Nat.Flip y_aIY ~# Nat.Flip 'Nat.Even

Nat.TFCo:R:Flip[0]फ्लिप का पहला नियम है जो है Nat.Flip 'Nat.Even ~# 'Nat.Odd'

इनको एक साथ रखने से हमें (dt1_dK7 ; (Nat.Flip (dt2_dK8 ; Sym dt_dK6))_N; Nat.TFCo:R:Flip[0])टाइप होता है x_aIX #~ 'Nat.Odd

दूसरी अधिक जटिल कास्ट बाहर काम करने के लिए थोड़ा कठिन है, लेकिन उसी सिद्धांत पर काम करना चाहिए।


वास्तव में मैं सिर्फ उस पोस्ट को देख रहा था कि क्या कोई उस गंदगी का बोध करा सकता है ^ ^ अच्छा किया सर।
गिरि ट्रेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.