脆弱规则在Isabelle中的应用

脆弱规则在Isabelle中的应用,isabelle,isar,Isabelle,Isar,为了更好地理解Isar和战术证明之间的对应关系,我正在使用Isabelle/HOL教程中的一个例子 这是一个有效的版本: lemma rtrancl_converseD: "(x,y) ∈ (r ^-1 )^* ⟹ (y,x) ∈ r^* " proof (induct y rule: rtrancl_induct) case base then show ?case .. next case (step y z) then have "(z, y) ∈

为了更好地理解Isar和战术证明之间的对应关系,我正在使用Isabelle/HOL教程中的一个例子

这是一个有效的版本:

lemma rtrancl_converseD: "(x,y) ∈ (r ^-1 )^* ⟹ (y,x) ∈ r^* "
proof (induct y rule: rtrancl_induct)
  case base
  then show ?case ..
next case (step y z)
  then have "(z, y) ∈ r" using rtrancl_converseD by simp 
  with `(y,x)∈ r^*` show "(z,x) ∈ r^*" using [[unify_trace_failure]]
    apply (subgoal_tac "1=(1::nat)")
    apply (rule converse_rtrancl_into_rtrancl)
      apply simp_all
    done
qed
我想将
转换成
来证明
(?a,?b)∈ ?R⟹ (?b,?c)∈ ?r^*⟹ (?a,?c)∈ ?r^*

但是如果没有看似荒谬的
apply(子目标“1=(1::nat)”,
将此错误与

Clash: r =/= Transitive_Closure.rtrancl 
Failed to apply proof method⌂:
using this:
    (y, x) ∈ r^*
    (z, y) ∈ r
goal (1 subgoal):
 1. (z, x) ∈ r^*
如果我完全实例化规则
apply(规则转换为[z y r x的])
这将变成
Clash:z\uuuuuuu=/=ya\uuu


这就给我留下了三个问题:为什么这个具体案例会破裂?我怎样才能修好它?既然我无法真正理解unify_trace_failure消息想要告诉我什么,我如何才能找出在这些情况下出现了什么问题。

规则
-战术通常对前提的顺序很敏感。
中的前提顺序将\u rtrancl\u转换为\u rtrancl
并且在证明状态下不匹配。使用
rotate\u tac
在证明状态下切换前提的顺序将使它们与规则匹配,这样您就可以像这样直接应用
fact

... show "(z,x) ∈ r^*" 
  apply (rotate_tac)
  apply (fact converse_rtrancl_into_rtrancl)
done
  apply (rotate_tac)
  apply (erule converse_rtrancl_into_rtrancl)
  apply (assumption)
或者,如果您想包含某种
规则
策略,则如下所示:

... show "(z,x) ∈ r^*" 
  apply (rotate_tac)
  apply (fact converse_rtrancl_into_rtrancl)
done
  apply (rotate_tac)
  apply (erule converse_rtrancl_into_rtrancl)
  apply (assumption)
(我个人在日常工作中从未使用过应用脚本。因此,应用风格大师可能知道处理这种情况的更优雅的方法。)


关于您的
1=(1::nat)
/
simp\u all
fix:

整个目标可以通过
simp\u all
直接解决。因此,尝试添加诸如
1=1
之类的内容可能并没有真正告诉您其他方法对解决证明有多大贡献

然而,额外的假设似乎实际上有助于Isabelle正确地匹配
将\u rtrancl\u转换为\u rtrancl
。(不要问我为什么!)因此,我们确实可以通过添加这个虚假假设,然后使用
refl
再次消除它来规避这个问题,如:

apply (subgoal_tac "1=(1::nat)")
  apply (erule converse_rtrancl_into_rtrancl)
  apply (assumption)
apply (rule refl)
当然,这看起来并不特别优雅



[[unify\u trace\u failure]]
只有在熟悉Nipkow高阶统一算法的内部工作原理的情况下才可能真正有用。(我不是。)我认为未来的启示是,我们必须仔细研究某些战术的前提顺序(而不是统一的调试输出)。

我在Isar参考6.4.3中找到了一个解释

with b1..bn
命令相当于来自b1..bn的
和此
,即它进入证明链接模式,将它们作为(结构化)假设添加到证明方法中

基本的证明方法(如规则)要求给出多个事实 按照它们的正确顺序,对应于 涉及的规则。请注意,可以使用 例如,类似于from和a以及b。这涉及到 平凡规则PROPψ=⇒ PROPψ,在Isabelle/Pure中绑定为“u” (下划线)

自动化方法(如simp或auto)只需插入任何给定的事实 在他们正常操作之前。取决于程序的类型 在这里,事实的顺序就不那么重要了

考虑到“with”翻译的相关信息,并且该规则要求链式事实按顺序排列,我们可以尝试翻转链式事实。这确实有效:

  from this and `(y,x)∈ r^*` show "(z,x) ∈ r^*"
    by (rule converse_rtrancl_into_rtrancl)
我认为“6.4.3基本方法和属性”也是相关的,因为它描述了基本方法如何与传入事实交互。值得注意的是,有时在开始证明时使用的“-”noop将前向链接转化为对目标的假设

  with `(y,x)∈ r^*` show "(z,x) ∈ r^*"
    apply -
    apply (rule converse_rtrancl_into_rtrancl; assumption)
    done

这是因为第一个
apply
消耗了所有链接事实,所以第二个apply是纯反向链接。这也是为什么
子目标_-tac
旋转_-tac
有效的原因,但前提是它们位于单独的应用命令中。

谢谢您的回答!我试图留在Isar,但在尝试应用归纳规则时遇到了足够多的问题,我觉得一些较低层次的知识会有所帮助。我后来注意到rule_tac和intro也起作用,因此可能是一些基本规则方法无法处理的边缘情况。