I'm trying to write a rule which decides whether an item X
occurs exactly one in a list L
.
unique(X, [X|T]):- !, \+ member(X, T).
unique(X, [_|T]):- unique(X, T).
The rule works for determining whether a value is unique within a list or nor, but when I try to get unique values within a list using unique(X, [1,2,3,1,3,2,5,4,3,8]).
it returns just false.
What I expected is this (like member(X, list).
:
X = 5 ;
X = 4 ;
X = 8 ;
I'm a complete beginner and I don't know what I am doing wrong.
Here is a simple solution using nth0/4
(or select/3
as pointed out by @false):
unique(X, L) :-
nth0(_, L, X, R),
\+ member(X, R).
nth0/4
4th argument R
is the list L
with the element X
removed. We simply check then that X
is not in R
.
unique(X, L) :-
nth0(_, L, X, R),
maplist(dif(X), R).
This fixes the problem pointed out by @false, though since you are a beginner I doubt this is of much interest to you.
This has the advantage of working in situations like this one:
?- unique(b, [X, Y, a]).
X = b,
dif(Y, b) ;
Y = b,
dif(X, b) ;
false.