(* Title: HOL/Bali/Decl.thy Author: David von Oheimb and Norbert Schirmer
*)
subsection \<open>Field, method, interface, and class declarations, whole Java programs \<close>
theory Decl importsTerm Table (** order is significant, because of clash for "var" **) begin
text\<open>
improvements: \begin{itemize} \item clarification and correction of some aspects of the package/access concept
(Also submitted as bug report to the Java Bug Database:
Bug Id: 4485402 and Bug Id: 4493343 \<^url>\<open>http://developer.java.sun.com/developer/bugParade/index.jshtml\<close>
) \end{itemize}
simplifications: \begin{itemize} \item the only field and method modifiers are static and the access modifiers \item no constructors, which may be simulated by new + suitable methods \item there is just one global initializer per class, which can simulate all
others
\item no throws clause \item a void method is replaced by one that returns Unit (of dummy type Void)
\item no interface fields
\item every class has an explicit superclass (unused for Object) \item the (standard) methods of Object and of standard exceptions are not
specified
text\<open>
We can define a linear order for the access modifiers. With Private yielding the
most restrictive access and public the most liberal access policy:
Private < Package < Protected < Public \<close>
instantiation acc_modi :: linorder begin
definition
less_acc_def: "a < b \<longleftrightarrow> (case a of
Private \<Rightarrow> (b=Package \<or> b=Protected \<or> b=Public)
| Package \<Rightarrow> (b=Protected \<or> b=Public)
| Protected \<Rightarrow> (b=Public)
| Public \<Rightarrow> False)"
definition
le_acc_def: "(a :: acc_modi) \ b \ a < b \ a = b"
instance proof fix x y z::acc_modi show"x < y \ x \ y \ \ y \ x" by (auto simp add: le_acc_def less_acc_def split: acc_modi.split) show"x \ x" \ \reflexivity\ by (auto simp add: le_acc_def) show"x \ y \ y \ z \ x \ z" \ \transitivity\ by (auto simp add: le_acc_def less_acc_def split: acc_modi.split) show"x = y"if"x \ y" "y \ x" \ \antisymmetry\ proof - have"\x y. x < (y::acc_modi) \ y < x \ False" by (auto simp add: less_acc_def split: acc_modi.split) with that show ?thesis by (unfold le_acc_def) iprover qed show"x \ y \ y \ x" by (auto simp add: less_acc_def le_acc_def split: acc_modi.split) qed
end
lemma acc_modi_top [simp]: "Public \ a \ a = Public" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_top1 [simp, intro!]: "a \ Public" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_le_Public: "a \ Public \ a=Private \ a = Package \ a=Protected \ a=Public" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_bottom: "a \ Private \ a = Private" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_Private_le: "Private \ a \ a=Private \ a = Package \ a=Protected \ a=Public" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_Package_le: "Package \ a \ a = Package \ a=Protected \ a=Public" by (auto simp add: le_acc_def less_acc_def split: acc_modi.split)
lemma acc_modi_le_Package: "a \ Package \ a=Private \ a = Package" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_Protected_le: "Protected \ a \ a=Protected \ a=Public" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
lemma acc_modi_le_Protected: "a \ Protected \ a=Private \ a = Package \ a = Protected" by (auto simp add: le_acc_def less_acc_def split: acc_modi.splits)
record field = member +
type :: ty translations
(type) "field" <= (type) "\access::acc_modi, static::bool, type::ty\"
(type) "field" <= (type) "\access::acc_modi, static::bool, type::ty,\::'a\"
definition
mhead :: "methd \ mhead" where"mhead m = \access=access m, static=static m, pars=pars m, resT=resT m\"
lemma access_mhead [simp]:"access (mhead m) = access m" by (simp add: mhead_def)
lemma static_mhead [simp]:"static (mhead m) = static m" by (simp add: mhead_def)
lemma pars_mhead [simp]:"pars (mhead m) = pars m" by (simp add: mhead_def)
lemma resT_mhead [simp]:"resT (mhead m) = resT m" by (simp add: mhead_def)
text\<open>To be able to talk uniformaly about field and method declarations we
introduce the notion of a member declaration (e.g. useful to define
accessiblity )\<close>
datatype memberdecl = fdecl fdecl | mdecl mdecl
datatype memberid = fid vname | mid sig
class has_memberid = fixes memberid :: "'a \ memberid"
instantiation memberdecl :: has_memberid begin
definition
memberdecl_memberid_def: "memberid m = (case m of
fdecl (vn,f) \<Rightarrow> fid vn
| mdecl (sig,m) \<Rightarrow> mid sig)"
abbreviation
iface :: "prog \ (qtname, iface) table" where"iface G I == table_of (ifaces G) I"
abbreviation "class" :: "prog \ (qtname, class) table" where"class G C == table_of (classes G) C"
abbreviation
is_iface :: "prog \ qtname \ bool" where"is_iface G I == iface G I \ None"
abbreviation
is_class :: "prog \ qtname \ bool" where"is_class G C == class G C \ None"
subsubsection "is type"
primrec is_type :: "prog \ ty \ bool" and isrtype :: "prog \ ref_ty \ bool" where "is_type G (PrimT pt) = True"
| "is_type G (RefT rt) = isrtype G rt"
| "isrtype G (NullT) = True"
| "isrtype G (IfaceT tn) = is_iface G tn"
| "isrtype G (ClassT tn) = is_class G tn"
| "isrtype G (ArrayT T ) = is_type G T"
lemma type_is_iface: "is_type G (Iface I) \ is_iface G I" by auto
lemma type_is_class: "is_type G (Class C) \ is_class G C" by auto
subsubsection "subinterface and subclass relation, in anticipation of TypeRel.thy"
notation (ASCII)
subcls1_syntax (\<open>_|-_<:C1_\<close> [71,71,71] 70) and
subclseq_syntax (\<open>_|-_<=:C _\<close>[71,71,71] 70) and
subcls_syntax (\<open>_|-_<:C _\<close>[71,71,71] 70)
lemma subint1I: "\iface G I = Some i; J \ set (isuperIfs i)\ \<Longrightarrow> (I,J) \<in> subint1 G" apply (simp add: subint1_def) done
lemma subcls1I:"\class G C = Some c; C \ Object\ \ (C,(super c)) \ subcls1 G" apply (simp add: subcls1_def) done
lemma subint1D: "(I,J)\subint1 G\ \i\iface G I: J\set (isuperIfs i)" by (simp add: subint1_def)
lemma subcls1D: "(C,D)\subcls1 G \ C\Object \ (\c. class G C = Some c \ (super c = D))" apply (simp add: subcls1_def) apply auto done
lemma subint1_def2: "subint1 G = (SIGMA I: {I. is_iface G I}. set (isuperIfs (the (iface G I))))" apply (unfold subint1_def) apply auto done
lemma subcls1_def2: "subcls1 G =
(SIGMA C: {C. is_class G C}. {D. C\<noteq>Object \<and> super (the(class G C))=D})" apply (unfold subcls1_def) apply auto done
lemma subcls_is_class: "\G\C \\<^sub>C D\ \ \ c. class G C = Some c" by (auto simp add: subcls1_def dest: tranclD)
lemma no_subcls1_Object:"G\Object\\<^sub>C1 D \ P" by (auto simp add: subcls1_def)
definition
ws_idecl :: "prog \ qtname \ qtname list \ bool" where"ws_idecl G I si = (\J\set si. is_iface G J \ (J,I)\(subint1 G)\<^sup>+)"
definition
ws_cdecl :: "prog \ qtname \ qtname \ bool" where"ws_cdecl G C sc = (C\Object \ is_class G sc \ (sc,C)\(subcls1 G)\<^sup>+)"
definition
ws_prog :: "prog \ bool" where "ws_prog G = ((\(I,i)\set (ifaces G). ws_idecl G I (isuperIfs i)) \
(\<forall>(C,c)\<in>set (classes G). ws_cdecl G C (super c)))"
lemma wf_subint1: "ws_prog G \ wf ((subint1 G)\)" by (auto intro: finite_acyclic_wf_converse finite_subint1 subint1_acyclic)
lemma wf_subcls1: "ws_prog G \ wf ((subcls1 G)\)" by (auto intro: finite_acyclic_wf_converse finite_subcls1 subcls1_acyclic)
lemma subint1_induct: "\ws_prog G; \x. \y. (x, y) \ subint1 G \ P y \ P x\ \ P a" apply (frule wf_subint1) apply (erule wf_induct) apply (simp (no_asm_use) only: converse_iff) apply blast done
lemma subcls1_induct [consumes 1]: "\ws_prog G; \x. \y. (x, y) \ subcls1 G \ P y \ P x\ \ P a" apply (frule wf_subcls1) apply (erule wf_induct) apply (simp (no_asm_use) only: converse_iff) apply blast done
lemma ws_subint1_induct: "\is_iface G I; ws_prog G; \I i. \iface G I = Some i \
(\<forall>J \<in> set (isuperIfs i). (I,J)\<in>subint1 G \<and> P J \<and> is_iface G J)\<rbrakk> \<Longrightarrow> P I \<rbrakk> \<Longrightarrow> P I" apply (erule rev_mp) apply (rule subint1_induct) apply assumption apply (simp (no_asm)) apply safe apply (blast dest: subint1I ws_prog_ideclD) done
lemma ws_subcls1_induct: "\is_class G C; ws_prog G; \<And>C c. \<lbrakk>class G C = Some c;
(C \<noteq> Object \<longrightarrow> (C,(super c))\<in>subcls1 G \<and>
P (super c) \<and> is_class G (super c))\<rbrakk> \<Longrightarrow> P C \<rbrakk> \<Longrightarrow> P C" apply (erule rev_mp) apply (rule subcls1_induct) apply assumption apply (simp (no_asm)) apply safe apply (fast dest: subcls1I ws_prog_cdeclD) done
lemma ws_class_induct [consumes 2, case_names Object Subcls]: "\class G C = Some c; ws_prog G; \<And> co. class G Object = Some co \<Longrightarrow> P Object; \<And> C c. \<lbrakk>class G C = Some c; C \<noteq> Object; P (super c)\<rbrakk> \<Longrightarrow> P C \<rbrakk> \<Longrightarrow> P C" proof - assume clsC: "class G C = Some c" and init: "\ co. class G Object = Some co \ P Object" and step: "\ C c. \class G C = Some c; C \ Object; P (super c)\ \ P C" assume ws: "ws_prog G" thenhave"is_class G C \ P C" proof (induct rule: subcls1_induct) fix C assume hyp:"\ S. G\C \\<^sub>C1 S \ is_class G S \ P S" and iscls:"is_class G C" show"P C" proof (cases "C=Object") case True with iscls init show"P C"by auto next case False with ws step hyp iscls show"P C"by (auto dest: subcls1I ws_prog_cdeclD) qed qed with clsC show ?thesis by simp qed
lemma ws_class_induct' [consumes 2, case_names Object Subcls]: "\is_class G C; ws_prog G; \<And> co. class G Object = Some co \<Longrightarrow> P Object; \<And> C c. \<lbrakk>class G C = Some c; C \<noteq> Object; P (super c)\<rbrakk> \<Longrightarrow> P C \<rbrakk> \<Longrightarrow> P C" by (auto intro: ws_class_induct)
lemma ws_class_induct'' [consumes 2, case_names Object Subcls]: "\class G C = Some c; ws_prog G; \<And> co. class G Object = Some co \<Longrightarrow> P Object co; \<And> C c sc. \<lbrakk>class G C = Some c; class G (super c) = Some sc;
C \<noteq> Object; P (super c) sc\<rbrakk> \<Longrightarrow> P C c \<rbrakk> \<Longrightarrow> P C c" proof - assume clsC: "class G C = Some c" and init: "\ co. class G Object = Some co \ P Object co" and step: "\ C c sc . \class G C = Some c; class G (super c) = Some sc;
C \<noteq> Object; P (super c) sc\<rbrakk> \<Longrightarrow> P C c" assume ws: "ws_prog G" thenhave"\ c. class G C = Some c\ P C c" proof (induct rule: subcls1_induct) fix C c assume hyp:"\ S. G\C \\<^sub>C1 S \ (\ s. class G S = Some s \ P S s)" and iscls:"class G C = Some c" show"P C c" proof (cases "C=Object") case True with iscls init show"P C c"by auto next case False with ws iscls obtain sc where
sc: "class G (super c) = Some sc" by (auto dest: ws_prog_cdeclD) from iscls False have"G\C \\<^sub>C1 (super c)" by (rule subcls1I) with False ws step hyp iscls sc show"P C c" by (auto) qed qed with clsC show"P C c"by auto qed
lemma ws_interface_induct [consumes 2, case_names Step]: assumes is_if_I: "is_iface G I"and
ws: "ws_prog G"and
hyp_sub: "\I i. \iface G I = Some i; \<forall> J \<in> set (isuperIfs i).
(I,J)\<in>subint1 G \<and> P J \<and> is_iface G J\<rbrakk> \<Longrightarrow> P I" shows"P I" proof - from is_if_I ws show"P I" proof (rule ws_subint1_induct) fix I i assume hyp: "iface G I = Some i \
(\<forall>J\<in>set (isuperIfs i). (I,J) \<in>subint1 G \<and> P J \<and> is_iface G J)" thenhave if_I: "iface G I = Some i" by blast show"P I" proof (cases "isuperIfs i") case Nil with if_I hyp_sub show"P I" by auto next case (Cons hd tl) with hyp if_I hyp_sub show"P I" by auto qed qed qed
subsubsection "general recursion operators for the interface and class hiearchies"
function iface_rec :: "prog \ qtname \ (qtname \ iface \ 'a set \ 'a) \ 'a" where
[simp del]: "iface_rec G I f =
(case iface G I of
None \<Rightarrow> undefined
| Some i \<Rightarrow> if ws_prog G then f I i
((\<lambda>J. iface_rec G J f)`set (isuperIfs i))
else undefined)" by auto termination by (relation "inv_image (same_fst ws_prog (\G. (subint1 G)\)) (%(x,y,z). (x,y))")
(auto simp: wf_subint1 subint1I wf_same_fst)
lemma iface_rec: "\iface G I = Some i; ws_prog G\ \
iface_rec G I f = f I i ((\<lambda>J. iface_rec G J f)`set (isuperIfs i))" apply (subst iface_rec.simps) apply simp done
function
class_rec :: "prog \ qtname \ 'a \ (qtname \ class \ 'a \ 'a) \ 'a" where
[simp del]: "class_rec G C t f =
(caseclass G C of
None \<Rightarrow> undefined
| Some c \<Rightarrow> if ws_prog G then f C c
(if C = Object then t
else class_rec G (super c) t f)
else undefined)"
by auto termination by (relation "inv_image (same_fst ws_prog (\G. (subcls1 G)\)) (%(x,y,z,w). (x,y))")
(auto simp: wf_subcls1 subcls1I wf_same_fst)
lemma class_rec: "\class G C = Some c; ws_prog G\ \
class_rec G C t f =
f C c (if C = Object then t else class_rec G (super c) t f)" apply (subst class_rec.simps) apply simp done
definition
imethds :: "prog \ qtname \ (sig,qtname \ mhead) tables" where \<comment> \<open>methods of an interface, with overriding and inheritance, cf. 9.2\<close> "imethds G I = iface_rec G I
(\<lambda>I i ts. (Un_tables ts) \<oplus>\<oplus>
(set_option \<circ> table_of (map (\<lambda>(s,m). (s,I,m)) (imethods i))))"
end
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet)
¤
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 ist noch experimentell.