7 header "Relations between Java Types" |
7 header "Relations between Java Types" |
8 |
8 |
9 theory TypeRel = Decl: |
9 theory TypeRel = Decl: |
10 |
10 |
11 consts |
11 consts |
12 subcls1 :: "'c prog => (cname \<times> cname) set" (* subclass *) |
12 subcls1 :: "'c prog => (cname \<times> cname) set" -- "subclass" |
13 widen :: "'c prog => (ty \<times> ty ) set" (* widening *) |
13 widen :: "'c prog => (ty \<times> ty ) set" -- "widening" |
14 cast :: "'c prog => (cname \<times> cname) set" (* casting *) |
14 cast :: "'c prog => (cname \<times> cname) set" -- "casting" |
15 |
15 |
16 syntax (xsymbols) |
16 syntax (xsymbols) |
17 subcls1 :: "'c prog => [cname, cname] => bool" ("_ \<turnstile> _ \<prec>C1 _" [71,71,71] 70) |
17 subcls1 :: "'c prog => [cname, cname] => bool" ("_ \<turnstile> _ \<prec>C1 _" [71,71,71] 70) |
18 subcls :: "'c prog => [cname, cname] => bool" ("_ \<turnstile> _ \<preceq>C _" [71,71,71] 70) |
18 subcls :: "'c prog => [cname, cname] => bool" ("_ \<turnstile> _ \<preceq>C _" [71,71,71] 70) |
19 widen :: "'c prog => [ty , ty ] => bool" ("_ \<turnstile> _ \<preceq> _" [71,71,71] 70) |
19 widen :: "'c prog => [ty , ty ] => bool" ("_ \<turnstile> _ \<preceq> _" [71,71,71] 70) |
29 "G\<turnstile>C \<prec>C1 D" == "(C,D) \<in> subcls1 G" |
29 "G\<turnstile>C \<prec>C1 D" == "(C,D) \<in> subcls1 G" |
30 "G\<turnstile>C \<preceq>C D" == "(C,D) \<in> (subcls1 G)^*" |
30 "G\<turnstile>C \<preceq>C D" == "(C,D) \<in> (subcls1 G)^*" |
31 "G\<turnstile>S \<preceq> T" == "(S,T) \<in> widen G" |
31 "G\<turnstile>S \<preceq> T" == "(S,T) \<in> widen G" |
32 "G\<turnstile>C \<preceq>? D" == "(C,D) \<in> cast G" |
32 "G\<turnstile>C \<preceq>? D" == "(C,D) \<in> cast G" |
33 |
33 |
|
34 -- "direct subclass, cf. 8.1.3" |
34 inductive "subcls1 G" intros |
35 inductive "subcls1 G" intros |
35 |
|
36 (* direct subclass, cf. 8.1.3 *) |
|
37 subcls1I: "\<lbrakk>class G C = Some (D,rest); C \<noteq> Object\<rbrakk> \<Longrightarrow> G\<turnstile>C\<prec>C1D" |
36 subcls1I: "\<lbrakk>class G C = Some (D,rest); C \<noteq> Object\<rbrakk> \<Longrightarrow> G\<turnstile>C\<prec>C1D" |
38 |
37 |
39 lemma subcls1D: |
38 lemma subcls1D: |
40 "G\<turnstile>C\<prec>C1D \<Longrightarrow> C \<noteq> Object \<and> (\<exists>fs ms. class G C = Some (D,fs,ms))" |
39 "G\<turnstile>C\<prec>C1D \<Longrightarrow> C \<noteq> Object \<and> (\<exists>fs ms. class G C = Some (D,fs,ms))" |
41 apply (erule subcls1.elims) |
40 apply (erule subcls1.elims) |
89 |
88 |
90 method :: "'c prog \<times> cname => ( sig \<leadsto> cname \<times> ty \<times> 'c)" (* ###curry *) |
89 method :: "'c prog \<times> cname => ( sig \<leadsto> cname \<times> ty \<times> 'c)" (* ###curry *) |
91 field :: "'c prog \<times> cname => ( vname \<leadsto> cname \<times> ty )" (* ###curry *) |
90 field :: "'c prog \<times> cname => ( vname \<leadsto> cname \<times> ty )" (* ###curry *) |
92 fields :: "'c prog \<times> cname => ((vname \<times> cname) \<times> ty) list" (* ###curry *) |
91 fields :: "'c prog \<times> cname => ((vname \<times> cname) \<times> ty) list" (* ###curry *) |
93 |
92 |
94 (* methods of a class, with inheritance, overriding and hiding, cf. 8.4.6 *) |
93 -- "methods of a class, with inheritance, overriding and hiding, cf. 8.4.6" |
95 defs method_def: "method \<equiv> \<lambda>(G,C). class_rec (G,C) empty (\<lambda>C fs ms ts. |
94 defs method_def: "method \<equiv> \<lambda>(G,C). class_rec (G,C) empty (\<lambda>C fs ms ts. |
96 ts ++ map_of (map (\<lambda>(s,m). (s,(C,m))) ms))" |
95 ts ++ map_of (map (\<lambda>(s,m). (s,(C,m))) ms))" |
97 |
96 |
98 lemma method_rec_lemma: "[|class G C = Some (D,fs,ms); wf ((subcls1 G)^-1)|] ==> |
97 lemma method_rec_lemma: "[|class G C = Some (D,fs,ms); wf ((subcls1 G)^-1)|] ==> |
99 method (G,C) = (if C = Object then empty else method (G,D)) ++ |
98 method (G,C) = (if C = Object then empty else method (G,D)) ++ |
103 apply (erule (1) class_rec_lemma [THEN trans]); |
102 apply (erule (1) class_rec_lemma [THEN trans]); |
104 apply auto |
103 apply auto |
105 done |
104 done |
106 |
105 |
107 |
106 |
108 (* list of fields of a class, including inherited and hidden ones *) |
107 -- "list of fields of a class, including inherited and hidden ones" |
109 defs fields_def: "fields \<equiv> \<lambda>(G,C). class_rec (G,C) [] (\<lambda>C fs ms ts. |
108 defs fields_def: "fields \<equiv> \<lambda>(G,C). class_rec (G,C) [] (\<lambda>C fs ms ts. |
110 map (\<lambda>(fn,ft). ((fn,C),ft)) fs @ ts)" |
109 map (\<lambda>(fn,ft). ((fn,C),ft)) fs @ ts)" |
111 |
110 |
112 lemma fields_rec_lemma: "[|class G C = Some (D,fs,ms); wf ((subcls1 G)^-1)|] ==> |
111 lemma fields_rec_lemma: "[|class G C = Some (D,fs,ms); wf ((subcls1 G)^-1)|] ==> |
113 fields (G,C) = |
112 fields (G,C) = |
127 apply (rule table_of_remap_SomeD) |
126 apply (rule table_of_remap_SomeD) |
128 apply simp |
127 apply simp |
129 done |
128 done |
130 |
129 |
131 |
130 |
132 inductive "widen G" intros (*widening, viz. method invocation conversion,cf. 5.3 |
131 -- "widening, viz. method invocation conversion,cf. 5.3 i.e. sort of syntactic subtyping" |
133 i.e. sort of syntactic subtyping *) |
132 inductive "widen G" intros |
134 refl [intro!, simp]: "G\<turnstile> T \<preceq> T" (* identity conv., cf. 5.1.1 *) |
133 refl [intro!, simp]: "G\<turnstile> T \<preceq> T" -- "identity conv., cf. 5.1.1" |
135 subcls : "G\<turnstile>C\<preceq>C D ==> G\<turnstile>Class C \<preceq> Class D" |
134 subcls : "G\<turnstile>C\<preceq>C D ==> G\<turnstile>Class C \<preceq> Class D" |
136 null [intro!]: "G\<turnstile> NT \<preceq> RefT R" |
135 null [intro!]: "G\<turnstile> NT \<preceq> RefT R" |
137 |
136 |
138 inductive "cast G" intros (* casting conversion, cf. 5.5 / 5.1.5 *) |
137 -- "casting conversion, cf. 5.5 / 5.1.5" |
139 (* left out casts on primitve types *) |
138 -- "left out casts on primitve types" |
|
139 inductive "cast G" intros |
140 widen: "G\<turnstile>C\<preceq>C D ==> G\<turnstile>C \<preceq>? D" |
140 widen: "G\<turnstile>C\<preceq>C D ==> G\<turnstile>C \<preceq>? D" |
141 subcls: "G\<turnstile>D\<preceq>C C ==> G\<turnstile>C \<preceq>? D" |
141 subcls: "G\<turnstile>D\<preceq>C C ==> G\<turnstile>C \<preceq>? D" |
142 |
142 |
143 lemma widen_PrimT_RefT [iff]: "(G\<turnstile>PrimT pT\<preceq>RefT rT) = False" |
143 lemma widen_PrimT_RefT [iff]: "(G\<turnstile>PrimT pT\<preceq>RefT rT) = False" |
144 apply (rule iffI) |
144 apply (rule iffI) |
171 apply (rule iffI) |
171 apply (rule iffI) |
172 apply (ind_cases "G\<turnstile>S\<preceq>T") |
172 apply (ind_cases "G\<turnstile>S\<preceq>T") |
173 apply (auto elim: widen.subcls) |
173 apply (auto elim: widen.subcls) |
174 done |
174 done |
175 |
175 |
176 lemma widen_trans [rule_format (no_asm)]: "G\<turnstile>S\<preceq>U ==> \<forall>T. G\<turnstile>U\<preceq>T --> G\<turnstile>S\<preceq>T" |
176 theorem widen_trans[trans]: "\<lbrakk>G\<turnstile>S\<preceq>U; G\<turnstile>U\<preceq>T\<rbrakk> \<Longrightarrow> G\<turnstile>S\<preceq>T" |
177 apply (erule widen.induct) |
|
178 apply safe |
|
179 apply (frule widen_Class) |
|
180 apply (frule_tac [2] widen_RefT) |
|
181 apply safe |
|
182 apply(erule (1) rtrancl_trans) |
|
183 done |
|
184 |
|
185 |
|
186 (*####theorem widen_trans: "\<lbrakk>G\<turnstile>S\<preceq>U; G\<turnstile>U\<preceq>T\<rbrakk> \<Longrightarrow> G\<turnstile>S\<preceq>T" |
|
187 proof - |
177 proof - |
188 assume "G\<turnstile>S\<preceq>U" |
178 assume "G\<turnstile>S\<preceq>U" thus "\<And>T. G\<turnstile>U\<preceq>T \<Longrightarrow> G\<turnstile>S\<preceq>T" |
189 thus "\<And>T. G\<turnstile>U\<preceq>T \<Longrightarrow> G\<turnstile>S\<preceq>T" ( *(is "PROP ?P S U")* ) |
|
190 proof (induct ( *cases* ) (open) ( *?P S U* ) rule: widen.induct [consumes 1]) |
|
191 case refl |
|
192 fix T' assume "G\<turnstile>T\<preceq>T'" thus "G\<turnstile>T\<preceq>T'". |
|
193 ( * fix T' show "PROP ?P T T".* ) |
|
194 next |
|
195 case subcls |
|
196 fix T assume "G\<turnstile>Class D\<preceq>T" |
|
197 then obtain E where "T = Class E" by (blast dest: widen_Class) |
|
198 from prems show "G\<turnstile>Class C\<preceq>T" proof (auto elim: rtrancl_trans) qed |
|
199 next |
|
200 case null |
|
201 fix RT assume "G\<turnstile>RefT R\<preceq>RT" |
|
202 then obtain rt where "RT = RefT rt" by (blast dest: widen_RefT) |
|
203 thus "G\<turnstile>NT\<preceq>RT" by auto |
|
204 qed |
|
205 qed |
|
206 *) |
|
207 |
|
208 theorem widen_trans: "\<lbrakk>G\<turnstile>S\<preceq>U; G\<turnstile>U\<preceq>T\<rbrakk> \<Longrightarrow> G\<turnstile>S\<preceq>T" |
|
209 proof - |
|
210 assume "G\<turnstile>S\<preceq>U" |
|
211 thus "\<And>T. G\<turnstile>U\<preceq>T \<Longrightarrow> G\<turnstile>S\<preceq>T" |
|
212 proof induct |
179 proof induct |
213 case (refl T T') |
180 case (refl T T') thus "G\<turnstile>T\<preceq>T'" . |
214 thus "G\<turnstile>T\<preceq>T'" . |
|
215 next |
181 next |
216 case (subcls C D T) |
182 case (subcls C D T) |
217 then obtain E where "T = Class E" by (blast dest: widen_Class) |
183 then obtain E where "T = Class E" by (blast dest: widen_Class) |
218 with subcls show "G\<turnstile>Class C\<preceq>T" by (auto elim: rtrancl_trans) |
184 with subcls show "G\<turnstile>Class C\<preceq>T" by (auto elim: rtrancl_trans) |
219 next |
185 next |