Module MemoryWD.
(** Valid memories are the ones that do not contain any dangling pointers*)
Definition valid_mem m :=
forall b,
Mem.valid_block m b ->
forall ofs mv,
Maps.ZMap.get ofs (Mem.mem_contents m) # b = mv ->
match mv with
| Fragment v q n =>
mem_wd.val_valid v m
| _ => True
end.
Transparent  Mem.storebytes.
eapply In_valid_memval_list in Hmval_wd; eauto.
simpl in Hmval_wd.
eapply wd_val_valid; eauto.
unfold domain_memren in *.
intros b.
split; intros Hb;
[eapply Mem.storebytes_valid_block_2 in Hb; eauto|
eapply Mem.storebytes_valid_block_1; eauto];
eapply Hdomain; eauto.
+ apply Intv.range_notin in n.
erewrite Mem.setN_outside by eauto.
specialize (Hmem_wd _ Hvalid ofs0 _ ltac:(reflexivity)).
destruct (ZMap.get ofs0 (Mem.mem_contents m) # b0); auto.
eapply valid_val_storebytes; eauto.
simpl.
zify; omega.
- erewrite Maps.PMap.gso by eauto.
specialize (Hmem_wd _ Hvalid ofs0 _ ltac:(reflexivity)).
destruct (ZMap.get ofs0 (Mem.mem_contents m) # b0); subst; auto.
eapply valid_val_storebytes; eauto. }
{ split.
intros. eapply Mem.storebytes_valid_block_2 in H; eauto.
eapply Hdomain; auto.
intros. eapply Mem.storebytes_valid_block_1; eauto.
apply Hdomain; auto.
}
Qed.

(** Loading a value from a well-defined memory returns a valid value*)
Lemma valid_mem_load:
forall chunk m b ofs v f
(Hwd: valid_mem m)
(Hdomain: domain_memren f m)
(Hload: Mem.load chunk m b ofs = Some v),
valid_val f v.