| |
wfenv.art
notation syntax rels ;
import syntax wf wfenv ;

// Reflexivity results for widening relations.
//

thm simpty_widens_to-refl
TE |- st1 simpty_widens_to st1
qed by structural cases on st1;
thm varty_widens_to-refl
TE |- vt1 varty_widens_to vt1
qed by simpty_widens_to-refl;
thm expty_widens_to-refl
TE |- et1 expty_widens_to et1
qed by structural cases on et1,EXPTY_WIDENS__elim,varty_widens_to-refl;

// Transitivity results for widening relations.

thm Object-implements
if TE wf_tyenv
then ~(TE |- Object implements i);
consider methods st Cdec(TE,Object) = SOME(CLASS(NONE,EMPTY,PEMPTY,methods)) [rw,auto]
by WF_TYENV__Object_declared [TE];
qed by IMPLEMENTS__elim,agro-grind;
thm Object-subclass
if TE wf_tyenv
then TE |- Object subclass_of C <=> C = Object g;
consider methods st Cdec(TE,Object) = SOME(CLASS(NONE,EMPTY,PEMPTY,methods)) [rw,auto]
by WF_TYENV__Object_declared [TE];
per cases
case + TE |- Object subclass_of C a
- C = Object;
then qed by rule cases on a;
end by IFF,g; // <-- got by auto rule
thm Object-simpty
if TE wf_tyenv
then TE |- Class(Object) simpty_widens_to st <=> st = Class(Object) g;
per cases
case + TE |- Class(Object) simpty_widens_to st a
- st = Class(Object);
then qed by rule cases on a, Object-subclass [TE], Object-implements [TE];
end by IFF,g,PEXISTS_SPLIT; // <-- got by auto rule
//thm subclass-Object
// if TE wf_tyenv
// TE |- C reachable_class a
// then TE |- C subclass_of Object;
// proceed by rule induction on a with C variable;
// case Base; qed by WF_TYENV__only_Object_has_no_superclass [TE,C];
// case Step; qed by subclass_of__Step [TE];
// end;
thm simpty_widens_to-trans
if TE wf_tyenv
TE |- st0 simpty_widens_to st1 a1
TE |- st1 simpty_widens_to st2 a2
then TE |- st0 simpty_widens_to st2
then qed by rule cases on a1,rule cases on a2,
subclass-trans [TE],subinterface-trans [TE],wellfounded_interface-trans [TE],
Object-subclass [TE],Object-simpty [TE],
Object-implements [TE];
thm varty_widens_to-trans
if TE wf_tyenv
TE |- C0 varty_widens_to C1
TE |- C1 varty_widens_to C2
then TE |- C0 varty_widens_to C2
qed by VARTY_WIDENS__elim,simpty_widens_to-trans [TE],Object-simpty [TE],PEXISTS_SPLIT;
thm expty_widens_to-trans
if TE wf_tyenv
TE |- C0 expty_widens_to C1
TE |- C1 expty_widens_to C2
then TE |- C0 expty_widens_to C2
qed by EXPTY_WIDENS__elim,varty_widens_to-trans [TE],PEXISTS_SPLIT;

// Decomposition results for widening

thm array-widens-lemma
TE |- expty expty_widens_to SOME(VT(simpty0,dim)) &
0 < dim
--> ?simpty1.
expty = SOME(VT(simpty1,dim)) &
TE |- simpty1 simpty_widens_to simpty0
qed by EXPTY_WIDENS__elim,VARTY_WIDENS__elim
thm prim-widens-lemma
TE |- expty expty_widens_to SOME(VT(PrimT(primty),0))
<=> expty = SOME(VT(PrimT(primty),0));
qed by IFF,EXPTY_WIDENS__elim,VARTY_WIDENS__elim,SIMPTY_WIDENS__elim,PEXISTS_SPLIT
thm var-prim-widens-lemma
TE |- varty varty_widens_to VT(PrimT(primty),0)
--> varty = VT(PrimT(primty),0)
qed by VARTY_WIDENS__elim,SIMPTY_WIDENS__elim
thm class-widens-lemma
TE wf_tyenv &
TE |- expty expty_widens_to SOME(VT(Class(C),0)) &
C <> Object
--> ?C'. TE |- C' subclass_of C &
expty = SOME(VT(Class(C'),0))
qed by EXPTY_WIDENS__elim,VARTY_WIDENS__elim,SIMPTY_WIDENS__elim;

// widening preserves field visibility

thm inherited-fields-exist
if TE wf_tyenv TE_wF
TE |- C1 subclass_of C0 C1_subclass
((C',f),var0_ty) :: FDecs(TE,C0) search
then ((C',f),var0_ty) :: FDecs(TE,C1)
proceed by rule induction on C1_subclass with C1 variable;
case Refl; qed by search;
case Step; qed by FDecs__Super,search,IN_ELIM;
end;

// widening preserves method visibility up to narrowing of return type.

thm class-inherited-class-methods-are-narrower
if TE wf_tyenv TE_wf
TE |- C1 subclass_of C0 C1_subclass
MSigsC(TE,C0)(m,MT(AT,rt0)) search
then ?rt1. MSigsC(TE,C1)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 g
proceed by rule induction on C1_subclass with C1 variable;
case Refl; qed by expty_widens_to-refl,search;
case Step
Cdec(TE,C1) = SOME(CLASS(SOME(Ca),Is,fields,methods)) [rw,auto]
?rt1. MSigsC(TE,Ca)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 ihyp
TE |- Ca subclass_of C0;
consider rt1 st
MSigsC(TE,Ca)(m,MT(AT,rt1)) ma
TE |- rt1 expty_widens_to rt0 miss_narrower by ihyp;
then qed by WF_TYENV__class_return_types_wider [TE,methods,fields,Is,C1/C],
TE_wf,PDOM,IN_ELIM,Cdec,expty_widens_to-trans [TE],TE_wf,PEXISTS_SPLIT;
end;

//

thm interface-inherited-interface-methods-are-narrower
if TE wf_tyenv TE_wf
TE |- i1 subinterface_of i0 i1_subclass
MSigsI(TE,i0)(m,MT(AT,rt0)) search
then ?rt1. MSigsI(TE,i1)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 g
proceed by rule induction on i1_subclass with i1 variable;
case Refl; qed by expty_widens_to-refl,search;
case Step
Idec(TE,i1) = SOME(INTERFACE(Is,methods)) [rw,auto]
ia :: Is
?rt1. MSigsI(TE,ia)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 ihyp
TE |- ia subinterface_of i0;
consider rt1 st
MSigsI(TE,ia)(m,MT(AT,rt1)) ma
TE |- rt1 expty_widens_to rt0 miss_narrower by ihyp;
then qed by WF_TYENV__interface_return_types_wider [TE,methods,Is,i1/i,ia/i',AT],
expty_widens_to-trans [TE], TE_wf,PDOM,IN_ELIM,Idec,ma,PEXISTS_SPLIT;
end;

//

thm class-inherited-interface-methods-are-narrower
if TE wf_tyenv TE_wf
TE |- C implements i imp
MSigsI(TE,i)(m,MT(AT,rt0)) search
then ?rt1. MSigsC(TE,C)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 g
consider Csupo,Is,fields,methods st
Cdec(TE,C) = SOME(CLASS(Csupo,Is,fields,methods)) [rw,auto]
i :: Is by IMPLEMENTS__elim,imp;
qed by WF_TYENV__interfaces_implemented [TE,C/C],search,TE_wf,PDOM,Cdec,IN_ELIM,PEXISTS_SPLIT;

// The base case (where interfaces support all methods in the Object class)
// needs careful attention. An ommission was discovered in the language
// spec and rule for well-formed environments with respect to this.

thm interface-inherited-Object-methods-are-narrower
if TE wf_tyenv TE_wf
TE |- i wellfounded_interface i_reachable
MSigsC(TE,Object)(m,MT(AT,rt0)) base
then ?rt1. MSigsI(TE,i)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 g
proceed by rule induction on i_reachable with i variable;
// the cases are:
// - the method occurs in the methods of the new interface (easy)
// - the method doesn't occur, and there are no superinterfaces (easy by WF)
// - the method doesn't occur in the new methods but does in
// some superinterface, and by wf. some most narrow interfaces
// exists amongst the superinterfaces.
case Base
Idec(TE,i) = SOME(INTERFACE(EMPTY,methods)) [rw,auto];
per cases
case (m,MT(AT,rt')) :: methods hit;
have TE |- rt' expty_widens_to rt0
by WF_TYENV__interface_return_types_wider_than_Object [TE,methods,i/i],
TE_wf,PDOM,IN_ELIM,Idec,base,hit,PEXISTS_SPLIT;
then qed by MSigsI__Hit,g [rt'],hit;
case !AT' rt'. (m,MT(AT',rt')) :: methods --> AT' <> AT;
then qed by MSigsI__Miss [methods,TE,m/m,i/i,AT],
base,g [rt0],expty_widens_to-refl,Args;
end by hard IN_ELIM,EMPTY_ELIM,FUN_EQ; // soeme sort of bug with EMPTY_ELIM
case Step
Idec(TE,i) = SOME(INTERFACE(Is,methods)) [rw,auto]
i' :: Is witness
?rt1. MSigsI(TE,i')(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 ihyp
TE |- i' wellfounded_interface;
qed by expty_widens_to-trans [TE],
WF_TYENV__interface_return_types_wider [TE,methods,Is,i/i,i'/i'],Idec,
witness,ihyp,TE_wf,PDOM,IN_ELIM,PEXISTS_SPLIT;
end;

//

thm array-inherited-Object-methods-are-identical
MSigsC(TE,Object)(m,MT(AT,rt))
--> MSigsA(TE)(m,MT(AT,rt))
qed by MSigsA__elim,PEXISTS_SPLIT;

// put it all together!!

thm inherited-methods-exist
if TE wf_tyenv TE_wf
MSigs(TE,VT(st0,dim0))(m,MT(AT,rt0)) search
TE |- vt1 varty_widens_to VT(st0,dim0) rel
then ?rt1. MSigs(TE,vt1)(m,MT(AT,rt1)) & TE |- rt1 expty_widens_to rt0 g
qed by VARTY_WIDENS__elim,SIMPTY_WIDENS__elim,rel,g,TE_wf,search,ZERO_CASES [dim0],
MSigs,
expty_widens_to-trans [TE],
array-inherited-Object-methods-are-identical [TE,rt0,AT],
interface-inherited-Object-methods-are-narrower [TE,rt0,AT],
class-inherited-interface-methods-are-narrower [TE,rt0,AT],
interface-inherited-interface-methods-are-narrower [TE,rt0,AT],
class-inherited-class-methods-are-narrower [TE,rt0,AT];

// This is an interesting little proof - it shows that for a well
// formed environment FDecs does not find more than one field type
// for a given field/class pair.

thm FDecs-finds-subclasses
if FDecs(TE,C)((Cf,f),vt) deriv
then TE |- C subclass_of Cf;
proceed by rule induction on deriv with C variable;
case Hit; qed;
case Super; qed by subclass_of__Step;
end;
thm object-fields-unique
if TE wf_tyenv
FDecs(TE,C)((Cf,f),vt1) deriv1
FDecs(TE,C)((Cf,f),vt2) deriv2
then vt1 = vt2;
have TE |- C subclass_of Cf C_subclass by FDecs-finds-subclasses,deriv1;
proceed by rule induction on C_subclass with C variable;
case Refl
Cf = C ;
consider methods1,Is1,fields1,Csup st
Cdec(TE,C) = SOME(CLASS(Csup,Is1,fields1,methods1)) [rw,auto]
fields1 f = SOME(vt1) [rw,auto]
by rule cases on deriv1,
FDecs-finds-subclasses [TE,C/Cf,f/f,vt1],
WF_TYENV__no_circular_classes [TE,C/C],PDOM,IN_ELIM,Cdec;
qed by rule cases on deriv2,
FDecs-finds-subclasses [TE,C/Cf,f/f,vt2],
WF_TYENV__no_circular_classes [TE,C/C,Is1,fields1,methods1],
PDOM,IN_ELIM,Cdec,PEXISTS_SPLIT;
case Step
Cdec(TE,C) = SOME(CLASS(SOME(C1'),Is1,fields1,methods1)) [rw,auto]
FDecs(TE,C1')((Cf,f),vt1) & FDecs(TE,C1')((Cf,f),vt2) --> vt1 = vt2 ihyp
TE |- C1' subclass_of Cf s2;
qed by rule cases on deriv1,rule cases on deriv2,ihyp,s2,PFORALL_SPLIT,
FDecs-finds-subclasses [TE,C/Cf,C1'/C,f/f,vt1],
FDecs-finds-subclasses [TE,C/Cf,C1'/C,f/f,vt2],
WF_TYENV__no_circular_classes [TE,C/C,Is1,fields1,methods1],
PDOM,IN_ELIM,Cdec;
end;

// And thus the graph found by FDecs form a partial function.

thm object-fields-form-graph
TE wf_tyenv --> IS_GRAPH {fspec | FDecs(TE,C)(fspec)};
qed by object-fields-unique [TE], IS_GRAPH_ELIM,GSPEC_ELIM,VT_11,VT_splits,PFORALL_SPLIT;
|