gpt4 book ai didi

haskell - 如何读取这个GHC核心 "proof"?

转载 作者:行者123 更新时间:2023-12-01 22:51:36 26 4
gpt4 key购买 nike

我写了一小段 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中的第一个 Actor :

  • 做什么 dt_dK6 , dt1_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 ...)_R 开始。这是一个类型构造函数应用程序。它解除了 x_aIX ~# 'Nat.Odd 的证明至Nat.ParNat x_aIX ~# Nat.ParNat 'Nat.OddR意味着它代表性地执行此操作,意味着类型是同构但不相同(在本例中它们是相同的,但我们不需要这些知识来执行转换)。

现在我们看证明的主体(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_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 .

第二个更复杂的 Actor 阵容有点难计算,但应该遵循相同的原则。

关于haskell - 如何读取这个GHC核心 "proof"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26524223/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com