【问题标题】:How to write a Prolog predicate that will return a list of successor facts, sorted by value如何编写一个 Prolog 谓词,它将返回一个按值排序的后继事实列表
【发布时间】:2017-05-14 16:15:48
【问题描述】:

所以我有一个名为get_order_successors(L) 的谓词,我试图让它返回一个后继事实列表,按升序排序/排序。

此列表的示例可能如下所示:

 h(a,12).
 h(b,8).
 h(c,4).
 h(d,3).
 h(f,5).
 h(e,5).
 h(g,0).

到目前为止,这是我尝试过的。 设置像 [[a,12],[b,8],[c,4],etc..] 这样的列表并像这样运行列表搜索子句:

on(Item,[Item|Rest]).  

on(Item,[DisregardHead|Tail]):-
          on(Item,Tail).

目的是逐个浏览列表,然后将该列表的值添加到新列表中,将其放在开头或前面,具体取决于它的值.. 但老实说,我觉得因为我对这门语言还很陌生,而且我什至不确定该解决方案是否可行,所以对此我有点不知所措?

我确信这个问题有一个简单的解决方案,但我目前还没有看到。任何认为他们可以提供帮助的人将不胜感激。 :)

【问题讨论】:

    标签: list sorting prolog logic


    【解决方案1】:

    假设您有一个谓词来设置像 [[a,12],[b,8],[c,4],etc.] 这样的列表,如您所描述的,您需要根据列表对列表进行排序在每个内部列表的第二个元素上。所以你需要实现一个排序算法(bubblesort,mergesort...)或者使用内置的排序谓词比如sort/2:

    问题是 sort/2 可以对列表列表进行排序,但基于每个内部列表的第一个元素,例如:

    ?- sort([[b,2],[a,3]],L).
    L = [[a, 3], [b, 2]].
    

    所以它没有给出想要的结果:L = [[b, 2], [a, 3]]

    如何解决?

    只需编写设置列表的谓词,如:

    set_up(L):- findall([X,Y], h(Y,X), L).
    

    然后:

    get_order_successors(L):- set_up(L1),sort(L1,L).
    

    示例:

    ?-get_order_successors(L).
    L = [[0, g], [3, d], [4, c], [5, e], [5, f], [8, b], [12, a]].
    

    为了反转内部列表,只需编写如下谓词:

    rev([],[]).
    rev([[Number, Letter]|T], [[Letter, Number]|T1]):-rev(T,T1).
    

    并像这样添加它:

    get_order_successors(L):- set_up(L1),sort(L1,L2),rev(L2,L).
    

    【讨论】:

    • 非常感谢。这帮助了很多。我只是想知道有没有更好的方法你认为我可以实现原始列表,即。 "h(a,12).h(b,8).h(c,4).h(d,3).h(f,5).h(e,5).h(g,0)。 "无需按照我上面的列表方式查找列表?一种更优化的方式,即。谢谢。
    • 另外,你能告诉我如何翻转最终结果"L = [[0, g], [3, d], [4, c], [5, e], [5, f], [8, b], [12, a]].",使其首先是字母,然后是数字。 IE。 "L = [[g, 0], [d, 3], [c, 4], etc.."?
    • 为什么不使用setof/3 而不是findall/3,因为setof/3 会为您排序? get_order_successors(L) :- setof(X-Y, h(Y,X), L1), maplist(rev, L1, L). where rev(X-Y, Y-X).(注意,有序对通常比二元素列表更可取)。
    • 是的,肯定有合理的想法。对于初学者,我有时也会对高级谓词犹豫不决。不过,这真是太合适了。 :)
    • @StephenDunne 不,不应该。如果你这样做了,L 将是一个单例并且在对get_order_successors(L) 的查询执行后未实例化。最后一个任期应该是rev(L2, L),正如编码员在他的回答中显示的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多