~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to theories/FSets/FSetProperties.v

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(***********************************************************************)
 
2
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team    *)
 
3
(* <O___,, *        INRIA-Rocquencourt  &  LRI-CNRS-Orsay              *)
 
4
(*   \VV/  *************************************************************)
 
5
(*    //   *      This file is distributed under the terms of the      *)
 
6
(*         *       GNU Lesser General Public License Version 2.1       *)
 
7
(***********************************************************************)
 
8
 
 
9
(* $Id: FSetProperties.v 11720 2008-12-28 07:12:15Z letouzey $ *)
 
10
 
 
11
(** * Finite sets library *)
 
12
 
 
13
(** This functor derives additional properties from [FSetInterface.S].
 
14
    Contrary to the functor in [FSetEqProperties] it uses 
 
15
    predicates over sets instead of sets operations, i.e.
 
16
    [In x s] instead of [mem x s=true], 
 
17
    [Equal s s'] instead of [equal s s'=true], etc. *)
 
18
 
 
19
Require Export FSetInterface.
 
20
Require Import DecidableTypeEx FSetFacts FSetDecide.
 
21
Set Implicit Arguments.
 
22
Unset Strict Implicit.
 
23
 
 
24
Hint Unfold transpose compat_op.
 
25
Hint Extern 1 (Equivalence _) => constructor; congruence.
 
26
 
 
27
(** First, a functor for Weak Sets in functorial version. *)
 
28
 
 
29
Module WProperties_fun (Import E : DecidableType)(M : WSfun E).
 
30
  Module Import Dec := WDecide_fun E M.
 
31
  Module Import FM := Dec.F (* FSetFacts.WFacts_fun E M *).
 
32
  Import M.
 
33
 
 
34
  Lemma In_dec : forall x s, {In x s} + {~ In x s}.
 
35
  Proof.
 
36
  intros; generalize (mem_iff s x); case (mem x s); intuition.
 
37
  Qed.
 
38
 
 
39
  Definition Add x s s' := forall y, In y s' <-> E.eq x y \/ In y s.
 
40
 
 
41
  Lemma Add_Equal : forall x s s', Add x s s' <-> s' [=] add x s.
 
42
  Proof.
 
43
  unfold Add.
 
44
  split; intros.
 
45
  red; intros.
 
46
  rewrite H; clear H.
 
47
  fsetdec.
 
48
  fsetdec.
 
49
  Qed.
 
50
  
 
51
  Ltac expAdd := repeat rewrite Add_Equal.
 
52
 
 
53
  Section BasicProperties.
 
54
 
 
55
  Variable s s' s'' s1 s2 s3 : t.
 
56
  Variable x x' : elt.
 
57
 
 
58
  Lemma equal_refl : s[=]s.
 
59
  Proof. fsetdec. Qed.
 
60
 
 
61
  Lemma equal_sym : s[=]s' -> s'[=]s.
 
62
  Proof. fsetdec. Qed.
 
63
 
 
64
  Lemma equal_trans : s1[=]s2 -> s2[=]s3 -> s1[=]s3.
 
65
  Proof. fsetdec. Qed.
 
66
 
 
67
  Lemma subset_refl : s[<=]s. 
 
68
  Proof. fsetdec. Qed.
 
69
 
 
70
  Lemma subset_trans : s1[<=]s2 -> s2[<=]s3 -> s1[<=]s3.
 
71
  Proof. fsetdec. Qed.
 
72
 
 
73
  Lemma subset_antisym : s[<=]s' -> s'[<=]s -> s[=]s'.
 
74
  Proof. fsetdec. Qed.
 
75
 
 
76
  Lemma subset_equal : s[=]s' -> s[<=]s'.
 
77
  Proof. fsetdec. Qed.
 
78
 
 
79
  Lemma subset_empty : empty[<=]s.
 
80
  Proof. fsetdec. Qed.
 
81
 
 
82
  Lemma subset_remove_3 : s1[<=]s2 -> remove x s1 [<=] s2.
 
83
  Proof. fsetdec. Qed.
 
84
 
 
85
  Lemma subset_diff : s1[<=]s3 -> diff s1 s2 [<=] s3.
 
86
  Proof. fsetdec. Qed.
 
87
 
 
88
  Lemma subset_add_3 : In x s2 -> s1[<=]s2 -> add x s1 [<=] s2.
 
89
  Proof. fsetdec. Qed.
 
90
 
 
91
  Lemma subset_add_2 : s1[<=]s2 -> s1[<=] add x s2.
 
92
  Proof. fsetdec. Qed.
 
93
 
 
94
  Lemma in_subset : In x s1 -> s1[<=]s2 -> In x s2.
 
95
  Proof. fsetdec. Qed.
 
96
 
 
97
  Lemma double_inclusion : s1[=]s2 <-> s1[<=]s2 /\ s2[<=]s1.
 
98
  Proof. intuition fsetdec. Qed.
 
99
 
 
100
  Lemma empty_is_empty_1 : Empty s -> s[=]empty.
 
101
  Proof. fsetdec. Qed.
 
102
 
 
103
  Lemma empty_is_empty_2 : s[=]empty -> Empty s.
 
104
  Proof. fsetdec. Qed.
 
105
 
 
106
  Lemma add_equal : In x s -> add x s [=] s.
 
107
  Proof. fsetdec. Qed.
 
108
 
 
109
  Lemma add_add : add x (add x' s) [=] add x' (add x s).
 
110
  Proof. fsetdec. Qed.
 
111
 
 
112
  Lemma remove_equal : ~ In x s -> remove x s [=] s.
 
113
  Proof. fsetdec. Qed.
 
114
 
 
115
  Lemma Equal_remove : s[=]s' -> remove x s [=] remove x s'.
 
116
  Proof. fsetdec. Qed.
 
117
 
 
118
  Lemma add_remove : In x s -> add x (remove x s) [=] s.
 
119
  Proof. fsetdec. Qed.
 
120
 
 
121
  Lemma remove_add : ~In x s -> remove x (add x s) [=] s.
 
122
  Proof. fsetdec. Qed.
 
123
 
 
124
  Lemma singleton_equal_add : singleton x [=] add x empty.
 
125
  Proof. fsetdec. Qed.
 
126
 
 
127
  Lemma remove_singleton_empty :
 
128
   In x s -> remove x s [=] empty -> singleton x [=] s.
 
129
  Proof. fsetdec. Qed.
 
130
 
 
131
  Lemma union_sym : union s s' [=] union s' s.
 
132
  Proof. fsetdec. Qed.
 
133
 
 
134
  Lemma union_subset_equal : s[<=]s' -> union s s' [=] s'.
 
135
  Proof. fsetdec. Qed.
 
136
 
 
137
  Lemma union_equal_1 : s[=]s' -> union s s'' [=] union s' s''.
 
138
  Proof. fsetdec. Qed.
 
139
 
 
140
  Lemma union_equal_2 : s'[=]s'' -> union s s' [=] union s s''.
 
141
  Proof. fsetdec. Qed.
 
142
 
 
143
  Lemma union_assoc : union (union s s') s'' [=] union s (union s' s'').
 
144
  Proof. fsetdec. Qed.
 
145
 
 
146
  Lemma add_union_singleton : add x s [=] union (singleton x) s.
 
147
  Proof. fsetdec. Qed.
 
148
 
 
149
  Lemma union_add : union (add x s) s' [=] add x (union s s').
 
150
  Proof. fsetdec. Qed.
 
151
 
 
152
  Lemma union_remove_add_1 : 
 
153
   union (remove x s) (add x s') [=] union (add x s) (remove x s').
 
154
  Proof. fsetdec. Qed.
 
155
 
 
156
  Lemma union_remove_add_2 : In x s -> 
 
157
   union (remove x s) (add x s') [=] union s s'.
 
158
  Proof. fsetdec. Qed.
 
159
 
 
160
  Lemma union_subset_1 : s [<=] union s s'.
 
161
  Proof. fsetdec. Qed.
 
162
 
 
163
  Lemma union_subset_2 : s' [<=] union s s'.
 
164
  Proof. fsetdec. Qed.
 
165
 
 
166
  Lemma union_subset_3 : s[<=]s'' -> s'[<=]s'' -> union s s' [<=] s''.
 
167
  Proof. fsetdec. Qed.
 
168
 
 
169
  Lemma union_subset_4 : s[<=]s' -> union s s'' [<=] union s' s''.
 
170
  Proof. fsetdec. Qed. 
 
171
 
 
172
  Lemma union_subset_5 : s[<=]s' -> union s'' s [<=] union s'' s'.
 
173
  Proof. fsetdec. Qed. 
 
174
 
 
175
  Lemma empty_union_1 : Empty s -> union s s' [=] s'.
 
176
  Proof. fsetdec. Qed.
 
177
 
 
178
  Lemma empty_union_2 : Empty s -> union s' s [=] s'.
 
179
  Proof. fsetdec. Qed.
 
180
 
 
181
  Lemma not_in_union : ~In x s -> ~In x s' -> ~In x (union s s'). 
 
182
  Proof. fsetdec. Qed.
 
183
 
 
184
  Lemma inter_sym : inter s s' [=] inter s' s.
 
185
  Proof. fsetdec. Qed.
 
186
 
 
187
  Lemma inter_subset_equal : s[<=]s' -> inter s s' [=] s.
 
188
  Proof. fsetdec. Qed.
 
189
 
 
190
  Lemma inter_equal_1 : s[=]s' -> inter s s'' [=] inter s' s''.
 
191
  Proof. fsetdec. Qed.
 
192
 
 
193
  Lemma inter_equal_2 : s'[=]s'' -> inter s s' [=] inter s s''.
 
194
  Proof. fsetdec. Qed.
 
195
 
 
196
  Lemma inter_assoc : inter (inter s s') s'' [=] inter s (inter s' s'').
 
197
  Proof. fsetdec. Qed.
 
198
 
 
199
  Lemma union_inter_1 : inter (union s s') s'' [=] union (inter s s'') (inter s' s'').
 
200
  Proof. fsetdec. Qed.
 
201
 
 
202
  Lemma union_inter_2 : union (inter s s') s'' [=] inter (union s s'') (union s' s'').
 
203
  Proof. fsetdec. Qed.
 
204
 
 
205
  Lemma inter_add_1 : In x s' -> inter (add x s) s' [=] add x (inter s s').
 
206
  Proof. fsetdec. Qed.
 
207
 
 
208
  Lemma inter_add_2 : ~ In x s' -> inter (add x s) s' [=] inter s s'.
 
209
  Proof. fsetdec. Qed.
 
210
 
 
211
  Lemma empty_inter_1 : Empty s -> Empty (inter s s').
 
212
  Proof. fsetdec. Qed.
 
213
 
 
214
  Lemma empty_inter_2 : Empty s' -> Empty (inter s s').
 
215
  Proof. fsetdec. Qed.
 
216
 
 
217
  Lemma inter_subset_1 : inter s s' [<=] s.
 
218
  Proof. fsetdec. Qed.
 
219
 
 
220
  Lemma inter_subset_2 : inter s s' [<=] s'.
 
221
  Proof. fsetdec. Qed.
 
222
 
 
223
  Lemma inter_subset_3 :
 
224
   s''[<=]s -> s''[<=]s' -> s''[<=] inter s s'.
 
225
  Proof. fsetdec. Qed.
 
226
 
 
227
  Lemma empty_diff_1 : Empty s -> Empty (diff s s'). 
 
228
  Proof. fsetdec. Qed.
 
229
 
 
230
  Lemma empty_diff_2 : Empty s -> diff s' s [=] s'.
 
231
  Proof. fsetdec. Qed.
 
232
 
 
233
  Lemma diff_subset : diff s s' [<=] s.
 
234
  Proof. fsetdec. Qed.
 
235
 
 
236
  Lemma diff_subset_equal : s[<=]s' -> diff s s' [=] empty.
 
237
  Proof. fsetdec. Qed.
 
238
 
 
239
  Lemma remove_diff_singleton :
 
240
   remove x s [=] diff s (singleton x).
 
241
  Proof. fsetdec. Qed.
 
242
 
 
243
  Lemma diff_inter_empty : inter (diff s s') (inter s s') [=] empty. 
 
244
  Proof. fsetdec. Qed.
 
245
 
 
246
  Lemma diff_inter_all : union (diff s s') (inter s s') [=] s.
 
247
  Proof. fsetdec. Qed.
 
248
 
 
249
  Lemma Add_add : Add x s (add x s).
 
250
  Proof. expAdd; fsetdec. Qed.
 
251
 
 
252
  Lemma Add_remove : In x s -> Add x (remove x s) s. 
 
253
  Proof. expAdd; fsetdec. Qed.
 
254
 
 
255
  Lemma union_Add : Add x s s' -> Add x (union s s'') (union s' s'').
 
256
  Proof. expAdd; fsetdec. Qed. 
 
257
 
 
258
  Lemma inter_Add :
 
259
   In x s'' -> Add x s s' -> Add x (inter s s'') (inter s' s'').
 
260
  Proof. expAdd; fsetdec. Qed. 
 
261
 
 
262
  Lemma union_Equal :
 
263
   In x s'' -> Add x s s' -> union s s'' [=] union s' s''.
 
264
  Proof. expAdd; fsetdec. Qed. 
 
265
 
 
266
  Lemma inter_Add_2 :
 
267
   ~In x s'' -> Add x s s' -> inter s s'' [=] inter s' s''.
 
268
  Proof. expAdd; fsetdec. Qed.
 
269
 
 
270
  End BasicProperties.
 
271
 
 
272
  Hint Immediate equal_sym add_remove remove_add union_sym inter_sym: set.
 
273
  Hint Resolve equal_refl equal_trans subset_refl subset_equal subset_antisym 
 
274
    subset_trans subset_empty subset_remove_3 subset_diff subset_add_3 
 
275
    subset_add_2 in_subset empty_is_empty_1 empty_is_empty_2 add_equal
 
276
    remove_equal singleton_equal_add union_subset_equal union_equal_1 
 
277
    union_equal_2 union_assoc add_union_singleton union_add union_subset_1 
 
278
    union_subset_2 union_subset_3 inter_subset_equal inter_equal_1 inter_equal_2
 
279
    inter_assoc union_inter_1 union_inter_2 inter_add_1 inter_add_2
 
280
    empty_inter_1 empty_inter_2 empty_union_1 empty_union_2 empty_diff_1 
 
281
    empty_diff_2 union_Add inter_Add union_Equal inter_Add_2 not_in_union 
 
282
    inter_subset_1 inter_subset_2 inter_subset_3 diff_subset diff_subset_equal 
 
283
    remove_diff_singleton diff_inter_empty diff_inter_all Add_add Add_remove
 
284
    Equal_remove add_add : set.
 
285
 
 
286
  (** * Properties of elements *)
 
287
 
 
288
  Lemma elements_Empty : forall s, Empty s <-> elements s = nil.
 
289
  Proof.
 
290
  intros.
 
291
  unfold Empty.
 
292
  split; intros.
 
293
  assert (forall a, ~ List.In a (elements s)).
 
294
   red; intros.
 
295
   apply (H a).
 
296
   rewrite elements_iff.
 
297
   rewrite InA_alt; exists a; auto.
 
298
  destruct (elements s); auto.
 
299
  elim (H0 e); simpl; auto.
 
300
  red; intros.
 
301
  rewrite elements_iff in H0.
 
302
  rewrite InA_alt in H0; destruct H0.
 
303
  rewrite H in H0; destruct H0 as (_,H0); inversion H0.
 
304
  Qed.
 
305
 
 
306
  Lemma elements_empty : elements empty = nil.
 
307
  Proof.
 
308
  rewrite <-elements_Empty; auto with set.
 
309
  Qed.
 
310
 
 
311
  (** * Conversions between lists and sets *)
 
312
 
 
313
  Definition of_list (l : list elt) := List.fold_right add empty l.
 
314
 
 
315
  Definition to_list := elements.
 
316
 
 
317
  Lemma of_list_1 : forall l x, In x (of_list l) <-> InA E.eq x l.
 
318
  Proof.
 
319
  induction l; simpl; intro x.
 
320
  rewrite empty_iff, InA_nil. intuition.
 
321
  rewrite add_iff, InA_cons, IHl. intuition.
 
322
  Qed.
 
323
 
 
324
  Lemma of_list_2 : forall l, equivlistA E.eq (to_list (of_list l)) l.
 
325
  Proof.
 
326
  unfold to_list; red; intros.
 
327
  rewrite <- elements_iff; apply of_list_1.
 
328
  Qed.
 
329
 
 
330
  Lemma of_list_3 : forall s, of_list (to_list s) [=] s.
 
331
  Proof.
 
332
  unfold to_list; red; intros.
 
333
  rewrite of_list_1; symmetry; apply elements_iff.
 
334
  Qed.
 
335
 
 
336
  (** * Fold *)
 
337
 
 
338
  Section Fold.
 
339
 
 
340
  Notation NoDup := (NoDupA E.eq).
 
341
  Notation InA := (InA E.eq).
 
342
 
 
343
  (** ** Induction principles for fold (contributed by S. Lescuyer) *)
 
344
 
 
345
  (** In the following lemma, the step hypothesis is deliberately restricted
 
346
      to the precise set s we are considering. *)
 
347
 
 
348
  Theorem fold_rec :
 
349
    forall (A:Type)(P : t -> A -> Type)(f : elt -> A -> A)(i:A)(s:t),
 
350
     (forall s', Empty s' -> P s' i) ->
 
351
     (forall x a s' s'', In x s -> ~In x s' -> Add x s' s'' ->
 
352
       P s' a -> P s'' (f x a)) ->
 
353
     P s (fold f s i).
 
354
  Proof.
 
355
  intros A P f i s Pempty Pstep.
 
356
  rewrite fold_1, <- fold_left_rev_right.
 
357
  set (l:=rev (elements s)).
 
358
  assert (Pstep' : forall x a s' s'', InA x l -> ~In x s' -> Add x s' s'' ->
 
359
           P s' a -> P s'' (f x a)).
 
360
   intros; eapply Pstep; eauto.
 
361
   rewrite elements_iff, <- InA_rev; auto.
 
362
  assert (Hdup : NoDup l) by
 
363
    (unfold l; eauto using elements_3w, NoDupA_rev).
 
364
  assert (Hsame : forall x, In x s <-> InA x l) by
 
365
    (unfold l; intros; rewrite elements_iff, InA_rev; intuition).
 
366
  clear Pstep; clearbody l; revert s Hsame; induction l.
 
367
  (* empty *)
 
368
  intros s Hsame; simpl.
 
369
  apply Pempty. intro x. rewrite Hsame, InA_nil; intuition.
 
370
  (* step *)
 
371
  intros s Hsame; simpl.
 
372
  apply Pstep' with (of_list l); auto.
 
373
   inversion_clear Hdup; rewrite of_list_1; auto.
 
374
   red. intros. rewrite Hsame, of_list_1, InA_cons; intuition.
 
375
  apply IHl.
 
376
   intros; eapply Pstep'; eauto.
 
377
   inversion_clear Hdup; auto.
 
378
   exact (of_list_1 l).
 
379
  Qed.
 
380
 
 
381
  (** Same, with [empty] and [add] instead of [Empty] and [Add]. In this
 
382
      case, [P] must be compatible with equality of sets *)
 
383
 
 
384
  Theorem fold_rec_bis :
 
385
    forall (A:Type)(P : t -> A -> Type)(f : elt -> A -> A)(i:A)(s:t),
 
386
     (forall s s' a, s[=]s' -> P s a -> P s' a) ->
 
387
     (P empty i) ->
 
388
     (forall x a s', In x s -> ~In x s' -> P s' a -> P (add x s') (f x a)) ->
 
389
     P s (fold f s i).
 
390
  Proof.
 
391
  intros A P f i s Pmorphism Pempty Pstep.
 
392
  apply fold_rec; intros.
 
393
  apply Pmorphism with empty; auto with set.
 
394
  rewrite Add_Equal in H1; auto with set.
 
395
  apply Pmorphism with (add x s'); auto with set.
 
396
  Qed.
 
397
 
 
398
  Lemma fold_rec_nodep :
 
399
    forall (A:Type)(P : A -> Type)(f : elt -> A -> A)(i:A)(s:t),
 
400
     P i -> (forall x a, In x s -> P a -> P (f x a)) ->
 
401
     P (fold f s i).
 
402
  Proof.
 
403
  intros; apply fold_rec_bis with (P:=fun _ => P); auto.
 
404
  Qed.
 
405
 
 
406
  (** [fold_rec_weak] is a weaker principle than [fold_rec_bis] :
 
407
      the step hypothesis must here be applicable to any [x].
 
408
      At the same time, it looks more like an induction principle,
 
409
      and hence can be easier to use. *)
 
410
 
 
411
  Lemma fold_rec_weak :
 
412
    forall (A:Type)(P : t -> A -> Type)(f : elt -> A -> A)(i:A),
 
413
    (forall s s' a, s[=]s' -> P s a -> P s' a) ->
 
414
    P empty i ->
 
415
    (forall x a s, ~In x s -> P s a -> P (add x s) (f x a)) ->
 
416
    forall s, P s (fold f s i).
 
417
  Proof.
 
418
  intros; apply fold_rec_bis; auto.
 
419
  Qed.
 
420
 
 
421
  Lemma fold_rel :
 
422
    forall (A B:Type)(R : A -> B -> Type)
 
423
     (f : elt -> A -> A)(g : elt -> B -> B)(i : A)(j : B)(s : t),
 
424
     R i j ->
 
425
     (forall x a b, In x s -> R a b -> R (f x a) (g x b)) ->
 
426
     R (fold f s i) (fold g s j).
 
427
  Proof.
 
428
  intros A B R f g i j s Rempty Rstep.
 
429
  do 2 rewrite fold_1, <- fold_left_rev_right.
 
430
  set (l:=rev (elements s)).
 
431
  assert (Rstep' : forall x a b, InA x l -> R a b -> R (f x a) (g x b)) by
 
432
    (intros; apply Rstep; auto; rewrite elements_iff, <- InA_rev; auto).
 
433
  clearbody l; clear Rstep s.
 
434
  induction l; simpl; auto.
 
435
  Qed.
 
436
 
 
437
  (** From the induction principle on [fold], we can deduce some general
 
438
      induction principles on sets. *)
 
439
 
 
440
  Lemma set_induction :
 
441
   forall P : t -> Type,
 
442
   (forall s, Empty s -> P s) ->
 
443
   (forall s s', P s -> forall x, ~In x s -> Add x s s' -> P s') ->
 
444
   forall s, P s.
 
445
  Proof.
 
446
  intros. apply (@fold_rec _ (fun s _ => P s) (fun _ _ => tt) tt s); eauto.
 
447
  Qed.
 
448
 
 
449
  Lemma set_induction_bis :
 
450
   forall P : t -> Type,
 
451
   (forall s s', s [=] s' -> P s -> P s') ->
 
452
   P empty ->
 
453
   (forall x s, ~In x s -> P s -> P (add x s)) ->
 
454
   forall s, P s.
 
455
  Proof.
 
456
  intros.
 
457
  apply (@fold_rec_bis _ (fun s _ => P s) (fun _ _ => tt) tt s); eauto.
 
458
  Qed.
 
459
 
 
460
  (** [fold] can be used to reconstruct the same initial set. *)
 
461
 
 
462
  Lemma fold_identity : forall s, fold add s empty [=] s.
 
463
  Proof.
 
464
  intros.
 
465
  apply fold_rec with (P:=fun s acc => acc[=]s); auto with set.
 
466
  intros. rewrite H2; rewrite Add_Equal in H1; auto with set.
 
467
  Qed.
 
468
 
 
469
  (** ** Alternative (weaker) specifications for [fold] *)
 
470
 
 
471
  (** When [FSets] was first designed, the order in which Ocaml's [Set.fold]
 
472
      takes the set elements was unspecified. This specification reflects
 
473
      this fact:
 
474
  *)
 
475
 
 
476
  Lemma fold_0 :
 
477
      forall s (A : Type) (i : A) (f : elt -> A -> A),
 
478
      exists l : list elt,
 
479
        NoDup l /\
 
480
        (forall x : elt, In x s <-> InA x l) /\
 
481
        fold f s i = fold_right f i l.
 
482
  Proof.
 
483
  intros; exists (rev (elements s)); split.
 
484
  apply NoDupA_rev; auto with set.
 
485
  exact E.eq_trans.
 
486
  split; intros.
 
487
  rewrite elements_iff; do 2 rewrite InA_alt.
 
488
  split; destruct 1; generalize (In_rev (elements s) x0); exists x0; intuition.
 
489
  rewrite fold_left_rev_right.
 
490
  apply fold_1.
 
491
  Qed.
 
492
 
 
493
  (** An alternate (and previous) specification for [fold] was based on
 
494
      the recursive structure of a set. It is now lemmas [fold_1] and
 
495
      [fold_2]. *)
 
496
 
 
497
  Lemma fold_1 :
 
498
   forall s (A : Type) (eqA : A -> A -> Prop)
 
499
     (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
 
500
   Empty s -> eqA (fold f s i) i.
 
501
  Proof.
 
502
  unfold Empty; intros; destruct (fold_0 s i f) as (l,(H1, (H2, H3))).
 
503
  rewrite H3; clear H3.
 
504
  generalize H H2; clear H H2; case l; simpl; intros.
 
505
  reflexivity.
 
506
  elim (H e).
 
507
  elim (H2 e); intuition. 
 
508
  Qed.
 
509
 
 
510
  Lemma fold_2 :
 
511
   forall s s' x (A : Type) (eqA : A -> A -> Prop)
 
512
     (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
 
513
   compat_op E.eq eqA f ->
 
514
   transpose eqA f ->
 
515
   ~ In x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i)).
 
516
  Proof.
 
517
  intros; destruct (fold_0 s i f) as (l,(Hl, (Hl1, Hl2))); 
 
518
    destruct (fold_0 s' i f) as (l',(Hl', (Hl'1, Hl'2))).
 
519
  rewrite Hl2; rewrite Hl'2; clear Hl2 Hl'2.
 
520
  apply fold_right_add with (eqA:=E.eq)(eqB:=eqA); auto.
 
521
  eauto.
 
522
  rewrite <- Hl1; auto.
 
523
  intros a; rewrite InA_cons; rewrite <- Hl1; rewrite <- Hl'1; 
 
524
   rewrite (H2 a); intuition.
 
525
  Qed.
 
526
 
 
527
  (** In fact, [fold] on empty sets is more than equivalent to 
 
528
      the initial element, it is Leibniz-equal to it. *)
 
529
 
 
530
  Lemma fold_1b :
 
531
   forall s (A : Type)(i : A) (f : elt -> A -> A),
 
532
   Empty s -> (fold f s i) = i.
 
533
  Proof.
 
534
  intros.
 
535
  rewrite M.fold_1.
 
536
  rewrite elements_Empty in H; rewrite H; simpl; auto.
 
537
  Qed.
 
538
 
 
539
  Section Fold_More.
 
540
 
 
541
  Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA).
 
542
  Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f)(Ass:transpose eqA f).
 
543
 
 
544
  Lemma fold_commutes : forall i s x, 
 
545
   eqA (fold f s (f x i)) (f x (fold f s i)).
 
546
  Proof.
 
547
  intros.
 
548
  apply fold_rel with (R:=fun u v => eqA u (f x v)); intros.
 
549
  reflexivity.
 
550
  transitivity (f x0 (f x b)); auto.
 
551
  Qed.
 
552
 
 
553
  (** ** Fold is a morphism *)
 
554
 
 
555
  Lemma fold_init : forall i i' s, eqA i i' -> 
 
556
   eqA (fold f s i) (fold f s i').
 
557
  Proof.
 
558
  intros. apply fold_rel with (R:=eqA); auto.
 
559
  Qed.
 
560
 
 
561
  Lemma fold_equal : 
 
562
   forall i s s', s[=]s' -> eqA (fold f s i) (fold f s' i).
 
563
  Proof. 
 
564
  intros i s; pattern s; apply set_induction; clear s; intros.
 
565
  transitivity i.
 
566
  apply fold_1; auto.
 
567
  symmetry; apply fold_1; auto.
 
568
  rewrite <- H0; auto.
 
569
  transitivity (f x (fold f s i)).
 
570
  apply fold_2 with (eqA := eqA); auto.
 
571
  symmetry; apply fold_2 with (eqA := eqA); auto.
 
572
  unfold Add in *; intros.
 
573
  rewrite <- H2; auto.
 
574
  Qed.
 
575
 
 
576
  (** ** Fold and other set operators *)
 
577
 
 
578
  Lemma fold_empty : forall i, fold f empty i = i.
 
579
  Proof. 
 
580
  intros i; apply fold_1b; auto with set.
 
581
  Qed.
 
582
 
 
583
  Lemma fold_add : forall i s x, ~In x s -> 
 
584
   eqA (fold f (add x s) i) (f x (fold f s i)).
 
585
  Proof. 
 
586
  intros; apply fold_2 with (eqA := eqA); auto with set.
 
587
  Qed.
 
588
 
 
589
  Lemma add_fold : forall i s x, In x s -> 
 
590
   eqA (fold f (add x s) i) (fold f s i).
 
591
  Proof.
 
592
  intros; apply fold_equal; auto with set.
 
593
  Qed.
 
594
 
 
595
  Lemma remove_fold_1: forall i s x, In x s -> 
 
596
   eqA (f x (fold f (remove x s) i)) (fold f s i).
 
597
  Proof.
 
598
  intros.
 
599
  symmetry.
 
600
  apply fold_2 with (eqA:=eqA); auto with set.
 
601
  Qed.
 
602
 
 
603
  Lemma remove_fold_2: forall i s x, ~In x s -> 
 
604
   eqA (fold f (remove x s) i) (fold f s i).
 
605
  Proof.
 
606
  intros.
 
607
  apply fold_equal; auto with set.
 
608
  Qed.
 
609
 
 
610
  Lemma fold_union_inter : forall i s s',
 
611
   eqA (fold f (union s s') (fold f (inter s s') i))
 
612
       (fold f s (fold f s' i)).
 
613
  Proof.
 
614
  intros; pattern s; apply set_induction; clear s; intros.
 
615
  transitivity (fold f s' (fold f (inter s s') i)).
 
616
  apply fold_equal; auto with set.
 
617
  transitivity (fold f s' i).
 
618
  apply fold_init; auto.
 
619
  apply fold_1; auto with set.
 
620
  symmetry; apply fold_1; auto.
 
621
  rename s'0 into s''.
 
622
  destruct (In_dec x s').
 
623
  (* In x s' *)   
 
624
  transitivity (fold f (union s'' s') (f x (fold f (inter s s') i))); auto with set.
 
625
  apply fold_init; auto.
 
626
  apply fold_2 with (eqA:=eqA); auto with set.
 
627
  rewrite inter_iff; intuition.
 
628
  transitivity (f x (fold f s (fold f s' i))).
 
629
  transitivity (fold f (union s s') (f x (fold f (inter s s') i))).
 
630
  apply fold_equal; auto.
 
631
  apply equal_sym; apply union_Equal with x; auto with set.
 
632
  transitivity (f x (fold f (union s s') (fold f (inter s s') i))).
 
633
  apply fold_commutes; auto.
 
634
  apply Comp; auto.
 
635
  symmetry; apply fold_2 with (eqA:=eqA); auto.
 
636
  (* ~(In x s') *)
 
637
  transitivity (f x (fold f (union s s') (fold f (inter s'' s') i))).
 
638
  apply fold_2 with (eqA:=eqA); auto with set.
 
639
  transitivity (f x (fold f (union s s') (fold f (inter s s') i))).
 
640
  apply Comp;auto.
 
641
  apply fold_init;auto.
 
642
  apply fold_equal;auto.
 
643
  apply equal_sym; apply inter_Add_2 with x; auto with set.
 
644
  transitivity (f x (fold f s (fold f s' i))).
 
645
  apply Comp; auto.
 
646
  symmetry; apply fold_2 with (eqA:=eqA); auto.
 
647
  Qed.
 
648
 
 
649
  Lemma fold_diff_inter : forall i s s', 
 
650
   eqA (fold f (diff s s') (fold f (inter s s') i)) (fold f s i).
 
651
  Proof.
 
652
  intros.
 
653
  transitivity (fold f (union (diff s s') (inter s s'))
 
654
               (fold f (inter (diff s s') (inter s s')) i)).
 
655
  symmetry; apply fold_union_inter; auto.
 
656
  transitivity (fold f s (fold f (inter (diff s s') (inter s s')) i)).
 
657
  apply fold_equal; auto with set.
 
658
  apply fold_init; auto.
 
659
  apply fold_1; auto with set.
 
660
  Qed.
 
661
 
 
662
  Lemma fold_union: forall i s s', 
 
663
   (forall x, ~(In x s/\In x s')) ->
 
664
   eqA (fold f (union s s') i) (fold f s (fold f s' i)).
 
665
  Proof.
 
666
  intros.
 
667
  transitivity (fold f (union s s') (fold f (inter s s') i)).
 
668
  apply fold_init; auto.
 
669
  symmetry; apply fold_1; auto with set.
 
670
  unfold Empty; intro a; generalize (H a); set_iff; tauto.
 
671
  apply fold_union_inter; auto.
 
672
  Qed.
 
673
 
 
674
  End Fold_More.
 
675
 
 
676
  Lemma fold_plus :
 
677
   forall s p, fold (fun _ => S) s p = fold (fun _ => S) s 0 + p.
 
678
  Proof.
 
679
  intros. apply fold_rel with (R:=fun u v => u = v + p); simpl; auto.
 
680
  Qed.
 
681
 
 
682
  End Fold.
 
683
 
 
684
  (** * Cardinal *)
 
685
 
 
686
  (** ** Characterization of cardinal in terms of fold *)
 
687
 
 
688
  Lemma cardinal_fold : forall s, cardinal s = fold (fun _ => S) s 0.
 
689
  Proof.
 
690
  intros; rewrite cardinal_1; rewrite M.fold_1.
 
691
  symmetry; apply fold_left_length; auto.
 
692
  Qed.
 
693
 
 
694
  (** ** Old specifications for [cardinal]. *)
 
695
 
 
696
  Lemma cardinal_0 :
 
697
     forall s, exists l : list elt,
 
698
        NoDupA E.eq l /\
 
699
        (forall x : elt, In x s <-> InA E.eq x l) /\ 
 
700
        cardinal s = length l.
 
701
  Proof. 
 
702
  intros; exists (elements s); intuition; apply cardinal_1.
 
703
  Qed.
 
704
 
 
705
  Lemma cardinal_1 : forall s, Empty s -> cardinal s = 0.
 
706
  Proof.
 
707
  intros; rewrite cardinal_fold; apply fold_1; auto.
 
708
  Qed.
 
709
 
 
710
  Lemma cardinal_2 :
 
711
    forall s s' x, ~ In x s -> Add x s s' -> cardinal s' = S (cardinal s).
 
712
  Proof.
 
713
  intros; do 2 rewrite cardinal_fold.
 
714
  change S with ((fun _ => S) x).
 
715
  apply fold_2; auto.
 
716
  Qed.
 
717
 
 
718
  (** ** Cardinal and (non-)emptiness *)
 
719
 
 
720
  Lemma cardinal_Empty : forall s, Empty s <-> cardinal s = 0.
 
721
  Proof.
 
722
  intros.
 
723
  rewrite elements_Empty, M.cardinal_1.
 
724
  destruct (elements s); intuition; discriminate.
 
725
  Qed.
 
726
 
 
727
  Lemma cardinal_inv_1 : forall s, cardinal s = 0 -> Empty s. 
 
728
  Proof.
 
729
  intros; rewrite cardinal_Empty; auto. 
 
730
  Qed.
 
731
  Hint Resolve cardinal_inv_1.
 
732
 
 
733
  Lemma cardinal_inv_2 :
 
734
   forall s n, cardinal s = S n -> { x : elt | In x s }.
 
735
  Proof. 
 
736
  intros; rewrite M.cardinal_1 in H.
 
737
  generalize (elements_2 (s:=s)).
 
738
  destruct (elements s); try discriminate. 
 
739
  exists e; auto.
 
740
  Qed.
 
741
 
 
742
  Lemma cardinal_inv_2b :
 
743
   forall s, cardinal s <> 0 -> { x : elt | In x s }.
 
744
  Proof.
 
745
  intro; generalize (@cardinal_inv_2 s); destruct cardinal; 
 
746
   [intuition|eauto].
 
747
  Qed.
 
748
 
 
749
  (** ** Cardinal is a morphism *)
 
750
 
 
751
  Lemma Equal_cardinal : forall s s', s[=]s' -> cardinal s = cardinal s'.
 
752
  Proof. 
 
753
  symmetry.
 
754
  remember (cardinal s) as n; symmetry in Heqn; revert s s' Heqn H.
 
755
  induction n; intros.
 
756
  apply cardinal_1; rewrite <- H; auto.
 
757
  destruct (cardinal_inv_2 Heqn) as (x,H2).
 
758
  revert Heqn.
 
759
  rewrite (cardinal_2 (s:=remove x s) (s':=s) (x:=x)); auto with set.
 
760
  rewrite (cardinal_2 (s:=remove x s') (s':=s') (x:=x)); eauto with set.
 
761
  Qed.
 
762
 
 
763
  Add Morphism cardinal : cardinal_m.
 
764
  Proof.
 
765
  exact Equal_cardinal.
 
766
  Qed.
 
767
 
 
768
  Hint Resolve Add_add Add_remove Equal_remove cardinal_inv_1 Equal_cardinal.
 
769
 
 
770
  (** ** Cardinal and set operators *)
 
771
 
 
772
  Lemma empty_cardinal : cardinal empty = 0.
 
773
  Proof.
 
774
  rewrite cardinal_fold; apply fold_1; auto with set.
 
775
  Qed.
 
776
 
 
777
  Hint Immediate empty_cardinal cardinal_1 : set.
 
778
 
 
779
  Lemma singleton_cardinal : forall x, cardinal (singleton x) = 1.
 
780
  Proof.
 
781
  intros.
 
782
  rewrite (singleton_equal_add x).
 
783
  replace 0 with (cardinal empty); auto with set.
 
784
  apply cardinal_2 with x; auto with set.
 
785
  Qed.
 
786
 
 
787
  Hint Resolve singleton_cardinal: set.
 
788
 
 
789
  Lemma diff_inter_cardinal :
 
790
   forall s s', cardinal (diff s s') + cardinal (inter s s') = cardinal s .
 
791
  Proof.
 
792
  intros; do 3 rewrite cardinal_fold.
 
793
  rewrite <- fold_plus.
 
794
  apply fold_diff_inter with (eqA:=@Logic.eq nat); auto.
 
795
  Qed.
 
796
 
 
797
  Lemma union_cardinal: 
 
798
   forall s s', (forall x, ~(In x s/\In x s')) -> 
 
799
   cardinal (union s s')=cardinal s+cardinal s'.
 
800
  Proof.
 
801
  intros; do 3 rewrite cardinal_fold.
 
802
  rewrite <- fold_plus.
 
803
  apply fold_union; auto.
 
804
  Qed.
 
805
 
 
806
  Lemma subset_cardinal : 
 
807
   forall s s', s[<=]s' -> cardinal s <= cardinal s' .
 
808
  Proof.
 
809
  intros.
 
810
  rewrite <- (diff_inter_cardinal s' s).
 
811
  rewrite (inter_sym s' s).
 
812
  rewrite (inter_subset_equal H); auto with arith.
 
813
  Qed.
 
814
 
 
815
  Lemma subset_cardinal_lt : 
 
816
   forall s s' x, s[<=]s' -> In x s' -> ~In x s -> cardinal s < cardinal s'.
 
817
  Proof. 
 
818
  intros.
 
819
  rewrite <- (diff_inter_cardinal s' s).
 
820
  rewrite (inter_sym s' s).
 
821
  rewrite (inter_subset_equal H).
 
822
  generalize (@cardinal_inv_1 (diff s' s)).
 
823
  destruct (cardinal (diff s' s)).
 
824
  intro H2; destruct (H2 (refl_equal _) x).
 
825
  set_iff; auto.
 
826
  intros _.
 
827
  change (0 + cardinal s < S n + cardinal s).
 
828
  apply Plus.plus_lt_le_compat; auto with arith.
 
829
  Qed. 
 
830
 
 
831
  Theorem union_inter_cardinal :
 
832
   forall s s', cardinal (union s s') + cardinal (inter s s')  = cardinal s  + cardinal s' .
 
833
  Proof.
 
834
  intros.
 
835
  do 4 rewrite cardinal_fold.
 
836
  do 2 rewrite <- fold_plus.
 
837
  apply fold_union_inter with (eqA:=@Logic.eq nat); auto.
 
838
  Qed.
 
839
 
 
840
  Lemma union_cardinal_inter : 
 
841
   forall s s', cardinal (union s s') = cardinal s + cardinal s' - cardinal (inter s s').
 
842
  Proof.
 
843
  intros.
 
844
  rewrite <- union_inter_cardinal.
 
845
  rewrite Plus.plus_comm.
 
846
  auto with arith.
 
847
  Qed.
 
848
 
 
849
  Lemma union_cardinal_le : 
 
850
   forall s s', cardinal (union s s') <= cardinal s  + cardinal s'.
 
851
  Proof.
 
852
   intros; generalize (union_inter_cardinal s s').
 
853
   intros; rewrite <- H; auto with arith.
 
854
  Qed.
 
855
 
 
856
  Lemma add_cardinal_1 : 
 
857
   forall s x, In x s -> cardinal (add x s) = cardinal s.
 
858
  Proof.
 
859
  auto with set.  
 
860
  Qed.
 
861
 
 
862
  Lemma add_cardinal_2 :
 
863
   forall s x, ~In x s -> cardinal (add x s) = S (cardinal s).
 
864
  Proof.
 
865
  intros.
 
866
  do 2 rewrite cardinal_fold.
 
867
  change S with ((fun _ => S) x);
 
868
   apply fold_add with (eqA:=@Logic.eq nat); auto.
 
869
  Qed.
 
870
 
 
871
  Lemma remove_cardinal_1 :
 
872
   forall s x, In x s -> S (cardinal (remove x s)) = cardinal s.
 
873
  Proof.
 
874
  intros.
 
875
  do 2 rewrite cardinal_fold.
 
876
  change S with ((fun _ =>S) x).
 
877
  apply remove_fold_1 with (eqA:=@Logic.eq nat); auto.
 
878
  Qed.
 
879
 
 
880
  Lemma remove_cardinal_2 : 
 
881
   forall s x, ~In x s -> cardinal (remove x s) = cardinal s.
 
882
  Proof. 
 
883
  auto with set.
 
884
  Qed.
 
885
 
 
886
  Hint Resolve subset_cardinal union_cardinal add_cardinal_1 add_cardinal_2.
 
887
 
 
888
End WProperties_fun.
 
889
 
 
890
(** Now comes variants for self-contained weak sets and for full sets.
 
891
    For these variants, only one argument is necessary. Thanks to
 
892
    the subtyping [WS<=S], the [Properties] functor which is meant to be
 
893
    used on modules [(M:S)] can simply be an alias of [WProperties]. *)
 
894
 
 
895
Module WProperties (M:WS) := WProperties_fun M.E M.
 
896
Module Properties := WProperties.
 
897
 
 
898
 
 
899
(** Now comes some properties specific to the element ordering,
 
900
    invalid for Weak Sets. *)
 
901
 
 
902
Module OrdProperties (M:S).
 
903
  Module ME:=OrderedTypeFacts(M.E).
 
904
  Module Import P := Properties M.
 
905
  Import FM.
 
906
  Import M.E.
 
907
  Import M.
 
908
 
 
909
  (** First, a specialized version of SortA_equivlistA_eqlistA: *)
 
910
  Lemma sort_equivlistA_eqlistA : forall l l' : list elt,
 
911
   sort E.lt l -> sort E.lt l' -> equivlistA E.eq l l' -> eqlistA E.eq l l'.
 
912
  Proof.
 
913
  apply SortA_equivlistA_eqlistA; eauto.
 
914
  Qed.
 
915
 
 
916
  Definition gtb x y := match E.compare x y with GT _ => true | _ => false end.
 
917
  Definition leb x := fun y => negb (gtb x y).
 
918
 
 
919
  Definition elements_lt x s := List.filter (gtb x) (elements s).
 
920
  Definition elements_ge x s := List.filter (leb x) (elements s).
 
921
 
 
922
  Lemma gtb_1 : forall x y, gtb x y = true <-> E.lt y x.
 
923
  Proof.
 
924
   intros; unfold gtb; destruct (E.compare x y); intuition; try discriminate; ME.order.
 
925
  Qed.
 
926
 
 
927
  Lemma leb_1 : forall x y, leb x y = true <-> ~E.lt y x.
 
928
  Proof.
 
929
   intros; unfold leb, gtb; destruct (E.compare x y); intuition; try discriminate; ME.order.
 
930
  Qed.
 
931
 
 
932
  Lemma gtb_compat : forall x, compat_bool E.eq (gtb x).
 
933
  Proof.
 
934
   red; intros x a b H.
 
935
   generalize (gtb_1 x a)(gtb_1 x b); destruct (gtb x a); destruct (gtb x b); auto.
 
936
   intros.
 
937
   symmetry; rewrite H1.
 
938
   apply ME.eq_lt with a; auto.
 
939
   rewrite <- H0; auto.
 
940
   intros.
 
941
   rewrite H0.
 
942
   apply ME.eq_lt with b; auto.
 
943
   rewrite <- H1; auto.
 
944
  Qed.
 
945
 
 
946
  Lemma leb_compat : forall x, compat_bool E.eq (leb x).
 
947
  Proof.
 
948
   red; intros x a b H; unfold leb.
 
949
   f_equal; apply gtb_compat; auto.
 
950
  Qed.
 
951
  Hint Resolve gtb_compat leb_compat.
 
952
 
 
953
  Lemma elements_split : forall x s, 
 
954
   elements s = elements_lt x s ++ elements_ge x s.
 
955
  Proof.
 
956
  unfold elements_lt, elements_ge, leb; intros.
 
957
  eapply (@filter_split _ E.eq); eauto with set. ME.order. ME.order. ME.order.
 
958
  intros.
 
959
  rewrite gtb_1 in H.
 
960
  assert (~E.lt y x).
 
961
   unfold gtb in *; destruct (E.compare x y); intuition; try discriminate; ME.order.
 
962
  ME.order.
 
963
  Qed.
 
964
 
 
965
  Lemma elements_Add : forall s s' x, ~In x s -> Add x s s' -> 
 
966
    eqlistA E.eq (elements s') (elements_lt x s ++ x :: elements_ge x s). 
 
967
  Proof.
 
968
  intros; unfold elements_ge, elements_lt.
 
969
  apply sort_equivlistA_eqlistA; auto with set.
 
970
  apply (@SortA_app _ E.eq); auto.
 
971
  apply (@filter_sort _ E.eq); auto with set; eauto with set.
 
972
  constructor; auto.
 
973
  apply (@filter_sort _ E.eq); auto with set; eauto with set.
 
974
  rewrite ME.Inf_alt by (apply (@filter_sort _ E.eq); eauto with set).
 
975
  intros.
 
976
  rewrite filter_InA in H1; auto; destruct H1.
 
977
  rewrite leb_1 in H2.
 
978
  rewrite <- elements_iff in H1.
 
979
  assert (~E.eq x y).
 
980
   contradict H; rewrite H; auto.
 
981
  ME.order.
 
982
  intros.
 
983
  rewrite filter_InA in H1; auto; destruct H1.
 
984
  rewrite gtb_1 in H3.
 
985
  inversion_clear H2.
 
986
  ME.order.
 
987
  rewrite filter_InA in H4; auto; destruct H4.
 
988
  rewrite leb_1 in H4.
 
989
  ME.order.
 
990
  red; intros a.
 
991
  rewrite InA_app_iff; rewrite InA_cons.
 
992
  do 2 (rewrite filter_InA; auto).
 
993
  do 2 rewrite <- elements_iff.
 
994
  rewrite leb_1; rewrite gtb_1.
 
995
  rewrite (H0 a); intuition.
 
996
  destruct (E.compare a x); intuition.
 
997
  right; right; split; auto.
 
998
  ME.order.
 
999
  Qed.
 
1000
 
 
1001
  Definition Above x s := forall y, In y s -> E.lt y x.
 
1002
  Definition Below x s := forall y, In y s -> E.lt x y.
 
1003
 
 
1004
  Lemma elements_Add_Above : forall s s' x, 
 
1005
   Above x s -> Add x s s' -> 
 
1006
     eqlistA E.eq (elements s') (elements s ++ x::nil).
 
1007
  Proof.
 
1008
  intros.
 
1009
  apply sort_equivlistA_eqlistA; auto with set.
 
1010
  apply (@SortA_app _ E.eq); auto with set.
 
1011
  intros.
 
1012
  inversion_clear H2.
 
1013
  rewrite <- elements_iff in H1.
 
1014
  apply ME.lt_eq with x; auto.
 
1015
  inversion H3.
 
1016
  red; intros a.
 
1017
  rewrite InA_app_iff; rewrite InA_cons; rewrite InA_nil.
 
1018
  do 2 rewrite <- elements_iff; rewrite (H0 a); intuition.
 
1019
  Qed.
 
1020
 
 
1021
  Lemma elements_Add_Below : forall s s' x, 
 
1022
   Below x s -> Add x s s' -> 
 
1023
     eqlistA E.eq (elements s') (x::elements s).
 
1024
  Proof.
 
1025
  intros.
 
1026
  apply sort_equivlistA_eqlistA; auto with set.
 
1027
  change (sort E.lt ((x::nil) ++ elements s)).
 
1028
  apply (@SortA_app _ E.eq); auto with set.
 
1029
  intros.
 
1030
  inversion_clear H1.
 
1031
  rewrite <- elements_iff in H2.
 
1032
  apply ME.eq_lt with x; auto.
 
1033
  inversion H3.
 
1034
  red; intros a.
 
1035
  rewrite InA_cons.
 
1036
  do 2 rewrite <- elements_iff; rewrite (H0 a); intuition.
 
1037
  Qed.
 
1038
 
 
1039
  (** Two other induction principles on sets: we can be more restrictive 
 
1040
      on the element we add at each step.  *)
 
1041
 
 
1042
  Lemma set_induction_max :
 
1043
   forall P : t -> Type,
 
1044
   (forall s : t, Empty s -> P s) ->
 
1045
   (forall s s', P s -> forall x, Above x s -> Add x s s' -> P s') ->
 
1046
   forall s : t, P s.
 
1047
  Proof.
 
1048
  intros; remember (cardinal s) as n; revert s Heqn; induction n; intros; auto.
 
1049
  case_eq (max_elt s); intros.
 
1050
  apply X0 with (remove e s) e; auto with set.
 
1051
  apply IHn.
 
1052
  assert (S n = S (cardinal (remove e s))).
 
1053
   rewrite Heqn; apply cardinal_2 with e; auto with set.
 
1054
  inversion H0; auto.
 
1055
  red; intros.
 
1056
  rewrite remove_iff in H0; destruct H0.
 
1057
  generalize (@max_elt_2 s e y H H0); ME.order.
 
1058
 
 
1059
  assert (H0:=max_elt_3 H).
 
1060
  rewrite cardinal_Empty in H0; rewrite H0 in Heqn; inversion Heqn.
 
1061
  Qed.
 
1062
 
 
1063
  Lemma set_induction_min :
 
1064
   forall P : t -> Type,
 
1065
   (forall s : t, Empty s -> P s) ->
 
1066
   (forall s s', P s -> forall x, Below x s -> Add x s s' -> P s') ->
 
1067
   forall s : t, P s.
 
1068
  Proof.
 
1069
  intros; remember (cardinal s) as n; revert s Heqn; induction n; intros; auto.
 
1070
  case_eq (min_elt s); intros.
 
1071
  apply X0 with (remove e s) e; auto with set.
 
1072
  apply IHn.
 
1073
  assert (S n = S (cardinal (remove e s))).
 
1074
   rewrite Heqn; apply cardinal_2 with e; auto with set.
 
1075
  inversion H0; auto.
 
1076
  red; intros.
 
1077
  rewrite remove_iff in H0; destruct H0.
 
1078
  generalize (@min_elt_2 s e y H H0); ME.order.
 
1079
 
 
1080
  assert (H0:=min_elt_3 H).
 
1081
  rewrite cardinal_Empty in H0; auto; rewrite H0 in Heqn; inversion Heqn.
 
1082
  Qed.
 
1083
 
 
1084
  (** More properties of [fold] : behavior with respect to Above/Below *)
 
1085
 
 
1086
  Lemma fold_3 :
 
1087
   forall s s' x (A : Type) (eqA : A -> A -> Prop)
 
1088
     (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
 
1089
   compat_op E.eq eqA f ->
 
1090
   Above x s -> Add x s s' -> eqA (fold f s' i) (f x (fold f s i)).
 
1091
  Proof.
 
1092
  intros.
 
1093
  do 2 rewrite M.fold_1.
 
1094
  do 2 rewrite <- fold_left_rev_right.
 
1095
  change (f x (fold_right f i (rev (elements s)))) with
 
1096
    (fold_right f i (rev (x::nil)++rev (elements s))).
 
1097
  apply (@fold_right_eqlistA E.t E.eq A eqA st); auto.
 
1098
  rewrite <- distr_rev.
 
1099
  apply eqlistA_rev.
 
1100
  apply elements_Add_Above; auto.
 
1101
  Qed.
 
1102
 
 
1103
  Lemma fold_4 :
 
1104
   forall s s' x (A : Type) (eqA : A -> A -> Prop)
 
1105
     (st : Equivalence eqA) (i : A) (f : elt -> A -> A),
 
1106
   compat_op E.eq eqA f ->
 
1107
   Below x s -> Add x s s' -> eqA (fold f s' i) (fold f s (f x i)).
 
1108
  Proof.
 
1109
  intros.
 
1110
  do 2 rewrite M.fold_1.
 
1111
  set (g:=fun (a : A) (e : elt) => f e a).
 
1112
  change (eqA (fold_left g (elements s') i) (fold_left g (x::elements s) i)).
 
1113
  unfold g.
 
1114
  do 2 rewrite <- fold_left_rev_right.
 
1115
  apply (@fold_right_eqlistA E.t E.eq A eqA st); auto.
 
1116
  apply eqlistA_rev.
 
1117
  apply elements_Add_Below; auto.
 
1118
  Qed.
 
1119
 
 
1120
  (** The following results have already been proved earlier, 
 
1121
    but we can now prove them with one hypothesis less:
 
1122
    no need for [(transpose eqA f)]. *)
 
1123
 
 
1124
  Section FoldOpt. 
 
1125
  Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA).
 
1126
  Variables (f:elt->A->A)(Comp:compat_op E.eq eqA f).
 
1127
 
 
1128
  Lemma fold_equal : 
 
1129
   forall i s s', s[=]s' -> eqA (fold f s i) (fold f s' i).
 
1130
  Proof.
 
1131
  intros; do 2 rewrite M.fold_1.
 
1132
  do 2 rewrite <- fold_left_rev_right.
 
1133
  apply (@fold_right_eqlistA E.t E.eq A eqA st); auto.
 
1134
  apply eqlistA_rev.
 
1135
  apply sort_equivlistA_eqlistA; auto with set.
 
1136
  red; intro a; do 2 rewrite <- elements_iff; auto.
 
1137
  Qed.
 
1138
 
 
1139
  Lemma add_fold : forall i s x, In x s -> 
 
1140
   eqA (fold f (add x s) i) (fold f s i).
 
1141
  Proof.
 
1142
  intros; apply fold_equal; auto with set.
 
1143
  Qed.
 
1144
 
 
1145
  Lemma remove_fold_2: forall i s x, ~In x s -> 
 
1146
   eqA (fold f (remove x s) i) (fold f s i).
 
1147
  Proof.
 
1148
  intros.
 
1149
  apply fold_equal; auto with set.
 
1150
  Qed.
 
1151
 
 
1152
  End FoldOpt.
 
1153
 
 
1154
  (** An alternative version of [choose_3] *)
 
1155
 
 
1156
  Lemma choose_equal : forall s s', Equal s s' -> 
 
1157
    match choose s, choose s' with  
 
1158
      | Some x, Some x' => E.eq x x'
 
1159
      | None, None => True
 
1160
      | _, _ => False
 
1161
     end.
 
1162
  Proof.
 
1163
  intros s s' H; 
 
1164
  generalize (@choose_1 s)(@choose_2 s)
 
1165
             (@choose_1 s')(@choose_2 s')(@choose_3 s s'); 
 
1166
  destruct (choose s); destruct (choose s'); simpl; intuition.
 
1167
  apply H5 with e; rewrite <-H; auto.
 
1168
  apply H5 with e; rewrite H; auto.
 
1169
  Qed.
 
1170
 
 
1171
End OrdProperties.