我正在通过阅读本书以及本书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)
这是预期的行为-但是建议您能够理解原因。我不知所措,正在寻找提示或如何考虑这一点。
答案 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已在此处停止,但并未替换它。因此,第二个分支没有到达。