Update: with the help of Arthur Azevedo De Amorim, I finally manage it. The code is attached at the end of the question.
I am reading the book 《Types and Programming Languages》, and I am trying to prove each theorem(lemma) in this book using coq. When it came to the theorem 3.5.4, I tried and could not manage it. Here is the problem description.
A small language with AST:
t = :: true
:: false
:: if t then t else t
The evaluation rules are:
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
The theorem I want to prove is: for any t1 t2 t3, given t1 -> t2 and t1 -> t3, then t2 = t3.
And I build the type and proposition in Coq as below:
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.
And I tried to induction on eval_small_step t1 t2
as mentioned in the book. But I failed:
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.
Since the inductive hypothesis is not generic.
IHeval_small_step : eval_small_step t1 t3 -> t2 = t3
Could any one help me with this proof?
Proof:
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.
This is a typical trap for beginners. The induction hypothesis is not sufficiently general because you introduced t3
before performing the induction, which has the effect of fixing t3
"across all induction steps". In your case, you need to introduce t3
so that you can introduce H1
and induct on it, so you can simply put t3
back into the context by using the revert
or generalize dependent
tactics. Simply begin your proof like this:
Proof.
intros t1 t2 t3.
intros H1.
revert t3.
induction H1. (* ... *)
This problem is also explained in the Software Foundations book; simply look up "generalize dependent
" there. (I am sure this question has already showed up on Stack Overflow as well, but couldn't find a reference, if somebody is willing to help.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With