(******************************************

Definitions of spacer and withspacer

Comment: spacer only has offset_zero property but does not have local_facts
and isptr property.

******************************************)

Definition spacer (sh: share) (be: Z) (ed: Z) : val -> mpred :=
  if Z.eq_dec (ed - be) 0
  then fun _ => emp
  else
    at_offset (memory_block sh (ed - be)) be.(* Arguments spacer sh be ed / _ . *)

Definition withspacer sh (be: Z) (ed: Z) P (p: val): mpred :=
   if Z.eq_dec (ed - be) 0
   then P p
   else P p * spacer sh be ed p.

(* Specifications: *)
Lemma withspacer_spacer: forall sh be ed P p, withspacer sh be ed P p = spacer sh be ed p * P p.
Lemma spacer_offset_zero: forall sh be ed v, spacer sh be ed v = spacer sh be ed (offset_val 0 v).
Lemma withspacer_add: forall sh pos be ed P p, withspacer sh (pos + be) (pos + ed) (fun p0 => P (offset_val pos p)) p = withspacer sh be ed P (offset_val pos p).
Lemma spacer_memory_block: forall sh be ed v, isptr v -> spacer sh be ed v = memory_block sh (ed - be) (offset_val be v).
Lemma spacer_sepcon_memory_block: forall sh ofs lo hi b i, 0 <= lo -> 0 <= ofs -> lo <= hi < Ptrofs.modulus -> Ptrofs.unsigned i + ofs + hi < Ptrofs.modulus -> spacer sh (ofs + lo) (ofs + hi) (Vptr b i) * memory_block sh lo (offset_val ofs (Vptr b i)) = memory_block sh hi (offset_val ofs (Vptr b i)).