您可以简单地对 findall 的输出进行排序。当然,实现 setof 是一条更有价值的路径,但绝对不简单。这里来自 SWI-Prolog:
%% setof(+Var, +Goal, -Set) is semidet.
%
% Equivalent to bagof/3, but sorts the resulting bag and removes
% duplicate answers. We sort immediately after the findall/3,
% removing duplicate Templ-Answer pairs early.
setof(Templ, Goal0, List) :-
'$free_variable_set'(Templ^Goal0, Goal, Vars),
( Vars == v
-> findall(Templ, Goal, Answers),
Answers \== [],
sort(Answers, List)
; findall(Vars-Templ, Goal, Answers),
( ground(Answers)
-> sort(Answers,Sorted),
pick(Sorted,Vars,List)
; bind_bagof_keys(Answers,_VDict),
sort(Answers, Sorted),
pick(Sorted, Vars, Listu),
sort(Listu,List) % Listu ordering may be nixed by Vars
)
).
如你所见,基本的总是findall...