diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-01-19 19:37:08 -0600 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-01-19 19:37:08 -0600 |
commit | a84e462b596c24d2562d766ceb019761085390c5 (patch) | |
tree | 51a87e24426a5ad9d94bab104e21d3d3ecbbb9f1 /discocaml/eval.ml | |
parent | 401bc1c5485e26329598d59a140e51f70f58857c (diff) |
Use GADTs for prims, actual redex finding.
Diffstat (limited to 'discocaml/eval.ml')
-rw-r--r-- | discocaml/eval.ml | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/discocaml/eval.ml b/discocaml/eval.ml index 816d269..9c12003 100644 --- a/discocaml/eval.ml +++ b/discocaml/eval.ml @@ -1,5 +1,43 @@ open Ast -let find_redex_cbv : expr ast -> expr index option = function _ -> None -let find_redex_cbn : expr ast -> expr index option = function _ -> None -let reduce : expr ast -> expr index -> expr ast = fun e _ -> e +let or_else (type a) (l : a option) (r : a option Lazy.t) : a option = + match l with Some x -> Some x | None -> Lazy.force r + +let is_redex (ast : expr ast) (i : expr index) : bool = + match get_subexpr ast i with + | App (f, _) -> ( + match get_subexpr ast f with Lam (_, _) -> true | _ -> false) + | Int _ -> false + | Lam (_, _) -> false + | Prim (Add, (l, r)) | Prim (Sub, (l, r)) | Prim (Mul, (l, r)) -> ( + match (get_subexpr ast l, get_subexpr ast r) with + | Int _, Int _ -> true + | _ -> false) + | Var _ -> false + +let find_redex_cbv_in (_ast : expr ast) (_i : expr index) : expr index option = + None + +let find_redex_cbn_in (ast : expr ast) : expr index -> expr index option = + let rec loop (i : expr index) : expr index option = + if is_redex ast i then Some i + else + match get_subexpr ast i with + | App (f, x) -> or_else (loop f) (lazy (loop x)) + | Int _ -> None + | Lam (_, _) -> None + | Prim (Add, (l, r)) | Prim (Sub, (l, r)) | Prim (Mul, (l, r)) -> + or_else (loop l) (lazy (loop r)) + | Var _ -> None + in + loop + +let find_redex_cbv (ast : expr ast) : expr index option = + find_redex_cbv_in ast ast.root + +let find_redex_cbn (ast : expr ast) : expr index option = + find_redex_cbn_in ast ast.root + +let reduce (ast : expr ast) (_i : expr index) : expr ast = + let ast = copy ast in + ast |