有时,当我编写应用式样张时,我想要一种方法来修改证明方法foo
到
在第一个目标上尝试
foo
。如果它解决了目标,那就好;如果是的话 不解决它,恢复原状并失败。
这出现在以下代码中:
qed (subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail)+
在进一步改变之后,对simp
的调用将不再完全解决目标,然后这将循环。如果我可以指定类似
qed (solve_goal(subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail))+
或(替代建议的synatx)
qed ((subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail)!)+
或(甚至更好的语法)
qed ((subst fibs.simps, (subst fib.simps)?, simp add: nth_zipWith nth_tail)[1!])+
它会在第一个目标停止,而这个目标无法解决。
答案 0 :(得分:3)
Isabelle没有这样的组合,这也是我想念的。通常,如果我用auto
或simp
(具有解决或失败行为)替换fastforce
或force
次调用,我就可以避免使用这种组合符。
所以,如果你的例子中的simp
应该解决目标(没有循环),
qed (subst fibs.simps, (subst fib.simps)?, fastforce simp: nth_zipWith nth_tail)+
可能是一个更强大的变种。
答案 1 :(得分:3)
自Eisbach proof script language出现以来,现在支持此功能。导入"~~/src/HOL/Eisbach/Eisbach"
后,可以替换
apply foo
与
apply (solves ‹foo›)
如果solves
产生任何新目标,该行将失败。这可以与
[1]
结合使用
apply (solves ‹(auto)[1]›)
如果需要。
solves
的定义实际上非常简单:
method solves methods m = (m; fail)
答案 2 :(得分:1)
虽然没有可用的内置策略或组合器,但您可以按照以下方式自行实施:
ML {*
fun solved_tac thm =
if nprems_of thm = 0 then Seq.single thm else Seq.empty
*}
method_setup solved = {*
Scan.succeed (K (SIMPLE_METHOD solved_tac))
*}
这会创建一个新方法solved
,如果当前目标已完全解决,则会成功;如果仍有一个或多个子目标,则会失败。
例如,它可以用于:
lemma "a ∨ ¬ a "
apply ((rule disjI1, solved) | (simp, solved))
done
如果没有solved
条款,Isabelle将会选择rule disjI1
步骤的apply
一侧,为您留下无法解决的目标。在每一方使用solved
子句时,Isabelle会尝试使用rule disjI1
,当它无法解决目标时,会切换到simp
然后成功。
这可以通过使用Isabelle的(...)[1]
语法来解决个人目标。例如,以下语句将尝试使用simp
解决尽可能多的子目标,但如果simp
无法完全解决它,则会保持子目标不变:
apply ((simp, solved)[1])+
答案 3 :(得分:0)
伊莎贝尔的伊萨尔语不提供这一特征;这是故意的而不是错误,正如on the isabelle developer list所述:
Isar证明方法语言是以某种方式设计的,以达到 证明文本中某些操作方面的“规范”规范。 它排除了任何类型的编程或复杂的控制 有目的的结构。