条件

时间:2016-08-02 14:44:08

标签: isabelle rewriting

在我的理论中,我有一些更大的定义,我从中使用引理得出一些简单的属性。

我的问题是,简化器不使用派生属性的引理,我必须手动实例化它们。有没有办法让这更自动化?

最小的例子如下所示:

definition complexFact :: "int ⇒ int ⇒ int ⇒ bool" where
"complexFact x y z ≡ x = y + z"

lemma useComplexFact: "complexFact x y z ⟹ x = y + z"
by (simp add: complexFact_def)

lemma example_1:
assumes cf: "complexFact a b c"
shows "a = b + c"
apply (simp add: cf useComplexFact) (* easy, works *)
done

lemma example_2a:
assumes cf: "complexFact a b c"
shows "a - b = c"
apply (simp add: cf useComplexFact) (* does not work *)
oops

lemma example_2b:
assumes cf: "complexFact a b c"
shows "a - b = c"
apply (simp add: useComplexFact[OF cf]) (* works *)
done

lemma example_2c:
assumes cf: "complexFact a b c"
shows "a - b = c"
apply (subst useComplexFact) (* manually it also works*)
apply (subst cf)
apply simp+
done

我在参考手册中找到了以下段落,所以我想我可以用自定义求解器解决我的问题。 但是,我从未真正触及Isabelle的内部ML部分,也不知道从哪里开始。

  

重写不会实例化未知数。例如,单独重写   不能证明a∈?A因为这需要实例化?A。该   然而,求解器是一种任意的策略,可以实例化未知数   随心所欲。这是Simplifier可以处理的唯一方法   条件重写规则,其条件包含额外的变量。

1 个答案:

答案 0 :(得分:3)

Isabelle简化器本身从不在条件重写规则的假设中实例化未知数。但是,解算器可以做到这一点,最可靠的是assumption。因此,如果complex_fact a b c字面上出现在目标的假设中(而不是添加到带有simp add:[simp]的simpset),则假设求解器会启动并实例化未知数。但是,它只会在假设中使用complex_fact的第一个实例。因此,如果有几个,它将不会尝试所有这些。总之,最好写

lemma
  assumes cf: "complexFact a b c"
  shows "a = b + c"
  using cf
  apply(simp add: useComplexFact)

您的示例的第二个问题是a = b + c abc是免费的,这不是一个好的重写规则,因为头上的符号是左侧不是常数,而是自由变量a。因此,简化器不会使用等式a = b + ca替换为b + c,而是用a = b + c替换等式True的字面值。您可以在simplifer的跟踪中看到此预处理(使用using [[simp_trace]]在本地启用它)。这就是为什么example_1有效而其他人无效的原因。如果您可以更改左侧,使得头部符号有一个常量,那么无需编写自定义求解器就可以实现一些不错的证明自动化。

此外,您可以使用useComplexFact作为销毁规则来执行某种(有限)形式的前向推理。也就是说,

using assms
apply(auto dest!: useComplexFact)

在某些情况下也可以使用。但是,这非常接近于在可伸缩性方面展开定义。