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


Inductive hasnot_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Shrunk_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_shrunk_left t k d l r b
  | Hasnot_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Left_Balanced
  | Hasnot_Shrunk_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Balanced.(**********************************************************************)


Inductive hasnot_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Shrunk_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_shrunk_left t k d l r b
  | Hasnot_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Left_Balanced
  | Hasnot_Shrunk_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Balanced.(**********************************************************************)


Inductive hasnot_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Shrunk_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_shrunk_left t k d l r b
  | Hasnot_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Left_Balanced
  | Hasnot_Shrunk_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Balanced.(**********************************************************************)


Inductive hasnot_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Hasnot_Shrunk_Left_Bal :
      forall b : bal,
      is_balanced_avl l r b ->
      height_avl t = height_avl (Avl_Node k d l r b) ->
      hasnot_shrunk_left t k d l r b
  | Hasnot_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Left_Balanced
  | Hasnot_Shrunk_Left_Shift_Balanced :
      is_balanced_avl_left_shift l r Balanced ->
      height_avl t = S (height_avl l) ->
      hasnot_shrunk_left t k d l r Balanced.Inductive has_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Has_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l -> has_shrunk_left t k d l r Left_Balanced
  | Has_Shrunk_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      has_shrunk_left t k d l r Right_Balanced.Inductive has_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Has_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l -> has_shrunk_left t k d l r Left_Balanced
  | Has_Shrunk_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      has_shrunk_left t k d l r Right_Balanced.Inductive has_shrunk_left (t : avl_tree) (k : Int) 
(d : B) (l r : avl_tree) : bal -> Prop :=
  | Has_Shrunk_Left_Shift_Left :
      is_balanced_avl_left_shift l r Left_Balanced ->
      height_avl t = height_avl l -> has_shrunk_left t k d l r Left_Balanced
  | Has_Shrunk_Left_Shift_Right :
      is_balanced_avl_left_shift l r Right_Balanced ->
      height_avl t = S (height_avl l) ->
      has_shrunk_left t k d l r Right_Balanced.Inductive bal_shrunk_left_spec (k : Int) (d : B) (l r : avl_tree) 
(b : bal) : Set :=
    Balance_Shrunk_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_shrunk_left t k d l r b} + {has_shrunk_left t k d l r b} ->
      bal_shrunk_left_spec k d l r b.Inductive bal_shrunk_left_spec (k : Int) (d : B) (l r : avl_tree) 
(b : bal) : Set :=
    Balance_Shrunk_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_shrunk_left t k d l r b} + {has_shrunk_left t k d l r b} ->
      bal_shrunk_left_spec k d l r b.

(* Specifications: *)
Lemma balance_shrunk_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_shrunk_left_spec k d l r b.