Almost prime: Difference between revisions

→‎{{header|Prolog}}: simplify generation of primes
(→‎{{header|Prolog}}: for k in 1 to 5)
(→‎{{header|Prolog}}: simplify generation of primes)
Line 402:
take(Take, Sorted, List).
</lang>That's it. The rest is machinery. For portability, a compatibility section is included below.
<lang Prolog>nPrimes( M, Primes) :- nPrimes( [2], M, Primes).
<lang Prolog>% Define prime(N) so that it can be used both to test and to generate primes indefinitely.
prime(2).
prime(N) :-
generate(3, N),
1 is N mod 2, % odd
M is floor(sqrt(N+1)), % round-off paranoia
Max is (M-1) // 2,
forall( between(1, Max, I), N mod (2*I+1) > 0 ).
 
nPrimes(Count Accumulator, I, Primes) :-
% nPrimes(+Count, ?Primes) is true iff Primes is a list of the first Count primes
next_prime(Accumulator, Prime),
% This predicate assume isPrime(_) is available for use.
append(Accumulator, [Prime], Next),
nPrimes(Count, Primes) :-
length(Next, N),
Counter = counter(0),
( N = I -> Primes = Next; nPrimes( Next, I, Primes)).
retractall( isPrime(_) ),
prime(P),
assertz( isPrime(P) ),
arg(1, Counter, N0),
N is N0 + 1,
nb_setarg(1, Counter, N),
(N < Count -> fail
; bagof(B, isPrime(B), Primes),
retractall(isPrime(_))).
 
% next_prime(+Primes, NextPrime) succeeds if NextPrime is the next
% multiply( +A, +List, Answer)
% prime after a list, Primes, of consecutive primes starting at 2.
next_prime([2], 3).
next_prime([2|Primes], P) :-
last(Primes, PP),
N P2 is N0PP + 12,
generate(3P2, N),
1 is N mod 2, % odd
M Max is floor(sqrt(N+1)), % round-off paranoia
forall( (member(Prime, [2|Primes]),
(Prime =< Max -> true
; (!, fail))), N mod Prime > 0 ),
!,
P = N.
 
% multiply( +A, +List, Answer )
multiply( A, [], [] ).
multiply( A, [X|Xs], [AX|As] ) :-
Line 431:
multiply(A, Xs, As).
 
% multiplylist( L1, L2, List ) succeeds if List is the concatenation of X * L2
% for successive elements X of L1.
multiplylist( [], B, [] ).
Line 457:
:- endif.
 
:- if(current_prolog_flag(dialect, gprologyap)).
append([],L,L).
nb_setarg(Arg, Term, Value) :-
append([X|Xs], L, [X|Ls]) :- append(Xs,L,Ls).
setarg( Arg, Term, Value, false). % no backtracking
 
last([X], X).
last([_|Xs],X) :- last(Xs,X).
:- endif.
 
:- if(current_prolog_flag(dialect, gprolog)).
generate(Min, I) :-
current_prolog_flag(max_integer, Max),
Line 478 ⟶ 484:
?- time( (almostPrime(5, 10, L), writeln(L))).
[32,48,72,80,108,112,120,162,168,176]
% 1,630906 inferences, 0.001 CPU in 0.010001 seconds (784% CPU, 23935392388471 Lips)
</pre>
 
2,526

edits