Пример 9.11. Правило no-repairs


 

(defrule no-repairs ""

(declare (salience -10) )

(not (repair ?) )

= >

(assert (repair "Take your car to a mechanic."))

)

 

Обратите внимание на использование приоритета при определении этого правила. Все правила, приведенные в предыдущем разделе, определялись с приоритетом, по умолчанию равным нулю. Использование для правила no-repairs приоритета, равного —10, гарантирует, что правило не будет вы­полнено, пока в плане решения задачи находится, по крайней мере, одно из диагностических правил. Если все активированные диагностические прави­ла отработали и ни одно из них не смогло подобрать подходящую рекомен­дацию по устранению неисправности, то CLIPS запустит правило no-repairs, которое просто порекомендует пользователю обратиться к более опытному механику.

Реализация правил 2 и 3 приведена ниже.

 

Пример 9.12. Правила normal-engine-state-conclusions и unsatisfactory-engine-state-conclusions

 

(defrule normal-engine-state-conclusions ""

(declare (salience 10) )

(working-state engine normal)

=>

(assert (repair "No repair needed."))

(assert (spark-state engine normal))

(assert (charge-state battery charged))

(assert (rotation-state engine rotates))

)

(defrule unsatisfactory-engine-state-conclusions ""

(declare (salience 10))

(working-state engine unsatisfactory)

=>

(assert (charge-state battery charged))

(assert (rotation-state engine rotates))

)

В этих правилах, наоборот, используется более высокий приоритет, что га­рантирует их выполнение до выполнения любого диагностического правила (естественно, только в случае удовлетворения условий, заданных в левой части правил). Это избавит нашу систему от лишних проверок, а пользова­теля от лишних вопросов.

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

Пример 9.13. Правила system-banner и print-repair

 

(defrule system-banner ""

(declare (salience 10))

=>

(printout t crlf crlf)

(printout t "**********************************" crlf)

(printout t "* The Engine Diagnosis Expert System *" crlf)

(printout t "**********************************" crlf)

(printout t crlf crlf)

)

(defrule print-repair ""

(declare (salience 10))

(repair ?item)

=>

(printout t crlf crlf)

(printout t "Suggested Repair:")

(printout t crlf crlf)

(format t " %s%n%n%n" ?item)

)

 

Листинг программы

 

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

Пример 9.14. Полный листинг программы

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

; Пример экспертной системы на языке CLIPS

;

; Приведенная ниже экспертная система способна

; диагностировать некоторые неисправности автомобиля и

; предоставлять пользователю рекомендации по устранению

; неисправности.

;

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

 

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

; Вспомогательные функции

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - -

; Функция ask-question задает пользователю вопрос, полученный

; в переменной ?question, и получает от пользователя ответ,

; принадлежащий списку допустимых ответов, заданному в $?allowed-values

(deffunction ask-question (?question $?allowed-values)

(printout t ?question)

(bind ?answer (read))

(if (lexemep ?answer)

then

(bind ?answer (lowcase ?answer)))

(while (not (member ?answer ?allowed-values)) do

(printout t ?question)

(bind ?answer (read))

(if (lexemep ?answer)

then

(bind ?answer (lowcase ?answer))))

?answer

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Функция yes-or-no-p задает пользователю вопрос, полученный

; в переменной ?question, и получает от пользователя ответ yes(у) или

; по(n). В случае положительного ответа функция возвращает значение TRUE,

; иначе — FALSE

(deffunction yes-or-no-p (?question)

(bind ?response (ask-question ?question yes no у n))

(if (or (eq ?response yes) (eq ?response y))

then

TRUE

else

FALSE)

)

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

; Диагностические правила

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-engine-state определяет текущее состояние двигателя

; машины по ответам, получаемым от пользователя. Двигатель может

; находиться в одном из трех состояний: работать нормально

; (working-state engine normal) , работать неудовлетворительно

; (working-state engine unsatisfactory) и не заводиться

; (working-state engine ;does-not-start) (см. правило 1).

(defrule determine-engine-state ""

(not (working-state engine ?) )

(not (repair ?) )

=>

(if (yes-or-no-p "Does the engine start (yes/no) ? ")

then

(if (yes-or-no-p "Does the engine run normally (yes/no)? ")

then

(assert (working-state engine normal) )

else

(assert (working-state engine unsatisfactory) ) )

else

(assert (working-state engine does-not-start) ) )

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-rotation-state определяет состояние вращения двигателя по ответу,

; получаемому от пользователя. Двигатель может вращаться (rotation-state engine rotates)

; или не вращаться (spark-state engine does-not-spark) (см. правило 4).

; Кроме того, правило делает предположение о наличии плохой искры

; или ее отсутствии в системе зажигания

(defrule determine-rotation-state ""

(working-state engine does-not-start)

(not (rotation-state engine ?))

(not (repair ?))

=>

(if (yes-or-no-p "Does the engine rotate (yes/no)? ")

then

; Двигатель вращается

(assert (rotation-state engine rotates))

; Плохая искра

(assert (spark-state engine irregular-spark))

else

; Двигатель не вращается

(assert (rotation-state engine does-not-rotate))

; Нет искры

(assert (spark-state engine does-not-spark)))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-gas-level по ответу пользователя определяет

; наличие топлива в баке. В случае если топлива нет, пользователю

; выдается рекомендация по ремонту машину необходимо заправить

; (repair "Add gas.") (см. правило 5) . При появлении соответствующей

; рекомендации выполнение диагностических правил прекращается.

(defrule determine-gas-level ""

(working-state engine does-not-start)

(rotation-state engine rotates)

(not (repair ?) )

=>

(if (not (yes-or-no-p "Does the tank have any gas in it (yes/no) ? ") )

then

; Машину необходимо заправить

(assert (repair "Add gas.")))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-battery-state по ответу пользователя определяет,

; заряжен ли аккумулятор. В случае если это не так, пользователю

; выдается рекомендация по ремонту — Зарядите аккумулятор (repair

; "Charge the battery.") (см. правило 6) .

; Кроме того, правило добавляет факт, описывающий состояние аккумулятора.

; Выполнение диагностических правил прекращается

(defrule determine-battery-state ""

(rotation-state engine does-not-rotate}

; Состояние аккумулятора еще не определено

(not (charge-state battery ?))

(not (repair ?))

=>

(if (yes-or-no-p "Is the battery charged (yes/no)? ")

then

; Аккумулятор заряжен

(assert (charge-state battery charged))

else

; Зарядите аккумулятор

(assert (repair "Charge the battery."))

; Аккумулятор разряжен

(assert (charge-state battery dead)))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-low-output определяет, развивает ли двигатель

; нормальную выходную мощность или нет и добавляет в систему факт,

; описывающий эту характеристику (см. правило 12).

(defrule determine-low-output ""

(working-state engine unsatisfactory)

; Мощность работы двигателя еще не определена

(not (symptom engine low-output | not-low-output))

(not (repair ?))

=>

(if (yes-or-no-p "Is the output of the engine low (yes/no)? ")

then

; Низкая выходная мощность двигателя

(assert (symptom engine low-output))

else

; Нормальная выходная мощность двигателя

(assert (symptom engine not-low-output)))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-point-surface-state определяет по ответу

; пользователя состояние контактов (см. правила 7, 12). Контакты могут

; находиться в одном из трех состояний: чистые, опаленные и

; загрязненные. В двух последних случаях пользователю выдаются

; соответствующие рекомендации.

; Выполнение диагностических правил прекращается.

(defrule determine-point-surfасе-state ""

(or (and (working-state engine does-not-start);не заводится

(spark-state engine irregular-spark));и плохая искра

(symptom engine low-output));или низкая мощность

(not (repair ?))

=>

(bind ?response (ask-question "What is the surface state of the

points (normal /burned /contaminated)?"

normal burned contaminated))

(if (eq ?response burned)

then

; Контакты опалены — замените контакты

(assert (repair "Replace the points."))

else

(if (eq ?response contaminated)

then

; Контакты загрязнены - почистите их

(assert (repair "Clean the points."))))

)

 

 

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-conductivity-test по ответу пользователя определяет,

; пропускает ли ток катушка зажигания. Если нет, то ее следует заменить.

; Если пропускает, то причина неисправности — распределительные провода.

; Для нормальной работы правила необходимо убедиться, что аккумулятор

; заряжен и искры нет (см. правило 8)

; Выполнение диагностических правил прекращается.

(defrule determine-conductivity-test ""

(working-state engine does-not-start)

(spark-state engine does-not-spark) ;нет искры

(charge-state battery charged) ;аккумулятор заряжен

(not (repair ?) )

=>

(if (yes-or-no-p "Is the conductivity test for the ignition coil positive (yes/no) ? ")

then

; Замените распределительные провода

(assert (repair "Repair the distributor lead wire."))

else

; Замените катушку зажигания

(assert (repair "Replace the ignition coil.")))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-sluggishness спрашивает пользователя, не ведет ли

; себя машина инертно (не сразу реагирует на подачу топлива) .

; Если такой факт обнаружен, то необходимо прочистить

; топливную систему (см. правило 9) и выполнение диагностических правил

; прекращается.

(defrule determine-sluggishness ""

(working-state engine unsatisfactory)

(not (repair ?))

=>

(if (yes-or-no-p "Is the engine sluggish (yes/no)? ")

then

; Прочистите систему подачи топлива

(assert (repair "Clean the fuel line.")))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-misfiring узнает — нет ли перебоев с зажиганием.

; Если это так, то необходимо отрегулировать зазоры между контактами

; (см. правило 10).

; Выполнение диагностических правил прекращается.

(defrule determine-misfiring ""

(working-state engine unsatisfactory)

(not (repair ?))

=>

(if (yes-or-no-p "Does the engine misfire (yes/no)? ")

then

; Отрегулируйте зазоры между контактами

(assert (repair "Point gap adjustment."))

; Плохая искра

(assert (spark-state engine irregular-spark)))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило determine-knocking узнает — не стучит ли двигатель.

; Если это так, то необходимо отрегулировать зажигание (см. правило 11).

; Выполнение диагностических правил прекращается.

(defrule determine-knocking ""

(working-state engine unsatisfactory)

(not (repair ?))

=>

(if (yes-or-no-p "Does the engine knock (yes/no)? ")

then

; Отрегулируйте положение зажигания

(assert (repair "Timing adjustment.")))

)

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

; Правила, определяющие состояние некоторых подсистем автомобиля

; по характерным состояниям двигателя

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило normal-engine-state-conclusions реализует правило 2

(defrule normal-engine-state-conclusions ""

(declare (salience 10))

; Если двигатель работает неудовлетворительно

(working-state engine normal)

=>

; то

(assert (repair "No repair needed.")) ; ремонт не нужен

(assert (spark-state engine normal)) ; зажигание в норме

(assert (charge-state battery charged)) ; аккумулятор заряжен

(assert (rotation-state engine rotates)) ; двигатель вращается

)

; Правило unsatisfactory-engine-state-conclusions реализует правило 3

(defrule unsatisfactory-engine-state-conclusions ""

(declare (salience 10))

; Если двигатель работает нормально

(working-state engine unsatisfactory)

=>

; то

(assert (charge-state battery charged)) ; аккумулятор заряжен

(assert (rotation-state engine rotates)) ; двигатель вращается

)

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ; Запуск и завершение

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило no-repairs запускается в случае, если ни одно

; из диагностических правил не способно определить неисправность.

; Правило корректно прерывает выполнение экспертной системы и предлагает

; пройти более тщательную проверку (см. правило 13).

(defrule no-repairs ""

(declare (salience -10))

(not (repair ?))

=>

(assert (repair "Take your car to a mechanic."))

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило print-repair выводит на экран диагностическое сообщение

; по устранению найденной неисправности,

(defrule print-repair ""

(declare (salience 10))

(repair ?item)

=>

(printout t crlf crlf)

(printout t "Suggested Repair:")

(printout t crlf crlf)

(format t " %s%n%n%n" ?item)

)

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Правило system-banner выводит на экран название экспертной системы

; при каждом новом запуске.

(defrule system-banner " каждом новом запуске."

(declare (salience 10) )

=>; каждом новом запуске.

(printout t crlf crlf)

(printout t "********************************************" crlf)

(printout t "* The Engine Diagnosis Expert System *" crlf)

(printout t "**********************************" crlf)

(printout t crlf crlf)

)

Помните, что среда CLIPS (по крайней мере, последняя версия 6.20) вос­принимает только символы английского алфавита. Все комментарии в при­веденном листинге даны на русском языке для наглядности, однако при вводе программы в таком виде CLIPS выведет сообщение об ошибке.

Запуск программы

 

Для запуска программы наберите приведенный в примере 9.14 листинг в каком-нибудь текстовом редакторе (лучше использовать встроенный ре­дактор CLIPS по причинам, упоминавшимся в гл. 6). Сохраните набранный файл, например, с именем auto.CLP.

После этого запустите CLIPS или, если он уже был у вас запущен, очистите его командой (clear). Загрузите созданный вами файл с помощью команды (load "auto.CLP"). Если файл был набран без ошибок, то вы должны уви­деть сообщения, представленные на рис. 9.1.

Рис. 9.1 демонстрирует успешную попытку загрузки файла конструкторов. Обратите внимание, что функция load вернула значение true. Если это нетак, значит, в синтаксисе определений функций или правил была допущена ошибка. Для загрузки вы также могли бы воспользоваться функцией load*. В этом случае на экран не выводилась бы информация, отражающая про­цесс загрузки.

 

 

Рис. 9.1.Загрузка экспертной системы

После удачной загрузки файла убедитесь, что все правила присутствуют в списке правил CLIPS, а функции — в списке функций. Легче всего это вы­полнить с помощью менеджеров правил и функций соответственно. Внеш­ний вид этих менеджеров показан на рис. 9.2 и 9.3.

Для того чтобы запустить нашу экспертную систему, достаточно выполнить команду reset, которая добавит факт initial-fact, необходимый для прави­ла system-banner, и команду run. После этого вы сразу увидите сообщение "The Engine Diagnosis Expert system", которое означает, что система начала работать, и получите серию вопросов, ответы на которые помогут эксперт­ной системе оценить текущее состояние вашей машины и подобрать соот­ветствующую рекомендацию по ремонту. Пример работы системы показан на рис. 9.4.

Обратите внимание, что если после завершения работы нашей экспертной системы в списке фактов CLIPS остаются факты, описывающие состояние автомобиля, их легко просмотреть с помощью команды Fact Windowиз ме­ню Window.Факты для нашего примера изображены на рис. 9.5.

 

 

Рис. 9.2. Правила экспертной системы

 

Рис. 9.3.Функции экспертной системы

 

Для повторного запуска экспертной системы необходимо еще раз выпол­нить команды reset и run. Протестируйте экспертную систему, по-разному отвечая на ее вопросы. Чтобы лучше понять механизмы ее работы и логический механизм вывода CLIPS, перед запуском системы сделайте видимым окно фактов (Fact Window)и окно плана решения задачи (Agenda Window).

Приведенный в этой главе пример доступен в Интернете по адресу: www.ghg.net/clips/download/executables/examples/auto.clp.

 

Рис. 9.4.Диалог с экспертной системой

 

Рис. 9.5.Результаты работы экспертной системы

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

 




Дата добавления: 2021-12-14; просмотров: 242;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.055 сек.