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.
Proof using.
intros l1 l2; generalize l1; elim l2; clear l1 l2; simpl in |- *; auto.
intros l1 l3; case l3; auto.
intros b l H; absurd (length ((b :: l) ++ l1) <= length l1).
simpl in |- *; rewrite length_app; auto with arith.
rewrite <- H; auto with arith.
intros a l H l1 l3; case l3.
simpl in |- *; intros H1; absurd (length (a :: l ++ l1) <= length l1).
simpl in |- *; rewrite length_app; auto with arith.
rewrite H1; auto with arith.
simpl in |- *; intros b l0 H0; injection H0.
intros H1 H2; apply f_equal2 with (f := cons (A:=A)); auto.
apply H with (1 := H1); auto.
Qed.
Proof using.
intros l1; elim l1; simpl in |- *; auto.
intros l2 l3 l4 a H; right; exists l3; auto.
intros a l H l2 l3 l4 a0; case l3; simpl in |- *.
intros H0; left; exists l; apply f_equal2 with (f := cons (A:=A));
injection H0; auto.
intros b l0 H0; case (H l2 l0 l4 a0); auto.
injection H0; auto.
intros (l5, H1).
left; exists l5; apply f_equal2 with (f := cons (A:=A)); injection H0; auto.
Qed.
Proof using.
intros l1; elim l1; simpl in |- *; auto.
intros l2 l3 l4 a b H; right; left; exists l3; auto.
intros a l H l2 l3 l4 a0 b; case l3; simpl in |- *.
case l; simpl in |- *.
intros H0; right; right; injection H0; split; auto.
apply f_equal2 with (f := cons (A:=A)); auto.
intros b0 l0 H0; left; exists l0; injection H0; intros;
repeat apply f_equal2 with (f := cons (A:=A)); auto.
intros b0 l0 H0; case (H l2 l0 l4 a0 b); auto.
injection H0; auto.
intros (l5, HH1); left; exists l5; apply f_equal2 with (f := cons (A:=A));
auto; injection H0; auto.
intros [H1| (H1, H2)]; auto.
right; right; split; auto; apply f_equal2 with (f := cons (A:=A)); auto;
injection H0; auto.
Qed.

Theorem same_length_ex :
forall (a : A) l1 l2 l3,
length (l1 ++ a :: l2) = length l3 ->
exists l4 : _,
(exists l5 : _,
(exists b : B,
length l1 = length l4 /\ length l2 = length l5 /\ l3 = l4 ++ b :: l5)).