Here a logically pure implementation, based on
if_/3
and (=)/3
by @false.
atLeastOnceMember_of(E,[X|Xs]) :-
if_(E = X, true, atLeastOnceMember_of(E,Xs)).
atLeastTwiceMember_of(E,[X|Xs]) :-
if_(E = X, atLeastOnceMember_of(E,Xs), atLeastTwiceMember_of(E,Xs)).
First, let's look at the queries you suggested in your question:
?- atLeastTwiceMember_of(a,[a,b,a,b,a,c]).
true. % succeeds deterministically
?- atLeastTwiceMember_of(b,[a,b,a,b,a,c]).
true. % succeeds deterministically
?- atLeastTwiceMember_of(c,[a,b,a,b,a,c]).
false.
?- atLeastTwiceMember_of(x,[a,b,a,b,a,c]).
false.
The code is monotone, so we get logically sound answers for more general uses, too!
?- atLeastTwiceMember_of(X,[a,b,a,b,a,c]).
X = a ;
X = b ;
false.
At last, let us consider a generalization of above query:
?- atLeastTwiceMember_of(X,[A,B,C,D,E,F]).
X = A, A = B ;
X = A, A = C, dif(C,B) ;
X = A, A = D, dif(D,C), dif(D,B) ;
X = A, A = E, dif(E,D), dif(E,C), dif(E,B) ;
X = A, A = F, dif(F,E), dif(F,D), dif(F,C), dif(F,B) ;
X = B, B = C, dif(C,A) ;
X = B, B = D, dif(D,C), dif(D,A) ;
X = B, B = E, dif(E,D), dif(E,C), dif(E,A) ;
X = B, B = F, dif(F,E), dif(F,D), dif(F,C), dif(F,A) ;
X = C, C = D, dif(D,B), dif(D,A) ;
X = C, C = E, dif(E,D), dif(E,B), dif(E,A) ;
X = C, C = F, dif(F,E), dif(F,D), dif(F,B), dif(F,A) ;
X = D, D = E, dif(E,C), dif(E,B), dif(E,A) ;
X = D, D = F, dif(F,E), dif(F,C), dif(F,B), dif(F,A) ;
X = E, E = F, dif(F,D), dif(F,C), dif(F,B), dif(F,A) ;
false.