mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
Change these benchmark programs from their original forms
Estimated hours taken: 0.5
Branches: main
tests/benchmarks/{primes,qsort,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.
This commit is contained in:
@@ -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.
|
||||
:- import_module int.
|
||||
:- import_module list.
|
||||
|
||||
main --> main3(_).
|
||||
main(!IO) :-
|
||||
primes(limit, Out),
|
||||
print_list(Out, !IO).
|
||||
|
||||
main1(Out) :-
|
||||
data(Data),
|
||||
primes(Data, Out).
|
||||
:- func limit = int.
|
||||
|
||||
:- pred main3(list(int), io__state, io__state).
|
||||
:- mode main3(out, di, uo) is det.
|
||||
limit = 98.
|
||||
|
||||
main3(Out) -->
|
||||
{ main1(Out) },
|
||||
print_list(Out).
|
||||
:- pred primes(int::in, list(int)::out) is det.
|
||||
|
||||
:- pred data(int).
|
||||
:- mode data(out) is det.
|
||||
primes(Limit, Primes) :-
|
||||
integers(2, Limit, Integers),
|
||||
sift(Integers, Primes).
|
||||
|
||||
data(98).
|
||||
:- pred integers(int::in, int::in, list(int)::out) is det.
|
||||
|
||||
:- pred primes(int, list(int)).
|
||||
:- mode primes(in, out) is det.
|
||||
|
||||
primes(Limit, Ps) :-
|
||||
integers(2, Limit, Is),
|
||||
sift(Is, Ps).
|
||||
|
||||
:- pred integers(int, int, list(int)).
|
||||
:- mode integers(in, in, out) is det.
|
||||
|
||||
integers(Low, High, Result) :-
|
||||
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)
|
||||
).
|
||||
|
||||
@@ -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, []).
|
||||
qsort(Data, [], SortedData),
|
||||
print_list(SortedData, !IO).
|
||||
|
||||
:- pred main3(list(int), io__state, io__state).
|
||||
:- mode main3(out, di, uo) is det.
|
||||
|
||||
main3(Out) -->
|
||||
{ main1(Out) },
|
||||
print_list(Out).
|
||||
|
||||
:- 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)
|
||||
).
|
||||
|
||||
@@ -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).
|
||||
qperm([H | T], Perm) :-
|
||||
qdelete([H | T], Element, Rest),
|
||||
qperm(Rest, RestPerm),
|
||||
Perm = [Element | RestPerm].
|
||||
|
||||
:- pred qdelete(int, list(int), list(int)).
|
||||
:- mode qdelete(out, in, out) is nondet.
|
||||
:- pred qdelete(list(int)::in, int::out, list(int)::out) is nondet.
|
||||
|
||||
qdelete(A, [A|L], L).
|
||||
qdelete(X, [A|Z], [A|R]) :-
|
||||
qdelete(X, Z, R).
|
||||
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)
|
||||
).
|
||||
|
||||
Reference in New Issue
Block a user