(deffunction yes-or-no-p (?question)
(bind?response (ask-question?guestion yes no у n))
(if (or (eq?response yes) (eq?response y))
then
TRUE
else
FALSE)
)
Функция yes-or-no-p вызывает функцию ask-question с постоянным набором допустимых ответов: yes, no, у и n. В случае если пользователь ввел ответ yes или у, функция возвращает значение true, иначе — false. Обратите внимание, что поскольку функция yes-or-no-p использует функцию ask-question, то она должна быть определена после нее.
Диагностические правила
Для упрощения реализации нашей экспертной системы введем следующее ограничение: за один запуск система может предоставить пользователю только одну рекомендацию по исправлению неисправности. В случае если в машине несколько неисправностей, то систему нужно будет последовательно вызывать несколько раз, удаляя обнаруженную на каждом новом шаге неисправность.
Таким образом, одним из образцов всех диагностических правил будет (not (repair?)), гарантирующий, что диагноз еще не поставлен.
Первым реализуем правило, определяющее общее состояние двигателя (см. правило 1).
Пример 9.6. Правило determine-engine-state
(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)))
)
Условный элемент (not (working-state engine?)) гарантирует, что общее состояние двигателя еще не определено. Если это так, то пользователю задаются соответствующие вопросы и в систему добавляется факт, описывающий текущее общее состояние двигателя.
Теперь реализуем правило, определяющее, пытается ли двигатель вращаться, в случае если он не заводится.