fork download
  1. module type LAYER =
  2. sig
  3. type 'a layer
  4. type 'a context
  5.  
  6. val smaller : 'a context -> 'a layer -> 'a list
  7. val generate : 'a context -> 'a layer * 'a layer -> ('a * 'a) list option
  8. end
  9.  
  10. module type POLY =
  11. sig
  12. type layer
  13. type context
  14. type variable
  15.  
  16. type expression =
  17. | Var of variable
  18. | Layer of layer
  19.  
  20. val fresh : int -> variable
  21. val read : variable -> expression
  22. val occurs : variable -> expression -> unit
  23. val unify : context -> expression * expression -> unit
  24. end
  25.  
  26. module Poly (L : LAYER) =
  27. struct
  28. type variable = private
  29. [ `Fresh of int * int
  30. | `Solved of expression
  31. ] ref
  32.  
  33. and expression =
  34. | Var of variable
  35. | Layer of layer
  36.  
  37. and layer = expression L.layer
  38.  
  39. type context = expression L.context
  40.  
  41. let fresh =
  42. let id = ref 0 in
  43. fun level -> ref (`Fresh (!id, level))
  44.  
  45. let rec read v =
  46. match !v with
  47. | `Fresh _ -> Var v
  48. | `Solved (Layer _ as e) -> e
  49. | `Solved (Var w) ->
  50. let e = read w in
  51. v := Solved e ; e
  52.  
  53. let simplify = function
  54. | Var v -> read v
  55. | e -> e
  56.  
  57. let tags v =
  58. match !v with
  59. | `Fresh (id, lvl) -> id, lvl
  60. | _ -> failwith "variable not fresh"
  61.  
  62. let occurs ctx v =
  63. let id, lvl = tags v in
  64. let loop e =
  65. match simplify e with
  66. | Layer l -> List.iter loop (L.smaller ctx l)
  67. | Var v ->
  68. let id', lvl' = tags v in
  69. if id = id' then
  70. failwith "infinite recursion"
  71. else if lvl < lvl' then
  72. v := Fresh (id', lvl)
  73. in loop
  74.  
  75. let unify ctx =
  76. let rec loop (e1, e2) =
  77. match simplify e1, simplify e2 with
  78. | Var v1, Var v2 ->
  79. let _, lvl1 = tags v1 in
  80. let _, lvl2 = tags v2 in
  81. if lvl1 < lvl2 then
  82. v2 := Solved (Var v1)
  83. else
  84. v1 := Solved (Var v2)
  85. | Var v, e | e, Var v ->
  86. occurs ctx v e;
  87. v := Solved e
  88. | Layer l1, Layer l2 ->
  89. match L.generate ctx (l1, l2) with
  90. | Some eqs -> List.iter loop eqs
  91. | None -> failwith "cannot unify"
  92. in loop
  93. end
  94.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
File "prog.ml", line 28, characters 8-97:
This fixed type is not an object or variant
stdout
Standard output is empty