我有这些事实:
name(john),
name(mary),
name(jack),
当我“迭代”所有事实时,我会为每个名称发现诸如等级(数字)之类的东西。我希望该等级与名称类似2-john或john-2配对,将它们存储在列表中,然后根据数字对列表进行排序。如何在ProLog中做到这一点?
name(PersonsName), findRating(PersonsName, Rating), fail.
答案 0 :(得分:0)
@false在评论中给出了正确答案:
setof(V-K, ( name(K), rating(K, V) ), VKs)
@false的个人笑话,超过:-
。 :)
对于那些需要缺少零件的人,我将在这里进行扩展。
首先,事实必须是事实,即
name(john),
不是事实,因为它以,
结尾。事实必须以句点(.
)结尾。
需要下一个事实才能将评级与该人相关联。
rating(john,2).
rating(mary,3).
rating(jack,4).
现在setof/3
setof / 3的签名为setof(+Template, +Goal, -Set)
Goal
是将返回所需数据的查询,在这种情况下,目标是name(K), rating(K,V)
,但是由于该语句多于一个语句,因此将其包装在()
中成为{{1 }}
示例运行:
( name(K), rating(K, V) )
尽管可以提供所需的数据,但格式却不实用,并且会一一返回结果。
?- name(Name),rating(Name,Rating).
Name = john,
Rating = 2 ;
Name = mary,
Rating = 3 ;
Name = jack,
Rating = 4.
是结果中数据的格式,在这种情况下为Template
,其中V-K
的{{1}}是等级,V
是{ {1}}是关键。结果将类似于Value
。
以下是我们到目前为止通过查询和示例运行所展示的示例:
K
请注意,结果以正确的格式重新累积,但仍不在列表中。
Key
是收集到结果中的内容。
由于您要求排序的结果,因此使用2-john
代替rating(V-K) :-
name(K),
rating(K,V).
?- rating(Ratings).
Ratings = 2-john ;
Ratings = 3-mary ;
Ratings = 4-jack.
。如Set
中所述:setof/3
要使运行查询更容易,而不是每次都键入整个setof / 3,只需将其放入谓词即可。
bagof/3
完整代码。
setof/3
示例运行:
sorts the result using sort/2 to get a sorted list of alternatives without duplicates.
注意:这也可以使用library(assoc): Association lists来完成,但是对于这个问题,使用ratings(VKs) :-
setof(V-K,(name(K),rating(K,V)),VKs).
更为简洁。