简化的Idris证明会导致“类型不匹配”错误

时间:2019-08-14 23:57:51

标签: proof idris

我正在通过阅读本书以及本书https://idris-hackers.github.io/software-foundations/pdf/sf-idris-2018.pdf

来学习Idris。

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

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)

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

1 个答案:

答案 0 :(得分:1)

此处Idris仅遵循定义(“简化证明”)。因此,以plus Zero n = n为例。为了简化此类型,plus的定义会有所帮助:一个分支定义plus Zero b = b。因此,我们可以将plus Zero n替换为n,以获取n = n,瞧瞧。另一方面,如果尝试简化plus n Zero = n,则plus的定义中没有分支与plus n Zero匹配。因此,在您提供帮助之前,无法进行任何替换,并且Idris陷入plus n Zero = n的困境。通过对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已在此处停止,但并未替换它。因此,第二个分支没有到达。