(* 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.
Theorem all_permutations_permutation : forall l1 l2 : list A, In l1 (all_permutations l2) -> permutation l1 l2.
Lemma permutation_all_permutations_aux : forall (n : nat) (l1 l2 : list A), n = length l2 -> permutation l1 l2 -> In l1 (all_permutations_aux l2 n).
Theorem permutation_all_permutations : forall l1 l2 : list A, permutation l1 l2 -> In l1 (all_permutations l2).