Coq中的析取交换性

时间:2018-10-23 23:46:53

标签: coq coq-tactic ltac

我想有一个Ltac战术来执行Disjunction Commutavity的工作。主要是,如果我在假设P \/ Q中某处有一个子项H,则Ltac Com H会将Q \/ P作为另一个假设添加到上下文中。

我尝试通过公理提供apply的可交换性规则;但是它仅适用于简单的假设,例如在R -> (P \/ Q)中失败;应该添加到上下文R -> (Q \/ P)中的位置。

1 个答案:

答案 0 :(得分:4)

您可以使用setoid重写库,该库允许您使用除相等以外的其他关系进行重写。以下代码段显示了如何在假设中将A \/ B替换为B \/ A

Require Import Setoid.

Variables A B C : Prop.

Goal ~ (A \/ B -> C).
intros H.
rewrite or_comm in H.
Abort.

要实施您想要的策略,我们只需要复制假设并重写其中即可。请注意,使用fresh策略会生成新的假设名称。

Ltac Comm H :=
  let H' := fresh "H" in
  pose proof H as H';
  rewrite or_comm in H'.

这里是Comm的演示示例。

Goal ~ (A \/ B -> C).
intros H.
Comm H.
Abort.

编辑 Coq manual包含有关setoid重写的部分。粗略地说,只要您证明该假设中出现的运算与该关系兼容,就可以在假设中使用 any 关系R进行重写。例如,如果我们将R设为<->,则上述重写之所以有效,是因为标准库中存在引理,表明逻辑对等受到隐含的尊重。


注意我通常建议不要让Coq名称假说本身:这些名称往往非常不稳定,通常会导致证明脚本被破坏。根据经验,如果要编写完全不涉及自动选择名称的全自动证明脚本,则应让Coq自行选择名称。这是Comm的另一个版本,可以避免此问题。

Ltac Comm' H H' :=
  pose proof H as H';
  rewrite or_comm in H'.

Goal ~ (A \/ B -> C).
intros H.
Comm H H'.
Abort.