(* Definition of permutations as sequences of adjacent transpositions *) 
Inductive permutation : list A -> list A -> Prop :=
  | permutation_nil : permutation nil nil
  | permutation_skip :
      forall (a : A) (l1 l2 : list A),
      permutation l2 l1 -> permutation (a :: l2) (a :: l1)
  | permutation_swap :
      forall (a b : A) (l : list A), permutation (a :: b :: l) (b :: a :: l)
  | permutation_trans :
      forall l1 l2 l3 : list A,
      permutation l1 l2 -> permutation l2 l3 -> permutation l1 l3.(* Definition of permutations as sequences of adjacent transpositions *) 
Inductive permutation : list A -> list A -> Prop :=
  | permutation_nil : permutation nil nil
  | permutation_skip :
      forall (a : A) (l1 l2 : list A),
      permutation l2 l1 -> permutation (a :: l2) (a :: l1)
  | permutation_swap :
      forall (a b : A) (l : list A), permutation (a :: b :: l) (b :: a :: l)
  | permutation_trans :
      forall l1 l2 l3 : list A,
      permutation l1 l2 -> permutation l2 l3 -> permutation l1 l3.(* Definition of permutations as sequences of adjacent transpositions *) 
Inductive permutation : list A -> list A -> Prop :=
  | permutation_nil : permutation nil nil
  | permutation_skip :
      forall (a : A) (l1 l2 : list A),
      permutation l2 l1 -> permutation (a :: l2) (a :: l1)
  | permutation_swap :
      forall (a b : A) (l : list A), permutation (a :: b :: l) (b :: a :: l)
  | permutation_trans :
      forall l1 l2 l3 : list A,
      permutation l1 l2 -> permutation l2 l3 -> permutation l1 l3.(* Definition of permutations as sequences of adjacent transpositions *) 
Inductive permutation : list A -> list A -> Prop :=
  | permutation_nil : permutation nil nil
  | permutation_skip :
      forall (a : A) (l1 l2 : list A),
      permutation l2 l1 -> permutation (a :: l2) (a :: l1)
  | permutation_swap :
      forall (a b : A) (l : list A), permutation (a :: b :: l) (b :: a :: l)
  | permutation_trans :
      forall l1 l2 l3 : list A,
      permutation l1 l2 -> permutation l2 l3 -> permutation l1 l3.(* Definition of permutations as sequences of adjacent transpositions *) 
Inductive permutation : list A -> list A -> Prop :=
  | permutation_nil : permutation nil nil
  | permutation_skip :
      forall (a : A) (l1 l2 : list A),
      permutation l2 l1 -> permutation (a :: l2) (a :: l1)
  | permutation_swap :
      forall (a b : A) (l : list A), permutation (a :: b :: l) (b :: a :: l)
  | permutation_trans :
      forall l1 l2 l3 : list A,
      permutation l1 l2 -> permutation l2 l3 -> permutation l1 l3.

(* Specifications: *)
Theorem permutation_refl : forall l : list A, permutation l l.
Theorem permutation_sym : forall l m : list A, permutation l m -> permutation m l.
Theorem permutation_length : forall l m : list A, permutation l m -> length l = length m.
Theorem permutation_nil_inv : forall l : list A, permutation l nil -> l = nil.
Lemma permutation_one_inv_aux : forall l1 l2 : list A, permutation l1 l2 -> forall a : A, l1 = a :: nil -> l2 = a :: nil.
Theorem permutation_one_inv : forall (a : A) (l : list A), permutation (a :: nil) l -> l = a :: nil.
Theorem permutation_in : forall (a : A) (l m : list A), permutation l m -> In a l -> In a m.
Theorem permutation_app_comp : forall l1 l2 l3 l4, permutation l1 l2 -> permutation l3 l4 -> permutation (l1 ++ l3) (l2 ++ l4).
Theorem permutation_app_swap : forall l1 l2, permutation (l1 ++ l2) (l2 ++ l1).
Theorem permutation_transposition : forall a b l1 l2 l3, permutation (l1 ++ a :: l2 ++ b :: l3) (l1 ++ b :: l2 ++ a :: l3).
Theorem in_permutation_ex : forall a l, In a l -> exists l1 : list A, permutation (a :: l1) l.
Lemma permutation_cons_ex_aux : forall (a : A) (l1 l2 : list A), permutation l1 l2 -> forall l11 l12 : list A, l1 = l11 ++ a :: l12 -> exists l3 : list A, (exists l4 : list A, l2 = l3 ++ a :: l4 /\ permutation (l11 ++ l12) (l3 ++ l4)).
Theorem permutation_cons_ex : forall (a : A) (l1 l2 : list A), permutation (a :: l1) l2 -> exists l3 : list A, (exists l4 : list A, l2 = l3 ++ a :: l4 /\ permutation l1 (l3 ++ l4)).
Theorem permutation_inv : forall (a : A) (l1 l2 : list A), permutation (a :: l1) (a :: l2) -> permutation l1 l2.