(* *) (* Formalisation of the chapter on Logical Relations *) (* and a Case Study in Equivalence Checking *) (* by Karl Crary from the book on Advanced Topics in *) (* Types and Programming Languages, MIT Press 2005 *)
(* The formalisation was done by Julien Narboux and *) (* Christian Urban. *)
lemma lookup_fresh: fixes z::"name" assumes a: "z♯θ""z♯x" shows"z♯ lookup θ x" using a by (induct rule: lookup.induct)
(auto simp: fresh_list_cons)
lemma lookup_fresh': assumes a: "z♯θ" shows"lookup θ z = Var z" using a by (induct rule: lookup.induct)
(auto simp: fresh_list_cons fresh_prod fresh_atm)
lemma subst_eqvt[eqvt]: fixes pi::"name prm" shows"pi∙(t[x::=t']) = (pi∙t)[(pi∙x)::=(pi∙t')]" by (nominal_induct t avoiding: x t' rule: trm.strong_induct)
(perm_simp add: fresh_bij)+
lemma subst_rename: fixes c::"name" assumes a: "c♯t🪙1" shows"t🪙1[a::=t🪙2] = ([(c,a)]∙t🪙1)[c::=t🪙2]" using a by (nominal_induct t🪙1 avoiding: a c t🪙2 rule: trm.strong_induct)
(auto simp: trm.inject calc_atm fresh_atm abs_fresh perm_nat_def)
lemma fresh_psubst: fixes z::"name" assumes a: "z♯t""z♯θ" shows"z♯(θ)" using a by (nominal_induct t avoiding: z θ t rule: trm.strong_induct)
(auto simp: abs_fresh lookup_fresh)
lemma fresh_subst'': fixes z::"name" assumes"z♯t🪙2" shows"z♯t🪙1[z::=t🪙2]" using assms by (nominal_induct t🪙1 avoiding: t🪙2 z rule: trm.strong_induct)
(auto simp: abs_fresh fresh_nat fresh_atm)
lemma fresh_subst': fixes z::"name" assumes"z♯[y].t🪙1""z♯t🪙2" shows"z♯t🪙1[y::=t🪙2]" using assms by (nominal_induct t🪙1 avoiding: y t🪙2 z rule: trm.strong_induct)
(auto simp: abs_fresh fresh_nat fresh_atm)
lemma fresh_subst: fixes z::"name" assumes a: "z♯t🪙1""z♯t🪙2" shows"z♯t🪙1[y::=t🪙2]" using a by (auto simp: fresh_subst' abs_fresh)
lemma fresh_psubst_simp: assumes"x♯t" shows"((x,u)#θ) = θ" using assms proof (nominal_induct t avoiding: x u θ rule: trm.strong_induct) case (Lam y t x u) have fs: "y♯θ""y♯x""y♯u"by fact+ moreoverhave"x♯ Lam [y].t"by fact ultimatelyhave"x♯t"by (simp add: abs_fresh fresh_atm) moreoverhave ih:"∧n T. n♯t ==> ((n,T)#θ) = θ"by fact ultimatelyhave"((x,u)#θ) = θ"by auto moreoverhave"((x,u)#θ) = Lam [y].(((x,u)#θ))"using fs by (simp add: fresh_list_cons fresh_prod) moreoverhave" θ = Lam [y]. (θ)"using fs by simp ultimatelyshow"((x,u)#θ) = θ"by auto qed (auto simp: fresh_atm abs_fresh)
lemma forget: fixes x::"name" assumes a: "x♯t" shows"t[x::=t'] = t" using a by (nominal_induct t avoiding: x t' rule: trm.strong_induct)
(auto simp: fresh_atm abs_fresh)
lemma subst_fun_eq: fixes u::trm assumes h:"[x].t🪙1 = [y].t🪙2" shows"t🪙1[x::=u] = t🪙2[y::=u]" proof -
{ assume"x=y"and"t🪙1=t🪙2" thenhave ?thesis using h by simp
} moreover
{ assume h1:"x ≠ y"and h2:"t🪙1=[(x,y)] ∙ t🪙2"and h3:"x ♯ t🪙2" thenhave"([(x,y)] ∙ t🪙2)[x::=u] = t🪙2[y::=u]"by (simp add: subst_rename) thenhave ?thesis using h2 by simp
} ultimatelyshow ?thesis using alpha h by blast qed
lemma psubst_empty[simp]: shows"[] = t" by (nominal_induct t rule: trm.strong_induct)
(auto simp: fresh_list_nil)
lemma psubst_subst_psubst: assumes h:"c♯θ" shows"θ[c::=s] = ((c,s)#θ)" using h by (nominal_induct t avoiding: θ c s rule: trm.strong_induct)
(auto simp: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst)
lemma subst_fresh_simp: assumes a: "x♯θ" shows"θ = Var x" using a by (induct θ arbitrary: x) (auto simp:fresh_list_cons fresh_prod fresh_atm)
lemma psubst_subst_propagate: assumes"x♯θ" shows"θ = θ[x::=θ]" using assms proof (nominal_induct t avoiding: x u θ rule: trm.strong_induct) case (Var n x u θ)
{ assume"x=n" moreoverhave"x♯θ"by fact ultimatelyhave"θ = θ[x::=θ]"using subst_fresh_simp by auto
} moreover
{ assume h:"x≠n" thenhave"x♯Var n"by (auto simp: fresh_atm) moreoverhave"x♯θ"by fact ultimatelyhave"x♯θ"using fresh_psubst by blast thenhave" θ[x::=θ] = θ"using forget by auto thenhave"θ = θ[x::=θ]"using h by auto
} ultimatelyshow ?caseby auto next case (Lam n t x u θ) have fs:"n♯x""n♯u""n♯θ""x♯θ"by fact+ have ih:"∧ y s θ. y♯θ ==> ((θ<(t[y::=s])>) = ((θ)[y::=(θ)]))"by fact have"θ <(Lam [n].t)[x::=u]> = θ"using fs by auto thenhave"θ <(Lam [n].t)[x::=u]> = Lam [n]. θ"using fs by auto moreoverhave"θ = θ[x::=θ]"using ih fs by blast ultimatelyhave"θ <(Lam [n].t)[x::=u]> = Lam [n].(θ[x::=θ])"by auto moreoverhave"Lam [n].(θ[x::=θ]) = (Lam [n].θ)[x::=θ]"using fs fresh_psubst by auto ultimatelyhave"θ<(Lam [n].t)[x::=u]> = (Lam [n].θ)[x::=θ]"using fs by auto thenshow"θ<(Lam [n].t)[x::=u]> = θ[x::=θ]"using fs by auto qed (auto)
lemma valid_monotonicity[elim]: fixes Γ Γ' :: Ctxt assumes a: "Γ ⊆ Γ'" and b: "x♯Γ'" shows"(x,T🪙1)#Γ ⊆ (x,T🪙1)#Γ'" using a b by auto
lemma fresh_context: fixes Γ :: "Ctxt" and a :: "name" assumes"a♯Γ" shows"¬(∃τ::ty. (a,τ)∈set Γ)" using assms by (induct Γ)
(auto simp: fresh_prod fresh_list_cons fresh_atm)
lemma type_unicity_in_context: assumes a: "valid Γ" and b: "(x,T🪙1) ∈ set Γ" and c: "(x,T🪙2) ∈ set Γ" shows"T🪙1=T🪙2" using a b c by (induct Γ)
(auto dest!: fresh_context)
abbreviation
nf :: "trm ==> bool" (‹_ ↝|› [100] 100) where "t↝| ≡¬(∃ u. t ↝ u)"
inductive
whn_def :: "trm==>trm==>bool" (‹_ ⇓ _› [80,80] 80) where
QAN_Reduce[intro]: "[s ↝ t; t ⇓ u]==> s ⇓ u"
| QAN_Normal[intro]: "t↝| ==> t ⇓ t"
declare trm.inject[simp]
inductive_cases whn_inv_auto[elim]: "t ⇓ t'"
declare trm.inject[simp del]
equivariance whn_def
lemma red_unicity : assumes a: "x ↝ a" and b: "x ↝ b" shows"a=b" using a b by (induct arbitrary: b) (use subst_fun_eq in blast)+
lemma nf_unicity : assumes"x ⇓ a"and"x ⇓ b" shows"a=b" using assms proof (induct arbitrary: b) case (QAN_Reduce x t a b) have h:"x ↝ t""t ⇓ a"by fact+ have ih:"∧b. t ⇓ b ==> a = b"by fact obtain t' where"x ↝ t'"and hl:"t' ⇓ b"using h ‹x ⇓ b›by auto thenhave"t=t'"using h red_unicity by auto thenshow"a=b"using ih hl by auto qed (auto)
section‹Algorithmic Term Equivalence and Algorithmic Path Equivalence›
inductive
alg_equiv :: "Ctxt==>trm==>trm==>ty==>bool" (‹_ ⊨ _ ⇔ _ : _› [60,60,60,60] 60) and
alg_path_equiv :: "Ctxt==>trm==>trm==>ty==>bool" (‹_ ⊨ _ ↔ _ : _› [60,60,60,60] 60) where
QAT_Base[intro]: "[s ⇓ p; t ⇓ q; Γ ⊨ p ↔ q : TBase]==> Γ ⊨ s ⇔ t : TBase"
| QAT_Arrow[intro]: "[x♯(Γ,s,t); (x,T🪙1)#Γ ⊨ App s (Var x) ⇔ App t (Var x) : T🪙2] ==> Γ ⊨ s ⇔ t : T🪙1 → T🪙2"
| QAT_One[intro]: "valid Γ ==> Γ ⊨ s ⇔ t : TUnit"
| QAP_Var[intro]: "[valid Γ;(x,T) ∈ set Γ]==> Γ ⊨ Var x ↔ Var x : T"
| QAP_App[intro]: "[Γ ⊨ p ↔ q : T🪙1 → T🪙2; Γ ⊨ s ⇔ t : T🪙1]==> Γ ⊨ App p s ↔ App q t : T🪙2"
| QAP_Const[intro]: "valid Γ ==> Γ ⊨ Const n ↔ Const n : TBase"
equivariance alg_equiv
nominal_inductive alg_equiv avoids QAT_Arrow: x by simp_all
"Γ ⊨ Var x ↔ t : T" "Γ ⊨ Var x ↔ t : T'" "Γ ⊨ s ↔ Var x : T" "Γ ⊨ s ↔ Var x : T'" "Γ ⊨ Const n ↔ t : T" "Γ ⊨ s ↔ Const n : T" "Γ ⊨ App p s ↔ t : T" "Γ ⊨ s ↔ App q t : T" "Γ ⊨ Lam[x].s ↔ t : T" "Γ ⊨ t ↔ Lam[x].s : T"
lemma Q_Arrow_strong_inversion: assumes fs: "x♯Γ""x♯t""x♯u" and h: "Γ ⊨ t ⇔ u : T🪙1→T🪙2" shows"(x,T🪙1)#Γ ⊨ App t (Var x) ⇔ App u (Var x) : T🪙2" proof - obtain y where fs2: "y♯(Γ,t,u)"and"(y,T🪙1)#Γ ⊨ App t (Var y) ⇔ App u (Var y) : T🪙2" using h by auto thenhave"([(x,y)]∙((y,T🪙1)#Γ)) ⊨ [(x,y)]∙ App t (Var y) ⇔ [(x,y)]∙ App u (Var y) : T🪙2" using alg_equiv.eqvt[simplified] by blast thenshow ?thesis using fs fs2 by (perm_simp) qed
(* Warning this lemma is false: lemma algorithmic_type_unicity: shows "[ Γ ⊨ s ⇔ t : T ; Γ ⊨ s ⇔ u : T' ]==> T = T'" and "[ Γ ⊨ s ↔ t : T ; Γ ⊨ s ↔ u : T' ]==> T = T'" Here is the counter example : Γ ⊨ Const n ⇔ Const n : Tbase and Γ ⊨ Const n ⇔ Const n : TUnit *)
lemma algorithmic_path_type_unicity: shows"Γ ⊨ s ↔ t : T ==> Γ ⊨ s ↔ u : T' ==> T = T'" proof (induct arbitrary: u T'
rule: alg_equiv_alg_path_equiv.inducts(2) [of _ _ _ _ _ "%a b c d . True" ]) case (QAP_Var Γ x T u T') have"Γ ⊨ Var x ↔ u : T'"by fact thenhave"u=Var x"and"(x,T') ∈ set Γ"by auto moreoverhave"valid Γ""(x,T) ∈ set Γ"by fact+ ultimatelyshow"T=T'"using type_unicity_in_context by auto next case (QAP_App Γ p q T🪙1 T🪙2 s t u T🪙2') have ih:"∧u T. Γ ⊨ p ↔ u : T ==> T🪙1→T🪙2 = T"by fact have"Γ ⊨ App p s ↔ u : T🪙2'"by fact thenobtain r t T🪙1' where"u = App r t""Γ ⊨ p ↔ r : T🪙1' → T🪙2'"by auto with ih have"T🪙1→T🪙2 = T🪙1' → T🪙2'"by auto thenshow"T🪙2=T🪙2'"using ty.inject by auto qed (auto)
lemma alg_path_equiv_implies_valid: shows"Γ ⊨ s ⇔ t : T ==> valid Γ" and"Γ ⊨ s ↔ t : T ==> valid Γ" by (induct rule : alg_equiv_alg_path_equiv.inducts) auto
lemma algorithmic_symmetry: shows"Γ ⊨ s ⇔ t : T ==> Γ ⊨ t ⇔ s : T" and"Γ ⊨ s ↔ t : T ==> Γ ⊨ t ↔ s : T" by (induct rule: alg_equiv_alg_path_equiv.inducts)
(auto simp: fresh_prod)
lemma algorithmic_transitivity: shows"Γ ⊨ s ⇔ t : T ==> Γ ⊨ t ⇔ u : T ==> Γ ⊨ s ⇔ u : T" and"Γ ⊨ s ↔ t : T ==> Γ ⊨ t ↔ u : T ==> Γ ⊨ s ↔ u : T" proof (nominal_induct Γ s t T and Γ s t T avoiding: u rule: alg_equiv_alg_path_equiv.strong_inducts) case (QAT_Base s p t q Γ u) have"Γ ⊨ t ⇔ u : TBase"by fact thenobtain r' q' where b1: "t ⇓ q'"and b2: "u ⇓ r'"and b3: "Γ ⊨ q' ↔ r' : TBase"by auto have ih: "Γ ⊨ q ↔ r' : TBase ==> Γ ⊨ p ↔ r' : TBase"by fact have"t ⇓ q"by fact with b1 have eq: "q=q'"by (simp add: nf_unicity) with ih b3 have"Γ ⊨ p ↔ r' : TBase"by simp moreover have"s ⇓ p"by fact ultimatelyshow"Γ ⊨ s ⇔ u : TBase"using b2 by auto next case (QAT_Arrow x Γ s t T🪙1 T🪙2 u) have ih:"(x,T🪙1)#Γ ⊨ App t (Var x) ⇔ App u (Var x) : T🪙2 ==> (x,T🪙1)#Γ ⊨ App s (Var x) ⇔ App u (Var x) : T🪙2"by fact have fs: "x♯Γ""x♯s""x♯t""x♯u"by fact+ have"Γ ⊨ t ⇔ u : T🪙1→T🪙2"by fact thenhave"(x,T🪙1)#Γ ⊨ App t (Var x) ⇔ App u (Var x) : T🪙2"using fs by (simp add: Q_Arrow_strong_inversion) with ih have"(x,T🪙1)#Γ ⊨ App s (Var x) ⇔ App u (Var x) : T🪙2"by simp thenshow"Γ ⊨ s ⇔ u : T🪙1→T🪙2"using fs by (auto simp: fresh_prod) next case (QAP_App Γ p q T🪙1 T🪙2 s t u) have"Γ ⊨ App q t ↔ u : T🪙2"by fact thenobtain r T🪙1' v where ha: "Γ ⊨ q ↔ r : T🪙1'→T🪙2"and hb: "Γ ⊨ t ⇔ v : T🪙1'"and eq: "u = App r v" by auto have ih1: "Γ ⊨ q ↔ r : T🪙1→T🪙2 ==> Γ ⊨ p ↔ r : T🪙1→T🪙2"by fact have ih2:"Γ ⊨ t ⇔ v : T🪙1 ==> Γ ⊨ s ⇔ v : T🪙1"by fact have"Γ ⊨ p ↔ q : T🪙1→T🪙2"by fact thenhave"Γ ⊨ q ↔ p : T🪙1→T🪙2"by (simp add: algorithmic_symmetry) with ha have"T🪙1'→T🪙2 = T🪙1→T🪙2"using algorithmic_path_type_unicity by simp thenhave"T🪙1' = T🪙1"by (simp add: ty.inject) thenhave"Γ ⊨ s ⇔ v : T🪙1""Γ ⊨ p ↔ r : T🪙1→T🪙2"using ih1 ih2 ha hb by auto thenshow"Γ ⊨ App p s ↔ u : T🪙2"using eq by auto qed (auto)
lemma algorithmic_weak_head_closure: shows"Γ ⊨ s ⇔ t : T ==> s' ↝ s ==> t' ↝ t ==> Γ ⊨ s' ⇔ t' : T" proof (nominal_induct Γ s t T avoiding: s' t'
rule: alg_equiv_alg_path_equiv.strong_inducts(1) [of _ _ _ _ "λa b c d e. True"]) qed(auto intro!: QAT_Arrow)
lemma algorithmic_monotonicity: shows"Γ ⊨ s ⇔ t : T ==> Γ ⊆ Γ' ==> valid Γ' ==> Γ' ⊨ s ⇔ t : T" and"Γ ⊨ s ↔ t : T ==> Γ ⊆ Γ' ==> valid Γ' ==> Γ' ⊨ s ↔ t : T" proof (nominal_induct Γ s t T and Γ s t T avoiding: Γ' rule: alg_equiv_alg_path_equiv.strong_inducts) case (QAT_Arrow x Γ s t T🪙1 T🪙2 Γ') have fs:"x♯Γ""x♯s""x♯t""x♯Γ'"by fact+ have h2:"Γ ⊆ Γ'"by fact have ih:"∧Γ'. [(x,T🪙1)#Γ ⊆ Γ'; valid Γ']==> Γ' ⊨ App s (Var x) ⇔ App t (Var x) : T??2"by fact have"valid Γ'"by fact thenhave"valid ((x,T🪙1)#Γ')"using fs by auto moreover have sub: "(x,T🪙1)#Γ ⊆ (x,T🪙1)#Γ'"using h2 by auto ultimatelyhave"(x,T🪙1)#Γ' ⊨ App s (Var x) ⇔ App t (Var x) : T🪙2"using ih by simp thenshow"Γ' ⊨ s ⇔ t : T🪙1→T🪙2"using fs by (auto simp: fresh_prod) qed (auto)
lemma path_equiv_implies_nf: assumes"Γ ⊨ s ↔ t : T" shows"s ↝|"and"t ↝|" using assms by (induct rule: alg_equiv_alg_path_equiv.inducts(2)) (simp, auto)
section‹Logical Equivalence›
function log_equiv :: "(Ctxt ==> trm ==> trm ==> ty ==> bool)" (‹_ ⊨ _ is _ : _› [60,60,60,60] 60) where "Γ ⊨ s is t : TUnit = True"
| "Γ ⊨ s is t : TBase = Γ ⊨ s ⇔ t : TBase"
| "Γ ⊨ s is t : (T🪙1 → T🪙2) = (∀Γ' s' t'. Γ⊆Γ' ⟶ valid Γ' ⟶ Γ' ⊨ s' is t' : T🪙1 ⟶ (Γ' ⊨ (App s s') is (App t t') : T🪙2))" using ty_cases by (force simp: ty.inject)+
terminationby lexicographic_order
lemma logical_monotonicity: fixes Γ Γ' :: Ctxt assumes a1: "Γ ⊨ s is t : T" and a2: "Γ ⊆ Γ'" and a3: "valid Γ'" shows"Γ' ⊨ s is t : T" using a1 a2 a3 proof (induct arbitrary: Γ' rule: log_equiv.induct) case (2 Γ s t Γ') thenshow"Γ' ⊨ s is t : TBase"using algorithmic_monotonicity by auto next case (3 Γ s t T🪙1 T🪙2 Γ') have"Γ ⊨ s is t : T🪙1→T🪙2" and"Γ ⊆ Γ'" and"valid Γ'"by fact+ thenshow"Γ' ⊨ s is t : T🪙1→T🪙2"by simp qed (auto)
lemma main_lemma: shows"Γ ⊨ s is t : T ==> valid Γ ==> Γ ⊨ s ⇔ t : T" and"Γ ⊨ p ↔ q : T ==> Γ ⊨ p is q : T" proof (nominal_induct T arbitrary: Γ s t p q rule: ty.strong_induct) case (Arrow T🪙1 T🪙2)
{ case (1 Γ s t) have ih1:"∧Γ s t. [Γ ⊨ s is t : T🪙2; valid Γ]==> Γ ⊨ s ⇔ t : T🪙2"by fact have ih2:"∧Γ s t. Γ ⊨ s ↔ t : T🪙1 ==> Γ ⊨ s is t : T🪙1"by fact have h:"Γ ⊨ s is t : T🪙1→T🪙2"by fact obtain x::name where fs:"x♯(Γ,s,t)"by (erule exists_fresh[OF fs_name1]) have"valid Γ"by fact thenhave v: "valid ((x,T🪙1)#Γ)"using fs by auto thenhave"(x,T🪙1)#Γ ⊨ Var x ↔ Var x : T🪙1"by auto thenhave"(x,T🪙1)#Γ ⊨ Var x is Var x : T🪙1"using ih2 by auto thenhave"(x,T🪙1)#Γ ⊨ App s (Var x) is App t (Var x) : T🪙2"using h v by auto thenhave"(x,T🪙1)#Γ ⊨ App s (Var x) ⇔ App t (Var x) : T🪙2"using ih1 v by auto thenshow"Γ ⊨ s ⇔ t : T🪙1→T🪙2"using fs by (auto simp: fresh_prod) next case (2 Γ p q) have h: "Γ ⊨ p ↔ q : T🪙1→T🪙2"by fact have ih1:"∧Γ s t. Γ ⊨ s ↔ t : T🪙2 ==> Γ ⊨ s is t : T🪙2"by fact have ih2:"∧Γ s t. [Γ ⊨ s is t : T🪙1; valid Γ]==> Γ ⊨ s ⇔ t : T🪙1"by fact
{ fix Γ' s t assume"Γ ⊆ Γ'"and hl:"Γ' ⊨ s is t : T🪙1"and hk: "valid Γ'" thenhave"Γ' ⊨ p ↔ q : T🪙1 → T🪙2"using h algorithmic_monotonicity by auto moreoverhave"Γ' ⊨ s ⇔ t : T🪙1"using ih2 hl hk by auto ultimatelyhave"Γ' ⊨ App p s ↔ App q t : T🪙2"by auto thenhave"Γ' ⊨ App p s is App q t : T🪙2"using ih1 by auto
} thenshow"Γ ⊨ p is q : T🪙1→T🪙2"by simp
} next case TBase
{ case 2 have h:"Γ ⊨ s ↔ t : TBase"by fact thenhave"s ↝|"and"t ↝|"using path_equiv_implies_nf by auto thenhave"s ⇓ s"and"t ⇓ t"by auto thenhave"Γ ⊨ s ⇔ t : TBase"using h by auto thenshow"Γ ⊨ s is t : TBase"by auto
} qed (auto elim: alg_path_equiv_implies_valid)
corollary corollary_main: assumes a: "Γ ⊨ s ↔ t : T" shows"Γ ⊨ s ⇔ t : T" using a main_lemma alg_path_equiv_implies_valid by blast
lemma logical_symmetry: assumes a: "Γ ⊨ s is t : T" shows"Γ ⊨ t is s : T" using a by (nominal_induct arbitrary: Γ s t rule: ty.strong_induct)
(auto simp: algorithmic_symmetry)
lemma logical_transitivity: assumes"Γ ⊨ s is t : T""Γ ⊨ t is u : T" shows"Γ ⊨ s is u : T" using assms proof (nominal_induct arbitrary: Γ s t u rule:ty.strong_induct) case TBase thenshow"Γ ⊨ s is u : TBase"by (auto elim: algorithmic_transitivity) next case (Arrow T🪙1 T🪙2 Γ s t u) have h1:"Γ ⊨ s is t : T🪙1 → T🪙2"by fact have h2:"Γ ⊨ t is u : T🪙1 → T🪙2"by fact have ih1:"∧Γ s t u. [Γ ⊨ s is t : T🪙1; Γ ⊨ t is u : T🪙1]==> Γ ⊨ s is u : T🪙1"by fact have ih2:"∧Γ s t u. [Γ ⊨ s is t : T🪙2; Γ ⊨ t is u : T🪙2]==> Γ ⊨ s is u : T🪙2"by fact
{ fix Γ' s' u' assume hsub:"Γ ⊆ Γ'"and hl:"Γ' ⊨ s' is u' : T🪙1"and hk: "valid Γ'" thenhave"Γ' ⊨ u' is s' : T🪙1"using logical_symmetry by blast thenhave"Γ' ⊨ u' is u' : T🪙1"using ih1 hl by blast thenhave"Γ' ⊨ App t u' is App u u' : T🪙2"using h2 hsub hk by auto moreoverhave"Γ' ⊨ App s s' is App t u' : T🪙2"using h1 hsub hl hk by auto ultimatelyhave"Γ' ⊨ App s s' is App u u' : T🪙2"using ih2 by blast
} thenshow"Γ ⊨ s is u : T🪙1 → T🪙2"by auto qed (auto)
lemma logical_weak_head_closure: assumes a: "Γ ⊨ s is t : T" and b: "s' ↝ s" and c: "t' ↝ t" shows"Γ ⊨ s' is t' : T" using a b c algorithmic_weak_head_closure proof (nominal_induct arbitrary: Γ s t s' t' rule: ty.strong_induct) next case (Arrow ty1 ty2) thenshow ?case by (smt (verit, ccfv_threshold) QAR_App log_equiv.simps(3)) qed auto
lemma logical_weak_head_closure': assumes"Γ ⊨ s is t : T"and"s' ↝ s" shows"Γ ⊨ s' is t : T" using assms proof (nominal_induct arbitrary: Γ s t s' rule: ty.strong_induct) case (TBase Γ s t s') thenshow ?caseby force next case (TUnit Γ s t s') thenshow ?caseby auto next case (Arrow T🪙1 T🪙2 Γ s t s') have h1:"s' ↝ s"by fact have ih:"∧Γ s t s'. [Γ ⊨ s is t : T🪙2; s' ↝ s]==> Γ ⊨ s' is t : T🪙2"by fact have h2:"Γ ⊨ s is t : T🪙1→T🪙2"by fact then have hb:"∀Γ' s' t'. Γ⊆Γ' ⟶ valid Γ' ⟶ Γ' ⊨ s' is t' : T🪙1 ⟶ (Γ' ⊨ (App s s') is (App t t') : T🪙2)" by auto
{ fix Γ' s🪙2 t🪙2 assume"Γ ⊆ Γ'"and"Γ' ⊨ s🪙2 is t🪙2 : T🪙1"and"valid Γ'" thenhave"Γ' ⊨ (App s s🪙2) is (App t t🪙2) : T🪙2"using hb by auto moreoverhave"(App s' s🪙2) ↝ (App s s🪙2)"using h1 by auto ultimatelyhave"Γ' ⊨ App s' s🪙2 is App t t🪙2 : T🪙2"using ih by auto
} thenshow"Γ ⊨ s' is t : T🪙1→T🪙2"by auto qed
abbreviation
log_equiv_for_psubsts :: "Ctxt ==> Subst ==> Subst ==> Ctxt ==> bool" (‹_ ⊨ _ is _ over _› [60,60] 60) where "Γ' ⊨ θ is θ' over Γ ≡∀x T. (x,T) ∈ set Γ ⟶ Γ' ⊨ θ is θ' : T"
lemma logical_pseudo_reflexivity: assumes"Γ' ⊨ t is s over Γ" shows"Γ' ⊨ s is s over Γ" by (meson assms logical_symmetry logical_transitivity)
lemma logical_subst_monotonicity : fixes Γ Γ' Γ'' :: Ctxt assumes a: "Γ' ⊨ θ is θ' over Γ" and b: "Γ' ⊆ Γ''" and c: "valid Γ''" shows"Γ'' ⊨ θ is θ' over Γ" using a b c logical_monotonicity by blast
lemma equiv_subst_ext : assumes h1: "Γ' ⊨ θ is θ' over Γ" and h2: "Γ' ⊨ s is t : T" and fs: "x♯Γ" shows"Γ' ⊨ (x,s)#θ is (x,t)#θ' over (x,T)#Γ" using assms proof -
{ fix y U assume"(y,U) ∈ set ((x,T)#Γ)" moreover
{ assume"(y,U) ∈ set [(x,T)]" with h2 have"Γ' ⊨ ((x,s)#θ) is ((x,t)#θ') : U"by auto
} moreover
{ assume hl:"(y,U) ∈ set Γ" thenhave"¬ y♯Γ"by (induct Γ) (auto simp: fresh_list_cons fresh_atm fresh_prod) thenhave hf:"x♯ Var y"using fs by (auto simp: fresh_atm) thenhave"((x,s)#θ) = θ""((x,t)#θ') = θ'" using fresh_psubst_simp by blast+ moreoverhave"Γ' ⊨ θ is θ' : U"using h1 hl by auto ultimatelyhave"Γ' ⊨ ((x,s)#θ) is ((x,t)#θ') : U"by auto
} ultimatelyhave"Γ' ⊨ ((x,s)#θ) is ((x,t)#θ') : U"by auto
} thenshow"Γ' ⊨ (x,s)#θ is (x,t)#θ' over (x,T)#Γ"by auto qed
theorem fundamental_theorem_1: assumes a1: "Γ ⊨ t : T" and a2: "Γ' ⊨ θ is θ' over Γ" and a3: "valid Γ'" shows"Γ' ⊨ θ is θ' : T" using a1 a2 a3 proof (nominal_induct Γ t T avoiding: θ θ' arbitrary: Γ' rule: typing.strong_induct) case (T_Lam x Γ T🪙1 t🪙2 T🪙2 θ θ' Γ') have vc: "x♯θ""x♯θ'""x♯Γ"by fact+ have asm1: "Γ' ⊨ θ is θ' over Γ"by fact have ih:"∧θ θ' Γ'. [Γ' ⊨ θ is θ' over (x,T🪙1)#Γ; valid Γ']==> Γ' ⊨ θ🪙2> is θ'🪙2> : T🪙2" by fact show"Γ' ⊨ θ🪙2> is θ'🪙2> : T🪙1→T🪙2" using vc proof (simp, intro strip) fix Γ'' s' t' assume sub: "Γ' ⊆ Γ''" and asm2: "Γ''⊨ s' is t' : T🪙1" and val: "valid Γ''" from asm1 val sub have"Γ'' ⊨ θ is θ' over Γ"using logical_subst_monotonicity by blast with asm2 vc have"Γ'' ⊨ (x,s')#θ is (x,t')#θ' over (x,T🪙1)#Γ"using equiv_subst_ext by blast with ih val have"Γ'' ⊨ ((x,s')#θ)🪙2> is ((x,t')#θ')🪙2> : T🪙2" by auto with vc have"Γ''⊨θ🪙2>[x::=s'] is θ'🪙2>[x::=t'] : T🪙2" by (simp add: psubst_subst_psubst) moreover have"App (Lam [x].θ🪙2>) s' ↝ θ🪙2>[x::=s']" by auto moreover have"App (Lam [x].θ'🪙2>) t' ↝ θ'🪙2>[x::=t']" by auto ultimatelyshow"Γ''⊨ App (Lam [x].θ🪙2>) s' is App (Lam [x].θ'🪙2>) t' : T🪙2" using logical_weak_head_closure by auto qed qed (auto)
theorem fundamental_theorem_2: assumes h1: "Γ ⊨ s ≡ t : T" and h2: "Γ' ⊨ θ is θ' over Γ" and h3: "valid Γ'" shows"Γ' ⊨ θ is θ' : T" using h1 h2 h3 proof (nominal_induct Γ s t T avoiding: Γ' θ θ' rule: def_equiv.strong_induct) case (Q_Refl Γ t T Γ' θ θ') thenshow"Γ' ⊨ θ is θ' : T"using fundamental_theorem_1 by blast next case (Q_Symm Γ t s T Γ' θ θ') thenshow"Γ' ⊨ θ is θ' : T"using logical_symmetry by blast next case (Q_Trans Γ s t T u Γ' θ θ') have ih1: "∧ Γ' θ θ'. [Γ' ⊨ θ is θ' over Γ; valid Γ']==> Γ' ⊨ θ is θ' : T"by fact have ih2: "∧ Γ' θ θ'. [Γ' ⊨ θ is θ' over Γ; valid Γ']==> Γ' ⊨ θ is θ' : T"by fact have h: "Γ' ⊨ θ is θ' over Γ" and v: "valid Γ'"by fact+ thenhave"Γ' ⊨ θ' is θ' over Γ"using logical_pseudo_reflexivity by auto thenhave"Γ' ⊨ θ' is θ' : T"using ih2 v by auto moreoverhave"Γ' ⊨ θ is θ' : T"using ih1 h v by auto ultimatelyshow"Γ' ⊨ θ is θ' : T"using logical_transitivity by blast next case (Q_Abs x Γ T🪙1 s🪙2 t🪙2 T🪙2 Γ' θ θ') have fs:"x♯Γ"by fact have fs2: "x♯θ""x♯θ'"by fact+ have h2: "Γ' ⊨ θ is θ' over Γ" and h3: "valid Γ'"by fact+ have ih:"∧Γ' θ θ'. [Γ' ⊨ θ is θ' over (x,T🪙1)#Γ; valid Γ']==> Γ' ⊨ θ🪙2> is θ'🪙2> : T🪙2" by fact
{ fix Γ'' s' t' assume"Γ' ⊆ Γ''"and hl:"Γ''⊨ s' is t' : T🪙1"and hk: "valid Γ''" thenhave"Γ'' ⊨ θ is θ' over Γ"using h2 logical_subst_monotonicity by blast thenhave"Γ'' ⊨ (x,s')#θ is (x,t')#θ' over (x,T🪙1)#Γ"using equiv_subst_ext hl fs by blast thenhave"Γ'' ⊨ ((x,s')#θ)🪙2> is ((x,t')#θ')🪙2> : T🪙2" using ih hk by blast thenhave"Γ''⊨ θ🪙2>[x::=s'] is θ'🪙2>[x::=t'] : T🪙2" using fs2 psubst_subst_psubst by auto moreoverhave"App (Lam [x]. θ🪙2>) s' ↝ θ🪙2>[x::=s']" and"App (Lam [x].θ'🪙2>) t' ↝ θ'🪙2>[x::=t']" by auto ultimatelyhave"Γ'' ⊨ App (Lam [x]. θ🪙2>) s' is App (Lam [x].θ'🪙2>) t' : T🪙2" using logical_weak_head_closure by auto
} moreoverhave"valid Γ'"by fact ultimatelyhave"Γ' ⊨ Lam [x].θ🪙2> is Lam [x].θ'🪙2> : T🪙1→T🪙2" by auto thenshow"Γ' ⊨ θ🪙2> is θ'🪙2> : T🪙1→T🪙2" using fs2 by auto next case (Q_App Γ s🪙1 t🪙1 T🪙1 T🪙2 s🪙2 t🪙2 Γ' θ θ') thenshow"Γ' ⊨ θ🪙1 s🪙2> is θ'🪙1 t🪙2> : T🪙2" by auto next case (Q_Beta x Γ s🪙2 t🪙2 T🪙1 s12 t12 T🪙2 Γ' θ θ') have h: "Γ' ⊨ θ is θ' over Γ" and h': "valid Γ'"by fact+ have fs: "x♯Γ"by fact have fs2: " x♯θ""x♯θ'"by fact+ have ih1: "∧Γ' θ θ'. [Γ' ⊨ θ is θ' over Γ; valid Γ']==> Γ' ⊨ θ🪙2> is θ'🪙2> : T🪙1" by fact have ih2: "∧Γ' θ θ'. [Γ' ⊨ θ is θ' over (x,T🪙1)#Γ; valid Γ']==> Γ' ⊨ θ is θ' : T🪙2"by fact have"Γ' ⊨ θ🪙2> is θ'🪙2> : T🪙1" using ih1 h' h by auto thenhave"Γ' ⊨ (x,θ🪙2>)#θ is (x,θ'🪙2>)#θ' over (x,T🪙1)#Γ" using equiv_subst_ext h fs by blast thenhave"Γ' ⊨ ((x,θ🪙2>)#θ) is ((x,θ'🪙2>)#θ') : T🪙2" using ih2 h' by auto thenhave"Γ' ⊨ θ[x::=θ🪙2>] is θ'[x::=θ'🪙2>] : T🪙2" using fs2 psubst_subst_psubst by auto thenhave"Γ' ⊨ θ[x::=θ🪙2>] is θ'🪙2]> : T🪙2" using fs2 psubst_subst_propagate by auto moreoverhave"App (Lam [x].θ) (θ🪙2>) ↝ θ[x::=θ🪙2>]" by auto ultimatelyhave"Γ' ⊨ App (Lam [x].θ) (θ🪙2>) is θ'🪙2]> : T🪙2" using logical_weak_head_closure' by auto thenshow"Γ' ⊨ θ🪙2> is θ'🪙2]> : T🪙2" using fs2 by simp next case (Q_Ext x Γ s t T🪙1 T🪙2 Γ' θ θ') have h2: "Γ' ⊨ θ is θ' over Γ" and h2': "valid Γ'"by fact+ have fs:"x♯Γ""x♯s""x♯t"by fact+ have ih:"∧Γ' θ θ'. [Γ' ⊨ θ is θ' over (x,T🪙1)#Γ; valid Γ'] ==> Γ' ⊨ θ is θ' : T🪙2"by fact
{ fix Γ'' s' t' assume hsub: "Γ' ⊆ Γ''"and hl: "Γ''⊨ s' is t' : T🪙1"and hk: "valid Γ''" thenhave"Γ'' ⊨ θ is θ' over Γ"using h2 logical_subst_monotonicity by blast thenhave"Γ'' ⊨ (x,s')#θ is (x,t')#θ' over (x,T🪙1)#Γ"using equiv_subst_ext hl fs by blast thenhave"Γ'' ⊨ ((x,s')#θ) is ((x,t')#θ') : T🪙2"using ih hk by blast then have"Γ'' ⊨ App (((x,s')#θ)) (((x,s')#θ)<(Var x)>) is App (((x,t')#θ')) (((x,t')#θ')<(Var x)>) : T🪙2" by auto thenhave"Γ'' ⊨ App ((x,s')#θ) s' is App ((x,t')#θ') t' : T🪙2"by auto thenhave"Γ'' ⊨ App (θ) s' is App (θ') t' : T🪙2"using fs fresh_psubst_simp by auto
} moreoverhave"valid Γ'"by fact ultimatelyshow"Γ' ⊨ θ is θ' : T🪙1→T🪙2"by auto next case (Q_Unit Γ s t Γ' θ θ') thenshow"Γ' ⊨ θ is θ' : TUnit"by auto qed
theorem completeness: assumes asm: "Γ ⊨ s ≡ t : T" shows"Γ ⊨ s ⇔ t : T" proof - have val: "valid Γ"using def_equiv_implies_valid asm by simp thenhave"Γ ⊨ [] is [] over Γ" by (simp add: QAP_Var main_lemma(2)) thenhave"Γ ⊨ [] is [] : T"using fundamental_theorem_2 val asm by blast thenhave"Γ ⊨ s is t : T"by simp thenshow"Γ ⊨ s ⇔ t : T"using main_lemma(1) val by simp qed
text‹We leave soundness as an exercise - just like Crary in the ATS book :-) \\ @{prop[mode=IfThen] "[Γ ⊨ s ⇔ t : T; Γ ⊨ t : T; Γ ⊨ s : T]==> Γ ⊨ s ≡ t : T"} \\ 🍋‹[Γ ⊨ s ↔ t : T; Γ ⊨ t : T; Γ ⊨ s : T]==> Γ ⊨ s ≡ t : T› ›
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet am 2026-05-03)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.