Search code examples
listprologcountingpredicates

Finding the most similar list from predicate knowledge base in Prolog


I have a problem in which I have a list of elements and I have to cycle through all instances of a particular /2 predicate to find which one has he highest number of matching elements in its list. In terms of implementation I can't seem to figure out how I should be updating the highest match so far and then stopping when there are no more.

findAnswer(MyList, HighMatchNum,_):-
    answer(X,Y),
    myIntersection(MyList, Y, NUM), //handles a single instance check and returns how many elements match.
    NUM > HighMatchNum,
    findAnswer(MyList, NUM, answer(X,Y)).

//Knowledge base
 answer(sample1, [a,b,c,d]).
 answer(sample2, [d,c,e]).

Solution

  • there is library(aggregate):

    findAnswer(MyList, HighMatchNum, K) :-
        aggregate_all(max(N, Key),
                  (   answer(Key, List),
                      myIntersection(MyList, List, N)
                  ),
                  max(HighMatchNum, K)).
    
    myIntersection(MyList, List, N) :-
        intersection(MyList, List, L),
        length(L, N).
    
    % Knowledge base
    answer(sample1, [a,b,c,d]).
    answer(sample2, [d,c,e]).
    

    yields

    ?- findAnswer([a], C, K).
    C = 1,
    K = sample1.
    
    ?- findAnswer([d,e], C, K).
    C = 2,
    K = sample2.