- •Глава 4
- •Введение
- •Три точки зрения на Пролог-программу
- •4. 1. Реляционный подход
- •Изображение отношений
- •Ограничения, обеспечивающие целостность, которые накладываются при записи отношений в программу
- •Ограничения, обеспечивающие целостность, накладываемые при выборке фраз
- •Реализация свойств отношений
- •Нерефлексивность
- •Симметричное и транзитивное отношение
- •Первая попытка
- •Вторая попытка
- •Запоминание списка посещенных мест
- •4. 2. Взгляд на программу с точки зрения потока данных Переход от выходного потока данных к программе
- •Упорядоченные множества ответов
- •Генерирование бесконечного множества
- •Экологический процесс
- •Версия программы, в которой применяется поиск с возвратом
- •Рекурсивная версия программы
- •Планирование производственных операций
- •Сильные и слабые стороны подхода к программе с позиций потока данных
- •4.3. Бихевиористический подход Приведенные ранее примеры, в которых проявился бихевиористический подход
- •Ограничение сферы действия эффектов поведения
- •Программа "найти_или_спросить"
- •Оценка бихевиористического подхода
- •Библиографические заметки
- •Упражнения
Ограничения, обеспечивающие целостность, накладываемые при выборке фраз
Наложение ограничений, обеспечивающих целостность отношений, некоторой промежуточной процедурой при выборке фраз (т. е. при обработке запроса) служит средством оптимизации выполнения запросов в Прологе. Самый простой способ введения ограничения один-к-одному заключается в написании процедуры, которая должна выполнить поиск факта, а затем пройти через предикат "сократить". Приведем пример с версией процедуры "отец", в которой накладывается ограничение один-к-одному:
оо_отец (О, Р): -
отец (О, Р),!.
Поскольку здесь присутствует предикат "сократить", на каждый запрос к правилу "оо_отец" будет найдено не более одного ответа. Процедура, накладывающая ограничение один-к-многим на отношение "отец", может быть написана по аналогии с процедурой "мо_возраст" из разд. 3. 6:
отец (билл, даниэль).
отец (билл, кеннет).
% найти отца конкретного ребенка
% Один Много
ом_отец (О, Р): - % (1)
nonvar (P),
отец (О, Р),!. % "сократить"
% найти в базе данных всех детей конкретного
% отца или все пары отец/ребенок:
ом_отец (О, Р): - % (2)
var (P),
отец (О, Р). % нет предиката "сократить"
Ответ на запрос:
|? - ом_отец (X, даниэль).
Х = билл;
нет
получен в соответствии с правилом (1). Ответы на запросы:
|? - ом_отец (билл, Y).
Y= даниэль;
Y =кеннет;
нет
|? -ом_отец (X, Y).
Х =билл
Y = даниэль;
Х = билл
Y = кеннет;
...
получены по правилу (2).
Использование в процедуре предиката "сократить" для наложения ограничений, обеспечивающих целостность отношений, является безопасным способом устранения ненужных частей пространства поиска этой процедуры.
Реализация свойств отношений
Как отмечалось в разд. 1. 5, бинарное отношение, реализуемое в языке Пролог, по умолчанию обладает свойствами рефлексивности, асимметричности и нетранзитивности. Самый простой способ реализации свойств, отличающихся от принятых по умолчанию - это явное введение в программу фактов, обеспечивающих соблюдение заданного свойства. Предположим, к примеру, что в текущей программе содержатся только нижеследующие факты "брат_или_сестра":
брат_или_сестра (элис, джейн).
брат_или_сестра (дорога, кэти).
Можно сделать отношение "брат_или_сестра" симметричным путем простого добавления в программу дополнительных фактов "брат_или_сестра" с обратным порядком следования аргументов:
брат_или_сестра (джейн, элис).
брат_или_сестра (кэти, дорога).
В соответствии с этим способом симметрию отношения "брат_или_сестра" может поддерживать программа ввода данных, которая добавляет по два новых факта "брат_или_сестра" на каждый представленный пользователем факт. Транзитивность отношения (например, отношения "предок") можно обеспечить аналогичным и столь же громоздким способом.
Альтернативой представлению каждого случая отношения в виде факта служит применение процедуры, устанавливающей симметричность, нерефлексивность или транзитивность отношения. Так, процедура "брат_или_сестра2" из разд. 1. 3 устанавливает симметрию отношения "брат_или_сестра", а рекурсивная процедура "предок" устанавливает транзитивность отношения "предок". Реализация свойств отношения при помощи процедуры, а не за счет добавления фактов, позволяет добиться огромной экономии ресурсов. В следующих разделах детально обсуждается реализация свойств отношений, не рассматривавшихся в гл. 1.