(*********************************************************************)
(*  equiv_ins                                                        *)

Inductive equiv_ins (key : Int) (update : B -> B) (init : B)
(t0 t : avl_tree) : Prop :=
    equiv_ins_intro :
      (forall (k : Int) (data : B),
       Equal k key -> lookup k t0 data -> lookup k t (update data)) ->
      (forall k : Int,
       Equal k key ->
       (forall data : B, lookup k t0 data -> False) ->
       lookup k t (update init)) ->
      (forall (k : Int) (data : B),
       ~ Equal k key -> lookup k t0 data -> lookup k t data) ->
      (forall (k : Int) (data : B),
       ~ Equal k key -> lookup k t data -> lookup k t0 data) ->
      equiv_ins key update init t0 t.(*********************************************************************)
(*  equiv_ins                                                        *)

Inductive equiv_ins (key : Int) (update : B -> B) (init : B)
(t0 t : avl_tree) : Prop :=
    equiv_ins_intro :
      (forall (k : Int) (data : B),
       Equal k key -> lookup k t0 data -> lookup k t (update data)) ->
      (forall k : Int,
       Equal k key ->
       (forall data : B, lookup k t0 data -> False) ->
       lookup k t (update init)) ->
      (forall (k : Int) (data : B),
       ~ Equal k key -> lookup k t0 data -> lookup k t data) ->
      (forall (k : Int) (data : B),
       ~ Equal k key -> lookup k t data -> lookup k t0 data) ->
      equiv_ins key update init t0 t.

(* Specifications: *)
Lemma inv_equiv_ins_equal0 : forall (key : Int) (update : B -> B) (init : B) (t0 t : avl_tree) (k : Int) (data : B), equiv_ins key update init t0 t -> Equal k key -> lookup k t0 data -> lookup k t (update data).
Lemma inv_equiv_ins_equal1 : forall (key : Int) (update : B -> B) (init : B) (t0 t : avl_tree) (k : Int), equiv_ins key update init t0 t -> Equal k key -> (forall data : B, lookup k t0 data -> False) -> lookup k t (update init).
Lemma inv_equiv_ins_notequal0 : forall (key : Int) (update : B -> B) (init : B) (t0 t : avl_tree) (k : Int) (data : B), equiv_ins key update init t0 t -> ~ Equal k key -> lookup k t0 data -> lookup k t data.
Lemma inv_equiv_ins_notequal1 : forall (key : Int) (update : B -> B) (init : B) (t0 t : avl_tree) (k : Int) (data : B), equiv_ins key update init t0 t -> ~ Equal k key -> lookup k t data -> lookup k t0 data.
Lemma equiv_ins_equiv_equiv_ins : forall (key : Int) (update : B -> B) (init : B) (t0 t1 t2 : avl_tree), equiv_ins key update init t0 t1 -> equiv t1 t2 -> equiv_ins key update init t0 t2.
Lemma equiv_ins_below : forall (key : Int) (update : B -> B) (init : B) (t0 t : avl_tree) (k0 : Int), equiv_ins key update init t0 t -> Less key k0 -> is_below t0 k0 -> is_below t k0.
Lemma equiv_ins_above : forall (key : Int) (update : B -> B) (init : B) (t0 t : avl_tree) (k0 : Int), equiv_ins key update init t0 t -> Less k0 key -> is_above t0 k0 -> is_above t k0.
Lemma leave_is_avl : forall (k : Int) (d : B), is_avl (Avl_Node k d Avl_Nil Avl_Nil Balanced).
Lemma equiv_ins_nil : forall (key : Int) (update : B -> B) (init : B), equiv_ins key update init Avl_Nil (Avl_Node key (update init) Avl_Nil Avl_Nil Balanced).
Lemma avl_ins_eq : forall (k : Int) (d : B) (l r : avl_tree) (b : bal) (d' : B), is_avl (Avl_Node k d l r b) -> is_avl (Avl_Node k d' l r b).
Lemma equiv_ins_eq : forall (key : Int) (update : B -> B) (init : B) (k : Int) (d : B) (l0 r0 : avl_tree) (b : bal), is_avl (Avl_Node k d l0 r0 b) -> Equal key k -> equiv_ins key update init (Avl_Node k d l0 r0 b) (Avl_Node k (update d) l0 r0 b).
Lemma equiv_ins_left : forall (key : Int) (update : B -> B) (init : B) (k0 : Int) (d0 : B) (l0 r0 : avl_tree) (b0 : bal) (l : avl_tree) (b : bal), is_avl (Avl_Node k0 d0 l0 r0 b0) -> Less key k0 -> equiv_ins key update init l0 l -> equiv_ins key update init (Avl_Node k0 d0 l0 r0 b0) (Avl_Node k0 d0 l r0 b).
Lemma equiv_ins_right : forall (key : Int) (update : B -> B) (init : B) (k0 : Int) (d0 : B) (l0 r0 : avl_tree) (b0 : bal) (r : avl_tree) (b : bal), is_avl (Avl_Node k0 d0 l0 r0 b0) -> Less k0 key -> equiv_ins key update init r0 r -> equiv_ins key update init (Avl_Node k0 d0 l0 r0 b0) (Avl_Node k0 d0 l0 r b).