(** Remove a range of locations from [nm], marking these locations as dead. The range starts at the abstract pointer [p] and has length [sz]. *)
Definition nmem_remove (nm: nmem) (p: aptr) (sz: Z) : nmem :=
match nm with
| NMemDead => NMemDead
| NMem stk gl =>
match p with
| Gl id ofs =>
let iv' :=
match gl!id with
| Some iv => ISet.add (Ptrofs.unsigned ofs) (Ptrofs.unsigned ofs + sz) iv
| None    => ISet.interval (Ptrofs.unsigned ofs) (Ptrofs.unsigned ofs + sz)
end in
NMem stk (PTree.set id iv' gl)
| Stk ofs =>
NMem (ISet.add (Ptrofs.unsigned ofs) (Ptrofs.unsigned ofs + sz) stk) gl
| _ => nm
end
end.

Lemma nlive_remove:
forall bc b ofs p nm sz b' i,
genv_match bc ge ->
bc sp = BCstack ->
pmatch bc b ofs p ->
nlive nm b' i ->
b' <> b \/ i < Ptrofs.unsigned ofs \/ Ptrofs.unsigned ofs + sz <= i ->
nlive (nmem_remove nm p sz) b' i.