Section List.
Variables (A : Type) (B : Type) (C : Type).
Variable f : A -> B.
Proof using.
intros P H l;
apply well_founded_ind with (R := fun x y : list A => length x < length y);
auto.
apply wf_inverse_image with (R := lt); auto.
apply lt_wf.
Qed.
Definition list_length_induction :
forall P : list A -> Type,
(forall l1 : list A,
(forall l2 : list A, length l2 < length l1 -> P l2) -> P l1) ->
forall l : list A, P l.
intros P H l;
apply
well_founded_induction_type with (R := fun x y : list A => length x < length y);
auto.
apply wf_inverse_image with (R := lt); auto.
apply lt_wf.
Defined.
Proof using.
intros a l; elim l; clear l; simpl in |- *; auto.
intros H; case H.
intros a1 l H [H1| H1]; auto.
exists (nil (A:=A)); exists l; simpl in |- *; auto.
apply f_equal2 with (f := cons (A:=A)); auto.
case H; auto; intros l1 (l2, Hl2); exists (a1 :: l1); exists l2;
simpl in |- *; auto.
apply f_equal2 with (f := cons (A:=A)); auto.
Qed.
Proof using.
intros l1; elim l1; simpl in |- *; auto.
Qed.
Proof using.
intros l1; elim l1; simpl in |- *; auto.
intros a l H l2 l3 H0; apply H; injection H0; auto.
Qed.

Theorem app_inv_tail :
forall l1 l2 l3 : list A, l2 ++ l1 = l3 ++ l1 -> l2 = l3.