简化器不适用于大于10的常量?

时间:2014-02-28 11:31:36

标签: isabelle

为什么Isabelle简化器拒绝证明以下引理?

lemma "n ≠ counter ⟹
  n ≠ Suc counter ⟹
  n ≠ Suc (Suc counter) ⟹
  n ≠ counter + 3 ⟹
  n ≠ counter + 4 ⟹
  n ≠ counter + 5 ⟹
  n ≠ counter + 6 ⟹
  n ≠ counter + 7 ⟹
  n ≠ counter + 8 ⟹ 
  n ≠ counter + 9 ⟹ 
  counter ≤ n ⟹ n < counter + 10 ⟹ False"
  by simp

虽然它证明了一个稍小的引理

lemma "n ≠ counter ⟹
  n ≠ Suc counter ⟹
  n ≠ Suc (Suc counter) ⟹
  n ≠ counter + 3 ⟹
  n ≠ counter + 4 ⟹
  n ≠ counter + 5 ⟹
  n ≠ counter + 6 ⟹
  n ≠ counter + 7 ⟹
  n ≠ counter + 8 ⟹ 
  counter ≤ n ⟹ n < counter + 9 ⟹ False"
  by simp

在我看来,常数10对于简化器来说太大了。是否有一个选项可以增加最大处理常数或另一个解决方法来证明第一个引理?

2 个答案:

答案 0 :(得分:2)

要回答变通方法,可以使用“arith”或“presburger”方法:

lemma "n ≠ counter ⟹
  n ≠ Suc counter ⟹
  n ≠ Suc (Suc counter) ⟹
  n ≠ counter + 3 ⟹
  n ≠ counter + 4 ⟹
  n ≠ counter + 5 ⟹
  n ≠ counter + 6 ⟹
  n ≠ counter + 7 ⟹
  n ≠ counter + 8 ⟹ 
  n ≠ counter + 9 ⟹ 
  counter ≤ n ⟹ n < counter + 10 ⟹ False"
  by presburger (* or by arith *)
在这种情况下,arith也可以工作,但会发出警告(linarith失败),而这个警告不会出现在较小的引理中。应该在某个地方存在相关性,但我不知道为什么simp方法会失败但是......

您可以通过使用尝试多个证明和方法的命令“try”或“try0”来发现这一点。

答案 1 :(得分:2)

感谢另一个答案显示arith可用于证明该定理,因为arith不是try0方法之一。

从所有情况看,来自linarith_trace的此消息为您提供了答案:

neq_limit exceeded (current value is 9), ignoring all inequalities

值10起作用不是因为你使用常量10,而是因为你使用了10个不等式,如下所示。像往常一样,因为我无法向某人证实看起来很明显(从查看源文件),我可能是错的。

我在neq_limit的{​​{1}}上抓了一下,它显示在两个文件中。还有一个适用的示例理论:

下面,我引用上面的文件,并使用Isabelle2013-2/src显示,无论我使用[[simp_trace, linarith_trace]]还是apply(simp only:)apply(arith)simp之间都有很多互动各种线性算术方法。

我删除了第一个答案。如果有人想看看我对(simp only:)所说的内容,以及其他有关尝试追踪事情的事情,可以点击下面某处的edit查看旧条目。

如下所示,无论我使用apply(simp only:)还是apply(arith),我都会收到上面的neq_limit exceeded跟踪消息。

我推测差异在fast_lin_arith.MLlin_arith.ML之间。在fast_lin_arith.ML,第788行有一张支票,不在lin_arith.ML

  val split_neq = count is_neq (map (LA_Data.decomp ctxt) Hs') <= neq_limit
in
  if split_neq then ()
  else
    trace_msg ctxt ("neq_limit exceeded (current value is " ^

这与该文件中的评论有关:

(*the limit on the number of ~= allowed; because each ~= is split
  into two cases, this can lead to an explosion*)
val neq_limit: int Config.T

一般来说,simp与线性算术自动校对方法之间存在很多相互作用,如Arith_Examples.thy中的注释所示。

The @{text arith} method combines them both, and tries other methods 
(e.g.~@{text presburger}) as well.  This is the one that you should use 
in your proofs!

现在,我摆脱了counter + 10引理中不相等的一个(因为它是多余的),这允许simp证明它。

(*_SRC.0_*)    
(*If we get rid of one inequality, and change the <= to <, it works.*)
lemma "(*n ≠ counter ==> *)
       counter < n ==> 
       n ≠ Suc counter ==>
       n ≠ Suc (Suc counter) ==>
       n ≠ counter + 3 ==>
       n ≠ counter + 4 ==>
       n ≠ counter + 5 ==>
       n ≠ counter + 6 ==>
       n ≠ counter + 7 ==>
       n ≠ counter + 8 ==> 
       n ≠ counter + 9 ==>
       n < counter + 10 ==> False"
by(simp)

我在这里展示simp和线性算术策略之间的相互作用。 (Arith_Examples.thy中的评论解释了存在差异。)

(*_SRC.1_*)
lemma "
  n ≠ counter ==>
  n ≠ Suc counter ==>
  n ≠ Suc (Suc counter) ==>
  counter ≤ n ==> 
  n < counter + 3 ==> False"
  using[[simp_trace, linarith_trace]] 
(*Click "1000" at the bottom of the output panel to get it to finish.

  The trace shows that `arith` is called very soon, but that there's also
  a lot of simp rule rewriting, such as with the rule `Groups.add_ac_2`.*)
apply(simp only:)
done

我向您展示了neq_limitapply(simp only:) apply(arith)相同的跟踪消息,但是有一个证据可以通过,而另一个则没有。显然,simp使用一种形式的线性算术策略,arith使用另一种形式。

(*_SRC.2_*)    
lemma "n ≠ counter ==>
       n ≠ Suc counter ==>
       n ≠ Suc (Suc counter) ==>
       n ≠ counter + 3 ==>
       n ≠ counter + 4 ==>
       n ≠ counter + 5 ==>
       n ≠ counter + 6 ==>
       n ≠ counter + 7 ==>
       n ≠ counter + 8 ==> 
       n ≠ counter + 9 ==> 
       counter ≤ n ==> 
       n < counter + 10 ==> False"
  using[[linarith_trace]]
  apply(simp only:)
(*Gets the following error message, and it goes no further:

  Trying to refute subgoal 1...
  neq_limit exceeded (current value is 9), ignoring all inequalities 
*)
oops

(*_SRC.3_*)    
lemma "n ≠ counter ==>
       n ≠ Suc counter ==>
       n ≠ Suc (Suc counter) ==>
       n ≠ counter + 3 ==>
       n ≠ counter + 4 ==>
       n ≠ counter + 5 ==>
       n ≠ counter + 6 ==>
       n ≠ counter + 7 ==>
       n ≠ counter + 8 ==> 
       n ≠ counter + 9 ==> 
       counter ≤ n ==> 
       n < counter + 10 ==> False"
  using[[simp_trace, linarith_trace]]
  apply(arith)
(*Same complaint about "9", but the proof will go through if there's no trace:

  Trying to refute subgoal 1...
  neq_limit exceeded (current value is 9), ignoring all inequalities 
*)
oops