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)         *)
(************************************************************************)

Finite maps library

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.

Facts about weak maps

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)

forall b b' : bool, b = b' <-> (b = true <-> b' = true)
destruct b; destruct b'; intuition. Qed.

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:Type
o, o':option elt
H:o = o'
e:elt

o = Some e <-> o' = Some e
elt:Type
o, o':option elt
H:forall e : elt, o = Some e <-> o' = Some e
o = o'
elt:Type
o, o':option elt
H:forall e : elt, o = Some e <-> o' = Some e

o = o'
elt:Type
e:elt
H:forall e0 : elt, Some e = Some e0 <-> None = Some e0

Some e = None
symmetry; rewrite <- H; auto. Qed.

forall (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:Type
m:t elt
x:key
e, e':elt
H:MapsTo x e m
H0:MapsTo x e' m

e = e'
elt:Type
m:t elt
x:key
e, e':elt

find x m = Some e -> find x m = Some e' -> e = e'
intros; rewrite H in H0; injection H0; auto. Qed.

Specifications written using equivalences

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'':Type

forall (m : t elt) (x y : key), E.eq x y -> In x m <-> In y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> In x m <-> In y m
elt, elt', elt'':Type

forall (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'':Type
m:t elt
x, y:key
H:E.eq x y
e0:elt
H0:MapsTo x e0 m

MapsTo y e0 m
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y
e0:elt
H0:MapsTo y e0 m
MapsTo x e0 m
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y
e0:elt
H0:MapsTo y e0 m

MapsTo x e0 m
apply (MapsTo_1 (E.eq_sym H) H0); auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> MapsTo x e m <-> MapsTo y e m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> MapsTo x e m <-> MapsTo y e m
split; apply MapsTo_1; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), In x m <-> mem x m = true
elt, elt', elt'':Type

forall (m : t elt) (x : key), In x m <-> mem x m = true
split; [apply mem_1|apply mem_2]. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), ~ In x m <-> mem x m = false
elt, elt', elt'':Type

forall (m : t elt) (x : key), ~ In x m <-> mem x m = false
intros; rewrite mem_in_iff; destruct (mem x m); intuition. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), {In x m} + {~ In x m}
elt, elt', elt'':Type

forall (m : t elt) (x : key), {In x m} + {~ In x m}
elt, elt', elt'':Type
m:t elt
x:key

{In x m} + {~ In x m}
elt, elt', elt'':Type
m:t elt
x:key

In x m <-> mem x m = true -> {In x m} + {~ In x m}
destruct (mem x m); [left|right]; intuition. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> find x m = Some e
elt, elt', elt'':Type

forall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> find x m = Some e
split; [apply find_1|apply find_2]. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), ~ In x m <-> find x m = None
elt, elt', elt'':Type

forall (m : t elt) (x : key), ~ In x m <-> find x m = None
elt, elt', elt'':Type
m:t elt
x:key
H:~ In x m

find x m = None
elt, elt', elt'':Type
m:t elt
x:key
H:find x m = None
~ In x m
elt, elt', elt'':Type
m:t elt
x:key
H:~ In x m

forall e : elt, find x m = Some e <-> None = Some e
elt, elt', elt'':Type
m:t elt
x:key
H:find x m = None
~ In x m
elt, elt', elt'':Type
m:t elt
x:key
H:~ In x m
e:elt

find x m = Some e <-> None = Some e
elt, elt', elt'':Type
m:t elt
x:key
H:find x m = None
~ In x m
elt, elt', elt'':Type
m:t elt
x:key
H:~ In x m
e:elt

MapsTo x e m <-> None = Some e
elt, elt', elt'':Type
m:t elt
x:key
H:find x m = None
~ In x m
elt, elt', elt'':Type
m:t elt
x:key
H:~ In x m
e:elt

MapsTo x e m -> None = Some e
elt, elt', elt'':Type
m:t elt
x:key
H:find x m = None
~ In x m
elt, elt', elt'':Type
m:t elt
x:key
H:find x m = None

~ In x m
intros (e,He); rewrite find_mapsto_iff,H in He; discriminate. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), In x m <-> find x m <> None
elt, elt', elt'':Type

forall (m : t elt) (x : key), In x m <-> find x m <> None
elt, elt', elt'':Type
m:t elt
x:key

mem x m = true <-> ~ mem x m <> true
destruct mem; intuition. Qed.
elt, elt', elt'':Type

forall (m m' : t elt) (cmp : elt -> elt -> bool), Equivb cmp m m' <-> equal cmp m m' = true
elt, elt', elt'':Type

forall (m m' : t elt) (cmp : elt -> elt -> bool), Equivb cmp m m' <-> equal cmp m m' = true
split; [apply equal_1|apply equal_2]. Qed.
elt, elt', elt'':Type

forall (x : key) (e : elt), MapsTo x e (empty elt) <-> False
elt, elt', elt'':Type

forall (x : key) (e : elt), MapsTo x e (empty elt) <-> False
intuition; apply (empty_1 H). Qed.
elt, elt', elt'':Type

forall x : key, In x (empty elt) <-> False
elt, elt', elt'':Type

forall x : key, In x (empty elt) <-> False
elt, elt', elt'':Type

forall x : key, (exists e : elt, MapsTo x e (empty elt)) <-> False
split; [intros (e,H); rewrite empty_mapsto_iff in H|]; intuition. Qed.
elt, elt', elt'':Type

forall m : t elt, Empty m <-> is_empty m = true
elt, elt', elt'':Type

forall m : t elt, Empty m <-> is_empty m = true
split; [apply is_empty_1|apply is_empty_2]. Qed.
elt, elt', elt'':Type

forall (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' m
elt, elt', elt'':Type

forall (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' m
elt, elt', elt'':Type
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' m
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)

E.eq x y /\ e = e' \/ (E.eq x y -> False) /\ MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:E.eq x y
H1:e = e'
MapsTo y e' (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
e0:E.eq x y

E.eq x y /\ e = e'
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
n:~ E.eq x y
(E.eq x y -> False) /\ MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:E.eq x y
H1:e = e'
MapsTo y e' (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
e0:E.eq x y

e = e'
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
n:~ E.eq x y
(E.eq x y -> False) /\ MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:E.eq x y
H1:e = e'
MapsTo y e' (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
n:~ E.eq x y

(E.eq x y -> False) /\ MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:E.eq x y
H1:e = e'
MapsTo y e' (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:E.eq x y
H1:e = e'

MapsTo y e' (add x e m)
subst; auto with map. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), In y (add x e m) <-> E.eq x y \/ In y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), In y (add x e m) <-> E.eq x y \/ In y m
elt, elt', elt'':Type
m:t elt
x, y:key
e: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'':Type
m:t elt
x, y:key
e:elt
E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)

E.eq x y \/ (exists e0 : elt, MapsTo y e0 m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
E:~ E.eq x y

E.eq x y \/ (exists e0 : elt, MapsTo y e0 m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e, e':elt
H:MapsTo y e' (add x e m)
E:~ E.eq x y

MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt

E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:E.eq x y

E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:~ E.eq x y
E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:E.eq x y
H:E.eq x y \/ (exists e0 : elt, MapsTo y e0 m)

exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:~ E.eq x y
E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:~ E.eq x y

E.eq x y \/ (exists e0 : elt, MapsTo y e0 m) -> exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:~ E.eq x y
H:E.eq x y

exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:~ E.eq x y
e':elt
H:MapsTo y e' m
exists e0 : elt, MapsTo y e0 (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
E:~ E.eq x y
e':elt
H:MapsTo y e' m

exists e0 : elt, MapsTo y e0 (add x e m)
exists e'; apply add_2; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e e' : elt), ~ E.eq x y -> MapsTo y e' (add x e m) <-> MapsTo y e' m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e e' : elt), ~ E.eq x y -> MapsTo y e' (add x e m) <-> MapsTo y e' m
split; [apply add_3|apply add_2]; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> In y (add x e m) <-> In y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> In y (add x e m) <-> In y m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y
e':elt
H0:MapsTo y e' (add x e m)

MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y
e':elt
H0:MapsTo y e' m
MapsTo y e' (add x e m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y
e':elt
H0:MapsTo y e' m

MapsTo y e' (add x e m)
apply add_2; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), MapsTo y e (remove x m) <-> ~ E.eq x y /\ MapsTo y e m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), MapsTo y e (remove x m) <-> ~ E.eq x y /\ MapsTo y e m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt

MapsTo y e (remove x m) <-> ~ E.eq x y /\ MapsTo y e m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)

~ E.eq x y /\ MapsTo y e m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y /\ MapsTo y e m
MapsTo y e (remove x m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)

~ E.eq x y
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)
MapsTo y e m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y /\ MapsTo y e m
MapsTo y e (remove x m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)
H0:In y (remove x m)

~ E.eq x y
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)
MapsTo y e m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y /\ MapsTo y e m
MapsTo y e (remove x m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)

MapsTo y e m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y /\ MapsTo y e m
MapsTo y e (remove x m)
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y /\ MapsTo y e m

MapsTo y e (remove x m)
apply remove_2; intuition. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), In y (remove x m) <-> ~ E.eq x y /\ In y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), In y (remove x m) <-> ~ E.eq x y /\ In y m
elt, elt', elt'':Type
m:t elt
x, 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'':Type
m:t elt
x, 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'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)

~ E.eq x y /\ (exists e0 : elt, MapsTo y e0 m)
elt, elt', elt'':Type
m:t elt
x, 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'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)

~ E.eq x y
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)
exists e0 : elt, MapsTo y e0 m
elt, elt', elt'':Type
m:t elt
x, 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'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)
H0:In y (remove x m)

~ E.eq x y
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)
exists e0 : elt, MapsTo y e0 m
elt, elt', elt'':Type
m:t elt
x, 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'':Type
m:t elt
x, y:key
e:elt
H:MapsTo y e (remove x m)

exists e0 : elt, MapsTo y e0 m
elt, elt', elt'':Type
m:t elt
x, 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'':Type
m:t elt
x, 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'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> MapsTo y e (remove x m) <-> MapsTo y e m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> MapsTo y e (remove x m) <-> MapsTo y e m
split; [apply remove_3|apply remove_2]; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), ~ E.eq x y -> In y (remove x m) <-> In y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), ~ E.eq x y -> In y (remove x m) <-> In y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:~ E.eq x y
e':elt
H0:MapsTo y e' (remove x m)

MapsTo y e' m
elt, elt', elt'':Type
m:t elt
x, y:key
H:~ E.eq x y
e':elt
H0:MapsTo y e' m
MapsTo y e' (remove x m)
elt, elt', elt'':Type
m:t elt
x, y:key
H:~ E.eq x y
e':elt
H0:MapsTo y e' m

MapsTo y e' (remove x m)
apply remove_2; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (e : elt), MapsTo x e m <-> InA (eq_key_elt (elt:=elt)) (x, e) (elements m)
elt, elt', elt'':Type

forall (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'':Type

forall (m : t elt) (x : key), In x m <-> (exists e : elt, InA (eq_key_elt (elt:=elt)) (x, e) (elements m))
elt, elt', elt'':Type

forall (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'':Type

forall (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'':Type

forall (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'':Type
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'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
e:elt
H:find x m = Some e
H0:MapsTo x b (map f m)

exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)
exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
e:elt
H:find x m = Some e
H0:MapsTo x b (map f m)

b = f e /\ MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)
exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
e:elt
H:find x m = Some e
H0:MapsTo x b (map f m)

b = f e
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
e:elt
H:find x m = Some e
H0:MapsTo x b (map f m)
MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)
exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
e:elt
H:find x m = Some e
H0:MapsTo x b (map f m)

MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)
exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)

exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)
H1:In x (map f m)

exists a : elt, b = f a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
H:find x m = None
H0:MapsTo x b (map f m)
H1:In x (map f m)
a:elt
H2:MapsTo x a m

exists a0 : elt, b = f a0 /\ MapsTo x a0 m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'

(exists a : elt, b = f a /\ MapsTo x a m) -> MapsTo x b (map f m)
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:elt -> elt'
a:elt
H:b = f a
H0:MapsTo x a m

MapsTo x b (map f m)
subst b; auto with map. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) <-> In x m
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) <-> In x m
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
H:In x m

In x (map f m)
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
a:elt
H:MapsTo x a m

In x (map f m)
exists (f a); auto with map. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : key -> elt -> elt'), In x (mapi f m) <-> In x m
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : key -> elt -> elt'), In x (mapi f m) <-> In x m
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:In x m

In x (mapi f m)
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
a:elt
H:MapsTo x a m

In x (mapi f m)
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
a:elt
H:MapsTo x a m
y:E.t
H0:E.eq y x
H1:MapsTo x (f y a) (mapi f m)

In x (mapi f m)
exists (f y a); auto. Qed.
Unfortunately, we don't have simple equivalences for mapi and MapsTo. The only correct one needs compatibility of f.
elt, elt', elt'':Type

forall (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 m
elt, elt', elt'':Type

forall (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 m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
e:elt
H0:find x m = Some e

exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
e:elt
H0:find x m = Some e

exists y : key, E.eq y x /\ b = f y e /\ MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
e:elt
H0:find x m = Some e

MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
e:elt
H0:find x m = Some e
y:E.t
H1:E.eq y x
H2:MapsTo x (f y e) (mapi f m)
exists y0 : key, E.eq y0 x /\ b = f y0 e /\ MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
e:elt
H0:find x m = Some e
y:E.t
H1:E.eq y x
H2:MapsTo x (f y e) (mapi f m)

exists y0 : key, E.eq y0 x /\ b = f y0 e /\ MapsTo x e m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
e:elt
H0:find x m = Some e
y:E.t
H1:E.eq y x
H2:MapsTo x (f y e) (mapi f m)

b = f y e
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None

exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
H1:In x (mapi f m)

exists (a : elt) (y : key), E.eq y x /\ b = f y a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:MapsTo x b (mapi f m)
H0:find x m = None
H1:In x (mapi f m)
a:elt
H2:MapsTo x a m

exists (a0 : elt) (y : key), E.eq y x /\ b = f y a0 /\ MapsTo x a0 m
rewrite (find_1 H2) in H0; discriminate. Qed.
elt, elt', elt'':Type

forall (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'':Type

forall (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'':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
H0:MapsTo x e m

MapsTo x (f x e) (mapi f m)
elt, elt', elt'':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'
H:forall (x0 y0 : key) (e0 : elt), E.eq x0 y0 -> f x0 e0 = f y0 e0
H0:MapsTo x e m
y:E.t
H1:E.eq y x
H2:MapsTo x (f y e) (mapi f m)

MapsTo x (f x e) (mapi f m)
elt, elt', elt'':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'
H:forall (x0 y0 : key) (e0 : elt), E.eq x0 y0 -> f x0 e0 = f y0 e0
H0:MapsTo x e m
y:E.t
H1:E.eq y x
H2:MapsTo x (f y e) (mapi f m)

MapsTo x (f y e) (mapi f m)
auto. Qed.
elt, elt', elt'':Type

forall (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'':Type

forall (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'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H: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'':Type
m:t elt
x:key
b: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'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e
H0:MapsTo x b (mapi f m)

exists a : elt, b = f x a /\ MapsTo x a m
elt, elt', elt'':Type
m:t elt
x:key
b: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'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:forall (x0 y0 : key) (e : elt), E.eq x0 y0 -> f x0 e = f y0 e
H0:MapsTo x b (mapi f m)
a:elt
y:key
H1:E.eq y x
H2:b = f y a
H3:MapsTo x a m

exists a0 : elt, b = f x a0 /\ MapsTo x a0 m
elt, elt', elt'':Type
m:t elt
x:key
b: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'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:forall (x0 y0 : key) (e : elt), E.eq x0 y0 -> f x0 e = f y0 e
H0:MapsTo x b (mapi f m)
a:elt
y:key
H1:E.eq y x
H2:b = f y a
H3:MapsTo x a m

b = f x a
elt, elt', elt'':Type
m:t elt
x:key
b: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'':Type
m:t elt
x:key
b: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'':Type
m:t elt
x:key
b:elt'
f:key -> elt -> elt'
H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e
a:elt
H0:b = f x a
H1:MapsTo x a m

MapsTo x b (mapi f m)
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e : elt), E.eq x0 y -> f x0 e = f y e
a:elt
H1:MapsTo x a m

MapsTo x (f x a) (mapi f m)
apply mapi_1bis; auto. Qed.
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)).

Specifications written using boolean predicates

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:Type
m:t elt
x:key

mem x m = (if find x m then true else false)
elt:Type
m:t elt
x: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:Type
m:t elt
x:key
e:elt

(forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0) -> (exists e0 : elt, MapsTo x e0 m) <-> false = true -> false = true
elt:Type
m:t elt
x:key
(forall e : elt, MapsTo x e m <-> None = Some e) -> (exists e : elt, MapsTo x e m) <-> true = true -> true = false
elt:Type
m:t elt
x:key
e:elt
H:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H0:(exists e0 : elt, MapsTo x e0 m) <-> false = true

false = true
elt:Type
m:t elt
x:key
(forall e : elt, MapsTo x e m <-> None = Some e) -> (exists e : elt, MapsTo x e m) <-> true = true -> true = false
elt:Type
m:t elt
x:key

(forall e : elt, MapsTo x e m <-> None = Some e) -> (exists e : elt, MapsTo x e m) <-> true = true -> true = false
elt:Type
m:t elt
x:key
H:forall e : elt, MapsTo x e m <-> None = Some e
H0:exists e : elt, MapsTo x e m
H2:true = true

true = false
elt:Type
m:t elt
x:key
H:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
e:elt
H0:MapsTo x e m
H2:true = true

true = false
destruct (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, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> mem x m = mem y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> mem x m = mem y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y

mem x m = mem y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y

In x m <-> mem x m = true -> In y m <-> mem y m = true -> In x m <-> In y m -> mem x m = mem y m
destruct (mem x m); destruct (mem y m); intuition. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> find x m = find y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> find x m = find y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y

find x m = find y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y

forall e : elt, find x m = Some e <-> find y m = Some e
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y
e:elt

find x m = Some e <-> find y m = Some e
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y
e:elt

MapsTo x e m <-> MapsTo y e m
apply MapsTo_iff; auto. Qed.
elt, elt', elt'':Type

forall x : key, find x (empty elt) = None
elt, elt', elt'':Type

forall x : key, find x (empty elt) = None
elt, elt', elt'':Type
x:key

find x (empty elt) = None
elt, elt', elt'':Type
x:key

forall e : elt, find x (empty elt) = Some e <-> None = Some e
elt, elt', elt'':Type
x:key
e:elt

find x (empty elt) = Some e <-> None = Some e
rewrite <- find_mapsto_iff, empty_mapsto_iff; now intuition. Qed.
elt, elt', elt'':Type

forall x : key, mem x (empty elt) = false
elt, elt', elt'':Type

forall x : key, mem x (empty elt) = false
elt, elt', elt'':Type
x:key

mem x (empty elt) = false
elt, elt', elt'':Type
x:key
H:mem x (empty elt) = true

true = false
elt, elt', elt'':Type
x:key
H:mem x (empty elt) = true

In x (empty elt) -> true = false
rewrite empty_in_iff; intuition. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> find y (add x e m) = Some e
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> find y (add x e m) = Some e
auto with map. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> find y (add x e m) = find y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> find y (add x e m) = find y m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y

find y (add x e m) = find y m
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y

forall e0 : elt, find y (add x e m) = Some e0 <-> find y m = Some e0
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y
e':elt

find y (add x e m) = Some e' <-> find y m = Some e'
elt, elt', elt'':Type
m:t elt
x, y:key
e:elt
H:~ E.eq x y
e':elt

MapsTo y e' (add x e m) <-> MapsTo y e' m
apply add_neq_mapsto_iff; auto. Qed. Hint Resolve add_neq_o : map.
elt, elt', elt'':Type

forall (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'':Type

forall (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'':Type

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> mem y (add x e m) = true
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> mem y (add x e m) = true
intros; rewrite mem_find_b; rewrite add_eq_o; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> mem y (add x e m) = mem y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> mem y (add x e m) = mem y m
intros; do 2 rewrite mem_find_b; rewrite add_neq_o; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), mem y (add x e m) = eqb x y || mem y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), mem y (add x e m) = eqb x y || mem y m
elt, elt', elt'':Type
m:t elt
x, y:key
e: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)
destruct (eq_dec x y); simpl; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> find y (remove x m) = None
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> find y (remove x m) = None
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y

find y (remove x m) = None
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y

forall e : elt, find y (remove x m) = Some e <-> None = Some e
elt, elt', elt'':Type
m:t elt
x, y:key
H:E.eq x y
e:elt

find y (remove x m) = Some e <-> None = Some e
rewrite <- find_mapsto_iff, remove_mapsto_iff; now intuition. Qed. Hint Resolve remove_eq_o : map.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), ~ E.eq x y -> find y (remove x m) = find y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), ~ E.eq x y -> find y (remove x m) = find y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:~ E.eq x y

find y (remove x m) = find y m
elt, elt', elt'':Type
m:t elt
x, y:key
H:~ E.eq x y

forall e : elt, find y (remove x m) = Some e <-> find y m = Some e
elt, elt', elt'':Type
m:t elt
x, y:key
H:~ E.eq x y
e:elt

find y (remove x m) = Some e <-> find y m = Some e
rewrite <- find_mapsto_iff, remove_neq_mapsto_iff; now intuition. Qed. Hint Resolve remove_neq_o : map.
elt, elt', elt'':Type

forall (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'':Type

forall (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'':Type

forall (m : t elt) (x y : key), E.eq x y -> mem y (remove x m) = false
elt, elt', elt'':Type

forall (m : t elt) (x y : key), E.eq x y -> mem y (remove x m) = false
intros; rewrite mem_find_b; rewrite remove_eq_o; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), ~ E.eq x y -> mem y (remove x m) = mem y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), ~ E.eq x y -> mem y (remove x m) = mem y m
intros; do 2 rewrite mem_find_b; rewrite remove_neq_o; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key), mem y (remove x m) = negb (eqb x y) && mem y m
elt, elt', elt'':Type

forall (m : t elt) (x y : key), mem y (remove x m) = negb (eqb x y) && mem y m
elt, elt', elt'':Type
m:t elt
x, 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)
destruct (eq_dec x y); auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : elt -> elt'), find x (map f m) = option_map f (find x m)
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : elt -> elt'), find x (map f m) = option_map f (find x m)
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'

find x (map f m) = option_map f (find x m)
elt, elt', elt'':Type
m:t elt
x:key
f: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt'
e0:elt
H:forall e1 : elt', MapsTo x e1 (map f m) <-> Some e = Some e1
H0:forall e1 : elt, MapsTo x e1 m <-> Some e0 = Some e1
H1: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt'
H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)
Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
e:elt
H:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H1: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt'
H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H1:forall b : elt', MapsTo x b (map f m) <-> (exists a : elt, b = f a /\ MapsTo x a m)

Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
e:elt
H:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H1: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt'
H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H1: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 = None
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
e:elt
H:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H1: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt'
H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H1: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 m

Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
e:elt
H:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H1: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt'
H:forall e0 : elt', MapsTo x e0 (map f m) <-> Some e = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H1:forall b : elt', MapsTo x b (map f m) <-> (exists a0 : elt, b = f a0 /\ MapsTo x a0 m)
a:elt
H2:MapsTo x a m

Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'
e:elt
H:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H1: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'':Type
m:t elt
x:key
f:elt -> elt'
e:elt
H:forall e0 : elt', MapsTo x e0 (map f m) <-> None = Some e0
H0:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H1: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'':Type

forall (m : t elt) (x : key) (f : elt -> elt'), mem x (map f m) = mem x m
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : elt -> elt'), mem x (map f m) = mem x m
elt, elt', elt'':Type
m:t elt
x:key
f:elt -> elt'

(if option_map f (find x m) then true else false) = (if find x m then true else false)
destruct (find x m); simpl; auto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : key -> elt -> elt'), mem x (mapi f m) = mem x m
elt, elt', elt'':Type

forall (m : t elt) (x : key) (f : key -> elt -> elt'), mem x (mapi f m) = mem x m
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'

mem x (mapi f m) = mem x m
elt, elt', elt'':Type
m:t elt
x:key
f: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 m
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:In x (mapi f m) <-> true = true
H0:In x m <-> false = true
H1:In x (mapi f m) <-> In x m

true = false
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:In x (mapi f m) <-> false = true
H0:In x m <-> true = true
H1:In x (mapi f m) <-> In x m
false = true
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:In x (mapi f m) <-> false = true
H0:In x m <-> true = true
H1:In x (mapi f m) <-> In x m

false = true
rewrite <- H; rewrite H1; rewrite H0; auto. Qed.
elt, elt', elt'':Type

forall (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'':Type

forall (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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H: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'':Type
m:t elt
x:key
f: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e1 : elt), E.eq x0 y -> f x0 e1 = f y e1
e:elt'
e0:elt
H0:forall e1 : elt', MapsTo x e1 (mapi f m) <-> Some e = Some e1
H1:forall e1 : elt, MapsTo x e1 m <-> Some e0 = Some e1
H2: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt'
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)
Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H2: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt'
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a : elt, b = f x a /\ MapsTo x a m)

Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H2: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt'
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H2: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 = None
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H2: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt'
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H2: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 m

Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H2: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt'
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> Some e = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> None = Some e0
H2:forall b : elt', MapsTo x b (mapi f m) <-> (exists a0 : elt, b = f x a0 /\ MapsTo x a0 m)
a:elt
H3:MapsTo x a m

Some e = None
elt, elt', elt'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H2: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'':Type
m:t elt
x:key
f:key -> elt -> elt'
H:forall (x0 y : key) (e0 : elt), E.eq x0 y -> f x0 e0 = f y e0
e:elt
H0:forall e0 : elt', MapsTo x e0 (mapi f m) <-> None = Some e0
H1:forall e0 : elt, MapsTo x e0 m <-> Some e = Some e0
H2: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'':Type

forall (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'':Type

forall (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'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None

find x (map2 f m m') = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
e:elt
H0:find x m = Some e

find x (map2 f m m') = f (Some e) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
find x (map2 f m m') = f None (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
e:elt
H0:find x m = Some e

find x (map2 f m m') = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
find x (map2 f m m') = f None (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
e:elt
H0:find x m = Some e

In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
find x (map2 f m m') = f None (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None

find x (map2 f m m') = f None (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
e:elt'
H1:find x m' = Some e

find x (map2 f m m') = f None (Some e)
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
find x (map2 f m m') = f None None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
e:elt'
H1:find x m' = Some e

find x (map2 f m m') = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
find x (map2 f m m') = f None None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
e:elt'
H1:find x m' = Some e

In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
find x (map2 f m m') = f None None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None

find x (map2 f m m') = f None None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None

find x (map2 f m m') = None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
e:elt''
H2:find x (map2 f m m') = Some e

Some e = None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
e:elt''
H2:find x (map2 f m m') = Some e
H3:In x (map2 f m m')

Some e = None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
e:elt''
H2:find x (map2 f m m') = Some e
H3:In x (map2 f m m')
e0:elt
H4:MapsTo x e0 m

Some e = None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
e:elt''
H2:find x (map2 f m m') = Some e
H3:In x (map2 f m m')
e0:elt'
H4:MapsTo x e0 m'
Some e = None
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:f None None = None
H0:find x m = None
H1:find x m' = None
e:elt''
H2:find x (map2 f m m') = Some e
H3:In x (map2 f m m')
e0:elt'
H4:MapsTo x e0 m'

Some e = None
rewrite (find_1 H4) in H1; discriminate. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), find x m = findA (eqb x) (elements m)
elt, elt', elt'':Type

forall (m : t elt) (x : key), find x m = findA (eqb x) (elements m)
elt, elt', elt'':Type
m:t elt
x:key

find x m = findA (eqb x) (elements m)
elt, elt', elt'':Type
m:t elt
x:key

forall e : elt, find x m = Some e <-> findA (eqb x) (elements m) = Some e
elt, elt', elt'':Type
m:t elt
x:key
e:elt

find x m = Some e <-> findA (eqb x) (elements m) = Some e
elt, elt', elt'':Type
m:t elt
x:key
e:elt

InA (eq_key_elt (elt:=elt)) (x, e) (elements m) <-> findA (eqb x) (elements m) = Some e
elt, elt', elt'':Type
m:t elt
x:key
e:elt

InA (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 e
rewrite <- findA_NoDupA; dintuition; try apply elements_3w; eauto. Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key), mem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)
elt, elt', elt'':Type

forall (m : t elt) (x : key), mem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)
elt, elt', elt'':Type
m:t elt
x:key

mem x m = existsb (fun p : E.t * elt => eqb x (fst p)) (elements m)
elt, elt', elt'':Type
m:t elt
x:key

In 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'':Type
m:t elt
x:key
H:In x m <-> true = true
H0: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 = false
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H0: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) = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H0: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) = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)
e:elt
He:InA (eq_key_elt (elt:=elt)) (x, e) (elements m)

exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)
e:elt
He: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) = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)
e:elt
y:key
e':elt
Ha1: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) = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)
e:elt
y:key
H0:E.eq x y
Ha2:List.In (y, e) (elements m)

exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> true = true
H1:false = true <-> (exists x0 : E.t * elt, List.In x0 (elements m) /\ eqb x (fst x0) = true)
e:elt
y:key
H0:E.eq x y
Ha2:List.In (y, e) (elements m)

eqb x y = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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 = true
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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'':Type
m:t elt
x:key
H:In x m <-> false = true
H0: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'':Type
m:t elt
x:key
H:In x m <-> false = true
H0:In x m <-> (exists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m))
y:E.t
e:elt
Ha1:List.In (y, e) (elements m)
Ha2:eqb x (fst (y, e)) = true

exists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m)
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0:In x m <-> (exists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m))
y:E.t
e:elt
Ha1:List.In (y, e) (elements m)
Ha2:eqb x y = true

exists e0 : elt, InA (eq_key_elt (elt:=elt)) (x, e0) (elements m)
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0:In x m <-> (exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m))
y:E.t
e:elt
Ha1:List.In (y, e) (elements m)
e0:E.eq x y
Ha2:true = true

exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m)
elt, elt', elt'':Type
m:t elt
x:key
H:In x m <-> false = true
H0:In x m <-> (exists e1 : elt, InA (eq_key_elt (elt:=elt)) (x, e1) (elements m))
y:E.t
e:elt
Ha1:List.In (y, e) (elements m)
e0:E.eq x y
Ha2:true = true

exists y0 : key * elt, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)
elt, elt', elt'':Type
m:t elt
x:key
y:E.t
e:elt
Ha1:List.In (y, e) (elements m)
e0:E.eq x y
Ha2:true = true
H1:In x m -> false = true
H2:false = true -> In x m
H: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 m

eq_key_elt (x, e) (y, e)
compute; auto. Qed. End BoolSpec. Section Equalities. Variable elt:Type.
Another characterisation of Equal
elt:Type

forall m1 m2 : t elt, Equal m1 m2 <-> (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2)
elt:Type

forall m1 m2 : t elt, Equal m1 m2 <-> (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2)
elt:Type
m1, m2:t elt

Equal m1 m2 <-> (forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2)
elt:Type
m1, m2:t elt
Heq:Equal m1 m2
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m2
elt:Type
m1, m2:t elt
Hiff:forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2
Equal m1 m2
elt:Type
m1, m2:t elt
Heq:Equal m1 m2
k:key
e:elt

find k m2 = Some e <-> find k m2 = Some e
elt:Type
m1, m2:t elt
Hiff:forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2
Equal m1 m2
elt:Type
m1, m2:t elt
Hiff:forall (k : key) (e : elt), MapsTo k e m1 <-> MapsTo k e m2

Equal m1 m2
elt:Type
m1, m2:t elt
Hiff:forall (k0 : key) (e : elt), MapsTo k0 e m1 <-> MapsTo k0 e m2
k:key

find k m1 = find k m2
elt:Type
m1, m2:t elt
Hiff:forall (k0 : key) (e : elt), MapsTo k0 e m1 <-> MapsTo k0 e m2
k:key

forall e : elt, find k m1 = Some e <-> find k m2 = Some e
elt:Type
m1, m2:t elt
Hiff:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 <-> MapsTo k0 e0 m2
k:key
e:elt

find k m1 = Some e <-> find k m2 = Some e
rewrite <- 2 find_mapsto_iff; auto. Qed.

Relations between Equal, Equiv and Equivb.

First, Equal is Equiv with Leibniz on elements.
elt:Type

forall m m' : t elt, Equal m m' <-> Equiv eq m m'
elt:Type

forall m m' : t elt, Equal m m' <-> Equiv eq m m'
elt:Type
m, m':t elt

Equal m m' <-> Equiv eq m m'
elt:Type
m, m':t elt

(forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m') <-> Equiv eq m m'
elt:Type
m, m':t elt
H:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m'

Equiv eq m m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
MapsTo k e m <-> MapsTo k e m'
elt:Type
m, m':t elt
H:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m'

forall k : key, In k m <-> In k m'
elt:Type
m, m':t elt
H: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:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
MapsTo k e m <-> MapsTo k e m'
elt:Type
m, m':t elt
H: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:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
MapsTo k e m <-> MapsTo k e m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt

MapsTo k e m <-> MapsTo k e m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
H':MapsTo k e m

MapsTo k e m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
H':MapsTo k e m'
MapsTo k e m
elt:Type
m, m':t elt
H: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:key
e:elt
H':MapsTo k e m

MapsTo k e m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
H':MapsTo k e m'
MapsTo k e m
elt:Type
m, m':t elt
H: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:key
e:elt
H':MapsTo k e m
Hin:In k m'

MapsTo k e m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
H':MapsTo k e m'
MapsTo k e m
elt:Type
m, m':t elt
H: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'0
k:key
e:elt
H':MapsTo k e m
e':elt
He':MapsTo k e' m'

MapsTo k e m'
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
H':MapsTo k e m'
MapsTo k e m
elt:Type
m, m':t elt
H:Equiv eq m m'
k:key
e:elt
H':MapsTo k e m'

MapsTo k e m
elt:Type
m, m':t elt
H: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:key
e:elt
H':MapsTo k e m'

MapsTo k e m
elt:Type
m, m':t elt
H: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:key
e:elt
H':MapsTo k e m'
Hin:In k m

MapsTo k e m
elt:Type
m, m':t elt
H: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'0
k:key
e:elt
H':MapsTo k e m'
e':elt
He':MapsTo k e' m

MapsTo k e m
rewrite <- (H0 k e' e); auto. Qed.
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:Type
eq_elt:elt -> elt -> Prop
cmp:elt -> elt -> bool

compat_cmp -> forall m m' : t elt, Equiv eq_elt m m' <-> Equivb cmp m m'
elt:Type
eq_elt:elt -> elt -> Prop
cmp:elt -> elt -> bool

compat_cmp -> forall m m' : t elt, Equiv eq_elt m m' <-> Equivb cmp m m'
elt:Type
eq_elt:elt -> elt -> Prop
cmp:elt -> elt -> bool
H:compat_cmp
m, m':t elt
H1: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'0
k:key
e, e':elt
H0:MapsTo k e m
H3:MapsTo k e' m'

cmp e e' = true
elt:Type
eq_elt:elt -> elt -> Prop
cmp:elt -> elt -> bool
H:compat_cmp
m, m':t elt
H1: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 = true
k:key
e, e':elt
H0:MapsTo k e m
H3:MapsTo k e' m'
eq_elt e e'
elt:Type
eq_elt:elt -> elt -> Prop
cmp:elt -> elt -> bool
H:compat_cmp
m, m':t elt
H1: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 = true
k:key
e, e':elt
H0:MapsTo k e m
H3:MapsTo k e' m'

eq_elt e e'
red in H; rewrite <-H; eauto. Qed. End Cmp.
Composition of the two last results: relation between Equal and Equivb.
elt:Type

forall 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:Type

forall 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:Type
cmp:elt -> elt -> bool
H:forall e e' : elt, cmp e e' = true <-> e = e'
m, m':t elt

Equiv eq m m' <-> Equivb cmp m m'
apply Equiv_Equivb; auto. Qed.
elt:Type

forall 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:Type

forall 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:Type
eq_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 -> bool
m, m':t elt

forall e e' : elt, cmp e e' = true <-> e = e'
elt:Type
eq_elt_dec:forall e0 e'0 : elt, {e0 = e'0} + {e0 <> e'0}
m, m':t elt
e, e':elt

(if eq_elt_dec e e' then true else false) = true <-> e = e'
destruct eq_elt_dec; now intuition. Qed. End Equalities.

Equal is a setoid equality.


forall (elt : Type) (m : t elt), Equal m m

forall (elt : Type) (m : t elt), Equal m m
red; reflexivity. Qed.

forall (elt : Type) (m m' : t elt), Equal m m' -> Equal m' m

forall (elt : Type) (m m' : t elt), Equal m m' -> Equal m' m
unfold Equal; auto. Qed.

forall (elt : Type) (m m' m'' : t elt), Equal m m' -> Equal m' m'' -> Equal m m''

forall (elt : Type) (m m' m'' : t elt), Equal m m' -> Equal m' m'' -> Equal m m''
unfold Equal; congruence. Qed.

forall elt : Type, Equivalence (Equal (elt:=elt))

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.
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> In x x0 <-> In y y0
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> In x x0 <-> In y y0
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:forall y : key, find y m = find y m'

In k m <-> In k' m'
rewrite (In_iff m Hk), in_find_iff, in_find_iff, Hm; intuition. Qed.
elt:Type

forall 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 y1
elt:Type

forall 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 y1
elt:Type
k, k':E.t
Hk:E.eq k k'
e:elt
m, m':t elt
Hm:forall y : key, find y m = find y m'

MapsTo k e m <-> MapsTo k' e m'
rewrite (MapsTo_iff m e Hk), find_mapsto_iff, find_mapsto_iff, Hm; intuition. Qed.
elt:Type

forall x y : t elt, Equal x y -> Empty x <-> Empty y
elt:Type

forall x y : t elt, Equal x y -> Empty x <-> Empty y
elt:Type
m, m':t elt
Hm:Equal m m'

(forall (a : key) (e : elt), ~ MapsTo a e m) <-> (forall (a : key) (e : elt), ~ MapsTo a e m')
elt:Type
m, m':t elt
Hm:Equal m m'
H:forall (a0 : key) (e0 : elt), ~ MapsTo a0 e0 m
a:key
e:elt
H0:MapsTo a e m'

False
elt:Type
m, m':t elt
Hm:Equal m m'
H:forall (a0 : key) (e0 : elt), ~ MapsTo a0 e0 m'
a:key
e:elt
H0:MapsTo a e m
False
elt:Type
m, m':t elt
Hm:Equal m m'
H:forall (a0 : key) (e0 : elt), ~ MapsTo a0 e0 m'
a:key
e:elt
H0:MapsTo a e m

False
rewrite Hm in H0; eapply H, H0. Qed.
elt:Type

forall x y : t elt, Equal x y -> is_empty x = is_empty y
elt:Type

forall x y : t elt, Equal x y -> is_empty x = is_empty y
elt:Type
m, m':t elt
Hm:Equal m m'

is_empty m = is_empty m'
rewrite eq_bool_alt, <-is_empty_iff, <-is_empty_iff, Hm; intuition. Qed.
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> mem x x0 = mem y y0
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> mem x x0 = mem y y0
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'

mem k m = mem k' m'
rewrite eq_bool_alt, <- mem_in_iff, <-mem_in_iff, Hk, Hm; intuition. Qed.
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> find x x0 = find y y0
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> find x x0 = find y y0
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'

find k m = find k' m'
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'

forall e : elt, find k m = Some e <-> find k' m' = Some e
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'
e:elt

find k m = Some e <-> find k' m' = Some e
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'
e:elt

MapsTo k' e m' <-> MapsTo k' e m'
split; auto. Qed.
elt:Type

forall 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:Type

forall 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:Type
k, k':E.t
Hk:E.eq k k'
e:elt
m, m':t elt
Hm:Equal m m'
y:key

find y (add k e m) = find y (add k' e m')
elt:Type
k, k':E.t
Hk:E.eq k k'
e:elt
m, m':t elt
Hm:Equal m m'
y:key
e0:E.eq k y
Hnot:~ E.eq k' y

Some e = find y m'
elt:Type
k, k':E.t
Hk:E.eq k k'
e:elt
m, m':t elt
Hm:Equal m m'
y:key
Hnot:~ E.eq k y
e0:E.eq k' y
find y m = Some e
elt:Type
k, k':E.t
Hk:E.eq k k'
e:elt
m, m':t elt
Hm:Equal m m'
y:key
Hnot:~ E.eq k y
e0:E.eq k' y

find y m = Some e
elim Hnot; rewrite Hk; auto. Qed.
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (remove x x0) (remove y y0)
elt:Type

forall x y : E.t, E.eq x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (remove x x0) (remove y y0)
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'
y:key

find y (remove k m) = find y (remove k' m')
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'
y:key
e:E.eq k y
Hnot:~ E.eq k' y

None = find y m'
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'
y:key
Hnot:~ E.eq k y
e:E.eq k' y
find y m = None
elt:Type
k, k':E.t
Hk:E.eq k k'
m, m':t elt
Hm:Equal m m'
y:key
Hnot:~ E.eq k y
e:E.eq k' y

find y m = None
elim Hnot; rewrite Hk; auto. Qed.
elt, elt':Type

forall (y : elt -> elt') (x y0 : t elt), Equal x y0 -> Equal (map y x) (map y y0)
elt, elt':Type

forall (y : elt -> elt') (x y0 : t elt), Equal x y0 -> Equal (map y x) (map y y0)
elt, elt':Type
f:elt -> elt'
m, m':t elt
Hm:Equal m m'
y:key

find y (map f m) = find y (map f m')
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.

Same facts for self-contained weak sets and for full maps

Module WFacts (M:WS) := WFacts_fun M.E M.
Module Facts := WFacts.

Additional Properties for weak maps

Results about fold, elements, induction principles...
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:Type

Equivalence eqk
elt:Type

Equivalence eqk
unfold eq_key; split; eauto. Qed.
elt:Type

Equivalence eqke
elt:Type

Equivalence eqke
elt:Type
x, y, z:(key * elt)%type
H0:E.eq (fst y) (fst z)
H1:snd y = snd z
H:E.eq (fst x) (fst y)
H2:snd x = snd y

E.eq (fst x) (fst z)
elt:Type
x, y, z:(key * elt)%type
H0:E.eq (fst y) (fst z)
H1:snd y = snd z
H:E.eq (fst x) (fst y)
H2:snd x = snd y
snd x = snd z
elt:Type
x, y, z:(key * elt)%type
H0:E.eq (fst y) (fst z)
H1:snd y = snd z
H:E.eq (fst x) (fst y)
H2:snd x = snd y

snd x = snd z
congruence. Qed.
Complements about InA, NoDupA and findA
  
elt:Type

forall (k1 k2 : E.t) (e1 e2 : elt) (l : list (key * elt)), E.eq k1 k2 -> InA eqke (k1, e1) l -> InA eqk (k2, e2) l
elt:Type

forall (k1 k2 : E.t) (e1 e2 : elt) (l : list (key * elt)), E.eq k1 k2 -> InA eqke (k1, e1) l -> InA eqk (k2, e2) l
elt:Type
k1, k2:E.t
e1, e2:elt
l:list (key * elt)
Hk:E.eq k1 k2

InA eqke (k1, e1) l -> InA eqk (k2, e2) l
elt:Type
k1, k2:E.t
e1, e2:elt
l: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 l
elt:Type
k1, k2:E.t
e1, e2:elt
l:list (key * elt)
Hk:E.eq k1 k2
k':key
e':elt
Hk':E.eq k1 k'
He':e1 = e'
H:List.In (k', e') l

exists y : key * elt, eqk (k2, e2) y /\ List.In y l
elt:Type
k1, k2:E.t
e1, e2:elt
l:list (key * elt)
Hk:E.eq k1 k2
k':key
e':elt
Hk':E.eq k1 k'
He':e1 = e'
H:List.In (k', e') l

eqk (k2, e2) (k', e')
red; simpl; eauto. Qed.
elt:Type

forall l : list (key * elt), NoDupA eqk l -> NoDupA eqke l
elt:Type

forall l : list (key * elt), NoDupA eqk l -> NoDupA eqke l
elt:Type
x:(key * elt)%type
l:list (key * elt)
H:~ InA eqk x l
H0:NoDupA eqk l
IHNoDupA:NoDupA eqke l

NoDupA eqke (x :: l)
elt:Type
x:(key * elt)%type
l:list (key * elt)
H:~ InA eqk x l
H0:NoDupA eqk l
IHNoDupA:NoDupA eqke l

~ InA eqke x l
elt:Type
k:key
e:elt
l:list (key * elt)
H:~ InA eqk (k, e) l
H0:NoDupA eqk l
IHNoDupA:NoDupA eqke l

~ InA eqke (k, e) l
eauto using InA_eqke_eqk. Qed.
elt:Type

forall (l : list (key * elt)) (k : E.t), NoDupA eqk l -> findA (eqb k) l = findA (eqb k) (rev l)
elt:Type

forall (l : list (key * elt)) (k : E.t), NoDupA eqk l -> findA (eqb k) l = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l

findA (eqb k) l = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l

forall e : elt, findA (eqb k) l = Some e -> Some e = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
findA (eqb k) l = None -> None = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
e:elt
H0:findA (eqb k) l = Some e

Some e = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
findA (eqb k) l = None -> None = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
e:elt
H0:findA (eqb k) l = Some e

findA (eqb k) (rev l) = Some e
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
findA (eqb k) l = None -> None = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
e:elt
H0:findA (eqb k) l = Some e

findA (fun y : E.t => if eq_dec k y then true else false) (rev l) = Some e
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
findA (eqb k) l = None -> None = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l

findA (eqb k) l = None -> None = findA (eqb k) (rev l)
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l

forall e : elt, findA (eqb k) (rev l) = Some e -> findA (eqb k) l = None -> None = Some e
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
e:elt

findA (eqb k) (rev l) = Some e -> findA (eqb k) l = None -> None = Some e
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
e:elt

findA (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 e
elt:Type
l:list (key * elt)
k:E.t
H:NoDupA eqk l
e:elt

findA (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
intro Eq; rewrite Eq; auto. Qed.

Elements

  
elt:Type

forall m : t elt, Empty m <-> elements m = nil
elt:Type

forall m : t elt, Empty m <-> elements m = nil
elt:Type
m:t elt

Empty m <-> elements m = nil
elt:Type
m:t elt

(forall (a : key) (e : elt), ~ MapsTo a e m) <-> elements m = nil
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m

elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m

forall a : key * elt, ~ List.In a (elements m)
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
H0:forall a : key * elt, ~ List.In a (elements m)
elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a0 : key) (e : elt), ~ MapsTo a0 e m
a:(key * elt)%type
H0:List.In a (elements m)

False
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
H0:forall a : key * elt, ~ List.In a (elements m)
elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a0 : key) (e : elt), ~ MapsTo a0 e m
a:(key * elt)%type
H0:List.In a (elements m)

MapsTo (fst a) (snd a) m
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
H0:forall a : key * elt, ~ List.In a (elements m)
elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a0 : key) (e : elt), ~ MapsTo a0 e m
a:(key * elt)%type
H0:List.In a (elements m)

InA eqke (fst a, snd a) (elements m)
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
H0:forall a : key * elt, ~ List.In a (elements m)
elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a0 : key) (e : elt), ~ MapsTo a0 e m
a:(key * elt)%type
H0:List.In a (elements m)

eqke (fst a, snd a) a /\ List.In a (elements m)
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
H0:forall a : key * elt, ~ List.In a (elements m)
elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
H0:forall a : key * elt, ~ List.In a (elements m)

elements m = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:forall (a : key) (e : elt), ~ MapsTo a e m
p:(key * elt)%type
l:list (key * elt)
H0:forall a : key * elt, ~ List.In a (p :: l)

p :: l = nil
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
~ MapsTo a e m
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt

~ MapsTo a e m
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
H0:MapsTo a e m

False
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
H0:InA eqke (a, e) (elements m)

False
elt:Type
m:t elt
H:elements m = nil
a:key
e:elt
x:(key * elt)%type
H0:eqke (a, e) x /\ List.In x (elements m)

False
rewrite H in H0; destruct H0 as (_,H0); inversion H0. Qed.
elt:Type

elements (empty elt) = nil
elt:Type

elements (empty elt) = nil
rewrite <-elements_Empty; apply empty_1. Qed.

Conversions between maps and association lists.

  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:Type

forall (l : list (key * elt)) (k : key) (e : elt), NoDupA eqk l -> MapsTo k e (of_list l) <-> InA eqke (k, e) l
elt:Type

forall (l : list (key * elt)) (k : key) (e : elt), NoDupA eqk l -> MapsTo k e (of_list l) <-> InA eqke (k, e) l
elt:Type
k:key
e:elt
Hnodup:NoDupA eqk nil

MapsTo k e (empty elt) <-> InA eqke (k, e) nil
elt:Type
k':key
e':elt
l:list (key * elt)
IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) l
k:key
e:elt
Hnodup: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:Type
k':key
e':elt
l:list (key * elt)
IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) l
k:key
e:elt
Hnodup: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:Type
k':key
e':elt
l:list (key * elt)
IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) l
k:key
e:elt
Hnodup:NoDupA eqk ((k', e') :: l)

MapsTo k e (add k' e' (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)
elt:Type
k':key
e':elt
l:list (key * elt)
IH:forall (k0 : key) (e0 : elt), NoDupA eqk l -> MapsTo k0 e0 (of_list l) <-> InA eqke (k0, e0) l
k:key
e:elt
Hnotin:~ InA eqk (k', e') l
Hnodup':NoDupA eqk l

MapsTo k e (add k' e' (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)
elt:Type
k':key
e':elt
l:list (key * elt)
k:key
e:elt
IH:MapsTo k e (of_list l) <-> InA eqke (k, e) l
Hnotin:~ InA eqk (k', e') l

MapsTo k e (add k' e' (of_list l)) <-> InA eqke (k, e) ((k', e') :: l)
elt:Type
k':key
e':elt
l:list (key * elt)
k:key
e:elt
IH:MapsTo k e (of_list l) <-> InA eqke (k, e) l
Hnotin:~ InA eqk (k', e') l

E.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:Type
k':key
e':elt
l:list (key * elt)
k:key
e:elt
IH:MapsTo k e (of_list l) <-> InA eqke (k, e) l
Hnotin:~ InA eqk (k', e') l

E.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:Type
k':key
e':elt
l:list (key * elt)
k:key
e:elt
IH:MapsTo k e (of_list l) <-> InA eqke (k, e) l
Hnotin:~ InA eqk (k', e') l
H:MapsTo k e (of_list l)

E.eq k' k /\ e' = e \/ ~ E.eq k' k /\ MapsTo k e (of_list l)
elt:Type
k':key
e':elt
l:list (key * elt)
k:key
e:elt
IH:MapsTo k e (of_list l) <-> InA eqke (k, e) l
Hnotin:~ InA eqk (k', e') l
H:MapsTo k e (of_list l)
e0:E.eq k k'

e' = e
elt:Type
k':key
e':elt
l:list (key * elt)
k:key
e:elt
IH:MapsTo k e (of_list l) <-> InA eqke (k, e) l
H:MapsTo k e (of_list l)
e0:E.eq k k'

InA eqk (k', e') l
apply InA_eqke_eqk with k e; intuition. Qed.
elt:Type

forall (l : list (key * elt)) (k : key), NoDupA eqk l -> find k (of_list l) = findA (eqb k) l
elt:Type

forall (l : list (key * elt)) (k : key), NoDupA eqk l -> find k (of_list l) = findA (eqb k) l
elt:Type
k:key
Hnodup:NoDupA eqk nil

find k (empty elt) = None
elt:Type
k':key
e':elt
l:list (key * elt)
IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) l
k:key
Hnodup: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:Type
k':key
e':elt
l:list (key * elt)
IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) l
k:key
Hnodup: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:Type
k':key
e':elt
l:list (key * elt)
IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) l
k:key
Hnodup: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:Type
k':key
e':elt
l:list (key * elt)
IH:forall k0 : key, NoDupA eqk l -> find k0 (of_list l) = findA (eqb k0) l
k:key
Hnotin:~ InA eqk (k', e') l
Hnodup':NoDupA eqk l

find k (add k' e' (of_list l)) = (if eqb k k' then Some e' else findA (eqb k) l)
elt:Type
k':key
e':elt
l:list (key * elt)
k:key
IH:find k (of_list l) = findA (eqb k) l
Hnotin:~ InA 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:Type
k':key
e':elt
l:list (key * elt)
k:key
IH:find k (of_list l) = findA (eqb k) l
Hnotin:~ 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)
unfold eqb; do 2 destruct eq_dec as [|?Hnot]; auto; elim Hnot; eauto. Qed.
elt:Type

forall l : list (key * elt), NoDupA eqk l -> equivlistA eqke l (to_list (of_list l))
elt:Type

forall l : list (key * elt), NoDupA eqk l -> equivlistA eqke l (to_list (of_list l))
elt:Type
l:list (key * elt)
Hnodup:NoDupA eqk l
k:key
e:elt

InA eqke (k, e) l <-> InA eqke (k, e) (to_list (of_list l))
rewrite <- elements_mapsto_iff, of_list_1; intuition. Qed.
elt:Type

forall s : t elt, Equal (of_list (to_list s)) s
elt:Type

forall s : t elt, Equal (of_list (to_list s)) s
elt:Type
s:t elt
k:key

find k (of_list (to_list s)) = find k s
elt:Type
s:t elt
k:key

NoDupA eqk (to_list s)
apply elements_3w. Qed.

Fold

  
Alternative specification via fold_right
  
elt:Type
m:t elt
A:Type
i:A
f:key -> elt -> A -> A

fold f m i = fold_right (uncurry f) i (rev (elements m))
elt:Type
m:t elt
A:Type
i:A
f:key -> elt -> A -> A

fold f m i = fold_right (uncurry f) i (rev (elements m))
elt:Type
m:t elt
A:Type
i:A
f:key -> elt -> A -> A

fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i = fold_right (uncurry f) i (rev (elements m))
elt:Type
m:t elt
A:Type
i:A
f:key -> elt -> A -> A

fold_right (uncurry f) i (rev (elements m)) = fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i
apply fold_left_rev_right. Qed.

Induction principles about fold contributed by S. Lescuyer

  
In the following lemma, the step hypothesis is deliberately restricted to the precise map m we are considering.
  
elt:Type

forall (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:Type

forall (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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A

P m (fold_right F i (rev (elements m)))
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=rev (elements m):list (key * elt)

P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=rev (elements m):list (key * elt)
k:key
e:elt
a:A
m', m'':t elt
H:InA eqke (k, e) l
H0:~ In k m'
H1:Add k e m' m''
X:P m' a

MapsTo (fst (k, e)) (snd (k, e)) m
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l

P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l

forall k : key, find k m = findA (eqb k) l
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
Hsame:forall k : key, find k m = findA (eqb k) l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
k:key

find k m = findA (eqb k) l
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
Hsame:forall k : key, find k m = findA (eqb k) l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
k:key

find k m = findA (eqb k) (rev (elements m))
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
Hsame:forall k : key, find k m = findA (eqb k) l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
k:key

NoDupA eqk (elements m)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
Hsame:forall k : key, find k m = findA (eqb k) l
P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l:=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 l
Hsame:forall k : key, find k m = findA (eqb k) l

P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l: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 l
Hsame:forall k : key, find k m = findA (eqb k) l

P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
Hstep: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 -> A
l: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 l
Hsame:forall k : key, find k m = findA (eqb k) l

P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
m:t elt
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
l: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 l
Hsame:forall k : key, find k m = findA (eqb k) l

P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
l: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 l

forall m : t elt, (forall k : key, find k m = findA (eqb k) l) -> P m (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
Hstep':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 nil

forall m : t elt, (forall k : key, find k m = findA (eqb k) nil) -> P m (fold_right F i nil)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
a:(key * elt)%type
l: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))
(* empty *)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
Hstep':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 nil
m:t elt
Hsame:forall k : key, find k m = findA (eqb k) nil

P m i
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
a:(key * elt)%type
l: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
Hstep':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 nil
m:t elt
Hsame:forall k : key, find k m = findA (eqb k) nil

Empty m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
a:(key * elt)%type
l: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
Hstep':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 nil
m:t elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) nil
k:key
e:elt

~ MapsTo k e m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
a:(key * elt)%type
l: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m : t elt, Empty m -> P m i
F:key * elt -> A -> A
a:(key * elt)%type
l: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

P m (F (k, e) (fold_right F i l))
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

InA eqke (k, e) ((k, e) :: l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
~ In k (of_list l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

~ In k (of_list l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
H:~ InA eqk (k, e) l
H0:NoDupA eqk l

~ In k (of_list l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
H0:NoDupA eqk l
H:In k (of_list l)

InA eqk (k, e) l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
H0:NoDupA eqk l
e':elt
He':MapsTo k e' (of_list l)

InA eqk (k, e) l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
H0:NoDupA eqk l
e':elt
He':MapsTo k e' (of_list l)

InA eqke (k, e') l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

Add k e (of_list l) m
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
k':key

find k' m = find k' (add k e (of_list l))
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
k':key

findA (eqb k') ((k, e) :: l) = (if eq_dec k k' then Some e else findA (eqb k') l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
k':key
NoDupA eqk l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
k':key
NoDupA eqk l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
k':key
NoDupA eqk l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
k':key

NoDupA eqk l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

P (of_list l) (fold_right F i l)
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame: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:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
NoDupA eqk l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
forall k0 : key, find k0 (of_list l) = findA (eqb k0) l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

NoDupA eqk l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)
forall k0 : key, find k0 (of_list l) = findA (eqb k0) l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k0 : key, find k0 m = findA (eqb k0) ((k, e) :: l)

forall k0 : key, find k0 (of_list l) = findA (eqb k0) l
elt, A:Type
P:t elt -> A -> Type
i:A
Hempty:forall m0 : t elt, Empty m0 -> P m0 i
F:key * elt -> A -> A
k:key
e:elt
l: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 elt
Hsame:forall k1 : key, find k1 m = findA (eqb k1) ((k, e) :: l)
k0:key

NoDupA eqk l
inversion_clear Hdup; auto. Qed.
Same, with empty and add instead of Empty and Add. In this case, P must be compatible with equality of sets
  
elt:Type

forall (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:Type

forall (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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m' : t elt) (a : A), Equal m0 m' -> P m0 a -> P m' a
Pempty:P (empty elt) i
Pstep: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:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' a
Pempty:P (empty elt) i
Pstep: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 elt
H:Empty m0

P m0 i
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0
Pempty:P (empty elt) i
Pstep: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:key
e:elt
a:A
m', m'':t elt
H:MapsTo k e m
H0:~ In k m'
H1:Add k e m' m''
X:P m' a
P m'' (f k e a)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' a
Pempty:P (empty elt) i
Pstep: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 elt
H:Empty m0

Equal (empty elt) m0
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0
Pempty:P (empty elt) i
Pstep: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:key
e:elt
a:A
m', m'':t elt
H:MapsTo k e m
H0:~ In k m'
H1:Add k e m' m''
X:P m' a
P m'' (f k e a)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' a
Pempty:P (empty elt) i
Pstep: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 elt
H:Empty m0
k:key

find k (empty elt) = find k m0
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0
Pempty:P (empty elt) i
Pstep: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:key
e:elt
a:A
m', m'':t elt
H:MapsTo k e m
H0:~ In k m'
H1:Add k e m' m''
X:P m' a
P m'' (f k e a)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' a
Pempty:P (empty elt) i
Pstep: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 elt
H:Empty m0
k:key

None = find k m0
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0
Pempty:P (empty elt) i
Pstep: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:key
e:elt
a:A
m', m'':t elt
H:MapsTo k e m
H0:~ In k m'
H1:Add k e m' m''
X:P m' a
P m'' (f k e a)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m1 m' : t elt) (a : A), Equal m1 m' -> P m1 a -> P m' a
Pempty:P (empty elt) i
Pstep: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 elt
H:Empty m0
k:key
e':elt

MapsTo k e' m0 -> None = Some e'
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0
Pempty:P (empty elt) i
Pstep: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:key
e:elt
a:A
m', m'':t elt
H:MapsTo k e m
H0:~ In k m'
H1:Add k e m' m''
X:P m' a
P m'' (f k e a)
elt, A:Type
P:t elt -> A -> Type
f:key -> elt -> A -> A
i:A
m:t elt
Pmorphism:forall (m0 m'0 : t elt) (a0 : A), Equal m0 m'0 -> P m0 a0 -> P m'0 a0
Pempty:P (empty elt) i
Pstep: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:key
e:elt
a:A
m', m'':t elt
H:MapsTo k e m
H0:~ In k m'
H1:Add k e m' m''
X:P m' a

P m'' (f k e a)
apply Pmorphism with (add k e m'); try intro; auto. Qed.
elt:Type

forall (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)
elt:Type

forall (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.
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:Type

forall (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:Type

forall (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:Type

forall (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:Type

forall (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:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
m:t elt
Rempty:R i j
Rstep: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:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
m:t elt
Rempty:R i j
Rstep: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:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
m:t elt
Rempty:R i j
Rstep: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:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
m:t elt
Rempty:R i j
Rstep: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:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
Rempty:R i j
l: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:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
Rempty:R i j
a:(key * elt)%type
l: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))
elt, A, B:Type
R:A -> B -> Type
f:key -> elt -> A -> A
g:key -> elt -> B -> B
i:A
j:B
Rempty:R i j
a:(key * elt)%type
l: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)
destruct a; simpl; rewrite InA_cons; left; red; auto. Qed.
From the induction principle on fold, we can deduce some general induction principles on maps.
  
elt:Type

forall 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 m
elt:Type

forall 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 m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : key) (e : elt), ~ In x m0 -> Add x e m0 m' -> P m'
m:t elt

P m
apply (@fold_rec _ (fun s _ => P s) (fun _ _ _ => tt) tt m); eauto. Qed.
elt:Type

forall 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 m
elt:Type

forall 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 m
elt:Type
P:t elt -> Type
X: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 elt

P m
apply (@fold_rec_bis _ (fun s _ => P s) (fun _ _ _ => tt) tt m); eauto. Qed.
fold can be used to reconstruct the same initial set.
  
elt:Type

forall m : t elt, Equal (fold (add (elt:=elt)) m (empty elt)) m
elt:Type

forall m : t elt, Equal (fold (add (elt:=elt)) m (empty elt)) m
elt:Type
m:t elt

Equal (fold (add (elt:=elt)) m (empty elt)) m
elt:Type
m:t elt

forall m0 : t elt, Empty m0 -> Equal (empty elt) m0
elt:Type
m:t elt
forall (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:Type
m, m':t elt
Heq:Empty m'
k':key

find k' (empty elt) = find k' m'
elt:Type
m:t elt
forall (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:Type
m, m':t elt
Heq:Empty m'
k':key

None = find k' m'
elt:Type
m:t elt
forall (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:Type
m, m':t elt
Heq:Empty m'
k':key
e':elt

MapsTo k' e' m' -> None = Some e'
elt:Type
m:t elt
forall (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:Type
m:t elt

forall (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:Type
m:t elt
k:key
e:elt
a, m', m'':t elt
Hadd:Add k e m' m''
Heq:Equal a m'
k':key

find k' (add k e a) = find k' m''
elt:Type
m:t elt
k:key
e:elt
a, m', m'':t elt
Hadd:Add k e m' m''
Heq:forall y : key, find y a = find y m'
k':key

find k' (add k e a) = find k' m''
rewrite Hadd, 2 add_o, Heq; auto. Qed. Section Fold_More.

Additional properties of fold

  
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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f

forall (m : t elt) (i i' : A), eqA i i' -> eqA (fold f m i) (fold f m i')
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f

forall (m : t elt) (i i' : A), eqA i i' -> eqA (fold f m i) (fold f m i')
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i, i':A
H:eqA i i'

eqA (fold f m i) (fold f m i')
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i, i':A
H: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)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i, i':A
H:eqA i i'
k:key
e:elt
a, b:A
H0:MapsTo k e m
H1:eqA a b

eqA (f k e a) (f k e b)
apply Comp; auto. Qed.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f

forall (m : t elt) (i : A), Empty m -> eqA (fold f m i) i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f

forall (m : t elt) (i : A), Empty m -> eqA (fold f m i) i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i:A
H:Empty m

eqA (fold f m i) i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i:A
H:Empty m

eqA i i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i:A
H:Empty m
forall (k : key) (e : elt) (a : A), MapsTo k e m -> eqA a i -> eqA (f k e a) i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i:A
H:Empty m

forall (k : key) (e : elt) (a : A), MapsTo k e m -> eqA a i -> eqA (f k e a) i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
m:t elt
i:A
H:Empty m
k:key
e:elt
a:A
H0:MapsTo k e m
H1:eqA a i

eqA (f k e a) i
elim (H k e); auto. Qed.
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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m

eqA (fold f m (f k e i)) (f k e (fold f m i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m

eqA (f k e i) (f k e i)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m
forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m
k0:key
e0:elt
a, b:A
H:MapsTo k0 e0 m
H0:eqA a (f k e b)

eqA (f k0 e0 a) (f k e (f k0 e0 b))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m
k0:key
e0:elt
a, b:A
H:MapsTo k0 e0 m
H0:eqA a (f k e b)

eqA (f k0 e0 a) (f k0 e0 (f k e b))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m
k0:key
e0:elt
a, b:A
H:MapsTo k0 e0 m
H0:eqA a (f k e b)
eqA (f k0 e0 (f k e b)) (f k e (f k0 e0 b))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m
k0:key
e0:elt
a, b:A
H:MapsTo k0 e0 m
H0:eqA a (f k e b)

eqA (f k0 e0 (f k e b)) (f k e (f k0 e0 b))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
i:A
m:t elt
k:key
e:elt
Hnotin:~ In k m
k0:key
e0:elt
a, b:A
H:MapsTo k0 e0 m
H0:eqA a (f k e b)

~ E.eq k0 k
contradict Hnotin; rewrite <- Hnotin; exists e0; auto. Qed. Hint Resolve NoDupA_eqk_eqke NoDupA_rev elements_3w : map.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (m1 m2 : t elt) (i : A), Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (m1 m2 : t elt) (i : A), Equal m1 m2 -> eqA (fold f m1 i) (fold f m2 i)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2

eqA (fold f m1 i) (fold f m2 i)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2

eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))

eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqA ==> eqA) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
transpose_restr eqA (complement eqk) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
transpose_restr eqA (complement eqk) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
transpose_restr eqA (complement eqk) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))

transpose_restr eqA (complement eqk) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))

ForallOrdPairs (complement eqk) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))

equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i:A
H:Equal m1 m2
H0:NoDupA eqk (rev (elements m1))
H1:NoDupA eqk (rev (elements m2))
k:key
e:elt

InA eqke (k, e) (rev (elements m1)) <-> InA eqke (k, e) (rev (elements m2))
rewrite 2 InA_rev, <- 2 elements_mapsto_iff, 2 find_mapsto_iff, H; auto with *. Qed.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (m1 m2 : t elt) (i j : A), Equal m1 m2 -> eqA i j -> eqA (fold f m1 i) (fold f m2 j)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (m1 m2 : t elt) (i j : A), Equal m1 m2 -> eqA i j -> eqA (fold f m1 i) (fold f m2 j)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j

eqA (fold f m1 i) (fold f m2 j)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j

eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) j (rev (elements m2)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))

eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) j (rev (elements m2)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqA ==> eqA) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
transpose_restr2 eqA (complement eqk) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqA ==> eqA) (uncurry f)
intros (k1,e1) (k2,e2) (Hk,He) a1 a2 Ha; simpl in *; apply Comp; auto.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1: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)
intuition eauto.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

transpose_restr2 eqA (complement eqk) (uncurry f)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
k:key
e:elt
k':key
e':elt
z, z':A
h: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'))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
k:key
e:elt
k':key
e':elt
z, z':A
h: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

ForallOrdPairs (complement eqk) (rev (elements m1))
rewrite <- NoDupA_altdef; auto.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

equivlistA eqke (rev (elements m1)) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
i, j:A
H:Equal m1 m2
H0:eqA i j
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
k:key
e:elt

InA eqke (k, e) (rev (elements m1)) <-> InA eqke (k, e) (rev (elements m2))
rewrite 2 InA_rev, <- 2 elements_mapsto_iff, 2 find_mapsto_iff, H; auto with *. Qed.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2

eqA (fold f m2 i) (f k e (fold f m1 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2

eqA (fold_right (uncurry f) i (rev (elements m2))) (f k e (fold_right (uncurry f) i (rev (elements m1))))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m2))) (f k e (fold_right f' i (rev (elements m1))))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m2))) (f' (k, e) (fold_right f' i (rev (elements m1))))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqA ==> eqA) f'
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
transpose_restr eqA (complement eqk) f'
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
~ InA eqke (k, e) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
k1:key
e1:elt
k2:key
e2:elt
Hk:E.eq k1 k2
He:e1 = e2
a, a':A
Ha:eqA a a'

eqA (uncurry f (k1, e1) a) (uncurry f (k2, e2) a')
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
transpose_restr eqA (complement eqk) f'
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
~ InA eqke (k, e) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

Proper (eqke ==> eqke ==> iff) (complement eqk)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
transpose_restr eqA (complement eqk) f'
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
~ InA eqke (k, e) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

transpose_restr eqA (complement eqk) f'
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
ForallOrdPairs (complement eqk) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
~ InA eqke (k, e) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

ForallOrdPairs (complement eqk) (rev (elements m2))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
~ InA eqke (k, e) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

~ InA eqke (k, e) (rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

~ MapsTo k e m1
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))

equivlistA eqke (rev (elements m2)) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt

InA eqke (a, b) (rev (elements m2)) <-> InA eqke (a, b) ((k, e) :: rev (elements m1))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt

find a m2 = Some b <-> eqke (a, b) (k, e) \/ find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt

find a m2 = Some b <-> E.eq a k /\ b = e \/ find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt

find a (add k e m1) = Some b <-> E.eq a k /\ b = e \/ find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b: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 b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
EQ:E.eq k a

Some e = Some b -> E.eq a k /\ b = e \/ find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
EQ:E.eq k a
E.eq a k /\ b = e \/ find a m1 = Some b -> Some e = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
NEQ:~ E.eq k a
E.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
EQ:E.eq k a

E.eq a k /\ b = e \/ find a m1 = Some b -> Some e = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
NEQ:~ E.eq k a
E.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:In k m1 -> False
H0:Add k e m1 m2
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
EQ:E.eq k a
H4:find a m1 = Some b
X0:A

Some e = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
NEQ:~ E.eq k a
E.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:In k m1 -> False
H0:Add k e m1 m2
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
EQ:E.eq k a
H4:find a m1 = Some b
X0:A

In k m1
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
NEQ:~ E.eq k a
E.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:~ In k m1
H0:Add k e m1 m2
f':=uncurry f:key * elt -> A -> A
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
NEQ:~ E.eq k a

E.eq a k /\ b = e \/ find a m1 = Some b -> find a m1 = Some b
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m1, m2:t elt
k:key
e:elt
i:A
H:In k m1 -> False
H0:Add k e m1 m2
H1:NoDupA eqk (rev (elements m1))
H2:NoDupA eqk (rev (elements m2))
a:key
b:elt
NEQ:E.eq k a -> False
H3:E.eq a k
H5:b = e
X0:A

find a m1 = Some b
elim NEQ; auto. Qed.
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey
m:t elt
k:key
e:elt
i:A
H:~ 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.

Cardinal

  
elt:Type

forall m : t elt, cardinal m = fold (fun (_ : key) (_ : elt) => S) m 0
elt:Type

forall m : t elt, cardinal m = fold (fun (_ : key) (_ : elt) => S) m 0
elt:Type
m:t elt

length (elements m) = fold_left (fun (a : nat) (_ : key * elt) => S a) (elements m) 0
symmetry; apply fold_left_length; auto. Qed.
elt:Type

forall m : t elt, Empty m <-> cardinal m = 0
elt:Type

forall m : t elt, Empty m <-> cardinal m = 0
elt:Type
m:t elt

Empty m <-> cardinal m = 0
elt:Type
m:t elt

elements m = nil <-> length (elements m) = 0
destruct (elements m); intuition; discriminate. Qed.
elt:Type

forall m m' : t elt, Equal m m' -> cardinal m = cardinal m'
elt:Type

forall m m' : t elt, Equal m m' -> cardinal m = cardinal m'
elt:Type
m, m':t elt
H:Equal m m'

fold (fun (_ : key) (_ : elt) => S) m 0 = fold (fun (_ : key) (_ : elt) => S) m' 0
apply fold_Equal with (eqA:=eq); compute; auto. Qed.
elt:Type

forall m : t elt, Empty m -> cardinal m = 0
elt:Type

forall m : t elt, Empty m -> cardinal m = 0
intros; rewrite <- cardinal_Empty; auto. Qed.
elt:Type

forall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> cardinal m' = S (cardinal m)
elt:Type

forall (m m' : t elt) (x : key) (e : elt), ~ In x m -> Add x e m m' -> cardinal m' = S (cardinal m)
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

fold (fun (_ : key) (_ : elt) => S) m' 0 = S (fold (fun (_ : key) (_ : elt) => S) m 0)
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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)
apply fold_Add with (eqA:=eq); compute; auto. Qed.
elt:Type

forall m : t elt, cardinal m = 0 -> Empty m
elt:Type

forall m : t elt, cardinal m = 0 -> Empty m
intros; rewrite cardinal_Empty; auto. Qed. Hint Resolve cardinal_inv_1 : map.
elt:Type

forall (m : t elt) (n : nat), cardinal m = S n -> {p : key * elt | MapsTo (fst p) (snd p) m}
elt:Type

forall (m : t elt) (n : nat), cardinal m = S n -> {p : key * elt | MapsTo (fst p) (snd p) m}
elt:Type
m:t elt
n:nat
H:length (elements m) = S n

{p : key * elt | MapsTo (fst p) (snd p) m}
elt:Type
m:t elt
n:nat
H: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:Type
m:t elt
n:nat
p:(key * elt)%type
l: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:Type
m:t elt
n:nat
p:(key * elt)%type
l:list (key * elt)
H:length (p :: l) = S n
H0:forall (x : key) (e : elt), MapsTo x e m <-> InA eqke (x, e) (p :: l)

MapsTo (fst p) (snd p) m
elt:Type
m:t elt
n:nat
k:key
e:elt
l:list (key * elt)
H:length ((k, e) :: l) = S n
H0:forall (x : key) (e0 : elt), MapsTo x e0 m <-> InA eqke (x, e0) ((k, e) :: l)

InA eqke (k, e) ((k, e) :: l)
constructor; red; auto. Qed.
elt:Type

forall m : t elt, cardinal m <> 0 -> {p : key * elt | MapsTo (fst p) (snd p) m}
elt:Type

forall m : t elt, cardinal m <> 0 -> {p : key * elt | MapsTo (fst p) (snd p) m}
elt:Type
m:t elt
H:cardinal m <> 0

{p : key * elt | MapsTo (fst p) (snd p) m}
elt:Type
m:t elt
H: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:Type
m:t elt
n:nat
H: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}
elt:Type
m:t elt
n:nat
H: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.

Additional notions over maps

  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).

Emulation of some functions lacking in the interface

  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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (m : t elt) (k : key) (e : elt), MapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (m : t elt) (k : key) (e : elt), MapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m : t elt) => if f k e then add k e m else m:key -> elt -> t elt -> t elt

forall (m : t elt) (k : key) (e : elt), MapsTo k e (fold f' m (empty elt)) <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt

forall (k : key) (e : elt), MapsTo k e (fold f' m (empty elt)) <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt

forall m0 : t elt, Empty m0 -> forall (k : key) (e : elt), MapsTo k e (empty elt) <-> MapsTo k e m0 /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt
forall (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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t elt
m, m':t elt
Hm':Empty m'
k:key
e:elt

MapsTo k e (empty elt) <-> MapsTo k e m' /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt
forall (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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t elt
m, m':t elt
Hm':Empty m'
k:key
e:elt

False <-> MapsTo k e m' /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt
forall (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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m':t elt
Hm':Empty m'
k:key
e:elt
X:t elt
H0:MapsTo k e m'
H1:f k e = true

False
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt
forall (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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (m0 : t elt) => if f k e then add k e m0 else m0:key -> elt -> t elt -> t elt
m:t elt

forall (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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t elt
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:~ In k m1
Hadd:Add k e m1 m2
IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 acc <-> MapsTo k0 e0 m1 /\ f k0 e0 = true
k':key
e':elt

MapsTo k' e' (f' k e acc) <-> MapsTo k' e' m2 /\ f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t elt
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 acc <-> MapsTo k0 e0 m1 /\ f k0 e0 = true
k':key
e':elt

MapsTo k' e' (f' k e acc) <-> MapsTo k' e' (add k e m1) /\ f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (m0 : t elt) => if f k0 e0 then add k0 e0 m0 else m0:key -> elt -> t elt -> t elt
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 acc <-> MapsTo k0 e0 m1 /\ f k0 e0 = true
k':key
e':elt

MapsTo k' e' (if f k e then add k e acc else acc) <-> MapsTo k' e' (add k e m1) /\ f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = true
X:t elt
H:E.eq k k'
H1:e = e'

f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H0:MapsTo k' e' m1
H1:f k' e' = true
E.eq k k' /\ e = e' \/ (E.eq k k' -> False) /\ MapsTo k' e' m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H1:f k' e' = true
H0:E.eq k k'
H2:e = e'
MapsTo k' e' m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H0:MapsTo k' e' m1
H1:f k' e' = true

E.eq k k' /\ e = e' \/ (E.eq k k' -> False) /\ MapsTo k' e' m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H1:f k' e' = true
H0:E.eq k k'
H2:e = e'
MapsTo k' e' m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H0:MapsTo k' e' m1
H1:f k' e' = true
Hk:E.eq k k'

E.eq k k' /\ e = e'
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H1:f k' e' = true
H0:E.eq k k'
H2:e = e'
MapsTo k' e' m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H1:f k' e' = true
H0:E.eq k k'
H2:e = e'

MapsTo k' e' m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
acc, m1, m2:t elt
Hke:MapsTo k e m
Hn:In k m1 -> False
Hadd:Equal m2 (add k e m1)
k':key
e':elt
Hfke:f k e = false
X:t elt
H1:f k' e' = true
H0:E.eq k k'
H2:e = e'
H:f k e = f k' e'

MapsTo k' e' m1
congruence. Qed.
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall m : t elt, for_all f m = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall m : t elt, for_all f m = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall 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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool

forall m : t elt, fold f' m true = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt

fold f' m true = true <-> (forall (k : key) (e : elt), MapsTo k e m -> f k e = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt

forall m0 : t elt, Empty m0 -> true = true <-> (forall (k : key) (e : elt), MapsTo k e m0 -> f k e = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m, m':t elt
Hm':Empty m'

true = true <-> (forall (k : key) (e : elt), MapsTo k e m' -> f k e = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m, m':t elt
Hm':Empty m'

true = true -> forall (k : key) (e : elt), MapsTo k e m' -> f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b : bool) => if f k0 e0 then b else false:key -> elt -> bool -> bool
m, m':t elt
Hm':Empty m'
k:key
e:elt
Hke:MapsTo k e m'

f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then b else false:key -> elt -> bool -> bool
m:t elt

forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
m:t elt
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Add k e m1 m2
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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Add k e m1 m2
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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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

b = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
(* f k e = true *)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m2

f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m1
f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true
k':key
e':elt
Hke':E.eq k k' /\ e = e' \/ ~ E.eq k k' /\ MapsTo k' e' m1

f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m1
f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 -> f k0 e0 = true
k':key
e':elt
H:E.eq k k'
H0:e = e'

f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m1
f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m1

f k' e' = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m1

MapsTo k' e' m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = true
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true
k':key
e':elt
Hke':MapsTo k' e' m1

~ E.eq k k'
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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

false = true <-> (forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true)
(* f k e = false *)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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 = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true

false = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true

f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then b0 else false:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
Hmapsto:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m2 -> f k0 e0 = true

MapsTo k e m2
rewrite Hadd, add_mapsto_iff; auto. Qed.
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall m : t elt, exists_ f m = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall m : t elt, exists_ f m = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall 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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool

forall 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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m:t elt

forall m0 : t elt, Empty m0 -> false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m0 /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m, m':t elt
Hm':Empty m'

false = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m, m':t elt
Hm':Empty m'

(exists p : key * elt, MapsTo (fst p) (snd p) m' /\ f (fst p) (snd p) = true) -> false = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b : bool) => if f k0 e0 then true else b:key -> elt -> bool -> bool
m, m':t elt
Hm':Empty m'
k:key
e:elt
Hke:MapsTo k e m'

false = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m:t elt
forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k : key) (e : elt) (b : bool) => if f k e then true else b:key -> elt -> bool -> bool
m:t elt

forall (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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
m:t elt
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Add k e m1 m2
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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Add k e m1 m2
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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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 = true

true = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)
(* f k e = true *)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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 = true

exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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 = true

MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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
b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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

b = true <-> (exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true)
(* f k e = false *)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd: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:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m1
Hke2:f k' e' = true

exists p : key * elt, MapsTo (fst p) (snd p) m2 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m2
Hke2:f k' e' = true
exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m1
Hke2:f k' e' = true

MapsTo k' e' m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m2
Hke2:f k' e' = true
exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m1
Hke2:f k' e' = true

~ E.eq k k'
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m2
Hke2:f k' e' = true
exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m1
Hke2:f k' e' = true
Hn:E.eq k k'

In k m1
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m2
Hke2:f k' e' = true
exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:MapsTo k' e' m2
Hke2:f k' e' = true

exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
Hke1:E.eq k k' /\ e = e' \/ ~ E.eq k k' /\ MapsTo k' e' m1
Hke2:f k' e' = true

exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
H:E.eq k k'
H0:e = e'
Hke2:f k' e' = true

exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
H:~ E.eq k k'
H0:MapsTo k' e' m1
Hke2:f k' e' = true
exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
H:E.eq k k'
H0:e = e'
Hke2:f k' e' = true
H1:f k' e' = f k e

exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
H:~ E.eq k k'
H0:MapsTo k' e' m1
Hke2:f k' e' = true
exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
f':=fun (k0 : key) (e0 : elt) (b0 : bool) => if f k0 e0 then true else b0:key -> elt -> bool -> bool
k:key
e:elt
b:bool
m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
Hfke:f k e = false
k':key
e':elt
H:~ E.eq k k'
H0:MapsTo k' e' m1
Hke2:f k' e' = true

exists p : key * elt, MapsTo (fst p) (snd p) m1 /\ f (fst p) (snd p) = true
exists (k',e'); auto. Qed. End Specs.
elt:Type

forall m m' : t elt, Disjoint m m' <-> (forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False)
elt:Type

forall m m' : t elt, Disjoint m m' <-> (forall (k : key) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> False)
elt:Type
m, 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' -> False
elt:Type
m, 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:Type
m, m':t elt
H:forall k0 : key, ~ (In k0 m /\ In k0 m')
k:key
v, v':elt
H1:MapsTo k v m
H2:MapsTo k v' m'

False
elt:Type
m, 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:Type
m, m':t elt
H:forall k0 : key, ~ (In k0 m /\ In k0 m')
k:key
v, v':elt
H1:MapsTo k v m
H2:MapsTo k v' m'

In k m
elt:Type
m, m':t elt
H:forall k0 : key, ~ (In k0 m /\ In k0 m')
k:key
v, v':elt
H1:MapsTo k v m
H2:MapsTo k v' m'
In k m'
elt:Type
m, 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:Type
m, m':t elt
H:forall k0 : key, ~ (In k0 m /\ In k0 m')
k:key
v, v':elt
H1:MapsTo k v m
H2:MapsTo k v' m'

In k m'
elt:Type
m, 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:Type
m, 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:Type
m, m':t elt
H:forall (k0 : key) (e e' : elt), MapsTo k0 e m -> MapsTo k0 e' m' -> False
k:key
v:elt
Hv:MapsTo k v m
v':elt
Hv':MapsTo k v' m'

False
eapply H; eauto. Qed. Section Partition. Variable f : key -> elt -> bool. Hypothesis Hf : Proper (E.eq==>eq==>eq) f.
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (m m1 : t elt) (k : key) (e : elt), m1 = fst (partition f m) -> MapsTo k e m1 <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (m m1 : t elt) (k : key) (e : elt), m1 = fst (partition f m) -> MapsTo k e m1 <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1:t elt
k:key
e:elt
H:m1 = filter f m

MapsTo k e m1 <-> MapsTo k e m /\ f k e = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt

MapsTo k e (filter f m) <-> MapsTo k e m /\ f k e = true
apply filter_iff; auto. Qed.
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (m m2 : t elt) (k : key) (e : elt), m2 = snd (partition f m) -> MapsTo k e m2 <-> MapsTo k e m /\ f k e = false
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall (m m2 : t elt) (k : key) (e : elt), m2 = snd (partition f m) -> MapsTo k e m2 <-> MapsTo k e m /\ f k e = false
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m2:t elt
k:key
e:elt
H:m2 = filter (fun (k0 : key) (e0 : elt) => negb (f k0 e0)) m

MapsTo k e m2 <-> MapsTo k e m /\ f k e = false
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt

MapsTo k e (filter (fun (k0 : key) (e0 : elt) => negb (f k0 e0)) m) <-> MapsTo k e m /\ f k e = false
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt

MapsTo k e m /\ negb (f k e) = true <-> MapsTo k e m /\ f k e = false
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
H:MapsTo k e m
H':negb (f k e) = true

f k e = false
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
H:MapsTo k e m
H':f k e = false
negb (f k e) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
H:MapsTo k e m
H':f k e = false

negb (f k e) = true
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt

Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (e0 : elt) => negb (f k0 e0))
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
x, y:E.t
H:E.eq x y
x0, y0:elt
H0:x0 = y0

negb (f x x0) = negb (f y y0)
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m:t elt
k:key
e:elt
x, y:E.t
H:E.eq x y
x0, y0:elt
H0:x0 = y0

f x x0 = f y y0
apply Hf; auto. Qed.
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall m m1 m2 : t elt, partition f m = (m1, m2) -> Partition m m1 m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

forall m m1 m2 : t elt, partition f m = (m1, m2) -> Partition m m1 m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)

Partition m m1 m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)

Disjoint m1 m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)

forall (k : key) (e e' : elt), MapsTo k e m1 -> MapsTo k e' m2 -> False
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
k:key
e, e':elt

MapsTo k e m1 -> MapsTo k e' m2 -> False
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
k:key
e, e':elt

MapsTo k e m /\ f k e = true -> MapsTo k e' m /\ f k e' = false -> False
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
k:key
e, e':elt
U:MapsTo k e m
V:f k e = true
W:MapsTo k e' m
Z:f k e' = false

False
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)

forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
k:key
e:elt

MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
elt:Type
f:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m, m1, m2:t elt
H:partition f m = (m1, m2)
k:key
e:elt

MapsTo k e m <-> MapsTo k e m /\ f k e = true \/ MapsTo k e m /\ f k e = false
destruct (f k e); intuition. Qed. End Partition.
elt:Type

forall (m m1 m2 : t elt) (k : key), Partition m m1 m2 -> In k m -> {In k m1} + {In k m2}
elt:Type

forall (m m1 m2 : t elt) (k : key), Partition m m1 m2 -> In k m -> {In k m1} + {In k m2}
elt:Type
m, m1, m2:t elt
k:key
Hm:Partition m m1 m2
Hk:In k m

{In k m1} + {In k m2}
elt:Type
m, m1, m2:t elt
k:key
Hm:Partition m m1 m2
Hk:In k m
H:~ In k m1

In k m2
elt:Type
m, m1, m2:t elt
k:key
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e : elt), MapsTo k0 e m <-> MapsTo k0 e m1 \/ MapsTo k0 e m2
Hk:In k m
H:~ In k m1

In k m2
elt:Type
m, m1, m2:t elt
k:key
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
e:elt
H0:MapsTo k e m1
H:~ In k m1

In k m2
elt:Type
m, m1, m2:t elt
k:key
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
e:elt
H0:MapsTo k e m2
H:~ In k m1
In k m2
elt:Type
m, m1, m2:t elt
k:key
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
e:elt
H0:MapsTo k e m2
H:~ In k m1

In k m2
exists e; auto. Defined.
elt:Type

forall m1 m2 : t elt, Disjoint m1 m2 -> Disjoint m2 m1
elt:Type

forall m1 m2 : t elt, Disjoint m1 m2 -> Disjoint m2 m1
elt:Type
m1, m2:t elt
H:Disjoint m1 m2
k:key
H1:In k m2
H2:In k m1

False
elim (H k); auto. Qed.
elt:Type

forall m m1 m2 : t elt, Partition m m1 m2 -> Partition m m2 m1
elt:Type

forall m m1 m2 : t elt, Partition m m1 m2 -> Partition m m2 m1
elt:Type
m, m1, m2:t elt
H:Disjoint m1 m2
H':forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2

Disjoint m2 m1
elt:Type
m, m1, m2:t elt
H:Disjoint m1 m2
H':forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m2 \/ MapsTo k e m1
elt:Type
m, m1, m2:t elt
H:Disjoint m1 m2
H':forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2

forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m2 \/ MapsTo k e m1
intros; rewrite H'; intuition. Qed.
elt:Type

forall m m1 m2 : t elt, Partition m m1 m2 -> Empty m <-> Empty m1 /\ Empty m2
elt:Type

forall m m1 m2 : t elt, Partition m m1 m2 -> Empty m <-> Empty m1 /\ Empty m2
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2

Empty m <-> Empty m1 /\ Empty m2
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2

Empty m -> Empty m1 /\ Empty m2
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
Empty m1 /\ Empty m2 -> Empty m
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
He:Empty m

Empty m1 /\ Empty m2
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2
Empty m1 /\ Empty m2 -> Empty m
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m1 \/ MapsTo k e m2

Empty m1 /\ Empty m2 -> Empty m
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
He1:Empty m1
He2:Empty m2
k:key
e:elt
Hke:MapsTo k e m

False
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
He1:Empty m1
He2:Empty m2
k:key
e:elt
Hke:MapsTo k e m1 \/ MapsTo k e m2

False
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
He1:Empty m1
He2:Empty m2
k:key
e:elt
H:MapsTo k e m1

False
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
He1:Empty m1
He2:Empty m2
k:key
e:elt
H:MapsTo k e m2
False
elt:Type
m, m1, m2:t elt
Hdisj:Disjoint m1 m2
Heq:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
He1:Empty m1
He2:Empty m2
k:key
e:elt
H:MapsTo k e m2

False
elim (He2 k e); auto. Qed.
elt:Type

forall (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 m3
elt:Type

forall (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 m3
elt:Type

forall (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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2

Equal m (remove x m')
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Equal m' (add x e m)
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2

Equal m (remove x m')
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Equal m' (add x e m)
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2

Equal m (remove x (add x e m))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Equal m' (add x e m)
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
k:key

find k m = find k (remove x (add x e m))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Equal m' (add x e m)
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
k:key

find k m = (if eq_dec x k then None else if eq_dec x k then Some e else find k m)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Equal m' (add x e m)
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
k:key
He:E.eq x k

find k m = None
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')

MapsTo x e m'
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Equal m' (add x e m)
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')

MapsTo x e (add x e m)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq: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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1

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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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)
(* first case : x in m1 *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1

Add 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1

Add x e (remove x m1) m1
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
Disjoint (remove x m1) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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)
(* add *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1

Equal m1 (add x e (remove x m1))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
Disjoint (remove x m1) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k:key

find k m1 = find k (add x e (remove x m1))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
Disjoint (remove x m1) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k:key

find k m1 = (if eq_dec x k then Some e else if eq_dec x k then None else find k m1)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
Disjoint (remove x m1) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k:key
He:E.eq x k

find k m1 = Some e
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
Disjoint (remove x m1) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1

Disjoint (remove x m1) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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)
(* disjoint *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k:key
H1:In k (remove x m1)
H2:In k m2

False
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k:key
H1:In k (remove x m1)
H2:In k m2

In k m1 /\ In k m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k:key
H1:In k (remove x m1)
H2:In k m2

In k m1
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1

forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 (remove x m1) \/ MapsTo k e0 m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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)
(* mapsto *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k':key
e':elt

MapsTo k' e' m <-> MapsTo k' e' (remove x m1) \/ MapsTo k' e' m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k':key
e':elt

~ E.eq x k' /\ (MapsTo k' e' m1 \/ MapsTo k' e' m2) <-> ~ E.eq x k' /\ MapsTo k' e' m1 \/ MapsTo k' e' m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:In x m -> False
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k':key
e':elt
H1:MapsTo k' e' m2
H0:E.eq x k'

False
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:In x m -> False
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m1
k':key
e':elt
H1:MapsTo k' e' m2
H0:E.eq x k'

MapsTo x e' m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e 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)
(* second case : x in m2 *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2

Add 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))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2

Add x e (remove x m2) m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
Disjoint m1 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
(* add *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2

Equal m2 (add x e (remove x m2))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
Disjoint m1 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k:key

find k m2 = find k (add x e (remove x m2))
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
Disjoint m1 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k:key

find k m2 = (if eq_dec x k then Some e else if eq_dec x k then None else find k m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
Disjoint m1 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k:key
He:E.eq x k

find k m2 = Some e
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
Disjoint m1 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2

Disjoint m1 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
(* disjoint *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k:key
H1:In k m1
H2:In k (remove x m2)

False
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k:key
H1:In k m1
H2:In k (remove x m2)

In k m1 /\ In k m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m' <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k:key
H1:In k m1
H2:In k (remove x m2)

In k m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2

forall (k : key) (e0 : elt), MapsTo k e0 m <-> MapsTo k e0 m1 \/ MapsTo k e0 (remove x m2)
(* mapsto *)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k':key
e':elt

MapsTo k' e' m <-> MapsTo k' e' m1 \/ MapsTo k' e' (remove x m2)
elt:Type
m, m':t elt
x:key
e:elt
Hn:~ In x m
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k':key
e':elt

~ E.eq x k' /\ (MapsTo k' e' m1 \/ MapsTo k' e' m2) <-> MapsTo k' e' m1 \/ ~ E.eq x k' /\ MapsTo k' e' m2
elt:Type
m, m':t elt
x:key
e:elt
Hn:In x m -> False
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k':key
e':elt
H1:MapsTo k' e' m1
H0:E.eq x k'

False
elt:Type
m, m':t elt
x:key
e:elt
Hn:In x m -> False
Hadd:Add x e m m'
m1, m2:t elt
Hdisj:Disjoint m1 m2
Hor:forall (k : key) (e0 : elt), MapsTo k e0 m' <-> MapsTo k e0 m1 \/ MapsTo k e0 m2
Heq:Equal m (remove x m')
H:MapsTo x e m2
k':key
e':elt
H1:MapsTo k' e' m1
H0:E.eq x k'

MapsTo x e' m1
apply MapsTo_1 with k'; auto. Qed.
elt:Type

forall (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:Type

forall (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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m:t elt
Hm:Empty m

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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m:t elt
Hm:Empty m
m1, m2:t elt
i:A
Hp:Partition m m1 m2

eqA (fold f m i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m:t elt
Hm:Empty m
m1, m2:t elt
i:A
Hp:Partition m m1 m2

eqA i (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m1, m2:t elt
Hm:Empty m1 /\ Empty m2
i:A
Hp:Partition m m1 m2

eqA i (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m1, m2:t elt
H:Empty m1
H0:Empty m2
i:A
Hp:Partition m m1 m2

eqA i (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m1, m2:t elt
H:Empty m1
H0:Empty m2
i:A
Hp:Partition m m1 m2

eqA i i
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2

eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2

eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
(* fst case: m3 is (k,e)::m1 *)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2

~ In k m3
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
Hn:In k m3

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
e':elt
He':MapsTo k e' m3

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp1:Disjoint m3 m2
Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m3 \/ MapsTo k0 e0 m2
e':elt
He':MapsTo k e' m3

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp1:Disjoint m3 m2
Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m3 \/ MapsTo k0 e0 m2
e':elt
He':MapsTo k e' m3

MapsTo k e' m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (fold f m' i) (f k e (fold f m i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (fold f m1 (fold f m2 i)) (f k e (fold f m i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (fold f m1 (fold f m2 i)) (f k e (fold f m3 (fold f m2 i)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3
eqA (f k e (fold f m3 (fold f m2 i))) (f k e (fold f m i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (f k e (fold f m3 (fold f m2 i))) (f k e (fold f m i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m1
Hp':Partition m m3 m2
H:~ In k m3

eqA (fold f m3 (fold f m2 i)) (fold f m i)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3

eqA (fold f m' i) (fold f m1 (fold f m2 i))
(* snd case: m3 is (k,e)::m2 *)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3

~ In k m3
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
Hn:In k m3

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
e':elt
He':MapsTo k e' m3

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp1:Disjoint m1 m3
Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3
e':elt
He':MapsTo k e' m3

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp1:Disjoint m1 m3
Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3
e':elt
He':MapsTo k e' m3

MapsTo k e' m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3

eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3

~ In k m1
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
Hn:In k m1

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
e':elt
He':MapsTo k e' m1

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp1:Disjoint m1 m3
Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3
H:~ In k m3
e':elt
He':MapsTo k e' m1

In k m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp1:Disjoint m1 m3
Hp2:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m3
H:~ In k m3
e':elt
He':MapsTo k e' m1

MapsTo k e' m
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (fold f m' i) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (fold f m' i) (f k e (fold f m i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (f k e (fold f m i)) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (f k e (fold f m i)) (f k e (fold f m1 (fold f m3 i)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (f k e (fold f m1 (fold f m3 i))) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (f k e (fold f m1 (fold f m3 i))) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (f k e (fold f m1 (fold f m3 i))) (fold f m1 (f k e (fold f m3 i)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m1 (f k e (fold f m3 i))) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (fold f m1 (f k e (fold f m3 i))) (f k e (fold f m1 (fold f m3 i)))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1
eqA (fold f m1 (f k e (fold f m3 i))) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (fold f m1 (f k e (fold f m3 i))) (fold f m1 (fold f m2 i))
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (f k e (fold f m3 i)) (fold f m2 i)
elt, A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
Comp:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Tra:transpose_neqkey eqA f
m, m':t elt
k:key
e:elt
Hn:~ In k m
Hadd: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 elt
i:A
Hp:Partition m' m1 m2
m3:t elt
Hadd':Add k e m3 m2
Hp':Partition m m1 m3
H:~ In k m3
H0:~ In k m1

eqA (fold f m2 i) (f k e (fold f m3 i))
apply fold_Add with (eqA:=eqA); auto. Qed.
elt:Type

forall m m1 m2 : t elt, Partition m m1 m2 -> cardinal m = cardinal m1 + cardinal m2
elt:Type

forall m m1 m2 : t elt, Partition m m1 m2 -> cardinal m = cardinal m1 + cardinal m2
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2

cardinal m = cardinal m1 + cardinal m2
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2

fold (fun (_ : key) (_ : elt) => S) m 0 = fold (fun (_ : key) (_ : elt) => S) m1 0 + cardinal m2
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2
f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> nat

fold f m 0 = fold f m1 0 + cardinal m2
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2
f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> nat

fold f m1 (fold f m2 0) = fold f m1 0 + cardinal m2
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2
f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> nat
fold f m 0 = fold f m1 (fold f m2 0)
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2
f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> nat

fold f m1 (cardinal m2) = fold f m1 0 + cardinal m2
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2
f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> nat
fold f m 0 = fold f m1 (fold f m2 0)
elt:Type
m, m1, m2:t elt
H:Partition m m1 m2
f:=fun (_ : key) (_ : elt) => S:key -> elt -> nat -> nat

fold f m 0 = fold f m1 (fold f m2 0)
apply Partition_fold with (eqA:=eq); repeat red; auto. Qed.
elt:Type

forall 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:Type

forall 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:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> bool

Equal m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> bool

Proper (E.eq ==> eq ==> eq) f
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
Equal m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f

Equal m1 (fst (partition f m)) /\ Equal m2 (snd (partition f m))
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt

Equal m1 m1' /\ Equal m2 (snd (partition f m))
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k : key) (_ : elt) => mem k m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt

Equal m1 m1' /\ Equal m2 m2'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m1'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m /\ f k e = true
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m /\ mem k m1 = true
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m /\ In k m1
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m /\ In k m1
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m1 <-> (MapsTo k e m1 \/ MapsTo k e m2) /\ In k m1
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
H:MapsTo k e m1

In k m1
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
H1:In k m1
H:MapsTo k e m2
MapsTo k e m1
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
H1:In k m1
H:MapsTo k e m2

MapsTo k e m1
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m2 <-> MapsTo k e m2'
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m2 <-> MapsTo k e m /\ f k e = false
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m2 <-> MapsTo k e m /\ mem k m1 = false
elt:Type
m, m1, m2:t elt
Hm:Partition m m1 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m2 <-> MapsTo k e m /\ ~ In k m1
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m2 <-> MapsTo k e m /\ ~ In k m1
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt

MapsTo k e m2 <-> (MapsTo k e m1 \/ MapsTo k e m2) /\ ~ In k m1
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
H:MapsTo k e m2
H0:In k m1

False
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
H1:In k m1 -> False
H:MapsTo k e m1
MapsTo k e m2
elt:Type
m, m1, m2:t elt
Hm:Disjoint m1 m2
Hm':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m2
f:=fun (k0 : key) (_ : elt) => mem k0 m1:key -> elt -> bool
Hf:Proper (E.eq ==> eq ==> eq) f
m1':=fst (partition f m):t elt
m2':=snd (partition f m):t elt
k:key
e:elt
H1:In k m1 -> False
H:MapsTo k e m1

MapsTo k e m2
elim H1; exists e; auto. Qed.
elt:Type

forall (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:Type

forall (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:Type

forall (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:Type
m, m':t elt

forall (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:Type
m, 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:Type
m, m':t elt

forall m0 : t elt, Empty m0 -> forall (k : key) (e : elt), MapsTo k e m <-> MapsTo k e m0 \/ MapsTo k e m /\ ~ In k m0
elt:Type
m, m':t elt
forall (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:Type
m, m', m0:t elt
Hm0:Empty m0
k:key
e:elt

MapsTo k e m <-> MapsTo k e m0 \/ MapsTo k e m /\ ~ In k m0
elt:Type
m, m':t elt
forall (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:Type
m, m', m0:t elt
Hm0:Empty m0
k:key
e:elt
H:~ In k m0

MapsTo k e m <-> MapsTo k e m0 \/ MapsTo k e m /\ ~ In k m0
elt:Type
m, m':t elt
forall (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:Type
m, m', m0:t elt
Hm0:Empty m0
k:key
e:elt
H:In k m0 -> False
H1:MapsTo k e m0

MapsTo k e m
elt:Type
m, m':t elt
forall (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:Type
m, m':t elt

forall (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:Type
m, m':t elt
k:key
e:elt
m0, m1, m2:t elt
Hn:~ In k m1
Hadd:Add k e m1 m2
IH:forall (k0 : key) (e0 : elt), MapsTo k0 e0 m0 <-> MapsTo k0 e0 m1 \/ MapsTo k0 e0 m /\ ~ In k0 m1
k':key
e':elt

MapsTo k' e' (add k e m0) <-> MapsTo k' e' m2 \/ MapsTo k' e' m /\ ~ In k' m2
elt:Type
m, m':t elt
k:key
e:elt
m0, m1, m2:t elt
Hn:~ In k m1
Hadd: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 m1
k':key
e':elt

MapsTo k' e' (add k e m0) <-> MapsTo k' e' m2 \/ MapsTo k' e' m /\ ~ In k' m2
elt:Type
m, m':t elt
k:key
e:elt
m0, m1, m2:t elt
Hn:~ In k m1
Hadd: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 m1
k':key
e':elt

E.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:Type
m, m':t elt
k:key
e:elt
m0, m1, m2:t elt
Hn:~ In k m1
Hadd:Equal m2 (add k e m1)
k':key
e':elt

E.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:Type

forall (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:Type

forall (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:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e (update m m')

{MapsTo k e m'} + {MapsTo k e m /\ ~ In k m'}
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'

{MapsTo k e m'} + {MapsTo k e m /\ ~ In k m'}
elt:Type
m, m':t elt
k:key
e:elt
H':In k m' -> False
H0:MapsTo k e m'

MapsTo k e m
elim H'; exists e; auto. Defined.
elt:Type

forall (m m' : t elt) (k : key), In k (update m m') <-> In k m \/ In k m'
elt:Type

forall (m m' : t elt) (k : key), In k (update m m') <-> In k m \/ In k m'
elt:Type
m, m':t elt
k:key

In k (update m m') <-> In k m \/ In k m'
elt:Type
m, m':t elt
k:key

In k (update m m') -> In k m \/ In k m'
elt:Type
m, m':t elt
k:key
In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m' \/ MapsTo k e m /\ ~ In k m'

In k m \/ In k m'
elt:Type
m, m':t elt
k:key
In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key

In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
H:In k m'

In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'
In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m'

In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'
In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m'

MapsTo k e (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'
In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'

In k m \/ In k m' -> In k (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'
H':In k m

In k (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'
e:elt
H':MapsTo k e m

In k (update m m')
elt:Type
m, m':t elt
k:key
H:~ In k m'
e:elt
H':MapsTo k e m

MapsTo k e (update m m')
rewrite update_mapsto_iff; right; auto. Qed.
elt:Type

forall (m m' : t elt) (k : key) (e : elt), MapsTo k e (diff m m') <-> MapsTo k e m /\ ~ In k m'
elt:Type

forall (m m' : t elt) (k : key) (e : elt), MapsTo k e (diff m m') <-> MapsTo k e m /\ ~ In k m'
elt:Type
m, m':t elt
k:key
e:elt

MapsTo k e (diff m m') <-> MapsTo k e m /\ ~ In k m'
elt:Type
m, m':t elt
k:key
e:elt

MapsTo k e (filter (fun (k0 : key) (_ : elt) => negb (mem k0 m')) m) <-> MapsTo k e m /\ ~ In k m'
elt:Type
m, m':t elt
k:key
e:elt

MapsTo k e m /\ negb (mem k m') = true <-> MapsTo k e m /\ ~ In k m'
elt:Type
m, m':t elt
k:key
e:elt
Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => negb (mem k0 m'))
elt:Type
m, m':t elt
k:key
e:elt
H0:MapsTo k e m
H1:negb (mem k m') = true
H:In k m'

False
elt:Type
m, m':t elt
k:key
e:elt
Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => negb (mem k0 m'))
elt:Type
m, m':t elt
k:key
e:elt

Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => negb (mem k0 m'))
intros ? ? Hk _ _ _; rewrite Hk; auto. Qed.
elt:Type

forall (m m' : t elt) (k : key), In k (diff m m') <-> In k m /\ ~ In k m'
elt:Type

forall (m m' : t elt) (k : key), In k (diff m m') <-> In k m /\ ~ In k m'
elt:Type
m, m':t elt
k:key

In k (diff m m') <-> In k m /\ ~ In k m'
elt:Type
m, m':t elt
k:key

In k (diff m m') -> In k m /\ ~ In k m'
elt:Type
m, m':t elt
k:key
In k m /\ ~ In k m' -> In k (diff m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m /\ ~ In k m'

In k m /\ ~ In k m'
elt:Type
m, m':t elt
k:key
In k m /\ ~ In k m' -> In k (diff m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m
H0:~ In k m'

In k m
elt:Type
m, m':t elt
k:key
In k m /\ ~ In k m' -> In k (diff m m')
elt:Type
m, m':t elt
k:key

In k m /\ ~ In k m' -> In k (diff m m')
intros ((e,H),H'); exists e; rewrite diff_mapsto_iff; auto. Qed.
elt:Type

forall (m m' : t elt) (k : key) (e : elt), MapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'
elt:Type

forall (m m' : t elt) (k : key) (e : elt), MapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'
elt:Type
m, m':t elt
k:key
e:elt

MapsTo k e (restrict m m') <-> MapsTo k e m /\ In k m'
elt:Type
m, m':t elt
k:key
e:elt

MapsTo k e (filter (fun (k0 : key) (_ : elt) => mem k0 m') m) <-> MapsTo k e m /\ In k m'
elt:Type
m, m':t elt
k:key
e:elt

MapsTo k e m /\ mem k m' = true <-> MapsTo k e m /\ In k m'
elt:Type
m, m':t elt
k:key
e:elt
Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => mem k0 m')
elt:Type
m, m':t elt
k:key
e:elt

Proper (E.eq ==> eq ==> eq) (fun (k0 : key) (_ : elt) => mem k0 m')
intros ? ? Hk _ _ _; rewrite Hk; auto. Qed.
elt:Type

forall (m m' : t elt) (k : key), In k (restrict m m') <-> In k m /\ In k m'
elt:Type

forall (m m' : t elt) (k : key), In k (restrict m m') <-> In k m /\ In k m'
elt:Type
m, m':t elt
k:key

In k (restrict m m') <-> In k m /\ In k m'
elt:Type
m, m':t elt
k:key

In k (restrict m m') -> In k m /\ In k m'
elt:Type
m, m':t elt
k:key
In k m /\ In k m' -> In k (restrict m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m /\ In k m'

In k m /\ In k m'
elt:Type
m, m':t elt
k:key
In k m /\ In k m' -> In k (restrict m m')
elt:Type
m, m':t elt
k:key
e:elt
H:MapsTo k e m
H0:In k m'

In k m
elt:Type
m, m':t elt
k:key
In k m /\ In k m' -> In k (restrict m m')
elt:Type
m, m':t elt
k:key

In k m /\ In k m' -> In k (restrict m m')
intros ((e,H),H'); exists e; rewrite restrict_mapsto_iff; auto. Qed.
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:Type

forall x y : t elt, Equal x y -> cardinal x = cardinal y
elt:Type

forall x y : t elt, Equal x y -> cardinal x = cardinal y
intros; apply Equal_cardinal; auto. Qed.
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Disjoint x x0 <-> Disjoint y y0
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Disjoint x x0 <-> Disjoint y y0
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Disjoint m1 m2 <-> Disjoint m1' m2'
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

(forall k : key, ~ (In k m1 /\ In k m2)) <-> (forall k : key, ~ (In k m1' /\ In k m2'))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
H:forall k0 : key, ~ (In k0 m1 /\ In k0 m2)
k:key

~ (In k m1' /\ In k m2')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
H:forall k0 : key, ~ (In k0 m1' /\ In k0 m2')
k:key
~ (In k m1 /\ In k m2)
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type

forall 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 y1
elt:Type

forall 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 y1
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
m3, m3':t elt
Hm3:Equal m3 m3'

Partition m1 m2 m3 <-> Partition m1' m2' m3'
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
m3, m3':t elt
Hm3: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
m3, m3':t elt
Hm3: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
m3, m3':t elt
Hm3:Equal m3 m3'
H:Disjoint m2 m3
H':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1 <-> MapsTo k0 e0 m2 \/ MapsTo k0 e0 m3
k:key
e:elt

MapsTo k e m1' <-> MapsTo k e m2' \/ MapsTo k e m3'
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
m3, m3':t elt
Hm3:Equal m3 m3'
H:Disjoint m2 m3
H':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1' <-> MapsTo k0 e0 m2' \/ MapsTo k0 e0 m3'
k:key
e:elt
MapsTo k e m1 <-> MapsTo k e m2 \/ MapsTo k e m3
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
m3, m3':t elt
Hm3:Equal m3 m3'
H:Disjoint m2 m3
H':forall (k0 : key) (e0 : elt), MapsTo k0 e0 m1' <-> MapsTo k0 e0 m2' \/ MapsTo k0 e0 m3'
k:key
e:elt

MapsTo k e m1 <-> MapsTo k e m2 \/ MapsTo k e m3
rewrite Hm1, Hm2, Hm3; auto. Qed.
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (update x x0) (update y y0)
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (update x x0) (update y y0)
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Equal (update m1 m2) (update m1' m2')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Equal (fold (add (elt:=elt)) m2 m1') (fold (add (elt:=elt)) m2' m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Proper (E.eq ==> eq ==> Equal ==> Equal) (add (elt:=elt))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
transpose_neqkey Equal (add (elt:=elt))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

transpose_neqkey Equal (add (elt:=elt))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key

find x (add k e (add k' e' i)) = find x (add k' e' (add k e i))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key
e0:E.eq k x
e1:E.eq k' x

Some e = Some e'
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Equal (fold (add (elt:=elt)) m2 m1) (fold (add (elt:=elt)) m2 m1')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Proper (E.eq ==> eq ==> Equal ==> Equal) (add (elt:=elt))
intros k k' Hk e e' He m m' Hm; rewrite Hk,He,Hm; red; auto. Qed.
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (restrict x x0) (restrict y y0)
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (restrict x x0) (restrict y y0)
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Equal (restrict m1 m2) (restrict m1' m2')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k:key
e:elt
i, i':t elt
H:MapsTo k e m1'
Hii':Equal i i'
x:key

find 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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k:key
e:elt
i, i':t elt
H:MapsTo k e m1'
Hii':Equal i i'
x:key

find 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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
Hk:E.eq k k'
e, e':elt
He:e = e'
m, m':t elt
Hm: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
Hk:E.eq k k'
e, e':elt
He:e = e'
m, m':t elt
Hm: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key

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) = 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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key
H:mem k' m2 = true
H0:mem k m2 = true

find x (add k e (add k' e' i)) = find x (add k' e' (add k e i))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key
H:mem k' m2 = true
H0:mem k m2 = true
e0:E.eq k x
e1:E.eq k' x

Some e = Some e'
elim Hneq; eauto. Qed.
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (diff x x0) (diff y y0)
elt:Type

forall x y : t elt, Equal x y -> forall x0 y0 : t elt, Equal x0 y0 -> Equal (diff x x0) (diff y y0)
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'

Equal (diff m1 m2) (diff m1' m2')
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k:key
e:elt
i, i':t elt
H:MapsTo k e m1'
Hii':Equal i i'
x:key

find 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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k:key
e:elt
i, i':t elt
H:MapsTo k e m1'
Hii':Equal i i'
x:key

find 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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
Hk:E.eq k k'
e, e':elt
He:e = e'
m, m':t elt
Hm: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
Hk:E.eq k k'
e, e':elt
He:e = e'
m, m':t elt
Hm: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2: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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key

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) = 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:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key
H:mem k' m2 = false
H0:mem k m2 = false

find x (add k e (add k' e' i)) = find x (add k' e' (add k e i))
elt:Type
m1, m1':t elt
Hm1:Equal m1 m1'
m2, m2':t elt
Hm2:Equal m2 m2'
k, k':E.t
e, e':elt
i:t elt
Hneq:~ E.eq k k'
x:key
H:mem k' m2 = false
H0:mem k m2 = false
e0:E.eq k x
e1:E.eq k' x

Some e = Some e'
elim Hneq; eauto. Qed. End WProperties_fun.

Same Properties for self-contained weak maps and for full maps

Module WProperties (M:WS) := WProperties_fun M.E M.
Module Properties := WProperties.

Properties specific to maps with ordered keys

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:Type

forall l l' : list (key * elt), Sorted ltk l -> Sorted ltk l' -> equivlistA eqke l l' -> eqlistA eqke l l'
elt:Type

forall 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:Type

forall p p' : key * elt, gtb p p' = true <-> ltk p' p
elt:Type

forall p p' : key * elt, gtb p p' = true <-> ltk p' p
elt:Type
x:key
e:elt
y:key
e':elt

match E.compare x y with | GT _ => true | _ => false end = true <-> E.lt y x
destruct (E.compare x y); intuition; try discriminate; ME.order. Qed.
elt:Type

forall p p' : key * elt, leb p p' = true <-> ~ ltk p' p
elt:Type

forall p p' : key * elt, leb p p' = true <-> ~ ltk p' p
elt:Type
x:key
e:elt
y:key
e':elt

negb match E.compare x y with | GT _ => true | _ => false end = true <-> ~ E.lt y x
destruct (E.compare x y); intuition; try discriminate; ME.order. Qed.
elt:Type

forall p : key * elt, Proper (eqke ==> eq) (gtb p)
elt:Type

forall p : key * elt, Proper (eqke ==> eq) (gtb p)
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''

gtb (x, e) (a, e') = gtb (x, e) (b, e'')
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''

true = true <-> ltk (a, e') (x, e) -> false = true <-> ltk (b, e'') (x, e) -> true = false
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = true
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
H1:true = true <-> E.lt a x
H2:false = true <-> E.lt b x

true = false
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = true
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
H1:true = true <-> E.lt a x
H2:false = true <-> E.lt b x

E.lt b x
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = true
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
H1:true = true <-> E.lt a x
H2:false = true <-> E.lt b x

E.lt a x
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = true
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''

false = true <-> ltk (a, e') (x, e) -> true = true <-> ltk (b, e'') (x, e) -> false = true
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
H1:false = true <-> E.lt a x
H2:true = true <-> E.lt b x

false = true
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
H1:false = true <-> E.lt a x
H2:true = true <-> E.lt b x

E.lt a x
elt:Type
x:key
e:elt
a:E.t
e':elt
b:E.t
e'':elt
H:E.eq a b
H0:e' = e''
H1:false = true <-> E.lt a x
H2:true = true <-> E.lt b x

E.lt b x
rewrite <- H2; auto. Qed.
elt:Type

forall p : key * elt, Proper (eqke ==> eq) (leb p)
elt:Type

forall p : key * elt, Proper (eqke ==> eq) (leb p)
elt:Type
x:(key * elt)%type
a, b:(E.t * elt)%type
H:eqke a b

leb x a = leb x b
unfold leb; f_equal; apply gtb_compat; auto. Qed. Hint Resolve gtb_compat leb_compat elements_3 : map.
elt:Type

forall (p : key * elt) (m : t elt), elements m = elements_lt p m ++ elements_ge p m
elt:Type

forall (p : key * elt) (m : t elt), elements m = elements_lt p m ++ elements_ge p m
elt:Type
p:(key * elt)%type
m:t elt

elements m = List.filter (gtb p) (elements m) ++ List.filter (fun p' : key * elt => negb (gtb p p')) (elements m)
elt:Type
p:(key * elt)%type
m:t elt

forall x y : E.t * elt, gtb p x = true -> gtb p y = false -> ltk x y
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:gtb (k, e1) (t0, e) = true
H0:gtb (k, e1) (t1, e0) = false

ltk (t0, e) (t1, e0)
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:E.lt t0 k
H0:gtb (k, e1) (t1, e0) = false

ltk (t0, e) (t1, e0)
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:E.lt t0 k
H0:gtb (k, e1) (t1, e0) = false

~ ltk (t1, e0) (k, e1)
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:E.lt t0 k
H0:gtb (k, e1) (t1, e0) = false
H1:~ ltk (t1, e0) (k, e1)
ltk (t0, e) (t1, e0)
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:E.lt t0 k
H0:match E.compare k t1 with | GT _ => true | _ => false end = false

~ E.lt t1 k
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:E.lt t0 k
H0:gtb (k, e1) (t1, e0) = false
H1:~ ltk (t1, e0) (k, e1)
ltk (t0, e) (t1, e0)
elt:Type
k:key
e1:elt
m:t elt
t0:E.t
e:elt
t1:E.t
e0:elt
H:E.lt t0 k
H0:gtb (k, e1) (t1, e0) = false
H1:~ ltk (t1, e0) (k, e1)

ltk (t0, e) (t1, e0)
unfold O.ltk in *; simpl in *; ME.order. Qed.
elt:Type

forall (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:Type

forall (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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

Sorted ltk (List.filter (gtb (x, e)) (elements m) ++ (x, e) :: List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

Sorted ltk (List.filter (gtb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk ((x, e) :: List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

Sorted ltk ((x, e) :: List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
HdRel ltk (x, e) (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

HdRel ltk (x, e) (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

forall y : E.t * elt, InA eqke y (List.filter (leb (x, e)) (elements m)) -> ltk (x, e) y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
y:(E.t * elt)%type
H1:InA eqke y (List.filter (leb (x, e)) (elements m))

ltk (x, e) y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
y:(E.t * elt)%type
H1:InA eqke y (elements m)
H2:leb (x, e) y = true

ltk (x, e) y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
y:(E.t * elt)%type
H1:InA eqke y (elements m)
H2:~ ltk y (x, e)

ltk (x, e) y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt
H1:InA eqke (t0, e0) (elements m)
H2:~ E.lt t0 x

E.lt x t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt
H1:MapsTo t0 e0 m
H2:~ E.lt t0 x

E.lt x t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt
H1:MapsTo t0 e0 m
H2:~ E.lt t0 x

~ E.eq x t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt
H1:MapsTo t0 e0 m
H2:~ E.lt t0 x
H3:~ E.eq x t0
E.lt x t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H0:Add x e m m'
t0:E.t
e0:elt
H1:MapsTo t0 e0 m
H2:~ E.lt t0 x
H:E.eq x t0

In x m
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt
H1:MapsTo t0 e0 m
H2:~ E.lt t0 x
H3:~ E.eq x t0
E.lt x t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt
H1:MapsTo t0 e0 m
H2:~ E.lt t0 x
H3:~ E.eq x t0

E.lt x t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'

Sorted ltk (List.filter (leb (x, e)) (elements m))
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:gtb (x, e) x0 = true
H2:InA eqke y ((x, e) :: List.filter (leb (x, e)) (elements m))

ltk x0 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1: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 y
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H2:InA eqke (t0, e0) ((x, e) :: List.filter (leb (x, e)) (elements m))

E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H4:eqke (t0, e0) (x, e)

E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H4:InA eqke (t0, e0) (List.filter (leb (x, e)) (elements m))
E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H2:E.eq t0 x
H4:e0 = e

E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H4:InA eqke (t0, e0) (List.filter (leb (x, e)) (elements m))
E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H4:InA eqke (t0, e0) (List.filter (leb (x, e)) (elements m))

E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H2:InA eqke (t0, e0) (elements m)
H4:leb (x, e) (t0, e0) = true

E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H1:InA eqke (t1, e1) (elements m)
H3:E.lt t1 x
H2:InA eqke (t0, e0) (elements m)
H4:~ ltk (t0, e0) (x, e)

E.lt t1 t0
elt:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0: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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt

InA 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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt

E.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:Type
m, m':t elt
x:key
e:elt
H:~ In x m
H0:Add x e m m'
t0:E.t
e0:elt

E.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 x
elt:Type
m, m':t elt
x:key
e:elt
H:In x m -> False
H0:Add x e m m'
t0:E.t
e0:elt
e1:E.eq t0 x
H2:MapsTo t0 e0 m
H3:E.lt t0 x -> False

E.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:key
e:elt
H:In x m -> False
H0:Add x e m m'
t0:E.t
e0:elt
l:E.lt x t0
H1:E.eq x t0 -> False
H3: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 x -> False)
elt:Type
m, m':t elt
x:key
e:elt
H:In x m -> False
H0:Add x e m m'
t0:E.t
e0:elt
e1:E.eq t0 x
H2:MapsTo t0 e0 m
H3:E.lt t0 x -> False

E.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m
elim H; exists e0; apply MapsTo_1 with t0; auto.
elt:Type
m, m':t elt
x:key
e:elt
H:In x m -> False
H0:Add x e m m'
t0:E.t
e0:elt
l:E.lt x t0
H1:E.eq x t0 -> False
H3: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 x -> False)
fold (~E.lt t0 x); auto. Qed.
elt:Type

forall (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:Type

forall (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:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'

eqlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'

Sorted ltk (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'

forall x0 y : E.t * elt, InA eqke x0 (elements m) -> InA eqke y ((x, e) :: nil) -> ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H2:InA eqke y ((x, e) :: nil)

ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:eqke y (x, e)

ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:InA eqke y nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
t1:E.t
e1:elt
H1:InA eqke (t0, e0) (elements m)
H3:eqke (t1, e1) (x, e)

ltk (t0, e0) (t1, e1)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:InA eqke y nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
t1:E.t
e1:elt
H1:MapsTo t0 e0 m
H3:eqke (t1, e1) (x, e)

ltk (t0, e0) (t1, e1)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:InA eqke y nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
t1:E.t
e1:elt
H1:MapsTo t0 e0 m
H2:E.eq t1 x
H3:e1 = e

E.lt t0 t1
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:InA eqke y nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
t1:E.t
e1:elt
H1:MapsTo t0 e0 m
H2:E.eq t1 x
H3:e1 = e

E.lt t0 x
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:InA eqke y nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 (elements m)
H3:InA eqke y nil

ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'

equivlistA eqke (elements m') (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt

InA eqke (t0, e0) (elements m') <-> InA eqke (t0, e0) (elements m ++ (x, e) :: nil)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt

E.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> MapsTo t0 e0 m \/ eqke (t0, e0) (x, e) \/ False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt

E.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> MapsTo t0 e0 m \/ E.eq t0 x /\ e0 = e \/ False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m

E.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0

E.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0

False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0

In t0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0
H1:In t0 m
False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0
H1:In t0 m

False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Above x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0
H1:In t0 m

E.lt t0 x -> False
ME.order. Qed.
elt:Type

forall (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:Type

forall (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:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'

eqlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'

Sorted ltk ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'

Sorted ltk (((x, e) :: nil) ++ elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'

forall x0 y : E.t * elt, InA eqke x0 ((x, e) :: nil) -> InA eqke y (elements m) -> ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H1:InA eqke x0 ((x, e) :: nil)
H2:InA eqke y (elements m)

ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:eqke x0 (x, e)

ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:InA eqke x0 nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H2:InA eqke (t0, e0) (elements m)
H3:eqke (t1, e1) (x, e)

ltk (t1, e1) (t0, e0)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:InA eqke x0 nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
H3:eqke (t1, e1) (x, e)

ltk (t1, e1) (t0, e0)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:InA eqke x0 nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
H1:E.eq t1 x
H3:e1 = e

E.lt t1 t0
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:InA eqke x0 nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t1:E.t
e1:elt
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
H1:E.eq t1 x
H3:e1 = e

E.lt x t0
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:InA eqke x0 nil
ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
x0, y:(E.t * elt)%type
H2:InA eqke y (elements m)
H3:InA eqke x0 nil

ltk x0 y
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'

equivlistA eqke (elements m') ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt

InA eqke (t0, e0) (elements m') <-> InA eqke (t0, e0) ((x, e) :: elements m)
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt

E.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> eqke (t0, e0) (x, e) \/ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt

E.eq x t0 /\ e = e0 \/ ~ E.eq x t0 /\ MapsTo t0 e0 m <-> E.eq t0 x /\ e0 = e \/ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m

E.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0

E.eq x t0 /\ e = e0 \/ (E.eq x t0 -> False) /\ MapsTo t0 e0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0

False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0

In t0 m
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0
H1:In t0 m
False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0
H1:In t0 m

False
elt:Type
m, m':t elt
x:E.t
e:elt
H:Below x m
H0:Add x e m m'
t0:E.t
e0:elt
H2:MapsTo t0 e0 m
Heq:E.eq x t0
H1:In t0 m

E.lt x t0 -> False
ME.order. Qed.
elt:Type

forall m m' : t elt, Equal m m' -> eqlistA eqke (elements m) (elements m')
elt:Type

forall m m' : t elt, Equal m m' -> eqlistA eqke (elements m) (elements m')
elt:Type
m, m':t elt
H:Equal m m'

eqlistA eqke (elements m) (elements m')
elt:Type
m, m':t elt
H:Equal m m'

equivlistA eqke (elements m) (elements m')
elt:Type
m, m':t elt
H:Equal m m'
x:(E.t * elt)%type

InA eqke x (elements m) <-> InA eqke x (elements m')
elt:Type
m, m':t elt
H:Equal m m'
t0:E.t
e:elt

MapsTo t0 e m <-> MapsTo t0 e m'
do 2 rewrite find_mapsto_iff; rewrite H; split; auto. Qed. End Elements. Section Min_Max_Elt.
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:Type

forall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> Above x (remove x m)
elt:Type

forall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> Above x (remove x m)
elt:Type
m:t elt
x:key
e:elt
H:max_elt m = Some (x, e)
y:key
H0:In y (remove x m)

E.lt y x
elt:Type
m:t elt
x:key
e:elt
H:max_elt m = Some (x, e)
y:key
H0:~ E.eq x y /\ In y m

E.lt y x
elt:Type
m:t elt
x:key
e:elt
H:max_elt m = Some (x, e)
y:key
H0:~ E.eq x y
H1:In y m

E.lt y x
elt:Type
m:t elt
x:key
e:elt
H:max_elt m = Some (x, e)
y:key
H0:~ E.eq x y
H1:exists e0 : elt, InA (eq_key_elt (elt:=elt)) (y, e0) (elements m)

E.lt y x
elt:Type
m:t elt
x:key
e:elt
H:max_elt m = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)

E.lt y x
elt:Type
m:t elt
x:key
e:elt
H:max_elt_aux (elements m) = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)

E.lt y x
elt:Type
m:t elt
x:key
e:elt
H:max_elt_aux (elements m) = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)

Sorted (lt_key (elt:=elt)) (elements m) -> E.lt y x
elt:Type
m:t elt

forall (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 x
elt:Type
m:t elt

forall (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 x
elt:Type
m:t elt
a:(key * elt)%type
l: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 x
forall (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 x
elt:Type
m:t elt
a:(key * elt)%type
l: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 x

forall (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 x
elt:Type
m:t elt
a:(key * elt)%type
l: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 x1
x:key
e:elt
H:max_elt_aux (a :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (a :: l)
H2:Sorted (lt_key (elt:=elt)) (a :: l)

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
IHl: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 x1
x:key
e:elt
H:Some (k, e0) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1:InA (eq_key_elt (elt:=elt)) (y, x0) ((k, e0) :: nil)
H2:Sorted (lt_key (elt:=elt)) ((k, e0) :: nil)

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
IHl: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 x1
x:key
e:elt
y:key
x0:elt
H0:~ E.eq x y
H1:InA (eq_key_elt (elt:=elt)) (y, x0) ((x, e) :: nil)
H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
IHl: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 x1
x:key
e:elt
y:key
x0:elt
H0:~ E.eq x y
H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)
H:eq_key_elt (y, x0) (x, e)

E.lt y x
elt:Type
m:t elt
IHl: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 x1
x:key
e:elt
y:key
x0:elt
H0:~ E.eq x y
H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)
H:InA (eq_key_elt (elt:=elt)) (y, x0) nil
E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
IHl: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 x1
x:key
e:elt
y:key
x0:elt
H0:E.eq x y -> False
H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)
H1:E.eq y x
H3:x0 = e

E.lt y x
elt:Type
m:t elt
IHl: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 x1
x:key
e:elt
y:key
x0:elt
H0:~ E.eq x y
H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)
H:InA (eq_key_elt (elt:=elt)) (y, x0) nil
E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
IHl: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 x1
x:key
e:elt
y:key
x0:elt
H0:~ E.eq x y
H2:Sorted (lt_key (elt:=elt)) ((x, e) :: nil)
H:InA (eq_key_elt (elt:=elt)) (y, x0) nil

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:(let (x1, e1) := p in match l with | nil => Some (x1, e1) | _ :: _ => max_elt_aux l end) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l: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 x1
x:key
e:elt
H:max_elt_aux (p :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l:list (key * elt)
x:key
e:elt
H:max_elt_aux (p :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H1: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 x

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l:list (key * elt)
x:key
e:elt
H:max_elt_aux (p :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
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 x
H3:eq_key_elt (y, x0) (k, e0)

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p:(key * elt)%type
l:list (key * elt)
x:key
e:elt
H:max_elt_aux (p :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
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 x
H1:E.eq y k
H3:x0 = e0

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Heq:E.eq p1 x

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Heq:E.eq p1 x

E.lt y p1
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
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 x
H1:E.eq y k
H3:x0 = e0
Heq:E.eq p1 x
H4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
H5:HdRel (lt_key (elt:=elt)) (k, e0) ((p1, p2) :: l)

E.lt y p1
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
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 x
H1:E.eq y k
H3:x0 = e0
Heq:E.eq p1 x
H4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
H2:lt_key (k, e0) (p1, p2)

E.lt y p1
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x

E.lt y x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x

E.lt y p1
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt p1 x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
H4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
H5:HdRel (lt_key (elt:=elt)) (k, e0) ((p1, p2) :: l)

E.lt y p1
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt p1 x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
H4:Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
H2:lt_key (k, e0) (p1, p2)

E.lt y p1
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
E.lt p1 x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x

E.lt p1 x
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x

InA (eq_key_elt (elt:=elt)) (p1, ?x0) ((p1, p2) :: l)
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x

eq_key_elt (p1, ?x0) (p1, p2)
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x
Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
elt:Type
m:t elt
k:key
e0:elt
p1:key
p2:elt
l:list (key * elt)
x:key
e:elt
H:max_elt_aux ((p1, p2) :: l) = Some (x, e)
y:key
x0:elt
H0:~ E.eq x y
H2: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 x
H1:E.eq y k
H3:x0 = e0
Hneq:~ E.eq p1 x

Sorted (lt_key (elt:=elt)) ((p1, p2) :: l)
inversion H2; auto. Qed.
elt:Type

forall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> MapsTo x e m
elt:Type

forall (m : t elt) (x : key) (e : elt), max_elt m = Some (x, e) -> MapsTo x e m
elt:Type
m:t elt
x:key
e:elt
H:max_elt m = Some (x, e)

MapsTo x e m
elt:Type
m:t elt
x:key
e:elt
H:max_elt_aux (elements m) = Some (x, e)

MapsTo x e m
elt:Type
m:t elt
x:key
e:elt
H:max_elt_aux (elements m) = Some (x, e)

InA (eq_key_elt (elt:=elt)) (x, e) (elements m)
elt:Type
m:t elt
x:key
e:elt
H:max_elt_aux nil = Some (x, e)

InA (eq_key_elt (elt:=elt)) (x, e) nil
elt:Type
m:t elt
x:key
e:elt
a:(key * elt)%type
l: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) l
InA (eq_key_elt (elt:=elt)) (x, e) (a :: l)
elt:Type
m:t elt
x:key
e:elt
a:(key * elt)%type
l: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) l

InA (eq_key_elt (elt:=elt)) (x, e) (a :: l)
elt:Type
m:t elt
x:key
e:elt
k:key
e0:elt
H:Some (k, e0) = Some (x, e)
IHl:None = Some (x, e) -> InA (eq_key_elt (elt:=elt)) (x, e) nil

InA (eq_key_elt (elt:=elt)) (x, e) ((k, e0) :: nil)
elt:Type
m:t elt
x:key
e:elt
k:key
e0:elt
p:(key * elt)%type
l: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:Type
m:t elt
x:key
e:elt
k:key
e0:elt
p:(key * elt)%type
l: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:Type

forall m : t elt, max_elt m = None -> Empty m
elt:Type

forall m : t elt, max_elt m = None -> Empty m
elt:Type
m:t elt
H:max_elt m = None

Empty m
elt:Type
m:t elt
H:max_elt_aux (elements m) = None

Empty m
elt:Type
m:t elt
H:max_elt_aux (elements m) = None

elements m = nil
elt:Type
m:t elt
a:(key * elt)%type
l:list (key * elt)
H:max_elt_aux (a :: l) = None
IHl:max_elt_aux l = None -> l = nil

a :: l = nil
elt:Type
m:t elt
k:key
e:elt
p:(key * elt)%type
l:list (key * elt)
H:(let (x, e0) := p in match l with | nil => Some (x, e0) | _ :: _ => max_elt_aux l end) = None
IHl:(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 = nil
assert (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:Type

forall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> Below x (remove x m)
elt:Type

forall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> Below x (remove x m)
elt:Type
m:t elt
x:key
e:elt
H:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)
y:key
H0:In y (remove x m)

E.lt x y
elt:Type
m:t elt
x:key
e:elt
H:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)
y:key
H0:~ E.eq x y
H1:In y m

E.lt x y
elt:Type
m:t elt
x:key
e:elt
H:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)
y:key
H0:~ E.eq x y
H1:exists e0 : elt, InA (eq_key_elt (elt:=elt)) (y, e0) (elements m)

E.lt x y
elt:Type
m:t elt
x:key
e:elt
H:match elements m with | nil => None | (x1, e0) :: _ => Some (x1, e0) end = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)

E.lt x y
elt:Type
m:t elt
x:key
e:elt
H:match elements m with | nil => None | (x1, e0) :: _ => Some (x1, e0) end = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (elements m)

Sorted (lt_key (elt:=elt)) (elements m) -> E.lt x y
elt:Type
m:t elt
x:key
e:elt
H:None = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) nil

Sorted (lt_key (elt:=elt)) nil -> E.lt x y
elt:Type
m:t elt
x:key
e:elt
p:(key * elt)%type
l:list (key * elt)
H:(let (x1, e0) := p in Some (x1, e0)) = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (p :: l)
Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt x y
elt:Type
m:t elt
x:key
e:elt
p:(key * elt)%type
l:list (key * elt)
H:(let (x1, e0) := p in Some (x1, e0)) = Some (x, e)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) (p :: l)

Sorted (lt_key (elt:=elt)) (p :: l) -> E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H1:InA (eq_key_elt (elt:=elt)) (y, x0) ((x, e) :: l)
H4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)

E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)
H2:eq_key_elt (y, x0) (x, e)

E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)
H2:InA (eq_key_elt (elt:=elt)) (y, x0) l
E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H4:Sorted (lt_key (elt:=elt)) ((x, e) :: l)
H2:InA (eq_key_elt (elt:=elt)) (y, x0) l

E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H2:InA (eq_key_elt (elt:=elt)) (y, x0) l
H:Sorted (lt_key (elt:=elt)) l
H1:HdRel (lt_key (elt:=elt)) (x, e) l

E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H2:InA (eq_key_elt (elt:=elt)) (y, x0) l
H:Sorted (lt_key (elt:=elt)) l
H3:HdRel (lt_key (elt:=elt)) (x, e) l

E.lt x y
elt:Type
m:t elt
x:key
e:elt
l:list (key * elt)
y:key
H0:~ E.eq x y
x0:elt
H2:InA (eq_key_elt (elt:=elt)) (y, x0) l
H:Sorted (lt_key (elt:=elt)) l
H3:forall y0 : E.t * elt, InA eqke y0 l -> lt_key (x, e) y0

E.lt x y
apply (H3 (y,x0)); auto. Qed.
elt:Type

forall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> MapsTo x e m
elt:Type

forall (m : t elt) (x : key) (e : elt), min_elt m = Some (x, e) -> MapsTo x e m
elt:Type
m:t elt
x:key
e:elt
H:min_elt m = Some (x, e)

MapsTo x e m
elt:Type
m:t elt
x:key
e:elt
H:match elements m with | nil => None | (x0, e0) :: _ => Some (x0, e0) end = Some (x, e)

MapsTo x e m
elt:Type
m:t elt
x:key
e:elt
H: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:Type
m:t elt
x:key
e:elt
H:None = Some (x, e)

InA (eq_key_elt (elt:=elt)) (x, e) nil
elt:Type
m:t elt
x:key
e:elt
p:(key * elt)%type
l: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:Type
m:t elt
x:key
e:elt
p:(key * elt)%type
l: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:Type
m:t elt
x:key
e:elt
k:key
e0:elt
l:list (key * elt)
H:Some (k, e0) = Some (x, e)

InA (eq_key_elt (elt:=elt)) (x, e) ((k, e0) :: l)
injection H; intros; subst; constructor; red; auto. Qed.
elt:Type

forall m : t elt, min_elt m = None -> Empty m
elt:Type

forall m : t elt, min_elt m = None -> Empty m
elt:Type
m:t elt
H:min_elt m = None

Empty m
elt:Type
m:t elt
H:match elements m with | nil => None | (x, e) :: _ => Some (x, e) end = None

Empty m
elt:Type
m:t elt
H:match elements m with | nil => None | (x, e) :: _ => Some (x, e) end = None

elements m = nil
elt:Type
m:t elt
p:(key * elt)%type
l:list (key * elt)
H:(let (x, e) := p in Some (x, e)) = None

p :: l = nil
destruct p; simpl in *; discriminate. Qed. End Min_Max_Elt. Section Induction_Principles.
elt:Type

forall 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 m
elt:Type

forall 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 m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0: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 elt
Heqn:0 = cardinal m

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
p:(key * elt)%type
H:max_elt m = Some p

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)

Add k e (remove k m) m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
y:key

find y m = find y (add k e (remove k m))
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Above x m0 -> Add x e1 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
y:key
e0:E.eq k y

find y m = Some e
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Above x m0 -> Add x e1 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
y:key
e0:E.eq k y

MapsTo k e m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m

P (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
Above k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m

n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
Above k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m

S n = S (cardinal (remove k m))
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
H1:S n = S (cardinal (remove k m))
n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
Above k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m

cardinal m = S (cardinal (remove k m))
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
H1:S n = S (cardinal (remove k m))
n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
Above k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
H1:S n = S (cardinal (remove k m))

n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m
Above k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Above x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:max_elt m = Some (k, e)
H0:Add k e (remove k m) m

Above k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Above x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:max_elt m = None

P m
apply X; apply max_elt_Empty; auto. Qed.
elt:Type

forall 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 m
elt:Type

forall 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 m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0: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 elt
Heqn:0 = cardinal m

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
p:(key * elt)%type
H:min_elt m = Some p

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)

Add k e (remove k m) m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
y:key

find y m = find y (add k e (remove k m))
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Below x m0 -> Add x e1 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
y:key
e0:E.eq k y

find y m = Some e
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e1 : elt), Below x m0 -> Add x e1 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
y:key
e0:E.eq k y

MapsTo k e m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m

P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m

P (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
Below k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m

n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
Below k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m

S n = S (cardinal (remove k m))
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
H1:S n = S (cardinal (remove k m))
n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
Below k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m

cardinal m = S (cardinal (remove k m))
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
H1:S n = S (cardinal (remove k m))
n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
Below k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
H1:S n = S (cardinal (remove k m))

n = cardinal (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m
Below k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e0 : elt), Below x m0 -> Add x e0 m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
k:key
e:elt
H:min_elt m = Some (k, e)
H0:Add k e (remove k m) m

Below k (remove k m)
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None
P m
elt:Type
P:t elt -> Type
X:forall m0 : t elt, Empty m0 -> P m0
X0:forall m0 m' : t elt, P m0 -> forall (x : E.t) (e : elt), Below x m0 -> Add x e m0 m' -> P m'
n:nat
IHn:forall m0 : t elt, n = cardinal m0 -> P m0
m:t elt
Heqn:S n = cardinal m
H:min_elt m = None

P m
apply X; apply min_elt_Empty; auto. Qed. End Induction_Principles. Section Fold_properties.
The following lemma has already been proved on Weak Maps, but with one additional hypothesis (some transpose fact).
  
elt:Type

forall (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:Type

forall (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:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2

eqA (fold f m1 i) (fold f m2 i)
elt:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2

eqA (fold_right (uncurry f) i (rev (elements m1))) (fold_right (uncurry f) i (rev (elements m2)))
elt:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2

Proper (eqke ==> eqA ==> eqA) (uncurry f)
elt:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2
eqlistA eqke (rev (elements m1)) (rev (elements m2))
elt:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2

eqlistA eqke (rev (elements m1)) (rev (elements m2))
elt:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2

eqlistA eqke (elements m1) (elements m2)
elt:Type
m1, m2:t elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
Hf:Proper (E.eq ==> eq ==> eqA ==> eqA) f
Heq:Equal m1 m2

Equal m1 m2
auto. Qed.
elt:Type

forall (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:Type

forall (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:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2

eqA (fold f m2 i) (f x e (fold f m1 i))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2

eqA (fold_right (uncurry f) i (rev (elements m2))) (f x e (fold_right (uncurry f) i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m2))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m2))) (fold_right f' i (rev (elements m1 ++ (x, e) :: nil)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

Proper (eqke ==> eqA ==> eqA) f'
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqlistA eqke (rev (elements m2)) (rev (elements m1 ++ (x, e) :: nil))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
k1:E.t
e1:elt
k2:E.t
e2:elt
Hk:E.eq k1 k2
He:e1 = e2
a1, a2:A
Ha:eqA a1 a2

eqA (uncurry f (k1, e1) a1) (uncurry f (k2, e2) a2)
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqlistA eqke (rev (elements m2)) (rev (elements m1 ++ (x, e) :: nil))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqlistA eqke (rev (elements m2)) (rev (elements m1 ++ (x, e) :: nil))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqlistA eqke (elements m2) (elements m1 ++ (x, e) :: nil)
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m1 ++ (x, e) :: nil))) (f x e (fold_right f' i (rev (elements m1))))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Above x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (f' (x, e) (fold_right f' i (rev (elements m1)))) (f x e (fold_right f' i (rev (elements m1))))
reflexivity. Qed.
elt:Type

forall (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:Type

forall (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:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2

eqA (fold f m2 i) (fold f m1 (f x e i))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2

eqA (fold_right (uncurry f) i (rev (elements m2))) (fold_right (uncurry f) (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m2))) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m2))) (fold_right f' i (rev (((x, e) :: nil) ++ elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

Proper (eqke ==> eqA ==> eqA) f'
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqlistA eqke (rev (elements m2)) (rev (((x, e) :: nil) ++ elements m1))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqlistA eqke (rev (elements m2)) (rev (((x, e) :: nil) ++ elements m1))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqlistA eqke (elements m2) (((x, e) :: nil) ++ elements m1)
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A
eqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (((x, e) :: nil) ++ elements m1))) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' i (rev (elements m1) ++ (x, e) :: nil)) (fold_right f' (f x e i) (rev (elements m1)))
elt:Type
m1, m2:t elt
x:E.t
e:elt
A:Type
eqA:A -> A -> Prop
st:Equivalence eqA
f:key -> elt -> A -> A
i:A
P:Proper (E.eq ==> eq ==> eqA ==> eqA) f
H:Below x m1
H0:Add x e m1 m2
f':=uncurry f:key * elt -> A -> A

eqA (fold_right f' (fold_right f' i ((x, e) :: nil)) (rev (elements m1))) (fold_right f' (f x e i) (rev (elements m1)))
reflexivity. Qed. End Fold_properties. End Elt. End OrdProperties.