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
(***********************************************************************)
9
(* Finite sets library.
10
* Authors: Pierre Letouzey and Jean-Christophe Filliâtre
11
* Institution: LRI, CNRS UMR 8623 - Université Paris Sud
12
* 91405 Orsay, France *)
14
(* $Id: FMapPositive.v 11699 2008-12-18 11:49:08Z letouzey $ *)
17
Require Import ZArith.
18
Require Import OrderedType.
19
Require Import OrderedTypeEx.
20
Require Import FMapInterface.
22
Set Implicit Arguments.
24
Open Local Scope positive_scope.
26
(** * An implementation of [FMapInterface.S] for positive keys. *)
28
(** This file is an adaptation to the [FMap] framework of a work by
29
Xavier Leroy and Sandrine Blazy (used for building certified compilers).
30
Keys are of type [positive], and maps are binary trees: the sequence
31
of binary digits of a positive number corresponds to a path in such a tree.
32
This is quite similar to the [IntMap] library, except that no path compression
33
is implemented, and that the current file is simple enough to be
36
(** Even if [positive] can be seen as an ordered type with respect to the
37
usual order (see [OrderedTypeEx]), we use here a lexicographic order
38
over bits, which is more natural here (lower bits are considered first). *)
40
Module PositiveOrderedTypeBits <: UsualOrderedType.
41
Definition t:=positive.
42
Definition eq:=@eq positive.
43
Definition eq_refl := @refl_equal t.
44
Definition eq_sym := @sym_eq t.
45
Definition eq_trans := @trans_eq t.
47
Fixpoint bits_lt (p q:positive) { struct p } : Prop :=
51
| xO p, xO q => bits_lt p q
53
| xI p, xI q => bits_lt p q
57
Definition lt:=bits_lt.
59
Lemma bits_lt_trans : forall x y z : positive, bits_lt x y -> bits_lt y z -> bits_lt x z.
62
induction y; destruct z; simpl; eauto; intuition.
63
induction y; destruct z; simpl; eauto; intuition.
64
induction y; destruct z; simpl; eauto; intuition.
67
Lemma lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z.
72
Lemma bits_lt_antirefl : forall x : positive, ~ bits_lt x x.
74
induction x; simpl; auto.
77
Lemma lt_not_eq : forall x y : t, lt x y -> ~ eq x y.
80
rewrite <- H0 in H; clear H0 y.
82
exact (bits_lt_antirefl x H).
85
Definition compare : forall x y : t, Compare lt eq x y.
87
induction x; destruct y.
91
apply EQ; rewrite e; red; auto.
94
apply GT; simpl; auto.
96
apply GT; simpl; auto.
98
apply LT; simpl; auto.
102
apply EQ; rewrite e; red; auto.
105
apply LT; simpl; auto.
107
apply LT; simpl; auto.
109
apply GT; simpl; auto.
114
Lemma eq_dec (x y: positive): {x = y} + {x <> y}.
116
intros. case_eq ((x ?= y) Eq); intros.
117
left. apply Pcompare_Eq_eq; auto.
118
right. red. intro. subst y. rewrite (Pcompare_refl x) in H. discriminate.
119
right. red. intro. subst y. rewrite (Pcompare_refl x) in H. discriminate.
122
End PositiveOrderedTypeBits.
124
(** Other positive stuff *)
126
Fixpoint append (i j : positive) {struct i} : positive :=
129
| xI ii => xI (append ii j)
130
| xO ii => xO (append ii j)
133
Lemma append_assoc_0 :
134
forall (i j : positive), append i (xO j) = append (append i (xO xH)) j.
136
induction i; intros; destruct j; simpl;
137
try rewrite (IHi (xI j));
138
try rewrite (IHi (xO j));
139
try rewrite <- (IHi xH);
143
Lemma append_assoc_1 :
144
forall (i j : positive), append i (xI j) = append (append i (xI xH)) j.
146
induction i; intros; destruct j; simpl;
147
try rewrite (IHi (xI j));
148
try rewrite (IHi (xO j));
149
try rewrite <- (IHi xH);
153
Lemma append_neutral_r : forall (i : positive), append i xH = i.
155
induction i; simpl; congruence.
158
Lemma append_neutral_l : forall (i : positive), append xH i = i.
164
(** The module of maps over positive keys *)
166
Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits.
168
Module E:=PositiveOrderedTypeBits.
169
Module ME:=KeyOrderedType E.
171
Definition key := positive.
173
Inductive tree (A : Type) :=
175
| Node : tree A -> option A -> tree A -> tree A.
177
Definition t := tree.
182
Implicit Arguments Leaf [A].
184
Definition empty : t A := Leaf.
186
Fixpoint is_empty (m : t A) {struct m} : bool :=
189
| Node l None r => (is_empty l) && (is_empty r)
193
Fixpoint find (i : positive) (m : t A) {struct i} : option A :=
204
Fixpoint mem (i : positive) (m : t A) {struct i} : bool :=
209
| xH => match o with None => false | _ => true end
215
Fixpoint add (i : positive) (v : A) (m : t A) {struct i} : t A :=
219
| xH => Node Leaf (Some v) Leaf
220
| xO ii => Node (add ii v Leaf) None Leaf
221
| xI ii => Node Leaf None (add ii v Leaf)
225
| xH => Node l (Some v) r
226
| xO ii => Node (add ii v l) o r
227
| xI ii => Node l o (add ii v r)
231
Fixpoint remove (i : positive) (m : t A) {struct i} : t A :=
236
| Node Leaf o Leaf => Leaf
237
| Node l o r => Node l None r
242
| Node l None Leaf =>
243
match remove ii l with
245
| mm => Node mm None Leaf
247
| Node l o r => Node (remove ii l) o r
252
| Node Leaf None r =>
253
match remove ii r with
255
| mm => Node Leaf None mm
257
| Node l o r => Node l o (remove ii r)
263
Fixpoint xelements (m : t A) (i : positive) {struct m}
264
: list (positive * A) :=
268
(xelements l (append i (xO xH))) ++ (xelements r (append i (xI xH)))
269
| Node l (Some x) r =>
270
(xelements l (append i (xO xH)))
271
++ ((i, x) :: xelements r (append i (xI xH)))
274
(* Note: function [xelements] above is inefficient. We should apply
275
deforestation to it, but that makes the proofs even harder. *)
277
Definition elements (m : t A) := xelements m xH.
281
Fixpoint cardinal (m : t A) : nat :=
284
| Node l None r => (cardinal l + cardinal r)%nat
285
| Node l (Some _) r => S (cardinal l + cardinal r)
288
Section CompcertSpec.
291
forall (i: positive), find i empty = None.
293
destruct i; simpl; auto.
297
forall (i: positive) (x: A) (m: t A), find i (add i x m) = Some x.
299
induction i; destruct m; simpl; auto.
302
Lemma gleaf : forall (i : positive), find i (Leaf : t A) = None.
303
Proof. exact gempty. Qed.
306
forall (i j: positive) (x: A) (m: t A),
307
i <> j -> find i (add j x m) = find i m.
309
induction i; intros; destruct j; destruct m; simpl;
310
try rewrite <- (gleaf i); auto; try apply IHi; congruence.
313
Lemma rleaf : forall (i : positive), remove i (Leaf : t A) = Leaf.
314
Proof. destruct i; simpl; auto. Qed.
317
forall (i: positive) (m: t A), find i (remove i m) = None.
319
induction i; destruct m.
321
destruct m1; destruct o; destruct m2 as [ | ll oo rr]; simpl; auto.
322
rewrite (rleaf i); auto.
323
cut (find i (remove i (Node ll oo rr)) = None).
324
destruct (remove i (Node ll oo rr)); auto; apply IHi.
327
destruct m1 as [ | ll oo rr]; destruct o; destruct m2; simpl; auto.
328
rewrite (rleaf i); auto.
329
cut (find i (remove i (Node ll oo rr)) = None).
330
destruct (remove i (Node ll oo rr)); auto; apply IHi.
333
destruct m1; destruct m2; simpl; auto.
337
forall (i j: positive) (m: t A),
338
i <> j -> find i (remove j m) = find i m.
340
induction i; intros; destruct j; destruct m;
341
try rewrite (rleaf (xI j));
342
try rewrite (rleaf (xO j));
343
try rewrite (rleaf 1); auto;
344
destruct m1; destruct o; destruct m2;
346
try apply IHi; try congruence;
347
try rewrite (rleaf j); auto;
348
try rewrite (gleaf i); auto.
349
cut (find i (remove j (Node m2_1 o m2_2)) = find i (Node m2_1 o m2_2));
350
[ destruct (remove j (Node m2_1 o m2_2)); try rewrite (gleaf i); auto
351
| apply IHi; congruence ].
352
destruct (remove j (Node m1_1 o0 m1_2)); simpl; try rewrite (gleaf i);
354
destruct (remove j (Node m2_1 o m2_2)); simpl; try rewrite (gleaf i);
356
cut (find i (remove j (Node m1_1 o0 m1_2)) = find i (Node m1_1 o0 m1_2));
357
[ destruct (remove j (Node m1_1 o0 m1_2)); try rewrite (gleaf i); auto
358
| apply IHi; congruence ].
359
destruct (remove j (Node m2_1 o m2_2)); simpl; try rewrite (gleaf i);
361
destruct (remove j (Node m1_1 o0 m1_2)); simpl; try rewrite (gleaf i);
365
Lemma xelements_correct:
366
forall (m: t A) (i j : positive) (v: A),
367
find i m = Some v -> List.In (append j i, v) (xelements m j).
370
rewrite (gleaf i) in H; congruence.
371
destruct o; destruct i; simpl; simpl in H.
372
rewrite append_assoc_1; apply in_or_app; right; apply in_cons;
374
rewrite append_assoc_0; apply in_or_app; left; apply IHm1; auto.
375
rewrite append_neutral_r; apply in_or_app; injection H;
376
intro EQ; rewrite EQ; right; apply in_eq.
377
rewrite append_assoc_1; apply in_or_app; right; apply IHm2; auto.
378
rewrite append_assoc_0; apply in_or_app; left; apply IHm1; auto.
382
Theorem elements_correct:
383
forall (m: t A) (i: positive) (v: A),
384
find i m = Some v -> List.In (i, v) (elements m).
387
exact (xelements_correct m i xH H).
390
Fixpoint xfind (i j : positive) (m : t A) {struct j} : option A :=
393
| xO ii, xO jj => xfind ii jj m
394
| xI ii, xI jj => xfind ii jj m
399
forall (j i : positive) (m1 m2 : t A) (o : option A) (v : A),
400
xfind i (append j (xO xH)) m1 = Some v -> xfind i j (Node m1 o m2) = Some v.
402
induction j; intros; destruct i; simpl; simpl in H; auto; try congruence.
403
destruct i; congruence.
407
forall (m: t A) (i j : positive) (v: A),
408
List.In (xI i, v) (xelements m (xI j)) -> List.In (i, v) (xelements m j).
412
intros; destruct o; simpl; simpl in H; destruct (in_app_or _ _ _ H);
414
left; apply IHm1; auto.
415
right; destruct (in_inv H0).
416
injection H1; intros Eq1 Eq2; rewrite Eq1; rewrite Eq2; apply in_eq.
417
apply in_cons; apply IHm2; auto.
418
left; apply IHm1; auto.
419
right; apply IHm2; auto.
423
forall (m: t A) (i j : positive) (v: A),
424
~List.In (xI i, v) (xelements m (xO j)).
428
intros; destruct o; simpl; intro H; destruct (in_app_or _ _ _ H).
429
apply (IHm1 _ _ _ H0).
430
destruct (in_inv H0).
432
apply (IHm2 _ _ _ H1).
433
apply (IHm1 _ _ _ H0).
434
apply (IHm2 _ _ _ H0).
438
forall (m: t A) (i j : positive) (v: A),
439
List.In (xO i, v) (xelements m (xO j)) -> List.In (i, v) (xelements m j).
443
intros; destruct o; simpl; simpl in H; destruct (in_app_or _ _ _ H);
445
left; apply IHm1; auto.
446
right; destruct (in_inv H0).
447
injection H1; intros Eq1 Eq2; rewrite Eq1; rewrite Eq2; apply in_eq.
448
apply in_cons; apply IHm2; auto.
449
left; apply IHm1; auto.
450
right; apply IHm2; auto.
454
forall (m: t A) (i j : positive) (v: A),
455
~List.In (xO i, v) (xelements m (xI j)).
459
intros; destruct o; simpl; intro H; destruct (in_app_or _ _ _ H).
460
apply (IHm1 _ _ _ H0).
461
destruct (in_inv H0).
463
apply (IHm2 _ _ _ H1).
464
apply (IHm1 _ _ _ H0).
465
apply (IHm2 _ _ _ H0).
469
forall (m1 m2: t A) (o: option A) (i : positive) (v: A),
470
List.In (xI i, v) (xelements (Node m1 o m2) xH) -> List.In (i, v) (xelements m2 xH).
472
destruct o; simpl; intros; destruct (in_app_or _ _ _ H).
473
absurd (List.In (xI i, v) (xelements m1 2)); auto; apply xelements_io; auto.
474
destruct (in_inv H0).
476
apply xelements_ii; auto.
477
absurd (List.In (xI i, v) (xelements m1 2)); auto; apply xelements_io; auto.
478
apply xelements_ii; auto.
482
forall (m1 m2: t A) (o: option A) (i : positive) (v: A),
483
List.In (xO i, v) (xelements (Node m1 o m2) xH) -> List.In (i, v) (xelements m1 xH).
485
destruct o; simpl; intros; destruct (in_app_or _ _ _ H).
486
apply xelements_oo; auto.
487
destruct (in_inv H0).
489
absurd (List.In (xO i, v) (xelements m2 3)); auto; apply xelements_oi; auto.
490
apply xelements_oo; auto.
491
absurd (List.In (xO i, v) (xelements m2 3)); auto; apply xelements_oi; auto.
495
forall (m: t A) (i : positive) (v: A),
496
~List.In (xH, v) (xelements m (xI i)).
500
destruct o; simpl; intro H; destruct (in_app_or _ _ _ H).
501
generalize H0; apply IHm1; auto.
502
destruct (in_inv H0).
504
generalize H1; apply IHm2; auto.
505
generalize H0; apply IHm1; auto.
506
generalize H0; apply IHm2; auto.
510
forall (m: t A) (i : positive) (v: A),
511
~List.In (xH, v) (xelements m (xO i)).
515
destruct o; simpl; intro H; destruct (in_app_or _ _ _ H).
516
generalize H0; apply IHm1; auto.
517
destruct (in_inv H0).
519
generalize H1; apply IHm2; auto.
520
generalize H0; apply IHm1; auto.
521
generalize H0; apply IHm2; auto.
525
forall (m: t A) (i: positive), find i m = xfind i xH m.
527
destruct i; simpl; auto.
530
Lemma xelements_complete:
531
forall (i j : positive) (m: t A) (v: A),
532
List.In (i, v) (xelements m j) -> xfind i j m = Some v.
534
induction i; simpl; intros; destruct j; simpl.
535
apply IHi; apply xelements_ii; auto.
536
absurd (List.In (xI i, v) (xelements m (xO j))); auto; apply xelements_io.
539
rewrite find_xfind_h. apply IHi. apply (xelements_ih _ _ _ _ _ H).
540
absurd (List.In (xO i, v) (xelements m (xI j))); auto; apply xelements_oi.
541
apply IHi; apply xelements_oo; auto.
544
rewrite find_xfind_h. apply IHi. apply (xelements_oh _ _ _ _ _ H).
545
absurd (List.In (xH, v) (xelements m (xI j))); auto; apply xelements_hi.
546
absurd (List.In (xH, v) (xelements m (xO j))); auto; apply xelements_ho.
549
destruct o; simpl in H; destruct (in_app_or _ _ _ H).
550
absurd (List.In (xH, v) (xelements m1 (xO xH))); auto; apply xelements_ho.
551
destruct (in_inv H0).
553
absurd (List.In (xH, v) (xelements m2 (xI xH))); auto; apply xelements_hi.
554
absurd (List.In (xH, v) (xelements m1 (xO xH))); auto; apply xelements_ho.
555
absurd (List.In (xH, v) (xelements m2 (xI xH))); auto; apply xelements_hi.
558
Theorem elements_complete:
559
forall (m: t A) (i: positive) (v: A),
560
List.In (i, v) (elements m) -> find i m = Some v.
563
unfold elements in H.
564
rewrite find_xfind_h.
565
exact (xelements_complete i xH m v H).
569
forall (m: t A), cardinal m = length (elements m).
572
intros m; set (p:=1); clearbody p; revert m p.
573
induction m; simpl; auto; intros.
574
rewrite (IHm1 (append p 2)), (IHm2 (append p 3)); auto.
575
destruct o; rewrite app_length; simpl; omega.
580
Definition MapsTo (i:positive)(v:A)(m:t A) := find i m = Some v.
582
Definition In (i:positive)(m:t A) := exists e:A, MapsTo i e m.
584
Definition Empty m := forall (a : positive)(e:A) , ~ MapsTo a e m.
586
Definition eq_key (p p':positive*A) := E.eq (fst p) (fst p').
588
Definition eq_key_elt (p p':positive*A) :=
589
E.eq (fst p) (fst p') /\ (snd p) = (snd p').
591
Definition lt_key (p p':positive*A) := E.lt (fst p) (fst p').
594
forall m x, mem x m = match find x m with None => false | _ => true end.
596
induction m; destruct x; simpl; auto.
599
Lemma Empty_alt : forall m, Empty m <-> forall a, find a m = None.
601
unfold Empty, MapsTo.
604
destruct (find a m); intuition.
606
rewrite H in H0; discriminate.
609
Lemma Empty_Node : forall l o r, Empty (Node l o r) <-> o=None /\ Empty l /\ Empty r.
616
generalize (H 1); simpl; auto.
617
split; rewrite Empty_alt; intros.
618
generalize (H (xO a)); auto.
619
generalize (H (xI a)); auto.
622
rewrite Empty_alt; intros.
624
simpl; generalize H1; rewrite Empty_alt; auto.
625
simpl; generalize H0; rewrite Empty_alt; auto.
630
Lemma mem_1 : forall m x, In x m -> mem x m = true.
632
unfold In, MapsTo; intros m x; rewrite mem_find.
633
destruct 1 as (e0,H0); rewrite H0; auto.
636
Lemma mem_2 : forall m x, mem x m = true -> In x m.
638
unfold In, MapsTo; intros m x; rewrite mem_find.
641
intros; discriminate.
644
Variable m m' m'' : t A.
645
Variable x y z : key.
648
Lemma MapsTo_1 : E.eq x y -> MapsTo x e m -> MapsTo y e m.
649
Proof. intros; rewrite <- H; auto. Qed.
651
Lemma find_1 : MapsTo x e m -> find x m = Some e.
652
Proof. unfold MapsTo; auto. Qed.
654
Lemma find_2 : find x m = Some e -> MapsTo x e m.
655
Proof. red; auto. Qed.
657
Lemma empty_1 : Empty empty.
659
rewrite Empty_alt; apply gempty.
662
Lemma is_empty_1 : Empty m -> is_empty m = true.
664
induction m; simpl; auto.
668
rewrite IHt0_1; simpl; auto.
671
Lemma is_empty_2 : is_empty m = true -> Empty m.
673
induction m; simpl; auto.
675
intros _; exact gempty.
678
intros; discriminate.
679
intro H; destruct (andb_prop _ _ H); intuition.
682
Lemma add_1 : E.eq x y -> MapsTo y e (add x e m).
685
intro H; rewrite H; clear H.
689
Lemma add_2 : ~ E.eq x y -> MapsTo y e m -> MapsTo y e (add x e' m).
692
intros; rewrite gso; auto.
695
Lemma add_3 : ~ E.eq x y -> MapsTo y e (add x e' m) -> MapsTo y e m.
698
intro H; rewrite gso; auto.
701
Lemma remove_1 : E.eq x y -> ~ In y (remove x m).
704
generalize (mem_1 H0).
708
intros; discriminate.
711
Lemma remove_2 : ~ E.eq x y -> MapsTo y e m -> MapsTo y e (remove x m).
714
intro H; rewrite gro; auto.
717
Lemma remove_3 : MapsTo y e (remove x m) -> MapsTo y e m.
720
destruct (E.eq_dec x y).
722
rewrite grs; intros; discriminate.
727
MapsTo x e m -> InA eq_key_elt (x,e) (elements m).
734
red; simpl; unfold E.eq; auto.
735
apply elements_correct; auto.
739
InA eq_key_elt (x,e) (elements m) -> MapsTo x e m.
743
intros ((e0,a),(H,H0)).
744
red in H; simpl in H; unfold E.eq in H; destruct H; subst.
745
apply elements_complete; auto.
748
Lemma xelements_bits_lt_1 : forall p p0 q m v,
749
List.In (p0,v) (xelements m (append p (xO q))) -> E.bits_lt p0 p.
752
generalize (xelements_complete _ _ _ _ H); clear H; intros.
754
induction p; destruct p0; simpl; intros; eauto; try discriminate.
757
Lemma xelements_bits_lt_2 : forall p p0 q m v,
758
List.In (p0,v) (xelements m (append p (xI q))) -> E.bits_lt p p0.
761
generalize (xelements_complete _ _ _ _ H); clear H; intros.
763
induction p; destruct p0; simpl; intros; eauto; try discriminate.
766
Lemma xelements_sort : forall p, sort lt_key (xelements m p).
770
destruct o; simpl; intros.
772
apply (SortA_app (eqA:=eq_key_elt)); auto.
775
apply In_InfA; intros.
778
eapply xelements_bits_lt_2; eauto.
780
do 2 rewrite InA_alt.
781
intros (y1,(Hy1,H)) (y2,(Hy2,H0)).
782
destruct y1; destruct x0; compute in Hy1; destruct Hy1; subst.
783
destruct y2; destruct y0; compute in Hy2; destruct Hy2; subst.
786
injection H0; clear H0; intros _ H0; subst.
787
eapply xelements_bits_lt_1; eauto.
788
apply E.bits_lt_trans with p.
789
eapply xelements_bits_lt_1; eauto.
790
eapply xelements_bits_lt_2; eauto.
792
apply (SortA_app (eqA:=eq_key_elt)); auto.
795
do 2 rewrite InA_alt.
796
intros (y1,(Hy1,H)) (y2,(Hy2,H0)).
797
destruct y1; destruct x0; compute in Hy1; destruct Hy1; subst.
798
destruct y2; destruct y0; compute in Hy2; destruct Hy2; subst.
800
apply E.bits_lt_trans with p.
801
eapply xelements_bits_lt_1; eauto.
802
eapply xelements_bits_lt_2; eauto.
805
Lemma elements_3 : sort lt_key (elements m).
808
apply xelements_sort; auto.
811
Lemma elements_3w : NoDupA eq_key (elements m).
813
change eq_key with (@ME.eqk A).
814
apply ME.Sort_NoDupA; apply elements_3; auto.
819
(** [map] and [mapi] *)
825
Variable f : positive -> A -> B.
827
Fixpoint xmapi (m : t A) (i : positive) {struct m} : t B :=
830
| Node l o r => Node (xmapi l (append i (xO xH)))
832
(xmapi r (append i (xI xH)))
835
Definition mapi m := xmapi m xH.
839
Definition map (f : A -> B) m := mapi (fun _ => f) m.
844
forall (A B: Type) (f: positive -> A -> B) (i j : positive) (m: t A),
845
find i (xmapi f m j) = option_map (f (append j i)) (find i m).
847
induction i; intros; destruct m; simpl; auto.
848
rewrite (append_assoc_1 j i); apply IHi.
849
rewrite (append_assoc_0 j i); apply IHi.
850
rewrite (append_neutral_r j); auto.
854
forall (A B: Type) (f: positive -> A -> B) (i: positive) (m: t A),
855
find i (mapi f m) = option_map (f i) (find i m).
859
replace (f i) with (f (append xH i)).
861
rewrite append_neutral_l; auto.
865
forall (elt elt':Type)(m: t elt)(x:key)(e:elt)(f:key->elt->elt'),
867
exists y, E.eq y x /\ MapsTo x (f y e) (mapi f m).
873
generalize (find_1 H); clear H; intros.
880
forall (elt elt':Type)(m: t elt)(x:key)(f:key->elt->elt'),
881
In x (mapi f m) -> In x m.
887
generalize (find_1 H); clear H; intros.
889
destruct (find x m); auto.
890
simpl in *; discriminate.
893
Lemma map_1 : forall (elt elt':Type)(m: t elt)(x:key)(e:elt)(f:elt->elt'),
894
MapsTo x e m -> MapsTo x (f e) (map f m).
897
destruct (mapi_1 (fun _ => f) H); intuition.
900
Lemma map_2 : forall (elt elt':Type)(m: t elt)(x:key)(f:elt->elt'),
901
In x (map f m) -> In x m.
903
intros; unfold map in *; eapply mapi_2; eauto.
907
Variable A B C : Type.
908
Variable f : option A -> option B -> option C.
910
Implicit Arguments Leaf [A].
912
Fixpoint xmap2_l (m : t A) {struct m} : t C :=
915
| Node l o r => Node (xmap2_l l) (f o None) (xmap2_l r)
918
Lemma xgmap2_l : forall (i : positive) (m : t A),
919
f None None = None -> find i (xmap2_l m) = f (find i m) None.
921
induction i; intros; destruct m; simpl; auto.
924
Fixpoint xmap2_r (m : t B) {struct m} : t C :=
927
| Node l o r => Node (xmap2_r l) (f None o) (xmap2_r r)
930
Lemma xgmap2_r : forall (i : positive) (m : t B),
931
f None None = None -> find i (xmap2_r m) = f None (find i m).
933
induction i; intros; destruct m; simpl; auto.
936
Fixpoint _map2 (m1 : t A)(m2 : t B) {struct m1} : t C :=
942
| Node l2 o2 r2 => Node (_map2 l1 l2) (f o1 o2) (_map2 r1 r2)
946
Lemma gmap2: forall (i: positive)(m1:t A)(m2: t B),
947
f None None = None ->
948
find i (_map2 m1 m2) = f (find i m1) (find i m2).
950
induction i; intros; destruct m1; destruct m2; simpl; auto;
951
try apply xgmap2_r; try apply xgmap2_l; auto.
956
Definition map2 (elt elt' elt'':Type)(f:option elt->option elt'->option elt'') :=
957
_map2 (fun o1 o2 => match o1,o2 with None,None => None | _, _ => f o1 o2 end).
959
Lemma map2_1 : forall (elt elt' elt'':Type)(m: t elt)(m': t elt')
960
(x:key)(f:option elt->option elt'->option elt''),
962
find x (map2 f m m') = f (find x m) (find x m').
967
generalize (@mem_1 _ m x) (@mem_1 _ m' x).
968
do 2 rewrite mem_find.
969
destruct (find x m); simpl; auto.
970
destruct (find x m'); simpl; auto.
972
destruct H; intuition; try discriminate.
975
Lemma map2_2 : forall (elt elt' elt'':Type)(m: t elt)(m': t elt')
976
(x:key)(f:option elt->option elt'->option elt''),
977
In x (map2 f m m') -> In x m \/ In x m'.
980
generalize (mem_1 H); clear H; intros.
981
rewrite mem_find in H.
983
rewrite gmap2 in H; auto.
984
generalize (@mem_2 _ m x) (@mem_2 _ m' x).
985
do 2 rewrite mem_find.
986
destruct (find x m); simpl in *; auto.
987
destruct (find x m'); simpl in *; auto.
993
Variables A B : Type.
994
Variable f : positive -> A -> B -> B.
996
Fixpoint xfoldi (m : t A) (v : B) (i : positive) :=
999
| Node l (Some x) r =>
1000
xfoldi r (f i x (xfoldi l v (append i 2))) (append i 3)
1002
xfoldi r (xfoldi l v (append i 2)) (append i 3)
1007
xfoldi m v i = fold_left (fun a p => f (fst p) (snd p) a) (xelements m i) v.
1009
set (F := fun a p => f (fst p) (snd p) a).
1010
induction m; intros; simpl; auto.
1012
rewrite fold_left_app; simpl.
1015
unfold F; simpl; reflexivity.
1016
rewrite fold_left_app; simpl.
1022
Definition fold m i := xfoldi m i 1.
1027
forall (A:Type)(m:t A)(B:Type)(i : B) (f : key -> A -> B -> B),
1028
fold f m i = fold_left (fun a p => f (fst p) (snd p) a) (elements m) i.
1030
intros; unfold fold, elements.
1031
rewrite xfoldi_1; reflexivity.
1034
Fixpoint equal (A:Type)(cmp : A -> A -> bool)(m1 m2 : t A) {struct m1} : bool :=
1036
| Leaf, _ => is_empty m2
1037
| _, Leaf => is_empty m1
1038
| Node l1 o1 r1, Node l2 o2 r2 =>
1040
| None, None => true
1041
| Some v1, Some v2 => cmp v1 v2
1044
&& equal cmp l1 l2 && equal cmp r1 r2
1047
Definition Equal (A:Type)(m m':t A) :=
1048
forall y, find y m = find y m'.
1049
Definition Equiv (A:Type)(eq_elt:A->A->Prop) m m' :=
1050
(forall k, In k m <-> In k m') /\
1051
(forall k e e', MapsTo k e m -> MapsTo k e' m' -> eq_elt e e').
1052
Definition Equivb (A:Type)(cmp: A->A->bool) := Equiv (Cmp cmp).
1054
Lemma equal_1 : forall (A:Type)(m m':t A)(cmp:A->A->bool),
1055
Equivb cmp m m' -> equal cmp m m' = true.
1063
assert (In a (Leaf A)).
1066
destruct H2; red in H2.
1067
destruct a; simpl in *; discriminate.
1074
assert (In xH (Leaf A)).
1076
exists a; red; auto.
1077
destruct H1; red in H1; simpl in H1; discriminate.
1078
apply andb_true_intro; split; apply is_empty_1; red; red; intros.
1079
assert (In (xO a) (Leaf A)).
1082
destruct H2; red in H2; simpl in H2; discriminate.
1083
assert (In (xI a) (Leaf A)).
1086
destruct H2; red in H2; simpl in H2; discriminate.
1089
assert (Equivb cmp m1 m'1).
1091
intros k; generalize (H (xO k)); unfold In, MapsTo; simpl; auto.
1092
intros k e e'; generalize (H0 (xO k) e e'); unfold In, MapsTo; simpl; auto.
1093
assert (Equivb cmp m2 m'2).
1095
intros k; generalize (H (xI k)); unfold In, MapsTo; simpl; auto.
1096
intros k e e'; generalize (H0 (xI k) e e'); unfold In, MapsTo; simpl; auto.
1098
destruct o; destruct o0; simpl.
1099
repeat (apply andb_true_intro; split); auto.
1100
apply (H0 xH); red; auto.
1101
generalize (H xH); unfold In, MapsTo; simpl; intuition.
1102
destruct H4; try discriminate; eauto.
1103
generalize (H xH); unfold In, MapsTo; simpl; intuition.
1104
destruct H5; try discriminate; eauto.
1105
apply andb_true_intro; split; auto.
1108
Lemma equal_2 : forall (A:Type)(m m':t A)(cmp:A->A->bool),
1109
equal cmp m m' = true -> Equivb cmp m m'.
1116
destruct 1; red in H0; destruct k; discriminate.
1117
destruct 1; elim (is_empty_2 H H0).
1118
red in H0; destruct k; discriminate.
1123
destruct o; intros; try discriminate.
1124
destruct (andb_prop _ _ H); clear H.
1126
split; unfold In, MapsTo; destruct 1.
1127
destruct k; simpl in *; try discriminate.
1128
destruct (is_empty_2 H1 (find_2 _ _ H)).
1129
destruct (is_empty_2 H0 (find_2 _ _ H)).
1130
destruct k; simpl in *; discriminate.
1131
unfold In, MapsTo; destruct k; simpl in *; discriminate.
1133
destruct o; destruct o0; simpl; intros; try discriminate.
1134
destruct (andb_prop _ _ H); clear H.
1135
destruct (andb_prop _ _ H0); clear H0.
1136
destruct (IHm1 _ _ H2); clear H2 IHm1.
1137
destruct (IHm2 _ _ H1); clear H1 IHm2.
1139
destruct k; unfold In, MapsTo in *; simpl; auto.
1141
destruct k; unfold In, MapsTo in *; simpl in *.
1145
destruct (andb_prop _ _ H); clear H.
1146
destruct (IHm1 _ _ H0); clear H0 IHm1.
1147
destruct (IHm2 _ _ H1); clear H1 IHm2.
1149
destruct k; unfold In, MapsTo in *; simpl; auto.
1151
destruct k; unfold In, MapsTo in *; simpl in *.
1159
(** Here come some additionnal facts about this implementation.
1160
Most are facts that cannot be derivable from the general interface. *)
1163
Module PositiveMapAdditionalFacts.
1166
(* Derivable from the Map interface *)
1168
forall (A:Type)(i j: positive) (x: A) (m: t A),
1169
find i (add j x m) = if E.eq_dec i j then Some x else find i m.
1172
destruct (E.eq_dec i j); [ rewrite e; apply gss | apply gso; auto ].
1175
(* Not derivable from the Map interface *)
1177
forall (A:Type)(i: positive) (m: t A) (v: A),
1178
find i m = Some v -> add i v m = m.
1180
induction i; intros; destruct m; simpl; simpl in H; try congruence.
1181
rewrite (IHi m2 v H); congruence.
1182
rewrite (IHi m1 v H); congruence.
1186
forall (A B : Type)(f g: option A -> option A -> option B)(m : t A),
1187
(forall (i j : option A), f i j = g j i) ->
1188
xmap2_l f m = xmap2_r g m.
1190
induction m; intros; simpl; auto.
1196
Theorem map2_commut:
1197
forall (A B: Type) (f g: option A -> option A -> option B),
1198
(forall (i j: option A), f i j = g j i) ->
1199
forall (m1 m2: t A),
1200
_map2 f m1 m2 = _map2 g m2 m1.
1203
assert (Eq2: forall (i j: option A), g i j = f j i).
1205
induction m1; intros; destruct m2; simpl;
1207
repeat rewrite (xmap2_lr f g);
1208
repeat rewrite (xmap2_lr g f);
1215
End PositiveMapAdditionalFacts.