代码之家  ›  专栏  ›  技术社区  ›  Pablo Inostroza

有没有可能表达一个定理,说明应用了哪些构造函数?

coq
  •  0
  • Pablo Inostroza  · 技术社区  · 6 年前

    鉴于这种简单的语言 eval 定义:

    Inductive  exp : Type :=
    | lit : nat -> exp
    | add : exp -> exp -> exp
    .
    
    Inductive eval : exp -> nat -> Prop :=
    | eval_lit: forall n, eval (lit n) n
    | eval_add0: forall e n, eval e n -> eval (add (lit 0) e) n
    | eval_add: forall e1 e2 n1 n2,  ~(e1 = lit 0) -> eval e1 n1 -> 
                                     eval e2 n2 -> eval (add e1 e2) (n1 + n2)
    .
    

    我想表达一下,如果表单有一个有效的实例 eval (add e1 e2) e 然后构造函数 eval_add0 eval_add 已使用。有可能做到这一点吗?如果是的话,这是可以证明的吗?这是我想要实现的不完整代码:

    Theorem appplied_constructor: forall e1 e2, exists e, eval (add e1 e2) e -> 
               (* either the constructor eval_add0 or eval_add had to be applied *).
    Proof.
    ...
    Qed.
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Tej Chajed    6 年前

    您不能直接表示使用了哪个构造函数,但您可以从构造函数的类型反向工作,以确定您知道是否使用了该构造函数。这正是反转策略所做的。你需要做的是手动陈述你所知道的 e1 e2 既然你有 eval (add ..) .. . 例如:

    Theorem appplied_constructor: forall e1 e2, (exists e, eval (add e1 e2) e) ->
                                          (e1 = lit 0) \/
                                          (~e1 = lit 0 /\
                                            exists n1 n2, eval e1 n1 /\
                                                    eval e2 n2).
    Proof.
      intros.
      destruct H as [e ?].
      inversion H; subst; eauto 10.
    Qed.
    

    你用 exists e ,所以我遵循了这个模式,没有提到 e 在结论中。然而,不是假设 exists e, ... ,你可以说 forall e 然后再回头看看 e :

    Theorem appplied_constructor': forall e1 e2 e, eval (add e1 e2) e ->
                                          (eval e2 e /\ e1 = lit 0) \/
                                          (~e1 = lit 0 /\
                                            exists n1 n2, eval e1 n1 /\
                                                     eval e2 n2 /\
                                                     n1 + n2 = e).
    Proof.
      intros.
      inversion H; subst; eauto 10.
    Qed.