Fixpoint addInAllLocations(A : Type)(a : A)(ls : list A) :=
  match ls with
    | nil =>  (a :: nil) :: nil
    | a' :: ls' => 
      (a :: ls) :: map (fun x => a' :: x) (addInAllLocations a ls')
  end.Fixpoint getAllPermutations(A : Type)(ls : list A) :=
  match ls with
    | nil => nil :: nil
    | a :: ls' =>
      let perms' := getAllPermutations ls' in
        flatten (map (addInAllLocations a) perms')
  end.

(* Specifications: *)
Theorem addInAllLocations_not_nil : forall (A : Type) l (a : A), addInAllLocations a l = nil -> False.
Theorem getAllPermutations_not_nil : forall (A : Type)(ls : list A), getAllPermutations ls = nil -> False.
Theorem addInAllLocations_perm : forall (A : Type) x0 (a : A) ls2, In ls2 (addInAllLocations a x0) -> Permutation ls2 (a :: x0).
Theorem getAllPermutations_perms : forall (A : Set)(ls1 ls2 : list A), In ls2 (getAllPermutations ls1) -> Permutation ls1 ls2.
Theorem shuffle_perm : forall (ls1 ls2 : list A), In ls2 (getSupport (shuffle ls1)) -> Permutation ls2 ls1.