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

Coq 有没有可能表达一个定理,说明应用了哪些构造函数?,coq,Coq,鉴于此简单的语言和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

鉴于此简单的语言和
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(adde1e2)e
有一个有效实例,那么构造函数
eval\u add0
eval\u 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.

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

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.
你用
存在e
说明了你的定理,所以我遵循了这个模式,在结论中没有提到
e
。但是,不必假设
存在e,…
,您只需对所有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.

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

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.
你用
存在e
说明了你的定理,所以我遵循了这个模式,在结论中没有提到
e
。但是,不必假设
存在e,…
,您只需对所有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.