Reputation: 65
I'm trying to write an alternative definition to member/2 which will won't return repetitions of numbers (i.e. will only succeed once for each element). I've currently got this code working using the cut procedurally:
once_member(X,[H|T]) :-
member(H,T),
!,
once_member(X,T).
once_member(H,[H|_]).
once_member(X,[_|T]) :-
once_member(X,T).
However, I'm aware that you can also use negation in a declarative approach to do this but I can't work out how to do it. If anyone could point me in the right direction that'd be great.
Upvotes: 1
Views: 67
Reputation: 58304
It is very simple using dif/2
:
once_member(X, [X|_]).
once_member(X, [Y|T]) :-
dif(X, Y),
once_member(X, T).
1 ?- once_member(A, [1,2,3,3,4]).
A = 1 ;
A = 2 ;
A = 3 ;
A = 4 ;
false.
2 ?- X = a, once_member(X,[A,b]).
X = A, A = a ;
false.
3 ?- once_member(X,[A,b]), X = a.
X = A, A = a ;
false.
Upvotes: 2