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

FMapPositive : an implementation of FMapInterface for positive keys.

Require Import Bool OrderedType ZArith OrderedType OrderedTypeEx FMapInterface.

Set Implicit Arguments.
Local Open Scope positive_scope.
Local Unset Elimination Schemes.
This file is an adaptation to the FMap framework of a work by Xavier Leroy and Sandrine Blazy (used for building certified compilers). Keys are of type positive, and maps are binary trees: the sequence of binary digits of a positive number corresponds to a path in such a tree. This is quite similar to the IntMap library, except that no path compression is implemented, and that the current file is simple enough to be self-contained.
First, some stuff about positive
Fixpoint append (i j : positive) : positive :=
    match i with
      | xH => j
      | xI ii => xI (append ii j)
      | xO ii => xO (append ii j)
    end.


forall i j : positive, append i j~0 = append (append i 2) j

forall i j : positive, append i j~0 = append (append i 2) j
induction i; intros; destruct j; simpl; try rewrite (IHi (xI j)); try rewrite (IHi (xO j)); try rewrite <- (IHi xH); auto. Qed.

forall i j : positive, append i j~1 = append (append i 3) j

forall i j : positive, append i j~1 = append (append i 3) j
induction i; intros; destruct j; simpl; try rewrite (IHi (xI j)); try rewrite (IHi (xO j)); try rewrite <- (IHi xH); auto. Qed.

forall i : positive, append i 1 = i

forall i : positive, append i 1 = i
induction i; simpl; congruence. Qed.

forall i : positive, append 1 i = i

forall i : positive, append 1 i = i
simpl; auto. Qed.
The module of maps over positive keys
Module PositiveMap <: S with Module E:=PositiveOrderedTypeBits.

  Module E:=PositiveOrderedTypeBits.
  Module ME:=KeyOrderedType E.

  Definition key := positive : Type. 

  #[universes(template)]
  Inductive tree (A : Type) :=
    | Leaf : tree A
    | Node : tree A -> option A -> tree A -> tree A.

  Scheme tree_ind := Induction for tree Sort Prop.

  Definition t := tree.

  Section A.
  Variable A:Type.

  Arguments Leaf {A}.

  Definition empty : t A := Leaf.

  Fixpoint is_empty (m : t A) : bool :=
   match m with
    | Leaf => true
    | Node l None r => (is_empty l) && (is_empty r)
    | _ => false
   end.

  Fixpoint find (i : key) (m : t A) : option A :=
    match m with
    | Leaf => None
    | Node l o r =>
        match i with
        | xH => o
        | xO ii => find ii l
        | xI ii => find ii r
        end
    end.

  Fixpoint mem (i : key) (m : t A) : bool :=
    match m with
    | Leaf => false
    | Node l o r =>
        match i with
        | xH => match o with None => false | _ => true end
        | xO ii => mem ii l
        | xI ii => mem ii r
        end
    end.

  Fixpoint add (i : key) (v : A) (m : t A) : t A :=
    match m with
    | Leaf =>
        match i with
        | xH => Node Leaf (Some v) Leaf
        | xO ii => Node (add ii v Leaf) None Leaf
        | xI ii => Node Leaf None (add ii v Leaf)
        end
    | Node l o r =>
        match i with
        | xH => Node l (Some v) r
        | xO ii => Node (add ii v l) o r
        | xI ii => Node l o (add ii v r)
        end
    end.

  Fixpoint remove (i : key) (m : t A) : t A :=
    match i with
    | xH =>
        match m with
        | Leaf => Leaf
        | Node Leaf o Leaf => Leaf
        | Node l o r => Node l None r
        end
    | xO ii =>
        match m with
        | Leaf => Leaf
        | Node l None Leaf =>
            match remove ii l with
            | Leaf => Leaf
            | mm => Node mm None Leaf
            end
        | Node l o r => Node (remove ii l) o r
        end
    | xI ii =>
        match m with
        | Leaf => Leaf
        | Node Leaf None r =>
            match remove ii r with
            | Leaf => Leaf
            | mm => Node Leaf None mm
            end
        | Node l o r => Node l o (remove ii r)
        end
    end.
elements
    Fixpoint xelements (m : t A) (i : key) : list (key * A) :=
      match m with
      | Leaf => nil
      | Node l None r =>
          (xelements l (append i (xO xH))) ++ (xelements r (append i (xI xH)))
      | Node l (Some x) r =>
          (xelements l (append i (xO xH)))
          ++ ((i, x) :: xelements r (append i (xI xH)))
      end.

  (* Note: function [xelements] above is inefficient.  We should apply
     deforestation to it, but that makes the proofs even harder. *)

  Definition elements (m : t A) := xelements m xH.
cardinal
  Fixpoint cardinal (m : t A) : nat :=
    match m with
      | Leaf => 0%nat
      | Node l None r => (cardinal l + cardinal r)%nat
      | Node l (Some _) r => S (cardinal l + cardinal r)
    end.

  Section CompcertSpec.

  
A:Type

forall i : key, find i empty = None
A:Type

forall i : key, find i empty = None
destruct i; simpl; auto. Qed.
A:Type

forall (i : key) (x : A) (m : t A), find i (add i x m) = Some x
A:Type

forall (i : key) (x : A) (m : t A), find i (add i x m) = Some x
induction i; destruct m; simpl; auto. Qed.
A:Type

forall i : key, find i (Leaf : t A) = None
A:Type

forall i : key, find i (Leaf : t A) = None
exact gempty. Qed.
A:Type

forall (i j : key) (x : A) (m : t A), i <> j -> find i (add j x m) = find i m
A:Type

forall (i j : key) (x : A) (m : t A), i <> j -> find i (add j x m) = find i m
induction i; intros; destruct j; destruct m; simpl; try rewrite <- (gleaf i); auto; try apply IHi; congruence. Qed.
A:Type

forall i : key, remove i Leaf = Leaf
A:Type

forall i : key, remove i Leaf = Leaf
destruct i; simpl; auto. Qed.
A:Type

forall (i : key) (m : t A), find i (remove i m) = None
A:Type

forall (i : key) (m : t A), find i (remove i m) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None

find i~1 (remove i~1 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~1 (remove i~1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A

find i~1 (remove i~1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None

match match remove i Leaf with | Leaf => Leaf | Node t0 o t1 => Node Leaf None (Node t0 o t1) end with | Leaf => None | Node _ _ r => find i r end = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A
match match remove i (Node ll oo rr) with | Leaf => Leaf | Node t0 o t1 => Node Leaf None (Node t0 o t1) end with | Leaf => None | Node _ _ r => find i r end = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A

match match remove i (Node ll oo rr) with | Leaf => Leaf | Node t0 o t1 => Node Leaf None (Node t0 o t1) end with | Leaf => None | Node _ _ r => find i r end = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A

find i (remove i (Node ll oo rr)) = None -> match match remove i (Node ll oo rr) with | Leaf => Leaf | Node t0 o t1 => Node Leaf None (Node t0 o t1) end with | Leaf => None | Node _ _ r => find i r end = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A
find i (remove i (Node ll oo rr)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A

find i (remove i (Node ll oo rr)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None

find i~0 (remove i~0 Leaf) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A
find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
m1:tree A
o:option A
m2:tree A

find i~0 (remove i~0 (Node m1 o m2)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None

match match remove i Leaf with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A
match match remove i (Node ll oo rr) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A

match match remove i (Node ll oo rr) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A

find i (remove i (Node ll oo rr)) = None -> match match remove i (Node ll oo rr) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A
find i (remove i (Node ll oo rr)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
i:positive
IHi:forall m : t A, find i (remove i m) = None
ll:tree A
oo:option A
rr:tree A

find i (remove i (Node ll oo rr)) = None
A:Type
find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type

find 1 (remove 1 Leaf) = None
A:Type
m1:tree A
o:option A
m2:tree A
find 1 (remove 1 (Node m1 o m2)) = None
A:Type
m1:tree A
o:option A
m2:tree A

find 1 (remove 1 (Node m1 o m2)) = None
destruct m1; destruct m2; simpl; auto. Qed.
A:Type

forall (i j : key) (m : t A), i <> j -> find i (remove j m) = find i m
A:Type

forall (i j : key) (m : t A), i <> j -> find i (remove j m) = find i m
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:i~1 <> j~1

match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node _ _ r => find i r end = find i (Node m2_1 o m2_2)
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:i~1 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ _ r => find i r end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:i~0 <> j~1
match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:i~0 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = find i (Node m1_1 o0 m1_2)
A:Type
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:1 <> j~1
match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node _ o0 _ => o0 end = None
A:Type
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:1 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ o _ => o end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:i~1 <> j~0

match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ _ r => find i r end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:i~0 <> j~1
match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:i~0 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = find i (Node m1_1 o0 m1_2)
A:Type
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:1 <> j~1
match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node _ o0 _ => o0 end = None
A:Type
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:1 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ o _ => o end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:i~0 <> j~1

match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node l _ _ => find i l end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:i~0 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = find i (Node m1_1 o0 m1_2)
A:Type
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:1 <> j~1
match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node _ o0 _ => o0 end = None
A:Type
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:1 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ o _ => o end = None
A:Type
i:positive
IHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i m
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:i~0 <> j~0

match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node l _ _ => find i l end = find i (Node m1_1 o0 m1_2)
A:Type
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:1 <> j~1
match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node _ o0 _ => o0 end = None
A:Type
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:1 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ o _ => o end = None
A:Type
j:positive
m2_1:tree A
o:option A
m2_2:tree A
H:1 <> j~1

match match remove j (Node m2_1 o m2_2) with | Leaf => Leaf | Node t0 o0 t1 => Node Leaf None (Node t0 o0 t1) end with | Leaf => None | Node _ o0 _ => o0 end = None
A:Type
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:1 <> j~0
match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ o _ => o end = None
A:Type
j:positive
m1_1:tree A
o0:option A
m1_2:tree A
H:1 <> j~0

match match remove j (Node m1_1 o0 m1_2) with | Leaf => Leaf | Node t0 o t1 => Node (Node t0 o t1) None Leaf end with | Leaf => None | Node _ o _ => o end = None
destruct (remove j (Node m1_1 o0 m1_2)); simpl; try rewrite (gleaf i); auto. Qed.
A:Type

forall (m : t A) (i j : key) (v : A), find i m = Some v -> In (append j i, v) (xelements m j)
A:Type

forall (m : t A) (i j : key) (v : A), find i m = Some v -> In (append j i, v) (xelements m j)
A:Type
i, j:key
v:A
H:find i Leaf = Some v

In (append j i, v) (xelements Leaf j)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i, j:key
v:A
H:find i (Node m1 o m2) = Some v
In (append j i, v) (xelements (Node m1 o m2) j)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i, j:key
v:A
H:find i (Node m1 o m2) = Some v

In (append j i, v) (xelements (Node m1 o m2) j)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m2 = Some v

In (append j i~1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v
In (append j i~0, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:Some a = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m2 = Some v
In (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v
In (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:None = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v

In (append j i~0, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:Some a = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m2 = Some v
In (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v
In (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:None = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:Some a = Some v

In (append j 1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m2 = Some v
In (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v
In (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:None = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m2 = Some v

In (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v
In (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:None = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), find i0 m1 = Some v0 -> In (append j0 i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), find i0 m2 = Some v0 -> In (append j0 i0, v0) (xelements m2 j0)
i:positive
j:key
v:A
H:find i m1 = Some v

In (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:None = Some v
In (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i j0 : key) (v0 : A), find i m1 = Some v0 -> In (append j0 i, v0) (xelements m1 j0)
IHm2:forall (i j0 : key) (v0 : A), find i m2 = Some v0 -> In (append j0 i, v0) (xelements m2 j0)
j:key
v:A
H:None = Some v

In (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))
congruence. Qed.
A:Type

forall (m : t A) (i : key) (v : A), find i m = Some v -> In (i, v) (elements m)
A:Type

forall (m : t A) (i : key) (v : A), find i m = Some v -> In (i, v) (elements m)
A:Type
m:t A
i:key
v:A
H:find i m = Some v

In (i, v) (elements m)
exact (xelements_correct m i xH H). Qed. Fixpoint xfind (i j : key) (m : t A) : option A := match i, j with | _, xH => find i m | xO ii, xO jj => xfind ii jj m | xI ii, xI jj => xfind ii jj m | _, _ => None end.
A:Type

forall (j i : key) (m1 m2 : t A) (o : option A) (v : A), xfind i (append j 2) m1 = Some v -> xfind i j (Node m1 o m2) = Some v
A:Type

forall (j i : key) (m1 m2 : t A) (o : option A) (v : A), xfind i (append j 2) m1 = Some v -> xfind i j (Node m1 o m2) = Some v
A:Type
i:positive
m1, m2:t A
o:option A
v:A
H:xfind i 1 m1 = Some v

find i m1 = Some v
destruct i; simpl in *; auto. Qed.
A:Type

forall (m : t A) (i j : key) (v : A), In (i~1, v) (xelements m j~1) -> In (i, v) (xelements m j)
A:Type

forall (m : t A) (i j : key) (v : A), In (i~1, v) (xelements m j~1) -> In (i, v) (xelements m j)
A:Type

forall (i j : key) (v : A), In (i~1, v) (xelements Leaf j~1) -> In (i, v) (xelements Leaf j)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), In (i~1, v) (xelements m1 j~1) -> In (i, v) (xelements m1 j)
IHm2:forall (i j : key) (v : A), In (i~1, v) (xelements m2 j~1) -> In (i, v) (xelements m2 j)
forall (i j : key) (v : A), In (i~1, v) (xelements (Node m1 o m2) j~1) -> In (i, v) (xelements (Node m1 o m2) j)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), In (i~1, v) (xelements m1 j~1) -> In (i, v) (xelements m1 j)
IHm2:forall (i j : key) (v : A), In (i~1, v) (xelements m2 j~1) -> In (i, v) (xelements m2 j)

forall (i j : key) (v : A), In (i~1, v) (xelements (Node m1 o m2) j~1) -> In (i, v) (xelements (Node m1 o m2) j)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m1 (append j 2)~1)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~1, v) ((j~1, a) :: xelements m2 (append j 3)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m1 (append j 2)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m2 (append j 3)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~1, v) ((j~1, a) :: xelements m2 (append j 3)~1)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m1 (append j 2)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m2 (append j 3)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~1, v) ((j~1, a) :: xelements m2 (append j 3)~1)
H1:(j~1, a) = (i~1, v)

In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~1, v) ((j~1, a) :: xelements m2 (append j 3)~1)
H1:In (i~1, v) (xelements m2 (append j 3)~1)
In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m1 (append j 2)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m2 (append j 3)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~1, v) ((j~1, a) :: xelements m2 (append j 3)~1)
H1:In (i~1, v) (xelements m2 (append j 3)~1)

In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m1 (append j 2)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m2 (append j 3)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m1 (append j 2)~1)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m2 (append j 3)~1)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m1 j0~1) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~1, v0) (xelements m2 j0~1) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~1, v) (xelements m2 (append j 3)~1)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
right; apply IHm2; auto. Qed.
A:Type

forall (m : t A) (i j : key) (v : A), ~ In (i~1, v) (xelements m j~0)
A:Type

forall (m : t A) (i j : key) (v : A), ~ In (i~1, v) (xelements m j~0)
A:Type

forall (i j : key) (v : A), ~ In (i~1, v) (xelements Leaf j~0)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), ~ In (i~1, v) (xelements m1 j~0)
IHm2:forall (i j : key) (v : A), ~ In (i~1, v) (xelements m2 j~0)
forall (i j : key) (v : A), ~ In (i~1, v) (xelements (Node m1 o m2) j~0)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), ~ In (i~1, v) (xelements m1 j~0)
IHm2:forall (i j : key) (v : A), ~ In (i~1, v) (xelements m2 j~0)

forall (i j : key) (v : A), ~ In (i~1, v) (xelements (Node m1 o m2) j~0)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m1 (append j 2)~0)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~1, v) ((j~0, a) :: xelements m2 (append j 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m1 (append j 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m2 (append j 3)~0)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~1, v) ((j~0, a) :: xelements m2 (append j 3)~0)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m1 (append j 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m2 (append j 3)~0)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~1, v) ((j~0, a) :: xelements m2 (append j 3)~0)
H1:(j~0, a) = (i~1, v)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~1, v) ((j~0, a) :: xelements m2 (append j 3)~0)
H1:In (i~1, v) (xelements m2 (append j 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m1 (append j 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m2 (append j 3)~0)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~1, v) ((j~0, a) :: xelements m2 (append j 3)~0)
H1:In (i~1, v) (xelements m2 (append j 3)~0)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m1 (append j 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m2 (append j 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m1 (append j 2)~0)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m2 (append j 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m1 j0~0)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~1, v0) (xelements m2 j0~0)
i, j:key
v:A
H:In (i~1, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~1, v) (xelements m2 (append j 3)~0)

False
apply (IHm2 _ _ _ H0). Qed.
A:Type

forall (m : t A) (i j : key) (v : A), In (i~0, v) (xelements m j~0) -> In (i, v) (xelements m j)
A:Type

forall (m : t A) (i j : key) (v : A), In (i~0, v) (xelements m j~0) -> In (i, v) (xelements m j)
A:Type

forall (i j : key) (v : A), In (i~0, v) (xelements Leaf j~0) -> In (i, v) (xelements Leaf j)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), In (i~0, v) (xelements m1 j~0) -> In (i, v) (xelements m1 j)
IHm2:forall (i j : key) (v : A), In (i~0, v) (xelements m2 j~0) -> In (i, v) (xelements m2 j)
forall (i j : key) (v : A), In (i~0, v) (xelements (Node m1 o m2) j~0) -> In (i, v) (xelements (Node m1 o m2) j)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), In (i~0, v) (xelements m1 j~0) -> In (i, v) (xelements m1 j)
IHm2:forall (i j : key) (v : A), In (i~0, v) (xelements m2 j~0) -> In (i, v) (xelements m2 j)

forall (i j : key) (v : A), In (i~0, v) (xelements (Node m1 o m2) j~0) -> In (i, v) (xelements (Node m1 o m2) j)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m1 (append j 2)~0)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~0, v) ((j~0, a) :: xelements m2 (append j 3)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m1 (append j 2)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m2 (append j 3)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~0, v) ((j~0, a) :: xelements m2 (append j 3)~0)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m1 (append j 2)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m2 (append j 3)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~0, v) ((j~0, a) :: xelements m2 (append j 3)~0)
H1:(j~0, a) = (i~0, v)

In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~0, v) ((j~0, a) :: xelements m2 (append j 3)~0)
H1:In (i~0, v) (xelements m2 (append j 3)~0)
In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m1 (append j 2)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m2 (append j 3)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ (j~0, a) :: xelements m2 (append j 3)~0)
H0:In (i~0, v) ((j~0, a) :: xelements m2 (append j 3)~0)
H1:In (i~0, v) (xelements m2 (append j 3)~0)

In (i, v) ((j, a) :: xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m1 (append j 2)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m2 (append j 3)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m1 (append j 2)~0)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m2 (append j 3)~0)
In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m1 j0~0) -> In (i0, v0) (xelements m1 j0)
IHm2:forall (i0 j0 : key) (v0 : A), In (i0~0, v0) (xelements m2 j0~0) -> In (i0, v0) (xelements m2 j0)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~0 ++ xelements m2 (append j 3)~0)
H0:In (i~0, v) (xelements m2 (append j 3)~0)

In (i, v) (xelements m1 (append j 2)) \/ In (i, v) (xelements m2 (append j 3))
right; apply IHm2; auto. Qed.
A:Type

forall (m : t A) (i j : key) (v : A), ~ In (i~0, v) (xelements m j~1)
A:Type

forall (m : t A) (i j : key) (v : A), ~ In (i~0, v) (xelements m j~1)
A:Type

forall (i j : key) (v : A), ~ In (i~0, v) (xelements Leaf j~1)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), ~ In (i~0, v) (xelements m1 j~1)
IHm2:forall (i j : key) (v : A), ~ In (i~0, v) (xelements m2 j~1)
forall (i j : key) (v : A), ~ In (i~0, v) (xelements (Node m1 o m2) j~1)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i j : key) (v : A), ~ In (i~0, v) (xelements m1 j~1)
IHm2:forall (i j : key) (v : A), ~ In (i~0, v) (xelements m2 j~1)

forall (i j : key) (v : A), ~ In (i~0, v) (xelements (Node m1 o m2) j~1)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m1 (append j 2)~1)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~0, v) ((j~1, a) :: xelements m2 (append j 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m1 (append j 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m2 (append j 3)~1)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~0, v) ((j~1, a) :: xelements m2 (append j 3)~1)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m1 (append j 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m2 (append j 3)~1)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~0, v) ((j~1, a) :: xelements m2 (append j 3)~1)
H1:(j~1, a) = (i~0, v)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~0, v) ((j~1, a) :: xelements m2 (append j 3)~1)
H1:In (i~0, v) (xelements m2 (append j 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m1 (append j 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m2 (append j 3)~1)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ (j~1, a) :: xelements m2 (append j 3)~1)
H0:In (i~0, v) ((j~1, a) :: xelements m2 (append j 3)~1)
H1:In (i~0, v) (xelements m2 (append j 3)~1)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m1 (append j 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m2 (append j 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m1 (append j 2)~1)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m2 (append j 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m1 j0~1)
IHm2:forall (i0 j0 : key) (v0 : A), ~ In (i0~0, v0) (xelements m2 j0~1)
i, j:key
v:A
H:In (i~0, v) (xelements m1 (append j 2)~1 ++ xelements m2 (append j 3)~1)
H0:In (i~0, v) (xelements m2 (append j 3)~1)

False
apply (IHm2 _ _ _ H0). Qed.
A:Type

forall (m1 m2 : t A) (o : option A) (i : key) (v : A), In (i~1, v) (xelements (Node m1 o m2) 1) -> In (i, v) (xelements m2 1)
A:Type

forall (m1 m2 : t A) (o : option A) (i : key) (v : A), In (i~1, v) (xelements (Node m1 o m2) 1) -> In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~1, v) (xelements m1 2)

In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~1, v) ((1, a) :: xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m1 2)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~1, v) ((1, a) :: xelements m2 3)

In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m1 2)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~1, v) ((1, a) :: xelements m2 3)
H1:(1, a) = (i~1, v)

In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~1, v) ((1, a) :: xelements m2 3)
H1:In (i~1, v) (xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m1 2)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~1, v) ((1, a) :: xelements m2 3)
H1:In (i~1, v) (xelements m2 3)

In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m1 2)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m1 2)

In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m2 3)
In (i, v) (xelements m2 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~1, v) (xelements m2 3)

In (i, v) (xelements m2 1)
apply xelements_ii; auto. Qed.
A:Type

forall (m1 m2 : t A) (o : option A) (i : key) (v : A), In (i~0, v) (xelements (Node m1 o m2) 1) -> In (i, v) (xelements m1 1)
A:Type

forall (m1 m2 : t A) (o : option A) (i : key) (v : A), In (i~0, v) (xelements (Node m1 o m2) 1) -> In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~0, v) (xelements m1 2)

In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~0, v) ((1, a) :: xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m1 2)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~0, v) ((1, a) :: xelements m2 3)

In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m1 2)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~0, v) ((1, a) :: xelements m2 3)
H1:(1, a) = (i~0, v)

In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~0, v) ((1, a) :: xelements m2 3)
H1:In (i~0, v) (xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m1 2)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
a:A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (i~0, v) ((1, a) :: xelements m2 3)
H1:In (i~0, v) (xelements m2 3)

In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m1 2)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m1 2)

In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m2 3)
In (i, v) (xelements m1 1)
A:Type
m1, m2:t A
i:key
v:A
H:In (i~0, v) (xelements m1 2 ++ xelements m2 3)
H0:In (i~0, v) (xelements m2 3)

In (i, v) (xelements m1 1)
absurd (List.In (xO i, v) (xelements m2 3)); auto; apply xelements_oi; auto. Qed.
A:Type

forall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~1)
A:Type

forall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~1)
A:Type
i:key
v:A

~ In (1, v) (xelements Leaf i~1)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
~ In (1, v) (xelements (Node m1 o m2) i~1)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A

~ In (1, v) (xelements (Node m1 o m2) i~1)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ (i~1, a) :: xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m1 (append i 2)~1)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ (i~1, a) :: xelements m2 (append i 3)~1)
H0:In (1, v) ((i~1, a) :: xelements m2 (append i 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m1 (append i 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m2 (append i 3)~1)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ (i~1, a) :: xelements m2 (append i 3)~1)
H0:In (1, v) ((i~1, a) :: xelements m2 (append i 3)~1)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m1 (append i 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m2 (append i 3)~1)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ (i~1, a) :: xelements m2 (append i 3)~1)
H0:In (1, v) ((i~1, a) :: xelements m2 (append i 3)~1)
H1:(i~1, a) = (1, v)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ (i~1, a) :: xelements m2 (append i 3)~1)
H0:In (1, v) ((i~1, a) :: xelements m2 (append i 3)~1)
H1:In (1, v) (xelements m2 (append i 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m1 (append i 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m2 (append i 3)~1)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ (i~1, a) :: xelements m2 (append i 3)~1)
H0:In (1, v) ((i~1, a) :: xelements m2 (append i 3)~1)
H1:In (1, v) (xelements m2 (append i 3)~1)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m1 (append i 2)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m2 (append i 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m1 (append i 2)~1)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m2 (append i 3)~1)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~1)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~1)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~1 ++ xelements m2 (append i 3)~1)
H0:In (1, v) (xelements m2 (append i 3)~1)

False
generalize H0; apply IHm2; auto. Qed.
A:Type

forall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~0)
A:Type

forall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~0)
A:Type
i:key
v:A

~ In (1, v) (xelements Leaf i~0)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
~ In (1, v) (xelements (Node m1 o m2) i~0)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A

~ In (1, v) (xelements (Node m1 o m2) i~0)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ (i~0, a) :: xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m1 (append i 2)~0)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ (i~0, a) :: xelements m2 (append i 3)~0)
H0:In (1, v) ((i~0, a) :: xelements m2 (append i 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m1 (append i 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m2 (append i 3)~0)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ (i~0, a) :: xelements m2 (append i 3)~0)
H0:In (1, v) ((i~0, a) :: xelements m2 (append i 3)~0)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m1 (append i 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m2 (append i 3)~0)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ (i~0, a) :: xelements m2 (append i 3)~0)
H0:In (1, v) ((i~0, a) :: xelements m2 (append i 3)~0)
H1:(i~0, a) = (1, v)

False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ (i~0, a) :: xelements m2 (append i 3)~0)
H0:In (1, v) ((i~0, a) :: xelements m2 (append i 3)~0)
H1:In (1, v) (xelements m2 (append i 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m1 (append i 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m2 (append i 3)~0)
False
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ (i~0, a) :: xelements m2 (append i 3)~0)
H0:In (1, v) ((i~0, a) :: xelements m2 (append i 3)~0)
H1:In (1, v) (xelements m2 (append i 3)~0)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m1 (append i 2)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m2 (append i 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m1 (append i 2)~0)

False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m2 (append i 3)~0)
False
A:Type
m1, m2:tree A
IHm1:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m1 i0~0)
IHm2:forall (i0 : key) (v0 : A), ~ In (1, v0) (xelements m2 i0~0)
i:key
v:A
H:In (1, v) (xelements m1 (append i 2)~0 ++ xelements m2 (append i 3)~0)
H0:In (1, v) (xelements m2 (append i 3)~0)

False
generalize H0; apply IHm2; auto. Qed.
A:Type

forall (m : t A) (i : key), find i m = xfind i 1 m
A:Type

forall (m : t A) (i : key), find i m = xfind i 1 m
destruct i; simpl; auto. Qed.
A:Type

forall (i j : key) (m : t A) (v : A), In (i, v) (xelements m j) -> xfind i j m = Some v
A:Type

forall (i j : key) (m : t A) (v : A), In (i, v) (xelements m j) -> xfind i j m = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~1, v) (xelements m j~1)

xfind i j m = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~1, v) (xelements m j~0)
None = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~1, v) (xelements m 1)
match m with | Leaf => None | Node _ _ r => find i r end = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~1, v) (xelements m j~0)

None = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~1, v) (xelements m 1)
match m with | Leaf => None | Node _ _ r => find i r end = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~1, v) (xelements m 1)

match m with | Leaf => None | Node _ _ r => find i r end = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
v:A
H:In (i~1, v) (xelements Leaf 1)

None = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~1, v) (xelements (Node m1 o m2) 1)
find i m2 = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~1, v) (xelements (Node m1 o m2) 1)

find i m2 = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~1, v) (xelements (Node m1 o m2) 1)

xfind i 1 m2 = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~1, v) (xelements (Node m1 o m2) 1)

In (i, v) (xelements m2 1)
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)
None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~1)

None = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)
xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0
j:positive
m:t A
v:A
H:In (i~0, v) (xelements m j~0)

xfind i j m = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)
match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0
m:t A
v:A
H:In (i~0, v) (xelements m 1)

match m with | Leaf => None | Node l _ _ => find i l end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
v:A
H:In (i~0, v) (xelements Leaf 1)

None = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~0, v) (xelements (Node m1 o m2) 1)
find i m1 = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~0, v) (xelements (Node m1 o m2) 1)

find i m1 = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~0, v) (xelements (Node m1 o m2) 1)

xfind i 1 m1 = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
i:positive
IHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0
m1:tree A
o:option A
m2:tree A
v:A
H:In (i~0, v) (xelements (Node m1 o m2) 1)

In (i, v) (xelements m1 1)
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)
None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~1)

None = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)
None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
j:positive
m:t A
v:A
H:In (1, v) (xelements m j~0)

None = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)
match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
m:t A
v:A
H:In (1, v) (xelements m 1)

match m with | Leaf => None | Node _ o _ => o end = Some v
A:Type
v:A
H:In (1, v) (xelements Leaf 1)

None = Some v
A:Type
m1:tree A
o:option A
m2:tree A
v:A
H:In (1, v) (xelements (Node m1 o m2) 1)
o = Some v
A:Type
m1:tree A
o:option A
m2:tree A
v:A
H:In (1, v) (xelements (Node m1 o m2) 1)

o = Some v
A:Type
m1:tree A
a:A
m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (1, v) (xelements m1 2)

Some a = Some v
A:Type
m1:tree A
a:A
m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (1, v) ((1, a) :: xelements m2 3)
Some a = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m1 2)
None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m2 3)
None = Some v
A:Type
m1:tree A
a:A
m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (1, v) ((1, a) :: xelements m2 3)

Some a = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m1 2)
None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m2 3)
None = Some v
A:Type
m1:tree A
a:A
m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (1, v) ((1, a) :: xelements m2 3)
H1:(1, a) = (1, v)

Some a = Some v
A:Type
m1:tree A
a:A
m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (1, v) ((1, a) :: xelements m2 3)
H1:In (1, v) (xelements m2 3)
Some a = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m1 2)
None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m2 3)
None = Some v
A:Type
m1:tree A
a:A
m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)
H0:In (1, v) ((1, a) :: xelements m2 3)
H1:In (1, v) (xelements m2 3)

Some a = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m1 2)
None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m2 3)
None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m1 2)

None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m2 3)
None = Some v
A:Type
m1, m2:tree A
v:A
H:In (1, v) (xelements m1 2 ++ xelements m2 3)
H0:In (1, v) (xelements m2 3)

None = Some v
absurd (List.In (xH, v) (xelements m2 (xI xH))); auto; apply xelements_hi. Qed.
A:Type

forall (m : t A) (i : key) (v : A), In (i, v) (elements m) -> find i m = Some v
A:Type

forall (m : t A) (i : key) (v : A), In (i, v) (elements m) -> find i m = Some v
A:Type
m:t A
i:key
v:A
H:In (i, v) (elements m)

find i m = Some v
A:Type
m:t A
i:key
v:A
H:In (i, v) (xelements m 1)

find i m = Some v
A:Type
m:t A
i:key
v:A
H:In (i, v) (xelements m 1)

xfind i 1 m = Some v
exact (xelements_complete i xH m v H). Qed.
A:Type

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

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

forall m : t A, cardinal m = length (xelements m 1)
A:Type

forall (m : t A) (p : positive), cardinal m = length (xelements m p)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall p0 : positive, cardinal m1 = length (xelements m1 p0)
IHm2:forall p0 : positive, cardinal m2 = length (xelements m2 p0)
p:positive

match o with | Some _ => S (cardinal m1 + cardinal m2) | None => (cardinal m1 + cardinal m2)%nat end = length match o with | Some x => xelements m1 (append p 2) ++ (p, x) :: xelements m2 (append p 3) | None => xelements m1 (append p 2) ++ xelements m2 (append p 3) end
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall p0 : positive, cardinal m1 = length (xelements m1 p0)
IHm2:forall p0 : positive, cardinal m2 = length (xelements m2 p0)
p:positive

match o with | Some _ => S (length (xelements m1 (append p 2)) + length (xelements m2 (append p 3))) | None => (length (xelements m1 (append p 2)) + length (xelements m2 (append p 3)))%nat end = length match o with | Some x => xelements m1 (append p 2) ++ (p, x) :: xelements m2 (append p 3) | None => xelements m1 (append p 2) ++ xelements m2 (append p 3) end
destruct o; rewrite app_length; simpl; omega. Qed. End CompcertSpec. Definition MapsTo (i:key)(v:A)(m:t A) := find i m = Some v. Definition In (i:key)(m:t A) := exists e:A, MapsTo i e m. Definition Empty m := forall (a : key)(e:A) , ~ MapsTo a e m. Definition eq_key (p p':key*A) := E.eq (fst p) (fst p'). Definition eq_key_elt (p p':key*A) := E.eq (fst p) (fst p') /\ (snd p) = (snd p'). Definition lt_key (p p':key*A) := E.lt (fst p) (fst p'). Instance eqk_equiv : Equivalence eq_key := _. Instance eqke_equiv : Equivalence eq_key_elt := _. Instance ltk_strorder : StrictOrder lt_key := _.
A:Type

forall (m : t A) (x : key), mem x m = match find x m with | Some _ => true | None => false end
A:Type

forall (m : t A) (x : key), mem x m = match find x m with | Some _ => true | None => false end
induction m; destruct x; simpl; auto. Qed.
A:Type

forall m : t A, Empty m <-> (forall a : key, find a m = None)
A:Type

forall m : t A, Empty m <-> (forall a : key, find a m = None)
A:Type

forall m : t A, (forall (a : key) (e : A), find a m <> Some e) <-> (forall a : key, find a m = None)
A:Type
m:t A
H:forall (a0 : key) (e : A), find a0 m = Some e -> False
a:key

find a m = None
A:Type
m:t A
H:forall a0 : key, find a0 m = None
a:key
e:A
H0:find a m = Some e
False
A:Type
m:t A
H:forall (a0 : key) (e : A), find a0 m = Some e -> False
a:key

(forall e : A, find a m = Some e -> False) -> find a m = None
A:Type
m:t A
H:forall a0 : key, find a0 m = None
a:key
e:A
H0:find a m = Some e
False
A:Type
m:t A
H:forall (a1 : key) (e : A), find a1 m = Some e -> False
a:key
a0:A
H0:forall e : A, Some a0 = Some e -> False

Some a0 = None
A:Type
m:t A
H:forall a0 : key, find a0 m = None
a:key
e:A
H0:find a m = Some e
False
A:Type
m:t A
H:forall a0 : key, find a0 m = None
a:key
e:A
H0:find a m = Some e

False
rewrite H in H0; discriminate. Qed.
A:Type

forall (l : tree A) (o : option A) (r : tree A), Empty (Node l o r) <-> o = None /\ Empty l /\ Empty r
A:Type

forall (l : tree A) (o : option A) (r : tree A), Empty (Node l o r) <-> o = None /\ Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A

Empty (Node l o r) <-> o = None /\ Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A

Empty (Node l o r) -> o = None /\ Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A

(forall a : key, find a (Node l o r) = None) -> o = None /\ Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A
H:forall a : key, find a (Node l o r) = None

o = None
A:Type
l:tree A
o:option A
r:tree A
H:forall a : key, find a (Node l o r) = None
Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
a:A
r:tree A
H:forall a0 : key, find a0 (Node l (Some a) r) = None

Some a = None
A:Type
l:tree A
o:option A
r:tree A
H:forall a : key, find a (Node l o r) = None
Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A
H:forall a : key, find a (Node l o r) = None

Empty l /\ Empty r
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A
H:forall a0 : key, find a0 (Node l o r) = None
a:key

find a l = None
A:Type
l:tree A
o:option A
r:tree A
H:forall a0 : key, find a0 (Node l o r) = None
a:key
find a r = None
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A
H:forall a0 : key, find a0 (Node l o r) = None
a:key

find a r = None
A:Type
l:tree A
o:option A
r:tree A
o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A

o = None /\ Empty l /\ Empty r -> Empty (Node l o r)
A:Type
l:tree A
o:option A
r:tree A
H:o = None
H0:Empty l
H1:Empty r

Empty (Node l o r)
A:Type
l, r:tree A
H0:Empty l
H1:Empty r

Empty (Node l None r)
A:Type
l, r:tree A
H0:Empty l
H1:Empty r
a:key

find a (Node l None r) = None
A:Type
l, r:tree A
H0:Empty l
H1:Empty r
a:positive

find a~1 (Node l None r) = None
A:Type
l, r:tree A
H0:Empty l
H1:Empty r
a:positive
find a~0 (Node l None r) = None
A:Type
l, r:tree A
H0:Empty l
H1:Empty r
a:positive

find a~0 (Node l None r) = None
simpl; generalize H0; rewrite Empty_alt; auto. Qed. Section FMapSpec.
A:Type

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

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

(exists e : A, find x m = Some e) -> match find x m with | Some _ => true | None => false end = true
destruct 1 as (e0,H0); rewrite H0; auto. Qed.
A:Type

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

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

match find x m with | Some _ => true | None => false end = true -> exists e : A, find x m = Some e
A:Type
m:t A
x:key
a:A

true = true -> exists e : A, Some a = Some e
A:Type
m:t A
x:key
false = true -> exists e : A, None = Some e
A:Type
m:t A
x:key

false = true -> exists e : A, None = Some e
intros; discriminate. Qed. Variable m m' m'' : t A. Variable x y z : key. Variable e e' : A.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

E.eq x y -> MapsTo x e m -> MapsTo y e m
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

E.eq x y -> MapsTo x e m -> MapsTo y e m
intros; rewrite <- H; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

MapsTo x e m -> find x m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

MapsTo x e m -> find x m = Some e
unfold MapsTo; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

find x m = Some e -> MapsTo x e m
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

find x m = Some e -> MapsTo x e m
red; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Empty empty
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Empty empty
rewrite Empty_alt; apply gempty. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Empty m -> is_empty m = true
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Empty m -> is_empty m = true
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:Empty t0_1 -> is_empty t0_1 = true
IHt0_2:Empty t0_2 -> is_empty t0_2 = true

Empty (Node t0_1 o t0_2) -> match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:Empty t0_1 -> is_empty t0_1 = true
IHt0_2:Empty t0_2 -> is_empty t0_2 = true

o = None /\ Empty t0_1 /\ Empty t0_2 -> match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:Empty t0_1 -> is_empty t0_1 = true
IHt0_2:Empty t0_2 -> is_empty t0_2 = true
H:o = None
H0:Empty t0_1
H1:Empty t0_2

match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:Empty t0_1 -> is_empty t0_1 = true
IHt0_2:Empty t0_2 -> is_empty t0_2 = true
H0:Empty t0_1
H1:Empty t0_2

is_empty t0_1 && is_empty t0_2 = true
rewrite IHt0_1; simpl; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

is_empty m = true -> Empty m
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

is_empty m = true -> Empty m
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

true = true -> Empty Leaf
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2
match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> Empty (Node t0_1 o t0_2)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

true = true -> forall a : key, find a Leaf = None
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2
match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> Empty (Node t0_1 o t0_2)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2

match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> Empty (Node t0_1 o t0_2)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2

match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> o = None /\ Empty t0_1 /\ Empty t0_2
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2

false = true -> Some a = None /\ Empty t0_1 /\ Empty t0_2
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2
is_empty t0_1 && is_empty t0_2 = true -> None = None /\ Empty t0_1 /\ Empty t0_2
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:is_empty t0_1 = true -> Empty t0_1
IHt0_2:is_empty t0_2 = true -> Empty t0_2

is_empty t0_1 && is_empty t0_2 = true -> None = None /\ Empty t0_1 /\ Empty t0_2
intro H; destruct (andb_prop _ _ H); intuition. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

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

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

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

find y (add y e m) = Some e
apply gss. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

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

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

~ E.eq x y -> find y m = Some e -> find y (add x e' m) = Some e
intros; rewrite gso; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

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

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

~ E.eq x y -> find y (add x e' m) = Some e -> find y m = Some e
intro H; rewrite gso; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

E.eq x y -> ~ In y (remove x m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

E.eq x y -> ~ In y (remove x m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:E.eq x y
H0:In y (remove x m)

False
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:E.eq x y
H0:In y (remove x m)

mem y (remove x m) = true -> False
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:E.eq x y
H0:In y (remove x m)

match find y (remove x m) with | Some _ => true | None => false end = true -> False
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:x = y
H0:In y (remove x m)

match find y (remove x m) with | Some _ => true | None => false end = true -> False
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:x = y
H0:In y (remove x m)

match find y (remove y m) with | Some _ => true | None => false end = true -> False
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:x = y
H0:In y (remove x m)

false = true -> False
intros; discriminate. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

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

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

~ E.eq x y -> find y m = Some e -> find y (remove x m) = Some e
intro H; rewrite gro; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

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

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

find y (remove x m) = Some e -> find y m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
e0:x = y

find y (remove x m) = Some e -> find y m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
n:x <> y
find y (remove x m) = Some e -> find y m = Some e
A:Type
m, m', m'':t A
y, z:key
e, e':A

find y (remove y m) = Some e -> find y m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
n:x <> y
find y (remove x m) = Some e -> find y m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
n:x <> y

find y (remove x m) = Some e -> find y m = Some e
rewrite gro; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

MapsTo x e m -> InA eq_key_elt (x, e) (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

MapsTo x e m -> InA eq_key_elt (x, e) (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

find x m = Some e -> InA eq_key_elt (x, e) (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

find x m = Some e -> exists y0 : key * A, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:find x m = Some e

exists y0 : key * A, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:find x m = Some e

eq_key_elt (x, e) (x, e) /\ List.In (x, e) (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:find x m = Some e

eq_key_elt (x, e) (x, e)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:find x m = Some e
List.In (x, e) (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
H:find x m = Some e

List.In (x, e) (elements m)
apply elements_correct; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

InA eq_key_elt (x, e) (elements m) -> MapsTo x e m
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

InA eq_key_elt (x, e) (elements m) -> MapsTo x e m
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

InA eq_key_elt (x, e) (elements m) -> find x m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

(exists y0 : key * A, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)) -> find x m = Some e
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
e0:key
a:A
H:eq_key_elt (x, e) (e0, a)
H0:List.In (e0, a) (elements m)

find x m = Some e
A:Type
m, m', m'':t A
y, z:key
e':A
e0:key
a:A
H0:List.In (e0, a) (elements m)

find e0 m = Some a
apply elements_complete; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall (p : positive) (p0 : key) (q : positive) (m0 : t A) (v : A), List.In (p0, v) (xelements m0 (append p q~0)) -> E.bits_lt p0 p
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall (p : positive) (p0 : key) (q : positive) (m0 : t A) (v : A), List.In (p0, v) (xelements m0 (append p q~0)) -> E.bits_lt p0 p
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
p:positive
p0:key
q:positive
m0:t A
v:A
H:List.In (p0, v) (xelements m0 (append p q~0))

E.bits_lt p0 p
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
p:positive
p0:key
q:positive
m0:t A
v:A
H:xfind p0 (append p q~0) m0 = Some v

E.bits_lt p0 p
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
p, q:positive
m0:t A
v:A

forall p0 : key, xfind p0 (append p q~0) m0 = Some v -> E.bits_lt p0 p
induction p; destruct p0; simpl; intros; eauto; try discriminate. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall (p : positive) (p0 : key) (q : positive) (m0 : t A) (v : A), List.In (p0, v) (xelements m0 (append p q~1)) -> E.bits_lt p p0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall (p : positive) (p0 : key) (q : positive) (m0 : t A) (v : A), List.In (p0, v) (xelements m0 (append p q~1)) -> E.bits_lt p p0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
p:positive
p0:key
q:positive
m0:t A
v:A
H:List.In (p0, v) (xelements m0 (append p q~1))

E.bits_lt p p0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
p:positive
p0:key
q:positive
m0:t A
v:A
H:xfind p0 (append p q~1) m0 = Some v

E.bits_lt p p0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
p, q:positive
m0:t A
v:A

forall p0 : key, xfind p0 (append p q~1) m0 = Some v -> E.bits_lt p p0
induction p; destruct p0; simpl; intros; eauto; try discriminate. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall p : key, Sorted lt_key (xelements m p)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall p : key, Sorted lt_key (xelements m p)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

forall p : key, Sorted lt_key (xelements Leaf p)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:forall p : key, Sorted lt_key (xelements t0_1 p)
IHt0_2:forall p : key, Sorted lt_key (xelements t0_2 p)
forall p : key, Sorted lt_key (xelements (Node t0_1 o t0_2) p)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
o:option A
t0_2:tree A
IHt0_1:forall p : key, Sorted lt_key (xelements t0_1 p)
IHt0_2:forall p : key, Sorted lt_key (xelements t0_2 p)

forall p : key, Sorted lt_key (xelements (Node t0_1 o t0_2) p)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key

Sorted lt_key (xelements t0_1 (append p 2) ++ (p, a) :: xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
(* Some *)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key

Sorted lt_key ((p, a) :: xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key

HdRel lt_key (p, a) (xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
y0:(key * A)%type
H:List.In y0 (xelements t0_2 (append p 3))

lt_key (p, a) y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_2 (append p 3))

lt_key (p, a) (k, a0)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_2 (append p 3))

E.bits_lt p k
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key

forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
x0, y0:(key * A)%type

InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 ((p, a) :: xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
x0, y0:(key * A)%type

(exists y1 : key * A, eq_key_elt x0 y1 /\ List.In y1 (xelements t0_1 (append p 2))) -> (exists y1 : key * A, eq_key_elt y0 y1 /\ List.In y1 ((p, a) :: xelements t0_2 (append p 3))) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
x0, y0, y1:(key * A)%type
Hy1:eq_key_elt x0 y1
H:List.In y1 (xelements t0_1 (append p 2))
y2:(key * A)%type
Hy2:eq_key_elt y0 y2
H0:List.In y2 ((p, a) :: xelements t0_2 (append p 3))

lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
y0:(key * A)%type
k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
y2:(key * A)%type
Hy2:eq_key_elt y0 y2
H0:List.In y2 ((p, a) :: xelements t0_2 (append p 3))

lt_key (k, a0) y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) ((p, a) :: xelements t0_2 (append p 3))

lt_key (k, a0) (k0, a1)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) ((p, a) :: xelements t0_2 (append p 3))

E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:(p, a) = (k0, a1)

E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) (xelements t0_2 (append p 3))
E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p : key, Sorted lt_key (xelements t0_1 p)
IHt0_2:forall p : key, Sorted lt_key (xelements t0_2 p)
k:key
a0:A
k0:key
H:List.In (k, a0) (xelements t0_1 (append k0 2))
a1:A

E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) (xelements t0_2 (append p 3))
E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) (xelements t0_2 (append p 3))

E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) (xelements t0_2 (append p 3))

E.bits_lt k p
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) (xelements t0_2 (append p 3))
E.bits_lt p k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1:tree A
a:A
t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a0:A
H:List.In (k, a0) (xelements t0_1 (append p 2))
k0:key
a1:A
H0:List.In (k0, a1) (xelements t0_2 (append p 3))

E.bits_lt p k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key

Sorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))
(* None *)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key

forall x0 y0 : key * A, InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 (xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
x0, y0:(key * A)%type

InA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 (xelements t0_2 (append p 3)) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
x0, y0:(key * A)%type

(exists y1 : key * A, eq_key_elt x0 y1 /\ List.In y1 (xelements t0_1 (append p 2))) -> (exists y1 : key * A, eq_key_elt y0 y1 /\ List.In y1 (xelements t0_2 (append p 3))) -> lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
x0, y0, y1:(key * A)%type
Hy1:eq_key_elt x0 y1
H:List.In y1 (xelements t0_1 (append p 2))
y2:(key * A)%type
Hy2:eq_key_elt y0 y2
H0:List.In y2 (xelements t0_2 (append p 3))

lt_key x0 y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p:key
y0:(key * A)%type
k:key
a:A
H:List.In (k, a) (xelements t0_1 (append p 2))
y2:(key * A)%type
Hy2:eq_key_elt y0 y2
H0:List.In y2 (xelements t0_2 (append p 3))

lt_key (k, a) y0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a:A
H:List.In (k, a) (xelements t0_1 (append p 2))
k0:key
a0:A
H0:List.In (k0, a0) (xelements t0_2 (append p 3))

lt_key (k, a) (k0, a0)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a:A
H:List.In (k, a) (xelements t0_1 (append p 2))
k0:key
a0:A
H0:List.In (k0, a0) (xelements t0_2 (append p 3))

E.bits_lt k k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a:A
H:List.In (k, a) (xelements t0_1 (append p 2))
k0:key
a0:A
H0:List.In (k0, a0) (xelements t0_2 (append p 3))

E.bits_lt k p
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a:A
H:List.In (k, a) (xelements t0_1 (append p 2))
k0:key
a0:A
H0:List.In (k0, a0) (xelements t0_2 (append p 3))
E.bits_lt p k0
A:Type
m, m', m'':t A
x, y, z:key
e, e':A
t0_1, t0_2:tree A
IHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)
IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)
p, k:key
a:A
H:List.In (k, a) (xelements t0_1 (append p 2))
k0:key
a0:A
H0:List.In (k0, a0) (xelements t0_2 (append p 3))

E.bits_lt p k0
eapply xelements_bits_lt_2; eauto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Sorted lt_key (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Sorted lt_key (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Sorted lt_key (xelements m 1)
apply xelements_sort; auto. Qed.
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

NoDupA eq_key (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

NoDupA eq_key (elements m)
A:Type
m, m', m'':t A
x, y, z:key
e, e':A

Sorted (ME.ltk (elt:=A)) (elements m)
apply elements_3. Qed. End FMapSpec.
map and mapi
  Variable B : Type.

  Section Mapi.

    Variable f : key -> A -> B.

    Fixpoint xmapi (m : t A) (i : key) : t B :=
       match m with
        | Leaf => @Leaf B
        | Node l o r => Node (xmapi l (append i (xO xH)))
                             (option_map (f i) o)
                             (xmapi r (append i (xI xH)))
       end.

    Definition mapi m := xmapi m xH.

  End Mapi.

  Definition map (f : A -> B) m := mapi (fun _ => f) m.

  End A.

  

forall (A B : Type) (f : key -> A -> B) (i j : key) (m : t A), find i (xmapi f m j) = option_map (f (append j i)) (find i m)

forall (A B : Type) (f : key -> A -> B) (i j : key) (m : t A), find i (xmapi f m j) = option_map (f (append j i)) (find i m)
A, B:Type
f:key -> A -> B
i:positive
IHi:forall (j0 : key) (m : t A), find i (xmapi f m j0) = option_map (f (append j0 i)) (find i m)
j:key
m1:tree A
o:option A
m2:tree A

find i (xmapi f m2 (append j 3)) = option_map (f (append j i~1)) (find i m2)
A, B:Type
f:key -> A -> B
i:positive
IHi:forall (j0 : key) (m : t A), find i (xmapi f m j0) = option_map (f (append j0 i)) (find i m)
j:key
m1:tree A
o:option A
m2:tree A
find i (xmapi f m1 (append j 2)) = option_map (f (append j i~0)) (find i m1)
A, B:Type
f:key -> A -> B
j:key
m1:tree A
o:option A
m2:tree A
option_map (f j) o = option_map (f (append j 1)) o
A, B:Type
f:key -> A -> B
i:positive
IHi:forall (j0 : key) (m : t A), find i (xmapi f m j0) = option_map (f (append j0 i)) (find i m)
j:key
m1:tree A
o:option A
m2:tree A

find i (xmapi f m1 (append j 2)) = option_map (f (append j i~0)) (find i m1)
A, B:Type
f:key -> A -> B
j:key
m1:tree A
o:option A
m2:tree A
option_map (f j) o = option_map (f (append j 1)) o
A, B:Type
f:key -> A -> B
j:key
m1:tree A
o:option A
m2:tree A

option_map (f j) o = option_map (f (append j 1)) o
rewrite (append_neutral_r j); auto. Qed.

forall (A B : Type) (f : key -> A -> B) (i : key) (m : t A), find i (mapi f m) = option_map (f i) (find i m)

forall (A B : Type) (f : key -> A -> B) (i : key) (m : t A), find i (mapi f m) = option_map (f i) (find i m)
A, B:Type
f:key -> A -> B
i:key
m:t A

find i (mapi f m) = option_map (f i) (find i m)
A, B:Type
f:key -> A -> B
i:key
m:t A

find i (xmapi f m 1) = option_map (f i) (find i m)
A, B:Type
f:key -> A -> B
i:key
m:t A

find i (xmapi f m 1) = option_map (f (append 1 i)) (find i m)
A, B:Type
f:key -> A -> B
i:key
m:t A
f (append 1 i) = f i
A, B:Type
f:key -> A -> B
i:key
m:t A

f (append 1 i) = f i
rewrite append_neutral_l; auto. Qed.

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

exists y : positive, E.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'
H:MapsTo x e m

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

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

find x (mapi f m) = Some (f x e)
elt, elt':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'
H:find x m = Some e

find x (mapi f m) = Some (f x e)
elt, elt':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'
H:find x m = Some e

option_map (f x) (find x m) = Some (f x e)
elt, elt':Type
m:t elt
x:key
e:elt
f:key -> elt -> elt'
H:find x m = Some e

option_map (f x) (Some e) = Some (f x e)
simpl; auto. Qed.

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

forall (elt elt' : Type) (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'
H:In x (mapi f m)

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

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

match find x m with | Some _ => true | None => false end = true
elt, elt':Type
m:t elt
x:key
f:key -> elt -> elt'
v:elt'
H:MapsTo x v (mapi f m)

match find x m with | Some _ => true | None => false end = true
elt, elt':Type
m:t elt
x:key
f:key -> elt -> elt'
v:elt'
H:find x (mapi f m) = Some v

match find x m with | Some _ => true | None => false end = true
elt, elt':Type
m:t elt
x:key
f:key -> elt -> elt'
v:elt'
H:option_map (f x) (find x m) = Some v

match find x m with | Some _ => true | None => false end = true
elt, elt':Type
m:t elt
x:key
f:key -> elt -> elt'
v:elt'
H:option_map (f x) None = Some v

false = true
simpl in *; discriminate. Qed.

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

MapsTo x (f e) (mapi (fun _ : key => f) m)
destruct (mapi_1 (fun _ => f) H); intuition. Qed.

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

forall (elt elt' : Type) (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) -> In x m
intros; unfold map in *; eapply mapi_2; eauto. Qed. Section map2. Variable A B C : Type. Variable f : option A -> option B -> option C. Arguments Leaf {A}. Fixpoint xmap2_l (m : t A) : t C := match m with | Leaf => Leaf | Node l o r => Node (xmap2_l l) (f o None) (xmap2_l r) end.
A, B, C:Type
f:option A -> option B -> option C

forall (i : key) (m : t A), f None None = None -> find i (xmap2_l m) = f (find i m) None
A, B, C:Type
f:option A -> option B -> option C

forall (i : key) (m : t A), f None None = None -> find i (xmap2_l m) = f (find i m) None
induction i; intros; destruct m; simpl; auto. Qed. Fixpoint xmap2_r (m : t B) : t C := match m with | Leaf => Leaf | Node l o r => Node (xmap2_r l) (f None o) (xmap2_r r) end.
A, B, C:Type
f:option A -> option B -> option C

forall (i : key) (m : t B), f None None = None -> find i (xmap2_r m) = f None (find i m)
A, B, C:Type
f:option A -> option B -> option C

forall (i : key) (m : t B), f None None = None -> find i (xmap2_r m) = f None (find i m)
induction i; intros; destruct m; simpl; auto. Qed. Fixpoint _map2 (m1 : t A)(m2 : t B) : t C := match m1 with | Leaf => xmap2_r m2 | Node l1 o1 r1 => match m2 with | Leaf => xmap2_l m1 | Node l2 o2 r2 => Node (_map2 l1 l2) (f o1 o2) (_map2 r1 r2) end end.
A, B, C:Type
f:option A -> option B -> option C

forall (i : key) (m1 : t A) (m2 : t B), f None None = None -> find i (_map2 m1 m2) = f (find i m1) (find i m2)
A, B, C:Type
f:option A -> option B -> option C

forall (i : key) (m1 : t A) (m2 : t B), f None None = None -> find i (_map2 m1 m2) = f (find i m1) (find i m2)
induction i; intros; destruct m1; destruct m2; simpl; auto; try apply xgmap2_r; try apply xgmap2_l; auto. Qed. End map2. Definition map2 (elt elt' elt'':Type)(f:option elt->option elt'->option elt'') := _map2 (fun o1 o2 => match o1,o2 with None,None => None | _, _ => f o1 o2 end).

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

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

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

find x (_map2 (fun (o1 : option elt) (o2 : option elt') => match o1 with | Some _ => f o1 o2 | None => match o2 with | Some _ => f o1 o2 | None => None end end) m m') = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:In x m \/ In x m'

match find x m with | Some _ => f (find x m) (find x m') | None => match find x m' with | Some _ => f (find x m) (find x m') | None => None end end = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:In x m \/ In x m'

(In x m -> mem x m = true) -> (In x m' -> mem x m' = true) -> match find x m with | Some _ => f (find x m) (find x m') | None => match find x m' with | Some _ => f (find x m) (find x m') | None => None end end = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:In x m \/ In x m'

(In x m -> match find x m with | Some _ => true | None => false end = true) -> (In x m' -> match find x m' with | Some _ => true | None => false end = true) -> match find x m with | Some _ => f (find x m) (find x m') | None => match find x m' with | Some _ => f (find x m) (find x m') | None => None end end = f (find x m) (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:In x m \/ In x m'

(In x m -> false = true) -> (In x m' -> match find x m' with | Some _ => true | None => false end = true) -> match find x m' with | Some _ => f None (find x m') | None => None end = f None (find x m')
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:In x m \/ In x m'

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

None = f None None
destruct H; intuition; try discriminate. Qed.

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

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

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

In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:match find x (map2 f m m') with | Some _ => true | None => false end = true

In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:match find x (_map2 (fun (o1 : option elt) (o2 : option elt') => match o1 with | Some _ => f o1 o2 | None => match o2 with | Some _ => f o1 o2 | None => None end end) m m') with | Some _ => true | None => false end = true

In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:match match find x m with | Some _ => f (find x m) (find x m') | None => match find x m' with | Some _ => f (find x m) (find x m') | None => None end end with | Some _ => true | None => false end = true

In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:match match find x m with | Some _ => f (find x m) (find x m') | None => match find x m' with | Some _ => f (find x m) (find x m') | None => None end end with | Some _ => true | None => false end = true

(mem x m = true -> In x m) -> (mem x m' = true -> In x m') -> In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:match match find x m with | Some _ => f (find x m) (find x m') | None => match find x m' with | Some _ => f (find x m) (find x m') | None => None end end with | Some _ => true | None => false end = true

(match find x m with | Some _ => true | None => false end = true -> In x m) -> (match find x m' with | Some _ => true | None => false end = true -> In x m') -> In x m \/ In x m'
elt, elt', elt'':Type
m:t elt
m':t elt'
x:key
f:option elt -> option elt' -> option elt''
H:match match find x m' with | Some _ => f None (find x m') | None => None end with | Some _ => true | None => false end = true

(false = true -> In x m) -> (match find x m' with | Some _ => true | None => false end = true -> In x m') -> In x m \/ In x m'
destruct (find x m'); simpl in *; auto. Qed. Section Fold. Variables A B : Type. Variable f : key -> A -> B -> B. Fixpoint xfoldi (m : t A) (v : B) (i : key) := match m with | Leaf _ => v | Node l (Some x) r => xfoldi r (f i x (xfoldi l v (append i 2))) (append i 3) | Node l None r => xfoldi r (xfoldi l v (append i 2)) (append i 3) end.
A, B:Type
f:key -> A -> B -> B

forall (m : t A) (v : B) (i : key), xfoldi m v i = fold_left (fun (a : B) (p : key * A) => f (fst p) (snd p) a) (xelements m i) v
A, B:Type
f:key -> A -> B -> B

forall (m : t A) (v : B) (i : key), xfoldi m v i = fold_left (fun (a : B) (p : key * A) => f (fst p) (snd p) a) (xelements m i) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B

forall (m : t A) (v : B) (i : key), xfoldi m v i = fold_left F (xelements m i) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1:tree A
o:option A
m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

match o with | Some x => xfoldi m2 (f i x (xfoldi m1 v (append i 2))) (append i 3) | None => xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) end = fold_left F match o with | Some x => xelements m1 (append i 2) ++ (i, x) :: xelements m2 (append i 3) | None => xelements m1 (append i 2) ++ xelements m2 (append i 3) end v
A, B:Type
f:key -> A -> B -> B
F:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> B
m1:tree A
a:A
m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (f i a (xfoldi m1 v (append i 2))) (append i 3) = fold_left F (xelements m1 (append i 2) ++ (i, a) :: xelements m2 (append i 3)) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key
xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> B
m1:tree A
a:A
m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (f i a (xfoldi m1 v (append i 2))) (append i 3) = fold_left F (xelements m2 (append i 3)) (F (fold_left F (xelements m1 (append i 2)) v) (i, a))
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key
xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> B
m1:tree A
a:A
m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (f i a (xfoldi m1 v (append i 2))) (append i 3) = fold_left F (xelements m2 (append i 3)) (F (xfoldi m1 v (append i 2)) (i, a))
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key
xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> B
m1:tree A
a:A
m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (f i a (xfoldi m1 v (append i 2))) (append i 3) = xfoldi m2 (F (xfoldi m1 v (append i 2)) (i, a)) (append i 3)
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key
xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) v
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m2 (append i 3)) (fold_left F (xelements m1 (append i 2)) v)
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m2 (append i 3)) (xfoldi m1 v (append i 2))
A, B:Type
f:key -> A -> B -> B
F:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> B
m1, m2:tree A
IHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0
IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0
v:B
i:key

xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3)
reflexivity. Qed. Definition fold m i := xfoldi m i 1. End Fold.

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

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

xfoldi f m i 1 = fold_left (fun (a : B) (p : key * A) => f (fst p) (snd p) a) (xelements m 1) i
rewrite xfoldi_1; reflexivity. Qed. Fixpoint equal (A:Type)(cmp : A -> A -> bool)(m1 m2 : t A) : bool := match m1, m2 with | Leaf _, _ => is_empty m2 | _, Leaf _ => is_empty m1 | Node l1 o1 r1, Node l2 o2 r2 => (match o1, o2 with | None, None => true | Some v1, Some v2 => cmp v1 v2 | _, _ => false end) && equal cmp l1 l2 && equal cmp r1 r2 end. Definition Equal (A:Type)(m m':t A) := forall y, find y m = find y m'. Definition Equiv (A:Type)(eq_elt:A->A->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 (A:Type)(cmp: A->A->bool) := Equiv (Cmp cmp).

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

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

forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Leaf A) m' -> equal cmp (Leaf A) m' = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
(* m = Leaf *)
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e e' : A), MapsTo k e (Leaf A) -> MapsTo k e' m' -> Cmp cmp e e'

equal cmp (Leaf A) m' = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e e' : A), MapsTo k e (Leaf A) -> MapsTo k e' m' -> Cmp cmp e e'

is_empty m' = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e e' : A), MapsTo k e (Leaf A) -> MapsTo k e' m' -> Cmp cmp e e'

Empty m'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'

False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'

In a (Leaf A)
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'
H2:In a (Leaf A)
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'

In a m'
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'
H2:In a (Leaf A)
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'
H2:In a (Leaf A)

False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m':t A
cmp:A -> A -> bool
H:forall k : key, In k (Leaf A) <-> In k m'
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Leaf A) -> MapsTo k e' m' -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m'
x:A
H2:find a (Leaf A) = Some x

False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true

forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = true
(* m = Node *)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true

forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Leaf A) -> equal cmp (Node m1 o m2) (Leaf A) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
(* m' = Leaf *)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'

equal cmp (Node m1 o m2) (Leaf A) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'

match o with | Some _ => false | None => is_empty m1 && is_empty m2 end = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'

false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
is_empty m1 && is_empty m2 = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'

In 1 (Leaf A)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
H1:In 1 (Leaf A)
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
is_empty m1 && is_empty m2 = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'

In 1 (Node m1 (Some a) m2)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
H1:In 1 (Leaf A)
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
is_empty m1 && is_empty m2 = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
H1:In 1 (Leaf A)

false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'
is_empty m1 && is_empty m2 = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e e'

is_empty m1 && is_empty m2 = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m1

False
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m1

In a~0 (Leaf A)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m1
H2:In a~0 (Leaf A)
False
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m1

In a~0 (Node m1 None m2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m1
H2:In a~0 (Leaf A)
False
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m1
H2:In a~0 (Leaf A)

False
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2

False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2

In a~1 (Leaf A)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
H2:In a~1 (Leaf A)
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2

In a~1 (Node m1 None m2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
H2:In a~1 (Leaf A)
False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Leaf A)
H0:forall (k : key) (e0 e' : A), MapsTo k e0 (Node m1 None m2) -> MapsTo k e' (Leaf A) -> Cmp cmp e0 e'
a:key
e:A
H1:MapsTo a e m2
H2:In a~1 (Leaf A)

False
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = true
IHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = true
m'1:tree A
o0:option A
m'2:tree A

forall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2) -> equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
(* m' = Node *)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'

equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'

Equivb cmp m1 m'1
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'

forall k : key, In k m1 <-> In k m'1
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
forall (k : key) (e e' : A), MapsTo k e m1 -> MapsTo k e' m'1 -> Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'

forall (k : key) (e e' : A), MapsTo k e m1 -> MapsTo k e' m'1 -> Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1

equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1

Equivb cmp m2 m'2
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1

forall k : key, In k m2 <-> In k m'2
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
forall (k : key) (e e' : A), MapsTo k e m2 -> MapsTo k e' m'2 -> Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1

forall (k : key) (e e' : A), MapsTo k e m2 -> MapsTo k e' m'2 -> Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
o0:option A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 o m2) <-> In k (Node m'1 o0 m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 o m2) -> MapsTo k e' (Node m'1 o0 m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

match o with | Some v1 => match o0 with | Some v2 => cmp v1 v2 | None => false end | None => match o0 with | Some _ => false | None => true end end && equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Node m'1 (Some a0) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Node m'1 (Some a0) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

cmp a a0 && equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 (Some a) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 (Some a) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Node m'1 (Some a0) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Node m'1 (Some a0) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

cmp a a0 = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 (Some a) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 (Some a) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 (Some a) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 (Some a) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 (Some a) m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 (Some a) m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
H4:(exists e : A, Some a = Some e) -> exists e : A, None = Some e
H5:(exists e : A, None = Some e) -> exists e : A, Some a = Some e

false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 (Some a) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 (Some a) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 (Some a) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 (Some a) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1:tree A
a:A
m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 (Some a) m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 (Some a) m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
H4:(exists e : A, None = Some e) -> exists e : A, Some a = Some e
H5:(exists e : A, Some a = Some e) -> exists e : A, None = Some e

false = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2
equal cmp m1 m'1 && equal cmp m2 m'2 = true
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = true
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = true
m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
H0:forall (k : key) (e e' : A), MapsTo k e (Node m1 None m2) -> MapsTo k e' (Node m'1 None m'2) -> Cmp cmp e e'
H1:Equivb cmp m1 m'1
H2:Equivb cmp m2 m'2

equal cmp m1 m'1 && equal cmp m2 m'2 = true
apply andb_true_intro; split; auto. Qed.

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

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

forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Leaf A) m' = true -> Equivb cmp (Leaf A) m'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
(* m = Leaf *)
A:Type

forall (m' : t A) (cmp : A -> A -> bool), is_empty m' = true -> Equivb cmp (Leaf A) m'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key

In k (Leaf A) <-> In k m'
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key
e, e':A
H0:MapsTo k e (Leaf A)
H1:MapsTo k e' m'
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key

In k (Leaf A) -> In k m'
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key
In k m' -> In k (Leaf A)
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key
e, e':A
H0:MapsTo k e (Leaf A)
H1:MapsTo k e' m'
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key

In k m' -> In k (Leaf A)
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key
e, e':A
H0:MapsTo k e (Leaf A)
H1:MapsTo k e' m'
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
A:Type
m':t A
cmp:A -> A -> bool
H:is_empty m' = true
k:key
e, e':A
H0:MapsTo k e (Leaf A)
H1:MapsTo k e' m'

Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'

forall (m' : t A) (cmp : A -> A -> bool), equal cmp (Node m1 o m2) m' = true -> Equivb cmp (Node m1 o m2) m'
(* m = Node *)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'

forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Leaf A) = true -> Equivb cmp (Node m1 o m2) (Leaf A)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
(* m' = Leaf *)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'

forall cmp : A -> A -> bool, match o with | Some _ => false | None => is_empty m1 && is_empty m2 end = true -> Equivb cmp (Node m1 o m2) (Leaf A)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H:is_empty m1 && is_empty m2 = true

Equivb cmp (Node m1 None m2) (Leaf A)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true

Equivb cmp (Node m1 None m2) (Leaf A)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key

In k (Node m1 None m2) <-> In k (Leaf A)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
e, e':A
H:MapsTo k e (Node m1 None m2)
H2:MapsTo k e' (Leaf A)
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
x:A
H:find k (Node m1 None m2) = Some x

exists e : A, find k (Leaf A) = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
x:A
H:find k (Leaf A) = Some x
exists e : A, find k (Node m1 None m2) = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
e, e':A
H:MapsTo k e (Node m1 None m2)
H2:MapsTo k e' (Leaf A)
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:positive
x:A
H:find k m2 = Some x

exists e : A, None = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:positive
x:A
H:find k m1 = Some x
exists e : A, None = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
x:A
H:find k (Leaf A) = Some x
exists e : A, find k (Node m1 None m2) = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
e, e':A
H:MapsTo k e (Node m1 None m2)
H2:MapsTo k e' (Leaf A)
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:positive
x:A
H:find k m1 = Some x

exists e : A, None = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
x:A
H:find k (Leaf A) = Some x
exists e : A, find k (Node m1 None m2) = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
e, e':A
H:MapsTo k e (Node m1 None m2)
H2:MapsTo k e' (Leaf A)
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
x:A
H:find k (Leaf A) = Some x

exists e : A, find k (Node m1 None m2) = Some e
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
e, e':A
H:MapsTo k e (Node m1 None m2)
H2:MapsTo k e' (Leaf A)
Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
cmp:A -> A -> bool
H0:is_empty m1 = true
H1:is_empty m2 = true
k:key
e, e':A
H:MapsTo k e (Node m1 None m2)
H2:MapsTo k e' (Leaf A)

Cmp cmp e e'
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A
forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
A:Type
m1:tree A
o:option A
m2:tree A
IHm1:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m1 m' = true -> Equivb cmp m1 m'
IHm2:forall (m' : t A) (cmp : A -> A -> bool), equal cmp m2 m' = true -> Equivb cmp m2 m'
m'1:tree A
o0:option A
m'2:tree A

forall cmp : A -> A -> bool, equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = true -> Equivb cmp (Node m1 o m2) (Node m'1 o0 m'2)
(* m' = Node *)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 && equal cmp m1 m'1 && equal cmp m2 m'2 = true

Equivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H0:cmp a a0 && equal cmp m1 m'1 = true
H1:equal cmp m2 m'2 = true

Equivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H1:equal cmp m2 m'2 = true
H:cmp a a0 = true
H2:equal cmp m1 m'1 = true

Equivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2:tree A
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H1:equal cmp m2 m'2 = true
H:cmp a a0 = true
H0:forall k : key, In k m1 <-> In k m'1
H3:forall (k : key) (e e' : A), MapsTo k e m1 -> MapsTo k e' m'1 -> Cmp cmp e e'

Equivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k : key, In k m1 <-> In k m'1
H3:forall (k : key) (e e' : A), MapsTo k e m1 -> MapsTo k e' m'1 -> Cmp cmp e e'
H2:forall k : key, In k m2 <-> In k m'2
H4:forall (k : key) (e e' : A), MapsTo k e m2 -> MapsTo k e' m'2 -> Cmp cmp e e'

Equivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, In k0 m1 <-> In k0 m'1
H3:forall (k0 : key) (e e' : A), MapsTo k0 e m1 -> MapsTo k0 e' m'1 -> Cmp cmp e e'
H2:forall k0 : key, In k0 m2 <-> In k0 m'2
H4:forall (k0 : key) (e e' : A), MapsTo k0 e m2 -> MapsTo k0 e' m'2 -> Cmp cmp e e'
k:key

In k (Node m1 (Some a) m2) <-> In k (Node m'1 (Some a0) m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, In k0 m1 <-> In k0 m'1
H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0
H2:forall k0 : key, In k0 m2 <-> In k0 m'2
H4:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0
k:key
e, e':A
H1:MapsTo k e (Node m1 (Some a) m2)
H5:MapsTo k e' (Node m'1 (Some a0) m'2)
Cmp cmp e e'
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k : key, (exists e : A, find k m1 = Some e) <-> (exists e : A, find k m'1 = Some e)
H3:forall (k : key) (e e' : A), find k m1 = Some e -> find k m'1 = Some e' -> Cmp cmp e e'
H2:forall k : key, (exists e : A, find k m2 = Some e) <-> (exists e : A, find k m'2 = Some e)
H4:forall (k : key) (e e' : A), find k m2 = Some e -> find k m'2 = Some e' -> Cmp cmp e e'

(exists e : A, Some a = Some e) <-> (exists e : A, Some a0 = Some e)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, In k0 m1 <-> In k0 m'1
H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0
H2:forall k0 : key, In k0 m2 <-> In k0 m'2
H4:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0
k:key
e, e':A
H1:MapsTo k e (Node m1 (Some a) m2)
H5:MapsTo k e' (Node m'1 (Some a0) m'2)
Cmp cmp e e'
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, In k0 m1 <-> In k0 m'1
H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0
H2:forall k0 : key, In k0 m2 <-> In k0 m'2
H4:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0
k:key
e, e':A
H1:MapsTo k e (Node m1 (Some a) m2)
H5:MapsTo k e' (Node m'1 (Some a0) m'2)

Cmp cmp e e'
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, (exists e0 : A, find k0 m1 = Some e0) <-> (exists e0 : A, find k0 m'1 = Some e0)
H3:forall (k0 : key) (e0 e'0 : A), find k0 m1 = Some e0 -> find k0 m'1 = Some e'0 -> Cmp cmp e0 e'0
H2:forall k0 : key, (exists e0 : A, find k0 m2 = Some e0) <-> (exists e0 : A, find k0 m'2 = Some e0)
H4:forall (k0 : key) (e0 e'0 : A), find k0 m2 = Some e0 -> find k0 m'2 = Some e'0 -> Cmp cmp e0 e'0
k:positive
e, e':A
H1:find k m2 = Some e
H5:find k m'2 = Some e'

Cmp cmp e e'
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, (exists e0 : A, find k0 m1 = Some e0) <-> (exists e0 : A, find k0 m'1 = Some e0)
H3:forall (k0 : key) (e0 e'0 : A), find k0 m1 = Some e0 -> find k0 m'1 = Some e'0 -> Cmp cmp e0 e'0
H2:forall k0 : key, (exists e0 : A, find k0 m2 = Some e0) <-> (exists e0 : A, find k0 m'2 = Some e0)
H4:forall (k0 : key) (e0 e'0 : A), find k0 m2 = Some e0 -> find k0 m'2 = Some e'0 -> Cmp cmp e0 e'0
k:positive
e, e':A
H1:find k m1 = Some e
H5:find k m'1 = Some e'
Cmp cmp e e'
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k : key, (exists e0 : A, find k m1 = Some e0) <-> (exists e0 : A, find k m'1 = Some e0)
H3:forall (k : key) (e0 e'0 : A), find k m1 = Some e0 -> find k m'1 = Some e'0 -> Cmp cmp e0 e'0
H2:forall k : key, (exists e0 : A, find k m2 = Some e0) <-> (exists e0 : A, find k m'2 = Some e0)
H4:forall (k : key) (e0 e'0 : A), find k m2 = Some e0 -> find k m'2 = Some e'0 -> Cmp cmp e0 e'0
e, e':A
H1:Some a = Some e
H5:Some a0 = Some e'
Cmp cmp e e'
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k0 : key, (exists e0 : A, find k0 m1 = Some e0) <-> (exists e0 : A, find k0 m'1 = Some e0)
H3:forall (k0 : key) (e0 e'0 : A), find k0 m1 = Some e0 -> find k0 m'1 = Some e'0 -> Cmp cmp e0 e'0
H2:forall k0 : key, (exists e0 : A, find k0 m2 = Some e0) <-> (exists e0 : A, find k0 m'2 = Some e0)
H4:forall (k0 : key) (e0 e'0 : A), find k0 m2 = Some e0 -> find k0 m'2 = Some e'0 -> Cmp cmp e0 e'0
k:positive
e, e':A
H1:find k m1 = Some e
H5:find k m'1 = Some e'

Cmp cmp e e'
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k : key, (exists e0 : A, find k m1 = Some e0) <-> (exists e0 : A, find k m'1 = Some e0)
H3:forall (k : key) (e0 e'0 : A), find k m1 = Some e0 -> find k m'1 = Some e'0 -> Cmp cmp e0 e'0
H2:forall k : key, (exists e0 : A, find k m2 = Some e0) <-> (exists e0 : A, find k m'2 = Some e0)
H4:forall (k : key) (e0 e'0 : A), find k m2 = Some e0 -> find k m'2 = Some e'0 -> Cmp cmp e0 e'0
e, e':A
H1:Some a = Some e
H5:Some a0 = Some e'
Cmp cmp e e'
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1:tree A
a:A
m2, m'1:tree A
a0:A
m'2:tree A
cmp:A -> A -> bool
H:cmp a a0 = true
H0:forall k : key, (exists e0 : A, find k m1 = Some e0) <-> (exists e0 : A, find k m'1 = Some e0)
H3:forall (k : key) (e0 e'0 : A), find k m1 = Some e0 -> find k m'1 = Some e'0 -> Cmp cmp e0 e'0
H2:forall k : key, (exists e0 : A, find k m2 = Some e0) <-> (exists e0 : A, find k m'2 = Some e0)
H4:forall (k : key) (e0 e'0 : A), find k m2 = Some e0 -> find k m'2 = Some e'0 -> Cmp cmp e0 e'0
e, e':A
H1:Some a = Some e
H5:Some a0 = Some e'

Cmp cmp e e'
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true
Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H:equal cmp m1 m'1 && equal cmp m2 m'2 = true

Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1, m2:tree A
IHm1:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m1 m' = true -> Equivb cmp0 m1 m'
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H0:equal cmp m1 m'1 = true
H1:equal cmp m2 m'2 = true

Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1, m2:tree A
IHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'
m'1, m'2:tree A
cmp:A -> A -> bool
H1:equal cmp m2 m'2 = true
H:forall k : key, In k m1 <-> In k m'1
H2:forall (k : key) (e e' : A), MapsTo k e m1 -> MapsTo k e' m'1 -> Cmp cmp e e'

Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, In k m1 <-> In k m'1
H2:forall (k : key) (e e' : A), MapsTo k e m1 -> MapsTo k e' m'1 -> Cmp cmp e e'
H0:forall k : key, In k m2 <-> In k m'2
H3:forall (k : key) (e e' : A), MapsTo k e m2 -> MapsTo k e' m'2 -> Cmp cmp e e'

Equivb cmp (Node m1 None m2) (Node m'1 None m'2)
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, In k0 m1 <-> In k0 m'1
H2:forall (k0 : key) (e e' : A), MapsTo k0 e m1 -> MapsTo k0 e' m'1 -> Cmp cmp e e'
H0:forall k0 : key, In k0 m2 <-> In k0 m'2
H3:forall (k0 : key) (e e' : A), MapsTo k0 e m2 -> MapsTo k0 e' m'2 -> Cmp cmp e e'
k:key

In k (Node m1 None m2) <-> In k (Node m'1 None m'2)
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, In k0 m1 <-> In k0 m'1
H2:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0
H0:forall k0 : key, In k0 m2 <-> In k0 m'2
H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0
k:key
e, e':A
H1:MapsTo k e (Node m1 None m2)
H4:MapsTo k e' (Node m'1 None m'2)
Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, (exists e : A, find k m1 = Some e) <-> (exists e : A, find k m'1 = Some e)
H2:forall (k : key) (e e' : A), find k m1 = Some e -> find k m'1 = Some e' -> Cmp cmp e e'
H0:forall k : key, (exists e : A, find k m2 = Some e) <-> (exists e : A, find k m'2 = Some e)
H3:forall (k : key) (e e' : A), find k m2 = Some e -> find k m'2 = Some e' -> Cmp cmp e e'

(exists e : A, None = Some e) <-> (exists e : A, None = Some e)
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, In k0 m1 <-> In k0 m'1
H2:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0
H0:forall k0 : key, In k0 m2 <-> In k0 m'2
H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0
k:key
e, e':A
H1:MapsTo k e (Node m1 None m2)
H4:MapsTo k e' (Node m'1 None m'2)
Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, In k0 m1 <-> In k0 m'1
H2:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0
H0:forall k0 : key, In k0 m2 <-> In k0 m'2
H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0
k:key
e, e':A
H1:MapsTo k e (Node m1 None m2)
H4:MapsTo k e' (Node m'1 None m'2)

Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, (exists e0 : A, find k0 m1 = Some e0) <-> (exists e0 : A, find k0 m'1 = Some e0)
H2:forall (k0 : key) (e0 e'0 : A), find k0 m1 = Some e0 -> find k0 m'1 = Some e'0 -> Cmp cmp e0 e'0
H0:forall k0 : key, (exists e0 : A, find k0 m2 = Some e0) <-> (exists e0 : A, find k0 m'2 = Some e0)
H3:forall (k0 : key) (e0 e'0 : A), find k0 m2 = Some e0 -> find k0 m'2 = Some e'0 -> Cmp cmp e0 e'0
k:positive
e, e':A
H1:find k m2 = Some e
H4:find k m'2 = Some e'

Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, (exists e0 : A, find k0 m1 = Some e0) <-> (exists e0 : A, find k0 m'1 = Some e0)
H2:forall (k0 : key) (e0 e'0 : A), find k0 m1 = Some e0 -> find k0 m'1 = Some e'0 -> Cmp cmp e0 e'0
H0:forall k0 : key, (exists e0 : A, find k0 m2 = Some e0) <-> (exists e0 : A, find k0 m'2 = Some e0)
H3:forall (k0 : key) (e0 e'0 : A), find k0 m2 = Some e0 -> find k0 m'2 = Some e'0 -> Cmp cmp e0 e'0
k:positive
e, e':A
H1:find k m1 = Some e
H4:find k m'1 = Some e'
Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, (exists e0 : A, find k m1 = Some e0) <-> (exists e0 : A, find k m'1 = Some e0)
H2:forall (k : key) (e0 e'0 : A), find k m1 = Some e0 -> find k m'1 = Some e'0 -> Cmp cmp e0 e'0
H0:forall k : key, (exists e0 : A, find k m2 = Some e0) <-> (exists e0 : A, find k m'2 = Some e0)
H3:forall (k : key) (e0 e'0 : A), find k m2 = Some e0 -> find k m'2 = Some e'0 -> Cmp cmp e0 e'0
e, e':A
H1:None = Some e
H4:None = Some e'
Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k0 : key, (exists e0 : A, find k0 m1 = Some e0) <-> (exists e0 : A, find k0 m'1 = Some e0)
H2:forall (k0 : key) (e0 e'0 : A), find k0 m1 = Some e0 -> find k0 m'1 = Some e'0 -> Cmp cmp e0 e'0
H0:forall k0 : key, (exists e0 : A, find k0 m2 = Some e0) <-> (exists e0 : A, find k0 m'2 = Some e0)
H3:forall (k0 : key) (e0 e'0 : A), find k0 m2 = Some e0 -> find k0 m'2 = Some e'0 -> Cmp cmp e0 e'0
k:positive
e, e':A
H1:find k m1 = Some e
H4:find k m'1 = Some e'

Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, (exists e0 : A, find k m1 = Some e0) <-> (exists e0 : A, find k m'1 = Some e0)
H2:forall (k : key) (e0 e'0 : A), find k m1 = Some e0 -> find k m'1 = Some e'0 -> Cmp cmp e0 e'0
H0:forall k : key, (exists e0 : A, find k m2 = Some e0) <-> (exists e0 : A, find k m'2 = Some e0)
H3:forall (k : key) (e0 e'0 : A), find k m2 = Some e0 -> find k m'2 = Some e'0 -> Cmp cmp e0 e'0
e, e':A
H1:None = Some e
H4:None = Some e'
Cmp cmp e e'
A:Type
m1, m2, m'1, m'2:tree A
cmp:A -> A -> bool
H:forall k : key, (exists e0 : A, find k m1 = Some e0) <-> (exists e0 : A, find k m'1 = Some e0)
H2:forall (k : key) (e0 e'0 : A), find k m1 = Some e0 -> find k m'1 = Some e'0 -> Cmp cmp e0 e'0
H0:forall k : key, (exists e0 : A, find k m2 = Some e0) <-> (exists e0 : A, find k m'2 = Some e0)
H3:forall (k : key) (e0 e'0 : A), find k m2 = Some e0 -> find k m'2 = Some e'0 -> Cmp cmp e0 e'0
e, e':A
H1:None = Some e
H4:None = Some e'

Cmp cmp e e'
try discriminate. Qed. End PositiveMap.
Here come some additional facts about this implementation. Most are facts that cannot be derivable from the general interface.
Module PositiveMapAdditionalFacts.
  Import PositiveMap.

  (* Derivable from the Map interface *)
  

forall (A : Type) (i j : key) (x : A) (m : t A), find i (add j x m) = (if E.eq_dec i j then Some x else find i m)

forall (A : Type) (i j : key) (x : A) (m : t A), find i (add j x m) = (if E.eq_dec i j then Some x else find i m)
A:Type
i, j:key
x:A
m:t A

find i (add j x m) = (if E.eq_dec i j then Some x else find i m)
destruct (E.eq_dec i j) as [ ->|]; [ apply gss | apply gso; auto ]. Qed. (* Not derivable from the Map interface *)

forall (A : Type) (i : key) (m : t A) (v : A), find i m = Some v -> add i v m = m

forall (A : Type) (i : key) (m : t A) (v : A), find i m = Some v -> add i v m = m
A:Type
i:positive
IHi:forall (m : t A) (v0 : A), find i m = Some v0 -> add i v0 m = m
m1:tree A
o:option A
m2:tree A
v:A
H:find i m2 = Some v

Node m1 o (add i v m2) = Node m1 o m2
A:Type
i:positive
IHi:forall (m : t A) (v0 : A), find i m = Some v0 -> add i v0 m = m
m1:tree A
o:option A
m2:tree A
v:A
H:find i m1 = Some v
Node (add i v m1) o m2 = Node m1 o m2
A:Type
i:positive
IHi:forall (m : t A) (v0 : A), find i m = Some v0 -> add i v0 m = m
m1:tree A
o:option A
m2:tree A
v:A
H:find i m1 = Some v

Node (add i v m1) o m2 = Node m1 o m2
rewrite (IHi m1 v H); congruence. Qed.

forall (A B : Type) (f g : option A -> option A -> option B) (m : t A), (forall i j : option A, f i j = g j i) -> xmap2_l f m = xmap2_r g m

forall (A B : Type) (f g : option A -> option A -> option B) (m : t A), (forall i j : option A, f i j = g j i) -> xmap2_l f m = xmap2_r g m
A, B:Type
f, g:option A -> option A -> option B
m1:tree A
o:option A
m2:tree A
IHm1:(forall i j : option A, f i j = g j i) -> xmap2_l f m1 = xmap2_r g m1
IHm2:(forall i j : option A, f i j = g j i) -> xmap2_l f m2 = xmap2_r g m2
H:forall i j : option A, f i j = g j i

Node (xmap2_l f m1) (f o None) (xmap2_l f m2) = Node (xmap2_r g m1) (g None o) (xmap2_r g m2)
A, B:Type
f, g:option A -> option A -> option B
m1:tree A
o:option A
m2:tree A
IHm1:(forall i j : option A, f i j = g j i) -> xmap2_l f m1 = xmap2_r g m1
IHm2:(forall i j : option A, f i j = g j i) -> xmap2_l f m2 = xmap2_r g m2
H:forall i j : option A, f i j = g j i

Node (xmap2_r g m1) (f o None) (xmap2_l f m2) = Node (xmap2_r g m1) (g None o) (xmap2_r g m2)
A, B:Type
f, g:option A -> option A -> option B
m1:tree A
o:option A
m2:tree A
IHm1:(forall i j : option A, f i j = g j i) -> xmap2_l f m1 = xmap2_r g m1
IHm2:(forall i j : option A, f i j = g j i) -> xmap2_l f m2 = xmap2_r g m2
H:forall i j : option A, f i j = g j i

Node (xmap2_r g m1) (f o None) (xmap2_r g m2) = Node (xmap2_r g m1) (g None o) (xmap2_r g m2)
rewrite H; auto. Qed.

forall (A B : Type) (f g : option A -> option A -> option B), (forall i j : option A, f i j = g j i) -> forall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1

forall (A B : Type) (f g : option A -> option A -> option B), (forall i j : option A, f i j = g j i) -> forall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i

forall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i

forall i j : option A, g i j = f j i
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i
Eq2:forall i j : option A, g i j = f j i
forall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i
Eq2:forall i j : option A, g i j = f j i

forall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i
Eq2:forall i j : option A, g i j = f j i
m1_1:tree A
o:option A
m1_2:tree A
IHm1_1:forall m2 : t A, _map2 f m1_1 m2 = _map2 g m2 m1_1
IHm1_2:forall m2 : t A, _map2 f m1_2 m2 = _map2 g m2 m1_2
m2_1:tree A
o0:option A
m2_2:tree A

Node (_map2 f m1_1 m2_1) (g o0 o) (_map2 f m1_2 m2_2) = Node (_map2 g m2_1 m1_1) (g o0 o) (_map2 g m2_2 m1_2)
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i
Eq2:forall i j : option A, g i j = f j i
m1_1:tree A
o:option A
m1_2:tree A
IHm1_1:forall m2 : t A, _map2 f m1_1 m2 = _map2 g m2 m1_1
IHm1_2:forall m2 : t A, _map2 f m1_2 m2 = _map2 g m2 m1_2
m2_1:tree A
o0:option A
m2_2:tree A

Node (_map2 g m2_1 m1_1) (g o0 o) (_map2 f m1_2 m2_2) = Node (_map2 g m2_1 m1_1) (g o0 o) (_map2 g m2_2 m1_2)
A, B:Type
f, g:option A -> option A -> option B
Eq1:forall i j : option A, f i j = g j i
Eq2:forall i j : option A, g i j = f j i
m1_1:tree A
o:option A
m1_2:tree A
IHm1_1:forall m2 : t A, _map2 f m1_1 m2 = _map2 g m2 m1_1
IHm1_2:forall m2 : t A, _map2 f m1_2 m2 = _map2 g m2 m1_2
m2_1:tree A
o0:option A
m2_2:tree A

Node (_map2 g m2_1 m1_1) (g o0 o) (_map2 g m2_2 m1_2) = Node (_map2 g m2_1 m1_1) (g o0 o) (_map2 g m2_2 m1_2)
auto. Qed. End PositiveMapAdditionalFacts.