% pri2
#ifndef MERCURY
#include "harness.cpp"
benchmark(Data, Out) :-
primes(Data, Out).
#else
:- module primes.
:- interface.
:- import_module list, int, io, printlist.
:- pred benchmark(list(int)).
:- mode benchmark(out) is det.
:- pred main(io__state, io__state).
:- mode main(di, uo) is det.
:- implementation.
benchmark(Out) :-
data(Data),
primes(Data, Out).
main -->
{ benchmark(Out) },
print_list(Out).
:- pred data(int).
:- mode data(out) is det.
:- pred primes(int, list(int)).
:- mode primes(in, out) is det.
:- pred integers(int, int, list(int)).
:- mode integers(in, in, out) is det.
:- pred sift(list(int), list(int)).
:- mode sift(in, out) is det.
:- pred remove(int, list(int), list(int)).
:- mode remove(in, in, out) is det.
#endif
#ifdef AQUARIUS_DECLS
:- mode((primes(L, P) :-
ground(L),
rderef(L),
integer(L)
)).
:- mode((integers(L, H, R) :-
ground(L),
rderef(L),
integer(L),
ground(H),
rderef(H),
integer(H)
)).
:- mode((sift(I, P) :-
ground(L),
rderef(L),
list(L)
)).
:- mode((remove(I, L, P) :-
ground(I),
rderef(I),
integer(I),
ground(L),
rderef(L),
list(L)
)).
#endif
data(98).
#ifdef NUPROLOG_DECLS
:- primes(L, P) when L.
#endif
#ifdef SICSTUS_DECLS
:- block primes(-, ?).
#endif
primes(Limit, Ps) :-
integers(2, Limit, Is),
sift(Is, Ps).
#ifdef NUPROLOG_DECLS
:- integers(L, H, R) when L and H.
#endif
#ifdef SICSTUS_DECLS
:- block integers(-, ?, ?), integers(?, -, ?).
#endif
#ifdef MERCURY
integers(Low, High, Result) :-
( Low =< High ->
M is Low + 1,
Result = [Low | Rest],
integers(M, High, Rest)
;
Result = []
).
#else
integers(Low, High, [Low | Rest]) :-
Low =< High,
!,
M is Low + 1,
integers(M, High, Rest).
integers(_,_,[]).
#endif
#ifdef NUPROLOG_DECLS
:- sift(I, P) when I.
#endif
#ifdef SICSTUS_DECLS
:- block sift(-, ?).
#endif
sift([], []).
sift([I | Is], [I | Ps]) :-
remove(I, Is, New),
sift(New, Ps).
#ifdef NUPROLOG_DECLS
:- remove(I, L, R) when I and L.
#endif
#ifdef SICSTUS_DECLS
:- block remove(-, ?, ?), remove(?, -, ?).
#endif
#ifdef MERCURY
remove(_P, [], []).
remove(P, [I | Is], Result) :-
M is I mod P,
( M = 0 ->
Result = Nis,
remove(P, Is, Nis)
;
Result = [I | Nis],
remove(P, Is, Nis)
).
#else
remove(_P,[],[]).
remove(P,[I | Is], [I | Nis]) :-
0 =\= I mod P,
!,
remove(P,Is,Nis).
remove(P,[I | Is], Nis) :-
0 =:= I mod P,
!,
remove(P,Is,Nis).
#endif