You are getting multiple solutions due to Prolog's backtracking. Technically, each solution provided is correct, which is why it is being generated. If you want just one solution to be generated, you are going to have to stop backtracking at some point. This is what the Prolog cut is used for. You might find that reading up on that will help you with this problem.
Update: Right. Your member()
predicate is evaluating as true
in several different ways if the first variable is in multiple positions in the second variable.
I've used the name mymember()
for this predicate, so as not to conflict with GNU Prolog's builtin member()
predicate. My knowledge base now looks like this:
mymember(X,[X|_]).
mymember(X,[_|T]) :- mymember(X,T).
not(A) :- + call(A).
set([],[]).
set([H|T],[H|Out]) :-
not(mymember(H,T)),
set(T,Out).
set([H|T],Out) :-
mymember(H,T),
set(T,Out).
So, mymember(1, [1, 1, 1]).
evaluates as true
in three different ways:
| ?- mymember(1, [1, 1, 1]).
true ? a
true
true
no
If you want to have only one answer, you're going to have to use a cut. Changing the first definition of mymember()
to this:
mymember(X,[X|_]) :- !.
Solves your problem.
Furthermore, you can avoid not()
altogether, if you wish, by defining a notamember()
predicate yourself. The choice is yours.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…