/* Это - маршрут, по которому надо следовать.
Последний параметр соответствует списку уже
посещенных комнат */
member(room,roomlist)
clauses
gallery(entry,monsters). gallery(entry,fountain)
gallery(fountain,hell). gallery(fountain,food).
gallery(exit,gold_treasure). gallery(fountain,mermaid).
gallery(robbers,gold_treasure).gallery(fountain,robbers).
gallery(food,gold_treasure). gallery(mermaid,exit).
gallery(monsters,gold_treasure).
heighborroom(X,Y) if gallery(X,Y).
heighborroom(X,Y) if gallery(Y,X).
avoid(monsters,robbers).
go(Here,There) if route(Here,There,[Here]).
route(exit,exit,VisitedRooms) if
member(gold_treasure,VisitedRooms) and
write(VisitedRooms) and nl.
route(Room,Way_out,VisitedRooms) if
heighborroom(Room,NextRoom) and
avoid(DangerousRooms) and
not(member(NextRoom,DangerousRooms)) and
not(member(NextRoom,VisitedRooms)) and
route(NextRoom,Way_out,[NextRoom|VisitedRooms]).
member(X,[X|_]).
member(X,[_|X]) if member(X,R).
Проверив, что программа действительно находит решение для
цели
go(mermaid,gold_treasure).
вы, быть может, захотите попробовать добавить несколько новых
штреков, например
gallery(mermaid,gold_treasure).
а также ввести новые источники угрозы, которых надо избегать.
Если даже здесь имеется несколько возможных решений зада-
чи, наша программа дойдет до конца только с одним решением.
Чтобы получить все решения, мы должны воспользоваться имею-
щимся в Турбо Прологе механизмом возврата и применить его
тогда, когда найдено одно решение. Это можно добиться, если
добавить в первое правило для предиката route предикат fail:
route(Room,Room,VisitedRooms) if
member(gold_treasure,VisitedRooms) and
write(VisitedRooms) and nl and
fail.
Чтобы вывести на экран список имен без охватывающих квад-
ратных скобок и разделяющих запятых, мы могли бы воспользо-
ваться предикатом выписывания списка write_a_list. Однако по-
сещаемые комнаты собираются в список VisitedRooms (посещен-
ные_комнаты) в обратном порядке, т.е. первым стоит элемент
exit (выход), а последним - entry (вход). Поэтому предикат
write_a_list должен быть изменен так, чтобы сначала выписы-
вался остаток списка, а затем - его голова.
Моделирование аппаратуры
~~~~~~~~~~~~~~~~~~~~~~~~
Всякую логическую схему можно описать с помощью предиката
Турбо Пролога, причем этот предикат определяет отношение меж-