(* Title: HOL/Bali/State.thy ID: $Id: State.thy,v 1.11 2005/06/17 14:13:06 haftmann Exp $ Author: David von Oheimb *) header {* State for evaluation of Java expressions and statements *} theory State imports DeclConcepts begin text {* design issues: \begin{itemize} \item all kinds of objects (class instances, arrays, and class objects) are handeled via a general object abstraction \item the heap and the map for class objects are combined into a single table @{text "(recall (loc, obj) table × (qtname, obj) table ~= (loc + qtname, obj) table)"} \end{itemize} *} section "objects" datatype obj_tag = --{* tag for generic object *} CInst qtname --{* class instance *} | Arr ty int --{* array with component type and length *} --{* | CStat qtname the tag is irrelevant for a class object, i.e. the static fields of a class, since its type is given already by the reference to it (see below) *} types vn = "fspec + int" --{* variable name *} record obj = tag :: "obj_tag" --{* generalized object *} values :: "(vn, val) table" translations "fspec" <= (type) "vname × qtname" "vn" <= (type) "fspec + int" "obj" <= (type) "(|tag::obj_tag, values::vn => val option|))," "obj" <= (type) "(|tag::obj_tag, values::vn => val option,…::'a|))," constdefs the_Arr :: "obj option => ty × int × (vn, val) table" "the_Arr obj ≡ SOME (T,k,t). obj = Some (|tag=Arr T k,values=t|))," lemma the_Arr_Arr [simp]: "the_Arr (Some (|tag=Arr T k,values=cs|)),) = (T,k,cs)" apply (auto simp: the_Arr_def) done lemma the_Arr_Arr1 [simp,intro,dest]: "[|tag obj = Arr T k|] ==> the_Arr (Some obj) = (T,k,values obj)" apply (auto simp add: the_Arr_def) done constdefs upd_obj :: "vn => val => obj => obj" "upd_obj n v ≡ λ obj . obj (|values:=(values obj)(n\<mapsto>v)|))," lemma upd_obj_def2 [simp]: "upd_obj n v obj = obj (|values:=(values obj)(n\<mapsto>v)|))," apply (auto simp: upd_obj_def) done constdefs obj_ty :: "obj => ty" "obj_ty obj ≡ case tag obj of CInst C => Class C | Arr T k => T.[]" lemma obj_ty_eq [intro!]: "obj_ty (|tag=oi,values=x|)), = obj_ty (|tag=oi,values=y|))," by (simp add: obj_ty_def) lemma obj_ty_eq1 [intro!,dest]: "tag obj = tag obj' ==> obj_ty obj = obj_ty obj'" by (simp add: obj_ty_def) lemma obj_ty_cong [simp]: "obj_ty (obj (|values:=vs|)),) = obj_ty obj" by auto lemma obj_ty_CInst [simp]: "obj_ty (|tag=CInst C,values=vs|)), = Class C" by (simp add: obj_ty_def) lemma obj_ty_CInst1 [simp,intro!,dest]: "[|tag obj = CInst C|] ==> obj_ty obj = Class C" by (simp add: obj_ty_def) lemma obj_ty_Arr [simp]: "obj_ty (|tag=Arr T i,values=vs|)), = T.[]" by (simp add: obj_ty_def) lemma obj_ty_Arr1 [simp,intro!,dest]: "[|tag obj = Arr T i|] ==> obj_ty obj = T.[]" by (simp add: obj_ty_def) lemma obj_ty_widenD: "G\<turnstile>obj_ty obj\<preceq>RefT t ==> (∃C. tag obj = CInst C) ∨ (∃T k. tag obj = Arr T k)" apply (unfold obj_ty_def) apply (auto split add: obj_tag.split_asm) done constdefs obj_class :: "obj => qtname" "obj_class obj ≡ case tag obj of CInst C => C | Arr T k => Object" lemma obj_class_CInst [simp]: "obj_class (|tag=CInst C,values=vs|)), = C" by (auto simp: obj_class_def) lemma obj_class_CInst1 [simp,intro!,dest]: "tag obj = CInst C ==> obj_class obj = C" by (auto simp: obj_class_def) lemma obj_class_Arr [simp]: "obj_class (|tag=Arr T k,values=vs|)), = Object" by (auto simp: obj_class_def) lemma obj_class_Arr1 [simp,intro!,dest]: "tag obj = Arr T k ==> obj_class obj = Object" by (auto simp: obj_class_def) lemma obj_ty_obj_class: "G\<turnstile>obj_ty obj\<preceq> Class statC = G\<turnstile>obj_class obj \<preceq>C statC" apply (case_tac "tag obj") apply (auto simp add: obj_ty_def obj_class_def) apply (case_tac "statC = Object") apply (auto dest: widen_Array_Class) done section "object references" types oref = "loc + qtname" --{* generalized object reference *} syntax Heap :: "loc => oref" Stat :: "qtname => oref" translations "Heap" => "Inl" "Stat" => "Inr" "oref" <= (type) "loc + qtname" constdefs fields_table:: "prog => qtname => (fspec => field => bool) => (fspec, ty) table" "fields_table G C P ≡ option_map type o table_of (filter (split P) (DeclConcepts.fields G C))" lemma fields_table_SomeI: "[|table_of (DeclConcepts.fields G C) n = Some f; P n f|] ==> fields_table G C P n = Some (type f)" apply (unfold fields_table_def) apply clarsimp apply (rule exI) apply (rule conjI) apply (erule map_of_filter_in) apply assumption apply simp done (* unused *) lemma fields_table_SomeD': "fields_table G C P fn = Some T ==> ∃f. (fn,f)∈set(DeclConcepts.fields G C) ∧ type f = T" apply (unfold fields_table_def) apply clarsimp apply (drule map_of_SomeD) apply auto done lemma fields_table_SomeD: "[|fields_table G C P fn = Some T; unique (DeclConcepts.fields G C)|] ==> ∃f. table_of (DeclConcepts.fields G C) fn = Some f ∧ type f = T" apply (unfold fields_table_def) apply clarsimp apply (rule exI) apply (rule conjI) apply (erule table_of_filter_unique_SomeD) apply assumption apply simp done constdefs in_bounds :: "int => int => bool" ("(_/ in'_bounds _)" [50, 51] 50) "i in_bounds k ≡ 0 ≤ i ∧ i < k" arr_comps :: "'a => int => int => 'a option" "arr_comps T k ≡ λi. if i in_bounds k then Some T else None" var_tys :: "prog => obj_tag => oref => (vn, ty) table" "var_tys G oi r ≡ case r of Heap a => (case oi of CInst C => fields_table G C (λn f. ¬static f) (+) empty | Arr T k => empty (+) arr_comps T k) | Stat C => fields_table G C (λfn f. declclassf fn = C ∧ static f) (+) empty" lemma var_tys_Some_eq: "var_tys G oi r n = Some T = (case r of Inl a => (case oi of CInst C => (∃nt. n = Inl nt ∧ fields_table G C (λn f. ¬static f) nt = Some T) | Arr t k => (∃ i. n = Inr i ∧ i in_bounds k ∧ t = T)) | Inr C => (∃nt. n = Inl nt ∧ fields_table G C (λfn f. declclassf fn = C ∧ static f) nt = Some T))" apply (unfold var_tys_def arr_comps_def) apply (force split add: sum.split_asm sum.split obj_tag.split) done section "stores" types globs --{* global variables: heap and static variables *} = "(oref , obj) table" heap = "(loc , obj) table" (* locals = "(lname, val) table" *) (* defined in Value.thy local variables *) translations "globs" <= (type) "(oref , obj) table" "heap" <= (type) "(loc , obj) table" (* "locals" <= (type) "(lname, val) table" *) datatype st = (* pure state, i.e. contents of all variables *) st globs locals subsection "access" constdefs globs :: "st => globs" "globs ≡ st_case (λg l. g)" locals :: "st => locals" "locals ≡ st_case (λg l. l)" heap :: "st => heap" "heap s ≡ globs s o Heap" lemma globs_def2 [simp]: " globs (st g l) = g" by (simp add: globs_def) lemma locals_def2 [simp]: "locals (st g l) = l" by (simp add: locals_def) lemma heap_def2 [simp]: "heap s a=globs s (Heap a)" by (simp add: heap_def) syntax val_this :: "st => val" lookup_obj :: "st => val => obj" translations "val_this s" == "the (locals s This)" "lookup_obj s a'" == "the (heap s (the_Addr a'))" subsection "memory allocation" constdefs new_Addr :: "heap => loc option" "new_Addr h ≡ if (∀a. h a ≠ None) then None else Some (SOME a. h a = None)" lemma new_AddrD: "new_Addr h = Some a ==> h a = None" apply (unfold new_Addr_def) apply auto apply (case_tac "h (SOME a::loc. h a = None)") apply simp apply (fast intro: someI2) done lemma new_AddrD2: "new_Addr h = Some a ==> ∀b. h b ≠ None --> b ≠ a" apply (drule new_AddrD) apply auto done lemma new_Addr_SomeI: "h a = None ==> ∃b. new_Addr h = Some b ∧ h b = None" apply (unfold new_Addr_def) apply (frule not_Some_eq [THEN iffD2]) apply auto apply (drule not_Some_eq [THEN iffD2]) apply auto apply (fast intro!: someI2) done subsection "initialization" syntax init_vals :: "('a, ty) table => ('a, val) table" translations "init_vals vs" == "option_map default_val o vs" lemma init_arr_comps_base [simp]: "init_vals (arr_comps T 0) = empty" apply (unfold arr_comps_def in_bounds_def) apply (rule ext) apply auto done lemma init_arr_comps_step [simp]: "0 < j ==> init_vals (arr_comps T j ) = init_vals (arr_comps T (j - 1))(j - 1\<mapsto>default_val T)" apply (unfold arr_comps_def in_bounds_def) apply (rule ext) apply auto done subsection "update" constdefs gupd :: "oref => obj => st => st" ("gupd'(_\<mapsto>_')"[10,10]1000) "gupd r obj ≡ st_case (λg l. st (g(r\<mapsto>obj)) l)" lupd :: "lname => val => st => st" ("lupd'(_\<mapsto>_')"[10,10]1000) "lupd vn v ≡ st_case (λg l. st g (l(vn\<mapsto>v)))" upd_gobj :: "oref => vn => val => st => st" "upd_gobj r n v ≡ st_case (λg l. st (chg_map (upd_obj n v) r g) l)" set_locals :: "locals => st => st" "set_locals l ≡ st_case (λg l'. st g l)" init_obj :: "prog => obj_tag => oref => st => st" "init_obj G oi r ≡ gupd(r\<mapsto>(|tag=oi, values=init_vals (var_tys G oi r)|)),)" syntax init_class_obj :: "prog => qtname => st => st" translations "init_class_obj G C" == "init_obj G arbitrary (Inr C)" lemma gupd_def2 [simp]: "gupd(r\<mapsto>obj) (st g l) = st (g(r\<mapsto>obj)) l" apply (unfold gupd_def) apply (simp (no_asm)) done lemma lupd_def2 [simp]: "lupd(vn\<mapsto>v) (st g l) = st g (l(vn\<mapsto>v))" apply (unfold lupd_def) apply (simp (no_asm)) done lemma globs_gupd [simp]: "globs (gupd(r\<mapsto>obj) s) = globs s(r\<mapsto>obj)" apply (induct "s") by (simp add: gupd_def) lemma globs_lupd [simp]: "globs (lupd(vn\<mapsto>v ) s) = globs s" apply (induct "s") by (simp add: lupd_def) lemma locals_gupd [simp]: "locals (gupd(r\<mapsto>obj) s) = locals s" apply (induct "s") by (simp add: gupd_def) lemma locals_lupd [simp]: "locals (lupd(vn\<mapsto>v ) s) = locals s(vn\<mapsto>v )" apply (induct "s") by (simp add: lupd_def) lemma globs_upd_gobj_new [rule_format (no_asm), simp]: "globs s r = None --> globs (upd_gobj r n v s) = globs s" apply (unfold upd_gobj_def) apply (induct "s") apply auto done lemma globs_upd_gobj_upd [rule_format (no_asm), simp]: "globs s r=Some obj--> globs (upd_gobj r n v s) = globs s(r\<mapsto>upd_obj n v obj)" apply (unfold upd_gobj_def) apply (induct "s") apply auto done lemma locals_upd_gobj [simp]: "locals (upd_gobj r n v s) = locals s" apply (induct "s") by (simp add: upd_gobj_def) lemma globs_init_obj [simp]: "globs (init_obj G oi r s) t = (if t=r then Some (|tag=oi,values=init_vals (var_tys G oi r)|)), else globs s t)" apply (unfold init_obj_def) apply (simp (no_asm)) done lemma locals_init_obj [simp]: "locals (init_obj G oi r s) = locals s" by (simp add: init_obj_def) lemma surjective_st [simp]: "st (globs s) (locals s) = s" apply (induct "s") by auto lemma surjective_st_init_obj: "st (globs (init_obj G oi r s)) (locals s) = init_obj G oi r s" apply (subst locals_init_obj [THEN sym]) apply (rule surjective_st) done lemma heap_heap_upd [simp]: "heap (st (g(Inl a\<mapsto>obj)) l) = heap (st g l)(a\<mapsto>obj)" apply (rule ext) apply (simp (no_asm)) done lemma heap_stat_upd [simp]: "heap (st (g(Inr C\<mapsto>obj)) l) = heap (st g l)" apply (rule ext) apply (simp (no_asm)) done lemma heap_local_upd [simp]: "heap (st g (l(vn\<mapsto>v))) = heap (st g l)" apply (rule ext) apply (simp (no_asm)) done lemma heap_gupd_Heap [simp]: "heap (gupd(Heap a\<mapsto>obj) s) = heap s(a\<mapsto>obj)" apply (rule ext) apply (simp (no_asm)) done lemma heap_gupd_Stat [simp]: "heap (gupd(Stat C\<mapsto>obj) s) = heap s" apply (rule ext) apply (simp (no_asm)) done lemma heap_lupd [simp]: "heap (lupd(vn\<mapsto>v) s) = heap s" apply (rule ext) apply (simp (no_asm)) done lemma heap_upd_gobj_Stat [simp]: "heap (upd_gobj (Stat C) n v s) = heap s" apply (rule ext) apply (simp (no_asm)) apply (case_tac "globs s (Stat C)") apply auto done lemma set_locals_def2 [simp]: "set_locals l (st g l') = st g l" apply (unfold set_locals_def) apply (simp (no_asm)) done lemma set_locals_id [simp]: "set_locals (locals s) s = s" apply (unfold set_locals_def) apply (induct_tac "s") apply (simp (no_asm)) done lemma set_set_locals [simp]: "set_locals l (set_locals l' s) = set_locals l s" apply (unfold set_locals_def) apply (induct_tac "s") apply (simp (no_asm)) done lemma locals_set_locals [simp]: "locals (set_locals l s) = l" apply (unfold set_locals_def) apply (induct_tac "s") apply (simp (no_asm)) done lemma globs_set_locals [simp]: "globs (set_locals l s) = globs s" apply (unfold set_locals_def) apply (induct_tac "s") apply (simp (no_asm)) done lemma heap_set_locals [simp]: "heap (set_locals l s) = heap s" apply (unfold heap_def) apply (induct_tac "s") apply (simp (no_asm)) done section "abrupt completion" consts the_Xcpt :: "abrupt => xcpt" the_Jump :: "abrupt => jump" the_Loc :: "xcpt => loc" the_Std :: "xcpt => xname" primrec "the_Xcpt (Xcpt x) = x" primrec "the_Jump (Jump j) = j" primrec "the_Loc (Loc a) = a" primrec "the_Std (Std x) = x" constdefs abrupt_if :: "bool => abopt => abopt => abopt" "abrupt_if c x' x ≡ if c ∧ (x = None) then x' else x" lemma abrupt_if_True_None [simp]: "abrupt_if True x None = x" by (simp add: abrupt_if_def) lemma abrupt_if_True_not_None [simp]: "x ≠ None ==> abrupt_if True x y ≠ None" by (simp add: abrupt_if_def) lemma abrupt_if_False [simp]: "abrupt_if False x y = y" by (simp add: abrupt_if_def) lemma abrupt_if_Some [simp]: "abrupt_if c x (Some y) = Some y" by (simp add: abrupt_if_def) lemma abrupt_if_not_None [simp]: "y ≠ None ==> abrupt_if c x y = y" apply (simp add: abrupt_if_def) by auto lemma split_abrupt_if: "P (abrupt_if c x' x) = ((c ∧ x = None --> P x') ∧ (¬ (c ∧ x = None) --> P x))" apply (unfold abrupt_if_def) apply (split split_if) apply auto done syntax raise_if :: "bool => xname => abopt => abopt" np :: "val => abopt => abopt" check_neg:: "val => abopt => abopt" error_if :: "bool => error => abopt => abopt" translations "raise_if c xn" == "abrupt_if c (Some (Xcpt (Std xn)))" "np v" == "raise_if (v = Null) NullPointer" "check_neg i'" == "raise_if (the_Intg i'<0) NegArrSize" "error_if c e" == "abrupt_if c (Some (Error e))" lemma raise_if_None [simp]: "(raise_if c x y = None) = (¬c ∧ y = None)" apply (simp add: abrupt_if_def) by auto declare raise_if_None [THEN iffD1, dest!] lemma if_raise_if_None [simp]: "((if b then y else raise_if c x y) = None) = ((c --> b) ∧ y = None)" apply (simp add: abrupt_if_def) apply auto done lemma raise_if_SomeD [dest!]: "raise_if c x y = Some z ==> c ∧ z=(Xcpt (Std x)) ∧ y=None ∨ (y=Some z)" apply (case_tac y) apply (case_tac c) apply (simp add: abrupt_if_def) apply (simp add: abrupt_if_def) apply auto done lemma error_if_None [simp]: "(error_if c e y = None) = (¬c ∧ y = None)" apply (simp add: abrupt_if_def) by auto declare error_if_None [THEN iffD1, dest!] lemma if_error_if_None [simp]: "((if b then y else error_if c e y) = None) = ((c --> b) ∧ y = None)" apply (simp add: abrupt_if_def) apply auto done lemma error_if_SomeD [dest!]: "error_if c e y = Some z ==> c ∧ z=(Error e) ∧ y=None ∨ (y=Some z)" apply (case_tac y) apply (case_tac c) apply (simp add: abrupt_if_def) apply (simp add: abrupt_if_def) apply auto done constdefs absorb :: "jump => abopt => abopt" "absorb j a ≡ if a=Some (Jump j) then None else a" lemma absorb_SomeD [dest!]: "absorb j a = Some x ==> a = Some x" by (auto simp add: absorb_def) lemma absorb_same [simp]: "absorb j (Some (Jump j)) = None" by (auto simp add: absorb_def) lemma absorb_other [simp]: "a ≠ Some (Jump j) ==> absorb j a = a" by (auto simp add: absorb_def) lemma absorb_Some_NoneD: "absorb j (Some abr) = None ==> abr = Jump j" by (simp add: absorb_def) lemma absorb_Some_JumpD: "absorb j s = Some (Jump j') ==> j'≠j" by (simp add: absorb_def) section "full program state" types state = "abopt × st" --{* state including abruption information *} syntax Norm :: "st => state" abrupt :: "state => abopt" store :: "state => st" translations "Norm s" == "(None,s)" "abrupt" => "fst" "store" => "snd" "abopt" <= (type) "State.abrupt option" "abopt" <= (type) "abrupt option" "state" <= (type) "abopt × State.st" "state" <= (type) "abopt × st" lemma single_stateE: "∀Z. Z = (s::state) ==> False" apply (erule_tac x = "(Some k,y)" in all_dupE) apply (erule_tac x = "(None,y)" in allE) apply clarify done lemma state_not_single: "All (op = (x::state)) ==> R" apply (drule_tac x = "(if abrupt x = None then Some ?x else None,?y)" in spec) apply clarsimp done constdefs normal :: "state => bool" "normal ≡ λs. abrupt s = None" lemma normal_def2 [simp]: "normal s = (abrupt s = None)" apply (unfold normal_def) apply (simp (no_asm)) done constdefs heap_free :: "nat => state => bool" "heap_free n ≡ λs. atleast_free (heap (store s)) n" lemma heap_free_def2 [simp]: "heap_free n s = atleast_free (heap (store s)) n" apply (unfold heap_free_def) apply simp done subsection "update" constdefs abupd :: "(abopt => abopt) => state => state" "abupd f ≡ prod_fun f id" supd :: "(st => st) => state => state" "supd ≡ prod_fun id" lemma abupd_def2 [simp]: "abupd f (x,s) = (f x,s)" by (simp add: abupd_def) lemma abupd_abrupt_if_False [simp]: "!! s. abupd (abrupt_if False xo) s = s" by simp lemma supd_def2 [simp]: "supd f (x,s) = (x,f s)" by (simp add: supd_def) lemma supd_lupd [simp]: "!! s. supd (lupd vn v ) s = (abrupt s,lupd vn v (store s))" apply (simp (no_asm_simp) only: split_tupled_all) apply (simp (no_asm)) done lemma supd_gupd [simp]: "!! s. supd (gupd r obj) s = (abrupt s,gupd r obj (store s))" apply (simp (no_asm_simp) only: split_tupled_all) apply (simp (no_asm)) done lemma supd_init_obj [simp]: "supd (init_obj G oi r) s = (abrupt s,init_obj G oi r (store s))" apply (unfold init_obj_def) apply (simp (no_asm)) done lemma abupd_store_invariant [simp]: "store (abupd f s) = store s" by (cases s) simp lemma supd_abrupt_invariant [simp]: "abrupt (supd f s) = abrupt s" by (cases s) simp syntax set_lvars :: "locals => state => state" restore_lvars :: "state => state => state" translations "set_lvars l" == "supd (set_locals l)" "restore_lvars s' s" == "set_lvars (locals (store s')) s" lemma set_set_lvars [simp]: "!! s. set_lvars l (set_lvars l' s) = set_lvars l s" apply (simp (no_asm_simp) only: split_tupled_all) apply (simp (no_asm)) done lemma set_lvars_id [simp]: "!! s. set_lvars (locals (store s)) s = s" apply (simp (no_asm_simp) only: split_tupled_all) apply (simp (no_asm)) done section "initialisation test" constdefs inited :: "qtname => globs => bool" "inited C g ≡ g (Stat C) ≠ None" initd :: "qtname => state => bool" "initd C ≡ inited C o globs o store" lemma not_inited_empty [simp]: "¬inited C empty" apply (unfold inited_def) apply (simp (no_asm)) done lemma inited_gupdate [simp]: "inited C (g(r\<mapsto>obj)) = (inited C g ∨ r = Stat C)" apply (unfold inited_def) apply (auto split add: st.split) done lemma inited_init_class_obj [intro!]: "inited C (globs (init_class_obj G C s))" apply (unfold inited_def) apply (simp (no_asm)) done lemma not_initedD: "¬ inited C g ==> g (Stat C) = None" apply (unfold inited_def) apply (erule notnotD) done lemma initedD: "inited C g ==> ∃ obj. g (Stat C) = Some obj" apply (unfold inited_def) apply auto done lemma initd_def2 [simp]: "initd C s = inited C (globs (store s))" apply (unfold initd_def) apply (simp (no_asm)) done section {* @{text error_free} *} constdefs error_free:: "state => bool" "error_free s ≡ ¬ (∃ err. abrupt s = Some (Error err))" lemma error_free_Norm [simp,intro]: "error_free (Norm s)" by (simp add: error_free_def) lemma error_free_normal [simp,intro]: "normal s ==> error_free s" by (simp add: error_free_def) lemma error_free_Xcpt [simp]: "error_free (Some (Xcpt x),s)" by (simp add: error_free_def) lemma error_free_Jump [simp,intro]: "error_free (Some (Jump j),s)" by (simp add: error_free_def) lemma error_free_Error [simp]: "error_free (Some (Error e),s) = False" by (simp add: error_free_def) lemma error_free_Some [simp,intro]: "¬ (∃ err. x=Error err) ==> error_free ((Some x),s)" by (auto simp add: error_free_def) lemma error_free_abupd_absorb [simp,intro]: "error_free s ==> error_free (abupd (absorb j) s)" by (cases s) (auto simp add: error_free_def absorb_def split: split_if_asm) lemma error_free_absorb [simp,intro]: "error_free (a,s) ==> error_free (absorb j a, s)" by (auto simp add: error_free_def absorb_def split: split_if_asm) lemma error_free_abrupt_if [simp,intro]: "[|error_free s; ¬ (∃ err. x=Error err)|] ==> error_free (abupd (abrupt_if p (Some x)) s)" by (cases s) (auto simp add: abrupt_if_def split: split_if) lemma error_free_abrupt_if1 [simp,intro]: "[|error_free (a,s); ¬ (∃ err. x=Error err)|] ==> error_free (abrupt_if p (Some x) a, s)" by (auto simp add: abrupt_if_def split: split_if) lemma error_free_abrupt_if_Xcpt [simp,intro]: "error_free s ==> error_free (abupd (abrupt_if p (Some (Xcpt x))) s)" by simp lemma error_free_abrupt_if_Xcpt1 [simp,intro]: "error_free (a,s) ==> error_free (abrupt_if p (Some (Xcpt x)) a, s)" by simp lemma error_free_abrupt_if_Jump [simp,intro]: "error_free s ==> error_free (abupd (abrupt_if p (Some (Jump j))) s)" by simp lemma error_free_abrupt_if_Jump1 [simp,intro]: "error_free (a,s) ==> error_free (abrupt_if p (Some (Jump j)) a, s)" by simp lemma error_free_raise_if [simp,intro]: "error_free s ==> error_free (abupd (raise_if p x) s)" by simp lemma error_free_raise_if1 [simp,intro]: "error_free (a,s) ==> error_free ((raise_if p x a), s)" by simp lemma error_free_supd [simp,intro]: "error_free s ==> error_free (supd f s)" by (cases s) (simp add: error_free_def) lemma error_free_supd1 [simp,intro]: "error_free (a,s) ==> error_free (a,f s)" by (simp add: error_free_def) lemma error_free_set_lvars [simp,intro]: "error_free s ==> error_free ((set_lvars l) s)" by (cases s) simp lemma error_free_set_locals [simp,intro]: "error_free (x, s) ==> error_free (x, set_locals l s')" by (simp add: error_free_def) end
lemma the_Arr_Arr:
the_Arr (Some (| obj.tag = Arr T k, values = cs |)) = (T, k, cs)
lemma the_Arr_Arr1:
obj.tag obj = Arr T k ==> the_Arr (Some obj) = (T, k, values obj)
lemma upd_obj_def2:
upd_obj n v obj = obj(| values := values obj(n |-> v) |)
lemma obj_ty_eq:
obj_ty (| obj.tag = oi, values = x |) = obj_ty (| obj.tag = oi, values = y |)
lemma obj_ty_eq1:
obj.tag obj = obj.tag obj' ==> obj_ty obj = obj_ty obj'
lemma obj_ty_cong:
obj_ty (obj(| values := vs |)) = obj_ty obj
lemma obj_ty_CInst:
obj_ty (| obj.tag = CInst C, values = vs |) = Class C
lemma obj_ty_CInst1:
obj.tag obj = CInst C ==> obj_ty obj = Class C
lemma obj_ty_Arr:
obj_ty (| obj.tag = Arr T i, values = vs |) = T.[]
lemma obj_ty_Arr1:
obj.tag obj = Arr T i ==> obj_ty obj = T.[]
lemma obj_ty_widenD:
G|-obj_ty obj<=:RefT t ==> (∃C. obj.tag obj = CInst C) ∨ (∃T k. obj.tag obj = Arr T k)
lemma obj_class_CInst:
obj_class (| obj.tag = CInst C, values = vs |) = C
lemma obj_class_CInst1:
obj.tag obj = CInst C ==> obj_class obj = C
lemma obj_class_Arr:
obj_class (| obj.tag = Arr T k, values = vs |) = Object
lemma obj_class_Arr1:
obj.tag obj = Arr T k ==> obj_class obj = Object
lemma obj_ty_obj_class:
G|-obj_ty obj<=:Class statC = G|-obj_class obj<=:C statC
lemma fields_table_SomeI:
[| table_of (DeclConcepts.fields G C) n = Some f; P n f |] ==> fields_table G C P n = Some (type f)
lemma fields_table_SomeD':
fields_table G C P fn = Some T ==> ∃f. (fn, f) ∈ set (DeclConcepts.fields G C) ∧ type f = T
lemma fields_table_SomeD:
[| fields_table G C P fn = Some T; unique (DeclConcepts.fields G C) |] ==> ∃f. table_of (DeclConcepts.fields G C) fn = Some f ∧ type f = T
lemma var_tys_Some_eq:
(var_tys G oi r n = Some T) = (case r of Inl a => case oi of CInst C => ∃nt. n = Inl nt ∧ fields_table G C (%n f. ¬ static f) nt = Some T | Arr t k => ∃i. n = Inr i ∧ i in_bounds k ∧ t = T | Inr C => ∃nt. n = Inl nt ∧ fields_table G C (%fn f. declclassf fn = C ∧ static f) nt = Some T)
lemma globs_def2:
globs (st g l) = g
lemma locals_def2:
locals (st g l) = l
lemma heap_def2:
heap s a = globs s (Inl a)
lemma new_AddrD:
new_Addr h = Some a ==> h a = None
lemma new_AddrD2:
new_Addr h = Some a ==> ∀b. h b ≠ None --> b ≠ a
lemma new_Addr_SomeI:
h a = None ==> ∃b. new_Addr h = Some b ∧ h b = None
lemma init_arr_comps_base:
init_vals (arr_comps T 0) = empty
lemma init_arr_comps_step:
0 < j ==> init_vals (arr_comps T j) = init_vals (arr_comps T (j - 1))(j - 1 |-> default_val T)
lemma gupd_def2:
gupd(r\<mapsto>obj) (st g l) = st (g(r |-> obj)) l
lemma lupd_def2:
lupd(vn\<mapsto>v) (st g l) = st g (l(vn |-> v))
lemma globs_gupd:
globs (gupd(r\<mapsto>obj) s) = globs s(r |-> obj)
lemma globs_lupd:
globs (lupd(vn\<mapsto>v) s) = globs s
lemma locals_gupd:
locals (gupd(r\<mapsto>obj) s) = locals s
lemma locals_lupd:
locals (lupd(vn\<mapsto>v) s) = locals s(vn |-> v)
lemma globs_upd_gobj_new:
globs s r = None ==> globs (upd_gobj r n v s) = globs s
lemma globs_upd_gobj_upd:
globs s r = Some obj ==> globs (upd_gobj r n v s) = globs s(r |-> upd_obj n v obj)
lemma locals_upd_gobj:
locals (upd_gobj r n v s) = locals s
lemma globs_init_obj:
globs (init_obj G oi r s) t = (if t = r then Some (| obj.tag = oi, values = init_vals (var_tys G oi r) |) else globs s t)
lemma locals_init_obj:
locals (init_obj G oi r s) = locals s
lemma surjective_st:
st (globs s) (locals s) = s
lemma surjective_st_init_obj:
st (globs (init_obj G oi r s)) (locals s) = init_obj G oi r s
lemma heap_heap_upd:
heap (st (g(Inl a |-> obj)) l) = heap (st g l)(a |-> obj)
lemma heap_stat_upd:
heap (st (g(Inr C |-> obj)) l) = heap (st g l)
lemma heap_local_upd:
heap (st g (l(vn |-> v))) = heap (st g l)
lemma heap_gupd_Heap:
heap (gupd(Inl a\<mapsto>obj) s) = heap s(a |-> obj)
lemma heap_gupd_Stat:
heap (gupd(Inr C\<mapsto>obj) s) = heap s
lemma heap_lupd:
heap (lupd(vn\<mapsto>v) s) = heap s
lemma heap_upd_gobj_Stat:
heap (upd_gobj (Inr C) n v s) = heap s
lemma set_locals_def2:
set_locals l (st g l') = st g l
lemma set_locals_id:
set_locals (locals s) s = s
lemma set_set_locals:
set_locals l (set_locals l' s) = set_locals l s
lemma locals_set_locals:
locals (set_locals l s) = l
lemma globs_set_locals:
globs (set_locals l s) = globs s
lemma heap_set_locals:
heap (set_locals l s) = heap s
lemma abrupt_if_True_None:
abrupt_if True x None = x
lemma abrupt_if_True_not_None:
x ≠ None ==> abrupt_if True x y ≠ None
lemma abrupt_if_False:
abrupt_if False x y = y
lemma abrupt_if_Some:
abrupt_if c x (Some y) = Some y
lemma abrupt_if_not_None:
y ≠ None ==> abrupt_if c x y = y
lemma split_abrupt_if:
P (abrupt_if c x' x) = ((c ∧ x = None --> P x') ∧ (¬ (c ∧ x = None) --> P x))
lemma raise_if_None:
((raise_if c x) y = None) = (¬ c ∧ y = None)
lemma if_raise_if_None:
((if b then y else (raise_if c x) y) = None) = ((c --> b) ∧ y = None)
lemma raise_if_SomeD:
(raise_if c x) y = Some z ==> c ∧ z = Xcpt (Std x) ∧ y = None ∨ y = Some z
lemma error_if_None:
((error_if c e) y = None) = (¬ c ∧ y = None)
lemma if_error_if_None:
((if b then y else (error_if c e) y) = None) = ((c --> b) ∧ y = None)
lemma error_if_SomeD:
(error_if c e) y = Some z ==> c ∧ z = Error e ∧ y = None ∨ y = Some z
lemma absorb_SomeD:
absorb j a = Some x ==> a = Some x
lemma absorb_same:
absorb j (Some (Jump j)) = None
lemma absorb_other:
a ≠ Some (Jump j) ==> absorb j a = a
lemma absorb_Some_NoneD:
absorb j (Some abr) = None ==> abr = Jump j
lemma absorb_Some_JumpD:
absorb j s = Some (Jump j') ==> j' ≠ j
lemma single_stateE:
∀Z. Z = s ==> False
lemma state_not_single:
All (op = x) ==> R
lemma normal_def2:
normal s = (fst s = None)
lemma heap_free_def2:
heap_free n s = atleast_free (heap (snd s)) n
lemma abupd_def2:
abupd f (x, s) = (f x, s)
lemma abupd_abrupt_if_False:
abupd (abrupt_if False xo) s = s
lemma supd_def2:
supd f (x, s) = (x, f s)
lemma supd_lupd:
supd lupd(vn\<mapsto>v) s = (fst s, lupd(vn\<mapsto>v) (snd s))
lemma supd_gupd:
supd gupd(r\<mapsto>obj) s = (fst s, gupd(r\<mapsto>obj) (snd s))
lemma supd_init_obj:
supd (init_obj G oi r) s = (fst s, init_obj G oi r (snd s))
lemma abupd_store_invariant:
snd (abupd f s) = snd s
lemma supd_abrupt_invariant:
fst (supd f s) = fst s
lemma set_set_lvars:
(set_lvars l) ((set_lvars l') s) = (set_lvars l) s
lemma set_lvars_id:
(set_lvars (locals (snd s))) s = s
lemma not_inited_empty:
¬ inited C empty
lemma inited_gupdate:
inited C (g(r |-> obj)) = (inited C g ∨ r = Inr C)
lemma inited_init_class_obj:
inited C (globs ((init_class_obj G C) s))
lemma not_initedD:
¬ inited C g ==> g (Inr C) = None
lemma initedD:
inited C g ==> ∃obj. g (Inr C) = Some obj
lemma initd_def2:
initd C s = inited C (globs (snd s))
lemma error_free_Norm:
error_free (Norm s)
lemma error_free_normal:
normal s ==> error_free s
lemma error_free_Xcpt:
error_free (Some (Xcpt x), s)
lemma error_free_Jump:
error_free (Some (Jump j), s)
lemma error_free_Error:
error_free (Some (Error e), s) = False
lemma error_free_Some:
¬ (∃err. x = Error err) ==> error_free (Some x, s)
lemma error_free_abupd_absorb:
error_free s ==> error_free (abupd (absorb j) s)
lemma error_free_absorb:
error_free (a, s) ==> error_free (absorb j a, s)
lemma error_free_abrupt_if:
[| error_free s; ¬ (∃err. x = Error err) |] ==> error_free (abupd (abrupt_if p (Some x)) s)
lemma error_free_abrupt_if1:
[| error_free (a, s); ¬ (∃err. x = Error err) |] ==> error_free (abrupt_if p (Some x) a, s)
lemma error_free_abrupt_if_Xcpt:
error_free s ==> error_free (abupd (abrupt_if p (Some (Xcpt x))) s)
lemma error_free_abrupt_if_Xcpt1:
error_free (a, s) ==> error_free (abrupt_if p (Some (Xcpt x)) a, s)
lemma error_free_abrupt_if_Jump:
error_free s ==> error_free (abupd (abrupt_if p (Some (Jump j))) s)
lemma error_free_abrupt_if_Jump1:
error_free (a, s) ==> error_free (abrupt_if p (Some (Jump j)) a, s)
lemma error_free_raise_if:
error_free s ==> error_free (abupd (raise_if p x) s)
lemma error_free_raise_if1:
error_free (a, s) ==> error_free ((raise_if p x) a, s)
lemma error_free_supd:
error_free s ==> error_free (supd f s)
lemma error_free_supd1:
error_free (a, s) ==> error_free (a, f s)
lemma error_free_set_lvars:
error_free s ==> error_free ((set_lvars l) s)
lemma error_free_set_locals:
error_free (x, s) ==> error_free (x, set_locals l s')