Coq - disj_conj_intro_patterns for inductive propositions

时间:2016-08-31 03:07:38

标签: constructor coq coq-tactic

在Coq中给出一个任意的归纳命题定义,是否有一个通用的公式来推导出一个合理的disj_conj_intro_pattern,以便在归纳命题上调用感应策略时使用?

通常,任何一个归纳定义构造函数的完整intro_pattern可能需要(名称)多个假设和多个归纳假设,在这种情况下,模式中提供的名称顺序可以包括所有参数,然后是一个假设和相应的归纳假设,接着是一个或多个由假设和归纳假设组成的附加对。例如,Software Foundations包括以下内容:

Inductive exp_match {T} : list T -> reg_exp T -> Prop :=
| MEmpty : exp_match [] EmptyStr
| MChar : forall x, exp_match [x] (Char x)
| MApp : forall s1 re1 s2 re2,
           exp_match s1 re1 ->
           exp_match s2 re2 ->
           exp_match (s1 ++ s2) (App re1 re2)
| MUnionL : forall s1 re1 re2,
              exp_match s1 re1 ->
              exp_match s1 (Union re1 re2)
| MUnionR : forall re1 s2 re2,
              exp_match s2 re2 ->
              exp_match s2 (Union re1 re2)
| MStar0 : forall re, exp_match [] (Star re)
| MStarApp : forall s1 s2 re,
               exp_match s1 re ->
               exp_match s2 (Star re) ->
               exp_match (s1 ++ s2) (Star re).

Notation "s =~ re" := (exp_match s re) (at level 80).

Theorem in_re_match : forall T (s : list T) (re : reg_exp T) (x : T),
  s =~ re ->
  In x s ->
  In x (re_chars re).
Proof.
  intros T s re x Hmatch Hin.
  induction Hmatch
    as [
        |x'
        |s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
        |s1 re1 re2 Hmatch IH|re1 s2 re2 Hmatch IH
        |re|s1 s2 re Hmatch1 IH1 Hmatch2 IH2].

在这个例子中,MApp和MStarApp的intro_patterns每个都有两对假设和归纳假设 - 大概是因为这两个构造函数都包含一个表达式

  

x - > y - > ž

关于这一点,目前的参考手册似乎只是说

  

诱导期限为disj_conj_intro_pattern

     

这表现为归纳术语,但使用的是名称   disj_conj_intro_pattern命名引入的变量   上下文。 disj_conj_intro_pattern通常必须采用[   p11 ... p1n1 | ...... | pm1 ... pmnm],m是构造函数的数量   这个词的类型。每个变量都是通过感应引入的   第i个目标的上下文从列表pi1 ... pini中获取其名称   订购。如果没有足够的名称,感应就会发明名称   要引入的剩余变量。更一般地说,pij可以是任何   析取/连接引入模式(参见第8.3.2节)。对于   例如,对于具有一个构造函数的归纳类型,模式   可以使用符号(p1,...,pn)代替[p1 ... pn]。

这似乎没有说明如何为给定的归纳定义确定完整的disj_conj_intro_pattern的正确形式。

我的上述经验观察是:1)每个构造函数的形式参数首先出现,然后是构造函数的假设与相应的归纳假设相结合; 2)假设和归纳假设对的数量来自构造函数中假设的数量,即事物的总和?或者还有它吗?

除了参考手册的战术章节以及第1章中关于Gallina语法模式的一般性讨论外,还有其他相关文件吗?

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,那么答案就是'是'。您可以导出入门的介绍模式。

Coq自动为任何归纳定义生成归纳原则,并将其添加_ind作为后缀,因此exp_match的归纳原则变为exp_match_ind。如果您使用exp_match_ind命令探索Check的类型,则可以生成所需的介绍模式。

Check exp_match_ind.

(* output:
exp_match_ind
     : forall (T : Type) (P : list T -> reg_exp T -> Prop),
       P [] EmptyStr ->
       (forall x : T, P [x] (Char x)) ->
       (forall (s1 : list T) (re1 : reg_exp T) 
          (s2 : list T) (re2 : reg_exp T),
        s1 =~ re1 ->
        P s1 re1 ->
        s2 =~ re2 -> P s2 re2 -> P (s1 ++ s2) (App re1 re2)) ->
       (forall (s1 : list T) (re1 re2 : reg_exp T),
        s1 =~ re1 -> P s1 re1 -> P s1 (Union re1 re2)) ->
       (forall (re1 : reg_exp T) (s2 : list T) (re2 : reg_exp T),
        s2 =~ re2 -> P s2 re2 -> P s2 (Union re1 re2)) ->
       (forall re : reg_exp T, P [] (Star re)) ->
       (forall (s1 s2 : list T) (re : reg_exp T),
        s1 =~ re ->
        P s1 re ->
        s2 =~ Star re -> P s2 (Star re) -> P (s1 ++ s2) (Star re)) ->
       forall (l : list T) (r : reg_exp T), l =~ r ->
       P l r
*)

这种类型表示(如果你跳过最初的forall“标题”)你需要证明一堆子目标来证明目标P l r。顶级的每个->都会分隔子目标:

1)MEmpty案例:

P [] EmptyStr

没有假设,这就是我们开始的原因 induction Hmatch as [ | - 请注意|左侧没有任何内容。

2)MChar案例:

(forall x : T, P [x] (Char x))

这种情况下的介绍模式很简单:对于某些x',我们需要证明P [x'] (Char x')。此时我们的模式变为:[ | x' ...

3)MApp案例:

(forall (s1 : list T) (re1 : reg_exp T) 
        (s2 : list T) (re2 : reg_exp T),  (* s1 re1 s2 re2 *)
        s1 =~ re1 ->                      (* Hmatch1 *)
        P s1 re1 ->                       (* IH1 *)
        s2 =~ re2 ->                      (* Hmatch2 *)
        P s2 re2 ->                       (* IH2 *)
        P (s1 ++ s2) (App re1 re2))       (* the current subgoal *)

我根据定理in_re_match中使用的标记在上面的注释中标记了变量和假设。此时我们的模式变为:[ | x' | s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2 ...

其余的子目标可以类似地完成,从而产生定理中使用的模式。