簡體   English   中英

如何閱讀GHC核心“證據”?

[英]How to read this GHC Core “proof”?

我寫了一小部分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 }

我知道通過Flip類型系列的實例來轉換類型的一般流程,但有些事情我無法完全遵循:

  • @~ <Nat.Flip x_apH>_N是什么意思? 它是x的Flip實例嗎? 這與@ (Nat.Flip x_apH)什么不同? 我對< >_N感興趣

對於一次投halve

  • dt_dK6dt1_dK7dt2_dK8代表什么? 我知道它們是某種等價證明,但哪個是哪個?
  • 據我所知, Sym向后運行等價
  • 做什么的; 的嗎? 等效證明是否僅按順序應用?
  • 這些_N_R后綴是什么?
  • TFCo:R:Flip[0]TFCo:R:Flip[1] Flip的實例?

@~是脅迫申請。

尖括號表示其所包含類型的反身強制與強調字母給出的作用。

因此<Nat.Flip x_ap0H>_N是相等證明Nat.Flip x_apH等於Nat.Flip x_apH名義上(如等於類型不恰好等於表示)。

PS有很多爭論。 我們看一下智能構造函數$WPS ,我們可以看到前兩個分別是x和y的類型。 我們已經證明構造函數參數是Flip x (在這種情況下我們有Flip x ~ Even 。然后我們有證明x ~ Flip yy ~ Flip x 。最后一個參數是ParNat x的值。

我現在將介紹Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd類型的第一個演員Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd

我們從(Nat.ParNat ...)_R 這是一個類型構造函數應用程序。 它將x_aIX ~# 'Nat.Odd的證明x_aIX ~# 'Nat.OddNat.ParNat x_aIX ~# Nat.ParNat 'Nat.Odd R意味着它表示這意味着類型是同構的但不相同(在這種情況下它們是相同的但我們不需要那些知識來執行演員表)。

現在我們看一下證明的主體(dt1_dK7 ; (Nat.Flip (dt2_dK8 ; Sym dt_dK6))_N; Nat.TFCo:R:Flip[0]) ; 意味着過渡,即按順序應用這些證明。

dt1_dK7x_aIX ~# Nat.Flip y_aIY的證明。

如果我們看(dt2_dK8 ; Sym dt_dK6) dt2_dK8顯示y_aIY ~# Nat.Flip x_aIX dt_dK6的類型為'Nat.Even ~# Nat.Flip x_aIX 所以Sym dt_dK6屬於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))_NNat.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

第二個更復雜的演員陣容有點難以解決,但應該按照相同的原則工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM