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

« back to all changes in this revision

Viewing changes to theories/Lists/List.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___,, * 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
(************************************************************************)
 
8
 
 
9
(*i $Id: List.v 10999 2008-05-27 15:55:22Z letouzey $ i*)
 
10
 
 
11
Require Import Le Gt Minus Min Bool.
 
12
 
 
13
Set Implicit Arguments.
 
14
 
 
15
 
 
16
(******************************************************************)
 
17
(** * Basics: definition of polymorphic lists and some operations *)
 
18
(******************************************************************)
 
19
 
 
20
(** ** Definitions *)
 
21
 
 
22
Section Lists.
 
23
 
 
24
  Variable A : Type.
 
25
 
 
26
  Inductive list : Type :=
 
27
    | nil : list
 
28
    | cons : A -> list -> list.
 
29
 
 
30
  Infix "::" := cons (at level 60, right associativity) : list_scope.
 
31
 
 
32
  Open Scope list_scope.
 
33
 
 
34
  (** Head and tail        *)
 
35
  Definition head (l:list) :=
 
36
    match l with
 
37
      | nil => error
 
38
      | x :: _ => value x
 
39
    end.
 
40
 
 
41
 Definition hd (default:A) (l:list) :=
 
42
   match l with
 
43
     | nil => default
 
44
     | x :: _ => x
 
45
   end. 
 
46
 
 
47
  Definition tail (l:list) : list :=
 
48
    match l with
 
49
      | nil => nil
 
50
      | a :: m => m
 
51
    end.
 
52
 
 
53
  (** Length of lists                *)
 
54
  Fixpoint length (l:list) : nat :=
 
55
    match l with
 
56
      | nil => 0
 
57
      | _ :: m => S (length m)
 
58
    end.
 
59
 
 
60
  (** The [In] predicate *)
 
61
  Fixpoint In (a:A) (l:list) {struct l} : Prop :=
 
62
    match l with
 
63
      | nil => False
 
64
      | b :: m => b = a \/ In a m
 
65
    end.
 
66
 
 
67
 
 
68
  (** Concatenation of two lists *)
 
69
  Fixpoint app (l m:list) {struct l} : list :=
 
70
    match l with
 
71
      | nil => m
 
72
      | a :: l1 => a :: app l1 m
 
73
    end.
 
74
  
 
75
  Infix "++" := app (right associativity, at level 60) : list_scope.
 
76
  
 
77
End Lists.
 
78
 
 
79
(** Exporting list notations and tactics *)
 
80
 
 
81
Implicit Arguments nil [A].
 
82
Infix "::" := cons (at level 60, right associativity) : list_scope.
 
83
Infix "++" := app (right associativity, at level 60) : list_scope.
 
84
 
 
85
Open Scope list_scope.
 
86
 
 
87
Delimit Scope list_scope with list.
 
88
 
 
89
Bind Scope list_scope with list.
 
90
 
 
91
Arguments Scope list [type_scope].
 
92
 
 
93
(** ** Facts about lists *)
 
94
 
 
95
Section Facts.
 
96
 
 
97
  Variable A : Type.
 
98
 
 
99
 
 
100
  (** *** Genereric facts *)
 
101
 
 
102
  (** Discrimination *)
 
103
  Theorem nil_cons : forall (x:A) (l:list A), nil <> x :: l.
 
104
  Proof. 
 
105
    intros; discriminate.
 
106
  Qed.
 
107
 
 
108
 
 
109
  (** Destruction *)
 
110
 
 
111
  Theorem destruct_list : forall l : list A, {x:A & {tl:list A | l = x::tl}}+{l = nil}.
 
112
  Proof.
 
113
    induction l as [|a tl].
 
114
    right; reflexivity.
 
115
    left; exists a; exists tl; reflexivity.
 
116
  Qed.
 
117
    
 
118
  (** *** Head and tail *)
 
119
  
 
120
  Theorem head_nil : head (@nil A) = None.
 
121
  Proof.
 
122
    simpl; reflexivity.
 
123
  Qed.
 
124
 
 
125
  Theorem head_cons : forall (l : list A) (x : A), head (x::l) = Some x.
 
126
  Proof.
 
127
    intros; simpl; reflexivity.
 
128
  Qed.
 
129
 
 
130
 
 
131
  (************************)
 
132
  (** *** Facts about [In] *) 
 
133
  (************************)
 
134
 
 
135
 
 
136
  (** Characterization of [In] *)
 
137
  
 
138
  Theorem in_eq : forall (a:A) (l:list A), In a (a :: l).
 
139
  Proof. 
 
140
    simpl in |- *; auto.
 
141
  Qed.
 
142
  
 
143
  Theorem in_cons : forall (a b:A) (l:list A), In b l -> In b (a :: l).
 
144
  Proof. 
 
145
    simpl in |- *; auto.
 
146
  Qed.
 
147
 
 
148
  Theorem in_nil : forall a:A, ~ In a nil.
 
149
  Proof.
 
150
    unfold not in |- *; intros a H; inversion_clear H.
 
151
  Qed.
 
152
 
 
153
  Lemma In_split : forall x (l:list A), In x l -> exists l1, exists l2, l = l1++x::l2.
 
154
  Proof.
 
155
  induction l; simpl; destruct 1.
 
156
  subst a; auto.
 
157
  exists (@nil A); exists l; auto.
 
158
  destruct (IHl H) as (l1,(l2,H0)).
 
159
  exists (a::l1); exists l2; simpl; f_equal; auto.
 
160
  Qed.
 
161
 
 
162
  (** Inversion *)
 
163
  Theorem in_inv : forall (a b:A) (l:list A), In b (a :: l) -> a = b \/ In b l.
 
164
  Proof.
 
165
    intros a b l H; inversion_clear H; auto.
 
166
  Qed.
 
167
 
 
168
  (** Decidability of [In] *)
 
169
  Theorem In_dec :
 
170
    (forall x y:A, {x = y} + {x <> y}) ->
 
171
    forall (a:A) (l:list A), {In a l} + {~ In a l}.
 
172
  Proof.
 
173
    intro H; induction l as [| a0 l IHl].
 
174
    right; apply in_nil.
 
175
    destruct (H a0 a); simpl in |- *; auto.
 
176
    destruct IHl; simpl in |- *; auto. 
 
177
    right; unfold not in |- *; intros [Hc1| Hc2]; auto.
 
178
  Defined.
 
179
 
 
180
 
 
181
  (*************************)
 
182
  (** *** Facts about [app] *)
 
183
  (*************************)
 
184
 
 
185
  (** Discrimination *)
 
186
  Theorem app_cons_not_nil : forall (x y:list A) (a:A), nil <> x ++ a :: y.
 
187
  Proof.
 
188
    unfold not in |- *.
 
189
    destruct x as [| a l]; simpl in |- *; intros.
 
190
    discriminate H.
 
191
    discriminate H.
 
192
  Qed.
 
193
 
 
194
 
 
195
  (** Concat with [nil] *)
 
196
 
 
197
  Theorem app_nil_end : forall l:list A, l = l ++ nil.
 
198
  Proof. 
 
199
    induction l; simpl in |- *; auto.
 
200
    rewrite <- IHl; auto.
 
201
  Qed.
 
202
 
 
203
  (** [app] is associative *)
 
204
  Theorem app_ass : forall l m n:list A, (l ++ m) ++ n = l ++ m ++ n.
 
205
  Proof. 
 
206
    intros. induction l; simpl in |- *; auto.
 
207
    now_show (a :: (l ++ m) ++ n = a :: l ++ m ++ n).
 
208
    rewrite <- IHl; auto.
 
209
  Qed.
 
210
  Hint Resolve app_ass.
 
211
 
 
212
  Theorem ass_app : forall l m n:list A, l ++ m ++ n = (l ++ m) ++ n.
 
213
  Proof. 
 
214
    auto using app_ass.
 
215
  Qed.
 
216
 
 
217
  (** [app] commutes with [cons] *) 
 
218
  Theorem app_comm_cons : forall (x y:list A) (a:A), a :: (x ++ y) = (a :: x) ++ y.
 
219
  Proof.
 
220
    auto.
 
221
  Qed.
 
222
 
 
223
 
 
224
 
 
225
  (** Facts deduced from the result of a concatenation *)  
 
226
 
 
227
  Theorem app_eq_nil : forall l l':list A, l ++ l' = nil -> l = nil /\ l' = nil.
 
228
  Proof.
 
229
    destruct l as [| x l]; destruct l' as [| y l']; simpl in |- *; auto.
 
230
    intro; discriminate.
 
231
    intros H; discriminate H.
 
232
  Qed.
 
233
 
 
234
  Theorem app_eq_unit :
 
235
    forall (x y:list A) (a:A),
 
236
      x ++ y = a :: nil -> x = nil /\ y = a :: nil \/ x = a :: nil /\ y = nil.
 
237
  Proof.
 
238
    destruct x as [| a l]; [ destruct y as [| a l] | destruct y as [| a0 l0] ];
 
239
      simpl in |- *.
 
240
    intros a H; discriminate H.
 
241
    left; split; auto.
 
242
    right; split; auto.
 
243
    generalize H.
 
244
    generalize (app_nil_end l); intros E.
 
245
    rewrite <- E; auto.
 
246
    intros.
 
247
    injection H.
 
248
    intro.
 
249
    cut (nil = l ++ a0 :: l0); auto.
 
250
    intro.
 
251
    generalize (app_cons_not_nil _ _ _ H1); intro.
 
252
    elim H2.
 
253
  Qed.
 
254
 
 
255
  Lemma app_inj_tail :
 
256
    forall (x y:list A) (a b:A), x ++ a :: nil = y ++ b :: nil -> x = y /\ a = b.
 
257
  Proof.
 
258
    induction x as [| x l IHl];
 
259
      [ destruct y as [| a l] | destruct y as [| a l0] ]; 
 
260
      simpl in |- *; auto.
 
261
    intros a b H.
 
262
    injection H.
 
263
    auto.
 
264
    intros a0 b H.
 
265
    injection H; intros.
 
266
    generalize (app_cons_not_nil _ _ _ H0); destruct 1.
 
267
    intros a b H.
 
268
    injection H; intros.
 
269
    cut (nil = l ++ a :: nil); auto.
 
270
    intro.
 
271
    generalize (app_cons_not_nil _ _ _ H2); destruct 1.
 
272
    intros a0 b H.
 
273
    injection H; intros.
 
274
    destruct (IHl l0 a0 b H0). 
 
275
    split; auto.
 
276
    rewrite <- H1; rewrite <- H2; reflexivity.
 
277
  Qed.
 
278
 
 
279
 
 
280
  (** Compatibility wtih other operations *)
 
281
 
 
282
  Lemma app_length : forall l l' : list A, length (l++l') = length l + length l'.
 
283
  Proof.
 
284
    induction l; simpl; auto.
 
285
  Qed.
 
286
 
 
287
  Lemma in_app_or : forall (l m:list A) (a:A), In a (l ++ m) -> In a l \/ In a m.
 
288
  Proof. 
 
289
    intros l m a.
 
290
    elim l; simpl in |- *; auto.
 
291
    intros a0 y H H0.
 
292
    now_show ((a0 = a \/ In a y) \/ In a m).
 
293
    elim H0; auto.
 
294
    intro H1.
 
295
    now_show ((a0 = a \/ In a y) \/ In a m).
 
296
    elim (H H1); auto.
 
297
  Qed.
 
298
 
 
299
  Lemma in_or_app : forall (l m:list A) (a:A), In a l \/ In a m -> In a (l ++ m).
 
300
  Proof. 
 
301
    intros l m a.
 
302
    elim l; simpl in |- *; intro H.
 
303
    now_show (In a m).
 
304
    elim H; auto; intro H0.
 
305
    now_show (In a m).
 
306
    elim H0. (* subProof completed *)
 
307
    intros y H0 H1.
 
308
    now_show (H = a \/ In a (y ++ m)).
 
309
    elim H1; auto 4.
 
310
    intro H2.
 
311
    now_show (H = a \/ In a (y ++ m)).
 
312
    elim H2; auto.
 
313
  Qed.
 
314
  
 
315
  Lemma app_inv_head:
 
316
   forall l l1 l2 : list A, l ++ l1 = l ++ l2 ->  l1 = l2.
 
317
  Proof.
 
318
    induction l; simpl; auto; injection 1; auto.
 
319
  Qed.
 
320
 
 
321
  Lemma app_inv_tail:
 
322
    forall l l1 l2 : list A, l1 ++ l = l2 ++ l ->  l1 = l2.
 
323
  Proof.
 
324
    intros l l1 l2; revert l1 l2 l.
 
325
    induction l1 as [ | x1 l1]; destruct l2 as [ | x2 l2]; 
 
326
     simpl; auto; intros l H.
 
327
    absurd (length (x2 :: l2 ++ l) <= length l).
 
328
    simpl; rewrite app_length; auto with arith.
 
329
    rewrite <- H; auto with arith.
 
330
    absurd (length (x1 :: l1 ++ l) <= length l).
 
331
    simpl; rewrite app_length; auto with arith.
 
332
    rewrite H; auto with arith.
 
333
    injection H; clear H; intros; f_equal; eauto.
 
334
  Qed.
 
335
 
 
336
End Facts.
 
337
 
 
338
Hint Resolve app_nil_end ass_app app_ass: datatypes v62.
 
339
Hint Resolve app_comm_cons app_cons_not_nil: datatypes v62.
 
340
Hint Immediate app_eq_nil: datatypes v62.
 
341
Hint Resolve app_eq_unit app_inj_tail: datatypes v62. 
 
342
Hint Resolve in_eq in_cons in_inv in_nil in_app_or in_or_app: datatypes v62.
 
343
 
 
344
 
 
345
 
 
346
(*******************************************)
 
347
(** * Operations on the elements of a list *)
 
348
(*******************************************)
 
349
 
 
350
Section Elts.
 
351
 
 
352
  Variable A : Type.
 
353
 
 
354
  (*****************************)
 
355
  (** ** Nth element of a list *)
 
356
  (*****************************)
 
357
 
 
358
  Fixpoint nth (n:nat) (l:list A) (default:A) {struct l} : A :=
 
359
    match n, l with
 
360
      | O, x :: l' => x
 
361
      | O, other => default
 
362
      | S m, nil => default
 
363
      | S m, x :: t => nth m t default
 
364
    end.
 
365
 
 
366
  Fixpoint nth_ok (n:nat) (l:list A) (default:A) {struct l} : bool :=
 
367
    match n, l with
 
368
      | O, x :: l' => true
 
369
      | O, other => false
 
370
      | S m, nil => false
 
371
      | S m, x :: t => nth_ok m t default
 
372
    end.
 
373
 
 
374
  Lemma nth_in_or_default :
 
375
    forall (n:nat) (l:list A) (d:A), {In (nth n l d) l} + {nth n l d = d}.
 
376
  (* Realizer nth_ok. Program_all. *)
 
377
  Proof. 
 
378
    intros n l d; generalize n; induction l; intro n0.
 
379
    right; case n0; trivial.
 
380
    case n0; simpl in |- *.
 
381
    auto.
 
382
    intro n1; elim (IHl n1); auto.     
 
383
  Qed.
 
384
 
 
385
  Lemma nth_S_cons :
 
386
    forall (n:nat) (l:list A) (d a:A),
 
387
      In (nth n l d) l -> In (nth (S n) (a :: l) d) (a :: l).
 
388
  Proof. 
 
389
    simpl in |- *; auto.
 
390
  Qed.
 
391
 
 
392
  Fixpoint nth_error (l:list A) (n:nat) {struct n} : Exc A :=
 
393
    match n, l with
 
394
      | O, x :: _ => value x
 
395
      | S n, _ :: l => nth_error l n
 
396
      | _, _ => error
 
397
    end.
 
398
 
 
399
  Definition nth_default (default:A) (l:list A) (n:nat) : A :=
 
400
    match nth_error l n with
 
401
      | Some x => x
 
402
      | None => default
 
403
    end.
 
404
 
 
405
  Lemma nth_In :
 
406
    forall (n:nat) (l:list A) (d:A), n < length l -> In (nth n l d) l.
 
407
 
 
408
  Proof.
 
409
    unfold lt in |- *; induction n as [| n hn]; simpl in |- *.
 
410
    destruct l; simpl in |- *; [ inversion 2 | auto ].
 
411
    destruct l as [| a l hl]; simpl in |- *.
 
412
    inversion 2.
 
413
    intros d ie; right; apply hn; auto with arith.
 
414
  Qed.
 
415
 
 
416
  Lemma nth_overflow : forall l n d, length l <= n -> nth n l d = d.
 
417
  Proof.
 
418
    induction l; destruct n; simpl; intros; auto.
 
419
    inversion H.
 
420
    apply IHl; auto with arith.
 
421
  Qed.
 
422
 
 
423
  Lemma nth_indep : 
 
424
    forall l n d d', n < length l -> nth n l d = nth n l d'.
 
425
  Proof.
 
426
    induction l; simpl; intros; auto.
 
427
    inversion H.
 
428
    destruct n; simpl; auto with arith.
 
429
  Qed.
 
430
 
 
431
  Lemma app_nth1 : 
 
432
    forall l l' d n, n < length l -> nth n (l++l') d = nth n l d.
 
433
  Proof.
 
434
    induction l.
 
435
    intros.
 
436
    inversion H.
 
437
    intros l' d n.
 
438
    case n; simpl; auto.
 
439
    intros; rewrite IHl; auto with arith.
 
440
  Qed.
 
441
 
 
442
  Lemma app_nth2 : 
 
443
    forall l l' d n, n >= length l -> nth n (l++l') d = nth (n-length l) l' d.
 
444
  Proof.
 
445
    induction l.
 
446
    intros.
 
447
    simpl.
 
448
    destruct n; auto.
 
449
    intros l' d n.
 
450
    case n; simpl; auto.
 
451
    intros.
 
452
    inversion H.
 
453
    intros.
 
454
    rewrite IHl; auto with arith.
 
455
  Qed.
 
456
 
 
457
 
 
458
 
 
459
 
 
460
  (*****************)
 
461
  (** ** Remove    *)
 
462
  (*****************)
 
463
 
 
464
  Section Remove.
 
465
 
 
466
    Hypothesis eq_dec : forall x y : A, {x = y}+{x <> y}.
 
467
    
 
468
    Fixpoint remove (x : A) (l : list A){struct l} : list A :=
 
469
      match l with
 
470
        | nil => nil
 
471
        | y::tl => if (eq_dec x y) then remove x tl else y::(remove x tl)
 
472
      end.
 
473
    
 
474
    Theorem remove_In : forall (l : list A) (x : A), ~ In x (remove x l).
 
475
    Proof.
 
476
      induction l as [|x l]; auto.
 
477
      intro y; simpl; destruct (eq_dec y x) as [yeqx | yneqx]. 
 
478
      apply IHl.
 
479
      unfold not; intro HF; simpl in HF; destruct HF; auto.
 
480
      apply (IHl y); assumption. 
 
481
    Qed.
 
482
  
 
483
  End Remove.
 
484
 
 
485
 
 
486
(******************************)
 
487
(** ** Last element of a list *)
 
488
(******************************)
 
489
 
 
490
  (** [last l d] returns the last element of the list [l], 
 
491
    or the default value [d] if [l] is empty. *)
 
492
 
 
493
  Fixpoint last (l:list A) (d:A)  {struct l} : A := 
 
494
  match l with 
 
495
    | nil => d 
 
496
    | a :: nil => a 
 
497
    | a :: l => last l d
 
498
  end.
 
499
 
 
500
  (** [removelast l] remove the last element of [l] *)
 
501
 
 
502
  Fixpoint removelast (l:list A) {struct l} : list A := 
 
503
    match l with 
 
504
      | nil =>  nil 
 
505
      | a :: nil => nil 
 
506
      | a :: l => a :: removelast l
 
507
    end.
 
508
  
 
509
  Lemma app_removelast_last : 
 
510
    forall l d, l<>nil -> l = removelast l ++ (last l d :: nil).
 
511
  Proof.
 
512
    induction l.
 
513
    destruct 1; auto.
 
514
    intros d _.
 
515
    destruct l; auto.
 
516
    pattern (a0::l) at 1; rewrite IHl with d; auto; discriminate.
 
517
  Qed.
 
518
  
 
519
  Lemma exists_last : 
 
520
    forall l, l<>nil -> { l' : (list A) & { a : A | l = l'++a::nil}}. 
 
521
  Proof. 
 
522
    induction l.
 
523
    destruct 1; auto.
 
524
    intros _.
 
525
    destruct l.
 
526
    exists (@nil A); exists a; auto.
 
527
    destruct IHl as [l' (a',H)]; try discriminate.
 
528
    rewrite H.
 
529
    exists (a::l'); exists a'; auto.
 
530
  Qed.
 
531
 
 
532
  Lemma removelast_app : 
 
533
    forall l l', l' <> nil -> removelast (l++l') = l ++ removelast l'.
 
534
  Proof.
 
535
    induction l.
 
536
    simpl; auto.
 
537
    simpl; intros.
 
538
    assert (l++l' <> nil).
 
539
    destruct l.
 
540
    simpl; auto.
 
541
    simpl; discriminate.
 
542
    specialize (IHl l' H).
 
543
    destruct (l++l'); [elim H0; auto|f_equal; auto].
 
544
  Qed.
 
545
 
 
546
  
 
547
  (****************************************)
 
548
  (** ** Counting occurences of a element *)
 
549
  (****************************************)
 
550
 
 
551
  Hypotheses eqA_dec : forall x y : A, {x = y}+{x <> y}.
 
552
  
 
553
  Fixpoint count_occ (l : list A) (x : A){struct l} : nat :=
 
554
    match l with 
 
555
      | nil => 0
 
556
      | y :: tl => 
 
557
        let n := count_occ tl x in 
 
558
          if eqA_dec y x then S n else n
 
559
    end.
 
560
  
 
561
  (** Compatibility of count_occ with operations on list *)
 
562
  Theorem count_occ_In : forall (l : list A) (x : A), In x l <-> count_occ l x > 0.
 
563
  Proof.
 
564
    induction l as [|y l].
 
565
    simpl; intros; split; [destruct 1 | apply gt_irrefl].
 
566
    simpl. intro x; destruct (eqA_dec y x) as [Heq|Hneq].
 
567
    rewrite Heq; intuition. 
 
568
    pose (IHl x). intuition.
 
569
  Qed.
 
570
  
 
571
  Theorem count_occ_inv_nil : forall (l : list A), (forall x:A, count_occ l x = 0) <-> l = nil.
 
572
  Proof.
 
573
    split.
 
574
    (* Case -> *)
 
575
    induction l as [|x l].
 
576
    trivial.
 
577
    intro H.
 
578
    elim (O_S (count_occ l x)).
 
579
    apply sym_eq.
 
580
    generalize (H x).
 
581
    simpl. destruct (eqA_dec x x) as [|HF].
 
582
    trivial.
 
583
    elim HF; reflexivity.
 
584
    (* Case <- *)
 
585
    intro H; rewrite H; simpl; reflexivity.
 
586
  Qed.
 
587
  
 
588
  Lemma count_occ_nil : forall (x : A), count_occ nil x = 0.
 
589
  Proof.
 
590
    intro x; simpl; reflexivity.
 
591
  Qed.
 
592
 
 
593
  Lemma count_occ_cons_eq : forall (l : list A) (x y : A), x = y -> count_occ (x::l) y = S (count_occ l y).
 
594
  Proof.
 
595
    intros l x y H; simpl.
 
596
    destruct (eqA_dec x y); [reflexivity | contradiction].
 
597
  Qed.
 
598
  
 
599
  Lemma count_occ_cons_neq : forall (l : list A) (x y : A), x <> y -> count_occ (x::l) y = count_occ l y.
 
600
  Proof.
 
601
    intros l x y H; simpl.
 
602
    destruct (eqA_dec x y); [contradiction | reflexivity]. 
 
603
  Qed.
 
604
 
 
605
End Elts.
 
606
 
 
607
 
 
608
 
 
609
(*******************************)
 
610
(** * Manipulating whole lists *)
 
611
(*******************************)
 
612
 
 
613
Section ListOps.
 
614
 
 
615
  Variable A : Type.
 
616
 
 
617
  (*************************)
 
618
  (** ** Reverse           *)
 
619
  (*************************)
 
620
 
 
621
  Fixpoint rev (l:list A) : list A :=
 
622
    match l with
 
623
      | nil => nil
 
624
      | x :: l' => rev l' ++ x :: nil
 
625
    end.
 
626
 
 
627
  Lemma distr_rev : forall x y:list A, rev (x ++ y) = rev y ++ rev x.
 
628
  Proof.
 
629
    induction x as [| a l IHl].
 
630
    destruct y as [| a l].
 
631
    simpl in |- *.
 
632
    auto.
 
633
 
 
634
    simpl in |- *.
 
635
    apply app_nil_end; auto.
 
636
 
 
637
    intro y.
 
638
    simpl in |- *.
 
639
    rewrite (IHl y).
 
640
    apply (app_ass (rev y) (rev l) (a :: nil)).
 
641
  Qed.
 
642
 
 
643
  Remark rev_unit : forall (l:list A) (a:A), rev (l ++ a :: nil) = a :: rev l.
 
644
  Proof.
 
645
    intros.
 
646
    apply (distr_rev l (a :: nil)); simpl in |- *; auto.
 
647
  Qed.
 
648
 
 
649
  Lemma rev_involutive : forall l:list A, rev (rev l) = l.
 
650
  Proof.
 
651
    induction l as [| a l IHl].
 
652
    simpl in |- *; auto.
 
653
 
 
654
    simpl in |- *.
 
655
    rewrite (rev_unit (rev l) a).
 
656
    rewrite IHl; auto.
 
657
  Qed.
 
658
 
 
659
 
 
660
  (** Compatibility with other operations *)
 
661
 
 
662
  Lemma In_rev : forall l x, In x l <-> In x (rev l).
 
663
  Proof.
 
664
    induction l.
 
665
    simpl; intuition.
 
666
    intros.
 
667
    simpl.
 
668
    intuition.
 
669
    subst.
 
670
    apply in_or_app; right; simpl; auto.
 
671
    apply in_or_app; left; firstorder.
 
672
    destruct (in_app_or _ _ _ H); firstorder.
 
673
  Qed.
 
674
 
 
675
  Lemma rev_length : forall l, length (rev l) = length l.
 
676
  Proof.
 
677
    induction l;simpl; auto.
 
678
    rewrite app_length.
 
679
    rewrite IHl.
 
680
    simpl.
 
681
    elim (length l); simpl; auto.
 
682
  Qed.
 
683
 
 
684
  Lemma rev_nth : forall l d n,  n < length l ->  
 
685
    nth n (rev l) d = nth (length l - S n) l d.
 
686
  Proof.
 
687
    induction l.
 
688
    intros; inversion H.
 
689
    intros.
 
690
    simpl in H.
 
691
    simpl (rev (a :: l)).
 
692
    simpl (length (a :: l) - S n).
 
693
    inversion H.
 
694
    rewrite <- minus_n_n; simpl.
 
695
    rewrite <- rev_length.
 
696
    rewrite app_nth2; auto.
 
697
    rewrite <- minus_n_n; auto.
 
698
    rewrite app_nth1; auto.
 
699
    rewrite (minus_plus_simpl_l_reverse (length l) n 1).
 
700
    replace (1 + length l) with (S (length l)); auto with arith.
 
701
    rewrite <- minus_Sn_m; auto with arith.
 
702
    apply IHl ; auto with arith.
 
703
    rewrite rev_length; auto.
 
704
  Qed.
 
705
 
 
706
 
 
707
  (**  An alternative tail-recursive definition for reverse *) 
 
708
 
 
709
  Fixpoint rev_append (l l': list A) {struct l} : list A := 
 
710
    match l with 
 
711
      | nil => l' 
 
712
      | a::l => rev_append l (a::l')
 
713
    end.
 
714
 
 
715
  Definition rev' l : list A := rev_append l nil.
 
716
 
 
717
  Notation rev_acc := rev_append (only parsing).
 
718
 
 
719
  Lemma rev_append_rev : forall l l', rev_acc l l' = rev l ++ l'.
 
720
  Proof.
 
721
    induction l; simpl; auto; intros.
 
722
    rewrite <- ass_app; firstorder.
 
723
  Qed.
 
724
 
 
725
  Notation rev_acc_rev := rev_append_rev (only parsing).
 
726
 
 
727
  Lemma rev_alt : forall l, rev l = rev_append l nil.
 
728
  Proof.
 
729
    intros; rewrite rev_append_rev.
 
730
    apply app_nil_end.
 
731
  Qed.
 
732
 
 
733
 
 
734
(*********************************************)
 
735
(** Reverse Induction Principle on Lists  *)
 
736
(*********************************************)
 
737
  
 
738
  Section Reverse_Induction.
 
739
    
 
740
    Unset Implicit Arguments.
 
741
    
 
742
    Lemma rev_list_ind :
 
743
      forall P:list A-> Prop,
 
744
        P nil ->
 
745
        (forall (a:A) (l:list A), P (rev l) -> P (rev (a :: l))) ->
 
746
        forall l:list A, P (rev l).
 
747
    Proof.
 
748
      induction l; auto.
 
749
    Qed.
 
750
    Set Implicit Arguments.
 
751
    
 
752
    Theorem rev_ind :
 
753
      forall P:list A -> Prop,
 
754
        P nil ->
 
755
        (forall (x:A) (l:list A), P l -> P (l ++ x :: nil)) -> forall l:list A, P l.
 
756
    Proof.
 
757
      intros.
 
758
      generalize (rev_involutive l).
 
759
      intros E; rewrite <- E.
 
760
      apply (rev_list_ind P).
 
761
      auto.
 
762
      
 
763
      simpl in |- *.
 
764
      intros.
 
765
      apply (H0 a (rev l0)).
 
766
      auto.
 
767
    Qed.
 
768
  
 
769
  End Reverse_Induction.
 
770
 
 
771
 
 
772
 
 
773
  (***********************************)
 
774
  (** ** Lists modulo permutation    *)
 
775
  (***********************************)
 
776
  
 
777
  Section Permutation.
 
778
 
 
779
    Inductive Permutation : list A -> list A -> Prop :=
 
780
      | perm_nil: Permutation nil nil
 
781
      | perm_skip: forall (x:A) (l l':list A), Permutation l l' -> Permutation (cons x l) (cons x l')
 
782
      | perm_swap: forall (x y:A) (l:list A), Permutation (cons y (cons x l)) (cons x (cons y l))
 
783
      | perm_trans: forall (l l' l'':list A), Permutation l l' -> Permutation l' l'' -> Permutation l l''.
 
784
 
 
785
    Hint Constructors Permutation.
 
786
 
 
787
  (** Some facts about [Permutation] *)
 
788
 
 
789
    Theorem Permutation_nil : forall (l : list A), Permutation nil l -> l = nil.
 
790
    Proof.
 
791
      intros l HF.
 
792
      set (m:=@nil A) in HF; assert (m = nil); [reflexivity|idtac]; clearbody m.
 
793
      induction HF; try elim (nil_cons (sym_eq H)); auto.
 
794
    Qed.
 
795
 
 
796
    Theorem Permutation_nil_cons : forall (l : list A) (x : A), ~ Permutation nil (x::l).
 
797
    Proof.
 
798
      unfold not; intros l x HF.
 
799
      elim (@nil_cons A x l). apply sym_eq. exact (Permutation_nil HF).
 
800
    Qed.
 
801
 
 
802
  (** Permutation over lists is a equivalence relation *)
 
803
 
 
804
    Theorem Permutation_refl : forall l : list A, Permutation l l.
 
805
    Proof.
 
806
      induction l; constructor. exact IHl. 
 
807
    Qed.
 
808
 
 
809
    Theorem Permutation_sym : forall l l' : list A, Permutation l l' -> Permutation l' l.
 
810
    Proof.
 
811
      intros l l' Hperm; induction Hperm; auto.
 
812
      apply perm_trans with (l':=l'); assumption.
 
813
    Qed.
 
814
 
 
815
    Theorem Permutation_trans : forall l l' l'' : list A, Permutation l l' -> Permutation l' l'' -> Permutation l l''.
 
816
    Proof.
 
817
      exact perm_trans.
 
818
    Qed.
 
819
 
 
820
    Hint Resolve Permutation_refl Permutation_sym Permutation_trans.
 
821
 
 
822
  (** Compatibility with others operations on lists *)
 
823
 
 
824
    Theorem Permutation_in : forall (l l' : list A) (x : A), Permutation l l' -> In x l -> In x l'.
 
825
    Proof.
 
826
      intros l l' x Hperm; induction Hperm; simpl; tauto. 
 
827
    Qed.
 
828
 
 
829
    Lemma Permutation_app_tail : forall (l l' tl : list A), Permutation l l' -> Permutation (l++tl) (l'++tl).
 
830
    Proof.
 
831
      intros l l' tl Hperm; induction Hperm as [|x l l'|x y l|l l' l'']; simpl; auto.
 
832
      eapply Permutation_trans with (l':=l'++tl); trivial.
 
833
    Qed.
 
834
 
 
835
    Lemma Permutation_app_head : forall (l tl tl' : list A), Permutation tl tl' -> Permutation (l++tl) (l++tl').
 
836
    Proof.
 
837
      intros l tl tl' Hperm; induction l; [trivial | repeat rewrite <- app_comm_cons; constructor; assumption].
 
838
    Qed.
 
839
 
 
840
    Theorem Permutation_app : forall (l m l' m' : list A), Permutation l l' -> Permutation m m' -> Permutation (l++m) (l'++m').
 
841
    Proof.
 
842
      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.
 
843
      apply Permutation_trans with (l' := (x :: y :: l ++ m));
 
844
        [idtac | repeat rewrite app_comm_cons; apply Permutation_app_head]; trivial.
 
845
      apply Permutation_trans with (l' := (l' ++ m')); try assumption.
 
846
      apply Permutation_app_tail; assumption.
 
847
    Qed.
 
848
 
 
849
    Theorem Permutation_app_swap : forall (l l' : list A), Permutation (l++l') (l'++l).
 
850
    Proof.
 
851
      induction l as [|x l]. 
 
852
      simpl; intro l'; rewrite <- app_nil_end; trivial.
 
853
      induction l' as [|y l'].
 
854
      simpl; rewrite <- app_nil_end; trivial.
 
855
      simpl; apply Permutation_trans with (l' := x :: y :: l' ++ l).
 
856
      constructor; rewrite app_comm_cons; apply IHl.
 
857
      apply Permutation_trans with (l' := y :: x :: l' ++ l); constructor.
 
858
      apply Permutation_trans with (l' := x :: l ++ l'); auto.
 
859
    Qed.
 
860
  
 
861
    Theorem Permutation_cons_app : forall (l l1 l2:list A) a,
 
862
      Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2).
 
863
    Proof.
 
864
    intros l l1; revert l.
 
865
    induction l1.
 
866
    simpl.
 
867
    intros; apply perm_skip; auto.
 
868
    simpl; intros.
 
869
    apply perm_trans with (a0::a::l1++l2).
 
870
    apply perm_skip; auto.
 
871
    apply perm_trans with (a::a0::l1++l2).
 
872
    apply perm_swap; auto.
 
873
    apply perm_skip; auto.
 
874
    Qed.
 
875
    Hint Resolve Permutation_cons_app.
 
876
 
 
877
    Theorem Permutation_length : forall (l l' : list A), Permutation l l' -> length l = length l'.
 
878
    Proof.
 
879
      intros l l' Hperm; induction Hperm; simpl; auto.
 
880
      apply trans_eq with (y:= (length l')); trivial.
 
881
    Qed.
 
882
 
 
883
    Theorem Permutation_rev : forall (l : list A), Permutation l (rev l). 
 
884
    Proof.
 
885
      induction l as [| x l]; simpl; trivial.
 
886
      apply Permutation_trans with (l' := (x::nil)++rev l).
 
887
      simpl; auto.
 
888
      apply Permutation_app_swap.
 
889
    Qed.
 
890
 
 
891
    Theorem Permutation_ind_bis : 
 
892
     forall P : list A -> list A -> Prop,
 
893
       P (@nil A) (@nil A) ->
 
894
       (forall x l l', Permutation l l' -> P l l' -> P (x :: l) (x :: l')) ->
 
895
       (forall x y l l', Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) ->
 
896
       (forall l l' l'', Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l'') ->
 
897
       forall l l', Permutation l l' -> P l l'.
 
898
    Proof.
 
899
    intros P Hnil Hskip Hswap Htrans.
 
900
    induction 1; auto.
 
901
    apply Htrans with (x::y::l); auto.
 
902
    apply Hswap; auto.
 
903
    induction l; auto.
 
904
    apply Hskip; auto.
 
905
    apply Hskip; auto.
 
906
    induction l; auto.
 
907
    eauto.
 
908
    Qed.
 
909
 
 
910
    Ltac break_list l x l' H := 
 
911
     destruct l as [|x l']; simpl in *; 
 
912
     injection H; intros; subst; clear H.
 
913
 
 
914
    Theorem Permutation_app_inv : forall (l1 l2 l3 l4:list A) a,
 
915
      Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4).
 
916
    Proof.
 
917
    set (P:=fun l l' =>  
 
918
             forall a l1 l2 l3 l4, l=l1++a::l2 -> l'=l3++a::l4 -> Permutation (l1++l2) (l3++l4)).
 
919
    cut (forall l l', Permutation l l' -> P l l').
 
920
    intros; apply (H _ _ H0 a); auto.
 
921
    intros; apply (Permutation_ind_bis P); unfold P; clear P; try clear H l l'; simpl; auto.
 
922
    (* nil *)
 
923
    intros; destruct l1; simpl in *; discriminate.
 
924
    (* skip *)
 
925
    intros x l l' H IH; intros.
 
926
    break_list l1 b l1' H0; break_list l3 c l3' H1.
 
927
    auto.
 
928
    apply perm_trans with (l3'++c::l4); auto.
 
929
    apply perm_trans with (l1'++a::l2); auto using Permutation_cons_app.
 
930
    apply perm_skip.
 
931
    apply (IH a l1' l2 l3' l4); auto.
 
932
    (* contradict *)
 
933
    intros x y l l' Hp IH; intros.
 
934
    break_list l1 b l1' H; break_list l3 c l3' H0.
 
935
    auto.
 
936
    break_list l3' b l3'' H.
 
937
    auto.
 
938
    apply perm_trans with (c::l3''++b::l4); auto.
 
939
    break_list l1' c l1'' H1. 
 
940
    auto.
 
941
    apply perm_trans with (b::l1''++c::l2); auto.
 
942
    break_list l3' d l3'' H; break_list l1' e l1'' H1. 
 
943
    auto.
 
944
    apply perm_trans with (e::a::l1''++l2); auto.
 
945
    apply perm_trans with (e::l1''++a::l2); auto.
 
946
    apply perm_trans with (d::a::l3''++l4); auto.
 
947
    apply perm_trans with (d::l3''++a::l4); auto.
 
948
    apply perm_trans with (e::d::l1''++l2); auto.
 
949
    apply perm_skip; apply perm_skip.
 
950
    apply (IH a l1'' l2 l3'' l4); auto.
 
951
    (*trans*)
 
952
    intros.
 
953
    destruct (In_split a l') as (l'1,(l'2,H6)).
 
954
    apply (Permutation_in a H).
 
955
    subst l.
 
956
    apply in_or_app; right; red; auto.
 
957
    apply perm_trans with (l'1++l'2).
 
958
    apply (H0 _ _ _ _ _ H3 H6).
 
959
    apply (H2 _ _ _ _ _ H6 H4).
 
960
    Qed.
 
961
 
 
962
    Theorem Permutation_cons_inv : 
 
963
       forall l l' a, Permutation (a::l) (a::l') -> Permutation l l'.
 
964
    Proof.
 
965
    intros; exact (Permutation_app_inv (@nil _) l (@nil _) l' a H). 
 
966
    Qed.
 
967
 
 
968
    Theorem Permutation_cons_app_inv :
 
969
       forall l l1 l2 a, Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).
 
970
    Proof.
 
971
    intros; exact (Permutation_app_inv (@nil _) l l1 l2 a H). 
 
972
    Qed.
 
973
    
 
974
    Theorem Permutation_app_inv_l : 
 
975
        forall l l1 l2, Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.
 
976
    Proof.    
 
977
    induction l; simpl; auto.
 
978
    intros.
 
979
    apply IHl.
 
980
    apply Permutation_cons_inv with a; auto.
 
981
    Qed.
 
982
 
 
983
    Theorem Permutation_app_inv_r : 
 
984
       forall l l1 l2, Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.
 
985
    Proof.
 
986
    induction l.
 
987
    intros l1 l2; do 2 rewrite <- app_nil_end; auto.
 
988
    intros.
 
989
    apply IHl.
 
990
    apply Permutation_app_inv with a; auto.
 
991
    Qed.
 
992
 
 
993
  End Permutation.
 
994
 
 
995
 
 
996
  (***********************************)
 
997
  (** ** Decidable equality on lists *)
 
998
  (***********************************)
 
999
 
 
1000
  Hypotheses eqA_dec : forall (x y : A), {x = y}+{x <> y}.
 
1001
 
 
1002
  Lemma list_eq_dec :
 
1003
    forall l l':list A, {l = l'} + {l <> l'}.
 
1004
  Proof.
 
1005
    induction l as [| x l IHl]; destruct l' as [| y l'].
 
1006
    left; trivial.
 
1007
    right; apply nil_cons. 
 
1008
    right; unfold not; intro HF; apply (nil_cons (sym_eq HF)).
 
1009
    destruct (eqA_dec x y) as [xeqy|xneqy]; destruct (IHl l') as [leql'|lneql']; 
 
1010
      try (right; unfold not; intro HF; injection HF; intros; contradiction).
 
1011
    rewrite xeqy; rewrite leql'; left; trivial.
 
1012
  Qed.
 
1013
 
 
1014
 
 
1015
End ListOps.
 
1016
 
 
1017
 
 
1018
(***************************************************)
 
1019
(** * Applying functions to the elements of a list *)
 
1020
(***************************************************)
 
1021
 
 
1022
(************)
 
1023
(** ** Map  *)
 
1024
(************)
 
1025
 
 
1026
Section Map.
 
1027
  Variables A B : Type.
 
1028
  Variable f : A -> B.
 
1029
  
 
1030
  Fixpoint map (l:list A) : list B :=
 
1031
    match l with
 
1032
      | nil => nil
 
1033
      | cons a t => cons (f a) (map t)
 
1034
    end.
 
1035
  
 
1036
  Lemma in_map :
 
1037
    forall (l:list A) (x:A), In x l -> In (f x) (map l).
 
1038
  Proof. 
 
1039
    induction l as [| a l IHl]; simpl in |- *;
 
1040
      [ auto
 
1041
        | destruct 1; [ left; apply f_equal with (f := f); assumption | auto ] ].
 
1042
  Qed.
 
1043
  
 
1044
  Lemma in_map_iff : forall l y, In y (map l) <-> exists x, f x = y /\ In x l.
 
1045
  Proof.
 
1046
    induction l; firstorder (subst; auto).
 
1047
  Qed.
 
1048
 
 
1049
  Lemma map_length : forall l, length (map l) = length l.
 
1050
  Proof.
 
1051
    induction l; simpl; auto.
 
1052
  Qed.
 
1053
 
 
1054
  Lemma map_nth : forall l d n, 
 
1055
    nth n (map l) (f d) = f (nth n l d).
 
1056
  Proof.
 
1057
    induction l; simpl map; destruct n; firstorder.
 
1058
  Qed.
 
1059
  
 
1060
  Lemma map_app : forall l l',  
 
1061
    map (l++l') = (map l)++(map l').
 
1062
  Proof. 
 
1063
    induction l; simpl; auto.
 
1064
    intros; rewrite IHl; auto.
 
1065
  Qed.
 
1066
  
 
1067
  Lemma map_rev : forall l, map (rev l) = rev (map l).
 
1068
  Proof. 
 
1069
    induction l; simpl; auto.
 
1070
    rewrite map_app.
 
1071
    rewrite IHl; auto.
 
1072
  Qed.
 
1073
 
 
1074
  Hint Constructors Permutation.
 
1075
 
 
1076
  Lemma Permutation_map : 
 
1077
    forall l l', Permutation l l' -> Permutation (map l) (map l').
 
1078
  Proof. 
 
1079
  induction 1; simpl; auto; eauto.
 
1080
  Qed.
 
1081
 
 
1082
  (** [flat_map] *)
 
1083
 
 
1084
  Fixpoint flat_map (f:A -> list B) (l:list A) {struct l} : 
 
1085
    list B :=
 
1086
    match l with
 
1087
      | nil => nil
 
1088
      | cons x t => (f x)++(flat_map f t)
 
1089
    end.
 
1090
  
 
1091
  Lemma in_flat_map : forall (f:A->list B)(l:list A)(y:B),
 
1092
    In y (flat_map f l) <-> exists x, In x l /\ In y (f x). 
 
1093
  Proof.
 
1094
    induction l; simpl; split; intros.
 
1095
    contradiction.
 
1096
    destruct H as (x,(H,_)); contradiction.
 
1097
    destruct (in_app_or _ _ _ H).
 
1098
    exists a; auto.
 
1099
    destruct (IHl y) as (H1,_); destruct (H1 H0) as (x,(H2,H3)).
 
1100
    exists x; auto.
 
1101
    apply in_or_app.
 
1102
    destruct H as (x,(H0,H1)); destruct H0.
 
1103
    subst; auto.
 
1104
    right; destruct (IHl y) as (_,H2); apply H2.
 
1105
    exists x; auto.
 
1106
  Qed.
 
1107
 
 
1108
End Map. 
 
1109
 
 
1110
Lemma map_map : forall (A B C:Type)(f:A->B)(g:B->C) l, 
 
1111
  map g (map f l) = map (fun x => g (f x)) l.
 
1112
Proof.
 
1113
  induction l; simpl; auto.
 
1114
  rewrite IHl; auto.
 
1115
Qed.
 
1116
 
 
1117
Lemma map_ext : 
 
1118
  forall (A B : Type)(f g:A->B), (forall a, f a = g a) -> forall l, map f l = map g l.
 
1119
Proof.
 
1120
  induction l; simpl; auto.
 
1121
  rewrite H; rewrite IHl; auto.
 
1122
Qed.
 
1123
 
 
1124
 
 
1125
(************************************)
 
1126
(** Left-to-right iterator on lists *)
 
1127
(************************************)
 
1128
 
 
1129
Section Fold_Left_Recursor.
 
1130
  Variables A B : Type.
 
1131
  Variable f : A -> B -> A.
 
1132
  
 
1133
  Fixpoint fold_left (l:list B) (a0:A) {struct l} : A :=
 
1134
    match l with
 
1135
      | nil => a0
 
1136
      | cons b t => fold_left t (f a0 b)
 
1137
    end.
 
1138
  
 
1139
  Lemma fold_left_app : forall (l l':list B)(i:A), 
 
1140
    fold_left (l++l') i = fold_left l' (fold_left l i).
 
1141
  Proof.
 
1142
    induction l. 
 
1143
    simpl; auto.
 
1144
    intros.
 
1145
    simpl.
 
1146
    auto.
 
1147
  Qed.
 
1148
 
 
1149
End Fold_Left_Recursor.
 
1150
 
 
1151
Lemma fold_left_length : 
 
1152
  forall (A:Type)(l:list A), fold_left (fun x _ => S x) l 0 = length l.
 
1153
Proof.
 
1154
  intro A.
 
1155
  cut (forall (l:list A) n, fold_left (fun x _ => S x) l n = n + length l).
 
1156
  intros.
 
1157
  exact (H l 0).
 
1158
  induction l; simpl; auto.
 
1159
  intros; rewrite IHl.
 
1160
  simpl; auto with arith.
 
1161
Qed.
 
1162
 
 
1163
(************************************)
 
1164
(** Right-to-left iterator on lists *)
 
1165
(************************************)
 
1166
 
 
1167
Section Fold_Right_Recursor.
 
1168
  Variables A B : Type.
 
1169
  Variable f : B -> A -> A.
 
1170
  Variable a0 : A.
 
1171
  
 
1172
  Fixpoint fold_right (l:list B) : A :=
 
1173
    match l with
 
1174
      | nil => a0
 
1175
      | cons b t => f b (fold_right t)
 
1176
    end.
 
1177
 
 
1178
End Fold_Right_Recursor.
 
1179
 
 
1180
  Lemma fold_right_app : forall (A B:Type)(f:A->B->B) l l' i, 
 
1181
    fold_right f i (l++l') = fold_right f (fold_right f i l') l.
 
1182
  Proof.
 
1183
    induction l.
 
1184
    simpl; auto.
 
1185
    simpl; intros.
 
1186
    f_equal; auto.
 
1187
  Qed.
 
1188
 
 
1189
  Lemma fold_left_rev_right : forall (A B:Type)(f:A->B->B) l i, 
 
1190
    fold_right f i (rev l) = fold_left (fun x y => f y x) l i.
 
1191
  Proof.
 
1192
    induction l.
 
1193
    simpl; auto.
 
1194
    intros.
 
1195
    simpl.
 
1196
    rewrite fold_right_app; simpl; auto.
 
1197
  Qed.
 
1198
 
 
1199
  Theorem fold_symmetric :
 
1200
    forall (A:Type) (f:A -> A -> A),
 
1201
      (forall x y z:A, f x (f y z) = f (f x y) z) ->
 
1202
      (forall x y:A, f x y = f y x) ->
 
1203
      forall (a0:A) (l:list A), fold_left f l a0 = fold_right f a0 l.
 
1204
  Proof.
 
1205
    destruct l as [| a l].
 
1206
    reflexivity.
 
1207
    simpl in |- *.
 
1208
    rewrite <- H0.
 
1209
    generalize a0 a.
 
1210
    induction l as [| a3 l IHl]; simpl in |- *.
 
1211
    trivial.
 
1212
    intros.
 
1213
    rewrite H.
 
1214
    rewrite (H0 a2).
 
1215
    rewrite <- (H a1).
 
1216
    rewrite (H0 a1).
 
1217
    rewrite IHl.
 
1218
    reflexivity.
 
1219
  Qed.
 
1220
 
 
1221
 
 
1222
 
 
1223
  (** [(list_power x y)] is [y^x], or the set of sequences of elts of [y]
 
1224
      indexed by elts of [x], sorted in lexicographic order. *)
 
1225
 
 
1226
  Fixpoint list_power (A B:Type)(l:list A) (l':list B) {struct l} :
 
1227
    list (list (A * B)) :=
 
1228
    match l with
 
1229
      | nil => cons nil nil
 
1230
      | cons x t =>
 
1231
        flat_map (fun f:list (A * B) => map (fun y:B => cons (x, y) f) l')
 
1232
        (list_power t l')
 
1233
    end.
 
1234
 
 
1235
 
 
1236
  (*************************************)
 
1237
  (** ** Boolean operations over lists *)
 
1238
  (*************************************)
 
1239
 
 
1240
  Section Bool. 
 
1241
    Variable A : Type.
 
1242
    Variable f : A -> bool.
 
1243
 
 
1244
  (** find whether a boolean function can be satisfied by an 
 
1245
       elements of the list. *)
 
1246
 
 
1247
    Fixpoint existsb (l:list A) {struct l}: bool := 
 
1248
      match l with 
 
1249
        | nil => false
 
1250
        | a::l => f a || existsb l
 
1251
      end.
 
1252
 
 
1253
    Lemma existsb_exists : 
 
1254
      forall l, existsb l = true <-> exists x, In x l /\ f x = true.
 
1255
    Proof.
 
1256
      induction l; simpl; intuition.
 
1257
      inversion H.
 
1258
      firstorder.
 
1259
      destruct (orb_prop _ _ H1); firstorder.
 
1260
      firstorder.
 
1261
      subst.
 
1262
      rewrite H2; auto.
 
1263
    Qed.
 
1264
 
 
1265
    Lemma existsb_nth : forall l n d, n < length l ->
 
1266
      existsb l = false -> f (nth n l d) = false.
 
1267
    Proof.
 
1268
      induction l.
 
1269
      inversion 1.
 
1270
      simpl; intros.
 
1271
      destruct (orb_false_elim _ _ H0); clear H0; auto.
 
1272
      destruct n ; auto. 
 
1273
      rewrite IHl; auto with arith.
 
1274
    Qed.
 
1275
 
 
1276
  (** find whether a boolean function is satisfied by 
 
1277
    all the elements of a list. *)
 
1278
 
 
1279
    Fixpoint forallb (l:list A) {struct l} : bool := 
 
1280
      match l with 
 
1281
        | nil => true
 
1282
        | a::l => f a && forallb l
 
1283
      end.
 
1284
 
 
1285
    Lemma forallb_forall : 
 
1286
      forall l, forallb l = true <-> (forall x, In x l -> f x = true).
 
1287
    Proof.
 
1288
      induction l; simpl; intuition.
 
1289
      destruct (andb_prop _ _ H1).
 
1290
      congruence.
 
1291
      destruct (andb_prop _ _ H1); auto.
 
1292
      assert (forallb l = true).
 
1293
      apply H0; intuition.
 
1294
      rewrite H1; auto. 
 
1295
    Qed.
 
1296
 
 
1297
  (** [filter] *)
 
1298
 
 
1299
    Fixpoint filter (l:list A) : list A := 
 
1300
      match l with 
 
1301
        | nil => nil
 
1302
        | x :: l => if f x then x::(filter l) else filter l
 
1303
      end.
 
1304
 
 
1305
    Lemma filter_In : forall x l, In x (filter l) <-> In x l /\ f x = true.
 
1306
    Proof.
 
1307
      induction l; simpl.
 
1308
      intuition.
 
1309
      intros.
 
1310
      case_eq (f a); intros; simpl; intuition congruence.
 
1311
    Qed.
 
1312
 
 
1313
  (** [find] *)
 
1314
 
 
1315
    Fixpoint find (l:list A) : option A :=
 
1316
      match l with
 
1317
        | nil => None
 
1318
        | x :: tl => if f x then Some x else find tl
 
1319
      end.
 
1320
 
 
1321
  (** [partition] *)
 
1322
 
 
1323
    Fixpoint partition (l:list A) {struct l} : list A * list A := 
 
1324
      match l with
 
1325
        | nil => (nil, nil)
 
1326
        | x :: tl => let (g,d) := partition tl in 
 
1327
          if f x then (x::g,d) else (g,x::d)
 
1328
      end.
 
1329
 
 
1330
  End Bool.
 
1331
 
 
1332
 
 
1333
 
 
1334
 
 
1335
  (******************************************************)
 
1336
  (** ** Operations on lists of pairs or lists of lists *)
 
1337
  (******************************************************)
 
1338
 
 
1339
  Section ListPairs.
 
1340
    Variables A B : Type.
 
1341
    
 
1342
  (** [split] derives two lists from a list of pairs *)
 
1343
 
 
1344
    Fixpoint split  (l:list (A*B)) { struct l }: list A * list B :=
 
1345
      match l with
 
1346
        | nil => (nil, nil)
 
1347
        | (x,y) :: tl => let (g,d) := split tl in (x::g, y::d)
 
1348
      end.
 
1349
 
 
1350
    Lemma in_split_l : forall (l:list (A*B))(p:A*B), 
 
1351
      In p l -> In (fst p) (fst (split l)). 
 
1352
    Proof.
 
1353
      induction l; simpl; intros; auto.
 
1354
      destruct p; destruct a; destruct (split l); simpl in *.
 
1355
      destruct H.
 
1356
      injection H; auto.
 
1357
      right; apply (IHl (a0,b) H).
 
1358
    Qed.
 
1359
 
 
1360
    Lemma in_split_r : forall (l:list (A*B))(p:A*B), 
 
1361
      In p l -> In (snd p) (snd (split l)). 
 
1362
    Proof.
 
1363
      induction l; simpl; intros; auto.
 
1364
      destruct p; destruct a; destruct (split l); simpl in *.
 
1365
      destruct H.
 
1366
      injection H; auto.
 
1367
      right; apply (IHl (a0,b) H).
 
1368
    Qed.
 
1369
 
 
1370
    Lemma split_nth : forall (l:list (A*B))(n:nat)(d:A*B), 
 
1371
      nth n l d = (nth n (fst (split l)) (fst d), nth n (snd (split l)) (snd d)).
 
1372
    Proof.
 
1373
      induction l.
 
1374
      destruct n; destruct d; simpl; auto.
 
1375
      destruct n; destruct d; simpl; auto.
 
1376
      destruct a; destruct (split l); simpl; auto.
 
1377
      destruct a; destruct (split l); simpl in *; auto.
 
1378
      apply IHl.
 
1379
    Qed.
 
1380
 
 
1381
    Lemma split_length_l : forall (l:list (A*B)),
 
1382
      length (fst (split l)) = length l. 
 
1383
    Proof.
 
1384
      induction l; simpl; auto.
 
1385
      destruct a; destruct (split l); simpl; auto.
 
1386
    Qed.
 
1387
 
 
1388
    Lemma split_length_r : forall (l:list (A*B)),
 
1389
      length (snd (split l)) = length l. 
 
1390
    Proof.
 
1391
      induction l; simpl; auto.
 
1392
      destruct a; destruct (split l); simpl; auto.
 
1393
    Qed.
 
1394
 
 
1395
  (** [combine] is the opposite of [split]. 
 
1396
      Lists given to [combine] are meant to be of same length. 
 
1397
      If not, [combine] stops on the shorter list *)
 
1398
 
 
1399
    Fixpoint combine (l : list A) (l' : list B){struct l} : list (A*B) :=
 
1400
      match l,l' with
 
1401
        | x::tl, y::tl' => (x,y)::(combine tl tl')
 
1402
        | _, _ => nil
 
1403
      end.
 
1404
 
 
1405
    Lemma split_combine : forall (l: list (A*B)), 
 
1406
      let (l1,l2) := split l in combine l1 l2 = l.
 
1407
    Proof.
 
1408
      induction l.
 
1409
      simpl; auto.
 
1410
      destruct a; simpl. 
 
1411
      destruct (split l); simpl in *.
 
1412
      f_equal; auto.
 
1413
    Qed.
 
1414
 
 
1415
    Lemma combine_split : forall (l:list A)(l':list B), length l = length l' -> 
 
1416
      split (combine l l') = (l,l').
 
1417
    Proof.
 
1418
      induction l; destruct l'; simpl; intros; auto; try discriminate.
 
1419
      injection H; clear H; intros.
 
1420
      rewrite IHl; auto.
 
1421
    Qed.
 
1422
 
 
1423
    Lemma in_combine_l : forall (l:list A)(l':list B)(x:A)(y:B), 
 
1424
      In (x,y) (combine l l') -> In x l.
 
1425
    Proof.
 
1426
      induction l.
 
1427
      simpl; auto.
 
1428
      destruct l'; simpl; auto; intros.
 
1429
      contradiction. 
 
1430
      destruct H.
 
1431
      injection H; auto.
 
1432
      right; apply IHl with l' y; auto.
 
1433
    Qed.
 
1434
 
 
1435
    Lemma in_combine_r : forall (l:list A)(l':list B)(x:A)(y:B), 
 
1436
      In (x,y) (combine l l') -> In y l'.
 
1437
    Proof.
 
1438
      induction l.
 
1439
      simpl; intros; contradiction.
 
1440
      destruct l'; simpl; auto; intros.
 
1441
      destruct H.
 
1442
      injection H; auto.
 
1443
      right; apply IHl with x; auto.
 
1444
    Qed.
 
1445
 
 
1446
    Lemma combine_length : forall (l:list A)(l':list B), 
 
1447
      length (combine l l') = min (length l) (length l').
 
1448
    Proof.
 
1449
      induction l.
 
1450
      simpl; auto.
 
1451
      destruct l'; simpl; auto.
 
1452
    Qed.
 
1453
 
 
1454
    Lemma combine_nth : forall (l:list A)(l':list B)(n:nat)(x:A)(y:B), 
 
1455
      length l = length l' -> 
 
1456
      nth n (combine l l') (x,y) = (nth n l x, nth n l' y).
 
1457
    Proof.
 
1458
      induction l; destruct l'; intros; try discriminate.
 
1459
      destruct n; simpl; auto.
 
1460
      destruct n; simpl in *; auto.
 
1461
    Qed.
 
1462
 
 
1463
  (** [list_prod] has the same signature as [combine], but unlike
 
1464
     [combine], it adds every possible pairs, not only those at the 
 
1465
     same position. *)
 
1466
 
 
1467
    Fixpoint list_prod (l:list A) (l':list B) {struct l} :
 
1468
      list (A * B) :=
 
1469
      match l with
 
1470
        | nil => nil
 
1471
        | cons x t => (map (fun y:B => (x, y)) l')++(list_prod t l')
 
1472
      end.
 
1473
 
 
1474
    Lemma in_prod_aux :
 
1475
      forall (x:A) (y:B) (l:list B),
 
1476
        In y l -> In (x, y) (map (fun y0:B => (x, y0)) l).
 
1477
    Proof. 
 
1478
      induction l;
 
1479
        [ simpl in |- *; auto
 
1480
          | simpl in |- *; destruct 1 as [H1| ];
 
1481
            [ left; rewrite H1; trivial | right; auto ] ].
 
1482
    Qed.
 
1483
 
 
1484
    Lemma in_prod :
 
1485
      forall (l:list A) (l':list B) (x:A) (y:B),
 
1486
        In x l -> In y l' -> In (x, y) (list_prod l l').
 
1487
    Proof. 
 
1488
      induction l;
 
1489
        [ simpl in |- *; tauto
 
1490
          | simpl in |- *; intros; apply in_or_app; destruct H;
 
1491
            [ left; rewrite H; apply in_prod_aux; assumption | right; auto ] ].
 
1492
    Qed.
 
1493
 
 
1494
    Lemma in_prod_iff : 
 
1495
      forall (l:list A)(l':list B)(x:A)(y:B), 
 
1496
        In (x,y) (list_prod l l') <-> In x l /\ In y l'.
 
1497
    Proof.
 
1498
      split; [ | intros; apply in_prod; intuition ].
 
1499
      induction l; simpl; intros.
 
1500
      intuition.
 
1501
      destruct (in_app_or _ _ _ H); clear H.
 
1502
      destruct (in_map_iff (fun y : B => (a, y)) l' (x,y)) as (H1,_).
 
1503
      destruct (H1 H0) as (z,(H2,H3)); clear H0 H1.
 
1504
      injection H2; clear H2; intros; subst; intuition.
 
1505
      intuition.
 
1506
    Qed. 
 
1507
 
 
1508
    Lemma prod_length : forall (l:list A)(l':list B), 
 
1509
      length (list_prod l l') = (length l) * (length l').
 
1510
    Proof.
 
1511
      induction l; simpl; auto.
 
1512
      intros.
 
1513
      rewrite app_length.
 
1514
      rewrite map_length.
 
1515
      auto.
 
1516
    Qed.
 
1517
 
 
1518
  End ListPairs.
 
1519
 
 
1520
 
 
1521
 
 
1522
 
 
1523
(***************************************)
 
1524
(** * Miscelenous operations on lists  *)
 
1525
(***************************************)
 
1526
 
 
1527
 
 
1528
 
 
1529
(******************************)
 
1530
(** ** Length order of lists  *)
 
1531
(******************************)
 
1532
 
 
1533
Section length_order.
 
1534
  Variable A : Type.
 
1535
 
 
1536
  Definition lel (l m:list A) := length l <= length m.
 
1537
 
 
1538
  Variables a b : A.
 
1539
  Variables l m n : list A.
 
1540
 
 
1541
  Lemma lel_refl : lel l l.
 
1542
  Proof. 
 
1543
    unfold lel in |- *; auto with arith.
 
1544
  Qed.
 
1545
 
 
1546
  Lemma lel_trans : lel l m -> lel m n -> lel l n.
 
1547
  Proof. 
 
1548
    unfold lel in |- *; intros.
 
1549
    now_show (length l <= length n).
 
1550
    apply le_trans with (length m); auto with arith.
 
1551
  Qed.
 
1552
 
 
1553
  Lemma lel_cons_cons : lel l m -> lel (a :: l) (b :: m).
 
1554
  Proof. 
 
1555
    unfold lel in |- *; simpl in |- *; auto with arith.
 
1556
  Qed.
 
1557
 
 
1558
  Lemma lel_cons : lel l m -> lel l (b :: m).
 
1559
  Proof. 
 
1560
    unfold lel in |- *; simpl in |- *; auto with arith.
 
1561
  Qed.
 
1562
 
 
1563
  Lemma lel_tail : lel (a :: l) (b :: m) -> lel l m.
 
1564
  Proof. 
 
1565
    unfold lel in |- *; simpl in |- *; auto with arith.
 
1566
  Qed.
 
1567
 
 
1568
  Lemma lel_nil : forall l':list A, lel l' nil -> nil = l'.
 
1569
  Proof. 
 
1570
    intro l'; elim l'; auto with arith.
 
1571
    intros a' y H H0.
 
1572
    now_show (nil = a' :: y).
 
1573
    absurd (S (length y) <= 0); auto with arith.
 
1574
  Qed.
 
1575
End length_order.
 
1576
 
 
1577
Hint Resolve lel_refl lel_cons_cons lel_cons lel_nil lel_nil nil_cons:
 
1578
  datatypes v62.
 
1579
 
 
1580
 
 
1581
(******************************)
 
1582
(** ** Set inclusion on list  *)
 
1583
(******************************)
 
1584
 
 
1585
Section SetIncl.
 
1586
 
 
1587
  Variable A : Type.
 
1588
 
 
1589
  Definition incl (l m:list A) := forall a:A, In a l -> In a m.
 
1590
  Hint Unfold incl.
 
1591
  
 
1592
  Lemma incl_refl : forall l:list A, incl l l.
 
1593
  Proof. 
 
1594
    auto.
 
1595
  Qed.
 
1596
  Hint Resolve incl_refl.
 
1597
  
 
1598
  Lemma incl_tl : forall (a:A) (l m:list A), incl l m -> incl l (a :: m).
 
1599
  Proof. 
 
1600
    auto with datatypes.
 
1601
  Qed.
 
1602
  Hint Immediate incl_tl.
 
1603
 
 
1604
  Lemma incl_tran : forall l m n:list A, incl l m -> incl m n -> incl l n.
 
1605
  Proof. 
 
1606
    auto.
 
1607
  Qed.
 
1608
  
 
1609
  Lemma incl_appl : forall l m n:list A, incl l n -> incl l (n ++ m).
 
1610
  Proof. 
 
1611
    auto with datatypes.
 
1612
  Qed.
 
1613
  Hint Immediate incl_appl.
 
1614
  
 
1615
  Lemma incl_appr : forall l m n:list A, incl l n -> incl l (m ++ n).
 
1616
  Proof. 
 
1617
    auto with datatypes.
 
1618
  Qed.
 
1619
  Hint Immediate incl_appr.
 
1620
  
 
1621
  Lemma incl_cons :
 
1622
    forall (a:A) (l m:list A), In a m -> incl l m -> incl (a :: l) m.
 
1623
  Proof. 
 
1624
    unfold incl in |- *; simpl in |- *; intros a l m H H0 a0 H1.
 
1625
    now_show (In a0 m).
 
1626
    elim H1.
 
1627
    now_show (a = a0 -> In a0 m).
 
1628
    elim H1; auto; intro H2.
 
1629
    now_show (a = a0 -> In a0 m).
 
1630
    elim H2; auto. (* solves subgoal *)
 
1631
    now_show (In a0 l -> In a0 m).
 
1632
    auto.
 
1633
  Qed.
 
1634
  Hint Resolve incl_cons.
 
1635
  
 
1636
  Lemma incl_app : forall l m n:list A, incl l n -> incl m n -> incl (l ++ m) n.
 
1637
  Proof. 
 
1638
    unfold incl in |- *; simpl in |- *; intros l m n H H0 a H1.
 
1639
    now_show (In a n).
 
1640
    elim (in_app_or _ _ _ H1); auto.
 
1641
  Qed.
 
1642
  Hint Resolve incl_app.
 
1643
  
 
1644
End SetIncl.
 
1645
 
 
1646
Hint Resolve incl_refl incl_tl incl_tran incl_appl incl_appr incl_cons
 
1647
  incl_app: datatypes v62.
 
1648
 
 
1649
 
 
1650
(**************************************)
 
1651
(** * Cutting a list at some position *)
 
1652
(**************************************)
 
1653
 
 
1654
Section Cutting.
 
1655
 
 
1656
  Variable A : Type.
 
1657
 
 
1658
  Fixpoint firstn (n:nat)(l:list A) {struct n} : list A := 
 
1659
    match n with 
 
1660
      | 0 => nil 
 
1661
      | S n => match l with  
 
1662
                 | nil => nil 
 
1663
                 | a::l => a::(firstn n l)
 
1664
               end
 
1665
    end.
 
1666
  
 
1667
  Fixpoint skipn (n:nat)(l:list A) { struct n } : list A := 
 
1668
    match n with 
 
1669
      | 0 => l 
 
1670
      | S n => match l with 
 
1671
                 | nil => nil 
 
1672
                 | a::l => skipn n l
 
1673
               end
 
1674
    end.
 
1675
  
 
1676
  Lemma firstn_skipn : forall n l, firstn n l ++ skipn n l = l.
 
1677
  Proof.
 
1678
    induction n.
 
1679
    simpl; auto.
 
1680
    destruct l; simpl; auto.
 
1681
    f_equal; auto.
 
1682
  Qed.
 
1683
 
 
1684
  Lemma firstn_length : forall n l, length (firstn n l) = min n (length l).
 
1685
  Proof.
 
1686
    induction n; destruct l; simpl; auto.
 
1687
  Qed.
 
1688
 
 
1689
   Lemma removelast_firstn : forall n l, n < length l -> 
 
1690
     removelast (firstn (S n) l) = firstn n l.
 
1691
   Proof.
 
1692
     induction n; destruct l.
 
1693
     simpl; auto.
 
1694
     simpl; auto.
 
1695
     simpl; auto.
 
1696
     intros.
 
1697
     simpl in H.
 
1698
     change (firstn (S (S n)) (a::l)) with ((a::nil)++firstn (S n) l).
 
1699
     change (firstn (S n) (a::l)) with (a::firstn n l).
 
1700
     rewrite removelast_app.
 
1701
     rewrite IHn; auto with arith.
 
1702
     
 
1703
     clear IHn; destruct l; simpl in *; try discriminate.
 
1704
     inversion_clear H.
 
1705
     inversion_clear H0.
 
1706
   Qed.
 
1707
 
 
1708
   Lemma firstn_removelast : forall n l, n < length l -> 
 
1709
     firstn n (removelast l) = firstn n l.
 
1710
   Proof.
 
1711
     induction n; destruct l.
 
1712
     simpl; auto.
 
1713
     simpl; auto.
 
1714
     simpl; auto.
 
1715
     intros.
 
1716
     simpl in H.
 
1717
     change (removelast (a :: l)) with (removelast ((a::nil)++l)).
 
1718
     rewrite removelast_app.
 
1719
     simpl; f_equal; auto with arith.
 
1720
     intro H0; rewrite H0 in H; inversion_clear H; inversion_clear H1.
 
1721
   Qed.
 
1722
 
 
1723
End Cutting.
 
1724
 
 
1725
 
 
1726
(********************************)
 
1727
(** ** Lists without redundancy *)
 
1728
(********************************)
 
1729
 
 
1730
Section ReDun.
 
1731
 
 
1732
  Variable A : Type.
 
1733
  
 
1734
  Inductive NoDup : list A -> Prop := 
 
1735
    | NoDup_nil : NoDup nil 
 
1736
    | NoDup_cons : forall x l, ~ In x l -> NoDup l -> NoDup (x::l). 
 
1737
 
 
1738
  Lemma NoDup_remove_1 : forall l l' a, NoDup (l++a::l') -> NoDup (l++l').
 
1739
  Proof.
 
1740
  induction l; simpl.
 
1741
  inversion_clear 1; auto.
 
1742
  inversion_clear 1.
 
1743
  constructor.
 
1744
  contradict H0.
 
1745
  apply in_or_app; destruct (in_app_or _ _ _ H0); simpl; tauto.
 
1746
  apply IHl with a0; auto.
 
1747
  Qed.
 
1748
 
 
1749
  Lemma NoDup_remove_2 : forall l l' a, NoDup (l++a::l') -> ~In a (l++l').
 
1750
  Proof.
 
1751
  induction l; simpl.
 
1752
  inversion_clear 1; auto.
 
1753
  inversion_clear 1.
 
1754
  contradict H0.
 
1755
  destruct H0.
 
1756
  subst a0.
 
1757
  apply in_or_app; right; red; auto.
 
1758
  destruct (IHl _ _ H1); auto.
 
1759
  Qed.
 
1760
 
 
1761
  Lemma NoDup_Permutation : forall l l', 
 
1762
    NoDup l -> NoDup l' -> (forall x, In x l <-> In x l') -> Permutation l l'.
 
1763
  Proof.
 
1764
  induction l. 
 
1765
  destruct l'; simpl; intros.
 
1766
  apply perm_nil.
 
1767
  destruct (H1 a) as (_,H2); destruct H2; auto.
 
1768
  intros.
 
1769
  destruct (In_split a l') as (l'1,(l'2,H2)).
 
1770
  destruct (H1 a) as (H2,H3); simpl in *; auto.
 
1771
  subst l'.
 
1772
  apply Permutation_cons_app.
 
1773
  inversion_clear H.
 
1774
  apply IHl; auto.
 
1775
  apply NoDup_remove_1 with a; auto.
 
1776
  intro x; split; intros.
 
1777
  assert (In x (l'1++a::l'2)).
 
1778
   destruct (H1 x); simpl in *; auto.
 
1779
  apply in_or_app; destruct (in_app_or _ _ _ H4); auto.
 
1780
  destruct H5; auto.
 
1781
  subst x; destruct H2; auto.
 
1782
  assert (In x (l'1++a::l'2)).
 
1783
    apply in_or_app; destruct (in_app_or _ _ _ H); simpl; auto.
 
1784
  destruct (H1 x) as (_,H5); destruct H5; auto. 
 
1785
  subst x.
 
1786
  destruct (NoDup_remove_2 _ _ _ H0 H).
 
1787
  Qed.
 
1788
 
 
1789
End ReDun.
 
1790
 
 
1791
 
 
1792
(***********************************)
 
1793
(** ** Sequence of natural numbers *)
 
1794
(***********************************)
 
1795
 
 
1796
Section NatSeq.
 
1797
 
 
1798
  (** [seq] computes the sequence of [len] contiguous integers 
 
1799
      that starts at [start]. For instance, [seq 2 3] is [2::3::4::nil]. *)
 
1800
  
 
1801
  Fixpoint seq (start len:nat) {struct len} : list nat := 
 
1802
    match len with 
 
1803
      | 0 => nil
 
1804
      | S len => start :: seq (S start) len
 
1805
    end. 
 
1806
  
 
1807
  Lemma seq_length : forall len start, length (seq start len) = len.
 
1808
  Proof.
 
1809
    induction len; simpl; auto.
 
1810
  Qed.
 
1811
  
 
1812
  Lemma seq_nth : forall len start n d, 
 
1813
    n < len -> nth n (seq start len) d = start+n.
 
1814
  Proof.
 
1815
    induction len; intros.
 
1816
    inversion H.
 
1817
    simpl seq.
 
1818
    destruct n; simpl.
 
1819
    auto with arith.
 
1820
    rewrite IHlen;simpl; auto with arith.
 
1821
  Qed.
 
1822
 
 
1823
  Lemma seq_shift : forall len start,
 
1824
    map S (seq start len) = seq (S start) len.
 
1825
  Proof. 
 
1826
    induction len; simpl; auto.
 
1827
    intros.
 
1828
    rewrite IHlen.
 
1829
    auto with arith.
 
1830
  Qed.
 
1831
 
 
1832
End NatSeq.
 
1833
 
 
1834
 
 
1835
 
 
1836
  (** * Exporting hints and tactics *)
 
1837
 
 
1838
 
 
1839
Hint Rewrite 
 
1840
  rev_involutive (* rev (rev l) = l *)
 
1841
  rev_unit (* rev (l ++ a :: nil) = a :: rev l *)
 
1842
  map_nth (* nth n (map f l) (f d) = f (nth n l d) *)
 
1843
  map_length (* length (map f l) = length l *)
 
1844
  seq_length (* length (seq start len) = len *)
 
1845
  app_length (* length (l ++ l') = length l + length l' *)
 
1846
  rev_length (* length (rev l) = length l *)
 
1847
  : list.
 
1848
 
 
1849
Hint Rewrite <- 
 
1850
  app_nil_end (* l = l ++ nil *)
 
1851
  : list.
 
1852
 
 
1853
Ltac simpl_list := autorewrite with list.
 
1854
Ltac ssimpl_list := autorewrite with list using simpl.