Search code examples
prologlogicpredicate

Defining predicates in prolog , work with lists


Using prolog,

Define the predicate, frequentest(InList, OutList), where OutList is a list of all elements that occur most often in list InList.

Using the above predicate, define a list "OutList" of all elements that occur most often in the given list "InList".


Solution

  • Here is code for a reasonable interpretation of "most often":

    frequentest(LstElems, FrequentestElems) :-
        % Sort, keeping any duplicates
        msort(LstElems, Sorted),
        frequentest_(Sorted, _E, 0, 0, [], FrequentestElems).
    
    frequentest_([], Elem, Count, Max, LstMax, F) :-
        frequentest_upd_(Count, Elem, Max, LstMax, _Max1, F).
    frequentest_([Elem|Sorted], Elem, Count, Max, LstMax, F) :-
        !,
        Count1 is Count + 1,
        frequentest_(Sorted, Elem, Count1, Max, LstMax, F).
    frequentest_([H|Sorted], Elem, Count, Max, LstMax, F) :-
        frequentest_upd_(Count, Elem, Max, LstMax, Max1, LstMax1),
        frequentest_(Sorted, H, 1, Max1, LstMax1, F).
        
    frequentest_upd_(0, _E, _M, _L, _M1, _LM1) :- !.
    frequentest_upd_(Count, Elem, Max, LstMax, Max1, LstMax1) :-
        compare(Comp, Count, Max),
        frequentest_upd_comp_(Comp, Count, Elem, Max, LstMax, Max1, LstMax1).
    
    frequentest_upd_comp_(<, _Count, _Elem, Max, LstMax, Max, LstMax).
    frequentest_upd_comp_(=, _Count, Elem, Max, LstMax, Max, [Elem|LstMax]).
    frequentest_upd_comp_(>, Count, Elem, _Max, _LstMax, Count, [Elem]).
    

    Results in swi-prolog:

    ?- time(frequentest([a,b,c,a], F)).
    % 16 inferences, 0.000 CPU in 0.000 seconds (88% CPU, 516829 Lips)
    F = [a].
    
    ?- time(frequentest([a,b,c,a,b], F)).
    % 17 inferences, 0.000 CPU in 0.000 seconds (85% CPU, 1247615 Lips)
    F = [b, a].
    
    ?- time(frequentest([a,b,c], F)).
    % 15 inferences, 0.000 CPU in 0.000 seconds (82% CPU, 816327 Lips)
    F = [c, b, a].
    
    ?- time(frequentest([1,4,8,4,5,4,8,4,7,8], F)).
    % 28 inferences, 0.000 CPU in 0.000 seconds (91% CPU, 779575 Lips)
    F = [4].