有没有办法通过重写步骤自动化Coq证明?

时间:2016-11-14 19:06:45

标签: automation coq

我正在制作证据,我的一个子目标看起来有点像这样:

Goal forall
  (a b : bool)
  (p: Prop)
  (H1: p -> a = b)
  (H2: p),
  negb a = negb b.
Proof.
  intros.
  apply H1 in H2. rewrite H2. reflexivity.
Qed.

证据不依赖于任何外部引理,只是在上下文中将一个假设应用于另一个假设,并使用已知假设进行重写步骤。

有没有办法实现自动化?我试过intros. auto.,但没有效果。我怀疑这是因为auto只能执行apply步骤但没有rewrite步骤,但我不确定。也许我需要一些更强大的策略?

我想要自动化的原因是,在我原来的问题中,我实际上有大量与这个非常相似的子目标,但假设名称(H1,H2等)的差异很小,假设的数量(有时还有一个额外的归纳假设或两个)和最后的布尔公式。我认为,如果我可以使用自动化来解决这个问题,那么我的整体校对脚本会更加简洁和强大。

编辑:如果其中一个假设存在错误怎么办?

Goal forall
  (a b c : bool)
  (p: bool -> Prop)
  (H1: forall x, p x -> a = b)
  (H2: p c),
  negb a = negb b.
Proof.
  intros.
  apply H1 in H2. subst. reflexivity.
Qed

2 个答案:

答案 0 :(得分:4)

当您在证明某些引理的方式中看到重复模式时,您通常可以定义自己的策略来自动化证明。

在您的具体情况下,您可以写下以下内容:

Ltac rewrite_all' :=
  match goal with
  | H  : _ |- _ => rewrite H; rewrite_all'
  | _ => idtac
 end.

Ltac apply_in_all :=
  match goal with
  | H  : _, H2 : _ |- _ => apply H in H2; apply_in_all
  | _ => idtac
 end.

Ltac my_tac :=
  intros;
  apply_in_all;
  rewrite_all';
  auto.

Goal forall (a b : bool) (p: Prop) (H1: p -> a = b) (H2: p), negb a = negb b.
Proof.
  my_tac.
Qed.

Goal forall (a b c : bool) (p: bool -> Prop)
  (H1: forall x, p x -> a = b)
  (H2: p c),
  negb a = negb b.
Proof.
  my_tac.
Qed.

如果你想按照这种编写证据的方式,经常推荐的参考文献(但我还没读过)是Adam Chlipala的CPDT

答案 1 :(得分:3)

这个特殊目标可以这样解决:

Goal forall (a b : bool) (p: Prop) (H1: p -> a = b) (H2: p),
  negb a = negb b.
Proof.
  now intuition; subst.
Qed.

或者,使用destruct_all策略(假设您没有很多布尔变量):

intros; destruct_all bool; intuition.

上述内容是根据Coq.Bool.Bool中定义的destr_bool策略建模的:

Ltac destr_bool :=
  intros; destruct_all bool; simpl in *; trivial; try discriminate.  

你也可以尝试使用像

这样的东西
destr_bool; intuition.

在更简单的intuition之后启动强大的destr_bool

nowCoq.Init.Tactics中定义如下

Tactic Notation "now" tactic(t) := t; easy.

easy正好位于它上方(顾名思义)可以解决简单的目标。

intuition可以解决需要应用(直觉)逻辑定律的目标。例如。来自问题原始版本的以下两个假设需要应用 modus ponens 法律。

H1 : p -> false = true
H2 : p
另一方面,

auto默认不这样做,它也不能解决矛盾。

如果您的假设包含一些一阶逻辑语句,firstorder策略可能就是答案(就像在这种情况下一样) - 只需用它替换intuition