I implemented Einstein Riddle in Prolog and I\'m trying to find out who had a fish at home.
I can\'t find fault in this code and trace option is not helping with this pr
You had two errors in your clues - the first you fixed already with the light smoker. The second is that the horse owner lives next to the yellow house, not the green.
Now, my prolog choked on the \+ operator so I recoded your helper predicates. This is what I did:
first(H,[H|_]). on_the_left(X,Y,[X,Y|_]). on_the_left(X,Y,[_|Hs]) :- on_the_left(X,Y,Hs). next_to(X,Y,[X,Y|_]). next_to(X,Y,[Y,X|_]). next_to(X,Y,[_|Hs]) :- next_to(X,Y,Hs). middle(X,[_,_,X,_,_]).
Now the puzzle worked nicely with these clues:
fish(Who) :-
Houses = [
house(_Color1, _From1, _Animal1, _Drink1, _Smoke1),
house(_Color2, _From2, _Animal2, _Drink2, _Smoke2),
house(_Color3, _From3, _Animal3, _Drink3, _Smoke3),
house(_Color4, _From4, _Animal4, _Drink4, _Smoke4),
house(_Color5, _From5, _Animal5, _Drink5, _Smoke5) ],
first(house(_, norway, _, _, _), Houses), %-- hint 1
member(house(red, england, _, _, _), Houses), %-- hint 2
on_the_left(house(green, _, _, _, _), house(white, _, _, _, _), Houses), %-- hint 3 - on_the_left
member(house(_, denmark, _, tea, _), Houses), %-- hint 4
next_to(house(_, _, _, _, light), house( _, _, cat, _, _), Houses), %-- hint 5 - next_to
member(house(yellow, _, _, _, cigar), Houses), %-- hint 6
member(house(_, germany, _, _, waterpipe), Houses), %-- hint 7
middle(house(_, _, _, milk, _), Houses), %-- hint 8
next_to(house(_, _, _, _, light), house(_, _, _, water, _), Houses), %-- hint 9 - next_to
member(house(_, _, bird, _, nofilter), Houses), %-- hint 10
member(house(_, sweden, dog, _, _), Houses), %-- hint 11
next_to(house(_, norway, _, _, _), house(blue, _, _, _, _), Houses), %-- hint 12 - next_to
next_to(house(_, _, horse, _, _), house(yellow, _, _, _, _), Houses), %-- hint 13 - next_to
member(house(_, _, _, beer, menthol), Houses), %-- hint 14
member(house(green, _, _, coffee, _), Houses), %-- hint 15
member(house(_, Who, fish, _, _), Houses),
write(Houses), nl.
I got:
[house(yellow, norway, cat, water, cigar), house(blue, denmark, horse, tea, light), house(red, england, bird, milk, nofilter), house(green, germany, fish, coffee, waterpipe), house(white, sweden, dog, beer, menthol)] germany
just to show an alternative encoding scheme:
solve :- solve(Sol, From), writeln(From), maplist(writeln, Sol).
solve(Sol, From) :-
phrase( (from(1, norway)
,color(red) = from(england)
,color(GREEN, green), color(WHITE, white), {GREEN is WHITE-1}
,from(denmark) = drink(tea)
,smoke(Light, light), animal(Cat, cat), next_to(Light, Cat)
,color(Yellow, yellow), smoke(Yellow, cigar)
,from(germany) = smoke(waterpipe)
,drink(3, milk)
,drink(Water, water), next_to(Light, Water)
,animal(bird) = smoke(nofilter)
,from(sweden) = animal(dog)
,from(NORWAY, norway), color(BLUE, blue), next_to(NORWAY, BLUE)
,animal(HORSE, horse), next_to(HORSE, GREEN) % next_to(HORSE, Yellow)
,drink(beer) = smoke(menthol)
,color(green) = drink(coffee)
,animal(Fish, fish), from(Fish, From)
), [[1,_,_,_,_,_],
[2,_,_,_,_,_],
[3,_,_,_,_,_],
[4,_,_,_,_,_],
[5,_,_,_,_,_]
], Sol).
state(S), [A,B,C,D,E] --> [A,B,C,D,E], {member(S, [A,B,C,D,E])}.
color(A, B) --> state([A,B,_,_,_,_]).
from(A, B) --> state([A,_,B,_,_,_]).
animal(A, B) --> state([A,_,_,B,_,_]).
drink(A, B) --> state([A,_,_,_,B,_]).
smoke(A, B) --> state([A,_,_,_,_,B]).
X = Y --> {
X=..[Fx|Ax], Y=..[Fy|Ay],
Xs=..[Fx,S|Ax], Ys=..[Fy,S|Ay]
}, call(Xs), call(Ys).
next_to(X, Y) --> {1 is abs(X-Y)}.