[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