(* Preservation of allocations *)

(* Specifications: *)
Theorem alloc_right_inject:
forall f m1 m2 lo hi b2 m2',
inject f m1 m2 ->
alloc m2 lo hi = (m2', b2) ->
inject f m1 m2'.
Theorem alloc_left_unmapped_inject:
forall f m1 m2 lo hi m1' b1,
inject f m1 m2 ->
alloc m1 lo hi = (m1', b1) ->
exists f',
inject f' m1' m2
/\ inject_incr f f'
/\ f' b1 = None
/\ (forall b, b <> b1 -> f' b = f b).
Theorem alloc_left_mapped_inject:
forall f m1 m2 lo hi m1' b1 b2 delta,
inject f m1 m2 ->
alloc m1 lo hi = (m1', b1) ->
valid_block m2 b2 ->
0 <= delta <= Ptrofs.max_unsigned ->
(forall ofs k p, perm m2 b2 ofs k p -> delta = 0 \/ 0 <= ofs < Ptrofs.max_unsigned) ->
(forall ofs k p, lo <= ofs < hi -> perm m2 b2 (ofs + delta) k p) ->
inj_offset_aligned delta (hi-lo) ->
(forall b delta' ofs k p,
f b = Some (b2, delta') ->
perm m1 b ofs k p ->
lo + delta <= ofs + delta' < hi + delta -> False) ->
exists f',
inject f' m1' m2
/\ inject_incr f f'
/\ f' b1 = Some(b2, delta)
/\ (forall b, b <> b1 -> f' b = f b).
Theorem alloc_parallel_inject:
forall f m1 m2 lo1 hi1 m1' b1 lo2 hi2,
inject f m1 m2 ->
alloc m1 lo1 hi1 = (m1', b1) ->
lo2 <= lo1 -> hi1 <= hi2 ->
exists f', exists m2', exists b2,
alloc m2 lo2 hi2 = (m2', b2)
/\ inject f' m1' m2'
/\ inject_incr f f'
/\ f' b1 = Some(b2, 0)
/\ (forall b, b <> b1 -> f' b = f b).