(* --------------------------------------------------------------------- *)
(* This is the place for "smart constructors" and "smart inversion" lemmas. They are especialy useful for constructing derivations from a particular variable and avoiding the co-finite quantification stuff.  *)
(* In a locally nameless development, these should be stated and immediately proven after substitution. *)

Lemma An_CAbsCong_inversion :
forall (G : context) (D : available_props) (g1 g3 g4 : co) A1 A2,
AnnDefEq G D (g_CAbsCong g1 g3 g4) A1 A2
-> exists phi1 phi2 a1 a2 a3 B1 B2 B,
A1 = (a_CAbs phi1 a1) /\
A2 = (a_CAbs phi2 a3) /\
AnnIso G D g1 phi1 phi2 /\
AnnTyping G (a_CAbs phi1 a1) (a_CPi phi1 B1) /\
AnnTyping G (a_CAbs phi2 a3) (a_CPi phi2 B2) /\
AnnTyping G (a_CAbs phi1 a2) B /\
AnnDefEq G (dom G) g4 (a_CPi phi1 B1) (a_CPi phi2 B2) /\
forall c1,
c1`notin` dom G
→ (AnnDefEq ([(c1, Co phi1)] ++ G) D (open_co_wrt_co g3 (g_Var_f c1))
(open_tm_wrt_co a1 (g_Var_f c1)) (open_tm_wrt_co a2 (g_Var_f c1))) /\
(open_tm_wrt_co a3 (g_Var_f c1) =
open_tm_wrt_co a2 (g_Cast (g_Var_f c1) (g_Sym g1))).