
:- module prime.
:- public prime/0.

prime :- go(500).

go(Max) :- true | prime(Max, Ps).
%go(Max) :- true | prime(Max, Ps), outstream(Ps).

prime(Max, Ps) :- true | gen(2, Max, Ns), sift(Ns, Ps).

gen(N0, Max, Ns0) :- 
	N0 =< Max, N1 := N0 + 1 | Ns0 = [N0|Ns1], gen(N1, Max, Ns1).
gen(N0, Max, Ns0) :- N0 > Max | Ns0 = [].

sift([P|Xs1], Zs0) :- 
	true | Zs0 = [P|Zs1], filter(P, Xs1, Ys), sift(Ys, Zs1).
sift([],      Zs0) :- true | Zs0 = [].

filter(P, [X|Xs1], Ys0) :- X mod P =\= 0 | Ys0 = [X|Ys1], filter(P, Xs1, Ys1).
filter(P, [X|Xs1], Ys0) :- X mod P =:= 0 |		  filter(P, Xs1, Ys0).
filter(P, [],      Ys0) :- true | Ys0 = [].

/*
outconv([X|Xs1], Os0) :- true | Os0 = [X|Os1], outconv(Xs1, Os1).
outconv([],      Os0) :- true | Os0 = [].

outstream([X|T]) :- display_console(X) | outstream(T).
outstream([]) :- true | true.
*/
