Иллюстрированный самоучитель по введению в экспертные системы

Объектно-ориентированные средства в CLIPS

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

(defmessage-handler pistol rack ()
(if (> (dynamic-get rounds) 0) then (dynamic-put chamber 1)
(dynamic-put rounds (– (dynamic-get rounds) 1))
(dynamic-put slide forward) else (dynamic-put chamber 0)
(dynamic-put slide back)

В этом обработчике обеспечивается досылка патрона в патронник в том случае, если в обойме имеются патроны. Следующее правило подготавливает пистолет к стрельбе, снимая его с предохранителя. Обратите внимание на то, что в нем повторно используется сообщение safety, но на этот раз с аргументом off.

(defrule ready
(object (name [PPK]) (chamber 1)) ›
(send [PPK] safety off))

Правило fire выполняет стрельбу.

(defrule fire
(object (name [PPK]) (safety off);
?T ← (range-test (fired no)) ›
(if (eq (send [PPK] fire) TRUE)
then (modify?T (fired yes))))

Обратите внимание, что в данном правиле используется обработчик сообщения, которое возвращает значение. Анализируя его, можно выяснить, произведен ли выстрел, т.е. выполнена ли в действительности та операция, которая "закреплена" за этим сообщением. Если в патроннике был патрон и пистолет был снят с предохранителя, то обработчик сообщения вернет значение TRUE (после того, как выведет на экран BANG!). В противном случае он вернет FALSE (после того, как выведет на экран click).

(def message-handler pistol fire () (if (and
(eq (dynamic-get chamber) 1) (eq (dynamic-get safety) off)
)
then (printout t crlf "BANG!" t crlf)
TRUE
else (printout t crlf "click" t crlf) FALSE
)

Пусть вас не смущает, что в обработчике сообщения анализируется условие, которое уже было проанализировано правилом, отославшим сообщение (в данном случае речь идет об условии safety off). Дело в том, что одно и то же сообщение может отсылаться разными правилами и нет никакой гарантии, что в каждом из них будет проверяться это условие.

После завершения стрельбы пистолет нужно вновь вернуть в положение "по-походному". Начинается это с того, что пистолет устанавливается на предохранитель, для чего используется ранее разработанный обработчик сообщения safety.

(defrule unready
(object (name [PPK]) (safety off))
(range-test (fired yes)) ›
(send [PPK] safety on))

Следующая операция – вынуть обойму. Обратите внимание, что в нем мы вновь обращается к обработчику сообщения drop.

(defrule drop
(object (name [PPK]) (safety on))
(range-test (fired yes)) ›
(send [PPK] drop))

Последнее правило выбрасывает патрон из патронника, вызывая обработчик сообщения clear.

(defrule unload
(object (name [PPK]) (safety on) (magazine out))
(range-test (fired yes)) ›
(send [PPK] clear))

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

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

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