intros k d l r b avl_l below_avl_l avl_r above_avl_r bal_or_shift.
elim bal_or_shift; clear bal_or_shift.
(* l and r is Balanced with respect to b *)
intro Balanced_l.
apply Balance_Shrunk_Left_Spec_Intro with (Avl_Node k d l r b).
apply Node_Is_Avl; assumption.
trivial.
apply equiv_refl.
left.
apply Hasnot_Shrunk_Left_Bal.
assumption.
trivial.
(* l and r is'nt Balanced with respect to b *)
elim b; clear b; intros Balanced_shift_l.
(* b=Left_Balanced *)
elim (rebalance_left k d l r Left_Balanced); try assumption.
intros t (avl_t,(lin_t,(equiv_t,height_t))).
apply Balance_Shrunk_Left_Spec_Intro with t.
assumption.
assumption.
assumption.
clear lin_t equiv_t avl_l below_avl_l.
generalize height_t; clear height_t.
generalize Balanced_shift_l; clear Balanced_shift_l.
case l; clear l.
intro u0.
elimtype False.
inversion_clear u0.
discriminate H.
intros kl dl ll rl bl.
elim bl; clear bl; simpl in |- *; intros Balanced_shift_l height_t.
(* bl=Left_Balanced *)
right.
apply Has_Shrunk_Left_Shift_Left; assumption.
(* bl=Balanced *)
left.
apply Hasnot_Shrunk_Left_Shift_Left; assumption.
(* bl=Right_Balanced *)
right.
apply Has_Shrunk_Left_Shift_Left; assumption.
(* side premisses of (Elim (rebalance ... )) *)
inversion_clear Balanced_shift_l; assumption.
(* b=Balanced *)
apply Balance_Shrunk_Left_Spec_Intro with (Avl_Node k d l r Left_Balanced).
apply Node_Is_Avl; try assumption.
apply Is_Left_Balanced_Avl.
inversion_clear Balanced_shift_l; assumption.
trivial.
apply equiv_refl.
left.
apply Hasnot_Shrunk_Left_Shift_Balanced.
assumption.
trivial.
(* b=Right_Balanced *)
apply Balance_Shrunk_Left_Spec_Intro with (Avl_Node k d l r Balanced).
apply Node_Is_Avl; try assumption.
apply Is_Fully_Balanced_Avl.
inversion_clear Balanced_shift_l; assumption.
trivial.
apply equiv_refl.
right.
apply Has_Shrunk_Left_Shift_Right.
assumption.
trivial.
Qed.
(*****************************************************************)
Inductive delete_max_spec (t0 : avl_tree) : Set :=
Del_Max_Spec_Intro :
forall (k : Int) (d : B) (t : avl_tree),
lookup k t0 d ->
is_avl t ->
is_below_avl t k ->
lin_avl t0 = lin_avl t ++ (k, d) :: nil ->
equiv_del k t0 t ->
{height_avl t0 = height_avl t} + {height_avl t0 = S (height_avl t)} ->
delete_max_spec t0.
(*****************************************************************)

Lemma delete_max :
forall (k0 : Int) (d0 : B) (l0 r0 : avl_tree) (b0 : bal),
is_avl (Avl_Node k0 d0 l0 r0 b0) ->
delete_max_spec (Avl_Node k0 d0 l0 r0 b0).