Require Import Zwf.
Require Import Axioms.
Require Import Coqlib.
Require Import Fappli_IEEE_bits.
Require Import Psatz.
Require Intv.
Require Import Maps.
Require Archi.
Require Import AST.
Require Import Integers.
Require Import Floats.
Require Import Values.
Require Import Values_symbolictype.
Require Import Values_symbolic.
Require Export Memtype.
Require Import IntFacts.
Require Import Normalise.
Require Import NormaliseSpec.
Require Export Memdata.
Require Import Alloc.
Require Import Permutation.
Require Import ExprEval.
Require Export Memperm.
Require Import Memory Tactics.
Import Mem.
We lift this equivalence to memories. In addition to the equivalence of the
contents, we demand that permissions, bounds, masks and next blocks are
identical in both memories.
Record mem_rel (
mr:
expr_sym ->
expr_sym ->
Prop) (
m1 m2:
mem) :
Prop :=
mk_mem_equiv
{
mem_contents_eq :
forall (
b :
positive) (
ofs :
ZIndexed.t),
Mem.perm m1 b ofs Cur Readable ->
memval_rel mr
(
ZMap.get ofs (
Mem.mem_contents m1) !!
b)
(
ZMap.get ofs (
Mem.mem_contents m2) !!
b);
mem_access_eq :
forall b, (
Mem.mem_access m1) !!
b = (
Mem.mem_access m2) !!
b;
mem_blocksize_eq :
forall b, (
Mem.mem_blocksize m1) !!
b = (
Mem.mem_blocksize m2) !!
b;
mem_blocktype_eq :
forall b, (
Mem.mem_blocktype m1) !!
b = (
Mem.mem_blocktype m2) !!
b;
mem_mask_eq :
forall b, (
Mem.mem_mask m1) !!
b = (
Mem.mem_mask m2) !!
b;
mem_nextblock_eq :
Mem.nextblock m1 =
Mem.nextblock m2;
mem_nb_extra_eq:
Mem.nb_extra m1 =
Mem.nb_extra m2
}.
Definition mem_equiv :=
mem_rel same_eval.
Definition mem_lessdef :=
mem_rel Val.lessdef.
Lemma mem_equiv_refl:
forall m mr (
WF:
wf_mr mr),
mem_rel mr m m.
Proof.
intros.
inv WF.
constructor;
intros;
simpl;
try tauto.
unfold memval_rel.
split;
eauto.
left;
red.
destr.
Qed.
Lemma perm_rel:
forall m m'
mr (
ME:
mem_rel mr m m')
b ofs k p,
Mem.perm m b ofs k p <->
Mem.perm m'
b ofs k p.
Proof.
intros.
inv ME.
unfold perm.
rewrite <-
mem_access_eq0.
tauto.
Qed.
Lemma mem_equiv_sym:
forall m1 m2,
mem_equiv m1 m2 ->
mem_equiv m2 m1.
Proof.
intros m1 m2 A;
constructor;
intros;
try (
inv A;
congruence).
-
destruct (
mem_contents_eq _ _ _ A b ofs)
as [
B C].
rewrite perm_rel;
eauto.
red;
split;
eauto.
rewrite B;
reflexivity.
unfold same_type_memval in *.
destr.
destr.
-
inv A.
auto.
Qed.
Lemma mem_equiv_trans:
forall m1 m2 m3,
mem_equiv m1 m2 ->
mem_equiv m2 m3 ->
mem_equiv m1 m3.
Proof.
Instance mem_equiv_equi :
RelationClasses.Equivalence mem_equiv.
Proof.
Lemma mem_lessdef_refl:
forall m,
mem_lessdef m m.
Proof.
constructor; intros; simpl; try tauto.
split. constructor.
left; red. destr.
Qed.
Lemma mem_lessdef_trans:
forall m1 m2 m3,
mem_lessdef m1 m2 ->
mem_lessdef m2 m3 ->
mem_lessdef m1 m3.
Proof.
intros m1 m2 m3 A B.
constructor;
try (
inv A;
inv B;
congruence).
-
intros.
destruct (
mem_contents_eq _ _ _ A b ofs)
as [
C D];
auto.
destruct (
mem_contents_eq _ _ _ B b ofs)
as [
E F].
rewrite <-
perm_rel;
eauto.
split.
eapply Val.lessdef_trans;
eauto.
unfold same_type_memval in *;
repeat destr.
destr_in D.
des D.
des F.
right;
red;
intros.
specialize (
C cm em).
rewrite <-
s in C.
inv C;
auto.
simpl.
rewrite H2.
auto.
-
intros.
rewrite (
mem_access_eq _ _ _ A), (
mem_access_eq _ _ _ B);
auto.
Qed.
Instance mem_lessdef_equi :
RelationClasses.PreOrder mem_lessdef.
Proof.
Lemma mem_eq_ld_trans:
forall m1 m2 m3,
mem_equiv m1 m2 ->
mem_lessdef m2 m3 ->
mem_lessdef m1 m3.
Proof.
intros m1 m2 m3 ME MLD.
constructor;
simpl;
intros;
try (
inv ME;
inv MLD;
congruence).
-
destruct (
mem_contents_eq _ _ _ ME b ofs)
as [
A B];
auto.
destruct (
mem_contents_eq _ _ _ MLD b ofs)
as [
C D].
rewrite <-
perm_rel;
eauto.
split;
intros.
eapply Val.lessdef_trans; [|
eauto].
red;
intros;
rewrite A;
constructor.
unfold same_type_memval in *;
repeat destr.
destr_in D.
-
inv ME;
inv MLD.
rewrite mem_access_eq0,
mem_access_eq1;
auto.
Qed.
Lemma compat_mem_rel:
forall mr m m'
(
MR:
mem_rel mr m m')
cm,
compat_m m M32 cm <->
compat_m m'
M32 cm.
Proof.
Lemma good_result_m_rel:
forall mr m m'
e v
(
MR:
mem_rel mr m m'),
good_result_m m e v <->
good_result_m m'
e v.
Proof.
Lemma is_norm_m_rel:
forall mr m m'
e v
(
MR:
mem_rel mr m m'),
is_norm_m m e v <->
is_norm_m m'
e v.
Proof.
Lemma mem_rel_norm:
forall mr m m'
e,
mem_rel mr m m' ->
Mem.mem_norm m e =
Mem.mem_norm m'
e.
Proof.
Lemma valid_block_rel:
forall m m'
mr (
ME:
mem_rel mr m m')
b
(
VB:
Mem.valid_block m b),
Mem.valid_block m'
b.
Proof.
red; intros.
inv ME. rewrite <- mem_nextblock_eq0.
apply VB.
Qed.
Lemma range_perm_mem_rel:
forall mr m m'
b o n k p,
mem_rel mr m m' ->
Mem.range_perm m b o n k p ->
Mem.range_perm m'
b o n k p.
Proof.
red; intros.
red. red.
inv H. rewrite <- mem_access_eq0.
apply H0; auto.
Qed.
Lemma mem_rel_valid_access:
forall mr chunk m m'
b o p,
mem_rel mr m m' ->
Mem.valid_access m chunk b o p ->
Mem.valid_access m'
chunk b o p.
Proof.
intros mr chunk m m' b o p ME VA.
red in VA; red.
destruct VA; split; auto.
red; intros.
red. red.
inv ME.
rewrite <- mem_access_eq0.
apply H; auto.
Qed.
Lemma memval_rel_lf2:
forall mr n o t t'
b,
(
forall (
ofs :
ZIndexed.t),
o <=
ofs <
o +
Z.of_nat n ->
memval_rel mr (
ZMap.get ofs t !!
b)
(
ZMap.get ofs t' !!
b)) ->
list_forall2 (
memval_rel mr)
(
Mem.getN n o t !!
b)
(
Mem.getN n o t' !!
b).
Proof.
induction n; simpl; intros; constructor; auto.
apply H. lia.
apply IHn; auto.
intros; apply H. lia.
Qed.
Lemma mem_rel_load:
forall mr (
WF:
wf_mr mr)
chunk m m'
b o v,
mem_rel mr m m' ->
Mem.load chunk m b o =
Some v ->
exists v',
Mem.load chunk m'
b o =
Some v' /\
mr v v'.
Proof.
Lemma loadv_mem_rel:
forall mr (
WF:
wf_mr mr)
m m'
chunk ptr v,
mem_rel mr m m' ->
Mem.loadv chunk m ptr =
Some v ->
exists v',
Mem.loadv chunk m'
ptr =
Some v' /\
mr v v'.
Proof.
intros mr Wf m m'
chunk ptr v ME LV.
unfold Mem.loadv in *.
revert LV;
destr_cond_match;
try discriminate.
intros.
generalize (
mem_rel_norm _ _ _ ptr ME).
rewrite Heqv0.
intro A;
rewrite <-
A.
eapply mem_rel_load;
eauto.
Qed.
Definition wf_mr_norm (
mr:
expr_sym ->
expr_sym ->
Prop) :
Prop :=
forall m v1 v2 (
REL:
mr v1 v2),
mr (
Eval (
mem_norm m v1)) (
Eval (
mem_norm m v2)).
Lemma wf_mr_norm_se:
wf_mr_norm same_eval.
Proof.
red;
intros.
erewrite (
same_eval_eqm _ _ _ REL);
eauto.
red;
auto.
Qed.
Lemma wf_mr_norm_ld:
wf_mr_norm Val.lessdef.
Proof.
red;
intros.
exploit lessdef_eqm;
eauto.
intro A;
inv A.
rewrite H1;
auto.
rewrite <-
H0;
red;
auto.
Qed.
Lemma rel_norm:
forall mr (
wf:
wf_mr mr) (
wfn:
wf_mr_norm mr)
m m'
v v',
mem_rel mr m m' ->
mr v v' ->
mr (
Eval (
Mem.mem_norm m v)) (
Eval (
Mem.mem_norm m'
v')).
Proof.
intros mr wf wfn m m'
v v'
ME LD.
erewrite mem_rel_norm;
eauto.
Qed.
Lemma loadv_addr_rel:
forall mr (
wf:
wf_mr mr) (
wfn:
wf_mr_norm mr)
m m'
chunk ptr ptr'
v,
mem_rel mr m m' ->
Mem.loadv chunk m ptr =
Some v ->
mr ptr ptr' ->
exists v',
Mem.loadv chunk m'
ptr' =
Some v' /\
mr v v'.
Proof.
intros mr wf wfn m m'
chunk ptr ptr'
v MLD LV VLD.
exploit loadv_mem_rel;
eauto.
intros [
v' [
A B]].
exists v';
split;
auto.
revert A.
unfold Mem.loadv.
generalize (
rel_norm _ wf wfn _ _ _ _ MLD VLD).
rewrite (
mem_rel_norm _ _ _ _ MLD).
des (
mem_norm m'
ptr).
inv wf.
intros.
apply mr_val_refl in H;
try rewrite <-
H;
destr.
Qed.
Lemma mem_rel_loadbytes:
forall mr m m'
b o n v,
mem_rel mr m m' ->
Mem.loadbytes m b o n =
Some v ->
exists v',
Mem.loadbytes m'
b o n =
Some v' /\
list_forall2 (
memval_rel mr)
v v'.
Proof.
Definition opt_mem_rel mr m1 m2 :
Prop :=
match m1,
m2 with
None,
None =>
True
|
Some mm1,
Some mm2 =>
mem_rel mr mm1 mm2
|
_,
_ =>
False
end.
Definition opt_mem_equiv :=
opt_mem_rel same_eval.
Definition opt_mem_lessdef :=
opt_mem_rel Val.lessdef.
Lemma ome_omld:
forall m1 m2,
opt_mem_equiv m1 m2 ->
opt_mem_lessdef m1 m2.
Proof.
intros m1 m2 A.
des m1; des m2; inv A; auto.
constructor; intros; auto.
specialize (mem_contents_eq0 b ofs).
repeat red in mem_contents_eq0.
red; intros.
destruct mem_contents_eq0. auto. split.
- red; intros. rewrite H0; auto.
- destr.
Qed.
Local Notation "
a #
b" := (
PMap.get b a) (
at level 1).
Lemma met_rel:
forall mr (
wf:
wf_mr mr)
i1 i2,
list_forall2 (
memval_rel mr)
i1 i2 ->
forall m b ofs b0 ofs0,
memval_rel mr
(
ZMap.get ofs0 ((
PMap.set b (
setN i1 ofs (
mem_contents m) #
b) (
mem_contents m)) #
b0))
(
ZMap.get ofs0 ((
PMap.set b (
setN i2 ofs (
mem_contents m) #
b) (
mem_contents m)) #
b0)).
Proof.
Transparent store.
Theorem store_int8_zero_ext:
forall mr (
wf:
wf_mr mr)
m b ofs n,
opt_mem_rel mr
(
store Mint8unsigned m b ofs (
Eval (
Vint (
Int.zero_ext 8
n))))
(
store Mint8unsigned m b ofs (
Eval (
Vint n))).
Proof.
Theorem store_int8_sign_ext:
forall mr (
wf:
wf_mr mr)
m b ofs n,
opt_mem_rel mr
(
store Mint8signed m b ofs (
Eval (
Vint (
Int.sign_ext 8
n))))
(
store Mint8signed m b ofs (
Eval (
Vint n))).
Proof.
Theorem store_int16_zero_ext:
forall mr (
wf:
wf_mr mr)
m b ofs n,
opt_mem_rel mr
(
store Mint16unsigned m b ofs (
Eval (
Vint (
Int.zero_ext 16
n))))
(
store Mint16unsigned m b ofs (
Eval (
Vint n))).
Proof.
Theorem store_int16_sign_ext:
forall mr (
wf:
wf_mr mr)
m b ofs n,
opt_mem_rel mr
(
store Mint16signed m b ofs (
Eval (
Vint (
Int.sign_ext 16
n))))
(
store Mint16signed m b ofs (
Eval (
Vint n))).
Proof.
Lemma storebytes_val_rel:
forall mr (
wf:
wf_mr mr)
m1 b ofs bytes m2,
Mem.storebytes m1 b ofs bytes =
Some m2 ->
forall bytes',
list_forall2 (
memval_rel mr)
bytes bytes' ->
exists m2',
Mem.storebytes m1 b ofs bytes' =
Some m2' /\
mem_rel mr m2 m2'.
Proof.
intros mr wf m1 b ofs bytes m2 STORE.
intros bytes'
SE.
generalize (
storebytes_range_perm _ _ _ _ _ STORE).
rewrite (
list_forall2_length SE) .
intro A;
apply (
range_perm_storebytes)
in A.
destruct A.
(
exists x;
split;
auto).
constructor.
-
erewrite storebytes_mem_contents;
eauto.
erewrite (
storebytes_mem_contents _ _ _ _ _ e);
eauto.
intros.
apply memval_rel_set';
auto.
inv wf;
eauto.
intros.
split.
apply mr_refl.
left;
apply same_type_memval_refl.
-
apply Mem.storebytes_access in e.
apply Mem.storebytes_access in STORE.
congruence.
-
Transparent Mem.storebytes.
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE;
simpl;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE;
simpl;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE;
simpl;
auto.
-
apply Mem.nextblock_storebytes in e.
apply Mem.nextblock_storebytes in STORE.
congruence.
-
revert e STORE.
unfold storebytes.
repeat destr.
intros A B;
inv A;
inv B.
reflexivity.
Qed.
Lemma lf2_rel_refl:
forall mr (
wf:
wf_mr mr)
v,
list_forall2 (
memval_rel mr)
v v.
Proof.
intros mr wf;
inv wf;
induction v;
simpl;
intros;
constructor;
eauto.
split.
apply mr_refl.
left;
apply same_type_memval_refl.
Qed.
Lemma memval_rel_set':
forall (
access:
block ->
Z ->
Prop)
mr v v'
ofs o t t'
b b0,
(
o <=
ofs <
o +
Z.of_nat (
length v) ->
memval_rel mr (
ZMap.get ofs t !!
b0) (
ZMap.get ofs t' !!
b0)) ->
(
forall b'
ofs,
b' <>
b \/
o >
ofs \/
ofs >=
o +
Z.of_nat (
length v) ->
access b'
ofs ->
memval_rel mr (
ZMap.get ofs t !!
b') (
ZMap.get ofs t' !!
b')) ->
list_forall2 (
memval_rel mr)
v v' ->
access b0 ofs ->
memval_rel mr
(
ZMap.get
ofs
(
PMap.set b (
Mem.setN v o t !!
b)
t) !!
b0)
(
ZMap.get
ofs
(
PMap.set b (
Mem.setN v'
o t' !!
b)
t') !!
b0).
Proof.
Lemma storebytes_mem_rel:
forall mr (
wf:
wf_mr mr)
m m'
b o v m1,
mem_rel mr m m' ->
Mem.storebytes m b o v =
Some m1 ->
exists m2,
Mem.storebytes m'
b o v =
Some m2 /\
mem_rel mr m1 m2.
Proof.
intros mr wf m m'
b o v m1 ME STORE.
generalize STORE;
intro STORE0.
generalize STORE;
intro STORE1.
apply Mem.storebytes_range_perm in STORE.
generalize (
range_perm_mem_rel _ _ _ _ _ _ _ _ ME STORE).
intros.
destruct (
Mem.range_perm_storebytes _ _ _ _ H).
eexists;
split;
eauto.
constructor;
auto.
-
intros.
apply Mem.storebytes_mem_contents in e.
apply Mem.storebytes_mem_contents in STORE0.
intros.
rewrite e.
rewrite STORE0.
apply memval_rel_set'
with (
access :=
fun b ofs =>
perm m1 b ofs Cur Readable).
+
intros.
eapply mem_contents_eq.
auto.
eapply perm_storebytes_2;
eauto.
+
intros.
eapply mem_contents_eq.
auto.
eapply perm_storebytes_2;
eauto.
+
apply lf2_rel_refl;
auto.
+
auto.
-
apply Mem.storebytes_access in e.
apply Mem.storebytes_access in STORE0.
intro;
inv ME.
rewrite e,
STORE0.
rewrite <-
mem_access_eq0;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE0;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE0;
simpl;
auto.
inv ME;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE0;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE0;
simpl;
auto.
inv ME;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE0;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE0;
simpl;
auto.
inv ME;
auto.
-
apply Mem.nextblock_storebytes in e.
apply Mem.nextblock_storebytes in STORE0.
inv ME;
congruence.
-
revert e STORE0.
unfold storebytes.
repeat destr.
intros A B;
inv A;
inv B.
simpl.
inv ME;
auto.
Qed.
Lemma storebytes_rel:
forall mr (
wf:
wf_mr mr)
m m'
b o v v'
m1,
mem_rel mr m m' ->
Mem.storebytes m b o v =
Some m1 ->
list_forall2 (
memval_rel mr)
v v' ->
exists m2,
Mem.storebytes m'
b o v' =
Some m2 /\
mem_rel mr m1 m2.
Proof.
intros mr wf m m'
b o v v'
m1 ME STORE LF.
generalize STORE;
intro STORE0.
generalize STORE;
intro STORE1.
apply Mem.storebytes_range_perm in STORE.
generalize (
range_perm_mem_rel _ _ _ _ _ _ _ _ ME STORE).
intros.
destruct (
Mem.range_perm_storebytes _ _ _ _ H).
unfold storebytes.
destr.
eexists;
split;
eauto.
constructor;
simpl;
intros;
auto.
-
intros.
apply Mem.storebytes_mem_contents in e.
apply Mem.storebytes_mem_contents in STORE0.
intros.
rewrite STORE0.
apply memval_rel_set'
with (
access :=
fun b ofs =>
perm m b ofs Cur Readable);
auto.
+
intros.
eapply mem_contents_eq.
auto.
eapply perm_storebytes_2;
eauto.
+
intros.
eapply mem_contents_eq.
auto.
auto.
+
eapply perm_storebytes_2;
eauto.
-
apply Mem.storebytes_access in e.
apply Mem.storebytes_access in STORE0.
inv ME.
rewrite STORE0;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE0;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE0;
simpl;
auto.
inv ME;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE0;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE0;
simpl;
auto.
inv ME;
auto.
-
unfold Mem.storebytes in *.
repeat (
revert e;
destr_cond_match;
intuition try discriminate).
repeat (
revert STORE0;
destr_cond_match;
intuition try discriminate).
repeat (
revert e0;
destr_cond_match;
intuition try discriminate).
inv e;
inv STORE0;
simpl;
auto.
inv ME;
auto.
-
apply Mem.nextblock_storebytes in e.
apply Mem.nextblock_storebytes in STORE0.
inv ME;
congruence.
-
revert e STORE0.
unfold storebytes.
repeat destr.
intros A B;
inv A;
inv B.
simpl.
inv ME;
auto.
-
apply list_forall2_length in LF.
congruence.
Qed.
Lemma mk_block_list_rel:
forall mr m m',
mem_rel mr m m' ->
mk_block_list m =
mk_block_list m'.
Proof.
Lemma nb_blocks_used_rel:
forall mr m m',
mem_rel mr m m' ->
nb_boxes_used_m m =
nb_boxes_used_m m'.
Proof.
Lemma alloc_mem_rel:
forall mr (
wf:
wf_mr mr)
m lo hi b m2 bt,
Mem.alloc m lo hi bt =
Some (
m2,
b) ->
forall m',
mem_rel mr m m' ->
exists m2',
Mem.alloc m'
lo hi bt =
Some (
m2',
b) /\
mem_rel mr m2 m2'.
Proof.
intros mr wf m lo hi b m2 bt ALLOC m'
ME.
Transparent Mem.alloc.
unfold Mem.alloc,
Mem.low_alloc in *.
destr_in ALLOC.
inv ALLOC.
destr;
generalize (
nb_blocks_used_rel _ _ _ ME).
eexists;
split;
eauto.
inv ME;
rewrite mem_nextblock_eq0.
f_equal.
inv ME.
constructor;
simpl;
intros;
eauto;
try intuition congruence.
red;
intros;
simpl;
auto.
-
rewrite !
PMap.gsspec.
rewrite mem_nextblock_eq0.
destruct (
peq b (
Mem.nextblock m')).
+
subst.
inv wf;
split.
apply mr_refl.
left;
apply same_type_memval_refl.
+
apply mem_contents_eq0.
unfold perm in *;
simpl in *.
rewrite PMap.gso in H0;
auto.
destr.
-
rewrite !
PMap.gsspec.
rewrite mem_access_eq0;
eauto.
rewrite mem_nextblock_eq0;
eauto.
-
rewrite !
PMap.gsspec.
rewrite mem_nextblock_eq0;
eauto.
eauto.
destr.
-
rewrite !
PMap.gsspec.
rewrite mem_nextblock_eq0;
eauto.
eauto.
destr.
-
rewrite mem_nextblock_eq0.
rewrite !
PMap.gsspec.
destr.
-
intros;
exfalso;
lia.
Qed.
Lemma free_mem_rel:
forall mr b lo hi m m'
m2,
mem_rel mr m m' ->
Mem.free m b lo hi =
Some m2 ->
exists m2',
Mem.free m'
b lo hi =
Some m2' /\
mem_rel mr m2 m2'.
Proof.
Lemma free_list_mem_equiv:
forall mr bl m m'
m2,
mem_rel mr m m' ->
Mem.free_list m bl =
Some m2 ->
exists m2',
Mem.free_list m'
bl =
Some m2' /\
mem_rel mr m2 m2'.
Proof.
induction bl;
simpl;
intros.
inv H0.
eexists;
split;
eauto.
destruct a;
destruct p.
revert H0;
destr_cond_match;
try intuition congruence.
eapply free_mem_rel in Heqo;
eauto.
destruct Heqo as [
m2' [
A B]].
rewrite A.
intros.
eapply IHbl;
eauto.
Qed.
Lemma mem_equiv_same_eval_norm:
forall m m'
e1 e2,
mem_equiv m m' ->
same_eval e1 e2 ->
Mem.mem_norm m e1 =
Mem.mem_norm m'
e2.
Proof.
Lemma mem_rel_drop_perm:
forall m m'
mr (
WF:
wf_mr mr) (
MR:
mem_rel mr m m')
m1 b lo hi p
(
AB:
drop_perm m b lo hi p =
Some m1),
exists m2 ,
drop_perm m'
b lo hi p =
Some m2 /\
mem_rel mr m1 m2.
Proof.
intros.
simp AB.
unfold drop_perm.
destr.
eexists;
split;
eauto.
constructor;
simpl;
auto;
try (
inv MR;
simpl;
auto).
-
unfold perm;
simpl;
intros.
eapply mem_contents_eq0.
rewrite PMap.gsspec in H;
repeat destr_in H.
apply zle_zlt in Heqb0.
generalize (
r _ Heqb0).
intros;
eapply perm_implies;
eauto.
constructor.
-
intros.
rewrite !
PMap.gsspec.
destr.
rewrite mem_access_eq0.
auto.
auto.
-
exfalso;
apply n.
eapply range_perm_mem_rel;
eauto.
Qed.
Lemma store_val_rel:
forall mr (
wf:
wf_mr mr)
m b o chunk v v'
m1,
mr v v' ->
Mem.store chunk m b o v =
Some m1 ->
exists m2,
Mem.store chunk m b o v' =
Some m2 /\
mem_rel mr m1 m2.
Proof.
Lemma store_mem_rel:
forall mr (
wf:
wf_mr mr)
m m'
b o chunk v m1,
mem_rel mr m m' ->
Mem.store chunk m b o v =
Some m1 ->
exists m2,
Mem.store chunk m'
b o v =
Some m2 /\
mem_rel mr m1 m2.
Proof.
Lemma storev_mem_rel:
forall mr (
wf:
wf_mr mr)
m m'
chunk ptr v m2,
mem_rel mr m m' ->
Mem.storev chunk m ptr v =
Some m2 ->
exists m2',
Mem.storev chunk m'
ptr v =
Some m2' /\
mem_rel mr m2 m2'.
Proof.
intros mr wf m m'
chunk ptr v m2 ME ST.
unfold Mem.storev in *.
revert ST;
destr_cond_match;
try discriminate.
intros.
rewrite <- (
mem_rel_norm _ _ _ ptr ME).
rewrite Heqv0.
eapply store_mem_rel;
eauto.
Qed.
Lemma storev_val_rel:
forall mr (
wf:
wf_mr mr)
m chunk ptr v v'
m2,
mr v v' ->
Mem.storev chunk m ptr v =
Some m2 ->
exists m2',
Mem.storev chunk m ptr v' =
Some m2' /\
mem_rel mr m2 m2'.
Proof.
intros mr wf m chunk ptr v v'
m2 SE ST.
unfold Mem.storev in *.
revert ST;
destr_cond_match;
try discriminate.
intros.
eapply store_val_rel;
eauto.
Qed.
Lemma mem_rel_refl:
forall mr (
wf:
wf_mr mr)
m,
mem_rel mr m m.
Proof.
intros;
constructor;
simpl;
intros;
auto.
apply memval_rel_refl;
auto.
Qed.
Lemma store_rel:
forall mr (
wf:
wf_mr mr)
m m'
b o chunk v v'
m1
(
MRel:
mem_rel mr m m')
(
VRel:
mr v v')
(
STORE:
store chunk m b o v =
Some m1),
exists m2,
store chunk m'
b o v' =
Some m2 /\
mem_rel mr m1 m2.
Proof.
Lemma storev_rel:
forall mr (
wf:
wf_mr mr) (
wfn:
wf_mr_norm mr)
m m'
m2 chunk ptr ptr'
v v',
mem_rel mr m m' ->
Mem.storev chunk m ptr v =
Some m2 ->
mr ptr ptr' ->
mr v v' ->
exists m2',
Mem.storev chunk m'
ptr'
v' =
Some m2' /\
mem_rel mr m2 m2'.
Proof.
intros mr wf wfn m m'
m2 chunk ptr ptr'
v v'
MLD STR ALD VLD .
unfold storev in *.
generalize (
rel_norm _ wf wfn _ _ _ _ MLD ALD).
des (
mem_norm m ptr).
inversion wf.
intro H;
apply mr_val_refl in H;
destr.
inv H.
eapply store_rel;
eauto.
Qed.
Lemma mem_lessdef_bounds:
forall mr m m'
b (
MR:
mem_rel mr m m'),
Mem.bounds_of_block m b =
Mem.bounds_of_block m'
b.
Proof.
Lemma mem_lessdef_in_bound_m:
forall mr m m' (
MLD:
mem_rel mr m m'),
forall b o,
Mem.in_bound_m o m b <->
Mem.in_bound_m o m'
b.
Proof.
split;
red;
intros;
inv MLD;
unfold Mem.bounds_of_block.
rewrite <-
mem_blocksize_eq0;
auto.
rewrite mem_blocksize_eq0;
auto.
Qed.
Lemma unchecked_free_mem_rel:
forall mr (
wf:
wf_mr mr)
m1 m1' (
MR:
mem_rel mr m1 m1')
b lo hi,
mem_rel mr (
unchecked_free m1 b lo hi)
(
unchecked_free m1'
b lo hi).
Proof.
intros.
inv MR.
constructor;
simpl;
intros;
auto.
apply mem_contents_eq0.
unfold unchecked_free in H.
unfold perm in H.
simpl in H.
rewrite PMap.gsspec in H;
repeat destr_in H.
rewrite !
PMap.gsspec.
rewrite mem_access_eq0;
auto.
destr.
auto.
rewrite !
PMap.gsspec.
rewrite mem_blocksize_eq0;
auto.
destr;
auto.
Qed.
Lemma storebytes_blocktype:
forall m1 b ofs bytes m2
(
SB:
storebytes m1 b ofs bytes =
Some m2),
mem_blocktype m2 =
mem_blocktype m1.
Proof.
intros;
unfold storebytes in SB.
destr_in SB.
inv SB;
auto.
Qed.
Theorem storebytes_int64_split:
forall m b ofs v m'
x x0
(
H :
store Mint64 m b ofs v =
Some m')
(
SB :
storebytes m b ofs (
encode_val Mint64 v) =
Some m')
(
e :
storebytes m b ofs (
encode_val Mint32 (
if big_endian then Val.hiword v else Val.loword v)) =
Some x)
(
e0 :
storebytes x b (
ofs + 4) (
encode_val Mint32 (
if big_endian then Val.loword v else Val.hiword v)) =
Some x0),
mem_equiv m'
x0.
Proof.
Theorem store_int64_split:
forall m b ofs v m',
store Mint64 m b ofs v =
Some m' ->
exists m1 m2,
store Mint32 m b ofs (
if Archi.big_endian then Val.hiword v else Val.loword v) =
Some m1
/\
store Mint32 m1 b (
ofs + 4) (
if Archi.big_endian then Val.loword v else Val.hiword v) =
Some m2
/\
mem_equiv m'
m2.
Proof.
Lemma storev_int64_split:
forall m ptr v m',
Mem.storev Mint64 m ptr v =
Some m' ->
exists m1 m2,
Mem.storev Mint32 m ptr (
if Archi.big_endian then Val.hiword v else Val.loword v) =
Some m1 /\
Mem.storev Mint32 m1 (
Val.add ptr (
Eval (
Vint (
Int.repr 4))))
(
if Archi.big_endian then Val.loword v else Val.hiword v) =
Some m2 /\
mem_equiv m'
m2.
Proof.
Lemma loadv_se:
forall c m ptr ptr'
v,
Val.lessdef ptr ptr' ->
Mem.loadv c m ptr =
Some v ->
Mem.loadv c m ptr' =
Some v.
Proof.