Экспертные системы. ПИ-51. Преподаватель – Утёмов В.В

advertisement
Экспертные системы. ПИ-51. Преподаватель – Утёмов В.В.
Лабораторная работа №5
Задачи на применение списков
1. (о лабиринте) Дом имеет комнаты b, c, d, e, f, g. Между некоторыми
из них есть двери (см. рисунок). В одной из комнат – клад. Опишите
схему дома с помощью Пролога и определите, можно ли пройти в
комнату с кладом?
Код решения будет следующим.
Domains
symlist = symbol*
Predicates
room(symbol)
door(symbol,symbol)
go(symbol,symbol)
way(symbol,symbol,symlist)
member(symbol,symlist)
Clauses
% перечисляем комнаты в доме
room(a). room(b). room(c). room(d). room(e). room(g).
room(f).
% указываем, между какими комнатами есть двери
door(a,b). door(b,c). door(c,d). door(d,e). door(e,b).
door(e,g).
% из комнаты X можно пройти в Y, если существует дверь
либо из первой во вторую, либо из второй в первую
go(X,Y):-door(X,Y);door(Y,X).
% путь между комнатами, очевидно, существует, если мы
сразу находимся в нужной комнате
way(X,Y,_):-Y=X.
% иначе путь между комнатами X и Y существует, если можно
пройти в какую-то комнату Z, которая ещё не пройдена, и из
1
Экспертные системы. ПИ-51. Преподаватель – Утёмов В.В.
Z существует путь в Y. В списке Rooms хранятся посещённые
комнаты.
way(X,Y,Rooms):-go(X,Z),
not(member(Z,Rooms)),
way(Z,Y,[Z|Rooms]).
% этот вспомогательный предикат определяет принадлежность
элемента списку
member(X,[X|_]).
member(X,[_|T]):- member(X,T).
Goal
% можно ли из a пройти в комнату g (список посещённых
комнат вначале содержит только комнату a)?
way(a,g,[a]).
Разберитесь с программой, запустите её. Для чего необходимо
проверять, что очередная комната на пути ещё не пройдена? Что
произойдёт,
если
не
делать
эту
проверку,
убрать
условие
not(member(Z,Rooms))?
В разделе Goal задайте ещё два таких вопроса. В какую комнату нельзя
пройти из a? Есть ли путь из a в g, не проходящий через d?
2. (о конверте) Определите, можно ли не
2
1
3
отрывая карандаша и не проводя дважды
одну линию нарисовать конверт?
Узнайте также с помощью Пролога, с каких
вершин
4
5
необходимо
начинать,
какими
заканчивать рисование, чтобы решить эту
задачу?
А после докажите, уже без Пролога, что никакие другие вершины не
подходят (для математиков).
3. (о магическом квадрате) В таблицу 3х3 расставьте числа от 1 до 9
так, чтобы сумма чисел по всем строкам, столбцам и по диагоналям
была одна и та же.
Domains
intlist = integer*
Predicates
2
Экспертные системы. ПИ-51. Преподаватель – Утёмов В.В.
solve(intlist)
select(integer, intlist, intlist)
Clauses
solve ([N1,N2,N3, N4,N5,N6, N7,N8,N9]):% решением является комбинация девяти различных
чисел от 1 до 9
select(N1,[1,2,3,4,5,6,7,8,9], Ost1),
select(N2,Ost1,Ost2), select(N3,Ost2,Ost3),
select(N4,Ost3,Ost4), select(N5,Ost4,Ost5),
select(N6,Ost5,Ost6), select(N7,Ost6,Ost7),
select(N8,Ost7,Ost8), select(N9,Ost8,_),
% удовлетворяющая следующим условиям
N1+N2+N3=15, N4+N5+N6=15, N7+N8+N9=15,
N1+N4+N7=15, N2+N5+N8=15, N3+N6+N9=15,
N1+N5+N9=15, N3+N5+N7=15.
% этот вспомогательный предикат выбирает элемент списка
и возвращает оставшиеся
select(X,[X|L],L).
select(X,[Y|L],[Y|R]):-select(X,L,R).
Goal
solve(X).
В программе мы уже посчитали, что сумма чисел по всем строкам,
столбцам и по диагоналям должна быть равна 15, то есть часть работы
выполнили за Пролог. Измените программу так, чтобы кроме
расстановок, она находила и эту сумму.
4. (о таинственных числах) В выражении SEND+MORE=MONEY
различным
буквам
соответствуют
различные
цифры.
Найдите
зашифрованные числа.
5. (о немцах) Жили четыре друга. Звали их Альберт, Карл, Дитрих и
Фридрих. Фамилии друзей различны и те же, что и их имена. Ни у кого
имя и фамилия не совпадают. Кроме того, фамилия Дитриха не
Альберт, а Альберта не Дитрих. Имя мальчика с фамилией Фридрих не
Альберт, а имя мальчика с фамилией Альберт не Фридрих. Какую
фамилию имеет каждый из друзей?
Код решения:
Domains
listsymbol= symbol*
3
Экспертные системы. ПИ-51. Преподаватель – Утёмов В.В.
Predicates
surname(symbol)
solve(listsymbol)
member(symbol,symbol, listsymbol)
Clauses
% задаём возможные фамилии
surname(albert).
surname(karl).
surname(ditrih).
surname(fridrih).
solve(D):% берём четыре различные фамилии
surname(S1),
surname(S2),S2<>S1,
surname(S3),S3<>S1,S3<>S2,
surname(S4),S4<>S1,S4<>S2,S4<>S3,
%
составляем
список-решение
D,
в
последовательно хранятся имя-фамилия
для каждого друга
D=[albert,S1, karl,S2, ditrih,S3, fridrih,S4],
% ни у кого имя и фамилия не совпадают
S1<>"albert",
S2<>"karl",
S3<>"ditrih",
S4<>"fridrih",
нём
S3<>"albert",
% фамилия Дитриха не Альберт
S1<>"ditrih",
% фамилия Альберта не Дитрих
% имя мальчика с фамилией Фридрих не Альберт
member(X,fridrih,D),X<>"albert",
% имя мальчика с фамилией Альберт не Фридрих
member(Y,albert,D),Y<>"fridrih".
% этот вспомогательный предикат проверяет принадлежность
пары элементов списку
member(A,B,[A,B|_]).
member(A,B,[_,_|T]):- member(A,B,T).
Goal
solve(D).
В результате выводится весь список имён-фамилий. Постройте новый
предикат, который позволяет узнавать фамилию по имени или
наоборот, имя по фамилии, без вывода всего списка.
Решите также самостоятельно другой вариант этой задачи.
Жили четыре друга. Звали их Альберт, Карл, Дитрих и Фридрих.
Фамилии друзей различны и те же, что и их имена. Известно, что имя
мальчика с фамилией Альберт, есть фамилия того, чьё имя совпадает с
4
Экспертные системы. ПИ-51. Преподаватель – Утёмов В.В.
фамилией Дитриха, а имя мальчика с фамилией Карл, есть фамилия
того, чьё имя совпадает с фамилией Альберта. Какую фамилию имеет
каждый из друзей?
6. (о владельце таракана) Три друга живут на одной улице, в
соседних домах. Дома имеют разные цвета, их номера – 1, 2 и 3.
Друзья – разной национальности, владеют разными домами и разными
домашними животными. Кроме того:
 Англичанин живет в красном доме.
 Ягуар – домашнее животное испанца.
 Японец живет направо от владельца улитки.
 Владелец улитки живет налево от синего дома.
 Хозяин таракана живет направо от испанца.
 Зелёный дом находится слева от дома англичанина.
Кто хозяин таракана?
5
Download