Definition memory_block (sh: share) (n: Z) (v: val) : mpred :=
match v with
| Vptr b ofs => (!!(Ptrofs.unsigned ofs + n < Ptrofs.modulus)) && memory_block' sh (nat_of_Z n) b (Ptrofs.unsigned ofs)
| _ => FF
end.

(* Specifications: *)
Lemma mapsto__exp_address_mapsto: forall sh t b i_ofs ch,
access_mode t = By_value ch ->
type_is_volatile t = false ->
readable_share sh ->
mapsto_ sh t (Vptr b i_ofs) = EX  v2' : val,
address_mapsto ch v2' sh (b, (Ptrofs.unsigned i_ofs)).
Lemma exp_address_mapsto_VALspec_range_eq:
forall ch sh l,
EX v: val, address_mapsto ch v sh l = !! (align_chunk ch | snd l) && VALspec_range (size_chunk ch) sh l.
Lemma VALspec_range_exp_address_mapsto_eq:
forall ch sh l,
(align_chunk ch | snd l) ->
VALspec_range (size_chunk ch) sh l = EX v: val, address_mapsto ch v sh l.
Lemma mapsto__memory_block: forall sh b ofs t ch,
access_mode t = By_value ch ->
type_is_volatile t = false ->
(align_chunk ch | Ptrofs.unsigned ofs) ->
Ptrofs.unsigned ofs + size_chunk ch < Ptrofs.modulus ->
mapsto_ sh t (Vptr b ofs) = memory_block sh (size_chunk ch) (Vptr b ofs).
Lemma nonreadable_memory_block_mapsto: forall sh b ofs t ch v,
~ readable_share sh ->
access_mode t = By_value ch ->
type_is_volatile t = false ->
(align_chunk ch | Ptrofs.unsigned ofs) ->
Ptrofs.unsigned ofs + size_chunk ch < Ptrofs.modulus ->
tc_val' t v ->
memory_block sh (size_chunk ch) (Vptr b ofs) = mapsto sh t (Vptr b ofs) v.
Lemma mapsto_share_join:
forall sh1 sh2 sh t p v,
join sh1 sh2 sh ->
mapsto sh1 t p v * mapsto sh2 t p v = mapsto sh t p v.
Lemma mapsto_mapsto_: forall sh t v v', mapsto sh t v v' |-- mapsto_ sh t v.
Lemma mapsto_not_nonunit: forall sh t p v, ~ nonunit sh -> mapsto sh t p v |-- emp.
Lemma mapsto_pure_facts: forall sh t p v,
mapsto sh t p v |-- !! ((exists ch, access_mode t = By_value ch) /\ isptr p).
Lemma mapsto_overlap: forall sh {cs: compspecs} t1 t2 p1 p2 v1 v2,
nonunit sh ->
pointer_range_overlap p1 (sizeof t1) p2 (sizeof t2) ->
mapsto sh t1 p1 v1 * mapsto sh t2 p2 v2 |-- FF.
Lemma Nat2Z_add_lt: forall n i, Ptrofs.unsigned i + n < Ptrofs.modulus ->
Z.of_nat (nat_of_Z n) + Ptrofs.unsigned i < Ptrofs.modulus.
Lemma Nat2Z_add_le: forall n i, Ptrofs.unsigned i + n <= Ptrofs.modulus ->
Z.of_nat (nat_of_Z n) + Ptrofs.unsigned i <= Ptrofs.modulus.
Lemma memory_block_overlap: forall sh p1 n1 p2 n2, nonunit sh -> pointer_range_overlap p1 n1 p2 n2 -> memory_block sh n1 p1 * memory_block sh n2 p2 |-- FF.
Lemma mapsto_conflict:
forall sh t v v2 v3,
nonunit sh ->
mapsto sh t v v2 * mapsto sh t v v3 |-- FF.
Lemma memory_block_conflict: forall sh n m p,
nonunit sh ->
0 < n <= Ptrofs.max_unsigned -> 0 < m <= Ptrofs.max_unsigned ->
memory_block sh n p * memory_block sh m p |-- FF.
Lemma memory_block_non_pos_Vptr: forall sh n b z, n <= 0 -> memory_block sh n (Vptr b z) = emp.
Lemma memory_block_zero_Vptr: forall sh b z, memory_block sh 0 (Vptr b z) = emp.
Lemma mapsto_zeros_memory_block: forall sh n p,
readable_share sh ->
mapsto_zeros n sh p |--
memory_block sh n p.
Lemma memory_block'_split:
forall sh b ofs i j,
0 <= i <= j ->
j <= j+ofs < Ptrofs.modulus ->
memory_block' sh (nat_of_Z j) b ofs =
memory_block' sh (nat_of_Z i) b ofs * memory_block' sh (nat_of_Z (j-i)) b (ofs+i).
Lemma memory_block_split:
forall (sh : share) (b : block) (ofs n m : Z),
0 <= n ->
0 <= m ->
n + m <= n + m + ofs < Ptrofs.modulus ->
memory_block sh (n + m) (Vptr b (Ptrofs.repr ofs)) =
memory_block sh n (Vptr b (Ptrofs.repr ofs)) *
memory_block sh m (Vptr b (Ptrofs.repr (ofs + n))).
Lemma memory_block_share_join:
forall sh1 sh2 sh n p,
sepalg.join sh1 sh2 sh ->
memory_block sh1 n p * memory_block sh2 n p = memory_block sh n p.
Lemma mapsto_pointer_void:
forall sh t a,
eqb_type (Tpointer t a) int_or_ptr_type = false ->
eqb_type (Tpointer Tvoid a) int_or_ptr_type = false ->
mapsto sh (Tpointer t a) = mapsto sh (Tpointer Tvoid a).
Lemma is_pointer_or_null_nullval: is_pointer_or_null nullval.
Hint Resolve is_pointer_or_null_nullval.
Lemma tc_val_pointer_nullval':
forall t a, tc_val (Tpointer t a) nullval.