(** The simulation diagram. *)
Fixpoint seq_left_depth (s: Csharpminor.stmt) : nat :=
match s with
| Csharpminor.Sseq s1 s2 => S (seq_left_depth s1)
| _ => O
end.
Definition measure (S: Csharpminor.state) : nat :=
match S with
| Csharpminor.State fn s k e le m => seq_left_depth s
| _ => O
end.
(*LENB: Refactoring of original proof: 1. isolate lemmas for individual cases 2. Have individual cases be more specific about which of the 2 disjuncts they imply 3. make place swhere meminj's are extended more explicit. This is done by exposing meminj's as additional parameter of match_state, so that individual lemmas can explicitly exisitenitally quantify over the extensions and impose additional conditions (eg in case Builtin) Other steps one could do: - refactoring of states into cores and memories - add knowlegsde the amounts to "at_external"*)
Inductive match_statesInj: meminj -> Csharpminor.state -> Cminor.state -> Prop :=
| matchInj_state:
forall fn s k e le m tfn ts tk sp te tm cenv xenv f lo hi cs sz
(TRF: transl_funbody cenv sz fn = OK tfn)
(TR: transl_stmt cenv xenv s = OK ts)
(MINJ: Mem.inject f m tm)
(MCS: match_callstack f m tm
(Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont k tk cenv xenv cs),
match_statesInj f (Csharpminor.State fn s k e le m)
(State tfn ts tk (Vptr sp Int.zero) te tm)
| matchInj_state_seq:
forall fn s1 s2 k e le m tfn ts1 tk sp te tm cenv xenv f lo hi cs sz
(TRF: transl_funbody cenv sz fn = OK tfn)
(TR: transl_stmt cenv xenv s1 = OK ts1)
(MINJ: Mem.inject f m tm)
(MCS: match_callstack f m tm
(Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont (Csharpminor.Kseq s2 k) tk cenv xenv cs),
match_statesInj f (Csharpminor.State fn (Csharpminor.Sseq s1 s2) k e le m)
(State tfn ts1 tk (Vptr sp Int.zero) te tm)
| matchInj_callstate:
forall fd args k m tfd targs tk tm f cs cenv
(TR: transl_fundef fd = OK tfd)
(MINJ: Mem.inject f m tm)
(MCS: match_callstack f m tm cs (Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont k tk cenv nil cs)
(ISCC: Csharpminor.is_call_cont k)
(ARGSINJ: val_list_inject f args targs),
match_statesInj f (Csharpminor.Callstate fd args k m)
(Callstate tfd targs tk tm)
| matchInj_returnstate:
forall v k m tv tk tm f cs cenv
(MINJ: Mem.inject f m tm)
(MCS: match_callstack f m tm cs (Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont k tk cenv nil cs)
(RESINJ: val_inject f v tv),
match_statesInj f (Csharpminor.Returnstate v k m)
(Returnstate tv tk tm).

(* Specifications: *)
Lemma matchInj_Intro: forall S T,
match_states S T -> exists j, match_statesInj j S T.
Lemma matchInj_Elim: forall j S T,
match_statesInj j S T -> match_states S T.
Lemma transl_step_case_SkipSeq:
forall cenv sz f tfn j m tm  e le te sp lo hi cs s k tk xenv
(TR: transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack j m tm (Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont (Csharpminor.Kseq s k) tk cenv xenv cs),
exists T2 : state,
plus step tge (State tfn Sskip tk (Vptr sp Int.zero) te tm) E0 T2 /\
match_statesInj j (Csharpminor.State f s k e le m) T2.
Lemma transl_step_case_SkipBlock:
forall cenv sz f tfn j m tm e le te sp lo hi cs k tk xenv
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack j m tm (Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont (Csharpminor.Kblock k) tk cenv xenv cs),
exists T2 : state,
plus step tge (State tfn Sskip tk (Vptr sp Int.zero) te tm) E0 T2 /\
match_statesInj j (Csharpminor.State f Csharpminor.Sskip k e le m) T2.
Lemma transl_step_case_SkipCall:
forall cenv sz f tfn j m tm e le te sp lo hi cs k tk xenv m'
(CC: Csharpminor.is_call_cont k)
(FL: Mem.free_list m (blocks_of_env e) = Some m')
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack j m tm (Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont k tk cenv xenv cs),
exists T2 : state,
plus step tge (State tfn Sskip tk (Vptr sp Int.zero) te tm) E0 T2 /\
match_statesInj j (Csharpminor.Returnstate Vundef k m') T2.
Lemma transl_step_case_Assign:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x a x0 v id
(EE: Csharpminor.eval_expr ge e lenv m a v)
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont k tk cenv xenv cs)
(EQ : transl_expr cenv a = OK (x, x0)),
exists T2 : state,
plus step tge (State tfn (Sassign id x) tk (Vptr sp Int.zero) te tm) E0 T2 /\
match_statesInj j (Csharpminor.State f Csharpminor.Sskip k e (PTree.set id v lenv) m) T2.