LynchDev
LynchDev

Reputation: 813

Prolog, Finding the best match

I have several prolog facts:

relation('Kitchen', [item(spoon), item(fork),  item(knife)  ]).
relation('Lounge',  [item(sofa),  item(chair), item(table)  ]).
relation('Bedroom', [item(bed),   item(desk),  item(drawers)]).

And a list that is generated at runtime, for example:

[item(spoon), item(knife)]

From this list, in this case, I would like 'Kitchen' to be returned as it is the best match.

I think I need to use the intersection/3 predicate to get a count of how many matches there are to the runtime list, so Kitchen would return 2 and the others would return 0, but I don't know a way of recursing through all the relation/2 predicates and testing each one, before only returning the best match.

Upvotes: 4

Views: 935

Answers (1)

Alexander Serebrenik
Alexander Serebrenik

Reputation: 3577

The best solution is the one that cannot be improved: \+ better_candidate(Goal,CurSolution). Of course, instead of a simple length comparison you can implement a more elaborate comparison technique.

:- use_module(library(lists)).

relation('Kitchen', [item(spoon), item(fork),  item(knife)  ]).
relation('Lounge',  [item(sofa),  item(chair), item(table)  ]).
relation('Bedroom', [item(bed),   item(desk),  item(drawers)]).

best(X,Best) :-
    relation(Best,BestList), intersection(X,BestList,I),
    length(I,L),
    \+ better_candidate(X,L).

better_candidate(X,L) :-
    relation(C,CList), intersection(X,CList,CI),
    length(CI,CIL), CIL > L.

Upvotes: 1

Related Questions