theory Sorted_Algebra
imports
F_Algebra
begin
type_synonym ('f,'v,'t) exp = "('f,'v ×'t) term"
consts rename_vars :: "('a ⇒ 'b) ⇒ 'c ⇒ 'd"
definition rename_vars_exp :: "('v ⇒ 'w) ⇒ ('f,'v,'t) exp ⇒ ('f,'w,'t) exp" where
"rename_vars_exp r = map_term id (map_prod r id)"
adhoc_overloading rename_vars rename_vars_exp
lemma rename_vars_exp_simps[simp]:
"rename_vars_exp r (Var (x,ty)) = Var (r x, ty)"
"rename_vars_exp r (Fun f ts) = Fun f (map (rename_vars_exp r) ts)"
by (auto simp: rename_vars_exp_def)
lemma rename_vars_exp_comp[simp]:
"rename_vars f (rename_vars g (t::(_,_,_) exp)) = rename_vars (f ∘ g) t"
by (induct t, auto)
lemma vars_term_rename_vars[simp]: "vars_term (rename_vars f t) = map_prod f id ` vars_term t" by (induct t, auto)
lemma rename_vars_exp_id[THEN ext, simp]: "rename_vars id (t :: ('f,'v,'t) exp) = t"
proof (induct t)
case (Var x)
then show ?case by (cases x, auto)
next
case (Fun f ts)
then show ?case by (auto intro: map_idI)
qed
locale pre_sorted_algebra = algebra I
for I :: "'f ⇒ 'a list ⇒ 'a"
and type_of_fun :: "'f ⇒ 't list × 't"
and Values_of_type :: "'t ⇒ 'a set"
and type_fixer :: "('f×'t×'a) itself"
begin
abbreviation type_of_var :: "'v × 't ⇒ 't" where "type_of_var ≡ snd"
definition "assignment α ≡ ∀x. α x ∈ Values_of_type (type_of_var x)"
abbreviation return_type where "return_type f ≡ snd (type_of_fun f)"
abbreviation param_types where "param_types f ≡ fst (type_of_fun f)"
lemma assignmentI[intro]:
assumes "⋀x t. α (x,t) ∈ Values_of_type t" shows "assignment α"
using assms by (auto simp: assignment_def)
lemma assignmentD[dest]:
assumes "assignment α" shows "⋀x. α x ∈ Values_of_type (type_of_var x)" using assms by (auto simp: assignment_def)
lemma assignmentE[elim]:
assumes "assignment α" and "(⋀x. α x ∈ Values_of_type (type_of_var x)) ⟹ thesis" shows thesis
using assms by (auto simp: assignment_def)
fun has_type (infix ":⇩f" 60) where
"Var v :⇩f ty ⟷ type_of_var v = ty"
| "Fun f es :⇩f ty ⟷
(ty = return_type f ∧ length es = length (param_types f) ∧ (∀i < length es. es ! i :⇩f param_types f ! i))"
notation has_type (infix ":⇩f" 60)
abbreviation "expression e ≡ ∃ty. e :⇩f ty"
lemma map_term_has_type:
assumes "⋀x. x ∈ vars_term e ⟹ type_of_var (r x) = type_of_var x"
and "⋀f. f ∈ funs_term e ⟹ type_of_fun (rf f) = type_of_fun f"
shows "map_term rf r e :⇩f ty ⟷ e :⇩f ty"
proof-
{ fix X F
assume X: "⋀x. x ∈ X ⟹ type_of_var (r x) = type_of_var x"
and F: "⋀f. f ∈ F ⟹ type_of_fun (rf f) = type_of_fun f"
have "vars_term e ⊆ X ⟹ funs_term e ⊆ F ⟹ ?thesis"
proof (induct e arbitrary: ty)
case (Var x)
then show ?case using X by auto
next
case (Fun f es)
show ?case
proof (cases "type_of_fun f")
case (Pair tys ty')
moreover {
fix i assume i: "i < length es" "length es = length tys"
from Fun X F have "e ∈ set es ⟹ vars_term e ⊆ X ∧ funs_term e ⊆ F" for e by auto
with i have "vars_term (es!i) ⊆ X" "funs_term (es!i) ⊆ F" by auto
with Fun(1)[OF _ this, of "tys!i"] i Pair Fun
have "map_term rf r (es ! i) :⇩f tys ! i = es ! i :⇩f tys ! i" by auto
}
moreover from Fun F have "type_of_fun (rf f) = type_of_fun f" by auto
ultimately show ?thesis by auto
qed
qed
}
from this[OF assms] show ?thesis by auto
qed
lemma rename_vars_has_type[simp]: "rename_vars r e :⇩f ty ⟷ e :⇩f ty"
by (unfold rename_vars_exp_def, intro map_term_has_type, auto)
context
fixes α :: "'v × 't ⇒ 'a" and β :: "'w × 't ⇒ 'a" and r :: "'v ⇒ 'w"
assumes r: "⋀ x t. α (x,t) = β (r x, t)"
begin
lemma eval_rename_vars: "⟦rename_vars r a⟧ β = ⟦a⟧ α"
proof (induct a)
case (Var x)
show ?case by (cases x, auto simp: rename_vars_exp_def r)
next
case (Fun f ts)
then show ?case by (auto intro: arg_cong[of _ _ "I f"])
qed
lemma assignment_rename_vars: "assignment β ⟹ assignment α"
unfolding assignment_def using r by auto
end
end
locale sorted_algebra = pre_sorted_algebra +
assumes well_typed:
"⋀f ds. length ds = length (param_types f) ⟹
(⋀i. i < length ds ⟹ ds!i ∈ Values_of_type (param_types f ! i)) ⟹ I f ds ∈ Values_of_type (return_type f)"
and consistent: "⋀ty. Values_of_type ty ≠ {}"
begin
lemma eval_types:
assumes "assignment α" and "x :⇩f ty" shows "⟦x⟧ α ∈ Values_of_type ty"
using assms by (induct x arbitrary: ty, insert well_typed, auto)
end
end