Library Coq.Sorting.Permutation


List permutations as a composition of adjacent transpositions



Require Import List Setoid.

Set Implicit Arguments.

Local Notation "[ ]" := nil.
Local Notation "[ a ; .. ; b ]" := (a :: .. (b :: []) ..).

Section Permutation.

Variable A:Type.

Inductive Permutation : list A -> list A -> Prop :=
| perm_nil: Permutation [] []
| perm_skip x l : Permutation l -> Permutation (x::l) (x::)
| perm_swap x y l : Permutation (y::x::l) (x::y::l)
| perm_trans l l´´ : Permutation l -> Permutation l´´ -> Permutation l l´´.

Local Hint Constructors Permutation.

Some facts about Permutation

Theorem Permutation_nil : forall (l : list A), Permutation [] l -> l = [].

Theorem Permutation_nil_cons : forall (l : list A) (x : A), ~ Permutation nil (x::l).

Permutation over lists is a equivalence relation

Theorem Permutation_refl : forall l : list A, Permutation l l.

Theorem Permutation_sym : forall l : list A, Permutation l -> Permutation l.

Theorem Permutation_trans : forall l l´´ : list A, Permutation l -> Permutation l´´ -> Permutation l l´´.

End Permutation.

Hint Resolve Permutation_refl perm_nil perm_skip.


Local Hint Resolve perm_swap perm_trans.
Local Hint Resolve Permutation_sym Permutation_trans.


Instance Permutation_Equivalence A : Equivalence (@Permutation A) | 10 := {
  Equivalence_Reflexive := @Permutation_refl A ;
  Equivalence_Symmetric := @Permutation_sym A ;
  Equivalence_Transitive := @Permutation_trans A }.

Add Parametric Morphism A (a:A) : (cons a)
  with signature @Permutation A ==> @Permutation A
  as Permutation_cons.

Section Permutation_properties.

Variable A:Type.

Implicit Types a b : A.
Implicit Types l m : list A.

Compatibility with others operations on lists

Theorem Permutation_in : forall (l : list A) (x : A), Permutation l -> In x l -> In x .

Lemma Permutation_app_tail : forall (l tl : list A), Permutation l -> Permutation (l++tl) (++tl).

Lemma Permutation_app_head : forall (l tl tl´ : list A), Permutation tl tl´ -> Permutation (l++tl) (l++tl´).

Theorem Permutation_app : forall (l m : list A), Permutation l -> Permutation m -> Permutation (l++m) (++).

Add Parametric Morphism : (@app A)
  with signature @Permutation A ==> @Permutation A ==> @Permutation A
  as Permutation_app´.
Qed.

Lemma Permutation_add_inside : forall a (l tl tl´ : list A),
  Permutation l -> Permutation tl tl´ ->
  Permutation (l ++ a :: tl) ( ++ a :: tl´).

Lemma Permutation_cons_append : forall (l : list A) x,
  Permutation (x :: l) (l ++ x :: nil).
Local Hint Resolve Permutation_cons_append.

Theorem Permutation_app_comm : forall (l : list A),
  Permutation (l ++ ) ( ++ l).
Local Hint Resolve Permutation_app_comm.

Theorem Permutation_cons_app : forall (l l1 l2:list A) a,
  Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2).
Local Hint Resolve Permutation_cons_app.

Theorem Permutation_middle : forall (l1 l2:list A) a,
  Permutation (a :: l1 ++ l2) (l1 ++ a :: l2).
Local Hint Resolve Permutation_middle.

Theorem Permutation_rev : forall (l : list A), Permutation l (rev l).

Add Parametric Morphism : (@rev A)
  with signature @Permutation A ==> @Permutation A as Permutation_rev´.

Theorem Permutation_length : forall (l : list A), Permutation l -> length l = length .

Theorem Permutation_ind_bis :
 forall P : list A -> list A -> Prop,
   P [] [] ->
   (forall x l , Permutation l -> P l -> P (x :: l) (x :: )) ->
   (forall x y l , Permutation l -> P l -> P (y :: x :: l) (x :: y :: )) ->
   (forall l l´´, Permutation l -> P l -> Permutation l´´ -> P l´´ -> P l l´´) ->
   forall l , Permutation l -> P l .

Ltac break_list l x H :=
  destruct l as [|x ]; simpl in *;
  injection H; intros; subst; clear H.

Theorem Permutation_nil_app_cons : forall (l : list A) (x : A), ~ Permutation nil (l++x::).

Theorem Permutation_app_inv : forall (l1 l2 l3 l4:list A) a,
  Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4).

Theorem Permutation_cons_inv :
   forall l a, Permutation (a::l) (a::) -> Permutation l .

Theorem Permutation_cons_app_inv :
   forall l l1 l2 a, Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).

Theorem Permutation_app_inv_l :
    forall l l1 l2, Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.

Theorem Permutation_app_inv_r :
   forall l l1 l2, Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.

Lemma Permutation_length_1_inv: forall a l, Permutation [a] l -> l = [a].

Lemma Permutation_length_1: forall a b, Permutation [a] [b] -> a = b.

Lemma Permutation_length_2_inv :
  forall a1 a2 l, Permutation [a1;a2] l -> l = [a1;a2] \/ l = [a2;a1].

Lemma Permutation_length_2 :
  forall a1 a2 b1 b2, Permutation [a1;a2] [b1;b2] ->
    a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1.

Lemma NoDup_Permutation : forall l ,
  NoDup l -> NoDup -> (forall x:A, In x l <-> In x ) -> Permutation l .

End Permutation_properties.

Section Permutation_map.

Variable A B : Type.
Variable f : A -> B.

Add Parametric Morphism : (map f)
  with signature (@Permutation A) ==> (@Permutation B) as Permutation_map_aux.

Lemma Permutation_map :
  forall l , Permutation l -> Permutation (map f l) (map f ).

End Permutation_map.