Notation nth := nth.
(*******************************)
(** * Manipulating whole lists *)
(*******************************)
Section ListOps.
Variable A : Type.
(*************************)
(** ** Reverse           *)
(*************************)
Fixpoint rev (l:list A) : list A :=
match l with
| [] => []
| x :: l' => rev l' ++ [x]
end.

(* Specifications: *)
Lemma rev_app_distr : forall x y:list A, rev (x ++ y) = rev y ++ rev x.
Remark rev_unit : forall (l:list A) (a:A), rev (l ++ [a]) = a :: rev l.
Lemma rev_involutive : forall l:list A, rev (rev l) = l.
Lemma rev_inj (l1 l2: list A):
rev l1 = rev l2 -> l1 = l2.
Lemma rev_eq_app : forall l l1 l2, rev l = l1 ++ l2 -> l = rev l2 ++ rev l1.
(*********************************************)
(** Reverse Induction Principle on Lists     *)
(*********************************************)
Lemma rev_list_ind : forall P:list A-> Prop,
P [] ->
(forall (a:A) (l:list A), P (rev l) -> P (rev (a :: l))) ->
forall l:list A, P (rev l).
Theorem rev_ind : forall P:list A -> Prop,
P [] ->
(forall (x:A) (l:list A), P l -> P (l ++ [x])) -> forall l:list A, P l.