Code: Select all
% description(HouseColour, Nationality, Beverage, Cigarette, Pet)
matchesHouseColour(HouseColour, description(HouseColour, _, _, _, _)).
matchesNationality(Nationality, description(_, Nationality, _, _, _)).
matchesBeverage(Beverage, description(_, _, Beverage, _, _)).
matchesCigarette(Cigarette, description(_, _, _, Cigarette, _)).
matchesPet(Pet, description(_, _, _, _, Pet)).
member(Element, [Element|_]).
member(Element, [_|Tail]) :- member(Element, Tail).
subset([], _).
subset([Head|Tail], List) :- member(Head, List), subset(Tail, List).
append([], List, List).
append([Head|Tail1], List, [Head|Tail2]) :- append(Tail1, List, Tail2).
sublist(List1, List2) :- append(List3, _, List2), append(_, List1, List3).
transform(_, [], []).
transform(Predicate, [Head1|Tail1], [Head2|Tail2]) :- call(Predicate, Head1, Head2), transform(Predicate, Tail1, Tail2).
matchAnyTwoSubsequentDescriptionsInAnyOrder(Description1, Description2, Solution) :-
sublist([Description1, Description2], Solution);
sublist([Description2, Description1], Solution).
matchesValues(Predicate, List, Solution) :- transform(Predicate, List, TransformedList), subset(TransformedList, Solution).
clue1Matches(Solution) :- member(description(red, british, _, _, _), Solution).
clue2Matches(Solution) :- member(description(_, swedish, _, _, dog), Solution).
clue3Matches(Solution) :- member(description(_, danish, tea, _, _), Solution).
clue4Matches(Solution) :- sublist([description(green, _, _, _, _), description(white, _, _, _, _)], Solution).
clue5Matches(Solution) :- member(description(green, _, coffee, _, _), Solution).
clue6Matches(Solution) :- member(description(_, _, _, pallMall, birds), Solution).
clue7Matches(Solution) :- member(description(yellow, _, _, dunhill, _), Solution).
clue8Matches([_, _, description(_, _, milk, _, _), _, _]).
clue9Matches([description(_, norwegian, _, _, _), _, _, _, _]).
clue10Matches(Solution) :- matchAnyTwoSubsequentDescriptionsInAnyOrder(description(_, _, _, blend, _), description(_, _, _, _, cats), Solution).
clue11Matches(Solution) :- matchAnyTwoSubsequentDescriptionsInAnyOrder(description(_, _, _, _, horses), description(_, _, _, dunhill, _), Solution).
clue12Matches(Solution) :- member(description(_, _, beer, camel, _), Solution).
clue13Matches(Solution) :- member(description(_, german, _, marlborough, _), Solution).
clue14Matches(Solution) :- matchAnyTwoSubsequentDescriptionsInAnyOrder(description(_, norwegian, _, _, _), description(blue, _, _, _, _), Solution).
clue15Matches(Solution) :- matchAnyTwoSubsequentDescriptionsInAnyOrder(description(_, _, _, blend, _), description(_, _, water, _, _), Solution).
fact1Matches(Solution) :- matchesValues(matchesHouseColour, [red, green, white, yellow, blue], Solution).
fact2Matches(Solution) :- matchesValues(matchesNationality, [british, swedish, danish, norwegian, german], Solution).
fact3Matches(Solution) :- matchesValues(matchesBeverage, [tea, coffee, milk, beer, water], Solution).
fact4Matches(Solution) :- matchesValues(matchesCigarette, [pallMall, dunhill, blend, camel, marlborough], Solution).
fact5Matches(Solution) :- matchesValues(matchesPet, [dog, birds, cats, horses, fish], Solution).
solution(Solution) :-
Solution = [_, _, _, _, _],
clue1Matches(Solution),
clue2Matches(Solution),
clue3Matches(Solution),
clue4Matches(Solution),
clue5Matches(Solution),
clue6Matches(Solution),
clue7Matches(Solution),
clue8Matches(Solution),
clue9Matches(Solution),
clue10Matches(Solution),
clue11Matches(Solution),
clue12Matches(Solution),
clue13Matches(Solution),
clue14Matches(Solution),
clue15Matches(Solution),
fact1Matches(Solution),
fact2Matches(Solution),
fact3Matches(Solution),
fact4Matches(Solution),
fact5Matches(Solution).
EDIT: I've added a small improvement.