Section ALLOC.
Variable m1: mem.
Variables lo hi: Z.
Variable m2: mem.
Variable b: Values.block.
Hypothesis ALLOC: Mem.alloc m1 lo hi = (m2, b).
Transparent Mem.alloc.
Opaque Mem.alloc.
Definition alloc_right_sm (mu: SM_Injection) sp: SM_Injection :=
Build_SM_Injection (locBlocksSrc mu)
(fun b => eq_block b sp || locBlocksTgt mu b)
(pubBlocksSrc mu) (pubBlocksTgt mu)
(local_of mu)
(extBlocksSrc mu) (extBlocksTgt mu)
(frgnBlocksSrc mu) (frgnBlocksTgt mu) (extern_of mu).

Theorem alloc_left_mapped_sm_inject:
forall mu m1 m2 lo hi m1' b1 b2 delta (WD: SM_wd mu)
(SMV: sm_valid mu m1 m2) (RC: REACH_closed m1 (vis mu))
(Locb2: locBlocksTgt mu b2 = true),
Mem.inject (as_inj mu) m1 m2 ->
Mem.alloc m1 lo hi = (m1', b1) ->
Mem.valid_block m2 b2 ->
0 <= delta <= Int.max_unsigned ->
(forall ofs k p, Mem.perm m2 b2 ofs k p -> delta = 0 \/ 0 <= ofs < Int.max_unsigned) ->
(forall ofs k p, lo <= ofs < hi -> Mem.perm m2 b2 (ofs + delta) k p) ->
Mem.inj_offset_aligned delta (hi-lo) ->
(forall b delta' ofs k p,
as_inj mu b = Some (b2, delta') ->
Mem.perm m1 b ofs k p ->
lo + delta <= ofs + delta' < hi + delta -> False) ->
exists mu',
Mem.inject (as_inj mu') m1' m2
/\ intern_incr mu mu'
/\ as_inj mu' b1 = Some(b2, delta)
/\ (forall b, b <> b1 -> as_inj mu' b = as_inj mu b)
/\ SM_wd mu' /\ sm_valid mu' m1' m2
/\ sm_locally_allocated mu mu' m1 m2 m1' m2
/\ REACH_closed m1' (vis mu').