草莓Prolog setof

时间:2011-10-20 16:15:04

标签: prolog

我正在使用Strawberry Prolog(我的学校的计算机实验室)实现一个家谱,并希望摆脱重复的答案。 findall函数在Strawberry Prolog中起作用,它将所有答案放在一个列表中,但我相信这个编译器不存在setof。我可以切换编译器或将setof-function添加到此编译器。我认为后者会是更好的学习经历,但我不知道从哪里开始。

有没有人碰巧知道其他编译器中setof函数背后的代码以及如何将其转换为Strawberry Prolog?或者草莓Prolog中是否有类似setof的功能?

感谢。

1 个答案:

答案 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
        )
    ).

正如你所看到的,它基本上总能找到......