src/Pure/type.ML
changeset 13666 a2730043029b
parent 12726 5ae4034883d5
child 14790 0d984ee030a1
equal deleted inserted replaced
13665:66e151df01c8 13666:a2730043029b
   753         Some U => devar (U, tye)
   753         Some U => devar (U, tye)
   754       | None => T)
   754       | None => T)
   755   | devar (T, tye) = T;
   755   | devar (T, tye) = T;
   756 
   756 
   757 
   757 
   758 (* add_env *)
       
   759 
       
   760 (*avoids chains 'a |-> 'b |-> 'c ...*)
       
   761 fun add_env (vT as (v, T), tab) = Vartab.update_new (vT, Vartab.map
       
   762   (fn (U as (TVar (w, S))) => if eq_ix (v, w) then T else U | U => U) tab);
       
   763 
       
   764 
       
   765 (* unify *)
   758 (* unify *)
   766 
   759 
   767 fun unify (tsig as TySg {classrel, arities, ...}) (tyenv, maxidx) TU =
   760 fun unify (tsig as TySg {classrel, arities, ...}) (tyenv, maxidx) TU =
   768   let
   761   let
   769     val tyvar_count = ref maxidx;
   762     val tyvar_count = ref maxidx;
   773       Sorts.mg_domain (classrel, arities) a S handle Sorts.DOMAIN _ => raise TUNIFY;
   766       Sorts.mg_domain (classrel, arities) a S handle Sorts.DOMAIN _ => raise TUNIFY;
   774 
   767 
   775     fun meet ((_, []), tye) = tye
   768     fun meet ((_, []), tye) = tye
   776       | meet ((TVar (xi, S'), S), tye) =
   769       | meet ((TVar (xi, S'), S), tye) =
   777           if Sorts.sort_le classrel (S', S) then tye
   770           if Sorts.sort_le classrel (S', S) then tye
   778           else add_env ((xi, gen_tyvar (Sorts.inter_sort classrel (S', S))), tye)
   771           else Vartab.update_new ((xi,
       
   772             gen_tyvar (Sorts.inter_sort classrel (S', S))), tye)
   779       | meet ((TFree (_, S'), S), tye) =
   773       | meet ((TFree (_, S'), S), tye) =
   780           if Sorts.sort_le classrel (S', S) then tye
   774           if Sorts.sort_le classrel (S', S) then tye
   781           else raise TUNIFY
   775           else raise TUNIFY
   782       | meet ((Type (a, Ts), S), tye) = meets ((Ts, mg_domain a S), tye)
   776       | meet ((Type (a, Ts), S), tye) = meets ((Ts, mg_domain a S), tye)
   783     and meets (([], []), tye) = tye
   777     and meets (([], []), tye) = tye
   787 
   781 
   788     fun unif ((ty1, ty2), tye) =
   782     fun unif ((ty1, ty2), tye) =
   789       (case (devar (ty1, tye), devar (ty2, tye)) of
   783       (case (devar (ty1, tye), devar (ty2, tye)) of
   790         (T as TVar (v, S1), U as TVar (w, S2)) =>
   784         (T as TVar (v, S1), U as TVar (w, S2)) =>
   791           if eq_ix (v, w) then tye
   785           if eq_ix (v, w) then tye
   792           else if Sorts.sort_le classrel (S1, S2) then add_env ((w, T), tye)
   786           else if Sorts.sort_le classrel (S1, S2) then
   793           else if Sorts.sort_le classrel (S2, S1) then add_env ((v, U), tye)
   787             Vartab.update_new ((w, T), tye)
       
   788           else if Sorts.sort_le classrel (S2, S1) then
       
   789             Vartab.update_new ((v, U), tye)
   794           else
   790           else
   795             let val S = gen_tyvar (Sorts.inter_sort classrel (S1, S2)) in
   791             let val S = gen_tyvar (Sorts.inter_sort classrel (S1, S2)) in
   796               add_env ((v, S), add_env ((w, S), tye))
   792               Vartab.update_new ((v, S), Vartab.update_new ((w, S), tye))
   797             end
   793             end
   798       | (TVar (v, S), T) =>
   794       | (TVar (v, S), T) =>
   799           if occurs v tye T then raise TUNIFY
   795           if occurs v tye T then raise TUNIFY
   800           else meet ((T, S), add_env ((v, T), tye))
   796           else meet ((T, S), Vartab.update_new ((v, T), tye))
   801       | (T, TVar (v, S)) =>
   797       | (T, TVar (v, S)) =>
   802           if occurs v tye T then raise TUNIFY
   798           if occurs v tye T then raise TUNIFY
   803           else meet ((T, S), add_env ((v, T), tye))
   799           else meet ((T, S), Vartab.update_new ((v, T), tye))
   804       | (Type (a, Ts), Type (b, Us)) =>
   800       | (Type (a, Ts), Type (b, Us)) =>
   805           if a <> b then raise TUNIFY
   801           if a <> b then raise TUNIFY
   806           else foldr unif (Ts ~~ Us, tye)
   802           else foldr unif (Ts ~~ Us, tye)
   807       | (T, U) => if T = U then tye else raise TUNIFY);
   803       | (T, U) => if T = U then tye else raise TUNIFY);
   808   in (unif (TU, tyenv), ! tyvar_count) end;
   804   in (unif (TU, tyenv), ! tyvar_count) end;