使用您的数据库示例,这可以做到
unique(S) :-
student(S, N), \+ (student(S, M), M \= N).
因为它产生
?- unique(S).
S = ross ;
S = rose ;
false.
一般来说,Prolog 的目标是解决方案的存在。然后关于基数的预测需要语言的“不纯”部分的一些支持:nb_setarg当我们需要有效地跟踪基数时,它是我们目前最好的朋友。
使用这样的元谓词:
%% count_solutions(+Goal, ?C)
%
% adapted from call_nth/2 for http://stackoverflow.com/a/14280226/874024
%
count_solutions(Goal, C) :-
State = count(0, _), % note the extra argument which remains a variable
( Goal,
arg(1, State, C1),
C2 is C1 + 1,
nb_setarg(1, State, C2),
fail
; arg(1, State, C)
).
:- meta_predicate count_solutions(0, ?).
你可以在不考虑第二个论点的情况下解决问题
unique(S) :-
student(S, _), count_solutions(student(S, _), 1).
相同的谓词可以使用来自 library(aggregate) 的 aggregate_all(count, student(S,_), 1),但是这样的库目前在内部构建一个列表,那么您可以认为 Peter 的答案更容易实现。