(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)


(* Contribution to the Coq Library   V6.3 (July 1999)                    *)

(****************************************************************************)
(*                                                                          *)
(*                                                                          *)
(*  Mini_ML.v                                                               *)
(*                                                                          *)
(*  This file contains the definitions of the Mini-ML and the               *)
(*  Categorical Abstract Machine (C.A.M) natural semantics                  *)
(*  It also contains the definition of the translation from                 *)
(*  Mini-ML to the CAM and the proof that this translation is               *)
(*  correct                                                                 *)
(*                                                                          *)
(*                                                                          *)
(*  Samuel Boutin                                                           *)
(*  Coq V5.10                                                               *)
(*  December  1994                                                          *)
(*                                                                          *)
(*                                                                          *)
(****************************************************************************)
(*                                Mini_ML.v                                 *)
(****************************************************************************)

(*****************************************************************************)
(*                CORRECTNESS PROOF OF A MINI_ML COMPILER                    *)
(*                             Samuel Boutin                                 *)
(*                             December 1994                                 *)
(*                              Coql  V5.10                                  *)
(*****************************************************************************)

(*****************************************************************************)
(* First we define a Set "OP" of variable which is a representation of the   *)
(* arithmetic functions *,+,-... that we will not describe explicitely       *)
(* We take the natural numbers to code the variables (but of course it has no*)
(* relation with the De bruijn indexes)                                      *)
(*****************************************************************************)

Parameter OP : Set.Parameter eval_op : OP -> nat -> nat -> nat.Definition Pat := nat.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*              Defining the syntax of ML expressions                        *)
(*****************************************************************************)

Inductive MLexp : Set :=
  | Bool : bool -> MLexp
  | Num : nat -> MLexp
  | op : OP -> MLexp
  | id : Pat -> MLexp
  | appl : MLexp -> MLexp -> MLexp
  | mlpair : MLexp -> MLexp -> MLexp
  | lambda : Pat -> MLexp -> MLexp
  | let' : Pat -> MLexp -> MLexp -> MLexp
  | letrec : Pat -> Pat -> MLexp -> MLexp -> MLexp
  | ite : MLexp -> MLexp -> MLexp -> MLexp.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(*     ML values and environment are defined with the following mutual       *)
(*     recursive definition                                                  *)
(*****************************************************************************)

Inductive MLval : Set :=
  | num : nat -> MLval
  | boolean : bool -> MLval
  | valpair : MLval -> MLval -> MLval
  | OP_clos : OP -> MLval
  | Clos : Pat -> MLexp -> MLenv -> MLval
  | Clos_rec : Pat -> MLexp -> Pat -> MLenv -> MLval
with MLenv : Set :=
  | Enil : MLenv
  | Econs : Pat -> MLval -> MLenv -> MLenv.(*****************************************************************************)
(* Definition of VAL_OF which decide if a variable belongs to an environment *)
(*****************************************************************************)

Inductive VAL_OF : MLenv -> Pat -> MLval -> Prop :=
  | ELT : forall (e : MLenv) (I : Pat) (a : MLval), VAL_OF (Econs I a e) I a
  | CHG :
      forall (e : MLenv) (X I : Pat) (a b : MLval),
      VAL_OF e I a -> X <> I :>Pat -> VAL_OF (Econs X b e) I a.(*****************************************************************************)
(* Definition of VAL_OF which decide if a variable belongs to an environment *)
(*****************************************************************************)

Inductive VAL_OF : MLenv -> Pat -> MLval -> Prop :=
  | ELT : forall (e : MLenv) (I : Pat) (a : MLval), VAL_OF (Econs I a e) I a
  | CHG :
      forall (e : MLenv) (X I : Pat) (a b : MLval),
      VAL_OF e I a -> X <> I :>Pat -> VAL_OF (Econs X b e) I a.(*****************************************************************************)
(* Definition of VAL_OF which decide if a variable belongs to an environment *)
(*****************************************************************************)

Inductive VAL_OF : MLenv -> Pat -> MLval -> Prop :=
  | ELT : forall (e : MLenv) (I : Pat) (a : MLval), VAL_OF (Econs I a e) I a
  | CHG :
      forall (e : MLenv) (X I : Pat) (a b : MLval),
      VAL_OF e I a -> X <> I :>Pat -> VAL_OF (Econs X b e) I a.

Lemma determ_VAL_OF : forall (e : MLenv) (i : Pat) (V V' : MLval), VAL_OF e i V' -> VAL_OF e i V -> V = V' :>MLval.