you can use the library ( aggregate ) to count decisions
:- use_module(library(aggregate)). % it useful to declare this for modularization :- meta_predicate at_least(0, +). at_least(Predicate, Minimum) :- aggregate_all(count, Predicate, N), N >= Minimum.
Example:
?- at_least(member(_,[1,2,3]),3). true. ?- at_least(member(_,[1,2,3]),4). false.
edit here is a more efficient way using SWI-Prolog tools for global variables
at_least(P, N) :- nb_setval(at_least, 0), P, nb_getval(at_least, C), S is C + 1, ( S >= N, ! ; nb_setval(at_least, S), fail ).
with this definition, P is called simply N times. (I present the m / 2 service predicate that displays what it returns)
m(X, L) :- member(X, L), writeln(x:X). ?- at_least(m(X,[1,2,3]),2). x:1 x:2 X = 2.
edit , given @false comment, I tried
?- call_nth(m(X,[1,2,3]),2). x:1 x:2 X = 2 ; x:3 false.
with a call to nth from here .
From a practical point of view, I think nb_setval (vs nb_setarg ) suffers from the usual tradeoffs between global and local variables. That is, for some task, one could easily find out that the limit hit in order to accept the condition. If this is not required, nb_setarg will be cleaner.
Bottom line: the best way to do this, obviously, would be to use call_nth, with a "double negation" trick that decides non-standard instance creation.