(** * Memory injections *)
(** A memory state [m1] injects into another memory state [m2] via the memory injection [f] if the following conditions hold: - each access in [m2] that corresponds to a valid access in [m1] is itself valid; - the memory value associated in [m1] to an accessible address must inject into [m2]'s memory value at the corersponding address; - unallocated blocks in [m1] must be mapped to [None] by [f]; - if [f b = Some(b', delta)], [b'] must be valid in [m2]; - distinct blocks in [m1] are mapped to non-overlapping sub-blocks in [m2]; - the sizes of [m2]'s blocks are representable with unsigned machine integers; - pointers that could be represented using unsigned machine integers remain representable after the injection. *)
Record inject' (f: meminj) (m1 m2: mem) : Prop :=
mk_inject {
mi_inj:
mem_inj f m1 m2;
mi_freeblocks:
forall b, ~(valid_block m1 b) -> f b = None;
mi_mappedblocks:
forall b b' delta, f b = Some(b', delta) -> valid_block m2 b';
mi_no_overlap:
meminj_no_overlap f m1;
mi_representable:
forall b b' delta ofs,
f b = Some(b', delta) ->
perm m1 b (Ptrofs.unsigned ofs) Max Nonempty \/ perm m1 b (Ptrofs.unsigned ofs - 1) Max Nonempty ->
delta >= 0 /\ 0 <= Ptrofs.unsigned ofs + delta <= Ptrofs.max_unsigned;
mi_perm_inv:
forall b1 ofs b2 delta k p,
f b1 = Some(b2, delta) ->
perm m2 b2 (ofs + delta) k p ->
perm m1 b1 ofs k p \/ ~perm m1 b1 ofs Max Nonempty
}.
Definition inject := inject'.
Local Hint Resolve mi_mappedblocks: mem.
(** Preservation of access validity and pointer validity *)

(* Specifications: *)
Theorem valid_block_inject_1:
forall f m1 m2 b1 b2 delta,
f b1 = Some(b2, delta) ->
inject f m1 m2 ->
valid_block m1 b1.
Theorem valid_block_inject_2:
forall f m1 m2 b1 b2 delta,
f b1 = Some(b2, delta) ->
inject f m1 m2 ->
valid_block m2 b2.