Section First.
Variable A : Type.
(* Take the first elements of a list *)
Fixpoint first_n (l : list A) (n : nat) {struct n} :
list A :=
match n with
| O => nil
| S n1 => match l with
| nil => nil
| a :: l1 => a :: first_n l1 n1
end
end.
Proof using.
intros n; elim n; simpl in |- *; auto.
intros l1; case l1; simpl in |- *; auto.
intros b l l2 H; Contradict H; auto with arith.
intros n0 H l1; case l1; simpl in |- *; auto with arith.
intros b l l2 H0; rewrite H; auto with arith.
Qed.
Proof using.
intros n; elim n; simpl in |- *; auto.
intros n0 H l1 l2; case l1; simpl in |- *.
intros H1; Contradict H1; auto with arith.
intros a l H0; (apply f_equal2 with (f := cons (A:=A)); auto).
apply H; apply le_S_n; auto.
Qed.
Proof using.
intros n l1; generalize n; elim l1; clear n l1; simpl in |- *; auto.
intros n; case n; simpl in |- *; auto.
intros n1 H1; Contradict H1; auto with arith.
intros a l H n; case n; simpl in |- *; auto with arith.
Qed.
Proof using.
intros l; elim l; simpl in |- *; auto.
intros a l0 H; apply f_equal2 with (f := cons (A:=A)); auto.
Qed.
(* Skip the first elements of a list *)
Fixpoint skip_n (l : list A) (n : nat) {struct n} :
list A :=
match n with
| O => l
| S n1 => match l with
| nil => nil
| a :: l1 => skip_n l1 n1
end
end.
Proof using.
intros n; elim n; simpl in |- *; auto.
intros l1; case l1; simpl in |- *; auto.
intros b l l2 H; Contradict H; auto with arith.
intros n0 H l1; case l1; simpl in |- *; auto with arith.
Qed.
Proof using.
intros n; elim n; simpl in |- *; auto.
intros n0 H l1; case l1; simpl in |- *; auto with arith.
intros l2 H1; Contradict H1; auto with arith.
Qed.
Proof using.
intros n; elim n; simpl in |- *; auto with arith.
intros n0 H l1; case l1; simpl in |- *; auto.
Qed.
Proof using.
intros l; elim l; simpl in |- *; auto.
Qed.

Theorem first_n_skip_n_app :
forall (n : nat) (l : list A), first_n l n ++ skip_n l n = l.