简体   繁体   中英

Prolog: count number of predicates relating to an atom

I have a set of facts in Prolog, such that:

likes(alice,   burger).
likes(bob,     burger).
likes(charlie, burger).

likes(bob,     sandwich).
likes(charlie, sandwich).

likes(alice,   muffin).

I want to know what's the most popular dish (burgers in the example above). I'm not interested in the 2nd, 3rd, etc most popular for this query as the list of preferences can be really long.

I'm struggling to write this query in SWI-Prolog. Can you help me?

most_popular(Popular) :-
    findall(X, likes(_, X), Xs),
    sort(0, @=<, Xs, Items),
    clumped(Items, Counts),
    sort(2, @>=, Counts, [Popular|_]).
  • findall/3 pulls them out of the Prolog database into a list.
  • clumped/2 really does run length encoding, but if they are sorted first that is the same as counting them.
  • then sort them by the count ( sort/4 first parameter is which part of the term to sort by. Item-Count is really the compound -(Item,Count) so 0 sorts with normal term sorting, 1 gets the Item name to sort by or 2 gets the Count to sort by) and unify the first element of the resulting list as the answer.
?- most_popular(Item-Count).
Count = 3,
Item = burger

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM