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_Grow_Left_Spec_Intro with (Avl_Node k d l r b).
apply Node_Is_Avl; assumption.
trivial.
apply equiv_refl.
left.
apply Hasnot_Grown_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,(equiv_t,height_t))).
apply Balance_Grow_Left_Spec_Intro with t.
assumption.
assumption.
assumption.
clear lin 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 *)
left.
apply Hasnot_Grown_Left_Shift_Left; assumption.
(* bl=Balanced *)
right.
apply Has_Grown_Left_Shift_Left; assumption.
(* bl=Right_Balanced *)
left.
apply Hasnot_Grown_Left_Shift_Left; assumption.
(* side premisses of (Elim (rebalance ... )) *)
inversion_clear Balanced_shift_l; assumption.
(* b=Balanced *)
apply Balance_Grow_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.
right.
apply Has_Grown_Left_Shift_Balanced.
assumption.
trivial.
(* b=Right_Balanced *)
apply Balance_Grow_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.
simpl in |- *.
left.
apply Hasnot_Grown_Left_Shift_Right.
assumption.
trivial.
Qed.
(**********************************************************************)
Inductive hasnot_grown_right (t : avl_tree) (k : Int)
(d : B) (l r : avl_tree) : bal -> Prop :=
| Hasnot_Grown_Right_Bal :
forall b : bal,
is_balanced_avl l r b ->
height_avl t = height_avl (Avl_Node k d l r b) ->
hasnot_grown_right t k d l r b
| Hasnot_Grown_Right_Shift_Left :
is_balanced_avl_right_shift l r Left_Balanced ->
height_avl t = S (height_avl r) ->
hasnot_grown_right t k d l r Left_Balanced
| Hasnot_Grown_Right_Shift_Right :
is_balanced_avl_right_shift l r Right_Balanced ->
height_avl t = height_avl r ->
hasnot_grown_right t k d l r Right_Balanced.
Inductive has_grown_right (t : avl_tree) (k : Int)
(d : B) (l r : avl_tree) : bal -> Prop :=
| Has_Grown_Right_Shift_Balanced :
is_balanced_avl_right_shift l r Balanced ->
height_avl t = S (height_avl r) -> has_grown_right t k d l r Balanced
| Has_Grown_Right_Shift_Right :
is_balanced_avl_right_shift l r Right_Balanced ->
height_avl t = S (height_avl r) ->
has_grown_right t k d l r Right_Balanced.
Inductive bal_grow_right_spec (k : Int) (d : B) (l r : avl_tree)
(b : bal) : Set :=
Balance_Grow_Right_Spec_Intro :
forall t : avl_tree,
is_avl t ->
lin_avl t = lin_avl (Avl_Node k d l r b) ->
equiv t (Avl_Node k d l r b) ->
{hasnot_grown_right t k d l r b} + {has_grown_right t k d l r b} ->
bal_grow_right_spec k d l r b.

(* Specifications: *)
Lemma balance_right :
forall (k : Int) (d : B) (l r : avl_tree) (b : bal),
is_avl l ->
is_below_avl l k ->
is_avl r ->
is_above_avl r k ->
{is_balanced_avl l r b} + {is_balanced_avl_right_shift l r b} ->
bal_grow_right_spec k d l r b.