Решение логической головоломки в Прологе

Я читаю "Изучай Пролог сейчас", и одно из упражнений, которое я не смог решить сам, заключается в следующем:

Есть улица с тремя соседними домами, которые имеют разный цвет. Они красные, синие и зеленые. Люди разных национальностей живут в разных домах, и у них у всех разное домашнее животное. Вот еще несколько фактов о них:

  • Англичанин живет в красном доме.
  • Ягуар - домашнее животное испанской семьи.
  • Японец живет справа от хранителя улитки.
  • Хранитель улитки живет слева от голубого дома.

Кто держит зебру?

Определить предикат zebra/1 это говорит вам о национальности владельца зебры.

Подсказка: подумайте о представлении домов и улиц. Код четырех ограничений в Прологе. member а также sublist могут быть полезны предикаты.

Любые идеи, как кодировать его под Пролог? Благодарю.

2 ответа

Решение
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).

Я новичок в Прологе, но я думаю, что определение ржа не совсем верно. Попробуйте:

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

Вам это не сработает, потому что есть два решения: одно с японской зеброй во втором доме, а другое с зеброй в третьем, и ваш код находит только одно (этого достаточно, чтобы ответить на вопрос:-). Этот код дает правильные ответы для ржа и, следовательно, оба ответа на проблему:

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

но тогда работает только на три дома. Более общая реализация:

neigh(Left, Right, List) :- 
        List = [Left , Right | _].
neigh(Left, Right, [_|Tail]) :- 
        neigh(Left, Right, Tail).
Другие вопросы по тегам