我正在做一些关于在 Coq 中形式化简单类型 lambda 演算的练习,并希望使用 Ltac 自动化我的证明。在证明进度定理时:
Theorem progress : forall t T,
empty |-- t \in T -> value t \/ exists t', t ==> t'.
我想出了这段 Ltac 代码:
Ltac progress_when_stepping :=
(* right, because progress statement places stepping on the right of \/ *)
right;
(* use induction hypotheses *)
repeat
match goal with
| [ H : _ -> value _ \/ exists _, ?t1 ==> _ |- exists _, ?C ?t1 _ ==> _ ] =>
induction H; auto
| [ H : _ -> value _ \/ exists _, ?t2 ==> _, H0 : value ?t1 |-
exists _, ?C ?t1 ?t2 ==> _ ] =>
induction H; auto
| [ H : _ -> value _ \/ exists _, ?t1 ==> _ |- exists _, ?C ?t1 ==> _ ] =>
induction H; auto
end.
==>
表示评估的单个步骤(通过小步语义)。每个匹配案例的意图是:
- 当我们有一个假设说构造函数中的第一项步骤时,匹配任何二元构造函数。
- 当我们有一个假设说构造函数步骤中的第二项和构造函数中的第一项已经是一个值时,匹配任何二元构造函数
- 当我们有一个假设说构造函数中的术语是步骤时,匹配任何一元构造函数。
然而,看看这段代码的行为,它看起来第三种情况也匹配二进制构造函数。如何将其限制为仅实际匹配一元构造函数?