'nat`类型的'plus`中第二个参数的附加模式匹配

时间:2018-03-18 23:05:57

标签: pattern-matching proof idris dependent-type

我发现plus的{​​{1}}函数已在this way中实现

Nat

我想知道是否有特殊理由不在第二个参数上进行模式匹配,就像这里一样:

total plus : (n, m : Nat) -> Nat
plus Z right        = right
plus (S left) right = S (plus left right)

正如我现在所看到的那样,这种实现会使许多证明和代码中的生活更简单。例如

total plus : (n, m : Nat) -> Nat
plus Z right        = right
plus left Z         = left
plus (S left) right = S (plus left right)

看起来像total plusZeroRightNeutral : (left : Nat) -> left + 0 = left plusZeroRightNeutral Z = Refl plusZeroRightNeutral (S n) = let inductiveHypothesis = plusZeroRightNeutral n in rewrite inductiveHypothesis in Refl

plusZeroLeftNeutral

在现实生活中,我们甚至不需要使用total plusZeroRightNeutral : (left : Nat) -> left + 0 = left plusZeroRightNeutral left = Refl 定理,因为Idris可以自动进行模式匹配(正如在此问题的答案中已经提到的那样:Concatenation of two vectors - why are lengths not treated as commutative?)。

那么为什么不添加额外的案例以使生活更轻松?

1 个答案:

答案 0 :(得分:4)

实际上,只有plusZeroLeftNeutral无法证明Refl

当你使用Refl时,你会说:“这是通过计算得出的”(另一个名称是定义相等或判断相等)。

但我们如何计算left + 0plus left Z类型的Nat?从本质上讲,Idris从上到下处理函数定义子句,在我们的例子中,它首先查看plus Z right子句。在这一点上,Idris需要决定leftZ,但它不能,因为我们没有破坏left。 Idris不能跳过第一个条款并转到plus left Z条款。

现在,对于plus的替代定义,我不需要归纳来证明正确的中立性:

total plusZeroRightNeutral : (left : Nat) -> plus left 0 = left
plusZeroRightNeutral Z = Refl
plusZeroRightNeutral (S _) = Refl

但另一方面,许多证据变得啰嗦,因为他们现在需要更多的模式匹配。让我们来看一下加法的相关性。对plus的原始定义:

,可以证明这一事实
total plusAssoc : (m,n,p : Nat) -> m + (n + p) = m + n + p
plusAssoc Z n p = Refl
plusAssoc (S m) n p = cong $ plusAssoc m n p

这里是修改后的plus的相应证据:

total plusAssoc : (m,n,p : Nat) -> m + (n + p) = m + n + p
plusAssoc Z n p = Refl
plusAssoc (S m) Z p = Refl
plusAssoc (S m) (S n) Z = Refl
plusAssoc (S m) (S n) (S p) = cong $ plusAssoc m (S n) (S p)

这里你被迫破坏plus函数出现的第二个参数只是因为那些块评估,但是你需要将S构造函数移开以便能够利用你的归纳法假设