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

         

База знаний для локализации неисправностей



  База знаний для локализации неисправностей

в схеме, показанной на рис. 14.6.

    Придумайте какую-нибудь задачу принятия решений и сформулируйте соответствующие знания в форме "если-то"-правил. Можете рассмотреть, например, планирование отпуска, предсказание погоды, простой медицинский диагноз и лечение и т.п.



Два правила из демонстрационной...



  Два правила из демонстрационной базы знаний системы
AL/X для диагностики неисправностей (Reiter 1980).    N   и   S   - 
величины "необходимости" и "достаточности", детально описанные
в разд. 14.7. Величина   S   указывает степень, с которой условие
влечет за собой заключение (вывод). Величина    N   указывает, до
какой степени истинность условия необходима для того, чтобы
заключение было истинным.

line();

если
    1        существует гипотеза  H,  что план  Р   ведет к


              успеху, и
    2        существуют две гипотезы
              H1,   что план  Р1  опровергает план  Р,   и
              Н2,   что план  Р2  опровергает план  Р,   и
    3        имеют место факты:        гипотеза  H1   ложна и
                                                        гипотеза   Н2  ложна
то
    1        породить гипотезу  Н3,  что составной план  "Р1
              или Р2"  опровергает план  Р,  и
    2        породить факт: из   Н3  следует  не( Н)

line();



Функции, выполняемые экспертной системой



    Функции, выполняемые экспертной системой

Экспертная система - это программа, которая ведет себя подобно эксперту в некоторой, обычно узкой, прикладной области. Типичные применения экспертных систем включают в себя такие задачи, как медицинская диагностика, локализация неисправностей в оборудовании и интерпретация результатов измерений. Экспертные системы должны решать задачи, требующие для своего решения экспертных знаний в некоторой конкретной области. В той или иной форме экспертные системы должны обладать этими знаниями. Поэтому их также называют системами, основанными на знаниях. Однако не всякую систему, основанную на знаниях, можно рассматривать как экспертную. Экспертная система должна также уметь каким-то образом объяснять свое поведение и свои решения пользователю, так же, как это делает эксперт-человек. Это особенно необходимо в областях, для которых характерна неопределенность, неточность информации (например, в медицинской диагностике). В этих случаях способность к объяснению нужна для того, чтобы повысить степень доверия пользователя к советам системы, а также для того, чтобы дать возможность пользователю обнаружить возможный дефект в рассуждениях системы. В связи с этим в экспертных системах следует предусматривать дружественное взаимодействие с пользователем, которое делает для пользователя процесс рассуждения системы "прозрачным".

Часто к экспертным системам предъявляют дополнительное требование - способность иметь дело с неопределенностью и неполнотой. Информация о поставленной задаче может быть неполной или ненадежной; отношения между объектами предметной области могут быть приближенными. Например, может не быть полной уверенности в наличии у пациента некоторого симптома или в том, что данные, полученные лри измерении, верны; лекарство может стать причиной осложнения, хотя обычно этого не происходит. Во всех этих случаях необходимы рассуждения с использованием вероятностного подхода.

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

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



Экспертные системы


Глава 14. ЭКСПЕРТНЫЕ СИСТЕМЫ

Экспертная система - это программа, которая ведет себя подобно эксперту в некоторой проблемной области. Она должна иметь способность к объяснению своих решений и тех рассуждений, на основе которых эти решения были приняты. Часто от экспертной системы требуют, чтобы она могла работать с неточной и неполной информацией.

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



Грубая структура экспертной системы



    Грубая структура экспертной системы

При разработке экспертной системы принято делить ее на три основных модуля, как показано на рис. 14.1:

    (1)        база знаний,
    (2)        машина логического вывода,
    (3)        интерфейс с пользователем.

База знаний содержит знания, относящиеся к конкретной прикладной области, в том числе отдельные факты, правила, описывающие отношения или явления, а также, возможно, методы, эвристики и различные идеи, относящиеся к решению задач в этой прикладной области. Машина логического вывода умеет активно использовать информацию, содержащуюся в базе знаний. Интерфейс с пользователем отвечает за бесперебойный обмен информацией между пользователем и системой; он также дает пользователю возможность наблюдать за процессом решения задач, протекающим в машине логического вывода. Принято рассматривать машину вывода и интерфейс как один крупный модуль, обычно называемый оболочкой экспертной системы, или, для краткости, просто оболочкой.

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



Литература



Литература

Книга Michie (1979) - это сборник статей, относящихся к различным аспектам экспертных систем и инженерии знаний. Две ранние экспертные системы, оказавшие большое влияние на развитие этой области, MYCIN и Prospector, описаны в Shortliffe (1976) и Duda et al (1979). Книга Buchanan and Shortliffe (1984) является хорошим сборником статей, посвященных результатам экспериментов с системой MYCIN. Weiss and Kulikowski (1984) описывают свой практический опыт разработки экспертных систем. Вопрос о работе в условиях неопределенности еще нельзя считать вполне решенным: в статье Quinlan (1983) сравниваются различные подходы к этой проблеме. Способ разработки нашей экспертной системы до некоторой степени аналогичен описанному в Hammond (1984). Некоторые примеры, использовавшиеся в тексте, заимствованы из Winston (1984), Shortliffe (1976), Duda et al (1979), Bratko (1982) и Reiter (1980).

Bratko I. (1982). Knowledge-based problem-solving in AL3. In: Machine Intelligence 10 (J.E. Hayes, D. Michie, Y.H. Pao, eds.). Ellis Horwood.

Buchanan B.G. and Shortliffe E.H. (1984, eds.). Rule-based Expert Systems: The МYСIN Experiments of the Stanford Heuristic Programming Project. Addison-Wesley.

Duda R., Gasschnig J. and Hart P. (1979). Model design in the Prospector consultant system for mineral exploration. In: Expert Systems in the Microelectronic Age (D. Michie, ed.). Edinburgh University Press.

Hammond P. (1984). vMicro-PROLOG for Expert Systems. In: Micro-PROLOG: Programming in Logic (K.L. Clark, F.G. McCabe, eds.). Prentice-Hall.

Michie D. (1979, ed.). Expert Systems in the Microelectronic Age. Edinburgh University Press.

Quinlan J.R. (1983). Inferno: a cautious approach to uncertain reasoning. The Computer Journal 26: 255-270.

Reiter J. (1980). AL/X: An Expert System Using Plausible Inference. Oxford: Intelligent Terminals Ltd.

Shortliffe E. (1976). Computer-based Medical Consultations: MYCIN. Elsevier.

Weiss S.M. and Kulikowski CA. (1984). A Practical Guide to Designing Expert Systems. Chapman and Hall.

Winston P. H. (1984). Artificial Intelligence (second edition). Addison-Wesley. [Имеется перевод первого издания: Уинстон П. Искусственный интеллект. - М.: Мир, 1980.]



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



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


        рассмотреть( не Цель, Трасса, Ответ) :-  !,
                рассмотреть( Цель, Трасса, Ответ1),
                обратить( Ответ1, Ответ).
                                % Получить обратное истинностное значение

        обратить( Цель это правда было Найдено,
                          ( не Цель) это ложь было Найдено).

        обратить( Цель это ложь было Найдено,
                          ( не Цель) это правда было Найдено).

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

        ?-  эксперт.

        Пожалуйста, спрашивайте:
        не ( X ест мясо).

        Есть (еще) решения для   :  Животное
        да.
        Животное = тигр.

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

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

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

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

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

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

    Итак,

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

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

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

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

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

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

Для того, чтобы рассмотреть (не Цель), рассмотрите Цель, а затем: если Цель это ложь, то (не Цель) это правда; если Цель' - это некоторое решение для Цель, и Цель' - утверждение той же степени общности, что и Цель, то (не Цель) это ложь; если Цель' - это некоторое решение для Цель, и Цель' - более конкретное утверждение, чем Цель, то об утверждении (не Цель) нельзя сказать ничего определенного.

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

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

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

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

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

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

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



Оболочка экспертной системы: отображение окончательного результата и



  Оболочка экспертной системы:
Отображение окончательного результата и

объяснение типа "как".

        ?-  эксперт.

        Пожалуйста, спрашивайте:    % Приглашение пользователю

        X это животное и голиаф это Х.    % Вопрос пользователя

        Это правда:  голиаф имеет шерсть?

        . . .

    Одно замечание по поводу программы-оболочки
6.    Одно замечание по поводу программы-оболочки

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

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

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

line();

% Процедура-драйвер верхнего уровня

        эксперт :-
                принять_вопрос( Вопрос),
                                            % Ввести вопрос пользователя
                ( ответ_да( Вопрос);
                                            % Попытка найти положительный ответ
                ответ_нет( Вопрос) ).
            % Если нет положительного ответа, то найти отрицательный

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

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

        статус( положительный) :-
                retract( пока_нет_положительного_решения),  !;  true.

        принять_вопрос( Вопрос) :-
                nl, write( 'Пожалуйста, спрашивайте:'), nl,
                read( Вопрос).

line();



Оболочка экспертной системы: вопросы к пользователю и ответы на вопросы "почему".



  Оболочка экспертной системы: Вопросы к пользователю
и ответы на вопросы "почему".

        нумпер( Терм, N, М) :-
                Терм =.. [Функтор | Аргументы],             % Структура или атом
                нумарг( Аргументы, N, M).
                                        % Пронумеровать переменные в аргументах
        нумарг( [ ], N, N) :-  !.

        нумарг( [X | Спис], N, M) :-
                нумпер( X, N, N1),
                нумарг( Спис, N1, М).

    Процедура     выдать
4.    Процедура     выдать

Процедура

        выдать( Ответ)

приведенная на рис. 14.12, показывает пользователю окончательный результат консультационного сеанса и дает объяснения типа "как". Ответ включает в себя как ответ на вопрос пользователя, так и дерево вывода, демонстрирующее как система пришла к такому заключению. Сначала процедура выдать представляет пользователю свое заключение. Затем, если пользователь пожелает узнать, как это заключение достигнуто, то печатается дерево вывода в некоторой удобной для восприятия форме - это и есть объяснение типа "как". Форма объяснения показана в примере разд. 14.4.3.

    Драйвер верхнего уровня
5.    Драйвер верхнего уровня

И наконец, для того, чтобы иметь удобный доступ к оболочке из интерпретатора Пролога, нам необходима процедура, выполняющая функцию "драйвера". На рис. 14.13 показано, как могла бы выглядеть предназначенная для этой цели процедура эксперт. Драйвер эксперт производит запуск трех основных модулей оболочки (рис. 14.10 - 14.12) и координирует их работу. Например:

line();

% Выдача заключения консультационного сеанса и
% объяснения типа "как"

        выдать( Ответ) :-
                nl, заключение( Ответ),
                nl, write( 'Хотите узнать, как?'),
                принять( Ответ1),
                ( Ответ1 = да,  !,  отобр( Ответ);
                    true).                                                  % Показ решающего дерева

        заключение( Ответ1 и Ответ2) :-  !,
                заключение( Ответ1), write( 'и'),
                заключение( Ответ2).

        заключение( Заключение было Найдено) :-
                write( Заключение).

% "отобр" отображает полное решающее дерево

        отобр( Решение) :-
                nl, отобр( Решение, 0),  !.                            % Отступ 0

        отобр( Ответ1 и Ответ2, Н) :-  !,                      % Отступ Н
                отобр( Ответ1, Н),
                tab( H), write( 'и'), nl,
                отобр( Ответ2, Н).

        отобр( Ответ был Найден, Н) :-                      % Отступ Н
                tab( H), печответ( Ответ),             % Показ заключения
                nl, tab( H),
                write( 'было'),
                отобр1( Найден, Н).                         % Показ доказательства

        отобр1( Выведено из Ответ, Н) :-  !,
                write( Выведено), write( 'из'),        % Показ имени правила
                nl, H1 is H + 4,
                отобр( Ответ, H1).                           % Показ "предшественника"

        отобр1( Найдено, _ ) :-
                                    % Найдено = 'сказано' или 'найдено как факт'
                write( Найдено), nl.

        печответ( Цель это правда) :-  !,
                write( Цель).            % На выходе 'это правда' опускается

        печответ( Ответ) :-                                % Отрицательный ответ
                write( Ответ).

line();



Объяснение типа "почему". На вопрос "почему вас интересует



  Объяснение типа "почему". На вопрос "Почему вас интересует


текущая цель?" дается объяснение в виде цепочки правил и целей,
соединяющей текущую цель с исходным вопросом пользователя,
находящимся в верхушке дерева. Эта цепочка называется трассой.

Будем называть такую цепочку трассой. Трассу можно себе представлять как цепочку правил, соединяющую в И / ИЛИ-дереве вопросов текущую цель с целью самого верхнего уровня так, как это показано на рис. 14.8. Таким образом, для формирования ответа на вопрос "почему" нужно двигаться в пространстве поиска от текущей цели вверх вплоть до самой верхней цели. Для того, чтобы суметь это сделать, нам придется в процессе рассуждений сохранять трассу в явном виде.

    Формирование ответа на вопрос "как"
3.    Формирование ответа на вопрос "как"

Получив ответ на свой вопрос, пользователь возможно захочет увидеть, как система пришла к такому заключению. Один из подходящих способов ответить на вопрос "как" - это представить доказательство, т. е. те правила и подцели, которые использовались для достижения полученного заключения. Это доказательство в случае нашего языка записи правил имеет вид решающего И / ИЛИ-дерева. Поэтому наша машина логического вывода будет не просто отвечать на вопрос, соответствующий цели самого верхнего уровня - этого нам недостаточно, а будет выдавать в качестве ответа решающее И / ИЛИ-дерево, составленное из имен правил и подцелей. Затем это дерево можно будет отобразить на выходе системы в качестве объяснения типа "как". Объяснению можно придать удобную для восприятия форму, если каждое поддерево печатать с надлежащим отступом, например:

        питер это хищник
            было выведено по прав3 из
                питер это млекопитающее
                    было выведено по прав1 из
                        питер имеет шерсть
                            было сказано
                и
                питер ест мясо
                    было сказано



Определение степени правдоподобия гипотезы при помощи



  Определение степени правдоподобия гипотезы при помощи


распространения информации об оценке уверенности по сети вывода.









Основная процедура оболочки экспертной системы.



  Основная процедура оболочки экспертной системы.

    Процедура    ответпольз
2.    Процедура    ответпольз

Прежде чем перейти к написанию процедуры ответпольз, давайте рассмотрим одну полезную вспомогательную процедуру

        принять( Ответ)

В процессе диалога часто возникает ситуация, когда от пользователя ожидается ответ "да", "нет" или "почему". Процедура принять предназначена для того, чтобы извлечь один из этих ответов, понимая его правильно и в тех случаях, когда пользователь применяет сокращения ('д' или 'н') или делает ошибки. Если ответ пользователя непонятен, то принять просит дать другой вариант ответа.

        принять( Ответ) :-
                read( Ответ1),
                означает( Ответ1, Значение),  !,
                                                            % Ответ1 означает что-нибудь?
                Ответ = Значение;         % Да
                nl, write( 'Непонятно, попробуйте еще раз,      % Нет
                                                        пожалуйста'),   nl,
                принять( Ответ).           % Новая попытка

        означает( да, да).
        означает( д, да).
        означает( нет, нет).
        означает( н, нет).
        означает( почему, почему).
        означает( п, почему).

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

        принять( да), интерп_да( ...);
        принять( нет), интерп_нет( ...);
        . . .

Здесь, если пользователь ответит "нет", то программа попросит его повторить свой ответ. Поэтому более правильный способ такой:

        принять( Ответ),
        ( Ответ = да, интерп_да( ...);
          Ответ = нет, интерп_нет( ...);
          ... )

        Процедура

        ответпольз( Цель, Трасса, Ответ)

спрашивает пользователя об истинности утверждения Цель. Ответ - это результат запроса. Трасса используется для объяснения в случае, если пользователь спросит "почему".

Сначала процедура ответпольз должна проверить, является ли Цель информацией, которую можно запрашивать у пользователя. Это свойство объекта Цель задается отношением

        можно_спросить( Цель)

которое в дальнейшем будет усовершенствовано. Если спросить можно, то утверждение Цель выдается пользователю, который, в свою очередь, указывает истинно оно или ложно. Если пользователь спросит "почему", то ему выдается Трасса. Если утверждение Цель истинно, то пользователь укажет также значения содержащихся в нем переменных (если таковые имеются).

Все вышеизложенное можно запрограммировать (в качестве первой попытки) следующим образом:

        остветпольз( Цель, Трасса, Ответ) :-
                можно_спросить( Цель),            % Можно ли спрашивать
                спросить( Цель, Трасса, Ответ).
                            % Задать вопрос относительно утверждения Цель

        спросить( Цель, Трасса, Ответ) :-
                показать( Цель),
                            % Показать пользователю вопрос
                принять(Ответ1),                        % Прочесть ответ
                обработать( Ответ1, Цель, Трасса, Ответ).
                            % Обработать ответ

        обработать( почему, Цель, Трасса, Ответ) :-
                            % Задан вопрос "почему"
                показать_трассу( Трасса),
                            % Выдача ответа на вопрос "почему"
                спросить( Цель, Трасса, Ответ).
                            % Еще раз спросить

        обработать( да, Цель, Трасса, Ответ) :-
                            % Пользователь ответил, что Цель истинна
                Ответ = правда,
                запрос_перем( Цель);
                            % Вопрос о значении переменных
                спросить( Цель, Трасса, Ответ).
                            % Потребовать от пользователя новых решений

        обработать( нет, Цель, Трасса, ложь).
                            % Пользователь ответил, что Цель ложна

        показать( Цель) :-
                nl, write( 'Это правда:'),
                write( Цель), write( ?), nl.

Обращение к процедуре запрос_перем( Цель) нужно для того, чтобы попросить пользователя указать значение каждой из переменных, содержащихся в утверждении Цель:

        запрос_перем( Терм) :-
                var( Терм),  !,                  % Переменная ?
                nl, write( Терм), write( '='),
                read( Терм).                    % Считать значение переменной

        запрос_перем( Терм) :-
                Терм =.. [Функтор | Аргументы],
                                % Получить аргументы структуры
        запрос_арг( Аргументы).
                                % Запросить значения переменных в аргументах

        запрос_арг( [ ]).

        запрос_арг( [Терм | Термы]) :-
                запрос_перем( Терм),
                запрос_арг( Термы).

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

        можно_спросить( X ест Y).

(В приведенных ниже диалогах между пролог-системой и пользователем тексты пользователя даются полужирным шрифтом, а реплики пролог-системы курсивом).

        ?-  ответпольз( питер ест мясо, [ ], Ответ).

            Это правда: питер ест мясо?          % Вопрос пользователю
            да.                                                         % Ответ пользователя

            Ответ = правда

Более интересный пример диалога (с использованием переменных) мог бы выглядеть примерно так:

        ?-  ответпольз( Кто ест Что, [ ], Ответ).

        Это правда: _17 ест _18?
                                % Пролог дает переменным свои внутренние имена
        да.
        _17 = питер.
        _18 = мясо.

        Ответ = правда.
        Кто = питер
        Что = мясо;         % Возврат для получения других решений

        Это правда: _17 ест _18?
        да.
        _17 = сьюзен.
        _18 = бананы.

        Ответ = правда
        Кто = сьюзен
        Что = бананы;

        Это правда : _17 ест _18?
        нет.

        Ответ = ложь

    Усовершенствование процедуры    ответпольз
3.    Усовершенствование процедуры    ответпольз

Один из недостатков нашей процедуры ответпольз, который хорошо виден из приведенного выше диалога, - это появление на выходе системы имен, генерируемых пролог-системой, что выглядит довольно неуклюже. Символы, подобные _17, следовало бы заменить на более осмысленные слова.

Другой, более серьезный дефект этой версии процедуры ответпольз состоит в следующем. Если мы еще раз обратимся к ответпольз, задав ту же самую цель, то пользователю придется повторно вводить все варианты решений. Поэтому, если наша экспертная система придет в процессе рассуждений к рассмотрению той же самой цели второй раз, то, вместо того, чтобы использовать информацию, уже полученную от пользователя, она проведет с пользователем в точности тот же самый скучный диалог.

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

        можно_спросить(Х ест Y, 'Животное' ест 'Что-то').

При передаче запроса пользователю каждая переменная вопроса должна быть заменена на ключевое слово, взятое из формата, например:

        ?-  ответпольз( X ест Y, [ ], Ответ).

        Это правда:   Животное ест Что-то?
        да.

        Животное = питер.
        Что-то = мясо.

        Ответ = правда
        X = питер
        Y = мясо

В улучшенной версии процедуры ответпольз, показанной на рис. 14.11, такое форматирование запросов выполняется процедурой

        формат( Цель, ВнешФормат, Вопрос, Перем0, Перем )

Здесь Цель - утверждение, которое нужно форматировать. ВнешФормат определяет внешний формат этого утверждения, задаваемый отношением

        можно_спросить( Цель, ВнешФормат)

Вопрос - это Цель, отформатированная в соответствии с ВнешФормат. Перем - список переменных, входящих в Цель, вместе с соответствующими ключевыми словами (как указано в ВнешФормат), причем список Перем получается из списка Перем0 добавлением новых переменных. Например:

        ?-  формат( X передает документы Y,
                            'Кто' передает 'Что' 'Кому',
                            Вопрос, [ ], Перем).

        Вопрос = 'Кто' передает документы 'Кому',
        Перем = [ Х/'Кто', Y/'Кому'].

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

        assert( сказано( мери передает документы друзьям, правда) ).

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

        ( X имеет Y) и                             % Первый вариант - Цель1
        . . .

        ( X1 имеет Y1) и                         % Второй вариант - Цель2
        . . .

Допустим также, что пользователя просят (через механизм возвратов) предложить несколько решений для Цель1. Затем процесс рассуждений продвигается вплоть до Цель2. Так как у нас уже есть несколько решений для Цель1, мы захотим, чтобы система автоматически применила их и к Цель2 (поскольку очевидно, что они удовлетворяют Цель2). Теперь предположим, что система пытается применить эти решения к Цель2, но ни одно из них не удовлетворяет некоторой другой цели, расположенной ниже. Система делает возврат к Цель2 и просит пользователя предложить новые решения. Если пользователь введет еще несколько решений, то их также придется запомнить. И если система в дальнейшем сделает возврат к Цель1, то эти новые решения надо будет применить к Цель1.

Для того, чтобы правильным образом использовать информацию, вводимую пользователем по запросам из разных точек программы, мы будем снабжать каждую такую информацию специальным индексом. Таким образом, факты, запоминаемые системой, будут иметь вид

        сказано( Цель, Истинность, Индекс)

где Индекс - это значение счетчика, ответов пользователя. Процедура

        ответпольз( Цель, Трасса, Ответ)

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

        ответпольз( Цель, Трасса, Ответ, N)

где N - некоторое целое число. Такое обращение к ответпольз должно порождать решения для Цель с индексами, начиная с N и далее. Обращение

        ответпольз( Цель, Трасса, Ответ)

соответствует получению всех решений, индексируемых, начиная с 1, поэтому мы имеем следующее соотношение:

        ответпольз( Цель, Трасса, Ответ) :-
                ответпольз( Цель, Трасса, Ответ, 1).

Принцип работы процедуры

        ответпольз( Цель, Трасса, Ответ, N)

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

        конец_ответов( Цель)

Если пользователь с самого начала скажет, что решений нет вообще, то записать факт

        сказано( Цель, ложь, Индекс)

Находя в памяти те или иные решения, процедура ответпольз должна правильно интерпретировать подобную информацию.

Однако существует еще одна трудность. Пользователь может, оставляя некоторые переменные неконкретизированными, указывать общие решения. Если найдено положительное решение, более общее, чем Цель, или столь же общее, как Цель, то нет смысла продолжать задавать вопросы об утверждении Цель, поскольку мы уже имеем более общее решение. Аналогичным образом следует поступить, если обнаружен факт

        сказано( Цель, ложь, _ )

Программа ответпольз, показанная на рис. 14.11, учитывает все вышеприведенные соображения. В нее введен новый аргумент Копия (копия утверждения Цель), который используется в нескольких случаях сопоставлений вместо Цель, с тем чтобы оставить в неприкосновенности переменные утверждения Цель. Эта программа использует также два вспомогательных отношения. Одно из них

        конкретный( Терм)

истинно, если Терм не содержит переменных. Другое

        конкретизация( Терм, Терм1)

означает, что Терм1 есть некоторая конкретизация (частный случай) терма Терм, т. е. Терм - это утверждение не менее общее, чем Терм1. Например:

        конкретизация( X передает информацию Y,
                                    мэри передает информацию Z)

Обе процедуры основаны на еще одной процедуре:

        нумпер( Терм, N, М)

Эта процедура "нумерует" переменные, содержащиеся в Терм, заменяя каждую из них на некоторый специальный новый терм таким образом, чтобы эти "нумерующие" термы соответствовали числам от N до М-1, Например, пусть эти термы имеют вид

        пер/0, пер/1, пер/2, ...

тогда в результате обращения к системе

        ?-  Терм - f( X, t( a,Y, X) ), нумпер( Терм, 5, М).

мы получим

        Терм = f( пер/5, t( а, пер/6, пер/5) )
        М = 7

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

        нумпер( Терм, N, Nплюс1) :-
                var( Терм),  !,                                 % Переменная ?
                Терм = пер/N,
                Nплюс1 is N + 1.

line();

% Процедура
%
% ответпольз( Цель, Трасса, Ответ)
%
% порождает, используя механизм возвратов, все решения
% для целевого утверждения Цель, которые указал пользователь.
% Трасса - это цепочка целей-предков и правил,
% используемая для объяснения типа "почему".

        ответпольз( Цель, Трасса, Ответ) :-
                можно_спросить( Цель, _ ),                % Можно спросить ?
                копия( Цель, Копия),                           % Переименование переменных
                ответпольз( Цель, Копия, Трасса, Ответ, 1).

% Не спрашивать второй раз относительно конкретизированной цели

        ответпольз( Цель, _, _, _, N) :-
                N > 1,                                                       % Повторный вопрос?
                конкретный( Цель),  !,                         % Больше не спрашивать
                fail.

% Известен ли ответ для всех конкретизации утверждения Цель?

        ответпольз( Цель, Копия, _, Ответ, _ ) :-
                сказано( Копия, Ответ, _ ),
                конкретизация( Копия, Цель),  !.       % Ответ известен

% Найти все известные решения для Цель с индексами, начиная с N

        ответпольз( Цель, _, _, правда, N) :-
                сказано( Цель, правда, М),
                М >= N.

% Все уже сказано об утверждении Цель?

        ответпольз( Цель, Копия, _, Ответ, _) :-
                конец_ответов( Копия),
                конкретизация( Копия, Цель),  !,      % Уже все сказано
                fail.

% Попросить пользователя дать (еще) решения

        ответпольз( Цель, _, Трасса, Ответ, N) :-
                спросить_польз( Цель, Трасса, Ответ, N).

        спросить_польз( Цель, Трасса, Ответ, N) :-
                можно спросить( Цель, ВнешФормат),
                формат( Цель, ВнешФормат, Вопрос, [ ], Перем),
                                                                     % Получить формат вопроса
                спросить( Цель, Вопрос, Перем, Трасса, Ответ, N).

        спросить( Цель, Вопрос, Перем, Трасса, Ответ, N) :-
                nl,
                ( Перем = [ ],  !,                       % Сформулировать вопрос
                write( 'Это правда: ');
                write( 'Есть (еще) решения для :' )),
                write( Вопрос), write( '?'),
                принять( Ответ1),  !,              % Ответ1 - да/нет/почему
                обработать( Ответ1, Цель, Вопрос, Перем,
                                                                                Трасса, Ответ, N).

        обработать( почему, Цель, Вопрос, Перем,
                                                                                Трасса, Ответ, N):-
                 выд_трассу( Трасса),
                 спросить( Цель, Вопрос, Перем, Трасса, Ответ, N).

        обработать( да, Цель,_, Перем, Трасса, правда, N) :-
                след_индекс( Инд),
                                        % Получить новый индекс для "сказано"
                Инд1 is Инд + 1,
                ( запрос_перем( Перем),
                assertz( сказано( Цель, правда, Инд) );
                                                                  % Запись решения
                копия( Цель, Копия),            % Копирование цели
                ответпольз( Цель, Копия, Трасса, Ответ, Инд1) ).
                                                                  % Есть еще решения?

        обработать( нет, Цель, _, _, _, ложь, N) :-
                копия( Цель, Копия),
                сказано( Копия, правда, _),  !,
                                        % 'нет' означает, больше нет решений
                assertz( конец_ответов( Цель) ),
                                        % Отметить конец ответов
                fail;
                след_индекс( Инд),
                                        % Следующий свободный индекс для "сказано"
                assertz( сказано( Цель, ложь, Инд) ).
                                        % 'нет' означает нет ни одного решения

        формат( Пер, Имя, Имя, Перем, [Пер/Имя | Перем]) :-
                var( Пер),  !.
        формат( Атом, Имя, Атом, Перем, Перем) :-
                atomic( Атом),  !,
                atomic( Имя).
        формат( Цель, Форм, Вопрос, Перем0, Перем) :-
                Цель =.. [Функтор | Apг1],
                Форм =.. [Функтор | Форм1],
                формвсе( Apг1, Форм1, Арг2, Перем0, Перем),
                Вопрос =.. [Функтор | Арг2].

        формвсе( [ ], [ ], [ ], Перем, Перем).

        формвсе( [Х | СпХ], [Ф | СпФ], [В | СпВ], Перем0, Перем) :-
                формвсе( СпХ, СпФ, СпВ, Перем0, Перем1),
                формат( X, Ф, В, Перем1, Перем).

        запрос_перем( [ ]).

        запрос_перем( [Переменная/Имя | Переменные]) :-
                nl, write( Имя), write( '='),
                read( Переменная),
                запрос_перем( Переменные).

        выд_трассу( [ ]) :-
                nl, write( 'Это был ваш вопрос'), nl.

        выд_трассу( [Цель по Прав | Трасса] ) :-
                nl, write( 'Чтобы проверить по' ),
                write( Прав), write( ', что'),
                write( Цель),
                выд_трассу( Трасса).

        конкретный( Терм) :-
                нумпер( Терм, 0, 0).                % Нет переменных в Терм'е

% конкретизация( Т1, Т2) означает, что Т2 - конкретизация Т1,
% т.е. терм Т1 - более общий, чем Т2, или той же степени
% общности, что и Т2

        конкретизация( Терм, Терм1) :-
                                        % Терм1 - частный случай Терм 'а
                копия( Терм1, Терм2),
                                        % Копия Терм1 с новыми переменными
                нумпер( Терм2, 0, _),  !,
                Терм = Терм2.            % Успех, если Терм1 - частный случай Терм2

        копия( Терм, НовТерм) :-
                                        % Копия Терм' а с новыми переменными
                asserta( copy( Терм) ),
                retract( сору( НовТерм) ),  !.

        посл_индекс( 0).                 % Начальный индекс для "сказано"

        след_индекс( Инд) :-         % Следующий индекс для "сказано"
                retract( посл_индекс( ПослИнд) ),  !,
                Инд is ПослИнд + 1,
                assert( посл_индекс( Инд) ).

line();



Отношение рассмотреть( цель, трасса, ответ). Ответ - это и / или решающее дерево для целевого



  Отношение рассмотреть( Цель,  Трасса,  Ответ).
Ответ - это И / ИЛИ решающее дерево для целевого

Цель.

Основными процедурами оболочки будут:

        рассмотреть( Цель, Трасса, Ответ)

Эта процедура находит ответ Ответ на вопрос Цель. Процедура

        ответпольз( Цель, Трасса, Ответ)

порождает решения для тех вопросов Цель, которые можно задавать пользователю. Она спрашивает пользователя об истинности утверждения Цель, а также отвечает на вопросы "почему". Процедура

        выдать( Ответ)

выводит результат и отвечает на вопросы "как". Все эти процедуры приводятся в действие процедурой-драйвером эксперт.

    Процедура     рассмотреть
1.    Процедура     рассмотреть

Центральной процедурой оболочки является процедура

        рассмотреть( Цель, Трасса, Ответ)

которая будет находить ответ Ответ на заданный вопрос Цель, используя принципы, намеченные в общих чертах в разд. 14.4.1: найти Цель среди фактов базы знаний, или применить правило из базы знаний, или спросить пользователя, или же обработать Цель как И / ИЛИ-комбинацию подцелей.

Аргументы имеют следующий смысл и следующую структуру:

Цель              вопрос, подлежащий рассмотрению, представленный
                       как И / ИЛИ-комбинация простых утверждений, например

                       X имеет перья или X летает или
                       X откладывает яйца

Трасса        цепочка, составленная из целей-предков и правил,
                    расположенных между Цель и исходной целью самого верхнего уровня. Представляется как список, состоящий из элементов вида

                       Цель  по  Прав

что означает:  Цель рассматривалась с использованием правила  Прав. Например, пусть исходной целью будет "питер это тигр", а текущей целью - "питер ест мясо". В соответствии с базой знаний рис. 14.5 имеем трассу

                      [( питер это хищник) по прав3,
                        ( питер это тигр) по прав5 ]

Смысл ее можно выразить так:

Я могу использовать "питер ест мясо" для того, чтобы проверить по прав3, что "питер это хищник".

Далее, я могу использовать "питер это хищник" для того, чтобы проверить по прав5, что "питер это тигр".

Ответ        решающее И / ИЛИ-дерево для вопроса  Цель. Общая форма
                   представления для объекта Ответ:

                       Заключение было Найдено

где Найдено - это обоснование для результата Заключение. Следующие три примера иллюстрируют различные варианты ответов:

(1)        ( соед( радиатор, предохр1) это правда) было
                                                        'найдено как факт'
(2)        (питер ест мясо) это ложь было сказано
(3)        (питер это хищник) это правда было
                    ( 'выведено по' прав3 из
            (питер это млекопитающее) это правда было
                    ( 'выведено по' прав1 из
            (питер имеет шерсть) это правда было сказано)
            и
            (питер ест мясо) это правда было сказано )

На рис. 14.10 показана прологовская программа для процедуры рассмотреть. В этой программе реализованы принципы разд. 14.4.1 с использованием только что описанных структур данных.

line();

% Процедура
%
% рассмотреть( Цель, Трасса, Ответ)
%
% находит Ответ на вопрос Цель. Трасса - это цепочка
% целей-предков и правил. "рассмотреть" стремится найти
% положительный ответ на вопрос. Ответ "ложь" выдается
% только в том случае, когда рассмотрены все возможности,
% и все они дали результат "ложь".

        :-ор( 900, xfx, :).
        :-ор( 800, xfx, было).
        :-ор( 870, fx, если).
        :-ор( 880, xfx, то).
        :-ор( 550, xfy, или).
        :-ор( 540, xfy, и).
        :- ор( 300, fx, 'выведено по').
        :- ор( 600, xfx, из).
        :- ор( 600, xfx, по).

% В программе предполагается,что ор( 700, хfх, это), ор( 500, fx, не)

        рассмотреть( Цель, Трасса, Цель это правда
                                                было 'найдено как факт') :-
                факт : Цель.

% Предполагается, что для каждого типа цели
% существует только одно правило

        рассмотреть( Цель, Трасса,
                Цель это ПравдаЛожь
                было 'выведено по' Прав из Ответ) :-
            Прав : если Условие то Цель,
                                    % Правило, относящееся к цели
            рассмотреть( Условие, [Цель по Прав | Трасса], Ответ),
            истинность( Ответ, ПравдаЛожь).

        рассмотреть( Цель1 и Цель2, Трасса, Ответ) :-  !,
                рассмотреть( Цель1, Трасса, Ответ1),
                продолжить( Ответ1, Цель1 и Цель2, Трасса, Ответ).

        рассмотреть( Цель1 или Цель2, Трасса, Ответ) :-
                рассм_да( Цель1, Трасса, Ответ);
                                    % Положительный ответ на Цель1
                рассм_да( Цель2, Трасса, Ответ).
                                    % Положительный ответ на Цель2

        рассмотреть( Цель1 или Цель2, Трасса,
                                                                Ответ1 и Ответ2) :-  !,
                not рассм_да( Цель1, Трасса, _ ),
                not рассм_да( Цель2, Трасса, _ ),
                                    % Нет положительного ответа
                рассмотреть( Цель1, Трасса, Ответ1),
                                    % Ответ1 отрицательный
                рассмотреть( Цель2, Трасса, Ответ2).
                                    % Ответ2 отрицательный

        рассмотреть( Цель, Трасса,
                                            Цель это Ответ было сказано) :-
                ответпольз( Цель, Трасса, Ответ).        % Ответ дан пользователем
        рассм_да( Цель, Трасса, Ответ) :-
                рассмотреть( Цель, Трасса, Ответ),
                положительный( Ответ).

        продолжить( Ответ1, Цель1 и Цель2, Трасса, Ответ) :-
                положительный( Ответ1),
                рассмотреть( Цель2, Трасса, Ответ2),
                ( положительный( Ответ2), Ответ = Ответ1 и Ответ2;
                отрицательный( Ответ2), Ответ = Ответ2).

        продолжить( Ответ1, Цель1 и Цель2, _, Ответ1) :-
                отрицательный( Ответ1).

        истинность( Вопрос это ПравдаЛожь было Найдено,
                                                                            ПравдаЛожь) :-  !.

        истинность( Ответ1 и Ответ2, ПравдаЛожь) :-
                истинность( Ответ1, правда),
                истинность( Ответ2, правда),  !,
                ПравдаЛожь = правда;
                ПравдаЛожь = ложь.

        положительный( Ответ) :-
                истинность( Ответ, правда).

        отрицательный( Ответ) :-
                истинность( Ответ, ложь).

line();



Правила распространения вероятностей по сети, принятые в системах prospector и al/x: (а) "мягкая импликация"



  Правила распространения вероятностей по сети,
принятые в системах Prospector и AL/X:  (а)   "мягкая импликация"


с силой (N, S);  (b)   логические комбинации отношений.

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

        шанс = вер / ( 1 - вер)
        вер = шанс / ( 1 + шанс)

Пусть между  E  и  H   существует отношение "мягкой импликации", тогда, в соответствии с рис. 14.15,

        шанс (Н | Е) = М * шанс (H)

где множитель М  определяется априорной и апостериорной вероятностями с учетом силы ( N, S) связи между E  и H.   Предполагается, что правила Prospector'a (рис. 14.15) для вычисления вероятностей логических комбинаций событий (использующие min и max) правильно моделируют поведение человека при оценке субъективной уверенности в таких составных событиях.

    Принципы реализации
3.    Принципы реализации

Давайте сначала расширим правила языка, с тем чтобы получить возможность работать с неопределенностью. К каждому, правилу мы можем добавить "силовой модификатор", определяемый двумя неотрицательными действительными числами  S  и  N.   Вот соответствующий формат:

        Имя Правила:      если
                                              Условие
                                       то
                                              Заключение
                                       с
                                              Сила( N, S).

Примеры правил рис. 14.14 можно изобразить в этой форме так:

        прав1 :         если
                                  не давлоткр и
                                  открклап
                            то
                                  открклрано
                            с
                                  сила( 0.001, 2000).

        прав2 :         если
                                  сепзапвд
                            то
                                  давлоткр
                            с
                                  сила( 0.05, 400).

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

        рассмотреть( Цель, Трасса, Ответ)

Мы предположим, что утверждение Цель не содержит переменных (как это сделано в Prospector'e и в AL/X). Это сильно упростит дело (особенно в процедуре ответпольз). Таким образом, Цель будет логической комбинацией элементарных утверждений. Например:

        не давлоткр и открклап

Цепочку целей-предков и правил Трасса можно представить таким же способом, как это сделано в разд. 14.5. Однако форму представления объекта Ответ придется модифицировать для того, чтобы включить в нее вероятности. Цель и ее вероятность можно соединить в один терм следующим образом:

        Цель : Вероятность

Получим такой пример объекта Ответ:

        индоткр : 1 было сказано

Смысл ответа: пользователь сообщил системе, что событие индоткр произошло, и что это абсолютно достоверно.

Представление объекта Ответ требует еще одной модификации, в связи с тем, что в одно и то же событие могут вести несколько независимых связей, которые все окажут влияние на вероятность этого события - его шанс будет помножен (рис. 14.15) на все множители. В этом случае Ответ будет содержать список всех ветвей вывода заключения. Приведем пример ответа такого рода для сети рис. 14.14 (для наглядности расположенный на нескольких строках):

        давлоткр : 1 было 'выведено по'
                [ прав2 из сепзапвд : 1 было сказано,
                   прав5 из диагсеп : 1 было сказано ]

Процедура рассмотреть, выдающая ответы в такой форме, показана на рис. 14.16. Она обращается к предикату

        импликация( Р0, Р, Сила, Вер0, Вер)

соответствующему отношению "мягкой импликации" (см. рис. 14.15).  Р0  -   априорная вероятность события  Е,   а  Р  - его апостериорная вероятность. Сила - сила импликации, представленная как

        сила( N, S)

Вер0 и Вер - соответственно априорная и апостериорная вероятности гипотезы   H.

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

Наконец, несколько замечаний относительно новой версии процедуры ответпольз. Она будет проще, чем процедура рис. 14.11, так как в запросах, передаваемых пользователю, уже не будет переменных. На этот раз пользователь в качестве ответа введет некоторую вероятность (вместо "да" или "нет"). Если пользователю ничего неизвестно о событии, содержащемся в вопросе, то вероятность этого события не изменится. Пользователь может также задать вопрос "почему" и получить изображение объекта Трасса в качестве объяснения. Кроме того, следует разрешить пользователю задавать вопрос: "Какова текущая вероятность моей гипотезы?" Тогда, если он устал вводить новую информацию (или у него мало времени), он может прекратить консультационный сеанс, довольствуясь ответом системы, полученным на основании неполной информации.

line();

% Процедура
% рассмотреть( Цель, Трасса, Ответ)
%
% находит степень правдоподобия утверждения "цель это правда".
% Оценка правдоподобия содержится в объекте Ответ. Трасса - это
% цепочка целей-предшественников и правил, которую можно
% использовать в объяснении типа "почему"

        рассмотреть( Цель, Трасса, ( Цель: Вер) было
                                    'выведено по' ПравОтв) :-
                bagof( Прав: если Условие то Цель с Сила, Правила),
                                    % Все правила, относящиеся к цели
                априори( Цель, Вер0),
                                    % Априорная вероятность цели
                модиф( Вер0, Правила, Трасса, Вер, ПравОтв).
                                    % Модифицировать априорные вероятности

        рассмотреть( Цель1 и Цель2, Трасса,
                                ( Цель1 и Цель2 : Вер было 'выведено из'
                                ( Ответ1 и Ответ2) ) :-
                !,
                рассмотреть( Цель1, Трасса, Ответ1),
                рассмотреть( Цель2, Трасса, Ответ2),
                вероятность( Ответ1, В1),
                вероятность( Ответ2, В2),
                мин( В1, В2, Вер).

        рассмотреть( Цель1 или Цель2, Трасса,
                                ( Цель или Цель2:Вер) было 'выведено из'
                                ( Ответ1 и Ответ2) ) :-
                !,
                рассмотреть( Цель1, Трасса, Ответ1),
                рассмотреть( Цель2, Трасса, Ответ2),
                вероятность( Ответ1, В1),
                вероятность( Ответ2, В2),
                макс( В1, В2, Вер).

        рассмотреть( не Цель, Трасса,
                        ( не Цель:Вер) было 'выведено из' Ответ) :-
                !,
                рассмотреть( Цель, Трасса, Ответ),
                вероятность( Ответ, В),
                обратить( В, Вер).

        рассмотреть( Цель, Трасса, ( Цель: Вер) было сказано) :-
                ответпольз( Цель, Трасса, Вер).
                                    % Ответ, выведенный пользователем

% Отношение
%
% модиф( Вер0, Правила, Трасса, Вер, ПравОтв)
%
% Существует Цель с априорной вероятностью Вер0. Правила имеют
% отношение к утверждению Цель; суммарное влияние этих правил
% (точнее, их условных частей) на Вер0 приводит к тому,
% что Вер0 заменяется на апостериорную вероятность Вер;
% Трасса - список целей-предков и правил, использовавшихся
% при выводе утверждения Цель;
% ПравОтв - результаты анализа условных частей
% правил из списка Правила.

        модиф( Вер0, [ ], Трасса, Вер0, [ ]).
                                    % Нет правил - нет модификации

        модиф( Вер0,
                        [ Прав : если Усл то Цель с Сила | Правила],
                        Трасса, Вер, [Прав из Ответ | ПравОтв] ):-
                рассмотреть( Усл, [Цель по Прав | Трасса], Ответ),
                                    % Условие из первого правила
                априори( Усл, В0),
                вероятность( Ответ, В),
                импликация( В0, В, Сила, Вер0, Вер1),
                                    % "Мягкая" импликация
                модиф( Вер1, Правила, Трасса, Вер, ПравОтв).

line();



Правила типа "если-то" для представления знаний



    Правила типа "если-то" для представления знаний

В качестве кандидата на использование в экспертной системе можно рассматривать, в принципе, любой непротиворечивый формализм, в рамках которого можно описывать знания о некоторой проблемной области. Однако самым популярным формальным языком представления знаний является язык правил типа "если-то" (или кратко: "если-то"-правил), называемых также продукциями. Каждое такое правило есть, вообще говоря, некоторое условное утверждение, но возможны и различные другие интерпретации. Вот примеры: если  предварительное условие  Р то   заключение (вывод)  С если  ситуация  S  то   действие  А если  выполнены условия  С1  и  С2   то не выполнено условие  С

"Если-то"-правила обычно оказываются весьма естественным выразительным средством представления знаний. Кроме того, они обладают следующими привлекательными свойствами: Модульность:   каждое правило описывает небольшой, относительно независимый фрагмент знаний. Возможность инкрементного наращивания:    добавление новых правил в базу знаний происходит относительно независимо от других правил. Удобство модификации (как следствие модульности):   старые правила можно изменять и заменять на новые относительно независимо от других правил. Применение правил способствует прозрачности системы.

Последнее свойство - это важное, отличительное свойство экспертных систем. Под прозрачностью мы понимаем способность системы к объяснению принятых решений и полученных результатов. Применение "если-то"-правил облегчает получение ответов на следующие основные типы вопросов пользователя:

    (1)        Вопросы типа "как":   Как вы пришли к этому выводу?

    (2)        Вопросы типа "почему":   Почему вас интересует эта информация?

Механизмы, основанные на "если-то"-правилах, для формирования ответов на подобные вопросы мы обсудим позже.

line();

если
    1        тип инфекции - это первичная бактериемия и
    2        материал для посева был отобран стерильно, и
    3         предполагаемые ворота инфекции - желудочно- кишечный тракт

то
            имеются веские аргументы  (0.7)  за то,
            что инфекционный агент является бактерией

line();



это набор простых утверждений, соединенных



  Правило уточнения плана из системы  AL3

для решения шахматных задач  (Bratko  1982).

Условие - это набор простых утверждений, соединенных между собой операторами  и  и  или.   Мы также разрешим в части условия использовать оператор  не,  хотя и с некоторыми оговорками. При надлежащем прологовском определении этих операторов (как это сделано на рис. 14.5) правила станут синтаксически верными предложениями Пролога. Заметим, что оператор  и  связывает операнды сильнее, чем  или,  что соответствует обычным соглашениям.

line(); % Небольшая база знаний для идентификации животных

:- ор( 100, xfx, [имеет, 'кормит детенышей',
                                'не может', ест, откладывает, это]).

:- ор( 100, xf, [плавает, летает, хорошо]).

прав1:        если
                        Животное имеет шерсть
                        или
                        Животное 'кормит детенышей' молоком
                   то
                        Животное это млекопитающее.
прав2:        если
                        Животное имеет перья
                        или
                        Животное летает и
                        Животное откладывает яйца
                   то
                        Животное это птица.
прав3:        если
                        Животное это млекопитающее и
                        ( Животное ест мясо
                        или
                        Животное имеет 'острые зубы' и
                        Животное имеет когти и
                        Животное имеет
                            'глаза, направленные вперед' )
                   то
                        Животное это хищник.
прав4:        если
                        Животное это хищник и
                        Животное имеет
                                'рыжевато-коричневый цвет' и
                        Животное имеет 'темные пятна'
                   то
                        Животное это гепард.
прав5:        если
                        Животное это хищник и
                        Животное имеет
                                'рыжевато-коричневый цвет' и
                        Животное имеет 'черные полосы'
                   то
                        Животное это тигр,
прав6:        если
                        Животное это птица и
                        Животное 'не может' летать и
                        Животное плавает
                   то
                        Животное это пингвин,
прав7:        если
                        Животное это птица и
                        Животное летает хорошо
                   то
                        Животное это альбатрос.

факт:  X это животное :-
        принадлежит( X, [гепард, тигр, пингвин, альбатрос]).

можно_спросить( _ 'кормит детенышей'_,
        'Животное' 'кормит детенышей' 'Чем').

можно_спросить( _ летает, 'Животное' летает).

можно_спросить( _ откладывает яйца,
        'Животное' откладывает яйца).

можно_спросить( _ ест _, 'Животное' ест 'Что').

можно_спросить( _ имеет _,'Животное' имеет 'Нечто').

можно_спросить( _ 'не может' _,
        'Животное' 'не может' 'Что делать').

можно_спросить( _ плавает, 'Животное' плавает).

можно_спросить( _ летает хорошо,
        'Животное' летает хорошо).

line();

Проекты



Проекты

Завершите программирование нашей оболочки в части, касающейся неопределенной информации (процедура ответпольз и другие).

Рассмотрите перечисленные выше критические замечания, а также возможные расширения нашей экспертной системы. Разработайте и реализуйте соответствующие усовершенствования.



Простая база знаний для идентификации...



  Простая база знаний для идентификации животных.
Заимствовано из Winston (1984). Отношение "можно_спросить"
определяет вопросы, которые можно задавать пользователю.
Операторы  еслитои,   или  определены на рис. 14.10.

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

        если
                лампа1 включена  и
                лампа1 не работает  и
                предохранитель1 заведомо цел
        то
                лампа1 заведомо неисправна.

Вот другой пример правила:

        если
                радиатор работает
        то
                предохранитель1 заведомо цел.

Эти два правила опираются на некоторые факты (относящиеся к нашей конкретной схеме), а именно что лампа1 соединена с предохранитель1 и что лампа1 и радиатор имеют общий предохранитель. Для другой схемы нам понадобится еще один набор правил. Поэтому было бы лучше сформулировать правила в более общем виде (используя прологовские переменные) так, чтобы они были применимы к любой схеме, а затем уже дополнять их информацией о конкретной схеме. Например, вот одно из полезных правил: если прибор включен, но не работает, а соответствующий предохранитель цел, то прибор неисправен. На наш



"если-то"-правило медицинской...



  "Если-то"-правило медицинской консультативной системы
MYCIN (Shortliffe, 1976). Параметр  0.7  показывает степень доверия
этому правилу.

"Если-то"-правила часто применяют для определения логических отношений между понятиями предметной области. Про чисто логические отношения можно сказать, что они принадлежат к "категорическим знаниям", "категорическим" - потому, что соответствующие утверждения всегда, абсолютно верны. Однако в некоторых предметных областях, таких, как медицинская диагностика, преобладают "мягкие" или вероятностные знания. Эти знания являются "мягкими"; в том смысле, что говорить об их применимости к любым практическим ситуациям можно только до некоторой степени ("часто, но не всегда"). В таких случаях используют модифицированные "если-то"-правила, дополняя их логическую интерпретацию вероятностной оценкой. Например:

        если     условие    А    то     заключение    В    с уверенностью    F

Рис.  14.2,  14.3  и  14.4  дают представление о разнообразии способов, которыми знания могут быть выражены при помощи "если-то"-правил. На этих рисунках приведены примеры правил из трех различных систем, основанных на знаниях: медицинской консультативной системы MYCIN, системы AL/X для диагностики неисправностей в оборудовании и системы AL3 для решения шахматных задач.

Вообще говоря, если вы хотите разработать серьезную экспертную систему для некоторой выбранной вами предметной области, вы должны провести консультации с экспертами в этой области и многое узнать о ней сами. Достигнуть определенного понимания предметной области после общения с экспертами и чтения литературы, а затем облечь это понимание в форму представления знаний в рамках выбранного формального языка - это искусство, называемое инженерией знаний. Как правило, это сложная задача, требующая больших усилий, чего мы не можем себе позволить в данной книге. Но какая-нибудь предметная область и какая-нибудь база данных нам необходимы в качестве материала для экспериментов. С практической точки зрения нам для этой цели вполне подойдет "игрушечная" база знаний. На рис. 14.5 показана часть такой базы знаний. Она состоит из простых правил, помогающих идентифицировать животных по их основным признаками в предположении, что задача идентификации ограничена только небольшим числом разных животных.

Правила, содержащиеся в базе знаний, имеют вид

        ИмяПравила  :   если  Условие  то  Заключение

где    Заключение    -     это простое утверждение, а

line();

если
        давление в v-01 достигло уровня открытия
        выпускного клапана
то
        выпускной клапан в v-01 открылся
        [N=0.005, S=400]
если
        давление в v-01 не достигло уровня открытия
        выпускного клапана и выпускной клапан в v-01
        открылся
то
        преждевременное открытие выпускного клапана
        (сместилась установка порогового давления)
        [N=0.001, S=2000]

line();



Работа с неопределенностью



    Работа с неопределенностью

    Степень достоверности
1.    Степень достоверности

Наша оболочка экспертной системы, описанная в предыдущем разделе, может работать только с такими вопросами (утверждениями), которые либо истинны, либо ложны. Предметные области, в которых на любой вопрос можно ответить "правда" или "ложь", называются категорическими. Наши правила базы знания (также, как и данные) были категорическими, это были "категорические импликации". Однако многие области экспертных знаний не являются категорическими. Как правило, в заключениях эксперта много догадок (впрочем, высказанных с большой уверенностью), которые обычно верны, но могут быть и исключения. Как данные, относящиеся к конкретной задаче, так и импликации, содержащиеся в правилах, могут быть не вполне определенными. Неопределенность можно промоделировать, приписывая утверждениям некоторые характеристики, отличные от "истина" и "ложь". Характеристики могут иметь свое внешнее выражение в форме дескрипторов, таких, как, например, верно, весьма вероятно, вероятно, маловероятно, невозможно. Другой способ: степень уверенности может выражаться в форме действительного числа, заключенного в некотором интервале, например между 0 и 1 или между -5 и +5. Такую числовую характеристику называют по-разному - "коэффициент определенности", "степень доверия" или "субъективная уверенность". Более естественным было бы использовать вероятности (в математическом смысле слова), но попытки применить их на практике приводят к трудностям. Происходит это по следующим причинам: Экспертам, по-видимому, неудобно мыслить в терминах вероятностей. Их оценки правдоподобия не вполне соответствуют математическому определению вероятностей. Работа с вероятностями, корректная с точки зрения математики, потребовала бы или какой-нибудь недоступной информации, или каких-либо упрощающих допущений, не вполне оправданных с точки зрения практического приложения.

Поэтому, даже если выбранная мера правдоподобия лежит в интервале 0 и 1, более правильным будет называть ее из осторожности "субъективной уверенностью", подчеркивая этим, что имеется в виду оценка, данная экспертом. Оценки эксперта не удовлетворяют всем требованиям теории вероятностей. Кроме того, вычисления над такими оценками могут отличаться от исчисления вероятностей. Но, несмотря на это, они могут служить вполне адекватной моделью того, как человек оценивает достоверность своих выводов.

Для работы в условиях неопределенности было придумано множество различных механизмов. Мы будем рассматривать здесь механизм, используемый в системах Prospector и AL/X для минералогической разведки и локализации неисправностей соответственно. Следует заметить, что модель, применяемая в системе Prospector, несовершенна как с теоретической, так и с практической точек зрения. Однако она использовалась на практике, она проста и может служить хорошей иллюстрацией при изложении основных принципов, а потому вполне подойдет нам, по крайней мере для первого знакомства с этой областью. С другой стороны, известно, что даже в значительно более сложных моделях не обходится без трудностей.

    Модель Prospector'а
2.    Модель Prospector'а

Достоверность событий моделируется с помощью действительных чисел, заключенных в интервале между 0 и 1. Для простоты изложения мы будем называть их "вероятностями", хотя более точный термин "субъективная уверенность". Отношения между событиями можно представить графически в форме "сети вывода". На рис. 14.14 показан пример сети вывода. События изображаются прямоугольниками, а отношения между ними - стрелками. Овалами изображены комбинации событий (И, ИЛИ, НЕ).

Мы будем считать, что отношения между событиями (стрелки) являются своего рода "мягкими импликациями". Пусть имеются два события E   и  H,  и пусть информация о том, что имело место событие Е,  оказывает влияние на нашу уверенность в том, что произошло событие H.  Если это влияние является "категорической импликацией", то можно просто написать

        если Е  то  H

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

        если E  то  H   с силой  S

Та сила, с которой достоверность Е   влияет на уверенность в H,   моделируется в системе Prospector при помощи двух параметров:

        N  =   "коэффициент необходимости"
        S  =   "коэффициент достаточности"



Разработка оболочки



    Разработка оболочки

Если мы посмотрим на правила наших двух маленьких баз знаний рис. 14.5 и 14.7, мы сразу увидим, что они по своему смыслу эквивалентны правилам Пролога. Однако, с точки зрения синтаксиса Пролога, эти правила в том виде, как они написаны, соответствуют всего лишь фактам. Для того, чтобы заставить их работать, самое простое, что может прийти в голову, это переписать их в виде настоящих прологовских правил. Например:

        Животное это млекопитающее :-
                Животное имеет шерсть;
                Животное 'кормит детенышей' молоком.

        Животное это хищник :-
                Животное это млекопитающее,
                Животное ест мясо.
        . . .

Теперь эта программа сможет подтвердить, что тигр по имени Питер - это действительно тигр, если мы добавим в нее некоторые из свойств Питера (в виде прологовских фактов):

        питер имеет шерсть.
        питер ленив.
        питер большой.
        питер имеет 'рыжевато-коричневый цвет'.
        питер имеет 'черные полосы'.
        питер ест мясо.

Тогда мы можем спросить:

        ?-  питер это тигр.
        yes

        ?-  питер это гепард.
        no

Хотя пролог-система и отвечает на вопросы, используя для этого нашу базу знаний, нельзя сказать, что ее поведение вполне соответствует поведению эксперта. Это происходит по крайней мере по двум причинам:

(1)        Мы не можем попросить систему объяснить свой ответ; например, как она установила, что Питер это тигр, и почему Питер это не гепард.

(2)        Прежде, чем задать вопрос, нужно ввести в систему всю необходимую информацию (в виде прологовских фактов). Но тогда пользователь, возможно, введет какую-нибудь лишнюю информацию (как в нашем примере) или же упустит какую-нибудь информацию, имеющую решающее значение. В первом случае будет проделана ненужная работа, а во втором - система будет давать неверные ответы.

Для того, чтобы исправить эти два недостатка, мы нуждаемся в более совершенном способе взаимодействия между пользователем и системой во время и после завершения процесса рассуждений. Поставим себе целью добиться того, чтобы система взаимодействовала с пользователем так, как в следующем примере диалога (ответы пользователя даются полужирным шрифтом, реплики пролог-системы - курсивом):

        Пожалуйста, спрашивайте:
        питер это тигр.

        Это правда: питер имеет шерсть?
        да.

        Это правда: питер ест мясо?
        нет.

        Это правда: питер имеет острые зубы?
        да.

        Это правда: питер имеет когти?
        почему.

        Чтобы проверить по прав3, что питер это хищник,
        Чтобы проверить по прав5, что питер это тигр
        Это был ваш вопрос

        Это правда: питер имеет когти?
        да.

        Это правда: питер имеет глаза, направленные вперед?
        да.

        Это правда: питер имеет рыжевато-коричневый цвет?
        да.

        Это правда: питер имеет черные полосы?
        да.

        (питер это тигр) это правда
        Хотите узнать, как?
        да.

       

        питер это тигр
          было выведено по прав5 из
            питер это хищник,
              было выведено по прав3 из
                питер это млекопитающее
                  было выведено по прав1 из
                    питер имеет шерсть
                      было сказано
                и
                питер имеет острые зубы
                  было сказано
                и
                питер имеет когти
                  было сказано
                и
                питер имеет глаза, направленные вперед
                  было сказано
            и
            питер имеет рыжевато-коричневый цвет
              было сказано
            и
            питер имеет черные полосы
              было сказано

Как видно из диалога, система задает пользователю вопросы, касающиеся "примитивной" информации, например:

        Это  правда:   питер  ест  мясо?

Эту информацию нельзя отыскать в базе знаний или вывести из другой информации. На подобные вопросы пользователь может отвечать двумя способами:

(1)        сообщив системе в качестве ответа на вопрос необходимую информацию или

(2)        спросив систему, почему эта информация необходима.

Последняя из двух возможностей полезна, поскольку она позволяет пользователю заглянуть внутрь системы и увидеть ее текущие намерения. Пользователь спросит "почему" в том случае, когда вопрос системы покажется ему не относящимся к делу либо когда ответ на вопрос системы потребует от него дополнительных усилий. Из объяснений системы пользователь поймет, стоит ли информация, которую запрашивает система, тех дополнительных усилий, которые необходимо приложить для ее приобретения. Предположим, например, что система спрашивает: "Это животное ест мясо?" Пользователь, не знающий ответа на этот вопрос, поскольку он никогда не видел, как это животное ело что-либо, может решить, что не стоит ждать, пока он застанет животное за едой и убедится, что оно действительно ест мясо.

Для того, чтобы заглянуть внутрь системы и до какой-то степени представить себе протекающий в ней процесс рассуждений, можно воспользоваться прологовскими средствами трассировки. Но эти средства в большинстве случаев окажутся недостаточно гибкими для наших целей. Поэтому, вместо того, чтобы воспользоваться собственным механизмом интерпретации Пролога, который не сможет справиться с нужным нам способом взаимодействия с пользователем, мы создадим свое средство интерпретации в виде специальной надстройки над пролог-системой. Этот новый интерпретатор будет включать в себя средства для взаимодействия с пользователем.

    Процесс рассуждений
1.    Процесс рассуждений

Наш интерпретатор будет принимать вопрос и искать на него ответ. Язык правил допускает, чтобы в условной части правила была И / ИЛИ-комбинация условий. Вопрос на входе интерпретатора может быть такой же комбинацией подвопросов. Поэтому процесс поиска ответов на эти вопросы будет аналогичен процессу поиска в И / ИЛИ-графах, который мы обсуждали в гл. 13.

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

line();

Для того, чтобы найти ответ  Отв  на вопрос  В,  используйте одну из следующих возможностей: если  В  найден в базе знаний в виде факта, то  Отв  -  это "В  это правда" если в базе знаний существует правило вида

        "если  Условие   то  В",

то для получения ответа  Отв   рассмотрите  Условие
если вопрос В  можно задавать пользователю, спросите пользователя об истинности В если в имеет вид  В1  и  В2,  то рассмотрите  В1,  а затем,
        если  В1  ложно, то положите  Отв  равным  "В   это ложь",  в противном случае рассмотрите  В2  и получите  Отв   как соответствующую комбинацию ответов на вопросы  В1  и  В2 если  В  имеет вид  В1  или  В2,   то рассмотрите  В1,  а затем,
        если  В1   истинно, то положите  Отв  равным   "В1 это правда",  в противном случае рассмотрите  В2  и получите  Oтв   как соответствующую комбинацию ответов на вопросы  В1  и  В2. line();

Вопросы вида

        не  В

обрабатываются не так просто, и мы обсудим их позже.

    Формирование ответа на вопрос "почему"
2.    Формирование ответа на вопрос "почему"

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

        а - это правда?

В ответ пользователь может спросить:

        почему?

Объяснение в этом случае выглядит примерно так:

        Потому, что

        Я могу использовать    а,
                чтобы проверить по правилу  Па,  что  b,   и

        Я могу использовать  b,
                чтобы проверить по правилу  Пb,  что  с,   и

        Я могу использовать  с,
                чтобы проверить по правилу  Пc,  что  d,   и
        . . .

        Я могу использовать  y,
                чтобы проверить по правилу  Пy,  что  z,   и

        z - это ваш исходный вопрос.

Объяснение - это демонстрация того, как система намерена использовать информацию, которую она хочет получить от пользователя. Намерения системы демонстрируются в виде цепочки правил и целей, соединяющей эту информацию с исходным вопросом.



Реализация



    Реализация

Теперь мы приступим к реализации нашей оболочки, следуя тем идеям, которые обсуждались в предыдущем разделе. На рис. 14.9 показаны основные объекты, которыми манипулирует оболочка. Цель - это вопрос, подлежащий рассмотрению; Трасса - это цепочка, составленная из "целей-предков" и правил, находящихся между вершиной Цель и вопросом самого верхнего уровня; Ответ - решающее дерево типа И / ИЛИ для вершины Цель.



Обычно от экспертных систем требуют



Резюме

Обычно от экспертных систем требуют выполнения следующих функций:

решение задач в заданной предметной области,
объяснение процесса решения задач,
работа с неопределенной и неполной информацией.
Удобно считать, что экспертная система со стоит из двух модулей: оболочки и базы знаний. Оболочка в свою очередь состоит из механизма логического вывода и интерфейса с пользователем. При создании экспертной системы необходимо принять решения о выборе формального языка представления знаний, механизма логического вывода, средств взаимодействия с пользователем и способа работы в условиях неопределенности. "Если-то"-правила, или продукции являются наиболее часто применяемой формой представ ления знаний в экспертных системах. Оболочка, разработанная в данной главе, интерпретирует "если-то"-правила, обеспечивает выдачу объяснений типа "как" и "почему" и запрашивает у пользователя необходимую информацию. Машина логического вывода была расширена для работы с неопределенной информацией. В данной главе были обсуждены следующие понятия:

экспертные системы
база знаний, оболочка,
машина логического вывода
"если-то"-правила, продукции
объяснения типа "как" и "почему"
категорические знания, неопределенные знания
сеть вывода,
распространение оценок достоверности по сети

Сеть вывода системы al/x (заимствовано...



  Сеть вывода системы AL/X (заимствовано
из Reiter (1980) ).
Числа, приписанные прямоугольникам, - априорные
вероятности событий; числами на стрелках задается
"сила" отношений между событиями.

В сети вывода это изображается так:

                E ------------> H
                      (N, S)

Два события, участвующие в отношении, часто называют "фактом" и "гипотезой" соответственно. Допустим, что мы проверяем гипотезу H.  Тогда мы будем искать такой факт  Е,  который мог бы подтвердить либо опровергнуть эту гипотезу.  S   говорит нам, в какой степени достаточно факта  Е  для подтверждения гипотезы   H;  N  -  насколько необходим факт Е  для подтверждения гипотезы  Н.   Если факт  Е  имел место, то чем больше  S,  тем больше уверенности в  H.   С другой стороны, если не верно, что имел место факт  Е,  то чем больше  N,   тем менее вероятно, что гипотеза  H   верна. В случае, когда степень достоверности   Е  находится где-то между полной достоверностью и невозможностью, степень достоверности  H  определяется при помощи интерполяции между двумя крайними случаями. Крайние случаи таковы:

    (1)        известно, что факта  Е  не было
    (2)        известно, что факт  Е  имел место
    (3)        ничего не известно относительно  Е

Для каждого события  H  сети вывода существует априорная вероятность р0(Н)    (безусловная) вероятность события  H   в состоянии, когда неизвестно ни одного положительного или отрицательного факта. Если становится известным какой-нибудь факт  E,   то вероятность  H  меняет свое значение с  р0(Н)  на  р(Н | Е).   Величина изменения зависит от "силы" стрелки, ведущей из  E  в  H.   Итак, мы начинаем проверку гипотез, принимая их априорные вероятности. В дальнейшем происходит накопление информации о фактах, что находит свое отражение в изменении вероятностей событий сети. Эти изменения распространяются по сети от события к событию в соответствии со связями между событиями. Например, рассмотрим рис. 14.14 и предположим, что получена информация о срабатывании индикатора открытия выпускного клапана. Эта информация повлияет на нашу уверенность в том, что выпускной клапан открылся, что, в свою очередь, повлияет на уверенность в том, что сместилась установка порогового давления.



Соединения между предохранителями и приборами



  Соединения между предохранителями и приборами в


простой электрической схеме.

формальный язык это транслируется так:

правило_поломки:
                        если
                                Прибор включен и
                                не (Прибор работает) и
                                Прибор соединен с Предохранитель и
                                Предохранитель заведомо цел
                        то
                                Прибор заведомо неисправен.

База знаний такого рода показана на рис.



Структура экспертной системы.



  Структура экспертной системы.

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

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

    (1)        Выбрать формальный аппарат для представления знаний.

    (2)        Разработать механизм логического вывода, соответствующий этому формализму.

    (3)        Добавить средства взаимодействия с пользователем.

    (4)        Обеспечить возможность работы в условиях неопределенности.



с подобной базой знаний, наша



Упражнение

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

в нашу систему обозначений для



Упражнения

Рассмотрите "если-то"-правила рис. 14.2-14.4 и транслируйте их в нашу систему обозначений для правил. Предложите расширение нотации, чтобы, при необходимости, можно было работать с оценками уверенности.
line(); % Небольшая база знаний для локализации неисправностей в
% электрической схеме
% Если прибор включен, но не работает, и предохранитель цел,
% то прибор неисправен.
        правило_поломки:
                                        если
                                                вкл( Прибор) и
                                                прибор( Прибор) и
                                                не работает( Прибор) и
                                                соед( Прибор, Предохр) и
                                                доказано( цел( Предохр) )
                                        то
                                                доказано( неиспр( Прибор) ).
% Если устройство работает, то его предохранитель цел
        правило_цел_предохр:
                                        если
                                                соед( Прибор, Предохр)
                                                и работает( Прибор)
                                        то
                                                доказано( цел( Предохр) ).
% Если два различных прибора подключены к одному и тому же
% предохранителю, оба включены и не работают, то предохранитель
% сгорел.
% ЗАМЕЧАНИЕ: предполагается, что из двух приборов неисправных -
% не более одного!
            правило_предохр:
                                        если
                                                соед( Прибор1, Предохр) и
                                                вкл( Прибор1) и
                                                не работает( Прибор1) и
                                                общ_предохр( Прибор2, Прибор1) и
                                                вкл( Прибор2) и
                                                не работает( Прибор2)
                                        то
                                                доказано( сгорел( Предохр) ).
        правило_общ_предохр:
                                        если
                                                соед( Прибор1, Предохр) и
                                                соед( Прибор2, Предохр) и
                                                различны( Прибор1, Прибор2)
                                        то
                                                общ_предохр( Прибор1, Прибор2).
        факт:  различны( X, Y) :- not (X=Y).
        факт:  прибор( радиатор).
        факт:  прибор( лампа1).
        факт:  прибор( лампа2).
        факт:  прибор( лампа3).
        факт:  прибор( лампа4).
        факт:  соед( лампа1, предохр1).
        факт:  соед( лампа2, предохр1).
        факт:  соед( радиатор, предохр1).
        факт:  соед( лампа3, предохр2).
        факт:  соед( лампа4, предохр2).
        можно_спросить( вкл( П), вкл( 'Прибор') ).
        можно_спросить( работает( П), работает(' Прибор')).
line();



Заключительные замечания



    Заключительные замечания

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

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

Наша процедура рассмотреть подвержена зацикливанию в тех случаях, когда в правилах базы знаний "циклически" упоминается одна и та же цель. Этот недостаток легко исправить, предусмотрев в рассмотреть соответствующий контроль, т. е. проверку, не является ли текущая цель частным случаем некоторой цели, уже введенной в состав объекта Трасса.

Наше объяснение типа "как" выводит дерево доказательства целиком. В случае больших деревьев, удобнее было бы вывести только верхнюю часть дерева, а затем дать пользователю возможность "гулять" по остальной части дерева по своему желанию. Тогда пользователь смог бы просматривать дерево выборочным образом, используя команды, такие как "Вниз по ветви 1", "Вниз по ветви 2", .... "Вверх ", "Достаточно".

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

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

        Это правда: сьюзен летает?
        нет.

        Это правда: сьюзен летает хорошо?

Конечно же нет, раз она совсем не летает! Другой пример:

        Есть (еще) решения для: Кто-нибудь летает?
        да.
        Кто-нибудь = птица.

        Это правда: альбатрос летает?

Для того, чтобы справиться с подобными нежелательными эффектами, следует ввести в экспертную систему дополнительные отношения между понятиями вместе с механизмами их обработки. Обычно эти новые отношения задают иерархию объектов и их свойств.

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

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

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

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