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.
我知道的可能解决方法:
- 不使用强制转换。
- 在战术中展开强制(使用
unfold nat_to_exp
)。这稍微缓解了问题,但是一旦引入新的强制转换策略就不知道了。
理想情况下,如果在展开所有定义后模式匹配(定义不应该保持展开,当然),我希望模式匹配成功。
这可能吗?如果不能,有什么理由不能实现吗?
您可以直接将构造函数 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.
假设我有以下设置:
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.
我知道的可能解决方法:
- 不使用强制转换。
- 在战术中展开强制(使用
unfold nat_to_exp
)。这稍微缓解了问题,但是一旦引入新的强制转换策略就不知道了。
理想情况下,如果在展开所有定义后模式匹配(定义不应该保持展开,当然),我希望模式匹配成功。
这可能吗?如果不能,有什么理由不能实现吗?
您可以直接将构造函数 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.