Создание экспертных систем средствами ПРОЛОГа

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

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

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

Создание экспертных систем средствами ПРОЛОГа - student2.ru

рис.27. Диалог экспертной системы с пользователем

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

- базу знаний;

- механизм вывода;

- пользовательский интерфейс.

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

1) ЕСЛИ

это отряд карпообразные и

И

у рыбы желто-золотистый окрас

И

губы с 4 усиками

ТО

это сазан

2) ЕСЛИ

это отряд карпообразные

И

у рыбы плавники с розовыми перьями

это плотва

3) ЕСЛИ

спинной плавник узкий

И

у рыбы желто-золотистый окрас

И

это отряд карпообразные

это лещ

4) ЕСЛИ

у рыбы нет зубов

И

одиночный спинной лучевой плавник

И

это костная рыба

И

это пресноводная рыба

это отряд карпообразные

5) ЕСЛИ

у рыбы есть костный скелет

ИЛИ

у рыбы есть жаберные крышки

это костная рыба

6) ЕСЛИ

рыба плавает в озерах

ИЛИ

рыба плавает в реках

ТО

это пресноводная рыба

Для создания базы знаний используем предикаты:

fish(symbol)

otrajd(symbol)

vid(symbol)

priznak(symbol)

Базу знаний будут составлять следующие правила:

fish("это сазан"):-

otrajd("отряд карпообразные"),

priznak("губы с 4 усиками").

fish("это плотва"):-

otrajd("отряд карпообразные"),

priznak("плавники с розовыми перьями").

fish("это лещ"):-

otrajd("отряд карпообразные"),

priznak("у рыбы желто-золотистый окрас"),

priznak("у рыбы спинной плавник узкий").

Необходимо предусмотреть, что искомой рыбы в базе знаний нет:

fish("Данной рыбы в базе знаний не обнаружено").

otrajd("отряд карпообразные"):-

vid("пресноводная рыба"),

vid("костная рыба"),

priznak("одиночный спинной лучевой плавник"),

priznak("у рыбы нет зубов").

vid("костная рыба"):-

priznak("у рыбы есть жаберные крышки");

priznak("у рыбы есть костный скелет").

vid("пресноводная рыба"):-

priznak("рыба плавает в реках или озерах").

Для хранения информации, полученной от пользователя, используются предикаты yes и no, составляющие внутреннюю базу фактов. Предикат yes служит для хранения фактов, соответствующих положительному ответу, а предикат no – для хранения отрицательных ответов. Т.е. предикат yes утверждает наличие какого-либо признака у рыбы, а no – отсутствие указанного признака. Эти предикаты объявляются в разделе внутренней базы фактов:

global facts

yes (symbol)

no (symbol)

Добавить новые факты во внутреннюю базу можно с помощью правила add_to_database, состоящего из двух частей. Первая часть добавляет факты, соответствующие положительному ответу (с клавиатуры вводится ‘y’). Вторая часть правила добавляет факты, указывающие на отсутствие данного признака у рыбы.

add_to_database (Y,'y') :- assertz (yes (Y)).

add_to_database (Y,'n') :- assertz (no (Y)),fail.

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

clear_from_database :- retract(yes(_)),fail.

clear_from_database :- retract(no(_)),fail.

Для проверки наличия у рыбы определенного признака создадим правило priznak (Y):

priznak (Y) :- yes (Y),!.

priznak (Y) :- not(no (Y)),

question (Y).

Формулировка вопроса, ввод ответа и сохранение соответствующего правила осуществляется с помощью правил:

answer :- fish(X),!,nl,

save("BF1.dbf"),

write (" Ответ: ",X,"."),nl.

question(Y) :-

write ("Вoпрос: ",Y,"?(y/n) "),

otvet(X),

write(X),nl,

add_to_database (Y,X).

otvet(C):-readchar(C).

И, наконец, правило begin, запускающее сеанс консультации:

begin :- write ("Ответьте на вопросы :"),nl,nl,

answer,

clear_from_database,

nl,nl,nl,nl,

exit.

Полный листинг программы выглядит следующим образом:

GLOBAL FACTS

yes (symbol)

no (symbol)

PREDICATES

fish(symbol)

otrajd(symbol)

vid(symbol)

begin

answer

question(symbol)

add_to_database(symbol,char)

otvet(char)

clear_from_database

priznak(symbol)

GOAL

begin.

CLAUSES

begin :-

write ("Ответьте на вопросы :"),nl,nl,

answer,

clear_from_database,

nl,nl,nl,nl,

exit.

answer :-

fish(X),!,nl,

save("BF1.dbf"),

write (" Ответ: ",X,"."),nl.

question(Y) :-

write ("Вoпрос: ",Y,"? "),

otvet(X),

write(X),nl,

add_to_database (Y,X).

otvet(C):-

readchar(C).

priznak (Y) :-

yes (Y),!.

priznak (Y) :-

not( no (Y)),

question (Y).

add_to_database (Y,'y') :-

assertz (yes (Y)).

add_to_database (Y,'n') :-

assertz (no (Y)),fail.

clear_from_database :- retract (yes(_)),fail.

clear_from_database :- retract (no(_)),fail.

fish("это сазан"):-

otrajd("отряд карпообразные"),

priznak("губы с 4 усиками").

fish("это плотва"):-

otrajd("отряд карпообразные"),

priznak("плавники с розовыми перьями").

fish("это лещ"):-

otrajd("отряд карпообразные"),

priznak("у рыбы желто-золотистый окрас"),

priznak("у рыбы спинной плавник узкий").

fish("Данной рыбы в базе знаний не обнаружено").

otrajd("отряд карпообразные"):-

vid("пресноводная рыба"),

vid("костная рыба"),

priznak("одиночный спинной лучевой плавник"),

priznak("у рыбы нет зубов").

vid("костная рыба"):-

priznak("у рыбы есть жаберные крышки");

priznak("у рыбы есть костный скелет").

vid("пресноводная рыба"):-

priznak(«рыба плавает в реках или озерах»).

Наши рекомендации