Require Import Coqlib.
Require Import Cplusconcepts.
Require Import CplusWf.
Require Import LibLists.
Require Import Tactics.
Require Import LibMaps.
Require Import Relations.
Require Import LayoutConstraints.
Require Import Target.
Require Import CPP.
Require Import Dynamic.
Require Import DynamicWf.
Require Import Wellfounded.
Load Param.
Open Scope Z_scope.
Section Ass.
Variable A :
Type.
Hypothesis A_eq_dec :
forall a1 a2 :
A, {
a1 =
a2} + {
a1 <>
a2}.
Section Attach.
Variable B :
Type.
Variable f :
A ->
B.
Definition attach a := (
a,
f a).
Lemma assoc_attach_some :
forall l a,
In a l ->
assoc A_eq_dec a (
map attach l) =
Some (
f a).
Proof.
induction l; simpl; try tauto.
intro.
destruct (A_eq_dec a a0); try congruence.
destruct 1; try contradiction.
eauto.
Qed.
Lemma assoc_attach_none :
forall l a, (
In a l ->
False) ->
assoc A_eq_dec a (
map attach l) =
None.
Proof.
induction l; simpl; auto.
intros.
destruct (A_eq_dec a a0).
tauto.
eauto.
Qed.
End Attach.
Section Remove.
Lemma In_remove :
forall l a a',
a <>
a' -> (
In a'
l <->
In a' (
remove A_eq_dec a l)).
Proof.
induction l; simpl.
tauto.
intros.
destruct (A_eq_dec a0 a).
subst.
split.
destruct 1.
contradiction.
eapply IHl; eauto.
right.
eapply IHl; eauto.
split.
destruct 1.
subst; auto.
right.
eapply IHl; eauto.
destruct 1.
auto.
right; eapply IHl; eauto.
Qed.
Function remove_dup (
l :
list A) :
list A :=
match l with
|
nil =>
nil
|
a ::
q =>
a :: (
remove A_eq_dec a (
remove_dup q))
end.
Lemma remove_dup_In :
forall l a,
In a l <->
In a (
remove_dup l).
Proof.
intro.
functional induction (
remove_dup l).
tauto.
intro;
split.
destruct (
A_eq_dec a a0).
subst;
auto.
destruct 1.
contradiction.
right.
refine (
let (
H,
_) :=
In_remove _ _ in H _).
assumption.
eapply IHl0.
assumption.
destruct (
A_eq_dec a a0).
subst;
auto.
destruct 1.
contradiction.
right.
eapply IHl0.
eapply In_remove.
eassumption.
assumption.
Qed.
End Remove.
Section Initass.
Variable B :
Type.
Variable f :
A ->
option B.
Function initass (
l :
list A) :
list (
A *
B) :=
match l with
|
nil =>
nil
|
a ::
q =>
match f a with
|
None =>
initass q
|
Some b => (
a,
b) ::
initass q
end
end.
Lemma initass_assoc_none :
forall l a, (
In a l ->
False) ->
assoc A_eq_dec a (
initass l) =
None.
Proof.
intro.
functional induction (
initass l);
simpl.
trivial.
eauto.
intros.
destruct (
A_eq_dec a a0);
eauto.
destruct H;
auto.
Qed.
Lemma initass_assoc :
forall l a,
In a l ->
assoc A_eq_dec a (
initass l) =
f a.
Proof.
intro.
functional induction (
initass l);
simpl.
tauto.
destruct 1.
subst.
destruct (
In_dec A_eq_dec a0 q).
eauto.
rewrite e0;
eauto using initass_assoc_none.
eauto.
intros.
destruct (
A_eq_dec a a0).
congruence.
destruct H;
eauto.
contradiction.
Qed.
End Initass.
Section Remass.
Variable a :
A.
Variable B :
Type.
Function remass (
l :
list (
A *
B)) :
list (
A *
B) :=
match l with
|
nil =>
nil
| (
a',
b') ::
q =>
if A_eq_dec a'
a then remass q else (
a',
b') ::
remass q
end.
Lemma remass_assoc_same :
forall l,
assoc A_eq_dec a (
remass l) =
None.
Proof.
intro.
functional induction (
remass l);
simpl;
auto.
rewrite e0;
auto.
Qed.
Lemma remass_assoc_other :
forall l a',
a <>
a' ->
assoc A_eq_dec a' (
remass l) =
assoc A_eq_dec a'
l.
Proof.
intro.
functional induction (
remass l);
simpl;
auto.
clear e0.
subst.
intros.
rewrite (
IHl0 _ H).
destruct (
A_eq_dec a a');
congruence.
intros.
rewrite (
IHl0 _ H).
trivial.
Qed.
End Remass.
Section Mapass.
Variables B C :
Type.
Variable f :
A ->
B ->
option C.
Function mapass (
l :
list (
A *
B)) :
list (
A *
C) :=
match l with
|
nil =>
nil
| (
a,
b) ::
q =>
match f a b with
|
Some c => (
a,
c) ::
mapass q
|
None =>
remass a (
mapass q)
end
end.
Lemma mapass_none :
forall l a,
assoc A_eq_dec a l =
None ->
assoc A_eq_dec a (
mapass l) =
None.
Proof.
intro.
functional induction (
mapass l);
simpl.
trivial.
intro.
destruct (
A_eq_dec a a0);
try congruence.
eauto.
intro.
destruct (
A_eq_dec a a0);
try congruence.
intros.
erewrite (
remass_assoc_other);
eauto.
Qed.
Lemma mapass_some :
forall l a b,
assoc A_eq_dec a l =
Some b ->
assoc A_eq_dec a (
mapass l) =
f a b.
Proof.
intro.
functional induction (
mapass l);
simpl.
congruence.
intro.
destruct (
A_eq_dec a a0).
congruence.
auto.
intro.
destruct (
A_eq_dec a a0).
injection 1;
intros;
subst.
rewrite e0;
eauto using remass_assoc_same.
erewrite remass_assoc_other;
eauto.
Qed.
End Mapass.
End Ass.
Construction of virtual tables
Section Common.
Variable A :
ATOM.t.
Variable hierarchy :
PTree.t (
Class.t A).
Hypothesis Hhier :
Well_formed_hierarchy.prop hierarchy.
Dynamic cast for non-bases : show that if C is a class defining some behaviour (success or failure) to dyncast to X,
if X is not a base of C, then, for any base B of C, the dynamic cast to X has the same behaviour.
Lemma non_base_dyncast_stable :
forall real c x, (
forall h p,
path hierarchy x p c h ->
False) ->
forall h p h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
forall b l,
path hierarchy b (
c ::
l)
c Class.Inheritance.Repeated ->
dynamic_cast hierarchy real h (
p ++
l)
b x h'
p'.
Proof.
Lemma non_base_dyncast_stable_recip :
forall real c x, (
forall h p,
path hierarchy x p c h ->
False) ->
forall b l,
path hierarchy b (
c ::
l)
c Class.Inheritance.Repeated ->
forall h p,
path hierarchy c p real h ->
forall h'
p',
dynamic_cast hierarchy real h (
p ++
l)
b x h'
p' ->
dynamic_cast hierarchy real h p c x h'
p'.
Proof.
Notation is_dynamic := (
Dynamic.is_dynamic).
Variable COP :
CPPOPTIM A.
Definition OP :=
Optim COP.
Variable vop' :
valop'
A Z.
Hypothesis vop'
_pos :
forall k t, 0 <
vop'
k t.
Function valtype_of_typ (
ty :
Typ.t A) :
valtype A :=
match ty with
|
Typ.atom a =>
tyAtom a
|
Typ.class _ =>
tyPtr _
end.
Definition typ_data k ty :=
vop'
k (
valtype_of_typ ty).
Remark typ_pos :
forall k ty, 0 <
typ_data k ty.
Proof.
unfold typ_data; simpl; eauto.
Qed.
Definition PF :=
Platform (
typ_pos Size) (
typ_pos Align) (
vop'
_pos Size (
tyVptr _)) (
vop'
_pos Align (
tyVptr _)).
Variable offsets :
PTree.t (
LayoutConstraints.t A).
Hypothesis intro :
forall ci o,
offsets !
ci =
Some o ->
class_level_prop OP PF offsets hierarchy ci o.
Hypothesis guard :
forall ci,
offsets !
ci <>
None ->
hierarchy !
ci <>
None.
Hypothesis exis:
forall ci,
hierarchy !
ci <>
None ->
offsets !
ci <>
None.
Hypothesis empty_prop :
forall (
ci :
positive) (
oc :
LayoutConstraints.t A),
offsets !
ci =
Some oc ->
disjoint_empty_base_offsets OP offsets hierarchy ci oc.
Lemma primary_subobject_offset :
forall l d,
is_primary_path offsets (
d ::
l) =
true ->
forall h p hr pr h0 p0, (
h0,
p0) =
concat (
hr,
pr) (
h,
p) ->
last p =
Some d ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p ++
l) ->
forall hyperreal z,
subobject_offset offsets hyperreal p0 =
Some z ->
subobject_offset offsets hyperreal p_ =
Some z.
Proof.
Lemma primary_subobject_offset_recip :
forall l d,
is_primary_path offsets (
d ::
l) =
true ->
forall h p hr pr h0 p0, (
h0,
p0) =
concat (
hr,
pr) (
h,
p) ->
last p =
Some d ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p ++
l) ->
forall hyperreal z,
subobject_offset offsets hyperreal p_ =
Some z ->
subobject_offset offsets hyperreal p0 =
Some z.
Proof.
intros.
assert ((
h,
p ++
l) =
concat (
h,
p) (
Class.Inheritance.Repeated,
d ::
l)).
simpl.
rewrite H1.
destruct (
peq d d);
congruence.
rewrite H4 in H2.
rewrite <-
concat_assoc in H2.
rewrite <-
H0 in H2.
simpl in H2.
refine (
_ (
concat_last _ H0)).
rewrite H1.
intro.
rewrite x in H2.
destruct (
peq d d);
try congruence.
injection H2;
intros;
subst.
destruct p0;
try discriminate.
functional inversion H3;
subst.
unfold subobject_offset.
rewrite H8.
rewrite H10.
rewrite H7.
destruct (
last_correct x).
replace (
i ::
p0 ++
l)
with ((
i ::
p0) ++
l)
in H7 by reflexivity.
rewrite e0 in *.
rewrite app_ass in H7.
simpl in H7.
destruct (
non_virtual_subobject_offset_app_recip H7).
destruct H5.
rewrite (
primary_path_offset intro H)
in H6.
congruence.
destruct p;
try discriminate.
Qed.
Inductive dyncast_offset_spec :
ident -> (
Class.Inheritance.t *
list ident) -> (
Class.Inheritance.t *
list ident) ->
ident ->
option Z ->
Prop :=
|
dyncast_offset_not_base_some :
forall real h p cn,
last p =
Some cn ->
forall x, (
forall h'
p',
path hierarchy x p'
cn h' ->
False) ->
forall h'
p',
dynamic_cast hierarchy real h p cn x h'
p' ->
forall hyperreal hr pr,
path hierarchy real pr hyperreal hr ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p) ->
forall z,
subobject_offset offsets hyperreal p_ =
Some z ->
forall h'
_ p'
_, (
h'
_,
p'
_) =
concat (
hr,
pr) (
h',
p') ->
forall z',
subobject_offset offsets hyperreal p'
_ =
Some z' ->
forall res,
res =
z' -
z ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
p)
x (
Some res)
|
dyncast_offset_not_base_none :
forall real h p cn,
last p =
Some cn ->
forall x, (
forall h'
p',
path hierarchy x p'
cn h' ->
False) ->
(
forall h'
p',
dynamic_cast hierarchy real h p cn x h'
p' ->
False) ->
forall hyperreal hr pr,
path hierarchy real pr hyperreal hr ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
p)
x None
|
dyncast_offset_base_with_primary :
forall p cn,
last p =
Some cn ->
forall x h'
p',
path hierarchy x p'
cn h' ->
forall of,
offsets !
cn =
Some of ->
forall b,
primary_base of =
Some b ->
forall hr pr hyperreal h res,
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
p ++
b ::
nil)
x res ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
p)
x res
.
Lemma dyncast_offset_spec_complete :
forall l d,
is_primary_path offsets (
d ::
l) =
true ->
forall c,
path hierarchy c (
d ::
l)
d Class.Inheritance.Repeated ->
forall x, (
forall h'
p',
path hierarchy x p'
c h' ->
False) ->
forall real h p,
path hierarchy d p real h ->
forall hyperreal pr hr,
path hierarchy real pr hyperreal hr ->
(
forall h'
p',
dynamic_cast hierarchy real h (
p ++
l)
c x h'
p' ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p ++
l) ->
forall z,
subobject_offset offsets hyperreal p_ =
Some z ->
forall h'
_ p'
_, (
h'
_,
p'
_) =
concat (
hr,
pr) (
h',
p') ->
forall z',
subobject_offset offsets hyperreal p'
_ =
Some z' ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
p)
x (
Some (
z' -
z))) /\
((
forall h'
p',
dynamic_cast hierarchy real h (
p ++
l)
c x h'
p' ->
False) ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
p)
x None).
Proof.
Corollary dyncast_offset_spec_reduce_path :
forall c x, (
forall h'
p',
path hierarchy x p'
c h' ->
False) ->
forall real h p,
path hierarchy c p real h ->
forall hyperreal hr pr,
path hierarchy real pr hyperreal hr ->
(
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p) ->
forall z,
subobject_offset offsets hyperreal p_ =
Some z ->
forall h'
_ p'
_, (
h'
_,
p'
_) =
concat (
hr,
pr) (
h',
p') ->
forall z',
subobject_offset offsets hyperreal p'
_ =
Some z' ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
reduce_path offsets p)
x (
Some (
z' -
z))) /\
((
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
False) ->
dyncast_offset_spec hyperreal (
hr,
pr) (
h,
reduce_path offsets p)
x None).
Proof.
Lemma dyncast_offset_spec_func :
forall hyperreal hpr hp x oz1,
dyncast_offset_spec hyperreal hpr hp x oz1 ->
forall oz2,
dyncast_offset_spec hyperreal hpr hp x oz2 ->
oz1 =
oz2.
Proof.
induction 1;
inversion 1;
subst;
try congruence;
replace cn0 with cn in *
by congruence;
try match goal with H :
path _ ?
real ?
hpr _ _,
H0 :
path _ ?
real0 ?
hpr _ _ |-
_ =>
let Hz :=
fresh "
H"
in
(
generalize (
path_last H);
rewrite (
path_last H0);
intro Hz;
injection Hz;
clear Hz;
intro;
subst)
end.
generalize (
Well_formed_hierarchy.dynamic_cast_unique Hhier H1 H15).
congruence.
destruct (
H18 _ _ H1).
destruct (
H0 _ _ H15).
destruct (
H1 _ _ H10).
destruct (
H0 _ _ H10).
destruct (
H10 _ _ H0).
destruct (
H11 _ _ H0).
replace of0 with of in *
by congruence.
replace b0 with b in *
by congruence.
eauto.
Qed.
Lemma dyncast_offset_spec_exists :
forall hyperreal hpr hp x,
{
oz |
dyncast_offset_spec hyperreal hpr hp x oz} + {
forall oz,
dyncast_offset_spec hyperreal hpr hp x oz ->
False}.
Proof.
intros.
case_eq (
hierarchy !
hyperreal).
Focus 2.
intros.
right.
intros.
revert hyperreal hpr hp x oz H0 H.
induction 1;
eauto;
generalize (
path_defined_from H2);
intro;
contradiction.
intros hrc Hhrc.
destruct (
Well_formed_hierarchy.paths Hhier).
invall.
case_eq hpr.
intros.
case_eq (
last l).
Focus 2.
intro.
right.
rewrite <-
H1.
intros.
revert hpr hp x oz H3 H1 H2.
induction 1;
eauto.
injection 1;
intros;
subst.
generalize (
path_last H4);
congruence.
injection 1;
intros;
subst.
generalize (
path_last H4);
congruence.
intros real Hreal.
case_eq (
hierarchy !
real).
Focus 2.
intros.
right.
rewrite <-
H1.
intros.
revert hpr hp x oz H3 H1 real Hreal H2.
induction 1;
eauto;
injection 1;
intros;
subst;
replace real0 with real in *
by (
generalize (
path_last H4);
intros;
congruence);
generalize (
path_defined_to H4);
intro;
contradiction.
intros rc Hrc.
case_eq (
x0 !
real).
Focus 2.
intros.
destruct (
H real).
congruence.
assumption.
intros.
generalize (
H0 _ _ H2).
destruct 1.
case_eq (
t0 !
hyperreal).
Focus 2.
intro.
destruct (
H3 hyperreal).
congruence.
assumption.
intros.
destruct (
H4 _ _ H5 (
t,
l)).
destruct (
In_dec path_eq_dec (
t,
l)
l0).
Focus 2.
right.
intros.
destruct n.
apply H7.
clear Hrc H2 H3 H4 H5 H6 H7 t0 l0.
rewrite <-
H1 in H8.
clear rc.
revert hpr hp x oz H8 t l H1 real Hreal.
induction 1;
eauto;
injection 1;
intros;
subst;
replace real0 with real in *
by (
generalize (
path_last H4);
intros;
congruence);
assumption.
generalize (
H6 i).
intro.
clear H2 H3 H4 l0 H5 H6 H7 i.
case_eq hp.
intros.
case_eq (
last l0).
Focus 2.
intro.
right.
inversion 1;
congruence.
intros.
subst.
revert t1 l0 H3 x.
induction i using (
well_founded_induction Plt_wf).
intros.
case_eq (
hierarchy !
x).
Focus 2.
intros.
left.
exists None.
eapply dyncast_offset_not_base_none.
eassumption.
intros.
generalize (
path_defined_to H4).
tauto.
intros.
2 :
eassumption.
assert (
path hierarchy x p'
real h').
inversion H4;
eauto using path_concat.
generalize (
path_defined_to H5).
tauto.
intros.
assert (
hierarchy !
x <>
None)
by congruence.
assert (
x0 !
x <>
None)
by eauto.
case_eq (
x0 !
x);
try congruence.
case_eq (
hierarchy !
i).
Focus 2.
intros.
left.
exists None.
eapply dyncast_offset_not_base_none.
eassumption.
intros.
generalize (
path_defined_from H9).
tauto.
intros.
2 :
eassumption.
assert (
path hierarchy i l0 real t1).
inversion H9;
subst;
eauto using path_concat.
generalize (
path_defined_to H10).
tauto.
intros.
assert (
hierarchy !
i <>
None)
by congruence.
destruct (
H0 _ _ H7).
assert (
t4 !
i <>
None)
by eauto.
case_eq (
t4 !
i);
try congruence.
destruct l1.
intros.
generalize (
fun k p =>
let (
_,
l) :=
H11 _ _ H13 (
k,
p)
in l).
simpl.
intros.
destruct (
Well_formed_hierarchy.dynamic_cast_dec Hhier real t1 l0 i x).
invall.
assert (
path hierarchy i l0 real t1).
inversion H16;
subst;
eauto using path_concat.
assert (
path hierarchy x x2 real x1).
inversion H16;
eauto using path_concat.
case_eq (
concat (
t,
l) (
t1,
l0)).
intros.
symmetry in H18.
refine (
_ (
subobject_offset_exist Hhier intro guard _ (
Plt_succ _) (
path_concat H8 H15 H18))).
2 :
eauto.
case_eq (
subobject_offset offsets hyperreal l1);
try congruence.
case_eq (
concat (
t,
l) (
x1,
x2)).
intros.
symmetry in H19.
refine (
_ (
subobject_offset_exist Hhier intro guard _ (
Plt_succ _) (
path_concat H8 H17 H19))).
2 :
eauto.
case_eq (
subobject_offset offsets hyperreal l2);
try congruence.
intros.
left.
exists (
Some (
z0 -
z)).
eapply dyncast_offset_not_base_some.
eassumption.
assumption.
eassumption.
assumption.
eassumption.
eassumption.
eassumption.
eassumption.
reflexivity.
left.
exists None.
eapply dyncast_offset_not_base_none.
eassumption.
assumption.
eassumption.
assumption.
intro.
destruct (
H11 _ _ H13 p).
generalize (
H14 (
or_introl _ (
refl_equal _))).
destruct p.
intros.
assert (
offsets !
i <>
None)
by eauto.
case_eq (
offsets !
i);
try congruence.
intros.
case_eq (
primary_base t6).
intros.
generalize (
non_virtual_primary_base_offset (
intro H18)
H19).
intros.
assert ((
non_virtual_direct_base_offsets t6) !
i0 <>
None)
by congruence.
generalize (
non_virtual_direct_base_offsets_guard (
intro H18)
H21 H6).
intros.
assert (
Plt i0 i)
by eauto using Well_formed_hierarchy.well_founded.
assert (
last (
l0 ++
i0 ::
nil) =
Some i0)
by eauto using last_complete.
destruct (
H1 _ H23 t1 _ H24 x).
invall.
left.
exists x1.
eapply dyncast_offset_base_with_primary.
eassumption.
eassumption.
eassumption.
eassumption.
assumption.
right.
inversion 1;
subst;
replace cn with i in *
by congruence.
destruct (
H31 _ _ H16).
destruct (
H32 _ _ H16).
replace i0 with b in *
by congruence.
destruct (
f _ H37).
right.
inversion 1;
intros;
subst;
replace cn with i in *
by congruence.
destruct (
H26 _ _ H16).
destruct (
H27 _ _ H16).
congruence.
Qed.
Definition dyncast_offset (
hyperreal :
ident) (
hpr hp : (
Class.Inheritance.t *
list ident)) (
x :
ident) :
option Z :=
match dyncast_offset_spec_exists hyperreal hpr hp x with
|
inleft (
Coq.Init.Specif.exist oz _) =>
oz
|
_ =>
None
end.
Corollary dyncast_offset_reduce_path :
forall c x, (
forall h'
p',
path hierarchy x p'
c h' ->
False) ->
forall real h p,
path hierarchy c p real h ->
forall hyperreal hr pr,
path hierarchy real pr hyperreal hr ->
(
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p) ->
forall z,
subobject_offset offsets hyperreal p_ =
Some z ->
forall h'
_ p'
_, (
h'
_,
p'
_) =
concat (
hr,
pr) (
h',
p') ->
exists z',
subobject_offset offsets hyperreal p'
_ =
Some z' /\
dyncast_offset hyperreal (
hr,
pr) (
h,
reduce_path offsets p)
x = (
Some (
z' -
z))) /\
((
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
False) ->
dyncast_offset hyperreal (
hr,
pr) (
h,
reduce_path offsets p)
x =
None).
Proof.
Virtual function dispatch
Theorem final_overrider_base :
forall ms ac1 rc rck1 rcp1 rk1 rp1,
final_overrider hierarchy ms ac1 rc rck1 rcp1 rk1 rp1 ->
forall ac2 k12 p12,
path hierarchy ac2 p12 ac1 k12 ->
forall rck2 rcp2, (
rck2,
rcp2) =
concat (
rck1,
rcp1) (
k12,
p12) ->
forall rk2 rp2,
final_overrider hierarchy ms ac2 rc rck2 rcp2 rk2 rp2 ->
final_overrider hierarchy ms ac2 rc rck2 rcp2 rk1 rp1
.
Proof.
Then, as method dispatch succeeds only if the final overrider for a class is unique, we have the following result: if a class *and one of its bases* dispatch to a method, then they dispatch to the same method.
Corollary method_dispatch_base :
forall ms ac1 rc rck1 rcp1 rk1 rp1,
method_dispatch hierarchy ms ac1 rc rck1 rcp1 rk1 rp1 ->
forall ac2 k12 p12,
path hierarchy ac2 p12 ac1 k12 ->
forall rck2 rcp2, (
rck2,
rcp2) =
concat (
rck1,
rcp1) (
k12,
p12) ->
forall rk2 rp2,
method_dispatch hierarchy ms ac2 rc rck2 rcp2 rk2 rp2 -> (
rk1,
rp1) = (
rk2,
rp2).
Proof.
inversion 1;
subst.
inversion 3;
subst.
symmetry.
eapply H14.
eauto using final_overrider_base.
Qed.
Section Generalize_to_primary_paths.
Variable U :
Type.
Variable f :
list ident ->
option U.
Definition llt := (
fun l1 l2 =>
match last l1,
last l2 with
|
Some e1,
Some e2 =>
Plt e1 e2
|
_,
_ =>
False
end
).
Lemma primary_base_lt :
forall b o,
offsets !
b =
Some o ->
forall b',
primary_base o =
Some b' ->
Plt b'
b.
Proof.
Function genprim (
l :
list positive) {
wf llt l} :
option U :=
match last l with
|
None =>
None
|
Some las =>
match f l with
|
Some o =>
Some o
|
None =>
match offsets !
las with
|
None =>
None
|
Some of =>
match primary_base of with
|
None =>
None
|
Some las' =>
genprim (
l ++
las' ::
nil)
end
end
end
end.
Proof.
intros.
unfold llt.
rewrite last_complete.
rewrite teq.
eauto using primary_base_lt.
unfold well_founded.
unfold llt.
intro.
var (
match last a with Some ll =>
Psucc ll |
_ =>
xH end).
revert v a H.
induction v using (
well_founded_induction Plt_wf).
intros.
case_eq (
last a).
intros.
rewrite H1 in H0.
subst.
constructor.
intro.
case_eq (
last y).
rewrite H1.
intros.
eapply H.
2 :
rewrite H0.
2 :
reflexivity.
unfold Plt in *.
rewrite Psucc_Zsucc.
rewrite Psucc_Zsucc.
unfold Zsucc.
omega.
tauto.
intro.
rewrite H1 in H0.
subst.
constructor.
intro.
case_eq (
last y).
rewrite H1;
tauto.
tauto.
Qed.
Hypothesis f_primary :
forall l o,
f l =
Some o ->
forall a,
last l =
Some a ->
forall l',
is_primary_path offsets (
a ::
l') =
true ->
is_valid_repeated_subobject hierarchy (
a ::
l') =
true ->
forall o',
f (
l ++
l') =
Some o' ->
o =
o'.
Lemma genprim_complete :
forall l a,
last l =
Some a ->
forall l',
is_primary_path offsets (
a ::
l') =
true ->
is_valid_repeated_subobject hierarchy (
a ::
l') =
true ->
forall o,
f (
l ++
l') =
Some o ->
genprim l =
Some o.
Proof.
intros.
revert l'
l a H H0 H1 o H2.
induction l'.
intros.
rewrite <-
app_nil_end in H2.
rewrite genprim_equation.
unfold ident in *.
rewrite H.
rewrite H2.
reflexivity.
intros.
functional inversion H0;
subst.
rewrite genprim_equation.
unfold ident in *.
rewrite H.
case_eq (
f l).
intros.
generalize (
f_primary H3 H H0 H1 H2).
congruence.
intros.
rewrite H9.
rewrite _x0.
functional inversion H1;
subst.
eapply IHl'.
eapply last_complete.
assumption.
assumption.
rewrite app_ass.
assumption.
Qed.
End Generalize_to_primary_paths.
Definition unique (
A :
Type) (
eqd :
forall a1 a2 :
A, {
a1 =
a2} + {
a1 <>
a2})
l :=
if at_most_list eqd l then false else true.
Section Dispatch.
Variable compile_method_name :
ident ->
MethodSignature.t A ->
ident.
Function dispfunc_naive (
ms :
MethodSignature.t A) (
hyperreal :
ident) (
hr :
Class.Inheritance.t) (
pr :
list ident) (
h :
Class.Inheritance.t) (
p :
list ident) :
option ident :=
match last pr with
|
None =>
None
|
Some real =>
match last p with
|
None =>
None
|
Some apparent =>
let (
l,
_) :=
Well_formed_hierarchy.final_overrider_list Hhier ms apparent real h p in
if unique (
path_eq_dec )
l then
match l with
|
nil =>
None
| (
h',
p') ::
_ =>
match last p'
with
|
None =>
None
|
Some cl =>
Some (
compile_method_name cl ms)
end
end
else
None
end
end.
Lemma dispfunc_naive_primary :
forall (
ms :
MethodSignature.t A) (
hyperreal :
ident) (
hr :
Class.Inheritance.t) (
pr :
list ident) (
h :
Class.Inheritance.t) (
p :
list ident)
o,
dispfunc_naive ms hyperreal hr pr h p =
Some o ->
forall a,
last p =
Some a ->
forall l',
is_primary_path offsets (
a ::
l') =
true ->
is_valid_repeated_subobject hierarchy (
a ::
l') =
true ->
forall o',
dispfunc_naive ms hyperreal hr pr h (
p ++
l') =
Some o' ->
o =
o'.
Proof.
intros.
functional inversion H;
subst.
functional inversion H3;
subst.
replace a with apparent in *
by congruence.
assert (
last (
apparent ::
l') =
Some apparent0).
destruct (
last_correct H6).
subst.
rewrite app_ass in H11.
simpl in H11.
assert (
apparent ::
l' <>
nil)
by congruence.
generalize (
last_app_left H4 x).
rewrite H11.
congruence.
destruct (
last_correct H4).
generalize (
let (
H,
_) :=
_x _ _ in H (
or_introl _ (
refl_equal _))).
intro.
generalize (
let (
H,
_) :=
_x1 _ _ in H (
or_introl _ (
refl_equal _))).
intro.
clear H12 H7.
replace real0 with real in *
by congruence.
refine (
_ (
final_overrider_base H14 _ _ H16)).
intro.
unfold unique in H13.
destruct (
at_most_list path_eq_dec ((
h'0,
p'0) ::
_x2)).
discriminate.
generalize (
e0 _ (
or_introl _ (
refl_equal _))
_ (
let (
_,
K) :=
_x1 _ _ in K x0)).
congruence.
eleft.
reflexivity.
eassumption.
assumption.
simpl.
rewrite H6.
destruct (
peq apparent apparent);
congruence.
Qed.
Definition dispfunc hyperreal hr pr rck1 rcp1 ms :=
genprim (
dispfunc_naive ms hyperreal hr pr rck1)
rcp1.
Corollary dispfunc_reduce_path :
forall ms ac1 real rck1 rcp1 rk1 rp1,
method_dispatch hierarchy ms ac1 real rck1 rcp1 rk1 rp1 ->
forall pr,
last pr =
Some real ->
forall hyperreal hr,
exists cn,
last rp1 =
Some cn /\
dispfunc hyperreal hr pr rck1 (
reduce_path offsets rcp1)
ms =
Some (
compile_method_name cn ms).
Proof.
unfold dispfunc.
inversion 1;
subst.
intros.
inversion H4;
subst.
rewrite (
path_last H13).
destruct (
reduce_path_prefix offsets Hhier H7).
esplit.
split.
reflexivity.
invall.
eapply genprim_complete.
eauto using dispfunc_naive_primary.
unfold ident in *.
eauto using path_last.
eassumption.
inversion H19;
assumption.
rewrite <-
H20.
unfold dispfunc_naive.
rewrite H6.
rewrite (
path_last H7).
destruct (
Well_formed_hierarchy.final_overrider_list Hhier ms ac1 real rck1 rcp1
).
unfold unique.
destruct (
at_most_list path_eq_dec x1).
destruct s.
destruct s.
invall.
destruct x2.
destruct x3.
generalize (
let (
K,
_) :=
i _ _ in K H21).
generalize (
let (
K,
_) :=
i _ _ in K H24).
intros.
generalize (
H5 _ _ H23).
generalize (
H5 _ _ H26).
congruence.
destruct x1.
destruct (
let (
_,
K) :=
i _ _ in K H4).
destruct p1.
generalize (
e _ (
or_introl _ (
refl_equal _))
_ (
let (
_,
K) :=
i _ _ in K H4)).
injection 1;
intros;
subst t l.
rewrite (
path_last H13).
reflexivity.
Qed.
End Dispatch.
Function dispoff_naive (
ms :
MethodSignature.t A) (
hyperreal :
ident) (
hr :
Class.Inheritance.t) (
pr :
list ident) (
h :
Class.Inheritance.t) (
p :
list ident) :
option Z :=
match last pr with
|
None =>
None
|
Some real =>
match last p with
|
None =>
None
|
Some apparent =>
let (
l,
_) :=
Well_formed_hierarchy.final_overrider_list Hhier ms apparent real h p in
if unique (
path_eq_dec )
l then
match l with
|
nil =>
None
| (
h',
p') ::
_ =>
let (
h0,
p0) :=
concat (
hr,
pr) (
h,
p)
in
let (
h'0,
p'0) :=
concat (
hr,
pr) (
h',
p')
in
match subobject_offset offsets hyperreal p0 with
|
None =>
None
|
Some o =>
match subobject_offset offsets hyperreal p'0
with
|
None =>
None
|
Some o' =>
Some (
o' -
o)
end
end
end
else
None
end
end.
Lemma dispoff_naive_primary :
forall (
ms :
MethodSignature.t A) (
hyperreal :
ident) (
hr :
Class.Inheritance.t) (
pr :
list ident) (
h :
Class.Inheritance.t) (
p :
list ident)
o,
dispoff_naive ms hyperreal hr pr h p =
Some o ->
forall a,
last p =
Some a ->
forall l',
is_primary_path offsets (
a ::
l') =
true ->
is_valid_repeated_subobject hierarchy (
a ::
l') =
true ->
forall o',
dispoff_naive ms hyperreal hr pr h (
p ++
l') =
Some o' ->
o =
o'.
Proof.
intros.
functional inversion H;
subst.
functional inversion H3;
subst.
replace a with apparent in *
by congruence.
assert (
last (
apparent ::
l') =
Some apparent0).
destruct (
last_correct H6).
subst.
rewrite app_ass in H14.
simpl in H14.
assert (
apparent ::
l' <>
nil)
by congruence.
generalize (
last_app_left H4 x).
rewrite H14.
congruence.
destruct (
last_correct H4).
generalize (
let (
H,
_) :=
_x _ _ in H (
or_introl _ (
refl_equal _))).
intro.
generalize (
let (
H,
_) :=
_x1 _ _ in H (
or_introl _ (
refl_equal _))).
intro.
clear H15 H7.
replace real0 with real in *
by congruence.
assert ((
h,
p ++
l') =
concat (
h,
p) (
Class.Inheritance.Repeated,
apparent ::
l')).
simpl.
rewrite H6.
destruct (
peq apparent apparent);
congruence.
refine (
_ (
final_overrider_base H17 _ _ H22)).
3 :
eassumption.
intro.
unfold unique in H16.
destruct (
at_most_list path_eq_dec ((
h'1,
p'1) ::
_x2)).
discriminate.
generalize (
e0 _ (
or_introl _ (
refl_equal _))
_ (
let (
_,
K) :=
_x1 _ _ in K x0)).
injection 1;
intros;
subst.
symmetry in H18.
symmetry in H10.
generalize (
primary_subobject_offset H1 H10 H6 H18 H12).
congruence.
eleft;
eauto.
Qed.
Definition dispoff hyperreal hr pr rck1 rcp1 ms :=
genprim (
dispoff_naive ms hyperreal hr pr rck1)
rcp1.
Corollary dispoff_reduce_path :
forall ms ac1 real rck1 rcp1 rk1 rp1,
method_dispatch hierarchy ms ac1 real rck1 rcp1 rk1 rp1 ->
forall hr pr hyperreal,
path hierarchy real pr hyperreal hr ->
forall h0 p0, (
h0,
p0) =
concat (
hr,
pr) (
rck1,
rcp1) ->
forall z,
subobject_offset offsets hyperreal p0 =
Some z ->
forall h'
p', (
h',
p') =
concat (
hr,
pr) (
rk1,
rp1) ->
exists z',
subobject_offset offsets hyperreal p' =
Some z' /\
dispoff hyperreal hr pr rck1 (
reduce_path offsets rcp1)
ms =
Some (
z' -
z).
Proof.
unfold dispoff.
inversion 1;
subst.
intros.
inversion H4;
subst.
generalize (
subobject_offset_exist Hhier intro guard (
fun ci _ =>
exis(
ci :=
ci)) (
Plt_succ _) (
path_concat H6 H16 H9)).
case_eq (
subobject_offset offsets hyperreal p');
try congruence.
intros until 1.
intros _.
esplit.
split.
reflexivity.
destruct (
reduce_path_prefix offsets Hhier H10).
invall.
eapply genprim_complete.
eauto using dispoff_naive_primary.
unfold ident in *.
eauto using path_last.
eassumption.
inversion H23;
assumption.
unfold dispoff_naive.
rewrite (
path_last H6).
rewrite <-
H24.
rewrite (
path_last H10).
destruct (
Well_formed_hierarchy.final_overrider_list Hhier ms ac1 real rck1 rcp1
).
unfold unique.
destruct (
at_most_list path_eq_dec x1).
destruct s.
destruct s.
invall.
destruct x2.
destruct x3.
generalize (
let (
K,
_) :=
i _ _ in K H25).
generalize (
let (
K,
_) :=
i _ _ in K H28).
intros.
generalize (
H5 _ _ H27).
generalize (
H5 _ _ H30).
congruence.
destruct x1.
destruct (
let (
_,
K) :=
i _ _ in K H4).
destruct p2.
generalize (
e _ (
or_introl _ (
refl_equal _))
_ (
let (
_,
K) :=
i _ _ in K H4)).
injection 1;
intros until 2;
subst t l.
rewrite <-
H7.
rewrite <-
H9.
rewrite H8.
rewrite H21.
reflexivity.
Qed.
Virtual base offsets
Function vboffsets (
hyperreal :
ident) (
hr :
Class.Inheritance.t) (
pr :
list ident) (
h :
Class.Inheritance.t) (
p :
list ident) (
vb :
ident) :
option Z :=
let (
h',
p') :=
concat (
hr,
pr) (
h,
p)
in
match subobject_offset offsets hyperreal p'
with
|
None =>
None
|
Some off =>
match offsets !
hyperreal with
|
None =>
None
|
Some o =>
match (
virtual_base_offsets o) !
vb with
|
None =>
None
|
Some off' =>
Some (
off' -
off)
end
end
end
.
Lemma vboffsets_reduce_path :
forall hyperreal hr pr class,
path hierarchy class pr hyperreal hr ->
forall h p cn,
path hierarchy cn p class h ->
forall h0 p0, (
h0,
p0) =
concat (
hr,
pr) (
h,
p) ->
forall z,
subobject_offset offsets hyperreal p0 =
Some z ->
forall vb,
is_virtual_base_of hierarchy vb cn ->
exists o,
offsets !
hyperreal =
Some o /\
exists z', (
virtual_base_offsets o) !
vb =
Some z' /\
vboffsets hyperreal hr pr h (
reduce_path offsets p)
vb =
Some (
z' -
z).
Proof.
Construction of virtual tables
Definition PVTable := (
ident * (
Class.Inheritance.t *
list ident) * (
Class.Inheritance.t *
list ident))%
type.
Definition VBase :=
ident.
Lemma vborder_list_ex :
forall class, {
vb |
exists c, (
hierarchy) !
class =
Some c /\
vborder_list (
hierarchy) (
Class.super c)
vb} + {(
hierarchy ) !
class =
None}.
Proof.
Definition vboffsets_l (
pv :
PVTable) :
list (
VBase *
Z) :=
match pv with
| (
hyperreal, (
hr,
pr), (
h,
p)) =>
match last p with
|
None =>
nil
|
Some c =>
match vborder_list_ex c with
|
inleft (
exist l _) =>
initass (
vboffsets hyperreal hr pr h p)
l
|
_ =>
nil
end
end
end.
Lemma vboffsets_l_complete :
forall hyperreal hr pr class,
path hierarchy class pr hyperreal hr ->
forall h p cn,
path hierarchy cn p class h ->
forall h0 p0, (
h0,
p0) =
concat (
hr,
pr) (
h,
p) ->
forall z,
subobject_offset offsets hyperreal p0 =
Some z ->
forall vb,
is_virtual_base_of hierarchy vb cn ->
exists o,
offsets !
hyperreal =
Some o /\
exists z', (
virtual_base_offsets o) !
vb =
Some z' /\
assoc peq vb (
vboffsets_l (
hyperreal, (
hr,
pr), (
h,
reduce_path offsets p))) =
Some (
z' -
z).
Proof.
Enumerating classes
Definition classes :=
map (@
fst _ _) (
PTree.elements hierarchy).
Lemma classes_complete :
forall i,
hierarchy !
i <>
None ->
In i classes.
Proof.
intros.
case_eq (
hierarchy !
i);
try congruence.
intros.
unfold classes.
change i with (
fst (
i,
t)).
apply in_map.
apply PTree.elements_correct.
assumption.
Qed.
Enumerating paths (in a better way than in CplusWf. Maybe later, this will be merged elsewhere.)
Lemma enum_paths_from :
forall from, {
l |
forall h p,
In (
h,
p)
l <->
exists to,
path hierarchy to p from h
}.
Proof.
induction from using (
well_founded_induction Plt_wf).
case_eq (
hierarchy !
from).
Focus 2.
exists nil.
simpl.
split;
try tauto.
destruct 1.
generalize (
path_defined_from H1).
intro;
contradiction.
intros cfrom Hcfrom.
exists (
remove_dup path_eq_dec
(
(
Class.Inheritance.Repeated,
from ::
nil) ::
flatten
(
map
(
fun hb :
_ *
_ =>
let (
h,
b) :=
hb in
match plt b from with
|
left Hlt =>
let (
l,
_) :=
H _ Hlt in
map (
fun hp =>
concat
(
h,
match h with
|
Class.Inheritance.Repeated =>
from ::
b ::
nil
|
Class.Inheritance.Shared =>
b ::
nil
end
)
hp
)
l
|
_ =>
nil
end
)
(
Class.super cfrom)
)
)
).
intros.
cut (
In (
h,
p)
(
((
Class.Inheritance.Repeated,
from ::
nil)
::
flatten
(
map
(
fun hb :
Class.Inheritance.t *
positive =>
let (
h0,
b) :=
hb in
match plt b from with
|
left Hlt =>
let (
l,
_) :=
H b Hlt in
map
(
fun hp :
Class.Inheritance.t *
list ident =>
concat
(
h0,
match h0 with
|
Class.Inheritance.Repeated =>
from ::
b ::
nil
|
Class.Inheritance.Shared =>
b ::
nil
end)
hp)
l
|
right _ =>
nil
end) (
Class.super cfrom)))) <->
(
exists to :
ident,
path (
A:=
A)
hierarchy to p from h)
).
generalize (
remove_dup_In path_eq_dec
(
((
Class.Inheritance.Repeated,
from ::
nil)
::
flatten
(
map
(
fun hb :
Class.Inheritance.t *
positive =>
let (
h0,
b) :=
hb in
match plt b from with
|
left Hlt =>
let (
l,
_) :=
H b Hlt in
map
(
fun hp :
Class.Inheritance.t *
list ident =>
concat
(
h0,
match h0 with
|
Class.Inheritance.Repeated =>
from ::
b ::
nil
|
Class.Inheritance.Shared =>
b ::
nil
end)
hp)
l
|
right _ =>
nil
end) (
Class.super cfrom))))
(
h,
p)
).
unfold ident.
tauto.
split.
destruct 1.
injection H0;
intros;
subst.
esplit.
eleft with (
lt :=
nil).
reflexivity.
reflexivity.
simpl.
rewrite Hcfrom.
trivial.
destruct (
member_flatten_elim H0).
destruct H1.
destruct (
let (
J,
_) :=
in_map_iff _ _ _ in J H1).
destruct H3.
destruct x0.
destruct (
plt p0 from).
Focus 2.
subst.
contradiction.
destruct (
H p0 p1).
subst.
destruct (
let (
J,
_) :=
in_map_iff _ _ _ in J H2).
destruct H3.
destruct x.
destruct (
let (
J,
_) :=
i _ _ in J H5).
esplit.
eapply path_concat.
2 :
eassumption.
2 :
symmetry;
eassumption.
case_eq (
hierarchy !
p0).
Focus 2.
generalize (
path_defined_from H6).
intros;
contradiction.
intros.
destruct t.
eleft with (
lt :=
from ::
nil).
reflexivity.
reflexivity.
simpl.
rewrite Hcfrom.
cut (
(
if In_dec super_eq_dec (
Class.Inheritance.Repeated,
p0)
(
Class.super cfrom)
then match hierarchy !
p0 with
|
Some _ =>
true
|
None =>
false
end
else false) =
true
);
try tauto.
destruct (
In_dec super_eq_dec (
Class.Inheritance.Repeated,
p0)
(
Class.super cfrom)
);
try contradiction.
rewrite H7.
trivial.
eright.
eleft.
eassumption.
eassumption.
eleft with (
lt :=
nil).
reflexivity.
reflexivity.
simpl.
rewrite H7.
trivial.
reciprocally
destruct 1.
destruct (
path_concat_recip H0).
invall;
subst.
generalize (
Well_formed_hierarchy.self_path_trivial Hhier H0).
injection 1;
intros;
subst;
eauto.
generalize (
H1 _ Hcfrom).
intro;
invall;
subst.
right.
case_eq (
plt x0 from).
Focus 2.
generalize (
Well_formed_hierarchy.well_founded Hhier Hcfrom H3).
intros;
contradiction.
intros.
case_eq (
H _ p0).
intros.
eapply member_flatten_intro.
eapply in_map_iff.
exists (
x1,
x0).
rewrite H4.
rewrite H6.
split.
reflexivity.
assumption.
eapply in_map_iff.
esplit.
split.
symmetry.
eassumption.
eapply i.
eauto.
Qed.
Definition enum_paths_from_weak_2 (
from :
ident) :=
let (
l,
_) :=
enum_paths_from from in l.
Definition enum_paths_from_weak (
from :
ident) (
_ :
Class.t A) :=
enum_paths_from_weak_2 from.
Definition paths_from := (
PTree.map enum_paths_from_weak hierarchy).
Lemma paths_from_complete :
forall from to h p,
path hierarchy to p from h ->
exists l,
paths_from !
from =
Some l /\
In (
h,
p)
l.
Proof.
intros.
unfold paths_from.
rewrite PTree.gmap.
unfold option_map.
generalize (
path_defined_from H).
case_eq (
hierarchy !
from);
try congruence.
intros until 1.
intros _.
esplit.
split.
reflexivity.
unfold enum_paths_from_weak,
enum_paths_from_weak_2.
destruct (
enum_paths_from from).
eapply i.
eauto.
Qed.
Virtual functions of a class and its bases
Definition vf_constr hp :=
match hp with
| (
h,
p) =>
let _ :
Class.Inheritance.t :=
h in
match last p with
|
None =>
nil
|
Some cn =>
match hierarchy !
cn with
|
None =>
nil
|
Some c =>
filter
(
fun ms =>
match Method.find ms (
Class.methods c)
with
|
None =>
false
|
Some m =>
Method.virtual m
end
)
(
map (@
Method.signature A) (
Class.methods c))
end
end
end.
Definition virtual_functions from :=
remove_dup
(@
MethodSignature.eq_dec _)
(
flatten
(
map vf_constr (
enum_paths_from_weak_2 from))
).
Lemma method_find_sig :
forall l ms (
m :
_ A),
Method.find ms l =
Some m ->
Method.signature m =
ms.
Proof.
Lemma virtual_functions_complete :
forall from to p h,
path hierarchy to p from h ->
forall c,
hierarchy !
to =
Some c ->
forall ms m,
Method.find ms (
Class.methods c) =
Some m ->
Method.virtual m =
true ->
In ms (
virtual_functions from).
Proof.
Definition Dispatch :=
MethodSignature.t A.
Section SDispatch.
Variable compile_method_name :
ident ->
MethodSignature.t A ->
ident.
Definition dispfunc_l (
pvtbl :
PVTable) :
list (
Dispatch *
ident) :=
match pvtbl with
| (
hyperreal, (
hr,
pr), (
h,
p)) =>
match last p with
|
None =>
nil
|
Some c =>
initass (
dispfunc compile_method_name hyperreal hr pr h p) (
virtual_functions c)
end
end.
Lemma dispfunc_l_reduce_path :
forall ms ac1 real rck1 rcp1 rk1 rp1,
method_dispatch hierarchy ms ac1 real rck1 rcp1 rk1 rp1 ->
forall pr,
last pr =
Some real ->
forall hyperreal hr,
exists cn,
last rp1 =
Some cn /\
assoc (@
MethodSignature.eq_dec _)
ms (
dispfunc_l (
hyperreal, (
hr,
pr), (
rck1,
reduce_path offsets rcp1))) =
Some (
compile_method_name cn ms).
Proof.
End SDispatch.
Definition dispoff_l (
pvtbl :
PVTable) :
list (
Dispatch *
Z) :=
match pvtbl with
| (
hyperreal, (
hr,
pr), (
h,
p)) =>
match last p with
|
None =>
nil
|
Some c =>
initass (
dispoff hyperreal hr pr h p) (
virtual_functions c)
end
end.
Lemma dispoff_l_reduce_path :
forall ms ac1 real rck1 rcp1 rk1 rp1,
method_dispatch hierarchy ms ac1 real rck1 rcp1 rk1 rp1 ->
forall hr pr hyperreal,
path hierarchy real pr hyperreal hr ->
forall h0 p0, (
h0,
p0) =
concat (
hr,
pr) (
rck1,
rcp1) ->
forall z,
subobject_offset offsets hyperreal p0 =
Some z ->
forall h'
p', (
h',
p') =
concat (
hr,
pr) (
rk1,
rp1) ->
exists z',
subobject_offset offsets hyperreal p' =
Some z' /\
assoc (@
MethodSignature.eq_dec _)
ms (
dispoff_l (
hyperreal, (
hr,
pr), (
rck1,
reduce_path offsets rcp1))) =
Some (
z' -
z).
Proof.
Definition DCast :=
ident.
Definition dyncast_offset_l (
pv :
PVTable) :
list (
DCast *
Z) :=
match pv with
| (
hyperreal,
hpr,
hp) =>
initass (
dyncast_offset hyperreal hpr hp)
classes
end.
Corollary dyncast_offset_l_reduce_path :
forall c x, (
forall h'
p',
path hierarchy x p'
c h' ->
False) ->
forall real h p,
path hierarchy c p real h ->
forall hyperreal hr pr,
path hierarchy real pr hyperreal hr ->
(
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
forall h_ p_, (
h_,
p_) =
concat (
hr,
pr) (
h,
p) ->
forall z,
subobject_offset offsets hyperreal p_ =
Some z ->
forall h'
_ p'
_, (
h'
_,
p'
_) =
concat (
hr,
pr) (
h',
p') ->
exists z',
subobject_offset offsets hyperreal p'
_ =
Some z' /\
assoc peq x (
dyncast_offset_l (
hyperreal, (
hr,
pr), (
h,
reduce_path offsets p))) = (
Some (
z' -
z))) /\
((
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
False) ->
assoc peq x (
dyncast_offset_l (
hyperreal, (
hr,
pr), (
h,
reduce_path offsets p))) =
None).
Proof.
Construction of VTTs
Definition PVTT := (
ident * (
Class.Inheritance.t *
list ident))%
type.
Lemma PVTT_eq_dec :
forall pvtt1 pvtt2 :
PVTT,
{
pvtt1 =
pvtt2} + {
pvtt1 <>
pvtt2}.
Proof.
Definition SubVTT := (
Class.Inheritance.t *
ident)%
type.
Section SubVTT.
Function filter_repeated (
hb :
Class.Inheritance.t *
ident) :
bool :=
match hb with
| (
Class.Inheritance.Repeated,
_) =>
true
|
_ =>
false
end.
Variable (
pvtt :
PVTT) .
Function sub_pvtt_repeated (
hb :
Class.Inheritance.t *
ident) :
option PVTT :=
match hb with
| (
Class.Inheritance.Repeated,
b) =>
if is_dynamic_dec Hhier b
then
match pvtt with
| (
c, (
h,
p)) =>
Some (
c, (
h,
p ++
b ::
nil))
end
else None
|
_ =>
None
end.
Function sub_pvtt_shared (
hb :
Class.Inheritance.t *
ident) :
option PVTT :=
match pvtt with
| (
c, (
Class.Inheritance.Repeated,
d ::
nil)) =>
if peq c d
then
match hb with
| (
Class.Inheritance.Shared,
b) =>
if is_dynamic_dec Hhier b
then
Some (
c, (
Class.Inheritance.Shared,
b ::
nil))
else
None
|
_ =>
None
end
else
None
|
_ =>
None
end.
Definition sub_pvtt :
list (
SubVTT *
PVTT) :=
match pvtt with
| (
c, (
h,
p)) =>
match last p with
|
Some cn =>
match hierarchy !
cn with
|
Some c =>
match vborder_list_ex cn with
|
inleft (
exist l _ ) =>
initass sub_pvtt_repeated (
filter filter_repeated (
Class.super c)) ++
initass sub_pvtt_shared (
map (
pair Class.Inheritance.Shared)
l)
|
_ =>
nil
end
|
_ =>
nil
end
|
_ =>
nil
end
end.
End SubVTT.
Lemma sub_pvtt_non_virtual_complete :
forall from through h p,
path hierarchy through p from h ->
forall to,
is_dynamic hierarchy to ->
forall cl,
hierarchy !
through =
Some cl ->
In (
Class.Inheritance.Repeated,
to) (
Class.super cl) ->
assoc super_eq_dec (
Class.Inheritance.Repeated,
to) (
sub_pvtt (
from, (
h,
p))) =
Some (
from, (
h,
p ++
to ::
nil)).
Proof.
Lemma sub_pvtt_virtual_complete :
forall to,
is_dynamic hierarchy to ->
forall from,
is_virtual_base_of hierarchy to from ->
assoc super_eq_dec (
Class.Inheritance.Shared,
to) (
sub_pvtt (
from, (
Class.Inheritance.Repeated,
from ::
nil))) =
Some (
from, (
Class.Inheritance.Shared,
to ::
nil)).
Proof.
Function is_dynamic_repeated_subobject (
p :
list ident) :
bool :=
match last p with
|
None =>
false
|
Some c =>
if is_dynamic_dec Hhier c then true else false
end.
Function is_reduced_repeated_subobject (
p :
list ident) :
bool :=
if list_eq_dec peq p (
reduce_path offsets p)
then true else false.
Definition VtblPath := (
Class.Inheritance.t *
list ident)%
type.
Definition reduced_dynamic_paths class :=
(
filter
(
fun hp :
_ *
_ =>
let (
_,
p) :=
hp in if is_dynamic_repeated_subobject p then is_reduced_repeated_subobject p else false)
(
enum_paths_from_weak_2 class)).
Lemma reduced_dynamic_paths_complete :
forall to,
is_dynamic hierarchy to ->
forall p,
p =
reduce_path offsets p ->
forall class h,
path hierarchy to p class h ->
In (
h,
p) (
reduced_dynamic_paths class).
Proof.
intros.
unfold reduced_dynamic_paths.
eapply filter_In.
split.
unfold enum_paths_from_weak_2.
destruct (
enum_paths_from class).
refine (
let (
_,
K) :=
i _ _ in K _).
eauto.
unfold is_dynamic_repeated_subobject.
rewrite (
path_last H1).
destruct (
is_dynamic_dec Hhier to);
try contradiction.
unfold is_reduced_repeated_subobject.
destruct (
list_eq_dec peq p (
reduce_path offsets p));
try contradiction.
trivial.
Qed.
Lemma reduced_dynamic_paths_correct :
forall class h p,
In (
h,
p) (
reduced_dynamic_paths class) ->
exists to,
path hierarchy to p class h /\
is_dynamic hierarchy to /\
p =
reduce_path offsets p.
Proof.
unfold reduced_dynamic_paths.
intros.
destruct (
let (
K,
_) :=
filter_In _ _ _ in K H).
unfold enum_paths_from_weak_2 in H0.
destruct (
enum_paths_from class).
destruct (
let (
K,
_) :=
i _ _ in K H0).
unfold is_dynamic_repeated_subobject in H1.
rewrite (
path_last H2)
in H1.
destruct (
is_dynamic_dec Hhier x0);
try discriminate.
unfold is_reduced_repeated_subobject in H1.
destruct (
list_eq_dec peq p (
reduce_path offsets p));
try discriminate.
eauto.
Qed.
Function pvtables (
pvtt :
PVTT) :
list (
VtblPath *
PVTable) :=
match pvtt with
| (
_, (
_,
pr)) =>
match last pr with
|
None =>
nil
|
Some class =>
(
map
(
attach (
pair pvtt))
(
reduced_dynamic_paths class)
)
end
end.
Lemma pvtables_complete :
forall hyperreal hr pr real,
path hierarchy real pr hyperreal hr ->
forall to,
is_dynamic hierarchy to ->
forall h p,
path hierarchy to p real h ->
p =
reduce_path offsets p ->
assoc path_eq_dec (
h,
p) (
pvtables (
hyperreal, (
hr,
pr))) =
Some (
hyperreal, (
hr,
pr), (
h,
p)).
Proof.
Assembling (determining which VTTs and PVTTs to generate)
Definition dynamic_classes :=
filter (
fun c =>
if is_dynamic_dec Hhier c then true else false)
classes.
Lemma dynamic_complete :
forall c,
is_dynamic hierarchy c ->
In c dynamic_classes.
Proof.
Definition InitVTT :=
ident.
Definition init_pvtt :
list (
InitVTT *
PVTT) :=
map (
attach (
fun c => (
c, (
Class.Inheritance.Repeated,
c ::
nil))))
dynamic_classes.
Lemma init_pvtt_complete :
forall c,
is_dynamic hierarchy c ->
assoc peq c init_pvtt =
Some (
c, (
Class.Inheritance.Repeated,
c ::
nil)).
Proof.
Definition VTableAccess :=
ident.
Definition vtable_access (
pv :
PVTable) :
option VTableAccess :=
match pv with
| (
_,
_, (
_,
p)) =>
last p
end.
Function vtable_access_sharing (
v :
VTableAccess) :
option VTableAccess :=
match offsets !
v with
|
None =>
None
|
Some o =>
primary_base o
end.
Definition vtable_access_VBase (
v :
VTableAccess) :=
match vborder_list_ex v with
|
inleft (
exist l _ ) =>
l
|
_ =>
nil
end.
Definition VTTAccess :=
ident.
Definition romty :=
ROMTypes
InitVTT
SubVTT
VTableAccess
VTTAccess
VtblPath
VBase
DCast
Dispatch
PVTT
PVTable
.
Lemma vtable_access_wf :
well_founded (
vtable_access_lt (
romty :=
romty) (
vtable_access_sharing)).
Proof.
Definition vtable compile_method_name (
pv :
PVTable) :=
VTable (
romty :=
romty)
(
vboffsets_l pv)
(
dyncast_offset_l pv)
(
dispfunc_l compile_method_name pv)
(
dispoff_l pv).
Definition vtt (
pvtt :
PVTT) :=
VTT (
romty :=
romty)
(
sub_pvtt pvtt)
(
pvtables pvtt)
.
Section Pseudo_flatten.
Variables U V :
Type.
Function pflatten (
l :
list (
U *
list V)) :
list (
U *
V) :=
match l with
|
nil =>
nil
| (
u,
lv) ::
q =>
map (
pair u)
lv ++
pflatten q
end.
Lemma pflatten_in_complete :
forall l u lv,
In (
u,
lv)
l ->
forall v,
In v lv ->
In (
u,
v) (
pflatten l).
Proof.
intro.
functional induction (
pflatten l);
simpl.
tauto.
intros.
apply in_or_app.
destruct H;
eauto.
left.
injection H;
intros;
subst.
eauto using in_map.
Qed.
End Pseudo_flatten.
Definition all_paths :=
pflatten (
PTree.elements paths_from).
Lemma all_paths_complete :
forall from to p h,
path hierarchy to p from h ->
In (
from, (
h,
p))
all_paths.
Proof.
Definition all_pvtt :
list PVTT :=
filter
(
fun pvtt =>
match pvtt with
| (
_, (
_,
p)) =>
is_dynamic_repeated_subobject p
end
)
all_paths.
Lemma all_pvtt_complete :
forall from to p h,
path hierarchy to p from h ->
is_dynamic hierarchy to ->
In (
from, (
h,
p))
all_pvtt.
Proof.
Definition map_all_pvtt :=
map (
attach vtt)
all_pvtt.
Lemma map_all_pvtt_complete :
forall from to p h,
path hierarchy to p from h ->
is_dynamic hierarchy to ->
assoc PVTT_eq_dec (
from, (
h,
p))
map_all_pvtt =
Some (
vtt (
from, (
h,
p))).
Proof.
Definition extract_pvtables pvtt :=
map (@
snd _ _) (
pvtables pvtt).
Definition all_pvtable :
list PVTable :=
flatten (
map extract_pvtables all_pvtt).
Lemma all_pvtable_complete :
forall hyperreal hr pr from,
path hierarchy from pr hyperreal hr ->
forall to p'
h',
path hierarchy to p'
from h' ->
p' =
reduce_path offsets p' ->
is_dynamic hierarchy to ->
In (
hyperreal, (
hr,
pr), (
h',
p'))
all_pvtable.
Proof.
Definition map_all_pvtable compile_method_name :=
map (
attach (
vtable compile_method_name))
all_pvtable.
Definition PVTable_eq_dec :
forall a1 a2 :
PVTable, {
a1 =
a2} + {
a1 <>
a2}.
Proof.
Lemma map_all_pvtable_complete :
forall hyperreal hr pr from,
path hierarchy from pr hyperreal hr ->
forall to p'
h',
path hierarchy to p'
from h' ->
p' =
reduce_path offsets p' ->
is_dynamic hierarchy to ->
forall compile_method_name,
assoc PVTable_eq_dec (
hyperreal, (
hr,
pr), (
h',
p')) (
map_all_pvtable compile_method_name) =
Some (
vtable compile_method_name (
hyperreal, (
hr,
pr), (
h',
p'))).
Proof.
Function vtt_access (
pv :
PVTT) :
option VTTAccess :=
match pv with
| (
_, (
_,
p)) =>
last p
end.
Definition rom compile_method_name :=
ROMopsemparam (
romty :=
romty)
init_pvtt
peq
map_all_pvtt
PVTT_eq_dec
super_eq_dec
path_eq_dec
(
map_all_pvtable compile_method_name)
PVTable_eq_dec
peq
peq
(
MethodSignature.eq_dec (
A :=
A))
vtable_access
vtable_access_sharing
vtable_access_VBase
virtual_functions
vtt_access
.
We need this decision procedure to prove the invariant. Remember for instance that "Object layout" technical report Theorem 5.4 is split into two parts: the empty part, and the non-empty part.
Variable is_empty_dec : forall cl, {is_empty hierarchy cl} + {~ is_empty OP hierarchy cl}.
End Common.