[m-rev.] for review: work around type ambiguity problem

Peter Wang novalazy at gmail.com
Fri Nov 16 13:06:58 AEDT 2007


Estimated hours taken: 1
Branches: main

Use a d.u. type for `set_ordlist(T)' to work around spurious type ambiguity
errors when a program makes calls unqualified procedures which could be
confused with `list' procedures if the type of `set_ordlist(T) == list(T)' is
exposed for intermodule optimisation.

library/set_ordlist.m:
	As above.


Index: library/set_ordlist.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/set_ordlist.m,v
retrieving revision 1.29
diff -u -r1.29 set_ordlist.m
--- library/set_ordlist.m	30 Oct 2006 01:24:04 -0000	1.29
+++ library/set_ordlist.m	16 Nov 2007 02:02:24 -0000
@@ -277,32 +277,44 @@
 
 %-----------------------------------------------------------------------------%
 
-:- type set_ordlist(T)  ==    list(T).
+    % We use a d.u. type to work around spurious type ambiguity errors when a
+    % program makes calls unqualified procedures which could be confused with
+    % `list' procedures if the type of `set_ordlist(T) == list(T)' is exposed
+    % for intermodule optimisation.
+    %
+:- type set_ordlist(T)
+    --->    sol(list(T)).
 
-set_ordlist.list_to_set(List0, List) :-
+set_ordlist.list_to_set(List0, sol(List)) :-
     list.sort_and_remove_dups(List0, List).
 
-set_ordlist.from_list(List0) = List :-
-    set_ordlist.list_to_set(List0, List).
+set_ordlist.from_list(List) = Set :-
+    set_ordlist.list_to_set(List, Set).
 
-set_ordlist.sorted_list_to_set(List0, List) :-
+set_ordlist.sorted_list_to_set(List0, sol(List)) :-
     list.remove_adjacent_dups(List0, List).
 
-set_ordlist.from_sorted_list(List0) = List :-
-    set_ordlist.sorted_list_to_set(List0, List).
+set_ordlist.from_sorted_list(List) = Set :-
+    set_ordlist.sorted_list_to_set(List, Set).
 
-set_ordlist.to_sorted_list(List, List).
+set_ordlist.to_sorted_list(sol(List), List).
 
 set_ordlist.insert_list(Set0, List0, Set) :-
     list.sort_and_remove_dups(List0, List),
-    set_ordlist.union(List, Set0, Set).
+    set_ordlist.union(sol(List), Set0, Set).
+
+set_ordlist.insert(sol(List0), E, sol(List)) :-
+    set_ordlist.insert_2(List0, E, List).
 
-set_ordlist.insert([], E, [E]).
-set_ordlist.insert([I | Is], E, Js) :-
+:- pred set_ordlist.insert_2(list(T)::in, T::in, list(T)::out)
+    is det.
+
+set_ordlist.insert_2([], E, [E]).
+set_ordlist.insert_2([I | Is], E, Js) :-
     compare(R, I, E),
     (
         R = (<),
-        set_ordlist.insert(Is, E, Ks),
+        set_ordlist.insert_2(Is, E, Ks),
         Js = [I | Ks]
     ;
         R = (=),
@@ -312,13 +324,13 @@
         Js = [E, I | Is]
     ).
 
-set_ordlist.init([]).
+set_ordlist.init(sol([])).
 
-set_ordlist.singleton_set([X], X).
+set_ordlist.singleton_set(sol([X]), X).
 
 set_ordlist.equal(Set, Set).
 
-set_ordlist.empty([]).
+set_ordlist.empty(sol([])).
 
 set_ordlist.subset(Subset, Set) :-
     set_ordlist.intersect(Set, Subset, Subset).
@@ -328,17 +340,22 @@
 
 :- pragma promise_equivalent_clauses(set_ordlist.member/2).
 
-set_ordlist.member(E::out, S::in) :-
+set_ordlist.member(E::out, sol(S)::in) :-
     list.member(E, S).
 set_ordlist.member(E::in, S::in) :-
     set_ordlist.is_member(E, S, yes).
 
-set_ordlist.is_member(_E, [], no).
-set_ordlist.is_member(E, [H | T], R) :-
+set_ordlist.is_member(E, sol(L), R) :-
+    set_ordlist.is_member_2(E, L, R).
+
+:- pred set_ordlist.is_member_2(T::in, list(T)::in, bool::out) is det.
+
+set_ordlist.is_member_2(_E, [], no).
+set_ordlist.is_member_2(E, [H | T], R) :-
     compare(Res, H, E),
     (
         Res = (<),
-        set_ordlist.is_member(E, T, R)
+        set_ordlist.is_member_2(E, T, R)
     ;
         Res = (=),
         R = yes
@@ -352,10 +369,10 @@
 
 set_ordlist.delete_list(S0, D, S) :-
     list.sort_and_remove_dups(D, DS),
-    set_ordlist.difference(S0, DS, S).
+    set_ordlist.difference(S0, sol(DS), S).
 
 set_ordlist.delete(Set0, Elem, Set) :-
-    set_ordlist.difference(Set0, [Elem], Set).
+    set_ordlist.difference(Set0, sol([Elem]), Set).
 
 set_ordlist.remove_list(Set0, Elems, Set) :-
     set_ordlist.sort_no_dups(Elems, ElemSet),
@@ -368,7 +385,7 @@
     % 
 :- pred set_ordlist.sort_no_dups(list(T)::in, set_ordlist(T)::out) is semidet.
 
-set_ordlist.sort_no_dups(List, Set) :-
+set_ordlist.sort_no_dups(List, sol(Set)) :-
     list.sort(List, Set),
     (
         Set = []
@@ -387,21 +404,20 @@
     Elem \= Elem0,
     set_ordlist.no_dups(Elem0, Elems).
 
-set_ordlist.remove(Set0, Elem, Set) :-
+set_ordlist.remove(sol(Set0), Elem, sol(Set)) :-
     list.delete_first(Set0, Elem, Set).
 
-set_ordlist.remove_least([Elem | Set], Elem, Set).
+set_ordlist.remove_least(sol([Elem | Set]), Elem, sol(Set)).
 
-set_ordlist.union(Set0, Set1, Set) :-
+set_ordlist.union(sol(Set0), sol(Set1), sol(Set)) :-
     list.merge_and_remove_dups(Set0, Set1, Set).
 
 set_ordlist.union_list(ListofSets) = Set :-
     set_ordlist.init(Set0),
     set_ordlist.power_union_2(ListofSets, Set0, Set).
 
-set_ordlist.power_union(SetofSets, Set) :-
-    set_ordlist.init(Set0),
-    set_ordlist.power_union_2(SetofSets, Set0, Set).
+set_ordlist.power_union(sol(ListofSets), Set) :-
+    Set = set_ordlist.union_list(ListofSets).
 
 :- pred set_ordlist.power_union_2(list(set_ordlist(T))::in, set_ordlist(T)::in,
     set_ordlist(T)::out) is det.
@@ -411,57 +427,70 @@
     set_ordlist.union(Set0, NextSet, Set1),
     set_ordlist.power_union_2(SetofSets, Set1, Set).
 
-set_ordlist.intersect([], _, []).
-set_ordlist.intersect([_ | _], [], []).
-set_ordlist.intersect([X | Xs], [Y | Ys], Set) :-
+set_ordlist.intersect(sol(Xs), sol(Ys), sol(Set)) :-
+    set_ordlist.intersect_2(Xs, Ys, Set).
+
+:- pred set_ordlist.intersect_2(list(T), list(T), list(T)).
+:- mode set_ordlist.intersect_2(in, in, out) is det.
+:- mode set_ordlist.intersect_2(in, in, in) is semidet.
+
+set_ordlist.intersect_2([], _, []).
+set_ordlist.intersect_2([_ | _], [], []).
+set_ordlist.intersect_2([X | Xs], [Y | Ys], Set) :-
     compare(R, X, Y),
     (
         R = (<),
-        set_ordlist.intersect(Xs, [Y | Ys], Set)
+        set_ordlist.intersect_2(Xs, [Y | Ys], Set)
     ;
         R = (=),
-        set_ordlist.intersect(Xs, Ys, Set0),
+        set_ordlist.intersect_2(Xs, Ys, Set0),
         Set = [X | Set0]
     ;
         R = (>),
-        set_ordlist.intersect([X | Xs], Ys, Set)
+        set_ordlist.intersect_2([X | Xs], Ys, Set)
     ).
 
-set_ordlist.power_intersect([], []).
-set_ordlist.power_intersect([S0 | Ss], S) :-
+set_ordlist.power_intersect(sol(S0), S) :-
+    set_ordlist.intersect_list(S0) = S.
+
+set_ordlist.intersect_list([]) = sol([]).
+set_ordlist.intersect_list([S0 | Ss]) = S :-
     (
         Ss = [],
         S = S0
     ;
         Ss = [_ | _],
-        set_ordlist.power_intersect(Ss, S1),
+        S1 = set_ordlist.intersect_list(Ss),
         set_ordlist.intersect(S1, S0, S)
     ).
 
-set_ordlist.intersect_list(Sets) =
-    set_ordlist.power_intersect(Sets).
-
 %--------------------------------------------------------------------------%
 
-set_ordlist.difference([], _, []).
-set_ordlist.difference([X | Xs], [], [X | Xs]).
-set_ordlist.difference([X | Xs], [Y | Ys], Set) :-
+set_ordlist.difference(sol(Xs), sol(Ys), sol(Set)) :-
+    set_ordlist.difference_2(Xs, Ys, Set).
+
+:- pred set_ordlist.difference_2(list(T)::in, list(T)::in, list(T)::out)
+    is det.
+
+set_ordlist.difference_2([], _, []).
+set_ordlist.difference_2([X | Xs], [], [X | Xs]).
+set_ordlist.difference_2([X | Xs], [Y | Ys], Set) :-
     compare(R, X, Y),
     (
         R = (<),
-        set_ordlist.difference(Xs, [Y | Ys], Set0),
+        set_ordlist.difference_2(Xs, [Y | Ys], Set0),
         Set = [X | Set0]
     ;
         R = (=),
-        set_ordlist.difference(Xs, Ys, Set)
+        set_ordlist.difference_2(Xs, Ys, Set)
     ;
         R = (>),
-        set_ordlist.difference([X | Xs], Ys, Set)
+        set_ordlist.difference_2([X | Xs], Ys, Set)
     ).
 
 %--------------------------------------------------------------------------%
 
-set_ordlist.count(Set, Count) :-
+set_ordlist.count(sol(Set), Count) :-
     list.length(Set, Count).
 
 %-----------------------------------------------------------------------------%
@@ -527,15 +556,15 @@
     % The calls to reverse allow us to make set_ordlist.divide_2 tail
     % recursive. This costs us a higher constant factor, but allows
     % set_ordlist.divide to work in constant stack space.
-set_ordlist.divide(Pred, Set, TruePart, FalsePart) :-
+set_ordlist.divide(Pred, sol(Set), sol(TruePart), sol(FalsePart)) :-
     set_ordlist.divide_2(Pred, Set, [], RevTruePart, [], RevFalsePart),
     list.reverse(RevTruePart, TruePart),
     list.reverse(RevFalsePart, FalsePart).
 
 :- pred set_ordlist.divide_2(pred(T)::in(pred(in) is semidet),
-    set_ordlist(T)::in,
-    set_ordlist(T)::in, set_ordlist(T)::out,
-    set_ordlist(T)::in, set_ordlist(T)::out) is det.
+    list(T)::in,
+    list(T)::in, list(T)::out,
+    list(T)::in, list(T)::out) is det.
 
 set_ordlist.divide_2(_Pred, [], RevTrue, RevTrue, RevFalse, RevFalse).
 set_ordlist.divide_2(Pred, [H | T], RevTrue0, RevTrue, RevFalse0, RevFalse) :-
@@ -548,16 +577,16 @@
     ),
     set_ordlist.divide_2(Pred, T, RevTrue1, RevTrue, RevFalse1, RevFalse).
 
-set_ordlist.divide_by_set(DivideBySet, Set, TruePart, FalsePart) :-
+set_ordlist.divide_by_set(sol(DivideBySet), sol(Set),
+        sol(TruePart), sol(FalsePart)) :-
     set_ordlist.divide_by_set_2(DivideBySet, Set,
         [], RevTruePart, [], RevFalsePart),
     list.reverse(RevTruePart, TruePart),
     list.reverse(RevFalsePart, FalsePart).
 
-:- pred set_ordlist.divide_by_set_2(set_ordlist(T1)::in,
-    set_ordlist(T1)::in,
-    set_ordlist(T1)::in, set_ordlist(T1)::out,
-    set_ordlist(T1)::in, set_ordlist(T1)::out) is det.
+:- pred set_ordlist.divide_by_set_2(list(T1)::in, list(T1)::in,
+    list(T1)::in, list(T1)::out,
+    list(T1)::in, list(T1)::out) is det.
 
 set_ordlist.divide_by_set_2([], [], !RevTrue, !RevFalse).
 set_ordlist.divide_by_set_2([], [H | T], !RevTrue, !RevFalse) :-
@@ -579,3 +608,6 @@
         set_ordlist.divide_by_set_2([Div | Divs], T,
             !RevTrue, !RevFalse)
     ).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list