伊莎贝尔的双重功能

Double function in Isabelle

我尝试通过 this 教程来学习 Isabelle/HOL。我对双重功能的练习有疑问。我是这样定义的:

fun double :: "nat ⇒ nat" where 
"double 0 = add 0 0" |
"double (Suc m) = Suc(Suc (double m))"

但是当试图证明 double m = 在我的定理中添加 m m 时:

theorem add_d [simp] : "double x = add x x"
apply(induction x)
apply(auto)
done

apply(auto) 永远不会被评估(它的背景是粉红色的(?))。同样的练习要求证明 add 的交换性和结合性,这工作正常。我使用 Isabelle2014 和默认 (Jedit) IDE.

在您评论的代码中,许多定理都有 [simp] 属性,告诉伊莎贝尔将它们添加到简单集。然而,其中一些不适合作为重写规则(由 simpauto 使用),因为它们导致可以再次应用相同规则的术语,从而导致无限循环。从简单集中删除有问题的定理就可以了:

theorem add_d: "double x = add x x"
  apply (induction x)
  apply (auto simp del: add_zero)
done

但更好的解决方案是首先避免将此类定理添加到简单集,例如从声明中删除 [simp] 属性:

lemma add_zero: "add x 0 = add 0 x"
  apply (induction x)
  apply (auto)
done

之后 add_d 不需要 simp del 部分。但是可能需要明确告知其他一些定理才能使用此特定规则,例如这个:

theorem add_com: "add x y = add y x"
  apply (induction x)
  apply (auto simp add: add_zero)
done

请注意,与您的代码相比,如果在别处使用 add_com,则再次删除 [simp] 属性以避免循环重写。

虽然 Alexander 关于 simp-rules 的建议很合理,但让我给出一些进一步的评论。

首先,在您对 double 的定义中,我会将 add 0 0 替换为 0。一般建议:相对于复杂的表达式,更喜欢简单的表达式

其次,Isabelle 的简化器实际上 "smart" 足以处理 AC 重写(即结合律和交换律)而无需循环,即你的两个引理

lemma add_assoc [simp]:
  "add (add x y) z = add x (add y z)"

lemma add_commute [simp]:
  "add x y = add y x"

与简单规则一样好(即,您可以保留 [simp] 属性)。您遇到的循环的原因是您的引理

(*BAD*)
lemma add_zero [simp]:
  "add x 0 = add 0 x"

由于在 simpset(Isabelle 行话,表示 simpauto 等方法使用的所有简化规则集)允许对于无限推导:

add 0 0 = add 0 0 = add 0 0 = ...

我建议将其替换为

lemma add_zero [simp]:
  "add x 0 = x"

那么你所有的证明(前提是它们以正确的顺序陈述)在某种意义上应该是"automatic"

apply (induction ...)
apply auto
done

可以简写为

by (induction ...) (auto)