我正在使用Strawberry Prolog(我的学校的计算机实验室)实现一个家谱,并希望摆脱重复的答案。 findall函数在Strawberry Prolog中起作用,它将所有答案放在一个列表中,但我相信这个编译器不存在setof。我可以切换编译器或将setof-function添加到此编译器。我认为后者会是更好的学习经历,但我不知道从哪里开始。
有没有人碰巧知道其他编译器中setof函数背后的代码以及如何将其转换为Strawberry Prolog?或者草莓Prolog中是否有类似setof的功能?
感谢。
答案 0 :(得分:0)
您可以简单地对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
)
).
正如你所看到的,它基本上总能找到......