1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(*i $Id: Permutation.v 10698 2008-03-19 18:46:59Z letouzey $ i*)
11
Require Import Relations List Multiset Arith.
13
(** This file define a notion of permutation for lists, based on multisets:
14
there exists a permutation between two lists iff every elements have
15
the same multiplicities in the two lists.
17
Unlike [List.Permutation], the present notion of permutation requires
18
a decidable equality. At the same time, this definition can be used
19
with a non-standard equality, whereas [List.Permutation] cannot.
21
The present file contains basic results, obtained without any particular
22
assumption on the decidable equality used.
24
File [PermutSetoid] contains additional results about permutations
25
with respect to an setoid equality (i.e. an equivalence relation).
27
Finally, file [PermutEq] concerns Coq equality : this file is similar
28
to the previous one, but proves in addition that [List.Permutation]
29
and [permutation] are equivalent in this context.
32
Set Implicit Arguments.
36
(** * From lists to multisets *)
39
Variable eqA : relation A.
40
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
42
Let emptyBag := EmptyBag A.
43
Let singletonBag := SingletonBag _ eqA_dec.
45
(** contents of a list *)
47
Fixpoint list_contents (l:list A) : multiset A :=
50
| a :: l => munion (singletonBag a) (list_contents l)
53
Lemma list_contents_app :
55
meq (list_contents (l ++ m)) (munion (list_contents l) (list_contents m)).
57
simple induction l; simpl in |- *; auto with datatypes.
60
(munion (singletonBag a) (munion (list_contents l0) (list_contents m)));
65
(** * [permutation]: definition and basic properties *)
67
Definition permutation (l m:list A) :=
68
meq (list_contents l) (list_contents m).
70
Lemma permut_refl : forall l:list A, permutation l l.
72
unfold permutation in |- *; auto with datatypes.
76
forall l1 l2 : list A, permutation l1 l2 -> permutation l2 l1.
78
unfold permutation, meq; intros; apply sym_eq; trivial.
82
forall l m n:list A, permutation l m -> permutation m n -> permutation l n.
84
unfold permutation in |- *; intros.
85
apply meq_trans with (list_contents m); auto with datatypes.
90
permutation l m -> forall a:A, permutation (a :: l) (a :: m).
92
unfold permutation in |- *; simpl in |- *; auto with datatypes.
96
forall l l' m m':list A,
97
permutation l l' -> permutation m m' -> permutation (l ++ m) (l' ++ m').
99
unfold permutation in |- *; intros.
100
apply meq_trans with (munion (list_contents l) (list_contents m));
101
auto using permut_cons, list_contents_app with datatypes.
102
apply meq_trans with (munion (list_contents l') (list_contents m'));
103
auto using permut_cons, list_contents_app with datatypes.
104
apply meq_trans with (munion (list_contents l') (list_contents m));
105
auto using permut_cons, list_contents_app with datatypes.
108
Lemma permut_add_inside :
109
forall a l1 l2 l3 l4,
110
permutation (l1 ++ l2) (l3 ++ l4) ->
111
permutation (l1 ++ a :: l2) (l3 ++ a :: l4).
113
unfold permutation, meq in *; intros.
114
generalize (H a0); clear H.
115
do 4 rewrite list_contents_app.
117
destruct (eqA_dec a a0); simpl; auto with arith.
118
do 2 rewrite <- plus_n_Sm; f_equal; auto.
121
Lemma permut_add_cons_inside :
123
permutation l (l1 ++ l2) ->
124
permutation (a :: l) (l1 ++ a :: l2).
127
replace (a :: l) with (nil ++ a :: l); trivial;
128
apply permut_add_inside; trivial.
131
Lemma permut_middle :
132
forall (l m:list A) (a:A), permutation (a :: l ++ m) (l ++ a :: m).
134
intros; apply permut_add_cons_inside; auto using permut_sym, permut_refl.
137
Lemma permut_sym_app :
138
forall l1 l2, permutation (l1 ++ l2) (l2 ++ l1).
141
unfold permutation, meq;
142
intro a; do 2 rewrite list_contents_app; simpl;
147
forall l, permutation l (rev l).
150
simpl; trivial using permut_refl.
152
apply permut_add_cons_inside.
153
rewrite <- app_nil_end. trivial.
156
(** * Some inversion results. *)
157
Lemma permut_conv_inv :
158
forall e l1 l2, permutation (e :: l1) (e :: l2) -> permutation l1 l2.
160
intros e l1 l2; unfold permutation, meq; simpl; intros H a;
161
generalize (H a); apply plus_reg_l.
164
Lemma permut_app_inv1 :
165
forall l l1 l2, permutation (l1 ++ l) (l2 ++ l) -> permutation l1 l2.
167
intros l l1 l2; unfold permutation, meq; simpl;
168
intros H a; generalize (H a); clear H.
169
do 2 rewrite list_contents_app.
171
intros; apply plus_reg_l with (multiplicity (list_contents l) a).
172
rewrite plus_comm; rewrite H; rewrite plus_comm.
176
Lemma permut_app_inv2 :
177
forall l l1 l2, permutation (l ++ l1) (l ++ l2) -> permutation l1 l2.
179
intros l l1 l2; unfold permutation, meq; simpl;
180
intros H a; generalize (H a); clear H.
181
do 2 rewrite list_contents_app.
183
intros; apply plus_reg_l with (multiplicity (list_contents l) a).
187
Lemma permut_remove_hd :
189
permutation (a :: l) (l1 ++ a :: l2) -> permutation l (l1 ++ l2).
191
intros l l1 l2 a; unfold permutation, meq; simpl; intros H a0; generalize (H a0); clear H.
192
do 2 rewrite list_contents_app; simpl; intro H.
193
apply plus_reg_l with (if eqA_dec a a0 then 1 else 0).
195
symmetry; rewrite plus_comm.
196
repeat rewrite <- plus_assoc; f_equal.
202
(** For compatibilty *)
203
Notation permut_right := permut_cons.
204
Unset Implicit Arguments.