Definition key := Key.A.Definition data := Val.data.Module M := More_Dec_Orders Key.(* search trees definitions and properties *)

 (* the underlying data structure : binary trees labeled 
    with keys and associated values *)

 Inductive btree : Set :=
   | leaf : btree
   | bnode : key -> data -> btree -> btree -> btree.(* search trees definitions and properties *)

 (* the underlying data structure : binary trees labeled 
    with keys and associated values *)

 Inductive btree : Set :=
   | leaf : btree
   | bnode : key -> data -> btree -> btree -> btree.(* search trees definitions and properties *)

 (* the underlying data structure : binary trees labeled 
    with keys and associated values *)

 Inductive btree : Set :=
   | leaf : btree
   | bnode : key -> data -> btree -> btree -> btree.(* The entry with key k and value v occurs in the binary tree t *)

 Inductive occ (v : data) (k : key) : btree -> Prop :=
   | occ_root : forall t1 t2 : btree, occ v k (bnode k v t1 t2)
   | occ_l :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t1 -> occ v k (bnode k' v' t1 t2)
   | occ_r :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t2 -> occ v k (bnode k' v' t1 t2).(* The entry with key k and value v occurs in the binary tree t *)

 Inductive occ (v : data) (k : key) : btree -> Prop :=
   | occ_root : forall t1 t2 : btree, occ v k (bnode k v t1 t2)
   | occ_l :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t1 -> occ v k (bnode k' v' t1 t2)
   | occ_r :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t2 -> occ v k (bnode k' v' t1 t2).(* The entry with key k and value v occurs in the binary tree t *)

 Inductive occ (v : data) (k : key) : btree -> Prop :=
   | occ_root : forall t1 t2 : btree, occ v k (bnode k v t1 t2)
   | occ_l :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t1 -> occ v k (bnode k' v' t1 t2)
   | occ_r :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t2 -> occ v k (bnode k' v' t1 t2).(* The entry with key k and value v occurs in the binary tree t *)

 Inductive occ (v : data) (k : key) : btree -> Prop :=
   | occ_root : forall t1 t2 : btree, occ v k (bnode k v t1 t2)
   | occ_l :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t1 -> occ v k (bnode k' v' t1 t2)
   | occ_r :
       forall (k' : key) (v' : data) (t1 t2 : btree),
       occ v k t2 -> occ v k (bnode k' v' t1 t2).(*  key k is less than every key in t  *)
 Inductive min (k : key) (t : btree) : Prop :=
     min_intro :
       (forall (k' : key) (v : data), occ v k' t -> Key.lt k k') -> min k t.(*  key k is less than every key in t  *)
 Inductive min (k : key) (t : btree) : Prop :=
     min_intro :
       (forall (k' : key) (v : data), occ v k' t -> Key.lt k k') -> min k t.(*  key k is gretaer than every key in t  *)
 Inductive maj (k : key) (t : btree) : Prop :=
     maj_intro :
       (forall (k' : key) (v : data), occ v k' t -> Key.lt k' k) -> maj k t.(*  key k is gretaer than every key in t  *)
 Inductive maj (k : key) (t : btree) : Prop :=
     maj_intro :
       (forall (k' : key) (v : data), occ v k' t -> Key.lt k' k) -> maj k t.(* searchness predicate on binary trees *)
 Inductive search_tree : btree -> Prop :=
   | leaf_search_tree : search_tree leaf
   | bnode_search_tree :
       forall (k : key) (v : data) (t1 t2 : btree),
       search_tree t1 ->
       search_tree t2 ->
       maj k t1 -> min k t2 -> search_tree (bnode k v t1 t2).(* searchness predicate on binary trees *)
 Inductive search_tree : btree -> Prop :=
   | leaf_search_tree : search_tree leaf
   | bnode_search_tree :
       forall (k : key) (v : data) (t1 t2 : btree),
       search_tree t1 ->
       search_tree t2 ->
       maj k t1 -> min k t2 -> search_tree (bnode k v t1 t2).(* searchness predicate on binary trees *)
 Inductive search_tree : btree -> Prop :=
   | leaf_search_tree : search_tree leaf
   | bnode_search_tree :
       forall (k : key) (v : data) (t1 t2 : btree),
       search_tree t1 ->
       search_tree t2 ->
       maj k t1 -> min k t2 -> search_tree (bnode k v t1 t2).Inductive is_bnode : btree -> Prop :=
     is_bnode_intro :
       forall (k : key) (v : data) (t1 t2 : btree),
       is_bnode (bnode k v t1 t2).Inductive is_bnode : btree -> Prop :=
     is_bnode_intro :
       forall (k : key) (v : data) (t1 t2 : btree),
       is_bnode (bnode k v t1 t2).Derive Inversion_clear OCC_INV with
  (forall (k k' : key) (v v' : data) (t1 t2 : btree),
   occ v' k' (bnode k v t1 t2)).

Lemma occ_inv : forall (k k' : key) (v v' : data) (t1 t2 : btree), occ v' k' (bnode k v t1 t2) -> k = k' /\ v = v' \/ occ v' k' t1 \/ occ v' k' t2.