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