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 = n
,plus
定义中的分支 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 已经停在这里,但没有替换它。所以第二个分支没有到。
我正在跟着这本书学习 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 = n
,plus
定义中的分支 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 已经停在这里,但没有替换它。所以第二个分支没有到。