prolog - findall排序并返回第一个

时间:2018-06-10 08:03:02

标签: prolog

我有一些事实:

motherboard('name', price, 'price range', score).

我需要通过得分获得最好的主板,所以我想我应该使用findall,但我不了解如何按分数(desc order)订购并采取第一个!请问你能帮帮我吗?

编辑 - @ user27815解决方案:

motherboard('Gigabyte B360M Aourus Gaming 3', 86, 'low_range', 3).
motherboard('MSI B350M Mortar', 93, 'low_range', 4).
motherboard('ASUS ROG Strix B350\u002DF', 114, 'middle_range', 6).
motherboard('MSI Z370 Tomahawk', 139, 'middle_range', 7).
motherboard('Gigabyte Aorus AX370 Gaming K7', 169, 'high_range', 8).

setof(Score-Nome,motherboard(Nome, Price,Price_range, Score),Pairs), sort(1,@>,Pairs,Sorted),
        write(Pairs),
        nl,
        write(Sorted).

结果是:[3-Gigabyte B360M Aourus Gaming 3]对于两个Pairs和Sorted,它以withoud dot结束,我可以按;要有更多解决方案,为什么不将它们全部打印在一起?无论如何,对和订单的顺序是相同的

@PauloMoura解决方案 - 使用先前解决方案的相同数据: setof(Score-Nome,主板(Nome,Price,Price_range,Score),对),last(Pairs,BestMotherboard),         写(BestMotherboard)。

我明白了:

?- start.
3-Gigabyte B360M Aourus Gaming 3
true ;
4-MSI B350M Mortar
true ;
6-ASUS ROG Strix B350-F
true ;
7-MSI Z370 Tomahawk
true ;
8-Gigabyte Aorus AX370 Gaming K7
true.

2 个答案:

答案 0 :(得分:2)

使用标准setof/3谓词而不是findall/3谓词将为您提供按升序排序的列表。然后,您可以遍历该列表以获取最后一个元素,这将是具有最高分数的主板。类似的东西:

...,
setof(..., ..., Motherboards),
last(Motherboards, BestMotherboard).

last/2谓词是一个常见的库谓词。

答案 1 :(得分:1)

鉴于:

motherboard('thing1', price, 'price range', 5).
motherboard('thing2', price, 'price range', 4).
motherboard('thing3', price, 'price range', 3).
motherboard('thing4', price, 'price range', 2).
motherboard('thing5', price, 'price range', 1).

我们可以查询:

?-setof(Score-Thing,motherboard(Thing,price,'price range',Scores),Pairs), sort(1,@>,Pairs,Sorted).
Pairs = [1-thing5, 2-thing4, 3-thing3, 4-thing2, 5-thing1],
Sorted = [5-thing1, 4-thing2, 3-thing3, 2-thing4, 1-thing5].

setof/3对答案进行排序,但不是按照您想要的顺序排序,因此如果我们希望整个列表排序而不仅仅是最高分,我们需要使用sort/4

或者你可以定义一个反向谓词(将5变为-5等),并在setof/3调用中包含该谓词以避免排序两次'但是你需要重新转换已排序的列表以查看原始数字,如果有任何负分,这将不起作用。