为什么使用Coq的setoid_replace" by"条款需要额外的idtac?

时间:2015-07-07 21:23:14

标签: coq

我使用setoid_replace遇到了一个奇怪的情况,其中有一个表单的校对步骤:

setoid_replace (a - c + d) with b by my_tactic

Error: No matching clauses for match goal失败,但在为策略追加idtac之后:

setoid_replace (a - c + d) with b by (my_tactic; idtac)

证明成功。我对idtac的理解是它本质上是一种无操作。为什么idtac的存在会产生影响?

这里是完整的代码。我通过Proof General使用Coq 8.4pl6。

Require Import QArith.
Open Scope Q.

Lemma rearrange_eq_r a b c d :
  a == b  ->  b + d == a + c  ->  c == d.
Proof.
  intro a_eq_b; rewrite a_eq_b; symmetry; now apply Qplus_inj_l with (z := b).
Qed.

Ltac rearrange :=
  match goal with
  | [ H : _ == _ |- _ == _ ] => apply rearrange_eq_r with (1 := H); ring
  end.

Lemma test_rearrange a b c d e (H0 : e < b) (H1 : b + c == a + d) :  e < a - c + d.
Proof.
  (* Why is the extra 'idtac' required in the line below? *)
  setoid_replace (a - c + d) with b by (rearrange; idtac).
  assumption.
Qed.

注意:正如Matt观察到的那样,idtac似乎并不特别:似乎可以使用任何策略(包括fail!)代替idtac使证明成功。

1 个答案:

答案 0 :(得分:2)

感谢Jason Gross对Coq bug追踪器的解释。这与Ltac战术语言中的评估顺序有关。在失败的情况下,rearrange中的匹配被应用于直接目标中的不等式,而不是setoid_replace生成的等式。这是Jason对错误报告的回应:

  

这是因为在[setoid_replace]之前评估了[match]   运行。这是Ltac不幸遭遇的事情之一   像[match]和[let ... in ...]一样急切地评估直到a   带分号的语句,或其他不匹配的非let-in语句   到达。如果你添加[idtac; ]在[重新排列]中的[匹配]之前,你的   问题就会消失。