Carol
Carol

Reputation: 65

Prolog - using negation (declarative approach) to define member/2 to only succeed once for each number

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

Answers (1)

lurker
lurker

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

Related Questions