(*<*)
theory Safety
imports Operational IVSubstTypingL BTVSubstTypingL
begin
(*>*)
method supp_calc = (metis (mono_tags, opaque_lifting) pure_supp c.supp e.supp v.supp supp_l_empty opp.supp sup_bot.right_neutral supp_at_base)
declare infer_e.intros[simp]
declare infer_e.intros[intro]
chapter ‹Safety›
text ‹Lemmas about the operational semantics leading up to progress and preservation and then
.›
section ‹Store Lemmas›
abbreviation delta_ext (‹ _ ⊑ _ ›) where
"delta_ext Δ Δ' ≡ (setD Δ ⊆ setD Δ')"
nominal_function dc_of :: "branch_s → string" where
"dc_of (AS_branch dc _ _) = dc"
apply(auto,simp add: eqvt_def dc_of_graph_aux_def)
using s_branch_s_branch_list.exhaust by metis
nominal_termination (eqvt) by lexicographic_order
lemma delta_sim_fresh:
assumes "Θ ⊨ δ ∼ Δ" and "atom u ♯ δ"
shows "atom u ♯ Δ"
using assms proof(induct rule : delta_sim.inducts)
case (delta_sim_nilI Θ)
then show ?case using fresh_def supp_DNil by blast
next
case (delta_sim_consI Θ δ Δ v τ u')
hence "Θ ; {||} ; GNil ⊨wf τ" using check_v_wf by meson
hence "supp τ = {}" using wfT_supp by fastforce
moreover have "atom u ♯ u'" using delta_sim_consI fresh_Cons fresh_Pair by blast
moreover have "atom u ♯ Δ" using delta_sim_consI fresh_Cons by blast
ultimately show ?case using fresh_Pair fresh_DCons fresh_def by blast
qed
lemma delta_sim_v:
fixes Δ::Δ
assumes "Θ ⊨ δ ∼ Δ " and "(u,v) ∈ set δ" and "(u,τ) ∈ setD Δ" and "Θ ; {||} ; GNil ⊨wf Δ"
shows "Θ ; {||} ; GNil ⊨ v ← τ"
using assms proof(induct δ arbitrary: Δ)
case Nil
then show ?case by auto
next
case (Cons uv δ)
obtain u' and v' where uv : "uv=(u',v')" by fastforce
show ?case proof(cases "u'=u")
case True
hence *:"Θ ⊨ ((u,v')#δ) ∼ Δ" using uv Cons by blast
then obtain τ' and Δ' where tt: "Θ ; {||} ; GNil ⊨ v' ← τ' ∧ u ∉ fst ` set δ ∧ Δ = (u,τ')#\<Delta>Δ'" using delta_sim_elims(3)[OF *] by metis
moreover hence "v'=v" using Cons True
by (metis Pair_inject fst_conv image_eqI set_ConsD uv)
moreover have "τ=τ'" using wfD_unique tt Cons
setD.simps list.set_intros by blast
ultimately show ?thesis by metis
next
case False
hence *:"Θ ⊨ ((u',v')#δ) ∼ Δ" using uv Cons by blast
then obtain τ' and Δ' where tt: "Θ ⊨ δ ∼ Δ' ∧ Θ ; {||} ; GNil ⊨ v' ← τ' ∧ u' ∉ fst ` set δ ∧ Δ = (u',τ')#\<Delta>Δ'" using delta_sim_elims(3)[OF *] by metis
moreover hence "Θ ; {||} ; GNil ⊨wf Δ'" using wfD_elims Cons delta_sim_elims by metis
ultimately show ?thesis using Cons
using False by auto
qed
qed
lemma delta_sim_delta_lookup:
assumes "Θ ⊨ δ ∼ Δ " and "(u, { z : b | c }) ∈ setD Δ"
shows "∃v. (u,v) ∈ set δ"
using assms by(induct rule: delta_sim.inducts,auto+)
lemma update_d_stable:
"fst ` set δ = fst ` set (update_d δ u v)"
proof(induct δ)
case Nil
then show ?case by auto
next
case (Cons a δ)
then show ?case using update_d.simps
by (metis (no_types, lifting) eq_fst_iff image_cong image_insert list.simps(15) prod.exhaust_sel)
qed
lemma update_d_sim:
fixes Δ::Δ
assumes "Θ ⊨ δ ∼ Δ" and "Θ ; {||} ; GNil ⊨ v ← τ" and "(u,τ) ∈ setD Δ" and "Θ ; {||} ; GNil ⊨wf Δ"
shows "Θ ⊨ (update_d δ u v) ∼ Δ"
using assms proof(induct δ arbitrary: Δ)
case Nil
then show ?case using delta_sim_consI by simp
next
case (Cons uv δ)
obtain u' and v' where uv : "uv=(u',v')" by fastforce
hence *:"Θ ⊨ ((u',v')#δ) ∼ Δ" using uv Cons by blast
then obtain τ' and Δ' where tt: "Θ ⊨ δ ∼ Δ' ∧ Θ ; {||} ; GNil ⊨ v' ← τ' ∧ u' ∉ fst ` set δ ∧ Δ = (u',τ')#\<Delta>Δ'" using delta_sim_elims * by metis
show ?case proof(cases "u=u'")
case True
then have "(u,τ') ∈ setD Δ" using tt by auto
then have "τ = τ'" using Cons wfD_unique by metis
moreover have "update_d ((u',v')#δ) u v = ((u',v)#δ)" using update_d.simps True by presburger
ultimately show ?thesis using delta_sim_consI tt Cons True
by (simp add: tt uv)
next
case False
have "Θ ⊨ (u',v') # (update_d δ u v) ∼ (u',τ')#\<Delta>Δ'"
proof(rule delta_sim_consI)
show "Θ ⊨ update_d δ u v ∼ Δ' " using Cons using delta_sim_consI
delta_sim.simps update_d.simps Cons delta_sim_elims uv tt
False fst_conv set_ConsD wfG_elims wfD_elims by (metis setD_ConsD)
show "Θ ; {||} ; GNil ⊨ v' ← τ'" using tt by auto
show "u' ∉ fst ` set (update_d δ u v)" using update_d.simps Cons update_d_stable tt by auto
qed
thus ?thesis using False update_d.simps uv
by (simp add: tt)
qed
qed
section ‹Preservation›
text ‹Types are preserved under reduction step. Broken down into lemmas about different operations›
subsection ‹Function Application›
lemma check_s_x_fresh:
fixes x::x and s::s
assumes "Θ ; Φ ; B ; GNil ; D ⊨ s ← τ"
shows "atom x ♯ s ∧ atom x ♯ τ ∧ atom x ♯ D"
proof -
have "Θ ; Φ ; B ; GNil ; D ⊨wf s : b_of τ" using check_s_wf[OF assms] by auto
moreover have "Θ ; B ; GNil ⊨wf τ " using check_s_wf assms by auto
moreover have "Θ ; B ; GNil ⊨wf D" using check_s_wf assms by auto
ultimately show ?thesis using wf_supp x_fresh_u
by (meson fresh_GNil wfS_x_fresh wfT_x_fresh wfD_x_fresh)
qed
lemma check_funtyp_subst_b:
fixes b'::b
assumes "check_funtyp Θ Φ {|bv|} (AF_fun_typ x b c τ s)" and ‹ Θ ; {||} ⊨wf b' ›
shows "check_funtyp Θ Φ {||} (AF_fun_typ x b[bv::=b']bb (c[bv::=b']cb) τ[bv::=b']\<tau>b s[bv::=b']sb)"
using assms proof (nominal_induct "{|bv|}" "AF_fun_typ x b c τ s" rule: check_funtyp.strong_induct)
case (check_funtypI x' Θ Φ c' s' τ')
have "check_funtyp Θ Φ {||} (AF_fun_typ x' b[bv::=b']bb (c'[bv::=b']cb) τ'[bv::=b']\<tau>b s'[bv::=b']sb)" proof
show ‹atom x' ♯ (Θ, Φ, {||}::bv fset, b[bv::=b']bb)› using check_funtypI fresh_prodN x_fresh_b fresh_empty_fset by metis
have ‹ Θ ; Φ ; {||} ; ((x', b, c') #\Γ GNil)[bv::=b']\Γb ; []\Δ[bv::=b']\Δb ⊨ s'[bv::=b']sb ← τ'[bv::=b']\τb› proof(rule subst_b_check_s)
show ‹ Θ ; {||} ⊨wf b' › using check_funtypI by metis
show ‹{|bv|} = {|bv|}› by auto
show ‹ Θ ; Φ ; {|bv|} ; (x', b, c') #\Γ GNil ; []\Δ ⊨ s' ← τ'› using check_funtypI by metis
qed
thus ‹ Θ ; Φ ; {||} ; (x', b[bv::=b']bb, c'[bv::=b']cb) #\Γ GNil ; []\Δ ⊨ s'[bv::=b']sb ← τ'[bv::=b']\τb›
using subst_gb.simps subst_db.simps by simp
qed
moreover have "(AF_fun_typ x b c τ s) = (AF_fun_typ x' b c' τ' s')" using fun_typ.eq_iff check_funtypI by metis
moreover hence "(AF_fun_typ x b[bv::=b']bb (c[bv::=b']cb) τ[bv::=b']\<tau>b s[bv::=b']sb) = (AF_fun_typ x' b[bv::=b']bb (c'[bv::=b']cb) τ'[bv::=b']\<tau>b s'[bv::=b']sb)"
using subst_ft_b.simps by metis
ultimately show ?case by metis
qed
lemma funtyp_simple_check:
fixes s::s and Δ::Δ and τ::τ and v::v
assumes "check_funtyp Θ Φ ({||}::bv fset) (AF_fun_typ x b c τ s)" and
"Θ ; {||} ; GNil ⊨ v ← { x : b | c }"
shows "Θ ; Φ ; {||} ; GNil ; DNil ⊨ s[x::=v]sv ← τ[x::=v]\<tau>v"
using assms proof(nominal_induct " ({||}::bv fset)" "AF_fun_typ x b c τ s" avoiding: v x rule: check_funtyp.strong_induct)
case (check_funtypI x' Θ Φ c' s' τ')
hence eq1: "{ x' : b | c' } = { x : b | c }" using funtyp_eq_iff_equalities by metis
obtain x'' and c'' where xf:"{ x : b | c } = { x'' : b | c'' } ∧ atom x'' ♯ (x',v) ∧ atom x'' ♯ (x,c)" using obtain_fresh_z3 by metis
moreover have "atom x' ♯ c''" proof -
have "supp { x'' : b | c'' } = {}" using eq1 check_funtypI xf check_v_wf wfT_nil_supp by metis
hence "supp c'' ⊆ { atom x'' }" using τ.supp eq1 xf by (auto simp add: freshers)
moreover have "atom x' ≠ atom x''" using xf fresh_Pair fresh_x_neq by metis
ultimately show ?thesis using xf fresh_Pair fresh_x_neq fresh_def fresh_at_base by blast
qed
ultimately have eq2: "c''[x''::=[ x' ]v]cv = c'" using eq1 type_eq_subst_eq3(1)[of x' b c' x'' b c''] by metis
have "atom x' ♯ c" proof -
have "supp { x : b | c } = {}" using eq1 check_funtypI xf check_v_wf wfT_nil_supp by metis
hence "supp c ⊆ { atom x }" using τ.supp by auto
moreover have "atom x ≠ atom x'" using check_funtypI fresh_Pair fresh_x_neq by metis
ultimately show ?thesis using fresh_def by force
qed
hence eq: " c[x::=[ x' ]v]cv = c' ∧ s'[x'::=v]sv = s[x::=v]sv ∧ τ'[x'::=v]\<tau>v = τ[x::=v]\<tau>v"
using funtyp_eq_iff_equalities type_eq_subst_eq3 check_funtypI by metis
have " Θ ; Φ ; {||} ; ((x', b, c''[x''::=[ x' ]v]cv) #\<Gamma> GNil)[x'::=v]\<Gamma>v ; []\<Delta>[x'::=v]\<Delta>v ⊨ s'[x'::=v]sv ← τ'[x'::=v]\<tau>v"
proof(rule subst_check_check_s )
show ‹Θ ; {||} ; GNil ⊨ v ← { x'' : b | c'' }› using check_funtypI eq1 xf by metis
show ‹atom x'' ♯ (x', v)› using check_funtypI fresh_x_neq fresh_Pair xf by metis
show ‹ Θ ; Φ ; {||} ; (x', b, c''[x''::=[ x' ]v]cv) #\Γ GNil ; []\Δ ⊨ s' ← τ'› using check_funtypI eq2 by metis
show ‹ (x', b, c''[x''::=[ x' ]v]cv) #\Γ GNil = GNil @ (x', b, c''[x''::=[ x' ]v]cv) #\Γ GNil› using append_g.simps by auto
qed
hence " Θ; Φ; {||}; GNil; []\<Delta> ⊨ s'[x'::=v]sv ← τ'[x'::=v]\<tau>v" using subst_gv.simps subst_dv.simps by auto
thus ?case using eq by auto
qed
lemma funtypq_simple_check:
fixes s::s and Δ::Δ and τ::τ and v::v
assumes "check_funtypq Θ Φ (AF_fun_typ_none (AF_fun_typ x b c t s))" and
"Θ ; {||} ; GNil ⊨ v ← { x : b | c }"
shows "Θ; Φ; {||}; GNil; DNil ⊨ s[x::=v]sv ← t[x::=v]\<tau>v"
using assms proof(nominal_induct "(AF_fun_typ_none (AF_fun_typ x b c t s))" avoiding: v rule: check_funtypq.strong_induct)
case (check_fundefq_simpleI Θ Φ x' c' t' s')
hence eq: "{ x : b | c } = { x' : b | c' } ∧ s'[x'::=v]sv = s[x::=v]sv ∧ t[x::=v]\<tau>v = t'[x'::=v]\<tau>v"
using funtyp_eq_iff_equalities by metis
hence "Θ; Φ; {||}; GNil; []\<Delta> ⊨ s'[x'::=v]sv ← t'[x'::=v]\<tau>v"
using funtyp_simple_check[OF check_fundefq_simpleI(1)] check_fundefq_simpleI by metis
thus ?case using eq by metis
qed
lemma funtyp_poly_eq_iff_equalities:
assumes "[[atom bv']]lst. AF_fun_typ x' b'' c' t' s' = [[atom bv]]lst. AF_fun_typ x b c t s"
shows "{ x' : b''[bv'::=b']bb | c'[bv'::=b']cb } = { x : b[bv::=b']bb | c[bv::=b']cb } ∧
s'[bv'::=b']sb[x'::=v]sv = s[bv::=b']sb[x::=v]sv ∧ t'[bv'::=b']\<tau>b[x'::=v]\<tau>v = t[bv::=b']\<tau>b[x::=v]\<tau>v"
proof -
have "subst_ft_b (AF_fun_typ x' b'' c' t' s') bv' b' = subst_ft_b (AF_fun_typ x b c t s) bv b'"
using subst_b_flip_eq_two subst_b_fun_typ_def assms by metis
thus ?thesis using fun_typ.eq_iff subst_ft_b.simps funtyp_eq_iff_equalities subst_tb.simps
by (metis (full_types) assms fun_poly_arg_unique)
qed
lemma funtypq_poly_check:
fixes s::s and Δ::Δ and τ::τ and v::v and b'::b
assumes "check_funtypq Θ Φ (AF_fun_typ_some bv (AF_fun_typ x b c t s))" and
"Θ ; {||} ; GNil ⊨ v ← { x : b[bv::=b']bb | c[bv::=b']cb }" and
"Θ ; {||} ⊨wf b'"
shows "Θ; Φ; {||}; GNil; DNil ⊨ s[bv::=b']sb[x::=v]sv ← t[bv::=b']\<tau>b[x::=v]\<tau>v"
using assms proof(nominal_induct "(AF_fun_typ_some bv (AF_fun_typ x b c t s))" avoiding: v rule: check_funtypq.strong_induct)
case (check_funtypq_polyI bv' Θ Φ x' b'' c' t' s')
hence **:"{ x' : b''[bv'::=b']bb | c'[bv'::=b']cb } = { x : b[bv::=b']bb | c[bv::=b']cb } ∧
s'[bv'::=b']sb[x'::=v]sv = s[bv::=b']sb[x::=v]sv ∧ t'[bv'::=b']\<tau>b[x'::=v]\<tau>v = t[bv::=b']\<tau>b[x::=v]\<tau>v"
using funtyp_poly_eq_iff_equalities by metis
have *:"check_funtyp Θ Φ {||} (AF_fun_typ x' b''[bv'::=b']bb (c'[bv'::=b']cb) (t'[bv'::=b']\<tau>b) s'[bv'::=b']sb)"
using check_funtyp_subst_b[OF check_funtypq_polyI(5) check_funtypq_polyI(8)] by metis
moreover have "Θ ; {||} ; GNil ⊨ v ← { x' : b''[bv'::=b']bb | c'[bv'::=b']cb }" using ** check_funtypq_polyI by metis
ultimately have "Θ; Φ; {||}; GNil; []\<Delta> ⊨ s'[bv'::=b']sb[x'::=v]sv ← t'[bv'::=b']\<tau>b[x'::=v]\<tau>v"
using funtyp_simple_check[OF *] check_funtypq_polyI by metis
thus ?case using ** by metis
qed
lemma fundef_simple_check:
fixes s::s and Δ::Δ and τ::τ and v::v
assumes "check_fundef Θ Φ (AF_fundef f (AF_fun_typ_none (AF_fun_typ x b c t s)))" and
"Θ ; {||} ; GNil ⊨ v ← { x : b | c }" and "Θ ; {||} ; GNil ⊨wf Δ"
shows "Θ; Φ; {||}; GNil; Δ ⊨ s[x::=v]sv ← t[x::=v]\<tau>v"
using assms proof(nominal_induct "(AF_fundef f (AF_fun_typ_none (AF_fun_typ x b c t s)))" avoiding: v rule: check_fundef.strong_induct)
case (check_fundefI Θ Φ)
then show ?case using funtypq_simple_check[THEN check_s_d_weakening(1) ] setD.simps by auto
qed
lemma fundef_poly_check:
fixes s::s and Δ::Δ and τ::τ and v::v and b'::b
assumes "check_fundef Θ Φ (AF_fundef f (AF_fun_typ_some bv (AF_fun_typ x b c t s)))" and
"Θ ; {||} ; GNil ⊨ v ← { x : b[bv::=b']bb | c[bv::=b']cb }" and "Θ ; {||} ; GNil ⊨wf Δ" and "Θ ; {||} ⊨wf b'"
shows "Θ; Φ; {||}; GNil; Δ ⊨ s[bv::=b']sb[x::=v]sv ← t[bv::=b']\<tau>b[x::=v]\<tau>v"
using assms proof(nominal_induct "(AF_fundef f (AF_fun_typ_some bv (AF_fun_typ x b c t s)))" avoiding: v rule: check_fundef.strong_induct)
case (check_fundefI Θ Φ)
then show ?case using funtypq_poly_check[THEN check_s_d_weakening(1) ] setD.simps by auto
qed
lemma preservation_app:
assumes
"Some (AF_fundef f (AF_fun_typ_none (AF_fun_typ x1 b1 c1 τ1' s1'))) = lookup_fun Φ f" and "(∀fd∈set Φ. check_fundef Θ Φ fd)"
shows "Θ ; Φ ; B ; G ; Δ ⊨ ss ← τ ==> B = {||} ==> G = GNil ==> ss = LET x = (AE_app f v) IN s ==>
Θ; Φ; {||}; GNil; Δ ⊨ LET x : (τ1'[x1::=v]\<tau>v) = (s1'[x1::=v]sv) IN s ← τ" and
"check_branch_s Θ Φ B GNil Δ tid dc const v cs τ ==> True" and
"check_branch_list Θ Φ B Γ Δ tid dclist v css τ ==> True"
using assms proof(nominal_induct τ and τ and τ avoiding: v rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_letI x2 Θ Φ B Γ Δ e τ z s2 b c)
hence eq: "e = (AE_app f v)" by simp
hence *:"Θ ; Φ ; {||} ;GNil ; Δ ⊨ (AE_app f v) → { z : b | c }" using check_letI by auto
then obtain x3 b3 c3 τ3 s3 where
**:"Θ ; {||} ; GNil ⊨wf Δ ∧ Θ ⊨wf Φ ∧ Some (AF_fundef f (AF_fun_typ_none (AF_fun_typ x3 b3 c3 τ3 s3))) = lookup_fun Φ f ∧
Θ ; {||} ; GNil ⊨ v ← { x3 : b3 | c3 } ∧ atom x3 ♯ (Θ, Φ, ({||}::bv fset), GNil, Δ, v, { z : b | c }) ∧ τ3[x3::=v]\<tau>v = { z : b | c }"
using infer_e_elims(6)[OF *] subst_defs by metis
obtain z3 where z3:"{ x3 : b3 | c3 } = { z3 : b3 | c3[x3::=V_var z3]cv } ∧ atom z3 ♯ (x3, v,c3,x1,c1)" using obtain_fresh_z3 by metis
have seq:"[[atom x3]]lst. s3 = [[atom x1]]lst. s1'" using fun_def_eq check_letI ** option.inject by metis
let ?ft = "AF_fun_typ x3 b3 c3 τ3 s3"
have sup: "supp τ3 ⊆ { atom x3} ∧ supp s3 ⊆ { atom x3}" using wfPhi_f_supp ** by metis
have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x2 τ3[x3::=v]\<tau>v (s3[x3::=v]sv) s2 ← τ" proof
show ‹atom x2 ♯ (Θ, Φ, {||}::bv fset, GNil, Δ, τ3[x3::=v]\τv, s3[x3::=v]sv, τ)›
unfolding fresh_prodN using check_letI fresh_subst_v_if subst_v_τ_def sup
by (metis all_not_in_conv fresh_def fresh_empty_fset fresh_subst_sv_if fresh_subst_tv_if singleton_iff subset_singleton_iff)
show ‹ Θ; Φ; {||}; GNil; Δ ⊨ s3[x3::=v]sv ← τ3[x3::=v]\τv› proof(rule fundef_simple_check)
show ‹check_fundef Θ Φ (AF_fundef f (AF_fun_typ_none (AF_fun_typ x3 b3 c3 τ3 s3)))› using ** check_letI lookup_fun_member by metis
show ‹Θ ; {||} ; GNil ⊨ v ← { x3 : b3 | c3 }› using ** by auto
show ‹ Θ ; {||} ; GNil ⊨wf Δ › using ** by auto
qed
show ‹ Θ ; Φ ; {||} ; (x2, b_of τ3[x3::=v]\τv, c_of τ3[x3::=v]\τv x2) #\Γ GNil ; Δ ⊨ s2 ← τ›
using check_letI ** b_of.simps c_of.simps subst_defs by metis
qed
moreover have "AS_let2 x2 τ3[x3::=v]\<tau>v (s3[x3::=v]sv) s2 = AS_let2 x (τ1'[x1::=v]\<tau>v) (s1'[x1::=v]sv) s" proof -
have *: "[[atom x2]]lst. s2 = [[atom x]]lst. s" using check_letI s_branch_s_branch_list.eq_iff by auto
moreover have " τ3[x3::=v]\<tau>v = τ1'[x1::=v]\<tau>v" using fun_ret_unique ** check_letI by metis
moreover have "s3[x3::=v]sv = (s1'[x1::=v]sv)" using subst_v_flip_eq_two subst_v_s_def seq by metis
ultimately show ?thesis using s_branch_s_branch_list.eq_iff by metis
qed
ultimately show ?case using check_letI by auto
qed(auto+)
lemma fresh_subst_v_subst_b:
fixes x2::x and tm::"'a::{has_subst_v,has_subst_b}" and x::x
assumes "supp tm ⊆ { atom bv, atom x }" and "atom x2 ♯ v"
shows "atom x2 ♯ tm[bv::=b]b[x::=v]v"
using assms proof(cases "x2=x")
case True
then show ?thesis using fresh_subst_v_if assms by blast
next
case False
hence "atom x2 ♯ tm" using assms fresh_def fresh_at_base by force
hence "atom x2 ♯ tm[bv::=b]b" using assms fresh_subst_if x_fresh_b False by force
then show ?thesis using fresh_subst_v_if assms by auto
qed
lemma preservation_poly_app:
assumes
"Some (AF_fundef f (AF_fun_typ_some bv1 (AF_fun_typ x1 b1 c1 τ1' s1'))) = lookup_fun Φ f" and "(∀fd∈set Φ. check_fundef Θ Φ fd)"
shows "Θ ; Φ ; B ; G ; Δ ⊨ ss ← τ ==> B = {||} ==> G = GNil ==> ss = LET x = (AE_appP f b' v) IN s ==> Θ ; {||} ⊨wf b' ==>
Θ; Φ; {||}; GNil; Δ ⊨ LET x : (τ1'[bv1::=b']\<tau>b[x1::=v]\<tau>v) = (s1'[bv1::=b']sb[x1::=v]sv) IN s ← τ" and
"check_branch_s Θ Φ B GNil Δ tid dc const v cs τ ==> True" and
"check_branch_list Θ Φ B Γ Δ tid dclist v css τ ==> True"
using assms proof(nominal_induct τ and τ and τ avoiding: v x1 rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_letI x2 Θ Φ B Γ Δ e τ z s2 b c)
hence eq: "e = (AE_appP f b' v)" by simp
hence *:"Θ ; Φ ; {||} ;GNil ; Δ ⊨ (AE_appP f b' v) → { z : b | c }" using check_letI by auto
then obtain x3 b3 c3 τ3 s3 bv3 where
**:"Θ ; {||} ; GNil ⊨wf Δ ∧ Θ ⊨wf Φ ∧ Some (AF_fundef f (AF_fun_typ_some bv3 (AF_fun_typ x3 b3 c3 τ3 s3))) = lookup_fun Φ f ∧
Θ ; {||} ; GNil ⊨ v ← { x3 : b3[bv3::=b']bb | c3[bv3::=b']cb } ∧ atom x3 ♯ GNil ∧ τ3[bv3::=b']\<tau>b[x3::=v]\<tau>v = { z : b | c }
∧ Θ ; {||} ⊨wf b'"
using infer_e_elims(21)[OF *] subst_defs by metis
obtain z3 where z3:"{ x3 : b3 | c3 } = { z3 : b3 | c3[x3::=V_var z3]cv } ∧ atom z3 ♯ (x3, v,c3,x1,c1)" using obtain_fresh_z3 by metis
let ?ft = "(AF_fun_typ x3 (b3[bv3::=b']bb) (c3[bv3::=b']cb) (τ3[bv3::=b']\<tau>b) (s3[bv3::=b']sb))"
have *:"check_fundef Θ Φ (AF_fundef f (AF_fun_typ_some bv3 (AF_fun_typ x3 b3 c3 τ3 s3)))" using ** check_letI lookup_fun_member by metis
hence ftq:"check_funtypq Θ Φ (AF_fun_typ_some bv3 (AF_fun_typ x3 b3 c3 τ3 s3))" using check_fundef_elims by auto
let ?ft = "AF_fun_typ_some bv3 (AF_fun_typ x3 b3 c3 τ3 s3)"
have sup: "supp τ3 ⊆ { atom x3, atom bv3} ∧ supp s3 ⊆ { atom x3, atom bv3 }"
using wfPhi_f_poly_supp_t wfPhi_f_poly_supp_s ** by metis
have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x2 τ3[bv3::=b']\<tau>b[x3::=v]\<tau>v (s3[bv3::=b']sb[x3::=v]sv) s2 ← τ"
proof
show ‹atom x2 ♯ (Θ, Φ, {||}::bv fset, GNil, Δ, τ3[bv3::=b']\τb[x3::=v]\τv, s3[bv3::=b']sb[x3::=v]sv, τ)›
proof -
have "atom x2 ♯ τ3[bv3::=b']\<tau>b[x3::=v]\<tau>v"
using fresh_subst_v_subst_b subst_v_τ_def subst_b_τ_def ‹ atom x2 ♯ v› sup by fastforce
moreover have "atom x2 ♯ s3[bv3::=b']sb[x3::=v]sv"
using fresh_subst_v_subst_b subst_v_s_def subst_b_s_def ‹ atom x2 ♯ v› sup
proof -
have "∀b. atom x2 = atom x3 ∨ atom x2 ♯ s3[bv3::=b]b"
by (metis (no_types) check_letI.hyps(1) fresh_subst_sv_if(1) fresh_subst_v_subst_b insert_commute subst_v_s_def sup) (* 140 ms *)
then show ?thesis
by (metis check_letI.hyps(1) fresh_subst_sb_if fresh_subst_sv_if(1) has_subst_b_class.subst_b_fresh_x x_fresh_b) (* 78 ms *)
qed
ultimately show ?thesis using fresh_prodN check_letI by metis
qed
show ‹ Θ; Φ; {||}; GNil; Δ ⊨ s3[bv3::=b']sb[x3::=v]sv ← τ3[bv3::=b']\τb[x3::=v]\τv› proof( rule fundef_poly_check)
show ‹check_fundef Θ Φ (AF_fundef f (AF_fun_typ_some bv3 (AF_fun_typ x3 b3 c3 τ3 s3)))›
using ** lookup_fun_member check_letI by metis
show ‹Θ ; {||} ; GNil ⊨ v ← { x3 : b3[bv3::=b']bb | c3[bv3::=b']cb }› using ** by metis
show ‹ Θ ; {||} ; GNil ⊨wf Δ › using ** by metis
show ‹ Θ ; {||} ⊨wf b' › using ** by metis
qed
show ‹ Θ ; Φ ; {||} ; (x2, b_of τ3[bv3::=b']\τb[x3::=v]\τv, c_of τ3[bv3::=b']\τb[x3::=v]\τv x2) #\Γ GNil ; Δ ⊨ s2 ← τ›
using check_letI ** b_of.simps c_of.simps subst_defs by metis
qed
moreover have "AS_let2 x2 τ3[bv3::=b']\<tau>b[x3::=v]\<tau>v (s3[bv3::=b']sb[x3::=v]sv) s2 = AS_let2 x (τ1'[bv1::=b']\<tau>b[x1::=v]\<tau>v) (s1'[bv1::=b']sb[x1::=v]sv) s" proof -
have *: "[[atom x2]]lst. s2 = [[atom x]]lst. s" using check_letI s_branch_s_branch_list.eq_iff by auto
moreover have " τ3[bv3::=b']\<tau>b[x3::=v]\<tau>v = τ1'[bv1::=b']\<tau>b[x1::=v]\<tau>v" using fun_poly_ret_unique ** check_letI by metis
moreover have "s3[bv3::=b']sb[x3::=v]sv = (s1'[bv1::=b']sb[x1::=v]sv)" using subst_v_flip_eq_two subst_v_s_def fun_poly_body_unique ** check_letI by metis
ultimately show ?thesis using s_branch_s_branch_list.eq_iff by metis
qed
ultimately show ?case using check_letI by auto
qed(auto+)
lemma check_s_plus:
assumes "Θ; Φ; {||}; GNil; Δ ⊨ LET x = (AE_op Plus (V_lit (L_num n1)) (V_lit (L_num n2))) IN s' ← τ"
shows "Θ; Φ; {||}; GNil; Δ ⊨ LET x = (AE_val (V_lit (L_num (n1+n2)))) IN s' ← τ"
proof -
obtain t1 where 1: "Θ; Φ; {||}; GNil; Δ ⊨ AE_op Plus (V_lit (L_num n1)) (V_lit (L_num n2)) → t1"
using assms check_s_elims by metis
then obtain z1 where 2: "t1 = { z1 : B_int | CE_val (V_var z1) == CE_op Plus ([V_lit (L_num n1)]ce) ([V_lit (L_num n2)]ce) }"
using infer_e_plus by metis
obtain z2 where 3: ‹Θ ; Φ ; {||} ; GNil ; Δ ⊨ AE_val (V_lit (L_num (n1+n2))) → { z2 : B_int | CE_val (V_var z2) == CE_val (V_lit (L_num (n1+n2))) }›
using infer_v_form infer_e_valI infer_v_litI infer_l.intros infer_e_wf 1
by (simp add: fresh_GNil)
let ?e = " (AE_op Plus (V_lit (L_num n1)) (V_lit (L_num n2)))"
show ?thesis proof(rule subtype_let)
show "Θ ; Φ ; {||} ; GNil ; Δ ⊨ LET x = ?e IN s' ← τ" using assms by auto
show "Θ ; Φ ; {||} ; GNil ; Δ ⊨ ?e → t1" using 1 by auto
show "Θ ; Φ ; {||} ; GNil ; Δ ⊨ [ [ L_num (n1 + n2) ]v ]e → { z2 : B_int | CE_val (V_var z2) == CE_val (V_lit (L_num (n1+n2))) }" using 3 by auto
show "Θ ; {||} ; GNil ⊨ { z2 : B_int | CE_val (V_var z2) == CE_val (V_lit (L_num (n1+n2))) } < t1" using subtype_bop_arith
by (metis "1" ‹∧thesis. (∧z1. t1 = { z1 : B_int | [ [ z1 ]v ]ce == [ plus [ [ L_num n1 ]v ]ce [ [ L_num n2 ]v ]ce ]ce } ==> thesis) ==> thesis› infer_e_wf(2) opp.distinct(1) type_for_lit.simps(3))
qed
qed
lemma check_s_leq:
assumes "Θ ; Φ ; {||} ; GNil ; Δ ⊨ LET x = (AE_op LEq (V_lit (L_num n1)) (V_lit (L_num n2))) IN s' ← τ"
shows "Θ; Φ; {||}; GNil; Δ ⊨ LET x = (AE_val (V_lit (if (n1 ≤ n2) then L_true else L_false))) IN s' ← τ"
proof -
obtain t1 where 1: "Θ; Φ; {||}; GNil; Δ ⊨ AE_op LEq (V_lit (L_num n1)) (V_lit (L_num n2)) → t1"
using assms check_s_elims by metis
then obtain z1 where 2: "t1 = { z1 : B_bool | CE_val (V_var z1) == CE_op LEq ([V_lit (L_num n1)]ce) ([V_lit (L_num n2)]ce) }"
using infer_e_leq by auto
obtain z2 where 3: ‹Θ ; Φ ; {||} ; GNil ; Δ ⊨ AE_val (V_lit ((if (n1 ≤ n2) then L_true else L_false))) → { z2 : B_bool | CE_val (V_var z2) == CE_val (V_lit ((if (n1 ≤ n2) then L_true else L_false))) }›
using infer_v_form infer_e_valI infer_v_litI infer_l.intros infer_e_wf 1
fresh_GNil
by simp
show ?thesis proof(rule subtype_let)
show ‹ Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_op LEq [ L_num n1 ]v [ L_num n2 ]v) s' ← τ› using assms by auto
show ‹Θ; Φ; {||}; GNil; Δ ⊨ AE_op LEq [ L_num n1 ]v [ L_num n2 ]v → t1› using 1 by auto
show ‹Θ; Φ; {||}; GNil; Δ ⊨ [ [ if n1 ≤ n2 then L_true else L_false ]v ]e → { z2 : B_bool | CE_val (V_var z2) == CE_val (V_lit ((if (n1 ≤ n2) then L_true else L_false))) }› using 3 by auto
show ‹Θ ; {||} ; GNil ⊨ { z2 : B_bool | CE_val (V_var z2) == CE_val (V_lit ((if (n1 ≤ n2) then L_true else L_false))) } < t1›
using subtype_bop_arith[where opp=LEq] check_s_wf assms 2
by (metis opp.distinct(1) subtype_bop_arith type_l_eq)
qed
qed
lemma check_s_eq:
assumes "Θ ; Φ ; {||} ; GNil ; Δ ⊨ LET x = (AE_op Eq (V_lit (n1)) (V_lit ( n2))) IN s' ← τ"
shows "Θ; Φ; {||}; GNil; Δ ⊨ LET x = (AE_val (V_lit (if (n1 = n2) then L_true else L_false))) IN s' ← τ"
proof -
obtain t1 where 1: "Θ; Φ; {||}; GNil; Δ ⊨ AE_op Eq (V_lit (n1)) (V_lit (n2)) → t1"
using assms check_s_elims by metis
then obtain z1 where 2: "t1 = { z1 : B_bool | CE_val (V_var z1) == CE_op Eq ([V_lit (n1)]ce) ([V_lit (n2)]ce) }"
using infer_e_leq by auto
obtain z2 where 3: ‹Θ ; Φ ; {||} ; GNil ; Δ ⊨ AE_val (V_lit ((if (n1 = n2) then L_true else L_false))) → { z2 : B_bool | CE_val (V_var z2) == CE_val (V_lit ((if (n1 = n2) then L_true else L_false))) }›
using infer_v_form infer_e_valI infer_v_litI infer_l.intros infer_e_wf 1
fresh_GNil
by simp
show ?thesis proof(rule subtype_let)
show ‹ Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_op Eq [ n1 ]v [ n2 ]v) s' ← τ› using assms by auto
show ‹Θ; Φ; {||}; GNil; Δ ⊨ AE_op Eq [ n1 ]v [ n2 ]v → t1› using 1 by auto
show ‹Θ; Φ; {||}; GNil; Δ ⊨ [ [ if n1 = n2 then L_true else L_false ]v ]e → { z2 : B_bool | CE_val (V_var z2) == CE_val (V_lit ((if (n1 = n2) then L_true else L_false))) }› using 3 by auto
show ‹Θ ; {||} ; GNil ⊨ { z2 : B_bool | CE_val (V_var z2) == CE_val (V_lit ((if (n1 = n2) then L_true else L_false))) } < t1›
proof -
have " { z2 : B_bool | [ [ z2 ]v ]ce == [ eq [ [ n1 ]v ]ce [ [ n2 ]v ]ce ]ce } = t1" using 2
by (metis τ_fresh_c fresh_opp_all infer_l_form2 infer_l_fresh ms_fresh_all(31) ms_fresh_all(33) obtain_fresh_z type_e_eq type_l_eq)
moreover have "Θ ; {||} ⊨wf GNil" using assms wfX_wfY by fastforce
moreover have "base_for_lit n1 = base_for_lit n2" using 1 infer_e_wf wfE_elims(12) wfV_elims
by metis
ultimately show ?thesis using subtype_bop_eq[OF ‹Θ ; {||} ⊨wf GNil›, of n1 n2 z2] by auto
qed
qed
qed
subsection ‹Operators›
lemma preservation_plus:
assumes "Θ; Φ; Δ ⊨ ⟨ δ , LET x = (AE_op Plus (V_lit (L_num n1)) (V_lit (L_num n2))) IN s' ⟩ ← τ"
shows "Θ; Φ; Δ ⊨ ⟨ δ , LET x = (AE_val (V_lit (L_num (n1+n2)))) IN s' ⟩ ← τ"
proof -
have tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_op Plus (V_lit (L_num n1)) (V_lit (L_num n2))) s' ← τ" and dsim: "Θ ⊨ δ ∼ Δ" and fd:"(∀fd∈set Φ. check_fundef Θ Φ fd)"
using assms config_type_elims by blast+
hence "Θ; Φ; {||}; GNil; Δ ⊨AS_let x (AE_val (V_lit (L_num (n1+n2)))) s' ← τ" using check_s_plus assms by auto
hence "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val (V_lit ( (L_num (n1+n2))))) s' ⟩ ← τ" using dsim config_typeI fd by presburger
then show ?thesis using dsim config_typeI
by (meson order_refl)
qed
lemma preservation_leq:
assumes "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_op LEq (V_lit (L_num n1)) (V_lit (L_num n2))) s' ⟩ ← τ"
shows "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val (V_lit (((if (n1 ≤ n2) then L_true else L_false))))) s' ⟩ ← τ"
proof -
have tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_op LEq (V_lit (L_num n1)) (V_lit (L_num n2))) s' ← τ" and dsim: "Θ ⊨ δ ∼ Δ" and fd:"(∀fd∈set Φ. check_fundef Θ Φ fd)"
using assms config_type_elims by blast+
hence "Θ; Φ; {||}; GNil; Δ ⊨AS_let x (AE_val (V_lit ( ((if (n1 ≤ n2) then L_true else L_false))))) s' ← τ" using check_s_leq assms by auto
hence "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val (V_lit ( (((if (n1 ≤ n2) then L_true else L_false)))))) s' ⟩ ← τ" using dsim config_typeI fd by presburger
then show ?thesis using dsim config_typeI
by (meson order_refl)
qed
lemma preservation_eq:
assumes "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_op Eq (V_lit (n1)) (V_lit (n2))) s' ⟩ ← τ"
shows "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val (V_lit (((if (n1 = n2) then L_true else L_false))))) s' ⟩ ← τ"
proof -
have tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_op Eq (V_lit (n1)) (V_lit (n2))) s' ← τ" and dsim: "Θ ⊨ δ ∼ Δ" and fd:"(∀fd∈set Φ. check_fundef Θ Φ fd)"
using assms config_type_elims by blast+
hence "Θ; Φ; {||}; GNil; Δ ⊨AS_let x (AE_val (V_lit ( ((if (n1 = n2) then L_true else L_false))))) s' ← τ" using check_s_eq assms by auto
hence "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val (V_lit ( (((if (n1 = n2) then L_true else L_false)))))) s' ⟩ ← τ" using dsim config_typeI fd by presburger
then show ?thesis using dsim config_typeI
by (meson order_refl)
qed
subsection ‹Let Statements›
lemma subst_s_abs_lst:
fixes s::s and sa::s and v'::v
assumes "[[atom x]]lst. s = [[atom xa]]lst. sa" and "atom xa ♯ v ∧ atom x ♯ v"
shows "s[x::=v]sv = sa[xa::=v]sv"
proof -
obtain c'::x where cdash: "atom c' ♯ (v, x, xa, s, sa)" using obtain_fresh by blast
moreover have " (x ↔ c') ∙ s = (xa ↔ c') ∙ sa" proof -
have "atom c' ♯ (s, sa) ∧ atom c' ♯ (x, xa, s, sa)" using cdash by auto
thus ?thesis using assms by auto
qed
ultimately show ?thesis using assms
using subst_sv_flip by auto
qed
lemma check_let_val:
fixes v::v and s::s
shows "Θ ; Φ ; B ; G ; Δ ⊨ ss ← τ ==> B = {||} ==> G = GNil ==>
ss = AS_let x (AE_val v) s ∨ ss = AS_let2 x t (AS_val v) s ==> Θ; Φ; {||}; GNil; Δ ⊨ (s[x::=v]sv) ← τ" and
"check_branch_s Θ Φ B GNil Δ tid dc const v cs τ ==> True" and
"check_branch_list Θ Φ B Γ Δ tid dclist v css τ ==> True"
proof(nominal_induct τ and τ and τ avoiding: v rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_letI x1 Θ Φ B Γ Δ e τ z s1 b c)
hence *:"e = AE_val v" by auto
let ?G = "(x1, b, c[z::=V_var x1]cv) #\<Gamma> Γ"
have "Θ ; Φ ; B ; ?G[x1::=v]\<Gamma>v ; Δ[x1::=v]\<Delta>v ⊨ s1[x1::=v]sv ← τ[x1::=v]\<tau>v"
proof(rule subst_infer_check_s(1))
show **:‹ Θ ; B ; Γ ⊨ v → { z : b | c }› using infer_e_elims check_letI * by fast
thus ‹Θ ; B ; Γ ⊨ { z : b | c } < { z : b | c }› using subtype_reflI infer_v_wf by metis
show ‹atom z ♯ (x1, v)› using check_letI fresh_Pair by auto
show ‹Θ ; Φ ; B ; (x1, b, c[z::=V_var x1]cv) #\Γ Γ ; Δ ⊨ s1 ← τ› using check_letI subst_defs by auto
show "(x1, b, c[z::=V_var x1]cv) #\<Gamma> Γ = GNil @ (x1, b, c[z::=V_var x1]cv) #\<Gamma> Γ" by auto
qed
hence "Θ ; Φ ; B ; Γ ; Δ ⊨ s1[x1::=v]sv ← τ" using check_letI by auto
moreover have " s1[x1::=v]sv = s[x::=v]sv"
by (metis (full_types) check_letI fresh_GNil infer_e_elims(7) s_branch_s_branch_list.distinct s_branch_s_branch_list.eq_iff(2)
subst_s_abs_lst wfG_x_fresh_in_v_simple)
ultimately show ?case using check_letI by simp
next
case (check_let2I x1 Θ Φ B Γ Δ t s1 τ s2 )
hence s1eq:"s1 = AS_val v" by auto
let ?G = "(x1, b_of t, c_of t x1) #\<Gamma> Γ"
obtain z::x where *:"atom z ♯ (x1 , v,t)" using obtain_fresh_z by metis
hence teq:"t = { z : b_of t | c_of t z }" using b_of_c_of_eq by auto
have "Θ ; Φ ; B ; ?G[x1::=v]\<Gamma>v ; Δ[x1::=v]\<Delta>v ⊨ s2[x1::=v]sv ← τ[x1::=v]\<tau>v"
proof(rule subst_check_check_s(1))
obtain t' where "Θ ; B ; Γ ⊨ v → t' ∧ Θ ; B ; Γ ⊨ t' < t" using check_s_elims(1) check_let2I(10) s1eq by auto
thus **:‹ Θ ; B ; Γ ⊨ v ← { z : b_of t | c_of t z }› using check_v.intros teq by auto
show "atom z ♯ (x1, v)" using * by auto
show ‹ Θ ; Φ ; B ; (x1, b_of t, c_of t x1) #\Γ Γ ; Δ ⊨ s2 ← τ› using check_let2I by auto
show "(x1, b_of t , c_of t x1) #\<Gamma> Γ = GNil @ (x1, b_of t, (c_of t z)[z::=V_var x1]cv) #\<Gamma> Γ" using append_g.simps c_of_switch * fresh_prodN by metis
qed
hence "Θ ; Φ ; B ; Γ ; Δ ⊨ s2[x1::=v]sv ← τ" using check_let2I by auto
moreover have " s2[x1::=v]sv = s[x::=v]sv" using
check_let2I fresh_GNil check_s_elims s_branch_s_branch_list.distinct s_branch_s_branch_list.eq_iff
subst_s_abs_lst wfG_x_fresh_in_v_simple
proof -
have "AS_let2 x t (AS_val v) s = AS_let2 x1 t s1 s2"
by (metis check_let2I.prems(3) s_branch_s_branch_list.distinct s_branch_s_branch_list.eq_iff(3)) (* 62 ms *)
then show ?thesis
by (metis (no_types) check_let2I check_let2I.prems(2) check_s_elims(1) fresh_GNil s_branch_s_branch_list.eq_iff(3) subst_s_abs_lst wfG_x_fresh_in_v_simple) (* 375 ms *)
qed
ultimately show ?case using check_let2I by simp
qed(auto+)
lemma preservation_let_val:
assumes "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val v) s ⟩ ← τ ∨ Θ; Φ; Δ ⊨ ⟨ δ , AS_let2 x t (AS_val v) s ⟩ ← τ" (is "?A ∨ ?B")
shows " ∃Δ'. Θ; Φ; Δ' ⊨ ⟨ δ , s[x::=v]sv ⟩ ← τ ∧ Δ ⊑ Δ'"
proof -
have tt: "Θ ⊨ δ ∼ Δ" and fd: "(∀fd∈set Φ. check_fundef Θ Φ fd)"
using assms by blast+
have "?A ∨ ?B" using assms by auto
then have "Θ; Φ; {||}; GNil; Δ ⊨ s[x::=v]sv ← τ"
proof
assume "Θ; Φ; Δ ⊨ ⟨ δ , AS_let x (AE_val v) s ⟩ ← τ"
hence * : " Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_val v) s ← τ" by blast
thus ?thesis using check_let_val by simp
next
assume "Θ; Φ; Δ ⊨ ⟨ δ , AS_let2 x t (AS_val v) s ⟩ ← τ"
hence * : "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x t (AS_val v) s ← τ" by blast
thus ?thesis using check_let_val by simp
qed
thus ?thesis using tt config_typeI fd
order_refl by metis
qed
lemma check_s_fst_snd:
assumes "fst_snd = AE_fst ∧ v=v1 ∨ fst_snd = AE_snd ∧ v=v2"
and "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (fst_snd (V_pair v1 v2)) s' ← τ"
shows "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x ( AE_val v) s' ← τ"
proof -
have 1: ‹ Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (fst_snd (V_pair v1 v2)) s' ← τ› using assms by auto
then obtain t1 where 2:"Θ; Φ; {||}; GNil; Δ ⊨ (fst_snd (V_pair v1 v2)) → t1" using check_s_elims by auto
show ?thesis using subtype_let 1 2 assms
by (meson infer_e_fst_pair infer_e_snd_pair)
qed
lemma preservation_fst_snd:
assumes "Θ; Φ; Δ ⊨ ⟨ δ , LET x = (fst_snd (V_pair v1 v2)) IN s' ⟩ ← τ" and
"fst_snd = AE_fst ∧ v=v1 ∨ fst_snd = AE_snd ∧ v=v2"
shows "∃Δ'. Θ; Φ; Δ ⊨ ⟨ δ , LET x = (AE_val v) IN s' ⟩ ← τ ∧ Δ ⊑ Δ'"
proof -
have tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (fst_snd (V_pair v1 v2)) s' ← τ ∧ Θ ⊨ δ ∼ Δ" using assms by blast
hence t2: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (fst_snd (V_pair v1 v2)) s' ← τ" by auto
moreover have "∀fd∈set Φ. check_fundef Θ Φ fd" using assms config_type_elims by auto
ultimately show ?thesis using config_typeI order_refl tt assms check_s_fst_snd by metis
qed
inductive_cases check_branch_s_elims2[elim!]:
"Θ ; Φ ; B ; Γ ; Δ; tid ; cons ; const ; v ⊨ cs ← τ"
lemmas freshers = freshers atom_dom.simps toSet.simps fresh_def x_not_in_b_set
declare freshers [simp]
lemma subtype_eq_if:
fixes t::τ and va::v
assumes "Θ ; B ; Γ ⊨wf { z : b_of t | c_of t z }" and "Θ ; B ; Γ ⊨wf { z : b_of t | c IMP c_of t z } "
shows "Θ ; B ; Γ ⊨ { z : b_of t | c_of t z } < { z : b_of t | c IMP c_of t z } "
proof -
obtain x::x where xf:"atom x ♯ ((Θ, B, Γ, z, c_of t z, z, c IMP c_of t z ),c)" using obtain_fresh by metis
moreover have "Θ ; B ; (x, b_of t, (c_of t z)[z::=[ x ]v]cv) #\<Gamma> Γ ⊨ (c IMP c_of t z )[z::=[ x ]v]cv "
unfolding subst_cv.simps
proof(rule valid_eq_imp)
have "Θ ; B ; (x, b_of t, (c_of t z)[z::=[ x ]v]v) #\<Gamma> Γ ⊨wf (c IMP (c_of t z))[z::=[ x ]v]v "
apply(rule wfT_wfC_cons)
apply(simp add: assms, simp add: assms, unfold fresh_prodN )
using xf fresh_prodN by metis+
thus "Θ ; B ; (x, b_of t, (c_of t z)[z::=[ x ]v]cv) #\<Gamma> Γ ⊨wf c[z::=[ x ]v]cv IMP (c_of t z)[z::=[ x ]v]cv "
using subst_cv.simps subst_defs by auto
qed
ultimately show ?thesis using subtype_baseI assms fresh_Pair subst_defs by metis
qed
lemma subtype_eq_if_τ:
fixes t::τ and va::v
assumes "Θ ; B ; Γ ⊨wf t" and "Θ ; B ; Γ ⊨wf { z : b_of t | c IMP c_of t z } " and "atom z ♯ t"
shows "Θ ; B ; Γ ⊨ t < { z : b_of t | c IMP c_of t z } "
proof -
have "t = { z : b_of t | c_of t z }" using b_of_c_of_eq assms by auto
thus ?thesis using subtype_eq_if assms c_of.simps b_of.simps by metis
qed
lemma valid_conj:
assumes "Θ ; B ; Γ ⊨ c1" and "Θ ; B ; Γ ⊨ c2"
shows "Θ ; B ; Γ ⊨ c1 AND c2"
proof
show ‹ Θ ; B ; Γ ⊨wf c1 AND c2 › using valid.simps wfC_conjI assms by auto
show ‹∀i. Θ ; Γ ⊨ i ∧ i ⊨ Γ ⟶ i ⊨ c1 AND c2 ›
proof(rule+)
fix i
assume *:"Θ ; Γ ⊨ i ∧ i ⊨ Γ "
thus "i [ c1 ] ~ True" using assms valid.simps
using is_satis.cases by blast
show "i [ c2 ] ~ True" using assms valid.simps
using is_satis.cases * by blast
qed
qed
subsection ‹Other Statements›
lemma check_if:
fixes s'::s and cs::branch_s and css::branch_list and v::v
shows "Θ; Φ; B; G; Δ ⊨ s' ← τ ==> s' = IF (V_lit ll) THEN s1 ELSE s2 ==>
Θ ; {||} ; GNil ⊨wf τ ==> G = GNil ==> B = {||} ==> ll = L_true ∧ s = s1 ∨ ll = L_false ∧ s = s2 ==>
Θ; Φ; {||}; GNil; Δ ⊨ s ← τ" and
"check_branch_s Θ Φ {||} GNil Δ tid dc const v cs τ ==> True" and
"check_branch_list Θ Φ {||} Γ Δ tid dclist v css τ ==> True"
proof(nominal_induct τ and τ and τ rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_ifI z Θ Φ B Γ Δ v s1 s2 τ)
obtain z' where teq: "τ = { z' : b_of τ | c_of τ z' } ∧ atom z' ♯ (z,τ)" using obtain_fresh_z_c_of by metis
hence ceq: "(c_of τ z')[z'::=[ z ]v]cv = (c_of τ z)" using c_of_switch fresh_Pair by metis
have zf: " atom z ♯ c_of τ z'"
using c_of_fresh check_ifI teq fresh_Pair fresh_at_base by metis
hence 1:"Θ; Φ; {||}; GNil; Δ ⊨ s ← { z : b_of τ | CE_val (V_lit ll) == CE_val (V_lit ll) IMP c_of τ z }" using check_ifI by auto
moreover have 2:"Θ ; {||} ; GNil ⊨ ({ z : b_of τ | CE_val (V_lit ll) == CE_val (V_lit ll) IMP c_of τ z }) < τ"
proof -
have "Θ ; {||} ; GNil ⊨wf ({ z : b_of τ | CE_val (V_lit ll ) == CE_val (V_lit ll) IMP c_of τ z })" using check_ifI check_s_wf by auto
moreover have "Θ ; {||} ; GNil ⊨wf τ" using check_s_wf check_ifI by auto
ultimately show ?thesis using subtype_if_simp[of Θ " {||}" z "b_of τ" ll "c_of τ z'" z'] using teq ceq zf subst_defs by metis
qed
ultimately show ?case using check_s_supertype(1) check_ifI by metis
qed(auto+)
lemma preservation_if:
assumes "Θ; Φ; Δ ⊨ ⟨ δ , IF (V_lit ll) THEN s1 ELSE s2 ⟩ ← τ" and
"ll = L_true ∧ s = s1 ∨ ll = L_false ∧ s = s2"
shows "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ ∧ setD Δ ⊆ setD Δ"
proof -
have *: "Θ; Φ; {||}; GNil; Δ ⊨ AS_if (V_lit ll) s1 s2 ← τ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using assms config_type_elims by metis
hence "Θ; Φ; {||}; GNil; Δ ⊨ s ← τ" using check_s_wf check_if assms by metis
hence "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ ∧ setD Δ ⊆ setD Δ" using config_typeI *
using assms(1) by blast
thus ?thesis by blast
qed
lemma wfT_conj:
assumes "Θ ; B ; GNil ⊨wf { z : b | c1 }" and "Θ ; B ; GNil ⊨wf { z : b | c2 }"
shows "Θ ; B ; GNil ⊨wf { z : b | c1 AND c2}"
proof
show ‹atom z ♯ (Θ, B, GNil)›
apply(unfold fresh_prodN, intro conjI)
using wfTh_fresh wfT_wf assms apply metis
using fresh_GNil x_not_in_b_set fresh_def by metis+
show ‹ Θ ; B ⊨wf b › using wfT_elims assms by metis
have "Θ ; B ; (z, b, TRUE) #\<Gamma> GNil ⊨wf c1" using wfT_wfC fresh_GNil assms by auto
moreover have "Θ ; B ; (z, b, TRUE) #\<Gamma> GNil ⊨wf c2" using wfT_wfC fresh_GNil assms by auto
ultimately show ‹ Θ ; B ; (z, b, TRUE) #\Γ GNil ⊨wf c1 AND c2 › using wfC_conjI by auto
qed
lemma subtype_conj:
assumes "Θ ; B ; GNil ⊨ t < { z : b | c1 }" and "Θ ; B ; GNil ⊨ t < { z : b | c2 }"
shows "Θ ; B ; GNil ⊨ { z : b | c_of t z } < { z : b | c1 AND c2 }"
proof -
have beq: "b_of t = b" using subtype_eq_base2 b_of.simps assms by metis
obtain x::x where x:‹atom x ♯ (Θ, B, GNil, z, c_of t z, z, c1 AND c2 )› using obtain_fresh by metis
thus ?thesis proof
have "atom z ♯ t" using subtype_wf wfT_supp fresh_def x_not_in_b_set atom_dom.simps toSet.simps assms dom.simps by fastforce
hence t:"t = { z : b_of t | c_of t z }" using b_of_c_of_eq by auto
thus ‹ Θ ; B ; GNil ⊨wf { z : b | c_of t z } › using subtype_wf beq assms by auto
show ‹Θ ; B ; (x, b, (c_of t z)[z::=[ x ]v]v) #\Γ GNil ⊨ (c1 AND c2 )[z::=[ x ]v]v ›
proof -
have ‹Θ ; B ; (x, b, (c_of t z)[z::=[ x ]v]v) #\Γ GNil ⊨ c1[z::=[ x ]v]v ›
proof(rule subtype_valid)
show ‹Θ ; B ; GNil ⊨ t < { z : b | c1 }› using assms by auto
show ‹atom x ♯ GNil› using fresh_GNil by auto
show ‹t = { z : b | c_of t z }› using t beq by auto
show ‹{ z : b | c1 } = { z : b | c1 }› by auto
qed
moreover have ‹Θ ; B ; (x, b, (c_of t z)[z::=[ x ]v]v) #\Γ GNil ⊨ c2[z::=[ x ]v]v ›
proof(rule subtype_valid)
show ‹Θ ; B ; GNil ⊨ t < { z : b | c2 }› using assms by auto
show ‹atom x ♯ GNil› using fresh_GNil by auto
show ‹t = { z : b | c_of t z }› using t beq by auto
show ‹{ z : b | c2 } = { z : b | c2 }› by auto
qed
ultimately show ?thesis unfolding subst_cv.simps subst_v_c_def using valid_conj by metis
qed
thus ‹ Θ ; B ; GNil ⊨wf { z : b | c1 AND c2 } › using subtype_wf wfT_conj assms by auto
qed
qed
lemma infer_v_conj:
assumes "Θ ; B ; GNil ⊨ v ← { z : b | c1 }" and "Θ ; B ; GNil ⊨ v ← { z : b | c2 }"
shows "Θ ; B ; GNil ⊨ v ← { z : b | c1 AND c2 }"
proof -
obtain t1 where t1: "Θ ; B ; GNil ⊨ v → t1 ∧ Θ ; B ; GNil ⊨ t1 < { z : b | c1 }"
using assms check_v_elims by metis
obtain t2 where t2: "Θ ; B ; GNil ⊨ v → t2 ∧ Θ ; B ; GNil ⊨ t2 < { z : b | c2 }"
using assms check_v_elims by metis
have teq: "t1 = { z : b | c_of t1 z }" using subtype_eq_base2 b_of.simps
by (metis (full_types) b_of_c_of_eq fresh_GNil infer_v_t_wf t1 wfT_x_fresh)
have "t1 = t2" using infer_v_uniqueness t1 t2 by auto
hence " Θ ; B ; GNil ⊨ { z : b | c_of t1 z } < { z : b | c1 AND c2 }" using subtype_conj t1 t2 by simp
hence " Θ ; B ; GNil ⊨ t1 < { z : b | c1 AND c2 }" using teq by auto
thus ?thesis using t1 using check_v.intros by auto
qed
lemma wfG_conj:
fixes c1::c
assumes "Θ ; B ⊨wf (x, b, c1 AND c2) #\<Gamma> Γ"
shows "Θ ; B ⊨wf (x, b, c1) #\<Gamma> Γ"
proof(cases "c1 ∈ {TRUE, FALSE}")
case True
then show ?thesis using assms wfG_cons2I wfG_elims wfX_wfY by metis
next
case False
then show ?thesis using assms wfG_cons1I wfG_elims wfX_wfY wfC_elims
by (metis wfG_elim2)
qed
lemma check_match:
fixes s'::s and s::s and css::branch_list and cs::branch_s
shows "Θ ; Φ ; B ; Γ ; Δ ⊨ s ← τ ==> True" and
"Θ ; Φ ; B ; G ; Δ ; tid ; dc ; const ; vcons ⊨ cs ← τ ==>
vcons = V_cons tid dc v ==> B = {||} ==> G = GNil ==> cs = (dc x' → s') ==>
Θ ; {||} ; GNil ⊨ v ← const ==>
Θ; Φ; {||}; GNil; Δ ⊨ s'[x'::=v]sv ← τ" and
"Θ ; Φ ; B ; G ; Δ ; tid ; dclist ; vcons ⊨ css ← τ ==> distinct (map fst dclist) ==>
vcons = V_cons tid dc v ==> B = {||} ==> (dc, const) ∈ set dclist ==> G = GNil ==>
Some (AS_branch dc x' s') = lookup_branch dc css ==> Θ ; {||} ; GNil ⊨ v ← const ==>
Θ; Φ; {||}; GNil; Δ ⊨ s'[x'::=v]sv ← τ"
proof(nominal_induct τ and τ and τ avoiding: x' v rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_branch_list_consI Θ Φ B Γ Δ tid consa consta va cs τ dclist cssa)
then obtain xa and sa where cseq:"cs = AS_branch consa xa sa" using check_branch_s_elims2[OF check_branch_list_consI(1)] by metis
show ?case proof(cases "dc = consa")
case True
hence "cs = AS_branch consa x' s'" using check_branch_list_consI cseq
by (metis lookup_branch.simps(2) option.inject)
moreover have "const = consta" using check_branch_list_consI distinct.simps
by (metis True dclist_distinct_unique list.set_intros(1))
moreover have "va = V_cons tid consa v" using check_branch_list_consI True by auto
ultimately show ?thesis using check_branch_list_consI by auto
next
case False
hence "Some (AS_branch dc x' s') = lookup_branch dc cssa" using lookup_branch.simps(2) check_branch_list_consI(10) cseq by auto
moreover have "(dc, const) ∈ set dclist" using check_branch_list_consI False by simp
ultimately show ?thesis using check_branch_list_consI by auto
qed
next
case (check_branch_list_finalI Θ Φ B Γ Δ tid cons const va cs τ)
hence " cs = AS_branch cons x' s'" using lookup.simps check_branch_list_finalI lookup_branch.simps option.inject
by (metis map_of.simps(1) map_of_Cons_code(2) option.distinct(1) s_branch_s_branch_list.exhaust(2) weak_map_of_SomeI)
then show ?case using check_branch_list_finalI by auto
next
case (check_branch_s_branchI Θ B Γ Δ τ const x Φ tid cons va s)
text ‹Supporting facts here to make the main body of the proof concise›
have xf:"atom x ♯ τ" proof -
have "supp τ ⊆ supp B" using wf_supp(4) check_branch_s_branchI atom_dom.simps toSet.simps dom.simps by fastforce
thus ?thesis using fresh_def x_not_in_b_set by blast
qed
hence "τ[x::=v]\<tau>v = τ" using forget_subst_v subst_v_τ_def by auto
have "Δ[x::=v]\<Delta>v = Δ" using forget_subst_dv wfD_x_fresh fresh_GNil check_branch_s_branchI by metis
have "supp v = {}" using check_branch_s_branchI check_v_wf wfV_supp_nil by metis
hence "supp va = {}" using ‹ va = V_cons tid cons v› v.supp pure_supp by auto
let ?G = "(x, b_of const, [ va ]ce == [ V_cons tid cons [ x ]v ]ce AND c_of const x ) #\<Gamma> Γ"
obtain z::x where z: "const = { z : b_of const | c_of const z } ∧ atom z ♯ (x', v,x,const,va)"
using obtain_fresh_z_c_of by metis
have vt: ‹Θ ; B ; GNil ⊨ v ← { z : b_of const | [ va ]ce == [ V_cons tid cons [ z ]v ]ce AND c_of const z }›
proof(rule infer_v_conj)
obtain t' where t: "Θ ; B ; GNil ⊨ v → t' ∧ Θ ; B ; GNil ⊨ t' < const"
using check_v_elims check_branch_s_branchI by metis
show "Θ ; B ; GNil ⊨ v ← { z : b_of const | [ va ]ce == [ V_cons tid cons [ z ]v ]ce }"
proof(rule check_v_top)
show "Θ ; B ; GNil ⊨wf { z : b_of const | [ va ]ce == [ V_cons tid cons [ z ]v ]ce } "
proof(rule wfG_wfT)
show ‹ Θ ; B ⊨wf (x, b_of const, ([ va ]ce == [ V_cons tid cons [ z ]v ]ce )[z::=[ x ]v]cv) #\Γ GNil ›
proof -
have 1: "va[z::=[ x ]v]vv = va" using forget_subst_v subst_v_v_def z fresh_prodN by metis
moreover have 2: "Θ ; B ⊨wf (x, b_of const, [ va ]ce == [ V_cons tid cons [ x ]v ]ce AND c_of const x ) #\<Gamma> GNil "
using check_branch_s_branchI(17)[THEN check_s_wf] ‹Γ = GNil› by auto
moreover hence "Θ ; B ⊨wf (x, b_of const, [ va ]ce == [ V_cons tid cons [ x ]v ]ce ) #\<Gamma> GNil"
using wfG_conj by metis
ultimately show ?thesis
unfolding subst_cv.simps subst_cev.simps subst_vv.simps by auto
qed
show ‹atom x ♯ ([ va ]ce == [ V_cons tid cons [ z ]v ]ce )› unfolding c.fresh ce.fresh v.fresh
apply(intro conjI )
using check_branch_s_branchI fresh_at_base z freshers apply simp
using check_branch_s_branchI fresh_at_base z freshers apply simp
using pure_supp apply force
using z fresh_x_neq fresh_prod5 by metis
qed
show ‹[ va ]ce = [ V_cons tid cons [ z ]v ]ce[z::=v]cev›
using ‹ va = V_cons tid cons v› subst_cev.simps subst_vv.simps by auto
show ‹ Θ ; B ; GNil ⊨ v ← const › using check_branch_s_branchI by auto
show "supp [ va ]ce ⊆ supp B" using ‹supp va = {}› ce.supp by simp
qed
show "Θ ; B ; GNil ⊨ v ← { z : b_of const | c_of const z }"
using check_branch_s_branchI z by auto
qed
text ‹Main body of proof for this case›
have "Θ ; Φ ; B ; (?G)[x::=v]\<Gamma>v ; Δ[x::=v]\<Delta>v ⊨ s[x::=v]sv ← τ[x::=v]\<tau>v"
proof(rule subst_check_check_s)
show ‹Θ ; B ; GNil ⊨ v ← { z : b_of const | [ va ]ce == [ V_cons tid cons [ z ]v ]ce AND c_of const z }› using vt by auto
show ‹atom z ♯ (x, v)› using z fresh_prodN by auto
show ‹ Θ ; Φ ; B ; ?G ; Δ ⊨ s ← τ›
using check_branch_s_branchI by auto
show ‹ ?G = GNil @ (x, b_of const, ([ va ]ce == [ V_cons tid cons [ z ]v ]ce AND c_of const z)[z::=[ x ]v]cv) #\Γ GNil›
proof -
have "va[z::=[ x ]v]vv = va" using forget_subst_v subst_v_v_def z fresh_prodN by metis
moreover have "(c_of const z)[z::=[ x ]v]cv = c_of const x"
using c_of_switch[of z const x] z fresh_prodN by metis
ultimately show ?thesis
unfolding subst_cv.simps subst_cev.simps subst_vv.simps append_g.simps
using c_of_switch[of z const x] z fresh_prodN z fresh_prodN check_branch_s_branchI by argo
qed
qed
moreover have "s[x::=v]sv = s'[x'::=v]sv"
using check_branch_s_branchI subst_v_flip_eq_two subst_v_s_def s_branch_s_branch_list.eq_iff by metis
ultimately show ?case using check_branch_s_branchI ‹τ[x::=v]\τv = τ› ‹Δ[x::=v]\Δv = Δ› by auto
qed(auto+)
text ‹Lemmas for while reduction. Making these separate lemmas allows flexibility in wiring them into the main proof and robustness
we change it›
lemma check_unit:
fixes τ::τ and Φ::Φ and Δ::Δ and G::Γ
assumes "Θ ; {||} ; GNil ⊨ { z : B_unit | TRUE } < τ'" and "Θ ; {||} ; GNil ⊨wf Δ" and "Θ ⊨wf Φ" and "Θ ; {||} ⊨wf G"
shows ‹ Θ ; Φ ; {||} ; G ; Δ ⊨ [[ L_unit ]v]s ← τ'›
proof -
have *:"Θ ; {||} ; GNil ⊨ [L_unit]v → { z : B_unit | [ [ z ]v ]ce == [ [ L_unit ]v ]ce }"
using infer_l.intros(4) infer_v_litI fresh_GNil assms wfX_wfY by (meson subtype_g_wf)
moreover have "Θ ; {||} ; GNil ⊨ { z : B_unit | [ [ z ]v ]ce == [ [ L_unit ]v ]ce } < τ'"
using subtype_top subtype_trans * infer_v_wf
by (meson assms(1))
ultimately show ?thesis (*apply(rule check_valI, auto simp add: assms,rule * )*)
using subtype_top subtype_trans fresh_GNil assms check_valI assms check_s_g_weakening assms toSet.simps
by (metis bot.extremum infer_v_g_weakening subtype_weakening wfD_wf)
qed
lemma preservation_var:
shows "Θ; Φ; {||}; GNil; Δ ⊨ VAR u : τ' = v IN s ← τ ==> Θ ⊨ δ ∼ Δ ==> atom u ♯ δ ==> atom u ♯ Δ ==>
Θ; Φ; {||}; GNil; (u,τ')#\<Delta>Δ ⊨ s ← τ ∧ Θ ⊨ (u,v)#δ ∼ (u,τ')#\<Delta>Δ"
and
"check_branch_s Θ Φ {||} GNil Δ tid dc const v cs τ ==> True" and
"check_branch_list Θ Φ {||} Γ Δ tid dclist v css τ ==> True"
proof(nominal_induct "{||}::bv fset" GNil Δ "VAR u : τ' = v IN s" τ and τ and τ rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_varI u' Θ Φ Δ τ s')
hence "Θ; Φ; {||}; GNil; (u, τ') #\<Delta> Δ ⊨ s ← τ" using check_s_abs_u check_v_wf by metis
moreover have "Θ ⊨ ((u,v)#δ) ∼ ((u,τ')#\<Delta>Δ)" proof
show ‹Θ ⊨ δ ∼ Δ › using check_varI by auto
show ‹Θ ; {||} ; GNil ⊨ v ← τ'› using check_varI by auto
show ‹u ∉ fst ` set δ› using check_varI fresh_d_fst_d by auto
qed
ultimately show ?case by simp
qed(auto+)
lemma check_while:
shows "Θ; Φ; {||}; GNil; Δ ⊨ WHILE s1 DO { s2 } ← τ ==> atom x ♯ (s1, s2) ==> atom z' ♯ x ==>
Θ; Φ; {||}; GNil; Δ ⊨ LET x : ({ z' : B_bool | TRUE }) = s1 IN (IF (V_var x) THEN (s2 ;; (WHILE s1 DO {s2}))
ELSE ([ V_lit L_unit]s)) ← τ" and
"check_branch_s Θ Φ {||} GNil Δ tid dc const v cs τ ==> True" and
"check_branch_list Θ Φ {||} Γ Δ tid dclist v css τ ==> True"
proof(nominal_induct "{||}::bv fset" GNil Δ "AS_while s1 s2" τ and τ and τ avoiding: s1 s2 x z' rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_whileI Θ Φ Δ s1 z s2 τ')
have teq:"{ z' : B_bool | TRUE } = { z : B_bool | TRUE }" using τ.eq_iff by auto
show ?case proof
have " atom x ♯ τ' " using wfT_nil_supp fresh_def subtype_wfT check_whileI(5) by fast
moreover have "atom x ♯ { z' : B_bool | TRUE } " using τ.fresh c.fresh b.fresh by metis
ultimately show ‹atom x ♯ (Θ, Φ, {||}, GNil, Δ, { z' : B_bool | TRUE }, s1, τ')›
apply(unfold fresh_prodN)
using check_whileI wb_x_fresh check_s_wf wfD_x_fresh fresh_empty_fset fresh_GNil fresh_Pair ‹atom x ♯ τ'› by metis
show ‹ Θ ; Φ ; {||} ; GNil ; Δ ⊨ s1 ← { z' : B_bool | TRUE }› using check_whileI teq by metis
let ?G = "(x, b_of { z' : B_bool | TRUE }, c_of { z' : B_bool | TRUE } x) #\<Gamma> GNil"
have cof:"(c_of { z' : B_bool | TRUE } x) = C_true" using c_of.simps check_whileI subst_cv.simps by metis
have wfg: "Θ ; {||} ⊨wf ?G" proof
show "c_of { z' : B_bool | TRUE } x ∈ {TRUE, FALSE}" using subst_cv.simps cof by auto
show "Θ ; {||} ⊨wf GNil " using wfG_nilI check_whileI wfX_wfY check_s_wf by metis
show "atom x ♯ GNil" using fresh_GNil by auto
show "Θ ; {||} ⊨wf b_of { z' : B_bool | TRUE } " using wfB_boolI wfX_wfY check_s_wf b_of.simps
by (metis ‹Θ ; {||} ⊨wf GNil›)
qed
obtain zz::x where zf:‹atom zz ♯ ((Θ, Φ, {||}::bv fset, ?G , Δ, [ x ]v,
AS_seq s2 (AS_while s1 s2), AS_val [ L_unit ]v, τ'),x,?G)›
using obtain_fresh by blast
show ‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨
AS_if [ x ]v (AS_seq s2 (AS_while s1 s2)) (AS_val [ L_unit ]v) ← τ'›
proof
show "atom zz ♯ (Θ, Φ, {||}::bv fset, ?G , Δ, [ x ]v, AS_seq s2 (AS_while s1 s2), AS_val [ L_unit ]v, τ')" using zf by auto
show ‹Θ ; {||} ; ?G ⊨ [ x ]v ← { zz : B_bool | TRUE }› proof
have "atom zz ♯ x ∧ atom zz ♯ (Θ, {||}::bv fset, ?G)" using zf fresh_prodN by metis
thus ‹ Θ ; {||} ; ?G ⊨ [ x ]v →{ zz : B_bool | [[zz]v]ce == [[ x ]v]ce }›
using infer_v_varI lookup.simps wfg b_of.simps by metis
thus ‹Θ ; {||} ; ?G ⊨ { zz : B_bool | [[ zz ]v]ce == [[ x ]v]ce } < { zz : B_bool | TRUE }›
using subtype_top infer_v_wf by metis
qed
show ‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨ AS_seq s2 (AS_while s1 s2) ← { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_true ]v ]ce IMP c_of τ' zz }›
proof
have "{ zz : B_unit | TRUE } = { z : B_unit | TRUE }" using τ.eq_iff by auto
thus ‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨ s2 ← { zz : B_unit | TRUE }› using check_s_g_weakening(1) [OF check_whileI(3) _ wfg] toSet.simps
by (simp add: ‹{ zz : B_unit | TRUE } = { z : B_unit | TRUE }›)
show ‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨ AS_while s1 s2 ← { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_true ]v ]ce IMP c_of τ' zz }›
proof(rule check_s_supertype(1))
have ‹ Θ; Φ; {||}; GNil; Δ ⊨ AS_while s1 s2 ← τ'› using check_whileI by auto
thus *:‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨ AS_while s1 s2 ← τ' › using check_s_g_weakening(1)[OF _ _ wfg] toSet.simps by auto
show ‹Θ ; {||} ; ?G ⊨ τ' < { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_true ]v ]ce IMP c_of τ' zz }›
proof(rule subtype_eq_if_τ)
show ‹ Θ ; {||} ; ?G ⊨wf τ' › using * check_s_wf by auto
show ‹ Θ ; {||} ; ?G ⊨wf { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_true ]v ]ce IMP c_of τ' zz } ›
apply(rule wfT_eq_imp, simp add: base_for_lit.simps)
using subtype_wf check_whileI wfg zf fresh_prodN by metis+
show ‹atom zz ♯ τ'› using zf fresh_prodN by metis
qed
qed
qed
show ‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨ AS_val [ L_unit ]v ← { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_false ]v ]ce IMP c_of τ' zz }›
proof(rule check_s_supertype(1))
show *:‹ Θ ; Φ ; {||} ; ?G ; Δ ⊨ AS_val [ L_unit ]v ← τ'›
using check_unit[OF check_whileI(5) _ _ wfg] using check_whileI wfg wfX_wfY check_s_wf by metis
show ‹Θ ; {||} ; ?G ⊨ τ' < { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_false ]v ]ce IMP c_of τ' zz }›
proof(rule subtype_eq_if_τ)
show ‹ Θ ; {||} ; ?G ⊨wf τ' › using * check_s_wf by metis
show ‹ Θ ; {||} ; ?G ⊨wf { zz : b_of τ' | [ [ x ]v ]ce == [ [ L_false ]v ]ce IMP c_of τ' zz } ›
apply(rule wfT_eq_imp, simp add: base_for_lit.simps)
using subtype_wf check_whileI wfg zf fresh_prodN by metis+
show ‹atom zz ♯ τ'› using zf fresh_prodN by metis
qed
qed
qed
qed
qed(auto+)
lemma check_s_narrow:
fixes s::s and x::x
assumes "atom x ♯ (Θ, Φ, B, Γ, Δ, c, τ, s)" and "Θ ; Φ ; B ; (x, B_bool, c) #\<Gamma> Γ ; Δ ⊨ s ← τ" and
"Θ ; B ; Γ ⊨ c "
shows "Θ ; Φ ; B ; Γ ; Δ ⊨ s ← τ"
proof -
let ?B = "({||}::bv fset)"
let ?v = "V_lit L_true"
obtain z::x where z: "atom z ♯ (x, [ L_true ]v,c)" using obtain_fresh by metis
have "atom z ♯ c" using z fresh_prodN by auto
hence c:" c[x::=[ z ]v]v[z::=[ x ]v]cv = c" using subst_v_c_def by simp
have "Θ ; Φ ; B ; ((x,B_bool, c) #\<Gamma> Γ)[x::=?v]\<Gamma>v ; Δ[x::=?v]\<Delta>v ⊨ s[x::=?v]sv ← τ[x::=?v]\<tau>v" proof(rule subst_infer_check_s(1) )
show vt: ‹ Θ ; B ; Γ ⊨ [ L_true ]v → { z : B_bool | (CE_val (V_var z)) == (CE_val (V_lit L_true )) } ›
using infer_v_litI check_s_wf wfG_elims(2) infer_trueI assms by metis
show ‹Θ ; B ; Γ ⊨ { z : B_bool | (CE_val (V_var z)) == (CE_val (V_lit L_true )) } < { z : B_bool | c[x::=[ z ]v]v }› proof
show ‹atom x ♯ (Θ, B, Γ, z, [ [ z ]v ]ce == [ [ L_true ]v ]ce , z, c[x::=[ z ]v]v)›
apply(unfold fresh_prodN, intro conjI)
prefer 5
using c.fresh ce.fresh v.fresh z fresh_prodN apply auto[1]
prefer 6
using fresh_subst_v_if[of "atom x" c x] assms fresh_prodN apply simp
using z assms fresh_prodN apply metis
using z assms fresh_prodN apply metis
using z assms fresh_prodN apply metis
using z fresh_prodN assms fresh_at_base by metis+
show ‹ Θ ; B ; Γ ⊨wf { z : B_bool | [ [ z ]v ]ce == [ [ L_true ]v ]ce } › using vt infer_v_wf by simp
show ‹ Θ ; B ; Γ ⊨wf { z : B_bool | c[x::=[ z ]v]v } › proof(rule wfG_wfT)
show ‹ Θ ; B ⊨wf (x, B_bool, c[x::=[ z ]v]v[z::=[ x ]v]cv) #\Γ Γ › using c check_s_wf assms by metis
have " atom x ♯ [ z ]v" using v.fresh z fresh_at_base by auto
thus ‹atom x ♯ c[x::=[ z ]v]v› using fresh_subst_v_if[of "atom x" c ] by auto
qed
have wfg: "Θ ; B ⊨wf(x, B_bool, ([ [ z ]v ]ce == [ [ L_true ]v ]ce )[z::=[ x ]v]v) #\<Gamma> Γ"
using wfT_wfG vt infer_v_wf fresh_prodN assms by simp
show ‹Θ ; B ; (x, B_bool, ([ [ z ]v ]ce == [ [ L_true ]v ]ce )[z::=[ x ]v]v) #\Γ Γ ⊨ c[x::=[ z ]v]v[z::=[ x ]v]v ›
using c valid_weakening[OF assms(3) _ wfg ] toSet.simps
using subst_v_c_def by auto
qed
show ‹atom z ♯ (x, [ L_true ]v)› using z fresh_prodN by metis
show ‹ Θ ; Φ ; B ; (x, B_bool, c) #\Γ Γ ; Δ ⊨ s ← τ› using assms by auto
thus ‹(x, B_bool, c) #\Γ Γ = GNil @ (x, B_bool, c[x::=[ z ]v]v[z::=[ x ]v]cv) #\Γ Γ› using append_g.simps c by auto
qed
moreover have "((x,B_bool, c) #\<Gamma> Γ)[x::=?v]\<Gamma>v = Γ " using subst_gv.simps by auto
ultimately show ?thesis using assms forget_subst_dv forget_subst_sv forget_subst_tv fresh_prodN by metis
qed
lemma check_assert_s:
fixes s::s and x::x
assumes "Θ; Φ; {||}; GNil; Δ ⊨ AS_assert c s ← τ"
shows "Θ; Φ; {||}; GNil; Δ ⊨ s ← τ ∧ Θ ; {||} ; GNil ⊨ c "
proof -
let ?B = "({||}::bv fset)"
let ?v = "V_lit L_true"
obtain x where x: "Θ ; Φ ; ?B ; (x,B_bool, c) #\<Gamma> GNil ; Δ ⊨ s ← τ ∧ atom x ♯ (Θ, Φ, ?B, GNil, Δ, c, τ, s ) ∧ Θ ; ?B ; GNil ⊨ c "
using check_s_elims(10)[OF ‹Θ ; Φ ; ?B ; GNil ; Δ ⊨ AS_assert c s ← τ›] valid.simps by metis
show ?thesis using assms check_s_narrow x by metis
qed
lemma infer_v_pair2I:
"atom z ♯ (v1, v2) ==>
atom z ♯ (Θ, B, Γ) ==>
Θ ; B ; Γ ⊨ v1 → t1 ==>
Θ ; B ; Γ ⊨ v2 → t2 ==>
b1 = b_of t1 ==> b2 = b_of t2 ==>
Θ ; B ; Γ ⊨ [ v1 , v2 ]v → { z : [ b1 , b2 ]b | [ [ z ]v ]ce == [ [ v1 , v2 ]v ]ce }"
using infer_v_pairI by simp
subsection ‹Main Lemma›
lemma preservation:
assumes "Φ ⊨ ⟨δ, s⟩ ⟶ ⟨δ', s'⟩" and "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ"
shows "∃Δ'. Θ; Φ; Δ' ⊨ ⟨δ', s'⟩ ← τ ∧ Δ ⊑ Δ'"
using assms
proof(induct arbitrary: τ rule: reduce_stmt.induct)
case (reduce_let_plusI δ x n1 n2 s')
then show ?case using preservation_plus
by (metis order_refl)
next
case (reduce_let_leqI b n1 n2 δ x s)
then show ?case using preservation_leq by (metis order_refl)
next
case (reduce_let_eqI b n1 n2 Φ δ x s)
then show ?case using preservation_eq[OF reduce_let_eqI(2)] order_refl by metis
next
case (reduce_let_appI f z b c τ' s' Φ δ x v s)
hence tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_app f v) s ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)" using config_type_elims[OF reduce_let_appI(2)] by metis
hence *:"Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_app f v) s ← τ" by auto
hence "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x (τ'[z::=v]\<tau>v) (s'[z::=v]sv) s ← τ"
using preservation_app reduce_let_appI tt by auto
hence "Θ; Φ; Δ ⊨ ⟨ δ , AS_let2 x (τ'[z::=v]\<tau>v) s'[z::=v]sv s ⟩ ← τ" using config_typeI tt by auto
then show ?case using tt order_refl reduce_let_appI by metis
next
case (reduce_let_appPI f bv z b c τ' s' Φ δ x b' v s)
hence tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_appP f b' v) s ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)" using config_type_elims[OF reduce_let_appPI(2)] by metis
hence *:"Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_appP f b' v) s ← τ" by auto
have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x (τ'[bv::=b']\<tau>b[z::=v]\<tau>v) (s'[bv::=b']sb[z::=v]sv) s ← τ"
proof(rule preservation_poly_app)
show ‹Some (AF_fundef f (AF_fun_typ_some bv (AF_fun_typ z b c τ' s'))) = lookup_fun Φ f› using reduce_let_appPI by metis
show ‹∀fd∈set Φ. check_fundef Θ Φ fd› using tt lookup_fun_member by metis
show ‹ Θ ; Φ ;{||} ; GNil ; Δ ⊨ AS_let x (AE_appP f b' v) s ← τ› using * by auto
show ‹ Θ ; {||} ⊨wf b' › using check_s_elims infer_e_wf wfE_elims * by metis
qed(auto+)
hence "Θ; Φ; Δ ⊨ ⟨ δ , AS_let2 x (τ'[bv::=b']\<tau>b[z::=v]\<tau>v) s'[bv::=b']sb[z::=v]sv s ⟩ ← τ" using config_typeI tt by auto
then show ?case using tt order_refl reduce_let_appI by metis
next
case (reduce_if_trueI δ s1 s2)
then show ?case using preservation_if by metis
next
case (reduce_if_falseI uw δ s1 s2)
then show ?case using preservation_if by metis
next
case (reduce_let_valI δ x v s)
then show ?case using preservation_let_val by presburger
next
case (reduce_let_mvar u v δ Φ x s)
hence *:"Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_mvar u) s ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by blast
hence **: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_mvar u) s ← τ" by auto
obtain xa::x and za::x and ca::c and ba::b and sa::s where
sa1: "atom xa ♯ (Θ, Φ, {||}::bv fset, GNil, Δ, AE_mvar u, τ) ∧ atom za ♯ (xa, Θ, Φ, {||}::bv fset, GNil, Δ, AE_mvar u, τ, sa) ∧
Θ; Φ; {||}; GNil; Δ ⊨ AE_mvar u → { za : ba | ca } ∧
Θ ; Φ ; {||} ; (xa, ba, ca[za::=V_var xa]cv) #\<Gamma> GNil ; Δ ⊨ sa ← τ ∧
(∀c. atom c ♯ (s, sa) ⟶ atom c ♯ (x, xa, s, sa) ⟶ (x ↔ c) ∙ s = (xa ↔ c) ∙ sa)"
using check_s_elims(2)[OF **] subst_defs by metis
have "Θ ; {||} ; GNil ⊨ v ← { za : ba | ca }" proof -
have " (u , { za : ba | ca }) ∈ setD Δ" using infer_e_elims(11) sa1 by fast
thus ?thesis using delta_sim_v reduce_let_mvar config_type_elims check_s_wf by metis
qed
then obtain τ' where vst: "Θ ; {||} ; GNil ⊨ v → τ' ∧
Θ ; {||} ; GNil ⊨ τ' < { za : ba | ca }" using check_v_elims by blast
obtain za2 and ba2 and ca2 where zbc: "τ' = ({ za2 : ba2 | ca2 }) ∧ atom za2 ♯ (xa, (xa, Θ, Φ, {||}::bv fset, GNil, Δ, AE_val v, τ, sa))"
using obtain_fresh_z by blast
have beq: "ba=ba2" using subtype_eq_base vst zbc by blast
moreover have xaf: "atom xa ♯ (za, za2)"
apply(unfold fresh_prodN, intro conjI)
using sa1 zbc fresh_prodN fresh_x_neq by metis+
have sat2: " Θ ; Φ ; {||} ; GNil@(xa, ba, ca2[za2::=V_var xa]cv) #\<Gamma> GNil ; Δ ⊨ sa ← τ" proof(rule ctx_subtype_s)
show "Θ ; Φ ; {||} ; GNil @ (xa, ba, ca[za::=V_var xa]cv) #\<Gamma> GNil ; Δ ⊨ sa ← τ" using sa1 by auto
show "Θ ; {||} ; GNil ⊨ { za2 : ba | ca2 } < { za : ba | ca }" using beq zbc vst by fast
show "atom xa ♯ (za, za2, ca, ca2)" proof -
have *:"Θ ; {||} ; GNil ⊨wf ({ za2 : ba2 | ca2 }) " using zbc vst subtype_wf by auto
hence "supp ca2 ⊆ { atom za2 }" using wfT_supp_c[OF *] supp_GNil by simp
moreover have "atom za2 ♯ xa" using zbc fresh_Pair fresh_x_neq by metis
ultimately have "atom xa ♯ ca2" using zbc supp_at_base fresh_def
by (metis empty_iff singleton_iff subset_singletonD)
moreover have "atom xa ♯ ca" proof -
have *:"Θ ; {||} ; GNil ⊨wf ({ za : ba | ca }) " using zbc vst subtype_wf by auto
hence "supp ca ⊆ { atom za }" using wfT_supp τ.supp by force
moreover have "xa ≠ za" using fresh_def fresh_x_neq xaf fresh_Pair by metis
ultimately show ?thesis using fresh_def by auto
qed
ultimately show ?thesis using xaf sa1 fresh_prod4 fresh_Pair by metis
qed
qed
hence dwf: "Θ ; {||} ; GNil ⊨wf Δ" using sa1 infer_e_wf by meson
have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let xa (AE_val v) sa ← τ" proof
have "atom xa ♯ (AE_val v)" using infer_v_wf(1) wfV_supp fresh_def e.fresh x_not_in_b_set vst by fastforce
thus "atom xa ♯ (Θ, Φ, {||}::bv fset, GNil, Δ, AE_val v, τ)" using sa1 freshers by simp
have "atom za2 ♯ (AE_val v)" using infer_v_wf(1) wfV_supp fresh_def e.fresh x_not_in_b_set vst by fastforce
thus "atom za2 ♯ (xa, Θ, Φ, {||}::bv fset, GNil, Δ, AE_val v, τ, sa)" using zbc freshers fresh_prodN by auto
have " Θ ⊨wf Φ" using sa1 infer_e_wf by auto
thus "Θ; Φ; {||}; GNil; Δ ⊨ AE_val v → { za2 : ba | ca2 }"
using zbc vst beq dwf infer_e_valI by blast
show "Θ ; Φ ; {||} ; (xa, ba, ca2[za2::=V_var xa]v) #\<Gamma> GNil ; Δ ⊨ sa ← τ" using sat2 append_g.simps subst_defs by metis
qed
moreover have "AS_let xa (AE_val v) sa = AS_let x (AE_val v) s" proof -
have "[[atom x]]lst. s = [[atom xa]]lst. sa"
using sa1 Abs1_eq_iff_all(3)[where z=" (s, sa)"] by metis
thus ?thesis using s_branch_s_branch_list.eq_iff(2) by metis
qed
ultimately have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_val v) s ← τ" by auto
then show ?case using reduce_let_mvar * config_typeI
by (meson order_refl)
next
case (reduce_let2I Φ δ s1 δ' s1' x t s2)
hence **: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x t s1 s2 ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)" using config_type_elims[OF reduce_let2I(3)] by blast
hence *:"Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x t s1 s2 ← τ" by auto
obtain xa::x and z::x and c and b and s2a::s where st: "atom xa ♯ (Θ, Φ, {||}::bv fset, GNil, Δ, t, s1, τ) ∧
Θ; Φ; {||}; GNil; Δ ⊨ s1 ← t ∧
Θ ; Φ ; {||} ; (xa, b_of t, c_of t xa) #\<Gamma> GNil ; Δ ⊨ s2a ← τ ∧ ([[atom x]]lst. s2 = [[atom xa]]lst. s2a) "
using check_s_elims(4)[OF *] Abs1_eq_iff_all(3) by metis
hence "Θ; Φ; Δ ⊨ ⟨ δ , s1 ⟩ ← t" using config_typeI ** by auto
then obtain Δ' where s1r: "Θ; Φ; Δ' ⊨ ⟨ δ' , s1' ⟩ ← t ∧ Δ ⊑ Δ'" using reduce_let2I by presburger
have "Θ; Φ; {||}; GNil; Δ' ⊨ AS_let2 xa t s1' s2a ← τ"
proof(rule check_let2I)
show *:"Θ; Φ; {||}; GNil; Δ' ⊨ s1' ← t" using config_type_elims st s1r by metis
show "atom xa ♯ (Θ, Φ, {||}::bv fset, GNil, Δ',t, s1', τ)" proof -
have "atom xa ♯ s1'" using check_s_x_fresh * by auto
moreover have "atom xa ♯ Δ'" using check_s_x_fresh * by auto
ultimately show ?thesis using st fresh_prodN by metis
qed
show "Θ ; Φ ; {||} ; (xa, b_of t, c_of t xa) #\<Gamma> GNil ; Δ' ⊨ s2a ← τ" proof -
have "Θ ; {||} ; GNil ⊨wf Δ'" using * check_s_wf by auto
moreover have "Θ ; {||} ⊨wf ((xa, b_of t, c_of t xa) #\<Gamma> GNil)" using st check_s_wf by auto
ultimately have "Θ ; {||} ; ((xa, b_of t , c_of t xa) #\<Gamma> GNil) ⊨wf Δ'" using wf_weakening by auto
thus ?thesis using check_s_d_weakening check_s_wf st s1r by metis
qed
qed
moreover have "AS_let2 xa t s1' s2a = AS_let2 x t s1' s2" using st s_branch_s_branch_list.eq_iff by metis
ultimately have "Θ; Φ; {||}; GNil; Δ' ⊨ AS_let2 x t s1' s2 ← τ" using st by argo
moreover have "Θ ⊨ δ' ∼ Δ'" using config_type_elims s1r by fast
ultimately show ?case using config_typeI **
by (meson s1r)
next
case (reduce_let2_valI vb δ x t v s)
then show ?case using preservation_let_val by meson
next
case (reduce_varI u δ Φ τ' v s)
hence ** : "Θ; Φ; {||}; GNil; Δ ⊨ AS_var u τ' v s ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by meson
have uf: "atom u ♯ Δ" using reduce_varI delta_sim_fresh by force
hence *: "Θ; Φ; {||}; GNil; Δ ⊨ AS_var u τ' v s ← τ" and " Θ ⊨ δ ∼ Δ" using ** by auto
thus ?case using preservation_var reduce_varI config_typeI ** set_subset_Cons
setD_ConsD subsetI by (metis delta_sim_fresh)
next
case (reduce_assignI Φ δ u v )
hence *: "Θ; Φ; {||}; GNil; Δ ⊨ AS_assign u v ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by meson
then obtain z and τ' where zt: "Θ ; {||} ; GNil ⊨ ({ z : B_unit | TRUE }) < τ ∧ (u,τ') ∈ setD Δ ∧ Θ ; {||} ; GNil ⊨ v ← τ' ∧ Θ ; {||} ; GNil ⊨wf Δ"
using check_s_elims(8) by metis
hence "Θ ⊨ update_d δ u v ∼ Δ" using update_d_sim * by metis
moreover have "Θ; Φ; {||}; GNil; Δ ⊨ AS_val (V_lit L_unit ) ← τ" using zt * check_s_v_unit check_s_wf
by auto
ultimately show ?case using config_typeI * by (meson order_refl)
next
case (reduce_seq1I Φ δ s)
hence "Θ ; Φ ; {||} ; GNil ; Δ ⊨ s ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using check_s_elims config_type_elims by force
then show ?case using config_typeI by blast
next
case (reduce_seq2I s1 v Φ δ δ' s1' s2)
hence tt: "Θ; Φ; {||}; GNil; Δ ⊨ AS_seq s1 s2 ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by blast
then obtain z where zz: "Θ ; Φ ; {||} ; GNil; Δ ⊨ s1 ← ({ z : B_unit | TRUE }) ∧ Θ; Φ; {||}; GNil; Δ ⊨ s2 ← τ"
using check_s_elims by blast
hence "Θ; Φ; Δ ⊨ ⟨ δ , s1 ⟩ ← ({ z : B_unit | TRUE })"
using tt config_typeI tt by simp
then obtain Δ' where *: "Θ; Φ; Δ' ⊨ ⟨ δ' , s1' ⟩ ← ({ z : B_unit | TRUE }) ∧ Δ ⊑ Δ'"
using reduce_seq2I by meson
moreover hence s't: "Θ; Φ; {||}; GNil; Δ' ⊨ s1' ← ({ z : B_unit | TRUE }) ∧ Θ ⊨ δ' ∼ Δ'"
using config_type_elims by force
moreover hence "Θ ; {||} ; GNil ⊨wf Δ'" using check_s_wf by meson
moreover hence "Θ; Φ; {||}; GNil; Δ' ⊨ s2 ← τ"
using calculation(1) zz check_s_d_weakening * by metis
moreover hence "Θ; Φ; {||}; GNil; Δ' ⊨ (AS_seq s1' s2) ← τ"
using check_seqI zz s't by meson
ultimately have "Θ; Φ; Δ' ⊨ ⟨ δ' , AS_seq s1' s2 ⟩ ← τ ∧ Δ ⊑ Δ'"
using zz config_typeI tt by meson
then show ?case by meson
next
case (reduce_whileI x s1 s2 z' Φ δ )
hence *: "Θ; Φ; {||}; GNil; Δ ⊨ AS_while s1 s2 ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by meson
hence **:"Θ; Φ; {||}; GNil; Δ ⊨ AS_while s1 s2 ← τ" by auto
hence "Θ; Φ; {||}; GNil; Δ ⊨ AS_let2 x ({ z' : B_bool | TRUE }) s1 (AS_if (V_var x) (AS_seq s2 (AS_while s1 s2)) (AS_val (V_lit L_unit)) ) ← τ"
using check_while reduce_whileI by auto
thus ?case using config_typeI * by (meson subset_refl)
next
case (reduce_caseI dc x' s' css Φ δ tyid v)
hence **: "Θ; Φ; {||}; GNil; Δ ⊨ AS_match (V_cons tyid dc v) css ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims[OF reduce_caseI(2)] by metis
hence ***: "Θ; Φ; {||}; GNil; Δ ⊨ AS_match (V_cons tyid dc v) css ← τ" by auto
let ?vcons = "V_cons tyid dc v"
obtain dclist tid and z::x where cv: "Θ; {||} ; GNil ⊨ (V_cons tyid dc v) ← ({ z : B_id tid | TRUE }) ∧
Θ; Φ; {||}; GNil; Δ ; tid ; dclist ; (V_cons tyid dc v) ⊨ css ← τ ∧ AF_typedef tid dclist ∈ set Θ ∧
Θ ; {||} ; GNil ⊨ V_cons tyid dc v ← { z : B_id tid | TRUE }"
using check_s_elims(9)[OF ***] by metis
hence vi:" Θ ; {||} ; GNil ⊨ V_cons tyid dc v ← { z : B_id tid | TRUE }" by auto
obtain tcons where vi2:" Θ ; {||} ; GNil ⊨ V_cons tyid dc v → tcons ∧ Θ ; {||} ; GNil ⊨ tcons < { z : B_id tid | TRUE }"
using check_v_elims(1)[OF vi] by metis
hence vi1: "Θ ; {||} ; GNil ⊨ V_cons tyid dc v → tcons" by auto
show ?case proof(rule infer_v_elims(4)[OF vi1],goal_cases)
case (1 dclist2 tc tv z2)
have "tyid = tid" using τ.eq_iff using subtype_eq_base vi2 1 by fastforce
hence deq:"dclist = dclist2" using check_v_wf wfX_wfY cv 1 wfTh_dclist_unique by metis
have "Θ; Φ; {||}; GNil; Δ ⊨ s'[x'::=v]sv ← τ" proof(rule check_match(3))
show ‹ Θ ; Φ ; {||} ; GNil ; Δ ; tyid ; dclist ; ?vcons ⊨ css ← τ› using ‹tyid = tid› cv by auto
show "distinct (map fst dclist)" using wfTh_dclist_distinct check_v_wf wfX_wfY cv by metis
show ‹?vcons = V_cons tyid dc v› by auto
show ‹{||} = {||}› by auto
show ‹(dc, tc) ∈ set dclist› using 1 deq by auto
show ‹GNil = GNil› by auto
show ‹Some (AS_branch dc x' s') = lookup_branch dc css› using reduce_caseI by auto
show ‹Θ ; {||} ; GNil ⊨ v ← tc› using 1 check_v.intros by auto
qed
thus ?case using config_typeI ** by blast
qed
next
case (reduce_let_fstI Φ δ x v1 v2 s)
thus ?case using preservation_fst_snd order_refl by metis
next
case (reduce_let_sndI Φ δ x v1 v2 s)
thus ?case using preservation_fst_snd order_refl by metis
next
case (reduce_let_concatI Φ δ x v1 v2 s)
hence elim: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_concat (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2))) s ← τ ∧
Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by metis
obtain z::x where z: "atom z ♯ (AE_concat (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2)), GNil, CE_val (V_lit (L_bitvec (v1 @ v2))))"
using obtain_fresh by metis
have "Θ ; {||} ⊨wf GNil" using check_s_wf elim by auto
have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_val (V_lit (L_bitvec (v1 @ v2)))) s ← τ" proof(rule subtype_let)
show ‹ Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_concat (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2))) s ← τ› using elim by auto
show ‹Θ; Φ; {||}; GNil; Δ ⊨ (AE_concat (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2))) → { z : B_bitvec | CE_val (V_var z) == (CE_concat ([V_lit (L_bitvec v1)]ce) ([V_lit (L_bitvec v2)]ce))} ›
(is "Θ; Φ; {||}; GNil; Δ ⊨ ?e1 → ?t1")
proof
show ‹ Θ ; {||} ; GNil ⊨wf Δ › using check_s_wf elim by auto
show ‹ Θ ⊨wf Φ › using check_s_wf elim by auto
show ‹ Θ ; {||} ; GNil ⊨ V_lit (L_bitvec v1) → { z : B_bitvec | CE_val (V_var z) == CE_val (V_lit (L_bitvec v1)) }›
using infer_v_litI infer_l.intros ‹Θ ; {||} ⊨wf GNil› fresh_GNil by auto
show ‹ Θ ; {||} ; GNil ⊨ V_lit (L_bitvec v2) → { z : B_bitvec | CE_val (V_var z) == CE_val (V_lit (L_bitvec v2)) }›
using infer_v_litI infer_l.intros ‹Θ ; {||} ⊨wf GNil› fresh_GNil by auto
show ‹atom z ♯ AE_concat (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2))› using z fresh_Pair by metis
show ‹atom z ♯ GNil› using z fresh_Pair by auto
qed
show ‹Θ; Φ; {||}; GNil; Δ ⊨ AE_val (V_lit (L_bitvec (v1 @ v2))) → { z : B_bitvec | CE_val (V_var z) == CE_val (V_lit (L_bitvec (v1 @ v2))) } ›
(is "Θ; Φ; {||}; GNil; Δ ⊨ ?e2 → ?t2")
using infer_e_valI infer_v_litI infer_l.intros ‹Θ ; {||} ⊨wf GNil› fresh_GNil check_s_wf elim by metis
show ‹Θ ; {||} ; GNil ⊨ ?t2 < ?t1› using subtype_concat check_s_wf elim by auto
qed
thus ?case using config_typeI elim by (meson order_refl)
next
case (reduce_let_lenI Φ δ x v s)
hence elim: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_len (V_lit (L_bitvec v))) s ← τ ∧ Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using check_s_elims config_type_elims by metis
then obtain t where t: "Θ; Φ; {||}; GNil; Δ ⊨ AE_len (V_lit (L_bitvec v)) → t" using check_s_elims by meson
moreover then obtain z::x where "t = { z : B_int | CE_val (V_var z) == CE_len ([V_lit (L_bitvec v)]ce) }" using infer_e_elims by meson
moreover obtain z'::x where "atom z' ♯ v" using obtain_fresh by metis
moreover have "Θ; Φ; {||}; GNil; Δ ⊨ AE_val (V_lit (L_num (int (length v)))) → { z' : B_int | CE_val (V_var z') == CE_val (V_lit (L_num (int (length v)))) }"
using infer_e_valI infer_v_litI infer_l.intros(3) t check_s_wf elim
by (metis infer_l_form2 type_for_lit.simps(3))
moreover have "Θ ; {||} ; GNil ⊨ { z' : B_int | CE_val (V_var z') == CE_val (V_lit (L_num (int (length v)))) } <
{ z : B_int | CE_val (V_var z) == CE_len [(V_lit (L_bitvec v))]ce }" using subtype_len check_s_wf elim by auto
ultimately have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_val (V_lit (L_num (int (length v))))) s ← τ" using subtype_let by (meson elim)
thus ?case using config_typeI elim by (meson order_refl)
next
case (reduce_let_splitI n v v1 v2 Φ δ x s)
hence elim: "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_split (V_lit (L_bitvec v)) (V_lit (L_num n))) s ← τ ∧
Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by metis
obtain z::x where z: "atom z ♯ (AE_split (V_lit (L_bitvec v)) (V_lit (L_num n)), GNil, CE_val (V_lit (L_bitvec (v1 @ v2))),
([ L_bitvec v1 ]v, [ L_bitvec v2 ]v), Θ, {||}::bv fset)"
using obtain_fresh by metis
have *:"Θ ; {||} ⊨wf GNil" using check_s_wf elim by auto
have "Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_val (V_pair (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2)))) s ← τ" proof(rule subtype_let)
show ‹ Θ; Φ; {||}; GNil; Δ ⊨ AS_let x (AE_split (V_lit (L_bitvec v)) (V_lit (L_num n))) s ← τ› using elim by auto
show ‹Θ; Φ; {||}; GNil; Δ ⊨ (AE_split (V_lit (L_bitvec v)) (V_lit (L_num n))) → { z : B_pair B_bitvec B_bitvec
| ((CE_val (V_lit (L_bitvec v))) == (CE_concat (CE_fst (CE_val (V_var z))) (CE_snd (CE_val (V_var z)))))
AND (((CE_len (CE_fst (CE_val (V_var z))))) == (CE_val (V_lit (L_num n)))) } ›
(is "Θ; Φ; {||}; GNil; Δ ⊨ ?e1 → ?t1")
proof
show ‹ Θ ; {||} ; GNil ⊨wf Δ › using check_s_wf elim by auto
show ‹ Θ ⊨wf Φ › using check_s_wf elim by auto
show ‹ Θ ; {||} ; GNil ⊨ V_lit (L_bitvec v) → { z : B_bitvec | CE_val (V_var z) == CE_val (V_lit (L_bitvec v)) }›
using infer_v_litI infer_l.intros ‹Θ ; {||} ⊨wf GNil› fresh_GNil by auto
show "Θ ; {||} ; GNil ⊨ ([ L_num
n ]v) ← { z : B_int | (([ leq [ [ L_num 0 ]v ]ce [ [ z ]v ]ce ]ce) == ([ [ L_true ]v ]ce)) AND [ leq [ [ z ]v ]ce [| [ [ L_bitvec
v ]v ]ce |]ce ]ce == [ [ L_true ]v ]ce }" using split_n reduce_let_splitI check_v_num_leq * wfX_wfY by metis
show ‹atom z ♯ AE_split [ L_bitvec v ]v [ L_num n ]v› using z fresh_Pair by auto
show ‹atom z ♯ GNil› using z fresh_Pair by auto
show ‹atom z ♯ AE_split [ L_bitvec v ]v [ L_num n ]v› using z fresh_Pair by auto
show ‹atom z ♯ GNil› using z fresh_Pair by auto
show ‹atom z ♯ AE_split [ L_bitvec v ]v [ L_num n ]v› using z fresh_Pair by auto
show ‹atom z ♯ GNil› using z fresh_Pair by auto
qed
show ‹Θ; Φ; {||}; GNil; Δ ⊨ AE_val (V_pair (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2))) → { z : B_pair B_bitvec B_bitvec | CE_val (V_var z) == CE_val ((V_pair (V_lit (L_bitvec v1)) (V_lit (L_bitvec v2)))) } ›
(is "Θ; Φ; {||}; GNil; Δ ⊨ ?e2 → ?t2")
apply(rule infer_e_valI)
using check_s_wf elim apply metis
using check_s_wf elim apply metis
apply(rule infer_v_pair2I)
using z fresh_prodN apply metis
using z fresh_GNil fresh_prodN apply metis
using infer_v_litI infer_l.intros ‹Θ ; {||} ⊨wf GNil› b_of.simps apply blast+
using b_of.simps apply simp+
done
show ‹Θ ; {||} ; GNil ⊨ ?t2 < ?t1› using subtype_split check_s_wf elim reduce_let_splitI by auto
qed
thus ?case using config_typeI elim by (meson order_refl)
next
case (reduce_assert1I Φ δ c v)
hence elim: "Θ; Φ; {||}; GNil; Δ ⊨ AS_assert c [v]s ← τ ∧
Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims reduce_assert1I by metis
hence *:"Θ; Φ; {||}; GNil; Δ ⊨ AS_assert c [v]s ← τ" by auto
have "Θ; Φ; {||}; GNil; Δ ⊨ [v]s ← τ" using check_assert_s * by metis
thus ?case using elim config_typeI by blast
next
case (reduce_assert2I Φ δ s δ' s' c)
hence elim: "Θ; Φ; {||}; GNil; Δ ⊨ AS_assert c s ← τ ∧
Θ ⊨ δ ∼ Δ ∧ (∀fd∈set Φ. check_fundef Θ Φ fd)"
using config_type_elims by metis
hence *:"Θ; Φ; {||}; GNil; Δ ⊨ AS_assert c s ← τ" by auto
have cv: "Θ; Φ; {||}; GNil; Δ ⊨ s ← τ ∧ Θ ; {||} ; GNil ⊨ c " using check_assert_s * by metis
hence "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ" using elim config_typeI by simp
then obtain Δ' where D: "Θ; Φ; Δ' ⊨ ⟨ δ' , s' ⟩ ← τ ∧ Δ ⊑ Δ'" using reduce_assert2I by metis
hence **:"Θ; Φ; {||}; GNil; Δ' ⊨ s' ← τ ∧ Θ ⊨ δ' ∼ Δ'" using config_type_elims by metis
obtain x::x where x:"atom x ♯ (Θ, Φ, ({||}::bv fset), GNil, Δ', c, τ, s')" using obtain_fresh by# SPDX--Identifier: GPL-2.0only
haveallthis isabout,it' to N.For information
show "atom x ♯ (Θ, Φ, {||}, GNil, Δ', c, τ, s')" using x by auto
have "Θ ; {||} ; GNil ⊨wf c" using * check_s_wf by auto
hence wfg:"Θ ; {||} ⊨wf (x, B_bool, c) #\<Gamma> GNil" using wfC_wfG wfB_boolI check_s_wf * fresh_GNil by auto
moreover have cs: "Θ; Φ; {||}; GNil; Δ' ⊨ s' ← τ" using ** by auto
ultimately show "Θ ; Φ ; {||} ; (x, B_bool, c) #\<Gamma> GNil ; Δ' ⊨ s' ← τ" using check_s_g_weakening(1)[OF cs _ wfg] toSet.simps by simp
show "Θ ; {||} ; GNil ⊨ c " using cv by auto
show "Θ ; {||} ; GNil ⊨wf Δ' " using check_s_wf ** by auto
qed
thus ?case using elim config_typeI D ** by metis
qed
lemma preservation_many:
assumes " Φ ⊨ ⟨δ, s⟩ ⟶* ⟨ δ' , s' ⟩"
shows "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ ==> ∃Δ'. Θ; Φ; Δ' ⊨ ⟨ δ' , s' ⟩ ← τ ∧ Δ ⊑ Δ'"
using assms proof(induct arbitrary: Δ rule: reduce_stmt_many.induct)
case (reduce_stmt_many_oneI Φ δ s δ' s')
then show ?case using preservation by simp
next
case (reduce_stmt_many_manyI Φ δ s δ' s' δ'' s'')
then show ?case using preservation subset_trans by metis
qed
section ‹Progress›
text ‹We prove that a well typed program is either a value or we can make a step›
lemma check_let_op_infer:
assumes "Θ; Φ; {||}; Γ; Δ ⊨ LET x = (AE_op opp v1 v2) IN s ← τ" and "supp ( LET x = (AE_op opp v1 v2) IN s) ⊆ atom`fst`setD Δ"
shows "∃ z b c. Θ; Φ; {||}; Γ; Δ ⊨ (AE_op opp v1 v2) → {z:b|c}"
proof -
have xx: "Θ; Φ; {||}; Γ; Δ ⊨ LET x = (AE_op opp v1 v2) IN s ← τ" using assms by simp
then show ?thesis using check_s_elims(2)[OF xx] by meson
qed
lemma infer_pair:
assumes "Θ ; B; Γ ⊨ v → { z : B_pair b1 b2 | c }" and "supp v = {}"
obtains v1 and v2 where "v = V_pair v1 v2"
using assms proof(nominal_induct v rule: v.strong_induct)
case (V_lit x)
then show ?case by auto
next
case (V_var x)
then show ?case using v.supp supp_at_base by auto
next
case (V_pair x1a x2a)
then show ?case by auto
next
case (V_cons x1a x2a x3)
then show ?case by auto
next
case (V_consp x1a x2a x3 x4)
then show ?case by auto
qed
lemma progress_fst:
assumes "Θ; Φ; {||}; Γ; Δ ⊨ LET x = (AE_fst v) IN s ← τ" and "Θ ⊨ δ ∼ Δ" and
"supp (LET x = (AE_fst v) IN s) ⊆ atom`fst`setD Δ"
shows "∃δ' s'. Φ ⊨ ⟨ δ , LET x = (AE_fst v) IN s ⟩ ⟶ ⟨δ', s'⟩"
proof -
have *:"supp v = {}" using assms s_branch_s_branch_list.supp by auto
obtain z and b and c where "Θ; Φ; {||}; Γ; Δ ⊨ (AE_fst v ) → { z : b | c }"
using check_s_elims(2) using assms by meson
moreover obtain z' and b' and c' where "Θ ; {||} ; Γ ⊨ v → { z' : B_pair b b' | c' }"
using infer_e_elims(8) using calculation by auto
moreover then obtain v1 and v2 where "V_pair v1 v2 = v"
using * infer_pair by metis
ultimately show ?thesis using reduce_let_fstI assms by metis
qed
lemma progress_let:
assumes "Θ; Φ; {||}; Γ; Δ ⊨ LET x = e IN s ← τ" and "Θ ⊨ δ ∼ Δ" and
"supp (LET x = e IN s) ⊆ atom ` fst ` setD Δ" and "sble Θ Γ"
shows "∃δ' s'. Φ ⊨ ⟨ δ , LET x = e IN s⟩ ⟶ ⟨ δ' , s'⟩"
proof -
obtain z b c where *: "Θ; Φ; {||}; Γ; Δ ⊨ e → { z : b | c } " using check_s_elims(2)[OF assms(1)] by metis
have **: "supp e ⊆ atom ` fst ` setD Δ" using assms s_branch_s_branch_list.supp by auto
from * ** assms show ?thesis proof(nominal_induct "{ z : b | c }" rule: infer_e.strong_induct)
case (infer_e_valI Θ B Γ Δ Φ v)
then show ?case using reduce_stmt_elims reduce_let_valI by metis
next
case (infer_e_plusI Θ B Γ Δ Φ v1 z1 c1 v2 z2 c2 z3)
hence vf: "supp v1 = {} ∧ supp v2 = {}" by force
then obtain n1 and n2 where *: "v1 = V_lit (L_num n1) ∧ v2 = (V_lit (L_num n2))" using infer_int infer_e_plusI by metis
then show ?case using reduce_let_plusI * by metis
next
case (infer_e_leqI Θ B Γ Δ Φ v1 z1 c1 v2 z2 c2 z3)
hence vf: "supp v1 = {} ∧ supp v2 = {}" by force
then obtain n1 and n2 where *: "v1 = V_lit (L_num n1) ∧ v2 = (V_lit (L_num n2))" using infer_int infer_e_leqI by metis
then show ?case using reduce_let_leqI * by metis
next
case (infer_e_eqI Θ B Γ Δ Φ v1 z1 bb c1 v2 z2 c2 z3)
hence vf: "supp v1 = {} ∧ supp v2 = {}" by force
then obtain n1 and n2 where *: "v1 = V_lit n1 ∧ v2 = (V_lit n2)" using infer_lit infer_e_eqI by metis
then show ?case using reduce_let_eqI by blast
next
case (infer_e_appI Θ B Γ Δ Φ f x b c τ' s' v)
then show ?case using reduce_let_appI by metis
next
case (infer_e_appPI Θ B Γ Δ Φ b' f bv x b c τ' s' v)
then show ?case using reduce_let_appPI by metis
next
case (infer_e_fstI Θ B Γ Δ Φ v z' b2 c z)
hence "supp v = {}" by force
then obtain v1 and v2 where "v = V_pair v1 v2" using infer_e_fstI infer_pair by metis
then show ?case using reduce_let_fstI * by metis
next
case (infer_e_sndI Θ B Γ Δ Φ v z' b1 c z)
hence "supp v = {}" by force
then obtain v1 and v2 where "v = V_pair v1 v2" using infer_e_sndI infer_pair by metis
then show ?case using reduce_let_sndI * by metis
next
case (infer_e_lenI Θ B Γ Δ Φ v z' c za)
hence "supp v = {}" by force
then obtain bvec where "v = V_lit (L_bitvec bvec)" using infer_e_lenI infer_bitvec by metis
then show ?case using reduce_let_lenI * by metis
next
case (infer_e_mvarI Θ B Γ Φ Δ u)
hence "(u, { z : b | c }) ∈ setD Δ" using infer_e_elims(10) by meson
then obtain v where "(u,v) ∈ set δ" using infer_e_mvarI delta_sim_delta_lookup by meson
then show ?case using reduce_let_mvar by metis
next
case (infer_e_concatI Θ B Γ Δ Φ v1 z1 c1 v2 z2 c2 z3)
hence vf: "supp v1 = {} ∧ supp v2 = {}" by force
then obtain n1 and n2 where *: "v1 = V_lit (L_bitvec n1) ∧ v2 = (V_lit (L_bitvec n2))" using infer_bitvec infer_e_concatI by metis
then show ?case using reduce_let_concatI * by metis
next
case (infer_e_splitI Θ B Γ Δ Φ v1 z1 c1 v2 z2 z3)
hence vf: "supp v1 = {} ∧ supp v2 = {}" by force
then obtain n1 and n2 where *: "v1 = V_lit (L_bitvec n1) ∧ v2 = (V_lit (L_num n2))" using infer_bitvec infer_e_splitI check_int by metis
have "0 ≤ n2 ∧ n2 ≤ int (length n1)" using check_v_range[OF _ * ] infer_e_splitI by simp
then obtain bv1 and bv2 where "split n2 n1 (bv1 , bv2)" using obtain_split by metis
then show ?case using reduce_let_splitI * by metis
qed
qed
lemma check_css_lookup_branch_exist:
fixes s::s and cs::branch_s and css::branch_list and v::v
shows
"Θ; Φ; B; G; Δ ⊨ s ← τ ==> True" and
"check_branch_s Θ Φ {||} GNil Δ tid dc const v cs τ ==> True" and
"Θ; Φ; B; Γ; Δ; tid; dclist; v ⊨ css ← τ ==> (dc, t) ∈ set dclist ==>
∃x' s'. Some (AS_branch dc x' s') = lookup_branch dc css"
proof(nominal_induct τ and τ and τ rule: check_s_check_branch_s_check_branch_list.strong_induct)
case (check_branch_list_consI Θ Φ B Γ Δ tid cons const v cs τ dclist css)
then show ?case using lookup_branch.simps check_branch_list_finalI by force
next
case (check_branch_list_finalI Θ Φ B Γ Δ tid cons const v cs τ)
then show ?case using lookup_branch.simps check_branch_list_finalI by force
qed(auto+)
lemma progress_aux:
shows "Θ; Φ; B; Γ; Δ ⊨ s ← τ ==> B = {||} ==> sble Θ Γ ==> supp s ⊆ atom ` fst ` setD Δ ==> Θ ⊨ δ ∼ Δ ==>
(∃v. s = [v]s) ∨ (∃δ' s'. Φ ⊨ ⟨δ, s⟩ ⟶ ⟨δ', s'⟩)" and
"Θ; Φ; {||}; Γ; Δ; tid; dc; const; v2 ⊨ cs ← τ ==> supp cs = {} ==> True "
"Θ; Φ; {||}; Γ; Δ; tid; dclist; v2 ⊨ css ← τ ==> supp css = {} ==> True "
proof(induct rule: check_s_check_branch_s_check_branch_list.inducts)
case (check_valI Δ Θ Γ v τ' τ)
then show ?case by auto
next
case (check_letI x Θ Φ B Γ Δ e τ z s b c)
hence "Θ; Φ; {||}; Γ; Δ ⊨ AS_let x e s ← τ" using Typing.check_letI by meson
then show ?case using progress_let check_letI by metis
next
case (check_branch_s_branchI Θ B Γ Δ τ const x Φ tid cons v s)
then show ?case by auto
next
case (check_branch_list_consI Θ Φ B Γ Δ tid dclist v cs τ css)
then show ?case by auto
next
case (check_branch_list_finalI Θ Φ B Γ Δ tid dclist v cs τ)
then show ?case by auto
next
case (check_ifI z Θ Φ B Γ Δ v s1 s2 τ)
have "supp v = {}" using check_ifI s_branch_s_branch_list.supp by auto
hence "v = V_lit L_true ∨ v = V_lit L_false" using check_bool_options check_ifI by auto
then show ?case using reduce_if_falseI reduce_if_trueI check_ifI by meson
next
case (check_let2I x Θ Φ B G Δ t s1 τ s2 )
then consider " (∃v. s1 = AS_val v)" | "(∃δ' a. Φ ⊨ ⟨δ, s1⟩ ⟶ ⟨δ', a⟩)" by auto
then show ?case proof(cases)
case 1
then show ?thesis using reduce_let2_valI by fast
next
case 2
then show ?thesis using reduce_let2I check_let2I by meson
qed
next
case (check_varI u Θ Φ B Γ Δ τ' v τ s)
obtain uu::u where uf: "atom uu ♯ (u,δ,s) " using obtain_fresh by blast
obtain sa where " (uu ↔ u ) ∙ s = sa" by presburger
moreover have "atom uu ♯ s" using uf fresh_prod3 by auto
ultimately have "AS_var uu τ' v sa = AS_var u τ' v s" using s_branch_s_branch_list.eq_iff(7) Abs1_eq_iff(3)[of uu sa u s] by auto
moreover have "atom uu ♯ δ" using uf fresh_prod3 by auto
ultimately have "Φ ⊨ ⟨δ, AS_var u τ' v s⟩ ⟶ ⟨(uu, v) # δ, sa⟩"
using reduce_varI uf by metis
then show ?case by auto
next
case (check_assignI Δ u τ P G v z τ')
then show ?case using reduce_assignI by blast
next
case (check_whileI Θ Φ B Γ Δ s1 z s2 τ')
obtain x::x where "atom x ♯ (s1,s2)" using obtain_fresh by metis
moreover obtain z::x where "atom z ♯ x" using obtain_fresh by metis
ultimately show ?case using reduce_whileI by fast
next
case (check_seqI P Φ B G Δ s1 z s2 τ)
thus ?case proof(cases "∃v. s1 = AS_val v")
case True
then obtain v where v: "s1 = AS_val v" by blast
hence "supp v = {}" using check_seqI by auto
have "∃z1 c1. P; B; G ⊨ v → ({ z1 : B_unit | c1 })" proof -
obtain t where t:"P; B; G ⊨ v → t ∧ P; B ; G ⊨ t < ({ z : B_unit | TRUE })"
using v check_seqI(1) check_s_elims(1) by blast
obtain z1 and b1 and c1 where teq: "t = ({ z1 : b1 | c1 })" using obtain_fresh_z by meson
hence "b1 = B_unit" using subtype_eq_base t by meson
thus ?thesis using t teq by fast
qed
then obtain z1 and c1 where "P ; B ; G ⊨ v → ({ z1 : B_unit | c1 })" by auto
hence "v = V_lit L_unit" using infer_v_unit_form ‹supp v = {}› by simp
hence "s1 = AS_val (V_lit L_unit)" using v by auto
then show ?thesis using check_seqI reduce_seq1I by meson
next
case False
then show ?thesis using check_seqI reduce_seq2I
by (metis Un_subset_iff s_branch_s_branch_list.supp(9))
qed
next
case (check_caseI Θ Φ B Γ Δ tid dclist v cs τ z)
hence "supp v = {}" by auto
then obtain v' and dc and t::τ where v: "v = V_cons tid dc v' ∧ (dc, t) ∈ set dclist"
using check_v_tid_form check_caseI by metis
obtain z and b and c where teq: "t = ({ z : b | c })" using obtain_fresh_z by meson
moreover then obtain x' s' where "Some (AS_branch dc x' s') = lookup_branch dc cs" using v teq check_caseI check_css_lookup_branch_exist by metis
ultimately show ?case using reduce_caseI v check_caseI dc_of.cases by metis
next
case (check_assertI x Θ Φ B Γ Δ c τ s)
hence sps: "supp s ⊆ atom ` fst ` setD Δ" by auto
have "atom x ♯ c " using check_assertI by auto
have "atom x ♯ Γ" using check_assertI check_s_wf wfG_elims by metis
have "sble Θ ((x, B_bool, c) #\<Gamma> Γ)" proof -
obtain i' where i':" i' ⊨ Γ ∧ Θ; Γ ⊨ i'" using check_assertI sble_def by metis
obtain i::valuation where i:"i = i' ( x ↦ SBool True)" by auto
have "i ⊨ (x, B_bool, c) #\<Gamma> Γ" proof -
have "i' ⊨ c" using valid.simps i' check_assertI by metis
hence "i ⊨ c" using is_satis_weakening_x i ‹atom x ♯ c› by auto
moreover have "i ⊨ Γ" using is_satis_g_weakening_x i' i check_assertI ‹atom x ♯ Γ› by metis
ultimately show ?thesis using is_satis_g.simps i by auto
qed
moreover have "Θ ; ((x, B_bool, c) #\<Gamma> Γ) ⊨ i" proof(rule wfI_cons)
show ‹ i' ⊨ Γ › using i' by auto
show ‹ Θ ; Γ ⊨ i'› using i' by auto
show ‹i = i'(x ↦ SBool True)› using i by auto
show ‹ Θ ⊨ SBool True: B_bool› using wfRCV_BBoolI by auto
show ‹atom x ♯ Γ› using check_assertI check_s_wf wfG_elims by auto
qed
ultimately show ?thesis using sble_def by auto
qed
then consider "(∃v. s = [v]s)" | "(∃δ' a. Φ ⊨ ⟨δ, s⟩ ⟶ ⟨ δ', a⟩)" using check_assertI sps by metis
hence "(∃δ' a. Φ ⊨ ⟨δ, ASSERT c IN s⟩ ⟶ ⟨δ', a⟩)" proof(cases)
case 1
then show ?thesis using reduce_assert1I by metis
next
case 2
then show ?thesis using reduce_assert2I by metis
qed
thus ?case by auto
qed
lemma progress:
assumes "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ"
shows "(∃v. s = [v]s) ∨ (∃δ' s'. Φ ⊨ ⟨δ, s⟩ ⟶ ⟨δ', s'⟩)"
proof -
have "Θ; Φ; {||}; GNil; Δ ⊨ s ← τ" and "Θ ⊨ δ ∼ Δ"
using config_type_elims[OF assms(1)] by auto+
moreover hence "supp s ⊆ atom ` fst ` setD Δ" using check_s_wf wfS_supp by fastforce
moreover have "sble Θ GNil" using sble_def wfI_def is_satis_g.simps by simp
ultimately show ?thesis using progress_aux by blast
qed
section ‹Safety›
lemma safety_stmt:
assumes "Φ ⊨ ⟨δ, s⟩ ⟶* ⟨δ', s'⟩" and "Θ; Φ; Δ ⊨ ⟨δ, s⟩ ← τ"
shows "(∃v. s' = [v]s) ∨ (∃δ'' s''. Φ ⊨ ⟨δ', s'⟩ ⟶ ⟨δ'', s''⟩)"
using preservation_many progress assms by meson
lemma safety:
assumes "⊨ ⟨PROG Θ Φ G s⟩ ← τ" and "Φ ⊨ ⟨δ_of G, s⟩ ⟶* ⟨δ', s'⟩"
shows "(∃v. s' = [v]s) ∨ (∃δ'' s''. Φ ⊨ ⟨δ', s'⟩ ⟶ ⟨δ'', s''⟩)"
using assms config_type_prog_elims safety_stmt by metis
end
¤ Dauer der Verarbeitung: 0.68 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|