Module infp
Require Import Coq.Program.Equality FSets Permutation.
Require Import FSets FSetAVL Orders Mergesort.
Require Import Coqlib Maps Ordered Errors Integers Floats.
Require Intv.
Require Import AST Linking.
Require Import Values Memory Events Globalenvs Smallstep.
Require Import Switch.
Require Import CUAST Footprint Blockset LDSimDefs_local LDSim_local.
Require Import InteractionSemantics IS_local val_casted InjRels
Op_fp Cminor_op_footprint.
Require Import Cop Cop_fp_local.
Local Open Scope error_monad_scope.
Local Notation empfp:=
FP.emp.
Local Notation footprint:=
FP.t.
Ltac inv_eq:=
repeat match goal with
|
H:?
P ,
H1: ?
P |-
_ =>
clear H
|
H:
context[
match ?
x with _ =>
_ end] |-
_ =>
destruct x eqn:?;
inversion H ;
subst
|
H:?
P = ?
Q,
H1:
context [ ?
P ] |-
_ =>
rewrite H in H1
|
H:?
P = ?
Q |-
context [ ?
P ] =>
rewrite H
end;
simpl in *;
subst;
try contradiction;
try discriminate.
Ltac Hsimpl:=
repeat match goal with
|
H1:?
a,
H2:?
a->?
b|-
_=>
specialize (
H2 H1)
|
H:
_/\
_|-
_=>
destruct H
|
H:
exists _,
_|-
_=>
destruct H
end.
Ltac Esimpl:=
repeat match goal with
|
H:
_|-
_/\
_=>
split
|
H:
_|-
exists _,
_=>
eexists
end.
Definition in_fp (
b:
block)(
ofs:
Z)(
fp:
footprint):
Prop:=
Locs.belongsto fp.(
FP.reads)
b ofs \/
Locs.belongsto fp.(
FP.writes)
b ofs\/
Locs.belongsto fp.(
FP.cmps)
b ofs \/
Locs.belongsto fp.(
FP.frees)
b ofs.
Definition in_fps (
b:
block)(
ofs:
Z)(
fp fp':
footprint):
Prop:=
(
Locs.belongsto fp'.(
FP.reads)
b ofs ->
Locs.belongsto fp.(
FP.reads)
b ofs) /\
(
Locs.belongsto fp'.(
FP.writes)
b ofs ->
Locs.belongsto fp.(
FP.writes)
b ofs) /\
(
Locs.belongsto fp'.(
FP.cmps)
b ofs ->
Locs.belongsto fp.(
FP.cmps)
b ofs) /\
(
Locs.belongsto fp'.(
FP.frees)
b ofs ->
Locs.belongsto fp.(
FP.frees)
b ofs).
Lemma in_empfp:
forall b ofs,
~
in_fp b ofs empfp.
Proof.
unfold in_fp;
intros.
intro.
destruct H as [|[|[|]]];
inv H.
Qed.
Lemma in_fp_split:
forall b ofs fp1 fp2,
in_fp b ofs (
FP.union fp1 fp2)->
in_fp b ofs fp1 \/
in_fp b ofs fp2.
Proof.
Lemma in_fp_union:
forall b ofs fp1 fp2,
in_fp b ofs fp1 ->
in_fp b ofs (
FP.union fp1 fp2).
Proof.
Lemma in_fps_union:
forall b ofs fp1 fp1'
fp2 fp2',
in_fps b ofs fp1 fp1' ->
in_fps b ofs fp2 fp2'->
in_fps b ofs (
FP.union fp1 fp2)(
FP.union fp1'
fp2').
Proof.
Lemma weak_valid_pointer_block_eq:
forall b ofs m b'
ofs',
in_fp b ofs (
MemOpFP.weak_valid_pointer_fp m b'
ofs') ->
b =
b'.
Proof.
Lemma in_fp_subset:
forall b ofs fp1 fp2,
in_fp b ofs fp1->
FP.subset fp1 fp2->
in_fp b ofs fp2.
Proof.
Lemma in_fps_emp:
forall b ofs fp,
in_fps b ofs fp empfp.
Proof.
unfold in_fps;
intros;
Esimpl;
intro;
inv H.
Qed.
Definition fp_match bound (
fp tfp:
footprint):
Prop:=
(
forall b ofs,
Plt b bound->
in_fps b ofs fp tfp).
Lemma fp_match_union:
forall ge fp tfp fp2 tfp2,
fp_match ge fp tfp->
fp_match ge fp2 tfp2->
fp_match ge (
FP.union fp fp2)(
FP.union tfp tfp2).
Proof.
Lemma weak_valid_pointer_eq:
forall m b ofs,
MemOpFP.weak_valid_pointer_fp m b ofs =
{|
FP.cmps:=
if Mem.valid_pointer m b ofs then FMemOpFP.range_locset b ofs 1
else FMemOpFP.range_locset b (
ofs-1) 2 ;
FP.reads:=
Locs.emp;
FP.writes:=
Locs.emp;
FP.frees:=
Locs.emp
|}.
Proof.
Lemma range_locset_belongsto_1:
forall b ofs ofs',
Locs.belongsto (
FMemOpFP.range_locset b (
Ptrofs.unsigned ofs') 1)
b ofs->
Locs.belongsto (
FMemOpFP.range_locset b (
Ptrofs.unsigned ofs' -1) 2)
b ofs.
Proof.
Lemma cmpu_fp_infps:
forall ge f m m'
c v1 v2 v1'
v2'
x v
(
DOMAIN:
forall b,
Plt b ge->
f b =
Some (
b,0))
(
IMAGE:
forall b1 b2 delta,
f b1 =
Some (
b2,
delta) ->
Plt b2 ge ->
b1 =
b2),
Mem.inject f m m'->
Val.inject f v1 v1'->
Val.inject f v2 v2'->
option_map Val.of_bool (
Val.cmpu_bool (
Mem.valid_pointer m)
c v1 v2) =
Some v ->
option_map Val.of_bool (
Val.cmpu_bool (
Mem.valid_pointer m')
c v1'
v2') =
Some x ->
fp_match ge (
cmpu_fp m c v1 v2)(
cmpu_fp m'
c v1'
v2').
Proof.
Lemma unmapped_closed_alloc_1:
forall mu Hm Lm Hm'
lo hi b
(
SVALID:
forall b0 :
block,
Bset.belongsto (
Injections.SharedSrc mu)
b0 ->
Mem.valid_block Hm b0)
(
TVALID:
forall b0 :
block,
Bset.belongsto (
Injections.SharedTgt mu)
b0 ->
Mem.valid_block Lm b0)
(
AGMU:
Bset.inject (
Injections.inj mu) (
Injections.SharedSrc mu) (
Injections.SharedTgt mu)),
MemClosures_local.unmapped_closed mu Hm Lm ->
Mem.alloc Hm lo hi = (
Hm',
b)->
MemClosures_local.unmapped_closed mu Hm'
Lm.
Proof.
Lemma unmapped_closed_alloc_2:
forall mu Hm Lm Lm'
lo hi b
(
SVALID:
forall b0 :
block,
Bset.belongsto (
Injections.SharedSrc mu)
b0 ->
Mem.valid_block Hm b0)
(
TVALID:
forall b0 :
block,
Bset.belongsto (
Injections.SharedTgt mu)
b0 ->
Mem.valid_block Lm b0)
(
AGMU:
Bset.inject (
Injections.inj mu) (
Injections.SharedSrc mu) (
Injections.SharedTgt mu)),
MemClosures_local.unmapped_closed mu Hm Lm ->
Mem.alloc Lm lo hi = (
Lm',
b)->
MemClosures_local.unmapped_closed mu Hm Lm'.
Proof.
Ltac resvalid:=
match goal with
valid blocks
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H':
Mem.free ?
m1 _ _ _ =
Some ?
m2
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
let X :=
fresh in
intros ?
X;
apply H in X;
eapply Mem.valid_block_free_1;
eauto
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H':
Mem.alloc ?
m1 _ _ = (?
m2,
_)
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
let X :=
fresh in
intros ?
X;
apply H in X;
eapply Mem.valid_block_alloc;
eauto
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H':
Mem.store _ ?
m1 _ _ _ =
Some ?
m2
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
let X :=
fresh in
intros ?
X;
apply H in X;
eapply Mem.store_valid_block_1;
eauto
Mem inv
|
H1:
Mem.store _ ?
m1 _ _ _ =
Some ?
m2,
H2:
Mem.store _ ?
m1'
_ _ _ =
Some ?
m2',
H3:
proper_mu _ _ _ _
|-
MemClosures_local.unmapped_closed _ ?
m2 ?
m2'
=>
inv H3;
eapply MemClosures_local.store_val_inject_unmapped_closed_preserved;
try (
rewrite Z.add_0_r);
try eassumption;
try (
compute;
eauto;
fail);
try omega
|
H1:
Mem.free ?
m1 _ _ _ =
Some ?
m2,
H2:
Mem.free ?
m1'
_ _ _ =
Some ?
m2',
H3:
proper_mu _ _ _ _
|-
MemClosures_local.unmapped_closed _ ?
m2 ?
m2'
=>
inv H3;
eapply MemClosures_local.free_inject_unmapped_closed_preserved;
eauto;
try (
rewrite Z.add_0_r);
try eassumption;
try (
compute;
eauto;
fail);
try omega
|
H1:
Mem.alloc ?
m1 _ _ = (?
m2,
_),
H2:
Mem.alloc ?
m1'
_ _ = (?
m2',
_),
H3:
proper_mu _ _ _ _
|-
MemClosures_local.unmapped_closed _ ?
m2 ?
m2'
=>
inv H3;
eapply MemClosures_local.unchanged_on_unmapped_closed_preserved;
eauto;
try (
eapply Mem.alloc_unchanged_on;
eauto;
fail)
|
_ =>
idtac
end.
Lemma freelist_free_unmapped_closed:
forall F1 V1 F2 V2 mu (
ge:
Genv.t F1 V1)(
tge:
Genv.t F2 V2)
Lm f0 sp l (
m m'
x :
mem)
tfn (
z :
Z),
Mem.free_list m l =
Some m' ->
Mem.free Lm sp z tfn =
Some x ->
proper_mu ge tge f0 mu ->
(
forall b :
block,
Bset.belongsto (
Injections.SharedSrc mu)
b ->
Mem.valid_block m b) ->
(
forall b :
block,
Bset.belongsto (
Injections.SharedTgt mu)
b ->
Mem.valid_block Lm b) ->
~
Plt sp (
Genv.genv_next ge) ->
Genv.genv_next ge =
Genv.genv_next tge ->
MemClosures_local.unmapped_closed mu m Lm ->
(
forall (
b :
block) (
lo hi :
Z),
In (
b,
lo,
hi)
l -> ~
Plt b (
Genv.genv_next ge) /\
lo =
z) ->
(
forall (
b :
block) (
lo hi :
Z),
In (
b,
lo,
hi)
l ->
exists delta :
Z,
f0 b =
Some (
sp,
delta)) ->
MemClosures_local.unmapped_closed mu m'
x.
Proof.
clear.
induction l;
intros until z;
intros ? ?
AGMU SVALID TVALID NGE S_EQ RCPRESV R R2.
{
clear R R2.
inv H.
unfold Mem.free_list in H0.
simpl in *.
inv RCPRESV.
econstructor;
eauto.
{
intros.
eapply Mem.perm_free_3 in H2;
eauto.
assert(
b' <>
sp).
intro;
subst.
inv AGMU.
inv proper_mu_ge_init_inj.
rewrite mu_shared_tgt in H;
unfold Bset.belongsto in H.
rewrite<-
S_EQ in H.
contradiction.
Transparent Mem.free.
unfold Mem.free in *.
unfold Mem.unchecked_free in *.
inv_eq.
Opaque Mem.free.
eauto.
}
{
intros.
eapply Mem.perm_free_3 in H2;
eauto.
assert(
b' <>
sp).
intro;
subst.
inv AGMU.
inv proper_mu_ge_init_inj.
rewrite mu_shared_tgt in H;
unfold Bset.belongsto in H.
rewrite<-
S_EQ in H.
contradiction.
Transparent Mem.free.
unfold Mem.free in *.
unfold Mem.unchecked_free in *.
inv_eq.
Opaque Mem.free.
eauto.
}
{
intros.
eapply Mem.perm_free_3 in H2;
eauto.
assert(
b' <>
sp).
intro;
subst.
inv AGMU.
inv proper_mu_ge_init_inj.
rewrite mu_shared_tgt in H;
unfold Bset.belongsto in H.
rewrite<-
S_EQ in H.
contradiction.
Transparent Mem.free.
unfold Mem.free in *.
unfold Mem.unchecked_free in *.
inv_eq.
Opaque Mem.free.
eauto.
}
}
{
simpl in H.
inv_eq.
exploit IHl;
eauto.
intros.
eapply Mem.valid_block_free_1;
eauto.
exploit R2;
eauto.
intros [].
exploit R;
eauto.
intros[].
subst.
inv RCPRESV.
econstructor;
intros.
{
eapply unmapped_closure;
eauto.
intros.
apply H4 in H7 as ?.
intro.
contradict H8.
assert(
b1<>
b).
intro;
subst.
inv AGMU.
apply proper_mu_inject in H7.
inv proper_mu_ge_init_inj.
rewrite mu_shared_src in H7;
unfold Bset.belongsto in H7.
rewrite S_EQ in H7.
contradiction.
eapply Mem.perm_free_1 in Heqo;
eauto.
}
{
eapply unmapped_no_undef;
eauto.
intros.
apply H4 in H6 as ?.
intro.
contradict H7.
assert(
b0<>
b).
intro;
subst.
inv AGMU.
apply proper_mu_inject in H6.
inv proper_mu_ge_init_inj.
rewrite mu_shared_src in H6;
unfold Bset.belongsto in H6.
rewrite S_EQ in H6.
contradiction.
eapply Mem.perm_free_1 in Heqo;
eauto.
}
{
eapply unmapped_no_vundef;
eauto.
intros.
apply H4 in H6 as ?.
intro.
contradict H7.
assert(
b0<>
b).
intro;
subst.
inv AGMU.
apply proper_mu_inject in H6.
inv proper_mu_ge_init_inj.
rewrite mu_shared_src in H6;
unfold Bset.belongsto in H6.
rewrite S_EQ in H6.
contradiction.
eapply Mem.perm_free_1 in Heqo;
eauto.
}
}
Qed.