Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
This functor derives additional facts from FMapInterface.S. These
facts are mainly the specifications of FMapInterface.S written using
different styles: equivalence and boolean equalities.
Require Import Bool DecidableType DecidableTypeEx OrderedType Morphisms. Require Export FMapInterface. Set Implicit Arguments. Unset Strict Implicit. Hint Extern 1 (Equivalence _) => constructor; congruence : core.
Module WFacts_fun (E:DecidableType)(Import M:WSfun E). Notation eq_dec := E.eq_dec. Definition eqb x y := if eq_dec x y then true else false.forall b b' : bool, b = b' <-> (b = true <-> b' = true)destruct b; destruct b'; intuition. Qed.forall b b' : bool, b = b' <-> (b = true <-> b' = true)forall (elt : Type) (o o' : option elt), o = o' <-> (forall e : elt, o = Some e <-> o' = Some e)forall (elt : Type) (o o' : option elt), o = o' <-> (forall e : elt, o = Some e <-> o' = Some e)elt:Typeo, o':option eltH:o = o'e:elto = Some e <-> o' = Some eelt:Typeo, o':option eltH:forall e : elt, o = Some e <-> o' = Some eo = o'elt:Typeo, o':option eltH:forall e : elt, o = Some e <-> o' = Some eo = o'symmetry; rewrite <- H; auto. Qed.elt:Typee:eltH:forall e0 : elt, Some e = Some e0 <-> None = Some e0Some e = Noneforall (elt : Type) (m : t elt) (x : key) (e e' : elt), MapsTo x e m -> MapsTo x e' m -> e = e'forall (elt : Type) (m : t elt) (x : key) (e e' : elt), MapsTo x e m -> MapsTo x e' m -> e = e'elt:Typem:t eltx:keye, e':eltH:MapsTo x e mH0:MapsTo x e' me = e'intros; rewrite H in H0; injection H0; auto. Qed.elt:Typem:t eltx:keye, e':eltfind x m = Some e -> find x m = Some e' -> e = e'
Section IffSpec. Variable elt elt' elt'': Type. Implicit Type m: t elt. Implicit Type x y z: key. Implicit Type e: elt.elt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> In x m <-> In y melt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> In x m <-> In y melt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> (exists e : elt, MapsTo x e m) <-> (exists e : elt, MapsTo y e m)elt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ye0:eltH0:MapsTo x e0 mMapsTo y e0 melt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ye0:eltH0:MapsTo y e0 mMapsTo x e0 mapply (MapsTo_1 (E.eq_sym H) H0); auto. Qed.elt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ye0:eltH0:MapsTo y e0 mMapsTo x e0 melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), E.eq x y -> MapsTo x e m <-> MapsTo y e msplit; apply MapsTo_1; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), E.eq x y -> MapsTo x e m <-> MapsTo y e melt, elt', elt'':Typeforall (m : t elt) (x : key), In x m <-> mem x m = truesplit; [apply mem_1|apply mem_2]. Qed.elt, elt', elt'':Typeforall (m : t elt) (x : key), In x m <-> mem x m = trueelt, elt', elt'':Typeforall (m : t elt) (x : key), ~ In x m <-> mem x m = falseintros; rewrite mem_in_iff; destruct (mem x m); intuition. Qed.elt, elt', elt'':Typeforall (m : t elt) (x : key), ~ In x m <-> mem x m = falseelt, elt', elt'':Typeforall (m : t elt) (x : key), {In x m} + {~ In x m}elt, elt', elt'':Typeforall (m : t elt) (x : key), {In x m} + {~ In x m}elt, elt', elt'':Typem:t eltx:key{In x m} + {~ In x m}destruct (mem x m); [left|right]; intuition. Qed.elt, elt', elt'':Typem:t eltx:keyIn x m <-> mem x m = true -> {In x m} + {~ In x m}elt, elt', elt'':Typeforall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> find x m = Some esplit; [apply find_1|apply find_2]. Qed.elt, elt', elt'':Typeforall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> find x m = Some eelt, elt', elt'':Typeforall (m : t elt) (x : key), ~ In x m <-> find x m = Noneelt, elt', elt'':Typeforall (m : t elt) (x : key), ~ In x m <-> find x m = Noneelt, elt', elt'':Typem:t eltx:keyH:~ In x mfind x m = Noneelt, elt', elt'':Typem:t eltx:keyH:find x m = None~ In x melt, elt', elt'':Typem:t eltx:keyH:~ In x mforall e : elt, find x m = Some e <-> None = Some eelt, elt', elt'':Typem:t eltx:keyH:find x m = None~ In x melt, elt', elt'':Typem:t eltx:keyH:~ In x me:eltfind x m = Some e <-> None = Some eelt, elt', elt'':Typem:t eltx:keyH:find x m = None~ In x melt, elt', elt'':Typem:t eltx:keyH:~ In x me:eltMapsTo x e m <-> None = Some eelt, elt', elt'':Typem:t eltx:keyH:find x m = None~ In x melt, elt', elt'':Typem:t eltx:keyH:~ In x me:eltMapsTo x e m -> None = Some eelt, elt', elt'':Typem:t eltx:keyH:find x m = None~ In x mintros (e,He); rewrite find_mapsto_iff,H in He; discriminate. Qed.elt, elt', elt'':Typem:t eltx:keyH:find x m = None~ In x melt, elt', elt'':Typeforall (m : t elt) (x : key), In x m <-> find x m <> Noneelt, elt', elt'':Typeforall (m : t elt) (x : key), In x m <-> find x m <> Nonedestruct mem; intuition. Qed.elt, elt', elt'':Typem:t eltx:keymem x m = true <-> ~ mem x m <> trueelt, elt', elt'':Typeforall (m m' : t elt) (cmp : elt -> elt -> bool), Equivb cmp m m' <-> equal cmp m m' = truesplit; [apply equal_1|apply equal_2]. Qed.elt, elt', elt'':Typeforall (m m' : t elt) (cmp : elt -> elt -> bool), Equivb cmp m m' <-> equal cmp m m' = trueelt, elt', elt'':Typeforall (x : key) (e : elt), MapsTo x e (empty elt) <-> Falseintuition; apply (empty_1 H). Qed.elt, elt', elt'':Typeforall (x : key) (e : elt), MapsTo x e (empty elt) <-> Falseelt, elt', elt'':Typeforall x : key, In x (empty elt) <-> Falseelt, elt', elt'':Typeforall x : key, In x (empty elt) <-> Falsesplit; [intros (e,H); rewrite empty_mapsto_iff in H|]; intuition. Qed.elt, elt', elt'':Typeforall x : key, (exists e : elt, MapsTo x e (empty elt)) <-> Falseelt, elt', elt'':Typeforall m : t elt, Empty m <-> is_empty m = truesplit; [apply is_empty_1|apply is_empty_2]. Qed.elt, elt', elt'':Typeforall m : t elt, Empty m <-> is_empty m = trueelt, elt', elt'':Typeforall (m : t elt) (x y : key) (e e' : elt), MapsTo y e' (add x e m) <-> E.eq x y /\ e = e' \/ ~ E.eq x y /\ MapsTo y e' melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e e' : elt), MapsTo y e' (add x e m) <-> E.eq x y /\ e = e' \/ ~ E.eq x y /\ MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye, e':eltMapsTo y e' (add x e m) <-> E.eq x y /\ e = e' \/ ~ E.eq x y /\ MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)E.eq x y /\ e = e' \/ (E.eq x y -> False) /\ MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye, e':eltH:E.eq x yH1:e = e'MapsTo y e' (add x e m)elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)e0:E.eq x yE.eq x y /\ e = e'elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)n:~ E.eq x y(E.eq x y -> False) /\ MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye, e':eltH:E.eq x yH1:e = e'MapsTo y e' (add x e m)elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)e0:E.eq x ye = e'elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)n:~ E.eq x y(E.eq x y -> False) /\ MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye, e':eltH:E.eq x yH1:e = e'MapsTo y e' (add x e m)elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)n:~ E.eq x y(E.eq x y -> False) /\ MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye, e':eltH:E.eq x yH1:e = e'MapsTo y e' (add x e m)subst; auto with map. Qed.elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:E.eq x yH1:e = e'MapsTo y e' (add x e m)elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), In y (add x e m) <-> E.eq x y \/ In y melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), In y (add x e m) <-> E.eq x y \/ In y melt, elt', elt'':Typem:t eltx, y:keye:elt(exists e0 : elt, MapsTo y e0 (add x e m)) -> E.eq x y \/ (exists e0 : elt, MapsTo y e0 m)elt, elt', elt'':Typem:t eltx, y:keye:eltE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)E.eq x y \/ (exists e0 : elt, MapsTo y e0 m)elt, elt', elt'':Typem:t eltx, y:keye:eltE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)E:~ E.eq x yE.eq x y \/ (exists e0 : elt, MapsTo y e0 m)elt, elt', elt'':Typem:t eltx, y:keye:eltE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye, e':eltH:MapsTo y e' (add x e m)E:~ E.eq x yMapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye:eltE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:E.eq x yE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:~ E.eq x yE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:E.eq x yH:E.eq x y \/ (exists e0 : elt, MapsTo y e0 m)exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:~ E.eq x yE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:~ E.eq x yE.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:~ E.eq x yH:E.eq x yexists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typem:t eltx, y:keye:eltE:~ E.eq x ye':eltH:MapsTo y e' mexists e0 : elt, MapsTo y e0 (add x e m)exists e'; apply add_2; auto. Qed.elt, elt', elt'':Typem:t eltx, y:keye:eltE:~ E.eq x ye':eltH:MapsTo y e' mexists e0 : elt, MapsTo y e0 (add x e m)elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e e' : elt), ~ E.eq x y -> MapsTo y e' (add x e m) <-> MapsTo y e' msplit; [apply add_3|apply add_2]; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e e' : elt), ~ E.eq x y -> MapsTo y e' (add x e m) <-> MapsTo y e' melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> In y (add x e m) <-> In y melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> In y (add x e m) <-> In y melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x ye':eltH0:MapsTo y e' (add x e m)MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x ye':eltH0:MapsTo y e' mMapsTo y e' (add x e m)apply add_2; auto. Qed.elt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x ye':eltH0:MapsTo y e' mMapsTo y e' (add x e m)elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), MapsTo y e (remove x m) <-> ~ E.eq x y /\ MapsTo y e melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), MapsTo y e (remove x m) <-> ~ E.eq x y /\ MapsTo y e melt, elt', elt'':Typem:t eltx, y:keye:eltMapsTo y e (remove x m) <-> ~ E.eq x y /\ MapsTo y e melt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)~ E.eq x y /\ MapsTo y e melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x y /\ MapsTo y e mMapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)~ E.eq x yelt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)MapsTo y e melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x y /\ MapsTo y e mMapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)H0:In y (remove x m)~ E.eq x yelt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)MapsTo y e melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x y /\ MapsTo y e mMapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)MapsTo y e melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x y /\ MapsTo y e mMapsTo y e (remove x m)apply remove_2; intuition. Qed.elt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x y /\ MapsTo y e mMapsTo y e (remove x m)elt, elt', elt'':Typeforall (m : t elt) (x y : key), In y (remove x m) <-> ~ E.eq x y /\ In y melt, elt', elt'':Typeforall (m : t elt) (x y : key), In y (remove x m) <-> ~ E.eq x y /\ In y melt, elt', elt'':Typem:t eltx, y:key(exists e : elt, MapsTo y e (remove x m)) -> ~ E.eq x y /\ (exists e : elt, MapsTo y e m)elt, elt', elt'':Typem:t eltx, y:key~ E.eq x y /\ (exists e : elt, MapsTo y e m) -> exists e : elt, MapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)~ E.eq x y /\ (exists e0 : elt, MapsTo y e0 m)elt, elt', elt'':Typem:t eltx, y:key~ E.eq x y /\ (exists e : elt, MapsTo y e m) -> exists e : elt, MapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)~ E.eq x yelt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)exists e0 : elt, MapsTo y e0 melt, elt', elt'':Typem:t eltx, y:key~ E.eq x y /\ (exists e : elt, MapsTo y e m) -> exists e : elt, MapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)H0:In y (remove x m)~ E.eq x yelt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)exists e0 : elt, MapsTo y e0 melt, elt', elt'':Typem:t eltx, y:key~ E.eq x y /\ (exists e : elt, MapsTo y e m) -> exists e : elt, MapsTo y e (remove x m)elt, elt', elt'':Typem:t eltx, y:keye:eltH:MapsTo y e (remove x m)exists e0 : elt, MapsTo y e0 melt, elt', elt'':Typem:t eltx, y:key~ E.eq x y /\ (exists e : elt, MapsTo y e m) -> exists e : elt, MapsTo y e (remove x m)intros (H,(e,H0)); exists e; apply remove_2; auto. Qed.elt, elt', elt'':Typem:t eltx, y:key~ E.eq x y /\ (exists e : elt, MapsTo y e m) -> exists e : elt, MapsTo y e (remove x m)elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> MapsTo y e (remove x m) <-> MapsTo y e msplit; [apply remove_3|apply remove_2]; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> MapsTo y e (remove x m) <-> MapsTo y e melt, elt', elt'':Typeforall (m : t elt) (x y : key), ~ E.eq x y -> In y (remove x m) <-> In y melt, elt', elt'':Typeforall (m : t elt) (x y : key), ~ E.eq x y -> In y (remove x m) <-> In y melt, elt', elt'':Typem:t eltx, y:keyH:~ E.eq x ye':eltH0:MapsTo y e' (remove x m)MapsTo y e' melt, elt', elt'':Typem:t eltx, y:keyH:~ E.eq x ye':eltH0:MapsTo y e' mMapsTo y e' (remove x m)apply remove_2; auto. Qed.elt, elt', elt'':Typem:t eltx, y:keyH:~ E.eq x ye':eltH0:MapsTo y e' mMapsTo y e' (remove x m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> InA (eq_key_elt (elt:=elt)) (x, e) (elements m)split; [apply elements_1 | apply elements_2]. Qed.elt, elt', elt'':Typeforall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> InA (eq_key_elt (elt:=elt)) (x, e) (elements m)elt, elt', elt'':Typeforall (m : t elt) (x : key), In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))unfold In; split; intros (e,H); exists e; [apply elements_1 | apply elements_2]; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x : key), In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))elt, elt', elt'':Typeforall (m : t elt) (x : key) (b : elt') (f : elt -> elt'), MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (b : elt') (f : elt -> elt'), MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'MapsTo x b (map f m) -> exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'e:eltH:find x m = Some eH0:MapsTo x b (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'e:eltH:find x m = Some eH0:MapsTo x b (map f m)b = f e /\ MapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'e:eltH:find x m = Some eH0:MapsTo x b (map f m)b = f eelt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'e:eltH:find x m = Some eH0:MapsTo x b (map f m)MapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'e:eltH:find x m = Some eH0:MapsTo x b (map f m)MapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)H1:In x (map f m)exists a : elt, b = f a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'H:find x m = NoneH0:MapsTo x b (map f m)H1:In x (map f m)a:eltH2:MapsTo x a mexists a0 : elt, b = f a0 /\ MapsTo x a0 melt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)subst b; auto with map. Qed.elt, elt', elt'':Typem:t eltx:keyb:elt'f:elt -> elt'a:eltH:b = f aH0:MapsTo x a mMapsTo x b (map f m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) <-> In x melt, elt', elt'':Typeforall (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) <-> In x melt, elt', elt'':Typem:t eltx:keyf:elt -> elt'H:In x mIn x (map f m)exists (f a); auto with map. Qed.elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'a:eltH:MapsTo x a mIn x (map f m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : key -> elt -> elt'), In x (mapi f m) <-> In x melt, elt', elt'':Typeforall (m : t elt) (x : key) (f : key -> elt -> elt'), In x (mapi f m) <-> In x melt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:In x mIn x (mapi f m)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'a:eltH:MapsTo x a mIn x (mapi f m)exists (f y a); auto. Qed.elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'a:eltH:MapsTo x a my:E.tH0:E.eq y xH1:MapsTo x (f y a) (mapi f m)In x (mapi f m)
Unfortunately, we don't have simple equivalences for mapi
and MapsTo. The only correct one needs compatibility of f.
elt, elt', elt'':Typeforall (m : t elt) (x : key) (b : elt') (f : key -> elt -> elt'), MapsTo x b (mapi f m) -> exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typeforall (m : t elt) (x : key) (b : elt') (f : key -> elt -> elt'), MapsTo x b (mapi f m) -> exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)e:eltH0:find x m = Some eexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = Noneexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)e:eltH0:find x m = Some eexists y : key, E.eq y x /\ b = f y e /\ MapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = Noneexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)e:eltH0:find x m = Some eMapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)e:eltH0:find x m = Some ey:E.tH1:E.eq y xH2:MapsTo x (f y e) (mapi f m)exists y0 : key, E.eq y0 x /\ b = f y0 e /\ MapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = Noneexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)e:eltH0:find x m = Some ey:E.tH1:E.eq y xH2:MapsTo x (f y e) (mapi f m)exists y0 : key, E.eq y0 x /\ b = f y0 e /\ MapsTo x e melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = Noneexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)e:eltH0:find x m = Some ey:E.tH1:E.eq y xH2:MapsTo x (f y e) (mapi f m)b = f y eelt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = Noneexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = Noneexists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = NoneH1:In x (mapi f m)exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a mrewrite (find_1 H2) in H0; discriminate. Qed.elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:MapsTo x b (mapi f m)H0:find x m = NoneH1:In x (mapi f m)a:eltH2:MapsTo x a mexists (a0 : elt) (y : key), E.eq y x /\ b = f y a0 /\ MapsTo x a0 melt, elt', elt'':Typeforall (m : t elt) (x : key) (e : elt) (f : key -> elt -> elt'), (forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0) -> MapsTo x e m -> MapsTo x (f x e) (mapi f m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (e : elt) (f : key -> elt -> elt'), (forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0) -> MapsTo x e m -> MapsTo x (f x e) (mapi f m)elt, elt', elt'':Typem:t eltx:keye:eltf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0H0:MapsTo x e mMapsTo x (f x e) (mapi f m)elt, elt', elt'':Typem:t eltx:keye:eltf:key -> elt -> elt'H:forall (x0 y0 : key) (e0 : elt), E.eq x0 y0 -> f x0 e0 = f y0 e0H0:MapsTo x e my:E.tH1:E.eq y xH2:MapsTo x (f y e) (mapi f m)MapsTo x (f x e) (mapi f m)auto. Qed.elt, elt', elt'':Typem:t eltx:keye:eltf:key -> elt -> elt'H:forall (x0 y0 : key) (e0 : elt), E.eq x0 y0 -> f x0 e0 = f y0 e0H0:MapsTo x e my:E.tH1:E.eq y xH2:MapsTo x (f y e) (mapi f m)MapsTo x (f y e) (mapi f m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (b : elt') (f : key -> elt -> elt'), (forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e) -> MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (b : elt') (f : key -> elt -> elt'), (forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e) -> MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y eMapsTo x b (mapi f m) -> exists a : elt, b = f x a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e(exists a : elt, b = f x a /\ MapsTo x a m) -> MapsTo x b (mapi f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y eH0:MapsTo x b (mapi f m)exists a : elt, b = f x a /\ MapsTo x a melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e(exists a : elt, b = f x a /\ MapsTo x a m) -> MapsTo x b (mapi f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y0 : key) (e : elt), E.eq x0 y0 -> f x0 e = f y0 eH0:MapsTo x b (mapi f m)a:elty:keyH1:E.eq y xH2:b = f y aH3:MapsTo x a mexists a0 : elt, b = f x a0 /\ MapsTo x a0 melt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e(exists a : elt, b = f x a /\ MapsTo x a m) -> MapsTo x b (mapi f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y0 : key) (e : elt), E.eq x0 y0 -> f x0 e = f y0 eH0:MapsTo x b (mapi f m)a:elty:keyH1:E.eq y xH2:b = f y aH3:MapsTo x a mb = f x aelt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e(exists a : elt, b = f x a /\ MapsTo x a m) -> MapsTo x b (mapi f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e(exists a : elt, b = f x a /\ MapsTo x a m) -> MapsTo x b (mapi f m)elt, elt', elt'':Typem:t eltx:keyb:elt'f:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y ea:eltH0:b = f x aH1:MapsTo x a mMapsTo x b (mapi f m)apply mapi_1bis; auto. Qed.elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y ea:eltH1:MapsTo x a mMapsTo x (f x a) (mapi f m)
Things are even worse for map2 : we don't try to state any
equivalence, see instead boolean results below.
End IffSpec.
Useful tactic for simplifying expressions like In y (add x e (remove z m))
Ltac map_iff :=
repeat (progress (
rewrite add_mapsto_iff || rewrite add_in_iff ||
rewrite remove_mapsto_iff || rewrite remove_in_iff ||
rewrite empty_mapsto_iff || rewrite empty_in_iff ||
rewrite map_mapsto_iff || rewrite map_in_iff ||
rewrite mapi_in_iff)).
Section BoolSpec.forall (elt : Type) (m : t elt) (x : key), mem x m = (if find x m then true else false)forall (elt : Type) (m : t elt) (x : key), mem x m = (if find x m then true else false)elt:Typem:t eltx:keymem x m = (if find x m then true else false)elt:Typem:t eltx:key(forall e : elt, MapsTo x e m <-> find x m = Some e) -> (exists e : elt, MapsTo x e m) <-> mem x m = true -> mem x m = (if find x m then true else false)elt:Typem:t eltx:keye:elt(forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0) -> (exists e0 : elt, MapsTo x e0 m) <-> false = true -> false = trueelt:Typem:t eltx:key(forall e : elt, MapsTo x e m <-> None = Some e) -> (exists e : elt, MapsTo x e m) <-> true = true -> true = falseelt:Typem:t eltx:keye:eltH:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H0:(exists e0 : elt, MapsTo x e0 m) <-> false = truefalse = trueelt:Typem:t eltx:key(forall e : elt, MapsTo x e m <-> None = Some e) -> (exists e : elt, MapsTo x e m) <-> true = true -> true = falseelt:Typem:t eltx:key(forall e : elt, MapsTo x e m <-> None = Some e) -> (exists e : elt, MapsTo x e m) <-> true = true -> true = falseelt:Typem:t eltx:keyH:forall e : elt, MapsTo x e m <-> None = Some eH0:exists e : elt, MapsTo x e mH2:true = truetrue = falsedestruct (H e); intuition discriminate. Qed. Variable elt elt' elt'' : Type. Implicit Types m : t elt. Implicit Types x y z : key. Implicit Types e : elt.elt:Typem:t eltx:keyH:forall e0 : elt, MapsTo x e0 m <-> None = Some e0e:eltH0:MapsTo x e mH2:true = truetrue = falseelt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> mem x m = mem y melt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> mem x m = mem y melt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ymem x m = mem y mdestruct (mem x m); destruct (mem y m); intuition. Qed.elt, elt', elt'':Typem:t eltx, y:keyH:E.eq x yIn x m <-> mem x m = true -> In y m <-> mem y m = true -> In x m <-> In y m -> mem x m = mem y melt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> find x m = find y melt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> find x m = find y melt, elt', elt'':Typem:t eltx, y:keyH:E.eq x yfind x m = find y melt, elt', elt'':Typem:t eltx, y:keyH:E.eq x yforall e : elt, find x m = Some e <-> find y m = Some eelt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ye:eltfind x m = Some e <-> find y m = Some eapply MapsTo_iff; auto. Qed.elt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ye:eltMapsTo x e m <-> MapsTo y e melt, elt', elt'':Typeforall x : key, find x (empty elt) = Noneelt, elt', elt'':Typeforall x : key, find x (empty elt) = Noneelt, elt', elt'':Typex:keyfind x (empty elt) = Noneelt, elt', elt'':Typex:keyforall e : elt, find x (empty elt) = Some e <-> None = Some erewrite <- find_mapsto_iff, empty_mapsto_iff; now intuition. Qed.elt, elt', elt'':Typex:keye:eltfind x (empty elt) = Some e <-> None = Some eelt, elt', elt'':Typeforall x : key, mem x (empty elt) = falseelt, elt', elt'':Typeforall x : key, mem x (empty elt) = falseelt, elt', elt'':Typex:keymem x (empty elt) = falseelt, elt', elt'':Typex:keyH:mem x (empty elt) = truetrue = falserewrite empty_in_iff; intuition. Qed.elt, elt', elt'':Typex:keyH:mem x (empty elt) = trueIn x (empty elt) -> true = falseelt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), E.eq x y -> find y (add x e m) = Some eauto with map. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), E.eq x y -> find y (add x e m) = Some eelt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> find y (add x e m) = find y melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> find y (add x e m) = find y melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x yfind y (add x e m) = find y melt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x yforall e0 : elt, find y (add x e m) = Some e0 <-> find y m = Some e0elt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x ye':eltfind y (add x e m) = Some e' <-> find y m = Some e'apply add_neq_mapsto_iff; auto. Qed. Hint Resolve add_neq_o : map.elt, elt', elt'':Typem:t eltx, y:keye:eltH:~ E.eq x ye':eltMapsTo y e' (add x e m) <-> MapsTo y e' melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), find y (add x e m) = (if eq_dec x y then Some e else find y m)intros; destruct (eq_dec x y); auto with map. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), find y (add x e m) = (if eq_dec x y then Some e else find y m)elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), E.eq x y -> mem y (add x e m) = trueintros; rewrite mem_find_b; rewrite add_eq_o; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), E.eq x y -> mem y (add x e m) = trueelt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> mem y (add x e m) = mem y mintros; do 2 rewrite mem_find_b; rewrite add_neq_o; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> mem y (add x e m) = mem y melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), mem y (add x e m) = eqb x y || mem y melt, elt', elt'':Typeforall (m : t elt) (x y : key) (e : elt), mem y (add x e m) = eqb x y || mem y mdestruct (eq_dec x y); simpl; auto. Qed.elt, elt', elt'':Typem:t eltx, y:keye:elt(if if eq_dec x y then Some e else find y m then true else false) = (if eq_dec x y then true else false) || (if find y m then true else false)elt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> find y (remove x m) = Noneelt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> find y (remove x m) = Noneelt, elt', elt'':Typem:t eltx, y:keyH:E.eq x yfind y (remove x m) = Noneelt, elt', elt'':Typem:t eltx, y:keyH:E.eq x yforall e : elt, find y (remove x m) = Some e <-> None = Some erewrite <- find_mapsto_iff, remove_mapsto_iff; now intuition. Qed. Hint Resolve remove_eq_o : map.elt, elt', elt'':Typem:t eltx, y:keyH:E.eq x ye:eltfind y (remove x m) = Some e <-> None = Some eelt, elt', elt'':Typeforall (m : t elt) (x y : key), ~ E.eq x y -> find y (remove x m) = find y melt, elt', elt'':Typeforall (m : t elt) (x y : key), ~ E.eq x y -> find y (remove x m) = find y melt, elt', elt'':Typem:t eltx, y:keyH:~ E.eq x yfind y (remove x m) = find y melt, elt', elt'':Typem:t eltx, y:keyH:~ E.eq x yforall e : elt, find y (remove x m) = Some e <-> find y m = Some erewrite <- find_mapsto_iff, remove_neq_mapsto_iff; now intuition. Qed. Hint Resolve remove_neq_o : map.elt, elt', elt'':Typem:t eltx, y:keyH:~ E.eq x ye:eltfind y (remove x m) = Some e <-> find y m = Some eelt, elt', elt'':Typeforall (m : t elt) (x y : key), find y (remove x m) = (if eq_dec x y then None else find y m)intros; destruct (eq_dec x y); auto with map. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key), find y (remove x m) = (if eq_dec x y then None else find y m)elt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> mem y (remove x m) = falseintros; rewrite mem_find_b; rewrite remove_eq_o; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key), E.eq x y -> mem y (remove x m) = falseelt, elt', elt'':Typeforall (m : t elt) (x y : key), ~ E.eq x y -> mem y (remove x m) = mem y mintros; do 2 rewrite mem_find_b; rewrite remove_neq_o; auto. Qed.elt, elt', elt'':Typeforall (m : t elt) (x y : key), ~ E.eq x y -> mem y (remove x m) = mem y melt, elt', elt'':Typeforall (m : t elt) (x y : key), mem y (remove x m) = negb (eqb x y) && mem y melt, elt', elt'':Typeforall (m : t elt) (x y : key), mem y (remove x m) = negb (eqb x y) && mem y mdestruct (eq_dec x y); auto. Qed.elt, elt', elt'':Typem:t eltx, y:key(if if eq_dec x y then None else find y m then true else false) = negb (if eq_dec x y then true else false) && (if find y m then true else false)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : elt -> elt'), find x (map f m) = option_map f (find x m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : elt -> elt'), find x (map f m) = option_map f (find x m)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'find x (map f m) = option_map f (find x m)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'(forall e : elt', MapsTo x e (map f m) <-> find x (map f m) = Some e) -> (forall e : elt, MapsTo x e m <-> find x m = Some e) -> (forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)) -> find x (map f m) = option_map f (find x m)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:elt'e0:eltH:forall e1 : elt', MapsTo x e1 (map f m) <-> Some e = Some e1H0:forall e1 : elt, MapsTo x e1 m <-> Some e0 = Some e1H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)Some e = Some (f e0)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:elt'H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)Some e = Noneelt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:eltH:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)None = Some (f e)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:elt'H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)Some e = Noneelt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:eltH:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)None = Some (f e)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:elt'H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)H2:Some e = Some e -> MapsTo x e (map f m)Some e = Noneelt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:eltH:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)None = Some (f e)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:elt'H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)H2:Some e = Some e -> exists a : elt, e = f a /\ MapsTo x a mSome e = Noneelt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:eltH:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)None = Some (f e)elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:elt'H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a0 : elt, b = f a0 /\ MapsTo x a0 m)a:eltH2:MapsTo x a mSome e = Noneelt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:eltH:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)None = Some (f e)rewrite <- H; rewrite H1; exists e; rewrite H0; auto. Qed.elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'e:eltH:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)None = Some (f e)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : elt -> elt'), mem x (map f m) = mem x melt, elt', elt'':Typeforall (m : t elt) (x : key) (f : elt -> elt'), mem x (map f m) = mem x mdestruct (find x m); simpl; auto. Qed.elt, elt', elt'':Typem:t eltx:keyf:elt -> elt'(if option_map f (find x m) then true else false) = (if find x m then true else false)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : key -> elt -> elt'), mem x (mapi f m) = mem x melt, elt', elt'':Typeforall (m : t elt) (x : key) (f : key -> elt -> elt'), mem x (mapi f m) = mem x melt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'mem x (mapi f m) = mem x melt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'In x (mapi f m) <-> mem x (mapi f m) = true -> In x m <-> mem x m = true -> In x (mapi f m) <-> In x m -> mem x (mapi f m) = mem x melt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:In x (mapi f m) <-> true = trueH0:In x m <-> false = trueH1:In x (mapi f m) <-> In x mtrue = falseelt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:In x (mapi f m) <-> false = trueH0:In x m <-> true = trueH1:In x (mapi f m) <-> In x mfalse = truerewrite <- H; rewrite H1; rewrite H0; auto. Qed.elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:In x (mapi f m) <-> false = trueH0:In x m <-> true = trueH1:In x (mapi f m) <-> In x mfalse = trueelt, elt', elt'':Typeforall (m : t elt) (x : key) (f : key -> elt -> elt'), (forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e) -> find x (mapi f m) = option_map (f x) (find x m)elt, elt', elt'':Typeforall (m : t elt) (x : key) (f : key -> elt -> elt'), (forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e) -> find x (mapi f m) = option_map (f x) (find x m)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y efind x (mapi f m) = option_map (f x) (find x m)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e(forall e : elt', MapsTo x e (mapi f m) <-> find x (mapi f m) = Some e) -> (forall e : elt, MapsTo x e m <-> find x m = Some e) -> (forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)) -> find x (mapi f m) = option_map (f x) (find x m)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e1 : elt), E.eq x0 y -> f x0 e1 = f y e1e:elt'e0:eltH0:forall e1 : elt', MapsTo x e1 (mapi f m) <-> Some e = Some e1H1:forall e1 : elt, MapsTo x e1 m <-> Some e0 = Some e1H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)Some e = Some (f x e0)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:elt'H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)Some e = Noneelt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:eltH0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)None = Some (f x e)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:elt'H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)Some e = Noneelt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:eltH0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)None = Some (f x e)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:elt'H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)H3:Some e = Some e -> MapsTo x e (mapi f m)Some e = Noneelt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:eltH0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)None = Some (f x e)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:elt'H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)H3:Some e = Some e -> exists a : elt, e = f x a /\ MapsTo x a mSome e = Noneelt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:eltH0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)None = Some (f x e)elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:elt'H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a0 : elt, b = f x a0 /\ MapsTo x a0 m)a:eltH3:MapsTo x a mSome e = Noneelt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:eltH0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)None = Some (f x e)rewrite <- H0; rewrite H2; exists e; rewrite H1; auto. Qed.elt, elt', elt'':Typem:t eltx:keyf:key -> elt -> elt'H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0e:eltH0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)None = Some (f x e)elt, elt', elt'':Typeforall (m : t elt) (m' : t elt') (x : key) (f : option elt -> option elt' -> option elt''), f None None = None -> find x (map2 f m m') = f (find x m) (find x m')elt, elt', elt'':Typeforall (m : t elt) (m' : t elt') (x : key) (f : option elt -> option elt' -> option elt''), f None None = None -> find x (map2 f m m') = f (find x m) (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = Nonefind x (map2 f m m') = f (find x m) (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = Nonee:eltH0:find x m = Some efind x (map2 f m m') = f (Some e) (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonefind x (map2 f m m') = f None (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = Nonee:eltH0:find x m = Some efind x (map2 f m m') = f (find x m) (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonefind x (map2 f m m') = f None (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = Nonee:eltH0:find x m = Some eIn x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonefind x (map2 f m m') = f None (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonefind x (map2 f m m') = f None (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonee:elt'H1:find x m' = Some efind x (map2 f m m') = f None (Some e)elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonefind x (map2 f m m') = f None Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonee:elt'H1:find x m' = Some efind x (map2 f m m') = f (find x m) (find x m')elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonefind x (map2 f m m') = f None Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = Nonee:elt'H1:find x m' = Some eIn x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonefind x (map2 f m m') = f None Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonefind x (map2 f m m') = f None Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonefind x (map2 f m m') = Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonee:elt''H2:find x (map2 f m m') = Some eSome e = Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonee:elt''H2:find x (map2 f m m') = Some eH3:In x (map2 f m m')Some e = Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonee:elt''H2:find x (map2 f m m') = Some eH3:In x (map2 f m m')e0:eltH4:MapsTo x e0 mSome e = Noneelt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonee:elt''H2:find x (map2 f m m') = Some eH3:In x (map2 f m m')e0:elt'H4:MapsTo x e0 m'Some e = Nonerewrite (find_1 H4) in H1; discriminate. Qed.elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:f None None = NoneH0:find x m = NoneH1:find x m' = Nonee:elt''H2:find x (map2 f m m') = Some eH3:In x (map2 f m m')e0:elt'H4:MapsTo x e0 m'Some e = Noneelt, elt', elt'':Typeforall (m : t elt) (x : key), find x m = findA (eqb x) (elements m)elt, elt', elt'':Typeforall (m : t elt) (x : key), find x m = findA (eqb x) (elements m)elt, elt', elt'':Typem:t eltx:keyfind x m = findA (eqb x) (elements m)elt, elt', elt'':Typem:t eltx:keyforall e : elt, find x m = Some e <-> findA (eqb x) (elements m) = Some eelt, elt', elt'':Typem:t eltx:keye:eltfind x m = Some e <-> findA (eqb x) (elements m) = Some eelt, elt', elt'':Typem:t eltx:keye:eltInA (eq_key_elt (elt:=elt)) (x, e) (elements m) <-> findA (eqb x) (elements m) = Some erewrite <- findA_NoDupA; dintuition; try apply elements_3w; eauto. Qed.elt, elt', elt'':Typem:t eltx:keye:eltInA (eq_key_elt (elt:=elt)) (x, e) (elements m) <-> findA (fun y : E.t => if eq_dec x y then true else false) (elements m) = Some eelt, elt', elt'':Typeforall (m : t elt) (x : key), mem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)elt, elt', elt'':Typeforall (m : t elt) (x : key), mem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)elt, elt', elt'':Typem:t eltx:keymem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)elt, elt', elt'':Typem:t eltx:keyIn x m <-> mem x m = true -> In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m)) -> existsb (fun p : E.t * elt => eqb x (fst p)) (elements m) = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true) -> mem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)elt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)true = falseelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH0:In x m -> exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m)H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)e:eltHe:InA (eq_key_elt (elt:=elt)) (x, e) (elements m)exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)e:eltHe:exists y : key * elt, eq_key_elt (x, e) y /\ List.In y (elements m)exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)e:elty:keye':eltHa1:eq_key_elt (x, e) (y, e')Ha2:List.In (y, e') (elements m)exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)e:elty:keyH0:E.eq x yHa2:List.In (y, e) (elements m)exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> true = trueH1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)e:elty:keyH0:E.eq x yHa2:List.In (y, e) (elements m)eqb x y = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)false = trueelt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m)elt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))H1:true = true -> exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = trueexists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m)elt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m))y:E.te:eltHa1:List.In (y, e) (elements m)Ha2:eqb x (fst (y, e)) = trueexists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m)elt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m))y:E.te:eltHa1:List.In (y, e) (elements m)Ha2:eqb x y = trueexists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m)elt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m))y:E.te:eltHa1:List.In (y, e) (elements m)e0:E.eq x yHa2:true = trueexists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m)elt, elt', elt'':Typem:t eltx:keyH:In x m <-> false = trueH0:In x m <-> (exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m))y:E.te:eltHa1:List.In (y, e) (elements m)e0:E.eq x yHa2:true = trueexists y0 : key * elt, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)compute; auto. Qed. End BoolSpec. Section Equalities. Variable elt:Type.elt, elt', elt'':Typem:t eltx:keyy:E.te:eltHa1:List.In (y, e) (elements m)e0:E.eq x yHa2:true = trueH1:In x m -> false = trueH2:false = true -> In x mH:In x m -> exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m)H3:(exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m)) -> In x meq_key_elt (x, e) (y, e)
Another characterisation of Equal
elt:Typeforall m1 m2 : t elt, Equal m1 m2 <-> (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2)elt:Typeforall m1 m2 : t elt, Equal m1 m2 <-> (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2)elt:Typem1, m2:t eltEqual m1 m2 <-> (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2)elt:Typem1, m2:t eltHeq:Equal m1 m2k:keye:eltMapsTo k e m1 <-> MapsTo k e m2elt:Typem1, m2:t eltHiff:forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2Equal m1 m2elt:Typem1, m2:t eltHeq:Equal m1 m2k:keye:eltfind k m2 = Some e <-> find k m2 = Some eelt:Typem1, m2:t eltHiff:forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2Equal m1 m2elt:Typem1, m2:t eltHiff:forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2Equal m1 m2elt:Typem1, m2:t eltHiff:forall (k0 : key) (e : elt), MapsTo k0 e m1 <-> MapsTo k0 e m2k:keyfind k m1 = find k m2elt:Typem1, m2:t eltHiff:forall (k0 : key) (e : elt), MapsTo k0 e m1 <-> MapsTo k0 e m2k:keyforall e : elt, find k m1 = Some e <-> find k m2 = Some erewrite <- 2 find_mapsto_iff; auto. Qed.elt:Typem1, m2:t eltHiff:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 <-> MapsTo k0 e0 m2k:keye:eltfind k m1 = Some e <-> find k m2 = Some e
First, Equal is Equiv with Leibniz on elements.
elt:Typeforall m m' : t elt, Equal m m' <-> Equiv eq m m'elt:Typeforall m m' : t elt, Equal m m' <-> Equiv eq m m'elt:Typem, m':t eltEqual m m' <-> Equiv eq m m'elt:Typem, m':t elt(forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m') <-> Equiv eq m m'elt:Typem, m':t eltH:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m'Equiv eq m m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltMapsTo k e m <-> MapsTo k e m'elt:Typem, m':t eltH:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m'forall k : key, In k m <-> In k m'elt:Typem, m':t eltH:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m'forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> e = e'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltMapsTo k e m <-> MapsTo k e m'elt:Typem, m':t eltH:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m'forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> e = e'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltMapsTo k e m <-> MapsTo k e m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltMapsTo k e m <-> MapsTo k e m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltH':MapsTo k e mMapsTo k e m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltH':MapsTo k e m'MapsTo k e melt:Typem, m':t eltH:forall k0 : key, In k0 m <-> In k0 m'H0:forall (k0 : key) (e0 e' : elt), MapsTo k0 e0 m -> MapsTo k0 e' m' -> e0 = e'k:keye:eltH':MapsTo k e mMapsTo k e m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltH':MapsTo k e m'MapsTo k e melt:Typem, m':t eltH:forall k0 : key, In k0 m <-> In k0 m'H0:forall (k0 : key) (e0 e' : elt), MapsTo k0 e0 m -> MapsTo k0 e' m' -> e0 = e'k:keye:eltH':MapsTo k e mHin:In k m'MapsTo k e m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltH':MapsTo k e m'MapsTo k e melt:Typem, m':t eltH:forall k0 : key, In k0 m <-> In k0 m'H0:forall (k0 : key) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> e0 = e'0k:keye:eltH':MapsTo k e me':eltHe':MapsTo k e' m'MapsTo k e m'elt:Typem, m':t eltH:Equiv eq m m'k:keye:eltH':MapsTo k e m'MapsTo k e melt:Typem, m':t eltH:Equiv eq m m'k:keye:eltH':MapsTo k e m'MapsTo k e melt:Typem, m':t eltH:forall k0 : key, In k0 m <-> In k0 m'H0:forall (k0 : key) (e0 e' : elt), MapsTo k0 e0 m -> MapsTo k0 e' m' -> e0 = e'k:keye:eltH':MapsTo k e m'MapsTo k e melt:Typem, m':t eltH:forall k0 : key, In k0 m <-> In k0 m'H0:forall (k0 : key) (e0 e' : elt), MapsTo k0 e0 m -> MapsTo k0 e' m' -> e0 = e'k:keye:eltH':MapsTo k e m'Hin:In k mMapsTo k e mrewrite <- (H0 k e' e); auto. Qed.elt:Typem, m':t eltH:forall k0 : key, In k0 m <-> In k0 m'H0:forall (k0 : key) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> e0 = e'0k:keye:eltH':MapsTo k e m'e':eltHe':MapsTo k e' mMapsTo k e m
Equivb and Equiv and equivalent when eq_elt and cmp
are related.
Section Cmp. Variable eq_elt : elt->elt->Prop. Variable cmp : elt->elt->bool. Definition compat_cmp := forall e e', cmp e e' = true <-> eq_elt e e'.elt:Typeeq_elt:elt -> elt -> Propcmp:elt -> elt -> boolcompat_cmp -> forall m m' : t elt, Equiv eq_elt m m' <-> Equivb cmp m m'elt:Typeeq_elt:elt -> elt -> Propcmp:elt -> elt -> boolcompat_cmp -> forall m m' : t elt, Equiv eq_elt m m' <-> Equivb cmp m m'elt:Typeeq_elt:elt -> elt -> Propcmp:elt -> elt -> boolH:compat_cmpm, m':t eltH1:forall k0 : key, In k0 m <-> In k0 m'H2:forall (k0 : key) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> eq_elt e0 e'0k:keye, e':eltH0:MapsTo k e mH3:MapsTo k e' m'cmp e e' = trueelt:Typeeq_elt:elt -> elt -> Propcmp:elt -> elt -> boolH:compat_cmpm, m':t eltH1:forall k0 : key, In k0 m <-> In k0 m'H2:forall (k0 : key) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> cmp e0 e'0 = truek:keye, e':eltH0:MapsTo k e mH3:MapsTo k e' m'eq_elt e e'red in H; rewrite <-H; eauto. Qed. End Cmp.elt:Typeeq_elt:elt -> elt -> Propcmp:elt -> elt -> boolH:compat_cmpm, m':t eltH1:forall k0 : key, In k0 m <-> In k0 m'H2:forall (k0 : key) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> cmp e0 e'0 = truek:keye, e':eltH0:MapsTo k e mH3:MapsTo k e' m'eq_elt e e'
Composition of the two last results: relation between Equal
and Equivb.
elt:Typeforall cmp : elt -> elt -> bool, (forall e e' : elt, cmp e e' = true <-> e = e') -> forall m m' : t elt, Equal m m' <-> Equivb cmp m m'elt:Typeforall cmp : elt -> elt -> bool, (forall e e' : elt, cmp e e' = true <-> e = e') -> forall m m' : t elt, Equal m m' <-> Equivb cmp m m'apply Equiv_Equivb; auto. Qed.elt:Typecmp:elt -> elt -> boolH:forall e e' : elt, cmp e e' = true <-> e = e'm, m':t eltEquiv eq m m' <-> Equivb cmp m m'elt:Typeforall eq_elt_dec : forall e e' : elt, {e = e'} + {e <> e'}, let cmp := fun e e' : elt => if eq_elt_dec e e' then true else false in forall m m' : t elt, Equal m m' <-> Equivb cmp m m'elt:Typeforall eq_elt_dec : forall e e' : elt, {e = e'} + {e <> e'}, let cmp := fun e e' : elt => if eq_elt_dec e e' then true else false in forall m m' : t elt, Equal m m' <-> Equivb cmp m m'elt:Typeeq_elt_dec:forall e e' : elt, {e = e'} + {e <> e'}cmp:=fun e e' : elt => if eq_elt_dec e e' then true else false:elt -> elt -> boolm, m':t eltforall e e' : elt, cmp e e' = true <-> e = e'destruct eq_elt_dec; now intuition. Qed. End Equalities.elt:Typeeq_elt_dec:forall e0 e'0 : elt, {e0 = e'0} + {e0 <> e'0}m, m':t elte, e':elt(if eq_elt_dec e e' then true else false) = true <-> e = e'
forall (elt : Type) (m : t elt), Equal m mred; reflexivity. Qed.forall (elt : Type) (m : t elt), Equal m mforall (elt : Type) (m m' : t elt), Equal m m' -> Equal m' munfold Equal; auto. Qed.forall (elt : Type) (m m' : t elt), Equal m m' -> Equal m' mforall (elt : Type) (m m' m'' : t elt), Equal m m' -> Equal m' m'' -> Equal m m''unfold Equal; congruence. Qed.forall (elt : Type) (m m' m'' : t elt), Equal m m' -> Equal m' m'' -> Equal m m''forall elt : Type, Equivalence (Equal (elt:=elt))constructor; red; [apply Equal_refl | apply Equal_sym | apply Equal_trans]. Qed. Add Relation key E.eq reflexivity proved by E.eq_refl symmetry proved by E.eq_sym transitivity proved by E.eq_trans as KeySetoid. Arguments Equal {elt} m m'. Add Parametric Relation (elt : Type) : (t elt) Equal reflexivity proved by (@Equal_refl elt) symmetry proved by (@Equal_sym elt) transitivity proved by (@Equal_trans elt) as EqualSetoid.forall elt : Type, Equivalence (Equal (elt:=elt))elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> In x x0 <-> In y y0elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> In x x0 <-> In y y0rewrite (In_iff m Hk), in_find_iff, in_find_iff, Hm; intuition. Qed.elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:forall y : key, find y m = find y m'In k m <-> In k' m'elt:Typeforall x y : E.t, E.eq x y -> forall (y0 : elt) (x0 y1 : t elt), Equal x0 y1 -> MapsTo x y0 x0 <-> MapsTo y y0 y1elt:Typeforall x y : E.t, E.eq x y -> forall (y0 : elt) (x0 y1 : t elt), Equal x0 y1 -> MapsTo x y0 x0 <-> MapsTo y y0 y1rewrite (MapsTo_iff m e Hk), find_mapsto_iff, find_mapsto_iff, Hm; intuition. Qed.elt:Typek, k':E.tHk:E.eq k k'e:eltm, m':t eltHm:forall y : key, find y m = find y m'MapsTo k e m <-> MapsTo k' e m'elt:Typeforall x y : t elt, Equal x y -> Empty x <-> Empty yelt:Typeforall x y : t elt, Equal x y -> Empty x <-> Empty yelt:Typem, m':t eltHm:Equal m m'(forall (a : key) (e : elt), ~ MapsTo a e m) <-> (forall (a : key) (e : elt), ~ MapsTo a e m')elt:Typem, m':t eltHm:Equal m m'H:forall (a0 : key) (e0 : elt), ~ MapsTo a0 e0 ma:keye:eltH0:MapsTo a e m'Falseelt:Typem, m':t eltHm:Equal m m'H:forall (a0 : key) (e0 : elt), ~ MapsTo a0 e0 m'a:keye:eltH0:MapsTo a e mFalserewrite Hm in H0; eapply H, H0. Qed.elt:Typem, m':t eltHm:Equal m m'H:forall (a0 : key) (e0 : elt), ~ MapsTo a0 e0 m'a:keye:eltH0:MapsTo a e mFalseelt:Typeforall x y : t elt, Equal x y -> is_empty x = is_empty yelt:Typeforall x y : t elt, Equal x y -> is_empty x = is_empty yrewrite eq_bool_alt, <-is_empty_iff, <-is_empty_iff, Hm; intuition. Qed.elt:Typem, m':t eltHm:Equal m m'is_empty m = is_empty m'elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> mem x x0 = mem y y0elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> mem x x0 = mem y y0rewrite eq_bool_alt, <- mem_in_iff, <-mem_in_iff, Hk, Hm; intuition. Qed.elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'mem k m = mem k' m'elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> find x x0 = find y y0elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> find x x0 = find y y0elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'find k m = find k' m'elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'forall e : elt, find k m = Some e <-> find k' m' = Some eelt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'e:eltfind k m = Some e <-> find k' m' = Some esplit; auto. Qed.elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'e:eltMapsTo k' e m' <-> MapsTo k' e m'elt:Typeforall x y : E.t, E.eq x y -> forall (y0 : elt) (x0 y1 : t elt), Equal x0 y1 -> Equal (add x y0 x0) (add y y0 y1)elt:Typeforall x y : E.t, E.eq x y -> forall (y0 : elt) (x0 y1 : t elt), Equal x0 y1 -> Equal (add x y0 x0) (add y y0 y1)elt:Typek, k':E.tHk:E.eq k k'e:eltm, m':t eltHm:Equal m m'y:keyfind y (add k e m) = find y (add k' e m')elt:Typek, k':E.tHk:E.eq k k'e:eltm, m':t eltHm:Equal m m'y:keye0:E.eq k yHnot:~ E.eq k' ySome e = find y m'elt:Typek, k':E.tHk:E.eq k k'e:eltm, m':t eltHm:Equal m m'y:keyHnot:~ E.eq k ye0:E.eq k' yfind y m = Some eelim Hnot; rewrite Hk; auto. Qed.elt:Typek, k':E.tHk:E.eq k k'e:eltm, m':t eltHm:Equal m m'y:keyHnot:~ E.eq k ye0:E.eq k' yfind y m = Some eelt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (remove x x0) (remove y y0)elt:Typeforall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (remove x x0) (remove y y0)elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'y:keyfind y (remove k m) = find y (remove k' m')elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'y:keye:E.eq k yHnot:~ E.eq k' yNone = find y m'elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'y:keyHnot:~ E.eq k ye:E.eq k' yfind y m = Noneelim Hnot; rewrite Hk; auto. Qed.elt:Typek, k':E.tHk:E.eq k k'm, m':t eltHm:Equal m m'y:keyHnot:~ E.eq k ye:E.eq k' yfind y m = Noneelt, elt':Typeforall (y : elt -> elt') (x y0 : t elt), Equal x y0 -> Equal (map y x) (map y y0)elt, elt':Typeforall (y : elt -> elt') (x y0 : t elt), Equal x y0 -> Equal (map y x) (map y y0)rewrite map_o, map_o, Hm; auto. Qed. (* Later: Add Morphism cardinal *) (* old name: *) Notation not_find_mapsto_iff := not_find_in_iff. End WFacts_fun.elt, elt':Typef:elt -> elt'm, m':t eltHm:Equal m m'y:keyfind y (map f m) = find y (map f m')
Module WFacts (M:WS) := WFacts_fun M.E M. Module Facts := WFacts.
Module WProperties_fun (E:DecidableType)(M:WSfun E). Module Import F:=WFacts_fun E M. Import M. Section Elt. Variable elt:Type. Definition Add x (e:elt) m m' := forall y, find y m' = find y (add x e m). Notation eqke := (@eq_key_elt elt). Notation eqk := (@eq_key elt).elt:TypeEquivalence eqkunfold eq_key; split; eauto. Qed.elt:TypeEquivalence eqkelt:TypeEquivalence eqkeelt:TypeEquivalence eqkeelt:Typex, y, z:(key * elt)%typeH0:E.eq (fst y) (fst z)H1:snd y = snd zH:E.eq (fst x) (fst y)H2:snd x = snd yE.eq (fst x) (fst z)elt:Typex, y, z:(key * elt)%typeH0:E.eq (fst y) (fst z)H1:snd y = snd zH:E.eq (fst x) (fst y)H2:snd x = snd ysnd x = snd zcongruence. Qed.elt:Typex, y, z:(key * elt)%typeH0:E.eq (fst y) (fst z)H1:snd y = snd zH:E.eq (fst x) (fst y)H2:snd x = snd ysnd x = snd z
Complements about InA, NoDupA and findA
elt:Typeforall (k1 k2 : E.t) (e1 e2 : elt) (l : list (key * elt)), E.eq k1 k2 -> InA eqke (k1, e1) l -> InA eqk (k2, e2) lelt:Typeforall (k1 k2 : E.t) (e1 e2 : elt) (l : list (key * elt)), E.eq k1 k2 -> InA eqke (k1, e1) l -> InA eqk (k2, e2) lelt:Typek1, k2:E.te1, e2:eltl:list (key * elt)Hk:E.eq k1 k2InA eqke (k1, e1) l -> InA eqk (k2, e2) lelt:Typek1, k2:E.te1, e2:eltl:list (key * elt)Hk:E.eq k1 k2(exists y : key * elt, eqke (k1, e1) y /\ List.In y l) -> exists y : key * elt, eqk (k2, e2) y /\ List.In y lelt:Typek1, k2:E.te1, e2:eltl:list (key * elt)Hk:E.eq k1 k2k':keye':eltHk':E.eq k1 k'He':e1 = e'H:List.In (k', e') lexists y : key * elt, eqk (k2, e2) y /\ List.In y lred; simpl; eauto. Qed.elt:Typek1, k2:E.te1, e2:eltl:list (key * elt)Hk:E.eq k1 k2k':keye':eltHk':E.eq k1 k'He':e1 = e'H:List.In (k', e') leqk (k2, e2) (k', e')elt:Typeforall l : list (key * elt), NoDupA eqk l -> NoDupA eqke lelt:Typeforall l : list (key * elt), NoDupA eqk l -> NoDupA eqke lelt:Typex:(key * elt)%typel:list (key * elt)H:~ InA eqk x lH0:NoDupA eqk lIHNoDupA:NoDupA eqke lNoDupA eqke (x :: l)elt:Typex:(key * elt)%typel:list (key * elt)H:~ InA eqk x lH0:NoDupA eqk lIHNoDupA:NoDupA eqke l~ InA eqke x leauto using InA_eqke_eqk. Qed.elt:Typek:keye:eltl:list (key * elt)H:~ InA eqk (k, e) lH0:NoDupA eqk lIHNoDupA:NoDupA eqke l~ InA eqke (k, e) lelt:Typeforall (l : list (key * elt)) (k : E.t), NoDupA eqk l -> findA (eqb k) l = findA (eqb k) (rev l)elt:Typeforall (l : list (key * elt)) (k : E.t), NoDupA eqk l -> findA (eqb k) l = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk lfindA (eqb k) l = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk lforall e : elt, findA (eqb k) l = Some e -> Some e = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk lfindA (eqb k) l = None -> None = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk le:eltH0:findA (eqb k) l = Some eSome e = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk lfindA (eqb k) l = None -> None = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk le:eltH0:findA (eqb k) l = Some efindA (eqb k) (rev l) = Some eelt:Typel:list (key * elt)k:E.tH:NoDupA eqk lfindA (eqb k) l = None -> None = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk le:eltH0:findA (eqb k) l = Some efindA (fun y : E.t => if eq_dec k y then true else false) (rev l) = Some eelt:Typel:list (key * elt)k:E.tH:NoDupA eqk lfindA (eqb k) l = None -> None = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk lfindA (eqb k) l = None -> None = findA (eqb k) (rev l)elt:Typel:list (key * elt)k:E.tH:NoDupA eqk lforall e : elt, findA (eqb k) (rev l) = Some e -> findA (eqb k) l = None -> None = Some eelt:Typel:list (key * elt)k:E.tH:NoDupA eqk le:eltfindA (eqb k) (rev l) = Some e -> findA (eqb k) l = None -> None = Some eelt:Typel:list (key * elt)k:E.tH:NoDupA eqk le:eltfindA (fun y : E.t => if eq_dec k y then true else false) (rev l) = Some e -> findA (fun y : E.t => if eq_dec k y then true else false) l = None -> None = Some eintro Eq; rewrite Eq; auto. Qed.elt:Typel:list (key * elt)k:E.tH:NoDupA eqk le:eltfindA (fun a' : E.t => if ?Goal0 k a' then true else false) l = Some e -> findA (fun y : E.t => if eq_dec k y then true else false) l = None -> None = Some e
elt:Typeforall m : t elt, Empty m <-> elements m = nilelt:Typeforall m : t elt, Empty m <-> elements m = nilelt:Typem:t eltEmpty m <-> elements m = nilelt:Typem:t elt(forall (a : key) (e : elt), ~ MapsTo a e m) <-> elements m = nilelt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e melements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mforall a : key * elt, ~ List.In a (elements m)elt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mH0:forall a : key * elt, ~ List.In a (elements m)elements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a0 : key) (e : elt), ~ MapsTo a0 e ma:(key * elt)%typeH0:List.In a (elements m)Falseelt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mH0:forall a : key * elt, ~ List.In a (elements m)elements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a0 : key) (e : elt), ~ MapsTo a0 e ma:(key * elt)%typeH0:List.In a (elements m)MapsTo (fst a) (snd a) melt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mH0:forall a : key * elt, ~ List.In a (elements m)elements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a0 : key) (e : elt), ~ MapsTo a0 e ma:(key * elt)%typeH0:List.In a (elements m)InA eqke (fst a, snd a) (elements m)elt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mH0:forall a : key * elt, ~ List.In a (elements m)elements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a0 : key) (e : elt), ~ MapsTo a0 e ma:(key * elt)%typeH0:List.In a (elements m)eqke (fst a, snd a) a /\ List.In a (elements m)elt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mH0:forall a : key * elt, ~ List.In a (elements m)elements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mH0:forall a : key * elt, ~ List.In a (elements m)elements m = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:forall (a : key) (e : elt), ~ MapsTo a e mp:(key * elt)%typel:list (key * elt)H0:forall a : key * elt, ~ List.In a (p :: l)p :: l = nilelt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:elements m = nila:keye:elt~ MapsTo a e melt:Typem:t eltH:elements m = nila:keye:eltH0:MapsTo a e mFalseelt:Typem:t eltH:elements m = nila:keye:eltH0:InA eqke (a, e) (elements m)Falserewrite H in H0; destruct H0 as (_,H0); inversion H0. Qed.elt:Typem:t eltH:elements m = nila:keye:eltx:(key * elt)%typeH0:eqke (a, e) x /\ List.In x (elements m)Falseelt:Typeelements (empty elt) = nilrewrite <-elements_Empty; apply empty_1. Qed.elt:Typeelements (empty elt) = nil
Definition uncurry {U V W : Type} (f : U -> V -> W) : U*V -> W := fun p => f (fst p) (snd p). Definition of_list := List.fold_right (uncurry (@add _)) (empty elt). Definition to_list := elements.elt:Typeforall (l : list (key * elt)) (k : key) (e : elt), NoDupA eqk l -> MapsTo k e (of_list l) <-> InA eqke (k, e) lelt:Typeforall (l : list (key * elt)) (k : key) (e : elt), NoDupA eqk l -> MapsTo k e (of_list l) <-> InA eqke (k, e) lelt:Typek:keye:eltHnodup:NoDupA eqk nilMapsTo k e (empty elt) <-> InA eqke (k, e) nilelt:Typek':keye':eltl:list (key * elt)IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) lk:keye:eltHnodup:NoDupA eqk ((k', e') :: l)MapsTo k e (uncurry (add (elt:=elt)) (k', e') (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)elt:Typek':keye':eltl:list (key * elt)IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) lk:keye:eltHnodup:NoDupA eqk ((k', e') :: l)MapsTo k e (uncurry (add (elt:=elt)) (k', e') (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)elt:Typek':keye':eltl:list (key * elt)IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) lk:keye:eltHnodup:NoDupA eqk ((k', e') :: l)MapsTo k e (add k' e' (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)elt:Typek':keye':eltl:list (key * elt)IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) lk:keye:eltHnotin:~ InA eqk (k', e') lHnodup':NoDupA eqk lMapsTo k e (add k' e' (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)elt:Typek':keye':eltl:list (key * elt)k:keye:eltIH:MapsTo k e (of_list l) <-> InA eqke (k, e) lHnotin:~ InA eqk (k', e') lMapsTo k e (add k' e' (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)elt:Typek':keye':eltl:list (key * elt)k:keye:eltIH:MapsTo k e (of_list l) <-> InA eqke (k, e) lHnotin:~ InA eqk (k', e') lE.eq k' k /\ e' = e \/ ~ E.eq k' k /\ MapsTo k e (of_list l) <-> eqke (k, e) (k', e') \/ MapsTo k e (of_list l)elt:Typek':keye':eltl:list (key * elt)k:keye:eltIH:MapsTo k e (of_list l) <-> InA eqke (k, e) lHnotin:~ InA eqk (k', e') lE.eq k' k /\ e' = e \/ ~ E.eq k' k /\ MapsTo k e (of_list l) <-> E.eq k k' /\ e = e' \/ MapsTo k e (of_list l)elt:Typek':keye':eltl:list (key * elt)k:keye:eltIH:MapsTo k e (of_list l) <-> InA eqke (k, e) lHnotin:~ InA eqk (k', e') lH:MapsTo k e (of_list l)E.eq k' k /\ e' = e \/ ~ E.eq k' k /\ MapsTo k e (of_list l)elt:Typek':keye':eltl:list (key * elt)k:keye:eltIH:MapsTo k e (of_list l) <-> InA eqke (k, e) lHnotin:~ InA eqk (k', e') lH:MapsTo k e (of_list l)e0:E.eq k k'e' = eapply InA_eqke_eqk with k e; intuition. Qed.elt:Typek':keye':eltl:list (key * elt)k:keye:eltIH:MapsTo k e (of_list l) <-> InA eqke (k, e) lH:MapsTo k e (of_list l)e0:E.eq k k'InA eqk (k', e') lelt:Typeforall (l : list (key * elt)) (k : key), NoDupA eqk l -> find k (of_list l) = findA (eqb k) lelt:Typeforall (l : list (key * elt)) (k : key), NoDupA eqk l -> find k (of_list l) = findA (eqb k) lelt:Typek:keyHnodup:NoDupA eqk nilfind k (empty elt) = Noneelt:Typek':keye':eltl:list (key * elt)IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) lk:keyHnodup:NoDupA eqk ((k', e') :: l)find k (uncurry (add (elt:=elt)) (k', e') (of_list l)) = (if eqb k k' then Some e' else findA (eqb k) l)elt:Typek':keye':eltl:list (key * elt)IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) lk:keyHnodup:NoDupA eqk ((k', e') :: l)find k (uncurry (add (elt:=elt)) (k', e') (of_list l)) = (if eqb k k' then Some e' else findA (eqb k) l)elt:Typek':keye':eltl:list (key * elt)IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) lk:keyHnodup:NoDupA eqk ((k', e') :: l)find k (add k' e' (of_list l)) = (if eqb k k' then Some e' else findA (eqb k) l)elt:Typek':keye':eltl:list (key * elt)IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) lk:keyHnotin:~ InA eqk (k', e') lHnodup':NoDupA eqk lfind k (add k' e' (of_list l)) = (if eqb k k' then Some e' else findA (eqb k) l)elt:Typek':keye':eltl:list (key * elt)k:keyIH:find k (of_list l) = findA (eqb k) lHnotin:~ InA eqk (k', e') lfind k (add k' e' (of_list l)) = (if eqb k k' then Some e' else findA (eqb k) l)unfold eqb; do 2 destruct eq_dec as [|?Hnot]; auto; elim Hnot; eauto. Qed.elt:Typek':keye':eltl:list (key * elt)k:keyIH:find k (of_list l) = findA (eqb k) lHnotin:~ InA eqk (k', e') l(if eq_dec k' k then Some e' else findA (eqb k) l) = (if eqb k k' then Some e' else findA (eqb k) l)elt:Typeforall l : list (key * elt), NoDupA eqk l -> equivlistA eqke l (to_list (of_list l))elt:Typeforall l : list (key * elt), NoDupA eqk l -> equivlistA eqke l (to_list (of_list l))rewrite <- elements_mapsto_iff, of_list_1; intuition. Qed.elt:Typel:list (key * elt)Hnodup:NoDupA eqk lk:keye:eltInA eqke (k, e) l <-> InA eqke (k, e) (to_list (of_list l))elt:Typeforall s : t elt, Equal (of_list (to_list s)) selt:Typeforall s : t elt, Equal (of_list (to_list s)) selt:Types:t eltk:keyfind k (of_list (to_list s)) = find k sapply elements_3w. Qed.elt:Types:t eltk:keyNoDupA eqk (to_list s)
Alternative specification via fold_right
elt:Typem:t eltA:Typei:Af:key -> elt -> A -> Afold f m i = fold_right (uncurry f) i (rev (elements m))elt:Typem:t eltA:Typei:Af:key -> elt -> A -> Afold f m i = fold_right (uncurry f) i (rev (elements m))elt:Typem:t eltA:Typei:Af:key -> elt -> A -> Afold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i = fold_right (uncurry f) i (rev (elements m))apply fold_left_rev_right. Qed.elt:Typem:t eltA:Typei:Af:key -> elt -> A -> Afold_right (uncurry f) i (rev (elements m)) = fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i
In the following lemma, the step hypothesis is deliberately restricted
to the precise map m we are considering.
elt:Typeforall (A : Type) (P : t elt -> A -> Type) (f : key -> elt -> A -> A) (i : A) (m : t elt), (forall m0 : t elt, Empty m0 -> P m0 i) -> (forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)) -> P m (fold f m i)elt:Typeforall (A : Type) (P : t elt -> A -> Type) (f : key -> elt -> A -> A) (i : A) (m : t elt), (forall m0 : t elt, Empty m0 -> P m0 i) -> (forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)) -> P m (fold f m i)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)P m (fold f m i)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)P m (fold_right (uncurry f) i (rev (elements m)))elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> AP m (fold_right F i (rev (elements m)))elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)P m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)P m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 m''0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> Add k0 e0 m'0 m''0 -> P m'0 a0 -> P m''0 (f k0 e0 a0)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)k:keye:elta:Am', m'':t eltH:InA eqke (k, e) lH0:~ In k m'H1:Add k e m' m''X:P m' aMapsTo (fst (k, e)) (snd (k, e)) melt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)P m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)P m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)NoDupA eqk lelt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)NoDupA eqk (rev (elements m))elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)NoDupA (fun p p' : key * elt => E.eq (fst p) (fst p')) (elements m)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lforall k : key, find k m = findA (eqb k) lelt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k0 : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k0 e m -> ~ In k0 m' -> Add k0 e m' m'' -> P m' a -> P m'' (f k0 e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k0 : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e) l -> ~ In k0 m' -> Add k0 e m' m'' -> P m' a -> P m'' (F (k0, e) a)Hdup:NoDupA eqk lk:keyfind k m = findA (eqb k) lelt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k0 : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k0 e m -> ~ In k0 m' -> Add k0 e m' m'' -> P m' a -> P m'' (f k0 e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k0 : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e) l -> ~ In k0 m' -> Add k0 e m' m'' -> P m' a -> P m'' (F (k0, e) a)Hdup:NoDupA eqk lk:keyfind k m = findA (eqb k) (rev (elements m))elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k0 : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k0 e m -> ~ In k0 m' -> Add k0 e m' m'' -> P m' a -> P m'' (f k0 e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k0 : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e) l -> ~ In k0 m' -> Add k0 e m' m'' -> P m' a -> P m'' (F (k0, e) a)Hdup:NoDupA eqk lk:keyNoDupA eqk (elements m)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:=rev (elements m):list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:=uncurry f:key * elt -> A -> Al:list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iHstep:forall (k : key) (e : elt) (a : A) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (f k e a)F:key * elt -> A -> Al:list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:Am:t eltHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Al:list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lHsame:forall k : key, find k m = findA (eqb k) lP m (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> Al:list (key * elt)Hstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk lforall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)(* empty *)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> AHstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) nil -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk nilforall m : t elt, (forall k : key, find k m = findA (eqb k) nil) -> P m (fold_right F i nil)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> Aa:(key * elt)%typel:list (key * elt)Hstep':forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) (a :: l) -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)Hdup:NoDupA eqk (a :: l)IHl:(forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)) -> NoDupA eqk l -> forall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)forall m : t elt, (forall k : key, find k m = findA (eqb k) (a :: l)) -> P m (fold_right F i (a :: l))elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> AHstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) nil -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk nilm:t eltHsame:forall k : key, find k m = findA (eqb k) nilP m ielt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> Aa:(key * elt)%typel:list (key * elt)Hstep':forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) (a :: l) -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)Hdup:NoDupA eqk (a :: l)IHl:(forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)) -> NoDupA eqk l -> forall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)forall m : t elt, (forall k : key, find k m = findA (eqb k) (a :: l)) -> P m (fold_right F i (a :: l))elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> AHstep':forall (k : key) (e : elt) (a : A) (m' m'' : t elt), InA eqke (k, e) nil -> ~ In k m' -> Add k e m' m'' -> P m' a -> P m'' (F (k, e) a)Hdup:NoDupA eqk nilm:t eltHsame:forall k : key, find k m = findA (eqb k) nilEmpty melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> Aa:(key * elt)%typel:list (key * elt)Hstep':forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) (a :: l) -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)Hdup:NoDupA eqk (a :: l)IHl:(forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)) -> NoDupA eqk l -> forall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)forall m : t elt, (forall k : key, find k m = findA (eqb k) (a :: l)) -> P m (fold_right F i (a :: l))elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> AHstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) nil -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk nilm:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) nilk:keye:elt~ MapsTo k e melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> Aa:(key * elt)%typel:list (key * elt)Hstep':forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) (a :: l) -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)Hdup:NoDupA eqk (a :: l)IHl:(forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)) -> NoDupA eqk l -> forall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)forall m : t elt, (forall k : key, find k m = findA (eqb k) (a :: l)) -> P m (fold_right F i (a :: l))(* step *)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m : t elt, Empty m -> P m iF:key * elt -> A -> Aa:(key * elt)%typel:list (key * elt)Hstep':forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) (a :: l) -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)Hdup:NoDupA eqk (a :: l)IHl:(forall (k : key) (e : elt) (a0 : A) (m' m'' : t elt), InA eqke (k, e) l -> ~ In k m' -> Add k e m' m'' -> P m' a0 -> P m'' (F (k, e) a0)) -> NoDupA eqk l -> forall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)forall m : t elt, (forall k : key, find k m = findA (eqb k) (a :: l)) -> P m (fold_right F i (a :: l))elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P m (F (k, e) (fold_right F i l))elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)InA eqke (k, e) ((k, e) :: l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)~ In k (of_list l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)~ In k (of_list l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)H:~ InA eqk (k, e) lH0:NoDupA eqk l~ In k (of_list l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)H0:NoDupA eqk lH:In k (of_list l)InA eqk (k, e) lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)H0:NoDupA eqk le':eltHe':MapsTo k e' (of_list l)InA eqk (k, e) lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)H0:NoDupA eqk le':eltHe':MapsTo k e' (of_list l)InA eqke (k, e') lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)Add k e (of_list l) melt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':keyfind k' m = find k' (add k e (of_list l))elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':keyfindA (eqb k') ((k, e) :: l) = (if eq_dec k k' then Some e else findA (eqb k') l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':keyNoDupA eqk lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':key(if eqb k' k then Some e else findA (eqb k') l) = (if eq_dec k k' then Some e else findA (eqb k') l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':keyNoDupA eqk lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':key(if if eq_dec k' k then true else false then Some e else findA (fun y : E.t => if eq_dec k' y then true else false) l) = (if eq_dec k k' then Some e else findA (fun y : E.t => if eq_dec k' y then true else false) l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':keyNoDupA eqk lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)k':keyNoDupA eqk lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)P (of_list l) (fold_right F i l)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)NoDupA eqk lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)forall k0 : key, find k0 (of_list l) = findA (eqb k0) lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)NoDupA eqk lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)forall k0 : key, find k0 (of_list l) = findA (eqb k0) lelt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) ((k, e) :: l) -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k0 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k0, e0) l -> ~ In k0 m' -> Add k0 e0 m' m'' -> P m' a -> P m'' (F (k0, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k0 : key, find k0 m0 = findA (eqb k0) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)forall k0 : key, find k0 (of_list l) = findA (eqb k0) linversion_clear Hdup; auto. Qed.elt, A:TypeP:t elt -> A -> Typei:AHempty:forall m0 : t elt, Empty m0 -> P m0 iF:key * elt -> A -> Ak:keye:eltl:list (key * elt)Hstep':forall (k1 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k1, e0) ((k, e) :: l) -> ~ In k1 m' -> Add k1 e0 m' m'' -> P m' a -> P m'' (F (k1, e0) a)Hdup:NoDupA eqk ((k, e) :: l)IHl:(forall (k1 : key) (e0 : elt) (a : A) (m' m'' : t elt), InA eqke (k1, e0) l -> ~ In k1 m' -> Add k1 e0 m' m'' -> P m' a -> P m'' (F (k1, e0) a)) -> NoDupA eqk l -> forall m0 : t elt, (forall k1 : key, find k1 m0 = findA (eqb k1) l) -> P m0 (fold_right F i l)m:t eltHsame:forall k1 : key, find k1 m = findA (eqb k1) ((k, e) :: l)k0:keyNoDupA eqk l
Same, with empty and add instead of Empty and Add. In this
case, P must be compatible with equality of sets
elt:Typeforall (A : Type) (P : t elt -> A -> Type) (f : key -> elt -> A -> A) (i : A) (m : t elt), (forall (m0 m' : t elt) (a : A), Equal m0 m' -> P m0 a -> P m' a) -> P (empty elt) i -> (forall (k : key) (e : elt) (a : A) (m' : t elt), MapsTo k e m -> ~ In k m' -> P m' a -> P (add k e m') (f k e a)) -> P m (fold f m i)elt:Typeforall (A : Type) (P : t elt -> A -> Type) (f : key -> elt -> A -> A) (i : A) (m : t elt), (forall (m0 m' : t elt) (a : A), Equal m0 m' -> P m0 a -> P m' a) -> P (empty elt) i -> (forall (k : key) (e : elt) (a : A) (m' : t elt), MapsTo k e m -> ~ In k m' -> P m' a -> P (add k e m') (f k e a)) -> P m (fold f m i)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m' : t elt) (a : A), Equal m0 m' -> P m0 a -> P m' aPempty:P (empty elt) iPstep:forall (k : key) (e : elt) (a : A) (m' : t elt), MapsTo k e m -> ~ In k m' -> P m' a -> P (add k e m') (f k e a)P m (fold f m i)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' aPempty:P (empty elt) iPstep:forall (k : key) (e : elt) (a : A) (m' : t elt), MapsTo k e m -> ~ In k m' -> P m' a -> P (add k e m') (f k e a)m0:t eltH:Empty m0P m0 ielt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0Pempty:P (empty elt) iPstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> P m'0 a0 -> P (add k0 e0 m'0) (f k0 e0 a0)k:keye:elta:Am', m'':t eltH:MapsTo k e mH0:~ In k m'H1:Add k e m' m''X:P m' aP m'' (f k e a)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' aPempty:P (empty elt) iPstep:forall (k : key) (e : elt) (a : A) (m' : t elt), MapsTo k e m -> ~ In k m' -> P m' a -> P (add k e m') (f k e a)m0:t eltH:Empty m0Equal (empty elt) m0elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0Pempty:P (empty elt) iPstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> P m'0 a0 -> P (add k0 e0 m'0) (f k0 e0 a0)k:keye:elta:Am', m'':t eltH:MapsTo k e mH0:~ In k m'H1:Add k e m' m''X:P m' aP m'' (f k e a)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' aPempty:P (empty elt) iPstep:forall (k0 : key) (e : elt) (a : A) (m' : t elt), MapsTo k0 e m -> ~ In k0 m' -> P m' a -> P (add k0 e m') (f k0 e a)m0:t eltH:Empty m0k:keyfind k (empty elt) = find k m0elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0Pempty:P (empty elt) iPstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> P m'0 a0 -> P (add k0 e0 m'0) (f k0 e0 a0)k:keye:elta:Am', m'':t eltH:MapsTo k e mH0:~ In k m'H1:Add k e m' m''X:P m' aP m'' (f k e a)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' aPempty:P (empty elt) iPstep:forall (k0 : key) (e : elt) (a : A) (m' : t elt), MapsTo k0 e m -> ~ In k0 m' -> P m' a -> P (add k0 e m') (f k0 e a)m0:t eltH:Empty m0k:keyNone = find k m0elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0Pempty:P (empty elt) iPstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> P m'0 a0 -> P (add k0 e0 m'0) (f k0 e0 a0)k:keye:elta:Am', m'':t eltH:MapsTo k e mH0:~ In k m'H1:Add k e m' m''X:P m' aP m'' (f k e a)elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' aPempty:P (empty elt) iPstep:forall (k0 : key) (e : elt) (a : A) (m' : t elt), MapsTo k0 e m -> ~ In k0 m' -> P m' a -> P (add k0 e m') (f k0 e a)m0:t eltH:Empty m0k:keye':eltMapsTo k e' m0 -> None = Some e'elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0Pempty:P (empty elt) iPstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> P m'0 a0 -> P (add k0 e0 m'0) (f k0 e0 a0)k:keye:elta:Am', m'':t eltH:MapsTo k e mH0:~ In k m'H1:Add k e m' m''X:P m' aP m'' (f k e a)apply Pmorphism with (add k e m'); try intro; auto. Qed.elt, A:TypeP:t elt -> A -> Typef:key -> elt -> A -> Ai:Am:t eltPmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0Pempty:P (empty elt) iPstep:forall (k0 : key) (e0 : elt) (a0 : A) (m'0 : t elt), MapsTo k0 e0 m -> ~ In k0 m'0 -> P m'0 a0 -> P (add k0 e0 m'0) (f k0 e0 a0)k:keye:elta:Am', m'':t eltH:MapsTo k e mH0:~ In k m'H1:Add k e m' m''X:P m' aP m'' (f k e a)elt:Typeforall (A : Type) (P : A -> Type) (f : key -> elt -> A -> A) (i : A) (m : t elt), P i -> (forall (k : key) (e : elt) (a : A), MapsTo k e m -> P a -> P (f k e a)) -> P (fold f m i)intros; apply fold_rec_bis with (P:=fun _ => P); auto. Qed.elt:Typeforall (A : Type) (P : A -> Type) (f : key -> elt -> A -> A) (i : A) (m : t elt), P i -> (forall (k : key) (e : elt) (a : A), MapsTo k e m -> P a -> P (f k e a)) -> P (fold f m i)
fold_rec_weak is a weaker principle than fold_rec_bis :
the step hypothesis must here be applicable anywhere.
At the same time, it looks more like an induction principle,
and hence can be easier to use.
elt:Typeforall (A : Type) (P : t elt -> A -> Type) (f : key -> elt -> A -> A) (i : A), (forall (m m' : t elt) (a : A), Equal m m' -> P m a -> P m' a) -> P (empty elt) i -> (forall (k : key) (e : elt) (a : A) (m : t elt), ~ In k m -> P m a -> P (add k e m) (f k e a)) -> forall m : t elt, P m (fold f m i)intros; apply fold_rec_bis; auto. Qed.elt:Typeforall (A : Type) (P : t elt -> A -> Type) (f : key -> elt -> A -> A) (i : A), (forall (m m' : t elt) (a : A), Equal m m' -> P m a -> P m' a) -> P (empty elt) i -> (forall (k : key) (e : elt) (a : A) (m : t elt), ~ In k m -> P m a -> P (add k e m) (f k e a)) -> forall m : t elt, P m (fold f m i)elt:Typeforall (A B : Type) (R : A -> B -> Type) (f : key -> elt -> A -> A) (g : key -> elt -> B -> B) (i : A) (j : B) (m : t elt), R i j -> (forall (k : key) (e : elt) (a : A) (b : B), MapsTo k e m -> R a b -> R (f k e a) (g k e b)) -> R (fold f m i) (fold g m j)elt:Typeforall (A B : Type) (R : A -> B -> Type) (f : key -> elt -> A -> A) (g : key -> elt -> B -> B) (i : A) (j : B) (m : t elt), R i j -> (forall (k : key) (e : elt) (a : A) (b : B), MapsTo k e m -> R a b -> R (f k e a) (g k e b)) -> R (fold f m i) (fold g m j)elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:Bm:t eltRempty:R i jRstep:forall (k : key) (e : elt) (a : A) (b : B), MapsTo k e m -> R a b -> R (f k e a) (g k e b)R (fold f m i) (fold g m j)elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:Bm:t eltRempty:R i jRstep:forall (k : key) (e : elt) (a : A) (b : B), MapsTo k e m -> R a b -> R (f k e a) (g k e b)R (fold_right (uncurry f) i (rev (elements m))) (fold_right (uncurry g) j (rev (elements m)))elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:Bm:t eltRempty:R i jRstep:forall (k : key) (e : elt) (a : A) (b : B), MapsTo k e m -> R a b -> R (f k e a) (g k e b)l:=rev (elements m):list (key * elt)R (fold_right (uncurry f) i l) (fold_right (uncurry g) j l)elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:Bm:t eltRempty:R i jRstep:forall (k : key) (e : elt) (a : A) (b : B), MapsTo k e m -> R a b -> R (f k e a) (g k e b)l:=rev (elements m):list (key * elt)Rstep':forall (k : key) (e : elt) (a : A) (b : B), InA eqke (k, e) l -> R a b -> R (f k e a) (g k e b)R (fold_right (uncurry f) i l) (fold_right (uncurry g) j l)elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:BRempty:R i jl:list (key * elt)Rstep':forall (k : key) (e : elt) (a : A) (b : B), InA eqke (k, e) l -> R a b -> R (f k e a) (g k e b)R (fold_right (uncurry f) i l) (fold_right (uncurry g) j l)elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:BRempty:R i ja:(key * elt)%typel:list (key * elt)Rstep':forall (k : key) (e : elt) (a0 : A) (b : B), InA eqke (k, e) (a :: l) -> R a0 b -> R (f k e a0) (g k e b)IHl:(forall (k : key) (e : elt) (a0 : A) (b : B), InA eqke (k, e) l -> R a0 b -> R (f k e a0) (g k e b)) -> R (fold_right (uncurry f) i l) (fold_right (uncurry g) j l)R (uncurry f a (fold_right (uncurry f) i l)) (uncurry g a (fold_right (uncurry g) j l))destruct a; simpl; rewrite InA_cons; left; red; auto. Qed.elt, A, B:TypeR:A -> B -> Typef:key -> elt -> A -> Ag:key -> elt -> B -> Bi:Aj:BRempty:R i ja:(key * elt)%typel:list (key * elt)Rstep':forall (k : key) (e : elt) (a0 : A) (b : B), InA eqke (k, e) (a :: l) -> R a0 b -> R (f k e a0) (g k e b)IHl:(forall (k : key) (e : elt) (a0 : A) (b : B), InA eqke (k, e) l -> R a0 b -> R (f k e a0) (g k e b)) -> R (fold_right (uncurry f) i l) (fold_right (uncurry g) j l)InA eqke (fst a, snd a) (a :: l)
From the induction principle on fold, we can deduce some general
induction principles on maps.
elt:Typeforall P : t elt -> Type, (forall m : t elt, Empty m -> P m) -> (forall m m' : t elt, P m -> forall (x : key) (e : elt), ~ In x m -> Add x e m m' -> P m') -> forall m : t elt, P melt:Typeforall P : t elt -> Type, (forall m : t elt, Empty m -> P m) -> (forall m m' : t elt, P m -> forall (x : key) (e : elt), ~ In x m -> Add x e m m' -> P m') -> forall m : t elt, P mapply (@fold_rec _ (fun s _ => P s) (fun _ _ _ => tt) tt m); eauto. Qed.elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : key) (e : elt), ~ In x m0 -> Add x e m0 m' -> P m'm:t eltP melt:Typeforall P : t elt -> Type, (forall m m' : t elt, Equal m m' -> P m -> P m') -> P (empty elt) -> (forall (x : key) (e : elt) (m : t elt), ~ In x m -> P m -> P (add x e m)) -> forall m : t elt, P melt:Typeforall P : t elt -> Type, (forall m m' : t elt, Equal m m' -> P m -> P m') -> P (empty elt) -> (forall (x : key) (e : elt) (m : t elt), ~ In x m -> P m -> P (add x e m)) -> forall m : t elt, P mapply (@fold_rec_bis _ (fun s _ => P s) (fun _ _ _ => tt) tt m); eauto. Qed.elt:TypeP:t elt -> TypeX:forall m0 m' : t elt, Equal m0 m' -> P m0 -> P m'X0:P (empty elt)X1:forall (x : key) (e : elt) (m0 : t elt), ~ In x m0 -> P m0 -> P (add x e m0)m:t eltP m
fold can be used to reconstruct the same initial set.
elt:Typeforall m : t elt, Equal (fold (add (elt:=elt)) m (empty elt)) melt:Typeforall m : t elt, Equal (fold (add (elt:=elt)) m (empty elt)) melt:Typem:t eltEqual (fold (add (elt:=elt)) m (empty elt)) melt:Typem:t eltforall m0 : t elt, Empty m0 -> Equal (empty elt) m0elt:Typem:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> Equal a m' -> Equal (add k e a) m''elt:Typem, m':t eltHeq:Empty m'k':keyfind k' (empty elt) = find k' m'elt:Typem:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> Equal a m' -> Equal (add k e a) m''elt:Typem, m':t eltHeq:Empty m'k':keyNone = find k' m'elt:Typem:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> Equal a m' -> Equal (add k e a) m''elt:Typem, m':t eltHeq:Empty m'k':keye':eltMapsTo k' e' m' -> None = Some e'elt:Typem:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> Equal a m' -> Equal (add k e a) m''elt:Typem:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> Equal a m' -> Equal (add k e a) m''elt:Typem:t eltk:keye:elta, m', m'':t eltHadd:Add k e m' m''Heq:Equal a m'k':keyfind k' (add k e a) = find k' m''rewrite Hadd, 2 add_o, Heq; auto. Qed. Section Fold_More.elt:Typem:t eltk:keye:elta, m', m'':t eltHadd:Add k e m' m''Heq:forall y : key, find y a = find y m'k':keyfind k' (add k e a) = find k' m''
When a function f is compatible and allows transpositions, we can
compute fold f in any order.
Variables (A:Type)(eqA:A->A->Prop)(st:Equivalence eqA)(f:key->elt->A->A).
This is more convenient than a compat_op eqke ....
In fact, every compat_op, compat_bool, etc, should
become a Proper someday.
Hypothesis Comp : Proper (E.eq==>eq==>eqA==>eqA) f.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fforall (m : t elt) (i i' : A), eqA i i' -> eqA (fold f m i) (fold f m i')elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fforall (m : t elt) (i i' : A), eqA i i' -> eqA (fold f m i) (fold f m i')elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti, i':AH:eqA i i'eqA (fold f m i) (fold f m i')elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti, i':AH:eqA i i'forall (k : key) (e : elt) (a b : A), MapsTo k e m -> eqA a b -> eqA (f k e a) (f k e b)apply Comp; auto. Qed.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti, i':AH:eqA i i'k:keye:elta, b:AH0:MapsTo k e mH1:eqA a beqA (f k e a) (f k e b)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fforall (m : t elt) (i : A), Empty m -> eqA (fold f m i) ielt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fforall (m : t elt) (i : A), Empty m -> eqA (fold f m i) ielt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti:AH:Empty meqA (fold f m i) ielt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti:AH:Empty meqA i ielt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti:AH:Empty mforall (k : key) (e : elt) (a : A), MapsTo k e m -> eqA a i -> eqA (f k e a) ielt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti:AH:Empty mforall (k : key) (e : elt) (a : A), MapsTo k e m -> eqA a i -> eqA (f k e a) ielim (H k e); auto. Qed.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fm:t elti:AH:Empty mk:keye:elta:AH0:MapsTo k e mH1:eqA a ieqA (f k e a) i
As noticed by P. Casteran, asking for the general SetoidList.transpose
here is too restrictive. Think for instance of f being M.add :
in general, M.add k e (M.add k e' m) is not equivalent to
M.add k e' (M.add k e m). Fortunately, we will never encounter this
situation during a real fold, since the keys received by this fold
are unique. Hence we can ask the transposition property to hold only
for non-equal keys.
This idea could be push slightly further, by asking the transposition
property to hold only for (non-equal) keys living in the map given to
fold. Please contact us if you need such a version.
FSets could also benefit from a restricted transpose, but for this
case the gain is unclear.
Definition transpose_neqkey := forall k k' e e' a, ~E.eq k k' -> eqA (f k e (f k' e' a)) (f k' e' (f k e a)). Hypothesis Tra : transpose_neqkey.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (i : A) (m : t elt) (k : key) (e : elt), ~ In k m -> eqA (fold f m (f k e i)) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (i : A) (m : t elt) (k : key) (e : elt), ~ In k m -> eqA (fold f m (f k e i)) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k meqA (fold f m (f k e i)) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k meqA (f k e i) (f k e i)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mforall (k0 : key) (e0 : elt) (a b : A), MapsTo k0 e0 m -> eqA a (f k e b) -> eqA (f k0 e0 a) (f k e (f k0 e0 b))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mforall (k0 : key) (e0 : elt) (a b : A), MapsTo k0 e0 m -> eqA a (f k e b) -> eqA (f k0 e0 a) (f k e (f k0 e0 b))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mk0:keye0:elta, b:AH:MapsTo k0 e0 mH0:eqA a (f k e b)eqA (f k0 e0 a) (f k e (f k0 e0 b))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mk0:keye0:elta, b:AH:MapsTo k0 e0 mH0:eqA a (f k e b)eqA (f k0 e0 a) (f k0 e0 (f k e b))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mk0:keye0:elta, b:AH:MapsTo k0 e0 mH0:eqA a (f k e b)eqA (f k0 e0 (f k e b)) (f k e (f k0 e0 b))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mk0:keye0:elta, b:AH:MapsTo k0 e0 mH0:eqA a (f k e b)eqA (f k0 e0 (f k e b)) (f k e (f k0 e0 b))contradict Hnotin; rewrite <- Hnotin; exists e0; auto. Qed. Hint Resolve NoDupA_eqk_eqke NoDupA_rev elements_3w : map.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyi:Am:t eltk:keye:eltHnotin:~ In k mk0:keye0:elta, b:AH:MapsTo k0 e0 mH0:eqA a (f k e b)~ E.eq k0 kelt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m1 m2 : t elt) (i : A), Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m1 m2 : t elt) (i : A), Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2eqA (fold f m1 i) (fold f m2 i)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqA ==> eqA) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))forall x y : key * elt, E.eq (fst x) (fst y) /\ snd x = snd y -> forall x0 y0 : key * elt, E.eq (fst x0) (fst y0) /\ snd x0 = snd y0 -> ((E.eq (fst x) (fst x0) -> False) -> E.eq (fst y) (fst y0) -> False) /\ ((E.eq (fst y) (fst y0) -> False) -> E.eq (fst x) (fst x0) -> False)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))rewrite 2 InA_rev, <- 2 elements_mapsto_iff, 2 find_mapsto_iff, H; auto with *. Qed.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti:AH:Equal m1 m2H0:NoDupA eqk (rev (elements m1))H1:NoDupA eqk (rev (elements m2))k:keye:eltInA eqke (k, e) (rev (elements m1)) <-> InA eqke (k, e) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m1 m2 : t elt) (i j : A), Equal m1 m2 -> eqA i j -> eqA (fold f m1 i) (fold f m2 j)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m1 m2 : t elt) (i j : A), Equal m1 m2 -> eqA i j -> eqA (fold f m1 i) (fold f m2 j)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jeqA (fold f m1 i) (fold f m2 j)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jeqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) j (rev (elements m2)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) j (rev (elements m2)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) j (rev (elements m2)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqA ==> eqA) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))transpose_restr2 eqA (complement eqk) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))intros (k1,e1) (k2,e2) (Hk,He) a1 a2 Ha; simpl in *; apply Comp; auto.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqA ==> eqA) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)intuition eauto.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))forall x y : key * elt, E.eq (fst x) (fst y) /\ snd x = snd y -> forall x0 y0 : key * elt, E.eq (fst x0) (fst y0) /\ snd x0 = snd y0 -> ((E.eq (fst x) (fst x0) -> False) -> E.eq (fst y) (fst y0) -> False) /\ ((E.eq (fst y) (fst y0) -> False) -> E.eq (fst x) (fst x0) -> False)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))transpose_restr2 eqA (complement eqk) (uncurry f)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))k:keye:eltk':keye':eltz, z':Ah:complement eqk (k, e) (k', e')h':eqA z z'eqA (f k e (f k' e' z)) (f k' e' (f k e z'))auto.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))k:keye:eltk':keye':eltz, z':Ah:complement eqk (k, e) (k', e')h':eqA z z'eqA (f k e (f k' e' z')) (f k' e' (f k e z'))rewrite <- NoDupA_altdef; auto.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m1)) (rev (elements m2))rewrite 2 InA_rev, <- 2 elements_mapsto_iff, 2 find_mapsto_iff, H; auto with *. Qed.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t elti, j:AH:Equal m1 m2H0:eqA i jH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))k:keye:eltInA eqke (k, e) (rev (elements m1)) <-> InA eqke (k, e) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m1 m2 : t elt) (k : key) (e : elt) (i : A), ~ In k m1 -> Add k e m1 m2 -> eqA (fold f m2 i) (f k e (fold f m1 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m1 m2 : t elt) (k : key) (e : elt) (i : A), ~ In k m1 -> Add k e m1 m2 -> eqA (fold f m2 i) (f k e (fold f m1 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2eqA (fold f m2 i) (f k e (fold f m1 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2eqA (fold_right (uncurry f) i (rev (elements m2))) (f k e (fold_right (uncurry f) i (rev (elements m1))))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m2))) (f k e (fold_right f' i (rev (elements m1))))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m2))) (f' (k, e) (fold_right f' i (rev (elements m1))))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))eqA (fold_right f' i (rev (elements m2))) (f' (k, e) (fold_right f' i (rev (elements m1))))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))eqA (fold_right f' i (rev (elements m2))) (f' (k, e) (fold_right f' i (rev (elements m1))))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqA ==> eqA) f'elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) f'elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ InA eqke (k, e) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))k1:keye1:eltk2:keye2:eltHk:E.eq k1 k2He:e1 = e2a, a':AHa:eqA a a'eqA (uncurry f (k1, e1) a) (uncurry f (k2, e2) a')elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) f'elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ InA eqke (k, e) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))Proper (eqke ==> eqke ==> iff) (complement eqk)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) f'elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ InA eqke (k, e) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))transpose_restr eqA (complement eqk) f'elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ InA eqke (k, e) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))ForallOrdPairs (complement eqk) (rev (elements m2))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ InA eqke (k, e) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ InA eqke (k, e) (rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))~ MapsTo k e m1elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltInA eqke (a, b) (rev (elements m2)) <-> InA eqke (a, b) ((k, e) :: rev (elements m1))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltfind a m2 = Some b <-> eqke (a, b) (k, e) \/ find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltfind a m2 = Some b <-> E.eq a k /\ b = e \/ find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltfind a (add k e m1) = Some b <-> E.eq a k /\ b = e \/ find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:elt(if eq_dec k a then Some e else find a m1) = Some b <-> E.eq a k /\ b = e \/ find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltEQ:E.eq k aSome e = Some b -> E.eq a k /\ b = e \/ find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltEQ:E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> Some e = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltNEQ:~ E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltEQ:E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> Some e = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltNEQ:~ E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:In k m1 -> FalseH0:Add k e m1 m2H1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltEQ:E.eq k aH4:find a m1 = Some bX0:ASome e = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltNEQ:~ E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:In k m1 -> FalseH0:Add k e m1 m2H1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltEQ:E.eq k aH4:find a m1 = Some bX0:AIn k m1elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltNEQ:~ E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:~ In k m1H0:Add k e m1 m2f':=uncurry f:key * elt -> A -> AH1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltNEQ:~ E.eq k aE.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some belim NEQ; auto. Qed.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym1, m2:t eltk:keye:elti:AH:In k m1 -> FalseH0:Add k e m1 m2H1:NoDupA eqk (rev (elements m1))H2:NoDupA eqk (rev (elements m2))a:keyb:eltNEQ:E.eq k a -> FalseH3:E.eq a kH5:b = eX0:Afind a m1 = Some belt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m : t elt) (k : key) (e : elt) (i : A), ~ In k m -> eqA (fold f (add k e m) i) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeyforall (m : t elt) (k : key) (e : elt) (i : A), ~ In k m -> eqA (fold f (add k e m) i) (f k e (fold f m i))apply fold_Add; try red; auto. Qed. End Fold_More.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkeym:t eltk:keye:elti:AH:~ In k meqA (fold f (add k e m) i) (f k e (fold f m i))
elt:Typeforall m : t elt, cardinal m = fold (fun (_ : key) (_ : elt) => S) m 0elt:Typeforall m : t elt, cardinal m = fold (fun (_ : key) (_ : elt) => S) m 0symmetry; apply fold_left_length; auto. Qed.elt:Typem:t eltlength (elements m) = fold_left (fun (a : nat) (_ : key * elt) => S a) (elements m) 0elt:Typeforall m : t elt, Empty m <-> cardinal m = 0elt:Typeforall m : t elt, Empty m <-> cardinal m = 0elt:Typem:t eltEmpty m <-> cardinal m = 0destruct (elements m); intuition; discriminate. Qed.elt:Typem:t eltelements m = nil <-> length (elements m) = 0elt:Typeforall m m' : t elt, Equal m m' -> cardinal m = cardinal m'elt:Typeforall m m' : t elt, Equal m m' -> cardinal m = cardinal m'apply fold_Equal with (eqA:=eq); compute; auto. Qed.elt:Typem, m':t eltH:Equal m m'fold (fun (_ : key) (_ : elt) => S) m 0 = fold (fun (_ : key) (_ : elt) => S) m' 0elt:Typeforall m : t elt, Empty m -> cardinal m = 0intros; rewrite <- cardinal_Empty; auto. Qed.elt:Typeforall m : t elt, Empty m -> cardinal m = 0elt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> cardinal m' = S (cardinal m)elt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> cardinal m' = S (cardinal m)elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'fold (fun (_ : key) (_ : elt) => S) m' 0 = S (fold (fun (_ : key) (_ : elt) => S) m 0)apply fold_Add with (eqA:=eq); compute; auto. Qed.elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'fold (fun (_ : key) (_ : elt) => (fun (_ : key) (_ : elt) => S) x e) m' 0 = (fun (_ : key) (_ : elt) => S) x e (fold (fun (_ : key) (_ : elt) => (fun (_ : key) (_ : elt) => S) x e) m 0)elt:Typeforall m : t elt, cardinal m = 0 -> Empty mintros; rewrite cardinal_Empty; auto. Qed. Hint Resolve cardinal_inv_1 : map.elt:Typeforall m : t elt, cardinal m = 0 -> Empty melt:Typeforall (m : t elt) (n : nat), cardinal m = S n -> {p : key * elt | MapsTo (fst p) (snd p) m}elt:Typeforall (m : t elt) (n : nat), cardinal m = S n -> {p : key * elt | MapsTo (fst p) (snd p) m}elt:Typem:t eltn:natH:length (elements m) = S n{p : key * elt | MapsTo (fst p) (snd p) m}elt:Typem:t eltn:natH:length (elements m) = S n(forall (x : key) (e : elt), MapsTo x e m <-> InA eqke (x, e) (elements m)) -> {p : key * elt | MapsTo (fst p) (snd p) m}elt:Typem:t eltn:natp:(key * elt)%typel:list (key * elt)H:length (p :: l) = S n(forall (x : key) (e : elt), MapsTo x e m <-> InA eqke (x, e) (p :: l)) -> {p0 : key * elt | MapsTo (fst p0) (snd p0) m}elt:Typem:t eltn:natp:(key * elt)%typel:list (key * elt)H:length (p :: l) = S nH0:forall (x : key) (e : elt), MapsTo x e m <-> InA eqke (x, e) (p :: l)MapsTo (fst p) (snd p) mconstructor; red; auto. Qed.elt:Typem:t eltn:natk:keye:eltl:list (key * elt)H:length ((k, e) :: l) = S nH0:forall (x : key) (e0 : elt), MapsTo x e0 m <-> InA eqke (x, e0) ((k, e) :: l)InA eqke (k, e) ((k, e) :: l)elt:Typeforall m : t elt, cardinal m <> 0 -> {p : key * elt | MapsTo (fst p) (snd p) m}elt:Typeforall m : t elt, cardinal m <> 0 -> {p : key * elt | MapsTo (fst p) (snd p) m}elt:Typem:t eltH:cardinal m <> 0{p : key * elt | MapsTo (fst p) (snd p) m}elt:Typem:t eltH:0 <> 0(forall n : nat, 0 = S n -> {p : key * elt | MapsTo (fst p) (snd p) m}) -> {p : key * elt | MapsTo (fst p) (snd p) m}elt:Typem:t eltn:natH:S n <> 0(forall n0 : nat, S n = S n0 -> {p : key * elt | MapsTo (fst p) (snd p) m}) -> {p : key * elt | MapsTo (fst p) (snd p) m}eauto. Qed.elt:Typem:t eltn:natH:S n <> 0(forall n0 : nat, S n = S n0 -> {p : key * elt | MapsTo (fst p) (snd p) m}) -> {p : key * elt | MapsTo (fst p) (snd p) m}
Definition Disjoint (m m' : t elt) := forall k, ~(In k m /\ In k m'). Definition Partition (m m1 m2 : t elt) := Disjoint m1 m2 /\ (forall k e, MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2).
Definition filter (f : key -> elt -> bool)(m : t elt) := fold (fun k e m => if f k e then add k e m else m) m (empty _). Definition for_all (f : key -> elt -> bool)(m : t elt) := fold (fun k e b => if f k e then b else false) m true. Definition exists_ (f : key -> elt -> bool)(m : t elt) := fold (fun k e b => if f k e then true else b) m false. Definition partition (f : key -> elt -> bool)(m : t elt) := (filter f m, filter (fun k e => negb (f k e)) m).
update adds to m1 all the bindings of m2. It can be seen as
an union operator which gives priority to its 2nd argument
in case of binding conflit.
Definition update (m1 m2 : t elt) := fold (@add _) m2 m1.
restrict keeps from m1 only the bindings whose key is in m2.
It can be seen as an inter operator, with priority to its 1st argument
in case of binding conflit.
Definition restrict (m1 m2 : t elt) := filter (fun k _ => mem k m2) m1.
diff erases from m1 all bindings whose key is in m2.
Definition diff (m1 m2 : t elt) := filter (fun k _ => negb (mem k m2)) m1. Section Specs. Variable f : key -> elt -> bool. Hypothesis Hf : Proper (E.eq==>eq==>eq) f.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m : t elt) (k : key) (e : elt), MapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m : t elt) (k : key) (e : elt), MapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m : t elt) (k : key) (e : elt), MapsTo k e (fold (fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0) m (empty elt)) <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m : t elt) => if f k e then add k e m else m:key -> elt -> t elt -> t eltforall (m : t elt) (k : key) (e : elt), MapsTo k e (fold f' m (empty elt)) <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall (k : key) (e : elt), MapsTo k e (fold f' m (empty elt)) <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t elt(fun t0 t1 : t elt => forall (k : key) (e : elt), MapsTo k e t1 <-> MapsTo k e t0 /\ f k e = true) m (fold f' m (empty elt))elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall m0 : t elt, Empty m0 -> forall (k : key) (e : elt), MapsTo k e (empty elt) <-> MapsTo k e m0 /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m' /\ f k0 e0 = true) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (f' k e a) <-> MapsTo k0 e0 m'' /\ f k0 e0 = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t eltm, m':t eltHm':Empty m'k:keye:eltMapsTo k e (empty elt) <-> MapsTo k e m' /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m' /\ f k0 e0 = true) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (f' k e a) <-> MapsTo k0 e0 m'' /\ f k0 e0 = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t eltm, m':t eltHm':Empty m'k:keye:eltFalse <-> MapsTo k e m' /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m' /\ f k0 e0 = true) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (f' k e a) <-> MapsTo k0 e0 m'' /\ f k0 e0 = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m':t eltHm':Empty m'k:keye:eltX:t eltH0:MapsTo k e m'H1:f k e = trueFalseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m' /\ f k0 e0 = true) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (f' k e a) <-> MapsTo k0 e0 m'' /\ f k0 e0 = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t eltm:t eltforall (k : key) (e : elt) (a m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m' /\ f k0 e0 = true) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (f' k e a) <-> MapsTo k0 e0 m'' /\ f k0 e0 = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t eltm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:~ In k m1Hadd:Add k e m1 m2IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 acc <-> MapsTo k0 e0 m1 /\ f k0 e0 = truek':keye':eltMapsTo k' e' (f' k e acc) <-> MapsTo k' e' m2 /\ f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t eltm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 acc <-> MapsTo k0 e0 m1 /\ f k0 e0 = truek':keye':eltMapsTo k' e' (f' k e acc) <-> MapsTo k' e' (add k e m1) /\ f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t eltm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 acc <-> MapsTo k0 e0 m1 /\ f k0 e0 = truek':keye':eltMapsTo k' e' (if f k e then add k e acc else acc) <-> MapsTo k' e' (add k e m1) /\ f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = trueX:t eltH:E.eq k k'H1:e = e'f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH0:MapsTo k' e' m1H1:f k' e' = trueE.eq k k' /\ e = e' \/ (E.eq k k' -> False) /\ MapsTo k' e' m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH1:f k' e' = trueH0:E.eq k k'H2:e = e'MapsTo k' e' m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH0:MapsTo k' e' m1H1:f k' e' = trueE.eq k k' /\ e = e' \/ (E.eq k k' -> False) /\ MapsTo k' e' m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH1:f k' e' = trueH0:E.eq k k'H2:e = e'MapsTo k' e' m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH0:MapsTo k' e' m1H1:f k' e' = trueHk:E.eq k k'E.eq k k' /\ e = e'elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH1:f k' e' = trueH0:E.eq k k'H2:e = e'MapsTo k' e' m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH1:f k' e' = trueH0:E.eq k k'H2:e = e'MapsTo k' e' m1congruence. Qed.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltacc, m1, m2:t eltHke:MapsTo k e mHn:In k m1 -> FalseHadd:Equal m2 (add k e m1)k':keye':eltHfke:f k e = falseX:t eltH1:f k' e' = trueH0:E.eq k k'H2:e = e'H:f k e = f k' e'MapsTo k' e' m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m : t elt, for_all f m = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m : t elt, for_all f m = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m : t elt, fold (fun (k : key) (e : elt) (b : bool) => if f k e then b else false) m true = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolforall m : t elt, fold f' m true = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltfold f' m true = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t elt(fun (t0 : t elt) (b : bool) => b = true <-> (forall (k : key) (e : elt), MapsTo k e t0 -> f k e = true)) m (fold f' m true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltforall m0 : t elt, Empty m0 -> true = true <-> (forall (k : key) (e : elt), MapsTo k e m0 -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' -> f k0 e0 = true) -> f' k e a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m'' -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm, m':t eltHm':Empty m'true = true <-> (forall (k : key) (e : elt), MapsTo k e m' -> f k e = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' -> f k0 e0 = true) -> f' k e a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m'' -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm, m':t eltHm':Empty m'true = true -> forall (k : key) (e : elt), MapsTo k e m' -> f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' -> f k0 e0 = true) -> f' k e a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m'' -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b : bool) => if f k0 e0 then b else false:key -> elt -> bool -> boolm, m':t eltHm':Empty m'k:keye:eltHke:MapsTo k e m'f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' -> f k0 e0 = true) -> f' k e a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m'' -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' -> f k0 e0 = true) -> f' k e a = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m'' -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolm:t eltk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Add k e m1 m2IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)f' k e b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Add k e m1 m2IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)f' k e b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)f' k e b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)(if f k e then b else false) = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)(* f k e = true *)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = trueb = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = true(forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true) <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = true(forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true) <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m2f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m1f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = truek':keye':eltHke':E.eq k k' /\ e = e' \/ ~ E.eq k k' /\ MapsTo k' e' m1f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m1f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = truek':keye':eltH:E.eq k k'H0:e = e'f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m1f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m1f k' e' = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m1MapsTo k' e' m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = trueHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truek':keye':eltHke':MapsTo k' e' m1~ E.eq k k'elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)(* f k e = false *)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falsefalse = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = false(forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true) -> false = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falseHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truefalse = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falseHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = truef k e = truerewrite Hadd, add_mapsto_iff; auto. Qed.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true)Hfke:f k e = falseHmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = trueMapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m : t elt, exists_ f m = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m : t elt, exists_ f m = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m : t elt, fold (fun (k : key) (e : elt) (b : bool) => if f k e then true else b) m false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolforall m : t elt, fold f' m false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltfold f' m false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t elt(fun (t0 : t elt) (b : bool) => b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) t0 /\ f (fst p) (snd p) = true)) m (fold f' m false)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltforall m0 : t elt, Empty m0 -> false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m0 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> f' k e a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m'' /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm, m':t eltHm':Empty m'false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> f' k e a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m'' /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm, m':t eltHm':Empty m'(exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> false = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> f' k e a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m'' /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b : bool) => if f k0 e0 then true else b:key -> elt -> bool -> boolm, m':t eltHm':Empty m'k:keye:eltHke:MapsTo k e m'false = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> f' k e a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m'' /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> boolm:t eltforall (k : key) (e : elt) (a : bool) (m' m'' : t elt), MapsTo k e m -> ~ In k m' -> Add k e m' m'' -> a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> f' k e a = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m'' /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolm:t eltk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Add k e m1 m2IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)f' k e b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Add k e m1 m2IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)f' k e b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)f' k e b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)(if f k e then true else b) = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)(* f k e = true *)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = truetrue = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = falseb = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = trueexists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = falseb = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = trueMapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = falseb = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)(* f k e = false *)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = falseb = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true)Hfke:f k e = false(exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true) <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = false(exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true) <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m1Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m2Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m1Hke2:f k' e' = trueMapsTo k' e' m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m2Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m1Hke2:f k' e' = true~ E.eq k k'elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m2Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m1Hke2:f k' e' = trueHn:E.eq k k'In k m1elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m2Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:MapsTo k' e' m2Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltHke1:E.eq k k' /\ e = e' \/ ~ E.eq k k' /\ MapsTo k' e' m1Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltH:E.eq k k'H0:e = e'Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltH:~ E.eq k k'H0:MapsTo k' e' m1Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltH:E.eq k k'H0:e = e'Hke2:f k' e' = trueH1:f k' e' = f k eexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltH:~ E.eq k k'H0:MapsTo k' e' m1Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueexists (k',e'); auto. Qed. End Specs.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) ff':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> boolk:keye:eltb:boolm1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)Hfke:f k e = falsek':keye':eltH:~ E.eq k k'H0:MapsTo k' e' m1Hke2:f k' e' = trueexists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = trueelt:Typeforall m m' : t elt, Disjoint m m' <-> (forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False)elt:Typeforall m m' : t elt, Disjoint m m' <-> (forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False)elt:Typem, m':t elt(forall k : key, ~ (In k m /\ In k m')) -> forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> Falseelt:Typem, m':t elt(forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False) -> forall k : key, ~ (In k m /\ In k m')elt:Typem, m':t eltH:forall k0 : key, ~ (In k0 m /\ In k0 m')k:keyv, v':eltH1:MapsTo k v mH2:MapsTo k v' m'Falseelt:Typem, m':t elt(forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False) -> forall k : key, ~ (In k m /\ In k m')elt:Typem, m':t eltH:forall k0 : key, ~ (In k0 m /\ In k0 m')k:keyv, v':eltH1:MapsTo k v mH2:MapsTo k v' m'In k melt:Typem, m':t eltH:forall k0 : key, ~ (In k0 m /\ In k0 m')k:keyv, v':eltH1:MapsTo k v mH2:MapsTo k v' m'In k m'elt:Typem, m':t elt(forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False) -> forall k : key, ~ (In k m /\ In k m')elt:Typem, m':t eltH:forall k0 : key, ~ (In k0 m /\ In k0 m')k:keyv, v':eltH1:MapsTo k v mH2:MapsTo k v' m'In k m'elt:Typem, m':t elt(forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False) -> forall k : key, ~ (In k m /\ In k m')elt:Typem, m':t elt(forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False) -> forall k : key, ~ (In k m /\ In k m')eapply H; eauto. Qed. Section Partition. Variable f : key -> elt -> bool. Hypothesis Hf : Proper (E.eq==>eq==>eq) f.elt:Typem, m':t eltH:forall (k0 : key) (e e' : elt), MapsTo k0 e m -> MapsTo k0 e' m' -> Falsek:keyv:eltHv:MapsTo k v mv':eltHv':MapsTo k v' m'Falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m m1 : t elt) (k : key) (e : elt), m1 = fst (partition f m) -> MapsTo k e m1 <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m m1 : t elt) (k : key) (e : elt), m1 = fst (partition f m) -> MapsTo k e m1 <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1:t eltk:keye:eltH:m1 = filter f mMapsTo k e m1 <-> MapsTo k e m /\ f k e = trueapply filter_iff; auto. Qed.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltMapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m m2 : t elt) (k : key) (e : elt), m2 = snd (partition f m) -> MapsTo k e m2 <-> MapsTo k e m /\ f k e = falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall (m m2 : t elt) (k : key) (e : elt), m2 = snd (partition f m) -> MapsTo k e m2 <-> MapsTo k e m /\ f k e = falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m2:t eltk:keye:eltH:m2 = filter (fun (k0 : key) (e0 : elt) => negb (f k0 e0)) mMapsTo k e m2 <-> MapsTo k e m /\ f k e = falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltMapsTo k e (filter (fun (k0 : key) (e0 : elt) => negb (f k0 e0)) m) <-> MapsTo k e m /\ f k e = falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltMapsTo k e m /\ negb (f k e) = true <-> MapsTo k e m /\ f k e = falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltH:MapsTo k e mH':negb (f k e) = truef k e = falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltH:MapsTo k e mH':f k e = falsenegb (f k e) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltH:MapsTo k e mH':f k e = falsenegb (f k e) = trueelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltx, y:E.tH:E.eq x yx0, y0:eltH0:x0 = y0negb (f x x0) = negb (f y y0)apply Hf; auto. Qed.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm:t eltk:keye:eltx, y:E.tH:E.eq x yx0, y0:eltH0:x0 = y0f x x0 = f y y0elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m m1 m2 : t elt, partition f m = (m1, m2) -> Partition m m1 m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fforall m m1 m2 : t elt, partition f m = (m1, m2) -> Partition m m1 m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)Partition m m1 m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)Disjoint m1 m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e e' : elt), MapsTo k e m1 -> MapsTo k e' m2 -> Falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)k:keye, e':eltMapsTo k e m1 -> MapsTo k e' m2 -> Falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)k:keye, e':eltMapsTo k e m /\ f k e = true -> MapsTo k e' m /\ f k e' = false -> Falseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)k:keye, e':eltU:MapsTo k e mV:f k e = trueW:MapsTo k e' mZ:f k e' = falseFalseelt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)k:keye:eltMapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2destruct (f k e); intuition. Qed. End Partition.elt:Typef:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm, m1, m2:t eltH:partition f m = (m1, m2)k:keye:eltMapsTo k e m <-> MapsTo k e m /\ f k e = true \/ MapsTo k e m /\ f k e = falseelt:Typeforall (m m1 m2 : t elt) (k : key), Partition m m1 m2 -> In k m -> {In k m1} + {In k m2}elt:Typeforall (m m1 m2 : t elt) (k : key), Partition m m1 m2 -> In k m -> {In k m1} + {In k m2}elt:Typem, m1, m2:t eltk:keyHm:Partition m m1 m2Hk:In k m{In k m1} + {In k m2}elt:Typem, m1, m2:t eltk:keyHm:Partition m m1 m2Hk:In k mH:~ In k m1In k m2elt:Typem, m1, m2:t eltk:keyHm:Disjoint m1 m2Hm':forall (k0 : key) (e : elt), MapsTo k0 e m <-> MapsTo k0 e m1 \/ MapsTo k0 e m2Hk:In k mH:~ In k m1In k m2elt:Typem, m1, m2:t eltk:keyHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2e:eltH0:MapsTo k e m1H:~ In k m1In k m2elt:Typem, m1, m2:t eltk:keyHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2e:eltH0:MapsTo k e m2H:~ In k m1In k m2exists e; auto. Defined.elt:Typem, m1, m2:t eltk:keyHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2e:eltH0:MapsTo k e m2H:~ In k m1In k m2elt:Typeforall m1 m2 : t elt, Disjoint m1 m2 -> Disjoint m2 m1elt:Typeforall m1 m2 : t elt, Disjoint m1 m2 -> Disjoint m2 m1elim (H k); auto. Qed.elt:Typem1, m2:t eltH:Disjoint m1 m2k:keyH1:In k m2H2:In k m1Falseelt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> Partition m m2 m1elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> Partition m m2 m1elt:Typem, m1, m2:t eltH:Disjoint m1 m2H':forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2Disjoint m2 m1elt:Typem, m1, m2:t eltH:Disjoint m1 m2H':forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m2 \/ MapsTo k e m1intros; rewrite H'; intuition. Qed.elt:Typem, m1, m2:t eltH:Disjoint m1 m2H':forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m2 \/ MapsTo k e m1elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> Empty m <-> Empty m1 /\ Empty m2elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> Empty m <-> Empty m1 /\ Empty m2elt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2Empty m <-> Empty m1 /\ Empty m2elt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2Empty m -> Empty m1 /\ Empty m2elt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2Empty m1 /\ Empty m2 -> Empty melt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2He:Empty mEmpty m1 /\ Empty m2elt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2Empty m1 /\ Empty m2 -> Empty melt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2Empty m1 /\ Empty m2 -> Empty melt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2He1:Empty m1He2:Empty m2k:keye:eltHke:MapsTo k e mFalseelt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2He1:Empty m1He2:Empty m2k:keye:eltHke:MapsTo k e m1 \/ MapsTo k e m2Falseelt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2He1:Empty m1He2:Empty m2k:keye:eltH:MapsTo k e m1Falseelt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2He1:Empty m1He2:Empty m2k:keye:eltH:MapsTo k e m2Falseelim (He2 k e); auto. Qed.elt:Typem, m1, m2:t eltHdisj:Disjoint m1 m2Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2He1:Empty m1He2:Empty m2k:keye:eltH:MapsTo k e m2Falseelt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> forall m1 m2 : t elt, Partition m' m1 m2 -> exists m3 : t elt, Add x e m3 m1 /\ Partition m m3 m2 \/ Add x e m3 m2 /\ Partition m m1 m3elt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> forall m1 m2 : t elt, Partition m' m1 m2 -> exists m3 : t elt, Add x e m3 m1 /\ Partition m m3 m2 \/ Add x e m3 m2 /\ Partition m m1 m3elt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> forall m1 m2 : t elt, Disjoint m1 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2) -> exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Equal m (remove x m')elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Equal m' (add x e m)m1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Equal m (remove x m')elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Equal m' (add x e m)m1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Equal m (remove x (add x e m))elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Equal m' (add x e m)m1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2k:keyfind k m = find k (remove x (add x e m))elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Equal m' (add x e m)m1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2k:keyfind k m = (if eq_dec x k then None else if eq_dec x k then Some e else find k m)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Equal m' (add x e m)m1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2k:keyHe:E.eq x kfind k m = Noneelt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')MapsTo x e m'elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m'exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Equal m' (add x e m)m1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')MapsTo x e (add x e m)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m'exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m'exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)(* first case : x in m1 *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Add x e (remove x m1) m1 /\ Disjoint (remove x m1) m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)(* add *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Add x e (remove x m1) m1elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Disjoint (remove x m1) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Equal m1 (add x e (remove x m1))elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Disjoint (remove x m1) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k:keyfind k m1 = find k (add x e (remove x m1))elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Disjoint (remove x m1) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k:keyfind k m1 = (if eq_dec x k then Some e else if eq_dec x k then None else find k m1)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Disjoint (remove x m1) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k:keyHe:E.eq x kfind k m1 = Some eelt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Disjoint (remove x m1) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)(* disjoint *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1Disjoint (remove x m1) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k:keyH1:In k (remove x m1)H2:In k m2Falseelt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k:keyH1:In k (remove x m1)H2:In k m2In k m1 /\ In k m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k:keyH1:In k (remove x m1)H2:In k m2In k m1elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)(* mapsto *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k':keye':eltMapsTo k' e' m <-> MapsTo k' e' (remove x m1) \/ MapsTo k' e' m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k':keye':elt~ E.eq x k' /\ (MapsTo k' e' m1 \/ MapsTo k' e' m2) <-> ~ E.eq x k' /\ MapsTo k' e' m1 \/ MapsTo k' e' m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:In x m -> FalseHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k':keye':eltH1:MapsTo k' e' m2H0:E.eq x k'Falseelt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:In x m -> FalseHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m1k':keye':eltH1:MapsTo k' e' m2H0:E.eq x k'MapsTo x e' m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)(* second case : x in m2 *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2exists m3 : t elt, Add x e m3 m1 /\ Disjoint m3 m2 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m3 \/ MapsTo k e0 m2) \/ Add x e m3 m2 /\ Disjoint m1 m3 /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 m3)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Add x e (remove x m2) m2 /\ Disjoint m1 (remove x m2) /\ (forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2))(* add *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Add x e (remove x m2) m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Disjoint m1 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Equal m2 (add x e (remove x m2))elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Disjoint m1 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k:keyfind k m2 = find k (add x e (remove x m2))elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Disjoint m1 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k:keyfind k m2 = (if eq_dec x k then Some e else if eq_dec x k then None else find k m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Disjoint m1 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k:keyHe:E.eq x kfind k m2 = Some eelt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Disjoint m1 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)(* disjoint *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2Disjoint m1 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k:keyH1:In k m1H2:In k (remove x m2)Falseelt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k:keyH1:In k m1H2:In k (remove x m2)In k m1 /\ In k m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k:keyH1:In k m1H2:In k (remove x m2)In k m2elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)(* mapsto *)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k':keye':eltMapsTo k' e' m <-> MapsTo k' e' m1 \/ MapsTo k' e' (remove x m2)elt:Typem, m':t eltx:keye:eltHn:~ In x mHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k':keye':elt~ E.eq x k' /\ (MapsTo k' e' m1 \/ MapsTo k' e' m2) <-> MapsTo k' e' m1 \/ ~ E.eq x k' /\ MapsTo k' e' m2elt:Typem, m':t eltx:keye:eltHn:In x m -> FalseHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k':keye':eltH1:MapsTo k' e' m1H0:E.eq x k'Falseapply MapsTo_1 with k'; auto. Qed.elt:Typem, m':t eltx:keye:eltHn:In x m -> FalseHadd:Add x e m m'm1, m2:t eltHdisj:Disjoint m1 m2Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2Heq:Equal m (remove x m')H:MapsTo x e m2k':keye':eltH1:MapsTo k' e' m1H0:E.eq x k'MapsTo x e' m1elt:Typeforall (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall f : key -> elt -> A -> A, Proper (E.eq ==> eq ==> eqA ==> eqA) f -> transpose_neqkey eqA f -> forall (m m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))elt:Typeforall (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall f : key -> elt -> A -> A, Proper (E.eq ==> eq ==> eqA ==> eqA) f -> transpose_neqkey eqA f -> forall (m m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fforall (m m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm:t eltHm:Empty mforall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm:t eltHm:Empty mm1, m2:t elti:AHp:Partition m m1 m2eqA (fold f m i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm:t eltHm:Empty mm1, m2:t elti:AHp:Partition m m1 m2eqA i (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m1, m2:t eltHm:Empty m1 /\ Empty m2i:AHp:Partition m m1 m2eqA i (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m1, m2:t eltH:Empty m1H0:Empty m2i:AHp:Partition m m1 m2eqA i (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m1, m2:t eltH:Empty m1H0:Empty m2i:AHp:Partition m m1 m2eqA i ielt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m1 m2 : t elt) (i : A), Partition m m1 m2 -> eqA (fold f m i) (fold f m1 (fold f m2 i))forall (m1 m2 : t elt) (i : A), Partition m' m1 m2 -> eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m3 : t elt) (i0 : A), Partition m m0 m3 -> eqA (fold f m i0) (fold f m0 (fold f m3 i0))m1, m2:t elti:AHp:Partition m' m1 m2eqA (fold f m' i) (fold f m1 (fold f m2 i))(* fst case: m3 is (k,e)::m1 *)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2~ In k m3elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2Hn:In k m3In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2e':eltHe':MapsTo k e' m3In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp1:Disjoint m3 m2Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m3 \/ MapsTo k0 e0 m2e':eltHe':MapsTo k e' m3In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp1:Disjoint m3 m2Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m3 \/ MapsTo k0 e0 m2e':eltHe':MapsTo k e' m3MapsTo k e' melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m' i) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m1 (fold f m2 i)) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m1 (fold f m2 i)) (f k e (fold f m3 (fold f m2 i)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (f k e (fold f m3 (fold f m2 i))) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (f k e (fold f m3 (fold f m2 i))) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m1Hp':Partition m m3 m2H:~ In k m3eqA (fold f m3 (fold f m2 i)) (fold f m i)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))(* snd case: m3 is (k,e)::m2 *)elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3~ In k m3elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3Hn:In k m3In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3e':eltHe':MapsTo k e' m3In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp1:Disjoint m1 m3Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3e':eltHe':MapsTo k e' m3In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp1:Disjoint m1 m3Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3e':eltHe':MapsTo k e' m3MapsTo k e' melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3~ In k m1elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3Hn:In k m1In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3e':eltHe':MapsTo k e' m1In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp1:Disjoint m1 m3Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3H:~ In k m3e':eltHe':MapsTo k e' m1In k melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp1:Disjoint m1 m3Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3H:~ In k m3e':eltHe':MapsTo k e' m1MapsTo k e' melt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m' i) (f k e (fold f m i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m i)) (f k e (fold f m1 (fold f m3 i)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m1 (fold f m3 i))) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m1 (fold f m3 i))) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m1 (fold f m3 i))) (fold f m1 (f k e (fold f m3 i)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m1 (f k e (fold f m3 i))) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m1 (f k e (fold f m3 i))) (f k e (fold f m1 (fold f m3 i)))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m1 (f k e (fold f m3 i))) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m1 (f k e (fold f m3 i))) (fold f m1 (fold f m2 i))elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (f k e (fold f m3 i)) (fold f m2 i)apply fold_Add with (eqA:=eqA); auto. Qed.elt, A:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> AComp:Proper (E.eq ==> eq ==> eqA ==> eqA) fTra:transpose_neqkey eqA fm, m':t eltk:keye:eltHn:~ In k mHadd:Add k e m m'IH:forall (m0 m4 : t elt) (i0 : A), Partition m m0 m4 -> eqA (fold f m i0) (fold f m0 (fold f m4 i0))m1, m2:t elti:AHp:Partition m' m1 m2m3:t eltHadd':Add k e m3 m2Hp':Partition m m1 m3H:~ In k m3H0:~ In k m1eqA (fold f m2 i) (f k e (fold f m3 i))elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> cardinal m = cardinal m1 + cardinal m2elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> cardinal m = cardinal m1 + cardinal m2elt:Typem, m1, m2:t eltH:Partition m m1 m2cardinal m = cardinal m1 + cardinal m2elt:Typem, m1, m2:t eltH:Partition m m1 m2fold (fun (_ : key) (_ : elt) => S) m 0 = fold (fun (_ : key) (_ : elt) => S) m1 0 + cardinal m2elt:Typem, m1, m2:t eltH:Partition m m1 m2f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> natfold f m 0 = fold f m1 0 + cardinal m2elt:Typem, m1, m2:t eltH:Partition m m1 m2f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> natfold f m1 (fold f m2 0) = fold f m1 0 + cardinal m2elt:Typem, m1, m2:t eltH:Partition m m1 m2f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> natfold f m 0 = fold f m1 (fold f m2 0)elt:Typem, m1, m2:t eltH:Partition m m1 m2f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> natfold f m1 (cardinal m2) = fold f m1 0 + cardinal m2elt:Typem, m1, m2:t eltH:Partition m m1 m2f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> natfold f m 0 = fold f m1 (fold f m2 0)apply Partition_fold with (eqA:=eq); repeat red; auto. Qed.elt:Typem, m1, m2:t eltH:Partition m m1 m2f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> natfold f m 0 = fold f m1 (fold f m2 0)elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> let f := fun (k : key) (_ : elt) => mem k m1 in Equal m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))elt:Typeforall m m1 m2 : t elt, Partition m m1 m2 -> let f := fun (k : key) (_ : elt) => mem k m1 in Equal m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> boolEqual m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> boolProper (E.eq ==> eq ==> eq) felt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fEqual m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fEqual m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltEqual m1 m1' /\ Equal m2 (snd (partition f m))elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltEqual m1 m1' /\ Equal m2 m2'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m1 <-> MapsTo k e m1'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m1 <-> MapsTo k e m /\ f k e = trueelt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m1 <-> MapsTo k e m /\ mem k m1 = trueelt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m1 <-> MapsTo k e m /\ In k m1elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m1 <-> MapsTo k e m /\ In k m1elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m1 <-> (MapsTo k e m1 \/ MapsTo k e m2) /\ In k m1elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltH:MapsTo k e m1In k m1elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltH1:In k m1H:MapsTo k e m2MapsTo k e m1elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltH1:In k m1H:MapsTo k e m2MapsTo k e m1elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m2'elt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m /\ f k e = falseelt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m /\ mem k m1 = falseelt:Typem, m1, m2:t eltHm:Partition m m1 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m /\ ~ In k m1elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> MapsTo k e m /\ ~ In k m1elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltMapsTo k e m2 <-> (MapsTo k e m1 \/ MapsTo k e m2) /\ ~ In k m1elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltH:MapsTo k e m2H0:In k m1Falseelt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltH1:In k m1 -> FalseH:MapsTo k e m1MapsTo k e m2elim H1; exists e; auto. Qed.elt:Typem, m1, m2:t eltHm:Disjoint m1 m2Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> boolHf:Proper (E.eq ==> eq ==> eq) fm1':=fst (partition f m):t eltm2':=snd (partition f m):t eltk:keye:eltH1:In k m1 -> FalseH:MapsTo k e m1MapsTo k e m2elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (update m m') <-> MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (update m m') <-> MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (fold (add (elt:=elt)) m' m) <-> MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'elt:Typem, m':t eltforall (k : key) (e : elt), MapsTo k e (fold (add (elt:=elt)) m' m) <-> MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'elt:Typem, m':t elt(fun t0 t1 : t elt => forall (k : key) (e : elt), MapsTo k e t1 <-> MapsTo k e t0 \/ MapsTo k e m /\ ~ In k t0) m' (fold (add (elt:=elt)) m' m)elt:Typem, m':t eltforall m0 : t elt, Empty m0 -> forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m0 \/ MapsTo k e m /\ ~ In k m0elt:Typem, m':t eltforall (k : key) (e : elt) (a m'0 m'' : t elt), MapsTo k e m' -> ~ In k m'0 -> Add k e m'0 m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m'0 \/ MapsTo k0 e0 m /\ ~ In k0 m'0) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (add k e a) <-> MapsTo k0 e0 m'' \/ MapsTo k0 e0 m /\ ~ In k0 m''elt:Typem, m', m0:t eltHm0:Empty m0k:keye:eltMapsTo k e m <-> MapsTo k e m0 \/ MapsTo k e m /\ ~ In k m0elt:Typem, m':t eltforall (k : key) (e : elt) (a m'0 m'' : t elt), MapsTo k e m' -> ~ In k m'0 -> Add k e m'0 m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m'0 \/ MapsTo k0 e0 m /\ ~ In k0 m'0) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (add k e a) <-> MapsTo k0 e0 m'' \/ MapsTo k0 e0 m /\ ~ In k0 m''elt:Typem, m', m0:t eltHm0:Empty m0k:keye:eltH:~ In k m0MapsTo k e m <-> MapsTo k e m0 \/ MapsTo k e m /\ ~ In k m0elt:Typem, m':t eltforall (k : key) (e : elt) (a m'0 m'' : t elt), MapsTo k e m' -> ~ In k m'0 -> Add k e m'0 m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m'0 \/ MapsTo k0 e0 m /\ ~ In k0 m'0) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (add k e a) <-> MapsTo k0 e0 m'' \/ MapsTo k0 e0 m /\ ~ In k0 m''elt:Typem, m', m0:t eltHm0:Empty m0k:keye:eltH:In k m0 -> FalseH1:MapsTo k e m0MapsTo k e melt:Typem, m':t eltforall (k : key) (e : elt) (a m'0 m'' : t elt), MapsTo k e m' -> ~ In k m'0 -> Add k e m'0 m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m'0 \/ MapsTo k0 e0 m /\ ~ In k0 m'0) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (add k e a) <-> MapsTo k0 e0 m'' \/ MapsTo k0 e0 m /\ ~ In k0 m''elt:Typem, m':t eltforall (k : key) (e : elt) (a m'0 m'' : t elt), MapsTo k e m' -> ~ In k m'0 -> Add k e m'0 m'' -> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 a <-> MapsTo k0 e0 m'0 \/ MapsTo k0 e0 m /\ ~ In k0 m'0) -> forall (k0 : key) (e0 : elt), MapsTo k0 e0 (add k e a) <-> MapsTo k0 e0 m'' \/ MapsTo k0 e0 m /\ ~ In k0 m''elt:Typem, m':t eltk:keye:eltm0, m1, m2:t eltHn:~ In k m1Hadd:Add k e m1 m2IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m0 <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m /\ ~ In k0 m1k':keye':eltMapsTo k' e' (add k e m0) <-> MapsTo k' e' m2 \/ MapsTo k' e' m /\ ~ In k' m2elt:Typem, m':t eltk:keye:eltm0, m1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m0 <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m /\ ~ In k0 m1k':keye':eltMapsTo k' e' (add k e m0) <-> MapsTo k' e' m2 \/ MapsTo k' e' m /\ ~ In k' m2elt:Typem, m':t eltk:keye:eltm0, m1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m0 <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m /\ ~ In k0 m1k':keye':eltE.eq k k' /\ e = e' \/ ~ E.eq k k' /\ (MapsTo k' e' m1 \/ MapsTo k' e' m /\ ~ In k' m1) <-> (E.eq k k' /\ e = e' \/ ~ E.eq k k' /\ MapsTo k' e' m1) \/ MapsTo k' e' m /\ ~ (E.eq k k' \/ In k' m1)intuition. Qed.elt:Typem, m':t eltk:keye:eltm0, m1, m2:t eltHn:~ In k m1Hadd:Equal m2 (add k e m1)k':keye':eltE.eq k k' /\ e = e' \/ ~ E.eq k k' /\ (MapsTo k' e' m1 \/ MapsTo k' e' m /\ ~ In k' m1) <-> (E.eq k k' /\ e = e' \/ ~ E.eq k k' /\ MapsTo k' e' m1) \/ MapsTo k' e' m /\ ~ (E.eq k k' \/ In k' m1)elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (update m m') -> {MapsTo k e m'} + {MapsTo k e m /\ ~ In k m'}elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (update m m') -> {MapsTo k e m'} + {MapsTo k e m /\ ~ In k m'}elt:Typem, m':t eltk:keye:eltH:MapsTo k e (update m m'){MapsTo k e m'} + {MapsTo k e m /\ ~ In k m'}elt:Typem, m':t eltk:keye:eltH:MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'{MapsTo k e m'} + {MapsTo k e m /\ ~ In k m'}elim H'; exists e; auto. Defined.elt:Typem, m':t eltk:keye:eltH':In k m' -> FalseH0:MapsTo k e m'MapsTo k e melt:Typeforall (m m' : t elt) (k : key), In k (update m m') <-> In k m \/ In k m'elt:Typeforall (m m' : t elt) (k : key), In k (update m m') <-> In k m \/ In k m'elt:Typem, m':t eltk:keyIn k (update m m') <-> In k m \/ In k m'elt:Typem, m':t eltk:keyIn k (update m m') -> In k m \/ In k m'elt:Typem, m':t eltk:keyIn k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'In k m \/ In k m'elt:Typem, m':t eltk:keyIn k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keyIn k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keyH:In k m'In k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keyH:~ In k m'In k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e m'In k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keyH:~ In k m'In k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e m'MapsTo k e (update m m')elt:Typem, m':t eltk:keyH:~ In k m'In k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keyH:~ In k m'In k m \/ In k m' -> In k (update m m')elt:Typem, m':t eltk:keyH:~ In k m'H':In k mIn k (update m m')elt:Typem, m':t eltk:keyH:~ In k m'e:eltH':MapsTo k e mIn k (update m m')rewrite update_mapsto_iff; right; auto. Qed.elt:Typem, m':t eltk:keyH:~ In k m'e:eltH':MapsTo k e mMapsTo k e (update m m')elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (diff m m') <-> MapsTo k e m /\ ~ In k m'elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (diff m m') <-> MapsTo k e m /\ ~ In k m'elt:Typem, m':t eltk:keye:eltMapsTo k e (diff m m') <-> MapsTo k e m /\ ~ In k m'elt:Typem, m':t eltk:keye:eltMapsTo k e (filter (fun (k0 : key) (_ : elt) => negb (mem k0 m')) m) <-> MapsTo k e m /\ ~ In k m'elt:Typem, m':t eltk:keye:eltMapsTo k e m /\ negb (mem k m') = true <-> MapsTo k e m /\ ~ In k m'elt:Typem, m':t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => negb (mem k0 m'))elt:Typem, m':t eltk:keye:eltH0:MapsTo k e mH1:negb (mem k m') = trueH:In k m'Falseelt:Typem, m':t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => negb (mem k0 m'))intros ? ? Hk _ _ _; rewrite Hk; auto. Qed.elt:Typem, m':t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => negb (mem k0 m'))elt:Typeforall (m m' : t elt) (k : key), In k (diff m m') <-> In k m /\ ~ In k m'elt:Typeforall (m m' : t elt) (k : key), In k (diff m m') <-> In k m /\ ~ In k m'elt:Typem, m':t eltk:keyIn k (diff m m') <-> In k m /\ ~ In k m'elt:Typem, m':t eltk:keyIn k (diff m m') -> In k m /\ ~ In k m'elt:Typem, m':t eltk:keyIn k m /\ ~ In k m' -> In k (diff m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e m /\ ~ In k m'In k m /\ ~ In k m'elt:Typem, m':t eltk:keyIn k m /\ ~ In k m' -> In k (diff m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e mH0:~ In k m'In k melt:Typem, m':t eltk:keyIn k m /\ ~ In k m' -> In k (diff m m')intros ((e,H),H'); exists e; rewrite diff_mapsto_iff; auto. Qed.elt:Typem, m':t eltk:keyIn k m /\ ~ In k m' -> In k (diff m m')elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'elt:Typeforall (m m' : t elt) (k : key) (e : elt), MapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'elt:Typem, m':t eltk:keye:eltMapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'elt:Typem, m':t eltk:keye:eltMapsTo k e (filter (fun (k0 : key) (_ : elt) => mem k0 m') m) <-> MapsTo k e m /\ In k m'elt:Typem, m':t eltk:keye:eltMapsTo k e m /\ mem k m' = true <-> MapsTo k e m /\ In k m'elt:Typem, m':t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => mem k0 m')intros ? ? Hk _ _ _; rewrite Hk; auto. Qed.elt:Typem, m':t eltk:keye:eltProper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => mem k0 m')elt:Typeforall (m m' : t elt) (k : key), In k (restrict m m') <-> In k m /\ In k m'elt:Typeforall (m m' : t elt) (k : key), In k (restrict m m') <-> In k m /\ In k m'elt:Typem, m':t eltk:keyIn k (restrict m m') <-> In k m /\ In k m'elt:Typem, m':t eltk:keyIn k (restrict m m') -> In k m /\ In k m'elt:Typem, m':t eltk:keyIn k m /\ In k m' -> In k (restrict m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e m /\ In k m'In k m /\ In k m'elt:Typem, m':t eltk:keyIn k m /\ In k m' -> In k (restrict m m')elt:Typem, m':t eltk:keye:eltH:MapsTo k e mH0:In k m'In k melt:Typem, m':t eltk:keyIn k m /\ In k m' -> In k (restrict m m')intros ((e,H),H'); exists e; rewrite restrict_mapsto_iff; auto. Qed.elt:Typem, m':t eltk:keyIn k m /\ In k m' -> In k (restrict m m')
specialized versions analyzing only keys (resp. elements)
Definition filter_dom (f : key -> bool) := filter (fun k _ => f k). Definition filter_range (f : elt -> bool) := filter (fun _ => f). Definition for_all_dom (f : key -> bool) := for_all (fun k _ => f k). Definition for_all_range (f : elt -> bool) := for_all (fun _ => f). Definition exists_dom (f : key -> bool) := exists_ (fun k _ => f k). Definition exists_range (f : elt -> bool) := exists_ (fun _ => f). Definition partition_dom (f : key -> bool) := partition (fun k _ => f k). Definition partition_range (f : elt -> bool) := partition (fun _ => f). End Elt.elt:Typeforall x y : t elt, Equal x y -> cardinal x = cardinal yintros; apply Equal_cardinal; auto. Qed.elt:Typeforall x y : t elt, Equal x y -> cardinal x = cardinal yelt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Disjoint x x0 <-> Disjoint y y0elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Disjoint x x0 <-> Disjoint y y0elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Disjoint m1 m2 <-> Disjoint m1' m2'elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'(forall k : key, ~ (In k m1 /\ In k m2)) <-> (forall k : key, ~ (In k m1' /\ In k m2'))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'H:forall k0 : key, ~ (In k0 m1 /\ In k0 m2)k:key~ (In k m1' /\ In k m2')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'H:forall k0 : key, ~ (In k0 m1' /\ In k0 m2')k:key~ (In k m1 /\ In k m2)rewrite Hm1, Hm2; auto. Qed.elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'H:forall k0 : key, ~ (In k0 m1' /\ In k0 m2')k:key~ (In k m1 /\ In k m2)elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> forall x1 y1 : t elt, Equal x1 y1 -> Partition x x0 x1 <-> Partition y y0 y1elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> forall x1 y1 : t elt, Equal x1 y1 -> Partition x x0 x1 <-> Partition y y0 y1elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'm3, m3':t eltHm3:Equal m3 m3'Partition m1 m2 m3 <-> Partition m1' m2' m3'elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'm3, m3':t eltHm3:Equal m3 m3'Disjoint m2 m3 /\ (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2 \/ MapsTo k e m3) <-> Disjoint m2' m3' /\ (forall (k : key) (e : elt), MapsTo k e m1' <-> MapsTo k e m2' \/ MapsTo k e m3')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'm3, m3':t eltHm3:Equal m3 m3'Disjoint m2 m3 /\ (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2 \/ MapsTo k e m3) <-> Disjoint m2 m3 /\ (forall (k : key) (e : elt), MapsTo k e m1' <-> MapsTo k e m2' \/ MapsTo k e m3')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'm3, m3':t eltHm3:Equal m3 m3'H:Disjoint m2 m3H':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 <-> MapsTo k0 e0 m2 \/ MapsTo k0 e0 m3k:keye:eltMapsTo k e m1' <-> MapsTo k e m2' \/ MapsTo k e m3'elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'm3, m3':t eltHm3:Equal m3 m3'H:Disjoint m2 m3H':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1' <-> MapsTo k0 e0 m2' \/ MapsTo k0 e0 m3'k:keye:eltMapsTo k e m1 <-> MapsTo k e m2 \/ MapsTo k e m3rewrite Hm1, Hm2, Hm3; auto. Qed.elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'm3, m3':t eltHm3:Equal m3 m3'H:Disjoint m2 m3H':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1' <-> MapsTo k0 e0 m2' \/ MapsTo k0 e0 m3'k:keye:eltMapsTo k e m1 <-> MapsTo k e m2 \/ MapsTo k e m3elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (update x x0) (update y y0)elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (update x x0) (update y y0)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (update m1 m2) (update m1' m2')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1') (fold (add (elt:=elt)) m2' m1')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Proper (E.eq ==> eq ==> Equal ==> Equal) (add (elt:=elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (add (elt:=elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (add (elt:=elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyfind x (add k e (add k' e' i)) = find x (add k' e' (add k e i))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keye0:E.eq k xe1:E.eq k' xSome e = Some e'elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')intros k k' Hk e e' He m m' Hm; rewrite Hk,He,Hm; red; auto. Qed.elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Proper (E.eq ==> eq ==> Equal ==> Equal) (add (elt:=elt))elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (restrict x x0) (restrict y y0)elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (restrict x x0) (restrict y y0)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (restrict m1 m2) (restrict m1' m2')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1' (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2' then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'forall (k : key) (e : elt) (a b : t elt), MapsTo k e m1' -> Equal a b -> forall y : key, find y (if mem k m2 then add k e a else a) = find y (if mem k m2' then add k e b else b)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k:keye:elti, i':t eltH:MapsTo k e m1'Hii':Equal i i'x:keyfind x (if mem k m2 then add k e i else i) = find x (if mem k m2' then add k e i' else i')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k:keye:elti, i':t eltH:MapsTo k e m1'Hii':Equal i i'x:keyfind x (if mem k m2' then add k e i else i) = find x (if mem k m2' then add k e i' else i')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Proper (E.eq ==> eq ==> Equal ==> Equal) (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.tHk:E.eq k k'e, e':eltHe:e = e'm, m':t eltHm:Equal m m'Equal (if mem k m2 then add k e m else m) (if mem k' m2 then add k' e' m' else m')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.tHk:E.eq k k'e, e':eltHe:e = e'm, m':t eltHm:Equal m m'Equal (if mem k' m2 then add k e m else m) (if mem k' m2 then add k' e' m' else m')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if mem k m2 then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyfind x (if mem k m2 then add k e (if mem k' m2 then add k' e' i else i) else if mem k' m2 then add k' e' i else i) = find x (if mem k' m2 then add k' e' (if mem k m2 then add k e i else i) else if mem k m2 then add k e i else i)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyH:mem k' m2 = trueH0:mem k m2 = truefind x (add k e (add k' e' i)) = find x (add k' e' (add k e i))elim Hneq; eauto. Qed.elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyH:mem k' m2 = trueH0:mem k m2 = truee0:E.eq k xe1:E.eq k' xSome e = Some e'elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (diff x x0) (diff y y0)elt:Typeforall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (diff x x0) (diff y y0)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (diff m1 m2) (diff m1' m2')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1' (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2') then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'forall (k : key) (e : elt) (a b : t elt), MapsTo k e m1' -> Equal a b -> forall y : key, find y (if negb (mem k m2) then add k e a else a) = find y (if negb (mem k m2') then add k e b else b)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k:keye:elti, i':t eltH:MapsTo k e m1'Hii':Equal i i'x:keyfind x (if negb (mem k m2) then add k e i else i) = find x (if negb (mem k m2') then add k e i' else i')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k:keye:elti, i':t eltH:MapsTo k e m1'Hii':Equal i i'x:keyfind x (if negb (mem k m2') then add k e i else i) = find x (if negb (mem k m2') then add k e i' else i')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Equal (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1 (empty elt)) (fold (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m) m1' (empty elt))elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'Proper (E.eq ==> eq ==> Equal ==> Equal) (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.tHk:E.eq k k'e, e':eltHe:e = e'm, m':t eltHm:Equal m m'Equal (if negb (mem k m2) then add k e m else m) (if negb (mem k' m2) then add k' e' m' else m')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.tHk:E.eq k k'e, e':eltHe:e = e'm, m':t eltHm:Equal m m'Equal (if negb (mem k' m2) then add k e m else m) (if negb (mem k' m2) then add k' e' m' else m')elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'transpose_neqkey Equal (fun (k : key) (e : elt) (m : t elt) => if negb (mem k m2) then add k e m else m)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyfind x (if negb (mem k m2) then add k e (if negb (mem k' m2) then add k' e' i else i) else if negb (mem k' m2) then add k' e' i else i) = find x (if negb (mem k' m2) then add k' e' (if negb (mem k m2) then add k e i else i) else if negb (mem k m2) then add k e i else i)elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyH:mem k' m2 = falseH0:mem k m2 = falsefind x (add k e (add k' e' i)) = find x (add k' e' (add k e i))elim Hneq; eauto. Qed. End WProperties_fun.elt:Typem1, m1':t eltHm1:Equal m1 m1'm2, m2':t eltHm2:Equal m2 m2'k, k':E.te, e':elti:t eltHneq:~ E.eq k k'x:keyH:mem k' m2 = falseH0:mem k m2 = falsee0:E.eq k xe1:E.eq k' xSome e = Some e'
Module WProperties (M:WS) := WProperties_fun M.E M. Module Properties := WProperties.
Module OrdProperties (M:S). Module Import ME := OrderedTypeFacts M.E. Module Import O:=KeyOrderedType M.E. Module Import P:=Properties M. Import F. Import M. Section Elt. Variable elt:Type. Notation eqke := (@eqke elt). Notation eqk := (@eqk elt). Notation ltk := (@ltk elt). Notation cardinal := (@cardinal elt). Notation Equal := (@Equal elt). Notation Add := (@Add elt). Definition Above x (m:t elt) := forall y, In y m -> E.lt y x. Definition Below x (m:t elt) := forall y, In y m -> E.lt x y. Section Elements.elt:Typeforall l l' : list (key * elt), Sorted ltk l -> Sorted ltk l' -> equivlistA eqke l l' -> eqlistA eqke l l'apply SortA_equivlistA_eqlistA; eauto with *. Qed. Ltac clean_eauto := unfold O.eqke, O.ltk; simpl; intuition; eauto. Definition gtb (p p':key*elt) := match E.compare (fst p) (fst p') with GT _ => true | _ => false end. Definition leb p := fun p' => negb (gtb p p'). Definition elements_lt p m := List.filter (gtb p) (elements m). Definition elements_ge p m := List.filter (leb p) (elements m).elt:Typeforall l l' : list (key * elt), Sorted ltk l -> Sorted ltk l' -> equivlistA eqke l l' -> eqlistA eqke l l'elt:Typeforall p p' : key * elt, gtb p p' = true <-> ltk p' pelt:Typeforall p p' : key * elt, gtb p p' = true <-> ltk p' pdestruct (E.compare x y); intuition; try discriminate; ME.order. Qed.elt:Typex:keye:elty:keye':eltmatch E.compare x y with | GT _ => true | _ => false end = true <-> E.lt y xelt:Typeforall p p' : key * elt, leb p p' = true <-> ~ ltk p' pelt:Typeforall p p' : key * elt, leb p p' = true <-> ~ ltk p' pdestruct (E.compare x y); intuition; try discriminate; ME.order. Qed.elt:Typex:keye:elty:keye':eltnegb match E.compare x y with | GT _ => true | _ => false end = true <-> ~ E.lt y xelt:Typeforall p : key * elt, Proper (eqke ==> eq) (gtb p)elt:Typeforall p : key * elt, Proper (eqke ==> eq) (gtb p)elt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''gtb (x, e) (a, e') = gtb (x, e) (b, e'')elt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''true = true <-> ltk (a, e') (x, e) -> false = true <-> ltk (b, e'') (x, e) -> true = falseelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = trueelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''H1:true = true <-> E.lt a xH2:false = true <-> E.lt b xtrue = falseelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = trueelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''H1:true = true <-> E.lt a xH2:false = true <-> E.lt b xE.lt b xelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = trueelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''H1:true = true <-> E.lt a xH2:false = true <-> E.lt b xE.lt a xelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = trueelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = trueelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''H1:false = true <-> E.lt a xH2:true = true <-> E.lt b xfalse = trueelt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''H1:false = true <-> E.lt a xH2:true = true <-> E.lt b xE.lt a xrewrite <- H2; auto. Qed.elt:Typex:keye:elta:E.te':eltb:E.te'':eltH:E.eq a bH0:e' = e''H1:false = true <-> E.lt a xH2:true = true <-> E.lt b xE.lt b xelt:Typeforall p : key * elt, Proper (eqke ==> eq) (leb p)elt:Typeforall p : key * elt, Proper (eqke ==> eq) (leb p)unfold leb; f_equal; apply gtb_compat; auto. Qed. Hint Resolve gtb_compat leb_compat elements_3 : map.elt:Typex:(key * elt)%typea, b:(E.t * elt)%typeH:eqke a bleb x a = leb x belt:Typeforall (p : key * elt) (m : t elt), elements m = elements_lt p m ++ elements_ge p melt:Typeforall (p : key * elt) (m : t elt), elements m = elements_lt p m ++ elements_ge p melt:Typep:(key * elt)%typem:t eltelements m = List.filter (gtb p) (elements m) ++ List.filter (fun p' : key * elt => negb (gtb p p')) (elements m)elt:Typep:(key * elt)%typem:t eltforall x y : E.t * elt, gtb p x = true -> gtb p y = false -> ltk x yelt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:gtb (k, e1) (t0, e) = trueH0:gtb (k, e1) (t1, e0) = falseltk (t0, e) (t1, e0)elt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:E.lt t0 kH0:gtb (k, e1) (t1, e0) = falseltk (t0, e) (t1, e0)elt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:E.lt t0 kH0:gtb (k, e1) (t1, e0) = false~ ltk (t1, e0) (k, e1)elt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:E.lt t0 kH0:gtb (k, e1) (t1, e0) = falseH1:~ ltk (t1, e0) (k, e1)ltk (t0, e) (t1, e0)elt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:E.lt t0 kH0:match E.compare k t1 with | GT _ => true | _ => false end = false~ E.lt t1 kelt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:E.lt t0 kH0:gtb (k, e1) (t1, e0) = falseH1:~ ltk (t1, e0) (k, e1)ltk (t0, e) (t1, e0)unfold O.ltk in *; simpl in *; ME.order. Qed.elt:Typek:keye1:eltm:t eltt0:E.te:eltt1:E.te0:eltH:E.lt t0 kH0:gtb (k, e1) (t1, e0) = falseH1:~ ltk (t1, e0) (k, e1)ltk (t0, e) (t1, e0)elt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> eqlistA eqke (elements m') (elements_lt (x, e) m ++ (x, e) :: elements_ge (x, e) m)elt:Typeforall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> eqlistA eqke (elements m') (elements_lt (x, e) m ++ (x, e) :: elements_ge (x, e) m)elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'eqlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (gtb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk ((x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk ((x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'HdRel ltk (x, e) (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'HdRel ltk (x, e) (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall y : E.t * elt, InA eqke y (List.filter (leb (x, e)) (elements m)) -> ltk (x, e) yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'y:(E.t * elt)%typeH1:InA eqke y (List.filter (leb (x, e)) (elements m))ltk (x, e) yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'y:(E.t * elt)%typeH1:InA eqke y (elements m)H2:leb (x, e) y = trueltk (x, e) yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'y:(E.t * elt)%typeH1:InA eqke y (elements m)H2:~ ltk y (x, e)ltk (x, e) yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltH1:InA eqke (t0, e0) (elements m)H2:~ E.lt t0 xE.lt x t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltH1:MapsTo t0 e0 mH2:~ E.lt t0 xE.lt x t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltH1:MapsTo t0 e0 mH2:~ E.lt t0 x~ E.eq x t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltH1:MapsTo t0 e0 mH2:~ E.lt t0 xH3:~ E.eq x t0E.lt x t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH0:Add x e m m't0:E.te0:eltH1:MapsTo t0 e0 mH2:~ E.lt t0 xH:E.eq x t0In x melt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltH1:MapsTo t0 e0 mH2:~ E.lt t0 xH3:~ E.eq x t0E.lt x t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltH1:MapsTo t0 e0 mH2:~ E.lt t0 xH3:~ E.eq x t0E.lt x t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'Sorted ltk (List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (List.filter (gtb (x, e)) (elements m)) -> InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m)) -> ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (List.filter (gtb (x, e)) (elements m))H2:InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m))ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:gtb (x, e) x0 = trueH2:InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m))ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:ltk x0 (x, e)H2:InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m))ltk x0 yelt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH2:InA eqke (t0, e0) ((x, e) :: List.filter (leb (x, e)) (elements m))E.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH4:eqke (t0, e0) (x, e)E.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH4:InA eqke (t0, e0) (List.filter (leb (x, e)) (elements m))E.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH2:E.eq t0 xH4:e0 = eE.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH4:InA eqke (t0, e0) (List.filter (leb (x, e)) (elements m))E.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH4:InA eqke (t0, e0) (List.filter (leb (x, e)) (elements m))E.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH2:InA eqke (t0, e0) (elements m)H4:leb (x, e) (t0, e0) = trueE.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH1:InA eqke (t1, e1) (elements m)H3:E.lt t1 xH2:InA eqke (t0, e0) (elements m)H4:~ ltk (t0, e0) (x, e)E.lt t1 t0elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m'equivlistA eqke (elements m') (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltInA eqke (t0, e0) (elements m') <-> InA eqke (t0, e0) (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> MapsTo t0 e0 m /\ ltk (t0, e0) (x, e) \/ eqke (t0, e0) (x, e) \/ MapsTo t0 e0 m /\ ~ ltk (t0, e0) (x, e)elt:Typem, m':t eltx:keye:eltH:~ In x mH0:Add x e m m't0:E.te0:eltE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> MapsTo t0 e0 m /\ E.lt t0 x \/ E.eq t0 x /\ e0 = e \/ MapsTo t0 e0 m /\ ~ E.lt t0 xelt:Typem, m':t eltx:keye:eltH:In x m -> FalseH0:Add x e m m't0:E.te0:elte1:E.eq t0 xH2:MapsTo t0 e0 mH3:E.lt t0 x -> FalseE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 melt:Typem, m':t eltx:keye:eltH:In x m -> FalseH0:Add x e m m't0:E.te0:eltl:E.lt x t0H1:E.eq x t0 -> FalseH3:MapsTo t0 e0 mMapsTo t0 e0 m /\ E.lt t0 x \/ E.eq t0 x /\ e0 = e \/ MapsTo t0 e0 m /\ (E.lt t0 x -> False)elim H; exists e0; apply MapsTo_1 with t0; auto.elt:Typem, m':t eltx:keye:eltH:In x m -> FalseH0:Add x e m m't0:E.te0:elte1:E.eq t0 xH2:MapsTo t0 e0 mH3:E.lt t0 x -> FalseE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 mfold (~E.lt t0 x); auto. Qed.elt:Typem, m':t eltx:keye:eltH:In x m -> FalseH0:Add x e m m't0:E.te0:eltl:E.lt x t0H1:E.eq x t0 -> FalseH3:MapsTo t0 e0 mMapsTo t0 e0 m /\ E.lt t0 x \/ E.eq t0 x /\ e0 = e \/ MapsTo t0 e0 m /\ (E.lt t0 x -> False)elt:Typeforall (m m' : t elt) (x : E.t) (e : elt), Above x m -> Add x e m m' -> eqlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typeforall (m m' : t elt) (x : E.t) (e : elt), Above x m -> Add x e m m' -> eqlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'eqlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'Sorted ltk (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 (elements m) -> InA eqke y ((x, e) :: nil) -> ltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H2:InA eqke y ((x, e) :: nil)ltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:eqke y (x, e)ltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:InA eqke y nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltt1:E.te1:eltH1:InA eqke (t0, e0) (elements m)H3:eqke (t1, e1) (x, e)ltk (t0, e0) (t1, e1)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:InA eqke y nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltt1:E.te1:eltH1:MapsTo t0 e0 mH3:eqke (t1, e1) (x, e)ltk (t0, e0) (t1, e1)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:InA eqke y nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltt1:E.te1:eltH1:MapsTo t0 e0 mH2:E.eq t1 xH3:e1 = eE.lt t0 t1elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:InA eqke y nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltt1:E.te1:eltH1:MapsTo t0 e0 mH2:E.eq t1 xH3:e1 = eE.lt t0 xelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:InA eqke y nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 (elements m)H3:InA eqke y nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m'equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltInA eqke (t0, e0) (elements m') <-> InA eqke (t0, e0) (elements m ++ (x, e) :: nil)elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> MapsTo t0 e0 m \/ eqke (t0, e0) (x, e) \/ Falseelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> MapsTo t0 e0 m \/ E.eq t0 x /\ e0 = e \/ Falseelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mE.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 melt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0E.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 melt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0Falseelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0In t0 melt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0H1:In t0 mFalseelt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0H1:In t0 mFalseME.order. Qed.elt:Typem, m':t eltx:E.te:eltH:Above x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0H1:In t0 mE.lt t0 x -> Falseelt:Typeforall (m m' : t elt) (x : E.t) (e : elt), Below x m -> Add x e m m' -> eqlistA eqke (elements m') ((x, e) :: elements m)elt:Typeforall (m m' : t elt) (x : E.t) (e : elt), Below x m -> Add x e m m' -> eqlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'eqlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'Sorted ltk ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'Sorted ltk (((x, e) :: nil) ++ elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'forall x0 y : E.t * elt, InA eqke x0 ((x, e) :: nil) -> InA eqke y (elements m) -> ltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH1:InA eqke x0 ((x, e) :: nil)H2:InA eqke y (elements m)ltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:eqke x0 (x, e)ltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:InA eqke x0 nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH2:InA eqke (t0, e0) (elements m)H3:eqke (t1, e1) (x, e)ltk (t1, e1) (t0, e0)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:InA eqke x0 nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH2:MapsTo t0 e0 mH3:eqke (t1, e1) (x, e)ltk (t1, e1) (t0, e0)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:InA eqke x0 nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH2:MapsTo t0 e0 mH1:E.eq t1 xH3:e1 = eE.lt t1 t0elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:InA eqke x0 nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't1:E.te1:eltt0:E.te0:eltH2:MapsTo t0 e0 mH1:E.eq t1 xH3:e1 = eE.lt x t0elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:InA eqke x0 nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'x0, y:(E.t * elt)%typeH2:InA eqke y (elements m)H3:InA eqke x0 nilltk x0 yelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m'equivlistA eqke (elements m') ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltInA eqke (t0, e0) (elements m') <-> InA eqke (t0, e0) ((x, e) :: elements m)elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> eqke (t0, e0) (x, e) \/ MapsTo t0 e0 melt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltE.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> E.eq t0 x /\ e0 = e \/ MapsTo t0 e0 melt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mE.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 melt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0E.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 melt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0Falseelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0In t0 melt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0H1:In t0 mFalseelt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0H1:In t0 mFalseME.order. Qed.elt:Typem, m':t eltx:E.te:eltH:Below x mH0:Add x e m m't0:E.te0:eltH2:MapsTo t0 e0 mHeq:E.eq x t0H1:In t0 mE.lt x t0 -> Falseelt:Typeforall m m' : t elt, Equal m m' -> eqlistA eqke (elements m) (elements m')elt:Typeforall m m' : t elt, Equal m m' -> eqlistA eqke (elements m) (elements m')elt:Typem, m':t eltH:Equal m m'eqlistA eqke (elements m) (elements m')elt:Typem, m':t eltH:Equal m m'equivlistA eqke (elements m) (elements m')elt:Typem, m':t eltH:Equal m m'x:(E.t * elt)%typeInA eqke x (elements m) <-> InA eqke x (elements m')do 2 rewrite find_mapsto_iff; rewrite H; split; auto. Qed. End Elements. Section Min_Max_Elt.elt:Typem, m':t eltH:Equal m m't0:E.te:eltMapsTo t0 e m <-> MapsTo t0 e m'
We emulate two max_elt and min_elt functions.
Fixpoint max_elt_aux (l:list (key*elt)) := match l with | nil => None | (x,e)::nil => Some (x,e) | (x,e)::l => max_elt_aux l end. Definition max_elt m := max_elt_aux (elements m).elt:Typeforall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> Above x (remove x m)elt:Typeforall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> Above x (remove x m)elt:Typem:t eltx:keye:eltH:max_elt m = Some (x, e)y:keyH0:In y (remove x m)E.lt y xelt:Typem:t eltx:keye:eltH:max_elt m = Some (x, e)y:keyH0:~ E.eq x y /\ In y mE.lt y xelt:Typem:t eltx:keye:eltH:max_elt m = Some (x, e)y:keyH0:~ E.eq x yH1:In y mE.lt y xelt:Typem:t eltx:keye:eltH:max_elt m = Some (x, e)y:keyH0:~ E.eq x yH1:exists e0 : elt, InA (eq_key_elt (elt:=elt)) (y, e0) (elements m)E.lt y xelt:Typem:t eltx:keye:eltH:max_elt m = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)E.lt y xelt:Typem:t eltx:keye:eltH:max_elt_aux (elements m) = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)E.lt y xelt:Typem:t eltx:keye:eltH:max_elt_aux (elements m) = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)Sorted (lt_key (elt:=elt)) (elements m) -> E.lt y xelt:Typem:t eltforall (x : key) (e : elt), max_elt_aux (elements m) = Some (x, e) -> forall (y : key) (x0 : elt), ~ E.eq x y -> InA (eq_key_elt (elt:=elt)) (y, x0) (elements m) -> Sorted (lt_key (elt:=elt)) (elements m) -> E.lt y xelt:Typem:t eltforall (x : key) (e : elt), max_elt_aux nil = Some (x, e) -> forall (y : key) (x0 : elt), ~ E.eq x y -> InA (eq_key_elt (elt:=elt)) (y, x0) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y xelt:Typem:t elta:(key * elt)%typel:list (key * elt)IHl:forall (x : key) (e : elt), max_elt_aux l = Some (x, e) -> forall (y : key) (x0 : elt), ~ E.eq x y -> InA (eq_key_elt (elt:=elt)) (y, x0) l -> Sorted (lt_key (elt:=elt)) l -> E.lt y xforall (x : key) (e : elt), max_elt_aux (a :: l) = Some (x, e) -> forall (y : key) (x0 : elt), ~ E.eq x y -> InA (eq_key_elt (elt:=elt)) (y, x0) (a :: l) -> Sorted (lt_key (elt:=elt)) (a :: l) -> E.lt y xelt:Typem:t elta:(key * elt)%typel:list (key * elt)IHl:forall (x : key) (e : elt), max_elt_aux l = Some (x, e) -> forall (y : key) (x0 : elt), ~ E.eq x y -> InA (eq_key_elt (elt:=elt)) (y, x0) l -> Sorted (lt_key (elt:=elt)) l -> E.lt y xforall (x : key) (e : elt), max_elt_aux (a :: l) = Some (x, e) -> forall (y : key) (x0 : elt), ~ E.eq x y -> InA (eq_key_elt (elt:=elt)) (y, x0) (a :: l) -> Sorted (lt_key (elt:=elt)) (a :: l) -> E.lt y xelt:Typem:t elta:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e0 : elt), max_elt_aux l = Some (x1, e0) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) l -> Sorted (lt_key (elt:=elt)) l -> E.lt y0 x1x:keye:eltH:max_elt_aux (a :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) (a :: l)H2:Sorted (lt_key (elt:=elt)) (a :: l)E.lt y xelt:Typem:t eltk:keye0:eltIHl:forall (x1 : key) (e1 : elt), None = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:eltH:Some (k, e0) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: nil)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: nil)E.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltIHl:forall (x1 : key) (e0 : elt), None = Some (x1, e0) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:elty:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((x, e) :: nil)H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)E.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltIHl:forall (x1 : key) (e0 : elt), None = Some (x1, e0) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:elty:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)H:eq_key_elt (y, x0) (x, e)E.lt y xelt:Typem:t eltIHl:forall (x1 : key) (e0 : elt), None = Some (x1, e0) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:elty:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)H:InA (eq_key_elt (elt:=elt)) (y, x0) nilE.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltIHl:forall (x1 : key) (e0 : elt), None = Some (x1, e0) -> forall (y0 : key) (x2 : elt), (E.eq x1 y0 -> False) -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:elty:keyx0:eltH0:E.eq x y -> FalseH2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)H1:E.eq y xH3:x0 = eE.lt y xelt:Typem:t eltIHl:forall (x1 : key) (e0 : elt), None = Some (x1, e0) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:elty:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)H:InA (eq_key_elt (elt:=elt)) (y, x0) nilE.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltIHl:forall (x1 : key) (e0 : elt), None = Some (x1, e0) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) nil -> Sorted (lt_key (elt:=elt)) nil -> E.lt y0 x1x:keye:elty:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)H:InA (eq_key_elt (elt:=elt)) (y, x0) nilE.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)IHl:forall (x1 : key) (e1 : elt), (let (x2, e2) := p in match l with | nil => Some (x2, e2) | _ :: _ => max_elt_aux l end) = Some (x1, e1) -> forall (y0 : key) (x2 : elt), ~ E.eq x1 y0 -> InA (eq_key_elt (elt:=elt)) (y0, x2) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 x1x:keye:eltH:max_elt_aux (p :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)E.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)x:keye:eltH:max_elt_aux (p :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: p :: l)H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 xE.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)x:keye:eltH:max_elt_aux (p :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 xH3:eq_key_elt (y, x0) (k, e0)E.lt y xelt:Typem:t eltk:keye0:eltp:(key * elt)%typel:list (key * elt)x:keye:eltH:max_elt_aux (p :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: p :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) (p :: l) -> Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0E.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0E.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Heq:E.eq p1 xE.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Heq:E.eq p1 xE.lt y p1elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yIHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Heq:E.eq p1 xH4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)H5:HdRel (lt_key (elt:=elt)) (k, e0) ((p1, p2) :: l)E.lt y p1elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yIHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Heq:E.eq p1 xH4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)H2:lt_key (k, e0) (p1, p2)E.lt y p1elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt y xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt y p1elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt p1 xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yIHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xH4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)H5:HdRel (lt_key (elt:=elt)) (k, e0) ((p1, p2) :: l)E.lt y p1elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt p1 xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yIHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xH4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)H2:lt_key (k, e0) (p1, p2)E.lt y p1elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt p1 xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xE.lt p1 xelt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xInA (eq_key_elt (elt:=elt)) (p1, ?x0) ((p1, p2) :: l)elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xSorted (lt_key (elt:=elt)) ((p1, p2) :: l)elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xeq_key_elt (p1, ?x0) (p1, p2)elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xSorted (lt_key (elt:=elt)) ((p1, p2) :: l)inversion H2; auto. Qed.elt:Typem:t eltk:keye0:eltp1:keyp2:eltl:list (key * elt)x:keye:eltH:max_elt_aux ((p1, p2) :: l) = Some (x, e)y:keyx0:eltH0:~ E.eq x yH2:Sorted (lt_key (elt:=elt)) ((k, e0) :: (p1, p2) :: l)IHl:forall (y0 : key) (x1 : elt), ~ E.eq x y0 -> InA (eq_key_elt (elt:=elt)) (y0, x1) ((p1, p2) :: l) -> Sorted (lt_key (elt:=elt)) ((p1, p2) :: l) -> E.lt y0 xH1:E.eq y kH3:x0 = e0Hneq:~ E.eq p1 xSorted (lt_key (elt:=elt)) ((p1, p2) :: l)elt:Typeforall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> MapsTo x e melt:Typeforall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> MapsTo x e melt:Typem:t eltx:keye:eltH:max_elt m = Some (x, e)MapsTo x e melt:Typem:t eltx:keye:eltH:max_elt_aux (elements m) = Some (x, e)MapsTo x e melt:Typem:t eltx:keye:eltH:max_elt_aux (elements m) = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) (elements m)elt:Typem:t eltx:keye:eltH:max_elt_aux nil = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) nilelt:Typem:t eltx:keye:elta:(key * elt)%typel:list (key * elt)H:max_elt_aux (a :: l) = Some (x, e)IHl:max_elt_aux l = Some (x, e) -> InA (eq_key_elt (elt:=elt)) (x, e) lInA (eq_key_elt (elt:=elt)) (x, e) (a :: l)elt:Typem:t eltx:keye:elta:(key * elt)%typel:list (key * elt)H:max_elt_aux (a :: l) = Some (x, e)IHl:max_elt_aux l = Some (x, e) -> InA (eq_key_elt (elt:=elt)) (x, e) lInA (eq_key_elt (elt:=elt)) (x, e) (a :: l)elt:Typem:t eltx:keye:eltk:keye0:eltH:Some (k, e0) = Some (x, e)IHl:None = Some (x, e) -> InA (eq_key_elt (elt:=elt)) (x, e) nilInA (eq_key_elt (elt:=elt)) (x, e) ((k, e0) :: nil)elt:Typem:t eltx:keye:eltk:keye0:eltp:(key * elt)%typel:list (key * elt)H:(let (x0, e1) := p in match l with | nil => Some (x0, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)IHl:(let (x0, e1) := p in match l with | nil => Some (x0, e1) | _ :: _ => max_elt_aux l end) = Some (x, e) -> InA (eq_key_elt (elt:=elt)) (x, e) (p :: l)InA (eq_key_elt (elt:=elt)) (x, e) ((k, e0) :: p :: l)constructor 2; auto. Qed.elt:Typem:t eltx:keye:eltk:keye0:eltp:(key * elt)%typel:list (key * elt)H:(let (x0, e1) := p in match l with | nil => Some (x0, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)IHl:(let (x0, e1) := p in match l with | nil => Some (x0, e1) | _ :: _ => max_elt_aux l end) = Some (x, e) -> InA (eq_key_elt (elt:=elt)) (x, e) (p :: l)InA (eq_key_elt (elt:=elt)) (x, e) ((k, e0) :: p :: l)elt:Typeforall m : t elt, max_elt m = None -> Empty melt:Typeforall m : t elt, max_elt m = None -> Empty melt:Typem:t eltH:max_elt m = NoneEmpty melt:Typem:t eltH:max_elt_aux (elements m) = NoneEmpty melt:Typem:t eltH:max_elt_aux (elements m) = Noneelements m = nilelt:Typem:t elta:(key * elt)%typel:list (key * elt)H:max_elt_aux (a :: l) = NoneIHl:max_elt_aux l = None -> l = nila :: l = nilassert (H':=IHl H); discriminate. Qed. Definition min_elt m : option (key*elt) := match elements m with | nil => None | (x,e)::_ => Some (x,e) end.elt:Typem:t eltk:keye:eltp:(key * elt)%typel:list (key * elt)H:(let (x, e0) := p in match l with | nil => Some (x, e0) | _ :: _ => max_elt_aux l end) = NoneIHl:(let (x, e0) := p in match l with | nil => Some (x, e0) | _ :: _ => max_elt_aux l end) = None -> p :: l = nil(k, e) :: p :: l = nilelt:Typeforall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> Below x (remove x m)elt:Typeforall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> Below x (remove x m)elt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)y:keyH0:In y (remove x m)E.lt x yelt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)y:keyH0:~ E.eq x yH1:In y mE.lt x yelt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)y:keyH0:~ E.eq x yH1:exists e0 : elt, InA (eq_key_elt (elt:=elt)) (y, e0) (elements m)E.lt x yelt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x1, e0) :: _ => Some (x1, e0) end = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)E.lt x yelt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x1, e0) :: _ => Some (x1, e0) end = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)Sorted (lt_key (elt:=elt)) (elements m) -> E.lt x yelt:Typem:t eltx:keye:eltH:None = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) nilSorted (lt_key (elt:=elt)) nil -> E.lt x yelt:Typem:t eltx:keye:eltp:(key * elt)%typel:list (key * elt)H:(let (x1, e0) := p in Some (x1, e0)) = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (p :: l)Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt x yelt:Typem:t eltx:keye:eltp:(key * elt)%typel:list (key * elt)H:(let (x1, e0) := p in Some (x1, e0)) = Some (x, e)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) (p :: l)Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt x yelt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH1:InA (eq_key_elt (elt:=elt)) (y, x0) ((x, e) :: l)H4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)E.lt x yelt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)H2:eq_key_elt (y, x0) (x, e)E.lt x yelt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)H2:InA (eq_key_elt (elt:=elt)) (y, x0) lE.lt x yelt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)H2:InA (eq_key_elt (elt:=elt)) (y, x0) lE.lt x yelt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH2:InA (eq_key_elt (elt:=elt)) (y, x0) lH:Sorted (lt_key (elt:=elt)) lH1:HdRel (lt_key (elt:=elt)) (x, e) lE.lt x yelt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH2:InA (eq_key_elt (elt:=elt)) (y, x0) lH:Sorted (lt_key (elt:=elt)) lH3:HdRel (lt_key (elt:=elt)) (x, e) lE.lt x yapply (H3 (y,x0)); auto. Qed.elt:Typem:t eltx:keye:eltl:list (key * elt)y:keyH0:~ E.eq x yx0:eltH2:InA (eq_key_elt (elt:=elt)) (y, x0) lH:Sorted (lt_key (elt:=elt)) lH3:forall y0 : E.t * elt, InA eqke y0 l -> lt_key (x, e) y0E.lt x yelt:Typeforall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> MapsTo x e melt:Typeforall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> MapsTo x e melt:Typem:t eltx:keye:eltH:min_elt m = Some (x, e)MapsTo x e melt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)MapsTo x e melt:Typem:t eltx:keye:eltH:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) (elements m)elt:Typem:t eltx:keye:eltH:None = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) nilelt:Typem:t eltx:keye:eltp:(key * elt)%typel:list (key * elt)H:(let (x0, e0) := p in Some (x0, e0)) = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) (p :: l)elt:Typem:t eltx:keye:eltp:(key * elt)%typel:list (key * elt)H:(let (x0, e0) := p in Some (x0, e0)) = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) (p :: l)injection H; intros; subst; constructor; red; auto. Qed.elt:Typem:t eltx:keye:eltk:keye0:eltl:list (key * elt)H:Some (k, e0) = Some (x, e)InA (eq_key_elt (elt:=elt)) (x, e) ((k, e0) :: l)elt:Typeforall m : t elt, min_elt m = None -> Empty melt:Typeforall m : t elt, min_elt m = None -> Empty melt:Typem:t eltH:min_elt m = NoneEmpty melt:Typem:t eltH:match elements m with | nil => None | (x, e) :: _ => Some (x, e) end = NoneEmpty melt:Typem:t eltH:match elements m with | nil => None | (x, e) :: _ => Some (x, e) end = Noneelements m = nildestruct p; simpl in *; discriminate. Qed. End Min_Max_Elt. Section Induction_Principles.elt:Typem:t eltp:(key * elt)%typel:list (key * elt)H:(let (x, e) := p in Some (x, e)) = Nonep :: l = nilelt:Typeforall P : t elt -> Type, (forall m : t elt, Empty m -> P m) -> (forall m m' : t elt, P m -> forall (x : E.t) (e : elt), Above x m -> Add x e m m' -> P m') -> forall m : t elt, P melt:Typeforall P : t elt -> Type, (forall m : t elt, Empty m -> P m) -> (forall m m' : t elt, P m -> forall (x : E.t) (e : elt), Above x m -> Add x e m m' -> P m') -> forall m : t elt, P melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'm:t eltHeqn:0 = cardinal mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mp:(key * elt)%typeH:max_elt m = Some pP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)P melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)Add k e (remove k m) melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)y:keyfind y m = find y (add k e (remove k m))elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Above x m0 -> Add x e1 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)y:keye0:E.eq k yfind y m = Some eelt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Above x m0 -> Add x e1 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)y:keye0:E.eq k yMapsTo k e melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mP (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mAbove k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mn = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mAbove k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mS n = S (cardinal (remove k m))elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mH1:S n = S (cardinal (remove k m))n = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mAbove k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mcardinal m = S (cardinal (remove k m))elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mH1:S n = S (cardinal (remove k m))n = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mAbove k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mH1:S n = S (cardinal (remove k m))n = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mAbove k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:max_elt m = Some (k, e)H0:Add k e (remove k m) mAbove k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP mapply X; apply max_elt_Empty; auto. Qed.elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:max_elt m = NoneP melt:Typeforall P : t elt -> Type, (forall m : t elt, Empty m -> P m) -> (forall m m' : t elt, P m -> forall (x : E.t) (e : elt), Below x m -> Add x e m m' -> P m') -> forall m : t elt, P melt:Typeforall P : t elt -> Type, (forall m : t elt, Empty m -> P m) -> (forall m m' : t elt, P m -> forall (x : E.t) (e : elt), Below x m -> Add x e m m' -> P m') -> forall m : t elt, P melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'm:t eltHeqn:0 = cardinal mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mp:(key * elt)%typeH:min_elt m = Some pP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)P melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)Add k e (remove k m) melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)y:keyfind y m = find y (add k e (remove k m))elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Below x m0 -> Add x e1 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)y:keye0:E.eq k yfind y m = Some eelt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Below x m0 -> Add x e1 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)y:keye0:E.eq k yMapsTo k e melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mP (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mBelow k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mn = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mBelow k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mS n = S (cardinal (remove k m))elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mH1:S n = S (cardinal (remove k m))n = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mBelow k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mcardinal m = S (cardinal (remove k m))elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mH1:S n = S (cardinal (remove k m))n = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mBelow k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mH1:S n = S (cardinal (remove k m))n = cardinal (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mBelow k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP melt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mk:keye:eltH:min_elt m = Some (k, e)H0:Add k e (remove k m) mBelow k (remove k m)elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP mapply X; apply min_elt_Empty; auto. Qed. End Induction_Principles. Section Fold_properties.elt:TypeP:t elt -> TypeX:forall m0 : t elt, Empty m0 -> P m0X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'n:natIHn:forall m0 : t elt, n = cardinal m0 -> P m0m:t eltHeqn:S n = cardinal mH:min_elt m = NoneP m
The following lemma has already been proved on Weak Maps,
but with one additional hypothesis (some transpose fact).
elt:Typeforall (m1 m2 : t elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (f : key -> elt -> A -> A) (i : A), Proper (E.eq ==> eq ==> eqA ==> eqA) f -> Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i)elt:Typeforall (m1 m2 : t elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (f : key -> elt -> A -> A) (i : A), Proper (E.eq ==> eq ==> eqA ==> eqA) f -> Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i)elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2eqA (fold f m1 i) (fold f m2 i)elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2Proper (eqke ==> eqA ==> eqA) (uncurry f)elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2eqlistA eqke (rev (elements m1)) (rev (elements m2))elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2eqlistA eqke (rev (elements m1)) (rev (elements m2))elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2eqlistA eqke (elements m1) (elements m2)auto. Qed.elt:Typem1, m2:t eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AHf:Proper (E.eq ==> eq ==> eqA ==> eqA) fHeq:Equal m1 m2Equal m1 m2elt:Typeforall (m1 m2 : t elt) (x : E.t) (e : elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (f : key -> elt -> A -> A) (i : A), Proper (E.eq ==> eq ==> eqA ==> eqA) f -> Above x m1 -> Add x e m1 m2 -> eqA (fold f m2 i) (f x e (fold f m1 i))elt:Typeforall (m1 m2 : t elt) (x : E.t) (e : elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (f : key -> elt -> A -> A) (i : A), Proper (E.eq ==> eq ==> eqA ==> eqA) f -> Above x m1 -> Add x e m1 m2 -> eqA (fold f m2 i) (f x e (fold f m1 i))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2eqA (fold f m2 i) (f x e (fold f m1 i))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2eqA (fold_right (uncurry f) i (rev (elements m2))) (f x e (fold_right (uncurry f) i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m2))) (f x e (fold_right f' i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m2))) (fold_right f' i (rev (elements m1 ++ (x, e) :: nil)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AProper (eqke ==> eqA ==> eqA) f'elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (rev (elements m2)) (rev (elements m1 ++ (x, e) :: nil))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> Ak1:E.te1:eltk2:E.te2:eltHk:E.eq k1 k2He:e1 = e2a1, a2:AHa:eqA a1 a2eqA (uncurry f (k1, e1) a1) (uncurry f (k2, e2) a2)elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (rev (elements m2)) (rev (elements m1 ++ (x, e) :: nil))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (rev (elements m2)) (rev (elements m1 ++ (x, e) :: nil))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (elements m2) (elements m1 ++ (x, e) :: nil)elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))reflexivity. Qed.elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Above x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (f' (x, e) (fold_right f' i (rev (elements m1)))) (f x e (fold_right f' i (rev (elements m1))))elt:Typeforall (m1 m2 : t elt) (x : E.t) (e : elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (f : key -> elt -> A -> A) (i : A), Proper (E.eq ==> eq ==> eqA ==> eqA) f -> Below x m1 -> Add x e m1 m2 -> eqA (fold f m2 i) (fold f m1 (f x e i))elt:Typeforall (m1 m2 : t elt) (x : E.t) (e : elt) (A : Type) (eqA : A -> A -> Prop), Equivalence eqA -> forall (f : key -> elt -> A -> A) (i : A), Proper (E.eq ==> eq ==> eqA ==> eqA) f -> Below x m1 -> Add x e m1 m2 -> eqA (fold f m2 i) (fold f m1 (f x e i))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2eqA (fold f m2 i) (fold f m1 (f x e i))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2eqA (fold_right (uncurry f) i (rev (elements m2))) (fold_right (uncurry f) (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m2))) (fold_right f' (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m2))) (fold_right f' i (rev (((x, e) :: nil) ++ elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AProper (eqke ==> eqA ==> eqA) f'elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (rev (elements m2)) (rev (((x, e) :: nil) ++ elements m1))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (rev (elements m2)) (rev (((x, e) :: nil) ++ elements m1))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqlistA eqke (elements m2) (((x, e) :: nil) ++ elements m1)elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' i (rev (elements m1) ++ (x, e) :: nil)) (fold_right f' (f x e i) (rev (elements m1)))reflexivity. Qed. End Fold_properties. End Elt. End OrdProperties.elt:Typem1, m2:t eltx:E.te:eltA:TypeeqA:A -> A -> Propst:Equivalence eqAf:key -> elt -> A -> Ai:AP:Proper (E.eq ==> eq ==> eqA ==> eqA) fH:Below x m1H0:Add x e m1 m2f':=uncurry f:key * elt -> A -> AeqA (fold_right f' (fold_right f' i ((x, e) :: nil)) (rev (elements m1))) (fold_right f' (f x e i) (rev (elements m1)))