- •Глава 1 факты и правила
- •1.1. Использование языка пролог
- •Вызов транслятора языка Пролог
- •Синтаксис различных версий Пролога
- •1. 2. Факты Части Пролог-программы
- •Форма записи фактов в Прологе
- •Ввод программы
- •3. Запросы к базе данных Составление запроса
- •Запросы с константами
- •Запросы с переменными
- •Выполнение запроса
- •Составные запросы
- •Переменная _
- •1. 4. Прав ила
- •Форма записи правила: Заголовок:— Тело
- •Правило, при определении которого используются переменные
- •Пример: база данных "путешествие"
- •Косвенные отношения
- •1. 5. Процедуры Декларативная и процедурная семантика
- •Версия программы "можно_путешествовать", состоящая из двух правил
- •Запросы к предикату "можно_путешествовать2"
- •Соединитель "или"
- •Версия предиката "можно_путешествовать", в которой употребляется соединитель;
- •1. 6. Рекурсивные процедуры Определение понятия рекурсии
- •"Предок"
- •Состав рекурсивной процедуры
- •Рекурсивная версия процедуры "можно_путешествовать"
- •Порядок выполнения запроса к процедуре "можно_путешествовать4"
- •1. 7. Типы отношений Характеристики отношений
- •Ограничения вида один-к-одному
- •Ограничения вида один-к-многим
- •Ограничения вида многие-к-одному
- •Ограничения вида многие-к-многим
- •Симметрия
- •Асимметрия
- •Рефлексивность и нерефлексивность
- •Транзитивность
- •Анализ общеупотребительных отношений
- •Библиографические заметки
- •Упражнения
Составные запросы
Все приведенные выше запросы были простыми запросами. Составной запрос образуется из нескольких простых запросов, соединенных между собой запятыми. Каждый простой запрос, входящий в составной, называется "подцелью". Для того чтобы составной запрос оказался истинным, необходимо, чтобы каждая из его подцелей была истинной. К примеру, запрос
|? — знает (мэри. А), знает (сэм. А).
соответствует вопросу: "Есть ли такой человек, которого знают одновременно и Мэри, и Сэм?" Одна и та же переменная А входит в обе подцели этого запроса, а это означает, что для истинности всего составного запроса вторые аргументы обеих подцелей должны принимать одно и то же значение. Интерпретатор ответит:
А=боб;
нет
Первый ответ, А = боб, показывает, что Боба знают одновременно и Мэри, и Сэм. Второй ответ, нет, свидетельствует о том, что Боб — это единственный их общий знакомый.
Аргументы как входные и выходные параметры
Выдача запроса — это единственный способ дать команду интерпретатору Пролога на выполнение программы. Использование константы в качестве аргумента запроса (скажем, констант "мэри" или "сэм" в последнем примере) эквивалентно заданию входного параметра программы. Любой положительный ответ должен унифицироваться с константой. Использование переменной в качестве аргумента запроса (скажем, переменной А в последнем примере) эквивалентно требованию получить от программы выходные данные.
Переменная _
Символ подчеркивания _ выступает в качестве анонимной переменной, которая предписывает интерпретатору проигнорировать значение аргумента. Анонимная переменная унифицируется с чем угодно, но не обеспечивает выдачу на терминал выходных данных. Каждая переменная _, входящая в запрос, отличается от всех других переменных этого запроса. Посмотрим, к примеру, что произойдет, если ввести запрос:
|? - знает (Б, _).
При выполнении этого запроса будут выданы все возможные значения первого аргумента предиката "знает", вне зависимости от того, какие значения будет принимать второй аргумент.
Б = мэри;
Б = сэм;
Б = сэм;
нет
Как вы думаете, почему интерпретатор дважды выдал ответ Б = сэм?
1. 4. Прав ила
Сравнение фактов и правил
Факт — это утверждение о существовании некоторого отношения между аргументами, обозначаемого именем предиката. С другой стороны, правило - это факт, значение истинности которого зависит от истинностных значений условий, образующих тело правила.
Форма записи правила: Заголовок:— Тело
Заголовок правила имеет точно такую же форму, как и факт. После заголовка стоит обозначение:— (которое читается как "если"), а затем располагается тело правила. Каждое условие, входящее в тело, называется подцелью. Для того чтобы заголовок правила оказался истинным, необходимо, чтобы каждая подцель, входящая в тело, была истинной. Тем самым совокупность подцелей в теле правила действует подобно составному запросу.
ЗАГОЛОВОК если ТЕЛО
ПОДЦЕЛЬ и ПОДЦЕЛЬ
начальник (Фамилия, Окл): - служ (Фамилия, Окл), Окл > 70000.
Заголовок правила сходен с макросом, который обозначает совокупность подцелей, входящих в его тело. Процесс доказательства истинности запроса к некоторому правилу сходен с выполнением подстановки макроса.
Пример правила
Предположим, что создана база данных "раб_смена". Каждый факт этой базы определяет смену, в которую работает служащий.
% служащий смена
раб_смена (мэри, дневная).
раб_смена (сэм, вечерняя).
раб_смена (боб, вечерняя).
раб_смена (патриция, вечерняя).
Следующее правило устанавливает, что Боб знает Мэри, если они вместе работают в вечернюю смену:
Знает1 (боб, мэри): - % заголовок
раб_смена (боб, вечерняя), %1-я подцель тела раб_смена (мэри, вечерняя). %2-я подцель тела
Заголовком данного правила является «знает1 (мэри, боб)». Тело правила состоит из двух подцелей "раб_смена". Запятая, стоящая между этими по/щелями, читается как "и". Все правило можно прочесть так:
Боб знает Мэри, если
Боб работает в вечернюю смену и
Мэри работает в вечернюю смену.
Запрос к правилу
Правила опрашиваются таким же способом, как и факты. В нижеследующем запросе требуется выяснить, кого знает Боб:
|? – знает1 (боб, А),
А =мэри
Успешность этого запроса зависит от успешности всех подцелей, входящих в тело опрашиваемого правила. Ответ на запрос будет отрицательным, если интерпретатор не сможет установить, что и Боб, и Мэри работают в вечернюю смену.