(** Matching between continuations *)
Inductive match_cont : Csem.cont -> cont -> Prop :=
| match_Kstop:
match_cont Csem.Kstop Kstop
| match_Kseq: forall s k ts tk,
tr_stmt s ts ->
match_cont k tk ->
match_cont (Csem.Kseq s k) (Kseq ts tk)
| match_Kwhile2: forall r s k s' ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s ts ->
match_cont k tk ->
match_cont (Csem.Kwhile2 r s k)
(Kloop1 (Ssequence s' ts) Sskip tk)
| match_Kdowhile1: forall r s k s' ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s ts ->
match_cont k tk ->
match_cont (Csem.Kdowhile1 r s k)
(Kloop1 ts s' tk)
| match_Kfor3: forall r s3 s k ts3 s' ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s3 ts3 ->
tr_stmt s ts ->
match_cont k tk ->
match_cont (Csem.Kfor3 r s3 s k)
(Kloop1 (Ssequence s' ts) ts3 tk)
| match_Kfor4: forall r s3 s k ts3 s' ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s3 ts3 ->
tr_stmt s ts ->
match_cont k tk ->
match_cont (Csem.Kfor4 r s3 s k)
(Kloop2 (Ssequence s' ts) ts3 tk)
| match_Kswitch2: forall k tk,
match_cont k tk ->
match_cont (Csem.Kswitch2 k) (Kswitch tk)
| match_Kcall: forall f e C ty k optid tf le sl tk a dest tmps,
tr_function f tf ->
leftcontext RV RV C ->
(forall v m, tr_top tge e (set_opttemp optid v le) m dest (C (Csyntax.Eval v ty)) sl a tmps) ->
match_cont_exp dest a k tk ->
match_cont (Csem.Kcall f e C ty k)
(Kcall optid tf e le (Kseqlist sl tk))
(* | match_Kcall_some: forall f e C ty k dst tf le sl tk a dest tmps, transl_function f = Errors.OK tf -> leftcontext RV RV C -> (forall v m, tr_top tge e (PTree.set dst v le) m dest (C (C.Eval v ty)) sl a tmps) -> match_cont_exp dest a k tk -> match_cont (Csem.Kcall f e C ty k) (Kcall (Some dst) tf e le (Kseqlist sl tk)) *)
with match_cont_exp : destination -> expr -> Csem.cont -> cont -> Prop :=
| match_Kdo: forall k a tk,
match_cont k tk ->
match_cont_exp For_effects a (Csem.Kdo k) tk
| match_Kifthenelse_empty: forall a k tk,
match_cont k tk ->
match_cont_exp For_val a (Csem.Kifthenelse Csyntax.Sskip Csyntax.Sskip k) (Kseq Sskip tk)
| match_Kifthenelse_1: forall a s1 s2 k ts1 ts2 tk,
tr_stmt s1 ts1 -> tr_stmt s2 ts2 ->
match_cont k tk ->
match_cont_exp For_val a (Csem.Kifthenelse s1 s2 k) (Kseq (Sifthenelse a ts1 ts2) tk)
| match_Kwhile1: forall r s k s' a ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s ts ->
match_cont k tk ->
match_cont_exp For_val a
(Csem.Kwhile1 r s k)
(Kseq (makeif a Sskip Sbreak)
(Kseq ts (Kloop1 (Ssequence s' ts) Sskip tk)))
| match_Kdowhile2: forall r s k s' a ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s ts ->
match_cont k tk ->
match_cont_exp For_val a
(Csem.Kdowhile2 r s k)
(Kseq (makeif a Sskip Sbreak) (Kloop2 ts s' tk))
| match_Kfor2: forall r s3 s k s' a ts3 ts tk,
tr_if r Sskip Sbreak s' ->
tr_stmt s3 ts3 ->
tr_stmt s ts ->
match_cont k tk ->
match_cont_exp For_val a
(Csem.Kfor2 r s3 s k)
(Kseq (makeif a Sskip Sbreak)
(Kseq ts (Kloop1 (Ssequence s' ts) ts3 tk)))
| match_Kswitch1: forall ls k a tls tk,
tr_lblstmts ls tls ->
match_cont k tk ->
match_cont_exp For_val a (Csem.Kswitch1 ls k) (Kseq (Sswitch a tls) tk)
| match_Kreturn: forall k a tk,
match_cont k tk ->
match_cont_exp For_val a (Csem.Kreturn k) (Kseq (Sreturn (Some a)) tk).

Lemma match_cont_call:
forall k tk,
match_cont k tk ->
match_cont (Csem.call_cont k) (call_cont tk).