(** Exit expressions. *)

Definition transl_exitexpr_prop
     (le: letenv) (a: exitexpr) (x: nat) : Prop :=
  forall tm cs f map ns nexits rs
    (MWF: map_wf map)
    (TE: tr_exitexpr f.(fn_code) map a ns nexits)
    (ME: match_env map e le rs)
    (EXT: Mem.extends m tm),
  exists nd, exists rs', exists tm',
     star step tge (State cs f sp ns rs tm) E0 (State cs f sp nd rs' tm')
  /\ nth_error nexits x = Some nd
  /\ match_env map e le rs'
  /\ Mem.extends m tm'.

(* Specifications: *)
Theorem transl_exitexpr_correct: forall le a x, eval_exitexpr ge sp e m le a x -> transl_exitexpr_prop le a x.
Lemma eval_exprlist_append: forall le al1 vl1 al2 vl2, eval_exprlist ge sp e m le (exprlist_of_expr_list al1) vl1 -> eval_exprlist ge sp e m le (exprlist_of_expr_list al2) vl2 -> eval_exprlist ge sp e m le (exprlist_of_expr_list (al1 ++ al2)) (vl1 ++ vl2).
Lemma invert_eval_builtin_arg: forall a v, eval_builtin_arg ge sp e m a v -> exists vl, eval_exprlist ge sp e m nil (exprlist_of_expr_list (params_of_builtin_arg a)) vl /\ Events.eval_builtin_arg ge (fun v => v) sp m (fst (convert_builtin_arg a vl)) v /\ (forall vl', convert_builtin_arg a (vl ++ vl') = (fst (convert_builtin_arg a vl), vl')).
Lemma invert_eval_builtin_args: forall al vl, list_forall2 (eval_builtin_arg ge sp e m) al vl -> exists vl', eval_exprlist ge sp e m nil (exprlist_of_expr_list (params_of_builtin_args al)) vl' /\ Events.eval_builtin_args ge (fun v => v) sp m (convert_builtin_args al vl') vl.