Section EVAL_EXPR.
Variables e te: env.
Variables le tle: temp_env.
Variables m tm: mem.
Variable f: meminj.
Variable cenv: compilenv.
Variables lo hi tlo thi: block.
Hypothesis MATCH: match_envs f cenv e le m lo hi te tle tlo thi.
Hypothesis MEMINJ: Mem.inject f m tm.
Hypothesis GLOB: exists bound, match_globalenvs f bound.
End EVAL_EXPR.
(** Matching continuations *)
Inductive match_cont (f: meminj): compilenv -> cont -> cont -> mem -> block -> block -> Prop :=
| match_Kstop: forall cenv m bound tbound hi,
match_globalenvs f hi -> Ple hi bound -> Ple hi tbound ->
match_cont f cenv Kstop Kstop m bound tbound
| match_Kseq: forall cenv s k ts tk m bound tbound,
simpl_stmt cenv s = OK ts ->
match_cont f cenv k tk m bound tbound ->
compat_cenv (addr_taken_stmt s) cenv ->
match_cont f cenv (Kseq s k) (Kseq ts tk) m bound tbound
| match_Kloop1: forall cenv s1 s2 k ts1 ts2 tk m bound tbound,
simpl_stmt cenv s1 = OK ts1 ->
simpl_stmt cenv s2 = OK ts2 ->
match_cont f cenv k tk m bound tbound ->
compat_cenv (VSet.union (addr_taken_stmt s1) (addr_taken_stmt s2)) cenv ->
match_cont f cenv (Kloop1 s1 s2 k) (Kloop1 ts1 ts2 tk) m bound tbound
| match_Kloop2: forall cenv s1 s2 k ts1 ts2 tk m bound tbound,
simpl_stmt cenv s1 = OK ts1 ->
simpl_stmt cenv s2 = OK ts2 ->
match_cont f cenv k tk m bound tbound ->
compat_cenv (VSet.union (addr_taken_stmt s1) (addr_taken_stmt s2)) cenv ->
match_cont f cenv (Kloop2 s1 s2 k) (Kloop2 ts1 ts2 tk) m bound tbound
| match_Kswitch: forall cenv k tk m bound tbound,
match_cont f cenv k tk m bound tbound ->
match_cont f cenv (Kswitch k) (Kswitch tk) m bound tbound
| match_Kcall: forall cenv optid fn e le k tfn te tle tk m hi thi lo tlo bound tbound x,
transf_function fn = OK tfn ->
match_envs f (cenv_for fn) e le m lo hi te tle tlo thi ->
match_cont f (cenv_for fn) k tk m lo tlo ->
check_opttemp (cenv_for fn) optid = OK x ->
Ple hi bound -> Ple thi tbound ->
match_cont f cenv (Kcall optid fn e le k)
(Kcall optid tfn te tle tk) m bound tbound.
(** Invariance property by change of memory and injection *)
(** Invariance by assignment to location "above" *)
(** Invariance by external calls *)
(** Invariance by change of bounds *)
(** [match_cont] and call continuations. *)
(** [match_cont] and freeing of environment blocks *)
Remark free_list_nextblock:
forall l m m',
Mem.free_list m l = Some m' -> Mem.nextblock m' = Mem.nextblock m.
Remark free_list_load:
forall chunk b' l m m',
Mem.free_list m l = Some m' ->
(forall b lo hi, In (b, lo, hi) l -> Plt b' b) ->
Mem.load chunk m' b' 0 = Mem.load chunk m b' 0.

Lemma match_cont_free_env:
forall f cenv e le m lo hi te tle tm tlo thi k tk m' tm',
match_envs f cenv e le m lo hi te tle tlo thi ->
match_cont f cenv k tk m lo tlo ->
Ple hi (Mem.nextblock m) ->
Ple thi (Mem.nextblock tm) ->
Mem.free_list m (blocks_of_env ge e) = Some m' ->
Mem.free_list tm (blocks_of_env tge te) = Some tm' ->
match_cont f cenv k tk m' (Mem.nextblock m') (Mem.nextblock tm').