Сначала необходимо сделать декларации базы данных. База данных будет хранить ответы пользователя на вопросы системы пользовательского интерфейса (СПИ). Эти данные являются утвердительными или отрицательными ответами.
Далее нужно объявить предикаты для выполнения вывода (машина вывода) и для взаимодействия с пользователем (система пользовательского интерфейса).
Все вместе это следующие декларации:
database
xpositive(symbol,symbol)
xnegative(symbol,symbol)
predicates
do_expert_job
do_consulting
ask(symbol,symbol)
dog_is(symbol)
it_is(symbol)
positive(symbol,symbol)
negative(symbol,symbol)
remember(symbol,symbol,symbol)
clear_facts
Предикаты базы данных xpositive и xnegative используются для хранения утвердительных и отрицательных ответов пользователя. Первые четыре предиката нужны для взаимодействия с пользователем, а остальные шесть - для механизма вывода.
Должны быть составлены восемь продукционных правил: по одному для каждой породы. Каждое правило должно идентифицировать породу по признаку принадлежности к группе длинношерстных или короткошерстных.
Правило it_is производит эту идентификацию. Затем правило positive идентифицирует характеристики собаки в каждом случае.
И it_is и positive используются механизмом вывода. Ниже приведено полное продукционное правило для дуба:
tree_is("Дуб"):-
positive(tree,"Лиственная"),
positive(tree,"Твердая"),
positive(tree,"Серо_Коричневая"),
positive(tree,"Мелкая_текстура"),!.
Механизм вывода должен иметь правила для управления данными вводимыми пользователем, для сопоставления их с продукционными правилами и сохранения "трассы" (или запоминания) отрицательных и утвердительных ответов. Правила positive и negative используются для сопоставления данных пользователя с данными в продукционных правилах. Правило remember (запоминание) производит добавление предложений с ответами yes (да) и no (нет), для использования при сопоставлении с образцом:
|
positive(X,Y):-
xpositive(X,Y),!.
positive(X,Y):-
not(negative(X,Y)),!,
ask(X,Y).
negative(X,Y):-
xnegative(X,Y),!.
remember(X,Y,yes):-
asserta(xpositive(X,Y)).
remember(X,Y,no):-
asserta(xnegative(X,Y)),
fail.
clear_facts:-
retract(xpositive(_,_)),
fail.
clear_facts:-
retract(xnegative(_,_)),
fail.
Назначение системы пользовательского интерфейса (СПИ) - связь вводимых пользователем данных с системой логического вывода. Главный модуль do_expert_job (выполни экспертную работу) и модуль do_consulting (выполни консультацию) осуществляют эту связь. Модуль ask(X,Y) (спроси) запрашивает данные у пользователя и сохраняет ответы в базе знаний. Кроме того, окно обеспечивает дополнительное удобство во время консультации. Система пользовательского интерфейса полностью приведена ниже:
do_expert_job:-
setup_window,
do_consulting,
write("Press space bar."),nl,
readch(_),
removewindow,
exit.
setup_window:-
makewindow(1,7,7,"AN EXPERT SYSTEM",1,16,22,58),
nl,write("* * * * * * * * * * * * * * * * * * * *"),
nl,write(" A Tree Expert "),
nl,write(" "),
nl,write("This is a tree identification system. "),
nl,write("Please answer the question about "),
nl,write("the dog you would like by typing in "),
nl,write("'yes' or 'no'. "),
nl,write("* * * * * * * * * * * * * * * * * * * *"),
nl,nl.
do_consulting:-
dog_is(X),!,nl,
write("the tree you have indicated is a(n)",X,"."),nl,
clear_facts.
do_consulting:-
nl,write("Sorry I can't help you! "),
clear_facts.
ask(X,Y):-
write(" Question:- ",X," it ",Y,"?"),
readln(Reply),
remember(X,Y,Reply).
Заметьте, что главный модуль do_expert_job вызывает модули setup_window (установи окно) и do_consulting (выполни консультацию). Консультирующий модуль имеет две альтернативные формы. Первая взаимодействует с механизмом вывода; если результат цикла "распознавание - действие" положительный, то результат сообщается пользователю. Вторая форма сообщает о негативном результате.
|
Теперь можно соединить отдельные компоненты и сформировать полную экспертную систему на правилах для выбора породы дерева.
Эта программа просит пользователя выбрать режим консультации или выход из программы. Затем экспертная система выбирает породу собаки на основании ответов пользователя на вопросы, или в конце неудачного поиска выдает сообщение “Sorry!”
Реализация:
domains
database
xpositive(symbol,symbol)
xnegative(symbol,symbol)
predicates
do_expert_bird.
do_consulting
ask(symbol,symbol)
tree_is(symbol)
positive(symbol,symbol)
negative(symbol,symbol)
remember(symbol,symbol,symbol)
clear_facts
goal
do_expert_bird.
clauses
do_expert_bird:-
makewindow(1,7,7,"Expert System",1,3,22,71),
nl,write(" ---------------------------------------------------"),
nl,write(" A Tree Expert "),
nl,write(" "),
nl,write(" Please answer the questions 'yes' or 'no'."),
nl,write(" ---------------------------------------------------"),
nl,nl,
do_consulting,
write("Press space bar."),nl,
readchar(_),
removewindow,
exit.
do_consulting:-
tree_is(X),!,nl,
write("Tree ",X,"."),nl,
clear_facts.
do_consulting:-
nl,write("Sorry!"),
clear_facts.
ask(X,Y):-
write(" expert> ",X," ",Y,"?"),
readln(Reply),
remember(X,Y,Reply).
positive(X,Y):-
xpositive(X,Y),!.
positive(X,Y):-
not(negative(X,Y)),!,
ask(X,Y).
negative(X,Y):-
xnegative(X,Y),!.
remember(X,Y,yes):-
asserta(xpositive(X,Y)).
remember(X,Y,no):-
asserta(xnegative(X,Y)),
fail.
clear_facts:-
retract(xpositive(_,_)),
fail.
clear_facts:-
retract(xnegative(_,_)),
fail.
tree_is("Дуб"):-
positive(tree,"Лиственная"),
positive(tree,"Твердая"),
positive(tree,"Серо_Коричневая"),
positive(tree,"Мелкая_текстура"),!.
|
tree_is("Бук"):-
positive(tree,"Лиственная"),
positive(tree,"Твердая"),
positive(tree,"Светло_Красная"),
positive(tree,"Крупная_текстура"),!.
tree_is("Осина"):-
positive(tree,"Лиственная"),
positive(tree,"Мягкая"),
positive(tree,"Светлая"),
positive(tree,"Мелкая_текстура"),!.
tree_is("Тис"):-
positive(tree,"Лиственная"),
positive(tree,"Очень_твердая"),
positive(tree,"Темная"),!.
tree_is("Ель"):-
positive(tree,"Хвойная"),
positive(tree,"Мягкая"),
positive(tree,"Светлая"),
positive(tree,"Смолистая"),!.
tree_is("Сосна"):-
positive(tree,"Хвойная"),
positive(tree,"Мягкая"),
positive(tree,"Светлая"),
positive(tree,"Очень_Смолистая"),!.
tree_is("Столб"):-
positive(tree,"Не_дерево"),
positive(tree,"Очень_Твердый"),!.