(*Lenb: Should Imports from sepcomp really be here?*)
(*Require Import VST.sepcomp.event_semantics. Require Import VST.sepcomp.extspec.*)
(*Lenb: Should stuff that requires Imports from sepcomp really be here?*)
Notation val_inject := Val.inject. (*as in sepcomp.mem_lemmas*)
Definition mem_lessdef m1 m2 :=
(forall b ofs len v,
Mem.loadbytes m1 b ofs len = Some v ->
exists v',
Mem.loadbytes m2 b ofs len = Some v' /\
list_forall2 memval_lessdef v v'
) /\
(forall b ofs k p,
Mem.perm m1 b ofs k p ->
Mem.perm m2 b ofs k p) /\
(Mem.nextblock m1 <=
Mem.nextblock m2)%positive.
Definition mem_lessalloc m1 m2 :=
Mem.loadbytes m1 = Mem.loadbytes m2 /\
Mem.perm m1 = Mem.perm m2 /\
(Mem.nextblock m1 <= Mem.nextblock m2)%positive.
Definition mem_equiv m1 m2 :=
Mem.loadbytes m1 = Mem.loadbytes m2 /\
Mem.perm m1 = Mem.perm m2 /\
Mem.nextblock m1 = Mem.nextblock m2.
Definition mem_equiv' m1 m2 :=
(forall x, Mem.perm_order' (access_at m1 x Cur) Readable -> contents_at m1 x = contents_at m2 x) /\
Mem.perm m1 = Mem.perm m2 /\
Mem.nextblock m1 = Mem.nextblock m2.
Definition mem_lessalloc' m1 m2 :=
(forall x, Mem.perm_order' (access_at m1 x Cur) Readable -> contents_at m1 x = contents_at m2 x) /\
Mem.perm m1 = Mem.perm m2 /\
(Mem.nextblock m1 <= Mem.nextblock m2)%positive.
Ltac memval_lessdef_tac :=
match goal with
| H: memval_lessdef ?a ?b |- _ => destruct a,b; inv H
| H: list_forall2 _ ?a ?b |- _ => destruct a,b; inv H
| H: proj_bytes ?a = Some _ |- _ => match a with context [nil] => inv H end
end;
try discriminate;
try solve [unfold decode_val; simpl; auto] .

Lemma mem_lessdef_loadbytes:
forall m1 m2, mem_lessdef m1 m2 ->
forall b z n v1, Mem.loadbytes m1 b z n = Some v1 ->
exists v2, list_forall2 memval_lessdef v1 v2 /\ Mem.loadbytes m2 b z n = Some v2.