Module MemErasure.
(** The values of the erased memory may be more defined and its permissions are top.*)
(** In retrospect setting the permissions to top was a bad choice. It should have been that the permissions of the erased memory are above the permissions of the other memory. This would make it more reusable and it wouldn't need a second definition for free. *)
Local Notation "a # b" := (PMap.get b a) (at level 1).
Record mem_erasure (m m': mem) :=
{ perm_le:
forall b ofs k,
Mem.valid_block m' b ->
(Mem.mem_access m')#b ofs k = Some Freeable;
erased_contents: forall b ofs,
memval_erasure (ZMap.get ofs ((Mem.mem_contents m) # b))
(ZMap.get ofs ((Mem.mem_contents m') # b));
erased_nb: Mem.nextblock m = Mem.nextblock m'
}.
Proof with eauto with val_erasure.
intros.
destruct v1,v2; simpl in *; inv Hval_erasure; auto;
unfold Val.cmpu, Val.cmpu_bool; simpl; eauto with val_erasure;
do 2 rewrite andb_if;
repeat match goal with
| [|- context[match ?Expr with | _ => _ end]] =>
destruct Expr eqn:?
end; simpl; eauto with val_erasure.
- eapply mem_erasure_valid_pointer_guard in Heqb2; eauto.
congruence.
- eapply mem_erasure_valid_pointer_guard in Heqb2; eauto.
congruence.
-  subst.
apply andb_false_iff in Heqb3.
destruct Heqb3 as [Heqb3 | Heqb3];
eapply mem_erasure_valid_pointer_guard in Heqb3; eauto;
congruence.
- apply andb_false_iff in Heqb3.
destruct Heqb3 as [Heqb3 | Heqb3].
eapply mem_erasure_valid_pointer in Heqb0; eauto.
exfalso; now eauto.
eapply mem_erasure_valid_pointer in Heqb2; eauto.
exfalso; now eauto.
Qed.

Lemma val_erasure_cmplu:
forall v1 v2 v1' v2' m m' cmp
(Hval_erasure: val_erasure v1 v1')
(Hval_erasure2: val_erasure v2 v2')
(Hmem: mem_erasure m m'),
val_erasure (Val.maketotal (Val.cmplu (Mem.valid_pointer m) cmp v1 v2))
(Val.maketotal (Val.cmplu (Mem.valid_pointer m') cmp v1' v2')).