Theory Milner_Tofte
section ‹Milner-Tofte: Co-induction in Relational Semantics›
theory Milner_Tofte
imports Main
begin
typedecl Const
typedecl ExVar
typedecl TyConst
datatype Ex =
e_const (e_const_fst: Const)
| e_var ExVar
| e_fn ExVar Ex ("fn _ => _" [0,51] 1000)
| e_fix ExVar ExVar Ex ("fix _ ( _ ) = _" [0,51,51] 1000)
| e_app Ex Ex ("_ @@ _" [51,51] 1000)
datatype Ty =
t_const TyConst
| t_fun Ty Ty ("_ -> _" [51,51] 1000)
datatype 'a genClos =
clos_mk ExVar Ex "ExVar ⇀ 'a" ("⟨_ , _ , _⟩" [0,0,0] 1000)
codatatype Val =
v_const Const
| v_clos "Val genClos"
type_synonym Clos = "Val genClos"
type_synonym ValEnv = "ExVar ⇀ Val"
type_synonym TyEnv = "ExVar ⇀ Ty"
axiomatization
c_app :: "[Const, Const] => Const" and
isof :: "[Const, Ty] => bool" ("_ isof _" [36,36] 50) where
isof_app: "⟦c1 isof t1 -> t2; c2 isof t1⟧ ⟹ c_app c1 c2 isof t2"
text ‹The dynamic semantics is defined inductively by a set of inference
rules. These inference rules allows one to draw conclusions of the form ve
|- e ---> v, read the expression e evaluates to the value v in the value
environment ve. Therefore the relation _ |- _ ---> _ is defined in Isabelle
as the least fixpoint of the functor eval_fun below. From this definition
introduction rules and a strong elimination (induction) rule can be derived.›
inductive eval :: "[ValEnv, Ex, Val] => bool" ("_ ⊢ _ ---> _" [36,0,36] 50) where
eval_const: "ve ⊢ e_const c ---> v_const c"
| eval_var2: "ev ∈ dom ve ⟹ ve ⊢ e_var ev ---> the (ve ev)"
| eval_fn: "ve ⊢ fn ev => e ---> v_clos ⟨ev, e, ve⟩"
| eval_fix: "cl = ⟨ev1, e, ve(ev2 ↦ v_clos cl)⟩ ⟹ ve ⊢ fix ev2(ev1) = e ---> v_clos(cl)"
| eval_app1: "⟦ve ⊢ e1 ---> v_const c1; ve ⊢ e2 ---> v_const c2⟧ ⟹
ve ⊢ e1 @@ e2 ---> v_const (c_app c1 c2)"
| eval_app2: "⟦ve ⊢ e1 ---> v_clos ⟨xm, em, vem⟩; ve ⊢ e2 ---> v2; vem(xm ↦ v2) ⊢ em ---> v⟧ ⟹
ve ⊢ e1 @@ e2 ---> v"
declare eval.intros[intro]
text ‹The static semantics is defined in the same way as the dynamic
semantics. The relation te |- e ===> t express the expression e has the
type t in the type environment te.›
inductive elab :: "[TyEnv, Ex, Ty] => bool" ("_ ⊢ _ ===> _" [36,0,36] 50) where
elab_const: "c isof ty ⟹ te ⊢ e_const c ===> ty"
| elab_var: "x ∈ dom te ⟹ te ⊢ e_var x ===> the (te x)"
| elab_fn: "te(x ↦ ty1) ⊢ e ===> ty2 ⟹ te ⊢ fn x => e ===> ty1 -> ty2"
| elab_fix: "te(f ↦ ty1 -> ty2, x ↦ ty1) ⊢ e ===> ty2 ⟹ te ⊢ fix f x = e ===> ty1 -> ty2"
| elab_app: "⟦te ⊢ e1 ===> ty1 -> ty2; te ⊢ e2 ===> ty1⟧ ⟹ te ⊢ e1 @@ e2 ===> ty2"
declare elab.intros[intro]
inductive_cases elabE[elim!]:
"te ⊢ e_const(c) ===> ty"
"te ⊢ e_var(x) ===> ty"
"te ⊢ fn x => e ===> ty"
"te ⊢ fix f(x) = e ===> ty"
"te ⊢ e1 @@ e2 ===> ty"
abbreviation isof_env :: "[ValEnv,TyEnv] => bool" ("_ isofenv _") where
"ve isofenv te ≡ (dom(ve) = dom(te) ∧
(∀x. x ∈ dom ve ⟶ (∃c. the (ve x) = v_const(c) ∧ c isof the (te x))))"
coinductive hasty :: "[Val, Ty] => bool" ("_ hasty _" [36,36] 50) where
hasty_const: "c isof t ⟹ v_const c hasty t"
| hasty_clos: "⟦te ⊢ fn ev => e ===> t; dom(ve) = dom(te) ∧
(∀x. x ∈ dom ve --> the (ve x) hasty the (te x)); cl = ⟨ev,e,ve⟩⟧ ⟹ v_clos cl hasty t"
declare hasty.intros[intro]
inductive_cases hastyE[elim!]:
"v_const c hasty t"
"v_clos ⟨xm , em , evm⟩ hasty u -> t"
definition hasty_env :: "[ValEnv, TyEnv] => bool" ("_ hastyenv _ " [36,36] 35) where
[simp]: "ve hastyenv te ≡ (dom(ve) = dom(te) ∧
(∀x. x ∈ dom ve --> the (ve x) hasty the (te x)))"
theorem consistency: "⟦ve ⊢ e ---> v; ve hastyenv te; te ⊢ e ===> t⟧ ⟹ v hasty t"
proof (induct ve e v arbitrary: t te rule: eval.induct)
case (eval_fix cl x e ve f)
then show ?case
by coinduction
(auto 0 11 intro: exI[of _ "te(f ↦ _)"] exI[of _ x] exI[of _ e] exI[of _ "ve(f ↦ v_clos cl)"])
next
case (eval_app2 ve e1 xm em evm e2 v2 v)
then obtain u where "te ⊢ e1 ===> u -> t" "te ⊢ e2 ===> u" by auto
with eval_app2(2)[of te "u -> t"] eval_app2(4)[of te u] eval_app2(1,3,5,7) show ?case
by (auto 0 4 elim!: eval_app2(6)[rotated])
qed (auto 8 0 intro!: isof_app)
lemma basic_consistency_aux:
"ve isofenv te ⟹ ve hastyenv te"
using hasty_const hasty_env_def by force
theorem basic_consistency:
"⟦ve isofenv te; ve ⊢ e ---> v_const c; te ⊢ e ===> t⟧ ⟹ c isof t"
by (auto dest: consistency intro!: basic_consistency_aux)
end