(**********************************************************************)


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 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 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 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 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 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.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.

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.