You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.7 KiB

4 years ago
  1. open import "prelude.ml"
  2. module S = import "data/set.ml"
  3. module M = import "data/map.ml"
  4. type expr =
  5. | Ref of string
  6. | App of expr * expr
  7. | Lam of string * expr
  8. | Case of expr * list (string * expr)
  9. let app = curry App
  10. let lam = curry Lam
  11. let rec free_vars = function
  12. | Ref v -> S.singleton v
  13. | App (f, x) -> S.union (free_vars f) (free_vars x)
  14. | Lam (v, x) -> v `S.delete` free_vars x
  15. | Case (e, bs) ->
  16. bs
  17. |> map (fun (_, e) -> free_vars e)
  18. |> foldl S.union S.empty
  19. |> S.union (free_vars e)
  20. let rec subst m = function
  21. | Ref v ->
  22. match M.lookup v m with
  23. | Some s -> s
  24. | None -> Ref v
  25. | App (f, x) -> App (subst m f, subst m x)
  26. | Lam (v, x) -> Lam (v, subst (M.delete v m) x)
  27. | Case (e, xs) -> Case (subst m e, map (second (subst m)) xs)
  28. type hstype =
  29. | Tycon of string
  30. | Tyvar of string
  31. | Tyapp of hstype * hstype
  32. type constr = Constr of string * list hstype
  33. type decl =
  34. | Decl of string * list string * expr
  35. | Data of string * list string * list constr
  36. type prog <- list decl
  37. let rec xs !! i =
  38. match xs, i with
  39. | Cons (x, _), 0 -> x
  40. | Cons (_, xs), i when i > 0 -> xs !! (i - 1)
  41. | _, _ -> error "empty list and/or negative index"
  42. let ds_data (_, _, cs) =
  43. let ncons = length cs
  44. let alts = map (("c" ^) # show) [1..ncons]
  45. let ds_con i (Constr (n, args)) =
  46. let arity = length args
  47. let alt = alts !! i
  48. let args = map (("x" ^) # show) [1..arity]
  49. Decl (n, args, foldr lam (foldl app (Ref alt) (map Ref args)) alts)
  50. let rec go i = function
  51. | [] -> []
  52. | Cons (x, xs) -> ds_con i x :: go (i + 1) xs
  53. go 0 cs
  54. let ds_prog prog =
  55. let! c = prog
  56. match c with
  57. | Data c -> ds_data c
  58. | Decl (n, args, e) -> [Decl (n, args, e)]