theory WellForm imports TypeRel SystemClasses begin
text‹\noindent This theory defines global well-formedness conditions
programs but does not look inside method bodies. Hence it works
both Jinja and JVM programs. Well-typing of expressions is defined
(in theory ‹WellType›).
Jinja does not have method overloading, its policy for method
is the classical one: \emph{covariant in the result type
contravariant in the argument types.} This means the result type
the overriding method becomes more specific, the argument types
more general. ›
definition wf_fdecl :: "'m prog ==> fdecl ==> bool" where "wf_fdecl P ≡ λ(F,T). is_type P T"
definition wf_mdecl :: "'m wf_mdecl_test ==> 'm wf_mdecl_test" where "wf_mdecl wf_md P C ≡ λ(M,Ts,T,mb). (∀T∈set Ts. is_type P T) ∧ is_type P T ∧ wf_md P C (M,Ts,T,mb)"
definition wf_cdecl :: "'m wf_mdecl_test ==> 'm prog ==> 'm cdecl ==> bool" where "wf_cdecl wf_md P ≡ λ(C,(D,fs,ms)). (∀f∈set fs. wf_fdecl P f) ∧ distinct_fst fs ∧ (∀m∈set ms. wf_mdecl wf_md P C m) ∧ distinct_fst ms ∧ (C ≠ Object ⟶ is_class P D ∧¬ P ⊨ D ⪯* C ∧ (∀(M,Ts,T,m)∈set ms. ∀D' Ts' T' m'. P ⊨ D sees M:Ts' → T' = m' in D' ⟶ P ⊨ Ts' [≤] Ts ∧ P ⊨ T ≤ T'))"
definition wf_syscls :: "'m prog ==> bool" where "wf_syscls P ≡ {Object} ∪ sys_xcpts ⊆ set(map fst P)"
definition wf_prog :: "'m wf_mdecl_test ==> 'm prog ==> bool" where "wf_prog wf_md P ≡ wf_syscls P ∧ (∀c ∈ set P. wf_cdecl wf_md P c) ∧ distinct_fst P"
subsection‹Well-formedness lemmas›
lemma class_wf: "[class P C = Some c; wf_prog wf_md P]==> wf_cdecl wf_md P (C,c)" (*<*)by (unfold wf_prog_def class_def) (fast dest: map_of_SomeD)(*>*)
lemma class_Object [simp]: "wf_prog wf_md P ==>∃C fs ms. class P Object = Some (C,fs,ms)" (*<*)by (unfold wf_prog_def wf_syscls_def class_def)
(auto simp: map_of_SomeI) (*>*)
lemma is_class_Object [simp]: "wf_prog wf_md P ==> is_class P Object" (*<*)by (simp add: is_class_def)(*>*) (* Unused lemmais_class_supclass: assumeswf:"wf_progwf_mdP"andsub:"P\<turnstile>C\<preceq>\<^sup>*D" shows"is_classPC\<Longrightarrow>is_classPD"
(*<*) using sub proof(induct) case step thenshow ?case by(auto simp:wf_cdecl_def is_class_def dest!:class_wf[OF _ wf] subcls1D) qed simp (*>*)
This is NOT true because P ⊨ NT ≤Class C for any Class C lemma is_type_suptype: "[ wf_prog p P; is_type P T; P ⊨ T ≤ T' ] ==> is_type P T'"
*)
lemma is_class_xcpt: "[ C ∈ sys_xcpts; wf_prog wf_md P ]==> is_class P C" (*<*) by (fastforce intro!: map_of_SomeI
simp add: wf_prog_def wf_syscls_def is_class_def class_def) (*>*)
lemma subcls1_wfD: assumes sub1: "P ⊨ C ≺1 D"and wf: "wf_prog wf_md P" shows"D ≠ C ∧ (D,C) ∉ (subcls1 P)+" (*<*) proof - obtain fs ms where"C ≠ Object"and cls: "class P C = ⌊(D, fs, ms)⌋" using subcls1D[OF sub1] by clarify thenshow ?thesis using wf class_wf[OF cls wf] r_into_trancl[OF sub1] by(force simp add: wf_cdecl_def reflcl_trancl [THEN sym]
simp del: reflcl_trancl) qed (*>*)
lemma wf_cdecl_supD: "[wf_cdecl wf_md P (C,D,r); C ≠ Object]==> is_class P D" (*<*)by (auto simp: wf_cdecl_def)(*>*)
lemma subcls_induct: "[ wf_prog wf_md P; ∧C. ∀D. (C,D) ∈ (subcls1 P)+⟶ Q D ==> Q C ]==> Q C" (*<*)
(is"?A ==> PROP ?P ==> _") proof - assume p: "PROP ?P" assume ?A thenhave wf: "wf_prog wf_md P"by assumption have wf':"wf (((subcls1 P)+)-1)"using wf_trancl[OF wf_subcls1[OF wf]] by(simp only: trancl_converse) show ?thesis using wf_induct[where a = C and P = Q, OF wf' p] by simp qed (*>*)
lemma subcls1_induct_aux: assumes"is_class P C"and wf: "wf_prog wf_md P"and QObj: "Q Object" shows "[∧C D fs ms. [ C ≠ Object; is_class P C; class P C = Some (D,fs,ms) ∧ wf_cdecl wf_md P (C,D,fs,ms) ∧ P ⊨ C ≺1 D ∧ is_class P D ∧ Q D]==> Q C ] ==> Q C" (*<*)
(is"PROP ?P ==> _") proof - assume p: "PROP ?P" have"class P C ≠ None ⟶ Q C" proof(induct rule: subcls_induct[OF wf]) case (1 C) have"class P C ≠ None ==> Q C" proof(cases "C = Object") case True thenshow ?thesis using QObj by fast next case False assume nNone: "class P C ≠ None" thenhave is_cls: "is_class P C"by(simp add: is_class_def) obtain D fs ms where cls: "class P C = ⌊(D, fs, ms)⌋"using nNone by safe alsohave wfC: "wf_cdecl wf_md P (C, D, fs, ms)"by(rule class_wf[OF cls wf]) moreoverhave D: "is_class P D"by(rule wf_cdecl_supD[OF wfC False]) moreoverhave"P ⊨ C ≺1 D"by(rule subcls1I[OF cls False]) moreoverhave"class P D ≠ None"using D by(simp add: is_class_def) ultimatelyshow ?thesis using1by (auto intro: p[OF False is_cls]) qed thenshow"class P C ≠ None ⟶ Q C"by simp qed thus ?thesis using assms by(unfold is_class_def) simp qed (*>*)
(* FIXME can't we prove this one directly?? *) lemma subcls1_induct [consumes 2, case_names Object Subcls]: "[ wf_prog wf_md P; is_class P C; Q Object; ∧C D. [C ≠ Object; P ⊨ C ≺1 D; is_class P D; Q D]==> Q C ] ==> Q C" (*<*)by (erule (2) subcls1_induct_aux) blast(*>*)
lemma subcls_C_Object: assumes"class": "is_class P C"and wf: "wf_prog wf_md P" shows"P ⊨ C ⪯* Object" (*<*) using wf "class" proof(induct rule: subcls1_induct) case Subcls thenshow ?caseby(simp add: converse_rtrancl_into_rtrancl) qed fast (*>*)
lemma is_type_pTs: assumes"wf_prog wf_md P"and"(C,S,fs,ms) ∈ set P"and"(M,Ts,T,m) ∈ set ms" shows"set Ts ⊆ types P" (*<*) proof from assms have"wf_mdecl wf_md P C (M,Ts,T,m)" by (unfold wf_prog_def wf_cdecl_def) auto hence"∀t ∈ set Ts. is_type P t"by (unfold wf_mdecl_def) auto moreoverfix t assume"t ∈ set Ts" ultimatelyhave"is_type P t"by blast thus"t ∈ types P" .. qed (*>*)
subsection‹Well-formedness and method lookup›
lemma sees_wf_mdecl: assumes wf: "wf_prog wf_md P"and sees: "P ⊨ C sees M:Ts→T = m in D" shows"wf_mdecl wf_md P D (M,Ts,T,m)" (*<*) using wf visible_method_exists[OF sees] by(fastforce simp:wf_cdecl_def dest!:class_wf dest:map_of_SomeD) (*>*)
lemma sees_method_mono [rule_format (no_asm)]: assumes sub: "P ⊨ C' ⪯* C"and wf: "wf_prog wf_md P" shows"∀D Ts T m. P ⊨ C sees M:Ts→T = m in D ⟶ (∃D' Ts' T' m'. P ⊨ C' sees M:Ts'→T' = m' in D' ∧ P ⊨ Ts [≤] Ts' ∧ P ⊨ T' ≤ T)" (*<*)
(is"∀D Ts T m. ?P C D Ts T m ⟶ ?Q C' D Ts T m") proof(rule disjE[OF rtranclD[OF sub]]) assume"C' = C" thenshow ?thesis using assms by fastforce next assume"C' ≠ C ∧ (C', C) ∈ (subcls1 P)+" thenhave neq: "C' ≠ C"and subcls1: "(C', C) ∈ (subcls1 P)+"by simp+ show ?thesis proof(induct rule: trancl_trans_induct[OF subcls1]) case (2 x y z) thenhave zy: "∧D Ts T m. ?P z D Ts T m ==> ?Q y D Ts T m"by blast have"∧D Ts T m. ?P z D Ts T m ==> ?Q x D Ts T m" proof - fix D Ts T m assume P: "?P z D Ts T m" thenshow"?Q x D Ts T m"using zy[OF P] 2(2) by(fast elim: widen_trans widens_trans) qed thenshow ?caseby blast next case (1 x y) have"∧D Ts T m. ?P y D Ts T m ==> ?Q x D Ts T m" proof - fix D Ts T m assume P: "?P y D Ts T m" thenobtain Mm where sees: "P ⊨ y sees_methods Mm"and
M: "Mm M = ⌊((Ts, T, m), D)⌋" by(clarsimp simp:Method_def) obtain fs ms where nObj: "x ≠ Object"and
cls: "class P x = ⌊(y, fs, ms)⌋" using subcls1D[OF 1] by clarsimp have x_meth: "P ⊨ x sees_methods Mm ++ (map_option (λm. (m, x)) ∘ map_of ms)" using sees_methods_rec[OF cls nObj sees] by simp show"?Q x D Ts T m"proof(cases "map_of ms M") case None thenhave"∃m'. P ⊨ x sees M : Ts→T = m' in D"using M x_meth by(fastforce simp add:Method_def map_add_def split:option.split) thenshow ?thesis by auto next case (Some a) thenobtain Ts' T' m' where a: "a = (Ts',T',m')"by(cases a) thenhave"(∃m' Mm. P ⊨ y sees_methods Mm ∧ Mm M = ⌊((Ts, T, m'), D)⌋) ⟶ P ⊨ Ts [≤] Ts' ∧ P ⊨ T' ≤ T" using nObj class_wf[OF cls wf] map_of_SomeD[OF Some] by(clarsimp simp: wf_cdecl_def Method_def) fast thenshow ?thesis using Some a sees M x_meth by(fastforce simp:Method_def map_add_def split:option.split) qed qed thenshow ?caseby simp qed qed (*>*)
lemma sees_method_mono2: "[ P ⊨ C' ⪯* C; wf_prog wf_md P; P ⊨ C sees M:Ts→T = m in D; P ⊨ C' sees M:Ts'→T' = m' in D' ] ==> P ⊨ Ts [≤] Ts' ∧ P ⊨ T' ≤ T" (*<*)by(blast dest:sees_method_mono sees_method_fun)(*>*)
lemma mdecls_visible: assumes wf: "wf_prog wf_md P"and"class": "is_class P C" shows"∧D fs ms. class P C = Some(D,fs,ms) ==>∃Mm. P ⊨ C sees_methods Mm ∧ (∀(M,Ts,T,m) ∈ set ms. Mm M = Some((Ts,T,m),C))" (*<*) using wf "class" proof (induct rule:subcls1_induct) case Object with wf have"distinct_fst ms" by (unfold class_def wf_prog_def wf_cdecl_def) (fastforce dest:map_of_SomeD) with Object show ?caseby(fastforce intro!: sees_methods_Object map_of_SomeI) next case Subcls with wf have"distinct_fst ms" by (unfold class_def wf_prog_def wf_cdecl_def) (fastforce dest:map_of_SomeD) with Subcls show ?case by(fastforce elim:sees_methods_rec dest:subcls1D map_of_SomeI
simp:is_class_def) qed (*>*)
lemma mdecl_visible: assumes wf: "wf_prog wf_md P"and C: "(C,S,fs,ms) ∈ set P"and m: "(M,Ts,T,m) ∈ set ms" shows"P ⊨ C sees M:Ts→T = m in C" (*<*) proof - from wf C have"class": "class P C = Some (S,fs,ms)" by (auto simp add: wf_prog_def class_def is_class_def intro: map_of_SomeI) from"class"have"is_class P C"by(auto simp:is_class_def) with assms "class"show ?thesis by(bestsimp simp:Method_def dest:mdecls_visible) qed (*>*)
lemma Call_lemma: assumes sees: "P ⊨ C sees M:Ts→T = m in D"and sub: "P ⊨ C' ⪯* C"and wf: "wf_prog wf_md P" shows"∃D' Ts' T' m'. P ⊨ C' sees M:Ts'→T' = m' in D' ∧ P ⊨ Ts [≤] Ts' ∧ P ⊨ T' ≤ T ∧ P ⊨ C' ⪯* D' ∧ is_type P T' ∧ (∀T∈set Ts'. is_type P T) ∧ wf_md P D' (M,Ts',T',m')" (*<*) using assms sees_method_mono[OF sub wf sees] by(fastforce intro:sees_method_decl_above dest:sees_wf_mdecl
simp: wf_mdecl_def) (*>*)
lemma wf_prog_lift: assumes wf: "wf_prog (λP C bd. A P C bd) P" and rule: "∧wf_md C M Ts C T m bd. wf_prog wf_md P ==> P ⊨ C sees M:Ts→T = m in C ==> set Ts ⊆ types P ==> bd = (M,Ts,T,m) ==> A P C bd ==> B P C bd" shows"wf_prog (λP C bd. B P C bd) P" (*<*) proof - have"∧c. c∈set P ==> wf_cdecl A P c ==> wf_cdecl B P c" proof - fix c assume"c∈set P"and"wf_cdecl A P c" thenshow"wf_cdecl B P c" using rule[OF wf mdecl_visible[OF wf] is_type_pTs[OF wf]] by (auto simp: wf_cdecl_def wf_mdecl_def) qed thenshow ?thesis using wf by (clarsimp simp: wf_prog_def) qed (*>*)
subsection‹Well-formedness and field lookup›
lemma wf_Fields_Ex: assumes wf: "wf_prog wf_md P"and"is_class P C" shows"∃FDTs. P ⊨ C has_fields FDTs" (*<*) using assms proof(induct rule:subcls1_induct) case Object thenshow ?caseusing class_Object[OF wf] by(blast intro:has_fields_Object) next case Subcls thenshow ?caseby(blast intro:has_fields_rec dest:subcls1D) qed (*>*)
lemma has_fields_types: "[ P ⊨ C has_fields FDTs; (FD,T) ∈ set FDTs; wf_prog wf_md P ]==> is_type P T" (*<*) proof(induct rule:Fields.induct) qed(fastforce dest!: class_wf simp: wf_cdecl_def wf_fdecl_def)+ (*>*)
lemma sees_field_is_type: "[ P ⊨ C sees F:T in D; wf_prog wf_md P ]==> is_type P T" (*<*) by(fastforce simp: sees_field_def
elim: has_fields_types map_of_SomeD[OF map_of_remap_SomeD]) (*>*)
lemma wf_syscls: "set SystemClasses ⊆ set P ==> wf_syscls P" (*<*) by (force simp add: image_def SystemClasses_def wf_syscls_def sys_xcpts_def
ObjectC_def NullPointerC_def ClassCastC_def OutOfMemoryC_def) (*>*)
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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.