(* ----------------------------------------------------------------------------- *)

(* Specifications: *)
Lemma E_PiCong2 :  ∀ (L : atoms) (G : context) (D : available_props) rho (A1 B1 A2 B2 : tm),
DefEq G D A1 A2 a_Star
→ (∀ x : atom,
x `notin` L
→ DefEq ([(x, Tm A1)] ++ G) D (open_tm_wrt_tm B1 (a_Var_f x))
(open_tm_wrt_tm B2 (a_Var_f x)) a_Star)
→ DefEq G D (a_Pi rho A1 B1) (a_Pi rho A2 B2) a_Star.
Lemma E_CPiCong2  : ∀ (L : atoms) (G : context) (D : available_props) (phi1 : constraint)
(A : tm) (phi2 : constraint) (B : tm),
Iso G D phi1 phi2
→ (∀ c : atom,
c `notin` L
→ DefEq ([(c, Co phi1)] ++ G) D (open_tm_wrt_co A (g_Var_f c))
(open_tm_wrt_co B (g_Var_f c)) a_Star)
→ DefEq G D (a_CPi phi1 A) (a_CPi phi2 B) a_Star.
(* could also be an exists form *)
Lemma E_Pi2 : forall L G rho A B,
(∀ x : atom, x `notin` L → Typing ([(x, Tm A)] ++ G) (open_tm_wrt_tm B (a_Var_f x)) a_Star) ->
Typing G (a_Pi rho A B) a_Star.
Lemma E_Abs2 : ∀ (L : atoms) (G : context) (rho : relflag) (a A B : tm),
(∀ x : atom,
x `notin` L → Typing ([(x, Tm A)] ++ G) (open_tm_wrt_tm a (a_Var_f x)) (open_tm_wrt_tm B (a_Var_f x)))
→ (∀ x : atom, x `notin` L → RhoCheck rho x (open_tm_wrt_tm a (a_Var_f x)))
→ Typing G (a_UAbs rho a) (a_Pi rho A B).
Lemma E_Conv2 : ∀ (G : context) (a B A : tm),
Typing G a A → DefEq G (dom G) A B a_Star →
Typing G a B.
Lemma E_CPi2 :  ∀ (L : atoms) (G : context) (phi : constraint) (B : tm),
(∀ c : atom, c `notin` L → Typing ([(c, Co phi)] ++ G) (open_tm_wrt_co B (g_Var_f c)) a_Star) ->
Typing G (a_CPi phi B) a_Star.
Lemma E_CAbs2 : ∀ (L : atoms) (G : context) (a : tm) (phi : constraint) (B : tm),
(∀ c : atom,
c `notin` L → Typing ([(c, Co phi)] ++ G) (open_tm_wrt_co a (g_Var_f c)) (open_tm_wrt_co B (g_Var_f c)))
→ Typing G (a_UCAbs a) (a_CPi phi B).
Lemma E_AbsCong2
: ∀ (L : atoms) (G : context) (D : available_props) (rho : relflag) (b1 b2 A1 B : tm),
(∀ x : atom,
x `notin` L
→ DefEq ([(x, Tm A1)] ++ G) D (open_tm_wrt_tm b1 (a_Var_f x)) (open_tm_wrt_tm b2 (a_Var_f x))
(open_tm_wrt_tm B (a_Var_f x)))
→ (∀ x : atom, x `notin` L → RhoCheck rho x (open_tm_wrt_tm b1 (a_Var_f x)))
→ (∀ x : atom, x `notin` L → RhoCheck rho x (open_tm_wrt_tm b2 (a_Var_f x)))
→ DefEq G D (a_UAbs rho b1) (a_UAbs rho b2) (a_Pi rho A1 B).
Lemma E_CAbsCong2
: ∀ (L : atoms) (G : context) (D : available_props) (a b : tm) (phi1 : constraint)
(B : tm),
(∀ c : atom,
c `notin` L
→ DefEq ([(c, Co phi1)] ++ G) D (open_tm_wrt_co a (g_Var_f c)) (open_tm_wrt_co b (g_Var_f c))
(open_tm_wrt_co B (g_Var_f c))) → DefEq G D (a_UCAbs a) (a_UCAbs b) (a_CPi phi1 B).
Lemma E_Fam2 : ∀ (G : context) (F : tyfam) (A a : tm),
Ctx G
→ binds F (Ax a A) toplevel → Typing G (a_Fam F) A.
Lemma E_Wff2 : ∀ (G : context) (a b A : tm), Typing G a A → Typing G b A → PropWff G (Eq a b A).
End ext_invert.