Section COMPSPECS.
Context {cs: compspecs}.
Global Opaque memory_block.
End COMPSPECS.
(******************************************  Lemmas about specific types  ******************************************)
(* We do these as Hint Extern, instead of Hint Resolve, to limit their application and make them fail faster *)
Hint Extern 1 (mapsto _ _ _ _ |-- mapsto _ _ _ _) =>
(simple apply mapsto_mapsto_int32; apply Coq.Init.Logic.I)  : cancel.
Hint Extern 1 (mapsto _ _ _ _ |-- mapsto_ _ _ _) =>
(simple apply mapsto_mapsto__int32; apply Coq.Init.Logic.I)  : cancel.
Hint Extern 1 (mapsto _ _ _ _ |-- mapsto_ _ _ _) =>
(apply mapsto_mapsto_) : cancel.
Hint Extern 1 (mapsto _ _ _ _ |-- mapsto_ _ _ _) =>
(apply mapsto_mapsto__int32)  : cancel.
Hint Extern 1 (mapsto _ _ _ _ |-- mapsto _ _ _ _) =>
(apply mapsto_mapsto_int32)  : cancel.
Hint Extern 0 (legal_alignas_type _ = true) => reflexivity : cancel.
Hint Rewrite mapsto_force_ptr: norm.
(******************************************  Definition of at_offset.  at_offset is the elementary definition. All useful lemmas about at_offset will be proved here.  ******************************************)
Definition at_offset (P: val -> mpred) (z: Z): val -> mpred :=
fun v => P (offset_val z v).
Arguments at_offset P z v : simpl never.
(******************************************  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.

Lemma at_offset_preserve_local_facts: forall P pos, (forall p, P p |-- !!(isptr p)) -> (forall p, at_offset P pos p |-- !!(isptr p)).