Theory AbstractTransform
theory AbstractTransform
imports Launchbury.Terms TransformTools
begin
locale AbstractAnalProp =
fixes PropApp :: "'a ⇒ 'a::cont_pt"
fixes PropLam :: "'a ⇒ 'a"
fixes AnalLet :: "heap ⇒ exp ⇒ 'a ⇒ 'b::cont_pt"
fixes PropLetBody :: "'b ⇒ 'a"
fixes PropLetHeap :: "'b⇒ var ⇒ 'a⇩⊥"
fixes PropIfScrut :: "'a ⇒ 'a"
assumes PropApp_eqvt: "π ∙ PropApp ≡ PropApp"
assumes PropLam_eqvt: "π ∙ PropLam ≡ PropLam"
assumes AnalLet_eqvt: "π ∙ AnalLet ≡ AnalLet"
assumes PropLetBody_eqvt: "π ∙ PropLetBody ≡ PropLetBody"
assumes PropLetHeap_eqvt: "π ∙ PropLetHeap ≡ PropLetHeap"
assumes PropIfScrut_eqvt: "π ∙ PropIfScrut ≡ PropIfScrut"
locale AbstractAnalPropSubst = AbstractAnalProp +
assumes AnalLet_subst: "x ∉ domA Γ ⟹ y ∉ domA Γ ⟹ AnalLet (Γ[x::h=y]) (e[x::=y]) a = AnalLet Γ e a"
locale AbstractTransform = AbstractAnalProp +
constrains AnalLet :: "heap ⇒ exp ⇒ 'a::pure_cont_pt ⇒ 'b::cont_pt"
fixes TransVar :: "'a ⇒ var ⇒ exp"
fixes TransApp :: "'a ⇒ exp ⇒ var ⇒ exp"
fixes TransLam :: "'a ⇒ var ⇒ exp ⇒ exp"
fixes TransLet :: "'b ⇒ heap ⇒ exp ⇒ exp"
assumes TransVar_eqvt: "π ∙ TransVar = TransVar"
assumes TransApp_eqvt: "π ∙ TransApp = TransApp"
assumes TransLam_eqvt: "π ∙ TransLam = TransLam"
assumes TransLet_eqvt: "π ∙ TransLet = TransLet"
assumes SuppTransLam: "supp (TransLam a v e) ⊆ supp e - supp v"
assumes SuppTransLet: "supp (TransLet b Γ e) ⊆ supp (Γ, e) - atom ` domA Γ"
begin
nominal_function transform where
"transform a (App e x) = TransApp a (transform (PropApp a) e) x"
| "transform a (Lam [x]. e) = TransLam a x (transform (PropLam a) e)"
| "transform a (Var x) = TransVar a x"
| "transform a (Let Γ e) = TransLet (AnalLet Γ e a)
(map_transform transform (PropLetHeap (AnalLet Γ e a)) Γ)
(transform (PropLetBody (AnalLet Γ e a)) e)"
| "transform a (Bool b) = (Bool b)"
| "transform a (scrut ? e1 : e2) = (transform (PropIfScrut a) scrut ? transform a e1 : transform a e2)"
proof goal_cases
case 1
note PropApp_eqvt[eqvt_raw] PropLam_eqvt[eqvt_raw] PropLetBody_eqvt[eqvt_raw] PropLetHeap_eqvt[eqvt_raw] AnalLet_eqvt[eqvt_raw] TransVar_eqvt[eqvt] TransApp_eqvt[eqvt] TransLam_eqvt[eqvt] TransLet_eqvt[eqvt]
show ?case
unfolding eqvt_def transform_graph_aux_def
apply rule
apply perm_simp
apply (rule refl)
done
next
case prems: (3 P x)
show ?case
proof (cases x)
fix a b
assume "x = (a, b)"
thus ?case
using prems
apply (cases b rule:Terms.exp_strong_exhaust)
apply auto
done
qed
next
case prems: (10 a x e a' x' e')
from prems(5)
have "a' = a" and "Lam [x]. e = Lam [x']. e'" by simp_all
from this(2)
show ?case
unfolding ‹a' = a›
proof(rule eqvt_lam_case)
fix π :: perm
have "supp (TransLam a x (transform_sumC (PropLam a, e))) ⊆ supp (Lam [x]. e)"
apply (rule subset_trans[OF SuppTransLam])
apply (auto simp add: exp_assn.supp supp_Pair supp_at_base pure_supp exp_assn.fsupp dest!: subsetD[OF supp_eqvt_at[OF prems(1)], rotated])
done
moreover
assume "supp π ♯* (Lam [x]. e)"
ultimately
have *: "supp π ♯* TransLam a x (transform_sumC (PropLam a, e))" by (auto simp add: fresh_star_def fresh_def)
note PropApp_eqvt[eqvt_raw] PropLam_eqvt[eqvt_raw] PropLetBody_eqvt[eqvt_raw] PropLetHeap_eqvt[eqvt_raw] TransVar_eqvt[eqvt] TransApp_eqvt[eqvt] TransLam_eqvt[eqvt] TransLet_eqvt[eqvt]
have "TransLam a (π ∙ x) (transform_sumC (PropLam a, π ∙ e))
= TransLam a (π ∙ x) (transform_sumC (π ∙ (PropLam a, e)))"
by perm_simp rule
also have "… = TransLam a (π ∙ x) (π ∙ transform_sumC (PropLam a, e))"
unfolding eqvt_at_apply'[OF prems(1)] ..
also have "… = π ∙ (TransLam a x (transform_sumC (PropLam a, e)))"
by simp
also have "… = TransLam a x (transform_sumC (PropLam a, e))"
by (rule perm_supp_eq[OF *])
finally show "TransLam a (π ∙ x) (transform_sumC (PropLam a, π ∙ e)) = TransLam a x (transform_sumC (PropLam a, e))" by simp
qed
next
case prems: (19 a as body a' as' body')
note PropApp_eqvt[eqvt_raw] PropLam_eqvt[eqvt_raw] PropLetBody_eqvt[eqvt_raw] AnalLet_eqvt[eqvt_raw] PropLetHeap_eqvt[eqvt_raw] TransVar_eqvt[eqvt] TransApp_eqvt[eqvt] TransLam_eqvt[eqvt] TransLet_eqvt[eqvt]
from supp_eqvt_at[OF prems(1)]
have "⋀ x e a. (x, e) ∈ set as ⟹ supp (transform_sumC (a, e)) ⊆ supp e"
by (auto simp add: exp_assn.fsupp supp_Pair pure_supp)
hence supp_map: "⋀ae. supp (map_transform (λx0 x1. transform_sumC (x0, x1)) ae as) ⊆ supp as"
by (rule supp_map_transform_step)
from prems(9)
have "a' = a" and "Terms.Let as body = Terms.Let as' body'" by simp_all
from this(2)
show ?case
unfolding ‹a' = a›
proof (rule eqvt_let_case)
have "supp (TransLet (AnalLet as body a) (map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet as body a)) as) (transform_sumC (PropLetBody (AnalLet as body a), body))) ⊆ supp (Let as body)"
by (auto simp add: Let_supp supp_Pair pure_supp exp_assn.fsupp
dest!: subsetD[OF supp_eqvt_at[OF prems(2)], rotated] subsetD[OF SuppTransLet] subsetD[OF supp_map])
moreover
fix π :: perm
assume "supp π ♯* Terms.Let as body"
ultimately
have *: "supp π ♯* TransLet (AnalLet as body a) (map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet as body a)) as) (transform_sumC (PropLetBody (AnalLet as body a), body))"
by (auto simp add: fresh_star_def fresh_def)
have "TransLet (AnalLet (π ∙ as) (π ∙ body) a) (map_transform (λx0 x1. (π ∙ transform_sumC) (x0, x1)) (PropLetHeap (AnalLet (π ∙ as) (π ∙ body) a)) (π ∙ as)) ((π ∙ transform_sumC) (PropLetBody (AnalLet (π ∙ as) (π ∙ body) a), π ∙ body)) =
π ∙ TransLet (AnalLet as body a) (map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet as body a)) as) (transform_sumC (PropLetBody (AnalLet as body a), body))"
by (simp del: Let_eq_iff Pair_eqvt add: eqvt_at_apply[OF prems(2)])
also have "… = TransLet (AnalLet as body a) (map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet as body a)) as) (transform_sumC (PropLetBody (AnalLet as body a), body))"
by (rule perm_supp_eq[OF *])
also
have "map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet (π ∙ as) (π ∙ body) a)) (π ∙ as)
= map_transform (λx xa. (π ∙ transform_sumC) (x, xa)) (PropLetHeap (AnalLet (π ∙ as) (π ∙ body) a)) (π ∙ as)"
apply (rule map_transform_fundef_cong[OF _ refl refl])
apply (subst (asm) set_eqvt[symmetric])
apply (subst (asm) mem_permute_set)
apply (auto simp add: permute_self dest: eqvt_at_apply''[OF prems(1)[where aa = "(- π ∙ a)" for a], where p = π, symmetric])
done
moreover
have "(π ∙ transform_sumC) (PropLetBody (AnalLet (π ∙ as) (π ∙ body) a), π ∙ body) = transform_sumC (PropLetBody (AnalLet (π ∙ as) (π ∙ body) a), π ∙ body)"
using eqvt_at_apply''[OF prems(2), where p = π] by perm_simp
ultimately
show "TransLet (AnalLet (π ∙ as) (π ∙ body) a) (map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet (π ∙ as) (π ∙ body) a)) (π ∙ as)) (transform_sumC (PropLetBody (AnalLet (π ∙ as) (π ∙ body) a), π ∙ body)) =
TransLet (AnalLet as body a) (map_transform (λx0 x1. transform_sumC (x0, x1)) (PropLetHeap (AnalLet as body a)) as) (transform_sumC (PropLetBody (AnalLet as body a), body))" by metis
qed
qed auto
nominal_termination by lexicographic_order
lemma supp_transform: "supp (transform a e) ⊆ supp e"
proof-
note PropApp_eqvt[eqvt_raw] PropLam_eqvt[eqvt_raw] PropLetBody_eqvt[eqvt_raw] AnalLet_eqvt[eqvt_raw] PropLetHeap_eqvt[eqvt_raw] TransVar_eqvt[eqvt] TransApp_eqvt[eqvt] TransLam_eqvt[eqvt] TransLet_eqvt[eqvt]
note transform.eqvt[eqvt]
show ?thesis
apply (rule supp_fun_app_eqvt)
apply (rule eqvtI)
apply perm_simp
apply (rule reflexive)
done
qed
lemma fv_transform: "fv (transform a e) ⊆ fv e"
unfolding fv_def by (auto dest: subsetD[OF supp_transform])
end
locale AbstractTransformSubst = AbstractTransform + AbstractAnalPropSubst +
assumes TransVar_subst: "(TransVar a v)[x ::= y] = (TransVar a v[x ::v= y])"
assumes TransApp_subst: "(TransApp a e v)[x ::= y] = (TransApp a e[x ::= y] v[x ::v= y])"
assumes TransLam_subst: "atom v ♯ (x,y) ⟹ (TransLam a v e)[x ::= y] = (TransLam a v[x ::v= y] e[x ::= y])"
assumes TransLet_subst: "atom ` domA Γ ♯* (x,y) ⟹ (TransLet b Γ e)[x ::= y] = (TransLet b Γ[x ::h= y] e[x ::= y])"
begin
lemma subst_transform: "(transform a e)[x ::= y] = transform a e[x ::= y]"
proof (nominal_induct e avoiding: x y arbitrary: a rule: exp_strong_induct_set)
case (Let Δ body x y)
hence *: "x ∉ domA Δ" "y ∉ domA Δ" by (auto simp add: fresh_star_def fresh_at_base)
hence "AnalLet Δ[x::h=y] body[x::=y] a = AnalLet Δ body a" by (rule AnalLet_subst)
with Let
show ?case
apply (auto simp add: fresh_star_Pair TransLet_subst simp del: Let_eq_iff)
apply (rule fun_cong[OF arg_cong[where f = "TransLet b" for b]])
apply (rule subst_map_transform)
apply simp
done
qed (simp_all add: TransVar_subst TransApp_subst TransLam_subst)
end
locale AbstractTransformBound = AbstractAnalProp + supp_bounded_transform +
constrains PropApp :: "'a ⇒ 'a::pure_cont_pt"
constrains PropLetHeap :: "'b::cont_pt ⇒ var ⇒ 'a⇩⊥"
constrains trans :: "'c::cont_pt ⇒ exp ⇒ exp"
fixes PropLetHeapTrans :: "'b⇒ var ⇒ 'c⇩⊥"
assumes PropLetHeapTrans_eqvt: "π ∙ PropLetHeapTrans = PropLetHeapTrans"
assumes TransBound_eqvt: "π ∙ trans = trans"
begin
sublocale AbstractTransform PropApp PropLam AnalLet PropLetBody PropLetHeap PropIfScrut
"(λ a. Var)"
"(λ a. App)"
"(λ a. Terms.Lam)"
"(λ b Γ e . Let (map_transform trans (PropLetHeapTrans b) Γ) e)"
proof goal_cases
case 1
note PropApp_eqvt[eqvt_raw] PropLam_eqvt[eqvt_raw] PropLetBody_eqvt[eqvt_raw] PropLetHeap_eqvt[eqvt_raw] PropIfScrut_eqvt[eqvt_raw]
AnalLet_eqvt[eqvt_raw] PropLetHeapTrans_eqvt[eqvt] TransBound_eqvt[eqvt]
show ?case
apply standard
apply ((perm_simp, rule)+)[4]
apply (auto simp add: exp_assn.supp supp_at_base)[1]
apply (auto simp add: Let_supp supp_Pair supp_at_base dest: subsetD[OF supp_map_transform])[1]
done
qed
lemma isLam_transform[simp]:
"isLam (transform a e) ⟷ isLam e"
by (induction e rule:isLam.induct) auto
lemma isVal_transform[simp]:
"isVal (transform a e) ⟷ isVal e"
by (induction e rule:isLam.induct) auto
end
locale AbstractTransformBoundSubst = AbstractAnalPropSubst + AbstractTransformBound +
assumes TransBound_subst: "(trans a e)[x::=y] = trans a e[x::=y]"
begin
sublocale AbstractTransformSubst PropApp PropLam AnalLet PropLetBody PropLetHeap PropIfScrut
"(λ a. Var)"
"(λ a. App)"
"(λ a. Terms.Lam)"
"(λ b Γ e . Let (map_transform trans (PropLetHeapTrans b) Γ) e)"
proof goal_cases
case 1
note PropApp_eqvt[eqvt_raw] PropLam_eqvt[eqvt_raw] PropLetBody_eqvt[eqvt_raw] PropLetHeap_eqvt[eqvt_raw] PropIfScrut_eqvt[eqvt_raw]
TransBound_eqvt[eqvt]
show ?case
apply standard
apply simp_all[3]
apply (simp del: Let_eq_iff)
apply (rule arg_cong[where f = "λ x. Let x y" for y])
apply (rule subst_map_transform)
apply (simp add: TransBound_subst)
done
qed
end
end