我正在做一些关于在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.
==>
表示评估的单一步骤(通过小步骤语义)。每个比赛案例的意图是:
然而,看看这段代码的行为,看起来第三种情况也匹配二进制构造函数。如何将其限制为仅实际匹配一元构造函数?
答案 0 :(得分:2)
问题是?C
匹配?C0 ?t0
形式的术语。你可以做一些二次匹配来排除这种情况。
match goal with
…
| [ H : _ -> value _ \/ exists _, ?t1 ==> _ |- exists _, ?C ?t1 ==> _ ] =>
match C with
| ?C0 ?t0 => fail
| _ => induction H; auto
end
end.
答案 1 :(得分:0)
似乎context ident [ term ]
结构可行:
有一种特殊形式的模式可以匹配模式的子项:
context ident [cpattern]
。 它匹配任何带有子项匹配cpattern的术语。如果存在匹配,则为可选的标识分配“匹配的上下文”,即匹配的子项被孔替换的初始项。 的 ... 强>由于历史原因,
context
过去常常考虑使用{-1}}这样的n-ary应用程序,而不是一系列的一元应用程序(f 1 2)
。因此((f 1) 2)
将无法在context [f ?x]
中找到匹配的子项:如果模式是部分应用程序,匹配的子项必然是具有完全相同数量的参数的应用程序。
所以,我想这可行(至少它适用于我编造的一个极小的人为例子):
(f 1 2)