Книга: Программирование на языке Пролог для искусственного интеллекта

14.5.7. Цели с отрицанием

14.5.7. Цели с отрицанием

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

рассмотреть( не Цель, Трасса, Ответ) :- !,
 рассмотреть( Цель, Трасса, Ответ1),
 обратить( Ответ1, Ответ).
  % Получить обратное истинностное значение
обратить( Цель это правда было Найдено,
 ( не Цель) это ложь было Найдено).
обратить( Цель это ложь было Найдено,
 ( не Цель) это правда было Найдено).
% Процедура-драйвер верхнего уровня
эксперт :-
 принять_вопрос( Вопрос),
  % Ввести вопрос пользователя
 ( ответ_да( Вопрос);
  % Попытка найти положительный ответ
 ответ_нет( Вопрос) ).
  % Если нет положительного ответа, то найти отрицательный
ответ_да( Вопрос) :-
  % Искать положительный ответ на Вопрос
 статус( отрицательный),
  % Пока еще нет положительного ответа
 рассмотреть( Вопрос, [], Ответ), % Трасса пуста
 положительный( Ответ), % Искать положительный ответ
 статус( положительный),
  % Найден положительный ответ
 выдать( Ответ), nl,
 write( 'Нужны еще решения?' ),
 принять( Ответ1), % Прочесть ответ пользователя
 Ответ1 = нет.
  % В противном случае возврат к "рассмотреть"
ответ_нет( Вопрос):-
  % Искать отрицательный ответ на Вопрос
 retract( пока_нет_положительного_решения), !,
  % Не было положительного решения?
 рассмотреть( Вопрос, [], Ответ),
 отрицательный( Ответ),
 выдать( Ответ), nl,
 write( 'Нужны еще решения?' ),
 принять( Ответ1),
 Ответ1 = нет.
  % В противном случае - возврат к "рассмотреть"
статус( отрицательный) :-
 assert( пока_нет_положительного_решения).
статус( положительный) :-
 retract( пока_нет_положительного_решения), !; true.
принять_вопрос( Вопрос) :-
 nl, write( 'Пожалуйста, спрашивайте:'), nl,
 read( Вопрос).

Рис. 14.13. Оболочка экспертной системы: драйвер. Обращение к оболочке из Пролога при помощи процедуры эксперт.

Если Цель конкретизирована, то все в порядке, если же нет, то возникают трудности. Рассмотрим, например, такой диалог:

?- эксперт.
Пожалуйста, спрашивайте:
не ( X ест мясо).
Есть (еще) решения для : Животное
да.
Животное =тигр.

В этот момент система даст ответ:

не ( тигр ест мясо) это ложь

Такой ответ нас не может удовлетворить. Источник затруднения следует искать в том, какой смысл мы вкладываем в вопросы типа

не ( X ест мясо)

В действительности мы хотим спросить: "Существует ли такой X, что X не ест мяса?" Однако процедура рассмотреть (так как мы ее определили) проинтерпретирует этот вопрос следующим образом:

(1) Существует ли такой X, что X ест мясо?

(2) Да, тигр ест мясо.

Итак,

(3) не (тигр ест мясо) это ложь.

Короче говоря, интерпретация такова — "Правда ли, что никакой X не ест мясо?" Положительный ответ мы получим, только если никто не ест мяса. Можно также сказать, что процедура рассмотреть отвечает на вопрос так, как будто X находится под знаком квантора всеобщности:

 для всех X: не (X ест мясо)?

а не квантора существования, в чем и состояло наше намерение:

 для некоторого X: не (X ест мясо)?

Если рассматриваемый вопрос конкретизирован, то проблемы исчезают. В противном случае правильный способ работы с отрицаниями становится более сложным. Например, вот некоторые из возможных правил:

Для того, чтобы рассмотреть (не Цель), рассмотрите Цель, а затем:

• если Цель это ложь, то (не Цель) это правда;

• если Цель' — это некоторое решение для Цель, и Цель' — утверждение той же степени общности, что и Цель, то (не Цель) это ложь;

• если Цель' — это некоторое решение для Цель, и Цель' — более конкретное утверждение, чем Цель, то об утверждении (не Цель) нельзя сказать ничего определенного.

Можно избежать всех этих осложнений, если потребовать, чтобы отрицания стояли только перед конкретизированными целями. Если правила базы знаний формулировать должным образом, то часто удается удовлетворить этому условию. Нам это удалось в "правиле поломки" (рис. 14.7):

правило_поломки:
 если
  вкл( Прибор) и
  прибор( Прибор) и % Конкретизация
  не работает( Прибор) и
  соед( Прибор, Предохр) и
  доказано( цел( Предохр) )
 то
  доказано( неиспр( Прибор) ).

Здесь условие

прибор( Прибор)

"защищает" следующее за ним условие

не работает( Прибор)

от неконкретизированной переменной.

Упражнение

14.3. База знаний может, в принципе, содержать циклы. Например:

прав1: если бутылка_пуста то джон_пьян.
прав2: если джон_пьян то бутылка_пуста.

Работая с подобной базой знаний, наша процедура рассмотреть может зациклиться на обработке одних и тех же целей. Внесите в процедуру рассмотреть изменения, предотвращающие зацикливание. Используйте для этого объект Трасса. Однако соблюдайте осторожность: если текущая цель сопоставима с одной из предыдущих целей, то такую ситуацию следует рассматривать как цикл только в том случае, когда текущая цель имеет большую, степень общности, чем предыдущая.

Оглавление книги


Генерация: 1.468. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз