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

  • 6. ПРИМЕРЫ РЕАЛИЗАЦИИ ИНТЕЛЛЕКТУАЛЬНЫХ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ

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


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

    154 Обработчик сообщений уникально идентифицируется наименованием класса и типом. Для класса обработчик сообщений может задаваться как при создании определения класса, таки после. Заметим, что при создании определения класса создаётся только заголовок обработчика сообщений. Собственно программный код обработчика создаётся позже при помощи команды defmessage-handler. Обработчики сообщений, определяемые системой. За классами можно закрепить не только данные, но и процедурную информацию. Процедуры, входящие в состав классов, называются обработчиками сообщений. Для каждого класса, кроме обработчиков сообщений, определяемых пользователем, автоматически создаётся также целый ряд обработчиков сообщений, определяемых системой. Эти обработчики сообщений можно вызывать для работы с некоторым экземпляром с помощью команды send. Команда send имеет следующий синтаксис [4 – 8]:
    (send *) Например, сообщение print отображает информацию о слотах экземпляра Для каждого слота, определяемого в конструкции defclass, система автоматически определяет обработчики сообщений слота с префиксами get- и put-, которые используются для выборки и задания значений слота. Действительные имена обработчиков сообщений формируются в результате добавления к этим префиксам имени слота. Поэтому, например, конструкция defclass с именем PERSON, имеющая слоты full-name, age, eye-color и hair-color, автоматически создаётся для данного класса с восемью обработчиками сообщений, имеющими имена get-full-name, put-full-name, get-age, put-age, get-eye-color, put- eye-color, get-hair-color и put-hair-color. Обработчики сообщений get- не имеют параметров и возвращают значение слота, например [4]:
    CLIPS> (send [John] get-full-name)
    "John Q. Public"

    155
    CLIPS> (send [John] get-age)
    24
    CLIPS> Обработчики сообщений put- принимают от нуля и больше параметров. Если параметры не задаются, то восстанавливается первоначальное, предусмотренное по умолчанию значение слота, а при передаче одного или большего количества параметров значение слота устанавливается с учётом этих параметров. Попытка поместить больше одного значения в однозначный слот приводит к возникновению ошибки. Обработчик сообщений put- возвращает значение, представляющее собой новое значение слота, например, как показано в следующем диалоге
    CLIPS> (send [Jack] get-age) nil
    CLIPS> (send [Jack] put-age 22)
    22
    CLIPS> (send [Jack] get-age)
    22
    CLIPS>(send [Jack] put-age) nil
    CLIPS> (send [Jack] get-age) nil
    CLIPS> Команда watch принимает в качестве параметров несколько элементов, подлежащих отслеживанию, которые относятся к данному экземпляру. Одним из таких элементов является slots (слоты. Если осуществляется отслеживание слотов, то при каждом изменении значения любого слота экземпляра выводится информационное сообщение. Отслеживание изменений в слотах можно отменить с помощью команды unwatch:
    CLIPS > (watch slots)
    CLIPS> (send [Jack] put-age 24)
    ::= local slot age in instance Jack <- 24 24
    CLIPS> (unwatch slots)
    CLIPS> (send [Jack] put-age 22)
    22
    CLIPS>

    156
    Ещё одним заранее определённым обработчиком сообщений является. Как и можно было бы предположить, обработчик сообщений используется для удаления экземпляра. Он возвращает символ TRUE, если экземпляр был успешно удалён, в противном случае символ FALSE:
    CLIPS> (instances)
    [John] of PERSON
    [genl] of PERSON
    [Jack] of PERSON
    For a total of 3 instances.
    CLIPS> (send [genl] delete)
    TRUE
    CLIPS> (instances)
    [John] of PERSON
    [Jack] of PERSON
    For a total of 2 instances.
    Ещё одним отслеживаемым элементом является instances (экземпляры. Если отслеживаются экземпляры, то система CLIPS автоматически выводит сообщение каждый раз, когда создаётся или удаляется экземпляр. В отличие оттого, какие действия выполняются при модификации значения слота факта, при модификации значения слота экземпляра не создаётся новый экземпляр с изменившимся значением и не удаляется первоначальный экземпляр, поэтому для наблюдения за изменениями значений слотов экземпляров необходимо использовать отслеживаемый элемент slots. Применение отслеживаемого элемента instances иллюстрируется в следующем примере диалогового выполнения команд
    CLIPS> (watch instances)
    CLIPS> (make-instance Jill of PERSON)
    ==>instance [Jill] of PERSON [Jill]
    CLIPS> (send [Jill] put-age 22)
    22
    CLIPS> (send [Jill] delete)
    <== instance [Jill] of PERSON TRUE
    CLIPS> (unwatchinstances)
    CLIPS> Последовательность знаков <== указывает, что экземпляр удаляется, а последовательность знаков ==> свидетельствует о том, что экземпляр создаётся.

    157 Пример создам класс прямоугольники объявляем у него обработчик сообщений, позволяющий находить его площадь
    (defclass rectangle (is-a USER)
    (slot side-a (default 1))
    (slot side-b (default 1))
    (message-handler find-area)) создам тело обработчика сообщений
    (defmessage-handler rectangle find-area ()
    (* ?self:side-a ?self:side-b)) создам ещё один обработчик сообщений, позволяющий напечатать полученную площадь прямоугольника
    (defmessage-handler rectangle print-area()
    (printout t (send ?self find-area) crlf)) Ссылка на активный (те. принимающий сообщение в данный момент) экземпляр сущности может быть получена при помощи переменной. Имя этого параметра зарезервировано. Пример

    (defclass A (is-a USER)
    (role concrete)
    (slot foo (default 1))
    (slot bar (default 2)))
    CLIPS>
    (defmessage-handler A print-all-slots ()
    (printout t ?self:foo “ “?self:bar crlf))
    CLIPS> (make-instance a of A) а
    CLIPS> (send [a] print-all-slots)
    1 2
    CLIPS>
    5.7. Контрольные вопросы и задания Опишите основные элементы языка CLIPS. Расскажите об основных типах данных языка. Расскажите про конструкторы, используемые в языке CLIPS. Абстракции данных. Упорядоченные факты. Неупорядоченные факты. Функции для работы с фактами. Поясните процесс инициализация фактов.

    158 Расскажите о процессе использования локальных и глобальных переменных. Создание правил. Конструктор defrule. Поясните основной цикл выполнения правил. Условные логические элементы. Команды и функции для работы с правилами. Функции, конструктор deffunction. Конструктор defclass. Расскажите об особенностях абстрактных и конкретных классов. Расскажите об особенностях активных и неактивных классов. Слоты класса. Конструктор обработчика сообщений. Работа с объектами. Поясните процесс инициализации объектов. Расскажите о функциях для работы с объектами. Преобразуйте сеть общего видана которой представлены авиалинии, вряд фактов, заданных в операторе deffacts. Для описания фактов используйте единственную конструкцию deftemplate. Преобразуйте семантическую сеть, представляющую семью, вряд фактов, заданных в операторе deffacts. Для описания сформированных фактов используйте несколько конструкций deftemplate. Преобразуйте семантическую сеть классификации летательных аппаратов вряд фактов, заданных в операторе deffacts. Для описания фактов используйте несколько конструкций deftemplate. Преобразуйте бинарное дерево решений, представляющее информацию о классификации животных вряд фактов, заданных в операторе deffacts. Преобразуйте семантическую сеть классификации автомобилей вряд фактов, заданных в операторе deffacts. Для описания фактов используйте несколько конструкций deftemplate. Преобразуйте бинарное дерево решений, представляющее информацию о классификации растений вряд фактов, заданных в операторе. Список литературы Адрес языка CLIPS в Интернете http://www.ghg.net/clips/
    CLIPS.html. Базы данных. Интеллектуальная обработка информации /
    В.В. Корнеев и др. – М. : Нолидж, 2000.
    3.
    Вахтин, А.А. Лабораторный практикум по программированию на языке CLIPS для курса Представление знаний в информационных

    159 системах : учебно-методическое пособие для вузов / А.А. Вахтин,
    В.В. Гришина. – Издательско-полиграфический центр ВГУ, 2010. – 95 с.
    4.
    Джарантино, Дж. Экспертные системы принципы разработки и программирования / Дж. Джарантино, Г. Райли. – е изд. ; перс англ. – М. : Изд. дом «Вильямc», 2007. – 1152 с.
    5.
    Джексон, П. Введение в экспертные системы / П. Джексон ; перс англ. – М. : Изд. дом «Вильямc», 2001. – 622 с.
    6.
    Люгер, Дж. Искусственный интеллект стратегии и методы решения сложных проблем / Дж. Люгер, С. Рассел, П. Норвиг. – е изд. ; перс англ. – М. : Изд. дом «Вильямc», 2003. – 864 с.
    7.
    Рассел, С. Искусственный интеллект современный подход /
    C. Рассел, П. Норвиг. – е изд. ; перс англ. – М. : Изд. дом «Вильямc»,
    2006. – 1408 с.
    8.
    Частиков, А.П. Разработка экспертных систем. Среда CLIPS /
    А.П. Частиков,Т.А. Гаврилов, Д.Л. Белов. – СПб. : БХВ-Петербург,
    2003. – 608 с.
    6. ПРИМЕРЫ РЕАЛИЗАЦИИ ИНТЕЛЛЕКТУАЛЬНЫХ ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ
    6.1. Пример объектно-ориентированного программирования на языке CLIPS Использование объектно-ориентированных средств в CLIPS позволяет значительно упростить программирование правил, поскольку для обновления данных можно применять механизм передачи и обработки сообщений методами классов. Мы продемонстрируем, как это делается на примере, который моделирует правила обращения с полуавтоматическим пистолетом. Первым делом определим класс pistol, в котором будут перечислены свойства, необходимые для моделирования.
    (defclass pistol
    (is-a USER)
    (role concrete)
    (pattern-match reactive)
    (slot safety (type SYMBOL) (create-accessor read-write))
    (slot slide (type SYMBOL) (create-accessor read-write))
    (slot hammer (type SYMBOL) (create-accessor read-write))
    (slot chamber (type INTEGER) (create-accessor read-write))
    (slot magazine (type SYMBOL) (create-accessor read-write))
    (slot rounds (type INTEGER) (create-accessor read-write)))

    160 Первые три слота – системные. Они нужны объектно-ориенти- рованной надстройке CLIPS (COOL – CLIPS object–oriented language). Эти слоты COOL извещают о том, что pistol – это пользовательский класс pistol является конкретным классом, те. возможно создание экземпляров этого класса. Экземпляры класса pistol могут быть использованы в качестве объектов данных, которые можно сопоставлять с условиями в правилах и использовать в действиях, определённых правилами. Следующие пять слотов представляют свойства и члены данных класса слот safety (предохранитель) может содержать символ on или off; слот slide (затвор) может содержать значение forward или back, те. хранит информацию о положении затвора слот hammer (курок) содержит информацию о состоянии курка или down; слот chamber (патронник) содержит значение 1 или 0, в зависимости оттого, есть ли патрон в патроннике слот magazine (обойма) может содержать значение in или out, в зависимости оттого, вставлена ли обойма слот rounds (патроны) содержит текущее количество патронов в обойме. Для того чтобы иметь возможность записывать в слот новое значение или считывать текущее, нужно разрешить формирование соответствующих функций доступа через грань акцессоров create-accessor. Теперь сформируем экземпляр класса pistol с помощью следующего выражения
    (definstances pistols (PPK of pistol (safety on)
    (slide forward) (hammer down) (chamber 0) (magazine out)
    (rounds 6))) Этот экземпляр, РРК, правильно уложен – обойма вынута из рукоятки, пистолет установлен на предохранитель, затвор в переднем положении, курок опущена патронник пуст. В обойме имеется 6 патронов. Теперь, имея в программе определение класса и сформировав экземпляр класса, разработаем правила и обработчики сообщений, с помощью которых можно описать отдельные операции обращения с пистолетом и стрельбы из него. Для этого сначала разработаем шаблон задачи. Желательно отслеживать две вещи

    161 есть ли патрон в патроннике

    произведён ли выстрел. Для этого можно использовать следующий шаблон
    (deftemplate range-test
    (field check (type SYMBOL) (default no))
    (field fired (type SYMBOL) (default no))) Первое правило будет устанавливать в рабочую память программы задачу range-test.
    (defrule start
    (initial-fact) =>
    (assert (range-test)))
    Приактивизации этого правила в рабочую память будет добавлено) Следующие три правила будут проверять, правильно ли снаряжён пистолет.
    (defrule check
    (object (name [PPK]) (safety on) (magazine out))
    ?T<-(range-test (check no))
    =>
    (send [PPK] clear)
    (modify ?T (check yes))) Правило check заключается в том, что если пистолет стоит на предохранителе (safety on), обойма вынута (magazine out) и пистолет не был проверен, то нужно очистить патронники проверить, нет ли в нём патрона. Обработчик сообщения clear для класса pistol будет выглядеть следующим образом
    (defmessage-handler pistol clear ()
    (dynamic-put chamber 0)
    (ppinstance)) Впервой строке объявляется, что clear является обработчиком сообщения для класса pistol, причём этот обработчик не требует передачи аргументов. Оператор во второй строке очищает патронник. Присвоение выполняется независимо оттого, какое текущее значение имеет слот chamber, – 0 или 1. Оператор в третьей строке требует, чтобы экземпляр распечатал информацию о текущем состоянии своих слотов. В следующих двух правилах обрабатываются ситуации, когда пистолет снаряжён неправильно, – не установлен на предохранитель

    162 или в него вставлена обойма. Правило correctl устанавливает пистолет на предохранитель, а правило correct2 извлекает из него обойму.
    (defrule correctl
    (object (name [PPK]) (safety off))
    (range-test (check no)) =>
    (send [PPK] safety on))
    (defrule correct2
    (object (name [PPK]) (safety on) (magazine in))
    (range-test (check no)) =>
    (send [PPK] drop)) Как и при разработке предыдущего правила, нам понадобятся обработчики сообщений safety и drop.
    (defmessage-handler pistol safety (?on-off)
    (dynamic-put safety ?on-off)
    (if (eq ?on-off on) then (dynamic-put hammer down))) Обработчик сообщения safety принимает единственный аргумент, который может иметь только два символических значения on или off. В противном случае нам пришлось бы разработать два обработчика один для сообщения safety-on, а другой – для сообщения safety-off . Обработчик сообщения drop просто извлекает обойму из пистолета.
    (defmessage-handler pistol drop ()
    (dynamic-put magazine out)
    ) Теперь, когда обеспечено правильное исходное снаряжение пистолета, можно приступить к стрельбе. Следующее правило обеспечивает вставку обоймы в пистолет перед стрельбой
    (defrulemag-in
    (object (name [PPK]) (safety on) (magazine out))
    (range-test (fired no) (check yes)) =>
    (send [PPK] seat)) Обработчик сообщения seat выполняет действия, противоположные тем, которые выполняет обработчик drop.
    (defmessage-handler pistol seat ()
    (dynamic-put magazine in))

    163 Следующее правило обеспечивает снаряжение обоймы патронами
    (defrule load
    (object (name [PPK]) (magazine in) (chamber 0)) =>
    (send [PPK] rack)) Обработчик сообщения rack.
    (defmessage-handler pistol rack ()
    (bind ?a (dynamic-get rounds))
    (if (> ?a 0) then
    (dynamic-put chamber 1)
    (dynamic-put rounds (- ?a 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).

    164
    (defmessage-handler pistol fire ()
    (if (and (eq (dynamic-get chamber) 1) (eq (dynamic-get safety) off)) then (printout t "BANG!" crlf) TRUE else (printout t "click" crlf) FALSE)) Пусть вас не смущает, что в обработчике сообщения анализируется условие, которое уже было проанализировано правилом, отославшим сообщение (в данном случае речь идёт об условии safety off). Дело в том, что одно и тоже сообщение может отсылаться разными правилами и нет никакой гарантии, что в каждом из них будет проверяться это условие. Рассмотрим ещё один пример
    (defclass RECTANGLE
    (is-a USER)
    (slot height)
    (slot width))
    (defclass CIRCLE
    (is-a USER)
    (slot radius))
    (defmessage-handler RECTANGLE compute-area ()
    (* (send ?self get-height)
    (send ?self get-width)))
    (defmessage-handler CIRCLE compute-area ()
    (* (pi)
    (send ?self get-radius)
    (send ?self get-radius)))
    (definstances figures
    (rectangle-1 of RECTANGLE (height 2) (width 4))
    (circle-1 of CIRCLE (radius 3))) В данном примере определяются два класса, RECTANGLE и
    CIRCLE, с соответствующими слотами. За каждым классом закреплён обработчик сообщений compute-area. Этот обработчик сообщений предназначен для вычисления площади каждого объекта. Для класса
    RECTANGLE площадь экземпляра RECTANGLE вычисляется путём умножения высоты, заданной в экземпляре, на ширину. А для класса
    CIRCLE площадь экземпляра CIRCLE представляет собой значение числа π, возвращаемое функцией pi, которое умножается назначение радиуса, заданное в экземпляре, возведённое в квадрат. Обратите внимание на то, что в обоих обработчиках сообщений используется переменная. Это – специальная переменная, автоматически определяемая для каждого обработчика сообщений. При вызове обработчика сообщений переменной ?self присваивается значение адреса того экземпляра, которому передаётся сообщение. Эта переменная может применяться для передачи в экземпляр сообщений, как и было сделано в рассматриваемом примере для выборки значений слотов height, width и radius. После определения обработчиков сообщений появляется возможность отправлять сообщения compute-area в экземпляры классов
    RECTANGLE и CIRCLE для получения информации о площади фигуры, заданной этим экземпляром, как в следующем примере
    CLIPS> (reset)
    CLIPS> (send [circle-1] compute-area)
    28.2743338823081
    CLIPS>
    (send [rectangle-1] compute-area)
    8
    CLIPS> Здесь заслуживает внимания то, что каждому экземпляру переда-
    ётся одно и тоже сообщение, но, вычисляя площадь фигуры, заданной сего помощью, каждый экземпляр отвечает по-разному. Такая способность различных экземпляров отвечать на одно и тоже сообщение в характерной для него форме называется полиморфизмом.
    1   ...   12   13   14   15   16   17   18   19   20


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