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