[m-dev.] for review: function def's for single out det mode library predicates

Fergus Henderson fjh at cs.mu.OZ.AU
Wed May 26 15:26:16 AEST 1999


Here's a reformatted version of Ralph's changes.
I've reformatted the diff to use unified diff format,
and modified the log message slightly to more closely
match how we usually format our log messages;

The diff itself is unchanged.  I will post my review comments
on this diff in a separate message.

--------------------

Estimated hours taken: 5

Add functions for the single output det predicates in a number
of modules in the standard library.  Basically, for each

	:- pred f(in, ..., in, out) is det.

I have added the declaration

	:- func f(in, ..., in) = out.

and definition

	f(X1, ..., Xn) = Y :-
		f(X1, ..., Xn, Y).

library/char.m:
library/dir.m:
library/map.m:
library/string.m:
library/list.m:
library/set.m:
	Make the changes described above.

library/array.m:
	As above, except array input modes are all array_ui or
	array_di as appropriate and array output modes are array_uo.

library/int.m:
	Added forward versions of +/2, */2 and -/2 as plus/2, times/2
	and minus/2 respectively, to make it easier to pass these
	as arguments to higher-order predicates.
	Also added func constants for max_int, min_int and bits_per_int.

library/integer.m:
	Replaced local functions for list head, tail and length with
	calls to equivalent functions now defined in list.m.

library/io.m:
	Added func for error_message/2.

library/list.m:
	Add functions det_head/1 and det_tail/1 which abort on null lists.

library/set.m:
	Add functions map/2, filter_map/2 and fold/3.

library/std_util.m:
	Added utility function to construct a pair object from its
	arguments and general purpose higher order functions for 
	partial functions and for function composition, exponentiation
	and exchanging the arguments of a binary function.

Workspace: /tmp/fjh/mercury
Index: library/array.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/array.m,v
retrieving revision 1.53
diff -u -r1.53 array.m
--- array.m	1999/03/31 04:42:49	1.53
+++ array.m	1999/05/26 04:23:58
@@ -28,6 +28,9 @@
 % part of the library.
 %
 
+% Ralph Becket <rwab1 at cam.sri.com> 24/04/99
+%	Function forms added.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -135,6 +138,7 @@
 :- pred array__set(array(T), int, T, array(T)).
 :- mode array__set(array_di, in, in, array_uo) is det.
 
+
 	% array__semidet_set sets the nth element of an array,
 	% and returns the resulting array.
 	% It fails if the index is out of bounds.
@@ -178,6 +182,7 @@
 :- pred array__shrink(array(T), int, array(T)).
 :- mode array__shrink(array_di, in, array_uo) is det.
 
+
 	% array__from_list takes a list,
 	% and returns an array containing those elements in
 	% the same order that they occured in the list.
@@ -198,6 +203,7 @@
 :- pred array__fetch_items(array(T), int, int, list(T)).
 :- mode array__fetch_items(in, in, in, out) is det.
 
+
 	% array__bsearch takes an array, an element to be found
 	% and a comparison predicate and returns the position of
 	% the element in the array.  Assumes the array is in sorted
@@ -209,6 +215,9 @@
 :- mode array__bsearch(array_ui, in, pred(in, in, out) is det, out) is det.
 :- mode array__bsearch(in, in, pred(in, in, out) is det, out) is det.
 
+	% XXX rwab1: I observe that the comparison procedure takes mode
+	% in, in, out whereas historically this type of predicate is
+
 	% array__map(Closure, OldArray, NewArray) applys `Closure' to
 	% each of the elements of `OldArray' to create `NewArray'.
 :- pred array__map(pred(T1, T2), array(T1), array(T2)).
@@ -756,3 +765,118 @@
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cam.sri.com> 24/04/99
+%	Function forms added.
+
+:- interface.
+
+:- func array__make_empty_array = array(T).
+:- mode array__make_empty_array = array_uo is det.
+
+:- func array__init(int, T) = array(T).
+:- mode array__init(in, in) = array_uo is det.
+
+:- func array__min(array(_T)) = int.
+:- mode array__min(array_ui) = out is det.
+
+:- func array__max(array(_T)) = int.
+:- mode array__max(array_ui) = out is det.
+
+:- func array__size(array(_T)) = int.
+:- mode array__size(array_ui) = out is det.
+
+:- func array__lookup(array(T), int) = T.
+:- mode array__lookup(array_ui, in) = out is det.
+
+	% XXX rwab1: Is the above missing an in, in, in, out mode is det.
+:- func array__set(array(T), int, T) = array(T).
+:- mode array__set(array_di, in, in) = array_uo is det.
+
+:- func array__slow_set(array(T), int, T) = array(T).
+:- mode array__slow_set(array_ui, in, in) = array_uo is det.
+
+:- func array__copy(array(T)) = array(T).
+:- mode array__copy(array_ui) = array_uo is det.
+
+:- func array__resize(array(T), int, T) = array(T).
+:- mode array__resize(array_di, in, in) = array_uo is det.
+
+:- func array__shrink(array(T), int) = array(T).
+:- mode array__shrink(array_di, in) = array_uo is det.
+
+:- func array__from_list(list(T)) = array(T).
+:- mode array__from_list(in) = array_uo is det.
+
+:- func array__to_list(array(T)) = list(T).
+:- mode array__to_list(array_ui) = out is det.
+
+:- func array__fetch_items(array(T), int, int) = list(T).
+:- mode array__fetch_items(array_ui, in, in) = out is det.
+
+:- func array__bsearch(array(T), T, func(T,T) = comparison_result) = maybe(int).
+:- mode array__bsearch(array_ui, in, func(in,in) = out is det) = out is det.
+
+:- func array__map(func(T1) = T2, array(T1)) = array(T2).
+:- mode array__map(func(in) = out is det, array_di) = array_uo is det.
+
+:- func array_compare(array(T), array(T)) = comparison_result.
+:- mode array_compare(in, in) = out is det.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+array__make_empty_array = A :-
+	array__make_empty_array(A).
+
+array__init(N, X) = A :-
+	array__init(N, X, A).
+
+array__min(A) = N :-
+	array__min(A, N).
+
+array__max(A) = N :-
+	array__max(A, N).
+
+array__size(A) = N :-
+	array__size(A, N).
+
+array__lookup(A, N) = X :-
+	array__lookup(A, N, X).
+
+array__set(A1, N, X) = A2 :-
+	array__set(A1, N, X, A2).
+
+array__slow_set(A1, N, X) = A2 :-
+	array__slow_set(A1, N, X, A2).
+
+array__copy(A1) = A2 :-
+	array__copy(A1, A2).
+
+array__resize(A1, N, X) = A2 :-
+	array__resize(A1, N, X, A2).
+
+array__shrink(A1, N) = A2 :-
+	array__shrink(A1, N, A2).
+
+array__from_list(Xs) = A :-
+	array__from_list(Xs, A).
+
+array__to_list(A) = Xs :-
+	array__to_list(A, Xs).
+
+array__fetch_items(A, N1, N2) = Xs :-
+	array__fetch_items(A, N1, N2, Xs).
+
+array__bsearch(A, X, F) = MN :-
+	P = ( pred(X1::in, X2::in, C::out) is det :- C = F(X1, X2) ),
+	array__bsearch(A, X, P, MN).
+
+array__map(F, A1) = A2 :-
+	P = ( pred(X::in, Y::out) is det :- Y = F(X) ),
+	array__map(P, A1, A2).
+
+array_compare(A1, A2) = C :-
+	array_compare(C, A1, A2).
+
Index: library/char.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/char.m,v
retrieving revision 1.27
diff -u -r1.27 char.m
--- char.m	1999/03/15 08:48:06	1.27
+++ char.m	1999/05/26 04:23:59
@@ -431,5 +431,48 @@
                [will_not_call_mercury, thread_safe], "
 	Max = UCHAR_MAX;
 ").
-	
+
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+%       Functional forms added.
+
+:- interface.
+
+:- func char__to_int(char) = int.
+
+:- func char__max_char_value = int.
+
+:- func char__min_char_value = int.
+
+:- func char__to_upper(char) = char.
+
+:- func char__to_lower(char) = char.
+
+:- func char__det_int_to_digit(int) = char.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+char__to_int(C) = N :-
+	char__to_int(C, N).
+
+char__max_char_value = N :-
+	char__max_char_value(N).
+
+char__min_char_value = N :-
+	char__min_char_value(N).
+
+char__to_upper(C1) = C2 :-
+	char__to_upper(C1, C2).
+
+char__to_lower(C1) = C2 :-
+	char__to_lower(C1, C2).
+
+char__det_int_to_digit(N) = C :-
+	char__det_int_to_digit(N, C).
+
+
+
Index: library/dir.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/dir.m,v
retrieving revision 1.10
diff -u -r1.10 dir.m
--- dir.m	1998/01/23 12:33:14	1.10
+++ dir.m	1999/05/26 04:23:59
@@ -77,3 +77,34 @@
 	dir__split_name(FileName, DirName, _).
 
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+%       Functional forms added.
+
+:- interface.
+
+:- func dir__directory_separator = character.
+
+:- func dir__this_directory = string.
+
+:- func dir__basename(string) = string.
+
+:- func dir__dirname(string) = string.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+dir__directory_separator = C :-
+	dir__directory_separator(C).
+
+dir__this_directory = S :-
+	dir__this_directory(S).
+
+dir__basename(S1) = S2 :-
+	dir__basename(S1, S2).
+
+dir__dirname(S1) = S2 :-
+	dir__dirname(S1, S2).
+
Index: library/int.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/int.m,v
retrieving revision 1.56
diff -u -r1.56 int.m
--- int.m	1999/03/30 05:30:46	1.56
+++ int.m	1999/05/26 04:23:59
@@ -424,3 +424,42 @@
 	Bits = sizeof(Integer) * CHAR_BIT;
 ").
 
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+% 	Functional forms added.
+
+:- interface.
+
+:- func int__plus(int, int) = int.
+
+:- func int__times(int, int) = int.
+
+:- func int__minus(int, int) = int.
+
+:- func int__max_int = int.
+
+:- func int__min_int = int.
+
+:- func int__bits_per_int = int.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+int__plus(X, Y) = X + Y.
+
+int__times(X, Y) = X * Y.
+
+int__minus(X, Y) = X - Y.
+
+int__max_int = X :-
+	int__max_int(X).
+
+int__min_int = X :-
+	int__min_int(X).
+
+int__bits_per_int = X :-
+	int__bits_per_int(X).
+
Index: library/integer.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/integer.m,v
retrieving revision 1.2
diff -u -r1.2 integer.m
--- integer.m	1998/04/16 12:13:41	1.2
+++ integer.m	1999/05/26 04:24:00
@@ -624,38 +624,40 @@
 		;
 			Q = Qhat - 2
 		),
-		V0 = head(V),
-		U0 = head(Ur),
-		LengthUr = length(Ur),
-		LengthV = length(V),
+		V0 = list__det_head(V),
+		U0 = list__det_head(Ur),
+		LengthUr = list__length(Ur),
+		LengthV = list__length(V),
 		( LengthUr > LengthV ->
 			Qhat = (U0*B+U1) div V0,
-			U1 = head(tail(Ur))
+			U1 = list__det_head(list__det_tail(Ur))
 		;
 			Qhat = U0 div V0
 		),
 		B = base
 	).
 
-:- func length(list(T)) = int.
-length([]) = 0.
-length([_|Xs]) = 1 + length(Xs).
+	% XXX rwab1 27/04/99: Versions of these functions now exist in list.m
 
-:- func head(list(T)) = T.
-head(HT) = H :-
-	( HT = [Hd|_T] ->
-		H = Hd
-	;
-		error("integer__head: []")
-	).
-		
-:- func tail(list(T)) = list(T).
-tail(HT) = T :-
-	( HT = [_H|Tl] ->
-		T = Tl
-	;
-		error("integer__tail: []")
-	).
+% :- func length(list(T)) = int.
+% length([]) = 0.
+% length([_|Xs]) = 1 + length(Xs).
+% 
+% :- func head(list(T)) = T.
+% head(HT) = H :-
+% 	( HT = [Hd|_T] ->
+% 		H = Hd
+% 	;
+% 		error("integer__head: []")
+% 	).
+% 		
+% :- func tail(list(T)) = list(T).
+% tail(HT) = T :-
+% 	( HT = [_H|Tl] ->
+% 		T = Tl
+% 	;
+% 		error("integer__tail: []")
+% 	).
 
 
 	% Multiply a *reverse* list of digits (big end first)
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.174
diff -u -r1.174 io.m
--- io.m	1999/03/10 23:24:33	1.174
+++ io.m	1999/05/26 04:24:00
@@ -3395,3 +3395,21 @@
 }").
 
 /*---------------------------------------------------------------------------*/
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+%	Functional forms added.
+
+:- interface.
+
+:- func io__error_message(io__error) = string.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+io__error_message(Error) = Msg :-
+	io__error_message(Error, Msg).
+
Index: library/list.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.86
diff -u -r1.86 list.m
--- list.m	1999/03/15 08:48:07	1.86
+++ list.m	1999/05/26 04:24:00
@@ -1127,3 +1127,173 @@
 
 
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+% 	Functional forms added.
+
+:- interface.
+
+:- func list__det_head(list(T)) = T.
+
+:- func list__det_tail(list(T)) = list(T).
+
+:- func list__append(list(T), list(T)) = list(T).
+
+:- func list__merge(list(T), list(T)) = list(T).
+
+:- func list__merge_and_remove_dups(list(T), list(T)) = list(T).
+
+:- func list__remove_adjacent_dups(list(T)) = list(T).
+
+:- func list__remove_dups(list(T)) = list(T).
+
+:- func list__length(list(T)) = int.
+
+:- func list__take_upto(int, list(T)) = list(T).
+
+:- func list__delete_all(list(T), T) = list(T).
+
+:- func list__delete_elems(list(T), list(T)) = list(T).
+
+:- func list__replace_all(list(T), T, T) = list(T).
+
+:- func list__replace_nth_det(list(T), int, T) = list(T).
+
+:- func list__sort_and_remove_dups(list(T)) = list(T).
+
+:- func list__sort(list(T)) = list(T).
+
+:- func list__reverse(list(T)) = list(T).
+
+:- func list__index0_det(list(T), int) = T.
+
+:- func list__index1_det(list(T), int) = T.
+
+:- func list__zip(list(T), list(T)) = list(T).
+
+:- func list__duplicate(int, T) = list(T).
+
+:- func list__condense(list(list(T))) = list(T).
+
+:- func list__chunk(list(T), int) = list(list(T)).
+
+:- func list__map(func(X) = Y, list(X)) = list(Y).
+
+:- func list__foldl(func(X, Y) = Y, list(X), Y) = Y.
+
+:- func list__foldr(func(X, Y) = Y, list(X), Y) = Y.
+
+:- func list__filter(pred(X), list(X)) = list(X).
+:- mode list__filter(pred(in) is semidet, in) = out is det.
+
+:- func list__filter_map(func(X) = Y, list(X)) = list(Y).
+:- mode list__filter_map(func(in) = out is semidet, in) = out is det.
+
+:- func list__sort(func(X, X) = comparison_result, list(X)) = list(X).
+
+:- func list__merge(func(X, X) = comparison_result, list(X), list(X)) = list(X).
+
+:- func list__merge_and_remove_dups(func(X, X) = comparison_result, list(X), list(X)) = list(X).
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+list__det_head([]) = _ :- error("list__det_head/1: empty list as argument").
+list__det_head([X | _]) = X.
+
+list__det_tail([]) = _ :- error("list__det_tail/1: empty list as argument").
+list__det_tail([_ | Xs]) = Xs.
+
+list__append(Xs, Ys) = Zs :-
+	list__append(Xs, Ys, Zs).
+
+list__merge(Xs, Ys) = Zs :-
+	list__merge(Xs, Ys, Zs).
+
+list__merge_and_remove_dups(Xs, Ys) = Zs :-
+	list__merge_and_remove_dups(Xs, Ys, Zs).
+
+list__remove_adjacent_dups(Xs) = Ys :-
+	list__remove_adjacent_dups(Xs, Ys).
+
+list__remove_dups(Xs) = Ys :-
+	list__remove_dups(Xs, Ys).
+
+list__length(Xs) = N :-
+	list__length(Xs, N).
+
+list__take_upto(N, Xs) = Ys :-
+	list__take_upto(N, Xs, Ys).
+
+list__delete_all(Xs, A) = Ys :-
+	list__delete_all(Xs, A, Ys).
+
+list__delete_elems(Xs, Ys) = Zs :-
+	list__delete_elems(Xs, Ys, Zs).
+
+list__replace_all(Xs, A, B) = Ys :-
+	list__replace_all(Xs, A, B, Ys).
+
+list__replace_nth_det(Xs, N, A) = Ys :-
+	list__replace_nth_det(Xs, N, A, Ys).
+
+list__sort_and_remove_dups(Xs) = Ys :-
+	list__sort_and_remove_dups(Xs, Ys).
+
+list__sort(Xs) = Ys :-
+	list__sort(Xs, Ys).
+
+list__reverse(Xs) = Ys :-
+	list__reverse(Xs, Ys).
+
+list__index0_det(Xs, N) = A :-
+	list__index0_det(Xs, N, A).
+
+list__index1_det(Xs, N) = A :-
+	list__index1_det(Xs, N, A).
+
+list__zip(Xs, Ys) = Zs :-
+	list__zip(Xs, Ys, Zs).
+
+list__duplicate(N, A) = Xs :-
+	list__duplicate(N, A, Xs).
+
+list__condense(Xss) = Ys :-
+	list__condense(Xss, Ys).
+
+list__chunk(Xs, N) = Ys :-
+	list__chunk(Xs, N, Ys).
+
+list__map(F, Xs) = Ys :-
+	P = ( pred(X::in, Y::out) is det :- Y = F(X) ),
+	list__map(P, Xs, Ys).
+
+list__foldl(F, Xs, A) = B :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	list__foldl(P, Xs, A, B).
+
+list__foldr(F, Xs, A) = B :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	list__foldr(P, Xs, A, B).
+
+list__filter(P, Xs) = Ys :-
+	list__filter(P, Xs, Ys).
+
+list__filter_map(F, Xs) = Ys :-
+	P = ( pred(X::in, Y::out) is semidet :- Y = F(X) ),
+	list__filter_map(P, Xs, Ys).
+
+list__sort(F, Xs) = Ys :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	list__sort(P, Xs, Ys).
+
+list__merge(F, Xs, Ys) = Zs :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	list__merge(P, Xs, Ys, Zs).
+
+list__merge_and_remove_dups(F, Xs, Ys) = Zs :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	list__merge_and_remove_dups(P, Xs, Ys, Zs).
+
Index: library/map.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/map.m,v
retrieving revision 1.69
diff -u -r1.69 map.m
--- map.m	1999/03/15 08:48:08	1.69
+++ map.m	1999/05/26 04:24:01
@@ -603,3 +603,162 @@
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+% 	Functional forms added.
+
+:- interface.
+
+:- func map__lookup(map(K,V), K) = V.
+
+:- func map__det_insert(map(K,V), K, V) = map(K,V).
+
+:- func map__det_insert_from_corresponding_lists(map(K,V), list(K), list(V)) =
+		map(K,V).
+
+:- func map__det_insert_from_assoc_list(map(K,V), assoc_list(K, V)) = map(K,V).
+
+:- func map__det_update(map(K,V), K, V) = map(K,V).
+
+:- func map__set(map(K,V), K, V) = map(K,V).
+
+:- func map__keys(map(K, _V)) = list(K).
+
+:- func map__sorted_keys(map(K, _V)) = list(K).
+
+:- func map__values(map(_K, V)) = list(V).
+
+:- func map__to_assoc_list(map(K,V)) = assoc_list(K,V).
+
+:- func map__to_sorted_assoc_list(map(K,V)) = assoc_list(K,V).
+
+:- func map__from_assoc_list(assoc_list(K,V)) = map(K,V).
+
+:- func map__from_sorted_assoc_list(assoc_list(K,V)) = map(K,V).
+
+:- func map__delete(map(K,V), K) = map(K,V).
+
+:- func map__delete_list(map(K,V), list(K)) = map(K,V).
+
+:- func map__count(map(K, V)) = int.
+
+:- func map__from_corresponding_lists(list(K), list(V)) = map(K, V).
+
+:- func map__merge(map(K, V), map(K, V)) = map(K, V).
+
+:- func map__overlay(map(K,V), map(K,V)) = map(K,V).
+
+:- func map__select(map(K,V), set(K)) = map(K,V).
+
+:- func map__apply_to_list(list(K), map(K, V)) = list(V).
+
+:- func map__optimize(map(K, V)) = map(K, V).
+
+:- func map__foldl(func(K, V, T) = T, map(K, V), T) = T.
+
+:- func map__map_values(func(K, V) = W, map(K, V)) = map(K, W).
+
+:- func map__intersect(func(V, V) = V, map(K, V), map(K, V)) = map(K, V).
+
+:- func map__det_intersect(func(V, V) = V, map(K, V), map(K, V)) = map(K, V).
+:- mode map__det_intersect(func(in, in) = out is semidet, in, in) = out is det.
+
+:- func map__union(func(V, V) = V, map(K, V), map(K, V)) = map(K, V).
+
+:- func map__det_union(func(V, V) = V, map(K, V), map(K, V)) = map(K, V).
+:- mode map__det_union(func(in, in) = out is semidet, in, in) = out is det.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+map__lookup(M, K) = V :-
+	map__lookup(M, K, V).
+
+map__det_insert(M1, K, V) = M2 :-
+	map__det_insert(M1, K, V, M2).
+
+map__det_insert_from_corresponding_lists(M1, Ks, Vs) = M2 :-
+	map__det_insert_from_corresponding_lists(M1, Ks, Vs, M2).
+
+map__det_insert_from_assoc_list(M1, AL) = M2 :-
+	map__det_insert_from_assoc_list(M1, AL, M2).
+
+map__det_update(M1, K, V) = M2 :-
+	map__det_update(M1, K, V, M2).
+
+map__set(M1, K, V) = M2 :-
+	map__set(M1, K, V, M2).
+
+map__keys(M) = Ks :-
+	map__keys(M, Ks).
+
+map__sorted_keys(M) = Ks :-
+	map__sorted_keys(M, Ks).
+
+map__values(M) = Vs :-
+	map__values(M, Vs).
+
+map__to_assoc_list(M) = AL :-
+	map__to_assoc_list(M, AL).
+
+map__to_sorted_assoc_list(M) = AL :-
+	map__to_sorted_assoc_list(M, AL).
+
+map__from_assoc_list(AL) = M :-
+	map__from_assoc_list(AL, M).
+
+map__from_sorted_assoc_list(AL) = M :-
+	map__from_sorted_assoc_list(AL, M).
+
+map__delete(M1, K) = M2 :-
+	map__delete(M1, K, M2).
+
+map__delete_list(M1, Ks) = M2 :-
+	map__delete_list(M1, Ks, M2).
+
+map__count(M) = N :-
+	map__count(M, N).
+
+map__from_corresponding_lists(Ks, Vs) = M :-
+	map__from_corresponding_lists(Ks, Vs, M).
+
+map__merge(M1, M2) = M3 :-
+	map__merge(M1, M2, M3).
+
+map__overlay(M1, M2) = M3 :-
+	map__overlay(M1, M2, M3).
+
+map__select(M1, S) = M2 :-
+	map__select(M1, S, M2).
+
+map__apply_to_list(Ks, M) = Vs :-
+	map__apply_to_list(Ks, M, Vs).
+
+map__optimize(M1) = M2 :-
+	map__optimize(M1, M2).
+
+map__foldl(F, M, A) = B :-
+	P = ( pred(W::in, X::in, Y::in, Z::out) is det :- Z = F(W, X, Y) ),
+	map__foldl(P, M, A, B).
+
+map__map_values(F, M1) = M2 :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	map__map_values(P, M1, M2).
+
+map__intersect(F, M1, M2) = M3 :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	map__intersect(P, M1, M2, M3).
+
+map__det_intersect(PF, M1, M2) = M3 :-
+	P = ( pred(X::in, Y::in, Z::out) is semidet :- Z = PF(X, Y) ),
+	map__det_intersect(P, M1, M2, M3).
+
+map__union(F, M1, M2) = M3 :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	map__union(P, M1, M2, M3).
+
+map__det_union(F, M1, M2) = M3 :-
+	P = ( pred(X::in, Y::in, Z::out) is semidet :- Z = F(X, Y) ),
+	map__det_union(P, M1, M2, M3).
+
Index: library/set.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/set.m,v
retrieving revision 1.50
diff -u -r1.50 set.m
--- set.m	1998/01/23 12:33:32	1.50
+++ set.m	1999/05/26 04:24:01
@@ -12,6 +12,9 @@
 % The implementation represents sets using ordered lists.
 % This file just calls the equivalent predicates in set_ordlist.
 
+% Ralph Becket <rwab1 at cam.sri.com> 24/04/99
+%	Function forms added.
+
 %--------------------------------------------------------------------------%
 
 :- module set.
@@ -26,6 +29,8 @@
 :- pred set__list_to_set(list(T), set(T)).
 :- mode set__list_to_set(in, out) is det.
 
+:- func set__list_to_set(list(T)) = set(T).
+
 	% `set__sorted_list_to_set(List, Set)' is true iff `Set' is the set 
 	% containing only the members of `List'.  `List' must be sorted
 	% and must not contain any duplicates.
@@ -33,6 +38,8 @@
 :- pred set__sorted_list_to_set(list(T), set(T)).
 :- mode set__sorted_list_to_set(in, out) is det.
 
+:- func set__sorted_list_to_set(list(T)) = set(T).
+
 	% `set__to_sorted_list(Set, List)' is true iff `List' is the list
 	% of all the members of `Set', in sorted order without any
 	% duplicates.
@@ -40,11 +47,15 @@
 :- pred set__to_sorted_list(set(T), list(T)).
 :- mode set__to_sorted_list(in, out) is det.
 
+:- func set__to_sorted_list(set(T)) = list(T).
+
 	% `set__init(Set)' is true iff `Set' is an empty set.
 
 :- pred set__init(set(T)).
 :- mode set__init(uo) is det.
 
+:- func set__init = set(T).
+
 	% `set__singleton_set(Set, Elem)' is true iff `Set' is the set
 	% containing just the single element `Elem'.
 
@@ -52,6 +63,8 @@
 :- mode set__singleton_set(in, out) is semidet.
 :- mode set__singleton_set(out, in) is det.
 
+:- func set__make_singleton_set(T) = set(T).
+
 	% `set__equal(SetA, SetB)' is true iff
 	% `SetA' and `SetB' contain the same elements.
 
@@ -91,12 +104,20 @@
 :- mode set__insert(di, di, uo) is det.
 :- mode set__insert(in, in, out) is det.
 
+	% XXX rwab1: I think we should reverse the args. here for
+	% higher order programming.
+:- func set__insert(set(T), T) = set(T).
+
 	% `set__insert_list(Set0, Xs, Set)' is true iff `Set' is the union of
 	% `Set0' and the set containing only the members of `Xs'.
 
 :- pred set__insert_list(set(T), list(T), set(T)).
 :- mode set__insert_list(in, in, out) is det.
 
+	% XXX rwab1: I think we should reverse the args. here for
+	% higher order programming.
+:- func set__insert_list(set(T), list(T)) = set(T).
+
 	% `set__delete(Set0, X, Set)' is true iff `Set' is the relative
 	% complement of `Set0' and the set containing only `X', i.e.
 	% if `Set' is the set which contains all the elements of `Set0'
@@ -106,6 +127,10 @@
 % :- mode set__delete(di, in, uo) is det.
 :- mode set__delete(in, in, out) is det.
 
+	% XXX rwab1: I think we should reverse the args. here for
+	% higher order programming.
+:- func set__delete(set(T), T) = set(T).
+
 	% `set__delete_list(Set0, Xs, Set)' is true iff `Set' is the relative
 	% complement of `Set0' and the set containing only the members of
 	% `Xs'.
@@ -113,6 +138,10 @@
 :- pred set__delete_list(set(T), list(T), set(T)).
 :- mode set__delete_list(in, in, out) is det.
 
+	% XXX rwab1: I think we should reverse the args. here for
+	% higher order programming.
+:- func set__delete_list(set(T), list(T)) = set(T).
+
 	% `set__remove(Set0, X, Set)' is true iff `Set0' contains `X',
 	% and `Set' is the relative complement of `Set0' and the set
 	% containing only `X', i.e.  if `Set' is the set which contains
@@ -150,12 +179,16 @@
 :- pred set__union(set(T), set(T), set(T)).
 :- mode set__union(in, in, out) is det.
 
+:- func set__union(set(T), set(T)) = set(T).
+
 	% `set__power_union(A, B)' is true iff `B' is the union of
 	% all the sets in `A'
 
 :- pred set__power_union(set(set(T)), set(T)).
 :- mode set__power_union(in, out) is det.
 
+:- func set__power_union(set(set(T))) = set(T).
+
 	% `set__intersect(SetA, SetB, Set)' is true iff `Set' is the
 	% intersection of `SetA' and `SetB'. If the two sets are
 	% known to be unequal in size, then making SetA be the larger
@@ -169,12 +202,16 @@
 :- pred set__intersect(set(T), set(T), set(T)).
 :- mode set__intersect(in, in, out) is det.
 
+:- func set__intersect(set(T), set(T)) = set(T).
+
 	% `set__power_intersect(A, B)' is true iff `B' is the intersection of
 	% all the sets in `A'
 
 :- pred set__power_intersect(set(set(T)), set(T)).
 :- mode set__power_intersect(in, out) is det.
 
+:- func set__power_intersect(set(set(T))) = set(T).
+
 	% `set__difference(SetA, SetB, Set)' is true iff `Set' is the
 	% set containing all the elements of `SetA' except those that
 	% occur in `SetB'
@@ -182,11 +219,24 @@
 :- pred set__difference(set(T), set(T), set(T)).
 :- mode set__difference(in, in, out) is det.
 
+:- func set__difference(set(T), set(T)) = set(T).
+
 	% `set__count(Set, Count)' is true iff `Set' has `Count' elements.
 
 :- pred set__count(set(T), int).
 :- mode set__count(in, out) is det.
 
+:- func set__count(set(T)) = int.
+
+	% Support for higher order set processing.
+
+:- func set__map(func(T1) = T2, set(T1)) = set(T2).
+
+:- func set__filter_map(func(T1) = T2, set(T1)) = set(T2).
+:- mode set__filter_map(func(in) = out is semidet, in) = out is det.
+
+:- func set__fold(func(T1, T2) = T2, set(T1), T2) = T2.
+
 %--------------------------------------------------------------------------%
 
 :- implementation.
@@ -269,3 +319,60 @@
 
 %--------------------------------------------------------------------------%
 %--------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cam.sri.com> 24/04/99
+%	Function forms added.
+
+set__list_to_set(Xs) = S :-
+	set__list_to_set(Xs, S).
+
+set__sorted_list_to_set(Xs) = S :-
+	set__sorted_list_to_set(Xs, S).
+
+set__to_sorted_list(S) = Xs :-
+	set__to_sorted_list(S, Xs).
+
+set__init = S :-
+	set__init(S).
+
+set__make_singleton_set(T) = S :-
+	set__singleton_set(S, T).
+
+set__insert(S1, T) = S2 :-
+	set__insert(S1, T, S2).
+
+set__insert_list(S1, Xs) = S2 :-
+	set__insert_list(S1, Xs, S2).
+
+set__delete(S1, T) = S2 :-
+	set__delete(S1, T, S2).
+
+set__delete_list(S1, Xs) = S2 :-
+	set__delete_list(S1, Xs, S2).
+
+set__union(S1, S2) = S3 :-
+	set__union(S1, S2, S3).
+
+set__power_union(SS) = S :-
+	set__power_union(SS, S).
+
+set__intersect(S1, S2) = S3 :-
+	set__intersect(S1, S2, S3).
+
+set__power_intersect(SS) = S :-
+	set__power_intersect(SS, S).
+
+set__difference(S1, S2) = S3 :-
+	set__difference(S1, S2, S3).
+
+set__count(S) = N :-
+	set__count(S, N).
+
+set__map(F, S1) = S2 :-
+	S2 = set__list_to_set(list__map(F, set__to_sorted_list(S1))).
+
+set__filter_map(PF, S1) = S2 :-
+	S2 = set__list_to_set(list__filter_map(PF, set__to_sorted_list(S1))).
+
+set__fold(F, S, A) = B :-
+	B = list__foldl(F, set__to_sorted_list(S), A).
+
Index: library/std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.143
diff -u -r1.143 std_util.m
--- std_util.m	1999/03/22 08:08:44	1.143
+++ std_util.m	1999/05/26 04:24:01
@@ -11,6 +11,9 @@
 % This file is intended for all the useful standard utilities
 % that don't belong elsewhere, like <stdlib.h> in C.
 
+% Ralph Becket <rwab1 at cam.sri.com> 24/04/99
+%	Function forms added.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -2763,3 +2766,50 @@
 % 	cc_multi.
 
 %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cam.sri.com> 24/04/99
+%	Function forms added.
+
+:- interface.
+
+:- func pair(T1, T2) = pair(T1, T2).
+
+:- func maybe_func(func(T1) = T2, T1) = maybe(T2).
+:- mode maybe_func(func(in) = out is semidet, in) = out is det.
+
+	% General purpose higher-order programming constructs.
+
+	% o(F, G, X) = F(G(X))
+	%
+	% Function composition.
+	% XXX It would be nice to have infix `o' or somesuch for this.
+:- func o(func(T2) = T3, func(T1) = T2, T1) = T3.
+
+	% converse(F, X, Y) = F(Y, X)
+:- func converse(func(T1, T2) = T3, T2, T1) = T3.
+
+	% pow(F, N, X) = F^N(X)
+	%
+	% Function exponentiation.
+:- func pow(func(T) = T, int, T) = T.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+pair(X, Y) =
+	X-Y.
+
+maybe_func(PF, X) =
+	( if Y = PF(X) then yes(Y) else no ).
+
+o(F, G, X) =
+	F(G(X)).
+
+converse(F, X, Y) =
+	F(Y, X).
+
+pow(F, N, X) =
+	( if N = 0 then X else pow(F, N - 1, F(X)) ).
+
Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.111
diff -u -r1.111 string.m
--- string.m	1999/03/25 04:59:01	1.111
+++ string.m	1999/05/26 04:24:01
@@ -1966,7 +1966,153 @@
 	strcpy(Str + 1, Rest);
 }").
 
-:- end_module string.
-
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
+% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
+%       Functional forms added.
+
+:- interface.
+
+:- func string__append(string, string) = string.
+
+:- func string__char_to_string(char) = string.
+
+:- func string__int_to_string(int) = string.
+
+:- func string__int_to_base_string(int, int) = string.
+
+:- func string__float_to_string(float) = string.
+
+:- func string__replace_all(string, string, string) = string.
+
+:- func string__to_lower(string) = string.
+
+:- func string__to_upper(string) = string.
+
+:- func string__capitalize_first(string) = string.
+
+:- func string__uncapitalize_first(string) = string.
+
+:- func string__to_char_list(string) = list(char).
+
+:- func string__from_char_list(list(char)) = string.
+
+:- func string__from_rev_char_list(list(char)) = string.
+
+:- func string__pad_left(string, char, int) = string.
+
+:- func string__pad_right(string, char, int) = string.
+
+:- func string__duplicate_char(char, int) = string.
+
+:- func string__index_det(string, int) = char.
+
+:- func string__unsafe_index(string, int) = char.
+
+:- func string__foldl(func(char, T) = T, string, T) = T.
+
+:- func string__left(string, int) = string.
+
+:- func string__right(string, int) = string.
+
+:- func string__substring(string, int, int) = string.
+
+:- func string__unsafe_substring(string, int, int) = string.
+
+:- func string__append_list(list(string)) = string.
+
+:- func string__hash(string) = int.
+
+:- func string__format(string, list(string__poly_type)) = string.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- implementation.
+
+string__append(S1, S2) = S3 :-
+	string__append(S1, S2, S3).
+
+string__char_to_string(C) = S1 :-
+	string__char_to_string(C, S1).
+
+string__int_to_string(N) = S1 :-
+	string__int_to_string(N, S1).
+
+string__int_to_base_string(N1, N2) = S2 :-
+	string__int_to_base_string(N1, N2, S2).
+
+string__float_to_string(R) = S2 :-
+	string__float_to_string(R, S2).
+
+string__replace_all(S1, S2, S3) = S4 :-
+	string__replace_all(S1, S2, S3, S4).
+
+string__to_lower(S1) = S2 :-
+	string__to_lower(S1, S2).
+
+string__to_upper(S1) = S2 :-
+	string__to_upper(S1, S2).
+
+string__capitalize_first(S1) = S2 :-
+	string__capitalize_first(S1, S2).
+
+string__uncapitalize_first(S1) = S2 :-
+	string__uncapitalize_first(S1, S2).
+
+string__to_char_list(S) = Cs :-
+	string__to_char_list(S, Cs).
+
+string__from_char_list(Cs) = S :-
+	string__from_char_list(Cs, S).
+
+string__from_rev_char_list(Cs) = S :-
+	string__from_rev_char_list(Cs, S).
+
+string__pad_left(S1, C, N) = S2 :-
+	string__pad_left(S1, C, N, S2).
+
+string__pad_right(S1, C, N) = S2 :-
+	string__pad_right(S1, C, N, S2).
+
+string__duplicate_char(C, N) = S :-
+	string__duplicate_char(C, N, S).
+
+string__index_det(S, N) = C :-
+	string__index_det(S, N, C).
+
+string__unsafe_index(S, N) = C :-
+	string__unsafe_index(S, N, C).
+
+string__foldl(F, S, A) = B :-
+	P = ( pred(X::in, Y::in, Z::out) is det :- Z = F(X, Y) ),
+	string__foldl(P, S, A, B).
+
+string__left(S1, N) = S2 :-
+	string__left(S1, N, S2).
+
+string__right(S1, N) = S2 :-
+	string__right(S1, N, S2).
+
+string__substring(S1, N1, N2) = S2 :-
+	string__substring(S1, N1, N2, S2).
+
+string__unsafe_substring(S1, N1, N2) = S2 :-
+	string__unsafe_substring(S1, N1, N2, S2).
+
+string__append_list(S1s) = S2 :-
+	string__append_list(S1s, S2).
+
+string__hash(S) = N :-
+	string__hash(S, N).
+
+string__format(S1, PT) = S2 :-
+	string__format(S1, PT, S2).
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %
+
+:- end_module string.
+
+% ---------------------------------------------------------------------------- %
+% ---------------------------------------------------------------------------- %

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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