Solving logic puzzle in Prolog [closed]
Asked Answered
A

2

5

I am reading "Learn Prolog Now" and one of its exercises I haven't been able to solve myself is the following:

There is a street with three neighboring houses that all have a different color. They are red, blue, and green. People of different nationalities live in the different houses and they all have a different pet. Here are some more facts about them:

  • The Englishman lives in the red house.
  • The jaguar is the pet of the Spanish family.
  • The Japanese lives to the right of the snail keeper.
  • The snail keeper lives to the left of the blue house.

Who keeps the zebra?

Define a predicate zebra/1 that tells you the nationality of the owner of the zebra.

Hint: Think of a representation for the houses and the street. Code the four constraints in Prolog. member and sublist might be useful predicates.

Any ideas how to code it under Prolog? Thanks.

Auriculate answered 17/1, 2011 at 18:0 Comment(0)
A
7
neigh(Left, Right, List) :- 
        List = [Left | [Right | _]];
        List = [_ | [Left | [Right]]].

zebraowner(Houses, ZebraOwner):-
        member([englishman, _, red], Houses),
        member([spanish, jaguar, _], Houses),
        neigh([_, snail, _], [japanese, _, _], Houses),
        neigh([_, snail, _], [_, _, blue], Houses),
        member([ZebraOwner, zebra, _], Houses),
        member([_, _, green], Houses).


zebra(X) :- zebraowner([_, _, _], X).
Admission answered 17/1, 2011 at 19:27 Comment(1)
Why don't you check that each house has its own color, etc.?Kerakerala
K
2

I'm new to Prolog, but I think the definition of neigh is not quite right.Try:

   neigh(2,3,[1,2,3]).

You get away with this not quite working because there are two solutions, one with the Japanese owned zebra in the second house, and one with the zebra in the third house and your code only finds one (which is enough to answer the question :-). This code give the right answers for neigh and hence both answers to the problem:

neigh(Left, Right, List) :- 
        List = [Left, Right ,_];
        List = [_, Left, Right]].

but then only works for three houses. A more general implementation is:

neigh(Left, Right, List) :- 
        List = [Left , Right | _].
neigh(Left, Right, [_|Tail]) :- 
        neigh(Left, Right, Tail).
Knuckle answered 11/11, 2015 at 16:31 Comment(1)
you are right, there was an error/typo in that definition in the other answer. you gave a valid definition for the case of the three houses, but that is what we have here, so it's OK. the other answer's definition works only for the three houses case, as well.Datum

© 2022 - 2024 — McMap. All rights reserved.