(*************************************************)
(*		Definition Avl		  	 *)
(*************************************************)

Inductive is_avl : avl_tree -> Prop :=
  | Nil_Is_Avl : is_avl Avl_Nil
  | Node_Is_Avl :
      forall (k : Int) (d : B) (l r : avl_tree) (b : bal),
      is_avl l ->
      is_avl r ->
      is_balanced_avl l r b ->
      is_below_avl l k -> is_above_avl r k -> is_avl (Avl_Node k d l r b).(*************************************************)
(*		Definition Avl		  	 *)
(*************************************************)

Inductive is_avl : avl_tree -> Prop :=
  | Nil_Is_Avl : is_avl Avl_Nil
  | Node_Is_Avl :
      forall (k : Int) (d : B) (l r : avl_tree) (b : bal),
      is_avl l ->
      is_avl r ->
      is_balanced_avl l r b ->
      is_below_avl l k -> is_above_avl r k -> is_avl (Avl_Node k d l r b).(*************************************************)
(*		Definition Avl		  	 *)
(*************************************************)

Inductive is_avl : avl_tree -> Prop :=
  | Nil_Is_Avl : is_avl Avl_Nil
  | Node_Is_Avl :
      forall (k : Int) (d : B) (l r : avl_tree) (b : bal),
      is_avl l ->
      is_avl r ->
      is_balanced_avl l r b ->
      is_below_avl l k -> is_above_avl r k -> is_avl (Avl_Node k d l r b).

(* Specifications: *)
Lemma is_avl_rec : forall P : avl_tree -> Set, P Avl_Nil -> (forall (k : Int) (d : B) (l r : avl_tree) (b : bal), is_avl l -> P l -> is_avl r -> P r -> is_balanced_avl l r b -> is_below_avl l k -> is_above_avl r k -> P (Avl_Node k d l r b)) -> forall t : avl_tree, is_avl t -> P t.
Lemma inv_is_avl_left : forall (k : Int) (d : B) (l r : avl_tree) (b : bal), is_avl (Avl_Node k d l r b) -> is_avl l.
Lemma inv_is_avl_right : forall (k : Int) (d : B) (l r : avl_tree) (b : bal), is_avl (Avl_Node k d l r b) -> is_avl r.
Lemma inv_is_avl_is_balanced_avl : forall (k : Int) (d : B) (l r : avl_tree) (b : bal), is_avl (Avl_Node k d l r b) -> is_balanced_avl l r b.
Lemma inv_is_avl_is_is_below_avl : forall (k : Int) (d : B) (l r : avl_tree) (b : bal), is_avl (Avl_Node k d l r b) -> is_below_avl l k.
Lemma inv_is_avl_is_is_above_avl : forall (k : Int) (d : B) (l r : avl_tree) (b : bal), is_avl (Avl_Node k d l r b) -> is_above_avl r k.
Lemma avl_height_avl_height : forall t : avl_tree, is_avl t -> height_avl t = height t.
Lemma is_balanced_avl_is_balanced : forall l r : avl_tree, is_avl l -> is_avl r -> forall b : bal, is_balanced_avl l r b -> is_balanced l r b.
Lemma is_avl_is_balanced : forall (l r : avl_tree) (k : Int) (d : B) (b : bal), is_avl (Avl_Node k d l r b) -> is_balanced l r b.
Lemma is_below_avl_is_below : forall t : avl_tree, is_avl t -> forall k0 : Int, is_below_avl t k0 -> is_below t k0.
Lemma is_above_avl_is_above : forall t : avl_tree, is_avl t -> forall k0 : Int, is_above_avl t k0 -> is_above t k0.
Lemma lookup_avl_inv_equal : forall (key k : Int) (d : B) (l r : avl_tree) (b : bal) (data : B), is_avl (Avl_Node k d l r b) -> Equal key k -> lookup key (Avl_Node k d l r b) data -> d = data.
Lemma lookup_avl_inv_less : forall (key k : Int) (d : B) (l r : avl_tree) (b : bal) (data : B), is_avl (Avl_Node k d l r b) -> Less key k -> lookup key (Avl_Node k d l r b) data -> lookup key l data.
Lemma lookup_avl_inv_greater : forall (key k : Int) (d : B) (l r : avl_tree) (b : bal) (data : B), is_avl (Avl_Node k d l r b) -> Less k key -> lookup key (Avl_Node k d l r b) data -> lookup key r data.
Lemma lookup_avl_equal : forall (k1 k : Int) (t : avl_tree) (d1 d : B), is_avl t -> lookup k1 t d1 -> lookup k t d -> Equal k1 k -> d1 = d.