End RMAX_np.
Hint Resolve rmax_t1_t2t3: searchtrees.
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.
refine
(fix rmax (t : Z_btree) : rmax_spec t :=
match t as x return (rmax_spec x) with
| Z_leaf => fun h h' => False_rec _ _
| Z_bnode r t1 t2 =>
match
t2 as z
return (rmax_spec z -> z = t2 -> rmax_spec (Z_bnode r t1 z))
with
| Z_leaf =>
fun h h' h'' h''' =>
existS (fun q : Z => rmax_sig (Z_bnode r t1 Z_leaf) q) r
(exist _ t1 _)
| Z_bnode n' t'1 t'2 =>
fun h h' h'' h''' =>
match rmax t2 _ _ with
| existS num (exist t' _) =>
existS
(fun q : Z =>
rmax_sig (Z_bnode r t1 (Z_bnode n' t'1 t'2)) q) num
(exist _ (Z_bnode r t1 t') _)
end
end _ _
end).
inversion h'.
auto with searchtrees.
case h'; eauto with searchtrees.
case h'; eauto with searchtrees.
rewrite h'; eauto with searchtrees.
case h'; apply rmax_t1_t2t3.
auto.
rewrite h'; auto.
auto.
auto.
Defined.
(* 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'}.
Hint Resolve rm_intro: searchtrees.
(* base cases *)
Remark RM_0 : forall n : Z, RM n Z_leaf Z_leaf.
Hint Resolve RM_0: searchtrees.
Remark RM_1 : forall n : Z, RM n (Z_bnode n Z_leaf Z_leaf) Z_leaf.
Hint Resolve RM_1: searchtrees.
(* 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).
Hint Resolve rm_left: searchtrees.
(* 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').
Hint Resolve rm_right: searchtrees.
(* 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.
Hint Resolve rm_root_base_case: searchtrees.
(* General case: we use the RMAX predicate *)
Section rm_root.
Variable n p : Z.
Variable t1 t2 t' : Z_btree.
Hypothesis S : search (Z_bnode n (Z_bnode p t1 t2) t').
Variable q : Z.
Variable t0 : Z_btree.
Hypothesis R : RMAX (Z_bnode p t1 t2) t0 q.
Hint Resolve S: searchtrees.
Remark rm_2 : (q < n)%Z.
(********************)
Hint Resolve rm_2: searchtrees.
Remark rm_3 : ~ occ n (Z_bnode q t0 t').
Hint Resolve rm_3: searchtrees.
Remark rm_4 :
forall p0 : Z,
occ p0 (Z_bnode q t0 t') -> occ p0 (Z_bnode n (Z_bnode p t1 t2) t').
Hint Resolve rm_4: searchtrees.
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.
Hint Resolve rm_5: searchtrees.
Remark rm_6 : search (Z_bnode q t0 t').
Hint Resolve rm_6: searchtrees.

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