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.