I'm having some trouble removing values from a list in prolog. I have a list of colors and I want to add a list of colors to it and keep all the values that have no duplicate and remove the rest.
[green, red, blue, purple, yellow, brown, orange, black, purple]
so purple appears twice in this list and I want to remove both of them. This is the list I want to be returned.
[green, red, blue, yellow, brown, orange, black]
I currently have this to remove all the duplicates but I can't get both purples out.
mymember(X,[H|_]) :- X==H,!.
mymember(X,[_|T]) :- mymember(X,T).
not(A) :- \+ call(A).
set([],[]).
set([Head|Tail],[Head|Out]) :-
not(mymember(Head,Tail)),
set(Tail, Out).
set([Head|Tail],Out) :-
mymember(Head,Tail),
set(Tail, Out).
this is the result I get now:
[green, red, blue, yellow, brown, orange, black, purple]
The simple way...a one-liner:
singletons(Xs,Zs) :-
findall( X , ( append(P,[X|S],Xs), \+member(X,P), \+member(X,S) ) , Zs )
.
Stay pure by using tfilter/3
in combination with list_uniqmember_t/3
!
list_uniqs(Es, Us) :-
tfilter(list_uniqmember_t(Es), Es, Us).
The sample query given by the OP has the expected result:
?- list_uniqs([green,red,blue,purple,yellow,brown,orange,black,purple], Xs).
Xs = [green,red,blue,yellow,brown,orange,black]. % succeeds deterministically
Do we get logically sound answers for more general queries, too?
?- list_uniqs([A,B,A], []). A=B ; false. ?- list_uniqs([A,B,A], [_]). dif(A,B). ?- list_uniqs([A,B,A], [_,_]). false. ?- list_uniqs([A,B,A], Xs). Xs = [] , A=B ; Xs = [B], dif(A,B).
Yes! How about something a little more general?
?- list_uniqs([A,B,C],Xs). Xs = [] , A=B , B=C ; Xs = [C] , A=B , dif(B,C) ; Xs = [B] , A=C , dif(B,C) ; Xs = [A] , dif(A,C), B=C ; Xs = [A,B,C], dif(A,B), dif(A,C), dif(B,C).
It works!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With