Главная

ПРОЕКТ "ЧЕЛОВЕК. ЗЕМЛЯ. ВСЕЛЕННАЯ"

Инструменты пользователя

Инструменты сайта


project:prolog:celi_v_prologe



Цели в Прологе. Внутренние цели. Внешние цели

Цель - это формулировка задачи, которую программа должна решить. Цель состоит из взаимосвязанных предикатов. Структура цели точно такая же, как у правила или факта.

Цель используется для запуска процесса выполнения программы. Пролог пытается сопоставить цель с фактами и правилами программы. Если цель является фактом, таким как «любит(мэри, яблоки)», то Пролог отвечает True (истина) или False (ложь). Если цель содержит переменные, то Пролог выдает либо те их значения, которые приводят к решению, если оно существует, либо сообщение No solutions (решений нет).

Внешние цели заставляют внутренние унификационные подпрограммы Пролога найти все решения, удовлетворяющие цели. Внутренние цели заставляют внутренние унификационные подпрограммы останавливаться после первого успешного сопоставления цели.

Схема работы программы:

likes - это отношение (символ предиката). Этот же самый символ likes может быть использован как цель. Предикат цели сопоставляется с предикатами в программе.

В ответ на запрос системы, необходимо ввести цель – likes(beth,apples) Такая цель является внешней. Программы Пролога (Prolog) с внешней целью называются интерактивными. Смысл применения внешних целей - дать пользователю полную свободу использования имеющихся данных. Программа в этом случае играет роль «нейтральной» базы данных.

Эта цель фактически означает, что вы хотите знать, действительно ли Бет любит яблоки в соответствии с информацией, имеющейся в программе. После ввода цели Пролог начинает поиск правил и фактов программы для сопоставления с предикатом likes.

Пытаясь выполнить цель, Пролог просматривает программу слева направо, выполняя поиск предиката с тем же предикатным термом, что и целевой предикат. Если предикат цели и предикат факта совпадают, Пролог пытается сопоставить первые объекты в цели и в факте, затем вторые объекты и т.д. Аналогичным образом Пролог просматривает все факты.

Пример программы:

  predicates
   likes(symbol,symbol)
  clauses
   likes(mary, apples).
   likes(beth, X) if likes(mary, X).

Фактически Пролог осуществляет поиск строки программы (факта или правила), которые совпадут с введенной целью с учетом имеющихся в фактах и правилах переменных.

Следующая программа проверяет нескольких целей:

  • любит ли beth что-то?;
  • любит ли beth mary?

На запрос цели необходимо ввести likes(beth, apples) или likes(beth,mary)

predicates
   likes(symbol,symbol)
 
clauses
   likes(mary, apples).
   likes(mary,beth).
   likes(beth, X) if likes(mary, X). /* beth любит это, если mary любит это */
   likes(beth, X) if likes(X, beth). /* beth любит mary, если mary любит beth */

Подцели

Так как цели, подобно фактам и правилам, строятся из предикатов, то цели также могут иметь связки and и or. (См. Связки в правилах) Цели, имеющие связки, называются целями, имеющими подцели. Подцели утверждения цели разделяются запятыми точно так же, как условия в правилах.

Когда цель введена в программу на Прологе, то подцели обрабатываются слева направо. Осуществляется попытка сопоставить подцели с фактами и правилами программы. Если одна из подцелей несопоставима, то вся цель является неуспешной. Если все подцели сопоставимы, то вся цель является успешной.

Например, программа содержит следующие утверждения:

likes(mary,apples). /* Мэри любит яблоки */
color(apples,red). /* цвет яблок красный */

Введем цель. Подцели этой цели разделены запятой и точка завершает цель как целое.

/* «Любит ли Мэри яблоки, и красные ли эти яблоки?». */
likes(mary,apples), color(apples,red).

Самая левая подцель likes(mary,apples) сопоставима с утверждением likes(mary,apples), так что эта подцель успешна. Следующая подцель справа сопоставима с утверждением color(apples,red), и поэтому вся цель является успешной.

Новая цель «Любит ли Мэри красные яблоки?» отличается от предыдущей. Ранее требовалось только проверить факты, что Мэри любит яблоки и что эти яблоки красные. В новой цели необходимо знать, любит ли Мэри яблоки, если они красные.

Яблоки могут быть и красные, и зеленые, и желтые. Но Мэри может вообще не любить яблоки, либо же она их любит, но они не красные. В таком случае ответ False.

Для того, что бы ввести эти факты в программу, необходимо убрать утверждение likes(mary,apples). и добавить правило likes(mary,apples) :- color(apples,red).

По-русски это правило читается как «Мэри любит яблоки, если они красные».

Если вы хотите узнать «Любит ли Мэри яблоки?», то используйте цель likes(mary,apples).

predicates
  color (symbol,symbol)
  likes(symbol,symbol)

clauses
  color(apples,red).			   /* Определение цвета яблок - красные */
  likes(mary,apples) :- color(apples,red). /* Мэри любит яблоки, если они красные. */

goal
  /* Ввод цели: «Любит ли Мэри яблоки?» . Да, потому что они красные. */
  likes(mary,apples), write("Mary likes apples, because apples red."),nl.

Даже если цель сама по себе не имеет подцелей, то Пролог все равно должен сопоставить правило с условием с соответствующим утверждением. Фактически Пролог создает подцель и сопоставляет цель likes(mary,apples) с головой правила likes(mary,apples). Это правило имеет условие color(apples,red). Поэтому это условие должно быть доказано для того, чтобы цель могла быть успешной. То есть цвет яблок (красный) должен быть определён ранее - color(apples,red).

Другими словами, если голова (левая часть) правила сопоставима с целью, то факты правой части становятся подцелями, которые Пролог должен вычислить, обрабытывая их слева направо. Для доказательства головы правила, должны быть доказаны условия тела правила точно так же, как если бы целевое утверждение состояло из связки этих подцелей.

Пролог успешно доказывает созданную подцель, обнаружив среди утверждений факт color(apples,red). Доказав эту подцель, Пролог доказал, что голова правила истинна. Так как голова правила сопоставима с целью, то цель является успешной.

Чтобы понять как Пролог генерирует внутренние подцели, можно считать, что условия справа от if (или символа :- ) становятся подцелями исходной цели, когда, пытаясь доказать эту цель, Турбо-Пролог сопоставляет ее с головой правила.

Внутренние цели в Прологе (Prolog)

В программе "Синонимы" в самом теле программы мы использовали внутреннюю цель:

clauses
  synonym(brave,daring).
 
/* внутренняя цель */
goal
  synonym(brave,X),
  write("A synonym for 'brave' is "),
  nl,
  write(" ",X,"."),
  nl.

Само предложение, определяющее цель, состоит из пяти подцелей, разделенных запятыми.

Первая подцель:

synonym(brave,X)

Х здесь является свободной переменной, ее значение не конкретизировано. (Имя переменной обязательно начинается с большой буквы.) Говоря обычным языком, в данном предложении сформулирована такая цель:

«Найти утверждение, использующее предикат synonym, такое, что первым объектом в нем является brave, и связать переменную Х с его вторым объектом».

После запуска программы, Турбо-Пролог будет просматривать утверждения, содержащие synonym. Если таковое с объектом brave будет обнаружено, то Х примет значение второго объекта - daring.

Второй подцелью является печать следующей строки символов на экране:

 A synonym for ‘brave’ is

Эта подцель образована при помощи предиката write, одного из многих «встроенных» предикатов Турбо-Пролога. Подобные предикаты не требуют специального описания в программе, их можно использовать сразу.

Встроенный предикат write в данной программе встречается в виде:

write("A synonym for 'brave' is "),

Двойные кавычки при этом применяются для ограничения символьной строки A synonym for 'brave' is; подобным образом должны выделяться все символьные строки. Предикат write может также содержать имена переменных, в этом случае кавычки не требуются.

Простейшим примером может служить:

write(X),

где Х - это имя переменной. Если Х принял значение daring, то write это daring и напечатает.

В обоих случаях, как символьная строка, так и переменная являются аргументами предиката write. Так же как и у других предикатов, аргументы write разделяются запятыми. Аргументы можно произвольно смешивать при условии соблюдения описываемых соглашений.

Компилятор Пролога поправит Вас, если Вы пропустите кавычки, или сделаете какую-либо другую ошибку того же порядка.

Пример смешанной записи аргументов:

write(“Today is the “,N,”th day of “,M,”, a “,D,”.”).

Этот предикат напечатает предложение

Today is the 19th day of August, a Tuesday.
(Сегодня 19 августа, вторник)

если значениями переменных N, M и D будут соответственно 19, August и Tuesday.

Третья подцель задается еще одним встроенным предикатом: nl. Предикат nl переводит курсор в начало следующей строки.

Четвертая подцель - печать всех трех объектов, заключенных в круглые скобки. Первый из них представляет собой обычную кавычку; второй, обозначенный как Х, - это daring; третий состоит из кавычки и точки.

Пятая подцель, еще один предикат nl, переводит курсор к началу строки, следующей за строкой с daring.

Предложение, описывающее цель, должно оканчиваться точкой; если точка будет опущена, компилятор выдаст сообщение об ошибке, и трансляция программы будет прекращена.

Результат выполнения программы:

A synonym for brave is  'daring'.

Внешние цели в Прологе (Prolog)

Если Вы запустите на счет программу, в которой будет отсутствовать описание цели или внутренняя цель, то Пролог (Prolog) попросит вас ввести цель с экрана. Такая цель является внешней целью. Программы Пролога с внешней целью называются интерактивными.

Цель применения внешних целей - дать пользователю полную свободу использования имеющихся данных. Программа в этом случае играет роль «нейтральной» базы данных.

Если, например, из программы «Синонимы» удалить раздел goal и запустить ее на счет, то на экране в окне возникнет приглашение Goal: .

Допустим, вы хотите задать вопрос: «Какое слово является синонимом слова brave?» Так же, как и при записи внутренней цели, переменная Q будет использоваться для представления значения, которое Пролог (Prolog) поставит ей в соответствие, используя утверждения базы данных. С ее помощью вопрос формулируется в виде:

synonym(brave,Q).

После выполнения внешней цели выполнение программы, однако, не завершается. Пролог (Prolog) просит ввести следующую внешнюю цель. Таким образом можно задать столько целей, сколько это представляется необходимым; чтобы остановить этот процесс нужно нажать клавишу Esc при выдаче очередного приглашения.

В формулировке запроса к программе можно использовать не только одну переменную, но и несколько. Если, к примеру, Вы введете две переменные, то программа выдаст все возможные комбинации значений, удовлетворяющие данным переменным.

Применение внешних целей бывает полезно при записи коротких целевых формулировок, а также для получения всего набора допустимых значений. Другое преимущество внешних целей - они позволяют адресовать базе данных совершенно произвольные запросы.

Использование правил в запросах

Целевые утверждения (утверждения с целью) обеспечивают одну из возможностей осуществления запросов к программе. Запросы строятся из предикатов, содержащих условия, которые ограничивают пути поиска желаемых результатов, причем, в случае, когда какой-либо запрос нужно повторить несколько раз, разумно предусмотреть возможность не задавать всякий раз одни и те же условия, что утомительно. Полезно также для получения ответов из базы данных не использовать фактов из базы данных.

В Prolog (Прологе) эта задача решается конструированием правил, не содержащих в себе данных, то есть правил нулевой арности. (См. "Предикаты разных арностей") Программа сама перебирает и находит нужные значения, удовлетворяющие правилам. Задача, таким образом, сводится к написанию сокращенного варианта запроса.

Представим себе некую гипотетическую семью: Фрэнк и Мэри являются мужем и женой. Их сына зовут Сэмом, а дочку - Дебби. Ниже приведен небольшой диалог, касающийся этой семьи.

Вопрос: Кем приходятся друг другу Дебби и Сэм?
Ответ: Дебби - сестра Сэма.
Вопрос: Из чего Вы это заключили?
Ответ: У Дебби и Сэма одни и те же родители, Дебби - девочка. Таким образом, Дебби - сестра Сэма.

Второй из вопросов является разговорной формулировкой правила, которое будет использоваться для ответа на запрос. Это правило можно перефразировать таким образом:

/* заключение или логическое следствие */
Дебби - сестра Сэма, 
если 
/* допущение или предпосылка. */
Дебби - существо женского пола, и родители Дебби есть родители Сэма. 

Фраза включает в себя условие «если» (if или :- ), которое логически связывает оба утверждения. Утверждение, предшествующее «если» называется заключением или логическим следствием, а утверждение, следующее за «если» - допущением или предпосылкой.

Предикатные выражения являются теми блоками, из которых в Прологе строятся правила. Факты, описывающие отношения между Фрэнком, Мэри, Сэмом и Дебби можно сформулировать при помощи таких утверждений Пролога:

male(«Frank»). /* Фрэнк - мужского пола */
male(«Sam»). /* Сэм - мужского пола */
female(«Mary»). /* Мэри - женского пола */
female(«Debbie»). /* Дебби - женского пола */
parents(«Sam»,«Frank»,«Mary»). /* Родители Сэма есть Фрэнк и Мери */
parents(«Debbie»,«Frank»,«Mary»). /* Родители Дебби есть Фрэнк и Мери */

Имея в наличии эти утверждения, необходимо лишь ввести правило, задающее отношение брат-сестра:

sister(Sister,Brother) if
female(Sister),
parents(Sister,Father,Mother),
parents(Brother,Father,Mother).

В формулировке правила нет никаких данных о конкретной семье; объекты Sister, Brother, Father и Mother являются переменными. Двойное использование предиката parents устанавливает логическую связь между переменными Sister и Brother. Наличие предиката female позволяет выбрать ребенка женского пола. Три предиката предпосылки правила вполне достаточны для получения нужного заключения.

Программа «Родственники» демонстрирует использование перечисленных фактов и правила sister.

domains
  person = symbol

predicates
  male(person) /* мужчины */
  female(person) /* женщины */
  parents(person,person,person) /* ребёнок и его родители */
  sister(person,person) /* сестра */

  who_is_the_sister /* предикат нулевой арности */

clauses
  /* факты */
  male("Frank"). /* отец */
  male("Sam"). /* сын */
  female("Mary"). /* мать */
  female("Debbie"). /* сестра */
  parents("Sam","Frank","Mary"). /*родители Sam - Frank и Mary */
  parents("Debbie","Frank","Mary"). /*родители Sam - Frank и Mary */

  /* правило, задающее отношение брат-сестра */
  sister(Sister,Brother) :- female(Sister), male(Brother), parents(Sister,Father,Mother), parents(Brother,Father,Mother).

  /* правило нулевой арности для вывода результатов цели */
  who_is_the_sister :- sister(Sister,Brother), write(Sister," is the sister of ",Brother, "."),nl.

goal
  /* цель - это предикат и правило */
  who_is_the_sister

Результат выполнения программы:

Debbie is the sister of Sam.

Программа «Родственники» содержит одно правило: предикат who_is_the_sister. who_is_the_sister является целью программы, ее единственным целевым утверждением. Само правило определяется в разделе утверждений программы clauses.

Ввиду того, что цель задается в виде правила, точка входа раздела goal являет собой единственное целевое утверждение без подцелей.

Тело правила состоит из двух частей. Первая часть это правило sister. В качестве второй части-предпосылки используется предикат write, который выводит полученные правилом sister результаты.

При разработке программы такой способ записи цели более предпочтителен, так как он упрощает эту самую запись. Особенно полезным он бывает тогда, когда программа имеет много разных подцелей, включающих в себя достаточно сложные операции. С точки зрения человека, лишь использующего эту программу, такой способ также более предпочтителен, так как упрощает процедуру запросов.

Предположим, что Вы хотите узнать имя сына. Этот запрос оформляется при помощи правила:

who_is_the_son :- parents(Son,Father,Mother), male(Son), write("The son is ",Son,"."),nl.

Это правило можно поместить в раздел clauses и заменить этим правилом целевое утверждение:

goal
  who_is_the_son

Результат этого запроса: «The son is Sam».

Подобным образом можно ввести еще достаточное количество правил. Правила можно будет активизировать выборочно путем использования их в целевой конструкции. (То есть в разделе clauses задали ряд правил, а потом в разделе goal сделали запрос (целевое утверждение).

Возможность Prolog (Пролога) выбирать нужные правила делает программу более гибким и мощным инструментом. Важным непосредственным приложением данного средства программирования является возможность задания запросов в форме правил, а также возможность «запасать» эти правила для использования при дальнейшей работе с базой данных.

!!Рекомендуем: Семейная Энциклопедия ЗдоровьяЧто должен знать современный человек?Самоанализ. Работа над собойОглавлениеГлавная сайта

Обсуждение

Ваш комментарий:
Q C U A G
 
project/prolog/celi_v_prologe.txt · Последние изменения: 2023/09/03 22:22 (внешнее изменение)

Вы можете оставить свои комментарии в разделе "Обсуждение".
Рекомендуем оформить подписку на новости данного раздела. Для этого нажмите на кнопку "Подписаться", расположенную справа снизу каждой страницы (знак конверта).

Индекс цитирования