(** ** Properties of [storebytes]. *)
(** [storebytes] preserves block validity, permissions, access validity, and bounds. Moreover, a [storebytes] succeeds if and only if we have write permissions on the addressed memory area. *)

(* Specifications: *)
Axiom range_perm_storebytes:
forall m1 b ofs bytes,
range_perm m1 b ofs (ofs + Z.of_nat (length bytes)) Cur Writable ->
{ m2 : mem | storebytes m1 b ofs bytes = Some m2 }.
Axiom storebytes_range_perm:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
range_perm m1 b ofs (ofs + Z.of_nat (length bytes)) Cur Writable.
Axiom perm_storebytes_1:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b' ofs' k p, perm m1 b' ofs' k p -> perm m2 b' ofs' k p.
Axiom perm_storebytes_2:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b' ofs' k p, perm m2 b' ofs' k p -> perm m1 b' ofs' k p.
Axiom storebytes_valid_access_1:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall chunk' b' ofs' p,
valid_access m1 chunk' b' ofs' p -> valid_access m2 chunk' b' ofs' p.
Axiom storebytes_valid_access_2:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall chunk' b' ofs' p,
valid_access m2 chunk' b' ofs' p -> valid_access m1 chunk' b' ofs' p.
Axiom nextblock_storebytes:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
nextblock m2 = nextblock m1.
Axiom storebytes_valid_block_1:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b', valid_block m1 b' -> valid_block m2 b'.
Axiom storebytes_valid_block_2:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b', valid_block m2 b' -> valid_block m1 b'.
Axiom range_perm_storebytes:
forall m1 b ofs bytes,
range_perm m1 b ofs (ofs + Z.of_nat (length bytes)) Cur Writable ->
{ m2 : mem | storebytes m1 b ofs bytes = Some m2 }.
Axiom storebytes_range_perm:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
range_perm m1 b ofs (ofs + Z.of_nat (length bytes)) Cur Writable.
Axiom perm_storebytes_1:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b' ofs' k p, perm m1 b' ofs' k p -> perm m2 b' ofs' k p.
Axiom perm_storebytes_2:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b' ofs' k p, perm m2 b' ofs' k p -> perm m1 b' ofs' k p.
Axiom storebytes_valid_access_1:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall chunk' b' ofs' p,
valid_access m1 chunk' b' ofs' p -> valid_access m2 chunk' b' ofs' p.
Axiom storebytes_valid_access_2:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall chunk' b' ofs' p,
valid_access m2 chunk' b' ofs' p -> valid_access m1 chunk' b' ofs' p.
Axiom nextblock_storebytes:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
nextblock m2 = nextblock m1.
Axiom storebytes_valid_block_1:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b', valid_block m1 b' -> valid_block m2 b'.
Axiom storebytes_valid_block_2:
forall m1 b ofs bytes m2, storebytes m1 b ofs bytes = Some m2 ->
forall b', valid_block m2 b' -> valid_block m1 b'.