Idris 简化证明导致 "type mismatch" 错误

Idris proof with simplification causing "type mismatch" error

我正在跟着这本书学习 Idris:https://idris-hackers.github.io/software-foundations/pdf/sf-idris-2018.pdf

我在进入关于简化证明的部分时遇到了障碍(是的,一开始就是这样)。我正在处理的一小段代码是:

namespace Numbers

  data Nat : Type where
    Zero : Numbers.Nat
    Successor : Numbers.Nat -> Numbers.Nat

  plus : Numbers.Nat -> Numbers.Nat -> Numbers.Nat
  plus Zero b = b
  plus (Successor a) b = Successor(plus a b)

这些更简单的证明工作正常:

One : Numbers.Nat
One = Successor Zero

Two : Numbers.Nat
Two = Successor One

Three : Numbers.Nat
Three = Successor Two

proofOnePlusZero : plus One Zero = One
proofOnePlusZero = Refl

proofOnePlusZero' : plus Zero One = One
proofOnePlusZero' = Refl

但是当我尝试复制更复杂的证明时出现错误

-- works
plus_Z_n : (n : Numbers.Nat) -> plus Zero n = n
plus_Z_n n = Refl

-- breaks / errors
plus_Z_n' : (n : Numbers.Nat) -> plus n Zero = n
plus_Z_n' n = Refl

这是错误

When checking right hand side of plus_Z_n' with expected type
        plus n One = Successor n

Type mismatch between
        Successor n = Successor n (Type of Refl)
and
        plus n (Successor Zero) = Successor n (Expected type)

Specifically:
        Type mismatch between
                Successor n
        and
                plus n (Successor Zero)

这是预期的行为 - 但建议是能够理解原因。我不知所措,正在寻找提示或如何考虑这一点。

这里 Idris 只是遵循定义(“简化证明”)。所以取plus Zero n = n。为了简化这种类型,plus 的定义有所帮助:一个分支定义了 plus Zero b = b。所以我们可以用 n 替换 plus Zero n 来得到 n = n,瞧。另一方面,如果试图简化 plus n Zero = nplus 定义中的分支 none 匹配 plus n Zero。因此无法进行替换,并且 Idris 卡在 plus n Zero = n,直到您提供帮助 f.e。通过 n.

上的大小写拆分

更准确地说,如果 Idris 尝试替换 plus x Zero,它会一个接一个地遍历所有分支并尝试匹配它们,就像评估它一样。如果可以匹配,它就会停止。但只有当分支等于plus x Zero时,它才会被替换。所以给出:

plus : Numbers.Nat -> Numbers.Nat -> Numbers.Nat
plus Zero b = b
plus a Zero = a
plus (Successor a) b = Successor(plus a b)

plus1 : plus n Zero = n
plus1 = Refl

这不会编译,因为 plus n Zero 可以 plus Zero b = b 处理,具体取决于 n 是什么。但是因为 n 是未知的,所以 Idris 已经停在这里,但没有替换它。所以第二个分支没有到。