Coq 强制和目标匹配

Coq coercions and goal matching

假设我有以下设置:

Inductive exp: Set :=
| CE: nat -> exp.

Inductive adt: exp -> Prop :=
| CA: forall e, adt e.

Coercion nat_to_exp := CE.

Ltac my_tactic := match goal with
| [ |- adt (CE ?N) ] => apply (CA (CE N))
end.

然后我尝试使用自定义策略证明一个简单的定理:

Theorem silly: adt 0.
Proof.
  my_tactic. (* Error: No matching clauses for match. *)
Abort.

这失败了,因为目标不是 adt (CE ?N) 的形式,而是 adt (nat_to_exp ?N) 的形式(这在使用 Set Printing Coercions 时明确显示)。

试图证明一个稍微不同的定理有效:

Theorem silly: adt (CE 0).
Proof.
  my_tactic. (* Success. *)
Qed.

我知道的可能解决方法:

理想情况下,如果在展开所有定义后模式匹配(定义不应该保持展开,当然),我希望模式匹配成功。

这可能吗?如果不能,有什么理由不能实现吗?

您可以直接将构造函数 CE 声明为强制转换,而不是像这样将其包装为 nat_to_exp

Coercion CE : nat >-> exp.

然后证明就没有任何问题了。如果你坚持命名你的强制转换(例如,因为它是一个复合表达式而不是单个构造函数),你可以改变你的策略,以便它显式处理未展开的强制转换:

Ltac my_tactic := match goal with
| [ |- adt (CE ?N) ] => apply (CA (CE N))
| [ |- adt (nat_to_exp ?N) ] => apply (CA (CE N))
end.