Нерефлексивность

В разд. 1. 3 было отмечено, что отношение "знает2" обладает ненужной рефлексивностью, так как будет успешным, к примеру, запрос:

|?— знает2 (мери, мери).

да

Отношение "знает" можно превратить в нерефлексивное путем добавления еще одной подцели:

знаетЗ (А, В): —

раб_смена (А, Смена),

раб_смена (В, Смена),

А\==В.

Симметричное и транзитивное отношение

Пока еще мы не смогли адекватно представить отношение, которое являлось бы одновременно и симметричным, и транзитивным. В разд. 1. 5 была рассмотрена версия процедуры "можно—путешествовать", названная "можно_путешествовать4", которая обладала свойством транзитивности, но не была симметричной, т. е. в ней допускается поездка из Нью-Йорка в Бостон, но не из Бостона в Нью-Йорк. Данные (т. е. база данных, состоящая из фактов "путешествие/4") были тщательно подобраны, чтобы не допустить появления циклов. К примеру, в базе данных имеются факты, описывающие возможность добраться из Бирлингтона в Нью-Йорк и из Нью-Йорка в Бостон, но нет факта, описывающего путешествие из Бостона в Бирлингтон. Отсутствие симметрии и необходимость в данных без циклов являются серьезными недостатками процедуры "можно-путешествовать4". Хотелось бы написать такую версию процедуры "можно_путешествовать", которая обладала бы симметричностью и позволяла бы обрабатывать любые данные.

Первая попытка

Один из подходов к решению этой задачи заключается в том, чтобы сделать базу данных "путешествие" симметричной, пользуясь тем же методом, который был применен для базы данных "брат_или_сестра", а затем обратиться к базе "путешествие" из рекурсивной процедуры "можно_путешествовать". Правило "можно_путешествовать" в этом случае автоматически унаследует симметрию базы данных "путешествие". Кроме того, добавим в него подцель А\ ==Б, что позволит сделать отношение нерефлексивным и, следовательно, даст возможность избавиться от некоторых ошибочных ответов. Получившуюся процедуру назовем "тснр_путешествовать1" ("тснр" означает транзитивное, симметричное, нерефлексивное отношение).

% Либо один вид транспорта соединяет пункты А и Б.

тснр_путешествовать1 (А, Б, м (Вид_тр, Б)): -

А\==Б

сим_путешествие (А, Б, Вид_тр).

% Либо более, чем один вид транспорта соединяет А и Б:

тснр_путешествовать1 (А, Б, м (Вид_тр1, В, Вид_тр2)): —

А\==Б,

сим_путешествие (А, В, Вид_тр1),

тснр_путешествовать1 (В, Б, Вид_тр2).

% Промежуточная процедура, обеспечивающая симметрию

% фактов, содержащихся в базе данных "путешествие"

сим_путешествие (А, Б, Вид_тр): — путешествие (А, Б, Вид_тр).

сим_путешествие (А, Б, Вид_тр): - путешествие (Б, А, Вид_тр).

% Из В Вид_транспорта

путешествие (манхэттен, ньюарк, автобус).

путешествие (манхэттен, куинс, жел_дорога).

Здесь "путешествие" — это явная база данных, в которой хранятся фактические данные. Для простоты в этой версии базы данных отсутствует аргумент с названием транспортной компании. Если мы выдадим запрос к процедуре "тснр_путешествовать1" по поводу того, как можно добраться из Ньюарка в Куинс, то первый ответ на него будет приемлемым:

|? - тснр_путешествовать1 (ньюарк, куинс, М).

М = м (автобус, манхэттен, м (жел_дорога. куинс));

Однако, кажется, существует бесконечное количество дополнительных ответов, ценность которых весьма сомнительна:

М = м (автобус, манхэттен, м (автобус, ньюарк,

м (автобус, манхэттен, м (жел_дорога, куинс)))) ;

М = м (автобус, манхэттен, м (автобус, ньюарк,

м (автобус, манхэттен, м (автобус, ньюарк,

м (автобус, манхэттен, м (жел_дорога, куинс))))));

М=м (автобус, манхэттен, м (автобус, ньюарк,

м (автобус, манхэттен, м (автобус, ньюарк,

м (автобус, манхэттен, м (автобус, ньюарк,

м (автобус, манхэттен, м (жел_дорога, куинс))))))));

Каждый раз, когда мы запрашиваем другой ответ, процедура совершает еще один цикл между Манхэттеном и Ньюарком, прежде чем в конце концов доходит до Куинса! Данные теперь обладают "врожденной" цикличностью, так как процедура "сим_путешествие" симметрична. Запрос к тснр_путешествовать1" тонет в ненужных циклических действиях.

Соседние файлы в папке Гл.0,1,2,3,4,5,Предисловие