匹配Ltac

时间:2016-05-06 08:39:53

标签: coq ltac

我正在做一些关于在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.

==>表示评估的单一步骤(通过小步骤语义)。每个比赛案例的意图是:

  1. 匹配任何二进制构造函数时,我们有一个假设,即构造函数中的第一个术语步骤。
  2. 当我们有一个假设时,匹配任何二进制构造函数,该假设说明构造函数中的第二个术语和构造函数中的第一个术语已经是值
  3. 匹配任何一元构造函数,当我们有一个假设,表示构造函数中的术语步骤。
  4. 然而,看看这段代码的行为,看起来第三种情况也匹配二进制构造函数。如何将其限制为仅实际匹配一元构造函数?

2 个答案:

答案 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)