simple induction 1.
intros.
inversion_clear H0; auto.
elim H2; auto.
intros.
apply H1.
inversion H3.
elim H2.
exact H4.
auto.
(* Injection H4. Intros. Try Rewrite <- H5. Elim H9;Auto. Intros;Auto. *)
Qed.
(*****************************************************************************)
(*                   We define now the Mini-ML semantics                     *)
(*In this semantics we want to distinguish the places where application is   *)
(*used in a recursive scheme from the other places.                          *)
(*That's why we have a special rule for application in the case where the    *)
(*function applied has as value a recursive closure (this correspond in fact *)
(*to a test during application                                               *)
(*****************************************************************************)
Inductive ML_DS : MLenv -> MLexp -> MLval -> Prop :=
| BOOL : forall (b : bool) (e : MLenv), ML_DS e (Bool b) (boolean b)
| NUM : forall (n : nat) (e : MLenv), ML_DS e (Num n) (num n)
| Sem_OP : forall (c : OP) (e : MLenv), ML_DS e (op c) (OP_clos c)
| LAMBDA :
forall (e : MLenv) (P : Pat) (E : MLexp),
ML_DS e (lambda P E) (Clos P E e)
| IDENT :
forall (e : MLenv) (v : MLval) (I : Pat),
VAL_OF e I v -> ML_DS e (id I) v
| ITE1 :
forall (e : MLenv) (E1 E2 E3 : MLexp) (v : MLval),
ML_DS e E1 (boolean true) -> ML_DS e E2 v -> ML_DS e (ite E1 E2 E3) v
| ITE2 :
forall (e : MLenv) (E1 E2 E3 : MLexp) (v : MLval),
ML_DS e E1 (boolean false) -> ML_DS e E3 v -> ML_DS e (ite E1 E2 E3) v
| MLPAIR :
forall (e : MLenv) (E1 E2 : MLexp) (u v : MLval),
ML_DS e E1 u -> ML_DS e E2 v -> ML_DS e (mlpair E1 E2) (valpair u v)
| APPml1 :
forall (e e1 : MLenv) (P : Pat) (E E1 E2 : MLexp) (u v : MLval),
ML_DS e E1 (Clos P E e1) ->
ML_DS e E2 u -> ML_DS (Econs P u e1) E v -> ML_DS e (appl E1 E2) v
| APPml2 :
forall (e e1 : MLenv) (x P : Pat) (E E1 E2 : MLexp) (u v : MLval),
ML_DS e E1 (Clos_rec x E P e1) ->
ML_DS e E2 u ->
ML_DS (Econs x u (Econs P (Clos_rec x E P e1) e1)) E v ->
ML_DS e (appl E1 E2) v
| APPml_op :
forall (e : MLenv) (E1 E2 : MLexp) (n m : nat) (c : OP),
ML_DS e E1 (OP_clos c) ->
ML_DS e E2 (valpair (num n) (num m)) ->
ML_DS e (appl E1 E2) (num (eval_op c n m))
| Sem_let :
forall (e : MLenv) (P : Pat) (E1 E2 : MLexp) (u v : MLval),
ML_DS e E2 u -> ML_DS (Econs P u e) E1 v -> ML_DS e (let' P E2 E1) v
| Sem_letrec :
forall (e : MLenv) (P x : Pat) (E E2 : MLexp) (u : MLval),
ML_DS (Econs P (Clos_rec x E P e) e) E2 u ->
ML_DS e (letrec P x E E2) u.
(*****************************************************************************)
(* This predicate can be seen as an injective partial function associating a *)
(*  value to an environment and an expression:                               *)
(*****************************************************************************)

(* Specifications: *)
Lemma ML_DS_determ :
forall (e : MLenv) (E : MLexp) (V : MLval),
ML_DS e E V -> forall V' : MLval, ML_DS e E V' -> V = V' :>MLval.