Основы логического программирования в среде Турбо Пролог. Учебное пособие по курсу «Экспертные системы»
.pdfСначала Пролог будет находить соответствие для первой цели. Если в базе данных соответствующий факт найден, то Пролог отметит найденное место и попытается согласовать вторую цель. Если и она достигнута, то Пролог также отмечает в базе данных соответствующее ей место. Если для второй цели в базе данных не находится фактов, то Пролог попытается найти новое соответствие для предыдущей цели. Таким образом, находится решение, удовлетворяющее обеим целям. Процесс нахождения соответствия между целью и фактом или правилом называется унификацией (согласованием, отождествлением).
Важно отметить, что каждая цель имеет свой собственный маркер для указания места в базе данных, где найдены соответствующие им факты. Пролог полностью просматривает базу данных для каждой из целей. Если случится так, что найденный факт также можно сопоставить с заданнойцелью,тоПрологотметитэтоместовбазеданныхнаслучай,если впоследствии он будет вынужден снова искать для этой цели другое соответствие. И когда такая необходимость возникает, Пролог начинает поиск не с начала базы данных, а с места, отмеченного маркером, соответствующим этой цели. Такой поиск носит название поиска с возвратом.
Таким образом, конъюнкцию целей можно представить как список целей, разделенных запятыми. Обрабатывая конъюнкцию целей, Пролог, согласовывая с базой данных каждую цель, просматривает вопрос слева направо.
Правила
Правила описывают (содержат) утверждения, зависящие от условий. Правило состоит из заголовка и тела правила.
Правила используются также для выражения определений. Напри-
мер,
X является птицей если,
Хявляется живым существом и
Химеет перья.
или
Хявляется сестрой Y, если
Хявляется женщиной и
Хи Y имеют одних и тех же родителей.
Например, |
|
child (X , Y):– p arent (Y, X ). |
(1.1) |
grandfather (X , Y):– p arent (X , Z), p arent (Z, Y), man (X ). |
(1.2) |
p arent (X , Y):– mother (X , Y); father (X , Y). |
(1.3) |
11
Правило (1.1) утверждает, что «X является ребенком Y», если истинно утверждение «Y является родителем X ». Здесь символ «:–» имеет смысл логического «если». Правило (1.2) утверждает, что «X является дедушкойY», если истинно утверждение, что существует такой Z, что «X является родителем Z» и «Z является родителем Y», «Х является мужчиной». Символ «,» между предикатами в правиле (1.2) воспринимается как связка «и». Правило (1.3) содержит утверждение, что «X является роди-
телем Y», если истинно утверждение, что «X является матерью Y» или «X является отцом Y». Символ («;») в правиле (1. 3) соответствует связке
«или».
Правила используются для определения новых предикатов через уже имеющиеся. Так, для (1. 1) определили предикат «child» через предикат
«p arent», а для (1. 2) – предикат «grandfather» через предикаты «p arent» и «man».
1.3. Объе кты данных – те рмы
Базисными единицами в Пролог-программе являются константы, переменные и структуры. Объекты данных в Прологе называются тер-
мами. Терм может быть константой, переменной или составным термом
(структурой).
На рисунке 1 приведена иерархия термов. Для наименования объектов нельзя использовать русские буквы, за исключением тех, которые записаны в двойных кавычках.
|
Ɍɟɪɦ |
|
|
|
|
ɉɟɪɟɦɟɧɧɚɹ |
|
|
|
|
|
ɋɬɪɭɤɬɭɪɚ |
Ʉɨɧɫɬɚɧɬɚ |
||
(ɪɚɡɦɟɪɧɨɫɬɶ > 0) |
|
|
|
ɑɢɫɥɨ |
|
|
Ⱥɬɨɦ |
|
|
|
(ɪɚɡɦɟɪɧɨɫɬɶ 0) |
ɐɟɥɨɟ Ⱦɟɣɫɬɜɢɬɟɥɶɧɨɟ
Р и с. 1. Иерархия термов
12
Константы
Константами являются целые и действительные числа. Диапазон изменения целых чисел от -32768 до + 32767, например:
0, -1, 123. 4, 0. 23E-5.
Диапазон изменения действительных чисел от 1Е-307 до 1Е+308. Как и в других языках программирования, константы обозначают
конкретные элементарные объекты, а все другие типы данных в Прологе составлены из сочетаний констант и переменных.
Пе реме нные
Понятие переменной в Прологе отличается от принятого во многих языках программирования. Переменная не рассматривается как выделенный участок памяти. Она служит для обозначения объекта, на который нельзя сослаться по имени. Областью действия переменной в Прологе является одно предложение. В разных предложенияхможет использоваться одно имя переменной для обозначения разных объектов. Исключением из правила определения области действия является анонимная переменная, которая обозначается символом подчеркивания “_”. Анонимная переменная применяется в случае, если имя переменной несущественно. Каждая анонимная переменная – это отдельный объект.
Переменные, отличные от анонимных, называются именованными, а неконкретизированные (переменные, которым не было присвоено значение) называются свободными.
Переменная, которая получила какое-то значение и оказалась связанной с определенным объектом, называется связанной.
Имена переменных должна начинаться с заглавной буквы или символа подчеркивания и содержать только символы букв, цифр и подчеркивания.
Примеры переменных:
X , Переменная, _3, _переменная.
Структуры
Структура считается более сложной единицей. Она состоит из предиката и аргументов. Аргументы разделяются запятыми и заключаются в круглые скобки.
Например, структура
likes(john, bird).
определяет, что Джон любит птиц. Предикатом здесь служит likes, а двумя аргументами – john и bird. Аргументами предиката могут быть кон-
13
станты, переменные и другие структуры. В частности, мы можем создать более сложную структуру, например:
likes(john, bird(p igeon, swallow)).
Второй аргумент представляет собой структуру со своими вариантами. Эта структура описывает конкретную птицу. Предикатом здесь яв-
ляется bird, а аргументами – p igeon и swallow. Мы используем второй
аргумент (swallow) для указания типа первого (p igeon). Однако Пролог воспринимает предикат с двумя аргументами.
Подобные структуры используются для описания сложных объектов данных.
Рассмотрим как происходит обработка запроса программы для сложного объекта. Например, по запросу
likes (Х, bird(p igeon, )).
будут найдены имена всех, кто любит голубей (p igeon), john – одно
из возможных возвращаемых значений.
1.4. Встрое нные пре дикаты
Встроенным предикатом называется предикат, определение которого уже имеется в Пролог-системе, и нет необходимости иметь собственное его описание. Встроенные предикаты предоставляют возможности, которые нельзя реализовать средствами Пролога. Они также предоставляют удобные средства при программировании, так как отпадает необходимость определять эти предикаты.
В Турбо Прологе существуют встроенные предикаты, предназначенные для обеспечения ввода-вывода, для управления файлами, выполнения арифметических операций, операций сравнения и других полезных операций.
Арифме тиче ские опе рации
Язык Пролог прежде всего ориентирован на обработку символьной информации и не предназначен для программирования задач с большим количеством арифметических операций. Однако в любую Пролог-систему включаются все обычные арифметические операторы. Порядок выполнения и приоритет могут регулироваться с помощью круглых скобок.
14
|
Арифметические операции |
|||
* |
|
умножение |
||
/ |
|
деление |
||
+ |
|
сложение |
||
– |
|
вычитание |
||
div |
|
частное от деления на целое число |
||
mod |
|
остаток от деления на целое число |
||
|
|
|
|
|
|
|
Операции отношения |
||
< |
|
меньше |
||
<= |
|
меньше или равно |
||
= |
|
равно |
||
>= |
|
больше или равно |
||
<> либо >< |
|
не равно |
||
|
|
|
|
|
|
|
Функции |
||
abs(X ) |
|
возвращает значение модуля x |
||
sin(X ) |
|
возвращает значение синуса x |
||
cos(X ) |
|
возвращает значение косинуса x |
||
tan(X ) |
|
возвращает значение тангенса x |
||
arctan(X ) |
|
возвращает значение арктангенса x |
||
exp (X ) |
|
возвращает значение еxpx |
||
In(X ) |
|
возвращает значение Inx |
||
log(X ) |
|
возвращает значение logx |
||
sqrt(X ) |
|
возвращает значение |
|
|
|
|
|||
round(X ) |
|
округляет значение x вещественного типа до бли- |
||
|
жайшего целого |
|||
|
|
|||
trunk(X ) |
|
отсекает дробную часть значения x вещественно- |
||
|
го типа |
|||
|
|
|||
Шестнадцатеричные числа в языке Пролог начинаются со знака $, например $ В8С5.
15
Спе циальные пре дикаты
Отсечение
Отсечение– встроенный предикат (обозначается «!»), повышающий эффективность выполнения программы за счет сокращения поиска. Он ограничивает число альтернатив, исследуемых Прологом как варианты при поиске решения. Предикат «отсечение» используется для исключения бесконечной петли при выполнении программ, программирования взаимоисключающих утверждений.
При использовании в какой-либо процедуре отсечения:
1.блокируется возврат к предшествующим ему подцелям в данном
утверждении (см. пример 1).
2.предотвращается использование всех утверждений, следующих
за данным утверждением в данной процедуре и которые могли бы быть использованы для согласования цели, соответствующей данной процедуре (см. пример 2).
Поясним вышесказанное на примерах.
Приме р 1.
Пусть в программе задана база данных: man(ivan).
man(p etr). woman(svetlana). woman(varvara).
Предикат allmen определенный как
allmen(X ):- man(X ).,
вызванный в качестве цели, выведет список всех мужчин. Предикат
firstman(X ):- man(X ), !.
выведет первого мужчину, найденного в базе данных, т. е. происходит блокирование возврата.
Предикат
p airs(X ,Y):- man(X ), woman(Y).
выведет список возможных пар мужчина – женщина. Предикат
firstp air(X ,Y):- man(X ), woman(Y), !.
выведет первую найденную пару.
16
Предикат
p airs1(X ,Y):- man(X ), !, woman(Y).
выведет пары, которые можно составить из первого найденного в базе мужчины и каждой из женщин.
Приме р 2.
Процедура определения максимума из двух чисел состоит из двух предложений. В случае если X больше или равенY, «срабатывает» первое предложение, при этом второе предложение блокируется «отсечением». В противном случае первое предложение «не срабатывает» и ответ будет формироваться вторым предложением.
max (X , Y, X ):- X >=Y, !. max (X , Y, Y).
Выполнение и невыполнение целевого утверждения
При выполнении программы на Прологе в зависимости от содержимого базы данных унификация может быть либо успешной, либо нет. В языке имеются два предиката, позволяющих определить успешность унификации целевого утверждения. Это предикаты true и fail.
true – предикат, который всегда успешно унифицируется. В действительности, он не является необходимым, так как утверждения в базе данных и цели могут быть переупорядочены или перегруппированы так, чтобы избежать его использования. Однако для удобства предикат true входит в состав встроенных предикатов.
fail – предикат, унификация которого всегда неудачна. Имеются две ситуации, когда этот предикат оказывается полезным. Одна из них – это использование fail в сочетании с отсечением.
Конъюнкция целевых утверждений
. . . !, fail.
применяется для того, чтобы указать, что если процесс выполнения дошел до этого момента, то можно больше не пытаться унифицировать данное целевое утверждение. Конъюнкция считается неунифицированной благодаря наличию предиката fail, а отсечение, прекращая поиск, приводит к неунификации всего утверждения.
Другая ситуация, в которой используется предикат fail, возникает, когда вы хотите явно указать, что для некоторого целевого утверждения нужно перебрать все решения. В некоторых случаях обработка Пролог системой целевого утверждения:
17
p airs(X ,Y), write(X ), write(“+”), write(Y).
приведет к печати первой найденной пары. В этом случае для печати всех вариантов необходимо использование целевого утверждения
p airs(X ,Y), write(X ), write(“+”), write(Y), fail.
Выбор пар осуществляется предикатом p airs, а вывод их на экран конструкцией write(X ), write(“+”), write(Y).
1.5. Структура программы Турбо Пролога
Программа на Турбо Прологе состоит из следующих разделов:
•CONSTANTS – раздел описания констант;
•DOMAINS – раздел описания доменов;
•DATABASE – раздел описания предикатов внутренней базы
данных;
•PREDICATES – раздел описания предикатов;
•CLAUSES – раздел описания предложений;
•GOAL – раздел описания внутренней цели.
Впрограмме не обязательно должны быть все эти разделы. Так, например, она может состоять из одного описания цели.
Однако, как правило, программа содержит разделы PREDICATES и CLAUSES.
Впрограмме может быть несколько разделов описаний DOMAIN S, PREDICATES, DATABASE и CLAUSES. Однако разделов GOAL в про-
грамме не может быть более одного.
Порядок разделов может быть произвольным, но при этом константы, домены и предикаты должны быть определены до их использования. Однако в разделе DOMAIN S можно ссылаться на домены, которые будут объявлены позже.
Рассмотрим разделы программы подробнее.
Разде л описания констант
Раздел CON STAN TS предназначен для описания констант.
Имя константы должно быть идентификатором, то есть оно может состоять из английских букв, цифр и знака подчеркивания, причем не может начинаться с цифры. Каждое определение константы должно размещаться в отдельной строке.
CON STAN TS
const1 = значение 1 const2 = значение 2
18
В этом разделе прописные и строчные символы не различаются. Рекомендуется в качестве первого символа имени константы использовать строчные буквы, для того чтобы при использовании констант в разделе описания предложений Пролог-система не восприняла константу как переменную.
Разделов описания констант может быть несколько, но каждая константа должна быть определена до ее первого использования.
Разде л описания доме нов
Раздел DOMAIN S содержит описание доменов. Раздел описания доменов является аналогом раздела описания типов в обычных императивных языках программирования.
Существуют следующие типы доменов:
•целые – integer из промежутка (- 32768. . . 32767);
•вещественные – real (лежащее между ±1e-307. . . ±1e308);
•символьные – char (один символ, заключенный в одиночные апострофы);
•строковые – string (последовательность символов, заключенная
вдвойные кавычки);
•символические – symbol (последовательность букв латинского алфавита, цифр и знаков подчеркивания, начинающаяся со строчной буквы, или последовательность любых символов, заключенная в кавычки);
•файловые – file.
При использовании символические имена и строки могут быть взаимозаменяемы, но их внутренняя обработка различна. Символические имена хранятся в таблице просмотра, которая допускает очень быструю процедуру сравнения, выполняемую во время поиска. Однако таблица символических имен занимает много памяти, а вставка в таблицу требует существенного времени.
Объявление домена имеет следующий вид:
<имя домена>=<определение домена>
Для представления данных в Турбо Прологе, в отличие от стандартных алгоритмических языков программирования, используются не массивы, а списки. Списковый домен задается следующим образом:
<имя спискового домена>=<имя домена элементов списка>*
Например, список целых чисел описывается так: list_of_integer=integer*
19
[GLOBAL] DOMAIN S
list of integer=integer*
Раздел GLOBAL DOMAINS указывает на то, что последующие объекты относятся к нескольким программным модулям.
Разде л описания пре дикатов внутре нней базы данных
В разделе описания предикатов внутренней (динамической) базы данных описываются те предикаты, которые можно в процессе выполнения программы добавлять во внутреннюю базу данных или удалять оттуда.
[GLOBAL] DATABASE <databasename> ]
[determ] p red1(. . .) p red2(. . . .)
Разде л описания пре дикатов
В разделе PREDICATES содержатся описания определяемых пользователем предикатов. Описание предиката имеет следующий вид:
<имя предиката>(<имя домена первого аргумента>,. . . <имя домена n-го аргумента>).
Домены аргументов должны быть либо стандартными, либо объявленными в разделе описания доменов. Обратите внимание на то, что имя предиката в Турбо Прологе должно состоять только из английских букв, цифр и символа подчеркивания, причем не может начинаться с цифры.
Например, предикат, описывающий отношение «мама», может быть описан следующим образом:
PREDICATES mother(string,string)
Один предикат может иметь несколько описаний. Это используется, когда нам нужно, чтобы предикат работал с аргументами различной природы. Например, опишем предикат, который будет проверять принадлежность элемента списку. Описать его можно, например, так:
PREDICATES
member(integer, integer*) member(real, real*)
Такие описания означают, что у предиката два аргумента. Первый аргумент может быть целым, второй аргумент, соответственно, списком целых или вещественных чисел.
20
