(*Lenb: moved to mpred Definition assert := environ -> mpred.  (* Unfortunately can't export this abbreviation through SeparationLogic.v because it confuses the Lift system *)
*)
Definition writable_block (id: ident) (n: Z): assert :=
fun rho =>
EX b: block,  EX sh: Share.t,
!! (writable_share sh /\ ge_of rho id = Some b) && VALspec_range n sh (b, 0).
Fixpoint writable_blocks (bl : list (ident*Z)) : assert :=
match bl with
| nil =>  fun rho => emp
| (b,n)::bl' =>  fun rho => writable_block b n rho * writable_blocks bl' rho
end.
Fixpoint address_mapsto_zeros (sh: share) (n: nat) (adr: address) : mpred :=
match n with
| O => emp
| S n' => address_mapsto Mint8unsigned (Vint Int.zero) sh adr
* address_mapsto_zeros sh n' (fst adr, Z.succ (snd adr))
end.
Definition address_mapsto_zeros' (n: Z) : spec :=
fun (sh: Share.t) (l: address) =>
allp (jam (adr_range_dec l (Z.max n 0))
(fun l' => yesat NoneP (VAL (Byte Byte.zero)) sh l')
noat) && noghost.

Lemma address_mapsto_zeros_eq:
forall sh n,
address_mapsto_zeros sh n =
address_mapsto_zeros' (Z_of_nat n) sh.