[m-rev.] diff: improve style of some tests
Zoltan Somogyi
zs at csse.unimelb.edu.au
Thu May 13 13:11:41 AEST 2010
I did this to make these programs presentable to 326 students.
Zoltan.
tests/benchmarks/{primes,sort,queens}.m:
Change these benchmark programs from their original forms
(which used the horrible variable names inherited from their Prolog
ancestors and which were set up for our benchmarking exercise a decade
a half ago to) to examples of good Mercury programming style.
cvs diff: Diffing .
Index: primes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/benchmarks/primes.m,v
retrieving revision 1.7
diff -u -b -r1.7 primes.m
--- primes.m 1 Dec 2003 15:56:05 -0000 1.7
+++ primes.m 13 May 2010 03:06:30 -0000
@@ -2,102 +2,80 @@
:- interface.
-:- import_module io, list.
+:- import_module io.
-:- pred main(io__state, io__state).
-:- mode main(di, uo) is det.
-
-:- pred main1(list(int)).
-:- mode main1(out) is det.
+:- pred main(io::di, io::uo) is det.
:- implementation.
-:- import_module int, prolog.
-
-main --> main3(_).
-
-main1(Out) :-
- data(Data),
- primes(Data, Out).
-
-:- pred main3(list(int), io__state, io__state).
-:- mode main3(out, di, uo) is det.
+:- import_module int.
+:- import_module list.
-main3(Out) -->
- { main1(Out) },
- print_list(Out).
+main(!IO) :-
+ primes(limit, Out),
+ print_list(Out, !IO).
-:- pred data(int).
-:- mode data(out) is det.
+:- func limit = int.
-data(98).
+limit = 98.
-:- pred primes(int, list(int)).
-:- mode primes(in, out) is det.
+:- pred primes(int::in, list(int)::out) is det.
-primes(Limit, Ps) :-
- integers(2, Limit, Is),
- sift(Is, Ps).
+primes(Limit, Primes) :-
+ integers(2, Limit, Integers),
+ sift(Integers, Primes).
-:- pred integers(int, int, list(int)).
-:- mode integers(in, in, out) is det.
+:- pred integers(int::in, int::in, list(int)::out) is det.
integers(Low, High, Result) :-
( Low =< High ->
- M is Low + 1,
- Result = [Low | Rest],
- integers(M, High, Rest)
+ NextLow = Low + 1,
+ integers(NextLow, High, Rest),
+ Result = [Low | Rest]
;
Result = []
).
-:- pred sift(list(int), list(int)).
-:- mode sift(in, out) is det.
+:- pred sift(list(int)::in, list(int)::out) is det.
sift([], []).
-sift([I | Is], [I | Ps]) :-
- remove(I, Is, New),
+sift([Integer | Integers], [Integer | Ps]) :-
+ remove_multiples(Integer, Integers, New),
sift(New, Ps).
-:- pred remove(int, list(int), list(int)).
-:- mode remove(in, in, out) is det.
+:- pred remove_multiples(int::in, list(int)::in, list(int)::out) is det.
-remove(_P, [], []).
-remove(P, [I | Is], Result) :-
- M is I mod P,
- ( M = 0 ->
- Result = Nis,
- remove(P, Is, Nis)
+remove_multiples(_Prime, [], []).
+remove_multiples(Prime, [I | Is], Result) :-
+ ( I mod Prime = 0 ->
+ remove_multiples(Prime, Is, TailResult),
+ Result = TailResult
;
- Result = [I | Nis],
- remove(P, Is, Nis)
+ remove_multiples(Prime, Is, TailResult),
+ Result = [I | TailResult]
).
-:- pred print_list(list(int), io__state, io__state).
-:- mode print_list(in, di, uo) is det.
+:- pred print_list(list(int)::in, io::di, io::uo) is det.
-print_list(Xs) -->
+print_list(Xs, !IO) :-
(
- { Xs = [] }
- ->
- io__write_string("[]\n")
+ Xs = [],
+ io.write_string("[]\n", !IO)
;
- io__write_string("["),
- print_list_2(Xs),
- io__write_string("]\n")
+ Xs = [H | T],
+ io.write_string("[", !IO),
+ print_list_elements(H, T, !IO),
+ io.write_string("]\n", !IO)
).
-:- pred print_list_2(list(int), io__state, io__state).
-:- mode print_list_2(in, di, uo) is det.
+:- pred print_list_elements(int::in, list(int)::in, io::di, io::uo) is det.
-print_list_2([]) --> [].
-print_list_2([X|Xs]) -->
- io__write_int(X),
+print_list_elements(X, Xs, !IO) :-
+ io.write_int(X, !IO),
(
- { Xs = [] }
- ->
- []
+ Xs = []
;
- io__write_string(", "),
- print_list_2(Xs)
+ Xs = [H | T],
+ io.write_string(", ", !IO),
+ print_list_elements(H, T, !IO)
).
Index: qsort.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/benchmarks/qsort.m,v
retrieving revision 1.8
diff -u -b -r1.8 qsort.m
--- qsort.m 1 Dec 2003 15:56:05 -0000 1.8
+++ qsort.m 13 May 2010 03:06:30 -0000
@@ -8,84 +8,68 @@
:- interface.
-:- import_module io, list.
+:- import_module io.
-:- pred main(io__state, io__state).
-:- mode main(di, uo) is det.
-
-:- pred main1(list(int)).
-:- mode main1(out) is det.
+:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module int.
+:- import_module list.
-main --> main3(_).
-
-main1(Out) :-
+main(!IO) :-
data(Data),
- qsort(Data, Out, []).
-
-:- pred main3(list(int), io__state, io__state).
-:- mode main3(out, di, uo) is det.
-
-main3(Out) -->
- { main1(Out) },
- print_list(Out).
+ qsort(Data, [], SortedData),
+ print_list(SortedData, !IO).
-:- pred data(list(int)).
-:- mode data(out) is det.
+:- pred data(list(int)::out) is det.
data([27,74,17,33,94,18,46,83,65,2,32,53,28,85,99,47,28,82,6,11,55,29,39,81,
90,37,10,0,66,51,7,21,85,27,31,63,75,4,95,99,11,28,61,74,18, 92,40,53,59,8]).
-:- pred qsort(list(int), list(int), list(int)).
-:- mode qsort(in, out, in) is det.
+:- pred qsort(list(int)::in, list(int)::in, list(int)::out) is det.
-qsort([X|L], R, R0) :-
- partition(L, X, L1, L2),
- qsort(L2, R1, R0),
- qsort(L1, R, [X|R1]).
-qsort([], R, R).
+qsort([], !SortedRest).
+qsort([H | T], !SortedRest) :-
+ partition(T, H, Los, His),
+ qsort(His, !SortedRest),
+ !:SortedRest = [H | !.SortedRest],
+ qsort(Los, !SortedRest).
:- pred partition(list(int), int, list(int), list(int)).
:- mode partition(in, in, out, out) is det.
partition([], _P, [], []).
-partition([H|T], P, Lo, Hi) :-
- ( H =< P ->
- partition(T, P, Lo1, Hi),
- Lo = [H|Lo1]
+partition([H | T], Pivot, Lo, Hi) :-
+ ( H =< Pivot ->
+ partition(T, Pivot, LoTail, Hi),
+ Lo = [H | LoTail]
;
- partition(T, P, Lo, Hi1),
- Hi = [H|Hi1]
+ partition(T, Pivot, Lo, HiTail),
+ Hi = [H | HiTail]
).
-:- pred print_list(list(int), io__state, io__state).
-:- mode print_list(in, di, uo) is det.
+:- pred print_list(list(int)::in, io::di, io::uo) is det.
-print_list(Xs) -->
+print_list(Xs, !IO) :-
(
- { Xs = [] }
- ->
- io__write_string("[]\n")
+ Xs = [],
+ io.write_string("[]\n", !IO)
;
- io__write_string("["),
- print_list_2(Xs),
- io__write_string("]\n")
+ Xs = [H | T],
+ io.write_string("[", !IO),
+ print_list_elements(H, T, !IO),
+ io.write_string("]\n", !IO)
).
-:- pred print_list_2(list(int), io__state, io__state).
-:- mode print_list_2(in, di, uo) is det.
+:- pred print_list_elements(int::in, list(int)::in, io::di, io::uo) is det.
-print_list_2([]) --> [].
-print_list_2([X|Xs]) -->
- io__write_int(X),
+print_list_elements(X, Xs, !IO) :-
+ io.write_int(X, !IO),
(
- { Xs = [] }
- ->
- []
+ Xs = []
;
- io__write_string(", "),
- print_list_2(Xs)
+ Xs = [H | T],
+ io.write_string(", ", !IO),
+ print_list_elements(H, T, !IO)
).
Index: queens.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/benchmarks/queens.m,v
retrieving revision 1.7
diff -u -b -r1.7 queens.m
--- queens.m 26 May 2003 09:00:40 -0000 1.7
+++ queens.m 13 May 2010 03:06:30 -0000
@@ -1,110 +1,106 @@
-% 9-queens program
+% This program solves the N-queens problem. Given an N-by-N chessboard,
+% this problem asks us to find positions for N queens on the board such
+% that they do not attack each other. This means that no two queens can be
+%
+% - in the same row
+% - in the same column
+% - on the same diagnonal.
+%
+% We print the result as a list of integers. Each integer corresponds to one
+% of the board's N columns, and it gives the number of the row occupied by
+% the queen in that column. (Given the constraints of the problem, every column
+% must be occupied by exactly one queen.)
:- module queens.
:- interface.
-:- import_module list, int, io.
+:- import_module io.
-:- pred main1(list(int)).
-:- mode main1(out) is nondet.
-
-:- pred main(io__state, io__state).
-:- mode main(di, uo) is cc_multi.
+:- pred main(io::di, io::uo) is cc_multi.
:- implementation.
-:- import_module prolog.
+:- import_module int.
+:- import_module list.
-main1(Out) :-
+main(!IO) :-
data(Data),
- queen(Data, Out).
-
-main -->
- ( { data(Data), queen(Data, Out) } ->
- print_list(Out)
+ ( queen(Data, Out) ->
+ print_list(Out, !IO)
;
- io__write_string("No solution\n")
+ io.write_string("No solution\n", !IO)
).
-:- pred data(list(int)).
-:- mode data(out) is det.
+% With this data, this program solves the 8-queens problem. To solve the
+% N-queens problem for some other N, make this predicate return the first
+% N integers.
+:- pred data(list(int)::out) is det.
data([1,2,3,4,5,6,7,8]).
-:- pred queen(list(int), list(int)).
-:- mode queen(in, out) is nondet.
+:- pred queen(list(int)::in, list(int)::out) is nondet.
-queen(Data, Out) :-
- qperm(Data, Out),
- safe(Out).
+queen(Data, Perm) :-
+ qperm(Data, Perm),
+ safe(Perm).
-:- pred qperm(list(int), list(int)).
-:- mode qperm(in, out) is nondet.
+:- pred qperm(list(int)::in, list(int)::out) is nondet.
qperm([], []).
-qperm([X|Y], K) :-
- qdelete(U, [X|Y], Z),
- K = [U|V],
- qperm(Z, V).
-
-:- pred qdelete(int, list(int), list(int)).
-:- mode qdelete(out, in, out) is nondet.
-
-qdelete(A, [A|L], L).
-qdelete(X, [A|Z], [A|R]) :-
- qdelete(X, Z, R).
+qperm([H | T], Perm) :-
+ qdelete([H | T], Element, Rest),
+ qperm(Rest, RestPerm),
+ Perm = [Element | RestPerm].
+
+:- pred qdelete(list(int)::in, int::out, list(int)::out) is nondet.
+
+qdelete([H | T], H, T).
+qdelete([H | T], E, [H | NT]) :-
+ qdelete(T, E, NT).
-:- pred safe(list(int)).
-:- mode safe(in) is semidet.
+:- pred safe(list(int)::in) is semidet.
safe([]).
-safe([N|L]) :-
- nodiag(N, 1, L),
- safe(L).
+safe([H | T]) :-
+ nodiag(H, 1, T),
+ safe(T).
-:- pred nodiag(int, int, list(int)).
-:- mode nodiag(in, in, in) is semidet.
+:- pred nodiag(int::in, int::in, list(int)::in) is semidet.
nodiag(_, _, []).
-nodiag(B, D, [N|L]) :-
- NmB is N - B,
- BmN is B - N,
- ( D = NmB ->
+nodiag(TestRow, !.Diff, [Row | Rows]) :-
+ ( !.Diff = Row - TestRow ->
fail
- ; D = BmN ->
+ ; !.Diff = TestRow - Row ->
fail
;
true
),
- D1 is D + 1,
- nodiag(B, D1, L).
+ !:Diff = !.Diff + 1,
+ nodiag(TestRow, !.Diff, Rows).
-:- pred print_list(list(int), io__state, io__state).
-:- mode print_list(in, di, uo) is det.
+:- pred print_list(list(int)::in, io::di, io::uo) is det.
-print_list(Xs) -->
+print_list(Xs, !IO) :-
(
- { Xs = [] }
- ->
- io__write_string("[]\n")
+ Xs = [],
+ io.write_string("[]\n", !IO)
;
- io__write_string("["),
- print_list_2(Xs),
- io__write_string("]\n")
+ Xs = [H | T],
+ io.write_string("[", !IO),
+ print_list_elements(H, T, !IO),
+ io.write_string("]\n", !IO)
).
-:- pred print_list_2(list(int), io__state, io__state).
-:- mode print_list_2(in, di, uo) is det.
+:- pred print_list_elements(int::in, list(int)::in, io::di, io::uo) is det.
-print_list_2([]) --> [].
-print_list_2([X|Xs]) -->
- io__write_int(X),
+print_list_elements(X, Xs, !IO) :-
+ io.write_int(X, !IO),
(
- { Xs = [] }
- ->
- []
+ Xs = []
;
- io__write_string(", "),
- print_list_2(Xs)
+ Xs = [H | T],
+ io.write_string(", ", !IO),
+ print_list_elements(H, T, !IO)
).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list