我发现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?)。
那么为什么不添加额外的案例以使生活更轻松?
答案 0 :(得分:4)
实际上,只有plusZeroLeftNeutral
无法证明Refl
。
当你使用Refl
时,你会说:“这是通过计算得出的”(另一个名称是定义相等或判断相等)。
但我们如何计算left + 0
(plus left Z
类型的Nat
?从本质上讲,Idris从上到下处理函数定义子句,在我们的例子中,它首先查看plus Z right
子句。在这一点上,Idris需要决定left
是Z
,但它不能,因为我们没有破坏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
构造函数移开以便能够利用你的归纳法假设