我尝试通过this教程学习Isabelle / HOL。关于双重功能的练习有问题。我这样定义:
fun double :: "nat ⇒ nat" where
"double 0 = add 0 0" |
"double (Suc m) = Suc(Suc (double m))"
但是当我在我的定理中试图证明双m =加m m时:
theorem add_d [simp] : "double x = add x x"
apply(induction x)
apply(auto)
done
apply(auto)永远不会被评估(它的背景是粉红色的(?))。同样的练习要求证明add的交换性和相关性,这个工作正常。我使用Isabelle2014和默认(Jedit)IDE。
答案 0 :(得分:1)
在评论的代码中,许多定理都有[simp]
属性,告诉Isabelle将它们添加到simpset中。然而,其中一些不适合作为重写规则(由simp
和auto
使用),因为它们导致一个术语可以再次应用相同的规则,从而导致无限循环。从simpset中删除有问题的定理可以解决问题:
theorem add_d: "double x = add x x"
apply (induction x)
apply (auto simp del: add_zero)
done
但更好的解决方案是避免首先将这些定理添加到simpset,例如从声明中删除[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
请注意,与您的代码相比,[simp]
属性会再次被删除,以避免在其他地方使用add_com
时进行循环重写。
答案 1 :(得分:1)
虽然亚历山大关于简单规则的建议是合理的,但我还是要进一步评论。
首先,在您对double
的定义中,我会将add 0 0
替换为0
。作为一般建议:更喜欢简单表达而不是复杂表达。
其次,Isabelle的简化实际上是“聪明”的,足以处理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术语,用于simp
和auto
等方法所使用的所有简化规则集)允许无限推导:
add 0 0 = add 0 0 = add 0 0 = ...
我建议用
替换它lemma add_zero [simp]:
"add x 0 = x"
然后你所有的证据(如果它们以正确的顺序陈述)应该是“自动的”在某种意义上
apply (induction ...)
apply auto
done
可以缩写为
by (induction ...) (auto)