Процедурные знания
Помимо эвристической, CLIPS поддерживает и процедурную парадигму представления знаний, используемую в большинстве языков программирования. Конструкторы deffunction и defgeneric позволяют пользователю определять новые выполняемые конструкции непосредственно в среде CLIPS, возвращающие некоторые значения или выполняющие какие-то полезные действия. Вызов этих новых функций ничем не отличается от вызова встроенных функций CLIPS. Обработчики сообщений позволяют пользователю определять поведение объектов, с помощью задания той или иной реакции на сообщения. Функции, родовые функции и обработчики сообщений представляют собой отрезки кода, заданного пользователем и выполняемого, в случае необходимости, интерпретатором CLIPS. Кроме того, механизм модулей (конструктор defmodule, см. гл. 12) позволяет разбивать базу знаний CLIPS на отдельные смысловые части. Функции Конструктор deffunction позволяет создавать новые функции непосредственно в CLIPS. Более ранние версии CLIPS позволяли использовать только внешние пользовательские функции, написанные на каком-нибудь языке программирования (чаще всего Си) и присоединенные к среде CLIPS. Тело функции, определенной с помощью конструктора deffunction, представляет собой последовательность действий, подобную используемой в правой части правил. Заданные пользователем действия выполняются при вызове соответствующей функции. Значение, возвращаемое функцией, является результатом вычисления последнего действия. Подробно тема функций освящена в гл. 7. Родовые функции Родовые функции, так же как и обычные функции, могут быть созданы непосредственно в CLIPS. Способ вызова таких функций также ничем не отличается от способа вызова обычных функций. Однако родовые функции гораздо мощнее обычных, т. к. они способны перегружаться. Благодаря механизму перегрузки родовая функция может выполнять различные действия в зависимости от типа и числа аргументов. Обычно родовая функция состоит из нескольких компонентов, называемых методами. Каждый метод содержит различный набор аргументов родовой функции. Например, можно перегрузить системную функцию + (арифметическое сложение) для выполнения операции конкатенации двух строк. Однако после этого функция + все еще сможет выполнять арифметическое сложение. В данном примере у родовой функции + существует два метода: первый метод явно определен пользователем для конкатенации двух строк, второй представляет собой неявный вызов стандартной функции, выполняющей арифметическое сложение. Значение, возвращенное родовой функцией, является значением, полученным в результате вычисления последнего действия в применяемом методе. Обработчики сообщений Как уже упоминалось, объект CLIPS состоит из двух основных частей — свойств объекта и его поведения. Свойства объектов определяются в терминах слотов. Поведение объекта обуславливается обработчиками сообщений, которые являются присоединенной к классу последовательностью действий с заданным именем. Любые манипуляции с объектом можно выполнить только с помощью сообщений. Например, в случае уже упоминавшегося объекта Rolls-Royce, являющегося экземпляром пользовательского класса car, для того чтобы запустить двигатель, пользователь должен послать объекту сообщение start-engine с помощью функции send. To, каким образом объект Rolls-Royce прореагирует на это сообщение, зависит от определения обработчика сообщения start-engine, связанного с классом car. Назначение обработчиков сообщений в принципе эквивалентно назначению любой функции — возвращение результата или выполнение неких полезных действий. Более подробно тема объектов раскрывается в гл. 11. Модули Модули позволяют разбивать базу знаний на отдельные смысловые части. Каждый вызываемый конструктор помещается в определенный модуль. Программист имеет возможность контролировать возможности доступа и видимость конструкторов в тех или иных модулях. Кроме того, для модулей можно устанавливать видимость определенных фактов или объектов. Модули можно использовать для контроля или изменения потока выполнения правил. Подробное описание модулей приведено в гл. 12.
|