Скачиваний:
16
Добавлен:
01.05.2014
Размер:
287.74 Кб
Скачать

Глава 6

1. Отношение "является" можно гарантировано превратить в транзитив­ное, если задать явную базу данных "является0" и написать рекурсивную процедуру "является", которая обращается к базе данных "является0":

является0 (канарейка, птица).

является0(твити, канарейка).

является (X, Y);—

является0 (X, Y).

является (X, Y) :—

является0 (X, Z),

является (Z,Y).

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

летает (птица).

летает (X) :- является0 (X,Y), летает (Y).

цвет (канарейка, желтый).

цвет(Х, Y):- является0(Х, Z), цвет(Z, Y).

2.

является0 (квадрат, прямоугольник).

является0 (прямоугольник. параллелограмм).

свойство (параллелограмм,

'площадь равна произведению основания на высоту').

свойство (прямоугольник,

'все углы равны 90 градусам').

свойство (квадрат, 'все стороны равны').

свойство (Узел, Свойство) :—

является0 (Узел, ДругойУзел),

свойство (ДругойУзел, Свойство).

3.

подсчет (Состояние, Счетчик) :—

% ввести критерий выбора:

послать (Состояние, за (тип, Т)),

послать (Состояние, за (марка, М) ),

послать(Состояние,за(вес,B)),

послать(Состояние,за(поверхность,П)),

послать (Состояние, за (цвет, Ц)),

!,

% подсчитать количество целостных информационных

% элементов, удовлетворяющих критериям выбора:

findall (Т, вед_бум (бумага. Т, М, В, П, Ц), Список),

длина (Список, Счетчик).

Примечание: при обращении к встроенному предикату "findall" не имеет никакого значения, какие сведения фактически собираются в список "Список", так как нас интересует лишь количество элементов списка, а не его содержание.

Глава 7

1. Пример базы данных с циклическими данными:

путешествие (амтрак, нью_йорк, бостон, поезд).

путешествие (грейхаунд, бостон, нью_йорк, автобус).

Обычный интерпретатор, выполняя нижеследующий запрос к процедуре "'можно путешествовать4":

| ?— можно путешествовать4 (нью йорк, X).

будет вырабатывать ответы по такой схеме:

Х = бостон ;

Х = нью йорк ;

Х= бостон ;

Х = нью_йорк ;

Еслли данный запрос выполнять при помощи процедуры "иоц", то будут получены точно такие же ответы. Процедура "иоц" обнаруживает только те циклы, в которых одна и та же подцель попадается три раза подряд. Приве­денный выше запрос входит в осциллирующий цикл, который интерпретатор "иоц" не сможет обнаружить. Наилучшее решение проблемы осцилляции бы­ло предложено в процедуре "тснр_путешествовать3" из гл. 4. Можете ли Вы написать универсальную программу-решатель задач, которая будет об­наруживать осциллирующие множества ответов, используя ту же методику, какая была применена в процедуре "тснр-путешествоватьЗ"?

2. Ввиду того что успешный вызов процедуры "поместить" фактически приводит к переходу из одного состояния в другое, смысл данного вызова станет более ясным, если имена нужных состояний будут фигурировать в качестве аргументов этой процедуры, например:

% + + ?

поместить (Объект, Куда_поместить, ТекущСост, НовСост) :—

3.

% объявить свойство один-к-многим отношения "мать"

% Отношение Один Много

один_много (мать (Мать, Ребенок), Мать, Ребенок).

% объявить свойство один-к-одному отношения

% "соц_страх_номер":

% Отношение Один Один

один_один (соц_страх_номер (Имя, Номер), Имя, Номер).

% решатель задач, которому известно про отношения

% один-к-одному и один-к-многим:

рз(truе):— !.

рз((А, Б)) :— % составной запрос

!,

рз(А),

рз(б).

рз(А) :— % особый случай: А - это отношение вида

% один-к-многим

один много (А, X, Y),

!,

ом_рз(А,Х,У).

рз(А) :- % особый случай : А - это отношение вида

% один-к-одному один_один(А, X, Y),

оо_рз(А,Х,У).

рз(А) :— % отношение А не является ни отношением

% вида один-к-одному, ни отношением вида

% один-к-многим

clause (А, Тело),

рз(Тело).

% эффективно обработать отношение вида один-к-многим:

% Один Много

ом_рз(А, X, Y) :-

nonvar(Y),

clause (А, Тело),

рз(Тело),!.

ом_ pз(A,X,Y):-

var(Y),

clause (А, Тело),

рз(Тело).

% эффективно вычислить отношение вида один-к-одному:

% Один Один

оо_рз(А, X, Y):-

clause(A, Тело),

рз(Тело),!.

Отношения вида многие-к-одному можно реализовать, объявив их как отношения вида "один_много" и изменив порядок следования аргументов на обратный.

Соседние файлы в папке Гл.6,7,Прилож.,Допол