Главная страница
Навигация по странице:

  • Window–>All Above. Данная команда открывает окна Facts

  • 126 Для загрузки содержимого файла в базу знаний CLIPS, нужно воспользоваться пунктом Load

  • Execution →→→→Reset

  • Execution →→→→Run

  • 131 Факты представляются в двух форматах позиционные и непози- ционные . Позиционные факты

  • 149 Пример 5: (defclass Е (is-a АС) В соответствии с правилом 2, А должен быть старше СВ нашем случае, С – это потомок Аи является более старшим в соответствии с правилом 1. Ошибка. Пример 6

  • кр. Ю. Ю. Громов, О. Г. Иванова, В. В. Алексеев, М. П. Беляев, Д. П. Швец, аи. Елисеев интеллектуальные информационные системы и технологии


    Скачать 2.03 Mb.
    НазваниеЮ. Ю. Громов, О. Г. Иванова, В. В. Алексеев, М. П. Беляев, Д. П. Швец, аи. Елисеев интеллектуальные информационные системы и технологии
    Дата17.02.2023
    Размер2.03 Mb.
    Формат файлаpdf
    Имя файлаgromov2-a.pdf
    ТипДокументы
    #941483
    страница14 из 20
    1   ...   10   11   12   13   14   15   16   17   ...   20

    5. ОСНОВЫ РЕАЛИЗАЦИИ ИНТЕЛЛЕКТУАЛЬНЫХ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ НА ЯЗЫКЕ CLIPS
    5.1. Основные теоретические сведения
    CLIPS использует продукционную модель представления знаний, которая реализуется следующими основными компонентами языка описания правил база фактов (fact base); база правил (rule base); блок вывода (машина логического вывода. На них возлагаются следующие функции база фактов представляет исходное состояние проблемы, база правил содержит операторы, которые преобразуют состояние проблемы, приводя его к решению. Машина логического вывода CLIPS сопоставляет эти факты и правила и выясняет, какие из правил можно активизировать. Это выполняется циклически, причём цикл состоит из трёх шагов сопоставление фактов и правил выбор правила, подлежащего активизации выполнение действий, предписанных правилом.

    125 Такой трёхшаговый циклический процесс иногда называют циклом распознавание–действие». Принципиальным отличием данной системы от аналогов является то, что она полностью реализована на языке C. Причём исходные тексты её программ опубликованы в Интернет. В CLIPS используется оригинальный подобный язык программирования, ориентированный на разработку экспертных систем (ЭС). CLIPS поддерживает две парадигмы программирования объектно-ориентированную и процедурную. Основными элементами технологии программирования в CLIPS являются три основных элемента простые типы данных конструкции для пополнения базы знаний функции для манипулирования данными
    [4 – 7]. Для представления информации в CLIPS предусмотрено восемь простых типов данных float, integer, symbol, string, external-address, fact-address, instance-name, instance-address. При записи числа используются цифры (0 – 9), десятичная точка, знаке. Любое число, состоящее только из цифр, перед которыми стоит знак, сохраняется как целое (В CLIPS – integer, в C – long integer). Все остальные числа сохраняются как float (в C – double float). Symbol – последовательность символов кода ASCII, причём как только в этой последовательности встречается символ-разделитель, symbol заканчивается. Символы-разделители: пробел, табуляция, двойные кавычки,
    ( , ), &, |, <, >,

    , ;.
    String – последовательность символов, заключённых в двойные кавычки ("a and b"). Причём, если внутри строки встречаются двойные кавычки, то передними надо поместить символ (\) ("a and \"b"). Язык CLIPS является чувствительным к регистру Например, такие символы рассматриваются в языке CLIPS как различные case–sensitive Case–Sensitive CASE–SENSITIVE Для того чтобы иметь возможность наблюдать за всеми изменениями, происходящими в состоянии CLIPS, предусмотрена команда
    Window–>All Above. Данная команда открывает окна Facts (содержит факты из списка фактов) и Agenda (содержит все правила из списка активных правил. Ввести команду в CLIPS можно непосредственно из диалогового окна, появившегося после запуска. Нов этом случае написанные правила после закрытия CLIPS будут потеряны. Поэтому текст программы необходимо сохранить в файле. В CLIPS имеется встроенный редактор.

    126 Для загрузки содержимого файла в базу знаний CLIPS, нужно воспользоваться пунктом Load меню File. Для того чтобы CLIPS активизировал начальный факт (initial-fact с идентификатором F-0) необходимо выбрать Execution_→→→→Reset'>Execution




    Reset. Данная команда удаляет существующие факты из списка фактов, включает в список фактов исходный факт (initial-fact), включает в список фактов все факты, описанные в конструкциях (deffacts). Затем, по команде Execution




    Run CLIPS начнёт выполнение всех правил программы. Для сохранения протокола работы программы, а также получения ответа в текстовом файле необходимо сразу после запуска CLIPS выполнить команду File




    Turn Dribble On ив диалоговом окне ввести имя файла, в который будет сохраняться содержимое главного окна CLIPS. После окончания работы программы выполнить
    Turn Dribble Off, по этой команде файл для вывода будет закрыт. Элементы математической логики. Логика высказываний. При решении логических задач с помощью экспертных систем в CLIPS предусмотрена возможность применения математического аппарата алгебры высказываний, позволяющего представлять факты и правила в виде логических выражений. Под высказыванием p понимается всякое утвердительное предложение, относительно которого можно сделать заключение, истинно оно или нет. Содержанием высказывания не интересуются, интерес представляет лишь истинность или ложность высказывания. Высказывание считается истинным, если оно равно 1, ложным – если оно равно. Над высказываниями можно производить логические операции для высказываний X и Y): Отрицание (¬X) – высказывание, которое истинно тогда и только тогда, когда X ложно. В разговорной речи высказыванию ¬X соответствуют фразы не X», неверно, что X». Конъюнкция (XY) – логическое умножение. Высказывание, которое истинно тогда и только тогда, когда истинны оба высказывания. В разговорной речи ей соответствует союз и (XY – «X и Y»). Дизъюнкция (XY) – логическое сложение. Высказывание, которое истинно тогда и только тогда, когда ложны оба высказывания. В разговорной речи ей соответствует союз или (XY – «X или Y»). Импликация (XY) – логическое следование. Высказывание, которое ложно тогда только тогда, когда X – истинно, а Y – ложно. В разговорной речи импликации соответствуют следующие высказывания только тогда, когда Y», из X следует Y», если X то Y». При этом X – посылка, а Y – заключение.

    127
    5.1. Таблица истинности для логических операций А В А В
    А∧В
    А∨В
    А→В
    А↔В И ИЛЛ И И И И ИЛЛ ИЛИ Л Л ЛИ ИЛЛ И ИЛЛ ЛИ ИЛЛ И И
    4. Эквиваленция (XY) – высказывание, которое истинно тогда и только тогда, когда истинностные значения высказываний X и Y совпадают. В разговорной речи эквиваленция соответствует высказываниям вида «X эквивалентно Y», «X тогда и только тогда, когда Y»,
    «X необходимо и достаточно для Y». Таблицей истинности логических операций называется таблица, в которой отражены результаты операций на всех возможных наборах значений высказываний (табл. 5.1). При помощи рассмотренных операций возможно создавать комбинации из высказываний. Для сложных высказываний, можно создавать комбинации, построенные из нескольких исходных высказываний посредством применения логических операций ¬, ∧, ∨, →, ↔. Их называют формулами алгебры высказываний. При вычислении по формуле учитывается приоритет логической операции. Перечисленные выше логические операции расположены в порядке убывания приоритета. Изменить порядок логических высказываний можно с помощью расстановки скобок. Исходные высказывания могут быть постоянными, то есть иметь определённые значения истина или ложь. Если элементарное высказывание не имеет определённого значения, то это переменное высказывание. Например А:=«Джек лает, Джек любит кости
    C:=AB (Джек лает и любит кости) – это постоянное высказывание
    2) Собака (X) лает, Собака (X) любит кости
    С(Х):=А(Х)В(Х) (Собака с именем X лает и любит кости) это переменное высказывание Пропозициональной формулой (ПФ называется логическое выражение, содержащее переменные, соответствующие логическим высказываниям, константы и логические операции ¬, ∨, ∧, →, ↔,

    128 называемые пропозициональными связками, скобки (,), используемые для определения приоритета операций. ПФ определяется индуктивно следующим образом
    1. Отдельно взятая переменная (высказывание) и константа
    (0, 1) – это ПФ.
    2. Если Аи В, составленные из допустимых символов, – ПФ, то и
    ¬A, В, A

    B, A

    B, A→B, A↔B – тоже ПФ. Никаких других ПФ, кроме образованных по правилу 2, нет. Пример

    p

    q

    r→p – пропозициональная формула р →˅p – непропозициональная формула Таблицей истинности для ПФ является перечень значений данной ПФ при всех возможных значениях входящих вне переменных. Пропозициональная формула называется тавтологией, если на всех значениях входящих вне переменных она равна 1. Обозначение А пропозициональная формула А есть тавтология.
    Приведём ряд тавтологий, могущих оказаться полезными при преобразовании высказываний. Закон двойного отрицания |=¬р↔р (1) Закон исключенного третьего |= р

    ¬р (2)
    Идемпотентность операций дизъюнкции и конъюнкции
    |

    р↔р (3)
    |= р

    р р (4) риз конъюнкции |= р

    qр (5) риз дизъюнкции |= р (6) Коммутативность операций дизъюнкции и конъюнкции
    |= р

    q↔q

    р (7)
    |= р

    q↔q

    р (8) Ассоциативность операций дизъюнкции и конъюнкции
    |= (р) (9)
    |= (p

    q)

    rp

    (q

    r) (10) Разложение операций дизъюнкции и конъюнкции
    |= p

    (q

    r)(p

    q)

    (p

    r) (11)
    |= p

    (q

    r)↔(p

    q)

    (p

    r) (12) Правила де Моргана
    |=¬ (р) р (13)
    |=¬ (

    p)↔¬p

    ¬q (14) Закон контрапозиции: |=→p¬p→¬q (15) Транзитивность импликации |= (p→q)

    (qr) ↔pr (16) Закон косвенного доказательства |= (¬pq)

    (¬p→¬q)
    p
    (17)

    129 Закон разбора случаев |= (p

    q)

    (pr)

    (qr)→r
    (18) Транзитивность эквиваленции: |= (pq)

    (qr)→( pr) (19) Закон противоположности р (¬p¬q) (20) Представление единицы
    |= 1↔р

    ¬р (21)
    |= 1↔ рр (22) Представление нуля
    |=0↔ р

    ¬р (23)
    |=0↔¬(рр) (24) Представление импликации через дизъюнкцию и отрицание
    |= (pq)↔(¬р

    р) (25) Представление эквиваленции:
    |=(pq)↔(pq)

    (qp) (26)
    |=(p↔q)(¬p

    q)

    (p

    ¬q) (27)
    |=(p↔q)↔(p

    q)

    (¬p

    ¬q) (28) Представление конъюнкции |=p

    q↔¬(p→¬q) (29) Представление дизъюнкции |= p

    q↔(¬p→q) (30) При проектировании интеллектуальных информационных систем язык CLIPS предоставляет возможность применения эвристических алгоритмов поискав пространстве состояний. При этом большинство поисковых задач можно сформулировать как задачи поиска впростран- стве состояний пути от исходного состояния заданной задачи до целевого состояния путём повторения возможных преобразований. При этом для организации поискав пространстве состояний удобно использовать дерево поиска (или его более общую форму – граф. Одним из подобных алгоритмов поиска является так называемый алгоритм А, где используются априорные оценки стоимости пути до целевого состояния, что обеспечивает высокую эффективность поиска [3]. Основная идея алгоритма состоит в использовании для каждого узла n на графе пространства состояний оценочной функции вида
    f (n) = g(n) + h(n). Здесь соответствует расстоянию на графе от узла п до начального состояния, а h(n) – оценка расстояния от узла n до узла, представляющего конечное (целевое) состояние. Чем меньше значение оценочной функции f (n), тем лучше, те. узел n лежит на более коротком пути от исходного состояния к целевому. Идея алгоритма состоит в том, чтобы с помощью f (n) отыскать кратчайший путь на графе от исходного состояния к целевому. Алгоритм А*
    [3].
    Введём следующие обозначения
    s – узел начального состояния
    g – узел конечного (целевого) состояния

    130
    OPEN – список выбранных, но необработанных узлов
    CLOSED– список обработанных узлов. Шаги
    1. OPEN = {s}.
    2. Если OPEN:={}, то прекратить выполнение. Путь к целевому состоянию на графе не существует.
    3. Удалить из списка OPEN узел n, для которого f (n) ≤ f для любого узла туже присутствующего в списке и перенести его в список CLOSED.
    4. Сформировать список очередных узлов, в который возможен переход из узла n, и удалить из него все узлы, образующие петли с каждым из оставшихся связать указатель на узел n.
    5. Если в сформированном списке очередных узлов присутствует то завершить выполнение. Сформировать результат – путь, поро- ждённый прослеживанием указателей от узла g до узла s.
    6. В противном случае для каждого очередного узла n', включён- ного в список выполнить следующую последовательность операций
    6.1. Вычислить f (n').
    6.2. Если пне присутствует нив списке нив списке добавить его в список, присоединить к нему оценку f и установить обратный указатель на узел п
    6.3. Если n' уже присутствует всписке или в списке сравнить новое значение f (n')= new с прежним f (n') = old.
    6.4. Если old прекратить обработку нового узла.
    6.5. Если old > заменить новым узлом прежний всписке, прич м, если прежний узел был в списке перенести его в список
    OPEN.
    5.2. Особенности создания баз данных и правил на языке CLIPS При работе с CLIPS применяется понятие факта. Факт представляет собой основную единицу данных, используемую правилами. Факты помещаются в текущий список фактов fact-list. Количество фактов в списке и объём информации, содержащейся в факте, ограничивается только размером памяти компьютера [4 – 8]. Факт может описываться индексом или адресом. Всякий раз, когда факт добавляется (изменяется) ему присваивается уникальный целочисленный индекс. Индексы в fact-list начинаются с нуля. Идентификатор факта – это короткая запись факта, которая состоит из символа факта – f и индекса факта (f-10). Например f-0 (today is Sunday), f-1 (weather is warm).

    131 Факты представляются в двух форматах позиционные и непози-
    ционные. Позиционные факты
    – состоят из выражения символьного типа, за которым следует последовательность (возможно, пустая) из полей, разделённых пробелами. Вся запись заключается в скобки. Для того чтобы обратиться к информации, содержащейся в позиционном факте, пользователь должен знать, какие данные содержаться в факте ив каком поле они хранятся. Пример

    (altitude is 10000 feet)
    (grocery_list bread milk eggs)
    (today is Sunday)
    (weather is warm) Поля в позиционных фактах могут быть любого простого типа, за исключением первого поля, которое всегда должно быть типа symbol. В тексте программы факты можно включать в базу не поодиночке, а целым массивом. Для этого в CLIPS имеется команда deffacts.
    (deffacts today
    (today is Sunday)
    (weather is warm)) Выражение начинается с команды deffacts, затем приводится имя списка фактов, который программист собирается определить (в нашем примере – today), аза ним следуют элементы списка, причём их количество не ограничивается. Конструкция defclass. Прежде чем появится возможность создания экземпляров, в систему CLIPS необходимо передать информацию о списке допустимых слотов для данного конкретного класса. Для этой цели применяется конструкция defclass. В своей наиболее фундаментальной форме эта конструкция весьма напоминает конструкцию deftemplate [4 – 7]:
    (defclass []
    (is-a ) *) В этом определении терм определяет класс, от которого данный, вновь создаваемый класс должен наследовать информацию. Классом, от которого в конечном итоге наследуют информацию все определяемые пользователем классы, является системный класс USER. Определяемый пользователем класс должен наследовать информацию либо от другого определяемого пользователем класса,

    132 либо от класса USER. Синтаксическое описание определено следующим образом
    (slot *) | (multislot *) С помощью этого синтаксиса экземпляр PERSON может быть описан с использованием такой конструкции defclass:
    (defclass PERSON "PERSON defclass"
    (is-a USER)
    (slot full-name)
    (slot age)
    (slot eye-color)
    (slot hair-color)) При определении слотов конструкции defclass могут также применяться следующие атрибуты слота из конструкции deftemplate: type, range, cardinality, allowed-symbols, allowed-strings, allowed-Iexemes, al- lowed-integers, allowed-floats, allowed-numbers, allowed-values, allowed- instance-names, default и default-dynamic. Пример применения таких атрибутов
    (defclass PERSON "PERSON defclass"
    (is-a USER)
    (slot full-name
    (type STRING))
    (slot age
    (type INTEGER)
    (range 0 120))
    (slot eye-color
    (type SYMBOL)
    (allowed-values brown blue green)
    (default brown))
    (slot hair-color
    (type SYMBOL)
    (allowed-values black brown red blonde)
    (default brown))
    ) Атрибуты слота для конструкций defclass называют также фасетами слота. В CLIPS существуют следующие зарезервированные слова, которые не могут использоваться как первое поле любого факта test, and,
    or, not, declare, logical, object, exists, forall.

    133
    Непозиционные факты (шаблонные факты) – реализуются через конструкцию, подобную структуре или записи в языках C и PASCAL. Шаблонные факты позволяют задавать имена каждому из полей факта. Для задания шаблона, который затем может использоваться при доступе к полям по именам, используется конструкция
    (deftemplate
    (slot-1)
    (slot-2)
    (slot-N)), где – имя шаблона, (slot-N) – именованное поле (или слот. Слоты могут быть ограничены по типу, значению, числовому диапазону, могут содержать значение по умолчанию. Порядок следования слотов значения не имеет. Пример

    (deftemplate student
    "a student record"
    (slot name (type STRING))
    (slot age (type NUMBER) (default 18))) Каждое определение шаблона состоит из произвольного имени шаблона, необязательного комментария и некоторого количества определений слотов (начинаются с ключевого слова slot или field). Слот включает поле данных, например name, и тип данных, например
    STRING. Можно указать и значение по умолчанию, как в приведённом выше примере, где возраст студента по умолчанию равен 18. Если в программу включено приведённое выше определение шаблона, то выражение
    (deffacts students
    (student (name "fred"))
    (student (name "jack")
    (age 19))) приведёт к тому, что и базу фактов после выполнения команды reset будет добавлено
    (student (name "fred") (age 18))
    (student (name "jack") (age 19)) При работе с базами данных язык CLIPS предоставляет пользователю возможность использования следующих операций над фактами добавление к списку фактов (assert); удаление из списка фактов

    134
    (retract); изменение списка фактов (modify), дублирование списка фактов (duplicate); очищение списка фактов (clear). Кроме того, команды assert и retract используются в выполняемой части правила (заключении правила) и сих помощью выполняется программное изменение базы фактов. Для вывода списка фактов, имеющихся в базе, используется команда facts. Для удаления из базы массив фактов применяется оператор (команда) undeffacts. Работа с базой правил основывается на их представлении соответствующими форматами. В языке CLIPS правила имеют следующий формат [4 – 8]:
    (defrule имя правила
    < необязательный комментарий >
    < необязательное объявление >
    < предпосылка >
    < предпосылка
    => действие > действие) Пример

    (defrule chores
    "Things to do on Sunday"
    (declare (salience 10))
    (today is Sunday)
    (weather is warm)
    =>
    (assert (wash car))
    (assert (chop wood))
    ) В этом примере Chores – произвольно выбранное имя правила. Предпосылки условной части правила – это
    (today is Sunday)
    (weather is warm) сопоставляются затем интерпретатором с базой фактов, а действия, перечисленные в выполняемой части правила (она начинается после пары символов =>), вставят в базу два факта
    (wash car)
    (chop wood) в случае, если правило будет активизировано. Приведённый в тексте правила комментарий "Things todo on Sunday" (Что сделать в воскресенье) поможет в дальнейшем вспомнить, чего ради это правило включено в программу. Выражение
    (declare (salience 10)) указывает на степень важности правила. Пусть, например, в программе имеется другое правило
    (defrule fun
    "Better things todo on Sunday"
    (salience 100)
    (today is Sunday)
    (weather is warm)
    =>
    (assert (drink beer))
    (assert (play guitar))
    ) Поскольку предпосылки обоих правил одинаковы, то при выполнении оговорённых условий они будут конкурировать за внимание интерпретатора, предпочтение будет отдано правилу, у которого параметр имеет более высокое значение, в данном случае – правилу. Параметру salience может быть присвоено любое целочисленное значение в диапазоне [-10 000, 10 000]. Если параметр salience в определении правила опущен, ему по умолчанию присваивается значение. Обычно в определении правила присутствуют и переменные (они начинаются с символа ?). Если, например, правило
    (defrule pick-a-chore
    "Allocating chores to days"
    (today is ?day)
    (chore is ?job)
    =>
    (assert (do ?job on ?day))) будет сопоставлено с фактами
    (today is Sunday)
    (chore is carwash) тов случае активизации оно включит в базу новый факт
    (do carwash on Sunday) Аналогично, правило
    (defrule drop-a-chore
    "Allocating chores to days"

    136
    (today is ?day)
    ?chore <- (do ?job on ?day)
    =>
    (retract ?chore)) отменит выполнение работ по дому (?chore). Обратите внимание на то, что оба экземпляра переменной ?day должны получить одно и тоже значение. Переменная ?chore в результате сопоставления должна получить ссылку на факт (это делает оператор <-), который мы собираемся исключить из базы. Таким образом, если это правило будет сопоставлено с базой фактов, в которой содержатся
    (today is Sunday)
    (do carwash on Sunday) то при активизации правила из базы будет удалён факт
    (do carwash on Sunday) Отметим, что факт
    (do carwash on Sunday) будет сопоставлен с любым из представленных ниже образцов
    (do ? ? Sunday)
    (do ? on ?)
    (do ? on ?when) Если за префиксом ? не следует имя переменной, он рассматривается как универсальный символ подстановки, которому может быть сопоставлен любой элемент. При написании правил в части посылок иногда требуются некоторые логические операции, например, необходимо указать факты, что сегодня суббота или воскресенье, цветок не синий, шар большой и зелёный». Это реализуется специальными логическими операторами ИЛИ, НЕ, И, которые обозначаются как |, , & соответственно. Таким образом, указанные выше факты запишутся следующим образом
    (today is Saturday|Sunday)
    (flower is blue)
    (ball is big&green) Использование экземпляров и классов вместо фактов и конструкций предоставляет несколько преимуществ. Первым из них является само наследование. Конструкция defclass может наследовать информацию от одного или нескольких различных классов. Это позволяет создавать более структурированные, модульные определения данных. Вторым преимуществом является то, что за объектами можно закрепить относящуюся к ним процедурную информацию с помощью обработчиков сообщений. Третьим преимуществом является то, что сопоставление с шаблонами на основе объектов обеспечивает большую гибкость, чем сопоставление с шаблонами на основе фактов. В объектных шаблонах может использоваться наследование, сопоставление с шаблонами может осуществляться с учётом слотов, принадлежащих нескольким классам, существует возможность исключить повторную активизацию шаблона под действием изменений в незадан- ных слотах, а также может обеспечиваться поддержание истинности на основе значений слотов.
    5.3. Типы функций манипулирования данными Существует несколько типов функций пользовательские и системные. Системные определены внутри среды CLIPS изначально, пользовательские – фрагменты кода, написанные пользователями на
    CLIPS или С. Хотя CLIPS неориентированна численные вычисления, в нём предусмотрены стандартные математические и арифметические функции (возведение в степень, Abs, Sqrt, Mod, Min, Max. Пример

    (+ 2 5 8). Конструкция deffunction позволяет пользователю определять новые функции непосредственно в среде CLIPS [4 – 8].
    (deffunction имя функции (аргумент ... < аргумент >) выражение выражение) Примера а а) (* ?b ?b)))
    )
    Аргументы-переменные должны иметь префикс ?, как это показано в приведённом примере. Вызовы функций в CLIPS имеют префиксную форму аргументы стоят после её названия. Вызов функции производится в скобках
    (hypotenuse 7 4) После открывающейся скобки следует имя функции, затем идут аргументы, каждый из которых отделён одним или несколькими пробелами. Аргументами функции могут быть данные простых типов, переменные или вызовы других функций. Функция возвращает результат последнего выражения в списке. Иногда выполнение функции имеет побочные эффекты, как в приве- дённом ниже примере.
    (deffunction init (?day)
    (reset)
    (assert (todayis ?day))
    ) В результате после запуска функции на выполнение командой
    CLIPS> (init Sunday) будет выполнена команда reset и, следовательно, очищена база фактов, а затем вне будет включён новый факт (today is Sunday). А в результате запуска функции hypotenuse на выполнение, командой) будет выдан известный ответ
    CLIPS> 5.0 Пример
    (deffunction between(?lb ?value ?ub)
    (or (> ?lb ?value) (> ?value ?ub))) Эта функция определяет, попало ли заданное целочисленное значение в диапазон между нижними верхним пределами. В некоторых задачах бывает полезным оператор присвоения bind. Например, переменной а присваивается значение 4:
    (bind ?a 4) Для более подробного изучения функциональных возможностей языка CLIPS целесообразно воспользоваться литературными источниками. Особенности решения задач планирования действий системы в заданной предметной области Задачи планирования – определить последовательность действий модуля решения, например системы управления. Традиционное планирование основано на знаниях, поскольку создание плана требует организации частей знаний и частичных планов в процедуру решения.

    139 Планирование используется в экспертных системах при рассуждении о событиях, происходящих во времени. Планирование находит применение в производстве, управлении, робототехнике, в задачах понимания естественного языка. Планы создаются путём поискав пространстве возможных действий до тех пор, пока не будет найдена последовательность, необходимая для решения задачи. Это пространство представляет состояния мира, которые изменяются при выполнении каждого действия. Поиск заканчивается, когда достигается целевое состояние (описание мира) [3].
    Приведём фрагмент программы по планированию действий робота Робот и ящик [3]. Имеются 2 комнаты – Аи В. В комнате А находится робот, в комнате В – ящик. Задача – вытолкнуть ящик в комнату А. Эта задача решается с помощью шаблонных фактов. Введём шаблон, определяющий местоположение предмета
    (deftemplate in
    (slot object (type SYMBOL))
    (slotlocation (typeSYMBOL))
    ) Слот object будет задавать название предмета или робота, location – название места, где этот предмет или робот находится. Чтобы задать роботу конкретную цель действий зададим шаблон goal:
    (deftemplate goal
    (slot object (type SYMBOL))
    (slot from (type SYMBOL))
    (slot to (type SYMBOL))
    ) слот object определяет название объекта, который необходимо переместить, слоты from и to определяют откуда и куда. На основе шаблонов in и goal запишем начальные факты
    (deffacts world
    (in (object robot) (location RoomA))
    (in (object box) (location RoomB))
    (goal (action push) (object box) (from RoomB) (to RoomA))
    ) Первый факт соответствует тому, что робот находится в комнате А, второй, что ящик в комнате В, третий – перетащить ящик из комнаты в A.

    140 Заключительным этапом создания данной программы является создание правил. В данной задаче необходимо реализовать три правила, которые осуществляли бы следующие действия робота перемещение робота в комнату, где находится объект перемещение робота с объектом в комнату, указанную в цели остановка программы если цель достигнута. Реализуем первое действие
    (defrule move
    (goal (object ?X) (from ?Y))
    (in (object ?X) (location ?Y))
    ?robot-position <- (in (object robot) (location ?Y))
    =>
    (modify ?robot-position (location ?Y))
    ) В данном правиле имеются три предпосылки. Впервой предпосылке, использующей шаблон goal, задаются значения переменных ?X и ?Y. Во второй определяется наличие объекта ?X в комнате ?Y. В третьей предпосылке проверяется, что местоположение робота не соответствует ?Y и запоминается ссылка на данный факт в переменной
    ?robot-position. Если все предпосылки данного правила истинны, то с помощью оператора modify меняется значение слота location назначение переменной ?Y факта ?robot-position, те. робот перемещается в комнату, в которой находится объект, который необходимо переместить. Аналогично реализуется правило перемещения робота с ящиком, в комнату, указанную в цели
    (defrule push
    (goal (object ?X) (from ?Y) (to ?Z))
    ?object-position <- (in (object ?X) (location ?Y))
    ?robot-position <- (in (object robot) (location ?Y))
    =>
    (modify ?robot-position (location ?Z))
    (modify ?object-position (location ?Z))
    ) В данном случае изменяются два факта, ссылки на которые задаются в переменных ?object-position и ?robot-position: значение слота location меняется назначение переменной ?Z, соответствующей значению, куда необходимо переместить предмет роботом. Остановка выполнения программы в CLIPS осуществляется с помощью команды (halt). Условием остановки является наличие факта,

    141 что предмет, указанный в цели (слот object) находится в комнате, указанной в слоте to:
    (defrule stop
    (goal (object ?X) (to ?Y))
    (in (object ?X) (location ?Y))
    =>
    (halt)) Полный листинг программы представлен в [3].
    5.5. Возможности наследования информации Одно из преимуществ использования языка COOL состоит в том, что классы могут наследовать информацию от других классов, что позволяет обеспечить совместный доступ к информации. Рассмотрим, какие действия пришлось бы предпринимать при наличии конструкции, которая представляет информацию о людях [4]:
    (deftemplate PERSON "PERSON deftemplate" (slot full-name) (slot age) (slot eye-color) (slot hair-color)) В таком случае, если бы потребовалось представить дополнительную информацию, относящуюся к тому, кто является служащим компании или студентом университета, пришлось бы предпринять оп- ределённые усилия. Один из возможных подходов мог бы предусматривать дополнение конструкции deftemplate с именем PERSON для включения другой необходимой информации
    (deftemplate PERSON "PERSON deftemplate"
    (slot full-name)
    (slot age)
    (slot eye-color)
    (slot hair-color)
    (slot job-position)
    (slot employer)
    (slot salary)
    (slot university)
    (slot major)
    (slot GPA)) Но ко всем людям относились бы только четыре слота этой конструкции и hair-color. С другой стороны, слоты job-position, employer и salary относились бы только к

    142 служащим, а слоты university, major и GPA – только к студентам. По мере добавления информации о людях, занимающихся другой деятельностью, приходилось бы вводить всё больше и больше слотов в конструкцию deftemplate с именем PERSON, причём по большей части эти слоты оказались бы неприменимыми для всех людей.
    Ещё один подход мог бы состоять в создании отдельных конструкций для служащих и студентов, как в следующем примере"
    (slot full-name)
    (slot age)
    (slot eye-color)
    (slot hair-color)
    (slot university)
    (slot major)
    (slot GPA)) При использовании такого подхода каждая конструкция deftemplate содержит только необходимую информацию, но приходится дублировать некоторые из слотов. Если бы пришлось модифицировать атрибуты одного из таких дублирующихся слотов, то потребовалось бы вносить изменения во многих местах, чтобы обеспечить единообразие представления информации. Кроме того, если бы нужно было написать правило, позволяющее отыскивать всех людей с синими глазами, то пришлось бы использовать два шаблона вместо одного а если потребовалось бы также включить факты PERSON, количество шаблонов стало бы равным трём), как показано ниже.
    (defrule find-blue-eyes
    (or (employee (full-name ?name) (eye-color blue))
    (student (full-name ?name) (eye-color blue)))
    =>
    (printout t ?full-name "has blue eyes." crlf))

    143 Классы позволяют совместно использовать общую информацию, принадлежащую к различным категориям, без дублирования, или включения ненужной информации. Вернёмся к первоначально рассматриваемому определению конструкции defclass с именем PERSON:
    (defclass PERSON "PERSON defclass"
    (is-a USER)
    (slot full-name)
    (slot age)
    (slot eye-color)
    (slot hair-color)) Чтобы определить новые классы, которые расширяют определение класса PERSON, достаточно указать имя класса PERSON в атрибуте нового класса, как показано ниже.
    (defclass EMPLOYEE "Employee defclass"
    (is-a PERSON)
    (slot job-position)
    (slot employer)
    (slot salary))
    (defclass STUDENT "Student defclass"
    (is-a PERSON)
    (slot university)
    (slot major) (slot GPA)) Атрибуты класса PERSON наследуются ив классе EMPLOYEE, ив классе STUDENT. Примеры создания экземпляров для каждого из этих трёх классов иллюстрирует следующий диалог
    CLIPS> (make-instance [John] of PERSON)
    [John]
    CLIPS> (make-instance [Jack] of EMPLOYEE)
    [Jack]
    CLIPS> (make-instance [Jill] of STUDENT)
    [Jill]
    CLIPS> (send [John] print)
    [John] of PERSON
    (full-name nil)
    (age nil)
    (eye-color nil)
    (hair-color nil)
    CLIPS> (send [Jack] print)
    [Jack] of EMPLOYEE

    144
    (full-name nil)
    (age nil)
    (eye-color nil)
    (hair-color nil)
    (job-position nil)
    (employer nil)
    (salary nil)
    CLIPS> (send [Jill] print)
    [Jill] of STUDENT (full-name nil) (age nil) (eye-color nil) (hair-color nil) (university nil) (major nil) (GPA nil)
    CLIPS> Обратите внимание на то, что каждый экземпляр содержит только слоты, относящиеся к его классу. Как показано в следующем подразделе, в любом классе можно переопределить любой слот, который был уже определён в любом из его суперклассов. Класс, который либо прямо, либо косвенно наследует свойство другого класса, называется подклассом того класса, от которого он наследует свойства. Класс, от которого наследуются свойства, называется суперклассом наследующего класса. Классы PERSON, EMPLOYEE и STUDENT представляют собой подклассы класса USER. Классы
    EMPLOYEE и STUDENT являются подклассами класса PERSON. Класс USER – суперкласс классов PERSON, EMPLOYEE и STUDENT, а класс PERSON – суперкласс классов EMPLOYEE и STUDENT. Иерархией классов с единичным наследованием называется такая иерархия, в которой каждый класс имеет только один суперкласс, связанный с ним прямыми отношениями наследования. Иерархией классов с множественным наследованием называется такая иерархия, в которой любой класс может иметь несколько суперклассов, связанных с ним прямыми отношениями наследования. В языке COOL поддерживается множественное наследование. Мы будем ограничиваться применением примеров единичного наследования. Ниже приведён пример класса, в котором используется множественное наследование (в нём рассматривается студент, который имеет работу) [4].
    (defclass WORKING–STUDENT "Working Student defclass" (is-a
    STUDENT EMPLOYEE)) По умолчанию, если какой-то слот переопределяется в подклассе, то атрибуты слота из нового определения используются исключительно в экземплярах этого класса. Например, предположим, что определены следующие классы

    145
    (defclass Ах у)
    (slot z (default 4))) В
    (is-a A)
    (slot x)
    (slot у (default 5))
    (slot z (default 6))) В таком случае создание экземпляров классов Аи В приведёт к получению следующих результатов
    CLIPS> (make-instance [a] of A)
    CLIPS> (make-instance [b] of В)
    CLIPS> (send [a] print)
    [a] of A (x 3) (y nil) (z 4)
    CLIPS> (send [b] print)
    [b] В (х nil) (y 5) (z 6)
    CLIPS> Обратите внимание на то, что слоту х экземпляра b по умолчанию присвоено значение nil вместо 3. Это связано стем, что при отсутствии заданного по умолчанию значения для слотах класса В полностью перекрывается заданное по умолчанию значение 3, присваиваемое слоту х в классе А. Чтобы обеспечить возможность наследовать атрибуты слота от суперклассов, можно воспользоваться атрибутом слота source. Если этому атрибуту присваивается значение exclusive, которое применяется по умолчанию, то атрибуты для слота устанавливаются на основе наиболее конкретного класса, определяющего этот слот. В иерархии единичного наследования как таковой рассматривается класс, имеющий наименьшее количество суперклассов. Если же атрибуту source присваивается значение composite, то атрибуты, которые не определены явно в наиболее конкретном классе, определяющем слот, берутся из следующего по порядку наиболее конкретного класса, в котором определяется данный атрибут. Например, если описанные ранее конструкции defclass с именами Аи В будут объявлены следующим образом Ах у)
    (slot z (default 4)))
    (defclass В (is-a A)
    (slot x (source composite))
    (slot у (default 5))
    (slot z (default 6))) то после создания экземпляров классов Аи В будут получены такие результаты
    CLIPS> (make-instance [a] of A)
    CLIPS> (make-instance [b] of В)
    CLIPS> (send [a] print)
    [a] of A (x 3) (y nil) (z 4)
    CLIPS> (send [b] print)
    [b] В (х 3) (y 5) (z 6)
    CLIPS> Теперь, после того как слот х класса В объявлен с атрибутом source, которому присвоено значение composite, этот слот может наследовать заданный по умолчанию атрибут от класса Аи применяемое по умолчанию результирующее значение для слотах экземпляра b становится равным 3. Возможно также запретить наследование значения слота с использованием атрибута слота propagation. Если этому атрибуту присваивается значение inherit, которое является заданным по умолчанию, то данный слот наследуется подклассами. А если этому атрибуту присваивается значение no-inherit, то слот подклассами не наследуется. Например, если классы Аи В будет определены следующим образом
    (defclass Ах В
    (is-a A)
    (slot z)) то после создания экземпляров классов Аи В будут получены такие результаты
    CLIPS> (make-instance [a] of A)
    CLIPS> (make-instance [b] of В)
    CLIPS> (send [a] print) a of A (x nil) (y nil)

    147
    CLIPS> (send [b] print) b of В (у nil) (z nil)
    CLIPS> Экземпляр b класса В наследует слоту из класса А, ноне наследует слот х из класса А, поскольку атрибут propagation последнего имеет значение no-inherit. Абстрактные и конкретные классы. В языке CLIPS предусмотрена возможность определять классы [4 – 8], используемые только для наследования. Такие классы называются абстрактными классами. Создание экземпляров абстрактных классов невозможно. По умолчанию классы являются конкретными. Для указания на то, должен ли класс быть абстрактным (abstract) или конкретным (concrete), применяется атрибут класса role. Атрибут класса role должен быть указан после атрибута класса is-a, но перед любыми определениями слотов, например, как показано ниже [4].
    (defclass ANIMAL
    (is-a USER)
    (role abstract))
    (defclass MAMMAL
    (is-a ANIMAL)
    (role abstract))
    (defclass CAT
    (is-a MAMMAL)
    (role concrete))
    (defclass DOG
    (is-a MAMMAL)
    (role concrete)) Классы ANIMAL и MAMMAL являются абстрактными, а классы
    CAT и DOG – конкретными. Атрибут role наследуется, поэтому, хотя и не требуется объявлять класс MAMMAL как абстрактный, поскольку он наследует этот атрибут от класса ANIMAL, необходимо объявить классы CAT и DOG как конкретные, в связи стем, что в противном случае они будут рассматриваться как абстрактные. Попытка создать экземпляр абстрактного класса приводит к формированию сообщения об ошибке, как в следующем примере
    CLIPS> (make-instance [animal-1] of ANIMAL)
    [INSMNGR3] Cannot create instances of abstract class ANIMAL.
    CLIPS> (make-instance [cat-1] of CAT)
    [cat-1]
    CLIPS>

    148 Настоятельная необходимость объявлять какой-либо класс как абстрактный не возникает, но при использовании такого подхода в соответствующих условиях код становится более удобным для сопровождения и проще обеспечивает повторное использование. При этом достаточно лишь исключить для пользователя возможность создавать экземпляры с помощью какого-то класса, если класс не предназначен для этой цели. Но если данный класс уже используется таким образом, тов будущих реализациях станет невозможным его исключение, поскольку это приведёт к нарушению работы существующего кода. В рассматриваемом примере [4] ответ на вопрос о том, должны ли классы ANIMAL и MAMMAL быть абстрактными, не так уж однозначен. Если требуется создать картотеку с информацией о животных, содержащихся в некотором зоопарке, то данные классы, по-видимому, должны быть абстрактными, поскольку в природе не существует животных (в данном случае речь идёт о млекопитающих, которые соответствовали бы только этому определению и не относились бык како- му-то более конкретному виду живых существ. Но если бы предпринималась попытка идентификации какого-то животного, то вполне могла бы возникнуть необходимость создавать экземпляры класса
    ANIMAL или MAMMAL, например, для включения в них информации о том, что мы смогли выяснить в отношении данного животного. Пример 1:

    (defclass A (is-a USER)) Класс А является прямым наследником класса USER. Список старшинства классов для A: A USER OBJECT. Пример 2:

    (defclass В (is-a USER)) Класс В является прямым наследником класса USER. Список старшинства классов для В В USER OBJECT. Пример 3:

    (defclass С (is-a А В) Класс С является прямым наследником классов Аи В. Список старшинства классов для С С А В USER OBJECT. Пример 4:
    (defclass D (is-a В A)) Класс D является прямым наследником классов Аи В. Список старшинства классов для D: D В A USER OBJECT.

    149 Пример 5:
    (defclass Е (is-a АС) В соответствии с правилом 2, А должен быть старше СВ нашем случае, С – это потомок Аи является более старшим в соответствии с правилом 1. Ошибка. Пример 6:
    defclass Е (is-a С А) Правильное определение класса из примера 5. Список старшинства для ЕЕ С А В USER OBJECT. Абстрактные и конкретные классы. Абстрактный класс предназначен только для наследования, на его основе не могут создаваться экземпляры. На основе конкретного класса могут создаваться его экземпляры. Слоты. Слот – это место для хранения значений поля класса. Каждый экземпляр класса содержит копию всех слотов своего родителя. Количество слотов класса ограничено только размером свободной памяти, имя слота – любой набор символов, за исключением зарезервированных слов. Потомок класса содержит слоты родителя. В случае конфликта имён слотов, он разрешается в соответствии с правилом старшинства. Пример
    (defclass A (is-a USER)
    (slot fooA)
    (slot barA))
    (defclass В (is-a A)
    (slot fooB)
    (slot barB)) Список старшинства для A: A USER OBJECT. Экземпляр класса А будет иметь 2 слота fooA и barA. Список старшинства для В В A
    USER OBJECT. Экземпляр класса В будет иметь 4 слота fooB, barB, fooA, barA. Для каждого слота может быть определён набор фасетов. Фасеты описывают различные свойства слотов значения по умолчанию, вид хранения, видимость и т.п. Более подробно фасеты будут рассмотрены далее. Создание экземпляра класса производится командой (make- instance a of А) – создаётся экземпляр с именем класса А. Другой вариант (создание массива экземпляра классов

    150
    (definstances my_inst
    (a of А)
    (b of А)
    (c of A)
    ) Тип поля слота. Слот может содержать как одно, таки несколько значений. По умолчанию слот содержит только одно значение. Ключевое слово multislot устанавливает тип слота, позволяющий хранить несколько значений, а slot или singleslot устанавливает тип слота, который может содержать только одно значение. Многозначные слоты хранятся как значения с несколькими полями. Манипуляции сними производятся посредством стандартных функций nth$ и length$. Для установки значения слота используется функция slotinsert$. Слоты с одним значением хранятся в CLIPS как обычные переменные стандартных типов. Пример
    CLIPS> (сlеаr)
    CLIPS>
    (defclass А (а USER)
    (rоlесоnсrеte)
    (multislot foo (сrеаtе-ассеssоr read)
    (default abc def ghi)))
    CLIPS> (make-instance а of А) а
    CLIPS> (nth$ 2 (send [a] get-foo)) def
    CLIPS> Если при создании слота указывается модификатор для создания методов для записи или чтения по умолчанию ((create-accessor read- write)), то экземпляр класса будет реагировать на сообщения get- имя_слота и put-имя_слота соответственно чтением и записью значения слота. Создание обработчиков сообщений будет рассмотрено далее. Фасет для задания значений по умолчанию. Фасеты используются для задания значений слота по умолчанию при создании экземпляра класса. Фасет default используется для задания статических значений слота. Фасет default-dynamic используется для заданий значения слота, которое задаётся всякий раз при создании нового экземпляра класса.

    151 Пример
    CLIPS> (сlеаr)
    CLIPS> (setgen 1)
    1 Сое А) а
    CLIPS> (make-instance a2 of А) а
    CLIPS> (send а get-foo) gen 1
    CLIPS> (send [a2] get-foo) gen2
    CLIPS> Фасет Storage. Фасет определяет, будет ли значение слота храниться локально в экземпляре класса (оса, либо это значение будет одно для всех экземпляров класса (shared). Пример
    CLIPS> (clear)
    CLIPS>
    (defclass A (is-a USER)
    (role concrete)
    (slot foo (create-accessor write)
    (storage shared)
    (default 1))
    (slot bar (create-accessor write)
    (storage shared)
    (default-dynamic 2))
    (slot woz (create-accessor write)
    (storage local)))
    CLIPS> (make-instance a of A)
    [a]
    CLIPS> (send [a] print)
    [a] of A
    (foo 1)
    (bar 2)
    (woz ni1)

    152
    CLIPS> (send [a] put-foo 56) С (send [a] put-bar 104)
    104
    CLIPS> (make-instance b of A)
    [b]
    CLIPS> (send [b] print)
    [b] of A
    (fоо 56)
    (bar 2)
    (woz nill)
    CLIPS> (send [b] put-foo 34)
    34
    CLIPS> (send [b] put-woz 68)
    68
    CLIPS> (send [a] print)
    [a] of A
    (foo 34)
    (bar 2)
    (woz nil)
    CLIPS> (send [b] print)
    [b] of A
    (foo 34)
    (bar 2)
    (woz 68)
    CLIPS> Фасет типа доступа к слоту. Для слота может быть задано три типа фасетов – 6]: read-write, read-only, initialize-only Пример работы с разными типами фасетов
    CLIPS> (clear)
    CLIPS>
    (defclass A (is-a USER)
    (role concrete)
    (slot foo (create-accessor write)
    (access read-write))
    (slot bar (access read-only)
    (default abc))
    (slot woz (create-accessor write)
    (access initialize-only)))
    CLIPS>
    (defmessage-handler A put-bar (?value)
    (dynamic-put (sym-cat bar) ?value))

    153
    CLIPS> (make-instance a of A (bar 34))
    [MSGFUN3] bar slot in [a] of A: write access denied.
    [PRCCODE4] Execution halted during the actions of message-handler put-bar primary in class A
    FALSE
    CLIPS> (make-instance a of A (foo 34) (woz 65)) а
    CLIPS> (send [a] put-bar 1)
    [MSGFUN3] bar slot in [a] of A: write access denied.
    [PRCCODE4] Execution halted during the actions of message-handler put-bar primary in class A
    FALSE
    CLIPS> (send [a] put-woz 1)
    [MSGFUN3] woz slot in [a] of A: write access denied.
    [PRCCODE4] Execution halted during the actions of message-handler put-bar primary in class A
    FALSE
    CLIPS> (send [a] print)
    [a] of A
    (foo 34)
    (bar abc)
    (woz 65)
    CLIPS>
    5.6. Обработка сообщений Изменение значений свойств объектов по правилам объектно- ориентированного программирования производится самими объектами, поэтому в языке CLIPS это реализовано посредством обработчиков сообщений
    [4 – Общий синтаксис команды создания обработчика сообщений
    (defmessage-handler
    [
    1   ...   10   11   12   13   14   15   16   17   ...   20


    написать администратору сайта