(****************The following three conditions are new******************)

(* Specifications: *)
(*LENB: Lemma is modified - we need to put sp into locBlocksTgt mu*)
Lemma structured_match_callstack_alloc_right:
forall mu cenv m tm cs tf tm' sp le te (WD: SM_wd mu) (SMV: sm_valid mu m tm),
structured_match_callstack mu m tm cs (Mem.nextblock m) (Mem.nextblock tm) ->
Mem.alloc tm 0 tf.(fn_stackspace) = (tm', sp) ->
Mem.inject (as_inj mu) m tm ->
match_temps (restrict (as_inj mu) (vis mu)) le te ->
(forall id, cenv!id = None) ->
structured_match_callstack (alloc_right_sm mu sp) m tm'
(Frame cenv tf empty_env le te sp (Mem.nextblock m) (Mem.nextblock m) :: cs)
(Mem.nextblock m) (Mem.nextblock tm')
/\ SM_wd (alloc_right_sm mu sp) /\ sm_valid (alloc_right_sm mu sp) m tm'.
Lemma MS_structured_match_callstack_alloc_variables_aux:
forall tm1 sp tm2 m1 vars e m2 cenv mu (cs:callstack) fn lenv te,
Mem.alloc tm1 0 (fn_stackspace fn) = (tm2, sp) ->
fn_stackspace fn <= Int.max_unsigned ->
alloc_variables empty_env m1 vars e m2 ->
list_norepet (map fst vars) ->
cenv_compat cenv vars (fn_stackspace fn) ->
cenv_separated cenv vars ->
(forall id ofs, cenv!id = Some ofs -> In id (map fst vars)) ->
REACH_closed m1 (vis mu) -> sm_valid mu m1 tm1 -> SM_wd mu ->
Mem.inject (as_inj mu) m1 tm1 ->
structured_match_callstack mu m1 tm1 cs (Mem.nextblock m1) (Mem.nextblock tm1) ->
match_temps (restrict (as_inj mu) (vis mu)) lenv te ->
exists mu',
structured_match_callstack mu' m2 tm2 (Frame cenv fn e lenv te sp (Mem.nextblock m1) (Mem.nextblock m2) :: cs)
(Mem.nextblock m2) (Mem.nextblock tm2)
/\ Mem.inject (as_inj mu') m2 tm2
/\ intern_incr mu mu'
/\ (forall b, Mem.valid_block m1 b -> (as_inj mu') b = (as_inj mu) b)
/\ (forall b b' d', as_inj mu b = None -> as_inj mu' b = Some (b',d') -> b' = sp)
/\ sm_locally_allocated mu mu' m1 tm1 m2 tm2
/\ SM_wd mu' /\ sm_valid mu' m2 tm2
/\ REACH_closed m2 (vis mu')
/\ forall mu'', SM_wd mu'' -> intern_incr mu' mu'' -> sm_inject_separated mu' mu'' m2 tm2 ->
sm_inject_separated mu mu'' m1 tm1.
Lemma MS_match_callstack_alloc_variables_aux:
forall tm1 sp tm2 m1 vars e m2 cenv f1 cs fn le te,
Mem.alloc tm1 0 (fn_stackspace fn) = (tm2, sp) ->
fn_stackspace fn <= Int.max_unsigned ->
alloc_variables empty_env m1 vars e m2 ->
list_norepet (map fst vars) ->
cenv_compat cenv vars (fn_stackspace fn) ->
cenv_separated cenv vars ->
(forall id ofs, cenv!id = Some ofs -> In id (map fst vars)) ->
Mem.inject f1 m1 tm1 ->
match_callstack prog f1 m1 tm1 cs (Mem.nextblock m1) (Mem.nextblock tm1) ->
match_temps f1 le te ->
exists f2,
match_callstack prog f2 m2 tm2 (Frame cenv fn e le te sp (Mem.nextblock m1) (Mem.nextblock m2) :: cs)
(Mem.nextblock m2) (Mem.nextblock tm2)
/\ Mem.inject f2 m2 tm2
/\ (*LENB: THIS IS NEW*) inject_incr f1 f2
/\ (forall b, Mem.valid_block m1 b -> f2 b = f1 b)
/\ (forall b b' d', f1 b = None -> f2 b = Some (b',d') -> b' = sp)
/\ forall j',  inject_incr f2 j' -> Events.inject_separated f2 j' m2 tm2 ->
Events.inject_separated f2 j' m1 tm1.