[m-rev.] for review: add predicate versions of int.fold_up/down
Julien Fischer
juliensf at students.cs.mu.OZ.AU
Mon Mar 29 15:26:17 AEST 2004
On Sat, 27 Mar 2004, Ralph Becket wrote:
> Julien Fischer, Friday, 26 March 2004:
> >
> > Estimated hours taken: 1
> > Branches: main
> >
> > Add predicate versions of int.fold_up and int.fold_down.
> >
> > XXX We should probably consider swapping the order of
> > the arguments in the function versions so they correspond
> > to the predicate versions more closely.
> >
> > library/int.m:
> > Add the predicates int.fold_up/5 and int.fold_down/5.
>
> While you're at it, could you also add int.fold_up2/7 and
> int.fold_down2/7 (the fold2 variants are useful enough to warrant
> inclusion in the library):
>
Done.
> > Index: library/int.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/library/int.m,v
> > retrieving revision 1.98
> > diff -u -r1.98 int.m
> > --- library/int.m 2 Feb 2004 03:53:07 -0000 1.98
> > +++ library/int.m 26 Mar 2004 00:34:35 -0000
> > @@ -233,15 +233,31 @@
> > :- func int__bits_per_int = int.
> > :- pred int__bits_per_int(int::out) is det.
> >
> > + % fold_up(F, Low, High, !Acc) <=> list.foldl(F, Low `..` High, !Acc)
> > + %
> > + % NOTE: fold_up/5 is undefined if High = int.max_int.
> > + %
> > +:- pred int__fold_up(pred(int, T, T), int, int, T, T).
> > +:- mode int__fold_up(pred(in, in, out) is det, in, in, in, out) is det.
> > +:- mode int__fold_up(pred(in, di, uo) is det, in, in, di, uo) is det.
>
> The list.fold[lr] predicates have more comprehensive mode coverage:
>
> :- pred list__foldl(pred(X, Y, Y), list(X), Y, Y).
> :- mode list__foldl(pred(in, di, uo) is det, in, di, uo) is det.
> :- 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.
> :- mode list__foldl(pred(in, in, out) is cc_multi, in, in, out) is cc_multi.
>
> It's probably a good idea to do the same thing here.
>
I've added some more modes based on those for foldl.
> > @@ -674,10 +690,22 @@
> >
> > %-----------------------------------------------------------------------------%
> >
> > +int__fold_up(F, Lo, Hi, !A) :-
> > + ( if Lo =< Hi
> > + then F(Lo, !A), int__fold_up(F, Lo + 1, Hi, !A)
> > + else true
> > + ).
> > +
>
> I would have used `P' rather than `F' for the closure name.
>
Good point. I've changed it to `P'.
I've also swapped the argument order of the function versions
and augmented the test case somewhat.
Revised diff follows:
Estimated hours taken: 2
Branches: main
Add the predicates int.fold_up, int.fold_down, int.fold_up2
and int.fold_down/2.
Swap the order of the arguments of the functions int.fold_up
and int.fold_down.
library/int.m:
Add the predicates int.fold_up/5, int.fold_down/5,
int.fold_up2/7 and int.fold_down2/7.
Swap the order of the arguments if int.fold_up/4 and
int.fold_down/4.
tests/hard_coded/int_fold_up_down.m:
tests/hard_coded/int_fold_up_down.exp:
Test the new predicates.
NEWS:
Mention the new predicates.
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.330
diff -u -r1.330 NEWS
--- NEWS 19 Mar 2004 14:33:36 -0000 1.330
+++ NEWS 27 Mar 2004 12:08:29 -0000
@@ -91,8 +91,10 @@
Changes to the Mercury standard library:
-* We've added two new functions, fold_up/4 and fold_down/4, to int.m.
- These functions support iteration over contiguous integer ranges.
+* We've add some new predicates and functions to int.m.
+ int.fold_up/4, int.fold_down/4, int.fold_up/5, int.fold_down/5,
+ int.fold_up2/7 and int.fold_down2/7 support iteration over
+ contiguous integer ranges.
* We've added a new library module, `array2d', for two-dimensional arrays.
Index: library/int.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/int.m,v
retrieving revision 1.98
diff -u -r1.98 int.m
--- library/int.m 2 Feb 2004 03:53:07 -0000 1.98
+++ library/int.m 29 Mar 2004 04:10:10 -0000
@@ -233,17 +233,83 @@
:- func int__bits_per_int = int.
:- pred int__bits_per_int(int::out) is det.
- % fold_up(F, Acc, Low, High) = list.foldl(F, Low `..` High, Acc)
+ % fold_up(F, Low, High, !Acc) <=> list.foldl(F, Low `..` High, !Acc)
%
- % NOTE: fold_up/4 is undefined if High = int__max_int.
+ % NOTE: fold_up/5 is undefined if High = int.max_int.
%
-:- func int__fold_up(func(int, T) = T, T, int, int) = T.
+:- pred int__fold_up(pred(int, T, T), int, int, T, T).
+:- mode int__fold_up(pred(in, in, out) is det, in, in, in, out) is det.
+:- mode int__fold_up(pred(in, di, uo) is det, in, in, di, uo) is det.
+:- mode int__fold_up(pred(in, in, out) is semidet, in, in, in, out)
+ is semidet.
+:- mode int__fold_up(pred(in, in, out) is nondet, in, in, in, out)
+ is nondet.
+:- mode int__fold_up(pred(in, di, uo) is cc_multi, in, in, di, uo)
+ is cc_multi.
+:- mode int__fold_up(pred(in, in, out) is cc_multi, in, in, in, out)
+ is cc_multi.
- % fold_down(F, Acc, Low, High) = list.foldr(F, Low `..` High, Acc)
+ % fold_up(F, Low, High, Acc) <=> list.foldl(F, Low `..` High, Acc)
%
- % NOTE: fold_down/4 is undefined if Low = int__min_int.
+ % NOTE: fold_up/4 is undefined if High = int.max_int.
%
-:- func int__fold_down(func(int, T) = T, T, int, int) = T.
+:- func int__fold_up(func(int, T) = T, int, int, T) = T.
+
+ % fold_down(F, Low, High, !Acc) <=> list.foldr(F, Low `..` High, !Acc)
+ %
+ % NOTE: fold_down/5 is undefined if Low int.min_int.
+ %
+:- pred int__fold_down(pred(int, T, T), int, int, T, T).
+:- mode int__fold_down(pred(in, in, out) is det, in, in, in, out) is det.
+:- mode int__fold_down(pred(in, di, uo) is det, in, in, di, uo) is det.
+:- mode int__fold_down(pred(in, in, out) is semidet, in, in, in, out)
+ is semidet.
+:- mode int__fold_down(pred(in, in, out) is nondet, in, in, in, out)
+ is nondet.
+:- mode int__fold_down(pred(in, di, uo) is cc_multi, in, in, di, uo)
+ is cc_multi.
+:- mode int__fold_down(pred(in, in, out) is cc_multi, in, in, in, out)
+ is cc_multi.
+
+ % fold_down(F, Low, High, Acc) <=> list.foldr(F, Low `..` High, Acc)
+ %
+ % NOTE: fold_down/4 is undefined if Low = int.min_int.
+ %
+:- func int__fold_down(func(int, T) = T, int, int, T) = T.
+
+ % fold_up2(F, Low, High, !Acc1, Acc2) <=>
+ % list.foldl2(F, Low `..` High, !Acc1, !Acc2)
+ %
+ % NOTE: fold_up2/7 is undefined if High = int.max_int.
+ %
+:- pred int__fold_up2(pred(int, T, T, U, U), int, int, T, T, U, U).
+:- mode int__fold_up2(pred(in, in, out, in, out) is det, in, in, in, out,
+ in, out) is det.
+:- mode int__fold_up2(pred(in, in, out, in, out) is semidet, in, in,
+ in, out, in, out) is semidet.
+:- mode int__fold_up2(pred(in, in, out, in, out) is nondet, in, in,
+ in, out, in, out) is nondet.
+:- mode int__fold_up2(pred(in, in, out, di, uo) is det, in, in, in, out,
+ di, uo) is det.
+:- mode int__fold_up2(pred(in, di, uo, di, uo) is det, in, in, di, uo,
+ di, uo) is det.
+
+ % fold_down2(F, Low, High, !Acc1, !Acc2) <=>
+ % list.foldr2(F, Low `..` High, !Acc1, Acc2).
+ %
+ % NOTE: fold_down2/7 is undefined if Low = int.min_int.
+ %
+:- pred int__fold_down2(pred(int, T, T, U, U), int, int, T, T, U, U).
+:- mode int__fold_down2(pred(in, in, out, in, out) is det, in, in, in, out,
+ in, out) is det.
+:- mode int__fold_down2(pred(in, in, out, in, out) is semidet, in, in,
+ in, out, in, out) is semidet.
+:- mode int__fold_down2(pred(in, in, out, in, out) is nondet, in, in,
+ in, out, in, out) is nondet.
+:- mode int__fold_down2(pred(in, in, out, di, uo) is det, in, in, in, out,
+ di, uo) is det.
+:- mode int__fold_down2(pred(in, di, uo, di, uo) is det, in, in, di, uo,
+ di, uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -674,13 +740,37 @@
%-----------------------------------------------------------------------------%
-int__fold_up(F, A, Lo, Hi) =
- ( if Lo =< Hi then int__fold_up(F, F(Lo, A), Lo + 1, Hi) else A ).
+int__fold_up(P, Lo, Hi, !A) :-
+ ( if Lo =< Hi
+ then P(Lo, !A), int__fold_up(P, Lo + 1, Hi, !A)
+ else true
+ ).
+
+int__fold_up(F, Lo, Hi, A) =
+ ( if Lo =< Hi then int__fold_up(F, Lo + 1, Hi, F(Lo, A)) else A ).
+
+int__fold_up2(P, Lo, Hi, !A, !B) :-
+ ( if Lo =< Hi
+ then P(Lo, !A, !B), int__fold_up2(P, Lo + 1, Hi, !A, !B)
+ else true
+ ).
%-----------------------------------------------------------------------------%
-int__fold_down(F, A, Lo, Hi) =
- ( if Lo =< Hi then int__fold_down(F, F(Hi, A), Lo, Hi - 1) else A ).
+int__fold_down(P, Lo, Hi, !A) :-
+ ( if Lo =< Hi
+ then P(Hi, !A), int__fold_down(P, Lo, Hi - 1, !A)
+ else true
+ ).
+
+int__fold_down(F, Lo, Hi, A) =
+ ( if Lo =< Hi then int__fold_down(F, Lo, Hi - 1, F(Hi, A)) else A ).
+
+int__fold_down2(P, Lo, Hi, !A, !B) :-
+ ( if Lo =< Hi
+ then P(Hi, !A, !B), int__fold_down2(P, Lo, Hi - 1, !A, !B)
+ else true
+ ).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
Index: tests/hard_coded/int_fold_up_down.exp
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/int_fold_up_down.exp,v
retrieving revision 1.1
diff -u -r1.1 int_fold_up_down.exp
--- tests/hard_coded/int_fold_up_down.exp 27 Jan 2004 03:26:38 -0000 1.1
+++ tests/hard_coded/int_fold_up_down.exp 29 Mar 2004 05:16:16 -0000
@@ -1,2 +1,45 @@
(5(4(3(2(1)))))
(1(2(3(4(5)))))
+(5(4(3(2(1)))))
+(1(2(3(4(5)))))
+(5(4(3(2(1)))))(5(4(3(2(1)))))
+(1(2(3(4(5)))))(1(2(3(4(5)))))
+12345
+54321
+(5-1(4-1(3-1(2-1(1-1)))))
+(5-1(4-1(3-1(2-1(1-2)))))
+(5-1(4-1(3-1(2-2(1-1)))))
+(5-1(4-1(3-1(2-2(1-2)))))
+(5-1(4-1(3-2(2-1(1-1)))))
+(5-1(4-1(3-2(2-1(1-2)))))
+(5-1(4-1(3-2(2-2(1-1)))))
+(5-1(4-1(3-2(2-2(1-2)))))
+(5-1(4-2(3-1(2-1(1-1)))))
+(5-1(4-2(3-1(2-1(1-2)))))
+(5-1(4-2(3-1(2-2(1-1)))))
+(5-1(4-2(3-1(2-2(1-2)))))
+(5-1(4-2(3-2(2-1(1-1)))))
+(5-1(4-2(3-2(2-1(1-2)))))
+(5-1(4-2(3-2(2-2(1-1)))))
+(5-1(4-2(3-2(2-2(1-2)))))
+(5-2(4-1(3-1(2-1(1-1)))))
+(5-2(4-1(3-1(2-1(1-2)))))
+(5-2(4-1(3-1(2-2(1-1)))))
+(5-2(4-1(3-1(2-2(1-2)))))
+(5-2(4-1(3-2(2-1(1-1)))))
+(5-2(4-1(3-2(2-1(1-2)))))
+(5-2(4-1(3-2(2-2(1-1)))))
+(5-2(4-1(3-2(2-2(1-2)))))
+(5-2(4-2(3-1(2-1(1-1)))))
+(5-2(4-2(3-1(2-1(1-2)))))
+(5-2(4-2(3-1(2-2(1-1)))))
+(5-2(4-2(3-1(2-2(1-2)))))
+(5-2(4-2(3-2(2-1(1-1)))))
+(5-2(4-2(3-2(2-1(1-2)))))
+(5-2(4-2(3-2(2-2(1-1)))))
+(5-2(4-2(3-2(2-2(1-2)))))
+
+(5(4(3(2(1)))))
+int.fold_up/5 failed
+(1(2(3(4(5)))))
+int.fold_down/5 failed
Index: tests/hard_coded/int_fold_up_down.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/int_fold_up_down.m,v
retrieving revision 1.1
diff -u -r1.1 int_fold_up_down.m
--- tests/hard_coded/int_fold_up_down.m 27 Jan 2004 03:26:38 -0000 1.1
+++ tests/hard_coded/int_fold_up_down.m 29 Mar 2004 05:16:06 -0000
@@ -12,27 +12,110 @@
:- import_module io.
:- pred main(io :: di, io :: uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module int, string, list.
+:- import_module int, string, list, std_util.
%-----------------------------------------------------------------------------%
main(!IO) :-
- io.write_string(int.fold_up(f, "", 1, 5) ++ "\n", !IO),
- io.write_string(int.fold_down(f, "", 1, 5) ++ "\n", !IO).
-
+
+ io.write_string(int.fold_up(f, 1, 5, "") ++ "\n", !IO),
+ io.write_string(int.fold_down(f, 1, 5, "") ++ "\n", !IO),
+
+ int.fold_up(p, 1, 5, "", FoldUpRes),
+ io.write_string(FoldUpRes ++ "\n", !IO),
+ int.fold_down(p, 1, 5, "", FoldDownRes),
+ io.write_string(FoldDownRes ++ "\n", !IO),
+
+ int.fold_up2(p2, 1, 5, "", FoldUp2Acc1, "", FoldUp2Acc2),
+ io.write_string(FoldUp2Acc1 ++ FoldUp2Acc2 ++ "\n", !IO),
+ int.fold_down2(p2, 1, 5, "", FoldDown2Acc1, "", FoldDown2Acc2),
+ io.write_string(FoldDown2Acc1 ++ FoldDown2Acc2 ++ "\n", !IO),
+
+ int.fold_up(io.write_int, 1, 5, !IO),
+ io.nl(!IO),
+ int.fold_down(io.write_int, 1, 5, !IO),
+ io.nl(!IO),
+
+ % This should produce some solutions.
+ UpNondetPred = (pred(Res::out) is nondet :-
+ int.fold_up(p_nondet, 1, 5, "", Res)
+ ),
+ std_util.solutions(UpNondetPred, NondetSolnsUp),
+ io.write_list(NondetSolnsUp, "\n", io.write_string, !IO),
+ io.nl(!IO),
+
+ % This will produce no solutions.
+ DownNondetPred = (pred(Res::out) is nondet :-
+ int.fold_down(p_nondet, 1, 6, "", Res)
+ ),
+ std_util.solutions(DownNondetPred, NondetSolnsDown),
+ io.write_list(NondetSolnsDown, "\n", io.write_string, !IO),
+ io.nl(!IO),
+
+ % This should succeed.
+ ( if int.fold_up(p_semi, 1, 5, "", SemidetUpResS)
+ then io.write_string(SemidetUpResS ++ "\n", !IO)
+ else io.write_string("int.fold_up/5 failed\n", !IO)
+ ),
+
+ % This should fail.
+ ( if int.fold_up(p_semi, 1, 6, "", SemidetUpResF)
+ then io.write_string(SemidetUpResF ++ "\n", !IO)
+ else io.write_string("int.fold_up/5 failed\n", !IO)
+ ),
+
+ % This should succeed.
+ ( if int.fold_down(p_semi, 1, 5, "", SemidetDownResS)
+ then io.write_string(SemidetDownResS ++ "\n", !IO)
+ else io.write_string("int.fold_down/5 failed\n", !IO)
+ ),
+
+ % This should fail.
+ ( if int.fold_down(p_semi, 1, 6, "", SemidetDownResF)
+ then io.write_string(SemidetDownResF ++ "\n", !IO)
+ else io.write_string("int.fold_down/5 failed\n", !IO)
+ ).
:- func f(int, string) = string.
f(X, S) = string.format("(%d%s)", [i(X), s(S)]).
+
+:- pred p(int::in, string::in, string::out) is det.
+
+p(X, S, string.format("(%d%s)", [i(X), s(S)])).
+
+:- pred p2(int::in, string::in, string::out, string::in, string::out) is det.
+
+p2(X, S, string.format("(%d%s)", [i(X), s(S)]), T,
+ string.format("(%d%s)", [i(X), s(T)])).
+
+:- pred p_nondet(int::in, string::in, string::out) is nondet.
+
+p_nondet(1, S, string.format("(1-1%s)", [s(S)])).
+p_nondet(1, S, string.format("(1-2%s)", [s(S)])).
+p_nondet(2, S, string.format("(2-1%s)", [s(S)])).
+p_nondet(2, S, string.format("(2-2%s)", [s(S)])).
+p_nondet(3, S, string.format("(3-1%s)", [s(S)])).
+p_nondet(3, S, string.format("(3-2%s)", [s(S)])).
+p_nondet(4, S, string.format("(4-1%s)", [s(S)])).
+p_nondet(4, S, string.format("(4-2%s)", [s(S)])).
+p_nondet(5, S, string.format("(5-1%s)", [s(S)])).
+p_nondet(5, S, string.format("(5-2%s)", [s(S)])).
+
+:- pred p_semi(int::in, string::in, string::out) is semidet.
+
+p_semi(1, S, string.format("(1%s)", [s(S)])).
+p_semi(2, S, string.format("(2%s)", [s(S)])).
+p_semi(3, S, string.format("(3%s)", [s(S)])).
+p_semi(4, S, string.format("(4%s)", [s(S)])).
+p_semi(5, S, string.format("(5%s)", [s(S)])).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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