Дедуктивная машина

Дедуктивная машина может быть организована в соответствии с псевдокодом, представленным в табл. 5.

В качестве примера реализации такого псевдокода на языке Паскаль приведена стандартная программа infer (см. распечатку 2), начинающаяся с вызова функции «получить_ основную_ цель» (get_main_goal), которая служит для запроса абонента о том, какова конечная цель консультации.

Ответ на этот вопрос записывается в виде глобальной переменной «основная_цель» (main_goal); кроме того, формируется и заносится в массив «список_целей» (goal_list)—структурный компонент, содержащий утверждение «основная_цель».

Затем начинается выполнение программы в циклическом режиме, продолжающееся до тех пор, пока булева переменная done («выполнено») не получит значения ИСТИНА.

Таблица 5. Псевдокод для реализации дедуктивной машины

В первую очередь с помощью булевой функции «найденное_правило» (found_rule) определяется, существует ли правило, которое требуется проанализировать. Такая функция программы реализует цепочку обратных рассуждений; она выполняет просмотр выводов всех действующих правил, проверяя их соответствие той цели, которая находится на самом верху стека целей. Если соответствие обнаруживается, то ,эта функция выдает значение ИСТИНА и сформирует указатель к тому компоненту правила, которым обеспечивается подобное соответствие.

Если можно найти правило, содержащее текущую цель, то вызывается функция «значение_правила» (rule_value) для
нахождения логического значения правила в зависимости от текущего состояния контекста. В системе «МикроЭксперт» используется трехзначная логика, т. е. значение правила может быть истинным, ложным или неизвестным. Истинное значение (чему соответствует буква Т в распечатке) правило имеет, когда всем компонентам его условия соответствуют какие-то компоненты в стеке контекстов. Правило дает ложное значение (обозначается буквой F), если значение какого-то признака, представленного в условии правила, отличается от того, которое у него имеется в контексте. Наконец, считается, что правило имеет неизвестное значение (этому соответствует буква U), когда хотя бы для одного из признаков в условии правила невозможно найти никакого значения в контексте.

Функция «значение_правила» формирует также указатель к тому компоненту контекста, который позволил определить, каково значение правила: Т, F или U.

В том случае, когда эта функция выдает значение F, анализируемое правило отмечается как недействующее присвоением значения ЛОЖЬ соответствующему элементу массива «действующее_правило» (active_rule). Если с помощью такой функции получено значение U, то признак первого компонента того правила, значение которого невозможно определить, переносится в верхнюю часть стека целей.

Наконец, когда получено значение Т, вызывается функция «истинное_правило» (true_rule), которая помещает выводы правила в контекст; данная функция также удаляет верхний компонент из массива «список_целей» и присваивает элементу правила (в массиве «действующие_правила») значение ЛОЖЬ. Она, кроме того, проверяет, не пуст ли массив «список_целей", и, если он пуст, приводит флажок done в состояние ИСТИНА.

Если функция «найденное правило»» не обнаруживает никакого правила, то программа вызывает функцию «найденная_подсказка»  (found_prompt);  последняя отыскивает в списке признаков вопрос, который следует задать абоненту, чтобы выяснить значение цели. В случае если подсказка для проверяемого признака существует, такая функция выдает значение ИСТИНА и формирует указатель к соответствующему элементу в списке признаков.

Когда подсказку найти не удастся, флажок done приводится в состояние ИСТИНА — программный цикл завершается. Обычно это означает, что база данных о правилах противоречива, и программный интерпретатор завершает свою работу, не найдя никакого значения для основной цели. Если же подсказка обнаружена, то вызывается функция «получить_ответ» (get_answer), которая обеспечивает визуальное отображение этой подсказки на экране дисплея и получение (от пользователя) значения признака цели.

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

Отвечая на вопросы «как?» и «почему?»

В ответ на запрос пользователя «почему?» программа выводит на печать ту цель, на которую направлен указатель why_ptr (процедура infer устанавливает этот указатель таким образом, что первоначально он направлен на рассматриваемую цель). Кроме того, она распечатывает перевод правила, которое обусловило размещение данной цели в списке целей. Номер такого правила был записан в компонент цели, когда он формировался с использованием функции «поместить_цель_на (put_on_goal). Затем указатель why_ptr направляется к следующей цели в списке. Таким образом, все время задавая вопросы «почему?», можно вывести на печать содержимое массива «список_целей», а также правила, проанализированные системой при достижении целей.

При распечатке правила каждому выражению присваивается номер, и компонент, отвечающий этому выражению, вносится в некий список. Данный список используется в огклике на запрос «как?». Пользователь может теперь задать вопрос «как?», за которым следует поставить число, представляющее собой номер строки, распечатанной в ответ на последний вопрос «почему?» (Напомним что правило распечатывается «в переводе» и при этом каждое выражение оказывается на новой строке).

К примеру, фраза «Как 3» (how 3) означает: «Как обосновывалась (или могла быть обоснована) фраза в строке 3?» Программа реагирует на фразу «Как 3», просматривая стек контекста в поисках компонента, с которым у признака, входящего в рассматриваемую фразу, имеется соответствие. В случае если подобный компонент найден, значение этой фразы сравнивается с соответствующим значением в контексте. При совпадении этих значений программа распечатывает правило, которое обусловило размещение указанного компонента в контексте. Если номер такого правила -оказывается равным нулю, то программа выводит на печать сообщение о том, что фраза обосновывалась информацией, вводимой пользователем.

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