Idris证明中的案例分析

时间:2019-02-10 10:56:22

标签: pattern-matching proof idris

因此,我使用以下类型来证明Integers的某些属性:

data Number : Type where
    PosN : Nat -> Number
    Zero : Number
    NegN : Nat -> Number

plusPosNeg : Nat -> Nat -> Number
plusPosNeg n m with (cmp n m)
    plusPosNeg (k + S d) k  | CmpGT d = PosN d
    plusPosNeg k k          | CmpEQ = Zero
    plusPosNeg k (k + S d)  | CmpLT d = NegN d

plus : Number -> Number -> Number
plus Zero y = y
plus x Zero = x
plus (PosN k) (PosN j) = PosN (k + j)
plus (NegN k) (NegN j) = NegN (k + j)
plus (PosN k) (NegN j) = plusPosNeg k j
plus (NegN k) (PosN j) = plusPosNeg j k

现在,我想证明Zero是加法的中性元素,从plus的定义来看,这是显而易见的。实际上,Idris接受以下证明:

plusRZeroNeutral : {l : Number} -> plus l Zero = l
plusRZeroNeutral {l = Zero} = Refl
plusRZeroNeutral {l = PosN _} = Refl
plusRZeroNeutral {l = NegN _} = Refl

但是拒绝我首先提出的简短版本:

plusRZeroNeutral : {l : Number} -> plus l Zero = l
plusRZeroNeutral {l} = Refl

我的问题是为什么会这样?查看plus的定义,似乎编译器应该知道,只要将右参数传递给plus的构造函数就没有关系,只要左参数为Zero(反之亦然) 。也许是错误,还是我错过了什么?

1 个答案:

答案 0 :(得分:2)

如果您对l的所有了解只是l(即某个任意参数),那么您将无法再减少plus l Zero,因为您被困在哪个分支上的plus中提取。

当您在例如l = Zero,现在将右侧的类型细化为plus Zero Zero = Zero,可以将其(通过plus的定义)简化为Zero = Zero。构造函数Refl的类型很容易与此精炼结果类型统一,因此子句plusRZeroNeutral {l = Zero} = Refl进行类型检查。

其他分支的处理方式与plusRZeroNeutral的第一个定义的其他子句类似。