Last year, I solved the following analytical reasoning problem by hand. Post learning Prolog, I think this is a good problem to solve using a computer! I had a interesting experience doing so.
Problem:
Problem:
Facts:
1: There are 5 villas in 5 different colors
2: In each villa lives a person with a different nationality.
3: These 5 owners drink a certain beverage, smoke a certain brand of cigar and keep a certain pet.
4: No owner has the same pet, smoke the same brand of cigar or drink the same drink.
Hints:
1: The British lives in a red villa.
2: The Swede keeps dogs as pets
3: The Dane drinks tea
4: The green villa is on the left of the white villa (it also means they are next door to each other)
5: The green villa owner drinks coffee
6: The person who smokes Pall Mall rears birds
7: The owner of the yellow villa smokes Dunhill
8: The man living in the villa right in the center drinks milk
9: The Norwegian lives in the first villa
10: The man who smokes Blend lives next to the one who keeps cats
11: The man who keeps horses lives next to the man who smokes Dunhill
12: The owner who smokes Blue Master drinks beer
13: The German smokes Prince
14: The Norwegian lives next to the blue villa
15: The man who smokes Blend has a neighbor who drinks water.
The question is: who keeps the fish?
Prolog Solution:
The following is what i could come up with after serval iterations through code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/opt/local/bin/gprolog --consult-file | |
segment([H1,H2],[H1,H2]):-!. | |
segment([H1,H2],[H1,H2|_]):-!. | |
segment([H1,H2],[_,H4|T2]) :- segment([H1,H2],[H4|T2]). | |
adjacent([H1,H2],L1,L2) :- segment([H1,H2],L1),!;segment([H2,H1],L2),!. | |
valid_set([],_,_). | |
valid_set([H|T],Y,AL):- member(H,Y), \+(member(H,AL)), valid_set(T,Y,[H|AL]). | |
valid_values(L,Y):- valid_set(L,Y,[]). | |
villas :- | |
Solution =[ | |
(1,N1,C1,D1,S1,P1), | |
(2,N2,C2,D2,S2,P2), | |
(3,N3,C3,D3,S3,P3), | |
(4,N4,C4,D4,S4,P4), | |
(5,N5,C5,D5,S5,P5) | |
], | |
% 9: Norwegian lives in first villa. | |
N1=norwegian, | |
% 8: Man living in the center villa drinks milk. | |
D3=milk, | |
valid_values([C1,C2,C3,C4,C5],[green,white,yellow,blue,red]), | |
% 4: Green villa is left of white villa. | |
segment([green,white],[C1,C2,C3,C4,C5]), | |
valid_values([N2,N3,N4,N5],[dane,german,british,swede]), | |
% 1: British lives in a red villa. | |
segment([british,red],[N1,C1,N2,C2,N3,C3,N4,C4,N5,C5]), | |
% 14: Norwegian lives next to blue villa. | |
segment([norwegian,blue],[N1,C2,N2,C3,N3,C4,N4,C5]), | |
valid_values([D1,D2,D4,D5],[coffee,beer,water,tea]), | |
% 5: Green villa owner drinks coffee. | |
segment([green,coffee],[C1,D1,C2,D2,C3,D3,C4,D4,C5,D5]), | |
% 3: Dane drinks tea. | |
segment([dane,tea],[N1,D1,N2,D2,N3,D3,N4,D4,N5,D5]), | |
valid_values([S1,S2,S3,S4,S5],[pallmall,dunhill,blend,bluemaster,prince]), | |
% 13: German Smokes Prince. | |
segment([german,prince],[N1,S1,N2,S2,N3,S3,N4,S4,N5,S5]), | |
% 12: Owner who smokes Bluemaster drinks beer. | |
segment([bluemaster,beer],[S1,D1,S2,D2,S3,D3,S4,D4,S5,D5]), | |
valid_values([P1,P2,P3,P4,P5],[fish,cat,birds,horse,dog]), | |
% 2: Swede keeps dogs as pets. | |
segment([swede,dog],[N1,P1,N2,P2,N3,P3,N4,P4,N5,P5]), | |
% 6: Person who smokes pallmall rears birds. | |
segment([pallmall,birds],[S1,P1,S2,P2,S3,P3,S4,P4,S5,P5]), | |
% 7: Owner of yellow vill smokes Dunhill. | |
segment([yellow,dunhill],[C1,S1,C2,S2,C3,S3,C4,S4,C5,S5]), | |
% 15: Man who smokes Blend has a neighbor who dinks water. | |
adjacent([blend,water],[S1,D2,S2,D3,S3,D4,S4,D5],[D1,S2,D2,S3,D3,S4,D4,S5]), | |
% 10: Man who smokes Blend lives next to the man who keeps cats. | |
adjacent([blend,cat],[S1,P2,S2,P3,S3,P4,S4,P5],[P1,S2,P2,S3,P3,S4,P4,S5]), | |
% 11: Man who keeps horses lives next to man who smokes Dunhill. | |
adjacent([dunhill,horse],[S1,P2,S2,P3,S3,P4,S4,P5],[P1,S2,P2,S3,P3,S4,P4,S5]), | |
printSol(Solution). | |
printSol([]). | |
printSol([H|T]) :- write(H),nl,printSol(T). |
Answer to Puzzle:
Following is the output of the prolog program.
1,norwegian,yellow,water,dunhill,cat
2,dane,blue,tea,blend,horse
3,british,red,milk,pallmall,birds
4,german,green,coffee,prince,fish
5,swede,white,beer,bluemaster,dog
Hence the answer is German keeps the fish.
1 comment:
Wow...!! Interesting...I too am yet to try Prolog...it's next on my 'Scheme' o' things...! :)
Amazing if such inference problems could be solved using automation...thus reducing human error...and perhaps, help 'discover' deeply nested 'conclusions' about patterns, theorems, etc...
Post a Comment