【问题标题】:Strawberry Prolog setof草莓序言集
【发布时间】:2011-10-20 16:15:03
【问题描述】:

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

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

谢谢。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    您可以简单地对 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...

    【讨论】:

    • 谢谢。我试图实现它,但没有成功。我最终切换到 SWI-Prolog。我的程序正常工作,但现在遇到了不同的问题。我要打印到屏幕上的列表太长,其中一部分被截断为 |...]。是否有可以用来扩展最大列表大小或更改其打印长度的命令?
    猜你喜欢
    • 2021-09-23
    • 2014-11-20
    • 2011-12-14
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2020-04-21
    • 2010-10-16
    相关资源
    最近更新 更多