intros key update init k d l0 r0 b avl_t0 equal.
generalize (avl_ins_eq k d l0 r0 b (update d) avl_t0).
intro avl_t.
apply equiv_ins_intro.
intros k0 data equal1.
generalize (equal_trans k0 key k equal1 equal).
intro equal2.
intro lookup_t0.
rewrite (lookup_avl_inv_equal k0 k d l0 r0 b data avl_t0 equal2 lookup_t0).
rewrite (equal_eq k0 k equal2).
apply Lookup_Equal.
intros k0 equal1.
generalize (equal_trans k0 key k equal1 equal).
intro equal2.
intro not_lookup_t0.
elimtype False.
apply (not_lookup_t0 d).
rewrite (equal_eq k0 k equal2).
apply Lookup_Equal.
intros k0 data notequal0.
intro lookup_t0.
elim (inv_lookup k0 k d l0 r0 b data lookup_t0); intro u0.
elimtype False.
apply notequal0.
elim u0; clear u0; intros u0 u1.
rewrite <- u0.
apply equal_sym; assumption.
elim u0; clear u0; intro u0.
apply Lookup_Left; assumption.
apply Lookup_Right; assumption.
intros k0 data notequal0.
intro lookup_t.
elim (inv_lookup k0 k (update d) l0 r0 b data lookup_t); intro u0.
elimtype False.
apply notequal0.
elim u0; clear u0; intros u0 u1.
rewrite <- u0.
apply equal_sym; assumption.
elim u0; clear u0; intro u0.
apply Lookup_Left; assumption.
apply Lookup_Right; assumption.
Qed.

(* Specifications: *)
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).