更新:在Arthur Azevedo De Amorim的帮助下,我终于完成了它。代码附在问题的末尾。
我正在阅读“类型和编程语言”一书,我试图用coq来证明本书中的每个定理(引理)。当谈到定理3.5.4时,我试过并且无法管理它。这是问题描述。
AST的一种小语言:
t = :: true
:: false
:: if t then t else t
评估规则是:
1. if true then t2 else t3 -> t2 (eval_if_true)
2. if false then t2 else t3 -> t3 (eval_if_false)
3. t1 -> t1'
------------------------ (eval_if)
if t1 then t2 else t3 ->
if t1' then t2 else t3
我想证明的定理是:对于任何t1 t2 t3,给定t1 - > t2和t1 - > t3,然后t2 = t3。
我在Coq中构建类型和命题如下:
Inductive t : Type :=
| zhen (* represent true *)
| jia (* represent false *)
| if_stat : t -> t -> t -> t.
Inductive eval_small_step : t -> t -> Prop :=
| ev_if_true : forall (t2 t3 : t),
eval_small_step (if_stat zhen t2 t3) t2
| ev_if_false : forall (t2 t3 : t),
eval_small_step (if_stat jia t2 t3) t3
| ev_if : forall (t1 t2 t3 t4 : t),
eval_small_step t1 t2 ->
eval_small_step (if_stat t1 t3 t4) (if_stat t2 t3 t4).
Theorem determinacy : forall (t1 t2 t3 : t),
eval_small_step t1 t2 -> eval_small_step t1 t3 -> t2 = t3.
我尝试在eval_small_step t1 t2
上进行归纳,正如书中所提到的那样。但我失败了:
Proof.
intros t1 t2 t3.
intros H1 H2.
induction H1.
- inversion H2. reflexivity. inversion H4.
- inversion H2. reflexivity. inversion H4.
- assert (H: eval_small_step (if_stat t1 t0 t4) (if_stat t2 t0 t4)).
{
apply ev_if. apply H1.
}
Abort.
由于归纳假设不是通用的。
IHeval_small_step : eval_small_step t1 t3 -> t2 = t3
任何人都可以帮我解决这个问题吗?
证明:
Inductive t : Type :=
| zhen (* represent true *)
| jia (* represent false *)
| if_stat : t -> t -> t -> t.
Inductive eval_small_step : t -> t -> Prop :=
| ev_if_true : forall (t2 t3 : t),
eval_small_step (if_stat zhen t2 t3) t2
| ev_if_false : forall (t2 t3 : t),
eval_small_step (if_stat jia t2 t3) t3
| ev_if : forall (t1 t2 t3 t4 : t),
eval_small_step t1 t2 ->
eval_small_step (if_stat t1 t3 t4) (if_stat t2 t3 t4).
Theorem determinacy : forall (t1 t2 t3 : t),
eval_small_step t1 t2 -> eval_small_step t1 t3 -> t2 = t3.
Proof.
intros t1 t2 t3.
intros H1.
revert t3.
induction H1.
- intros t0. intros H.
inversion H.
+ reflexivity.
+ inversion H4.
- intros t0. intros H.
inversion H.
+ reflexivity.
+ inversion H4.
- intros t0.
intros H.
assert(H': eval_small_step (if_stat t1 t3 t4) (if_stat t2 t3 t4)).
{
apply ev_if. apply H1.
}
inversion H.
+ rewrite <- H2 in H1. inversion H1.
+ rewrite <- H2 in H1. inversion H1.
+ assert(H'': t2 = t6).
{
apply IHeval_small_step.
apply H5.
}
rewrite H''. reflexivity.
Qed.
答案 0 :(得分:6)
这是初学者的典型陷阱。归纳假设不够通用,因为您在执行归纳之前引入了t3
,这具有在所有归纳步骤中修复t3
“的效果”。在您的情况下,您需要引入t3
,以便您可以引入H1
并对其进行导入,因此您只需使用t3
将revert
放回上下文中即可或generalize dependent
战术。只需开始这样的证明:
Proof.
intros t1 t2 t3.
intros H1.
revert t3.
induction H1. (* ... *)
Software Foundations book中也解释了这个问题;只需在那里查找“generalize dependent
”即可。 (我确信这个问题已经出现在Stack Overflow上,但如果有人愿意提供帮助,则无法找到参考。)