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.

(** Well-definedeness is preserved through storing of a well-defined value *)
Lemma store_wd_domain:
forall (m m' : mem) (chunk : memory_chunk) (v : val) b ofs f
(Hdomain: domain_memren f m)
(Hstore: Mem.store chunk m b ofs v = Some m')
(Hval_wd: mem_wd.val_valid v m)
(Hmem_wd: valid_mem m),
valid_mem m' /\ domain_memren f m'.