[m-dev.] for review: set__divide
Zoltan Somogyi
zs at cs.mu.OZ.AU
Thu Jan 4 16:13:11 AEDT 2001
For review by anyone.
Estimated hours taken: 1
Add a predicate to each of the set, set_ordlist and set_unordlist modules
that divides a set into two parts: the elements for which a test succeeds
and the elements for which it fails.
library/set.m:
library/set_ordlist.m:
library/set_unordlist.m:
Add {set,set_ordlist,set_unordlist}_divide.
Zoltan.
cvs diff: Diffing library
Index: library/set.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/set.m,v
retrieving revision 1.55
diff -u -b -r1.55 set.m
--- library/set.m 2000/11/12 08:51:36 1.55
+++ library/set.m 2001/01/03 12:56:57
@@ -1,5 +1,5 @@
%---------------------------------------------------------------------------%
-% Copyright (C) 1994-1997, 1999-2000 The University of Melbourne.
+% Copyright (C) 1994-1997, 1999-2001 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -245,6 +245,12 @@
:- func set__fold(func(T1, T2) = T2, set(T1), T2) = T2.
+ % set__divide(Pred, Set, TruePart, FalsePart):
+ % TruePart consists of those elements of Set for which Pred succeeds;
+ % FalsePart consists of those elements of Set for which Pred fails.
+:- pred set__divide(pred(T1), set(T1), set(T1), set(T1)).
+:- mode set__divide(pred(in) is semidet, in, out, out) is det.
+
%--------------------------------------------------------------------------%
:- implementation.
@@ -426,3 +432,5 @@
set__fold(F, S, A) = B :-
B = list__foldl(F, set__to_sorted_list(S), A).
+set__divide(P, Set, TruePart, FalsePart) :-
+ set_ordlist__divide(P, Set, TruePart, FalsePart).
Index: library/set_ordlist.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/set_ordlist.m,v
retrieving revision 1.12
diff -u -b -r1.12 set_ordlist.m
--- library/set_ordlist.m 2000/11/12 08:51:36 1.12
+++ library/set_ordlist.m 2001/01/03 13:27:11
@@ -230,6 +230,13 @@
:- func set_ordlist__fold(func(T1, T2) = T2, set_ordlist(T1), T2) = T2.
+ % set_ordlist__divide(Pred, Set, TruePart, FalsePart):
+ % TruePart consists of those elements of Set for which Pred succeeds;
+ % FalsePart consists of those elements of Set for which Pred fails.
+:- pred set_ordlist__divide(pred(T1), set_ordlist(T1), set_ordlist(T1),
+ set_ordlist(T1)).
+:- mode set_ordlist__divide(pred(in) is semidet, in, out, out) is det.
+
%--------------------------------------------------------------------------%
:- implementation.
@@ -487,3 +494,27 @@
set_ordlist__fold(F, S, A) = B :-
B = list__foldl(F, set_ordlist__to_sorted_list(S), A).
+ % 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_2(Pred, Set, [], RevTruePart, [], RevFalsePart),
+ list__reverse(RevTruePart, TruePart),
+ list__reverse(RevFalsePart, FalsePart).
+
+:- pred set_ordlist__divide_2(pred(T1), set_ordlist(T1),
+ set_ordlist(T1), set_ordlist(T1),
+ set_ordlist(T1), set_ordlist(T1)).
+:- mode set_ordlist__divide_2(pred(in) is semidet, in, in, out, in, out)
+ is det.
+
+set_ordlist__divide_2(_Pred, [], RevTrue, RevTrue, RevFalse, RevFalse).
+set_ordlist__divide_2(Pred, [H | T], RevTrue0, RevTrue, RevFalse0, RevFalse) :-
+ ( call(Pred, H) ->
+ RevTrue1 = [H | RevTrue0],
+ RevFalse1 = RevFalse0
+ ;
+ RevTrue1 = RevTrue0,
+ RevFalse1 = [H | RevFalse0]
+ ),
+ set_ordlist__divide_2(Pred, T, RevTrue1, RevTrue, RevFalse1, RevFalse).
Index: library/set_unordlist.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/set_unordlist.m,v
retrieving revision 1.17
diff -u -b -r1.17 set_unordlist.m
--- library/set_unordlist.m 2000/11/12 08:51:36 1.17
+++ library/set_unordlist.m 2001/01/04 04:10:04
@@ -226,6 +226,12 @@
:- func set_unordlist__fold(func(T1, T2) = T2, set_unordlist(T1), T2) = T2.
+ % set_unordlist__divide(Pred, Set, TruePart, FalsePart):
+ % TruePart consists of those elements of Set for which Pred succeeds;
+ % FalsePart consists of those elements of Set for which Pred fails.
+:- pred set_unordlist__divide(pred(T1), set_unordlist(T1), set_unordlist(T1),
+ set_unordlist(T1)).
+:- mode set_unordlist__divide(pred(in) is semidet, in, out, out) is det.
%--------------------------------------------------------------------------%
@@ -417,3 +423,24 @@
set_unordlist__fold(F, S, A) = B :-
B = list__foldl(F, set_unordlist__to_sorted_list(S), A).
+set_unordlist__divide(Pred, Set, RevTruePart, RevFalsePart) :-
+ set_unordlist__divide_2(Pred, Set, [], RevTruePart, [], RevFalsePart).
+
+:- pred set_unordlist__divide_2(pred(T1), set_unordlist(T1),
+ set_unordlist(T1), set_unordlist(T1),
+ set_unordlist(T1), set_unordlist(T1)).
+:- mode set_unordlist__divide_2(pred(in) is semidet, in, in, out, in, out)
+ is det.
+
+set_unordlist__divide_2(_Pred, [], RevTrue, RevTrue, RevFalse, RevFalse).
+set_unordlist__divide_2(Pred, [H | T],
+ RevTrue0, RevTrue, RevFalse0, RevFalse) :-
+ ( call(Pred, H) ->
+ RevTrue1 = [H | RevTrue0],
+ RevFalse1 = RevFalse0
+ ;
+ RevTrue1 = RevTrue0,
+ RevFalse1 = [H | RevFalse0]
+ ),
+ set_unordlist__divide_2(Pred, T,
+ RevTrue1, RevTrue, RevFalse1, RevFalse).
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list