当且仅当它解决当前目标时应用方法

时间:2013-03-08 09:07:20

标签: proof isabelle

有时,当我编写应用式样张时,我想要一种方法来修改证明方法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!])+

它会在第一个目标停止,而这个目标无法解决。

4 个答案:

答案 0 :(得分:3)

Isabelle没有这样的组合,这也是我想念的。通常,如果我用autosimp(具有解决或失败行为)替换fastforceforce次调用,我就可以避免使用这种组合符。

所以,如果你的例子中的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证明方法语言是以某种方式设计的,以达到   证明文本中某些操作方面的“规范”规范。   它排除了任何类型的编程或复杂的控制   有目的的结构。