Theory ContextFacts

subsection‹Contextual typing›

theory ContextFacts
imports
    Reduction
    Types
begin

text‹Naturally, we may wonder when instantiating the hole in a context is type-preserving.
    To assess this, we define a typing judgement for contexts.›

inductive typing_ctxt :: "(nat  type)  (nat  type)  ctxt  type  type  bool"
                         (‹_ , _ ctxt _ : _  _› [50, 50, 50, 50, 50] 50)
where
  type_ctxtEmpty [intro!]: "Γ, Δ ctxt  : T  T" |
  type_ctxtApp   [intro!]: " Γ, Δ ctxt E : (T1T2)  U; Γ, Δ T t : T1   Γ, Δ ctxt (E  t) : T2  U"

inductive_cases typing_ctxt_elims [elim!]:
  "Γ, Δ ctxt  : T  T"
  "Γ, Δ ctxt (E  t) : T  U"

lemma typing_ctxt_correct1:
  shows "Γ, Δ T (ctxt_subst E r) : T   U. (Γ, Δ T r : U  Γ, Δ ctxt E : T  U)"
  by(induction E arbitrary: Γ Δ T r; force)

lemma typing_ctxt_correct2:
  shows "Γ, Δ ctxt E : T  U  Γ, Δ T r : U   Γ, Δ T (ctxt_subst E r) : T"
  by(induction arbitrary: r rule: typing_ctxt.induct) auto

lemma ctxt_subst_basecase: 
  "n. c[n = n ]C =  c"
  "n. t[n = n ]T =  t"
  by(induct c and t) (auto) 

lemma ctxt_subst_caseApp:
  "n E s. (c[n=n (liftM_ctxt E n)]C)[n=n (  (liftM_trm s n))]C = c[n=n ((liftM_ctxt E n)  (liftM_trm s n))]C"
  "n E s. (t[n=n (liftM_ctxt E n)]T)[n=n (  (liftM_trm s n))]T = t[n=n ((liftM_ctxt E n)  (liftM_trm s n))]T"
  by (induction c and t) (auto simp add: liftLM_comm_ctxt liftLM_comm liftMM_comm_ctxt  liftMM_comm liftM_ctxt_struct_subst)

lemma ctxt_subst:
  assumes "Γ, Δ ctxt E : U  T"
  shows   "(ctxt_subst E (μ T : c)) * μ U : (c[0 = 0 (liftM_ctxt E 0)]C)"
using assms proof(induct E arbitrary: U T Γ Δ c)
  case ContextEmpty
  have ctxtEmpty_inv: "Γ, Δ ctxt  : U  T  U = T"
    by(cases Γ Δ "" rule: typing_ctxt.cases, fastforce, simp)
  show ?case
    using ContextEmpty by (clarsimp dest!: ctxtEmpty_inv simp: ctxt_subst_basecase)
next
  case (ContextApp E x)
  then show ?case
    by clarsimp (rule rtc_term_trans, rule rtc_appL, assumption, rule step_term, force, clarsimp simp add: ctxt_subst_caseApp(1))
qed
  
end