I have the following definition
Inductive subseq : list nat -> list nat -> Prop :=
| empty_subseq : subseq [] []
| add_right : forall y xs ys, subseq xs ys -> subseq xs (y::ys)
| add_both : forall x y xs ys, subseq xs ys -> subseq (x::xs) (y::ys)
.
Using this, I wish to prove the following lemma
Lemma del_l_preserves_subseq : forall x xs ys, subseq (x :: xs) ys -> subseq xs ys.
So, I tried looking at the proof of subseq (x :: xs) ys
by doing destruct H
.
Proof.
intros. induction H.
3 subgoals (ID 209)
x : nat
xs : list nat
============================
subseq xs [ ]
subgoal 2 (ID 216) is:
subseq xs (y :: ys)
subgoal 3 (ID 222) is:
subseq xs (y :: ys)
Why does the first subgoal ask me to prove subseq xs []
? Shouldn't the destruct
tactic know that the proof cannot be of the form empty_subseq
since the type contains x :: xs
and not []
?
In general how do I prove the lemma that I am trying to prove?
Shouldn't the destruct tactic know that the proof cannot be of the form empty_subseq since the type contains x :: xs and not []?
In fact, destruct
doesn't know that much. It just replaces x :: xs
and xs
with []
and []
in the empty_subseq
case. In particular, this frequently leads to lost information in the context. Better alternatives:
Use inversion
instead of destruct
.
Use remember
to ensure both type indices of subseq
are variables before destruct
. (remember (x :: xs) as xxs in H.
) This more explicit goal management also works well with induction
.