[m-rev.] Additions to list.m

Ralph Becket rafe at cs.mu.OZ.AU
Thu Dec 13 16:55:26 AEDT 2001


Estimated hours taken: 1.5
Branches: main

Additions to list.m.

library/list.m:
	Added cc_multi modes to list__fold[lr]/4 preds.
	Added list__map_corresponding/3 and list__map_corresponding3/4.

tests/general/map_corresponding.m:
	Added test cases for list__map_corresponding/3 and
	list__map_corresponding3/4.

tests/general/map_corresponding.exp:
	Expected output for above test cases.

tests/general/Mmakefile:
	Include the new test case.

Index: list.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.100
diff -u -r1.100 list.m
--- list.m	24 Aug 2001 08:44:08 -0000	1.100
+++ list.m	13 Dec 2001 04:54:30 -0000
@@ -441,6 +441,21 @@
 	is nondet.
 :- mode list__map3(pred(in, in, in, in) is semidet, in, in, in, in) is semidet.
 
+	% list__map_corresponding(F, [A1, .. An], [B1, .. Bn]) =
+	% 	[F(A1, B1), .., F(An, Bn)].
+	%
+	% An exception is raised if the list arguments differ in length.
+	%
+:- func list__map_corresponding(func(A, B) = C, list(A), list(B)) = list(C).
+
+	% list__map_corresponding3(F, [A1, .. An], [B1, .. Bn], [C1, .. Cn]) =
+	% 	[F(A1, B1, C1), .., F(An, Bn, Cn)].
+	%
+	% An exception is raised if the list arguments differ in length.
+	%
+:- func list__map_corresponding3(func(A, B, C) = D, list(A), list(B), list(C)) =
+		list(D).
+
 	% list__foldl(Pred, List, Start, End) calls Pred with each
 	% element of List (working left-to-right) and an accumulator
 	% (with the initial value of Start), and returns the final
@@ -450,6 +465,7 @@
 :- mode list__foldl(pred(in, in, out) is det, in, in, out) is det.
 :- mode list__foldl(pred(in, in, out) is semidet, in, in, out) is semidet.
 :- mode list__foldl(pred(in, in, out) is nondet, in, in, out) is nondet.
+:- mode list__foldl(pred(in, di, uo) is cc_multi, in, di, uo) is cc_multi.
 
 :- func list__foldl(func(X, Y) = Y, list(X), Y) = Y.
 
@@ -461,6 +477,7 @@
 :- mode list__foldr(pred(in, in, out) is det, in, in, out) is det.
 :- mode list__foldr(pred(in, in, out) is semidet, in, in, out) is semidet.
 :- mode list__foldr(pred(in, in, out) is nondet, in, in, out) is nondet.
+:- mode list__foldr(pred(in, di, uo) is cc_multi, in, di, uo) is cc_multi.
 
 :- func list__foldr(func(X, Y) = Y, list(X), Y) = Y.
 
@@ -659,7 +676,7 @@
 
 :- implementation.
 
-:- import_module bintree_set, require, std_util.
+:- import_module bintree_set, require, std_util, exception.
 
 %-----------------------------------------------------------------------------%
 
@@ -1161,6 +1178,33 @@
 list__map3(P, [H0 | T0], [H1 | T1], [H2 | T2], [H3 | T3]) :-
 	call(P, H0, H1, H2, H3),
 	list__map3(P, T0, T1, T2, T3).
+
+
+
+list__map_corresponding(_, [],       []      ) = [].
+
+list__map_corresponding(_, [],       [_|_]   ) = _ :-
+	error("list__map_corresponding/3: mismatched list arguments").
+
+list__map_corresponding(_, [_|_],    []      ) = _ :-
+	error("list__map_corresponding/3: mismatched list arguments").
+
+list__map_corresponding(F, [A | As], [B | Bs]) = 
+	[F(A, B) | list__map_corresponding(F, As, Bs)].
+
+
+
+list__map_corresponding3(F, As, Bs, Cs) =
+	( if      As = [A | As0], Bs = [B | Bs0], Cs = [C | Cs0] then
+		[F(A, B, C) | list__map_corresponding3(F, As0, Bs0, Cs0)]
+	  else if As = [],        Bs = [],        Cs = []        then
+	  	[]
+	  else
+	  	throw(software_error(
+			"list__map_corresponding3: mismatched list arguments"))
+	).
+
+
 
 list__foldl(_, [], Acc, Acc).
 list__foldl(P, [H|T], Acc0, Acc) :-

Index: map_corresponding.m
===================================================================
RCS file: map_corresponding.m
diff -N map_corresponding.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ map_corresponding.m	13 Dec 2001 05:27:48 -0000
@@ -0,0 +1,149 @@
+%------------------------------------------------------------------------------%
+% map_corresponding.m
+% Ralph Becket <rafe at cs.mu.oz.au>
+% Thu Dec 13 14:36:55 EST 2001
+% vim: ft=mercury ff=unix ts=4 sw=4 et tw=0 wm=0
+%
+%------------------------------------------------------------------------------%
+
+:- module map_corresponding.
+
+:- interface.
+
+:- import_module io.
+
+
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+%------------------------------------------------------------------------------%
+%------------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list, bool, int, string, pprint, std_util, exception.
+
+%------------------------------------------------------------------------------%
+
+main -->
+    list__foldl(run_test2, solutions(test_case2)),
+    io__nl,
+    list__foldl(run_test3, solutions(test_case3)),
+    io__nl.
+
+%------------------------------------------------------------------------------%
+
+:- pred run_test2({bool, list(int), list(int), list(int)}, io, io).
+:- mode run_test2(in, di, uo) is cc_multi.
+
+run_test2({ShouldSucceed, As, Bs, Cs}, IO0, IO) :-
+    P = ( pred(Zs::out) is det :- Zs = list__map_corresponding(sum2, As, Bs)),
+    try(P, ExceptionResult),
+    Inputs = to_doc(As) `<>` space `<>` to_doc(Bs),
+    (
+        ExceptionResult = succeeded(Ws),
+        (
+            ShouldSucceed = yes,
+            Result =
+                ( if   Ws = Cs
+                  then text("succeeded correctly on inputs ") `<>` Inputs
+                  else text("*** succeeded incorrectly on inputs ") `<>` Inputs
+                )
+        ;
+            ShouldSucceed = no,
+            Result =
+                text("*** succeeded unexpectedly on inputs ") `<>` Inputs `<>`
+                text(" with result ") `<>` to_doc(Ws)
+        )
+    ;
+        ExceptionResult = exception(_),
+        (
+            ShouldSucceed = yes,
+            Result =
+                text("*** failed unexpectedly on inputs ") `<>` Inputs
+        ;
+            ShouldSucceed = no,
+            Result =
+                text("failed as expected on inputs ") `<>` Inputs
+        )
+    ),
+    io__print("\nlist__map_corresponding/3: ", IO0, IO1),
+    pprint__write(80, Result, IO1, IO).
+
+%------------------------------------------------------------------------------%
+
+:- func sum2(int, int) = int.
+
+sum2(X, Y) = X + Y.
+
+%------------------------------------------------------------------------------%
+
+:- pred run_test3({bool, list(int), list(int), list(int), list(int)}, io, io).
+:- mode run_test3(in, di, uo) is cc_multi.
+
+run_test3({ShouldSucceed, As, Bs, Cs, Ds}, IO0, IO) :-
+    P = ( pred(Zs::out) is det :- Zs = list__map_corresponding3(sum3, As, Bs, Cs)),
+    try(P, ExceptionResult),
+    Inputs = to_doc(As) `<>` space `<>` to_doc(Bs) `<>` space `<>` to_doc(Cs),
+    (
+        ExceptionResult = succeeded(Ws),
+        (
+            ShouldSucceed = yes,
+            Result =
+                ( if   Ws = Ds
+                  then text("succeeded correctly on inputs ") `<>` Inputs
+                  else text("*** succeeded incorrectly on inputs ") `<>` Inputs
+                )
+        ;
+            ShouldSucceed = no,
+            Result =
+                text("*** succeeded unexpectedly on inputs ") `<>` Inputs `<>`
+                text(" with result ") `<>` to_doc(Ws)
+        )
+    ;
+        ExceptionResult = exception(_),
+        (
+            ShouldSucceed = yes,
+            Result =
+                text("*** failed unexpectedly on inputs ") `<>` Inputs
+        ;
+            ShouldSucceed = no,
+            Result =
+                text("failed as expected on inputs ") `<>` Inputs
+        )
+    ),
+    io__print("\nlist__map_corresponding3/4: ", IO0, IO1),
+    pprint__write(80, Result, IO1, IO).
+
+%------------------------------------------------------------------------------%
+
+:- func sum3(int, int, int) = int.
+
+sum3(X, Y, Z) = X + Y + Z.
+
+%------------------------------------------------------------------------------%
+
+:- pred test_case2({bool, list(int), list(int), list(int)}).
+:- mode test_case2(out) is multi.
+
+test_case2({yes, [], [], []}).
+test_case2({yes, [1, 2, 3], [4, 5, 6], [5, 7, 9]}).
+test_case2({no,  [], [1], []}).
+test_case2({no,  [1], [], []}).
+
+%------------------------------------------------------------------------------%
+
+:- pred test_case3({bool, list(int), list(int), list(int), list(int)}).
+:- mode test_case3(out) is multi.
+
+test_case3({yes, [], [], [], []}).
+test_case3({yes, [1, 2, 3], [4, 5, 6], [7, 8, 9], [12, 15, 18]}).
+test_case3({no,  [], [1], [1], []}).
+test_case3({no,  [1], [], [1], []}).
+test_case3({no,  [], [], [1], []}).
+test_case3({no,  [1], [1], [], []}).
+test_case3({no,  [], [1], [], []}).
+test_case3({no,  [1], [], [], []}).
+
+%------------------------------------------------------------------------------%
+%------------------------------------------------------------------------------%

Index: map_corresponding.exp
===================================================================
RCS file: map_corresponding.exp
diff -N map_corresponding.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ map_corresponding.exp	13 Dec 2001 05:29:13 -0000
@@ -0,0 +1,14 @@
+
+list__map_corresponding/3: failed as expected on inputs [] [1]
+list__map_corresponding/3: failed as expected on inputs [1] []
+list__map_corresponding/3: succeeded correctly on inputs [] []
+list__map_corresponding/3: succeeded correctly on inputs [1, 2, 3] [4, 5, 6]
+
+list__map_corresponding3/4: failed as expected on inputs [] [] [1]
+list__map_corresponding3/4: failed as expected on inputs [] [1] []
+list__map_corresponding3/4: failed as expected on inputs [] [1] [1]
+list__map_corresponding3/4: failed as expected on inputs [1] [] []
+list__map_corresponding3/4: failed as expected on inputs [1] [] [1]
+list__map_corresponding3/4: failed as expected on inputs [1] [1] []
+list__map_corresponding3/4: succeeded correctly on inputs [] [] []
+list__map_corresponding3/4: succeeded correctly on inputs [1, 2, 3] [4, 5, 6] [7, 8, 9]

Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/general/Mmakefile,v
retrieving revision 1.34
diff -u -r1.34 Mmakefile
--- Mmakefile	2 Sep 2001 10:33:06 -0000	1.34
+++ Mmakefile	13 Dec 2001 05:29:29 -0000
@@ -40,6 +40,7 @@
 		io_regression \
 		liveness \
 		liveness2 \
+		map_corresponding \
 		mode_inf \
 		mode_inf_bug \
 		mode_inference_reorder \
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list