在我的理论中,我有一些更大的定义,我从中使用引理得出一些简单的属性。
我的问题是,简化器不使用派生属性的引理,我必须手动实例化它们。有没有办法让这更自动化?
最小的例子如下所示:
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可以处理的唯一方法 条件重写规则,其条件包含额外的变量。
答案 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
a
,b
和c
是免费的,这不是一个好的重写规则,因为头上的符号是左侧不是常数,而是自由变量a
。因此,简化器不会使用等式a = b + c
将a
替换为b + c
,而是用a = b + c
替换等式True
的字面值。您可以在simplifer的跟踪中看到此预处理(使用using [[simp_trace]]
在本地启用它)。这就是为什么example_1
有效而其他人无效的原因。如果您可以更改左侧,使得头部符号有一个常量,那么无需编写自定义求解器就可以实现一些不错的证明自动化。
此外,您可以使用useComplexFact
作为销毁规则来执行某种(有限)形式的前向推理。也就是说,
using assms
apply(auto dest!: useComplexFact)
在某些情况下也可以使用。但是,这非常接近于在可伸缩性方面展开定义。