Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по Прологу.doc
Скачиваний:
68
Добавлен:
01.05.2014
Размер:
501.25 Кб
Скачать

5.1. Оболочка экспертной системыGeni

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

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

Знания в этой системе представляют собой правила, имеющие вид:

rule(N,CAT1,CAT2,COND).

Здесь N-порядковый номер правила,

CAT1- выражение, стоящее в левой части правила и характеризующее признак класса (подкласса и т.д.), к которому относится данное правило;

CAT2- содержание правила в правой части, содержащее вывод из этого правила;

COND- список номеров условий, определяющих правило.

Условие имеет вид:

cond( N, CONDTEXT),

где N - номер условия,

CONDTEXT- текст условия.

Таким образом, база знаний рассматриваемой экспертной системы следующая:

rule(1,"хищник","гепард",[1,2])

rule(2,"хищник","тигр",[1,3])

rule(3,"копытное","жираф",[5,4,2])

rule(4,"копытное","зебра",[3])

rule(5,"птица","страус",[5,7])

rule(6,"птица","пингвин",[9,7])

rule(7,"птица","альбатрос",[10])

rule(8,"животное","млекопитающее",[11,12])

rule(9,"животное","птица",[8,13])

rule(10,"млекопитающее","хищник",[14])

rule(11,"млекопитающее","копытное",[15])

cond(1,"оно имеет рыжий цвет")

cond(2,"оно имеет темные пятна")

cond(3,"оно имеет черные полосы")

cond(4,"оно имеет длинную шею")

cond(5,"оно имеет длинные ноги")

cond(6,"оно летает")

cond(7,"оно имеет черный и белый цвет")

cond(8,"оно имеет перья")

cond(9,"оно плавает")

cond(10,"оно летает хорошо")

cond(11,"оно имеет шерсть")

cond(12,"оно кормит детенышей молоком")

cond(13,"оно откладывает яйца")

cond(14,"оно ест мясо")

cond(15,"оно имеет копыта")

Легко видеть, что такой способ представления знаний реализует конструкцию вида ЕСЛИ ТО:

ЕСЛИ САТ1 отвечает условиям СOND, ТО САТ1 есть САТ2.

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

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

yes(N) или no(N),

где N- номер условияcond.

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

go( _, Mygoal ):- /*Цель достигнута */

not(rule(_,Mygoal,_,_)),!,nl,

write("I think it is a(n): ",Mygoal),nl,nl,

write("I was right, wasn't I? (enter y or n)"),

readchar(Ans),

evalans(Ans).

go( HISTORY, Mygoal ):-

rule(RNO,Mygoal,NY,COND),

check(RNO,HISTORY, COND),

go([RNO|HISTORY],NY).

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

Предикат check, входящий во второе правило предикатаgo, производит проверку списка условийCONDна достоверность, т.е. поиск уже имеющихся фактов, относящихся к данным условиям. Если ответ на эти условия имеется в базе данных в виде фактовyes(BNO)илиno(BNO), проверка на этом заканчивается. В случае, если требуемые факты не обнаружены, определяется запрос пользователю с помощью предикатаinpq. Если проверкаcheckзаканчивается ложно, то выбирается следующее правило из базы знаний. Если же проверка успешна, номер правила присоединяется к списку успешных правилHISTORY, по которому можно восстановить историю поиска, а текущей целью становится третий аргумент правилаrule, что означает переход к следующему уровню дерева:

check( RNO, HISTORY, [BNO|REST] ):- yes(BNO), !,

check(RNO, HISTORY, REST).

check( _, _, [BNO|_] ):- no(BNO), !,fail.

check( RNO, HISTORY, [BNO|REST] ):-

cond(BNO,TEXT),

inpq(HISTORY,RNO,BNO,TEXT),

check(RNO, HISTORY, REST).

check( _, _, [ ] ).

Предикат inpqзапускает диалоговый механизм, посредством которого система получает недостающую информацию. Система задает пользователю вопросы, представляющие собой условия истинности конкретного правила, при этом пользователь может ответить “yes”, “no” или “why”. Третий ответ означает, что пользователю нужно знать, почему система задала такой вопрос. В этом случае намерения системы демонстрируются в виде цепочки правил и целей, соединяющих эту информацию с исходным вопросом.

inpq(HISTORY,RNO,BNO,TEXT):-

write("Is it true that ",TEXT,": "),

ROW = 14,

COL = 60,

menu(ROW,COL,7,7,[yes,no,why],"",1,CHOICE),

do_answer(HISTORY,RNO,TEXT,BNO,CHOICE).

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

do_answer(_,_,_,BNO,1):-assert(yes(BNO)), write(yes),nl. % Ответ yes

do_answer(_,_,_,BNO,2):-assert(no(BNO)), write(no),nl,fail. % Ответ no

do_answer(HISTORY,RNO,TEXT,BNO,3):- !, % Ответ why

rule( RNO, Mygoal1, Mygoal2, _ ),

sub_cat(Mygoal1,Mygoal2,Lstr),

concat("I try to show that: ",Lstr,Lstr1),

concat(Lstr1,"\nBy using rule number ",Ls1),

str_int(Str_num,RNO),

concat(Ls1,Str_num,Ans),

show_rule(RNO,Lls1),

concat(Ans,Lls1,Ans1),

report(HISTORY,Sng),

concat(Ans1,Sng,Answ),

display(Answ),

write(" Use Arrow Keys To Select Option "),

shiftwindow(1),

ROW = 14,COL = 60,

menu(ROW,COL,7,7,[yes,no,why],"",1,CHOICE),

do_answer(HISTORY,RNO,TEXT,BNO,CHOICE).

Объяснению придается удобная для восприятия форма с помощью стандартных предикатов concat,str_int,displayи рекурсивного предикатаreport:

report([],"").

report([RNO|REST],Strg) :-

rule( RNO, Mygoal1, Mygoal2, _), % Выбирается правило с номером RNO

sub_cat(Mygoal1,Mygoal2,Lstr),

concat("I have shown that: ",Lstr,L1),

concat(L1,"By using rule number ",L2),

str_int(Str_RNO,RNO),

concat(L2,Str_RNO,L3),

concat(L3, L4),

show_rule(RNO,Str), % Показ правила

concat(L4,Str,L5),

report(REST,Next_strg),

concat(L5,Next_strg,Strg).

Модификацию бзы данных выполняет предикат update:

update:-

write("Name of category: "),

readln(KAT), % Ввод категории

KAT><"", % Окончание работы предиката

write("Name of subcategory: "),

readln(SUB), SUB><"", % Ввод подкатегории

readcondl(CONDL), % Ввод списка условий

getrnr(1,RNO), % Получение номера правила

assert( rule(RNO,KAT,SUB,CONDL) ), % Добавление правила к БД

update.

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

rule(RNO,"хищник","пантера", [BNO] ) и условие

cond(BNO,"оно имеет черный цвет") , где RNO и BNO - соответственно номер правила и номер условия, еще не конкретизированные переменные. Предикат readcondlпозволяет ввести список условий:

readcondl( [BNO|R] ):-

readln(COND), % Вод текста условия

COND><"",!, % Окончание ввода списка условий

getcond(BNO,COND), % Получение номера условия

readcondl( R ).

readcondl( [ ] ).

Предикат getcondlнаходит номер условия в базе данных, если такое условие там уже есть, или получает следующий по порядку свободный номер условия с помощью предикатаgetbnr:

getcond(BNO,COND):-cond(BNO,COND),!. % Условие есть в базе данных

getcond(BNO,COND):-getbnr(1,BNO),

assert( cond(BNO,COND) ). % Условие добавляется к базе данных

getbnr(N,N):-not(cond(N,_)),!.

getbnr(N,N1):-H=N+1,getbnr(H,N1).

Сходным образом определяется номер правила, которого еще нет в базе данных:

getrnr(N,N):-not(rule(N,_,_,_)),!.

getrnr(N,N1):-H=N+1,getrnr(H,N1).

Файлы оболочки программы и примеров баз знаний расположены в каталоге Programs.