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


Inductive hasnot_grown_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Grown_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_grown_left t k d l r b
  | Hasnot_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l ->
      hasnot_grown_left t k d l r Left_Balanced
  | Hasnot_Grown_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_grown_left t k d l r Right_Balanced.(**********************************************************************)


Inductive hasnot_grown_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Grown_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_grown_left t k d l r b
  | Hasnot_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l ->
      hasnot_grown_left t k d l r Left_Balanced
  | Hasnot_Grown_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_grown_left t k d l r Right_Balanced.(**********************************************************************)


Inductive hasnot_grown_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Grown_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_grown_left t k d l r b
  | Hasnot_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l ->
      hasnot_grown_left t k d l r Left_Balanced
  | Hasnot_Grown_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_grown_left t k d l r Right_Balanced.(**********************************************************************)


Inductive hasnot_grown_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Grown_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_grown_left t k d l r b
  | Hasnot_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l ->
      hasnot_grown_left t k d l r Left_Balanced
  | Hasnot_Grown_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_grown_left t k d l r Right_Balanced.Inductive has_grown_left (t : avl_tree) (k : Int) (d : B) 
(l r : avl_tree) : bal -> Prop :=
  | Has_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      has_grown_left t k d l r Left_Balanced
  | Has_Grown_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) -> has_grown_left t k d l r Balanced.Inductive has_grown_left (t : avl_tree) (k : Int) (d : B) 
(l r : avl_tree) : bal -> Prop :=
  | Has_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      has_grown_left t k d l r Left_Balanced
  | Has_Grown_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) -> has_grown_left t k d l r Balanced.Inductive has_grown_left (t : avl_tree) (k : Int) (d : B) 
(l r : avl_tree) : bal -> Prop :=
  | Has_Grown_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      has_grown_left t k d l r Left_Balanced
  | Has_Grown_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) -> has_grown_left t k d l r Balanced.Inductive bal_grow_left_spec (k : Int) (d : B) (l r : avl_tree) 
(b : bal) : Set :=
    Balance_Grow_Left_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_left t k d l r b} + {has_grown_left t k d l r b} ->
      bal_grow_left_spec k d l r b.Inductive bal_grow_left_spec (k : Int) (d : B) (l r : avl_tree) 
(b : bal) : Set :=
    Balance_Grow_Left_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_left t k d l r b} + {has_grown_left t k d l r b} ->
      bal_grow_left_spec k d l r b.

(* Specifications: *)
Lemma balance_left : 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_left_shift l r b} -> bal_grow_left_spec k d l r b.