I'm trying to prove something in coq and the same problem keeps coming up; I want to unfold the definition of a Fixpoint inside the recursive (not nil) step of induction. Unfold works as expected, here's an example:
Before unfolding the list reverse (rev) definition:
n : nat
l' : natlist
IHl' : rev (rev l') = l'
============================
rev (rev (n :: l')) = n :: l'
After:
n : nat
l' : natlist
IHl' : rev (rev l') = l'
============================
(fix rev (l : natlist) : natlist := match l with
| [ ] => [ ]
| h :: t => rev t ++ [h]
end)
((fix rev (l : natlist) : natlist := match l with
| [ ] => [ ]
| h :: t => rev t ++ [h]
end) l' ++ [n]) = n :: l'
So far so good. Now I would expect simpl
to figure out I'm on the non-nil case of the induction since n :: l'
can never be nil,
and simplify away the nil case of the match ([ ] => [ ]
), keeping only the non-nil part of the definition.
Unfortunately it does not do that implicitly. How can I make unfold
of a recursive Fixpoint definition play well with induction? How do I get:
n : nat
l' : natlist
IHl' : rev (rev l') = l'
============================
rev (rev l' ++ [n]) = n :: l'
According to the rev
definition for the inner rev
.
Note: The use of Lists is irrelevant here, the same technique can be used for any inductively defined types.
Edit: Definition of rev and proof that leads to the After state.
Fixpoint rev (l:natlist) : natlist :=
match l with
| nil => nil
| h :: t => rev t ++ [h]
end.
Theorem rev_involutive : forall l : natlist,
rev (rev l) = l.
Proof.
intros l. induction l as [| n l'].
- reflexivity.
- unfold rev.
rev
and the proof that leads to the After state. – rausted