Inductive structured_match_callstack mu (m: mem) (tm: mem):
callstack -> Values.block -> Values.block -> Prop :=
| st_mcs_nil:
forall hi bound tbound,
match_globalenvs prog (restrict (as_inj mu) (vis mu)) hi ->
Ple hi bound -> Ple hi tbound ->
structured_match_callstack mu m tm nil bound tbound
| st_mcs_cons:
forall cenv tf e le te sp lo hi cs bound tbound
(BOUND: Ple hi bound)
(TBOUND: Plt sp tbound)
(MTMP: match_temps (restrict (as_inj mu) (vis mu)) le te)
(MENV: match_env (restrict (as_inj mu) (vis mu)) cenv e sp lo hi)
(BOUND: match_bounds e m)
(PERM: padding_freeable (restrict (as_inj mu) (vis mu)) e tm sp tf.(fn_stackspace))
(SPlocal: locBlocksTgt mu sp = true) (*NEW*)
(*LENB: Here is the condition me_incr from match_env above, but we assert it on the entire as_inj mu*)
(ME_INCR: forall b tb delta,
(as_inj mu) b = Some(tb, delta) -> Plt b lo -> Plt tb sp)
(MCS: structured_match_callstack mu m tm cs lo sp),
structured_match_callstack mu m tm (Frame cenv tf e le te sp lo hi :: cs) bound tbound.

Lemma structured_match_callstack_intern_invariant:
forall f1 m1 tm1 f2 m2 tm2 cs bound tbound (WD1: SM_wd f1) (WD2: SM_wd f2),
intern_incr f1 f2 ->
structured_match_callstack f1 m1 tm1 cs bound tbound ->
(forall b ofs p, Plt b bound -> Mem.perm m2 b ofs Max p -> Mem.perm m1 b ofs Max p) ->
(forall sp ofs, Plt sp tbound -> Mem.perm tm1 sp ofs Cur Freeable -> Mem.perm tm2 sp ofs Cur Freeable) ->
(forall b, Plt b bound -> (as_inj f2) b = (as_inj f1) b) ->
(forall b b' delta, (as_inj f2) b = Some(b', delta) -> Plt b' tbound -> (as_inj f1) b = Some(b', delta)) ->
structured_match_callstack f2 m2 tm2 cs bound tbound.