(* --------------------------------------------------------------------- *)
(* 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_PiCong_exists : forall x1 x2 (G:context) D rho
(g1 g2 : co) (A1 B1 A2 B3 B2 : tm),
x1 `notin` (dom G \u fv_tm_tm_tm B1 \u fv_tm_tm_tm B2 \u  fv_tm_tm_co g2)
-> x2 `notin` (dom G \u fv_tm_tm_tm B2 \u fv_tm_tm_tm B3 \u  fv_tm_tm_co g1)
-> AnnDefEq G D g1 A1 A2
→ AnnDefEq ([(x1, Tm A1)] ++ G) D (open_co_wrt_tm g2 (a_Var_f x1))
(open_tm_wrt_tm B1 (a_Var_f x1)) (open_tm_wrt_tm B2 (a_Var_f x1))
→ (open_tm_wrt_tm B3 (a_Var_f x2) =
open_tm_wrt_tm B2 (a_Conv (a_Var_f x2) (g_Sym g1)))
→ AnnTyping G (a_Pi rho A1 B1) a_Star
→ AnnTyping G (a_Pi rho A2 B3) a_Star
→ AnnTyping G (a_Pi rho A1 B2) a_Star
→ AnnDefEq G D (g_PiCong rho g1 g2) (a_Pi rho A1 B1) (a_Pi rho A2 B3).