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_Right_Spec_Intro with (Avl_Node k d l r b).
apply Node_Is_Avl; assumption.
trivial.
apply equiv_refl.
left.
apply Hasnot_Shrunk_Right_Bal.
assumption.
trivial.
(* l and r is'nt Balanced with respect to b *)
elim b; clear b; intros Balanced_shift_l.
(* b=Left_Balanced *)
apply Balance_Shrunk_Right_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_Right_Shift_Left.
assumption.
simpl in |- *.
inversion_clear Balanced_shift_l.
rewrite H; trivial.
(* b=Balanced *)
apply Balance_Shrunk_Right_Spec_Intro with (Avl_Node k d l r Right_Balanced).
apply Node_Is_Avl; try assumption.
apply Is_Right_Balanced_Avl.
inversion_clear Balanced_shift_l; assumption.
trivial.
apply equiv_refl.
left.
apply Hasnot_Shrunk_Right_Shift_Balanced.
assumption.
trivial.
(* b=Right_Balanced *)
elim (rebalance_right k d l r Right_Balanced); try assumption.
intros t (avl_t,(lin_t,(equiv_t,height_t))).
apply Balance_Shrunk_Right_Spec_Intro with t.
assumption.
assumption.
assumption.
clear lin_t equiv_t avl_l below_avl_l avl_r above_avl_r.
generalize height_t; clear height_t.
generalize Balanced_shift_l; clear Balanced_shift_l.
case r; clear r.
intro u0.
elimtype False.
inversion_clear u0.
discriminate H.
intros kr dr lr rr br.
elim br; clear br; simpl in |- *; intros Balanced_shift_l height_t.
(* br=Left_Balanced *)
right.
apply Has_Shrunk_Right_Shift_Right; assumption.
(* br=Balanced *)
left.
apply Hasnot_Shrunk_Right_Shift_Right; assumption.
(* br=Right_Balanced *)
right.
apply Has_Shrunk_Right_Shift_Right; assumption.
(* side premisses of (Elim (rebalance ... )) *)
inversion_clear Balanced_shift_l; assumption.
Qed.
(*******************************************************************)
Inductive lin_del_spec (key : Int) (d : B) (t0 t : avl_tree) : Prop :=
Lin_Del_Spec_Intro :
forall l0 l1 : list (Int * B),
lin_avl t0 = l0 ++ (key, d) :: l1 ->
lin_avl t = l0 ++ l1 -> lin_del_spec key d t0 t.
Inductive delete_spec (key : Int) (t0 : avl_tree) : Set :=
Delete_Spec_Intro :
forall t : avl_tree,
lookup_dec_spec key t0 ->
is_avl t ->
(forall d : B, lookup key t0 d -> lin_del_spec key d t0 t) ->
equiv_del key t0 t ->
{height_avl t0 = height_avl t} + {height_avl t0 = S (height_avl t)} ->
delete_spec key t0.

Lemma equiv_del_nil : forall key : Int, equiv_del key Avl_Nil Avl_Nil.
intros key.