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.
(* -*- coding: utf-8 -*- *)
(************************************************************************)
(*         *   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)         *)
(************************************************************************)

MSetAVL : Implementation of MSetInterface via AVL trees

This module implements finite sets using AVL trees. It follows the implementation from Ocaml's standard library,
All operations given here expect and produce well-balanced trees (in the ocaml sense: heights of subtrees shouldn't differ by more than 2), and hence has low complexities (e.g. add is logarithmic in the size of the set). But proving these balancing preservations is in fact not necessary for ensuring correct operational behavior and hence fulfilling the MSet interface. As a consequence, balancing results are not part of this file anymore, they can now be found in MSetFullAVL.
Four operations (union, subset, compare and equal) have been slightly adapted in order to have only structural recursive calls. The precise ocaml versions of these operations have also been formalized (thanks to Function+measure), see ocaml_union, ocaml_subset, ocaml_compare and ocaml_equal in MSetFullAVL. The structural variants compute faster in Coq, whereas the other variants produce nicer and/or (slightly) faster code after extraction.
Require Import FunInd MSetInterface MSetGenTree BinInt Int.

Set Implicit Arguments.
Unset Strict Implicit.
(* for nicer extraction, we create inductive principles
   only when needed *)
Local Unset Elimination Schemes.

Ops : the pure functions

Module Ops (Import I:Int)(X:OrderedType) <: MSetInterface.Ops X.
Local Open Scope Int_scope.
Notation int := I.t.

Generic trees instantiated with integer height

We reuse a generic definition of trees where the information parameter is a Int.t. Functions like mem or fold are also provided by this generic functor.
Include MSetGenTree.Ops X I.

Definition t := tree.

Height of trees

Definition height (s : t) : int :=
  match s with
  | Leaf => 0
  | Node h _ _ _ => h
  end.

Singleton set

Definition singleton x := Node 1 Leaf x Leaf.

Helper functions

create l x r creates a node, assuming l and r to be balanced and |height l - height r| 2.
Definition create l x r :=
   Node (max (height l) (height r) + 1) l x r.
bal l x r acts as create, but performs one step of rebalancing if necessary, i.e. assumes |height l - height r| 3.
Definition assert_false := create.

Definition bal l x r :=
  let hl := height l in
  let hr := height r in
  if (hr+2) <? hl then
    match l with
     | Leaf => assert_false l x r
     | Node _ ll lx lr =>
       if (height lr) <=? (height ll) then
         create ll lx (create lr x r)
       else
         match lr with
          | Leaf => assert_false l x r
          | Node _ lrl lrx lrr =>
              create (create ll lx lrl) lrx (create lrr x r)
         end
    end
  else
    if (hl+2) <? hr then
      match r with
       | Leaf => assert_false l x r
       | Node _ rl rx rr =>
         if (height rl) <=? (height rr) then
            create (create l x rl) rx rr
         else
           match rl with
            | Leaf => assert_false l x r
            | Node _ rll rlx rlr =>
                create (create l x rll) rlx (create rlr rx rr)
           end
      end
    else
      create l x r.

Insertion

Fixpoint add x s := match s with
   | Leaf => Node 1 Leaf x Leaf
   | Node h l y r =>
      match X.compare x y with
         | Lt => bal (add x l) y r
         | Eq => Node h l y r
         | Gt => bal l y (add x r)
      end
  end.

Join

Same as bal but does not assume anything regarding heights of l and r.
Fixpoint join l : elt -> t -> t :=
  match l with
    | Leaf => add
    | Node lh ll lx lr => fun x =>
       fix join_aux (r:t) : t := match r with
          | Leaf => add x l
          | Node rh rl rx rr =>
               if (rh+2) <? lh then bal ll lx (join lr x r)
               else if (lh+2) <? rh then bal (join_aux rl) rx rr
               else create l x r
          end
  end.

Extraction of minimum element

Morally, remove_min is to be applied to a non-empty tree t = Node h l x r. Since we can't deal here with assert false for t=Leaf, we pre-unpack t (and forget about h).
Fixpoint remove_min l x r : t*elt :=
  match l with
    | Leaf => (r,x)
    | Node lh ll lx lr =>
       let (l',m) := remove_min ll lx lr in (bal l' x r, m)
  end.

Merging two trees

merge t1 t2 builds the union of t1 and t2 assuming all elements of t1 to be smaller than all elements of t2, and |height t1 - height t2| 2.
Definition merge s1 s2 :=  match s1,s2 with
  | Leaf, _ => s2
  | _, Leaf => s1
  | _, Node _ l2 x2 r2 =>
        let (s2',m) := remove_min l2 x2 r2 in bal s1 m s2'
end.

Deletion

Fixpoint remove x s := match s with
  | Leaf => Leaf
  | Node _ l y r =>
      match X.compare x y with
         | Lt => bal (remove x l) y r
         | Eq => merge l r
         | Gt => bal l y (remove x r)
      end
   end.

Concatenation

Same as merge but does not assume anything about heights.
Definition concat s1 s2 :=
   match s1, s2 with
      | Leaf, _ => s2
      | _, Leaf => s1
      | _, Node _ l2 x2 r2 =>
            let (s2',m) := remove_min l2 x2 r2 in
            join s1 m s2'
   end.

Splitting

split x s returns a triple (l, present, r) where
Record triple := mktriple { t_left:t; t_in:bool; t_right:t }.
Notation "<< l , b , r >>" := (mktriple l b r) (at level 9).

Fixpoint split x s : triple := match s with
  | Leaf => << Leaf, false, Leaf >>
  | Node _ l y r =>
     match X.compare x y with
      | Lt => let (ll,b,rl) := split x l in << ll, b, join rl y r >>
      | Eq => << l, true, r >>
      | Gt => let (rl,b,rr) := split x r in << join l y rl, b, rr >>
     end
 end.

Intersection

Fixpoint inter s1 s2 := match s1, s2 with
    | Leaf, _ => Leaf
    | _, Leaf => Leaf
    | Node _ l1 x1 r1, _ =>
            let (l2',pres,r2') := split x1 s2 in
            if pres then join (inter l1 l2') x1 (inter r1 r2')
            else concat (inter l1 l2') (inter r1 r2')
    end.

Difference

Fixpoint diff s1 s2 := match s1, s2 with
 | Leaf, _ => Leaf
 | _, Leaf => s1
 | Node _ l1 x1 r1, _ =>
    let (l2',pres,r2') := split x1 s2 in
    if pres then concat (diff l1 l2') (diff r1 r2')
    else join (diff l1 l2') x1 (diff r1 r2')
end.

Union

In ocaml, heights of s1 and s2 are compared each time in order to recursively perform the split on the smaller set. Unfortunately, this leads to a non-structural algorithm. The following code is a simplification of the ocaml version: no comparison of heights. It might be slightly slower, but experimentally all the tests I've made in ocaml have shown this potential slowdown to be non-significant. Anyway, the exact code of ocaml has also been formalized thanks to Function+measure, see ocaml_union in MSetFullAVL.
Fixpoint union s1 s2 :=
 match s1, s2 with
  | Leaf, _ => s2
  | _, Leaf => s1
  | Node _ l1 x1 r1, _ =>
     let (l2',_,r2') := split x1 s2 in
     join (union l1 l2') x1 (union r1 r2')
 end.

Filter

Fixpoint filter (f:elt->bool) s := match s with
  | Leaf => Leaf
  | Node _ l x r =>
    let l' := filter f l in
    let r' := filter f r in
    if f x then join l' x r' else concat l' r'
 end.

Partition

Fixpoint partition (f:elt->bool)(s : t) : t*t :=
  match s with
   | Leaf => (Leaf, Leaf)
   | Node _ l x r =>
      let (l1,l2) := partition f l in
      let (r1,r2) := partition f r in
      if f x then (join l1 x r1, concat l2 r2)
      else (concat l1 r1, join l2 x r2)
  end.

End Ops.

MakeRaw

Functor of pure functions + a posteriori proofs of invariant preservation
Module MakeRaw (Import I:Int)(X:OrderedType) <: RawSets X.
Include Ops I X.
Generic definition of binary-search-trees and proofs of specifications for generic functions such as mem or fold.
Include MSetGenTree.Props X I.
Automation and dedicated tactics
Local Hint Immediate MX.eq_sym : core.
Local Hint Unfold In lt_tree gt_tree Ok : core.
Local Hint Constructors InT bst : core.
Local Hint Resolve MX.eq_refl MX.eq_trans MX.lt_trans ok : core.
Local Hint Resolve lt_leaf gt_leaf lt_tree_node gt_tree_node : core.
Local Hint Resolve lt_tree_not_in lt_tree_trans gt_tree_not_in gt_tree_trans : core.
Local Hint Resolve elements_spec2 : core.

(* Sometimes functional induction will expose too much of
   a tree structure. The following tactic allows factoring back
   a Node whose internal parts occurs nowhere else. *)

(* TODO: why Ltac instead of Tactic Notation don't work ? why clear ? *)

Tactic Notation "factornode" ident(s) :=
 try clear s;
 match goal with
   | |- context [Node ?l ?x ?r ?h] =>
       set (s:=Node l x r h) in *; clearbody s; clear l x r h
   | _ : context [Node ?l ?x ?r ?h] |- _ =>
       set (s:=Node l x r h) in *; clearbody s; clear l x r h
 end.
Inductions principles for some of the set operators
Functional Scheme bal_ind := Induction for bal Sort Prop.
Functional Scheme remove_min_ind := Induction for remove_min Sort Prop.
Functional Scheme merge_ind := Induction for merge Sort Prop.
Functional Scheme concat_ind := Induction for concat Sort Prop.
Functional Scheme inter_ind := Induction for inter Sort Prop.
Functional Scheme diff_ind := Induction for diff Sort Prop.
Functional Scheme union_ind := Induction for union Sort Prop.
Notations and helper lemma about pairs and triples
Declare Scope pair_scope.

Notation "s #1" := (fst s) (at level 9, format "s '#1'") : pair_scope.
Notation "s #2" := (snd s) (at level 9, format "s '#2'") : pair_scope.
Notation "t #l" := (t_left t) (at level 9, format "t '#l'") : pair_scope.
Notation "t #b" := (t_in t) (at level 9, format "t '#b'") : pair_scope.
Notation "t #r" := (t_right t) (at level 9, format "t '#r'") : pair_scope.

Local Open Scope pair_scope.

Singleton set


forall (x : X.t) (y : elt), InT y (singleton x) <-> X.eq y x

forall (x : X.t) (y : elt), InT y (singleton x) <-> X.eq y x
unfold singleton; intuition_in. Qed.
x:X.t

Ok (singleton x)
x:X.t

Ok (singleton x)
unfold singleton; auto. Qed.

Helper functions


forall (l : t) (x : X.t) (r : t) (y : elt), InT y (create l x r) <-> X.eq y x \/ InT y l \/ InT y r

forall (l : t) (x : X.t) (r : t) (y : elt), InT y (create l x r) <-> X.eq y x \/ InT y l \/ InT y r
unfold create; split; [ inversion_clear 1 | ]; intuition. Qed.
l:tree
x:X.t
r:tree
H:Ok l
H0:Ok r
lt_tree0:lt_tree x l
gt_tree0:gt_tree x r

Ok (create l x r)
l:tree
x:X.t
r:tree
H:Ok l
H0:Ok r
lt_tree0:lt_tree x l
gt_tree0:gt_tree x r

Ok (create l x r)
unfold create; auto. Qed.

forall (l : t) (x : X.t) (r : t) (y : elt), InT y (bal l x r) <-> X.eq y x \/ InT y l \/ InT y r

forall (l : t) (x : X.t) (r : t) (y : elt), InT y (bal l x r) <-> X.eq y x \/ InT y l \/ InT y r
intros l x r; functional induction bal l x r; intros; try clear e0; rewrite !create_spec; intuition_in. Qed.
l:tree
x:X.t
r:tree
H:Ok l
H0:Ok r
lt_tree0:lt_tree x l
gt_tree0:gt_tree x r

Ok (bal l x r)
l:tree
x:X.t
r:tree
H:Ok l
H0:Ok r
lt_tree0:lt_tree x l
gt_tree0:gt_tree x r

Ok (bal l x r)
functional induction bal l x r; intros; inv; repeat apply create_ok; auto; unfold create; (apply lt_tree_node || apply gt_tree_node); auto; (eapply lt_tree_trans || eapply gt_tree_trans); eauto. Qed.

Insertion


forall (s : tree) (x : X.t) (y : elt), InT y (add x s) <-> X.eq y x \/ InT y s

forall (s : tree) (x : X.t) (y : elt), InT y (add x s) <-> X.eq y x \/ InT y s
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), InT y0 (add x0 l) <-> X.eq y0 x0 \/ InT y0 l
IHr:forall (x0 : X.t) (y0 : elt), InT y0 (add x0 r) <-> X.eq y0 x0 \/ InT y0 r
x:X.t
y:elt
H:X.eq x x'
H1:X.eq y x

InT y (Node i l x' r)
setoid_replace y with x'; eauto. Qed.

forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (add x s) <-> X.eq y x \/ InT y s

forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (add x s) <-> X.eq y x \/ InT y s
intros; apply add_spec'. Qed.
s:tree
x:X.t
H:Ok s

Ok (add x s)
s:tree
x:X.t
H:Ok s

Ok (add x s)
induct s x; auto; apply bal_ok; auto; intros y; rewrite add_spec'; intuition; order. Qed. Local Open Scope Int_scope.

Join

Function/Functional Scheme can't deal with internal fix. Let's do its job by hand:
Ltac join_tac :=
 let l := fresh "l" in
 intro l; induction l as [| lh ll _ lx lr Hlr];
   [ | intros x r; induction r as [| rh rl Hrl rx rr _]; unfold join;
     [ | destruct ((rh+2) <? lh) eqn:LT;
       [ match goal with |- context b [ bal ?a ?b ?c] =>
           replace (bal a b c)
           with (bal ll lx (join lr x (Node rh rl rx rr))); [ | auto]
         end
       | destruct ((lh+2) <? rh) eqn:LT';
         [ match goal with |- context b [ bal ?a ?b ?c] =>
             replace (bal a b c)
             with (bal (join (Node lh ll lx lr) x rl) rx rr); [ | auto]
           end
         | ] ] ] ]; intros.


forall (l : tree) (x : elt) (r : t) (y : elt), InT y (join l x r) <-> X.eq y x \/ InT y l \/ InT y r

forall (l : tree) (x : elt) (r : t) (y : elt), InT y (join l x r) <-> X.eq y x \/ InT y l \/ InT y r
x:elt
r:t
y:elt

InT y (join Leaf x r) <-> X.eq y x \/ InT y Leaf \/ InT y r
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x, y:elt
InT y (add x (Node lh ll lx lr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y Leaf
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = true
y:elt
InT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
y:elt
InT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = false
y:elt
InT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
x:elt
r:t
y:elt

InT y (add x r) <-> X.eq y x \/ InT y Leaf \/ InT y r
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x, y:elt
InT y (add x (Node lh ll lx lr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y Leaf
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = true
y:elt
InT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
y:elt
InT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = false
y:elt
InT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x, y:elt

InT y (add x (Node lh ll lx lr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y Leaf
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = true
y:elt
InT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
y:elt
InT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = false
y:elt
InT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = true
y:elt

InT y (bal ll lx (join lr x (Node rh rl rx rr))) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
y:elt
InT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = false
y:elt
InT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
y:elt

InT y (bal (join (Node lh ll lx lr) x rl) rx rr) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = false
y:elt
InT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
lh:I.t
ll:tree
lx:X.t
lr:tree
Hlr:forall (x0 : elt) (r : t) (y0 : elt), InT y0 (join lr x0 r) <-> X.eq y0 x0 \/ InT y0 lr \/ InT y0 r
x:elt
rh:I.t
rl:tree
rx:X.t
rr:tree
Hrl:forall y0 : elt, InT y0 (join (Node lh ll lx lr) x rl) <-> X.eq y0 x \/ InT y0 (Node lh ll lx lr) \/ InT y0 rl
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = false
y:elt

InT y (create (Node lh ll lx lr) x (Node rh rl rx rr)) <-> X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y (Node rh rl rx rr)
apply create_spec. Qed.

forall (l : tree) (x : X.t) (r : tree), Ok l -> Ok r -> lt_tree x l -> gt_tree x r -> Ok (join l x r)

forall (l : tree) (x : X.t) (r : tree), Ok l -> Ok r -> lt_tree x l -> gt_tree x r -> Ok (join l x r)
lh:I.t
ll:tree
lx:X.t
lr:tree
x:X.t
rh:I.t
rl:tree
rx:X.t
rr:tree
LT:(rh + 2 <? lh) = true
lt_tree0:lt_tree x (Node lh ll lx lr)
gt_tree0:gt_tree x (Node rh rl rx rr)
H5:Ok rl
H6:Ok rr
H7:lt_tree rx rl
H8:gt_tree rx rr
H4:Ok ll
H9:Ok lr
H10:lt_tree lx ll
H11:gt_tree lx lr
y:elt
H:X.eq y x \/ InT y lr \/ InT y (Node rh rl rx rr)

X.lt lx y
lh:I.t
ll:tree
lx:X.t
lr:tree
x:X.t
rh:I.t
rl:tree
rx:X.t
rr:tree
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
lt_tree0:lt_tree x (Node lh ll lx lr)
gt_tree0:gt_tree x (Node rh rl rx rr)
H5:Ok rl
H6:Ok rr
H7:lt_tree rx rl
H8:gt_tree rx rr
H4:Ok ll
H9:Ok lr
H10:lt_tree lx ll
H11:gt_tree lx lr
y:elt
H:X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y rl
X.lt y rx
lh:I.t
ll:tree
lx:X.t
lr:tree
x:X.t
rh:I.t
rl:tree
rx:X.t
rr:tree
LT:(rh + 2 <? lh) = false
LT':(lh + 2 <? rh) = true
lt_tree0:lt_tree x (Node lh ll lx lr)
gt_tree0:gt_tree x (Node rh rl rx rr)
H5:Ok rl
H6:Ok rr
H7:lt_tree rx rl
H8:gt_tree rx rr
H4:Ok ll
H9:Ok lr
H10:lt_tree lx ll
H11:gt_tree lx lr
y:elt
H:X.eq y x \/ InT y (Node lh ll lx lr) \/ InT y rl

X.lt y rx
intuition; [ setoid_replace y with x | ]; eauto. Qed.

Extraction of minimum element


forall (l : tree) (x : X.t) (r : tree) (y : elt) (h : I.t), InT y (Node h l x r) <-> X.eq y (remove_min l x r)#2 \/ InT y (remove_min l x r)#1

forall (l : tree) (x : X.t) (r : tree) (y : elt) (h : I.t), InT y (Node h l x r) <-> X.eq y (remove_min l x r)#2 \/ InT y (remove_min l x r)#1
x:elt
r:t
y:elt
h:I.t

InT y (Node h Leaf x r) <-> X.eq y x \/ InT y r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall (y0 : elt) (h0 : I.t), InT y0 (Node h0 ll lx lr) <-> X.eq y0 (remove_min ll lx lr)#2 \/ InT y0 (remove_min ll lx lr)#1
y:elt
h:I.t
InT y (Node h (Node _x ll lx lr) x r) <-> X.eq y m \/ InT y (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall (y0 : elt) (h0 : I.t), InT y0 (Node h0 ll lx lr) <-> X.eq y0 (remove_min ll lx lr)#2 \/ InT y0 (remove_min ll lx lr)#1
y:elt
h:I.t

InT y (Node h (Node _x ll lx lr) x r) <-> X.eq y m \/ InT y (bal l' x r)
rewrite bal_spec, In_node_iff, IHp, e0; simpl; intuition. Qed.
l:tree
x:X.t
r:tree

forall h : I.t, Ok (Node h l x r) -> Ok (remove_min l x r)#1
l:tree
x:X.t
r:tree

forall h : I.t, Ok (Node h l x r) -> Ok (remove_min l x r)#1
x:elt
r:t
h:I.t
H:Ok (Node h Leaf x r)

Ok r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
Ok (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)

Ok (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)

Ok (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> Ok (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

Ok (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

Ok (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

Ok r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)
lt_tree x l'
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)
gt_tree x r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

lt_tree x l'
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)
gt_tree x r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
y:elt
L:InT y (Node _x ll lx lr) -> X.lt y x

InT y l' -> X.lt y x
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)
gt_tree x r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:Ok l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

gt_tree x r
inv; auto. Qed.

forall (l : tree) (x : X.t) (r : tree) (h : I.t), Ok (Node h l x r) -> gt_tree (remove_min l x r)#2 (remove_min l x r)#1

forall (l : tree) (x : X.t) (r : tree) (h : I.t), Ok (Node h l x r) -> gt_tree (remove_min l x r)#2 (remove_min l x r)#1
x:elt
r:t
h:I.t
H:Ok (Node h Leaf x r)

gt_tree x r
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
gt_tree m (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)

gt_tree m (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)

gt_tree m (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:forall h0 : I.t, Ok (Node h0 ll lx lr) -> gt_tree (remove_min ll lx lr)#2 (remove_min ll lx lr)#1
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

gt_tree m (bal l' x r)
x:elt
r:t
_x:I.t
ll:tree
lx:X.t
lr:tree
l':t
m:elt
e0:remove_min ll lx lr = (l', m)
IHp:gt_tree m l'
h:I.t
H:Ok (Node h (Node _x ll lx lr) x r)
O:Ok (Node _x ll lx lr)
L:lt_tree x (Node _x ll lx lr)

gt_tree m (bal l' x r)
intro y; rewrite bal_spec; intuition; specialize (L m); rewrite remove_min_spec, e0 in L; simpl in L; [setoid_replace y with x|inv]; eauto. Qed. Local Hint Resolve remove_min_gt_tree : core.

Merging two trees


forall (s1 s2 : tree) (y : elt), InT y (merge s1 s2) <-> InT y s1 \/ InT y s2

forall (s1 s2 : tree) (y : elt), InT y (merge s1 s2) <-> InT y s1 \/ InT y s2
s2:tree
y:elt

InT y s2 <-> InT y Leaf \/ InT y s2
y:elt
s1:tree
InT y s1 <-> InT y s1 \/ InT y Leaf
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
y:elt
s1:tree
InT y (bal s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)
y:elt
s1:tree

InT y s1 <-> InT y s1 \/ InT y Leaf
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
y:elt
s1:tree
InT y (bal s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
y:elt
s1:tree

InT y (bal s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)
rewrite bal_spec, remove_min_spec, e1; simpl; intuition. Qed.
s1, s2:tree

Ok s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (merge s1 s2)
s1, s2:tree

Ok s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (merge s1 s2)
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

Ok (bal s1 m s2')
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

Ok s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
lt_tree m s1
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

lt_tree m s1
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
y:elt
Hy:InT y s1

X.lt y m
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
y:elt
Hy:InT y s1

InT m (Node _x3 l2 x2 r2)
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

gt_tree m s2'
change (gt_tree (s2',m)#2 (s2',m)#1); rewrite <-e1; eauto. Qed.

Deletion


forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (remove x s) <-> InT y s /\ ~ X.eq y x

forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (remove x s) <-> InT y s /\ ~ X.eq y x
x:X.t
y:elt
H:Ok Leaf

InT y Leaf <-> InT y Leaf /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (merge l r) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (merge l r) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ (X.eq y0 x0 -> False)
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ (X.eq y0 x0 -> False)
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
H2:X.eq y x -> False
H3:X.eq y x'

InT y l \/ InT y r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (bal (remove x l) x' r) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (remove x0 l) <-> InT y0 l /\ ~ X.eq y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (remove x0 r) <-> InT y0 r /\ ~ X.eq y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (bal l x' (remove x r)) <-> InT y (Node i l x' r) /\ ~ X.eq y x
rewrite bal_spec, IHr; clear IHl IHr; intuition; [order|order|intuition_in]. Qed.
s:tree
x:X.t
H:Ok s

Ok (remove x s)
s:tree
x:X.t
H:Ok s

Ok (remove x s)
x:X.t
H:Ok Leaf

Ok Leaf
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (merge l r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (bal (remove x l) x' r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (bal l x' (remove x r))
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (merge l r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (bal (remove x l) x' r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (bal l x' (remove x r))
(* EQ *)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (bal (remove x l) x' r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (bal l x' (remove x r))
(* LT *)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

lt_tree x' (remove x l)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (bal l x' (remove x r))
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (bal l x' (remove x r))
(* GT *)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (remove x l)
IHr:Ok r -> Ok (remove x r)
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

gt_tree x' (remove x r)
intro z; rewrite remove_spec; auto; destruct 1; eauto. Qed.

Concatenation


forall (s1 s2 : tree) (y : elt), InT y (concat s1 s2) <-> InT y s1 \/ InT y s2

forall (s1 s2 : tree) (y : elt), InT y (concat s1 s2) <-> InT y s1 \/ InT y s2
s2:tree
y:elt

InT y s2 <-> InT y Leaf \/ InT y s2
y:elt
s1:tree
InT y s1 <-> InT y s1 \/ InT y Leaf
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
y:elt
s1:tree
InT y (join s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)
y:elt
s1:tree

InT y s1 <-> InT y s1 \/ InT y Leaf
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
y:elt
s1:tree
InT y (join s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
y:elt
s1:tree

InT y (join s1 m s2') <-> InT y s1 \/ InT y (Node _x3 l2 x2 r2)
rewrite join_spec, remove_min_spec, e1; simpl; intuition. Qed.
s1, s2:tree

Ok s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (concat s1 s2)
s1, s2:tree

Ok s1 -> Ok s2 -> (forall y1 y2 : elt, InT y1 s1 -> InT y2 s2 -> X.lt y1 y2) -> Ok (concat s1 s2)
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

Ok (join s1 m s2')
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

Ok s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
lt_tree m s1
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

lt_tree m s1
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
y:elt
Hy:InT y s1

X.lt y m
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
y:elt
Hy:InT y s1

InT m (Node _x3 l2 x2 r2)
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2
gt_tree m s2'
_x3:I.t
l2:tree
x2:X.t
r2:tree
s2':t
m:elt
e1:remove_min l2 x2 r2 = (s2', m)
s1:tree
H:Ok s1
H0:Ok (Node _x3 l2 x2 r2)
H1:forall y1 y2 : elt, InT y1 s1 -> InT y2 (Node _x3 l2 x2 r2) -> X.lt y1 y2

gt_tree m s2'
change (gt_tree (s2',m)#2 (s2',m)#1); rewrite <-e1; eauto. Qed.

Splitting


forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#l <-> InT y s /\ X.lt y x

forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#l <-> InT y s /\ X.lt y x
x:X.t
y:elt
H:Ok Leaf

InT y Leaf <-> InT y Leaf /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (<< l, true, r >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (<< l, true, r >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
x:X.t
y:elt
IHl:Ok l -> InT y (split x l)#l <-> InT y l /\ X.lt y x
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
x:X.t
y:elt
t_left0:t
t_in0:bool
t_right0:t
IHl:Ok l -> InT y t_left0 <-> InT y l /\ X.lt y x
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y t_left0 <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#l <-> InT y0 r /\ X.lt y0 x0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
x:X.t
y:elt
IHr:Ok r -> InT y (split x r)#l <-> InT y r /\ X.lt y x
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l <-> InT y (Node i l x' r) /\ X.lt y x
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#l <-> InT y0 l /\ X.lt y0 x0
x:X.t
y:elt
t_left0:t
t_in0:bool
t_right0:t
IHr:Ok r -> InT y t_left0 <-> InT y r /\ X.lt y x
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (join l x' t_left0) <-> InT y (Node i l x' r) /\ X.lt y x
rewrite join_spec, IHr; intuition_in; order. Qed.

forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#r <-> InT y s /\ X.lt x y

forall (s : tree) (x : X.t) (y : elt), Ok s -> InT y (split x s)#r <-> InT y s /\ X.lt x y
x:X.t
y:elt
H:Ok Leaf

InT y Leaf <-> InT y Leaf /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (<< l, true, r >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (<< l, true, r >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
x:X.t
y:elt
IHl:Ok l -> InT y (split x l)#r <-> InT y l /\ X.lt x y
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
x:X.t
y:elt
t_left0:t
t_in0:bool
t_right0:t
IHl:Ok l -> InT y t_right0 <-> InT y l /\ X.lt x y
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (join t_right0 x' r) <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
IHr:forall (x0 : X.t) (y0 : elt), Ok r -> InT y0 (split x0 r)#r <-> InT y0 r /\ X.lt x0 y0
x:X.t
y:elt
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
x:X.t
y:elt
IHr:Ok r -> InT y (split x r)#r <-> InT y r /\ X.lt x y
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r <-> InT y (Node i l x' r) /\ X.lt x y
i:I.t
l:tree
x':X.t
r:tree
IHl:forall (x0 : X.t) (y0 : elt), Ok l -> InT y0 (split x0 l)#r <-> InT y0 l /\ X.lt x0 y0
x:X.t
y:elt
t_left0:t
t_in0:bool
t_right0:t
IHr:Ok r -> InT y t_right0 <-> InT y r /\ X.lt x y
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

InT y t_right0 <-> InT y (Node i l x' r) /\ X.lt x y
rewrite IHr; intuition_in; order. Qed.

forall (s : tree) (x : X.t), Ok s -> (split x s)#b = true <-> InT x s

forall (s : tree) (x : X.t), Ok s -> (split x s)#b = true <-> InT x s
x:X.t
H:Ok Leaf

false = true <-> InT x Leaf
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(<< l, true, r >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.eq x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(<< l, true, r >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> (split x l)#b = true <-> InT x l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
x:X.t
t_left0:t
t_in0:bool
t_right0:t
IHl:Ok l -> t_in0 = true <-> InT x l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

t_in0 = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
IHr:forall x0 : X.t, Ok r -> (split x0 r)#b = true <-> InT x0 r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
x:X.t
IHr:Ok r -> (split x r)#b = true <-> InT x r
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#b = true <-> InT x (Node i l x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> (split x0 l)#b = true <-> InT x0 l
x:X.t
t_left0:t
t_in0:bool
t_right0:t
IHr:Ok r -> t_in0 = true <-> InT x r
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

t_in0 = true <-> InT x (Node i l x' r)
rewrite IHr; intuition_in; order. Qed.

forall (s : tree) (x : X.t), Ok s -> Ok (split x s)#l /\ Ok (split x s)#r

forall (s : tree) (x : X.t), Ok s -> Ok (split x s)#l /\ Ok (split x s)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l /\ Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (split x l)#l /\ Ok (split x l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l /\ Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
x:X.t
IHl:Ok l -> Ok (split x l)#l /\ Ok (split x l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(forall y : elt, InT y (split x l)#r <-> InT y l /\ X.lt x y) -> Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#l /\ Ok (let (ll, b, rl) := split x l in << ll, b, join rl x' r >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
x:X.t
t_left0:t
t_in0:bool
t_right0:t
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
H:forall y : elt, InT y t_right0 <-> InT y l /\ X.lt x y
H2:Ok t_left0
H3:Ok t_right0

Ok (join t_right0 x' r)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
x:X.t
t_left0:t
t_in0:bool
t_right0:t
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
H0:X.lt x x'
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
H:forall y : elt, InT y t_right0 <-> InT y l /\ X.lt x y
H2:Ok t_left0
H3:Ok t_right0

lt_tree x' t_right0
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
IHr:forall x0 : X.t, Ok r -> Ok (split x0 r)#l /\ Ok (split x0 r)#r
x:X.t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
x:X.t
IHr:Ok r -> Ok (split x r)#l /\ Ok (split x r)#r
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
x:X.t
IHr:Ok r -> Ok (split x r)#l /\ Ok (split x r)#r
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r

(forall y : elt, InT y (split x r)#l <-> InT y r /\ X.lt y x) -> Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#l /\ Ok (let (rl, b, rr) := split x r in << join l x' rl, b, rr >>)#r
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
x:X.t
t_left0:t
t_in0:bool
t_right0:t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
H:forall y : elt, InT y t_left0 <-> InT y r /\ X.lt y x
H2:Ok t_left0
H3:Ok t_right0

Ok (join l x' t_left0)
i:I.t
l:tree
x':X.t
r:tree
IHl:forall x0 : X.t, Ok l -> Ok (split x0 l)#l /\ Ok (split x0 l)#r
x:X.t
t_left0:t
t_in0:bool
t_right0:t
H0:X.lt x' x
H5:Ok l
H6:Ok r
H7:lt_tree x' l
H8:gt_tree x' r
H:forall y : elt, InT y t_left0 <-> InT y r /\ X.lt y x
H2:Ok t_left0
H3:Ok t_right0

gt_tree x' t_left0
intros y; rewrite H; intuition. Qed.
s:tree
x:X.t
H:Ok s

Ok (split x s)#l
s:tree
x:X.t
H:Ok s

Ok (split x s)#l
intros; destruct (@split_ok s x); auto. Qed.
s:tree
x:X.t
H:Ok s

Ok (split x s)#r
s:tree
x:X.t
H:Ok s

Ok (split x s)#r
intros; destruct (@split_ok s x); auto. Qed.

Intersection

Ltac destruct_split := match goal with
 | H : split ?x ?s = << ?u, ?v, ?w >> |- _ =>
   assert ((split x s)#l = u) by (rewrite H; auto);
   assert ((split x s)#b = v) by (rewrite H; auto);
   assert ((split x s)#r = w) by (rewrite H; auto);
   clear H; subst u w
 end.


forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (inter s1 s2) /\ (forall y : elt, InT y (inter s1 s2) <-> InT y s1 /\ InT y s2)

forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (inter s1 s2) /\ (forall y : elt, InT y (inter s1 s2) <-> InT y s1 /\ InT y s2)
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#r

Ok (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r))
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
InT y (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#r
Ok (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r))
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
InT y (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#r

Ok (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r))
apply join_ok; auto with *; intro y; rewrite ?IHi1, ?IHi2; intuition.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt

InT y (join (inter l1 (split x1 s2)#l) x1 (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
H1:X.eq y x1

InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
H1:X.eq y x1

InT x1 s2
rewrite <- split_spec3; auto.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (inter l1 (split x1 s2)#l) <-> InT y l1 /\ InT y (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (inter r1 (split x1 s2)#r) <-> InT y r1 /\ InT y (split x1 s2)#r

Ok (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r))
apply concat_ok; auto with *; intros y1 y2; rewrite IHi1, IHi2; intuition; order.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt

InT y (concat (inter l1 (split x1 s2)#l) (inter r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt

InT y l1 /\ InT y s2 /\ X.lt y x1 \/ InT y r1 /\ InT y s2 /\ X.lt x1 y <-> InT y (Node _x l1 x1 r1) /\ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
H2:InT y s2
H3:X.eq y x1

InT y l1 /\ InT y s2 /\ X.lt y x1 \/ InT y r1 /\ InT y s2 /\ X.lt x1 y
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
H2:InT y s2
H3:X.eq y x1

~ InT x1 s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
H2:InT y s2
H3:X.eq y x1
InT x1 s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHo1:Ok (inter l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (inter l1 (split x1 s2)#l) <-> InT y0 l1 /\ InT y0 (split x1 s2)#l
IHo2:Ok (inter r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (inter r1 (split x1 s2)#r) <-> InT y0 r1 /\ InT y0 (split x1 s2)#r
y:elt
H2:InT y s2
H3:X.eq y x1

InT x1 s2
setoid_replace x1 with y; auto. Qed.

forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (inter s1 s2) <-> InT y s1 /\ InT y s2

forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (inter s1 s2) <-> InT y s1 /\ InT y s2
intros; destruct (@inter_spec_ok s1 s2); auto. Qed.
s1, s2:tree
H:Ok s1
H0:Ok s2

Ok (inter s1 s2)
s1, s2:tree
H:Ok s1
H0:Ok s2

Ok (inter s1 s2)
intros; destruct (@inter_spec_ok s1 s2); auto. Qed.

Difference


forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (diff s1 s2) /\ (forall y : elt, InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2)

forall s1 s2 : tree, Ok s1 -> Ok s2 -> Ok (diff s1 s2) /\ (forall y : elt, InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2)
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#r

Ok (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r))
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#r
y:elt
InT y (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#r
Ok (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r))
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#r
y:elt
InT y (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#r

Ok (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r))
apply concat_ok; auto; intros y1 y2; rewrite IHi1, IHi2; intuition; order.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#r
y:elt

InT y (concat (diff l1 (split x1 s2)#l) (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H2:InT y s2 -> False
H3:X.eq y x1

InT y l1 /\ (InT y s2 /\ X.lt y x1 -> False) \/ InT y r1 /\ (InT y s2 /\ X.lt x1 y -> False)
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H2:InT y s2 -> False
H3:X.eq y x1

~ InT x1 s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H2:InT y s2 -> False
H3:X.eq y x1
InT x1 s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H2:InT y s2 -> False
H3:X.eq y x1

~ InT x1 s2
setoid_replace x1 with y; auto.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = true
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H2:InT y s2 -> False
H3:X.eq y x1

InT x1 s2
rewrite <- split_spec3; auto; congruence.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y : elt, InT y (diff l1 (split x1 s2)#l) <-> InT y l1 /\ ~ InT y (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y : elt, InT y (diff r1 (split x1 s2)#r) <-> InT y r1 /\ ~ InT y (split x1 s2)#r

Ok (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r))
apply join_ok; auto; intro y; rewrite ?IHi1, ?IHi2; intuition.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#r
y:elt

InT y (join (diff l1 (split x1 s2)#l) x1 (diff r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ ~ InT y0 (split x1 s2)#l
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ ~ InT y0 (split x1 s2)#r
y:elt

X.eq y x1 \/ InT y l1 /\ ~ (InT y s2 /\ X.lt y x1) \/ InT y r1 /\ ~ (InT y s2 /\ X.lt x1 y) <-> InT y (Node _x l1 x1 r1) /\ ~ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H1:X.eq y x1
H:InT y s2

False
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H1:X.eq y x1
H:InT y s2

~ InT x1 s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H1:X.eq y x1
H:InT y s2
InT x1 s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H1:X.eq y x1
H:InT y s2

~ InT x1 s2
rewrite <- split_spec3; auto; congruence.
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
B2:Ok s2
H0:(split x1 s2)#b = false
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
IHb1:Ok (diff l1 (split x1 s2)#l)
IHi1:forall y0 : elt, InT y0 (diff l1 (split x1 s2)#l) <-> InT y0 l1 /\ (InT y0 (split x1 s2)#l -> False)
IHb2:Ok (diff r1 (split x1 s2)#r)
IHi2:forall y0 : elt, InT y0 (diff r1 (split x1 s2)#r) <-> InT y0 r1 /\ (InT y0 (split x1 s2)#r -> False)
y:elt
H1:X.eq y x1
H:InT y s2

InT x1 s2
setoid_replace x1 with y; auto. Qed.

forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2

forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (diff s1 s2) <-> InT y s1 /\ ~ InT y s2
intros; destruct (@diff_spec_ok s1 s2); auto. Qed.
s1, s2:tree
H:Ok s1
H0:Ok s2

Ok (diff s1 s2)
s1, s2:tree
H:Ok s1
H0:Ok s2

Ok (diff s1 s2)
intros; destruct (@diff_spec_ok s1 s2); auto. Qed.

Union


forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (union s1 s2) <-> InT y s1 \/ InT y s2

forall (s1 s2 : tree) (y : elt), Ok s1 -> Ok s2 -> InT y (union s1 s2) <-> InT y s1 \/ InT y s2
s2:tree
y:elt
B1:Ok Leaf
B2:Ok s2

InT y s2 <-> InT y Leaf \/ InT y s2
_x:I.t
l1:tree
x1:X.t
r1:tree
y:elt
B1:Ok (Node _x l1 x1 r1)
B2:Ok Leaf
InT y (Node _x l1 x1 r1) <-> InT y (Node _x l1 x1 r1) \/ InT y Leaf
_x:I.t
l1:tree
x1:X.t
r1:tree
_x0:I.t
_x1:tree
_x2:X.t
_x3:tree
l2':t
_x4:bool
r2':t
e1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>
IHt0:forall y0 : elt, Ok l1 -> Ok l2' -> InT y0 (union l1 l2') <-> InT y0 l1 \/ InT y0 l2'
IHt1:forall y0 : elt, Ok r1 -> Ok r2' -> InT y0 (union r1 r2') <-> InT y0 r1 \/ InT y0 r2'
y:elt
B1:Ok (Node _x l1 x1 r1)
B2:Ok (Node _x0 _x1 _x2 _x3)
InT y (join (union l1 l2') x1 (union r1 r2')) <-> InT y (Node _x l1 x1 r1) \/ InT y (Node _x0 _x1 _x2 _x3)
_x:I.t
l1:tree
x1:X.t
r1:tree
y:elt
B1:Ok (Node _x l1 x1 r1)
B2:Ok Leaf

InT y (Node _x l1 x1 r1) <-> InT y (Node _x l1 x1 r1) \/ InT y Leaf
_x:I.t
l1:tree
x1:X.t
r1:tree
_x0:I.t
_x1:tree
_x2:X.t
_x3:tree
l2':t
_x4:bool
r2':t
e1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>
IHt0:forall y0 : elt, Ok l1 -> Ok l2' -> InT y0 (union l1 l2') <-> InT y0 l1 \/ InT y0 l2'
IHt1:forall y0 : elt, Ok r1 -> Ok r2' -> InT y0 (union r1 r2') <-> InT y0 r1 \/ InT y0 r2'
y:elt
B1:Ok (Node _x l1 x1 r1)
B2:Ok (Node _x0 _x1 _x2 _x3)
InT y (join (union l1 l2') x1 (union r1 r2')) <-> InT y (Node _x l1 x1 r1) \/ InT y (Node _x0 _x1 _x2 _x3)
_x:I.t
l1:tree
x1:X.t
r1:tree
_x0:I.t
_x1:tree
_x2:X.t
_x3:tree
l2':t
_x4:bool
r2':t
e1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>
IHt0:forall y0 : elt, Ok l1 -> Ok l2' -> InT y0 (union l1 l2') <-> InT y0 l1 \/ InT y0 l2'
IHt1:forall y0 : elt, Ok r1 -> Ok r2' -> InT y0 (union r1 r2') <-> InT y0 r1 \/ InT y0 r2'
y:elt
B1:Ok (Node _x l1 x1 r1)
B2:Ok (Node _x0 _x1 _x2 _x3)

InT y (join (union l1 l2') x1 (union r1 r2')) <-> InT y (Node _x l1 x1 r1) \/ InT y (Node _x0 _x1 _x2 _x3)
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
IHt0:forall y0 : elt, Ok l1 -> Ok (split x1 s2)#l -> InT y0 (union l1 (split x1 s2)#l) <-> InT y0 l1 \/ InT y0 (split x1 s2)#l
IHt1:forall y0 : elt, Ok r1 -> Ok (split x1 s2)#r -> InT y0 (union r1 (split x1 s2)#r) <-> InT y0 r1 \/ InT y0 (split x1 s2)#r
y:elt
B2:Ok s2
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1

InT y (join (union l1 (split x1 s2)#l) x1 (union r1 (split x1 s2)#r)) <-> InT y (Node _x l1 x1 r1) \/ InT y s2
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
IHt0:forall y0 : elt, Ok l1 -> Ok (split x1 s2)#l -> InT y0 (union l1 (split x1 s2)#l) <-> InT y0 l1 \/ InT y0 (split x1 s2)#l
IHt1:forall y0 : elt, Ok r1 -> Ok (split x1 s2)#r -> InT y0 (union r1 (split x1 s2)#r) <-> InT y0 r1 \/ InT y0 (split x1 s2)#r
y:elt
B2:Ok s2
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1

X.eq y x1 \/ (InT y l1 \/ InT y s2 /\ X.lt y x1) \/ InT y r1 \/ InT y s2 /\ X.lt x1 y <-> InT y (Node _x l1 x1 r1) \/ InT y s2
destruct (X.compare_spec y x1); intuition_in. Qed.
s1, s2:tree

Ok s1 -> Ok s2 -> Ok (union s1 s2)
s1, s2:tree

Ok s1 -> Ok s2 -> Ok (union s1 s2)
_x:I.t
l1:tree
x1:X.t
r1:tree
_x0:I.t
_x1:tree
_x2:X.t
_x3:tree
l2':t
_x4:bool
r2':t
e1:split x1 (Node _x0 _x1 _x2 _x3) = << l2', _x4, r2' >>
IHt0:Ok l1 -> Ok l2' -> Ok (union l1 l2')
IHt1:Ok r1 -> Ok r2' -> Ok (union r1 r2')
B1:Ok (Node _x l1 x1 r1)
B2:Ok (Node _x0 _x1 _x2 _x3)

Ok (join (union l1 l2') x1 (union r1 r2'))
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
IHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)
IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)
B2:Ok s2
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1

Ok (join (union l1 (split x1 s2)#l) x1 (union r1 (split x1 s2)#r))
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
IHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)
IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)
B2:Ok s2
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1

lt_tree x1 (union l1 (split x1 s2)#l)
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
IHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)
IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)
B2:Ok s2
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1
gt_tree x1 (union r1 (split x1 s2)#r)
_x:I.t
l1:tree
x1:X.t
r1, s2:tree
IHt0:Ok l1 -> Ok (split x1 s2)#l -> Ok (union l1 (split x1 s2)#l)
IHt1:Ok r1 -> Ok (split x1 s2)#r -> Ok (union r1 (split x1 s2)#r)
B2:Ok s2
H4:Ok l1
H5:Ok r1
H6:lt_tree x1 l1
H7:gt_tree x1 r1

gt_tree x1 (union r1 (split x1 s2)#r)
intro y; rewrite union_spec, split_spec2; intuition_in. Qed.

Filter


forall (s : tree) (x : elt) (f : X.t -> bool), Proper (X.eq ==> Logic.eq) f -> InT x (filter f s) <-> InT x s /\ f x = true

forall (s : tree) (x : elt) (f : X.t -> bool), Proper (X.eq ==> Logic.eq) f -> InT x (filter f s) <-> InT x s /\ f x = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f

InT x Leaf <-> InT x Leaf /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
InT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f

InT x Leaf <-> InT x Leaf /\ f x = true
intuition_in.
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f

InT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = true

InT x (join (filter f l) x0 (filter f r)) <-> InT x (Node h l x0 r) /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = false
InT x (concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = true

InT x (join (filter f l) x0 (filter f r)) <-> InT x (Node h l x0 r) /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = true
H0:X.eq x x0

f x = true
now setoid_replace x with x0.
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = false

InT x (concat (filter f l) (filter f r)) <-> InT x (Node h l x0 r) /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = false
H1:f x = true
H2:X.eq x x0

InT x l /\ f x = true \/ InT x r /\ f x = true
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 l) <-> InT x1 l /\ f0 x1 = true
Hr:forall (x1 : elt) (f0 : X.t -> bool), Proper (X.eq ==> Logic.eq) f0 -> InT x1 (filter f0 r) <-> InT x1 r /\ f0 x1 = true
x:elt
f:X.t -> bool
Hf:Proper (X.eq ==> Logic.eq) f
Hx0:f x0 = false
H1:f x = true
H2:X.eq x x0
H:f x = f x0

InT x l /\ f x = true \/ InT x r /\ f x = true
congruence. Qed.

forall (s : tree) (x : elt) (f : elt -> bool), InT x (filter f s) -> InT x s

forall (s : tree) (x : elt) (f : elt -> bool), InT x (filter f s) -> InT x s
x:elt
f:elt -> bool

InT x Leaf -> InT x Leaf
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 l
Hr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 r
x:elt
f:elt -> bool
InT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)
x:elt
f:elt -> bool

InT x Leaf -> InT x Leaf
trivial.
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 l
Hr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 r
x:elt
f:elt -> bool

InT x (if f x0 then join (filter f l) x0 (filter f r) else concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 l
Hr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 r
x:elt
f:elt -> bool

InT x (join (filter f l) x0 (filter f r)) -> InT x (Node h l x0 r)
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 l
Hr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 r
x:elt
f:elt -> bool
InT x (concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 l
Hr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 r
x:elt
f:elt -> bool

InT x (join (filter f l) x0 (filter f r)) -> InT x (Node h l x0 r)
rewrite join_spec; intuition_in; eauto.
h:I.t
l:tree
x0:X.t
r:tree
Hl:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 l) -> InT x1 l
Hr:forall (x1 : elt) (f0 : elt -> bool), InT x1 (filter f0 r) -> InT x1 r
x:elt
f:elt -> bool

InT x (concat (filter f l) (filter f r)) -> InT x (Node h l x0 r)
rewrite concat_spec; intuition_in; eauto. Qed.
s:tree
f:elt -> bool
H:Ok s

Ok (filter f s)
s:tree
f:elt -> bool
H:Ok s

Ok (filter f s)
f:elt -> bool

Ok (filter f Leaf)
f:elt -> bool
h:I.t
x:X.t
l, r:tree
Hl:bst l
Hr:bst r
Hlt:lt_tree x l
Hgt:gt_tree x r
Hfl:Ok (filter f l)
Hfr:Ok (filter f r)
Ok (filter f (Node h l x r))
f:elt -> bool

Ok (filter f Leaf)
constructor.
f:elt -> bool
h:I.t
x:X.t
l, r:tree
Hl:bst l
Hr:bst r
Hlt:lt_tree x l
Hgt:gt_tree x r
Hfl:Ok (filter f l)
Hfr:Ok (filter f r)

Ok (filter f (Node h l x r))
f:elt -> bool
h:I.t
x:X.t
l, r:tree
Hl:bst l
Hr:bst r
Hlt:lt_tree x l
Hgt:gt_tree x r
Hfl:Ok (filter f l)
Hfr:Ok (filter f r)

Ok (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))
f:elt -> bool
h:I.t
x:X.t
l, r:tree
Hl:bst l
Hr:bst r
Hlt:lt_tree x l
Hgt:gt_tree x r
Hfl:Ok (filter f l)
Hfr:Ok (filter f r)
H:lt_tree x (filter f l)

Ok (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))
f:elt -> bool
h:I.t
x:X.t
l, r:tree
Hl:bst l
Hr:bst r
Hlt:lt_tree x l
Hgt:gt_tree x r
Hfl:Ok (filter f l)
Hfr:Ok (filter f r)
H:lt_tree x (filter f l)
H0:gt_tree x (filter f r)

Ok (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))
destruct (f x); eauto using concat_ok, join_ok. Qed.

Partition

s:t
f:elt -> bool

(partition f s)#1 = filter f s
s:t
f:elt -> bool

(partition f s)#1 = filter f s
f:elt -> bool

Leaf = Leaf
h:I.t
l:tree
x:X.t
r:tree
f:elt -> bool
Hl:(partition f l)#1 = filter f l
Hr:(partition f r)#1 = filter f r
(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#1 = (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))
f:elt -> bool

Leaf = Leaf
trivial.
h:I.t
l:tree
x:X.t
r:tree
f:elt -> bool
Hl:(partition f l)#1 = filter f l
Hr:(partition f r)#1 = filter f r

(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#1 = (if f x then join (filter f l) x (filter f r) else concat (filter f l) (filter f r))
h:I.t
l:tree
x:X.t
r:tree
f:elt -> bool
Hl:(partition f l)#1 = filter f l
Hr:(partition f r)#1 = filter f r

(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#1 = (if f x then join (partition f l)#1 x (partition f r)#1 else concat (partition f l)#1 (partition f r)#1)
now destruct (partition f l), (partition f r), (f x). Qed.
s:t
f:elt -> bool

(partition f s)#2 = filter (fun x : elt => negb (f x)) s
s:t
f:elt -> bool

(partition f s)#2 = filter (fun x : elt => negb (f x)) s
f:elt -> bool

Leaf = Leaf
h:I.t
l:tree
x:X.t
r:tree
f:elt -> bool
Hl:(partition f l)#2 = filter (fun x0 : elt => negb (f x0)) l
Hr:(partition f r)#2 = filter (fun x0 : elt => negb (f x0)) r
(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#2 = (if negb (f x) then join (filter (fun x0 : elt => negb (f x0)) l) x (filter (fun x0 : elt => negb (f x0)) r) else concat (filter (fun x0 : elt => negb (f x0)) l) (filter (fun x0 : elt => negb (f x0)) r))
f:elt -> bool

Leaf = Leaf
trivial.
h:I.t
l:tree
x:X.t
r:tree
f:elt -> bool
Hl:(partition f l)#2 = filter (fun x0 : elt => negb (f x0)) l
Hr:(partition f r)#2 = filter (fun x0 : elt => negb (f x0)) r

(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#2 = (if negb (f x) then join (filter (fun x0 : elt => negb (f x0)) l) x (filter (fun x0 : elt => negb (f x0)) r) else concat (filter (fun x0 : elt => negb (f x0)) l) (filter (fun x0 : elt => negb (f x0)) r))
h:I.t
l:tree
x:X.t
r:tree
f:elt -> bool
Hl:(partition f l)#2 = filter (fun x0 : elt => negb (f x0)) l
Hr:(partition f r)#2 = filter (fun x0 : elt => negb (f x0)) r

(let (l1, l2) := partition f l in let (r1, r2) := partition f r in if f x then (join l1 x r1, concat l2 r2) else (concat l1 r1, join l2 x r2))#2 = (if negb (f x) then join (partition f l)#2 x (partition f r)#2 else concat (partition f l)#2 (partition f r)#2)
now destruct (partition f l), (partition f r), (f x). Qed.
s:t
f:X.t -> bool

Proper (X.eq ==> Logic.eq) f -> Equal (partition f s)#1 (filter f s)
s:t
f:X.t -> bool

Proper (X.eq ==> Logic.eq) f -> Equal (partition f s)#1 (filter f s)
now rewrite partition_spec1'. Qed.
s:t
f:X.t -> bool

Proper (X.eq ==> Logic.eq) f -> Equal (partition f s)#2 (filter (fun x : elt => negb (f x)) s)
s:t
f:X.t -> bool

Proper (X.eq ==> Logic.eq) f -> Equal (partition f s)#2 (filter (fun x : elt => negb (f x)) s)
now rewrite partition_spec2'. Qed.
s:tree
f:elt -> bool
H:Ok s

Ok (partition f s)#1
s:tree
f:elt -> bool
H:Ok s

Ok (partition f s)#1
rewrite partition_spec1'; now apply filter_ok. Qed.
s:tree
f:elt -> bool
H:Ok s

Ok (partition f s)#2
s:tree
f:elt -> bool
H:Ok s

Ok (partition f s)#2
rewrite partition_spec2'; now apply filter_ok. Qed. End MakeRaw.

Encapsulation

Now, in order to really provide a functor implementing S, we need to encapsulate everything into a type of binary search trees. They also happen to be well-balanced, but this has no influence on the correctness of operations, so we won't state this here, see MSetFullAVL if you need more than just the MSet interface.
Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X.
 Module Raw := MakeRaw I X.
 Include Raw2Sets X Raw.
End IntMake.

(* For concrete use inside Coq, we propose an instantiation of [Int] by [Z]. *)

Module Make (X: OrderedType) <: S with Module E := X
 :=IntMake(Z_as_Int)(X).