Search code examples
listprologprolog-dif

Check if any element's frequency is above a limit


I want to solve a problem that is I have a Prolog list of elements. If the any of the element frequency is greater than N then false is return. My expectation like below.

?- frequency([1,2,2,2,5],3).
true.

?- frequency([1,2,2,2,2,5],3).
false.

I have a code for get particular element frequency. Any idea for the problem.

count(_, [], 0) :-
   !.
count(X, [X|T], N) :-
   count(X, T, N2),
   N is N2 + 1.
count(X, [Y|T], N) :-
   X \= Y,
   count(X, T, N).

Solution

  • Use !

    :- use_module(library(clpfd)).
    

    If we build on auxiliary predicate list_counts/2, we can define frequency/2 like this:

    frequency(Es, M) :-
       list_counts(Es, Xss),
       maplist(arg(2), Xss, Zs),
       maplist(#>=(M), Zs).
    

    Sample queries:

    ?- frequency([1,2,2,2,5], 3).
    true.
    
    ?- frequency([1,2,2,2,2,5], 3).
    false.
    

    Thanks to we can ask quite general queries—and get logically sound answers, too!

    ?- frequency([A,B,C], 2).
           A=B ,           dif(B,C)
    ;                A=C , dif(B,C)
    ;            dif(A,C),     B=C
    ;  dif(A,B), dif(A,C), dif(B,C).