[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