由于 Prolog 的回溯,您会得到多个解决方案。从技术上讲,提供的每个解决方案都是正确的,这就是生成它的原因。如果您只想生成一个解决方案,则必须在某个时刻停止回溯。这就是序言cut是用来。您可能会发现阅读该内容将帮助您解决这个问题。
更新:对。你的member()
谓词评估为true
如果第一个变量在第二个变量中处于多个位置,则可以采用几种不同的方式。
我用过这个名字mymember()
对于这个谓词,以免与内置的 GNU Prolog 冲突member()
谓词。我的知识库现在看起来像这样:
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]).
评估为true
以三种不同的方式:
| ?- mymember(1, [1, 1, 1]).
true ? a
true
true
no
如果你只想得到一个答案,你就必须使用剪切。改变第一个定义mymember()
对此:
mymember(X,[X|_]) :- !.
解决你的问题。
此外,您还可以避免not()
如果你愿意的话,可以通过定义一个notamember()
自己做谓语。这是你的选择。