mr_dot_convict

Most-General-Unifier-SML-implementation

Oct 24th, 2019
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (* Control.Print.printDepth := 1024; *)
  2. datatype monotype = Var of string
  3.                   | Bool
  4.                   | App of monotype * monotype;
  5.  
  6. datatype scheme = Polytype of (string list * monotype);
  7. datatype result = Pair of (string * monotype);
  8.  
  9. (*---------------------------------_some_required_functions_-----------------------------------*)
  10. (*
  11. val sub         = fn : result -> monotype -> monotype
  12. val subst       = fn : result list -> monotype -> monotype
  13. val mentions    = fn : string -> monotype -> bool
  14. val composition = fn : result list -> result list -> result list
  15. *)
  16.  
  17.  
  18. fun subst [] t     = t
  19.   | subst (e::E) t =
  20.   let
  21.     fun sub (Pair(x, y)) (Var z) = if (x = z) then y else (Var z)
  22.       | sub e (App (m1, m2))     = App (sub e m1, sub e m2)
  23.       | sub e Bool               = Bool
  24.   in
  25.     subst E (sub e t)
  26.   end;
  27.  
  28. fun mentions x (Var y)        = (x = y)
  29.   | mentions x (App (e1, e2)) = mentions x e1 orelse mentions x e2
  30.   | mentions x Bool           = false;
  31.  
  32. fun composition [] tau                  = tau
  33.   | composition ((Pair(v, t))::pho) tau = (Pair(v, subst tau t))::(composition pho tau);
  34.  
  35.   (*---------------------------------__Most_general_unifier__------------------------------------*)
  36.  
  37. (*
  38. val mgu = fn : (monotype * monotype) list -> result list
  39. *)
  40.  
  41. exception Unify;
  42.  
  43. fun mgu []            = []
  44.   | mgu ((t1, t2)::L) =
  45.   let
  46.     val pho        = mgu L
  47.     val (t1', t2') = (subst pho t1, subst pho t2)
  48.     val tau        =
  49.       case (t1', t2') of
  50.            (Var x, Var z)             => if (x = z) then [] else [ Pair (x, Var z) ]
  51.          | (Var x, b)                 => if (mentions x b) then raise Unify else [ Pair (x, b) ]
  52.          | (a, Var y)                 => if (mentions y a) then raise Unify else [ Pair (y, a) ]
  53.          | (Bool, Bool)               => []
  54.          | (App(a1, a2), App(b1, b2)) => mgu [(a1, b1), (a2, b2)]
  55.          | (_, _)                     => raise Unify
  56.   in
  57.     composition pho tau
  58.   end;
  59.  
  60.   (* ------------------everything below is just to test in a pretty format-------------------------*)
  61.   (* -----------------------------------_____Test_Cases____----------------------------------------*)
  62. val (green, yellow, normal, pink) = ("\027[1;32m", "\027[1;33m", "\027[1;0m", "\027[1;35m");
  63.  
  64. val tests = [[(App(Var "hello", Var "world"), Var "test")],
  65.  
  66.             [((App(Bool, Bool)), App(Var "x", Var "y"))],
  67.  
  68.             [((App(Var "z", Var "w")), App(Var "x", Var "y"))],
  69.  
  70.             [(App(Var "Alpha", Bool), App(Var "Gamma", Var "Gamma")), (Var
  71.             "Beta", Var "Gamma")],
  72.  
  73.             [(App(Var "Alpha", Var "Beta"), App(Var "Gamma", Var "Gamma"))],
  74.  
  75.             (* Uncommenting the test below will result in exception because there is no solution for this case*)
  76.             (* [(App(App(Var "Alpha", Var "Beta"), Var "Beta"), App(Var "Gamma", Var "Gamma"))], *)
  77.  
  78.             [(App(App(Var "Alpha", Var "Beta"), App(Var "Alpha", Var "Beta")), App(Var "Gamma", Var "Gamma"))],
  79.  
  80.             [(App(App(Var "Alpha", Var "Beta"), App(Var "Alpha", Var "Beta")),
  81.             App(App(Var "Gamma", Var "Gamma"), App(Var "Gamma", Var "Gamma")))]
  82.             ];
  83.  
  84. fun run_tests []             = green ^ "Testing finished...\n" ^ normal
  85.   | run_tests (test::t_list) =
  86. let
  87.   fun pretty (Var x)        = x
  88.     | pretty (App(a1, a2))  = yellow ^ " ( " ^ normal ^ (pretty a1) ^ yellow ^ " -> " ^
  89.     normal ^ (pretty a2) ^ yellow ^ " ) " ^ normal
  90.     | pretty Bool           = "bool";
  91.  
  92.   fun showSubt (Pair(x, z)) = " [ " ^ pink ^ x ^ normal ^ " : " ^ (pretty z) ^ " ] ";
  93.  
  94.   fun showResult []         = "\n"
  95.     | showResult (a::L)     = (showSubt a) ^ "\n" ^ (showResult(L));
  96.  
  97.   fun showTest []           = "\n"
  98.     | showTest ((x, y)::L)  = " [ " ^ pretty(x) ^ ", " ^ pretty(y) ^ " ]\n" ^ (showTest L);
  99.   val strTest               = showTest test;
  100.   val res                   = mgu test;
  101.   val strResult             = showResult res;
  102. in
  103.   green ^ "Test Case # \n" ^ normal ^ strTest ^ "\n" ^ yellow ^
  104.   " Resulting substitutions : \n" ^ normal ^ strResult
  105.   ^ "-----------------------------------------------\n" ^ run_tests t_list
  106. end;
  107.  
  108. print(run_tests tests);
Add Comment
Please, Sign In to add comment