Definition rmax_sig (t : Z_btree) (q : Z) := {t' : Z_btree | RMAX t t' q}.Definition rmax_spec (t : Z_btree) :=
  search t -> Binp t -> {q : Z &  rmax_sig t q}.Definition rmax : forall t : Z_btree, rmax_spec t.(* VI    Deletion.
******************
*******************


  Deleting an element from a binary search tree is a little more
  complex than inserting or searching.
  The difficult case is the deletion of the root of a tree; we have
  to reconstruct a search tree. To solve this problem, we define
  an auxiliary operation: deleting the greatest element of a non-empty
  binary search tree.
*)

(* VI.2  Deletion in general
****************************

  We are now ready to study the remove operation in it's generality:
 (RM n t t') if t' is a search tree obtained by removing n from t *)


Inductive RM (n : Z) (t t' : Z_btree) : Prop :=
    rm_intro :
      ~ occ n t' ->
      (forall p : Z, occ p t' -> occ p t) ->
      (forall p : Z, occ p t -> occ p t' \/ n = p) -> search t' -> RM n t t'.(* VI    Deletion.
******************
*******************


  Deleting an element from a binary search tree is a little more
  complex than inserting or searching.
  The difficult case is the deletion of the root of a tree; we have
  to reconstruct a search tree. To solve this problem, we define
  an auxiliary operation: deleting the greatest element of a non-empty
  binary search tree.
*)

(* VI.2  Deletion in general
****************************

  We are now ready to study the remove operation in it's generality:
 (RM n t t') if t' is a search tree obtained by removing n from t *)


Inductive RM (n : Z) (t t' : Z_btree) : Prop :=
    rm_intro :
      ~ occ n t' ->
      (forall p : Z, occ p t' -> occ p t) ->
      (forall p : Z, occ p t -> occ p t' \/ n = p) -> search t' -> RM n t t'.Definition RM_SPEC (n : Z) (t : Z_btree) := {t' : Z_btree | RM n t t'}.(* base cases *)

Remark RM_0 : forall n : Z, RM n Z_leaf Z_leaf.Remark RM_1 : forall n : Z, RM n (Z_bnode n Z_leaf Z_leaf) Z_leaf.(* deleting in the left son *)

Remark rm_left :
 forall (n p : Z) (t1 t2 t' : Z_btree),
 (p < n)%Z ->
 search (Z_bnode n t1 t2) ->
 RM p t1 t' -> RM p (Z_bnode n t1 t2) (Z_bnode n t' t2).(* deleting in the right son *)

Remark rm_right :
 forall (n p : Z) (t1 t2 t' : Z_btree),
 (n < p)%Z ->
 search (Z_bnode n t1 t2) ->
 RM p t2 t' -> RM p (Z_bnode n t1 t2) (Z_bnode n t1 t').(* base case for deleting the root *)

Remark rm_root_base_case :
 forall (n : Z) (t : Z_btree),
 search (Z_bnode n Z_leaf t) -> RM n (Z_bnode n Z_leaf t) t.Remark rm_2 : (q < n)%Z.Remark rm_3 : ~ occ n (Z_bnode q t0 t').Remark rm_4 :
      forall p0 : Z,
      occ p0 (Z_bnode q t0 t') -> occ p0 (Z_bnode n (Z_bnode p t1 t2) t').Remark rm_5 :
      forall p0 : Z,
      occ p0 (Z_bnode n (Z_bnode p t1 t2) t') ->
      occ p0 (Z_bnode q t0 t') \/ n = p0.Remark rm_6 : search (Z_bnode q t0 t').

Lemma rm_root_lemma : RM n (Z_bnode n (Z_bnode p t1 t2) t') (Z_bnode q t0 t').