(** ** Permissions on the Cminor stack block *)
(** The parts of the Cminor stack data block that are not images of C#minor local variable blocks remain freeable at all times. *)
Inductive is_reachable_from_env (f: meminj) (e: Csharpminor.env) (sp: block) (ofs: Z) : Prop :=
| is_reachable_intro: forall id b sz delta,
e!id = Some(b, sz) ->
f b = Some(sp, delta) ->
delta <= ofs < delta + sz ->
is_reachable_from_env f e sp ofs.
Definition padding_freeable (f: meminj) (e: Csharpminor.env) (tm: mem) (sp: block) (sz: Z) : Prop :=
forall ofs,
0 <= ofs < sz -> Mem.perm tm sp ofs Cur Freeable \/ is_reachable_from_env f e sp ofs.

(* Specifications: *)
Lemma padding_freeable_invariant:
forall f1 e tm1 sp sz cenv lo hi f2 tm2,
padding_freeable f1 e tm1 sp sz ->
match_env f1 cenv e sp lo hi ->
(forall ofs, Mem.perm tm1 sp ofs Cur Freeable -> Mem.perm tm2 sp ofs Cur Freeable) ->
(forall b, Plt b hi -> f2 b = f1 b) ->
padding_freeable f2 e tm2 sp sz.
Lemma padding_freeable_invariant:
forall f1 e tm1 sp sz cenv lo hi f2 tm2,
padding_freeable f1 e tm1 sp sz ->
match_env f1 cenv e sp lo hi ->
(forall ofs, Mem.perm tm1 sp ofs Cur Freeable -> Mem.perm tm2 sp ofs Cur Freeable) ->
(forall b, Plt b hi -> f2 b = f1 b) ->
padding_freeable f2 e tm2 sp sz.