Решение логической головоломки в Prolog
Я читаю "Изучите Пролог сейчас", и одно из упражнений, которое я не смог решить самостоятельно, заключается в следующем:
Есть улица с тремя соседними домами, которые имеют разный цвет. Они красные, синие и зеленые. Люди разных национальностей живут в разных домах, и у них у всех разное домашнее животное. Вот еще несколько фактов о них:
- Англичанин живет в красном доме.
- Ягуар - домашнее животное испанской семьи.
- Японец живет справа от хранителя улитки.
- Хранитель улитки живет слева от голубого дома.
Кто держит зебру?
Определите предикат zebra/1
который сообщает вам национальность владельца зебры.
Подсказка: подумайте о представлении домов и улиц. Запишите четыре ограничения в Прологе. member
и sublist
могут быть полезными предикатами.
Любые идеи, как кодировать его под Пролог? Благодарю.
Ответы
Ответ 1
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).
Ответ 2
Я новичок в Prolog, но я считаю, что определение рз не совсем правильно. Попробуйте:
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).