(* Title: Jinja/Common/TypeRel.thy
ID: $Id: TypeRel.html 1910 2004-05-19 04:46:04Z kleing $
Author: Tobias Nipkow
Copyright 2003 Technische Universitaet Muenchen
*)
header {* \isaheader{Relations between Jinja Types} *}
theory TypeRel = Decl:
subsection{* The subclass relations *}
consts
subcls1 :: "'m prog => (cname × cname) set" -- "subclass"
(*<*)
syntax (xsymbols)
subcls1 :: "'m prog => [cname, cname] => bool" ("_ \<turnstile> _ \<prec>1 _" [71,71,71] 70)
subcls :: "'m prog => [cname, cname] => bool" ("_ \<turnstile> _ \<preceq>* _" [71,71,71] 70)
(*>*)
translations
"P \<turnstile> C \<prec>1 D" == "(C,D) ∈ subcls1 P"
"P \<turnstile> C \<preceq>* D" == "(C,D) ∈ (subcls1 P)*"
(*<*)
"¬ P \<turnstile> C \<preceq>* D" <= "(C,D) ∉ (subcls1 P)*"
(*>*)
inductive "subcls1 P"
intros subcls1I: "[|class P C = Some (D,rest); C ≠ Object|] ==> P \<turnstile> C \<prec>1 D"
lemma subcls1D: "P \<turnstile> C \<prec>1 D ==> C ≠ Object ∧ (∃fs ms. class P C = Some (D,fs,ms))"
(*<*)by(erule subcls1.induct)(fastsimp simp add:is_class_def)(*>*)
lemma [iff]: "¬ P \<turnstile> Object \<prec>1 C"
(*<*)by(fastsimp dest:subcls1D)(*>*)
lemma [iff]: "(P \<turnstile> Object \<preceq>* C) = (C = Object)"
(*<*)
apply(rule iffI)
apply(erule converse_rtranclE)
apply simp_all
done
(*>*)
lemma finite_subcls1: "finite (subcls1 P)"
(*<*)
apply(subgoal_tac "subcls1 P =
(Σ C∈{C. is_class P C} . {D. C≠Object ∧ fst (the (class P C))=D})")
prefer 2
apply(fastsimp simp:is_class_def dest: subcls1D elim: subcls1I)
apply simp
apply(rule finite_SigmaI [OF finite_is_class])
apply(rule_tac B = "{fst (the (class P C))}" in finite_subset)
apply auto
done
(*>*)
(*
lemma subcls_is_class: "(C,D) ∈ (subcls1 P)+ ==> is_class P C"
apply (unfold is_class_def)
apply(erule trancl_trans_induct)
apply (auto dest!: subcls1D)
done
lemma subcls_is_class: "P \<turnstile> C \<preceq>* D ==> is_class P D --> is_class P C"
apply (unfold is_class_def)
apply (erule rtrancl_induct)
apply (drule_tac [2] subcls1D)
apply auto
done
*)
subsection{* The subtype relations *}
consts
widen :: "'m prog => (ty × ty) set" -- "widening"
(*<*)
syntax (xsymbols)
widen :: "'m prog => ty => ty => bool" ("_ \<turnstile> _ ≤ _" [71,71,71] 70)
widens :: "'m prog => ty list => ty list => bool" ("_ \<turnstile> _ [≤] _" [71,71,71] 70)
(*>*)
translations
"P \<turnstile> S ≤ T" == "(S,T) ∈ widen P"
"P \<turnstile> Ts [≤] Ts'" == "list_all2 (fun_of (widen P)) Ts Ts'"
inductive "widen P"
intros
widen_refl[iff]: "P \<turnstile> T ≤ T"
widen_subcls: "P \<turnstile> C \<preceq>* D ==> P \<turnstile> Class C ≤ Class D"
widen_null[iff]: "P \<turnstile> NT ≤ Class C"
lemma [iff]: "(P \<turnstile> T ≤ Void) = (T = Void)"
(*<*)by (auto elim: widen.elims)(*>*)
lemma [iff]: "(P \<turnstile> T ≤ Boolean) = (T = Boolean)"
(*<*)by (auto elim: widen.elims)(*>*)
lemma [iff]: "(P \<turnstile> T ≤ Integer) = (T = Integer)"
(*<*)by (auto elim: widen.elims)(*>*)
lemma [iff]: "(P \<turnstile> Void ≤ T) = (T = Void)"
(*<*)by (auto elim: widen.elims)(*>*)
lemma [iff]: "(P \<turnstile> Boolean ≤ T) = (T = Boolean)"
(*<*)by (auto elim: widen.elims)(*>*)
lemma [iff]: "(P \<turnstile> Integer ≤ T) = (T = Integer)"
(*<*)by (auto elim: widen.elims)(*>*)
lemma Class_widen: "P \<turnstile> Class C ≤ T ==> ∃D. T = Class D"
(*<*)
apply (ind_cases "P\<turnstile>S≤T")
apply auto
done
(*>*)
lemma [iff]: "(P \<turnstile> T ≤ NT) = (T = NT)"
(*<*)
apply(cases T)
apply(auto dest:Class_widen)
done
(*>*)
lemma Class_widen_Class [iff]: "(P \<turnstile> Class C ≤ Class D) = (P \<turnstile> C \<preceq>* D)"
(*<*)
apply (rule iffI)
apply (ind_cases " P \<turnstile> S ≤ T")
apply (auto elim: widen_subcls)
done
(*>*)
lemma widen_Class: "(P \<turnstile> T ≤ Class C) = (T = NT ∨ (∃D. T = Class D ∧ P \<turnstile> D \<preceq>* C))"
(*<*)by(induct T, auto)(*>*)
lemma widen_trans[trans]: "[|P \<turnstile> S ≤ U; P \<turnstile> U ≤ T|] ==> P \<turnstile> S ≤ T"
(*<*)
proof -
assume "P\<turnstile>S ≤ U" thus "!!T. P \<turnstile> U ≤ T ==> P \<turnstile> S ≤ T"
proof induct
case (widen_refl T T') thus "P \<turnstile> T ≤ T'" .
next
case (widen_subcls C D T)
then obtain E where "T = Class E" by (blast dest: Class_widen)
with widen_subcls show "P \<turnstile> Class C ≤ T" by (auto elim: rtrancl_trans)
next
case (widen_null C RT)
then obtain D where "RT = Class D" by (blast dest: Class_widen)
thus "P \<turnstile> NT ≤ RT" by auto
qed
qed
(*>*)
lemma widens_trans [trans]: "[|P \<turnstile> Ss [≤] Ts; P \<turnstile> Ts [≤] Us|] ==> P \<turnstile> Ss [≤] Us"
(*<*)by (rule rel_list_all2_trans, rule widen_trans)(*>*)
(*<*)
lemmas widens_refl [iff] = rel_list_all2_refl [OF widen_refl]
lemmas widens_Cons [iff] = rel_list_all2_Cons1 [of "widen P", standard]
(*>*)
subsection{* Method lookup *}
consts
Methods :: "'m prog => (cname × (mname => (ty list × ty × 'm) × cname))set"
(*<*)
syntax
"_sees_methods" :: "['m prog, cname, mname => (ty list × ty × 'm) × cname] => bool"
("_ \<turnstile> _ sees'_methods _" [51,51,51] 50)
(*>*)
translations "P \<turnstile> C sees_methods Mm" == "(C,Mm) ∈ Methods P"
inductive "Methods P"
intros
sees_methods_Object:
"[| class P Object = Some(D,fs,ms); Mm = option_map (λm. (m,Object)) ˆ map_of ms |]
==> P \<turnstile> Object sees_methods Mm"
sees_methods_rec:
"[| class P C = Some(D,fs,ms); C ≠ Object; P \<turnstile> D sees_methods Mm;
Mm' = Mm ++ (option_map (λm. (m,C)) ˆ map_of ms) |]
==> P \<turnstile> C sees_methods Mm'";
lemma sees_methods_fun:
assumes 1: "P \<turnstile> C sees_methods Mm"
shows "!!Mm'. P \<turnstile> C sees_methods Mm' ==> Mm' = Mm"
(*<*)
using 1
proof induct
case (sees_methods_rec C D Dres Cres fs ms Cres')
have class: "class P C = Some (D, fs, ms)"
and notObj: "C ≠ Object" and Dmethods: "P \<turnstile> D sees_methods Dres"
and IH: "!!Dres'. P \<turnstile> D sees_methods Dres' ==> Dres' = Dres"
and Cres: "Cres = Dres ++ (option_map (λm. (m,C)) ˆ map_of ms)"
and Cmethods': "P \<turnstile> C sees_methods Cres'" .
from Cmethods' notObj class obtain Dres'
where Dmethods': "P \<turnstile> D sees_methods Dres'"
and Cres': "Cres' = Dres' ++ (option_map (λm. (m,C)) ˆ map_of ms)"
by(auto elim: Methods.elims)
from Cres Cres' IH[OF Dmethods'] show "Cres' = Cres" by simp
next
case sees_methods_Object thus ?case by(auto elim: Methods.elims)
qed
(*>*)
lemma visible_methods_exist:
"P \<turnstile> C sees_methods Mm ==> Mm M = Some(m,D) ==>
(∃D' fs ms. class P D = Some(D',fs,ms) ∧ map_of ms M = Some m)"
(*<*)by(induct rule:Methods.induct) auto(*>*)
lemma sees_methods_decl_above:
assumes Csees: "P \<turnstile> C sees_methods Mm"
shows "Mm M = Some(m,D) ==> P \<turnstile> C \<preceq>* D"
(*<*)
using Csees
proof induct
case sees_methods_Object thus ?case by auto
next
case sees_methods_rec thus ?case
by(fastsimp simp:option_map_def split:option.splits
elim:converse_rtrancl_into_rtrancl[OF subcls1I])
qed
(*>*)
lemma sees_methods_idemp:
assumes Cmethods: "P \<turnstile> C sees_methods Mm"
shows "!!m D. Mm M = Some(m,D) ==>
∃Mm'. (P \<turnstile> D sees_methods Mm') ∧ Mm' M = Some(m,D)"
(*<*)
using Cmethods
proof induct
case sees_methods_Object thus ?case
by(fastsimp dest: Methods.sees_methods_Object)
next
case sees_methods_rec thus ?case
by(fastsimp split:option.splits dest: Methods.sees_methods_rec)
qed
(*>*)
(*FIXME something wrong with induct: need to attache [consumes 1]
directly to proof of thm, declare does not work. *)
lemma sees_methods_decl_mono:
assumes sub: "P \<turnstile> C' \<preceq>* C"
shows "P \<turnstile> C sees_methods Mm ==>
∃Mm' Mm2. P \<turnstile> C' sees_methods Mm' ∧ Mm' = Mm ++ Mm2 ∧
(∀M m D. Mm2 M = Some(m,D) --> P \<turnstile> D \<preceq>* C)"
(*<*)
(is "_ ==> ∃Mm' Mm2. ?Q C' C Mm' Mm2")
using sub
proof (induct rule:converse_rtrancl_induct)
assume "P \<turnstile> C sees_methods Mm"
hence "?Q C C Mm empty" by simp
thus "∃Mm' Mm2. ?Q C C Mm' Mm2" by blast
next
fix C'' C'
assume sub1: "P \<turnstile> C'' \<prec>1 C'" and sub: "P \<turnstile> C' \<preceq>* C"
and IH: "P \<turnstile> C sees_methods Mm ==>
∃Mm' Mm2. P \<turnstile> C' sees_methods Mm' ∧
Mm' = Mm ++ Mm2 ∧ (∀M m D. Mm2 M = Some(m,D) --> P \<turnstile> D \<preceq>* C)"
and Csees: "P \<turnstile> C sees_methods Mm"
from IH[OF Csees] obtain Mm' Mm2 where C'sees: "P \<turnstile> C' sees_methods Mm'"
and Mm': "Mm' = Mm ++ Mm2"
and subC:"∀M m D. Mm2 M = Some(m,D) --> P \<turnstile> D \<preceq>* C" by blast
obtain fs ms where class: "class P C'' = Some(C',fs,ms)" "C'' ≠ Object"
using subcls1D[OF sub1] by blast
let ?Mm3 = "option_map (λm. (m,C'')) ˆ map_of ms"
have "P \<turnstile> C'' sees_methods (Mm ++ Mm2) ++ ?Mm3"
using sees_methods_rec[OF class C'sees refl] Mm' by simp
hence "?Q C'' C ((Mm ++ Mm2) ++ ?Mm3) (Mm2++?Mm3)"
using converse_rtrancl_into_rtrancl[OF sub1 sub]
by simp (simp add:map_add_def subC split:option.split)
thus "∃Mm' Mm2. ?Q C'' C Mm' Mm2" by blast
qed
(*>*)
constdefs
Method :: "'m prog => cname => mname => ty list => ty => 'm => cname => bool"
("_ \<turnstile> _ sees _: _->_ = _ in _" [51,51,51,51,51,51,51] 50)
"P \<turnstile> C sees M: Ts->T = m in D ≡
∃Mm. P \<turnstile> C sees_methods Mm ∧ Mm M = Some((Ts,T,m),D)";
lemma sees_method_fun:
"[|P \<turnstile> C sees M:TS->T = m in D; P \<turnstile> C sees M:TS'->T' = m' in D' |]
==> TS' = TS ∧ T' = T ∧ m' = m ∧ D' = D"
(*<*)by(fastsimp dest: sees_methods_fun simp:Method_def)(*>*)
lemma sees_method_decl_above:
"P \<turnstile> C sees M:Ts->T = m in D ==> P \<turnstile> C \<preceq>* D"
(*<*)by(clarsimp simp:Method_def sees_methods_decl_above)(*>*)
lemma visible_method_exists:
"P \<turnstile> C sees M:Ts->T = m in D ==>
∃D' fs ms. class P D = Some(D',fs,ms) ∧ map_of ms M = Some(Ts,T,m)"
(*<*)by(fastsimp simp:Method_def dest!: visible_methods_exist)(*>*)
lemma sees_method_idemp:
"P \<turnstile> C sees M:Ts->T=m in D ==> P \<turnstile> D sees M:Ts->T=m in D"
(*<*)by(fastsimp simp: Method_def intro:sees_methods_idemp)(*>*)
lemma sees_method_decl_mono:
"[| P \<turnstile> C' \<preceq>* C; P \<turnstile> C sees M:Ts->T = m in D;
P \<turnstile> C' sees M:Ts'->T' = m' in D' |] ==> P \<turnstile> D' \<preceq>* D"
(*<*)
apply(frule sees_method_decl_above)
apply(unfold Method_def)
apply clarsimp
apply(drule (1) sees_methods_decl_mono)
apply clarsimp
apply(drule (1) sees_methods_fun)
apply clarsimp
apply(blast intro:rtrancl_trans)
done
(*>*)
lemma sees_method_is_class:
"[| P \<turnstile> C sees M:Ts->T = m in D |] ==> is_class P C"
(*<*)by (auto simp add: is_class_def Method_def elim: Methods.induct)(*>*)
subsection{* Field lookup *}
consts
Fields :: "'m prog => (cname × ((vname × cname) × ty) list)set"
(*<*)
syntax
"_has_fields" :: "['m prog, cname, ((vname × cname) × ty) list] => bool"
("_ \<turnstile> _ has'_fields _" [51,51,51] 50)
(*>*)
translations
"P \<turnstile> C has_fields FDTs" == "(C,FDTs) ∈ Fields P"
inductive "Fields P"
intros
has_fields_rec:
"[| class P C = Some(D,fs,ms); C ≠ Object; P \<turnstile> D has_fields FDTs;
FDTs' = map (λ(F,T). ((F,C),T)) fs @ FDTs |]
==> P \<turnstile> C has_fields FDTs'"
has_fields_Object:
"[| class P Object = Some(D,fs,ms); FDTs = map (λ(F,T). ((F,Object),T)) fs |]
==> P \<turnstile> Object has_fields FDTs"
lemma has_fields_fun:
assumes 1: "P \<turnstile> C has_fields FDTs"
shows "!!FDTs'. P \<turnstile> C has_fields FDTs' ==> FDTs' = FDTs"
(*<*)
using 1
proof induct
case (has_fields_rec C D Dres Cres fs ms Cres')
have class: "class P C = Some (D, fs, ms)"
and notObj: "C ≠ Object" and DFields: "P \<turnstile> D has_fields Dres"
and IH: "!!Dres'. P \<turnstile> D has_fields Dres' ==> Dres' = Dres"
and Cres: "Cres = map (λ(F,T). ((F,C),T)) fs @ Dres"
and CFields': "P \<turnstile> C has_fields Cres'" .
from CFields' notObj class obtain Dres'
where DFields': "P \<turnstile> D has_fields Dres'"
and Cres': "Cres' = map (λ(F,T). ((F,C),T)) fs @ Dres'"
by(auto elim: Fields.elims)
from Cres Cres' IH[OF DFields'] show "Cres' = Cres" by simp
next
case has_fields_Object thus ?case by(auto elim: Fields.elims)
qed
(*>*)
lemma all_fields_in_has_fields:
assumes sub: "P \<turnstile> C has_fields FDTs"
shows "[| P \<turnstile> C \<preceq>* D; class P D = Some(D',fs,ms); (F,T) ∈ set fs |]
==> ((F,D),T) ∈ set FDTs"
(*<*)
using sub apply(induct)
apply(simp add:image_def)
apply(erule converse_rtranclE)
apply(force)
apply(drule subcls1D)
apply fastsimp
apply(force simp:image_def)
done
(*>*)
lemma has_fields_decl_above:
assumes fields: "P \<turnstile> C has_fields FDTs"
shows "((F,D),T) ∈ set FDTs ==> P \<turnstile> C \<preceq>* D"
(*<*)
using fields apply(induct)
prefer 2 apply(fastsimp dest: tranclD)
apply clarsimp
apply(erule disjE)
apply(clarsimp simp add:image_def)
apply simp
apply(blast dest:subcls1I converse_rtrancl_into_rtrancl)
done
(*>*)
lemma subcls_notin_has_fields:
assumes fields: "P \<turnstile> C has_fields FDTs"
shows "((F,D),T) ∈ set FDTs ==> (D,C) ∉ (subcls1 P)+"
(*<*)
using fields apply(induct)
prefer 2 apply(fastsimp dest: tranclD)
apply clarsimp
apply(erule disjE)
apply(clarsimp simp add:image_def)
apply(drule tranclD)
apply clarify
apply(frule subcls1D)
apply(fastsimp dest:tranclD all_fields_in_has_fields)
apply simp
apply(blast dest:subcls1I trancl_into_trancl)
done
(*>*)
lemma has_fields_mono_lem:
assumes sub: "P \<turnstile> D \<preceq>* C"
shows "P \<turnstile> C has_fields FDTs
==> ∃pre. P \<turnstile> D has_fields pre@FDTs ∧ dom(map_of pre) ∩ dom(map_of FDTs) = {}"
(*<*)
using sub apply(induct rule:converse_rtrancl_induct)
apply(rule_tac x = "[]" in exI)
apply simp
apply clarsimp
apply(rename_tac D' D pre)
apply(subgoal_tac "(D',C) : (subcls1 P)^+")
prefer 2 apply(erule (1) rtrancl_into_trancl2)
apply(drule subcls1D)
apply clarsimp
apply(rename_tac fs ms)
apply(drule (2) has_fields_rec)
apply(rule refl)
apply(rule_tac x = "map (λ(F,T). ((F,D'),T)) fs @ pre" in exI)
apply simp
apply(simp add:Int_Un_distrib2)
apply(rule equals0I)
apply(auto dest: subcls_notin_has_fields simp:dom_map_of image_def)
done
(*>*)
(* FIXME why is Field not displayed correctly? TypeRel qualifier seems to confuse printer*)
constdefs
has_field :: "'m prog => cname => vname => ty => cname => bool"
("_ \<turnstile> _ has _:_ in _" [51,51,51,51,51] 50)
"P \<turnstile> C has F:T in D ≡
∃FDTs. P \<turnstile> C has_fields FDTs ∧ map_of FDTs (F,D) = Some T"
lemma has_field_mono:
"[| P \<turnstile> C has F:T in D; P \<turnstile> C' \<preceq>* C |] ==> P \<turnstile> C' has F:T in D"
(*<*)
apply(clarsimp simp:has_field_def)
apply(drule (1) has_fields_mono_lem)
apply(fastsimp simp: map_add_def split:option.splits)
done
(*>*)
constdefs
sees_field :: "'m prog => cname => vname => ty => cname => bool"
("_ \<turnstile> _ sees _:_ in _" [51,51,51,51,51] 50)
"P \<turnstile> C sees F:T in D ≡
∃FDTs. P \<turnstile> C has_fields FDTs ∧
map_of (map (λ((F,D),T). (F,(D,T))) FDTs) F = Some(D,T)"
lemma map_of_remap_SomeD:
"map_of (map (λ((k,k'),x). (k,(k',x))) t) k = Some (k',x) ==> map_of t (k, k') = Some x"
(*<*)by (induct t) (auto simp:fun_upd_apply split: split_if_asm)(*>*)
lemma has_visible_field:
"P \<turnstile> C sees F:T in D ==> P \<turnstile> C has F:T in D"
(*<*)by(auto simp add:has_field_def sees_field_def map_of_remap_SomeD)(*>*)
lemma sees_field_fun:
"[|P \<turnstile> C sees F:T in D; P \<turnstile> C sees F:T' in D'|] ==> T' = T ∧ D' = D"
(*<*)by(fastsimp simp:sees_field_def dest:has_fields_fun)(*>*)
lemma sees_field_decl_above:
"P \<turnstile> C sees F:T in D ==> P \<turnstile> C \<preceq>* D"
(*<*)
apply(auto simp:sees_field_def)
apply(blast intro: has_fields_decl_above map_of_SomeD map_of_remap_SomeD)
done
(*>*)
(* FIXME ugly *)
lemma sees_field_idemp:
"P \<turnstile> C sees F:T in D ==> P \<turnstile> D sees F:T in D"
(*<*)
apply (unfold sees_field_def)
apply clarsimp
apply (rule_tac P = "map_of ?xs F = ?y" in mp)
prefer 2
apply assumption
apply (thin_tac "map_of ?xs F = ?y")
apply (erule Fields.induct)
apply clarsimp
apply (frule map_of_SomeD)
apply clarsimp
apply (fastsimp intro: has_fields_rec)
apply clarsimp
apply (frule map_of_SomeD)
apply clarsimp
apply (fastsimp intro: has_fields_Object)
done
(*>*)
subsection "Functional lookup"
constdefs
method :: "'m prog => cname => mname => cname × ty list × ty × 'm"
"method P C M ≡ THE (D,Ts,T,m). P \<turnstile> C sees M:Ts -> T = m in D"
field :: "'m prog => cname => vname => cname × ty"
"field P C F ≡ THE (D,T). P \<turnstile> C sees F:T in D"
fields :: "'m prog => cname => ((vname × cname) × ty) list"
"fields P C ≡ THE FDTs. P \<turnstile> C has_fields FDTs"
lemma [simp]: "P \<turnstile> C has_fields FDTs ==> fields P C = FDTs"
(*<*)by (unfold fields_def) (auto dest: has_fields_fun)(*>*)
lemma field_def2 [simp]: "P \<turnstile> C sees F:T in D ==> field P C F = (D,T)"
(*<*)by (unfold field_def) (auto dest: sees_field_fun)(*>*)
lemma method_def2 [simp]: "P \<turnstile> C sees M: Ts->T = m in D ==> method P C M = (D,Ts,T,m)"
(*<*)by (unfold method_def) (auto dest: sees_method_fun)(*>*)
(*<*)
end
(*>*)
lemma subcls1D:
subcls1 P C D ==> C ~= Object & (EX fs ms. class P C = ⌊(D, fs, ms)⌋)
lemma
(Object, C) ~: subcls1 P
lemma
subcls P Object C = (C = Object)
lemma finite_subcls1:
finite (subcls1 P)
lemma
widen P T Void = (T = Void)
lemma
widen P T Boolean = (T = Boolean)
lemma
widen P T Integer = (T = Integer)
lemma
widen P Void T = (T = Void)
lemma
widen P Boolean T = (T = Boolean)
lemma
widen P Integer T = (T = Integer)
lemma Class_widen:
widen P (Class C) T ==> EX D. T = Class D
lemma
widen P T NT = (T = NT)
lemma Class_widen_Class:
widen P (Class C) (Class D) = subcls P C D
lemma widen_Class:
widen P T (Class C) = (T = NT | (EX D. T = Class D & subcls P D C))
lemma widen_trans:
[| widen P S U; widen P U T |] ==> widen P S T
lemma widens_trans:
[| widens P Ss Ts; widens P Ts Us |] ==> widens P Ss Us
lemmas widens_refl:
widens P_2 xs xs
lemmas widens_Cons:
widens P (x # xs) ys = (EX z zs. ys = z # zs & widen P x z & widens P xs zs)
lemma
[| P \<turnstile> C sees_methods Mm; P \<turnstile> C sees_methods Mm' |] ==> Mm' = Mm
lemma visible_methods_exist:
[| P \<turnstile> C sees_methods Mm; Mm M = ⌊(m, D)⌋ |] ==> EX D' fs ms. class P D = ⌊(D', fs, ms)⌋ & map_of ms M = ⌊m⌋
lemma
[| P \<turnstile> C sees_methods Mm; Mm M = ⌊(m, D)⌋ |] ==> subcls P C D
lemma
[| P \<turnstile> C sees_methods Mm; Mm M = ⌊(m, D)⌋ |] ==> EX Mm'. P \<turnstile> D sees_methods Mm' & Mm' M = ⌊(m, D)⌋
lemma
[| subcls P C' C; P \<turnstile> C sees_methods Mm |] ==> EX Mm' Mm2. P \<turnstile> C' sees_methods Mm' & Mm' = Mm ++ Mm2 & (ALL M m D. Mm2 M = ⌊(m, D)⌋ --> subcls P D C)
lemma sees_method_fun:
[| P \<turnstile> C sees M: TS->T = m in D; P \<turnstile> C sees M: TS'->T' = m' in D' |] ==> TS' = TS & T' = T & m' = m & D' = D
lemma sees_method_decl_above:
P \<turnstile> C sees M: Ts->T = m in D ==> subcls P C D
lemma visible_method_exists:
P \<turnstile> C sees M: Ts->T = m in D ==> EX D' fs ms. class P D = ⌊(D', fs, ms)⌋ & map_of ms M = ⌊(Ts, T, m)⌋
lemma sees_method_idemp:
P \<turnstile> C sees M: Ts->T = m in D ==> P \<turnstile> D sees M: Ts->T = m in D
lemma sees_method_decl_mono:
[| subcls P C' C; P \<turnstile> C sees M: Ts->T = m in D; P \<turnstile> C' sees M: Ts'->T' = m' in D' |] ==> subcls P D' D
lemma sees_method_is_class:
P \<turnstile> C sees M: Ts->T = m in D ==> is_class P C
lemma
[| P \<turnstile> C has_fields FDTs; P \<turnstile> C has_fields FDTs' |] ==> FDTs' = FDTs
lemma
[| P \<turnstile> C has_fields FDTs; subcls P C D; class P D = ⌊(D', fs, ms)⌋; (F, T) : set fs |] ==> ((F, D), T) : set FDTs
lemma
[| P \<turnstile> C has_fields FDTs; ((F, D), T) : set FDTs |] ==> subcls P C D
lemma
[| P \<turnstile> C has_fields FDTs; ((F, D), T) : set FDTs |] ==> (D, C) ~: (subcls1 P)^+
lemma
[| subcls P D C; P \<turnstile> C has_fields FDTs |] ==> EX pre. P \<turnstile> D has_fields pre @ FDTs & dom (map_of pre) Int dom (map_of FDTs) = {}
lemma has_field_mono:
[| P \<turnstile> C has F:T in D; subcls P C' C |] ==> P \<turnstile> C' has F:T in D
lemma map_of_remap_SomeD:
map_of (map (%((k, k'), x). (k, k', x)) t) k = ⌊(k', x)⌋ ==> map_of t (k, k') = ⌊x⌋
lemma has_visible_field:
P \<turnstile> C sees F:T in D ==> P \<turnstile> C has F:T in D
lemma sees_field_fun:
[| P \<turnstile> C sees F:T in D; P \<turnstile> C sees F:T' in D' |] ==> T' = T & D' = D
lemma sees_field_decl_above:
P \<turnstile> C sees F:T in D ==> subcls P C D
lemma sees_field_idemp:
P \<turnstile> C sees F:T in D ==> P \<turnstile> D sees F:T in D
lemma
P \<turnstile> C has_fields FDTs ==> fields P C = FDTs
lemma field_def2:
P \<turnstile> C sees F:T in D ==> field P C F = (D, T)
lemma method_def2:
P \<turnstile> C sees M: Ts->T = m in D ==> method P C M = (D, Ts, T, m)