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

Значения по умолчанию и демоны

Перейдем к следующему уровню в иерархии фреймов. Для фрейма Четырехугольник совершенно очевидно нужно установить значение 4 в слот Количество сторон. Это значение будет наследоваться фреймами на каждом из последующих уровней иерархии. Вычислять площадь и цену всех фигур, представленных фреймами последующих уровней, можно тем же способом, что и для многоугольника. Поэтому описанные выше демоны также могут быть унаследованы всеми последующими фреймами.

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

Эта эвристика может быть реализована в виде демона по требованию, подсоединенного к слоту Площадь фрейма Четырехугольник. Такой демон должен выполнять следующее:

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

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

Этот простой пример демонстрирует, как, используя значения по умолчанию и демоны, можно заполнить слоты иерархической системы фреймов, причем этот механизм оказывается более удобным, чем тот, который используется в структурах записей языка PASCAL. Данные, процедуры и определения оформляются в виде единого пакета и образуют отдельный модуль для каждого фрейма, причем разные модули могут совместно использовать данные и процедуры, пользуясь механизмом наследования.

Реализация фреймов и наследования в языке CLIPS

Хотя язык CLIPS и не поддерживает в явном виде формализм семантических сетей и фреймов, их можно неявно определить, используя имеющуюся в CLIPS конструкцию def class. Мы более подробно поговорим об этой конструкции в следующей главе, поскольку ее основное назначение – реализация объектно-ориентированного подхода. Для представления иерархии геометрических объектов, показанной на рис. 6.6, нам понадобятся следующие определения:

(defclass polygon (is-a USER))
(defclass quadrilateral (is-a polygon))
(defclass trapezium (is-a quadrilateral))
(defclass parallelogram (is-a trapezium))
(defclass rectangle (is-a parallelogram))
(defclass square (is-a rectangle))

Обратите внимание на то, что класс polygon (многоугольник) объявлен как подкласс класса USER, который является базовым для всех классов, объявленных пользователем. Отношение is-a (является), которое фигурирует во всех языках представления фреймов, обычно обладает свойством транзитивности: квадрат является прямоугольником, но квадрат также является и трапецией и т.д. Это отношение является антисимметричным, т.е. если квадрат является прямоугольником, то прямоугольник в общем случае не является квадратом.

Для того чтобы представить на языке CLIPS тот факт, что большинство многоугольников предположительно должно иметь четыре стороны, потребуются кое-какие дополнительные языковые конструкции. Нужно будет несколько изменить определение классов polygon и quadrilateral:

(defclass polygon (is-a USER)
(role abstract)
(slot no-of-sides (default 4)))
(defclass quadrilateral (is-a polygon)
(role concrete))

Теперь polygon объявлен как абстрактный класс, т.е. класс, не способный самостоятельно порождать определенные объекты. Его подкласс quadrilateral и все последующие подклассы класса quadrilateral являются конкретными классами, т.е. эти классы могут порождать конкретные экземпляры (объекты классов). При определении класса polygon его слоту no-of-sides (количество сторон) назначено по умолчанию значение 4. Это отражает наше интуитивное предположение, что большинство многоугольников будет четырехугольниками. В терминологии систем фреймов такое значение по умолчанию называется фацетом слота no-of-sides.

После этого можно приступить к описанию демонов. Для этого нужно воспользоваться конструкцией defmessage-handler, которая имеется в CLIPS. (Подробно конструкция defmessage-handler также будет описана в следующей главе.)

(defmessage-handler polygon sides ()?self:no-of-sides)

Демон sides связан с классом polygon и попросту получает доступ к слоту no-of-sides того объекта, который его вызвал. Предположим, например, что определен конкретный участок, имеющий форму квадрата, причем ему присвоено наименование square-one.

(definstances geometry (square-one of square))

Система инициализируется командой (reset). Теперь можно активизировать демон, послав ему сообщение:

(send [square-one] sides)

В ответ интерпретатор CLIPS выведет результат.

Обратите внимание на то, что выражение ?self:no-of-sides вычисляется в контексте объекта square-one, которому было направлено сообщение и который в ответ на него активизировал демона. В этом выражении ?self является переменной и определяет объект, к слоту которого производится обращение, а двоеточие – это инфиксный оператор доступа к конкретному слоту.

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