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