Can someone please tell me how to find the mode of a list in Prolog?
I have tried this:
count_elt([], _, 0) :- !.
count_elt([H|T], H, P) :-
count_elt(T, H, P1),
P is P1 + 1, !.
count_elt([_|T], E, P) :- count_elt(T, E, P).
listMode([], 0) :- !.
listMode([_], 1) :- !.
listMode([H1|[H2|T]], M) :-
count_elt([H1|[H2|T]], H1, C),
listMode([H2|T], C1),
C > C1,
M is C, !.
listMode([_|[H2|T]], M) :- listMode([H2|T], M).
which only returns the maximum occurrences in the list. But I need to return the element which has the maximum occurrence (The most frequent value in the list).
You're actually quite close with
count_elt/3
, but you need more non-determinism. In short, you need to find a way to expresscount_elt/3
with fewer cuts, because right now you get this:And what you want to get is this:
From there you're just trying to find the solutions with the maximum value, which you can do with
setof/3
or a logical expression or using theaggregate
library. So fixcount_elt/3
first and go from there.Edit: some general remarks:
[H1|[H2|T]]
as[H1,H2|T]
, which is a bit more clear.listMode/2
should probably be returning the item in the second position rather than the count. Since you need the count to do this procedure, you're probably going to need to make alistMode/3
orlistMode/5
helper to manage your state during the recursion.Edit: solution
Since @MaDu_LK has decided to show the solution, even though this is most likely homework, I thought I'd share mine, using @false's reified equality predicate:
This has somewhat more pleasing performance properties:
The other solution also produces only one mode, even if the list is multimodal:
Food for thought.
Hope you already got number of suggestions. Here this is working code for you.
You already got good advices from Daniel, about your code. I'll show a library(aggregate) alternative way to obtain the information:
test