Module FMemLemmas
Require Import Coqlib InteractionSemantics FMemory FMemOpFP MemOpFP GMemory Footprint Values InteractionSemantics MemAux loadframe AsmLang Cop_fp.
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.
Ltac ex_match:=
repeat match goal with
|
H:
match ?
x with _ =>
_ end =
_ |-
_ =>
destruct x eqn:?
Hx;
try discriminate
end;
try congruence.
Ltac ex_match2:=
repeat match goal with
|
H:
context[
match ?
x with _ =>
_ end] |-
_ =>
destruct x eqn:?
Hx;
try discriminate
|
H:
_ |-
context[
match ?
x with _ =>
_ end ] =>
destruct x eqn:?
Hx;
try discriminate
end;
try congruence.
Lemma eq_access_eq_perm:
forall m1 m2,
(
forall b ofs k,
Memperm.perm_order''
(
Maps.PMap.get b (
GMem.mem_access (
strip m1))
ofs k)
(
Maps.PMap.get b (
GMem.mem_access (
strip m2))
ofs k) /\
Memperm.perm_order''
(
Maps.PMap.get b (
GMem.mem_access (
strip m2))
ofs k)
(
Maps.PMap.get b (
GMem.mem_access (
strip m1))
ofs k))->
(
forall b ofs k,
(
Maps.PMap.get b (
Mem.mem_access m1)
ofs k) = (
Maps.PMap.get b (
Mem.mem_access m2)
ofs k)).
Proof.
Lemma strip_eq_perm:
forall m1 m2 ,
(
forall b ofs k,
(
Maps.PMap.get b (
Mem.mem_access m1)
ofs k) = (
Maps.PMap.get b (
Mem.mem_access m2)
ofs k)) ->
forall chunk b z p,
Mem.valid_access m1 chunk b z p ->
Mem.valid_access m2 chunk b z p.
Proof.
Definition fmem_eq (
m1 m2:
mem) :
Prop :=
GMem.eq (
strip m1) (
strip m2) /\
Mem.freelist m1 =
Mem.freelist m2 /\
Mem.nextblockid m1 =
Mem.nextblockid m2.
Lemma fmem_eq_refl:
forall m,
fmem_eq m m.
econstructor;
eauto.
apply GMem.eq_refl. Defined.
Lemma fmem_eq_sym:forall m1 m2,fmem_eq m1 m2 ->fmem_eq m2 m1. unfold fmem_eq;intros;Hsimpl;Esimpl;eauto. apply GMem.eq_sym. auto. Defined.
Lemma fmem_eq_access_eq:
forall m1 m2 chunk b z p,
fmem_eq m1 m2 ->
Mem.valid_access m1 chunk b z p ->
Mem.valid_access m2 chunk b z p.
Proof.
Record gmem_fl_wd(gm:GMemory.gmem)(fl:freelist)(nextblockid:nat):=
{
freelist_wd0 : forall n n' : nat,
n <> n' -> get_block fl n <> get_block fl n';
valid_wd0 : forall (n : nat) (b : block),
get_block fl n = b ->
List.In b (GMem.validblocks gm)<-> (n < nextblockid)%nat;
}.
Lemma fmem_strip_fl_wd:
forall m,
gmem_fl_wd (strip m) m.(Mem.freelist) m.(Mem.nextblockid).
Proof.
destruct m;constructor;simpl;intros;eauto. Qed.
Lemma gmem_fl_wd_eqrefl:
forall m m',
GMem.eq m m'->
forall fl n,
gmem_fl_wd m fl n->
gmem_fl_wd m' fl n.
Proof.
destruct 2.
split;
auto.
intros.
specialize (
valid_wd1 n0 b H0).
pose proof GMem.eq_validblocks _ _ H.
split;
intro;
try apply valid_wd1;
apply H1;
try apply valid_wd1;
auto.
Qed.
Definition combine(gm:gmem)(fl:freelist)(n:nat)(g:gmem_fl_wd gm fl n):=
Mem.mkmem
(GMem.mem_contents gm)
(GMem.mem_access gm)
(GMem.validblocks gm)
(fl)
(n)
(freelist_wd0 gm fl n g)
(valid_wd0 gm fl n g)
(GMem.access_max gm)
(GMem.invalid_noaccess gm)
(GMem.contents_default gm).
Lemma strip_combine:
forall gm fl n (wd:gmem_fl_wd gm fl n),
strip (combine gm fl n wd) = gm.
Proof.
Lemma gmem_fl_wd_embed:
forall gm fl n (wd:gmem_fl_wd gm fl n),
embed gm fl (combine gm fl n wd).
Proof.
Lemma mem_eq_combine_eq:
forall m1 m2 fl n (wd1:gmem_fl_wd m1 fl n) (Gmemeq:GMem.eq m1 m2),
fmem_eq (combine m1 fl n wd1)(combine m2 fl n (gmem_fl_wd_eqrefl m1 m2 Gmemeq fl n wd1)).
Proof.
Lemma combine_equiv:
forall m l i wd wd',
combine m l i wd = combine m l i wd'.
Proof.
Lemma combine_equiv2:
forall m fl1 fl2 i1 i2 wd1 wd2,
fl1 = fl2 ->
i1 = i2 ->
combine m fl1 i1 wd1= combine m fl2 i2 wd2.
Proof.
Lemma combine_refl:
forall x,
x = combine (strip x)(Mem.freelist x)(Mem.nextblockid x)(fmem_strip_fl_wd x).
Proof.
Lemma eq_mem_eq_fmem:
forall gm1 gm2 fl m1,
GMemory.GMem.eq gm1 gm2 ->
FMemory.embed gm1 fl m1 ->
exists m2,FMemory.embed gm2 fl m2 /\
fmem_eq m1 m2.
Proof.
Local Transparent Mem.load Mem.store Mem.alloc Mem.free.
Lemma fmem_eq_load:
forall m1 m2 chunk b z,
fmem_eq m1 m2 ->
FMemory.Mem.load chunk m1 b z =
FMemory.Mem.load chunk m2 b z.
Proof.
Lemma fmem_alloc_exists:
forall m l h,
exists m' b, Mem.alloc m l h = (m',b).
Proof.
Lemma fmem_eq_alloc:
forall m1 m2 lo hi m1' b1 m2' b2,
fmem_eq m1 m2 ->
FMemory.Mem.alloc m1 lo hi = (m1', b1) ->
FMemory.Mem.alloc m2 lo hi = (m2', b2) ->
fmem_eq m1' m2' /\ b1 = b2.
Proof.
Lemma setN_geteq:
forall i v j z p p',
(i < length v)%nat ->
j = BinInt.Z.of_nat i ->
Maps.ZMap.get (BinInt.Z.add z j) (Mem.setN v z p) = Maps.ZMap.get (BinInt.Z.add z j) (Mem.setN v z p').
Proof.
Lemma Z_of_nat_zify : forall x, BinInt.Z.le 0 x ->BinInt.Z.of_nat (BinInt.Z.to_nat x) = x.
Proof.
Lemma setN_geteq2:
forall ofs v i p p',
BinInt.Z.le i ofs -> BinInt.Z.lt ofs (BinInt.Z.add i (BinInt.Z.of_nat (length v))) ->
Maps.ZMap.get ofs (Mem.setN v i p) =
Maps.ZMap.get ofs (Mem.setN v i p').
Proof.
Lemma fmem_eq_store:
forall m1 m2 chunk b z v m1',
fmem_eq m1 m2 ->
FMemory.Mem.store chunk m1 b z v = Some m1' ->
exists m2', FMemory.Mem.store chunk m2 b z v = Some m2' /\
fmem_eq m1' m2'.
Proof.
Lemma fmem_eq_free:
forall m1 m2 b lo hi m1',
fmem_eq m1 m2 ->
FMemory.Mem.free m1 b lo hi = Some m1' ->
exists m2', FMemory.Mem.free m2 b lo hi = Some m2' /\
fmem_eq m1' m2'.
Proof.
Lemma fmem_eq_valid_pointer:
forall m1 m2 b z,
fmem_eq m1 m2 ->
FMemory.Mem.valid_pointer m1 b z = true <->
FMemory.Mem.valid_pointer m2 b z = true.
Proof.
Lemma fmem_eq_valid_pointer_eq:
forall m1 m2 ,
fmem_eq m1 m2 ->
FMemory.Mem.valid_pointer m1 = FMemory.Mem.valid_pointer m2 .
Proof.
Forward
Lemma alloc_forward:
forall m fl m0 b lo hi m1,
FMemory.embed m fl m0 ->
FMemory.Mem.alloc m0 lo hi = (m1, b) ->
GMemory.GMem.forward m (FMemory.strip m1).
Proof.
Lemma store_forward:
forall m fl m0 chunk b ofs v m1,
FMemory.embed m fl m0 ->
FMemory.Mem.store chunk m0 b ofs v = Some m1 ->
GMemory.GMem.forward m (FMemory.strip m1).
Proof.
Lemma free_forward:
forall m fl m0 b lo hi m1,
FMemory.embed m fl m0 ->
FMemory.Mem.free m0 b lo hi = Some m1 ->
GMemory.GMem.forward m (FMemory.strip m1).
Proof.
embed
Lemma embed_refl:
forall m,
FMemory.embed (FMemory.strip m) (FMemory.Mem.freelist m) m.
Proof.
destruct m; simpl; constructor; auto. Qed.
Lemma fmem_eq_cmpu_bool_fp_eq:
forall m m',
fmem_eq m m'->
Cop_fp.cmpu_bool_fp m' = Cop_fp.cmpu_bool_fp m.
Proof.
Ltac gmem_unfolds:=
try unfold strip in *;
try unfold FMemOpFP.alloc_fp,FMemOpFP.uncheck_alloc_fp,effects in *;
try unfold Locs.belongsto,notbelongsto in *;
try unfold LocalAlloc in *;
try unfold unchanged_content in *;
try unfold unchanged_perm in *;
try unfold unchanged_validity in *;
try unfold GMem.valid_block in *;
try unfold GMem.eq_perm in *;
try unfold GMem.perm in *;
try unfold Mem.nextblock in *;
simpl in *.
Lemma mem_free_fleq:
forall m0 i sz m b,
Mem.free m0 i sz b= Some m->
Mem.freelist m0 = Mem.freelist m.
Proof.
Lemma mem_free_eff:
forall m0 i sz m b0,
Mem.free m0 i sz b0= Some m->
LEffect (strip m0)(strip m)(FMemOpFP.free_fp i sz b0) m0.(Mem.freelist).
Proof.
Lemma mem_alloc_fleq:
forall m0 i sz m b0,
Mem.alloc m0 i sz = (m, b0)->
Mem.freelist m0 = Mem.freelist m.
Proof.
Lemma mem_alloc_eff:
forall m0 i sz m b0,
Mem.alloc m0 i sz = (m, b0)->
LEffect (strip m0)(strip m)(FMemOpFP.alloc_fp m0 i sz) m0.(Mem.freelist).
Proof.
Lemma mem_storev_fleq:
forall m m' a b c,
Mem.storev a m b c = Some m'->
Mem.freelist m = Mem.freelist m'.
Proof.
Lemma mem_storev_eff:
forall m m' a b c,
Mem.storev a m b c = Some m'->
LEffect (strip m)(strip m') (MemOpFP.storev_fp a b)m.(Mem.freelist).
Proof.
Lemma FreelistEq_mem_fl_wd:
forall m gm,
FreelistEq (strip m) gm (Mem.freelist m)->
gmem_fl_wd gm m.(Mem.freelist) m.(Mem.nextblockid).
Proof.
Lemma MemPostemp:
forall m m',
MemPost m m' FP.emp.
Proof.
constructor;gmem_unfolds;Esimpl;try(intros;inv H).
Qed.
Lemma unchanged_perm_access_eq:
forall m1 m2 chunk b z p,
unchanged_perm (belongsto(FMemOpFP.range_locset b z (size_chunk chunk))) (strip m1)(strip m2) ->
Mem.valid_access m1 chunk b z p ->
Mem.valid_access m2 chunk b z p.
Proof.
Lemma range_locset_belongsto:
forall b0 i a (b : Values.block) (ofs : Z),
belongsto
(FMemOpFP.range_locset b0 i a) b
ofs <->
b = b0 /\ i <=ofs < (i + a).
Proof.
Lemma range_locset_belongsto2:
forall i a (b : Values.block) (ofs : Z),
belongsto
(FMemOpFP.range_locset b i a) b
ofs <->
i <=ofs <(i+a).
Proof.
Lemma get_eq_getN_eq:
forall i k p0 p1,
(forall ofs,i <= ofs < i+ Z.of_nat k-> Maps.ZMap.get ofs p0 = Maps.ZMap.get ofs p1) ->
Mem.getN k i p0 = Mem.getN k i p1.
Proof.
intros.
assert(
forall t, (
t<=
k)%
nat->
Mem.getN t (
i+
Z.of_nat (
k-
t))
p0 =
Mem.getN t (
i+
Z.of_nat (
k-
t))
p1).
induction t;
intros;
auto.
assert(
t<=
k)%
nat.
omega.
Hsimpl.
simpl.
assert(
i +
Z.of_nat (
k -
S t) + 1 =
i +
Z.of_nat(
k -
t)).
Lia.lia.
rewrite H2.
clear H2.
rewrite IHt.
f_equal.
apply H.
Lia.lia.
specialize (
H0 k).
assert(
i +
Z.of_nat (
k -
k) =
i).
Lia.lia.
rewrite H1 in H0.
apply H0.
auto.
Qed.
Lemma MemPre_mem_loadv_eq:
forall m m' a b v (Fleq: FreelistEq (strip m) m' (Mem.freelist m)),
MemPre (strip m) m' (FMemOpFP.loadv_fp a b) ->
Mem.loadv a m b = Some v->
Mem.loadv a (combine m' (Mem.freelist m)(Mem.nextblockid m) (FreelistEq_mem_fl_wd _ _ Fleq)) b = Some v.
Proof.
Lemma MemPre_mem_loadv_eq2:
forall m m' a b v (Fleq: FreelistEq (strip m) (strip m') (Mem.freelist m)),
MemPre (strip m) (strip m') (FMemOpFP.loadv_fp a b) ->
Mem.loadv a m b = Some v->
Mem.loadv a m' b = Some v.
Proof.
Lemma MemPost_effect_emp:
forall m m' fp,
Locs.eq (effects fp) Locs.emp ->
MemPost m m' fp.
Proof.
intros.
constructor;gmem_unfolds;Esimpl;intros;Locs.unfolds;inv H0;try congruence.
Qed.
Lemma loadv_fp_emp_effects:
forall a b,
Locs.eq (effects (FMemOpFP.loadv_fp a b)) Locs.emp.
Proof.
Lemma MemPost_loadv_fp:
forall m m' a b,
MemPost m m' (FMemOpFP.loadv_fp a b).
Proof.
Lemma LPre_mem_storev_LPost:
forall m m' m1 a b c
(mempre:MemPre (strip m) m' (FMemOpFP.storev_fp a b))
(Fleq:FreelistEq (strip m) m' (Mem.freelist m)),
Mem.storev a m b c = Some m1 ->
exists m'1, Mem.storev a (combine m' (Mem.freelist m)(Mem.nextblockid m) (FreelistEq_mem_fl_wd m m' Fleq)) b c = Some m'1 /\ LPost (strip m1)(strip m'1)(FMemOpFP.storev_fp a b)(Mem.freelist m) /\ Mem.freelist m'1 = Mem.freelist m1 /\ Mem.nextblockid m'1 = Mem.nextblockid m1.
Proof.
Lemma LPre_mem_storev_LPost2:
forall m m' m1 a b c
(mempre:MemPre (strip m) (strip m') (FMemOpFP.storev_fp a b))
(Fleq:FreelistEq (strip m) (strip m') (Mem.freelist m)),
Mem.freelist m = Mem.freelist m'->
Mem.nextblockid m = Mem.nextblockid m'->
Mem.storev a m b c = Some m1 ->
exists m'1, Mem.storev a m' b c = Some m'1 /\ LPost (strip m1)(strip m'1)(FMemOpFP.storev_fp a b)(Mem.freelist m) /\ Mem.freelist m'1 = Mem.freelist m1 /\ Mem.nextblockid m'1 = Mem.nextblockid m1.
Proof.
Lemma unchanged_perm_cmp:
forall m m' b i,
unchanged_perm (belongsto (FP.cmps (FMemOpFP.weak_valid_pointer_fp m b i)))(strip m)(strip m')->
Mem.valid_pointer m b i = Mem.valid_pointer m' b i.
Proof.
Lemma unchanged_perm_cmp2:
forall m m' b i,
unchanged_perm (belongsto (FP.cmps (FMemOpFP.weak_valid_pointer_fp m b i)))(strip m)(strip m')->
Mem.valid_pointer m b i = false ->
Mem.valid_pointer m b (i-1) = Mem.valid_pointer m' b (i-1).
Proof.
Lemma unchanged_perm_cmp_valid_pointer:
forall m m' b i,
unchanged_perm (belongsto (FP.cmps (FMemOpFP.weak_valid_pointer_fp m b i)))(strip m)(strip m')->
(Mem.valid_pointer m b i|| Mem.valid_pointer m b (i - 1)) = (Mem.valid_pointer m' b i|| Mem.valid_pointer m' b (i - 1)).
Proof.
Lemma unchanged_perm_range_locset_1_valid_pointer:
forall m m' b i,
unchanged_perm (belongsto (FMemOpFP.range_locset b i 1))(strip m)(strip m')->
Mem.valid_pointer m b i = Mem.valid_pointer m' b i.
Proof.
Lemma union_refl_eq: forall l, Locs.union l l = l. intros;eapply Locs.locs_eq. eapply Locs.union_refl. Defined.
Lemma unchanged_perm_split:
forall l1 l2 m m',
unchanged_perm (belongsto (Locs.union l1 l2)) m m'->
unchanged_perm (belongsto l1) m m' /\ unchanged_perm (belongsto l2) m m'.
Proof.
Lemma cmps_union:
forall fp1 fp2,
FP.cmps (FP.union fp1 fp2) = Locs.union (FP.cmps fp1)(FP.cmps fp2).
Proof.
destruct fp1,
fp2;
unfold FP.union;
simpl;
auto. Qed.
Ltac cmpu_bool_destruct_int_fp:=
try destruct Integers.Int.eq eqn:?;try apply Locs.union_refl;eauto;
try destruct Values.eq_block eqn:?;try apply Locs.union_refl;eauto;
try destruct Values.Val.cmp_different_blocks eqn:?;try apply Locs.union_refl;eauto;
try unfold FMemOpFP.weak_valid_pointer_fp ;try unfold FMemOpFP.valid_pointer_fp;eauto;try destruct Mem.valid_pointer eqn:?;try apply Locs.union_refl;eauto.
Ltac cmpu_bool_destruct_b_fp:=
try destruct Values.eq_block;try apply Locs.union_refl;
try unfold FMemOpFP.weak_valid_pointer_fp;try unfold FMemOpFP.valid_pointer_fp;
try destruct Mem.valid_pointer eqn:?;try apply Locs.union_refl;auto.
Lemma MemPre_cmpu_valid_pointer_ceq:
forall m m' i j,
MemPre (strip m)(strip m')(Cop_fp.cmpu_bool_fp_total m Integers.Ceq i j)->
Values.Val.cmpu_bool (Mem.valid_pointer m) Integers.Ceq i j = Values.Val.cmpu_bool (Mem.valid_pointer m') Integers.Ceq i j.
Proof.
Lemma MemPre_cmpu_valid_pointer_eq:
forall m m' c i j,
c = Integers.Clt \/ c = Integers.Ceq->
MemPre (strip m)(strip m')(compare_ints_fp i j m)->
Values.Val.cmpu_bool (Mem.valid_pointer m) c i j = Values.Val.cmpu_bool (Mem.valid_pointer m') c i j.
Proof.
Lemma range_locset_union:
forall b o i1 i2,
Z.lt 0 i2->
Z.lt 0 i1->
Locs.union (FMemOpFP.range_locset b o i1)(FMemOpFP.range_locset b (Z.add o i1) i2) =
FMemOpFP.range_locset b o (Z.add i1 i2).
Proof.
Lemma fp_union_refl_eq:
forall fp,
FP.union fp fp = fp.
Proof.
Lemma MemPre_mem_alloc_LPost:
forall m m0 sz m' b(Memeq:MemPre (strip m) m0 (FMemOpFP.alloc_fp m 0 sz))(Fleq: FreelistEq (strip m) m0 (Mem.freelist m)),
Mem.alloc m 0 sz = (m',b)->
exists m1,
Mem.alloc (combine m0 (Mem.freelist m)(Mem.nextblockid m)(FreelistEq_mem_fl_wd m m0 Fleq)) 0 sz = (m1,b) /\ FMemOpFP.alloc_fp m 0 sz = FMemOpFP.alloc_fp (combine m0 (Mem.freelist m)(Mem.nextblockid m)(FreelistEq_mem_fl_wd m m0 Fleq)) 0 sz /\ LPost (strip m')(strip m1)(FMemOpFP.alloc_fp m 0 sz)(Mem.freelist m).
Proof.
Lemma MemPre_range_perm_eq:
forall m b ofs sz p,
Mem.range_perm m b ofs sz Memperm.Cur p->
forall m',
MemPre (strip m)(strip m')(FMemOpFP.free_fp b ofs sz)->
Mem.range_perm m' b ofs sz Memperm.Cur p.
Proof.
Lemma MemPre_dep_range_perm_eq:
forall m m' fp b sz a p,
MemPre (strip m)(strip m')fp->
Locs.subset (FMemOpFP.range_locset b 0 sz)(depends fp) ->
Mem.range_perm m b 0 sz a p->
Mem.range_perm m' b 0 sz a p.
Proof.
unfold Mem.range_perm.
destruct fp;
simpl;
intros.
apply H1 in H2 as ?.
Locs.unfolds.
assert(
FMemOpFP.range_locset b 0
sz b ofs =
true).
unfold FMemOpFP.range_locset.
destruct Values.eq_block;
auto.
destruct zle,
zlt;
auto;
omega.
specialize (
H0 _ _ H4).
unfold depends in H0.
simpl in H0.
Locs.unfolds.
assert(
cmps b ofs =
true \/
reads b ofs =
true).
destruct cmps,
reads;
auto;
inv H0.
destruct H5.
destruct H as [
_ ?
_].
eapply CmpMemPermExists;
eauto.
destruct H as [?
_ _].
eapply ReadMemEq;
eauto.
Qed.
Lemma MemPre_eff_range_perm_eq:
forall m m' fp b sz a p,
MemPre (strip m)(strip m')fp->
Locs.subset (FMemOpFP.range_locset b 0 sz)(effects fp) ->
Mem.range_perm m b 0 sz a p->
Mem.range_perm m' b 0 sz a p.
Proof.
Lemma LPre_mem_free_LPost:
forall m m0 b i sz m' (Memeq:MemPre (strip m) m0 (FMemOpFP.free_fp b i sz))(Fleq:FreelistEq(strip m) m0 (Mem.freelist m)),
Mem.free m b i sz = Some m'->
exists m0',
Mem.free (combine m0 (Mem.freelist m)(Mem.nextblockid m)(FreelistEq_mem_fl_wd m m0 Fleq)) b i sz = Some m0' /\ LPost (strip m0')(strip m')(FMemOpFP.free_fp b i sz)(Mem.freelist m) /\ Mem.freelist m0' = Mem.freelist m' /\ Mem.nextblockid m0' = Mem.nextblockid m'.
Proof.
Local Transparent Mem.free.
unfold Mem.free,
FMemOpFP.free_fp;
intros.
ex_match.
inv H.
clear Hx.
remember (
combine m0 (
Mem.freelist m)(
Mem.nextblockid m)(
FreelistEq_mem_fl_wd m m0 Fleq))
as m1.
assert(
strip m1 =
m0).
rewrite Heqm1.
rewrite strip_combine.
auto.
rewrite <-
H in *.
eapply MemPre_range_perm_eq in r as r2;
eauto.
destruct Mem.range_perm_dec ;
try congruence.
eexists.
split.
eauto.
simpl.
Esimpl;
eauto;
try(
rewrite Heqm1;
auto;
fail).
constructor.
{
destruct Memeq.
constructor;[
constructor|];
unfold strip,
Mem.unchecked_free,
effects;
simpl;
gmem_unfolds;
eauto;
intros.
rewrite Heqm1;
simpl.
rewrite Locs.emp_union_locs in H0.
apply range_locset_belongsto in H0 as [].
rewrite H0 in *;
clear H0.
rewrite Zplus_minus in H1.
apply r in H1 as ?.
apply r2 in H1 as ?.
apply Mem.perm_valid_block in H0.
apply Mem.perm_valid_block in H2.
rewrite Heqm1 in H2.
unfold Mem.valid_block in *.
simpl in H2.
split;
auto.
rewrite Locs.emp_union_locs in H0.
apply range_locset_belongsto in H0 as [].
rewrite H0,
Maps.PMap.gss,
Maps.PMap.gss.
destruct zle,
zlt;
try omega;
simpl.
split;
auto.
rewrite Locs.emp_union_locs in H0.
apply range_locset_belongsto in H0 as [].
rewrite H0,
Maps.PMap.gss in H1.
destruct zle,
zlt;
try omega;
simpl in H1.
contradiction.
}
{
rewrite Heqm1.
unfold strip,
Mem.unchecked_free,
FreelistEq in *;
gmem_unfolds;
simpl in *.
intros.
eapply Fleq in H0;
eauto.
split;
intro;
apply H0;
auto.
}
Qed.
Lemma LPre_mem_free_LPost2:
forall m m0 b i sz m' (Memeq:MemPre (strip m) (strip m0) (FMemOpFP.free_fp b i sz))(Fleq:FreelistEq(strip m) (strip m0) (Mem.freelist m)),
Mem.free m b i sz = Some m'->
exists m0',
Mem.free m0 b i sz = Some m0' /\ LPost (strip m0')(strip m')(FMemOpFP.free_fp b i sz)(Mem.freelist m).
Proof.
Local Transparent Mem.free.
unfold Mem.free,
FMemOpFP.free_fp;
intros.
ex_match.
inv H.
clear Hx.
eapply MemPre_range_perm_eq in r as r2;
eauto.
destruct Mem.range_perm_dec ;
try congruence.
eexists.
split.
eauto.
simpl.
Esimpl;
eauto;
try(
rewrite Heqm1;
auto;
fail).
constructor.
{
destruct Memeq.
constructor;[
constructor|];
unfold strip,
Mem.unchecked_free,
effects;
simpl;
gmem_unfolds;
eauto;
intros.
rewrite Locs.emp_union_locs in *.
apply range_locset_belongsto in H as [].
rewrite H in *;
clear H.
rewrite Zplus_minus in H0.
apply r in H0 as ?.
apply r2 in H0 as ?.
apply Mem.perm_valid_block in H.
apply Mem.perm_valid_block in H1.
unfold Mem.valid_block in *.
split;
auto.
rewrite Locs.emp_union_locs in H.
apply range_locset_belongsto in H as [].
rewrite H,
Maps.PMap.gss,
Maps.PMap.gss.
destruct zle,
zlt;
try omega;
simpl.
split;
auto.
rewrite Locs.emp_union_locs in H.
apply range_locset_belongsto in H as [].
rewrite H,
Maps.PMap.gss in H0.
destruct zle,
zlt;
try omega;
simpl in H0.
contradiction.
}
{
unfold strip,
Mem.unchecked_free,
FreelistEq in *;
gmem_unfolds;
simpl in *.
intros.
eapply Fleq in H;
eauto.
split;
intro;
apply H;
auto.
}
Qed.
Lemma cmpu_bool_fp_effemp0:
forall m c v i,
Locs.eq (effects (of_optfp (Cop_fp.cmpu_bool_fp m c v i))) Locs.emp.
Proof.
Lemma cmpu_bool_fp_effemp:
forall m c v i,
Locs.eq (effects (Cop_fp.cmpu_bool_fp_total m c v i)) Locs.emp.
Proof.
Lemma LPre_weak_valid_pointer_fp_eq2:
forall m m' c v (Memeq:MemPre (strip m) (strip m') (FMemOpFP.weak_valid_pointer_fp m c v))(Fleq:FreelistEq (strip m) (strip m') (Mem.freelist m)),
FMemOpFP.weak_valid_pointer_fp m' c v = FMemOpFP.weak_valid_pointer_fp m c v.
Proof.
Lemma LPre_weak_valid_pointer_fp_eq:
forall m m' c v (Memeq:MemPre (strip m) m' (FMemOpFP.weak_valid_pointer_fp m c v))(Fleq:FreelistEq (strip m) m' (Mem.freelist m)),
FMemOpFP.weak_valid_pointer_fp (combine m' (Mem.freelist m)(Mem.nextblockid m)(FreelistEq_mem_fl_wd m m' Fleq)) c v = FMemOpFP.weak_valid_pointer_fp m c v.
Proof.
Lemma range_locset_expend1_subset:
forall b i ,
Locs.subset (FMemOpFP.range_locset b i 1)(FMemOpFP.range_locset b (i - 1)2).
Proof.
Lemma locs_subset_union:
forall l l1 l2,
Locs.subset l l1 \/ Locs.subset l l2->
Locs.subset l (Locs.union l1 l2 ).
Proof.
Locs.unfolds.
intros.
destruct H;eapply H in H0;eauto;rewrite H0;auto with bool.
Qed.
Ltac solv_locs:=
match goal with
| H:?q |- ?q => assumption
| H:_|- Locs.subset ?a ?a => apply Locs.subset_refl
| H:_|- Locs.subset _ (Locs.union _ _) => apply locs_subset_union;try (left;solv_locs;fail);try(right;solv_locs;fail)
| H:_|- Locs.subset (FMemOpFP.range_locset ?b ?i 1)(FMemOpFP.range_locset ?b (?i - 1) 2) => eapply range_locset_expend1_subset ;eauto
end.
Lemma MemPre_split:
forall m m' fp1 fp2,
MemPre m m' (FP.union fp1 fp2)->
MemPre m m' fp1 /\ MemPre m m' fp2.
Proof.
Lemma LPre_cmpu_bool_fp_total_eq:
forall m m' c v i (Memeq:MemPre (strip m) m' (Cop_fp.cmpu_bool_fp_total m c v i))(Fleq:FreelistEq (strip m) m' (Mem.freelist m)),
Cop_fp.cmpu_bool_fp_total(combine m' (Mem.freelist m) (Mem.nextblockid m)(FreelistEq_mem_fl_wd m m' Fleq)) c v i = Cop_fp.cmpu_bool_fp_total m c v i.
Proof.
Lemma LPre_cmpu_bool_fp_eq:
forall m m' c v i (Memeq:MemPre (strip m) m' (of_optfp (Cop_fp.cmpu_bool_fp m c v i)))(Fleq:FreelistEq (strip m) m' (Mem.freelist m)),
Cop_fp.cmpu_bool_fp(combine m' (Mem.freelist m) (Mem.nextblockid m)(FreelistEq_mem_fl_wd m m' Fleq)) c v i = Cop_fp.cmpu_bool_fp m c v i.
Proof.