
Identify(giraffe):-
it_is(ungulate),
confirm(has,long_neck),
confirm(has,long_legs),
confirm(has,dark_spots),!.
identify(zebra):-
it_is(ungulate),
confirm(has,black_stripes),!.
identify(cheetah):-
it_is(mammal),
it_is(carnivorous),
confirm(has,tawny_color),
confirm(has,black_spots),!.
identify(tiger):-
it_is(mammal),
it_is(carnivorous),
confirm(has,tawny_color),
confirm(has,black_stripes),!.
identify(eagle):-
it_is(bird),
confirm(does,fly),
it_is(carnivorous),
confirm(has,use_as_national_symbol),!.
identify(ostrich):-
it_is(bird),
not(confirm(does,fly)),
confirm(has,long_neck),
confirm(has,long_legs),!.
identify(penguin):-
it_is(bird),
not(confirm(does,fly)),
confirm(does,swim),
confirm(has,black_and_white_color),!.
identify(blue_whale):-
it_is(mammal),
not(it_is(carnivorous)),
confirm(does,swim),
confirm(has,huge_size),!.
identify(octopus):-
not(it_is(mammal)),
it_is(carnivorous),
confirm(does,swim),
confirm(has,tentacles),!.
identify(sardine):-
it_is(fish),
confirm(has,small_size),
confirm(has,use_in_sandwiches),!.
/* Если ответ не получен, то срабатывает это правило. */
identify(unknown).
Все правила поддерживаются на следующем, более низком уровне некоторыми соподчиненными правилами классификации животных:
it_is(bird):-
not(it_is(mammal)),
confirm(has,feathers),
confirm(does,lay_eggs),!.
it_is(fish):-
confirm(does,swim),
confirm(has,fins),!.
it_is(mammal):-
confirm(has,hair),!.
it_is(mammal):-
confirm(does,give_milk),!.
it_is(ungulate):-
it_is(mammal),
confirm(has,hooves),
confirm(does,chew_cud),!.
it_is(carnivorous):-
confirm(has,pointed_teeth),!.
it_is(carnivorous):-
confirm(does,eat_meat),!.
В данной версии ПЗР, как и в версии с прямой цепочкой рассуждений, которую мы рассмотрим далее, большая часть работы совершается правилами confirm и denied. Они используются для проверки конкретных атрибутов животных, которые могут быть обнаружены в процессе диалога и записаны в базу данных. Здесь задействован механизм вопросов-ответов, поэтому нам необходимо подробно рассмотреть эти правила. Ниже следует соответствующая часть программы.
database
db_confirm(symbol,symbol)
db_denied(symbol,symbol)
clauses
confirm(X,Y):-
db_confirm(X,Y),!.
confirm(X,Y):-
not(denied(X,Y)),
!,
check_if(X,Y).
denied(X,Y):-
db_denied(X,Y),!.
check_if(X,Y):-
write(X," it ",Y,"\n"),
readln(Reply),
remember(X,Y,Reply).
remember(X,Y,yes):-
asserta(db_confirm(X,Y)).
remember(X,Y,no):-
asserta(db_denied(X,Y)),
fail.
Прежде всего необходимо иметь факты, называемые db_confirm и db_denied, которые становятся реальной формой ответно-вопросной информации, когда они поступают в базу данных. Это обусловлено тем, что в Турбо Прологе допустимо помещать в базу данных в процессе выполнения программы только те предложения, которые представлены простыми фактами. Турбо Пролог позволяет оптимизировать по скорости выполнения многие действия, чему мы и находим здесь подтверждение. Предикаты confirm и denied не могут использоваться для этой цели, потому что есть правила, связанные с ними.
Обратите внимание на правила для confirm - их два. Когда механизм вывода доходит до места, где требуется узнать, был ли установлен некоторый атрибут животного, он использует эти правила. Первое из них заставляет систему непосредственно просмотреть информацию, уже включенную в базу данных. Если атрибут в ней найден, процесс заканчивается. Второе правило инициирует поиск отрицания того, что мы пытаемся установить, и если его также нет в базе данных, то вызывается правило check_if. К этому моменту система определила, что не располагает нужной информацией, поэтому она вынуждена задать вопрос пользователю. Любой полученный ответ запоминается с целью непосредственного или последующего применения.
Теперь разберем структуру вопросов, порождаемых правилом check_if:
has it wings Есть ли у него крылья
has it teeth Есть ли у него зубы
does it bite Кусается ли оно
does it shed_skin Сбрасывает ли оно кожу
Все, что программа помещает в базу данных, всегда имеет вид пары, состоящей из глагола и атрибута, например:
db_confirm(has,wings).
Так как программа хранит данные в таком виде, легко создать грамматически правильное предложение для предъявления его пользователю, просто поставив слово "оно" между глаголом и атрибутом. Структуру подобного типа можно увидеть и в правиле check_if.
Пользователь, вероятно, введет слова "да" или "нет" в ответ на запрос, а запоминающее правило введет информацию в базу данных посредством одного из двух предикатов:
db_confirm(verb,attribute)
db_denied(verb,attribute)
Поэтому если вы захотите перезапустить ПЗР (в такой форме), то нужно сначала очистить базу данных от ответов на вопросы, заданных при ведении последнего диалога. Они продолжают находиться в базе данных и будут влиять на следующие результаты, если их не удалить или не перезапустить программу.
Программа ПЗР производит выбор среди множества гипотез. Сначала каждое животное должно рассматриваться как отдельная гипотеза. В любой момент времени программа работает только с одной гипотезой. Прежде чем перейти к следующей гипотезе, она полностью подтверждает или опровергает предыдущую и, естественно, никогда не возвращается к тому месту, где уже была.
Задание
1. Сформировать собственную базу правил (не менее 20 правил) в произвольной предметной области на основе собственных знаний или знаний эксперта.
2. Написать программный модуль на Прологе, реализующий вышеприведенный алгоритм.
Содержание отчета
Описание работы программы. Листинг программы с комментариями. Пример работы системы.
Контрольные вопросы
1. Что такое символьная и числовая обработка ?
2. Каковы отличительные особенности ЭС ?
3. Что такое продукционная система, база правил, рабочая память ?
4. Как работает механизм вывода (интерпретатор правил) в Прологе?
5. Что такое обратный вывод ?
6. Как представляются факты и правила на языке Пролог?