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; |