(** Compatibility of evaluation functions with the "less defined than" relation. *)

Ltac TrivialExists :=
  match goal with
  | [ |- exists v, Some ?x = Some v /\ _ ] => exists x; split; auto
  | _ => idtac
  end.

(* Specifications: *)
Lemma eval_unop_lessdef: forall op v1 v1' v, eval_unop op v1 = Some v -> Val.lessdef v1 v1' -> exists v', eval_unop op v1' = Some v' /\ Val.lessdef v v'.
Lemma eval_binop_lessdef: forall op v1 v1' v2 v2' v m m', eval_binop op v1 v2 m = Some v -> Val.lessdef v1 v1' -> Val.lessdef v2 v2' -> Mem.extends m m' -> exists v', eval_binop op v1' v2' m' = Some v' /\ Val.lessdef v v'.
Lemma set_var_lessdef: forall e1 e2 id v1 v2, env_lessdef e1 e2 -> Val.lessdef v1 v2 -> env_lessdef (PTree.set id v1 e1) (PTree.set id v2 e2).
Lemma set_optvar_lessdef: forall e1 e2 optid v1 v2, env_lessdef e1 e2 -> Val.lessdef v1 v2 -> env_lessdef (set_optvar optid v1 e1) (set_optvar optid v2 e2).
Lemma set_params_lessdef: forall il vl1 vl2, Val.lessdef_list vl1 vl2 -> env_lessdef (set_params vl1 il) (set_params vl2 il).
Lemma set_locals_lessdef: forall e1 e2, env_lessdef e1 e2 -> forall il, env_lessdef (set_locals il e1) (set_locals il e2).
Lemma sel_expr_correct: forall sp e m a v, Cminor.eval_expr ge sp e m a v -> forall e' le m', env_lessdef e e' -> Mem.extends m m' -> exists v', eval_expr tge sp e' m' le (sel_expr a) v' /\ Val.lessdef v v'.
Lemma sel_exprlist_correct: forall sp e m a v, Cminor.eval_exprlist ge sp e m a v -> forall e' le m', env_lessdef e e' -> Mem.extends m m' -> exists v', eval_exprlist tge sp e' m' le (sel_exprlist a) v' /\ Val.lessdef_list v v'.
Lemma sel_builtin_arg_correct: forall sp e e' m m' a v c, env_lessdef e e' -> Mem.extends m m' -> Cminor.eval_expr ge sp e m a v -> exists v', CminorSel.eval_builtin_arg tge sp e' m' (sel_builtin_arg a c) v' /\ Val.lessdef v v'.
Lemma sel_builtin_args_correct: forall sp e e' m m', env_lessdef e e' -> Mem.extends m m' -> forall al vl, Cminor.eval_exprlist ge sp e m al vl -> forall cl, exists vl', list_forall2 (CminorSel.eval_builtin_arg tge sp e' m') (sel_builtin_args al cl) vl' /\ Val.lessdef_list vl vl'.
Lemma sel_builtin_res_correct: forall oid v e v' e', env_lessdef e e' -> Val.lessdef v v' -> env_lessdef (set_optvar oid v e) (set_builtin_res (sel_builtin_res oid) v' e').