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 map library

This file proposes an implementation of the non-dependent interface FMapInterface.WS using lists of pairs, unordered but without redundancy.
Require Import FunInd FMapInterface.

Set Implicit Arguments.
Unset Strict Implicit.

Module Raw (X:DecidableType).

Module Import PX := KeyDecidableType X.

Definition key := X.t.
Definition t (elt:Type) := list (X.t * elt).

Section Elt.

Variable elt : Type.

Notation eqk := (eqk (elt:=elt)).
Notation eqke := (eqke (elt:=elt)).
Notation MapsTo := (MapsTo (elt:=elt)).
Notation In := (In (elt:=elt)).
Notation NoDupA := (NoDupA eqk).

empty

Definition empty : t elt := nil.

Definition Empty m := forall (a : key)(e:elt), ~ MapsTo a e m.

elt:Type

Empty empty
elt:Type

Empty empty
elt:Type

forall (a : key) (e : elt), ~ MapsTo a e nil
elt:Type
a:key
e:elt

~ MapsTo a e nil
elt:Type
a:key
e:elt
abs:MapsTo a e nil

False
inversion abs. Qed. Hint Resolve empty_1 : core.
elt:Type

NoDupA empty
elt:Type

NoDupA empty
unfold empty; auto. Qed.

is_empty

Definition is_empty (l : t elt) : bool := if l then true else false.

elt:Type

forall m : list (X.t * elt), Empty m -> is_empty m = true
elt:Type

forall m : list (X.t * elt), Empty m -> is_empty m = true
elt:Type

forall m : list (X.t * elt), (forall (a : key) (e : elt), ~ InA eqke (a, e) m) -> is_empty m = true
elt:Type
m:list (X.t * elt)

(forall (a : key) (e : elt), ~ InA eqke (a, e) m) -> is_empty m = true
elt:Type
m:list (X.t * elt)

forall (p : X.t * elt) (l : list (X.t * elt)), (forall (a : key) (e : elt), ~ InA eqke (a, e) (p :: l)) -> is_empty (p :: l) = true
elt:Type
m:list (X.t * elt)
p:(X.t * elt)%type
l:list (X.t * elt)
inlist:forall (a : key) (e : elt), ~ InA eqke (a, e) (p :: l)

is_empty (p :: l) = true
elt:Type
m:list (X.t * elt)
t0:X.t
e:elt
l:list (X.t * elt)
inlist:forall (a : key) (e0 : elt), ~ InA eqke (a, e0) ((t0, e) :: l)

is_empty ((t0, e) :: l) = true
absurd (InA eqke (t0, e) ((t0, e) :: l));auto. Qed.
elt:Type

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

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

is_empty m = true -> Empty m
elt:Type
m:t elt

forall (p : X.t * elt) (l : list (X.t * elt)), is_empty (p :: l) = true -> Empty (p :: l)
elt:Type
m:t elt
p:(X.t * elt)%type
l:list (X.t * elt)
abs:is_empty (p :: l) = true

Empty (p :: l)
inversion abs. Qed.

mem

Function mem (k : key) (s : t elt) {struct s} : bool :=
  match s with
   | nil => false
   | (k',_) :: l => if X.eq_dec k k' then true else mem k l
  end.

elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x : X.t, In x m -> mem x m = true
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x : X.t, In x m -> mem x m = true
elt:Type
m:list (X.t * elt)
x:X.t

NoDupA m -> In x m -> mem x m = true
elt:Type
x:X.t
NoDup:NoDupA nil
belong1:In x nil

false = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
NoDup:NoDupA ((k', _x) :: l)
belong1:In x ((k', _x) :: l)
mem x l = true
elt:Type
x:X.t
NoDup:NoDupA nil
belong1:In x nil
x0:elt
H:MapsTo x x0 nil

false = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
NoDup:NoDupA ((k', _x) :: l)
belong1:In x ((k', _x) :: l)
mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
NoDup:NoDupA ((k', _x) :: l)
belong1:In x ((k', _x) :: l)

mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
belong1:In x ((k', _x) :: l)
H:~ InA eqk (k', _x) l
H0:NoDupA l

mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H1:MapsTo x x0 ((k', _x) :: l)

mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H2:eqke (x, x0) (k', _x)

mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H2:InA eqke (x, x0) l
mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H1:X.eq x k'
H2:x0 = _x

mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H2:InA eqke (x, x0) l
mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H2:InA eqke (x, x0) l

mem x l = true
elt:Type
x, k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> In x l -> mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H2:InA eqke (x, x0) l

In x l
exists x0; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x : key, mem x m = true -> In x m
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x : key, mem x m = true -> In x m
elt:Type
m:list (X.t * elt)
x:key

NoDupA m -> mem x m = true -> exists e : elt, InA eqke (x, e) m
elt:Type
x:key
k':X.t
_x:elt
l:list (X.t * elt)
_x0:X.eq x k'
e0:X.eq_dec x k' = left _x0
NoDup:NoDupA ((k', _x) :: l)
hyp:true = true

exists e : elt, InA eqke (x, e) ((k', _x) :: l)
elt:Type
x:key
k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> mem x l = true -> exists e : elt, InA eqke (x, e) l
NoDup:NoDupA ((k', _x) :: l)
hyp:mem x l = true
exists e : elt, InA eqke (x, e) ((k', _x) :: l)
elt:Type
x:key
k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> mem x l = true -> exists e : elt, InA eqke (x, e) l
NoDup:NoDupA ((k', _x) :: l)
hyp:mem x l = true

exists e : elt, InA eqke (x, e) ((k', _x) :: l)
elt:Type
x:key
k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
IHb:NoDupA l -> mem x l = true -> exists e : elt, InA eqke (x, e) l
hyp:mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l

exists e : elt, InA eqke (x, e) ((k', _x) :: l)
elt:Type
x:key
k':X.t
_x:elt
l:list (X.t * elt)
_x0:~ X.eq x k'
e0:X.eq_dec x k' = right _x0
hyp:mem x l = true
H:~ InA eqk (k', _x) l
H0:NoDupA l
x0:elt
H1:InA eqke (x, x0) l

exists e : elt, InA eqke (x, e) ((k', _x) :: l)
exists x0; auto. Qed.

find

Function find (k:key) (s: t elt) {struct s} : option elt :=
  match s with
   | nil => None
   | (k',x)::s' => if X.eq_dec k k' then Some x else find k s'
  end.

elt:Type

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

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

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

forall e : elt, find x m = Some e -> InA eqke (x, e) m
functional induction (find x m);simpl;intros e' eqfind; inversion eqfind; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : X.t) (e : elt), MapsTo x e m -> find x m = Some e
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : X.t) (e : elt), MapsTo x e m -> find x m = Some e
elt:Type
m:list (X.t * elt)
x:X.t
e:elt

NoDupA m -> InA eqke (x, e) m -> find x m = Some e
elt:Type
x:X.t
e:elt

NoDupA nil -> InA eqke (x, e) nil -> None = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x
NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> Some x0 = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHo:NoDupA s' -> InA eqke (x, e) s' -> find x s' = Some e
NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> find x s' = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x

NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> Some x0 = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHo:NoDupA s' -> InA eqke (x, e) s' -> find x s' = Some e
NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> find x s' = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x
H:~ InA eqk (k', x0) s'
H0:NoDupA s'
H2:eqke (x, e) (k', x0)

Some x0 = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x
H:~ InA eqk (k', x0) s'
H0:NoDupA s'
H2:InA eqke (x, e) s'
Some x0 = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHo:NoDupA s' -> InA eqke (x, e) s' -> find x s' = Some e
NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> find x s' = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x
H:~ InA eqk (k', x0) s'
H0:NoDupA s'
H2:InA eqke (x, e) s'

Some x0 = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHo:NoDupA s' -> InA eqke (x, e) s' -> find x s' = Some e
NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> find x s' = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHo:NoDupA s' -> InA eqke (x, e) s' -> find x s' = Some e

NoDupA ((k', x0) :: s') -> InA eqke (x, e) ((k', x0) :: s') -> find x s' = Some e
elt:Type
x:X.t
e:elt
k':X.t
x0:elt
s':list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHo:NoDupA s' -> InA eqke (x, e) s' -> find x s' = Some e
H:~ InA eqk (k', x0) s'
H0:NoDupA s'
H2:eqke (x, e) (k', x0)

find x s' = Some e
compute in H2; destruct H2; elim _x; auto. Qed. (* Not part of the exported specifications, used later for [combine]. *)
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x x' : X.t, X.eq x x' -> find x m = find x' m
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x x' : X.t, X.eq x x' -> find x m = find x' m
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 x'0 : X.t, X.eq x0 x'0 -> find x0 m = find x'0 m
Hm:NoDupA ((t0, e) :: m)
x, x':X.t
H:X.eq x x'

(if X.eq_dec x t0 then Some e else find x m) = (if X.eq_dec x' t0 then Some e else find x' m)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 x'0 : X.t, X.eq x0 x'0 -> find x0 m = find x'0 m
x, x':X.t
H:X.eq x x'
H0:~ InA eqk (t0, e) m
H1:NoDupA m

(if X.eq_dec x t0 then Some e else find x m) = (if X.eq_dec x' t0 then Some e else find x' m)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 x'0 : X.t, X.eq x0 x'0 -> find x0 m = find x'0 m
x, x':X.t
H:X.eq x x'
H0:~ InA eqk (t0, e) m
H1:NoDupA m

(if X.eq_dec x t0 then Some e else find x' m) = (if X.eq_dec x' t0 then Some e else find x' m)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 x'0 : X.t, X.eq x0 x'0 -> find x0 m = find x'0 m
x, x':X.t
H:X.eq x x'
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e0:X.eq x t0
Hneq':~ X.eq x' t0

Some e = find x' m
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 x'0 : X.t, X.eq x0 x'0 -> find x0 m = find x'0 m
x, x':X.t
H:X.eq x x'
H0:~ InA eqk (t0, e) m
H1:NoDupA m
Hneq:~ X.eq x t0
e0:X.eq x' t0
find x' m = Some e
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 x'0 : X.t, X.eq x0 x'0 -> find x0 m = find x'0 m
x, x':X.t
H:X.eq x x'
H0:~ InA eqk (t0, e) m
H1:NoDupA m
Hneq:~ X.eq x t0
e0:X.eq x' t0

find x' m = Some e
elim Hneq; apply X.eq_trans with x'; auto. Qed.

add

Function add (k : key) (x : elt) (s : t elt) {struct s} : t elt :=
  match s with
   | nil => (k,x) :: nil
   | (k',y) :: l => if X.eq_dec k k' then (k,x)::l else (k',y)::add k x l
  end.

elt:Type

forall (m : t elt) (x y : X.t) (e : elt), X.eq x y -> MapsTo y e (add x e m)
elt:Type

forall (m : t elt) (x y : X.t) (e : elt), X.eq x y -> MapsTo y e (add x e m)
elt:Type
m:t elt
x:X.t
e:elt

forall y : X.t, X.eq x y -> InA eqke (y, e) (add x e m)
functional induction (add x e m);simpl;auto. Qed.
elt:Type

forall (m : list (X.t * elt)) (x y : X.t) (e e' : elt), ~ X.eq x y -> MapsTo y e m -> MapsTo y e (add x e' m)
elt:Type

forall (m : list (X.t * elt)) (x y : X.t) (e e' : elt), ~ X.eq x y -> MapsTo y e m -> MapsTo y e (add x e' m)
elt:Type
m:list (X.t * elt)
x:X.t
e':elt

forall (y : X.t) (e : elt), ~ X.eq x y -> InA eqke (y, e) m -> InA eqke (y, e) (add x e' m)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x

forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: l) -> InA eqke (y0, e) ((x, e') :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) l -> InA eqke (y0, e) (add x e' l)
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: l) -> InA eqke (y0, e) ((k', y) :: add x e' l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
y':X.t
e'':elt
eqky':~ X.eq x y'
H0:eqke (y', e'') (k', y)

InA eqke (y', e'') ((x, e') :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
y':X.t
e'':elt
eqky':~ X.eq x y'
H0:InA eqke (y', e'') l
InA eqke (y', e'') ((x, e') :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) l -> InA eqke (y0, e) (add x e' l)
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: l) -> InA eqke (y0, e) ((k', y) :: add x e' l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
y':X.t
e'':elt
eqky':~ X.eq x y'
H:X.eq y' k'
H0:e'' = y

InA eqke (y', e'') ((x, e') :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
y':X.t
e'':elt
eqky':~ X.eq x y'
H0:InA eqke (y', e'') l
InA eqke (y', e'') ((x, e') :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) l -> InA eqke (y0, e) (add x e' l)
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: l) -> InA eqke (y0, e) ((k', y) :: add x e' l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
y':X.t
e'':elt
eqky':~ X.eq x y'
H0:InA eqke (y', e'') l

InA eqke (y', e'') ((x, e') :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) l -> InA eqke (y0, e) (add x e' l)
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: l) -> InA eqke (y0, e) ((k', y) :: add x e' l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) l -> InA eqke (y0, e) (add x e' l)

forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: l) -> InA eqke (y0, e) ((k', y) :: add x e' l)
intros y' e'' eqky'; inversion_clear 1; intuition. Qed.
elt:Type

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

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

~ X.eq x y -> MapsTo y e (add x e' m) -> MapsTo y e m
elt:Type
m:t elt
x:X.t
e':elt

forall (y : X.t) (e : elt), ~ X.eq x y -> InA eqke (y, e) (add x e' m) -> InA eqke (y, e) m
elt:Type
x:X.t
e':elt

forall (y : X.t) (e : elt), ~ X.eq x y -> InA eqke (y, e) ((x, e') :: nil) -> InA eqke (y, e) nil
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((x, e') :: l) -> InA eqke (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) (add x e' l) -> InA eqke (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: add x e' l) -> InA eqke (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x

forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((x, e') :: l) -> InA eqke (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) (add x e' l) -> InA eqke (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: add x e' l) -> InA eqke (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) (add x e' l) -> InA eqke (y0, e) l

forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqke (y0, e) ((k', y) :: add x e' l) -> InA eqke (y0, e) ((k', y) :: l)
inversion_clear 2; auto. Qed.
elt:Type

forall (m : t elt) (x y : X.t) (e e' : elt), ~ X.eq x y -> InA eqk (y, e) (add x e' m) -> InA eqk (y, e) m
elt:Type

forall (m : t elt) (x y : X.t) (e e' : elt), ~ X.eq x y -> InA eqk (y, e) (add x e' m) -> InA eqk (y, e) m
elt:Type
m:t elt
x, y:X.t
e, e':elt

~ X.eq x y -> InA eqk (y, e) (add x e' m) -> InA eqk (y, e) m
elt:Type
m:t elt
x:X.t
e':elt

forall (y : X.t) (e : elt), ~ X.eq x y -> InA eqk (y, e) (add x e' m) -> InA eqk (y, e) m
elt:Type
x:X.t
e':elt

forall (y : X.t) (e : elt), ~ X.eq x y -> InA eqk (y, e) ((x, e') :: nil) -> InA eqk (y, e) nil
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((x, e') :: l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) (add x e' l) -> InA eqk (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((k', y) :: add x e' l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
y:X.t
e:elt
H:~ X.eq x y
H1:eqk (y, e) (x, e')

InA eqk (y, e) nil
elt:Type
x:X.t
e':elt
y:X.t
e:elt
H:~ X.eq x y
H1:InA eqk (y, e) nil
InA eqk (y, e) nil
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((x, e') :: l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) (add x e' l) -> InA eqk (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((k', y) :: add x e' l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
y:X.t
e:elt
H:~ X.eq x y
H1:InA eqk (y, e) nil

InA eqk (y, e) nil
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((x, e') :: l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) (add x e' l) -> InA eqk (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((k', y) :: add x e' l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x

forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((x, e') :: l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) (add x e' l) -> InA eqk (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((k', y) :: add x e' l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
y0:X.t
e:elt
H:~ X.eq x y0
H1:eqk (y0, e) (x, e')

InA eqk (y0, e) l
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) (add x e' l) -> InA eqk (y0, e) l
forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((k', y) :: add x e' l) -> InA eqk (y0, e) ((k', y) :: l)
elt:Type
x:X.t
e':elt
k':X.t
y:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) (add x e' l) -> InA eqk (y0, e) l

forall (y0 : X.t) (e : elt), ~ X.eq x y0 -> InA eqk (y0, e) ((k', y) :: add x e' l) -> InA eqk (y0, e) ((k', y) :: l)
inversion_clear 2; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : key) (e : elt), NoDupA (add x e m)
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : key) (e : elt), NoDupA (add x e m)
elt:Type

NoDupA nil -> forall (x : key) (e : elt), NoDupA (add x e nil)
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall (x : key) (e : elt), NoDupA (add x e m)
NoDupA (a :: m) -> forall (x : key) (e : elt), NoDupA (add x e (a :: m))
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall (x : key) (e : elt), NoDupA (add x e m)

NoDupA (a :: m) -> forall (x : key) (e : elt), NoDupA (add x e (a :: m))
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
Hm:NoDupA (a :: m)
x:key
e:elt

NoDupA (add x e (a :: m))
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
Hm:NoDupA ((x', e') :: m)
x:key
e:elt

NoDupA (add x e ((x', e') :: m))
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m

X.eq x x' -> NoDupA ((x, e) :: m)
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m
~ X.eq x x' -> NoDupA ((x', e') :: add x e m)
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e1 : elt), NoDupA (add x0 e1 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m
e0:X.eq x x'

~ InA eqk (x, e) m
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m
~ X.eq x x' -> NoDupA ((x', e') :: add x e m)
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e1 : elt), NoDupA (add x0 e1 m)
x:key
e:elt
H0:NoDupA m
e0:X.eq x x'
H:InA eqk (x, e) m

InA eqk (x', e') m
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m
~ X.eq x x' -> NoDupA ((x', e') :: add x e m)
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m

~ X.eq x x' -> NoDupA ((x', e') :: add x e m)
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall (x0 : key) (e0 : elt), NoDupA (add x0 e0 m)
x:key
e:elt
H:~ InA eqk (x', e') m
H0:NoDupA m
n:~ X.eq x x'

~ InA eqk (x', e') (add x e m)
contradict H; apply add_3' with x e; auto. Qed. (* Not part of the exported specifications, used later for [combine]. *)
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x a : X.t) (e : elt), X.eq x a -> find x (add a e m) = Some e
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x a : X.t) (e : elt), X.eq x a -> find x (add a e m) = Some e
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:X.eq x a

find x (add a e m) = Some e
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:X.eq x a

NoDupA (add a e m)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:X.eq x a
MapsTo x e (add a e m)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:X.eq x a

MapsTo x e (add a e m)
apply add_1; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x a : X.t) (e : elt), ~ X.eq x a -> find x (add a e m) = find x m
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x a : X.t) (e : elt), ~ X.eq x a -> find x (add a e m) = find x m
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a

find x (add a e m) = find x m
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
e0:elt
H0:find x m = Some e0

find x (add a e m) = Some e0
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
find x (add a e m) = None
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
e0:elt
H0:find x m = Some e0

NoDupA (add a e m)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
e0:elt
H0:find x m = Some e0
MapsTo x e0 (add a e m)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
find x (add a e m) = None
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
e0:elt
H0:find x m = Some e0

MapsTo x e0 (add a e m)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
find x (add a e m) = None
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
e0:elt
H0:find x m = Some e0

MapsTo x e0 m
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
find x (add a e m) = None
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None

find x (add a e m) = None
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
e0:elt
H1:find x (add a e m) = Some e0

Some e0 = None
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
e0:elt
H1:find x (add a e m) = Some e0

find x m = Some e0
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
e0:elt
H1:find x (add a e m) = Some e0

MapsTo x e0 m
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
x, a:X.t
e:elt
H:~ X.eq x a
H0:find x m = None
e0:elt
H1:find x (add a e m) = Some e0

MapsTo x e0 (add a e m)
apply find_2; auto. Qed.

remove

Function remove (k : key) (s : t elt) {struct s} : t elt :=
  match s with
   | nil => nil
   | (k',x) :: l => if X.eq_dec k k' then l else (k',x) :: remove k l
  end.

elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x y : X.t, X.eq x y -> ~ In y (remove x m)
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x y : X.t, X.eq x y -> ~ In y (remove x m)
elt:Type
m:list (X.t * elt)
x, y:X.t

NoDupA m -> X.eq x y -> ~ In y (remove x m)
elt:Type
x, y:X.t
Hm:NoDupA nil
H:X.eq x y

~ In y nil
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y l
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y

~ In y l
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
H:X.eq x y
H0:~ InA eqk (k', x0) l
H1:NoDupA l

~ In y l
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
H:X.eq x y
H0:~ InA eqk (k', x0) l
H1:NoDupA l

~ In y l
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
H:X.eq x y
H1:NoDupA l
H0:In y l

InA eqk (k', x0) l
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
H:X.eq x y
H1:NoDupA l
e:elt
H2:InA eqke (y, e) l

InA eqk (k', x0) l
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e0:X.eq_dec x k' = left _x
H:X.eq x y
H1:NoDupA l
e:elt
H2:InA eqke (y, e) l

eqk (y, e) (k', x0)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y

~ In y ((k', x0) :: remove x l)
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
H2:In y ((k', x0) :: remove x l)

False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
e:elt
H0:eqke (y, e) (k', x0)

False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
e:elt
H0:InA eqke (y, e) (remove x l)
False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
e:elt
H0:X.eq y k'
H1:e = x0

False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
e:elt
H0:InA eqke (y, e) (remove x l)
False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
Hm:NoDupA ((k', x0) :: l)
H:X.eq x y
e:elt
H0:InA eqke (y, e) (remove x l)

False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
H:X.eq x y
e:elt
H0:InA eqke (y, e) (remove x l)
H1:~ InA eqk (k', x0) l
H2:NoDupA l

False
elt:Type
x, y, k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e0:X.eq_dec x k' = right _x
IHt0:NoDupA l -> X.eq x y -> ~ In y (remove x l)
H:X.eq x y
e:elt
H0:InA eqke (y, e) (remove x l)
H1:~ InA eqk (k', x0) l
H2:NoDupA l

In y (remove x l)
exists e; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x y : X.t) (e : elt), ~ X.eq x y -> MapsTo y e m -> MapsTo y e (remove x m)
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x y : X.t) (e : elt), ~ X.eq x y -> MapsTo y e m -> MapsTo y e (remove x m)
elt:Type
m:list (X.t * elt)
x, y:X.t
e:elt

NoDupA m -> ~ X.eq x y -> InA eqke (y, e) m -> InA eqke (y, e) (remove x m)
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x

NoDupA ((k', x0) :: l) -> ~ X.eq x y -> InA eqke (y, e) ((k', x0) :: l) -> InA eqke (y, e) l
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHt0:NoDupA l -> ~ X.eq x y -> InA eqke (y, e) l -> InA eqke (y, e) (remove x l)
NoDupA ((k', x0) :: l) -> ~ X.eq x y -> InA eqke (y, e) ((k', x0) :: l) -> InA eqke (y, e) ((k', x0) :: remove x l)
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x
Hm:NoDupA ((k', x0) :: l)
H:~ X.eq x y
H1:eqke (y, e) (k', x0)

InA eqke (y, e) l
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHt0:NoDupA l -> ~ X.eq x y -> InA eqke (y, e) l -> InA eqke (y, e) (remove x l)
NoDupA ((k', x0) :: l) -> ~ X.eq x y -> InA eqke (y, e) ((k', x0) :: l) -> InA eqke (y, e) ((k', x0) :: remove x l)
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:X.eq x k'
e1:X.eq_dec x k' = left _x
Hm:NoDupA ((k', x0) :: l)
H:~ X.eq x y
H0:X.eq y k'
H1:e = x0

InA eqke (y, e) l
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHt0:NoDupA l -> ~ X.eq x y -> InA eqke (y, e) l -> InA eqke (y, e) (remove x l)
NoDupA ((k', x0) :: l) -> ~ X.eq x y -> InA eqke (y, e) ((k', x0) :: l) -> InA eqke (y, e) ((k', x0) :: remove x l)
elt:Type
x, y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHt0:NoDupA l -> ~ X.eq x y -> InA eqke (y, e) l -> InA eqke (y, e) (remove x l)

NoDupA ((k', x0) :: l) -> ~ X.eq x y -> InA eqke (y, e) ((k', x0) :: l) -> InA eqke (y, e) ((k', x0) :: remove x l)
inversion_clear 1; inversion_clear 2; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : key) (y : X.t) (e : elt), MapsTo y e (remove x m) -> MapsTo y e m
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : key) (y : X.t) (e : elt), MapsTo y e (remove x m) -> MapsTo y e m
elt:Type
m:list (X.t * elt)
x:key
y:X.t
e:elt

NoDupA m -> InA eqke (y, e) (remove x m) -> InA eqke (y, e) m
elt:Type
x:key
y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHt0:NoDupA l -> InA eqke (y, e) (remove x l) -> InA eqke (y, e) l

NoDupA ((k', x0) :: l) -> InA eqke (y, e) ((k', x0) :: remove x l) -> InA eqke (y, e) ((k', x0) :: l)
do 2 inversion_clear 1; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : key) (y : X.t) (e : elt), InA eqk (y, e) (remove x m) -> InA eqk (y, e) m
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall (x : key) (y : X.t) (e : elt), InA eqk (y, e) (remove x m) -> InA eqk (y, e) m
elt:Type
m:list (X.t * elt)
x:key
y:X.t
e:elt

NoDupA m -> InA eqk (y, e) (remove x m) -> InA eqk (y, e) m
elt:Type
x:key
y:X.t
e:elt
k':X.t
x0:elt
l:list (X.t * elt)
_x:~ X.eq x k'
e1:X.eq_dec x k' = right _x
IHt0:NoDupA l -> InA eqk (y, e) (remove x l) -> InA eqk (y, e) l

NoDupA ((k', x0) :: l) -> InA eqk (y, e) ((k', x0) :: remove x l) -> InA eqk (y, e) ((k', x0) :: l)
do 2 inversion_clear 1; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x : key, NoDupA (remove x m)
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall x : key, NoDupA (remove x m)
elt:Type

NoDupA nil -> forall x : key, NoDupA (remove x nil)
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall x : key, NoDupA (remove x m)
NoDupA (a :: m) -> forall x : key, NoDupA (remove x (a :: m))
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall x : key, NoDupA (remove x m)

NoDupA (a :: m) -> forall x : key, NoDupA (remove x (a :: m))
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 : key, NoDupA (remove x0 m)
Hm:NoDupA (a :: m)
x:key

NoDupA (remove x (a :: m))
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 : key, NoDupA (remove x0 m)
x:key
H:~ InA eqk a m
H0:NoDupA m

NoDupA (remove x (a :: m))
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 : key, NoDupA (remove x0 m)
x:key
H:~ InA eqk (x', e') m
H0:NoDupA m

NoDupA (remove x ((x', e') :: m))
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 : key, NoDupA (remove x0 m)
x:key
H:~ InA eqk (x', e') m
H0:NoDupA m

~ X.eq x x' -> NoDupA ((x', e') :: remove x m)
elt:Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA m -> forall x0 : key, NoDupA (remove x0 m)
x:key
H:~ InA eqk (x', e') m
H0:NoDupA m
n:~ X.eq x x'

~ InA eqk (x', e') (remove x m)
contradict H; apply remove_3' with x; auto. Qed.

elements

Definition elements (m: t elt) := m.

elt:Type

forall (m : list (X.t * elt)) (x : X.t) (e : elt), MapsTo x e m -> InA eqke (x, e) (elements m)
elt:Type

forall (m : list (X.t * elt)) (x : X.t) (e : elt), MapsTo x e m -> InA eqke (x, e) (elements m)
auto. Qed.
elt:Type

forall (m : t elt) (x : X.t) (e : elt), InA eqke (x, e) (elements m) -> MapsTo x e m
elt:Type

forall (m : t elt) (x : X.t) (e : elt), InA eqke (x, e) (elements m) -> MapsTo x e m
auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> NoDupA (elements m)
elt:Type

forall m : list (X.t * elt), NoDupA m -> NoDupA (elements m)
auto. Qed.

fold

Function fold (A:Type)(f:key->elt->A->A)(m:t elt) (acc : A) {struct m} :  A :=
  match m with
   | nil => acc
   | (k,e)::m' => fold f m' (f k e acc)
  end.

elt:Type

forall (m : t elt) (A : Type) (i : A) (f : key -> elt -> A -> A), fold f m i = fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i
elt:Type

forall (m : t elt) (A : Type) (i : A) (f : key -> elt -> A -> A), fold f m i = fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i
intros; functional induction (@fold A f m i); auto. Qed.

equal

Definition check (cmp : elt -> elt -> bool)(k:key)(e:elt)(m': t elt) :=
  match find k m' with
   | None => false
   | Some e' => cmp e e'
  end.

Definition submap (cmp : elt -> elt -> bool)(m m' : t elt) : bool :=
  fold (fun k e b => andb (check cmp k e m') b) m true.

Definition equal (cmp : elt -> elt -> bool)(m m' : t elt) : bool :=
  andb (submap cmp m m') (submap (fun e' e => cmp e e') m' m).

Definition Submap cmp m m' :=
  (forall k, In k m -> In k m') /\
  (forall k e e', MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true).

Definition Equivb cmp m m' :=
  (forall k, In k m <-> In k m') /\
  (forall k e e', MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true).

elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, Submap cmp m m' -> submap cmp m m' = true
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, Submap cmp m m' -> submap cmp m m' = true
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true) -> fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true
elt:Type

NoDupA nil -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k nil -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e nil -> MapsTo k e' m' -> cmp e e' = true) -> fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) nil true = true
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true) -> fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true
NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true) -> fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true) -> fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true

NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true) -> fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
Hm:NoDupA ((t0, e) :: m)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
Hm:NoDupA ((t0, e) :: m)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m

In t0 m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m
H3:In t0 m'
fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m
H3:In t0 m'

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m'0 -> cmp0 e0 e'0 = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e'0 m' -> cmp e0 e'0 = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m'0 -> cmp0 e0 e'0 = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e'0 m' -> cmp e0 e'0 = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (cmp e e' && true) = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m'0 -> cmp0 e0 e'0 = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e'0 m' -> cmp e0 e'0 = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'

fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m true = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m'0 -> cmp0 e0 e'0 = true) -> fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k : X.t, In k ((t0, e) :: m) -> In k m'
H0:forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e'0 m' -> cmp e0 e'0 = true
H1:~ InA eqk (t0, e) m
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'

(forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m' -> cmp e0 e'0 = true)
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k0 : X.t, In k0 ((t0, e) :: m) -> In k0 m'
H0:forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 ((t0, e) :: m) -> MapsTo k0 e'0 m' -> cmp e0 e'0 = true
H1:InA eqk (t0, e) m -> False
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'
H4:forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m'0 -> cmp0 e0 e'0 = true) -> fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true
k:X.t
H5:In k m

In k m'
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k0 : X.t, In k0 ((t0, e) :: m) -> In k0 m'
H0:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 ((t0, e) :: m) -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H1:InA eqk (t0, e) m -> False
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'
H4:forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true) -> fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true
k:X.t
e0, e'0:elt
H5:MapsTo k e0 m
H6:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k0 : X.t, In k0 ((t0, e) :: m) -> In k0 m'
H0:forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 ((t0, e) :: m) -> MapsTo k0 e'0 m' -> cmp e0 e'0 = true
H1:InA eqk (t0, e) m -> False
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'
H4:forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m'0 -> cmp0 e0 e'0 = true) -> fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true
k:X.t
H5:In k m

In k ((t0, e) :: m)
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k0 : X.t, In k0 ((t0, e) :: m) -> In k0 m'
H0:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 ((t0, e) :: m) -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H1:InA eqk (t0, e) m -> False
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'
H4:forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true) -> fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true
k:X.t
e0, e'0:elt
H5:MapsTo k e0 m
H6:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:forall k0 : X.t, In k0 ((t0, e) :: m) -> In k0 m'
H0:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 ((t0, e) :: m) -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H1:InA eqk (t0, e) m -> False
H2:NoDupA m
e':elt
H3:MapsTo t0 e' m'
H4:forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true) -> fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true
k:X.t
e0, e'0:elt
H5:MapsTo k e0 m
H6:MapsTo k e'0 m'

cmp e0 e'0 = true
apply H0 with k; auto. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, submap cmp m m' = true -> Submap cmp m m'
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, submap cmp m m' = true -> Submap cmp m m'
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true -> (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
elt:Type

NoDupA nil -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) nil true = true -> (forall k : X.t, In k nil -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e nil -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true -> (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true -> (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true)
elt:Type

NoDupA nil -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, true = true -> (forall k : X.t, In k nil -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e nil -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true -> (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true -> (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
Hm:NoDupA nil
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:true = true
k:X.t
H0:In k nil

In k m'
elt:Type
Hm:NoDupA nil
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:true = true
k:X.t
e, e':elt
H0:MapsTo k e nil
H1:MapsTo k e' m'
cmp e e' = true
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true -> (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true -> (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
Hm:NoDupA nil
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:true = true
k:X.t
e, e':elt
H0:MapsTo k e nil
H1:MapsTo k e' m'

cmp e e' = true
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true -> (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true -> (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) m true = true -> (forall k : X.t, In k m -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)

NoDupA (a :: m) -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, fold (fun (k : key) (e : elt) (b : bool) => check cmp k e m' && b) (a :: m) true = true -> (forall k : X.t, In k (a :: m) -> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e (a :: m) -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
Hm:NoDupA ((t0, e) :: m)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m' && true) = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m

check cmp t0 e m' = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true

check cmp t0 e m' = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
cmp:elt -> elt -> bool
b:=check cmp t0 e m':bool
H:fold (fun (k : key) (e0 : elt) (b0 : bool) => check cmp k e0 m' && b0) m b = true

b = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m, m':list (X.t * elt)
cmp:elt -> elt -> bool

forall b : bool, fold (fun (k : key) (e0 : elt) (b0 : bool) => check cmp k e0 m' && b0) m b = true -> b = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
a:(X.t * elt)%type
m, m':list (X.t * elt)
cmp:elt -> elt -> bool
IHm:forall b0 : bool, fold (fun (k : key) (e0 : elt) (b1 : bool) => check cmp k e0 m' && b1) m b0 = true -> b0 = true
b:bool
H:(let (k, e0) := a in fold (fun (k0 : key) (e1 : elt) (b0 : bool) => check cmp k0 e1 m' && b0) m (check cmp k e0 m' && b)) = true

b = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
t1:X.t
e0:elt
m, m':list (X.t * elt)
cmp:elt -> elt -> bool
IHm:forall b0 : bool, fold (fun (k : key) (e1 : elt) (b1 : bool) => check cmp k e1 m' && b1) m b0 = true -> b0 = true
b:bool
H:fold (fun (k : key) (e1 : elt) (b0 : bool) => check cmp k e1 m' && b0) m (check cmp t1 e0 m' && b) = true

b = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m (check cmp t0 e m') = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:check cmp t0 e m' = true
H3:forall k : X.t, In k m -> In k m'
H4:forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m' -> cmp e0 e' = true

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m'0 -> cmp0 e0 e' = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
H2:match find t0 m' with | Some e' => cmp e e' | None => false end = true
H3:forall k : X.t, In k m -> In k m'
H4:forall (k : X.t) (e0 e' : elt), MapsTo k e0 m -> MapsTo k e' m' -> cmp e0 e' = true

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e' : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e' m' -> cmp e0 e' = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k : key) (e0 : elt) (b : bool) => check cmp0 k e0 m'0 && b) m true = true -> (forall k : X.t, In k m -> In k m'0) /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m'0 -> cmp0 e0 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k : key) (e0 : elt) (b : bool) => check cmp k e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k : X.t, In k m -> In k m'
H4:forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 m -> MapsTo k e'0 m' -> cmp e0 e'0 = true
H5:find t0 m' = Some e'

(forall k : X.t, In k ((t0, e) :: m) -> In k m') /\ (forall (k : X.t) (e0 e'0 : elt), MapsTo k e0 ((t0, e) :: m) -> MapsTo k e'0 m' -> cmp e0 e'0 = true)
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m'0 -> cmp0 e0 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp k0 e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> cmp e0 e'0 = true
H5:find t0 m' = Some e'
k:X.t
H6:In k ((t0, e) :: m)

In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:eqke (k, e0) (t0, e)

In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:InA eqke (k, e0) m
In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m'0 -> cmp0 e0 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp k0 e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> cmp e0 e'0 = true
H5:find t0 m' = Some e'
k:X.t
H6:X.eq k t0

In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:InA eqke (k, e0) m
In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m'0 -> cmp0 e0 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp k0 e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> cmp e0 e'0 = true
H5:find t0 m' = Some e'
k:X.t
H6:X.eq k t0

MapsTo k e' m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:InA eqke (k, e0) m
In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m'0 -> cmp0 e0 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp k0 e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e0 e'0 : elt), MapsTo k0 e0 m -> MapsTo k0 e'0 m' -> cmp e0 e'0 = true
H5:find t0 m' = Some e'
k:X.t
H6:X.eq k t0

MapsTo t0 e' m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:InA eqke (k, e0) m
In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:InA eqke (k, e0) m

In k m'
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m'0 -> cmp0 e1 e'0 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'0 : elt), MapsTo k0 e1 m -> MapsTo k0 e'0 m' -> cmp e1 e'0 = true
H5:find t0 m' = Some e'
k:X.t
e0:elt
H7:InA eqke (k, e0) m

In k m
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H6:MapsTo k e0 ((t0, e) :: m)
H7:MapsTo k e'0 m'

cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H7:MapsTo k e'0 m'
H8:eqke (k, e0) (t0, e)

cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H7:MapsTo k e'0 m'
H8:InA eqke (k, e0) m
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp0 k0 e0 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e0 e'1 : elt), MapsTo k0 e0 m -> MapsTo k0 e'1 m'0 -> cmp0 e0 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e0 : elt) (b : bool) => check cmp k0 e0 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e0 e'1 : elt), MapsTo k0 e0 m -> MapsTo k0 e'1 m' -> cmp e0 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e'0:elt
H7:MapsTo k e'0 m'
H6:X.eq k t0

cmp e e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H7:MapsTo k e'0 m'
H8:InA eqke (k, e0) m
cmp e0 e'0 = true
elt:Type
t0:X.t
e:elt
m:list (X.t * elt)
IHm:NoDupA m -> forall m'0 : list (X.t * elt), NoDupA m'0 -> forall cmp0 : elt -> elt -> bool, fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp0 k0 e1 m'0 && b) m true = true -> (forall k0 : X.t, In k0 m -> In k0 m'0) /\ (forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m'0 -> cmp0 e1 e'1 = true)
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:fold (fun (k0 : key) (e1 : elt) (b : bool) => check cmp k0 e1 m' && b) m true = true
H0:~ InA eqk (t0, e) m
H1:NoDupA m
e':elt
H2:cmp e e' = true
H3:forall k0 : X.t, In k0 m -> In k0 m'
H4:forall (k0 : X.t) (e1 e'1 : elt), MapsTo k0 e1 m -> MapsTo k0 e'1 m' -> cmp e1 e'1 = true
H5:find t0 m' = Some e'
k:X.t
e0, e'0:elt
H7:MapsTo k e'0 m'
H8:InA eqke (k, e0) m

cmp e0 e'0 = true
apply H4 with k; auto. Qed.
Specification of equal
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, Equivb cmp m m' -> equal cmp m m' = true
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, Equivb cmp m m' -> equal cmp m m' = true
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, (forall k : X.t, In k m <-> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true) -> submap cmp m m' && submap (fun e' e : elt => cmp e e') m' m = true
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H0:forall k : X.t, In k m <-> In k m'
H1:forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true

submap cmp m m' && submap (fun e' e : elt => cmp e e') m' m = true
apply andb_true_intro; split; apply submap_1; unfold Submap; firstorder. Qed.
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, equal cmp m m' = true -> Equivb cmp m m'
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, equal cmp m m' = true -> Equivb cmp m m'
elt:Type

forall m : list (X.t * elt), NoDupA m -> forall m' : list (X.t * elt), NoDupA m' -> forall cmp : elt -> elt -> bool, submap cmp m m' && submap (fun e' e : elt => cmp e e') m' m = true -> (forall k : X.t, In k m <-> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H:submap cmp m m' && submap (fun e' e : elt => cmp e e') m' m = true

(forall k : X.t, In k m <-> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H0:submap cmp m m' = true
H1:submap (fun e' e : elt => cmp e e') m' m = true

(forall k : X.t, In k m <-> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H0:submap cmp m m' = true
H1:submap (fun e' e : elt => cmp e e') m' m = true

Submap cmp m m' -> (forall k : X.t, In k m <-> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
elt:Type
m:list (X.t * elt)
Hm:NoDupA m
m':list (X.t * elt)
Hm':NoDupA m'
cmp:elt -> elt -> bool
H0:submap cmp m m' = true
H1:submap (fun e' e : elt => cmp e e') m' m = true

Submap (fun e' e : elt => cmp e e') m' m -> Submap cmp m m' -> (forall k : X.t, In k m <-> In k m') /\ (forall (k : X.t) (e e' : elt), MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true)
firstorder. Qed. Variable elt':Type.

map and mapi

Fixpoint map (f:elt -> elt') (m:t elt) : t elt' :=
  match m with
   | nil => nil
   | (k,e)::m' => (k,f e) :: map f m'
  end.

Fixpoint mapi (f: key -> elt -> elt') (m:t elt) : t elt' :=
  match m with
   | nil => nil
   | (k,e)::m' => (k,f k e) :: mapi f m'
  end.

End Elt.
Section Elt2.
(* A new section is necessary for previous definitions to work
   with different [elt], especially [MapsTo]... *)

Variable elt elt' : Type.
Specification of map
elt, elt':Type

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

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

MapsTo x e m -> MapsTo x (f e) (map f m)
(* functional induction map elt elt' f m. *) (* Marche pas ??? *)
elt, elt':Type
x:key
e:elt
f:elt -> elt'

MapsTo x e nil -> MapsTo x (f e) (map f nil)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
MapsTo x e (a :: m) -> MapsTo x (f e) (map f (a :: m))
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)

MapsTo x e (a :: m) -> MapsTo x (f e) (map f (a :: m))
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)

MapsTo x e ((x', e') :: m) -> MapsTo x (f e) (map f ((x', e') :: m))
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)

MapsTo x e ((x', e') :: m) -> MapsTo x (f e) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
H0:eqke (x, e) (x', e')

MapsTo x (f e) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
H0:InA (eqke (elt:=elt)) (x, e) m
MapsTo x (f e) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
H0:eqke (x, e) (x', e')

eqke (x, f e) (x', f e')
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
H0:InA (eqke (elt:=elt)) (x, e) m
MapsTo x (f e) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
H0:InA (eqke (elt:=elt)) (x, e) m

MapsTo x (f e) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:elt -> elt'
IHm:MapsTo x e m -> MapsTo x (f e) (map f m)
H0:InA (eqke (elt:=elt)) (x, e) m

InA (eqke (elt:=elt')) (x, f e) (map f m)
unfold MapsTo in *; auto. Qed.
elt, elt':Type

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

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

In x (map f m) -> In x m
(* functional induction map elt elt' f m. *) (* Marche pas ??? *)
elt, elt':Type
x:key
f:elt -> elt'

In x nil -> In x nil
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
In x (let (k, e) := a in (k, f e) :: map f m) -> In x (a :: m)
elt, elt':Type
x:key
f:elt -> elt'
e:elt'
abs:MapsTo x e nil

In x nil
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
In x (let (k, e) := a in (k, f e) :: map f m) -> In x (a :: m)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m

In x (let (k, e) := a in (k, f e) :: map f m) -> In x (a :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m

In x ((x', f e) :: map f m) -> In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
hyp:In x ((x', f e) :: map f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
hyp:In x ((x', f e) :: map f m)
x0:elt'
H:MapsTo x x0 ((x', f e) :: map f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
x0:elt'
H:MapsTo x x0 ((x', f e) :: map f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:eqke (x, e') (x', f e)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)
In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:eqke (x, e') (x', f e)

eqke (x, e) (x', e)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)
In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
IHm:In x (map f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)

In x (map f m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)
e'':elt
hyp:MapsTo x e'' m
In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)
e'':elt
hyp:MapsTo x e'' m

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:elt -> elt'
e':elt'
H:MapsTo x e' ((x', f e) :: map f m)
H1:InA (eqke (elt:=elt')) (x, e') (map f m)
e'':elt
hyp:MapsTo x e'' m

MapsTo x e'' ((x', e) :: m)
constructor 2; auto. Qed.
elt, elt':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall f : elt -> elt', NoDupA (eqk (elt:=elt')) (map f m)
elt, elt':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall f : elt -> elt', NoDupA (eqk (elt:=elt')) (map f m)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f : elt -> elt', NoDupA (eqk (elt:=elt')) (map f m)

NoDupA (eqk (elt:=elt)) (a :: m) -> forall f : elt -> elt', NoDupA (eqk (elt:=elt')) (let (k, e) := a in (k, f e) :: map f m)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : elt -> elt', NoDupA (eqk (elt:=elt')) (map f0 m)
Hm:NoDupA (eqk (elt:=elt)) (a :: m)
f:elt -> elt'

NoDupA (eqk (elt:=elt')) (let (k, e) := a in (k, f e) :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : elt -> elt', NoDupA (eqk (elt:=elt')) (map f0 m)
Hm:NoDupA (eqk (elt:=elt)) ((x', e') :: m)
f:elt -> elt'

NoDupA (eqk (elt:=elt')) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : elt -> elt', NoDupA (eqk (elt:=elt')) (map f0 m)
f:elt -> elt'
H:~ InA (eqk (elt:=elt)) (x', e') m
H0:NoDupA (eqk (elt:=elt)) m

NoDupA (eqk (elt:=elt')) ((x', f e') :: map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : elt -> elt', NoDupA (eqk (elt:=elt')) (map f0 m)
f:elt -> elt'
H:~ InA (eqk (elt:=elt)) (x', e') m
H0:NoDupA (eqk (elt:=elt)) m

~ InA (eqk (elt:=elt')) (x', f e') (map f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : elt -> elt', NoDupA (eqk (elt:=elt')) (map f0 m)
f:elt -> elt'
H0:NoDupA (eqk (elt:=elt)) m
H:InA (eqk (elt:=elt')) (x', f e') (map f m)

InA (eqk (elt:=elt)) (x', e') m
(* il faut un map_1 avec eqk au lieu de eqke *)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
f:elt -> elt'
H:InA (eqk (elt:=elt')) (x', f e') (map f m)

InA (eqk (elt:=elt)) (x', e') m
elt, elt':Type
x':X.t
e':elt
f:elt -> elt'
H:InA (eqk (elt:=elt')) (x', f e') nil

InA (eqk (elt:=elt)) (x', e') nil
elt, elt':Type
x':X.t
e':elt
a:(X.t * elt)%type
m:list (X.t * elt)
f:elt -> elt'
H:InA (eqk (elt:=elt')) (x', f e') (let (k, e) := a in (k, f e) :: map f m)
IHm:InA (eqk (elt:=elt')) (x', f e') (map f m) -> InA (eqk (elt:=elt)) (x', e') m
InA (eqk (elt:=elt)) (x', e') (a :: m)
elt, elt':Type
x':X.t
e':elt
a:(X.t * elt)%type
m:list (X.t * elt)
f:elt -> elt'
H:InA (eqk (elt:=elt')) (x', f e') (let (k, e) := a in (k, f e) :: map f m)
IHm:InA (eqk (elt:=elt')) (x', f e') (map f m) -> InA (eqk (elt:=elt)) (x', e') m

InA (eqk (elt:=elt)) (x', e') (a :: m)
destruct a; inversion H; auto. Qed.
Specification of mapi
elt, elt':Type

forall (m : t elt) (x : key) (e : elt) (f : key -> elt -> elt'), MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
elt, elt':Type

forall (m : t elt) (x : key) (e : elt) (f : key -> elt -> elt'), MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
elt, elt':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'

MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
(* functional induction mapi elt elt' f m. *) (* Marche pas ??? *)
elt, elt':Type
x:key
e:elt
f:key -> elt -> elt'

MapsTo x e nil -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f nil)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
MapsTo x e (a :: m) -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f (a :: m))
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)

MapsTo x e (a :: m) -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f (a :: m))
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)

MapsTo x e ((x', e') :: m) -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f ((x', e') :: m))
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)

MapsTo x e ((x', e') :: m) -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:eqke (x, e) (x', e')

exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:InA (eqke (elt:=elt)) (x, e) m
exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:eqke (x, e) (x', e')

X.eq x' x /\ MapsTo x (f x' e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:InA (eqke (elt:=elt)) (x, e) m
exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H:X.eq x x'
H0:e = e'

X.eq x' x /\ MapsTo x (f x' e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:InA (eqke (elt:=elt)) (x, e) m
exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H:X.eq x x'
H0:e = e'

MapsTo x (f x' e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:InA (eqke (elt:=elt)) (x, e) m
exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H:X.eq x x'
H0:e = e'

eqke (x, f x' e) (x', f x' e')
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:InA (eqke (elt:=elt)) (x, e) m
exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
IHm:MapsTo x e m -> exists y : X.t, X.eq y x /\ MapsTo x (f y e) (mapi f m)
H0:InA (eqke (elt:=elt)) (x, e) m

exists y : X.t, X.eq y x /\ MapsTo x (f y e) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
x:key
e:elt
f:key -> elt -> elt'
H0:InA (eqke (elt:=elt)) (x, e) m
y:X.t
hyp:X.eq y x /\ MapsTo x (f y e) (mapi f m)

exists y0 : X.t, X.eq y0 x /\ MapsTo x (f y0 e) ((x', f x' e') :: mapi f m)
exists y; intuition. Qed.
elt, elt':Type

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

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

In x (mapi f m) -> In x m
(* functional induction mapi elt elt' f m. *) (* Marche pas ??? *)
elt, elt':Type
x:key
f:key -> elt -> elt'

In x nil -> In x nil
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
In x (let (k, e) := a in (k, f k e) :: mapi f m) -> In x (a :: m)
elt, elt':Type
x:key
f:key -> elt -> elt'
e:elt'
abs:MapsTo x e nil

In x nil
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
In x (let (k, e) := a in (k, f k e) :: mapi f m) -> In x (a :: m)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m

In x (let (k, e) := a in (k, f k e) :: mapi f m) -> In x (a :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m

In x ((x', f x' e) :: mapi f m) -> In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
hyp:In x ((x', f x' e) :: mapi f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
hyp:In x ((x', f x' e) :: mapi f m)
x0:elt'
H:MapsTo x x0 ((x', f x' e) :: mapi f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
x0:elt'
H:MapsTo x x0 ((x', f x' e) :: mapi f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:eqke (x, e') (x', f x' e)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)
In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:eqke (x, e') (x', f x' e)

eqke (x, e) (x', e)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)
In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
IHm:In x (mapi f m) -> In x m
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)

In x (mapi f m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)
e'':elt
hyp:MapsTo x e'' m
In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)
e'':elt
hyp:MapsTo x e'' m

In x ((x', e) :: m)
elt, elt':Type
x':X.t
e:elt
m:list (X.t * elt)
x:key
f:key -> elt -> elt'
e':elt'
H:MapsTo x e' ((x', f x' e) :: mapi f m)
H1:InA (eqke (elt:=elt')) (x, e') (mapi f m)
e'':elt
hyp:MapsTo x e'' m

MapsTo x e'' ((x', e) :: m)
constructor 2; auto. Qed.
elt, elt':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall f : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f m)
elt, elt':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall f : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f m)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f m)

NoDupA (eqk (elt:=elt)) (a :: m) -> forall f : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (let (k, e) := a in (k, f k e) :: mapi f m)
elt, elt':Type
a:(X.t * elt)%type
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f0 m)
Hm:NoDupA (eqk (elt:=elt)) (a :: m)
f:key -> elt -> elt'

NoDupA (eqk (elt:=elt')) (let (k, e) := a in (k, f k e) :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f0 m)
Hm:NoDupA (eqk (elt:=elt)) ((x', e') :: m)
f:key -> elt -> elt'

NoDupA (eqk (elt:=elt')) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f0 m)
f:key -> elt -> elt'
H:~ InA (eqk (elt:=elt)) (x', e') m
H0:NoDupA (eqk (elt:=elt)) m

NoDupA (eqk (elt:=elt')) ((x', f x' e') :: mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f0 m)
f:key -> elt -> elt'
H:~ InA (eqk (elt:=elt)) (x', e') m
H0:NoDupA (eqk (elt:=elt)) m

~ InA (eqk (elt:=elt')) (x', f x' e') (mapi f m)
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
IHm:NoDupA (eqk (elt:=elt)) m -> forall f0 : key -> elt -> elt', NoDupA (eqk (elt:=elt')) (mapi f0 m)
f:key -> elt -> elt'
H0:NoDupA (eqk (elt:=elt)) m
H:InA (eqk (elt:=elt')) (x', f x' e') (mapi f m)

InA (eqk (elt:=elt)) (x', e') m
elt, elt':Type
x':X.t
e':elt
m:list (X.t * elt)
f:key -> elt -> elt'
H:InA (eqk (elt:=elt')) (x', f x' e') (mapi f m)

InA (eqk (elt:=elt)) (x', e') m
elt, elt':Type
x':X.t
e':elt
f:key -> elt -> elt'
H:InA (eqk (elt:=elt')) (x', f x' e') nil

InA (eqk (elt:=elt)) (x', e') nil
elt, elt':Type
x':X.t
e':elt
a:(X.t * elt)%type
m:list (X.t * elt)
f:key -> elt -> elt'
H:InA (eqk (elt:=elt')) (x', f x' e') (let (k, e) := a in (k, f k e) :: mapi f m)
IHm:InA (eqk (elt:=elt')) (x', f x' e') (mapi f m) -> InA (eqk (elt:=elt)) (x', e') m
InA (eqk (elt:=elt)) (x', e') (a :: m)
elt, elt':Type
x':X.t
e':elt
a:(X.t * elt)%type
m:list (X.t * elt)
f:key -> elt -> elt'
H:InA (eqk (elt:=elt')) (x', f x' e') (let (k, e) := a in (k, f k e) :: mapi f m)
IHm:InA (eqk (elt:=elt')) (x', f x' e') (mapi f m) -> InA (eqk (elt:=elt)) (x', e') m

InA (eqk (elt:=elt)) (x', e') (a :: m)
destruct a; inversion_clear H; auto. Qed. End Elt2. Section Elt3. Variable elt elt' elt'' : Type. Notation oee' := (option elt * option elt')%type. Definition combine_l (m:t elt)(m':t elt') : t oee' := mapi (fun k e => (Some e, find k m')) m. Definition combine_r (m:t elt)(m':t elt') : t oee' := mapi (fun k e' => (find k m, Some e')) m'. Definition fold_right_pair (A B C:Type)(f:A->B->C->C) := List.fold_right (fun p => f (fst p) (snd p)). Definition combine (m:t elt)(m':t elt') : t oee' := let l := combine_l m m' in let r := combine_r m m' in fold_right_pair (add (elt:=oee')) r l.
elt, elt', elt'':Type

forall l r : list (X.t * oee'), NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r l)
elt, elt', elt'':Type

forall l r : list (X.t * oee'), NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r l)
elt, elt', elt'':Type
a:(X.t * oee')%type
l:list (X.t * oee')
IHl:forall r : list (X.t * oee'), NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r l)

forall r : list (X.t * oee'), NoDupA (eqk (elt:=oee')) (a :: l) -> NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (add (fst a) (snd a) (fold_right_pair (add (elt:=oee')) r l))
elt, elt', elt'':Type
t0:X.t
p:oee'
l:list (X.t * oee')
IHl:forall r : list (X.t * oee'), NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r l)

forall r : list (X.t * oee'), NoDupA (eqk (elt:=oee')) ((t0, p) :: l) -> NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (add t0 p (fold_right_pair (add (elt:=oee')) r l))
elt, elt', elt'':Type
t0:X.t
p:oee'
l:list (X.t * oee')
IHl:forall r0 : list (X.t * oee'), NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) r0 -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r0 l)
r:list (X.t * oee')
H:~ InA (eqk (elt:=oee')) (t0, p) l
H0:NoDupA (eqk (elt:=oee')) l

NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) (add t0 p (fold_right_pair (add (elt:=oee')) r l))
intros; apply add_NoDup; auto. Qed. Hint Resolve fold_right_pair_NoDup : core.
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> NoDupA (eqk (elt:=oee')) (combine m m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> NoDupA (eqk (elt:=oee')) (combine m m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m))
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'

NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m))
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
f1:=fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m'):key -> elt -> oee'

NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') (mapi f1 m))
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
f1:=fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m'):key -> elt -> oee'
f2:=fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e'):key -> elt' -> oee'

NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi f2 m') (mapi f1 m))
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
f1:=fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m'):key -> elt -> oee'
f2:=fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e'):key -> elt' -> oee'

NoDupA (eqk (elt:=oee')) (mapi f1 m) -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi f2 m') (mapi f1 m))
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
f1:=fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m'):key -> elt -> oee'
f2:=fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e'):key -> elt' -> oee'

NoDupA (eqk (elt:=oee')) (mapi f2 m') -> NoDupA (eqk (elt:=oee')) (mapi f1 m) -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi f2 m') (mapi f1 m))
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
f1:=fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m'):key -> elt -> oee'
f2:=fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e'):key -> elt' -> oee'
l:t oee'

NoDupA (eqk (elt:=oee')) (mapi f2 m') -> NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) (mapi f2 m') l)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
f1:=fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m'):key -> elt -> oee'
f2:=fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e'):key -> elt' -> oee'
l, r:t oee'

NoDupA (eqk (elt:=oee')) r -> NoDupA (eqk (elt:=oee')) l -> NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r l)
auto. Qed. Definition at_least_left (o:option elt)(o':option elt') := match o with | None => None | _ => Some (o,o') end. Definition at_least_right (o:option elt)(o':option elt') := match o' with | None => None | _ => Some (o,o') end.
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:find (elt:=elt) x m = Some e

find (elt:=oee') x (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m) = at_least_left (Some e) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left None (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:find (elt:=elt) x m = Some e

find (elt:=oee') x (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m) = Some (Some e, find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left None (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:find (elt:=elt) x m = Some e

NoDupA (eqk (elt:=oee')) (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:find (elt:=elt) x m = Some e
MapsTo x (Some e, find (elt:=elt') x m') (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left None (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:find (elt:=elt) x m = Some e

MapsTo x (Some e, find (elt:=elt') x m') (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left None (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:find (elt:=elt) x m = Some e
y:X.t
H0:X.eq y x
H1:MapsTo x (Some e, find (elt:=elt') y m') (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m)

MapsTo x (Some e, find (elt:=elt') x m') (mapi (fun (k : key) (e0 : elt) => (Some e0, find (elt:=elt') k m')) m)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left None (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None

find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = at_least_left None (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None

find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = Some p

Some p = None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = Some p

In x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = Some p
x0:elt
H1:MapsTo x x0 m
Some p = None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt) x m = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e : elt) => (Some e, find (elt:=elt') k m')) m) = Some p
x0:elt
H1:MapsTo x x0 m

Some p = None
rewrite (find_1 Hm H1) in H; discriminate. Qed.
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:find (elt:=elt') x m' = Some e

find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) (Some e)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:find (elt:=elt') x m' = Some e

find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = Some (find (elt:=elt) x m, Some e)
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:find (elt:=elt') x m' = Some e

NoDupA (eqk (elt:=oee')) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:find (elt:=elt') x m' = Some e
MapsTo x (find (elt:=elt) x m, Some e) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:find (elt:=elt') x m' = Some e

MapsTo x (find (elt:=elt) x m, Some e) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:find (elt:=elt') x m' = Some e
y:X.t
H0:X.eq y x
H1:MapsTo x (find (elt:=elt) y m, Some e) (mapi (fun (k : key) (e0 : elt') => (find (elt:=elt) k m, Some e0)) m')

MapsTo x (find (elt:=elt) x m, Some e) (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None

find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = at_least_right (find (elt:=elt) x m) None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None

find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = Some p

Some p = None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = Some p

In x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = Some p
x0:elt'
H1:MapsTo x x0 m'
Some p = None
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=elt') x m' = None
p:oee'
H0:find (elt:=oee') x (mapi (fun (k : key) (e' : elt') => (find (elt:=elt) k m, Some e')) m') = Some p
x0:elt'
H1:MapsTo x x0 m'

Some p = None
rewrite (find_1 Hm' H1) in H; discriminate. Qed. Definition at_least_one (o:option elt)(o':option elt') := match o, o' with | None, None => None | _, _ => Some (o,o') end.
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (combine m m') = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (combine m m') = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

NoDupA (eqk (elt:=oee')) (combine_l m m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:NoDupA (eqk (elt:=oee')) (combine_l m m')
find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:NoDupA (eqk (elt:=oee')) (combine_l m m')

find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:NoDupA (eqk (elt:=oee')) (combine_l m m')

NoDupA (eqk (elt:=oee')) (combine_r m m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:NoDupA (eqk (elt:=oee')) (combine_l m m')
H0:NoDupA (eqk (elt:=oee')) (combine_r m m')
find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:NoDupA (eqk (elt:=oee')) (combine_l m m')
H0:NoDupA (eqk (elt:=oee')) (combine_r m m')

find (elt:=oee') x (combine_l m m') = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') (combine_l m m')) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
l:t oee'
H:NoDupA (eqk (elt:=oee')) l
H0:NoDupA (eqk (elt:=oee')) (combine_r m m')

find (elt:=oee') x l = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (combine_r m m') = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) (combine_r m m') l) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
l:t oee'
H:NoDupA (eqk (elt:=oee')) l
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r

find (elt:=oee') x l = at_least_left (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x r = at_least_right (find (elt:=elt) x m) (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
l:t oee'
H:NoDupA (eqk (elt:=oee')) l
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt

find (elt:=oee') x l = at_least_left o (find (elt:=elt') x m') -> find (elt:=oee') x r = at_least_right o (find (elt:=elt') x m') -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o (find (elt:=elt') x m')
elt, elt', elt'':Type
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
l:t oee'
H:NoDupA (eqk (elt:=oee')) l
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'

find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
elt, elt', elt'':Type
x:key
l:t oee'
H:NoDupA (eqk (elt:=oee')) l
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'

find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
elt, elt', elt'':Type
x:key
H:NoDupA (eqk (elt:=oee')) nil
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'

find (elt:=oee') x nil = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r nil) = at_least_one o o'
elt, elt', elt'':Type
x:key
a:(X.t * oee')%type
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) (a :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
find (elt:=oee') x (a :: l) = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r (a :: l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
a:(X.t * oee')%type
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) (a :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'

find (elt:=oee') x (a :: l) = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r (a :: l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
H1:(if X.eq_dec x t0 then Some p else find (elt:=oee') x l) = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
e:X.eq x t0
H1:Some p = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
e:X.eq x t0
H1:Some p = match o with | Some _ => Some (o, o') | None => None end
H2:find (elt:=oee') x r = at_least_right o o'

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
e0:elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = Some (Some e0, o') -> find (elt:=oee') x r = at_least_right (Some e0) o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = Some (Some e0, o')
e:X.eq x t0
H1:Some p = Some (Some e0, o')
H2:find (elt:=oee') x r = at_least_right (Some e0) o'

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = Some (Some e0, o')
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
l:list (X.t * oee')
e0:elt
o':option elt'
H:NoDupA (eqk (elt:=oee')) ((t0, (Some e0, o')) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = Some (Some e0, o') -> find (elt:=oee') x r = at_least_right (Some e0) o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = Some (Some e0, o')
e:X.eq x t0
H1:Some (Some e0, o') = Some (Some e0, o')
H2:find (elt:=oee') x r = at_least_right (Some e0) o'

find (elt:=oee') x (add t0 (Some e0, o') (fold_right_pair (add (elt:=oee')) r l)) = Some (Some e0, o')
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
l:list (X.t * oee')
e0:elt
o':option elt'
H:NoDupA (eqk (elt:=oee')) ((t0, (Some e0, o')) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = Some (Some e0, o') -> find (elt:=oee') x r = at_least_right (Some e0) o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = Some (Some e0, o')
e:X.eq x t0
H1:Some (Some e0, o') = Some (Some e0, o')
H2:find (elt:=oee') x r = at_least_right (Some e0) o'

NoDupA (eqk (elt:=oee')) (fold_right_pair (add (elt:=oee')) r l)
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
H:NoDupA (eqk (elt:=oee')) ((t0, p) :: l)
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
H3:~ InA (eqk (elt:=oee')) (t0, p) l
H4:NoDupA (eqk (elt:=oee')) l

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = at_least_one o o'
elt, elt', elt'':Type
x:key
t0:X.t
p:oee'
l:list (X.t * oee')
r:t oee'
H0:NoDupA (eqk (elt:=oee')) r
o:option elt
o':option elt'
IHl:NoDupA (eqk (elt:=oee')) l -> find (elt:=oee') x l = at_least_left o o' -> find (elt:=oee') x r = at_least_right o o' -> find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l) = at_least_one o o'
n:~ X.eq x t0
H1:find (elt:=oee') x l = at_least_left o o'
H2:find (elt:=oee') x r = at_least_right o o'
H3:~ InA (eqk (elt:=oee')) (t0, p) l
H4:NoDupA (eqk (elt:=oee')) l

find (elt:=oee') x (add t0 p (fold_right_pair (add (elt:=oee')) r l)) = find (elt:=oee') x (fold_right_pair (add (elt:=oee')) r l)
apply add_not_eq; auto. Qed. Variable f : option elt -> option elt' -> option elt''. Definition option_cons (A:Type)(k:key)(o:option A)(l:list (key*A)) := match o with | Some e => (k,e)::l | None => l end. Definition map2 m m' := let m0 : t oee' := combine m m' in let m1 : t (option elt'') := map (fun p => f (fst p) (snd p)) m0 in fold_right_pair (option_cons (A:=elt'')) nil m1.
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> NoDupA (eqk (elt:=elt'')) (map2 m m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> NoDupA (eqk (elt:=elt'')) (map2 m m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'

NoDupA (eqk (elt:=elt'')) (map2 m m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) (combine m m')))
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
H0:NoDupA (eqk (elt:=oee')) (combine m m')

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) (combine m m')))
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
l0:t oee'
H0:NoDupA (eqk (elt:=oee')) l0

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) l0))
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
l0:t oee'
H0:NoDupA (eqk (elt:=oee')) l0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' l0))
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
l0:t oee'
H0:NoDupA (eqk (elt:=oee')) l0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
H1:NoDupA (eqk (elt:=option elt'')) (map f' l0)

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' l0))
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
l0:t oee'
H0:NoDupA (eqk (elt:=oee')) l0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
l1:t (option elt'')
H1:NoDupA (eqk (elt:=option elt'')) l1

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
elt, elt', elt'':Type
l1:t (option elt'')
H1:NoDupA (eqk (elt:=option elt'')) l1

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
elt, elt', elt'':Type
H1:NoDupA (eqk (elt:=option elt'')) nil

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil nil)
elt, elt', elt'':Type
a:(X.t * option elt'')%type
l1:list (X.t * option elt'')
H1:NoDupA (eqk (elt:=option elt'')) (a :: l1)
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (a :: l1))
elt, elt', elt'':Type
a:(X.t * option elt'')%type
l1:list (X.t * option elt'')
H1:NoDupA (eqk (elt:=option elt'')) (a :: l1)
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (a :: l1))
elt, elt', elt'':Type
a:(X.t * option elt'')%type
l1:list (X.t * option elt'')
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
H:~ InA (eqk (elt:=option elt'')) a l1
H0:NoDupA (eqk (elt:=option elt'')) l1

NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil (a :: l1))
elt, elt', elt'':Type
t0:X.t
e:elt''
l1:list (X.t * option elt'')
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
H:~ InA (eqk (elt:=option elt'')) (t0, Some e) l1
H0:NoDupA (eqk (elt:=option elt'')) l1

NoDupA (eqk (elt:=elt'')) ((t0, e) :: fold_right_pair (option_cons (A:=elt'')) nil l1)
elt, elt', elt'':Type
t0:X.t
e:elt''
l1:list (X.t * option elt'')
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
H:~ InA (eqk (elt:=option elt'')) (t0, Some e) l1
H0:NoDupA (eqk (elt:=option elt'')) l1

~ InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1)
elt, elt', elt'':Type
t0:X.t
e:elt''
l1:list (X.t * option elt'')
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> NoDupA (eqk (elt:=elt'')) (fold_right_pair (option_cons (A:=elt'')) nil l1)
H0:NoDupA (eqk (elt:=option elt'')) l1
H:InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1)

InA (eqk (elt:=option elt'')) (t0, Some e) l1
elt, elt', elt'':Type
t0:X.t
e:elt''
l1:list (X.t * option elt'')
H0:NoDupA (eqk (elt:=option elt'')) l1
H:InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1)

InA (eqk (elt:=option elt'')) (t0, Some e) l1
elt, elt', elt'':Type
t0:X.t
e:elt''
H0:NoDupA (eqk (elt:=option elt'')) nil
H:InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil nil)

InA (eqk (elt:=option elt'')) (t0, Some e) nil
elt, elt', elt'':Type
t0:X.t
e:elt''
a:(X.t * option elt'')%type
l1:list (X.t * option elt'')
H0:NoDupA (eqk (elt:=option elt'')) (a :: l1)
H:InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil (a :: l1))
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1) -> InA (eqk (elt:=option elt'')) (t0, Some e) l1
InA (eqk (elt:=option elt'')) (t0, Some e) (a :: l1)
elt, elt', elt'':Type
t0:X.t
e:elt''
a:(X.t * option elt'')%type
l1:list (X.t * option elt'')
H0:NoDupA (eqk (elt:=option elt'')) (a :: l1)
H:InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil (a :: l1))
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1) -> InA (eqk (elt:=option elt'')) (t0, Some e) l1

InA (eqk (elt:=option elt'')) (t0, Some e) (a :: l1)
elt, elt', elt'':Type
t0:X.t
e:elt''
a:(X.t * option elt'')%type
l1:list (X.t * option elt'')
H:InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil (a :: l1))
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1) -> InA (eqk (elt:=option elt'')) (t0, Some e) l1
H1:~ InA (eqk (elt:=option elt'')) a l1
H2:NoDupA (eqk (elt:=option elt'')) l1

InA (eqk (elt:=option elt'')) (t0, Some e) (a :: l1)
elt, elt', elt'':Type
t0:X.t
e:elt''
t1:X.t
e0:elt''
l1:list (X.t * option elt'')
H:InA (eqk (elt:=elt'')) (t0, e) ((t1, e0) :: fold_right_pair (option_cons (A:=elt'')) nil l1)
IHl1:NoDupA (eqk (elt:=option elt'')) l1 -> InA (eqk (elt:=elt'')) (t0, e) (fold_right_pair (option_cons (A:=elt'')) nil l1) -> InA (eqk (elt:=option elt'')) (t0, Some e) l1
H1:~ InA (eqk (elt:=option elt'')) (t1, Some e0) l1
H2:NoDupA (eqk (elt:=option elt'')) l1

InA (eqk (elt:=option elt'')) (t0, Some e) ((t1, Some e0) :: l1)
inversion_clear H; auto. Qed. Definition at_least_one_then_f (o:option elt)(o':option elt') := match o, o' with | None, None => None | _, _ => f o o' end.
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=elt'') x (map2 m m') = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, find (elt:=elt'') x (map2 m m') = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=elt'') x (map2 m m') = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) (combine m m'))) = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=oee') x (combine m m') = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) (combine m m'))) = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=oee') x (combine m m') = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
H2:NoDupA (eqk (elt:=oee')) (combine m m')

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) (combine m m'))) = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:find (elt:=oee') x (combine m m') = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
H2:NoDupA (eqk (elt:=oee')) (combine m m')
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' (combine m m'))) = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
m0:t oee'
H:find (elt:=oee') x m0 = at_least_one (find (elt:=elt) x m) (find (elt:=elt') x m')
H2:NoDupA (eqk (elt:=oee')) m0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
m0:t oee'
o:option elt
H:find (elt:=oee') x m0 = at_least_one o (find (elt:=elt') x m')
H2:NoDupA (eqk (elt:=oee')) m0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
m0:t oee'
o:option elt
o':option elt'
H:find (elt:=oee') x m0 = at_least_one o o'
H2:NoDupA (eqk (elt:=oee')) m0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
m0:t oee'
o:option elt
o':option elt'
H:find (elt:=oee') x m0 = at_least_one o o'
H2:NoDupA (eqk (elt:=oee')) m0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
m0:t oee'
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) m0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
m0:t oee'
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) m0
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''

(find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) nil
X:option elt''
H:None = at_least_one o o'

None = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = at_least_one o o'
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = at_least_one o o'

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) ((k, (oo, oo')) :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(if X.eq_dec x k then Some (oo, oo') else find (elt:=oee') x m0) = at_least_one o o'

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(if X.eq_dec x k then Some (oo, oo') else find (elt:=oee') x m0) = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
(* x = k *)
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

at_least_one_then_f o o' = f oo oo'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = f oo oo'
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = f oo oo'

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = f oo oo'

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = f oo oo'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = f oo oo'

find (elt:=elt'') x (option_cons k (f oo oo') (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0))) = f oo oo'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
e0:elt''
H2:at_least_one_then_f o o' = Some e0

(if X.eq_dec x k then Some e0 else find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0))) = Some e0
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None
H4:find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None

find (elt:=oee') x m0 = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p0 : oee' => f (fst p0) (snd p0):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None
H4:find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None
p:oee'
H3:find (elt:=oee') x m0 = Some p

Some p = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p0 : oee' => f (fst p0) (snd p0):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None
H4:find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None
p:oee'
H3:find (elt:=oee') x m0 = Some p

InA (eqk (elt:=oee')) (k, (oo, oo')) m0
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p0 : oee' => f (fst p0) (snd p0):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None
H4:find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None
p:oee'
H3:find (elt:=oee') x m0 = Some p

InA (eqk (elt:=oee')) (x, p) m0
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p0 : oee' => f (fst p0) (snd p0):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
H2:at_least_one_then_f o o' = None
H4:find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None
p:oee'
H3:find (elt:=oee') x m0 = Some p

InA (eqke (elt:=oee')) (x, p) m0
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
(* k < x *)
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f oo oo') (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
e:elt''

(if X.eq_dec x k then Some e else find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0))) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
e:elt''
n:~ X.eq x k

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = at_least_one o o'
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = at_least_one_then_f o o'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
a:(X.t * oee')%type
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) (a :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(let (k', x0) := a in if X.eq_dec x k' then Some x0 else find (elt:=oee') x m0) = None

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (let (k, e) := a in (k, f' e) :: map f' m0)) = None
(* None -> None *)
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) ((k, (oo, oo')) :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(if X.eq_dec x k then Some (oo, oo') else find (elt:=oee') x m0) = None

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil ((k, f' (oo, oo')) :: map f' m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
H2:NoDupA (eqk (elt:=oee')) ((k, (oo, oo')) :: m0)
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(if X.eq_dec x k then Some (oo, oo') else find (elt:=oee') x m0) = None

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
H:(if X.eq_dec x k then Some (oo, oo') else find (elt:=oee') x m0) = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
e:X.eq x k
H:Some (oo, oo') = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = None
(* x = k *)
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f' (oo, oo')) (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0))) = None
(* k < x *)
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (option_cons k (f oo oo') (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0))) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
e:elt''

(if X.eq_dec x k then Some e else find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0))) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
e:elt''
n:~ X.eq x k

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0
find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = None
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
x:key
k:X.t
oo:option elt
oo':option elt'
m0:list (X.t * oee')
o:option elt
o':option elt'
f':=fun p : oee' => f (fst p) (snd p):oee' -> option elt''
IHm0:NoDupA (eqk (elt:=oee')) m0 -> (find (elt:=oee') x m0 = at_least_one o o' -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = at_least_one_then_f o o') /\ (find (elt:=oee') x m0 = None -> find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map f' m0)) = None)
Hneq:~ X.eq x k
H:find (elt:=oee') x m0 = None
H0:~ InA (eqk (elt:=oee')) (k, (oo, oo')) m0
H1:NoDupA (eqk (elt:=oee')) m0

find (elt:=elt'') x (fold_right_pair (option_cons (A:=elt'')) nil (map (fun p : oee' => f (fst p) (snd p)) m0)) = None
destruct (IHm0 H1) as (_,H4); apply H4; auto. Qed.
Specification of map2
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, In x m \/ In x m' -> find (elt:=elt'') x (map2 m m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, In x m \/ In x m' -> find (elt:=elt'') x (map2 m m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:In x m \/ In x m'

find (elt:=elt'') x (map2 m m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:In x m \/ In x m'

at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:MapsTo x e m

at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:MapsTo x e m'
at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt
H:MapsTo x e m

at_least_one_then_f (Some e) (find (elt:=elt') x m') = f (Some e) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:MapsTo x e m'
at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:MapsTo x e m'

at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt'
H:MapsTo x e m'

at_least_one_then_f (find (elt:=elt) x m) (Some e) = f (find (elt:=elt) x m) (Some e)
destruct (find x m); simpl; auto. Qed.
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, In x (map2 m m') -> In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''

forall m : list (X.t * elt), NoDupA (eqk (elt:=elt)) m -> forall m' : list (X.t * elt'), NoDupA (eqk (elt:=elt')) m' -> forall x : key, In x (map2 m m') -> In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
H:In x (map2 m m')

In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')

In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')

find (elt:=elt'') x (map2 m m') = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') -> In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')

Some e = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') -> In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')

(forall e0 : elt, find (elt:=elt) x m = Some e0 -> MapsTo x e0 m) -> Some e = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') -> In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')

(forall e0 : elt', find (elt:=elt') x m' = Some e0 -> MapsTo x e0 m') -> (forall e0 : elt, find (elt:=elt) x m = Some e0 -> MapsTo x e0 m) -> Some e = at_least_one_then_f (find (elt:=elt) x m) (find (elt:=elt') x m') -> In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
e0:elt
e1:elt'
H0:forall e2 : elt', Some e1 = Some e2 -> MapsTo x e2 m'
H1:forall e2 : elt, Some e0 = Some e2 -> MapsTo x e2 m
H2:Some e = f (Some e0) (Some e1)

In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
e0:elt
H0:forall e1 : elt', None = Some e1 -> MapsTo x e1 m'
H1:forall e1 : elt, Some e0 = Some e1 -> MapsTo x e1 m
H2:Some e = f (Some e0) None
In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
e0:elt'
H0:forall e1 : elt', Some e0 = Some e1 -> MapsTo x e1 m'
H1:forall e1 : elt, None = Some e1 -> MapsTo x e1 m
H2:Some e = f None (Some e0)
In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
H0:forall e0 : elt', None = Some e0 -> MapsTo x e0 m'
H1:forall e0 : elt, None = Some e0 -> MapsTo x e0 m
H2:Some e = None
In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
e0:elt
H0:forall e1 : elt', None = Some e1 -> MapsTo x e1 m'
H1:forall e1 : elt, Some e0 = Some e1 -> MapsTo x e1 m
H2:Some e = f (Some e0) None

In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
e0:elt'
H0:forall e1 : elt', Some e0 = Some e1 -> MapsTo x e1 m'
H1:forall e1 : elt, None = Some e1 -> MapsTo x e1 m
H2:Some e = f None (Some e0)
In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
H0:forall e0 : elt', None = Some e0 -> MapsTo x e0 m'
H1:forall e0 : elt, None = Some e0 -> MapsTo x e0 m
H2:Some e = None
In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
e0:elt'
H0:forall e1 : elt', Some e0 = Some e1 -> MapsTo x e1 m'
H1:forall e1 : elt, None = Some e1 -> MapsTo x e1 m
H2:Some e = f None (Some e0)

In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
H0:forall e0 : elt', None = Some e0 -> MapsTo x e0 m'
H1:forall e0 : elt, None = Some e0 -> MapsTo x e0 m
H2:Some e = None
In x m \/ In x m'
elt, elt', elt'':Type
f:option elt -> option elt' -> option elt''
m:list (X.t * elt)
Hm:NoDupA (eqk (elt:=elt)) m
m':list (X.t * elt')
Hm':NoDupA (eqk (elt:=elt')) m'
x:key
e:elt''
H:MapsTo x e (map2 m m')
H0:forall e0 : elt', None = Some e0 -> MapsTo x e0 m'
H1:forall e0 : elt, None = Some e0 -> MapsTo x e0 m
H2:Some e = None

In x m \/ In x m'
discriminate. Qed. End Elt3. End Raw. Module Make (X: DecidableType) <: WS with Module E:=X. Module Raw := Raw X. Module E := X. Definition key := E.t. Record slist (elt:Type) := {this :> Raw.t elt; NoDup : NoDupA (@Raw.PX.eqk elt) this}. Definition t (elt:Type) := slist elt. Section Elt. Variable elt elt' elt'':Type. Implicit Types m : t elt. Implicit Types x y : key. Implicit Types e : elt. Definition empty : t elt := Build_slist (Raw.empty_NoDup elt). Definition is_empty m : bool := Raw.is_empty (this m). Definition add x e m : t elt := Build_slist (Raw.add_NoDup (NoDup m) x e). Definition find x m : option elt := Raw.find x (this m). Definition remove x m : t elt := Build_slist (Raw.remove_NoDup (NoDup m) x). Definition mem x m : bool := Raw.mem x (this m). Definition map f m : t elt' := Build_slist (Raw.map_NoDup (NoDup m) f). Definition mapi (f:key->elt->elt') m : t elt' := Build_slist (Raw.mapi_NoDup (NoDup m) f). Definition map2 f m (m':t elt') : t elt'' := Build_slist (Raw.map2_NoDup f (NoDup m) (NoDup m')). Definition elements m : list (key*elt) := @Raw.elements elt (this m). Definition cardinal m := length (this m). Definition fold (A:Type)(f:key->elt->A->A) m (i:A) : A := @Raw.fold elt A f (this m) i. Definition equal cmp m m' : bool := @Raw.equal elt cmp (this m) (this m'). Definition MapsTo x e m : Prop := Raw.PX.MapsTo x e (this m). Definition In x m : Prop := Raw.PX.In x (this m). Definition Empty m : Prop := Raw.Empty (this m). Definition Equal m m' := forall y, find y m = find y m'. Definition Equiv (eq_elt:elt->elt->Prop) m m' := (forall k, In k m <-> In k m') /\ (forall k e e', MapsTo k e m -> MapsTo k e' m' -> eq_elt e e'). Definition Equivb cmp m m' : Prop := @Raw.Equivb elt cmp (this m) (this m'). Definition eq_key : (key*elt) -> (key*elt) -> Prop := @Raw.PX.eqk elt. Definition eq_key_elt : (key*elt) -> (key*elt) -> Prop:= @Raw.PX.eqke elt.
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
intros m; exact (@Raw.PX.MapsTo_eq elt (this m)). 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
intros m; exact (@Raw.mem_1 elt (this m) (NoDup m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x : key), mem x m = true -> In x m
intros m; exact (@Raw.mem_2 elt (this m) (NoDup m)). Qed.
elt, elt', elt'':Type

Empty empty
elt, elt', elt'':Type

Empty empty
exact (@Raw.empty_1 elt). 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
intros m; exact (@Raw.is_empty_1 elt (this m)). Qed.
elt, elt', elt'':Type

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

forall m : t elt, is_empty m = true -> Empty m
intros m; exact (@Raw.is_empty_2 elt (this m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x y : key) (e : elt), E.eq x y -> MapsTo y e (add x e m)
intros m; exact (@Raw.add_1 elt (this m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x y : key) (e e' : elt), ~ E.eq x y -> MapsTo y e m -> MapsTo y e (add x e' m)
intros m; exact (@Raw.add_2 elt (this m)). 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
intros m; exact (@Raw.add_3 elt (this m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x y : key), E.eq x y -> ~ In y (remove x m)
intros m; exact (@Raw.remove_1 elt (this m) (NoDup m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x y : key) (e : elt), ~ E.eq x y -> MapsTo y e m -> MapsTo y e (remove x m)
intros m; exact (@Raw.remove_2 elt (this m) (NoDup m)). Qed.
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), MapsTo y e (remove x m) -> MapsTo y e m
elt, elt', elt'':Type

forall (m : t elt) (x y : key) (e : elt), MapsTo y e (remove x m) -> MapsTo y e m
intros m; exact (@Raw.remove_3 elt (this m) (NoDup m)). 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
intros m; exact (@Raw.find_1 elt (this m) (NoDup m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x : key) (e : elt), find x m = Some e -> MapsTo x e m
intros m; exact (@Raw.find_2 elt (this m)). Qed.
elt, elt', elt'':Type

forall (m : t elt) (x : key) (e : elt), MapsTo x e m -> InA eq_key_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 (x, e) (elements m)
intros m; exact (@Raw.elements_1 elt (this m)). Qed.
elt, elt', elt'':Type

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

forall (m : t elt) (x : key) (e : elt), InA eq_key_elt (x, e) (elements m) -> MapsTo x e m
intros m; exact (@Raw.elements_2 elt (this m)). Qed.
elt, elt', elt'':Type

forall m : t elt, NoDupA eq_key (elements m)
elt, elt', elt'':Type

forall m : t elt, NoDupA eq_key (elements m)
intros m; exact (@Raw.elements_3w elt (this m) (NoDup m)). Qed.
elt, elt', elt'':Type

forall m : t elt, cardinal m = length (elements m)
elt, elt', elt'':Type

forall m : t elt, cardinal m = length (elements m)
intros; reflexivity. Qed.
elt, elt', elt'':Type

forall (m : t elt) (A : Type) (i : A) (f : key -> elt -> A -> A), fold f m i = fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i
elt, elt', elt'':Type

forall (m : t elt) (A : Type) (i : A) (f : key -> elt -> A -> A), fold f m i = fold_left (fun (a : A) (p : key * elt) => f (fst p) (snd p) a) (elements m) i
intros m; exact (@Raw.fold_1 elt (this m)). 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
intros m m'; exact (@Raw.equal_1 elt (this m) (NoDup m) (this m') (NoDup m')). Qed.
elt, elt', elt'':Type

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

forall (m m' : t elt) (cmp : elt -> elt -> bool), equal cmp m m' = true -> Equivb cmp m m'
intros m m'; exact (@Raw.equal_2 elt (this m) (NoDup m) (this m') (NoDup m')). Qed. End Elt.

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

forall (elt elt' : Type) (m : t elt) (x : key) (e : elt) (f : elt -> elt'), MapsTo x e m -> MapsTo x (f e) (map f m)
intros elt elt' m; exact (@Raw.map_1 elt elt' (this m)). Qed.

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

forall (elt elt' : Type) (m : t elt) (x : key) (f : elt -> elt'), In (elt:=elt') x (map f m) -> In (elt:=elt) x m
intros elt elt' m; exact (@Raw.map_2 elt elt' (this m)). Qed.

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

forall (elt elt' : Type) (m : t elt) (x : key) (e : elt) (f : key -> elt -> elt'), MapsTo x e m -> exists y : E.t, E.eq y x /\ MapsTo x (f y e) (mapi f m)
intros elt elt' m; exact (@Raw.mapi_1 elt elt' (this m)). Qed.

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

forall (elt elt' : Type) (m : t elt) (x : key) (f : key -> elt -> elt'), In (elt:=elt') x (mapi f m) -> In (elt:=elt) x m
intros elt elt' m; exact (@Raw.mapi_2 elt elt' (this m)). Qed.

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

forall (elt elt' elt'' : Type) (m : t elt) (m' : t elt') (x : key) (f : option elt -> option elt' -> option elt''), In (elt:=elt) x m \/ In (elt:=elt') x m' -> find (elt:=elt'') x (map2 f m m') = f (find (elt:=elt) x m) (find (elt:=elt') x m')
intros elt elt' elt'' m m' x f; exact (@Raw.map2_1 elt elt' elt'' f (this m) (NoDup m) (this m') (NoDup m') x). Qed.

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

forall (elt elt' elt'' : Type) (m : t elt) (m' : t elt') (x : key) (f : option elt -> option elt' -> option elt''), In (elt:=elt'') x (map2 f m m') -> In (elt:=elt) x m \/ In (elt:=elt') x m'
intros elt elt' elt'' m m' x f; exact (@Raw.map2_2 elt elt' elt'' f (this m) (NoDup m) (this m') (NoDup m') x). Qed. End Make.