theory BVExample imports"../JVM/JVMListExample" BVSpecTypeSafe BVExec "HOL-Library.Code_Target_Numeral" begin
text‹
This theory shows type correctness of the example program in section \ref{sec:JVMListExample} (p. \pageref{sec:JVMListExample}) by
explicitly providing a welltyping. It also shows that the start
state of the program conforms to the welltyping; hence type safe
execution is guaranteed. ›
text‹Abbreviations for definitions we will have to use often in the
below:› lemmas system_defs = SystemClasses_def ObjectC_def NullPointerC_def
OutOfMemoryC_def ClassCastC_def lemmas class_defs = list_class_def test_class_def
text‹These auxiliary proofs are for efficiency: class lookup,
relation, method and field lookup are computed only once: › lemma class_Object [simp]: "class E Object = Some (undefined, [],[])" by (simp add: class_def system_defs E_def)
lemma class_NullPointer [simp]: "class E NullPointer = Some (Object, [], [])" by (simp add: class_def system_defs E_def distinct_classes)
lemma class_OutOfMemory [simp]: "class E OutOfMemory = Some (Object, [], [])" by (simp add: class_def system_defs E_def distinct_classes)
lemma class_ClassCast [simp]: "class E ClassCast = Some (Object, [], [])" by (simp add: class_def system_defs E_def distinct_classes)
lemma class_list [simp]: "class E list_name = Some list_class" by (simp add: class_def system_defs E_def distinct_classes)
lemma class_test [simp]: "class E test_name = Some test_class" by (simp add: class_def system_defs E_def distinct_classes)
text‹The subclass releation spelled out:› lemma subcls1: "subcls1 E = {(list_name,Object), (test_name,Object), (NullPointer, Object), (ClassCast, Object), (OutOfMemory, Object)}" (*<*) apply (simp add: subcls1_def2) apply (simp add: class_defs system_defs E_def class_def) (* FIXME: cannot simply expand class names, since
inequality proofs on strings are too inefficient *) apply (auto simp: distinct_classes split!: if_splits) done (*>*)
text‹The subclass relation is acyclic; hence its converse is well founded:› lemma notin_rtrancl: "(a,b) ∈ r*==> a ≠ b ==> (∧y. (a,y) ∉ r) ==> False" by (auto elim: converse_rtranclE)
text‹
The program is structurally wellformed: › lemma wf_struct: "wf_prog (λG C mb. True) E" (is"wf_prog ?mb E") (*<*) proof - have"distinct_fst E" by (simp add: system_defs E_def class_defs distinct_classes) moreover have"set SystemClasses ⊆ set E"by (simp add: system_defs E_def) hence"wf_syscls E"by (rule wf_syscls) moreover have"wf_cdecl ?mb E ObjectC"by (simp add: wf_cdecl_def ObjectC_def) moreover have"wf_cdecl ?mb E NullPointerC" by (auto elim: notin_rtrancl
simp add: wf_cdecl_def distinct_classes NullPointerC_def subcls1) moreover have"wf_cdecl ?mb E ClassCastC" by (auto elim: notin_rtrancl
simp add: wf_cdecl_def distinct_classes ClassCastC_def subcls1) moreover have"wf_cdecl ?mb E OutOfMemoryC" by (auto elim: notin_rtrancl
simp add: wf_cdecl_def distinct_classes OutOfMemoryC_def subcls1) moreover have"wf_cdecl ?mb E (list_name, list_class)" apply (auto elim!: notin_rtrancl
simp add: wf_cdecl_def wf_fdecl_def list_class_def
wf_mdecl_def subcls1) apply (auto simp add: distinct_classes distinct_fields Method_def elim: Methods.cases) done moreover have"wf_cdecl ?mb E (test_name, test_class)" apply (auto elim!: notin_rtrancl
simp add: wf_cdecl_def wf_fdecl_def test_class_def
wf_mdecl_def subcls1) apply (auto simp add: distinct_classes distinct_fields Method_def elim: Methods.cases) done ultimately show ?thesis by (simp add: wf_prog_def E_def SystemClasses_def) qed (*>*)
subsection"Welltypings" text‹
We show welltypings of the methods @{term append_name} in class @{term list_name},
and @{term makelist_name} in class @{term test_name}: › lemmas eff_simps [simp] = eff_def norm_eff_def xcpt_eff_def (*declare app'Invoke [simp del]*)
definition phi_append :: tym (‹φa›) where "φa≡ map (λ(x,y). Some (x, map OK y)) [ ( [], [Class list_name, Class list_name]), ( [Class list_name], [Class list_name, Class list_name]), ( [Class list_name], [Class list_name, Class list_name]), ( [Class list_name, Class list_name], [Class list_name, Class list_name]), ( [Class list_name, Class list_name], [Class list_name, Class list_name]), ([NT, Class list_name, Class list_name], [Class list_name, Class list_name]), ( [Boolean, Class list_name], [Class list_name, Class list_name]),
( [Class Object], [Class list_name, Class list_name]), ( [], [Class list_name, Class list_name]), ( [Class list_name], [Class list_name, Class list_name]), ( [Class list_name, Class list_name], [Class list_name, Class list_name]), ( [], [Class list_name, Class list_name]), ( [Void], [Class list_name, Class list_name]),
( [Class list_name], [Class list_name, Class list_name]), ( [Class list_name, Class list_name], [Class list_name, Class list_name]), ( [Void], [Class list_name, Class list_name])]"
text‹
The next definition and three proof rules implement an algorithm to
enumarate natural numbers. The command ‹apply (elim pc_end pc_next pc_0›
transforms a goal of the form
@{prop [display] "pc < n ==> P pc"}
into a series of goals
@{prop [display] "P 0"}
@{prop [display] "P (Suc 0)"}
‹…›
@{prop [display] "P n"} › definition intervall :: "nat ==> nat ==> nat ==> bool" (‹_ ∈ [_, _')›) where "x ∈ [a, b) ≡ a ≤ x ∧ x < b"
lemma pc_0: "x < n ==> (x ∈ [0, n) ==> P x) ==> P x" by (simp add: intervall_def)
( [], [OK Clist, OK Clist, Err ]), ( [Clist], [OK Clist, OK Clist, Err ]), ( [], [OK Clist, OK Clist, OK Clist]), ( [Clist], [OK Clist, OK Clist, OK Clist]), ( [Integer, Clist], [OK Clist, OK Clist, OK Clist]),
( [], [OK Clist, OK Clist, OK Clist]), ( [Clist], [OK Clist, OK Clist, OK Clist]), ( [Clist, Clist], [OK Clist, OK Clist, OK Clist]), ( [Void], [OK Clist, OK Clist, OK Clist]), ( [], [OK Clist, OK Clist, OK Clist]), ( [Clist], [OK Clist, OK Clist, OK Clist]), ( [Clist, Clist], [OK Clist, OK Clist, OK Clist]), ( [Void], [OK Clist, OK Clist, OK Clist])]"
lemma types_makelist [simp]: "check_types E 3 (Suc (Suc (Suc 0))) (map OK φm)" (*<*) by (auto simp add: check_types_def phi_makelist_def JVM_states_unfold) (*>*)
lemma wf_md'E: "[ wf_prog wf_md P; ∧C S fs ms m.[(C,S,fs,ms) ∈ set P; m ∈ set ms]==> wf_md' P C m ] ==> wf_prog wf_md' P" (*<*) apply (simp add: wf_prog_def) apply auto apply (simp add: wf_cdecl_def wf_mdecl_def) apply fastforce done (*>*)
text‹The whole program is welltyped:› definition Phi :: tyP (‹Φ›) where "Φ C mn ≡ if C = test_name ∧ mn = makelist_name then φm else if C = list_name ∧ mn = append_name then φa else []"
subsection"Example for code generation: inferring method types"
definition test_kil :: "jvm_prog ==> cname ==> ty list ==> ty ==> nat ==> nat ==> ex_table ==> instr list ==> tyi' err list" where "test_kil G C pTs rT mxs mxl et instr ≡ (let first = Some ([],(OK (Class C))#(map OK pTs)@(replicate mxl Err)); start = OK first#(replicate (size instr - 1) (OK None)) in kiljvm G mxs (1+size pTs+mxl) rT instr et start)"
lemma [code]: "unstables r step ss = fold (λp A. if ¬stable r step ss p then insert p A else A) [0..<size ss] {}" proof - have"unstables r step ss = (UN p:{..<size ss}. if ¬stable r step ss p then {p} else {})" by (auto simp: unstables_def) alsohave"∧f. (UN p:{..<size ss}. f p) = Union (set (map f [0..<size ss]))"by auto alsonote Sup_set_fold alsonote fold_map alsohave"(∪) ∘ (λp. if ¬ stable r step ss p then {p} else {}) = (λp A. if ¬stable r step ss p then insert p A else A)" by(auto simp add: fun_eq_iff) finallyshow ?thesis . qed
text‹This code setup is just a demonstration and \emph{not} sound!›
notepad begin have"some_elem (set [False, True]) = False"by eval moreoverhave"some_elem (set [True, False]) = True"by eval ultimatelyhave False by (simp add: some_elem_def) end
lemma [code]: "iter f step ss w = while (λ(ss, w). ¬ Set.is_empty w) (λ(ss, w). let p = some_elem w in propa f (step p (ss ! p)) ss (w - {p})) (ss, w)" by (simp add: iter_def)
lemma JVM_sup_unfold [code]: "JVM_SemiType.sup S m n = lift2 (Opt.sup (Product.sup (Listn.sup (SemiType.sup S)) (λx y. OK (map2 (lift2 (SemiType.sup S)) x y))))" by (auto simp: JVM_SemiType.sup_def JVM_SemiType.sl_def Opt.esl_def Err.sl_def
stk_esl_def loc_sl_def Product.esl_def
Listn.sl_def upto_esl_def SemiType.esl_def Err.esl_def)
lemma [code]: "appi (Getfield F C, P, pc, mxs, Tr, (T#ST, LT)) = Predicate.holds (Predicate.bind (sees_field_i_i_i_o_i P C F C) (λTf. if P ⊨ T ≤ Class C then Predicate.single () else bot))" by (auto simp add: Predicate.holds_eq intro: sees_field_i_i_i_o_iI elim: sees_field_i_i_i_o_iE)
lemma [code]: "appi (Putfield F C, P, pc, mxs, Tr, (T1#T2#ST, LT)) = Predicate.holds (Predicate.bind (sees_field_i_i_i_o_i P C F C) (λTf. if P ⊨ T2≤(Class C) ∧ P ⊨ T1≤ Tf then Predicate.single () else bot))" by (auto simp add: Predicate.holds_eq simp del: eval_bind split: if_split_asm elim!: sees_field_i_i_i_o_iE Predicate.bindE intro: Predicate.bindI sees_field_i_i_i_o_iI)
lemma [code]: "appi (Invoke M n, P, pc, mxs, Tr, (ST,LT)) = (n < length ST ∧ (ST!n ≠ NT ⟶ (case ST!n of Class C ==> Predicate.holds (Predicate.bind (Method_i_i_i_o_o_o_o P C M) (λ(Ts, T, m, D). if P ⊨ rev (take n ST) [≤] Ts then Predicate.single () else bot)) | _ ==> False)))" by (fastforce simp add: Predicate.holds_eq simp del: eval_bind split: ty.split_asm if_split_asm intro: bindI Method_i_i_i_o_o_o_oI elim!: bindE Method_i_i_i_o_o_o_oE)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.