Manuel Eberl 做了最难的部分,我只是回答你关于如何尝试和控制simp 等的问题。
在继续之前,我跑题并澄清另一个网站上所说的内容。 “小费”这个词被用来表示对 M.E. 的赞扬,但它应该是“3 个解释提供了 2 个答案”。如果不向列表发送垃圾邮件,就无法更正邮件列表中的电子邮件。
以下是一些简短的答案:
- 无法保证完全控制
simp,但属性del 和only,如下所示,将多次控制到您想要的程度。要查看它并没有超出您的预期,需要使用跟踪;下面给出了一个跟踪示例。
- 要完全控制证明步骤,您可以使用“受控”
simp、rule、drule 和 erule 以及其他方法。其他人需要提供一份详尽的清单。
- 大多数具有专业知识能够回答“
simp、auto、blast 等的详细证据是什么”的人很少愿意投入工作来回答这个问题。调查 simp 正在做什么可能是一项简单而乏味的工作。
- “黑盒证明”总是可选的,据我所知,如果我们希望它们是并且拥有使它们成为可选的专业知识。使它们成为可选的专业知识通常是一个主要的限制因素。有了专业知识,动力就会成为限制因素。
什么是简单的?它不能取悦所有人
如果你看,你会看到。人们抱怨自动化太多,或者他们抱怨 Isabelle 自动化太少。
自动化永远不会过多,但这是因为对于 Isabelle/HOL,自动化大多是可选的。 没有自动化的可能性使证明变得潜在有趣,但只有没有自动化,在宏伟的计划中,证明只不过是纯粹的乏味。
有only和del属性,可以大部分控制simp。仅从实验痕迹说起,即使simp 也会调用其他证明方法,类似于auto 调用simp、blast 等。
我认为你不能阻止simp 调用线性算术方法。但是线性算术在很多时候并不适用。
设置跟踪,甚至是爆炸跟踪
我在这里的回答很笼统,因为它还试图确定auto 在做什么。 auto 采用的最大方法之一是 blast。
如果您不关心blast 何时被auto 使用或直接调用,则不需要attribute_setups。 Makarius Wenzel 删除了爆炸跟踪,但随后很好地展示了如何实现它的代码。
没有爆破部分,只有declare的使用。在证明中,您可以使用using 而不是declare。拿出你不想要的东西。请务必查看 PIDE Simplifier Trace 面板中的新 simp_trace_new 信息。
attribute_setup blast_trace = {*
Scan.lift
(Parse.$$$ "=" -- Args.$$$ "true" >> K true ||
Parse.$$$ "=" -- Args.$$$ "false" >> K false ||
Scan.succeed true) >>
(fn b => Thm.declaration_attribute (K (Config.put_generic Blast.trace b)))
*}
attribute_setup blast_stats = {*
Scan.lift
(Parse.$$$ "=" -- Args.$$$ "true" >> K true ||
Parse.$$$ "=" -- Args.$$$ "false" >> K false ||
Scan.succeed true) >>
(fn b => Thm.declaration_attribute (K (Config.put_generic Blast.stats b)))
*}
declare[[simp_trace_new mode=full]]
declare[[linarith_trace,rule_trace,blast_trace,blast_stats]]
通过only 和del 尝试和控制简单,随心所欲
我不想在您的问题中使用公式来努力工作。使用 simp,您在 only 中寻找的结果是没有使用您不期望的规则。
查看simp 跟踪,了解已完成哪些基本的重写将始终完成,例如True 和False 的基本重写。如果您甚至不想这样做,那么您必须求助于rule 之类的方法。
查看是否可以完全关闭simp 的起点是apply(simp only:)。
这里有几个例子。我将不得不更加努力地找到一个示例来显示何时自动使用线性算术:
lemma
"a = 0 --> a + b = (b::'a::comm_monoid_add)"
apply(simp only:) (*
ERROR: simp can't apply any magic whatsoever.
*)
oops
lemma
"a = 0 --> a + b = (b::'a::comm_monoid_add)"
apply(simp only: add_0) (*
ERROR: Still can't. Rule 'add_0' is used, but it can't be used first.
*)
oops
lemma
"a = 0 --> a + b = (b::'a::comm_monoid_add)"
apply(simp del: add_0) (*
A LITTLE MAGIC:
It applied at least one rule. See the simp trace. It tried to finish
the job automatically, but couldn't. It says "Trying to refute subgoal 1,
etc.".
Don't trust me about this, but it looks typical of blast. I was under
the impressions that simp doesn't call blast.*)
oops
lemma
"a = 0 --> a + b = (b::'a::comm_monoid_add)"
by(simp) (*
This is your question. I don't want to step through the rules that simp
uses to prove it all.
*)