Proof using.
intros a l1; elim l1; simpl in |- *; auto.
intros H; case H.
intros a0 l H [H0| H0]; auto.
exists l; left; apply f_equal2 with (f := pair (A:=A) (B:=list A)); auto.
case H; auto.
intros x H1; exists (a0 :: x); right; auto.
apply
(in_map (fun p : A * list A => (fst p, a0 :: snd p)) (split_one l) (a, x));
auto.
Qed.
(* An auxillary function to generate all permutations *)
Fixpoint all_permutations_aux (l : list A) (n : nat) {struct n} :
list (list A) :=
match n with
| O => nil :: nil
| S n1 =>
flat_map
(fun p : A * list A =>
map (cons (fst p)) (all_permutations_aux (snd p) n1))
(split_one l)
end.
(* Generate all the permutations *)
Definition all_permutations (l : list A) := all_permutations_aux l (length l).

(* Specifications: *)
Lemma all_permutations_aux_permutation :
forall (n : nat) (l1 l2 : list A),
n = length l2 -> In l1 (all_permutations_aux l2 n) -> permutation l1 l2.