summaryrefslogtreecommitdiff
path: root/theories/Sorting
diff options
context:
space:
mode:
Diffstat (limited to 'theories/Sorting')
-rw-r--r--theories/Sorting/Heap.v12
-rw-r--r--theories/Sorting/Mergesort.v2
-rw-r--r--theories/Sorting/PermutEq.v8
-rw-r--r--theories/Sorting/PermutSetoid.v6
-rw-r--r--theories/Sorting/Permutation.v462
-rw-r--r--theories/Sorting/Sorted.v6
-rw-r--r--theories/Sorting/Sorting.v2
7 files changed, 352 insertions, 146 deletions
diff --git a/theories/Sorting/Heap.v b/theories/Sorting/Heap.v
index 1cff280a..6313dbf6 100644
--- a/theories/Sorting/Heap.v
+++ b/theories/Sorting/Heap.v
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
@@ -152,23 +152,23 @@ Section defs.
revert l2 H0. fix 1. intros.
destruct l2 as [|a0 l0].
apply merge_exist with (a :: l); simpl; auto with datatypes.
- elim (leA_dec a a0); intros.
+ induction (leA_dec a a0) as [Hle|Hle].
(* 1 (leA a a0) *)
apply Sorted_inv in H. destruct H.
- destruct (merge l H (a0 :: l0) H0).
+ destruct (merge l H (a0 :: l0) H0) as [l1 H2 H3 H4].
apply merge_exist with (a :: l1). clear merge merge0.
auto using cons_sort, cons_leA with datatypes.
- simpl. rewrite m. now rewrite munion_ass.
+ simpl. rewrite H3. now rewrite munion_ass.
intros. apply cons_leA.
apply (@HdRel_inv _ leA) with l; trivial with datatypes.
(* 2 (leA a0 a) *)
apply Sorted_inv in H0. destruct H0.
- destruct (merge0 l0 H0). clear merge merge0.
+ destruct (merge0 l0 H0) as [l1 H2 H3 H4]. clear merge merge0.
apply merge_exist with (a0 :: l1);
auto using cons_sort, cons_leA with datatypes.
- simpl; rewrite m. simpl. setoid_rewrite munion_ass at 1. rewrite munion_comm.
+ simpl; rewrite H3. simpl. setoid_rewrite munion_ass at 1. rewrite munion_comm.
repeat rewrite munion_ass. setoid_rewrite munion_comm at 3. reflexivity.
intros. apply cons_leA.
apply (@HdRel_inv _ leA) with l0; trivial with datatypes.
diff --git a/theories/Sorting/Mergesort.v b/theories/Sorting/Mergesort.v
index b08e1e1e..593b2e9b 100644
--- a/theories/Sorting/Mergesort.v
+++ b/theories/Sorting/Mergesort.v
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
diff --git a/theories/Sorting/PermutEq.v b/theories/Sorting/PermutEq.v
index 6579fcdb..9bae43c2 100644
--- a/theories/Sorting/PermutEq.v
+++ b/theories/Sorting/PermutEq.v
@@ -1,19 +1,19 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-Require Import Relations Setoid SetoidList List Multiset PermutSetoid Permutation.
+Require Import Relations Setoid SetoidList List Multiset PermutSetoid Permutation Omega.
Set Implicit Arguments.
(** This file is similar to [PermutSetoid], except that the equality used here
is Coq usual one instead of a setoid equality. In particular, we can then
- prove the equivalence between [List.Permutation] and
- [Permutation.permutation].
+ prove the equivalence between [Permutation.Permutation] and
+ [PermutSetoid.permutation].
*)
Section Perm.
diff --git a/theories/Sorting/PermutSetoid.v b/theories/Sorting/PermutSetoid.v
index 681e8824..64dda448 100644
--- a/theories/Sorting/PermutSetoid.v
+++ b/theories/Sorting/PermutSetoid.v
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
@@ -19,7 +19,7 @@ Require Import Omega Relations Multiset SetoidList.
The relation between the two relations are in lemma
[permutation_Permutation].
- File [PermutEq] concerns Leibniz equality : it shows in particular
+ File [Permutation] concerns Leibniz equality : it shows in particular
that [List.Permutation] and [permutation] are equivalent in this context.
*)
@@ -179,7 +179,7 @@ Proof.
simpl; trivial using permut_refl.
simpl.
apply permut_add_cons_inside.
- rewrite <- app_nil_end. trivial.
+ rewrite app_nil_r. trivial.
Qed.
(** * Some inversion results. *)
diff --git a/theories/Sorting/Permutation.v b/theories/Sorting/Permutation.v
index 803e1083..fcb4e787 100644
--- a/theories/Sorting/Permutation.v
+++ b/theories/Sorting/Permutation.v
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
@@ -13,12 +13,10 @@
(* Adapted in May 2006 by Jean-Marc Notin from initial contents by
Laurent Théry (Huffmann contribution, October 2003) *)
-Require Import List Setoid.
-
+Require Import List Setoid Compare_dec Morphisms FinFun.
+Import ListNotations. (* For notations [] and [a;b;c] *)
Set Implicit Arguments.
-
-Local Notation "[ ]" := nil.
-Local Notation "[ a ; .. ; b ]" := (a :: .. (b :: []) ..).
+(* Set Universe Polymorphism. *)
Section Permutation.
@@ -28,7 +26,8 @@ Inductive Permutation : list A -> list A -> Prop :=
| perm_nil: Permutation [] []
| perm_skip x l l' : Permutation l l' -> Permutation (x::l) (x::l')
| perm_swap x y l : Permutation (y::x::l) (x::y::l)
-| perm_trans l l' l'' : Permutation l l' -> Permutation l' l'' -> Permutation l l''.
+| perm_trans l l' l'' :
+ Permutation l l' -> Permutation l' l'' -> Permutation l l''.
Local Hint Constructors Permutation.
@@ -41,7 +40,8 @@ Proof.
induction HF; discriminate || auto.
Qed.
-Theorem Permutation_nil_cons : forall (l : list A) (x : A), ~ Permutation nil (x::l).
+Theorem Permutation_nil_cons : forall (l : list A) (x : A),
+ ~ Permutation nil (x::l).
Proof.
intros l x HF.
apply Permutation_nil in HF; discriminate.
@@ -54,13 +54,15 @@ Proof.
induction l; constructor. exact IHl.
Qed.
-Theorem Permutation_sym : forall l l' : list A, Permutation l l' -> Permutation l' l.
+Theorem Permutation_sym : forall l l' : list A,
+ Permutation l l' -> Permutation l' l.
Proof.
intros l l' Hperm; induction Hperm; auto.
apply perm_trans with (l':=l'); assumption.
Qed.
-Theorem Permutation_trans : forall l l' l'' : list A, Permutation l l' -> Permutation l' l'' -> Permutation l l''.
+Theorem Permutation_trans : forall l l' l'' : list A,
+ Permutation l l' -> Permutation l' l'' -> Permutation l l''.
Proof.
exact perm_trans.
Qed.
@@ -83,11 +85,10 @@ Instance Permutation_Equivalence A : Equivalence (@Permutation A) | 10 := {
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.
+Instance Permutation_cons A :
+ Proper (Logic.eq ==> @Permutation A ==> @Permutation A) (@cons A) | 10.
Proof.
- auto using perm_skip.
+ repeat intro; subst; auto using perm_skip.
Qed.
Section Permutation_properties.
@@ -99,35 +100,48 @@ Implicit Types l m : list A.
(** Compatibility with others operations on lists *)
-Theorem Permutation_in : forall (l l' : list A) (x : A), Permutation l l' -> In x l -> In x l'.
+Theorem Permutation_in : forall (l l' : list A) (x : A),
+ Permutation l l' -> In x l -> In x l'.
Proof.
intros l l' x Hperm; induction Hperm; simpl; tauto.
Qed.
-Lemma Permutation_app_tail : forall (l l' tl : list A), Permutation l l' -> Permutation (l++tl) (l'++tl).
+Global Instance Permutation_in' :
+ Proper (Logic.eq ==> @Permutation A ==> iff) (@In A) | 10.
+Proof.
+ repeat red; intros; subst; eauto using Permutation_in.
+Qed.
+
+Lemma Permutation_app_tail : forall (l l' tl : list A),
+ Permutation l l' -> Permutation (l++tl) (l'++tl).
Proof.
intros l l' tl Hperm; induction Hperm as [|x l l'|x y l|l l' l'']; simpl; auto.
eapply Permutation_trans with (l':=l'++tl); trivial.
Qed.
-Lemma Permutation_app_head : forall (l tl tl' : list A), Permutation tl tl' -> Permutation (l++tl) (l++tl').
+Lemma Permutation_app_head : forall (l tl tl' : list A),
+ Permutation tl tl' -> Permutation (l++tl) (l++tl').
Proof.
- intros l tl tl' Hperm; induction l; [trivial | repeat rewrite <- app_comm_cons; constructor; assumption].
+ intros l tl tl' Hperm; induction l;
+ [trivial | repeat rewrite <- app_comm_cons; constructor; assumption].
Qed.
-Theorem Permutation_app : forall (l m l' m' : list A), Permutation l l' -> Permutation m m' -> Permutation (l++m) (l'++m').
+Theorem Permutation_app : forall (l m l' m' : list A),
+ Permutation l l' -> Permutation m m' -> Permutation (l++m) (l'++m').
Proof.
- intros l m l' m' Hpermll' Hpermmm'; induction Hpermll' as [|x l l'|x y l|l l' l'']; repeat rewrite <- app_comm_cons; auto.
+ intros l m l' m' Hpermll' Hpermmm';
+ induction Hpermll' as [|x l l'|x y l|l l' l''];
+ repeat rewrite <- app_comm_cons; auto.
apply Permutation_trans with (l' := (x :: y :: l ++ m));
- [idtac | repeat rewrite app_comm_cons; apply Permutation_app_head]; trivial.
+ [idtac | repeat rewrite app_comm_cons; apply Permutation_app_head]; trivial.
apply Permutation_trans with (l' := (l' ++ m')); try assumption.
apply Permutation_app_tail; assumption.
Qed.
-Add Parametric Morphism : (@app A)
- with signature @Permutation A ==> @Permutation A ==> @Permutation A
- as Permutation_app'.
- auto using Permutation_app.
+Global Instance Permutation_app' :
+ Proper (@Permutation A ==> @Permutation A ==> @Permutation A) (@app A) | 10.
+Proof.
+ repeat intro; now apply Permutation_app.
Qed.
Lemma Permutation_add_inside : forall a (l l' tl tl' : list A),
@@ -146,20 +160,27 @@ Theorem Permutation_app_comm : forall (l l' : list A),
Permutation (l ++ l') (l' ++ l).
Proof.
induction l as [|x l]; simpl; intro l'.
- rewrite app_nil_r; trivial. rewrite IHl.
- rewrite app_comm_cons, Permutation_cons_append.
- now rewrite <- app_assoc.
+ rewrite app_nil_r; trivial. rewrite IHl.
+ rewrite app_comm_cons, Permutation_cons_append.
+ now rewrite <- app_assoc.
Qed.
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).
-Proof. intros l l1 l2 a H. rewrite H.
- rewrite app_comm_cons, Permutation_cons_append.
- now rewrite <- app_assoc.
+Proof.
+ intros l l1 l2 a H. rewrite H.
+ rewrite app_comm_cons, Permutation_cons_append.
+ now rewrite <- app_assoc.
Qed.
Local Hint Resolve Permutation_cons_app.
+Lemma Permutation_Add a l l' : Add a l l' -> Permutation (a::l) l'.
+Proof.
+ induction 1; simpl; trivial.
+ rewrite perm_swap. now apply perm_skip.
+Qed.
+
Theorem Permutation_middle : forall (l1 l2:list A) a,
Permutation (a :: l1 ++ l2) (l1 ++ a :: l2).
Proof.
@@ -169,18 +190,27 @@ Local Hint Resolve Permutation_middle.
Theorem Permutation_rev : forall (l : list A), Permutation l (rev l).
Proof.
- induction l as [| x l]; simpl; trivial. now rewrite IHl at 1.
+ induction l as [| x l]; simpl; trivial. now rewrite IHl at 1.
Qed.
-Add Parametric Morphism : (@rev A)
- with signature @Permutation A ==> @Permutation A as Permutation_rev'.
-Proof. intros. now do 2 rewrite <- Permutation_rev. Qed.
+Global Instance Permutation_rev' :
+ Proper (@Permutation A ==> @Permutation A) (@rev A) | 10.
+Proof.
+ repeat intro; now rewrite <- 2 Permutation_rev.
+Qed.
-Theorem Permutation_length : forall (l l' : list A), Permutation l l' -> length l = length l'.
+Theorem Permutation_length : forall (l l' : list A),
+ Permutation l l' -> length l = length l'.
Proof.
intros l l' Hperm; induction Hperm; simpl; auto. now transitivity (length l').
Qed.
+Global Instance Permutation_length' :
+ Proper (@Permutation A ==> Logic.eq) (@length A) | 10.
+Proof.
+ exact Permutation_length.
+Qed.
+
Theorem Permutation_ind_bis :
forall P : list A -> list A -> Prop,
P [] [] ->
@@ -200,73 +230,62 @@ Proof.
eauto.
Qed.
-Ltac break_list l x l' H :=
- destruct l as [|x l']; simpl in *;
- injection H; intros; subst; clear H.
-
-Theorem Permutation_nil_app_cons : forall (l l' : list A) (x : A), ~ Permutation nil (l++x::l').
+Theorem Permutation_nil_app_cons : forall (l l' : list A) (x : A),
+ ~ Permutation nil (l++x::l').
Proof.
- intros l l' x HF.
+ intros l l' x HF.
apply Permutation_nil in HF. destruct l; discriminate.
Qed.
-Theorem Permutation_app_inv : forall (l1 l2 l3 l4:list A) a,
+Ltac InvAdd := repeat (match goal with
+ | H: Add ?x _ (_ :: _) |- _ => inversion H; clear H; subst
+ end).
+
+Ltac finish_basic_perms H :=
+ try constructor; try rewrite perm_swap; try constructor; trivial;
+ (rewrite <- H; now apply Permutation_Add) ||
+ (rewrite H; symmetry; now apply Permutation_Add).
+
+Theorem Permutation_Add_inv a l1 l2 :
+ Permutation l1 l2 -> forall l1' l2', Add a l1' l1 -> Add a l2' l2 ->
+ Permutation l1' l2'.
+Proof.
+ revert l1 l2. refine (Permutation_ind_bis _ _ _ _ _).
+ - (* nil *)
+ inversion_clear 1.
+ - (* skip *)
+ intros x l1 l2 PE IH. intros. InvAdd; try finish_basic_perms PE.
+ constructor. now apply IH.
+ - (* swap *)
+ intros x y l1 l2 PE IH. intros. InvAdd; try finish_basic_perms PE.
+ rewrite perm_swap; do 2 constructor. now apply IH.
+ - (* trans *)
+ intros l1 l l2 PE IH PE' IH' l1' l2' AD1 AD2.
+ assert (Ha : In a l). { rewrite <- PE. rewrite (Add_in AD1). simpl; auto. }
+ destruct (Add_inv _ _ Ha) as (l',AD).
+ transitivity l'; auto.
+Qed.
+
+Theorem Permutation_app_inv (l1 l2 l3 l4:list A) a :
Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4).
Proof.
- set (P l l' :=
- forall a l1 l2 l3 l4, l=l1++a::l2 -> l'=l3++a::l4 -> Permutation (l1++l2) (l3++l4)).
- cut (forall l l', Permutation l l' -> P l l').
- intros; apply (H _ _ H0 a); auto.
- intros; apply (Permutation_ind_bis P); unfold P; clear P; try clear H l l'; simpl; auto.
-(* nil *)
- intros; destruct l1; simpl in *; discriminate.
- (* skip *)
- intros x l l' H IH; intros.
- break_list l1 b l1' H0; break_list l3 c l3' H1.
- auto.
- now rewrite H.
- now rewrite <- H.
- now rewrite (IH a _ _ _ _ eq_refl eq_refl).
- (* contradict *)
- intros x y l l' Hp IH; intros.
- break_list l1 b l1' H; break_list l3 c l3' H0.
- auto.
- break_list l3' b l3'' H.
- auto.
- rewrite <- Permutation_middle in Hp. now rewrite Hp.
- break_list l1' c l1'' H1.
- auto.
- rewrite <- Permutation_middle in Hp. now rewrite Hp.
- break_list l3' d l3'' H; break_list l1' e l1'' H1.
- auto.
- rewrite <- Permutation_middle in Hp. rewrite perm_swap. auto.
- rewrite perm_swap, Permutation_middle. auto.
- now rewrite perm_swap, (IH a _ _ _ _ eq_refl eq_refl).
- (*trans*)
- intros.
- destruct (In_split a l') as (l'1,(l'2,H6)).
- apply (Permutation_in a H).
- subst l.
- apply in_or_app; right; red; auto.
- apply perm_trans with (l'1++l'2).
- apply (H0 _ _ _ _ _ H3 H6).
- apply (H2 _ _ _ _ _ H6 H4).
+ intros. eapply Permutation_Add_inv; eauto using Add_app.
Qed.
-Theorem Permutation_cons_inv :
- forall l l' a, Permutation (a::l) (a::l') -> Permutation l l'.
+Theorem Permutation_cons_inv l l' a :
+ Permutation (a::l) (a::l') -> Permutation l l'.
Proof.
- intros; exact (Permutation_app_inv [] l [] l' a H).
+ intro. eapply Permutation_Add_inv; eauto using Add_head.
Qed.
-Theorem Permutation_cons_app_inv :
- forall l l1 l2 a, Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).
+Theorem Permutation_cons_app_inv l l1 l2 a :
+ Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).
Proof.
- intros; exact (Permutation_app_inv [] l l1 l2 a H).
+ intro. eapply Permutation_Add_inv; eauto using Add_head, Add_app.
Qed.
-Theorem Permutation_app_inv_l :
- forall l l1 l2, Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.
+Theorem Permutation_app_inv_l : forall l l1 l2,
+ Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.
Proof.
induction l; simpl; auto.
intros.
@@ -274,20 +293,16 @@ Proof.
apply Permutation_cons_inv with a; auto.
Qed.
-Theorem Permutation_app_inv_r :
- forall l l1 l2, Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.
+Theorem Permutation_app_inv_r l l1 l2 :
+ Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.
Proof.
- induction l.
- intros l1 l2; do 2 rewrite app_nil_r; auto.
- intros.
- apply IHl.
- apply Permutation_app_inv with a; auto.
+ rewrite 2 (Permutation_app_comm _ l). apply Permutation_app_inv_l.
Qed.
Lemma Permutation_length_1_inv: forall a l, Permutation [a] l -> l = [a].
Proof.
intros a l H; remember [a] as m in H.
- induction H; try (injection Heqm as -> ->; clear Heqm);
+ induction H; try (injection Heqm as -> ->);
discriminate || auto.
apply Permutation_nil in H as ->; trivial.
Qed.
@@ -318,32 +333,47 @@ Proof.
apply Permutation_length_2_inv in H as [H|H]; injection H as -> ->; auto.
Qed.
-Lemma NoDup_Permutation : forall l l',
- NoDup l -> NoDup l' -> (forall x:A, In x l <-> In x l') -> Permutation l l'.
+Lemma NoDup_Permutation l l' : NoDup l -> NoDup l' ->
+ (forall x:A, In x l <-> In x l') -> Permutation l l'.
Proof.
- induction l.
- destruct l'; simpl; intros.
- apply perm_nil.
- destruct (H1 a) as (_,H2); destruct H2; auto.
- intros.
- destruct (In_split a l') as (l'1,(l'2,H2)).
- destruct (H1 a) as (H2,H3); simpl in *; auto.
- subst l'.
- apply Permutation_cons_app.
- inversion_clear H.
- apply IHl; auto.
- apply NoDup_remove_1 with a; auto.
- intro x; split; intros.
- assert (In x (l'1++a::l'2)).
- destruct (H1 x); simpl in *; auto.
- apply in_or_app; destruct (in_app_or _ _ _ H4); auto.
- destruct H5; auto.
- subst x; destruct H2; auto.
- assert (In x (l'1++a::l'2)).
- apply in_or_app; destruct (in_app_or _ _ _ H); simpl; auto.
- destruct (H1 x) as (_,H5); destruct H5; auto.
- subst x.
- destruct (NoDup_remove_2 _ _ _ H0 H).
+ intros N. revert l'. induction N as [|a l Hal Hl IH].
+ - destruct l'; simpl; auto.
+ intros Hl' H. exfalso. rewrite (H a); auto.
+ - intros l' Hl' H.
+ assert (Ha : In a l') by (apply H; simpl; auto).
+ destruct (Add_inv _ _ Ha) as (l'' & AD).
+ rewrite <- (Permutation_Add AD).
+ apply perm_skip.
+ apply IH; clear IH.
+ * now apply (NoDup_Add AD).
+ * split.
+ + apply incl_Add_inv with a l'; trivial. intro. apply H.
+ + intro Hx.
+ assert (Hx' : In x (a::l)).
+ { apply H. rewrite (Add_in AD). now right. }
+ destruct Hx'; simpl; trivial. subst.
+ rewrite (NoDup_Add AD) in Hl'. tauto.
+Qed.
+
+Lemma NoDup_Permutation_bis l l' : NoDup l -> NoDup l' ->
+ length l' <= length l -> incl l l' -> Permutation l l'.
+Proof.
+ intros. apply NoDup_Permutation; auto.
+ split; auto. apply NoDup_length_incl; trivial.
+Qed.
+
+Lemma Permutation_NoDup l l' : Permutation l l' -> NoDup l -> NoDup l'.
+Proof.
+ induction 1; auto.
+ * inversion_clear 1; constructor; eauto using Permutation_in.
+ * inversion_clear 1 as [|? ? H1 H2]. inversion_clear H2; simpl in *.
+ constructor. simpl; intuition. constructor; intuition.
+Qed.
+
+Global Instance Permutation_NoDup' :
+ Proper (@Permutation A ==> iff) (@NoDup A) | 10.
+Proof.
+ repeat red; eauto using Permutation_NoDup.
Qed.
End Permutation_properties.
@@ -353,20 +383,194 @@ 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 l l' :
+ Permutation l l' -> Permutation (map f l) (map f l').
Proof.
- induction 1; simpl; eauto using Permutation.
+ induction 1; simpl; eauto.
Qed.
-Lemma Permutation_map :
- forall l l', Permutation l l' -> Permutation (map f l) (map f l').
+Global Instance Permutation_map' :
+ Proper (@Permutation A ==> @Permutation B) (map f) | 10.
Proof.
- exact Permutation_map_aux_Proper.
+ exact Permutation_map.
Qed.
End Permutation_map.
+Lemma nat_bijection_Permutation n f :
+ bFun n f ->
+ Injective f ->
+ let l := seq 0 n in Permutation (map f l) l.
+Proof.
+ intros Hf BD.
+ apply NoDup_Permutation_bis; auto using Injective_map_NoDup, seq_NoDup.
+ * now rewrite map_length.
+ * intros x. rewrite in_map_iff. intros (y & <- & Hy').
+ rewrite in_seq in *. simpl in *.
+ destruct Hy' as (_,Hy'). auto with arith.
+Qed.
+
+Section Permutation_alt.
+Variable A:Type.
+Implicit Type a : A.
+Implicit Type l : list A.
+
+(** Alternative characterization of permutation
+ via [nth_error] and [nth] *)
+
+Let adapt f n :=
+ let m := f (S n) in if le_lt_dec m (f 0) then m else pred m.
+
+Let adapt_injective f : Injective f -> Injective (adapt f).
+Proof.
+ unfold adapt. intros Hf x y EQ.
+ destruct le_lt_dec as [LE|LT]; destruct le_lt_dec as [LE'|LT'].
+ - now apply eq_add_S, Hf.
+ - apply Lt.le_lt_or_eq in LE.
+ destruct LE as [LT|EQ']; [|now apply Hf in EQ'].
+ unfold lt in LT. rewrite EQ in LT.
+ rewrite <- (Lt.S_pred _ _ LT') in LT.
+ elim (Lt.lt_not_le _ _ LT' LT).
+ - apply Lt.le_lt_or_eq in LE'.
+ destruct LE' as [LT'|EQ']; [|now apply Hf in EQ'].
+ unfold lt in LT'. rewrite <- EQ in LT'.
+ rewrite <- (Lt.S_pred _ _ LT) in LT'.
+ elim (Lt.lt_not_le _ _ LT LT').
+ - apply eq_add_S, Hf.
+ now rewrite (Lt.S_pred _ _ LT), (Lt.S_pred _ _ LT'), EQ.
+Qed.
+
+Let adapt_ok a l1 l2 f : Injective f -> length l1 = f 0 ->
+ forall n, nth_error (l1++a::l2) (f (S n)) = nth_error (l1++l2) (adapt f n).
+Proof.
+ unfold adapt. intros Hf E n.
+ destruct le_lt_dec as [LE|LT].
+ - apply Lt.le_lt_or_eq in LE.
+ destruct LE as [LT|EQ]; [|now apply Hf in EQ].
+ rewrite <- E in LT.
+ rewrite 2 nth_error_app1; auto.
+ - rewrite (Lt.S_pred _ _ LT) at 1.
+ rewrite <- E, (Lt.S_pred _ _ LT) in LT.
+ rewrite 2 nth_error_app2; auto with arith.
+ rewrite <- Minus.minus_Sn_m; auto with arith.
+Qed.
+
+Lemma Permutation_nth_error l l' :
+ Permutation l l' <->
+ (length l = length l' /\
+ exists f:nat->nat,
+ Injective f /\ forall n, nth_error l' n = nth_error l (f n)).
+Proof.
+ split.
+ { intros P.
+ split; [now apply Permutation_length|].
+ induction P.
+ - exists (fun n => n).
+ split; try red; auto.
+ - destruct IHP as (f & Hf & Hf').
+ exists (fun n => match n with O => O | S n => S (f n) end).
+ split; try red.
+ * intros [|y] [|z]; simpl; now auto.
+ * intros [|n]; simpl; auto.
+ - exists (fun n => match n with 0 => 1 | 1 => 0 | n => n end).
+ split; try red.
+ * intros [|[|z]] [|[|t]]; simpl; now auto.
+ * intros [|[|n]]; simpl; auto.
+ - destruct IHP1 as (f & Hf & Hf').
+ destruct IHP2 as (g & Hg & Hg').
+ exists (fun n => f (g n)).
+ split; try red.
+ * auto.
+ * intros n. rewrite <- Hf'; auto. }
+ { revert l. induction l'.
+ - intros [|l] (E & _); now auto.
+ - intros l (E & f & Hf & Hf').
+ simpl in E.
+ assert (Ha : nth_error l (f 0) = Some a)
+ by (symmetry; apply (Hf' 0)).
+ destruct (nth_error_split l (f 0) Ha) as (l1 & l2 & L12 & L1).
+ rewrite L12. rewrite <- Permutation_middle. constructor.
+ apply IHl'; split; [|exists (adapt f); split].
+ * revert E. rewrite L12, !app_length. simpl.
+ rewrite <- plus_n_Sm. now injection 1.
+ * now apply adapt_injective.
+ * intro n. rewrite <- (adapt_ok a), <- L12; auto.
+ apply (Hf' (S n)). }
+Qed.
+
+Lemma Permutation_nth_error_bis l l' :
+ Permutation l l' <->
+ exists f:nat->nat,
+ Injective f /\
+ bFun (length l) f /\
+ (forall n, nth_error l' n = nth_error l (f n)).
+Proof.
+ rewrite Permutation_nth_error; split.
+ - intros (E & f & Hf & Hf').
+ exists f. do 2 (split; trivial).
+ intros n Hn.
+ destruct (Lt.le_or_lt (length l) (f n)) as [LE|LT]; trivial.
+ rewrite <- nth_error_None, <- Hf', nth_error_None, <- E in LE.
+ elim (Lt.lt_not_le _ _ Hn LE).
+ - intros (f & Hf & Hf2 & Hf3); split; [|exists f; auto].
+ assert (H : length l' <= length l') by auto with arith.
+ rewrite <- nth_error_None, Hf3, nth_error_None in H.
+ destruct (Lt.le_or_lt (length l) (length l')) as [LE|LT];
+ [|apply Hf2 in LT; elim (Lt.lt_not_le _ _ LT H)].
+ apply Lt.le_lt_or_eq in LE. destruct LE as [LT|EQ]; trivial.
+ rewrite <- nth_error_Some, Hf3, nth_error_Some in LT.
+ assert (Hf' : bInjective (length l) f).
+ { intros x y _ _ E. now apply Hf. }
+ rewrite (bInjective_bSurjective Hf2) in Hf'.
+ destruct (Hf' _ LT) as (y & Hy & Hy').
+ apply Hf in Hy'. subst y. elim (Lt.lt_irrefl _ Hy).
+Qed.
+
+Lemma Permutation_nth l l' d :
+ Permutation l l' <->
+ (let n := length l in
+ length l' = n /\
+ exists f:nat->nat,
+ bFun n f /\
+ bInjective n f /\
+ (forall x, x < n -> nth x l' d = nth (f x) l d)).
+Proof.
+ split.
+ - intros H.
+ assert (E := Permutation_length H).
+ split; auto.
+ apply Permutation_nth_error_bis in H.
+ destruct H as (f & Hf & Hf2 & Hf3).
+ exists f. split; [|split]; auto.
+ intros x y _ _ Hxy. now apply Hf.
+ intros n Hn. rewrite <- 2 nth_default_eq. unfold nth_default.
+ now rewrite Hf3.
+ - intros (E & f & Hf1 & Hf2 & Hf3).
+ rewrite Permutation_nth_error.
+ split; auto.
+ exists (fun n => if le_lt_dec (length l) n then n else f n).
+ split.
+ * intros x y.
+ destruct le_lt_dec as [LE|LT];
+ destruct le_lt_dec as [LE'|LT']; auto.
+ + apply Hf1 in LT'. intros ->.
+ elim (Lt.lt_irrefl (f y)). eapply Lt.lt_le_trans; eauto.
+ + apply Hf1 in LT. intros <-.
+ elim (Lt.lt_irrefl (f x)). eapply Lt.lt_le_trans; eauto.
+ * intros n.
+ destruct le_lt_dec as [LE|LT].
+ + assert (LE' : length l' <= n) by (now rewrite E).
+ rewrite <- nth_error_None in LE, LE'. congruence.
+ + assert (LT' : n < length l') by (now rewrite E).
+ specialize (Hf3 n LT). rewrite <- 2 nth_default_eq in Hf3.
+ unfold nth_default in Hf3.
+ apply Hf1 in LT.
+ rewrite <- nth_error_Some in LT, LT'.
+ do 2 destruct nth_error; congruence.
+Qed.
+
+End Permutation_alt.
+
(* begin hide *)
Notation Permutation_app_swap := Permutation_app_comm (only parsing).
-(* end hide *) \ No newline at end of file
+(* end hide *)
diff --git a/theories/Sorting/Sorted.v b/theories/Sorting/Sorted.v
index fde796af..dc4a1e0a 100644
--- a/theories/Sorting/Sorted.v
+++ b/theories/Sorting/Sorted.v
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
@@ -20,6 +20,8 @@
Require Import List Relations Relations_1.
+(* Set Universe Polymorphism. *)
+
(** Preambule *)
Set Implicit Arguments.
@@ -67,7 +69,7 @@ Section defs.
(forall a l, Sorted l -> P l -> HdRel a l -> P (a :: l)) ->
forall l:list A, Sorted l -> P l.
Proof.
- induction l; firstorder using Sorted_inv.
+ induction l. firstorder using Sorted_inv. firstorder using Sorted_inv.
Qed.
Lemma Sorted_LocallySorted_iff : forall l, Sorted l <-> LocallySorted l.
diff --git a/theories/Sorting/Sorting.v b/theories/Sorting/Sorting.v
index 6a9105ab..712b8fd6 100644
--- a/theories/Sorting/Sorting.v
+++ b/theories/Sorting/Sorting.v
@@ -1,6 +1,6 @@
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)