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) *)
(************************************************************************)
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) jinduction 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~0 = append (append i 2) jforall i j : positive, append i j~1 = append (append i 3) jinduction 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) jforall i : positive, append i 1 = iinduction i; simpl; congruence. Qed.forall i : positive, append i 1 = iforall i : positive, append 1 i = isimpl; auto. Qed.forall i : positive, append 1 i = i
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:Typeforall i : key, find i empty = Nonedestruct i; simpl; auto. Qed.A:Typeforall i : key, find i empty = NoneA:Typeforall (i : key) (x : A) (m : t A), find i (add i x m) = Some xinduction i; destruct m; simpl; auto. Qed.A:Typeforall (i : key) (x : A) (m : t A), find i (add i x m) = Some xA:Typeforall i : key, find i (Leaf : t A) = Noneexact gempty. Qed.A:Typeforall i : key, find i (Leaf : t A) = NoneA:Typeforall (i j : key) (x : A) (m : t A), i <> j -> find i (add j x m) = find i minduction i; intros; destruct j; destruct m; simpl; try rewrite <- (gleaf i); auto; try apply IHi; congruence. Qed.A:Typeforall (i j : key) (x : A) (m : t A), i <> j -> find i (add j x m) = find i mA:Typeforall i : key, remove i Leaf = Leafdestruct i; simpl; auto. Qed.A:Typeforall i : key, remove i Leaf = LeafA:Typeforall (i : key) (m : t A), find i (remove i m) = NoneA:Typeforall (i : key) (m : t A), find i (remove i m) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~1 (remove i~1 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~1 (remove i~1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~1 (remove i~1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonematch 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 = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Amatch 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 = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Amatch 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 = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Afind 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 = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Afind i (remove i (Node ll oo rr)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Afind i (remove i (Node ll oo rr)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonefind i~0 (remove i~0 Leaf) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonem1:tree Ao:option Am2:tree Afind i~0 (remove i~0 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonematch 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 = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Amatch 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 = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Amatch 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 = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Afind 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 = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Afind i (remove i (Node ll oo rr)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typei:positiveIHi:forall m : t A, find i (remove i m) = Nonell:tree Aoo:option Arr:tree Afind i (remove i (Node ll oo rr)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typefind 1 (remove 1 Leaf) = NoneA:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = Nonedestruct m1; destruct m2; simpl; auto. Qed.A:Typem1:tree Ao:option Am2:tree Afind 1 (remove 1 (Node m1 o m2)) = NoneA:Typeforall (i j : key) (m : t A), i <> j -> find i (remove j m) = find i mA:Typeforall (i j : key) (m : t A), i <> j -> find i (remove j m) = find i mA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem2_1:tree Ao:option Am2_2:tree AH:i~1 <> j~1match 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:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem1_1:tree Ao0:option Am1_2:tree AH:i~1 <> j~0match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem2_1:tree Ao:option Am2_2:tree AH:i~0 <> j~1match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem1_1:tree Ao0:option Am1_2:tree AH:i~0 <> j~0match 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:Typej:positivem2_1:tree Ao:option Am2_2:tree AH:1 <> j~1match 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 = NoneA:Typej:positivem1_1:tree Ao0:option Am1_2:tree AH:1 <> j~0match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem1_1:tree Ao0:option Am1_2:tree AH:i~1 <> j~0match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem2_1:tree Ao:option Am2_2:tree AH:i~0 <> j~1match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem1_1:tree Ao0:option Am1_2:tree AH:i~0 <> j~0match 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:Typej:positivem2_1:tree Ao:option Am2_2:tree AH:1 <> j~1match 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 = NoneA:Typej:positivem1_1:tree Ao0:option Am1_2:tree AH:1 <> j~0match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem2_1:tree Ao:option Am2_2:tree AH:i~0 <> j~1match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem1_1:tree Ao0:option Am1_2:tree AH:i~0 <> j~0match 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:Typej:positivem2_1:tree Ao:option Am2_2:tree AH:1 <> j~1match 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 = NoneA:Typej:positivem1_1:tree Ao0:option Am1_2:tree AH:1 <> j~0match 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 = NoneA:Typei:positiveIHi:forall (j0 : key) (m : t A), i <> j0 -> find i (remove j0 m) = find i mj:positivem1_1:tree Ao0:option Am1_2:tree AH:i~0 <> j~0match 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:Typej:positivem2_1:tree Ao:option Am2_2:tree AH:1 <> j~1match 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 = NoneA:Typej:positivem1_1:tree Ao0:option Am1_2:tree AH:1 <> j~0match 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 = NoneA:Typej:positivem2_1:tree Ao:option Am2_2:tree AH:1 <> j~1match 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 = NoneA:Typej:positivem1_1:tree Ao0:option Am1_2:tree AH:1 <> j~0match 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 = Nonedestruct (remove j (Node m1_1 o0 m1_2)); simpl; try rewrite (gleaf i); auto. Qed.A:Typej:positivem1_1:tree Ao0:option Am1_2:tree AH:1 <> j~0match 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 = NoneA:Typeforall (m : t A) (i j : key) (v : A), find i m = Some v -> In (append j i, v) (xelements m j)A:Typeforall (m : t A) (i j : key) (v : A), find i m = Some v -> In (append j i, v) (xelements m j)A:Typei, j:keyv:AH:find i Leaf = Some vIn (append j i, v) (xelements Leaf j)A:Typem1:tree Ao:option Am2:tree AIHm1: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:keyv:AH:find i (Node m1 o m2) = Some vIn (append j i, v) (xelements (Node m1 o m2) j)A:Typem1:tree Ao:option Am2:tree AIHm1: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:keyv:AH:find i (Node m1 o m2) = Some vIn (append j i, v) (xelements (Node m1 o m2) j)A:Typem1:tree Aa:Am2:tree AIHm1: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:positivej:keyv:AH:find i m2 = Some vIn (append j i~1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))A:Typem1:tree Aa:Am2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))A:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH:Some a = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m2 = Some vIn (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:keyv:AH:None = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1:tree Aa:Am2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))A:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH:Some a = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m2 = Some vIn (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:keyv:AH:None = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH:Some a = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ (j, a) :: xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m2 = Some vIn (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:keyv:AH:None = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m2 = Some vIn (append j i~1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:keyv:AH:None = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:positivej:keyv:AH:find i m1 = Some vIn (append j i~0, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typem1, m2:tree AIHm1: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:keyv:AH:None = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))congruence. Qed.A:Typem1, m2:tree AIHm1: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:keyv:AH:None = Some vIn (append j 1, v) (xelements m1 (append j 2) ++ xelements m2 (append j 3))A:Typeforall (m : t A) (i : key) (v : A), find i m = Some v -> In (i, v) (elements m)A:Typeforall (m : t A) (i : key) (v : A), 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:Typem:t Ai:keyv:AH:find i m = Some vIn (i, v) (elements m)A:Typeforall (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 vA:Typeforall (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 vdestruct i; simpl in *; auto. Qed.A:Typei:positivem1, m2:t Ao:option Av:AH:xfind i 1 m1 = Some vfind i m1 = Some vA:Typeforall (m : t A) (i j : key) (v : A), In (i~1, v) (xelements m j~1) -> In (i, v) (xelements m j)A:Typeforall (m : t A) (i j : key) (v : A), In (i~1, v) (xelements m j~1) -> In (i, v) (xelements m j)A:Typeforall (i j : key) (v : A), In (i~1, v) (xelements Leaf j~1) -> In (i, v) (xelements Leaf j)A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typeforall (m : t A) (i j : key) (v : A), ~ In (i~1, v) (xelements m j~0)A:Typeforall (m : t A) (i j : key) (v : A), ~ In (i~1, v) (xelements m j~0)A:Typeforall (i j : key) (v : A), ~ In (i~1, v) (xelements Leaf j~0)A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)Falseapply (IHm2 _ _ _ H0). Qed.A:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typeforall (m : t A) (i j : key) (v : A), In (i~0, v) (xelements m j~0) -> In (i, v) (xelements m j)A:Typeforall (m : t A) (i j : key) (v : A), In (i~0, v) (xelements m j~0) -> In (i, v) (xelements m j)A:Typeforall (i j : key) (v : A), In (i~0, v) (xelements Leaf j~0) -> In (i, v) (xelements Leaf j)A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typem1, m2:tree AIHm1: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:keyv:AH: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:Typeforall (m : t A) (i j : key) (v : A), ~ In (i~0, v) (xelements m j~1)A:Typeforall (m : t A) (i j : key) (v : A), ~ In (i~0, v) (xelements m j~1)A:Typeforall (i j : key) (v : A), ~ In (i~0, v) (xelements Leaf j~1)A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)Falseapply (IHm2 _ _ _ H0). Qed.A:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typeforall (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:Typeforall (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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typeforall (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:Typeforall (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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Aa:Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typem1, m2:t Ai:keyv:AH: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:Typeforall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~1)A:Typeforall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~1)A:Typei:keyv:A~ In (1, v) (xelements Leaf i~1)A:Typem1:tree Ao:option Am2:tree AIHm1: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:keyv:A~ In (1, v) (xelements (Node m1 o m2) i~1)A:Typem1:tree Ao:option Am2:tree AIHm1: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:keyv:A~ In (1, v) (xelements (Node m1 o m2) i~1)A:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)Falsegeneralize H0; apply IHm2; auto. Qed.A:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typeforall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~0)A:Typeforall (m : t A) (i : key) (v : A), ~ In (1, v) (xelements m i~0)A:Typei:keyv:A~ In (1, v) (xelements Leaf i~0)A:Typem1:tree Ao:option Am2:tree AIHm1: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:keyv:A~ In (1, v) (xelements (Node m1 o m2) i~0)A:Typem1:tree Ao:option Am2:tree AIHm1: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:keyv:A~ In (1, v) (xelements (Node m1 o m2) i~0)A:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1:tree Aa:Am2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typem1, m2:tree AIHm1: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:keyv:AH: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)Falsegeneralize H0; apply IHm2; auto. Qed.A:Typem1, m2:tree AIHm1: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:keyv:AH: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)FalseA:Typeforall (m : t A) (i : key), find i m = xfind i 1 mdestruct i; simpl; auto. Qed.A:Typeforall (m : t A) (i : key), find i m = xfind i 1 mA:Typeforall (i j : key) (m : t A) (v : A), In (i, v) (xelements m j) -> xfind i j m = Some vA:Typeforall (i j : key) (m : t A) (v : A), In (i, v) (xelements m j) -> xfind i j m = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~1, v) (xelements m j~1)xfind i j m = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~1, v) (xelements m j~0)None = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~1, v) (xelements m 1)match m with | Leaf => None | Node _ _ r => find i r end = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~1, v) (xelements m j~0)None = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~1, v) (xelements m 1)match m with | Leaf => None | Node _ _ r => find i r end = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~1, v) (xelements m 1)match m with | Leaf => None | Node _ _ r => find i r end = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0v:AH:In (i~1, v) (xelements Leaf 1)None = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~1, v) (xelements (Node m1 o m2) 1)find i m2 = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~1, v) (xelements (Node m1 o m2) 1)find i m2 = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~1, v) (xelements (Node m1 o m2) 1)xfind i 1 m2 = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~1, v) (xelements (Node m1 o m2) 1)In (i, v) (xelements m2 1)A:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~1)None = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j0 : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j0) -> xfind i j0 m0 = Some v0j:positivem:t Av:AH:In (i~0, v) (xelements m j~0)xfind i j m = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m0 : t A) (v0 : A), In (i, v0) (xelements m0 j) -> xfind i j m0 = Some v0m:t Av:AH:In (i~0, v) (xelements m 1)match m with | Leaf => None | Node l _ _ => find i l end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0v:AH:In (i~0, v) (xelements Leaf 1)None = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~0, v) (xelements (Node m1 o m2) 1)find i m1 = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~0, v) (xelements (Node m1 o m2) 1)find i m1 = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~0, v) (xelements (Node m1 o m2) 1)xfind i 1 m1 = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typei:positiveIHi:forall (j : key) (m : t A) (v0 : A), In (i, v0) (xelements m j) -> xfind i j m = Some v0m1:tree Ao:option Am2:tree Av:AH:In (i~0, v) (xelements (Node m1 o m2) 1)In (i, v) (xelements m1 1)A:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~1)None = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typej:positivem:t Av:AH:In (1, v) (xelements m j~0)None = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typem:t Av:AH:In (1, v) (xelements m 1)match m with | Leaf => None | Node _ o _ => o end = Some vA:Typev:AH:In (1, v) (xelements Leaf 1)None = Some vA:Typem1:tree Ao:option Am2:tree Av:AH:In (1, v) (xelements (Node m1 o m2) 1)o = Some vA:Typem1:tree Ao:option Am2:tree Av:AH:In (1, v) (xelements (Node m1 o m2) 1)o = Some vA:Typem1:tree Aa:Am2:tree Av:AH:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)H0:In (1, v) (xelements m1 2)Some a = Some vA:Typem1:tree Aa:Am2:tree Av:AH:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)H0:In (1, v) ((1, a) :: xelements m2 3)Some a = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m1 2)None = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m2 3)None = Some vA:Typem1:tree Aa:Am2:tree Av:AH:In (1, v) (xelements m1 2 ++ (1, a) :: xelements m2 3)H0:In (1, v) ((1, a) :: xelements m2 3)Some a = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m1 2)None = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m2 3)None = Some vA:Typem1:tree Aa:Am2:tree Av:AH: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 vA:Typem1:tree Aa:Am2:tree Av:AH: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 vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m1 2)None = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m2 3)None = Some vA:Typem1:tree Aa:Am2:tree Av:AH: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 vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m1 2)None = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m2 3)None = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m1 2)None = Some vA:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m2 3)None = Some vabsurd (List.In (xH, v) (xelements m2 (xI xH))); auto; apply xelements_hi. Qed.A:Typem1, m2:tree Av:AH:In (1, v) (xelements m1 2 ++ xelements m2 3)H0:In (1, v) (xelements m2 3)None = Some vA:Typeforall (m : t A) (i : key) (v : A), In (i, v) (elements m) -> find i m = Some vA:Typeforall (m : t A) (i : key) (v : A), In (i, v) (elements m) -> find i m = Some vA:Typem:t Ai:keyv:AH:In (i, v) (elements m)find i m = Some vA:Typem:t Ai:keyv:AH:In (i, v) (xelements m 1)find i m = Some vexact (xelements_complete i xH m v H). Qed.A:Typem:t Ai:keyv:AH:In (i, v) (xelements m 1)xfind i 1 m = Some vA:Typeforall m : t A, cardinal m = length (elements m)A:Typeforall m : t A, cardinal m = length (elements m)A:Typeforall m : t A, cardinal m = length (xelements m 1)A:Typeforall (m : t A) (p : positive), cardinal m = length (xelements m p)A:Typem1:tree Ao:option Am2:tree AIHm1:forall p0 : positive, cardinal m1 = length (xelements m1 p0)IHm2:forall p0 : positive, cardinal m2 = length (xelements m2 p0)p:positivematch 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) enddestruct 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:Typem1:tree Ao:option Am2:tree AIHm1:forall p0 : positive, cardinal m1 = length (xelements m1 p0)IHm2:forall p0 : positive, cardinal m2 = length (xelements m2 p0)p:positivematch 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) endA:Typeforall (m : t A) (x : key), mem x m = match find x m with | Some _ => true | None => false endinduction m; destruct x; simpl; auto. Qed.A:Typeforall (m : t A) (x : key), mem x m = match find x m with | Some _ => true | None => false endA:Typeforall m : t A, Empty m <-> (forall a : key, find a m = None)A:Typeforall m : t A, Empty m <-> (forall a : key, find a m = None)A:Typeforall m : t A, (forall (a : key) (e : A), find a m <> Some e) <-> (forall a : key, find a m = None)A:Typem:t AH:forall (a0 : key) (e : A), find a0 m = Some e -> Falsea:keyfind a m = NoneA:Typem:t AH:forall a0 : key, find a0 m = Nonea:keye:AH0:find a m = Some eFalseA:Typem:t AH:forall (a0 : key) (e : A), find a0 m = Some e -> Falsea:key(forall e : A, find a m = Some e -> False) -> find a m = NoneA:Typem:t AH:forall a0 : key, find a0 m = Nonea:keye:AH0:find a m = Some eFalseA:Typem:t AH:forall (a1 : key) (e : A), find a1 m = Some e -> Falsea:keya0:AH0:forall e : A, Some a0 = Some e -> FalseSome a0 = NoneA:Typem:t AH:forall a0 : key, find a0 m = Nonea:keye:AH0:find a m = Some eFalserewrite H in H0; discriminate. Qed.A:Typem:t AH:forall a0 : key, find a0 m = Nonea:keye:AH0:find a m = Some eFalseA:Typeforall (l : tree A) (o : option A) (r : tree A), Empty (Node l o r) <-> o = None /\ Empty l /\ Empty rA:Typeforall (l : tree A) (o : option A) (r : tree A), Empty (Node l o r) <-> o = None /\ Empty l /\ Empty rA:Typel:tree Ao:option Ar:tree AEmpty (Node l o r) <-> o = None /\ Empty l /\ Empty rA:Typel:tree Ao:option Ar:tree AEmpty (Node l o r) -> o = None /\ Empty l /\ Empty rA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree A(forall a : key, find a (Node l o r) = None) -> o = None /\ Empty l /\ Empty rA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree AH:forall a : key, find a (Node l o r) = Noneo = NoneA:Typel:tree Ao:option Ar:tree AH:forall a : key, find a (Node l o r) = NoneEmpty l /\ Empty rA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Aa:Ar:tree AH:forall a0 : key, find a0 (Node l (Some a) r) = NoneSome a = NoneA:Typel:tree Ao:option Ar:tree AH:forall a : key, find a (Node l o r) = NoneEmpty l /\ Empty rA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree AH:forall a : key, find a (Node l o r) = NoneEmpty l /\ Empty rA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree AH:forall a0 : key, find a0 (Node l o r) = Nonea:keyfind a l = NoneA:Typel:tree Ao:option Ar:tree AH:forall a0 : key, find a0 (Node l o r) = Nonea:keyfind a r = NoneA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree AH:forall a0 : key, find a0 (Node l o r) = Nonea:keyfind a r = NoneA:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree Ao = None /\ Empty l /\ Empty r -> Empty (Node l o r)A:Typel:tree Ao:option Ar:tree AH:o = NoneH0:Empty lH1:Empty rEmpty (Node l o r)A:Typel, r:tree AH0:Empty lH1:Empty rEmpty (Node l None r)A:Typel, r:tree AH0:Empty lH1:Empty ra:keyfind a (Node l None r) = NoneA:Typel, r:tree AH0:Empty lH1:Empty ra:positivefind a~1 (Node l None r) = NoneA:Typel, r:tree AH0:Empty lH1:Empty ra:positivefind a~0 (Node l None r) = Nonesimpl; generalize H0; rewrite Empty_alt; auto. Qed. Section FMapSpec.A:Typel, r:tree AH0:Empty lH1:Empty ra:positivefind a~0 (Node l None r) = NoneA:Typeforall (m : t A) (x : key), In x m -> mem x m = trueA:Typeforall (m : t A) (x : key), In x m -> mem x m = truedestruct 1 as (e0,H0); rewrite H0; auto. Qed.A:Typem:t Ax:key(exists e : A, find x m = Some e) -> match find x m with | Some _ => true | None => false end = trueA:Typeforall (m : t A) (x : key), mem x m = true -> In x mA:Typeforall (m : t A) (x : key), mem x m = true -> In x mA:Typem:t Ax:keymatch find x m with | Some _ => true | None => false end = true -> exists e : A, find x m = Some eA:Typem:t Ax:keya:Atrue = true -> exists e : A, Some a = Some eA:Typem:t Ax:keyfalse = true -> exists e : A, None = Some eintros; discriminate. Qed. Variable m m' m'' : t A. Variable x y z : key. Variable e e' : A.A:Typem:t Ax:keyfalse = true -> exists e : A, None = Some eA:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> MapsTo x e m -> MapsTo y e mintros; rewrite <- H; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> MapsTo x e m -> MapsTo y e mA:Typem, m', m'':t Ax, y, z:keye, e':AMapsTo x e m -> find x m = Some eunfold MapsTo; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':AMapsTo x e m -> find x m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':Afind x m = Some e -> MapsTo x e mred; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':Afind x m = Some e -> MapsTo x e mA:Typem, m', m'':t Ax, y, z:keye, e':AEmpty emptyrewrite Empty_alt; apply gempty. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':AEmpty emptyA:Typem, m', m'':t Ax, y, z:keye, e':AEmpty m -> is_empty m = trueA:Typem, m', m'':t Ax, y, z:keye, e':AEmpty m -> is_empty m = trueA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:Empty t0_1 -> is_empty t0_1 = trueIHt0_2:Empty t0_2 -> is_empty t0_2 = trueEmpty (Node t0_1 o t0_2) -> match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = trueA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:Empty t0_1 -> is_empty t0_1 = trueIHt0_2:Empty t0_2 -> is_empty t0_2 = trueo = None /\ Empty t0_1 /\ Empty t0_2 -> match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = trueA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:Empty t0_1 -> is_empty t0_1 = trueIHt0_2:Empty t0_2 -> is_empty t0_2 = trueH:o = NoneH0:Empty t0_1H1:Empty t0_2match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = truerewrite IHt0_1; simpl; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:Empty t0_1 -> is_empty t0_1 = trueIHt0_2:Empty t0_2 -> is_empty t0_2 = trueH0:Empty t0_1H1:Empty t0_2is_empty t0_1 && is_empty t0_2 = trueA:Typem, m', m'':t Ax, y, z:keye, e':Ais_empty m = true -> Empty mA:Typem, m', m'':t Ax, y, z:keye, e':Ais_empty m = true -> Empty mA:Typem, m', m'':t Ax, y, z:keye, e':Atrue = true -> Empty LeafA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> Empty (Node t0_1 o t0_2)A:Typem, m', m'':t Ax, y, z:keye, e':Atrue = true -> forall a : key, find a Leaf = NoneA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> Empty (Node t0_1 o t0_2)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> Empty (Node t0_1 o t0_2)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2match o with | Some _ => false | None => is_empty t0_1 && is_empty t0_2 end = true -> o = None /\ Empty t0_1 /\ Empty t0_2A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2false = true -> Some a = None /\ Empty t0_1 /\ Empty t0_2A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2is_empty t0_1 && is_empty t0_2 = true -> None = None /\ Empty t0_1 /\ Empty t0_2intro H; destruct (andb_prop _ _ H); intuition. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:is_empty t0_1 = true -> Empty t0_1IHt0_2:is_empty t0_2 = true -> Empty t0_2is_empty t0_1 && is_empty t0_2 = true -> None = None /\ Empty t0_1 /\ Empty t0_2A:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> MapsTo y e (add x e m)A:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> MapsTo y e (add x e m)A:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> find y (add x e m) = Some eapply gss. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':Afind y (add y e m) = Some eA:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> MapsTo y e m -> MapsTo y e (add x e' m)A:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> MapsTo y e m -> MapsTo y e (add x e' m)intros; rewrite gso; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> find y m = Some e -> find y (add x e' m) = Some eA:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> MapsTo y e (add x e' m) -> MapsTo y e mA:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> MapsTo y e (add x e' m) -> MapsTo y e mintro H; rewrite gso; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> find y (add x e' m) = Some e -> find y m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> ~ In y (remove x m)A:Typem, m', m'':t Ax, y, z:keye, e':AE.eq x y -> ~ In y (remove x m)A:Typem, m', m'':t Ax, y, z:keye, e':AH:E.eq x yH0:In y (remove x m)FalseA:Typem, m', m'':t Ax, y, z:keye, e':AH:E.eq x yH0:In y (remove x m)mem y (remove x m) = true -> FalseA:Typem, m', m'':t Ax, y, z:keye, e':AH:E.eq x yH0:In y (remove x m)match find y (remove x m) with | Some _ => true | None => false end = true -> FalseA:Typem, m', m'':t Ax, y, z:keye, e':AH:x = yH0:In y (remove x m)match find y (remove x m) with | Some _ => true | None => false end = true -> FalseA:Typem, m', m'':t Ax, y, z:keye, e':AH:x = yH0:In y (remove x m)match find y (remove y m) with | Some _ => true | None => false end = true -> Falseintros; discriminate. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':AH:x = yH0:In y (remove x m)false = true -> FalseA:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> MapsTo y e m -> MapsTo y e (remove x m)A:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> MapsTo y e m -> MapsTo y e (remove x m)intro H; rewrite gro; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':A~ E.eq x y -> find y m = Some e -> find y (remove x m) = Some eA:Typem, m', m'':t Ax, y, z:keye, e':AMapsTo y e (remove x m) -> MapsTo y e mA:Typem, m', m'':t Ax, y, z:keye, e':AMapsTo y e (remove x m) -> MapsTo y e mA:Typem, m', m'':t Ax, y, z:keye, e':Afind y (remove x m) = Some e -> find y m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':Ae0:x = yfind y (remove x m) = Some e -> find y m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':An:x <> yfind y (remove x m) = Some e -> find y m = Some eA:Typem, m', m'':t Ay, z:keye, e':Afind y (remove y m) = Some e -> find y m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':An:x <> yfind y (remove x m) = Some e -> find y m = Some erewrite gro; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':An:x <> yfind y (remove x m) = Some e -> find y m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':AMapsTo x e m -> InA eq_key_elt (x, e) (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':AMapsTo x e m -> InA eq_key_elt (x, e) (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':Afind x m = Some e -> InA eq_key_elt (x, e) (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':Afind x m = Some e -> exists y0 : key * A, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':AH:find x m = Some eexists y0 : key * A, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':AH:find x m = Some eeq_key_elt (x, e) (x, e) /\ List.In (x, e) (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':AH:find x m = Some eeq_key_elt (x, e) (x, e)A:Typem, m', m'':t Ax, y, z:keye, e':AH:find x m = Some eList.In (x, e) (elements m)apply elements_correct; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':AH:find x m = Some eList.In (x, e) (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':AInA eq_key_elt (x, e) (elements m) -> MapsTo x e mA:Typem, m', m'':t Ax, y, z:keye, e':AInA eq_key_elt (x, e) (elements m) -> MapsTo x e mA:Typem, m', m'':t Ax, y, z:keye, e':AInA eq_key_elt (x, e) (elements m) -> find x m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':A(exists y0 : key * A, eq_key_elt (x, e) y0 /\ List.In y0 (elements m)) -> find x m = Some eA:Typem, m', m'':t Ax, y, z:keye, e':Ae0:keya:AH:eq_key_elt (x, e) (e0, a)H0:List.In (e0, a) (elements m)find x m = Some eapply elements_complete; auto. Qed.A:Typem, m', m'':t Ay, z:keye':Ae0:keya:AH0:List.In (e0, a) (elements m)find e0 m = Some aA:Typem, m', m'':t Ax, y, z:keye, e':Aforall (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 pA:Typem, m', m'':t Ax, y, z:keye, e':Aforall (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 pA:Typem, m', m'':t Ax, y, z:keye, e':Ap:positivep0:keyq:positivem0:t Av:AH:List.In (p0, v) (xelements m0 (append p q~0))E.bits_lt p0 pA:Typem, m', m'':t Ax, y, z:keye, e':Ap:positivep0:keyq:positivem0:t Av:AH:xfind p0 (append p q~0) m0 = Some vE.bits_lt p0 pinduction p; destruct p0; simpl; intros; eauto; try discriminate. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':Ap, q:positivem0:t Av:Aforall p0 : key, xfind p0 (append p q~0) m0 = Some v -> E.bits_lt p0 pA:Typem, m', m'':t Ax, y, z:keye, e':Aforall (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 p0A:Typem, m', m'':t Ax, y, z:keye, e':Aforall (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 p0A:Typem, m', m'':t Ax, y, z:keye, e':Ap:positivep0:keyq:positivem0:t Av:AH:List.In (p0, v) (xelements m0 (append p q~1))E.bits_lt p p0A:Typem, m', m'':t Ax, y, z:keye, e':Ap:positivep0:keyq:positivem0:t Av:AH:xfind p0 (append p q~1) m0 = Some vE.bits_lt p p0induction p; destruct p0; simpl; intros; eauto; try discriminate. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':Ap, q:positivem0:t Av:Aforall p0 : key, xfind p0 (append p q~1) m0 = Some v -> E.bits_lt p p0A:Typem, m', m'':t Ax, y, z:keye, e':Aforall p : key, Sorted lt_key (xelements m p)A:Typem, m', m'':t Ax, y, z:keye, e':Aforall p : key, Sorted lt_key (xelements m p)A:Typem, m', m'':t Ax, y, z:keye, e':Aforall p : key, Sorted lt_key (xelements Leaf p)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_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:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Ao:option At0_2:tree AIHt0_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)(* Some *)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ (p, a) :: xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key ((p, a) :: xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyHdRel lt_key (p, a) (xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyy0:(key * A)%typeH:List.In y0 (xelements t0_2 (append p 3))lt_key (p, a) y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_2 (append p 3))lt_key (p, a) (k, a0)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_2 (append p 3))E.bits_lt p kA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyx0, y0:(key * A)%typeInA 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyx0, 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyx0, y0, y1:(key * A)%typeHy1:eq_key_elt x0 y1H:List.In y1 (xelements t0_1 (append p 2))y2:(key * A)%typeHy2:eq_key_elt y0 y2H0:List.In y2 ((p, a) :: xelements t0_2 (append p 3))lt_key x0 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyy0:(key * A)%typek:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))y2:(key * A)%typeHy2:eq_key_elt y0 y2H0:List.In y2 ((p, a) :: xelements t0_2 (append p 3))lt_key (k, a0) y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) ((p, a) :: xelements t0_2 (append p 3))lt_key (k, a0) (k0, a1)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) ((p, a) :: xelements t0_2 (append p 3))E.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:(p, a) = (k0, a1)E.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) (xelements t0_2 (append p 3))E.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_1:forall p : key, Sorted lt_key (xelements t0_1 p)IHt0_2:forall p : key, Sorted lt_key (xelements t0_2 p)k:keya0:Ak0:keyH:List.In (k, a0) (xelements t0_1 (append k0 2))a1:AE.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) (xelements t0_2 (append p 3))E.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) (xelements t0_2 (append p 3))E.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) (xelements t0_2 (append p 3))E.bits_lt k pA:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) (xelements t0_2 (append p 3))E.bits_lt p k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1:tree Aa:At0_2:tree AIHt0_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:keya0:AH:List.In (k, a0) (xelements t0_1 (append p 2))k0:keya1:AH0:List.In (k0, a1) (xelements t0_2 (append p 3))E.bits_lt p k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))(* None *)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keySorted lt_key (xelements t0_1 (append p 2) ++ xelements t0_2 (append p 3))A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyforall 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyx0, y0:(key * A)%typeInA eq_key_elt x0 (xelements t0_1 (append p 2)) -> InA eq_key_elt y0 (xelements t0_2 (append p 3)) -> lt_key x0 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyx0, 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 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyx0, y0, y1:(key * A)%typeHy1:eq_key_elt x0 y1H:List.In y1 (xelements t0_1 (append p 2))y2:(key * A)%typeHy2:eq_key_elt y0 y2H0:List.In y2 (xelements t0_2 (append p 3))lt_key x0 y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_1:forall p0 : key, Sorted lt_key (xelements t0_1 p0)IHt0_2:forall p0 : key, Sorted lt_key (xelements t0_2 p0)p:keyy0:(key * A)%typek:keya:AH:List.In (k, a) (xelements t0_1 (append p 2))y2:(key * A)%typeHy2:eq_key_elt y0 y2H0:List.In y2 (xelements t0_2 (append p 3))lt_key (k, a) y0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_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:keya:AH:List.In (k, a) (xelements t0_1 (append p 2))k0:keya0:AH0:List.In (k0, a0) (xelements t0_2 (append p 3))lt_key (k, a) (k0, a0)A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_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:keya:AH:List.In (k, a) (xelements t0_1 (append p 2))k0:keya0:AH0:List.In (k0, a0) (xelements t0_2 (append p 3))E.bits_lt k k0A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_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:keya:AH:List.In (k, a) (xelements t0_1 (append p 2))k0:keya0:AH0:List.In (k0, a0) (xelements t0_2 (append p 3))E.bits_lt k pA:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_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:keya:AH:List.In (k, a) (xelements t0_1 (append p 2))k0:keya0:AH0:List.In (k0, a0) (xelements t0_2 (append p 3))E.bits_lt p k0eapply xelements_bits_lt_2; eauto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':At0_1, t0_2:tree AIHt0_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:keya:AH:List.In (k, a) (xelements t0_1 (append p 2))k0:keya0:AH0:List.In (k0, a0) (xelements t0_2 (append p 3))E.bits_lt p k0A:Typem, m', m'':t Ax, y, z:keye, e':ASorted lt_key (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':ASorted lt_key (elements m)apply xelements_sort; auto. Qed.A:Typem, m', m'':t Ax, y, z:keye, e':ASorted lt_key (xelements m 1)A:Typem, m', m'':t Ax, y, z:keye, e':ANoDupA eq_key (elements m)A:Typem, m', m'':t Ax, y, z:keye, e':ANoDupA eq_key (elements m)apply elements_3. Qed. End FMapSpec.A:Typem, m', m'':t Ax, y, z:keye, e':ASorted (ME.ltk (elt:=A)) (elements m)
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:Typef:key -> A -> Bi:positiveIHi:forall (j0 : key) (m : t A), find i (xmapi f m j0) = option_map (f (append j0 i)) (find i m)j:keym1:tree Ao:option Am2:tree Afind i (xmapi f m2 (append j 3)) = option_map (f (append j i~1)) (find i m2)A, B:Typef:key -> A -> Bi:positiveIHi:forall (j0 : key) (m : t A), find i (xmapi f m j0) = option_map (f (append j0 i)) (find i m)j:keym1:tree Ao:option Am2:tree Afind i (xmapi f m1 (append j 2)) = option_map (f (append j i~0)) (find i m1)A, B:Typef:key -> A -> Bj:keym1:tree Ao:option Am2:tree Aoption_map (f j) o = option_map (f (append j 1)) oA, B:Typef:key -> A -> Bi:positiveIHi:forall (j0 : key) (m : t A), find i (xmapi f m j0) = option_map (f (append j0 i)) (find i m)j:keym1:tree Ao:option Am2:tree Afind i (xmapi f m1 (append j 2)) = option_map (f (append j i~0)) (find i m1)A, B:Typef:key -> A -> Bj:keym1:tree Ao:option Am2:tree Aoption_map (f j) o = option_map (f (append j 1)) orewrite (append_neutral_r j); auto. Qed.A, B:Typef:key -> A -> Bj:keym1:tree Ao:option Am2:tree Aoption_map (f j) o = option_map (f (append j 1)) oforall (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:Typef:key -> A -> Bi:keym:t Afind i (mapi f m) = option_map (f i) (find i m)A, B:Typef:key -> A -> Bi:keym:t Afind i (xmapi f m 1) = option_map (f i) (find i m)A, B:Typef:key -> A -> Bi:keym:t Afind i (xmapi f m 1) = option_map (f (append 1 i)) (find i m)A, B:Typef:key -> A -> Bi:keym:t Af (append 1 i) = f irewrite append_neutral_l; auto. Qed.A, B:Typef:key -> A -> Bi:keym:t Af (append 1 i) = f iforall (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':Typem:t eltx:keye:eltf:key -> elt -> elt'H:MapsTo x e mexists y : positive, E.eq y x /\ MapsTo x (f y e) (mapi f m)elt, elt':Typem:t eltx:keye:eltf:key -> elt -> elt'H:MapsTo x e mE.eq x x /\ MapsTo x (f x e) (mapi f m)elt, elt':Typem:t eltx:keye:eltf:key -> elt -> elt'H:MapsTo x e mMapsTo x (f x e) (mapi f m)elt, elt':Typem:t eltx:keye:eltf:key -> elt -> elt'H:MapsTo x e mfind x (mapi f m) = Some (f x e)elt, elt':Typem:t eltx:keye:eltf:key -> elt -> elt'H:find x m = Some efind x (mapi f m) = Some (f x e)elt, elt':Typem:t eltx:keye:eltf:key -> elt -> elt'H:find x m = Some eoption_map (f x) (find x m) = Some (f x e)simpl; auto. Qed.elt, elt':Typem:t eltx:keye:eltf:key -> elt -> elt'H:find x m = Some eoption_map (f x) (Some e) = Some (f x e)forall (elt elt' : Type) (m : t elt) (x : key) (f : key -> elt -> elt'), In x (mapi f m) -> In x mforall (elt elt' : Type) (m : t elt) (x : key) (f : key -> elt -> elt'), In x (mapi f m) -> In x melt, elt':Typem:t eltx:keyf:key -> elt -> elt'H:In x (mapi f m)In x melt, elt':Typem:t eltx:keyf:key -> elt -> elt'H:In x (mapi f m)mem x m = trueelt, elt':Typem:t eltx:keyf:key -> elt -> elt'H:In x (mapi f m)match find x m with | Some _ => true | None => false end = trueelt, elt':Typem:t eltx:keyf:key -> elt -> elt'v:elt'H:MapsTo x v (mapi f m)match find x m with | Some _ => true | None => false end = trueelt, elt':Typem:t eltx:keyf:key -> elt -> elt'v:elt'H:find x (mapi f m) = Some vmatch find x m with | Some _ => true | None => false end = trueelt, elt':Typem:t eltx:keyf:key -> elt -> elt'v:elt'H:option_map (f x) (find x m) = Some vmatch find x m with | Some _ => true | None => false end = truesimpl in *; discriminate. Qed.elt, elt':Typem:t eltx:keyf:key -> elt -> elt'v:elt'H:option_map (f x) None = Some vfalse = trueforall (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)destruct (mapi_1 (fun _ => f) H); intuition. Qed.elt, elt':Typem:t eltx:keye:eltf:elt -> elt'H:MapsTo x e mMapsTo x (f e) (mapi (fun _ : key => f) m)forall (elt elt' : Type) (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) -> In x mintros; 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.forall (elt elt' : Type) (m : t elt) (x : key) (f : elt -> elt'), In x (map f m) -> In x mA, B, C:Typef:option A -> option B -> option Cforall (i : key) (m : t A), f None None = None -> find i (xmap2_l m) = f (find i m) Noneinduction 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:Typef:option A -> option B -> option Cforall (i : key) (m : t A), f None None = None -> find i (xmap2_l m) = f (find i m) NoneA, B, C:Typef:option A -> option B -> option Cforall (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:Typef:option A -> option B -> option Cforall (i : key) (m : t B), f None None = None -> find i (xmap2_r m) = f None (find i m)A, B, C:Typef:option A -> option B -> option Cforall (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).A, B, C:Typef:option A -> option B -> option Cforall (i : key) (m1 : t A) (m2 : t B), f None None = None -> find i (_map2 m1 m2) = f (find i m1) (find i m2)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'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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 Nonedestruct H; intuition; try discriminate. Qed.elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:In x m \/ In x m'H0:In x m -> false = trueH1:In x m' -> false = trueNone = f None Noneforall (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'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:In x (map2 f m m')In x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:mem x (map2 f m m') = trueIn x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf:option elt -> option elt' -> option elt''H:match find x (map2 f m m') with | Some _ => true | None => false end = trueIn x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf: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 = trueIn x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf: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 = trueIn x m \/ In x m'elt, elt', elt'':Typem:t eltm':t elt'x:keyf: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'':Typem:t eltm':t elt'x:keyf: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'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.elt, elt', elt'':Typem:t eltm':t elt'x:keyf: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'A, B:Typef:key -> A -> B -> Bforall (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) vA, B:Typef:key -> A -> B -> Bforall (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) vA, B:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bforall (m : t A) (v : B) (i : key), xfoldi m v i = fold_left F (xelements m i) vA, B:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1:tree Ao:option Am2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keymatch 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 vA, B:Typef:key -> A -> B -> BF:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> Bm1:tree Aa:Am2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi 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)) vA, B:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) vA, B:Typef:key -> A -> B -> BF:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> Bm1:tree Aa:Am2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi 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:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) vA, B:Typef:key -> A -> B -> BF:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> Bm1:tree Aa:Am2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi 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:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) vA, B:Typef:key -> A -> B -> BF:=fun (a0 : B) (p : key * A) => f (fst p) (snd p) a0:B -> key * A -> Bm1:tree Aa:Am2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi 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:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) vA, B:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m1 (append i 2) ++ xelements m2 (append i 3)) vA, B:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi 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:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = fold_left F (xelements m2 (append i 3)) (xfoldi m1 v (append i 2))reflexivity. Qed. Definition fold m i := xfoldi m i 1. End Fold.A, B:Typef:key -> A -> B -> BF:=fun (a : B) (p : key * A) => f (fst p) (snd p) a:B -> key * A -> Bm1, m2:tree AIHm1:forall (v0 : B) (i0 : key), xfoldi m1 v0 i0 = fold_left F (xelements m1 i0) v0IHm2:forall (v0 : B) (i0 : key), xfoldi m2 v0 i0 = fold_left F (xelements m2 i0) v0v:Bi:keyxfoldi m2 (xfoldi m1 v (append i 2)) (append i 3) = xfoldi m2 (xfoldi m1 v (append i 2)) (append i 3)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) iforall (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) irewrite 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).A:Typem:t AB:Typei:Bf:key -> A -> B -> Bxfoldi f m i 1 = fold_left (fun (a : B) (p : key * A) => f (fst p) (snd p) a) (xelements m 1) iforall (A : Type) (m m' : t A) (cmp : A -> A -> bool), Equivb cmp m m' -> equal cmp m m' = trueforall (A : Type) (m m' : t A) (cmp : A -> A -> bool), Equivb cmp m m' -> equal cmp m m' = true(* m = Leaf *)A:Typeforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Leaf A) m' -> equal cmp (Leaf A) m' = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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' = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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' = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'In a (Leaf A)A:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'H2:In a (Leaf A)FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'In a m'A:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'H2:In a (Leaf A)FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'H2:In a (Leaf A)FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (m' : t A) (cmp : A -> A -> bool), Equivb cmp (Node m1 o m2) m' -> equal cmp (Node m1 o m2) m' = trueA:Typem':t Acmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m'x:AH2:find a (Leaf A) = Some xFalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (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:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall (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:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = trueforall cmp : A -> A -> bool, Equivb cmp (Node m1 o m2) (Leaf A) -> equal cmp (Node m1 o m2) (Leaf A) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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 = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m1FalseA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m1In a~0 (Leaf A)A:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m1H2:In a~0 (Leaf A)FalseA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m1In a~0 (Node m1 None m2)A:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m1H2:In a~0 (Leaf A)FalseA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m1H2:In a~0 (Leaf A)FalseA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2In a~1 (Leaf A)A:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2H2:In a~1 (Leaf A)FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2In a~1 (Node m1 None m2)A:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2H2:In a~1 (Leaf A)FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truecmp:A -> A -> boolH: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:keye:AH1:MapsTo a e m2H2:In a~1 (Leaf A)FalseA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m1 m' -> equal cmp m1 m' = trueIHm2:forall (m' : t A) (cmp : A -> A -> bool), Equivb cmp m2 m' -> equal cmp m2 m' = truem'1:tree Ao0:option Am'2:tree Aforall 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) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1A:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1A:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1Equivb cmp m2 m'2A:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1forall k : key, In k m2 <-> In k m'2A:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1forall (k : key) (e e' : A), MapsTo k e m2 -> MapsTo k e' m'2 -> Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1forall (k : key) (e e' : A), MapsTo k e m2 -> MapsTo k e' m'2 -> Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp (Node m1 o m2) (Node m'1 o0 m'2) = trueA:Typem1:tree Ao:option Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Ao0:option Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2match 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 = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2cmp a a0 && equal cmp m1 m'1 && equal cmp m2 m'2 = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2cmp a a0 = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueA:Typem1:tree Aa:Am2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2H4:(exists e : A, Some a = Some e) -> exists e : A, None = Some eH5:(exists e : A, None = Some e) -> exists e : A, Some a = Some efalse = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2false = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1:tree Aa:Am'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2H4:(exists e : A, None = Some e) -> exists e : A, Some a = Some eH5:(exists e : A, Some a = Some e) -> exists e : A, None = Some efalse = trueA:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueapply andb_true_intro; split; auto. Qed.A:Typem1, m2:tree AIHm1:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m1 m' -> equal cmp0 m1 m' = trueIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), Equivb cmp0 m2 m' -> equal cmp0 m2 m' = truem'1, m'2:tree Acmp:A -> A -> boolH: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'1H2:Equivb cmp m2 m'2equal cmp m1 m'1 && equal cmp m2 m'2 = trueforall (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'(* m = Leaf *)A:Typeforall (m' : t A) (cmp : A -> A -> bool), equal cmp (Leaf A) m' = true -> Equivb cmp (Leaf A) m'A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typeforall (m' : t A) (cmp : A -> A -> bool), is_empty m' = true -> Equivb cmp (Leaf A) m'A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keyIn k (Leaf A) <-> In k m'A:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keye, e':AH0:MapsTo k e (Leaf A)H1:MapsTo k e' m'Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keyIn k (Leaf A) -> In k m'A:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keyIn k m' -> In k (Leaf A)A:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keye, e':AH0:MapsTo k e (Leaf A)H1:MapsTo k e' m'Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keyIn k m' -> In k (Leaf A)A:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keye, e':AH0:MapsTo k e (Leaf A)H1:MapsTo k e' m'Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem':t Acmp:A -> A -> boolH:is_empty m' = truek:keye, e':AH0:MapsTo k e (Leaf A)H1:MapsTo k e' m'Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1:tree Ao:option Am2:tree AIHm1: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:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH:is_empty m1 && is_empty m2 = trueEquivb cmp (Node m1 None m2) (Leaf A)A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = trueEquivb cmp (Node m1 None m2) (Leaf A)A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keyIn k (Node m1 None m2) <-> In k (Leaf A)A:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keye, e':AH:MapsTo k e (Node m1 None m2)H2:MapsTo k e' (Leaf A)Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keyx:AH:find k (Node m1 None m2) = Some xexists e : A, find k (Leaf A) = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keyx:AH:find k (Leaf A) = Some xexists e : A, find k (Node m1 None m2) = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keye, e':AH:MapsTo k e (Node m1 None m2)H2:MapsTo k e' (Leaf A)Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:positivex:AH:find k m2 = Some xexists e : A, None = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:positivex:AH:find k m1 = Some xexists e : A, None = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keyx:AH:find k (Leaf A) = Some xexists e : A, find k (Node m1 None m2) = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keye, e':AH:MapsTo k e (Node m1 None m2)H2:MapsTo k e' (Leaf A)Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:positivex:AH:find k m1 = Some xexists e : A, None = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keyx:AH:find k (Leaf A) = Some xexists e : A, find k (Node m1 None m2) = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keye, e':AH:MapsTo k e (Node m1 None m2)H2:MapsTo k e' (Leaf A)Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keyx:AH:find k (Leaf A) = Some xexists e : A, find k (Node m1 None m2) = Some eA:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keye, e':AH:MapsTo k e (Node m1 None m2)H2:MapsTo k e' (Leaf A)Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1, m2:tree AIHm1: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 -> boolH0:is_empty m1 = trueH1:is_empty m2 = truek:keye, e':AH:MapsTo k e (Node m1 None m2)H2:MapsTo k e' (Leaf A)Cmp cmp e e'A:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1:tree Ao:option Am2:tree AIHm1: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 Ao0:option Am'2:tree Aforall 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:Typem1:tree Aa:Am2:tree AIHm1: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 Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 && equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2:tree AIHm1: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 Aa0:Am'2:tree Acmp:A -> A -> boolH0:cmp a a0 && equal cmp m1 m'1 = trueH1:equal cmp m2 m'2 = trueEquivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2:tree AIHm1: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 Aa0:Am'2:tree Acmp:A -> A -> boolH1:equal cmp m2 m'2 = trueH:cmp a a0 = trueH2:equal cmp m1 m'1 = trueEquivb cmp (Node m1 (Some a) m2) (Node m'1 (Some a0) m'2)A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2:tree AIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'm'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH1:equal cmp m2 m'2 = trueH:cmp a a0 = trueH0:forall k : key, In k m1 <-> In k m'1H3: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:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0:forall k : key, In k m1 <-> In k m'1H3: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'2H4: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:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0:forall k0 : key, In k0 m1 <-> In k0 m'1H3: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'2H4:forall (k0 : key) (e e' : A), MapsTo k0 e m2 -> MapsTo k0 e' m'2 -> Cmp cmp e e'k:keyIn k (Node m1 (Some a) m2) <-> In k (Node m'1 (Some a0) m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0:forall k0 : key, In k0 m1 <-> In k0 m'1H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0H2:forall k0 : key, In k0 m2 <-> In k0 m'2H4:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0k:keye, e':AH1:MapsTo k e (Node m1 (Some a) m2)H5:MapsTo k e' (Node m'1 (Some a0) m'2)Cmp cmp e e'A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0:forall k0 : key, In k0 m1 <-> In k0 m'1H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0H2:forall k0 : key, In k0 m2 <-> In k0 m'2H4:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0k:keye, e':AH1:MapsTo k e (Node m1 (Some a) m2)H5:MapsTo k e' (Node m'1 (Some a0) m'2)Cmp cmp e e'A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0:forall k0 : key, In k0 m1 <-> In k0 m'1H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0H2:forall k0 : key, In k0 m2 <-> In k0 m'2H4:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0k:keye, e':AH1:MapsTo k e (Node m1 (Some a) m2)H5:MapsTo k e' (Node m'1 (Some a0) m'2)Cmp cmp e e'A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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'0H2: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'0k:positivee, e':AH1:find k m2 = Some eH5:find k m'2 = Some e'Cmp cmp e e'A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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'0H2: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'0k:positivee, e':AH1:find k m1 = Some eH5:find k m'1 = Some e'Cmp cmp e e'A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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'0H2: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'0e, e':AH1:Some a = Some eH5:Some a0 = Some e'Cmp cmp e e'A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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'0H2: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'0k:positivee, e':AH1:find k m1 = Some eH5:find k m'1 = Some e'Cmp cmp e e'A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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'0H2: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'0e, e':AH1:Some a = Some eH5:Some a0 = Some e'Cmp cmp e e'A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1:tree Aa:Am2, m'1:tree Aa0:Am'2:tree Acmp:A -> A -> boolH:cmp a a0 = trueH0: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'0H2: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'0e, e':AH1:Some a = Some eH5:Some a0 = Some e'Cmp cmp e e'A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH:equal cmp m1 m'1 && equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1, m2:tree AIHm1: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 Acmp:A -> A -> boolH0:equal cmp m1 m'1 = trueH1:equal cmp m2 m'2 = trueEquivb cmp (Node m1 None m2) (Node m'1 None m'2)A:Typem1, m2:tree AIHm2:forall (m' : t A) (cmp0 : A -> A -> bool), equal cmp0 m2 m' = true -> Equivb cmp0 m2 m'm'1, m'2:tree Acmp:A -> A -> boolH1:equal cmp m2 m'2 = trueH:forall k : key, In k m1 <-> In k m'1H2: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:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH:forall k : key, In k m1 <-> In k m'1H2: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'2H3: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:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH:forall k0 : key, In k0 m1 <-> In k0 m'1H2: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'2H3:forall (k0 : key) (e e' : A), MapsTo k0 e m2 -> MapsTo k0 e' m'2 -> Cmp cmp e e'k:keyIn k (Node m1 None m2) <-> In k (Node m'1 None m'2)A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH:forall k0 : key, In k0 m1 <-> In k0 m'1H2:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0H0:forall k0 : key, In k0 m2 <-> In k0 m'2H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0k:keye, e':AH1:MapsTo k e (Node m1 None m2)H4:MapsTo k e' (Node m'1 None m'2)Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH:forall k0 : key, In k0 m1 <-> In k0 m'1H2:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0H0:forall k0 : key, In k0 m2 <-> In k0 m'2H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0k:keye, e':AH1:MapsTo k e (Node m1 None m2)H4:MapsTo k e' (Node m'1 None m'2)Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH:forall k0 : key, In k0 m1 <-> In k0 m'1H2:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m1 -> MapsTo k0 e'0 m'1 -> Cmp cmp e0 e'0H0:forall k0 : key, In k0 m2 <-> In k0 m'2H3:forall (k0 : key) (e0 e'0 : A), MapsTo k0 e0 m2 -> MapsTo k0 e'0 m'2 -> Cmp cmp e0 e'0k:keye, e':AH1:MapsTo k e (Node m1 None m2)H4:MapsTo k e' (Node m'1 None m'2)Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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'0H0: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'0k:positivee, e':AH1:find k m2 = Some eH4:find k m'2 = Some e'Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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'0H0: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'0k:positivee, e':AH1:find k m1 = Some eH4:find k m'1 = Some e'Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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'0H0: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'0e, e':AH1:None = Some eH4:None = Some e'Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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'0H0: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'0k:positivee, e':AH1:find k m1 = Some eH4:find k m'1 = Some e'Cmp cmp e e'A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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'0H0: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'0e, e':AH1:None = Some eH4:None = Some e'Cmp cmp e e'try discriminate. Qed. End PositiveMap.A:Typem1, m2, m'1, m'2:tree Acmp:A -> A -> boolH: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'0H0: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'0e, e':AH1:None = Some eH4:None = Some e'Cmp cmp e e'
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)destruct (E.eq_dec i j) as [ ->|]; [ apply gss | apply gso; auto ]. Qed. (* Not derivable from the Map interface *)A:Typei, j:keyx:Am:t Afind i (add j x m) = (if E.eq_dec i j then Some x else find i m)forall (A : Type) (i : key) (m : t A) (v : A), find i m = Some v -> add i v m = mforall (A : Type) (i : key) (m : t A) (v : A), find i m = Some v -> add i v m = mA:Typei:positiveIHi:forall (m : t A) (v0 : A), find i m = Some v0 -> add i v0 m = mm1:tree Ao:option Am2:tree Av:AH:find i m2 = Some vNode m1 o (add i v m2) = Node m1 o m2A:Typei:positiveIHi:forall (m : t A) (v0 : A), find i m = Some v0 -> add i v0 m = mm1:tree Ao:option Am2:tree Av:AH:find i m1 = Some vNode (add i v m1) o m2 = Node m1 o m2rewrite (IHi m1 v H); congruence. Qed.A:Typei:positiveIHi:forall (m : t A) (v0 : A), find i m = Some v0 -> add i v0 m = mm1:tree Ao:option Am2:tree Av:AH:find i m1 = Some vNode (add i v m1) o m2 = Node m1 o m2forall (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 mforall (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 mA, B:Typef, g:option A -> option A -> option Bm1:tree Ao:option Am2:tree AIHm1:(forall i j : option A, f i j = g j i) -> xmap2_l f m1 = xmap2_r g m1IHm2:(forall i j : option A, f i j = g j i) -> xmap2_l f m2 = xmap2_r g m2H:forall i j : option A, f i j = g j iNode (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:Typef, g:option A -> option A -> option Bm1:tree Ao:option Am2:tree AIHm1:(forall i j : option A, f i j = g j i) -> xmap2_l f m1 = xmap2_r g m1IHm2:(forall i j : option A, f i j = g j i) -> xmap2_l f m2 = xmap2_r g m2H:forall i j : option A, f i j = g j iNode (xmap2_r g m1) (f o None) (xmap2_l f m2) = Node (xmap2_r g m1) (g None o) (xmap2_r g m2)rewrite H; auto. Qed.A, B:Typef, g:option A -> option A -> option Bm1:tree Ao:option Am2:tree AIHm1:(forall i j : option A, f i j = g j i) -> xmap2_l f m1 = xmap2_r g m1IHm2:(forall i j : option A, f i j = g j i) -> xmap2_l f m2 = xmap2_r g m2H:forall i j : option A, f i j = g j iNode (xmap2_r g m1) (f o None) (xmap2_r g m2) = Node (xmap2_r g m1) (g None o) (xmap2_r g m2)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 m1forall (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 m1A, B:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iforall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1A, B:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iforall i j : option A, g i j = f j iA, B:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iEq2:forall i j : option A, g i j = f j iforall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1A, B:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iEq2:forall i j : option A, g i j = f j iforall m1 m2 : t A, _map2 f m1 m2 = _map2 g m2 m1A, B:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iEq2:forall i j : option A, g i j = f j im1_1:tree Ao:option Am1_2:tree AIHm1_1:forall m2 : t A, _map2 f m1_1 m2 = _map2 g m2 m1_1IHm1_2:forall m2 : t A, _map2 f m1_2 m2 = _map2 g m2 m1_2m2_1:tree Ao0:option Am2_2:tree ANode (_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:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iEq2:forall i j : option A, g i j = f j im1_1:tree Ao:option Am1_2:tree AIHm1_1:forall m2 : t A, _map2 f m1_1 m2 = _map2 g m2 m1_1IHm1_2:forall m2 : t A, _map2 f m1_2 m2 = _map2 g m2 m1_2m2_1:tree Ao0:option Am2_2:tree ANode (_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)auto. Qed. End PositiveMapAdditionalFacts.A, B:Typef, g:option A -> option A -> option BEq1:forall i j : option A, f i j = g j iEq2:forall i j : option A, g i j = f j im1_1:tree Ao:option Am1_2:tree AIHm1_1:forall m2 : t A, _map2 f m1_1 m2 = _map2 g m2 m1_1IHm1_2:forall m2 : t A, _map2 f m1_2 m2 = _map2 g m2 m1_2m2_1:tree Ao0:option Am2_2:tree ANode (_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)