4

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.

false
  • 10,264
  • 13
  • 101
  • 209
LynchDev
  • 793
  • 1
  • 12
  • 27

1 Answers1

1

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.
Alexander Serebrenik
  • 3,567
  • 2
  • 16
  • 32