Основы логического программирования в среде Турбо Пролог. Учебное пособие по курсу «Экспертные системы»
.pdfРазде л описания пре дложе ний
Этот раздел можно считать основным разделом программы, потому что именно в нем содержатся факты и правила. Все предикаты, которые применяются в этом разделе и не являются стандартными предикатами, должны быть описаны в разделе описания предикатов или в разделе описания предикатов базы данных. Начинается этот раздел со служебного слова CLAUSES.
Напомним, что предложения, у которых в заголовке указан один и тот же предикат, должны идти друг за другом. Такой набор предложений называется проце дурой. Программу на Прологе принято оформлять по следующим правилам:
CLAUSES
p (. . .):-p 1(. . .), p 2(. . .), . . . .
p (. . .):-p 1(. . .), p 2(. . .), . . . .
Разде л описания внутре нней це ли
С зарезервированного слова GOAL начинается раздел описания внутренней цели программы. Если этот раздел отсутствует, то после запуска программы Пролог-система выдает приглашение вводить вопросы в диалоговом режиме (внешняя цель). При выполнении внешней цели Пролог-система ищет все решения, выводя все возможные значения для переменных, участвующих в вопросе. Если же выполняется внутренняя цель, то осуществляется поиск только первого решения, а для получения всех решений нужно предпринимать дополнительные действия.
Программа, компилируемая в исполняемый файл, который можно запускать независимо от среды разработки, обязательно должна иметь внутреннюю цель. Внешнюю цель обычно применяют на этапе отладки программы.
Рассмотрим возможную структуру программы на языке Пролог.
domains
…операторы доменов…
p redicates
…операторы предикатов…
clauses
…факты и правила…
goal
… цель…
21
Приме р 1. Представлена программа, содержащая сведения о родственных отношениях (мама, дочь, бабушка).
domains
s=string
p redicates
mother(s,s)
grandmother(s,s)
clauses
mother(helen, nastya). mother(nastya, varvara).
grandmother(X ,Y):- mother(X ,Z), mother(Z,Y). /* X является бабушкой Y, если найдется такой Z, что X является мамой Z, а Z является мамой Y */
В данной программе отсутствует внутренняя цель. Это значит, что после запуска программы система выдаст приглашение вводить вопросы в диалоговом режиме (вне шняя це ль). Рассмотрим различные варианты вопросов.
Можно спросить у системы, является ли Елена мамой Насти. Этот вопрос можно ввести в виде:
mother (helen, nastya).
Найдя соответствующий факт в программе, система ответит «Yes» (то есть «Да»).
Если мы спросим: mother (helen, masha).
то получим ответ «N o» (то есть «Нет»). Выведем имя мамы Насти:
mother (X , nastya).
Система сопоставит вопрос с первым фактом, конкретизирует переменную X значением helen и выдаст ответ:
X =helen
1 Solution (1 Решение)
Сформулируем вопрос об имени дочери Елены: mother (helen, X ).
Соответствующим ответом будет: X = nastya
1 Solution (1 Решение)
Найдем имена всех известных системе мам и дочерей, задав вопрос: mother (X , Y).
22
Система последовательно будет согласовывать вопрос с имеющимися в программе предложениями. В случае успешной унификации соответствующих термов переменная X будет означена именем матери, а переменная Y – именем ее дочери.
В итоге получим ответ: X = helen Y= nastya X = nastya Y= varvara
2 solutions (2 Решения)
Если необходимо получить только имена всех матерей, можно воспользоваться анонимной переменной и записать вопрос:
mother (X , ).
Получим ответ: X = helen X = nastya
2 solutions (2 Решения)
Вопрос, содержащий информацию о людях, находящихся в отношении «мама – дочь», можно сформулировать в следующем виде:
mother ( , ).
Ответом в данном случае будет просто «Yes». Система сообщит о том, что у нее есть информация об объектах, связанных отношением «мама – дочь», так как в данном случае нам не важны конкретные имена, а интересует, есть ли в нашей базе знаний хотя бы один соответствую-
щий факт.
Вопрос о том, чьей бабушкой является helen, запишется следующим образом:
grandmother (helen, X ).
Проанализируем, каким образом система будет искать ответ на вопрос. Система начинает просматривать базу знаний сверху вниз, пытаясь найтипредложение,взаголовкекоторогостоитпредикатgrandmother.Най-
дя такое предложение (это предложение grandmother(X ,Y) :- mother(X ,Z), mother(Z,Y)), система конкретизирует переменную из заголовка предло-
жения X именем helen, переменную Y с переменной X из вопроса, после чего попытается достигнуть цели: mother(helen, Z) и mother(Z, Y). Для этого она просматривает базу знаний в поиске предложения, заголовок которого можно сопоставить с предикатом mother (helen, Z).
Это можно сделать, конкретизировав переменную Z именем nastya. Затем система ищет предложение, в заголовке которого стоит предикат mother с первым аргументом nastya и каким-то именем в качестве второго аргумента. Подходящим предложением оказывается факт mother (helen,
23
nastya). Система установила, чтообеподцели mother(helen,Z) и mother(Z,
Y) достижимы при Z=nastya, Y=varvara. Получим следующий ответ:
X =varvara
Приме р 2. Представлена программа определения максимального из двух чисел.
domains
number=real
p redicates
max(number, number, number)
clauses
max (X , Y, X ):- X >=Y. max (X , Y, Y):- X <Y.
Приведем пример формулировки вопроса к указанной программе: max(3, 5, X ).
В этом случае «3» и «5» – заданные числа, а «X » – неопределенная переменная, значение которой предстоит определить Пролог-системе. Так как 3<5, первое предложение не выполнимо, а второе будет истинно в случае, если второй аргумент равен третьему. В результате получим ответ:
X =5.
Приме р 3. Представлена программа классификации объектов.
Определим отношение «класс», распределяющее сотрудников по категориям:
класс (Сотрудник, Категория). Введем следующие категории:
Дире ктор – сотрудник, который имеет только подчиненных; Масте р – сотрудник, который находится в подчинении и сам имеет
подчиненных; Рабочий – сотрудник, который является подчиненным и не имеет
своих подчиненных. Определим правила: для директора:
X – директор, если в подчинении у него некоторый Y, а сам он ни кому не подчиняется;
для мастера:
X – мастер, если существует некоторыйY, который подчиняется X , и существует некоторый Z, которому подчиняется X;
24
для рабочего:
X – рабочий, если он подчинен некоторому Y, и нет такого Z, который бы ему подчинялся.
Объединив определения отношений дире ктор, масте р, рабочий и использовав связку «иначе», можно записать правила в следующем виде:
X – мастер, если существует некоторый Y, который подчиняется X , и существует некоторый Z, которому подчиняется X ,
иначе, X – директор, если в подчинении у него некоторый Y, иначе, X – рабочий.
Программа на Турбо Прологе запишется в виде:
domains
sotrudnik=string kategoriya=director; master; rabochiy
p redicates
p odchinenyj (sotrudnik, sotrudnik) klass (sotrudnik, kategoriya)
clauses
p odchinenyj (ivan, fedor). p odchinenyj (fedor, sergey). p odchinenyj (p etr, sergey). p odchinenyj (natali, p etr).
klass(X , master):- p odchinenyj(X , ), p odchinenyj( ,X ),!. klass(X , director):- p odchinenyj(_,X ) , !.
klass(X , rabochiy):- p odchinenyj(X , ).
К примеру, для того чтобы узнать, к какой категории относится
сотрудник p etr, вопрос формулируется следующим образом:
klass(p etr, X ).
Пролог-система выдаст ответ: X = master.
1.6. Знакомство со сре дой Турбо Пролога
Рабочий экран среды Турбо Пролога имеет вид: см. рис. 2.
В верхней части экрана находится главное меню, имеющее древовидную структуру (рис. 3) и содержащее доступные команды и подменю. Под главным меню расположено четыре системных окна:
25
Р и с. 2. Главное меню и четыре системных окна
Editor – окно редактирования. В нем отображается исходный текст программы.
Dialog – окно диалога Пролог-программы с пользователем. Message – окно сообщений. В этом окне выводятся различные сооб-
щения системы Турбо Пролог.
Trace – окно трассировки. В это окно выводятся сообщения о ходе выполнения программы в режим трассировки.
Внизу экрана находится «строка состояния», в которой описывается использование функциональных клавиш или клавиш курсора. Смысл этих клавиш меняется в зависимости от текущего состояния системы.
Назначе ние пунктов ме ню
Пункт Files – работы с файлами, содержит подпункты:
•Load – загрузить исходный текст программы на Турбо Прологе;
•Pick – загрузить исходный текст программы из списка программ;
•New file – создать новый файл (по умолчанию создается Work. p ro);
•Save – записать текст программы в файл;
•Write to – записать текст программы в файл под другим именем;
•Directory – посмотреть содержимое текущей директории с определенной маской для файлов (по умолчанию *.Pro);
26
Ɇɟɧɸ Ɍɭɪɛɨ ɉɪɨɥɨɝ
File |
Edit |
Run |
Compile |
Options |
Setup |
|
Load |
|
Edit PRJ file |
|
|
|
Pick |
|
Compiler directives |
|
|
|
New file |
|
|
|
|
|
Save |
|
Memory |
|
Colors |
|
|
|
|
||
|
|
|
|
|
|
|
Write to |
|
OBJ file |
|
Window size |
|
|
|
|
||
|
|
|
|
|
|
|
Directory |
|
EXE file (auto link) |
|
Directories |
|
|
|
|
||
|
|
|
|
|
|
|
Change dir |
|
Project (all modules) |
|
Miscellaneous |
|
|
|
|
||
|
|
|
|
|
|
|
OS shell |
|
Link only |
|
Load SYS file |
|
|
|
|
||
|
|
|
|
|
|
|
Quit |
|
|
|
Save SYS file |
|
|
|
|
|
Ри с. 3. Структура меню среды Турбо пролог
•Change dir – сменить текущую директорию;
•OS shell – временный выход в DOS;
•Quit – выход из Турбо среды.
Пункт Edit – редактирование текста программы. Пункт Run – запуск программы.
Пункт Compile – компиляция и отладка программы, содержит подпункты:
•Memory – компиляция в память.
Под компиляцией в память (memory) понимается компиляция программы для того, чтобы запустить ее в Турбо среде. При этом наличие в программе раздела «Цель» (Goal) не обязательно. При его отсутствии Турбо среда запросит ввод предиката в окне «Dialog» для его дальнейше-
27
го выполнения, при наличии – в окне «Dialog» произойдет выполнение перечисленных в разделе предикатов;
•OBJ file – компиляция с созданием объектного файла;
•EXE file (auto link) – создание EX E файла (автоматическая ком-
поновка).
Компиляцияссозданиемобъектногофайла(OBJ file)исозданиеEXE
файла (EXE file) требует обязательного наличия раздела «Цель» (Goal) в
программе, так как в данном случае программа будет выполняться вне среды Турбо пролог;
• Project (all modules) – компилирование проекта (всех модулей). Проект (Project) – совокупность программ (модулей), взаимосвязанных между собой. Компилирование проекта означает, что все модули бу-
дут откомпилированы;
• Link only – означает компоновку уже имеющегося объектного файла.
Пункт Options – настройка параметров программы:
•Edit PRJ file – редактирование PRJ-файла (проекта);
•Compiler directives – директивы компилятора.
Пункт Setup – настройка среды Турбо пролог:
•Colors – цвет;
•Window si ze – размеры окон;
•Directories – директории;
•Miscellaneous – разное;
•Load SYS file – загрузить PROLOG. SYS файл;
•Save SYS file – записать PROLOG. SYS файл.
Файл PROLOG. SYS содержит в себе настройки, задаваемые в пункте Setup . При запуске среды он загружается автоматически, но чтобы сохранить изменения, произведенные в пункте Setup , требуется выбрать подпункт Save SYS file.
Задания для самостояте льной работы
1. Имеется множество объектов и заданы отношения между ними:
родитель, мужчина, женщина. Создайте предикат, проверяющий, являются ли два человека
а) сестрами; б) братьями;
в) дедушкой и внуком (внучкой);
28
г) дядей и племянником (племянницей); д) родственниками.
2.Имеется множество объектов и заданы отношения между ними:
класс – элемент класса. Создайте предикат, проверяющий, являются ли два объекта элементами одного класса.
3.Заданы три числа a, b, .c Определите, сколько среди них положительных.
4.Заданы три числа a, b, .c Определите сумму положительных
чисел.
5.Заданы три числа a, b, .c Определите, являются ли они упорядоченными:
а) по возрастанию; б) по убыванию;
в) равны (a = b = );c
г) не упорядочены.
6.Для произвольных a, b, c определить количество действительных
корней уравнения a2 b 0 .
7. Для произвольных a, b, c найти решение уравнения a2 b 0 .
8.Заданы система координат и произвольная точка А(x, )y . Опреде-
лите, где располагается точка:
а) на пересечении осей координат; б) на оси Х;
в) на оси Y;
г) вне осей координат.
9.Заданы прямые a1 + b1 + 1 =0 и a2 + b2 + 2 =0. Определить их взаимное расположение:
а) пересекаются; б) параллельны; в) совпадают.
10.Определите предикат max(X , Y, Max) так, чтобы Мах равнялось
наибольшему из двух чисел X и Y.
11.Создайте предикат, переводящий число из десятичной системы
счисления в двоичную.
29
Глава 2. Рекурсия и обработка списков
2.1. Рекурсия как основной прием программирования в Прологе
Рекурсией называется алгоритмический метод, заключающийся в том, что процедура сама вызывается в качестве подцели в теле одного или нескольких своих утверждений. Такая процедура носит название
рекурсивной.
Предположим, что в базе знаний есть набор фактов, описывающий родственные связи людей через отношение «быть родителем». Предикат p arent имеет два аргумента. В качестве его первого аргумента указыва-
ется имя родителя, в качестве второго – имя ребенка. Мы хотим создать отношение «быть предком», используя предикат p arent.
Для того чтобы один человек был предком другого человека, нужно, чтобы он либо был его родителем, либо являлся родителем другого его предка.
На Прологе вышесказанное напишется в виде рекурсивной процедуры
ancestor (X , Y):- p arent(X , Y). /* предком является родитель*/ ancestor (X , Y):- p arent(X , Z), ancestor(Z, Y). /* предком является ро-
дитель предка*/ Следует отметить, что любая рекурсивная процедура включает в
себя базис и шаг рекурсии.
Базис рекурсии – это предложение, определяющее некую начальную ситуацию или ситуацию в момент прекращения. Как правило, в этом предложении записывается некий простейший случай, при котором ответ получается сразу, даже без использования рекурсии. Так, в приведенной выше процедуре, описывающей предикат «предок», базисом рекурсии является первое правило, в котором определено, что ближайшими предками человека являются его родители. Это предложение часто содержит условие, при выполнении которого происходит выход из рекурсии или отсечение.
Шаг рекурсии – это правило, в теле которого обязательно содержится, в качестве подцели, вызов определяемого предиката. Если мы хотим избежать зацикливания, определяемый предикат должен вызываться не
30
