From 8c50463ec4f468369c698b6023b64599e907cfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Pottier?= Date: Thu, 12 Oct 2017 15:40:11 +0200 Subject: [PATCH] New OCaml exercise. --- ocaml/EvalCBVExercise.ml | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ocaml/EvalCBVExercise.ml diff --git a/ocaml/EvalCBVExercise.ml b/ocaml/EvalCBVExercise.ml new file mode 100644 index 0000000..36b11ca --- /dev/null +++ b/ocaml/EvalCBVExercise.ml @@ -0,0 +1,71 @@ +(* -------------------------------------------------------------------------- *) + +(* The type of lambda-terms, in de Bruijn's representation. *) + +type var = int (* a de Bruijn index *) +type term = + | Var of var + | Lam of (* bind: *) term + | App of term * term + | Let of (* bind: *) term * term + +(* -------------------------------------------------------------------------- *) + +(* An environment-based big-step interpreter. This is the same interpreter + that we programmed in Coq, except here, in OCaml, fuel is not needed. *) + +type cvalue = + | Clo of (* bind: *) term * cenv + +and cenv = + cvalue list + +let empty : cenv = + [] + +exception RuntimeError + +let lookup (e : cenv) (x : var) : cvalue = + try + List.nth e x + with Failure _ -> + raise RuntimeError + +let rec eval (e : cenv) (t : term) : cvalue = + match t with + | Var x -> + lookup e x + | Lam t -> + Clo (t, e) + | App (t1, t2) -> + let cv1 = eval e t1 in + let cv2 = eval e t2 in + let Clo (u1, e') = cv1 in + eval (cv2 :: e') u1 + | Let (t1, t2) -> + eval (eval e t1 :: e) t2 + +(* -------------------------------------------------------------------------- *) + +(* The CPS-transformed interpreter. *) + +let rec evalk (e : cenv) (t : term) (k : cvalue -> 'a) : 'a = + assert false + +let eval (e : cenv) (t : term) : cvalue = + evalk e t (fun cv -> cv) + +(* -------------------------------------------------------------------------- *) + +(* The CPS-transformed, defunctionalized interpreter. *) + +type kont + +let rec evalkd (e : cenv) (t : term) (k : kont) : cvalue = + assert false + +and apply (k : kont) (cv : cvalue) : cvalue = + assert false + +let eval e t = + evalkd e t (assert false)