在教程 Isabelle / HOL中的编程和证明中,分步说明了两次反转列表的证明会产生原始列表(2.2.4证明过程)。
theorem rev_rev [simp]: "rev(rev xs) = xs"
apply(induction xs)
apply(auto)
遵循自动步骤后,一个子目标仍然存在:
1. V x1 xs.
rev (rev xs) = xs =⇒
rev (app (rev xs) (Cons x1 Nil)) = Cons x1 xs
作者然后说:“为了进一步简化此子目标,建议使用引理。”,并在下面介绍rev_app引理:
lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
就像笔和纸上的证明一样,这仅仅是直觉和实践,而是使人们看到如何简化子目标1并提出像rev_app这样的引理吗?我简直不知道这个引理是如何暗示自己的。
答案 0 :(得分:4)
对于不熟悉正式证据开发的人们来说,这确实是棘手的。随着时间的流逝,人们将学习许多启发式方法来提出潜在引理。
在这种情况下(纯粹是方程式推理),启发式方法通常通过查看子目标的相关常数来起作用。
例如,主要引理描述了rev
/ rev
属性。但是,子目标需要一些有关rev
/ app
的信息。这就是告诉您您需要关于这两个的引理。
不幸的是,其余的只能被描述为“人的创造力”:看到rev(app xs ys) = app (rev ys) (rev xs)
是rev
/ app
上的合理财产。
有许多关于自动检测此类属性的研究,例如IsaHipster。