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

« back to all changes in this revision

Viewing changes to theories/Lists/SetoidList.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: SetoidList.v 11800 2009-01-18 18:34:15Z msozeau $ *)
 
10
 
 
11
Require Export List.
 
12
Require Export Sorting.
 
13
Require Export Setoid.
 
14
Set Implicit Arguments.
 
15
Unset Strict Implicit.
 
16
 
 
17
(** * Logical relations over lists with respect to a setoid equality 
 
18
      or ordering. *) 
 
19
 
 
20
(** This can be seen as a complement of predicate [lelistA] and [sort] 
 
21
    found in [Sorting]. *)
 
22
 
 
23
Section Type_with_equality.
 
24
Variable A : Type.
 
25
Variable eqA : A -> A -> Prop. 
 
26
 
 
27
(** Being in a list modulo an equality relation over type [A]. *)
 
28
 
 
29
Inductive InA (x : A) : list A -> Prop :=
 
30
  | InA_cons_hd : forall y l, eqA x y -> InA x (y :: l)
 
31
  | InA_cons_tl : forall y l, InA x l -> InA x (y :: l).
 
32
 
 
33
Hint Constructors InA.
 
34
 
 
35
Lemma InA_cons : forall x y l, InA x (y::l) <-> eqA x y \/ InA x l.
 
36
Proof.
 
37
 intuition.
 
38
 inversion H; auto.
 
39
Qed.
 
40
 
 
41
Lemma InA_nil : forall x, InA x nil <-> False.
 
42
Proof.
 
43
 intuition.
 
44
 inversion H.
 
45
Qed.
 
46
 
 
47
(** An alternative definition of [InA]. *)
 
48
 
 
49
Lemma InA_alt : forall x l, InA x l <-> exists y, eqA x y /\ In y l.
 
50
Proof. 
 
51
 induction l; intuition.
 
52
 inversion H.
 
53
 firstorder.
 
54
 inversion H1; firstorder.
 
55
 firstorder; subst; auto.
 
56
Qed.
 
57
 
 
58
(** A list without redundancy modulo the equality over [A]. *)
 
59
 
 
60
Inductive NoDupA : list A -> Prop :=
 
61
  | NoDupA_nil : NoDupA nil
 
62
  | NoDupA_cons : forall x l, ~ InA x l -> NoDupA l -> NoDupA (x::l).
 
63
 
 
64
Hint Constructors NoDupA.
 
65
 
 
66
(** lists with same elements modulo [eqA] *)
 
67
 
 
68
Definition equivlistA l l' := forall x, InA x l <-> InA x l'.
 
69
 
 
70
(** lists with same elements modulo [eqA] at the same place *)
 
71
 
 
72
Inductive eqlistA : list A -> list A -> Prop :=
 
73
  | eqlistA_nil : eqlistA nil nil
 
74
  | eqlistA_cons : forall x x' l l',
 
75
      eqA x x' -> eqlistA l l' -> eqlistA (x::l) (x'::l').
 
76
 
 
77
Hint Constructors eqlistA.
 
78
 
 
79
(** Compatibility of a  boolean function with respect to an equality. *)
 
80
 
 
81
Definition compat_bool (f : A->bool) := forall x y, eqA x y -> f x = f y.
 
82
 
 
83
(** Compatibility of a function upon natural numbers. *)
 
84
 
 
85
Definition compat_nat (f : A->nat) := forall x y, eqA x y -> f x = f y.
 
86
 
 
87
(** Compatibility of a predicate with respect to an equality. *)
 
88
 
 
89
Definition compat_P (P : A->Prop) := forall x y, eqA x y -> P x -> P y.
 
90
 
 
91
(** Results concerning lists modulo [eqA] *)
 
92
 
 
93
Hypothesis eqA_refl : forall x, eqA x x.
 
94
Hypothesis eqA_sym : forall x y, eqA x y -> eqA y x.
 
95
Hypothesis eqA_trans : forall x y z, eqA x y -> eqA y z -> eqA x z.
 
96
 
 
97
Hint Resolve eqA_refl eqA_trans.
 
98
Hint Immediate eqA_sym.
 
99
 
 
100
Lemma InA_eqA : forall l x y, eqA x y -> InA x l -> InA y l.
 
101
Proof. 
 
102
 intros s x y.
 
103
 do 2 rewrite InA_alt.
 
104
 intros H (z,(U,V)).  
 
105
 exists z; split; eauto.
 
106
Qed.
 
107
Hint Immediate InA_eqA.
 
108
 
 
109
Lemma In_InA : forall l x, In x l -> InA x l.
 
110
Proof.
 
111
 simple induction l; simpl in |- *; intuition.
 
112
 subst; auto.  
 
113
Qed.
 
114
Hint Resolve In_InA.
 
115
 
 
116
Lemma InA_split : forall l x, InA x l -> 
 
117
 exists l1, exists y, exists l2, 
 
118
 eqA x y /\ l = l1++y::l2.
 
119
Proof.
 
120
induction l; inversion_clear 1.
 
121
exists (@nil A); exists a; exists l; auto.
 
122
destruct (IHl x H0) as (l1,(y,(l2,(H1,H2)))).
 
123
exists (a::l1); exists y; exists l2; auto.
 
124
split; simpl; f_equal; auto.
 
125
Qed.
 
126
 
 
127
Lemma InA_app : forall l1 l2 x,
 
128
 InA x (l1 ++ l2) -> InA x l1 \/ InA x l2.
 
129
Proof.
 
130
 induction l1; simpl in *; intuition.
 
131
 inversion_clear H; auto.
 
132
 elim (IHl1 l2 x H0); auto.
 
133
Qed.
 
134
 
 
135
Lemma InA_app_iff : forall l1 l2 x,
 
136
 InA x (l1 ++ l2) <-> InA x l1 \/ InA x l2.
 
137
Proof.
 
138
 split.
 
139
 apply InA_app.
 
140
 destruct 1; generalize H; do 2 rewrite InA_alt.
 
141
 destruct 1 as (y,(H1,H2)); exists y; split; auto.
 
142
 apply in_or_app; auto.
 
143
 destruct 1 as (y,(H1,H2)); exists y; split; auto.
 
144
 apply in_or_app; auto.
 
145
Qed.
 
146
 
 
147
Lemma InA_rev : forall p m, 
 
148
 InA p (rev m) <-> InA p m.
 
149
Proof.
 
150
 intros; do 2 rewrite InA_alt.
 
151
 split; intros (y,H); exists y; intuition.
 
152
 rewrite In_rev; auto.
 
153
 rewrite <- In_rev; auto.
 
154
Qed.
 
155
 
 
156
(** Results concerning lists modulo [eqA] and [ltA] *)
 
157
 
 
158
Variable ltA : A -> A -> Prop.
 
159
 
 
160
Hypothesis ltA_trans : forall x y z, ltA x y -> ltA y z -> ltA x z.
 
161
Hypothesis ltA_not_eqA : forall x y, ltA x y -> ~ eqA x y.
 
162
Hypothesis ltA_eqA : forall x y z, ltA x y -> eqA y z -> ltA x z.
 
163
Hypothesis eqA_ltA : forall x y z, eqA x y -> ltA y z -> ltA x z.
 
164
 
 
165
Hint Resolve ltA_trans.
 
166
Hint Immediate ltA_eqA eqA_ltA.
 
167
 
 
168
Notation InfA:=(lelistA ltA).
 
169
Notation SortA:=(sort ltA).
 
170
 
 
171
Hint Constructors lelistA sort.
 
172
 
 
173
Lemma InfA_ltA :
 
174
 forall l x y, ltA x y -> InfA y l -> InfA x l.
 
175
Proof.
 
176
 destruct l; constructor; inversion_clear H0; 
 
177
 eapply ltA_trans; eauto.
 
178
Qed.
 
179
 
 
180
Lemma InfA_eqA :
 
181
 forall l x y, eqA x y -> InfA y l -> InfA x l.
 
182
Proof.
 
183
 intro s; case s; constructor; inversion_clear H0; eauto.
 
184
Qed.
 
185
Hint Immediate InfA_ltA InfA_eqA. 
 
186
 
 
187
Lemma SortA_InfA_InA :
 
188
 forall l x a, SortA l -> InfA a l -> InA x l -> ltA a x.
 
189
Proof. 
 
190
 simple induction l.
 
191
 intros; inversion H1.
 
192
 intros.
 
193
 inversion_clear H0; inversion_clear H1; inversion_clear H2.
 
194
 eapply ltA_eqA; eauto.
 
195
 eauto.
 
196
Qed.
 
197
  
 
198
Lemma In_InfA :
 
199
 forall l x, (forall y, In y l -> ltA x y) -> InfA x l.
 
200
Proof.
 
201
 simple induction l; simpl in |- *; intros; constructor; auto.
 
202
Qed.
 
203
 
 
204
Lemma InA_InfA :
 
205
 forall l x, (forall y, InA y l -> ltA x y) -> InfA x l.
 
206
Proof.
 
207
 simple induction l; simpl in |- *; intros; constructor; auto.
 
208
Qed.
 
209
 
 
210
(* In fact, this may be used as an alternative definition for InfA: *)
 
211
 
 
212
Lemma InfA_alt : 
 
213
 forall l x, SortA l -> (InfA x l <-> (forall y, InA y l -> ltA x y)).
 
214
Proof. 
 
215
split.
 
216
intros; eapply SortA_InfA_InA; eauto.
 
217
apply InA_InfA.
 
218
Qed.
 
219
 
 
220
Lemma InfA_app : forall l1 l2 a, InfA a l1 -> InfA a l2 -> InfA a (l1++l2).
 
221
Proof.
 
222
 induction l1; simpl; auto.
 
223
 inversion_clear 1; auto.
 
224
Qed.
 
225
 
 
226
Lemma SortA_app :
 
227
 forall l1 l2, SortA l1 -> SortA l2 ->
 
228
 (forall x y, InA x l1 -> InA y l2 -> ltA x y) ->
 
229
 SortA (l1 ++ l2).
 
230
Proof.
 
231
 induction l1; simpl in *; intuition.
 
232
 inversion_clear H.
 
233
 constructor; auto.
 
234
 apply InfA_app; auto.
 
235
 destruct l2; auto.
 
236
Qed.
 
237
 
 
238
Section NoDupA.
 
239
 
 
240
Lemma SortA_NoDupA : forall l, SortA l -> NoDupA l.
 
241
Proof.
 
242
 simple induction l; auto.
 
243
 intros x l' H H0.
 
244
 inversion_clear H0.
 
245
 constructor; auto.  
 
246
 intro.
 
247
 assert (ltA x x) by (eapply SortA_InfA_InA; eauto).
 
248
 elim (ltA_not_eqA H3); auto.
 
249
Qed.
 
250
 
 
251
Lemma NoDupA_app : forall l l', NoDupA l -> NoDupA l' -> 
 
252
  (forall x, InA x l -> InA x l' -> False) -> 
 
253
  NoDupA (l++l').
 
254
Proof.
 
255
induction l; simpl; auto; intros.
 
256
inversion_clear H.
 
257
constructor.
 
258
rewrite InA_alt; intros (y,(H4,H5)).
 
259
destruct (in_app_or _ _ _ H5).
 
260
elim H2.
 
261
rewrite InA_alt.
 
262
exists y; auto.
 
263
apply (H1 a).
 
264
auto.
 
265
rewrite InA_alt.
 
266
exists y; auto.
 
267
apply IHl; auto.
 
268
intros.
 
269
apply (H1 x); auto.
 
270
Qed.
 
271
 
 
272
Lemma NoDupA_rev : forall l, NoDupA l -> NoDupA (rev l).
 
273
Proof.
 
274
induction l.
 
275
simpl; auto.
 
276
simpl; intros.
 
277
inversion_clear H.
 
278
apply NoDupA_app; auto.
 
279
constructor; auto.
 
280
intro H2; inversion H2.
 
281
intros x.
 
282
rewrite InA_alt.
 
283
intros (x1,(H2,H3)).
 
284
inversion_clear 1.
 
285
destruct H0.
 
286
apply InA_eqA with x1; eauto.
 
287
apply In_InA.
 
288
rewrite In_rev; auto.
 
289
inversion H4.
 
290
Qed.
 
291
 
 
292
Lemma NoDupA_split : forall l l' x, NoDupA (l++x::l') -> NoDupA (l++l').
 
293
Proof.
 
294
 induction l; simpl in *; inversion_clear 1; auto.
 
295
 constructor; eauto.
 
296
 contradict H0.
 
297
 rewrite InA_app_iff in *; rewrite InA_cons; intuition.
 
298
Qed.
 
299
 
 
300
Lemma NoDupA_swap : forall l l' x, NoDupA (l++x::l') -> NoDupA (x::l++l').
 
301
Proof.
 
302
 induction l; simpl in *; inversion_clear 1; auto.
 
303
 constructor; eauto.
 
304
 assert (H2:=IHl _ _ H1).
 
305
 inversion_clear H2.
 
306
 rewrite InA_cons.
 
307
 red; destruct 1.
 
308
 apply H0.
 
309
 rewrite InA_app_iff in *; rewrite InA_cons; auto.
 
310
 apply H; auto.
 
311
 constructor.
 
312
 contradict H0.
 
313
 rewrite InA_app_iff in *; rewrite InA_cons; intuition.
 
314
 eapply NoDupA_split; eauto.
 
315
Qed.
 
316
 
 
317
End NoDupA.
 
318
 
 
319
(** Some results about [eqlistA] *)
 
320
 
 
321
Section EqlistA.
 
322
 
 
323
Lemma eqlistA_length : forall l l', eqlistA l l' -> length l = length l'.
 
324
Proof.
 
325
induction 1; auto; simpl; congruence.
 
326
Qed.
 
327
 
 
328
Lemma eqlistA_app : forall l1 l1' l2 l2', 
 
329
   eqlistA l1 l1' -> eqlistA l2 l2' -> eqlistA (l1++l2) (l1'++l2').
 
330
Proof.
 
331
intros l1 l1' l2 l2' H; revert l2 l2'; induction H; simpl; auto.
 
332
Qed.
 
333
 
 
334
Lemma eqlistA_rev_app : forall l1 l1', 
 
335
   eqlistA l1 l1' -> forall l2 l2', eqlistA l2 l2' -> 
 
336
   eqlistA ((rev l1)++l2) ((rev l1')++l2').
 
337
Proof.
 
338
induction 1; auto.
 
339
simpl; intros.
 
340
do 2 rewrite app_ass; simpl; auto.
 
341
Qed.
 
342
 
 
343
Lemma eqlistA_rev : forall l1 l1', 
 
344
   eqlistA l1 l1' -> eqlistA (rev l1) (rev l1').
 
345
Proof.
 
346
intros.
 
347
rewrite (app_nil_end (rev l1)).
 
348
rewrite (app_nil_end (rev l1')).
 
349
apply eqlistA_rev_app; auto.
 
350
Qed.
 
351
 
 
352
Lemma SortA_equivlistA_eqlistA : forall l l', 
 
353
   SortA l -> SortA l' -> equivlistA l l' -> eqlistA l l'.
 
354
Proof.
 
355
induction l; destruct l'; simpl; intros; auto.
 
356
destruct (H1 a); assert (H4 : InA a nil) by auto; inversion H4.  
 
357
destruct (H1 a); assert (H4 : InA a nil) by auto; inversion H4.  
 
358
inversion_clear H; inversion_clear H0.
 
359
assert (forall y, InA y l -> ltA a y).
 
360
intros; eapply SortA_InfA_InA with (l:=l); eauto.
 
361
assert (forall y, InA y l' -> ltA a0 y).
 
362
intros; eapply SortA_InfA_InA with (l:=l'); eauto.
 
363
clear H3 H4.
 
364
assert (eqA a a0).
 
365
 destruct (H1 a).
 
366
 destruct (H1 a0).
 
367
 assert (InA a (a0::l')) by auto.
 
368
 inversion_clear H8; auto.
 
369
 assert (InA a0 (a::l)) by auto.
 
370
 inversion_clear H8; auto.
 
371
 elim (@ltA_not_eqA a a); auto.
 
372
 apply ltA_trans with a0; auto.
 
373
constructor; auto.
 
374
apply IHl; auto.
 
375
split; intros.
 
376
destruct (H1 x).
 
377
assert (H8 : InA x (a0::l')) by auto; inversion_clear H8; auto. 
 
378
elim (@ltA_not_eqA a x); eauto.
 
379
destruct (H1 x).
 
380
assert (H8 : InA x (a::l)) by auto; inversion_clear H8; auto. 
 
381
elim (@ltA_not_eqA a0 x); eauto.
 
382
Qed.
 
383
 
 
384
End EqlistA.
 
385
 
 
386
(** A few things about [filter] *)
 
387
 
 
388
Section Filter.
 
389
 
 
390
Lemma filter_sort : forall f l, SortA l -> SortA (List.filter f l).
 
391
Proof.
 
392
induction l; simpl; auto.
 
393
inversion_clear 1; auto.
 
394
destruct (f a); auto.
 
395
constructor; auto.
 
396
apply In_InfA; auto.
 
397
intros.
 
398
rewrite filter_In in H; destruct H.
 
399
eapply SortA_InfA_InA; eauto.
 
400
Qed.
 
401
 
 
402
Lemma filter_InA : forall f, (compat_bool f) -> 
 
403
 forall l x, InA x (List.filter f l) <-> InA x l /\ f x = true.
 
404
Proof.
 
405
intros; do 2 rewrite InA_alt; intuition.
 
406
destruct H0 as (y,(H0,H1)); rewrite filter_In in H1; exists y; intuition.
 
407
destruct H0 as (y,(H0,H1)); rewrite filter_In in H1; intuition.
 
408
  rewrite (H _ _ H0); auto.
 
409
destruct H1 as (y,(H0,H1)); exists y; rewrite filter_In; intuition.
 
410
  rewrite <- (H _ _ H0); auto.
 
411
Qed.
 
412
 
 
413
Lemma filter_split : 
 
414
 forall f, (forall x y, f x = true -> f y = false -> ltA x y) -> 
 
415
 forall l, SortA l -> l = filter f l ++ filter (fun x=>negb (f x)) l.
 
416
Proof.
 
417
induction l; simpl; intros; auto.
 
418
inversion_clear H0.
 
419
pattern l at 1; rewrite IHl; auto.
 
420
case_eq (f a); simpl; intros; auto.
 
421
assert (forall e, In e l -> f e = false).
 
422
  intros.
 
423
  assert (H4:=SortA_InfA_InA H1 H2 (In_InA H3)).
 
424
  case_eq (f e); simpl; intros; auto.
 
425
  elim (@ltA_not_eqA e e); auto.
 
426
  apply ltA_trans with a; eauto.
 
427
replace (List.filter f l) with (@nil A); auto.
 
428
generalize H3; clear; induction l; simpl; auto.
 
429
case_eq (f a); auto; intros.
 
430
rewrite H3 in H; auto; try discriminate.
 
431
Qed.
 
432
 
 
433
End Filter.
 
434
 
 
435
Section Fold.
 
436
 
 
437
Variable B:Type.
 
438
Variable eqB:B->B->Prop.
 
439
 
 
440
(** Compatibility of a two-argument function with respect to two equalities. *)
 
441
Definition compat_op (f : A -> B -> B) :=
 
442
  forall (x x' : A) (y y' : B), eqA x x' -> eqB y y' -> eqB (f x y) (f x' y').
 
443
 
 
444
(** Two-argument functions that allow to reorder their arguments. *)
 
445
Definition transpose (f : A -> B -> B) :=
 
446
  forall (x y : A) (z : B), eqB (f x (f y z)) (f y (f x z)). 
 
447
 
 
448
(** A version of transpose with restriction on where it should hold *)
 
449
Definition transpose_restr (R : A -> A -> Prop)(f : A -> B -> B) :=
 
450
  forall (x y : A) (z : B), R x y -> eqB (f x (f y z)) (f y (f x z)).
 
451
 
 
452
Variable st:Equivalence eqB.
 
453
Variable f:A->B->B.
 
454
Variable i:B.
 
455
Variable Comp:compat_op f.
 
456
 
 
457
Lemma fold_right_eqlistA : 
 
458
   forall s s', eqlistA s s' -> 
 
459
   eqB (fold_right f i s) (fold_right f i s').
 
460
Proof.
 
461
induction 1; simpl; auto.
 
462
reflexivity.
 
463
Qed.
 
464
 
 
465
Lemma equivlistA_NoDupA_split : forall l l1 l2 x y, eqA x y -> 
 
466
 NoDupA (x::l) -> NoDupA (l1++y::l2) -> 
 
467
 equivlistA (x::l) (l1++y::l2) -> equivlistA l (l1++l2).
 
468
Proof.
 
469
 intros; intro a.
 
470
 generalize (H2 a).
 
471
 repeat rewrite InA_app_iff.
 
472
 do 2 rewrite InA_cons.
 
473
 inversion_clear H0.
 
474
 assert (SW:=NoDupA_swap H1).
 
475
 inversion_clear SW.
 
476
 rewrite InA_app_iff in H0.
 
477
 split; intros.
 
478
 assert (~eqA a x).
 
479
  contradict H3; apply InA_eqA with a; auto.
 
480
 assert (~eqA a y).
 
481
  contradict H8; eauto.
 
482
 intuition.
 
483
 assert (eqA a x \/ InA a l) by intuition.
 
484
 destruct H8; auto.
 
485
 elim H0.
 
486
 destruct H7; [left|right]; eapply InA_eqA; eauto.
 
487
Qed.
 
488
 
 
489
(** [ForallList2] : specifies that a certain binary predicate should
 
490
    always hold when inspecting two different elements of the list. *)
 
491
 
 
492
Inductive ForallList2 (R : A -> A -> Prop) : list A -> Prop :=
 
493
  | ForallNil : ForallList2 R nil
 
494
  | ForallCons : forall a l,
 
495
     (forall b, In b l -> R a b) ->
 
496
     ForallList2 R l -> ForallList2 R (a::l).
 
497
Hint Constructors ForallList2.
 
498
 
 
499
(** [NoDupA] can be written in terms of [ForallList2] *)
 
500
 
 
501
Lemma ForallList2_NoDupA : forall l,
 
502
 ForallList2 (fun a b => ~eqA a b) l <-> NoDupA l.
 
503
Proof.
 
504
 induction l; split; intros; auto.
 
505
 inversion_clear H. constructor; [ | rewrite <- IHl; auto ].
 
506
 rewrite InA_alt; intros (a',(Haa',Ha')).
 
507
 exact (H0 a' Ha' Haa').
 
508
 inversion_clear H. constructor; [ | rewrite IHl; auto ].
 
509
 intros b Hb.
 
510
 contradict H0.
 
511
 rewrite InA_alt; exists b; auto.
 
512
Qed.
 
513
 
 
514
Lemma ForallList2_impl : forall (R R':A->A->Prop),
 
515
 (forall a b, R a b -> R' a b) ->
 
516
 forall l, ForallList2 R l -> ForallList2 R' l.
 
517
Proof.
 
518
 induction 2; auto.
 
519
Qed.
 
520
 
 
521
(** The following definition is easier to use than [ForallList2]. *)
 
522
 
 
523
Definition ForallList2_alt (R:A->A->Prop) l :=
 
524
 forall a b, InA a l -> InA b l -> ~eqA a b -> R a b.
 
525
 
 
526
Section Restriction.
 
527
Variable R : A -> A -> Prop.
 
528
 
 
529
(** [ForallList2] and [ForallList2_alt] are related, but no completely
 
530
    equivalent. For proving one implication, we need to know that the
 
531
    list has no duplicated elements... *)
 
532
 
 
533
Lemma ForallList2_equiv1 : forall l, NoDupA l ->
 
534
 ForallList2_alt R l -> ForallList2 R l.
 
535
Proof.
 
536
 induction l; auto.
 
537
 constructor. intros b Hb.
 
538
 inversion_clear H.
 
539
 apply H0; auto.
 
540
 contradict H1.
 
541
 apply InA_eqA with b; auto.
 
542
 apply IHl.
 
543
 inversion_clear H; auto.
 
544
 intros b c Hb Hc Hneq.
 
545
 apply H0; auto.
 
546
Qed.
 
547
 
 
548
(** ... and for proving the other implication, we need to be able
 
549
   to reverse and adapt relation [R] modulo [eqA]. *)
 
550
 
 
551
Hypothesis R_sym : forall a b, R a b -> R b a.
 
552
Hypothesis R_compat : forall a, compat_P (R a).
 
553
 
 
554
Lemma ForallList2_equiv2 : forall l,
 
555
 ForallList2 R l -> ForallList2_alt R l.
 
556
Proof.
 
557
 induction l.
 
558
 intros _. red. intros a b Ha. inversion Ha.
 
559
 inversion_clear 1 as [|? ? H_R Hl].
 
560
 intros b c Hb Hc Hneq.
 
561
 inversion_clear Hb; inversion_clear Hc.
 
562
 (* b,c = a : impossible *)
 
563
 elim Hneq; eauto.
 
564
 (* b = a, c in l *)
 
565
 rewrite InA_alt in H0; destruct H0 as (d,(Hcd,Hd)).
 
566
 apply R_compat with d; auto.
 
567
 apply R_sym; apply R_compat with a; auto.
 
568
 (* b in l, c = a *)
 
569
 rewrite InA_alt in H; destruct H as (d,(Hcd,Hd)).
 
570
 apply R_compat with a; auto.
 
571
 apply R_sym; apply R_compat with d; auto.
 
572
 (* b,c in l *)
 
573
 apply (IHl Hl); auto.
 
574
Qed.
 
575
 
 
576
Lemma ForallList2_equiv : forall l, NoDupA l ->
 
577
 (ForallList2 R l <-> ForallList2_alt R l).
 
578
Proof.
 
579
split; [apply ForallList2_equiv2|apply ForallList2_equiv1]; auto.
 
580
Qed.
 
581
 
 
582
Lemma ForallList2_equivlistA : forall l l', NoDupA l' ->
 
583
 equivlistA l l' -> ForallList2 R l -> ForallList2 R l'.
 
584
Proof.
 
585
intros.
 
586
apply ForallList2_equiv1; auto.
 
587
intros a b Ha Hb Hneq.
 
588
red in H0; rewrite <- H0 in Ha,Hb.
 
589
revert a b Ha Hb Hneq.
 
590
change (ForallList2_alt R l).
 
591
apply ForallList2_equiv2; auto.
 
592
Qed.
 
593
 
 
594
Variable TraR :transpose_restr R f.
 
595
 
 
596
Lemma fold_right_commutes_restr :
 
597
  forall s1 s2 x, ForallList2 R (s1++x::s2) ->
 
598
  eqB (fold_right f i (s1++x::s2)) (f x (fold_right f i (s1++s2))).
 
599
Proof.
 
600
induction s1; simpl; auto; intros.
 
601
reflexivity.
 
602
transitivity (f a (f x (fold_right f i (s1++s2)))).
 
603
apply Comp; auto.
 
604
apply IHs1.
 
605
inversion_clear H; auto.
 
606
apply TraR.
 
607
inversion_clear H.
 
608
apply H0.
 
609
apply in_or_app; simpl; auto.
 
610
Qed.
 
611
 
 
612
Lemma fold_right_equivlistA_restr :
 
613
  forall s s', NoDupA s -> NoDupA s' -> ForallList2 R s ->
 
614
  equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s').
 
615
Proof.
 
616
 simple induction s.
 
617
 destruct s'; simpl.
 
618
 intros; reflexivity.
 
619
 unfold equivlistA; intros.
 
620
 destruct (H2 a).
 
621
 assert (X : InA a nil); auto; inversion X.
 
622
 intros x l Hrec s' N N' F E; simpl in *.
 
623
 assert (InA x s').
 
624
  rewrite <- (E x); auto.
 
625
 destruct (InA_split H) as (s1,(y,(s2,(H1,H2)))).
 
626
 subst s'.
 
627
 transitivity (f x (fold_right f i (s1++s2))).
 
628
 apply Comp; auto.
 
629
 apply Hrec; auto.
 
630
 inversion_clear N; auto.
 
631
 eapply NoDupA_split; eauto.
 
632
 inversion_clear F; auto.
 
633
 eapply equivlistA_NoDupA_split; eauto.
 
634
 transitivity (f y (fold_right f i (s1++s2))).
 
635
 apply Comp; auto. reflexivity.
 
636
 symmetry; apply fold_right_commutes_restr.
 
637
 apply ForallList2_equivlistA with (x::l); auto.
 
638
Qed.
 
639
 
 
640
Lemma fold_right_add_restr :
 
641
  forall s' s x, NoDupA s -> NoDupA s' -> ForallList2 R s' -> ~ InA x s ->
 
642
  equivlistA s' (x::s) -> eqB (fold_right f i s') (f x (fold_right f i s)).
 
643
Proof.
 
644
 intros; apply (@fold_right_equivlistA_restr s' (x::s)); auto.
 
645
Qed.
 
646
 
 
647
End Restriction.
 
648
 
 
649
(** we know state similar results, but without restriction on transpose. *)
 
650
 
 
651
Variable Tra :transpose f.
 
652
 
 
653
Lemma fold_right_commutes : forall s1 s2 x,
 
654
  eqB (fold_right f i (s1++x::s2)) (f x (fold_right f i (s1++s2))).
 
655
Proof.
 
656
induction s1; simpl; auto; intros.
 
657
reflexivity.
 
658
transitivity (f a (f x (fold_right f i (s1++s2)))); auto.
 
659
Qed.
 
660
 
 
661
Lemma fold_right_equivlistA :
 
662
  forall s s', NoDupA s -> NoDupA s' ->
 
663
  equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s').
 
664
Proof.
 
665
intros; apply fold_right_equivlistA_restr with (R:=fun _ _ => True);
 
666
 try red; auto.
 
667
apply ForallList2_equiv1; try red; auto.
 
668
Qed.
 
669
 
 
670
Lemma fold_right_add :
 
671
  forall s' s x, NoDupA s -> NoDupA s' -> ~ InA x s ->
 
672
  equivlistA s' (x::s) -> eqB (fold_right f i s') (f x (fold_right f i s)).
 
673
Proof.
 
674
 intros; apply (@fold_right_equivlistA s' (x::s)); auto.
 
675
Qed.
 
676
 
 
677
Section Remove.
 
678
 
 
679
Hypothesis eqA_dec : forall x y : A, {eqA x y}+{~(eqA x y)}.
 
680
 
 
681
Lemma InA_dec : forall x l, { InA x l } + { ~ InA x l }.
 
682
Proof.
 
683
induction l.
 
684
right; auto.
 
685
red; inversion 1.
 
686
destruct (eqA_dec x a).
 
687
left; auto.
 
688
destruct IHl.
 
689
left; auto.
 
690
right; red; inversion_clear 1; contradiction. 
 
691
Qed.
 
692
 
 
693
Fixpoint removeA (x : A) (l : list A){struct l} : list A :=
 
694
  match l with
 
695
    | nil => nil
 
696
    | y::tl => if (eqA_dec x y) then removeA x tl else y::(removeA x tl)
 
697
  end.
 
698
 
 
699
Lemma removeA_filter : forall x l,
 
700
  removeA x l = filter (fun y => if eqA_dec x y then false else true) l.
 
701
Proof.
 
702
induction l; simpl; auto.
 
703
destruct (eqA_dec x a); auto.
 
704
rewrite IHl; auto.
 
705
Qed.
 
706
 
 
707
Lemma removeA_InA : forall l x y, InA y (removeA x l) <-> InA y l /\ ~eqA x y.
 
708
Proof.
 
709
induction l; simpl; auto.
 
710
split.
 
711
inversion_clear 1.
 
712
destruct 1; inversion_clear H.
 
713
intros.
 
714
destruct (eqA_dec x a); simpl; auto.
 
715
rewrite IHl; split; destruct 1; split; auto.
 
716
inversion_clear H; auto.
 
717
destruct H0; apply eqA_trans with a; auto.
 
718
split.
 
719
inversion_clear 1.
 
720
split; auto.
 
721
contradict n.
 
722
apply eqA_trans with y; auto.
 
723
rewrite (IHl x y) in H0; destruct H0; auto.
 
724
destruct 1; inversion_clear H; auto.
 
725
constructor 2; rewrite IHl; auto.
 
726
Qed.
 
727
 
 
728
Lemma removeA_NoDupA :
 
729
  forall s x, NoDupA s ->  NoDupA (removeA x s).
 
730
Proof.
 
731
simple induction s; simpl; intros.
 
732
auto.
 
733
inversion_clear H0.
 
734
destruct (eqA_dec x a); simpl; auto. 
 
735
constructor; auto.
 
736
rewrite removeA_InA.
 
737
intuition.
 
738
Qed. 
 
739
 
 
740
Lemma removeA_equivlistA : forall l l' x, 
 
741
  ~InA x l -> equivlistA (x :: l) l' -> equivlistA l (removeA x l').
 
742
Proof.  
 
743
unfold equivlistA; intros. 
 
744
rewrite removeA_InA.
 
745
split; intros.
 
746
rewrite <- H0; split; auto.
 
747
contradict H.
 
748
apply InA_eqA with x0; auto.
 
749
rewrite <- (H0 x0) in H1.
 
750
destruct H1.
 
751
inversion_clear H1; auto.
 
752
elim H2; auto.
 
753
Qed.
 
754
 
 
755
End Remove.
 
756
 
 
757
End Fold.
 
758
 
 
759
End Type_with_equality.
 
760
 
 
761
Hint Unfold compat_bool compat_nat compat_P.
 
762
Hint Constructors InA NoDupA sort lelistA eqlistA.
 
763
 
 
764
Section Find. 
 
765
Variable A B : Type. 
 
766
Variable eqA : A -> A -> Prop. 
 
767
Hypothesis eqA_sym : forall x y, eqA x y -> eqA y x.
 
768
Hypothesis eqA_trans : forall x y z, eqA x y -> eqA y z -> eqA x z.
 
769
Hypothesis eqA_dec : forall x y : A, {eqA x y}+{~(eqA x y)}.
 
770
 
 
771
Fixpoint findA (f : A -> bool) (l:list (A*B)) : option B := 
 
772
 match l with  
 
773
  | nil => None 
 
774
  | (a,b)::l => if f a then Some b else findA f l
 
775
 end.
 
776
 
 
777
Lemma findA_NoDupA : 
 
778
 forall l a b, 
 
779
 NoDupA (fun p p' => eqA (fst p) (fst p')) l -> 
 
780
 (InA (fun p p' => eqA (fst p) (fst p') /\ snd p = snd p') (a,b) l <->
 
781
  findA (fun a' => if eqA_dec a a' then true else false) l = Some b).
 
782
Proof.
 
783
induction l; simpl; intros.
 
784
split; intros; try discriminate.
 
785
inversion H0.
 
786
destruct a as (a',b'); rename a0 into a.
 
787
inversion_clear H.
 
788
split; intros.
 
789
inversion_clear H.
 
790
simpl in *; destruct H2; subst b'.
 
791
destruct (eqA_dec a a'); intuition.
 
792
destruct (eqA_dec a a'); simpl.
 
793
destruct H0.
 
794
generalize e H2 eqA_trans eqA_sym; clear.
 
795
induction l.
 
796
inversion 2.
 
797
inversion_clear 2; intros; auto.
 
798
destruct a0.
 
799
compute in H; destruct H.
 
800
subst b.
 
801
constructor 1; auto.
 
802
simpl.
 
803
apply eqA_trans with a; auto.
 
804
rewrite <- IHl; auto.
 
805
destruct (eqA_dec a a'); simpl in *.
 
806
inversion H; clear H; intros; subst b'; auto.
 
807
constructor 2.
 
808
rewrite IHl; auto.
 
809
Qed.
 
810
 
 
811
End Find.