Say I want to find sum of all solutions to a predicate, I just can use
findall(L, find(L), Sols),
and just sum members of Sols.
But
A portable solution in ISO Prolog:
:- dynamic(find_n_solution/1).
:- dynamic(find_n_counter/1).
find_n(N, Term, Goal, Solutions) :-
( set_find_n_counter(N),
retractall(find_n_solution(_)),
once((
call(Goal),
assertz(find_n_solution(Term)),
dec_find_n_counter(M),
M =:= 0
)),
fail
; findall(Solution, retract(find_n_solution(Solution)), Solutions)
).
set_find_n_counter(N) :-
retractall(find_n_counter(_)),
assertz(find_n_counter(N)).
dec_find_n_counter(M) :-
retract(find_n_counter(N)),
M is N - 1,
assertz(find_n_counter(M)).
Using the sample predicate find/1 @ChristianF answer:
| ?- find_n(10, X, find(X), L).
L = [0,1,2,3,4,5,6,7,8,9]
yes
Note that this solution will still return a list of solutions even if there are less than the required number of solutions. Some Prolog compilers, including B-Prolog and ECLiPSe provide non-logical global variables that can be used to implement the counter but that would make the solution non-portable.