diff options
| author | Pierre Letouzey | 2015-03-06 22:23:27 +0100 |
|---|---|---|
| committer | Pierre Letouzey | 2015-04-02 11:44:18 +0200 |
| commit | c356a3b01a428504f66f027802b7b19f0761203e (patch) | |
| tree | ad8b3ec5bd732addee938d219151af6a8194e392 | |
| parent | 8581e1a977518c354eb06820d3513238412af7de (diff) | |
MMapPositive: some improvements
Most of them are backports of improvements already there in
FSetPositive when compared with the original FMapPositive file.
| -rw-r--r-- | theories/MMaps/MMapPositive.v | 653 |
1 files changed, 207 insertions, 446 deletions
diff --git a/theories/MMaps/MMapPositive.v b/theories/MMaps/MMapPositive.v index 2da1fff1e5..d3aab2389d 100644 --- a/theories/MMaps/MMapPositive.v +++ b/theories/MMaps/MMapPositive.v @@ -8,7 +8,7 @@ (** * MMapPositive : an implementation of MMapInterface for [positive] keys. *) -Require Import Bool BinPos Orders OrdersEx OrdersLists MMapInterface. +Require Import Bool PeanoNat BinPos Orders OrdersEx OrdersLists MMapInterface. Set Implicit Arguments. Local Open Scope lazy_bool_scope. @@ -23,44 +23,16 @@ Local Unset Elimination Schemes. compression is implemented, and that the current file is simple enough to be self-contained. *) -(** First, some stuff about [positive] *) +(** Reverses the positive [y] and concatenate it with [x] *) -Fixpoint append (i j : positive) : positive := - match i with - | xH => j - | xI ii => xI (append ii j) - | xO ii => xO (append ii j) - end. - -Lemma append_assoc_0 : - forall (i j : positive), append i (xO j) = append (append i (xO xH)) j. -Proof. - induction i; intros; destruct j; simpl; - try rewrite (IHi (xI j)); - try rewrite (IHi (xO j)); - try rewrite <- (IHi xH); - auto. -Qed. - -Lemma append_assoc_1 : - forall (i j : positive), append i (xI j) = append (append i (xI xH)) j. -Proof. - induction i; intros; destruct j; simpl; - try rewrite (IHi (xI j)); - try rewrite (IHi (xO j)); - try rewrite <- (IHi xH); - auto. -Qed. - -Lemma append_neutral_r : forall (i : positive), append i xH = i. -Proof. - induction i; simpl; congruence. -Qed. - -Lemma append_neutral_l : forall (i : positive), append xH i = i. -Proof. - simpl; auto. -Qed. +Fixpoint rev_append (y x : positive) : positive := + match y with + | 1 => x + | y~1 => rev_append y x~1 + | y~0 => rev_append y x~0 + end. +Local Infix "@" := rev_append (at level 60). +Definition rev x := x@1. (** The module of maps over positive keys *) @@ -71,6 +43,17 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. Definition key := positive : Type. + Definition eq_key {A} (p p':key*A) := E.eq (fst p) (fst p'). + + Definition eq_key_elt {A} (p p':key*A) := + E.eq (fst p) (fst p') /\ (snd p) = (snd p'). + + Definition lt_key {A} (p p':key*A) := E.lt (fst p) (fst p'). + + Instance eqk_equiv {A} : Equivalence (@eq_key A) := _. + Instance eqke_equiv {A} : Equivalence (@eq_key_elt A) := _. + Instance ltk_strorder {A} : StrictOrder (@lt_key A) := _. + Inductive tree (A : Type) := | Leaf : tree A | Node : tree A -> option A -> tree A -> tree A. @@ -152,20 +135,14 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. (** [bindings] *) - Fixpoint xbindings (m : t A) (i : key) : list (key * A) := + Fixpoint xbindings (m : t A) (i : positive) (a: list (key*A)) := match m with - | Leaf => nil - | Node l None r => - (xbindings l (append i (xO xH))) ++ (xbindings r (append i (xI xH))) - | Node l (Some x) r => - (xbindings l (append i (xO xH))) - ++ ((i, x) :: xbindings r (append i (xI xH))) + | Leaf => a + | Node l None r => xbindings l i~0 (xbindings r i~1 a) + | Node l (Some e) r => xbindings l i~0 ((rev i,e) :: xbindings r i~1 a) end. - (* Note: function [xbindings] above is inefficient. We should apply - deforestation to it, but that makes the proofs even harder. *) - - Definition bindings (m : t A) := xbindings m xH. + Definition bindings (m : t A) := xbindings m 1 nil. (** [cardinal] *) @@ -178,6 +155,33 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. (** Specification proofs *) + Definition MapsTo (i:key)(v:A)(m:t A) := find i m = Some v. + Definition In (i:key)(m:t A) := exists e:A, MapsTo i e m. + + Lemma MapsTo_compat : Proper (E.eq==>eq==>eq==>iff) MapsTo. + Proof. + intros k k' Hk e e' He m m' Hm. red in Hk. now subst. + Qed. + + Lemma find_spec m x e : find x m = Some e <-> MapsTo x e m. + Proof. reflexivity. Qed. + + Lemma mem_find : + forall m x, mem x m = match find x m with None => false | _ => true end. + Proof. + induction m; destruct x; simpl; auto. + Qed. + + Lemma mem_spec : forall m x, mem x m = true <-> In x m. + Proof. + unfold In, MapsTo; intros m x; rewrite mem_find. + split. + - destruct (find x m). + exists a; auto. + intros; discriminate. + - destruct 1 as (e0,H0); rewrite H0; auto. + Qed. + Lemma gleaf : forall (i : key), find i Leaf = None. Proof. destruct i; simpl; auto. Qed. @@ -185,6 +189,20 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. forall (i: key), find i empty = None. Proof. exact gleaf. Qed. + Lemma is_empty_spec m : + is_empty m = true <-> forall k, find k m = None. + Proof. + induction m; simpl. + - intuition. apply empty_spec. + - destruct o. split; try discriminate. + intros H. now specialize (H xH). + rewrite <- andb_lazy_alt, andb_true_iff, IHm1, IHm2. + clear IHm1 IHm2. + split. + + intros (H1,H2) k. destruct k; simpl; auto. + + intros H; split; intros k. apply (H (xO k)). apply (H (xI k)). + Qed. + Theorem add_spec1: forall (m: t A) (i: key) (x: A), find i (add i x m) = Some x. Proof. @@ -230,354 +248,114 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. try apply IHm1; try apply IHm2; congruence. Qed. - Lemma xbindings_correct: - forall (m: t A) (i j : key) (v: A), - find i m = Some v -> List.In (append j i, v) (xbindings m j). - Proof. - induction m; intros. - - rewrite (gleaf i) in H; discriminate. - - destruct o, i; simpl in *; apply in_or_app. - + rewrite append_assoc_1. right; now apply in_cons, IHm2. - + rewrite append_assoc_0. left; now apply IHm1. - + rewrite append_neutral_r. injection H as ->. - right; apply in_eq. - + rewrite append_assoc_1. right; now apply IHm2. - + rewrite append_assoc_0. left; now apply IHm1. - + discriminate. - Qed. - - Theorem bindings_correct: - forall (m: t A) (i: key) (v: A), - find i m = Some v -> List.In (i, v) (bindings m). - Proof. - intros m i v H. - exact (xbindings_correct m i xH H). - Qed. - - Fixpoint xfind (i j : key) (m : t A) : option A := - match i, j with - | _, xH => find i m - | xO ii, xO jj => xfind ii jj m - | xI ii, xI jj => xfind ii jj m - | _, _ => None - end. - - Lemma xfind_left : - forall (j i : key) (m1 m2 : t A) (o : option A) (v : A), - xfind i (append j (xO xH)) m1 = Some v -> - xfind i j (Node m1 o m2) = Some v. - Proof. - induction j; intros; destruct i; simpl; simpl in H; auto; try congruence. - destruct i; simpl in *; auto. - Qed. - - Lemma xbindings_ii : - forall (m: t A) (i j : key) (v: A), - List.In (xI i, v) (xbindings m (xI j)) -> - List.In (i, v) (xbindings m j). - Proof. - induction m. - - simpl; auto. - - intros; destruct o; simpl in *; rewrite in_app_iff in *; - destruct H. - + left; now apply IHm1. - + right; destruct (in_inv H). - * injection H0 as -> ->. apply in_eq. - * apply in_cons; now apply IHm2. - + left; now apply IHm1. - + right; now apply IHm2. - Qed. - - Lemma xbindings_io : - forall (m: t A) (i j : key) (v: A), - ~List.In (xI i, v) (xbindings m (xO j)). - Proof. - induction m. - - simpl; auto. - - intros; destruct o; simpl; intro H; destruct (in_app_or _ _ _ H). - + apply (IHm1 _ _ _ H0). - + destruct (in_inv H0). congruence. apply (IHm2 _ _ _ H1). - + apply (IHm1 _ _ _ H0). - + apply (IHm2 _ _ _ H0). - Qed. - - Lemma xbindings_oo : - forall (m: t A) (i j : key) (v: A), - List.In (xO i, v) (xbindings m (xO j)) -> - List.In (i, v) (xbindings m j). - Proof. - induction m. - - simpl; auto. - - intros; destruct o; simpl; simpl in H; destruct (in_app_or _ _ _ H); - apply in_or_app. - + left; now apply IHm1. - + right; destruct (in_inv H0). - injection H1 as -> ->; apply in_eq. - apply in_cons; now apply IHm2. - + left; now apply IHm1. - + right; now apply IHm2. - Qed. - - Lemma xbindings_oi : - forall (m: t A) (i j : key) (v: A), - ~List.In (xO i, v) (xbindings m (xI j)). - Proof. - induction m. - - simpl; auto. - - intros; destruct o; simpl; intro H; destruct (in_app_or _ _ _ H). - + apply (IHm1 _ _ _ H0). - + destruct (in_inv H0). congruence. apply (IHm2 _ _ _ H1). - + apply (IHm1 _ _ _ H0). - + apply (IHm2 _ _ _ H0). - Qed. - - Lemma xbindings_ih : - forall (m1 m2: t A) (o: option A) (i : key) (v: A), - List.In (xI i, v) (xbindings (Node m1 o m2) xH) -> - List.In (i, v) (xbindings m2 xH). - Proof. - destruct o; simpl; intros; destruct (in_app_or _ _ _ H). - absurd (List.In (xI i, v) (xbindings m1 2)); auto; apply xbindings_io; auto. - destruct (in_inv H0). - congruence. - apply xbindings_ii; auto. - absurd (List.In (xI i, v) (xbindings m1 2)); auto; apply xbindings_io; auto. - apply xbindings_ii; auto. - Qed. - - Lemma xbindings_oh : - forall (m1 m2: t A) (o: option A) (i : key) (v: A), - List.In (xO i, v) (xbindings (Node m1 o m2) xH) -> - List.In (i, v) (xbindings m1 xH). - Proof. - destruct o; simpl; intros; destruct (in_app_or _ _ _ H). - apply xbindings_oo; auto. - destruct (in_inv H0). - congruence. - absurd (List.In (xO i, v) (xbindings m2 3)); auto; apply xbindings_oi; auto. - apply xbindings_oo; auto. - absurd (List.In (xO i, v) (xbindings m2 3)); auto; apply xbindings_oi; auto. - Qed. - - Lemma xbindings_hi : - forall (m: t A) (i : key) (v: A), - ~List.In (xH, v) (xbindings m (xI i)). - Proof. - induction m; intros. - - simpl; auto. - - destruct o; simpl; intro H; destruct (in_app_or _ _ _ H). - + generalize H0; apply IHm1; auto. - + destruct (in_inv H0). congruence. - generalize H1; apply IHm2; auto. - + generalize H0; apply IHm1; auto. - + generalize H0; apply IHm2; auto. - Qed. - - Lemma xbindings_ho : - forall (m: t A) (i : key) (v: A), - ~List.In (xH, v) (xbindings m (xO i)). - Proof. - induction m; intros. - - simpl; auto. - - destruct o; simpl; intro H; destruct (in_app_or _ _ _ H). - + generalize H0; apply IHm1; auto. - + destruct (in_inv H0). congruence. - generalize H1; apply IHm2; auto. - + generalize H0; apply IHm1; auto. - + generalize H0; apply IHm2; auto. - Qed. - - Lemma find_xfind_h : - forall (m: t A) (i: key), find i m = xfind i xH m. - Proof. - destruct i; simpl; auto. - Qed. - - Lemma xbindings_complete: - forall (i j : key) (m: t A) (v: A), - List.In (i, v) (xbindings m j) -> xfind i j m = Some v. - Proof. - induction i; simpl; intros; destruct j; simpl. - apply IHi; apply xbindings_ii; auto. - absurd (List.In (xI i, v) (xbindings m (xO j))); auto; apply xbindings_io. - destruct m. - simpl in H; tauto. - rewrite find_xfind_h. apply IHi. apply (xbindings_ih _ _ _ _ _ H). - absurd (List.In (xO i, v) (xbindings m (xI j))); auto; apply xbindings_oi. - apply IHi; apply xbindings_oo; auto. - destruct m. - simpl in H; tauto. - rewrite find_xfind_h. apply IHi. apply (xbindings_oh _ _ _ _ _ H). - absurd (List.In (xH, v) (xbindings m (xI j))); auto; apply xbindings_hi. - absurd (List.In (xH, v) (xbindings m (xO j))); auto; apply xbindings_ho. - destruct m. - simpl in H; tauto. - destruct o; simpl in H; destruct (in_app_or _ _ _ H). - absurd (List.In (xH, v) (xbindings m1 (xO xH))); auto; apply xbindings_ho. - destruct (in_inv H0). - congruence. - absurd (List.In (xH, v) (xbindings m2 (xI xH))); auto; apply xbindings_hi. - absurd (List.In (xH, v) (xbindings m1 (xO xH))); auto; apply xbindings_ho. - absurd (List.In (xH, v) (xbindings m2 (xI xH))); auto; apply xbindings_hi. - Qed. - - Theorem bindings_complete: - forall (m: t A) (i: key) (v: A), - List.In (i, v) (bindings m) -> find i m = Some v. - Proof. - intros m i v H. - unfold bindings in H. - rewrite find_xfind_h. - exact (xbindings_complete i xH m v H). - Qed. - - Lemma cardinal_spec : - forall (m: t A), cardinal m = length (bindings m). - Proof. - unfold bindings. - intros m; set (p:=1); clearbody p; revert m p. - induction m; simpl; auto; intros. - rewrite (IHm1 (append p 2)), (IHm2 (append p 3)); auto. - destruct o; rewrite app_length; simpl; auto. - Qed. - - Definition MapsTo (i:key)(v:A)(m:t A) := find i m = Some v. - - Definition In (i:key)(m:t A) := exists e:A, MapsTo i e m. - - Definition eq_key (p p':key*A) := E.eq (fst p) (fst p'). - - Definition eq_key_elt (p p':key*A) := - E.eq (fst p) (fst p') /\ (snd p) = (snd p'). - - Definition lt_key (p p':key*A) := E.lt (fst p) (fst p'). - - Global Instance eqk_equiv : Equivalence eq_key := _. - Global Instance eqke_equiv : Equivalence eq_key_elt := _. - Global Instance ltk_strorder : StrictOrder lt_key := _. - - Lemma mem_find : - forall m x, mem x m = match find x m with None => false | _ => true end. - Proof. - induction m; destruct x; simpl; auto. - Qed. - - Lemma mem_spec : forall m x, mem x m = true <-> In x m. - Proof. - unfold In, MapsTo; intros m x; rewrite mem_find. - split. - - destruct (find x m). - exists a; auto. - intros; discriminate. - - destruct 1 as (e0,H0); rewrite H0; auto. - Qed. - - Variable m m' m'' : t A. - Variable x y z : key. - Variable e e' : A. - - Lemma MapsTo_compat : Proper (E.eq==>eq==>eq==>iff) MapsTo. - Proof. - intros k1 k2 Hk e1 e2 He m1 m2 Hm. red in Hk. now subst. - Qed. - - Lemma find_spec : find x m = Some e <-> MapsTo x e m. - Proof. reflexivity. Qed. - - Lemma is_empty_spec : is_empty m = true <-> forall k, find k m = None. - Proof. - induction m; simpl. - - intuition. apply empty_spec. - - destruct o. split; try discriminate. - intros H. now specialize (H xH). - rewrite <- andb_lazy_alt, andb_true_iff, IHt0_1, IHt0_2. - clear IHt0_1 IHt0_2. - split. - + intros (H1,H2) k. destruct k; simpl; auto. - + intros H; split; intros k. apply (H (xO k)). apply (H (xI k)). - Qed. - - Lemma bindings_spec1 : - InA eq_key_elt (x,e) (bindings m) <-> MapsTo x e m. - Proof. - unfold MapsTo. - rewrite InA_alt. - split. - - intros ((e0,a),(H,H0)). - red in H; simpl in H; unfold E.eq in H; destruct H; subst. - apply bindings_complete; auto. - - intro H. - exists (x,e). - split. - red; simpl; unfold E.eq; auto. - apply bindings_correct; auto. - Qed. - - Lemma xbindings_bits_lt_1 : forall p p0 q m v, - List.In (p0,v) (xbindings m (append p (xO q))) -> E.bits_lt p0 p. + Local Notation InL := (InA eq_key_elt). + + Lemma xbindings_spec: forall m j acc k e, + InL (k,e) (xbindings m j acc) <-> + InL (k,e) acc \/ exists x, k=(j@x) /\ find x m = Some e. + Proof. + induction m as [|l IHl o r IHr]; simpl. + - intros. split; intro H. + + now left. + + destruct H as [H|[x [_ H]]]. assumption. + now rewrite gleaf in H. + - intros j acc k e. case o as [e'|]; + rewrite IHl, ?InA_cons, IHr; clear IHl IHr; split. + + intros [[H|[H|H]]|H]; auto. + * unfold eq_key_elt, E.eq, fst, snd in H. destruct H as (->,<-). + right. now exists 1. + * destruct H as (x,(->,H)). right. now exists x~1. + * destruct H as (x,(->,H)). right. now exists x~0. + + intros [H|H]; auto. + destruct H as (x,(->,H)). + destruct x; simpl in *. + * left. right. right. now exists x. + * right. now exists x. + * left. left. injection H as ->. reflexivity. + + intros [[H|H]|H]; auto. + * destruct H as (x,(->,H)). right. now exists x~1. + * destruct H as (x,(->,H)). right. now exists x~0. + + intros [H|H]; auto. + destruct H as (x,(->,H)). + destruct x; simpl in *. + * left. right. now exists x. + * right. now exists x. + * discriminate. + Qed. + + Lemma lt_rev_append: forall j x y, E.lt x y -> E.lt (j@x) (j@y). + Proof. induction j; intros; simpl; auto. Qed. + + Lemma xbindings_sort m j acc : + sort lt_key acc -> + (forall x p, In x m -> InL p acc -> E.lt (j@x) (fst p)) -> + sort lt_key (xbindings m j acc). + Proof. + revert j acc. + induction m as [|l IHl o r IHr]; simpl; trivial. + intros j acc Hacc Hsacc. destruct o as [e|]. + - apply IHl;[constructor;[apply IHr; [apply Hacc|]|]|]. + + intros. now apply Hsacc. + + case_eq (xbindings r j~1 acc); [constructor|]. + intros (z,e') q H. constructor. + assert (H': InL (z,e') (xbindings r j~1 acc)). + { rewrite H. now constructor. } + clear H q. rewrite xbindings_spec in H'. + destruct H' as [H'|H']. + * apply (Hsacc 1 (z,e')); trivial. now exists e. + * destruct H' as (x,(->,H)). + red. simpl. now apply lt_rev_append. + + intros x (y,e') Hx Hy. inversion_clear Hy. + rewrite H. simpl. now apply lt_rev_append. + rewrite xbindings_spec in H. + destruct H as [H|H]. + * now apply Hsacc. + * destruct H as (z,(->,H)). simpl. + now apply lt_rev_append. + - apply IHl; [apply IHr; [apply Hacc|]|]. + + intros. now apply Hsacc. + + intros x (y,e') Hx H. rewrite xbindings_spec in H. + destruct H as [H|H]. + * now apply Hsacc. + * destruct H as (z,(->,H)). simpl. + now apply lt_rev_append. + Qed. + + Lemma bindings_spec1 m k e : + InA eq_key_elt (k,e) (bindings m) <-> MapsTo k e m. + Proof. + unfold bindings, MapsTo. rewrite xbindings_spec. + split; [ intros [H|(y & H & H')] | intros IN ]. + - inversion H. + - simpl in *. now subst. + - right. now exists k. + Qed. + + Lemma bindings_spec2 m : sort lt_key (bindings m). + Proof. + unfold bindings. + apply xbindings_sort. constructor. inversion 2. + Qed. + + Lemma bindings_spec2w m : NoDupA eq_key (bindings m). Proof. - intros. - generalize (xbindings_complete _ _ _ _ H); clear H; intros. - revert p0 q m v H. - induction p; destruct p0; simpl; intros; eauto; try discriminate. + apply ME.Sort_NoDupA. + apply bindings_spec2. Qed. - Lemma xbindings_bits_lt_2 : forall p p0 q m v, - List.In (p0,v) (xbindings m (append p (xI q))) -> E.bits_lt p p0. + Lemma xbindings_length m j acc : + length (xbindings m j acc) = (cardinal m + length acc)%nat. Proof. - intros. - generalize (xbindings_complete _ _ _ _ H); clear H; intros. - revert p0 q m v H. - induction p; destruct p0; simpl; intros; eauto; try discriminate. + revert j acc. + induction m; simpl; trivial; intros. + destruct o; simpl; rewrite IHm1; simpl; rewrite IHm2; + now rewrite ?Nat.add_succ_r, Nat.add_assoc. Qed. - Lemma xbindings_sort : forall p, sort lt_key (xbindings m p). + Lemma cardinal_spec m : cardinal m = length (bindings m). Proof. - induction m. - simpl; auto. - destruct o; simpl; intros. - (* Some *) - apply (SortA_app (eqA:=eq_key_elt)); auto with *. - constructor; auto. - apply In_InfA; intros. - destruct y0. - red; red; simpl. - eapply xbindings_bits_lt_2; eauto. - intros x0 y0. - do 2 rewrite InA_alt. - intros (y1,(Hy1,H)) (y2,(Hy2,H0)). - destruct y1; destruct x0; compute in Hy1; destruct Hy1; subst. - destruct y2; destruct y0; compute in Hy2; destruct Hy2; subst. - red; red; simpl. - destruct H0. - injection H0; clear H0; intros _ H0; subst. - eapply xbindings_bits_lt_1; eauto. - apply E.bits_lt_trans with p. - eapply xbindings_bits_lt_1; eauto. - eapply xbindings_bits_lt_2; eauto. - (* None *) - apply (SortA_app (eqA:=eq_key_elt)); auto with *. - intros x0 y0. - do 2 rewrite InA_alt. - intros (y1,(Hy1,H)) (y2,(Hy2,H0)). - destruct y1; destruct x0; compute in Hy1; destruct Hy1; subst. - destruct y2; destruct y0; compute in Hy2; destruct Hy2; subst. - red; red; simpl. - apply E.bits_lt_trans with p. - eapply xbindings_bits_lt_1; eauto. - eapply xbindings_bits_lt_2; eauto. - Qed. - - Lemma bindings_spec2 : sort lt_key (bindings m). - Proof. - unfold bindings. - apply xbindings_sort; auto. - Qed. - - Lemma bindings_spec2w : NoDupA eq_key (bindings m). - Proof. - apply ME.Sort_NoDupA. - apply bindings_spec2. + unfold bindings. rewrite xbindings_length. simpl. + symmetry. apply Nat.add_0_r. Qed. (** [map] and [mapi] *) @@ -591,40 +369,33 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. Fixpoint xmapi (m : t A) (i : key) : t B := match m with | Leaf => Leaf - | Node l o r => Node (xmapi l (append i (xO xH))) - (f i o) - (xmapi r (append i (xI xH))) + | Node l o r => Node (xmapi l (i~0)) + (f (rev i) o) + (xmapi r (i~1)) end. End Mapi. Definition mapi (f : key -> A -> B) m := - xmapi (fun k => option_map (f k)) m xH. + xmapi (fun k => option_map (f k)) m 1. Definition map (f : A -> B) m := mapi (fun _ => f) m. End A. Lemma xgmapi: - forall (A B: Type) (f: key -> option A -> option B) (i j : key) (m: t A), - (forall k, f k None = None) -> - find i (xmapi f m j) = f (append j i) (find i m). + forall (A B: Type) (f: key -> option A -> option B) (i j : key) (m: t A), + (forall k, f k None = None) -> + find i (xmapi f m j) = f (j@i) (find i m). Proof. - induction i; intros; destruct m; simpl; auto. - rewrite (append_assoc_1 j i); apply IHi; auto. - rewrite (append_assoc_0 j i); apply IHi; auto. - rewrite append_neutral_r; auto. + induction i; intros; destruct m; simpl; rewrite ?IHi; auto. Qed. Theorem mapi_spec0 : forall (A B: Type) (f: key -> A -> B) (i: key) (m: t A), find i (mapi f m) = option_map (f i) (find i m). Proof. - intros. - unfold mapi. - replace (f i) with (f (append xH i)). - apply xgmapi; auto. - rewrite append_neutral_l; auto. + intros. unfold mapi. rewrite xgmapi; simpl; auto. Qed. Lemma mapi_spec : @@ -654,20 +425,18 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. match m2 with | Leaf => xmapi (fun k o => f k o None) m1 i | Node l2 o2 r2 => - Node (xmerge l1 l2 (append i (xO xH))) - (f i o1 o2) - (xmerge r1 r2 (append i (xI xH))) + Node (xmerge l1 l2 (i~0)) + (f (rev i) o1 o2) + (xmerge r1 r2 (i~1)) end end. Lemma xgmerge: forall (i j: key)(m1:t A)(m2: t B), (forall i, f i None None = None) -> - find i (xmerge m1 m2 j) = f (append j i) (find i m1) (find i m2). + find i (xmerge m1 m2 j) = f (j@i) (find i m1) (find i m2). Proof. induction i; intros; destruct m1; destruct m2; simpl; auto; - rewrite ?xgmapi, ?IHi, - <- ?append_assoc_1, <- ?append_assoc_0, - ?append_neutral_l, ?append_neutral_r; auto. + rewrite ?xgmapi, ?IHi; simpl; auto. Qed. End merge. @@ -688,8 +457,7 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. Proof. intros. exists x. split. reflexivity. unfold merge. - rewrite xgmerge; auto. - rewrite append_neutral_l. + rewrite xgmerge; simpl; auto. rewrite <- 2 mem_spec, 2 mem_find in H. destruct (find x m); simpl; auto. destruct (find x m'); simpl; auto. intuition discriminate. @@ -701,8 +469,7 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. intros. rewrite <-mem_spec, mem_find in H. unfold merge in H. - rewrite xgmerge in H; auto. - rewrite append_neutral_l in H. + rewrite xgmerge in H; simpl; auto. rewrite <- 2 mem_spec, 2 mem_find. destruct (find x m); simpl in *; auto. destruct (find x m'); simpl in *; auto. @@ -713,42 +480,36 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. Variables A B : Type. Variable f : key -> A -> B -> B. - Fixpoint xfoldi (m : t A) (v : B) (i : key) := + (** the additional argument, [i], records the current path, in + reverse order (this should be more efficient: we reverse this argument + only at present nodes only, rather than at each node of the tree). + we also use this convention in all functions below + *) + + Fixpoint xfold (m : t A) (v : B) (i : key) := match m with | Leaf => v | Node l (Some x) r => - xfoldi r (f i x (xfoldi l v (append i 2))) (append i 3) + xfold r (f (rev i) x (xfold l v i~0)) i~1 | Node l None r => - xfoldi r (xfoldi l v (append i 2)) (append i 3) + xfold r (xfold l v i~0) i~1 end. - - Lemma xfoldi_1 : - forall m v i, - xfoldi m v i = fold_left (fun a p => f (fst p) (snd p) a) (xbindings m i) v. - Proof. - set (F := fun a p => f (fst p) (snd p) a). - induction m; intros; simpl; auto. - destruct o. - rewrite fold_left_app; simpl. - rewrite <- IHm1. - rewrite <- IHm2. - unfold F; simpl; reflexivity. - rewrite fold_left_app; simpl. - rewrite <- IHm1. - rewrite <- IHm2. - reflexivity. - Qed. - - Definition fold m i := xfoldi m i 1. + Definition fold m i := xfold m i 1. End Fold. Lemma fold_spec : - forall (A:Type)(m:t A)(B:Type)(i : B) (f : key -> A -> B -> B), + forall {A}(m:t A){B}(i : B) (f : key -> A -> B -> B), fold f m i = fold_left (fun a p => f (fst p) (snd p) a) (bindings m) i. Proof. - intros; unfold fold, bindings. - rewrite xfoldi_1; reflexivity. + unfold fold, bindings. intros A m B i f. revert m i. + set (f' := fun a p => f (fst p) (snd p) a). + assert (H: forall m i j acc, + fold_left f' acc (xfold f m i j) = + fold_left f' (xbindings m j acc) i). + { induction m as [|l IHl o r IHr]; intros; trivial. + destruct o; simpl; now rewrite IHr, <- IHl. } + intros. exact (H m i 1 nil). Qed. Fixpoint equal (A:Type)(cmp : A -> A -> bool)(m1 m2 : t A) : bool := @@ -872,11 +633,11 @@ Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits. try discriminate. Qed. -Lemma equal_spec : forall (A:Type)(m m':t A)(cmp:A->A->bool), + Lemma equal_spec : forall (A:Type)(m m':t A)(cmp:A->A->bool), equal cmp m m' = true <-> Equivb cmp m m'. -Proof. - split. apply equal_2. apply equal_1. -Qed. + Proof. + split. apply equal_2. apply equal_1. + Qed. End PositiveMap. |
