(** * Memory injections *)
(** A memory injection [f] is a function from addresses to either [None] or [Some] of an address and an offset.  It defines a correspondence between the blocks of two memory states [m1] and [m2]: - if [f b = None], the block [b] of [m1] has no equivalent in [m2]; - if [f b = Some(b', ofs)], the block [b] of [m2] corresponds to a sub-block at offset [ofs] of the block [b'] in [m2].  A memory injection [f] defines a relation [Val.inject] between values that is the identity for integer and float values, and relocates pointer values as prescribed by [f].  (See module [Values].)  Likewise, a memory injection [f] defines a relation between memory states that we now axiomatize. *)
Parameter inject: meminj -> mem -> mem -> Prop.

Axiom storebytes_outside_inject:
forall f m1 m2 b ofs bytes2 m2',
inject f m1 m2 ->
(forall b' delta ofs',
f b' = Some(b, delta) ->
perm m1 b' ofs' Cur Readable ->
ofs <= ofs' + delta < ofs + Z.of_nat (length bytes2) -> False) ->
storebytes m2 b ofs bytes2 = Some m2' ->
inject f m1 m2'.