fork(1) 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 expression =
  29. | Var of variable
  30. | Layer of layer
  31.  
  32. and state =
  33. | Fresh of int * int
  34. | Solved of expression
  35.  
  36. and variable = state ref
  37.  
  38. and layer = expression L.layer
  39.  
  40. type context = expression L.context
  41.  
  42. let fresh =
  43. let id = ref 0 in
  44. fun level -> ref (Fresh (!id, level))
  45.  
  46. let rec read v =
  47. match !v with
  48. | Fresh _ -> Var v
  49. | Solved (Layer _ as e) -> e
  50. | Solved (Var w) ->
  51. let e = read w in
  52. v := Solved e ; e
  53.  
  54. let simplify = function
  55. | Var v -> read v
  56. | e -> e
  57.  
  58. let tags v =
  59. match !v with
  60. | Fresh (id, lvl) -> id, lvl
  61. | _ -> failwith "variable not fresh"
  62.  
  63. let occurs ctx v =
  64. let id, lvl = tags v in
  65. let rec loop e =
  66. match simplify e with
  67. | Layer l -> List.iter loop (L.smaller ctx l)
  68. | Var v ->
  69. let id', lvl' = tags v in
  70. if id = id' then
  71. failwith "infinite recursion"
  72. else if lvl < lvl' then
  73. v := Fresh (id', lvl)
  74. in loop
  75.  
  76. let unify ctx =
  77. let rec loop (e1, e2) =
  78. match simplify e1, simplify e2 with
  79. | Var v1, Var v2 ->
  80. let _, lvl1 = tags v1 in
  81. let _, lvl2 = tags v2 in
  82. if lvl1 < lvl2 then
  83. v2 := Solved (Var v1)
  84. else
  85. v1 := Solved (Var v2)
  86. | Var v, e | e, Var v ->
  87. occurs ctx v e;
  88. v := Solved e
  89. | Layer l1, Layer l2 ->
  90. match L.generate ctx (l1, l2) with
  91. | Some eqs -> List.iter loop eqs
  92. | None -> failwith "cannot unify"
  93. in loop
  94. end
  95.  
Success #stdin #stdout 0.02s 2736KB
stdin
Standard input is empty
stdout
Standard output is empty