close

Вход

Забыли?

вход по аккаунту

?

MetCLIPS

код для вставкиСкачать
 Программирование экспертных систем на языке CLIPS
КРАТКАЯ ИСТОРИЯ CLIPS
Название языка CLIPS - аббревиатура от С Language Integrated Production System. Язык был разработан в Центре космических исследований NASA (NASA's Johnson Space Center) в середине 1980-х годов и во многом сходен с языками, созданными на базе LISP, в частности OPS5 и ART. Использование С в качестве языка реализации объясняется тем, что компилятор LISP не поддерживается частью распространенных платформ, а также сложностью интеграции LISP-кода в приложения, которые используют отличный от LISP язык программирования. Хотя в то время на рынке уже появились программные средства для задач искусственного интеллекта, разработанные на языке С, специалисты из NASA решили создать такой продукт самостоятельно. Разработанная ими система в настоящее время доступна во всем мире, и нужно сказать, что по своим возможностям она не уступает множеству гораздо более дорогих коммерческих продуктов.
ЛАБОРАТОРНАЯ РАБОТА №1
ОСНОВЫ ПРОГРАММИРОВАНИЯ НА ЯЗЫКЕ CLIPS
Цель работы: ознакомление с основными принципами программирования на языке CLIPS, получение навыков работы в оболочке CLIPS.
Технические средства: персональный компьютер с операционной системой Windows 9x/Me/NT/2000/XP
Программные средства: текстовый редактор (Блокнот, WordPad и т.п.), оболочка языка CLIPS версии 6.1 и выше
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
1.Правила и функции в CLIPS
CLIPS включает в язык представления порождающих правил и язык описания процедур, В этом разделе мы рассмотрим оба этих модуля, сопровождая описание отдельных функций примерами.
Основными компонентами языка описания правил являются база фактов (fact base) и база правил (rule base). На них возлагаются следующие функции:
* база фактов представляет исходное состояние проблемы;
* база правил содержит операторы, которые преобразуют состояние проблемы, приводя его к решению.
Машина логического вывода CLIPS сопоставляет эти факты и правила и выясняет, какие из правил можно активизировать. Это выполняется циклически, причем к цикл состоит из трех шагов:
(1) сопоставление фактов и правил;
(2) выбор правила, подлежащего активизации;
(3) выполнение действий, предписанных правилом.
Такой трехшаговый циклический процесс иногда называют "циклом распознавание-действие".
1.1. Факты
Сразу после запуска CLIPS-приложения (clipswin.exe) на выполнение на экране появится сообщение, извещающее пользователя, что он работает с интерпретатором.
CLIPS>
В режиме интерпретатора пользователь может использовать множество команд, так можно включить в базу фактов прямо из командной строки с помощью assert, например:
CLIPS> (assert (today is Sunday))
<Fact-0>
CLIPS> (assert (weather is warm))
<Fact-l>
Для вывода списка фактов, имеющихся в базе, используется команда facts:
CLIPS> (facts)
f-0 (today is Sunday)
f-1 (weather is warm)
В последних версиях CLIPS, в частности, в той, которая работает в операционной среде Windows, такие команды, как facts, можно вызывать с помощью меню.
Для удаления фактов из базы используется команда retract.
CLIPS> (retract 1)
CLIPS> (facts)
f-0 (today is Sunday)
Эти же команды, assert и retract, используются в выполняемой части правила (заключении правила) и с их помощью выполняется программное изменение базы фактов. Часто приходится пользоваться и другой командой интерпретатора, clear, которая очищает базу фактов (как правило, эта команда доступна в одном из выпадающих меню).
CLIPS> (clear)
CLIPS> (facts)
В тексте программы факты можно включать в базу не по одиночке, а целым массивом. Для этого в CLIPS имеется команда deffacts.
(deffacts today
(today is Sunday)
(weather is warm)
)
Выражение deffacts начинается с команды deffacts, затем приводится имя списка фактов, который программист собирается определить (в нашем примере - today), а за ним следуют элементы списка, причем их количество не ограничивается. Этот массив фактов можно затем удалить из базы командой undeffacts.
CLIPS> (undeffacts today)
Выражение deffacts можно вводить и в командную строку интерпретатора, но лучше записать его в текстовый файл с помощью редактора CLIPS или любого другого текстового редактора (файлы имеют расширение .clp). Загрузить этот файл в дальнейшем можно с помощью команды в меню File либо из командной строки.
CLIPS> (load "my file")
Однако после загрузки файла факты не передаются сразу же в базу фактов CLIPS. Команда deffacts просто указывает интерпретатору, что существует массив today, который содержит множество фактов. Собственно загрузка выполняется командой reset.
CLIPS> (reset)
Команда reset сначала очищает базу фактов, а затем включает в нее факты из всех ранее загруженных массивов. Она также добавляет в базу единственный системноопределенный факт:
f-0 (initial-fact)
Это делается по умолчанию, поскольку иногда имеет смысл включить в программу правило start rule, которое может быть сопоставлено с этим фактом и позволит выполнить какие-либо нестандартные инициализирующие операции. Однако включать такое правило в программу или нет - дело программиста.
Можно проследить, как выполняется команда reset, если перед выполнением приведенных выше команд установить режим слежения среды разработки. Для этого нужно вызвать команду Watch из меню Execution и установить в ней флажок Facts.
1.2. Правила
В языке CLIPS правила имеют следующий формат:
(defrule <имя правила>
< необязательный комментарий >
< необязательное объявление >
< предпосылка_1 >
< предпосылка_m >
=>
< действие_1 >
< действие_n >
)
Например:
(defrule chores
"Things to do on Sunday"
(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 to do on Sunday"
** "Что сделать в воскресенье" **
поможет в дальнейшем вспомнить, зачем это правило включено в программу.
Выражение
(salience 10)
указывает на степень важности правила. Пусть, например, в программе имеется другое правило
(defrule fun
"Better things to do on Sunday"
(salience 100)
(today is Sunday)
(weather is warm)
=>
(assert (drink beer))
(assert (play guitar))
)
Поскольку предпосылки обоих правил одинаковы, то при выполнении оговоренных условий они будут "конкурировать" за внимание интерпретатора, Предпочтение будет отдано правилу, у которого параметр salience имеет более высокое значение, в данном случае - правилу fun. Параметру salience может быть присвоено любое целочисленное значение в диапазоне [-10 000, 10 000]. Если параметр salience в определении правила опущен, ему по умолчанию присваивается значение 0.
Обычно в определении правила присутствуют и переменные (они начинаются с символа ?). Если, например, правило
(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"
(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)
1.3. Наблюдение за процессом интерпретации
Теперь на простом примере познакомимся с возможностями, которые предоставляет среда разработки CLIPS в части отладки программы, состоящей из правил и фактов.
Введите в текстовый файл правило, а затем загрузите этот файл в среду CLIPS.
(defrule start
(initial-fact)
=>
(printout t "hello, world" crlf)
)
Здесь стандартная команда printout t организует вывод на экран, символ crlf - это символ перевода строки.
Выполните команду reset. Для этого либо введите эту команду в командной строке интерпретатора
CLIPS> (reset)
либо выберите в меню команду Execution->Reset, либо нажмите <CTRL+U>.
Затем запустите интерпретатор. Для этого либо введите эту команду run в командную строку интерпретатора
CLIPS> (run)
либо выберите в меню команду Execution->Reset, либо нажмите <CTRL+R>.
В ответ программа должна вывести сообщение hello, world, знакомое всем программистам мира. Для повторного запуска программы повторите команды reset и run.
Если в меню Execution->Watch ранее был установлен флажок Rules или перед запуском программы на выполнение вы ввели в командную строку команду watch rules, то на экране появится результат трассировки процесса выполнения
CLIPS> (run) FIRE 1
start: f-0
hello, world
В этом сообщении в строке, начинающейся с FIRE, выведена информация об активизированном правиле: start - это имя правила, а f-0 - имя факта, который "удовлетворил" условие в этом правиле. Команда watch позволяет организовать несколько разных режимов трассировки. Если перед запуском программы вы ввели
CLIPS> (dribble-on "dribble.clp")
TRUE
то выведенный протокол трассировки будет сохранен в файле dribble.clp. Сохранение протокола прекратится после ввода команды
CLIPS> (dribble-off)
TRUE
Это очень удобная опция, особенно на этапе освоения языка.
1.4. Использование шаблонов
Для определения фактов можно использовать не только списочные структуры, но и шаблоны, которые напоминают простые записи. Шаблон выглядит примерно так:
(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))
1.5. Определение функций
В языке CLIPS функции конструируются примерно так же, как в языке LISP. Существенное отличие состоит в том, что переменные должны иметь префикс ?, как это показано в приведенном ниже определении:
(deffunction hypotenuse (?a ?b)
(sqrt (+ (* ?a ?a) (* ?b ?b)))
)
Следует отметить, что символы операций в языке CLIPS предшествуют своим параметрам, которые указываются через пробел, например, привычное выражение (3+4+5) записывается как (+ 3 4 5), а (a > b) как (> a b).
Формат определения функции в CLIPS следующий:
(deffunction <имя функции> (<аргумент> ... < аргумент >)
<выражение>
<выражение>
)
Функция возвращает результат последнего выражения в списке. Иногда выполнение функции имеет побочные эффекты, как в приведенном ниже примере.
(deffunction init (?day)
(reset)
(assert (today is ?day))
)
В результате после запуска функции на выполнение командой
CLIPS> (init Sunday) будет выполнена команда reset и, следовательно, очищена база фактов, а затем в будет включен новый факт (today is Sunday).
А в результате запуска функции hypotenuse на выполнение командой
CLIPS> (hypotenuse 3 4) будет выдан известный ответ
CLIPS> 5.0
1.6. Пример программы: "Робот и ящик"
С целью закрепления теории ознакомимся со следующей программой: имеются 2 комнаты - A и B, в комнате A находится робот, в комнате B - ящик; задача - вытолкнуть ящик в комнату A
Исходный текст приведен ниже:
;; ШАБЛОНЫ
;; Шаблон "цель"
(deftemplate goal
(slot action (type SYMBOL))
(slot object (type SYMBOL))
(slot from (type SYMBOL))
(slot to (type SYMBOL))
)
;; Шаблон "в"
(deftemplate in
(slot object (type SYMBOL))
(slot location (type SYMBOL))
)
;; ФАКТЫ
;; Робот в комнате А,
;; ящик в комнате B,
;; цель - вытолкнуть ящик в комнату A.
(deffacts world
(in (object robot) (location RoomA))
(in (object box) (location RoomB))
(goal (action push) (object box) (from RoomB) (to RoomA))
)
;;ПРАВИЛА
;; Прекратить процесс, когда цель будет достигнута.
(defrule stop
(goal (object ?X) (to ?Y))
(in (object ?X) (location ?Y))
=>
(halt)
)
;; Если робот отсутствует в том месте, где находится объект,
;; который нужно передвинуть,
;; переместить туда робот.
(defrule move
(goal (object ?X) (from ?Y))
(in (object ?X) (location ?Y))
?robot-position <- (in (object robot) (location ?Z&~?Y))
=>
(modify ?robot-position (location ?Y))
)
;; Если робот и объект не в том помещении,
;; которое указано в цели,
;; переместить туда робот и объект.
(defrule push
(goal (object ?X) (from ?Y) (to ?Z))
(in (object ?X) (location ?Y))
?object-position <- (in (object ?X) (location ?Y))
?robot-position <- (in (object robot) (location ?Y))
=>
(modify ?robot-position (location ?Z))
(modify ?object-position (location ?Z))
)
Следует заметить, что здесь встречается новый оператор modify, который позволяет изменять уже существующий факт. В данной программе мы изменяем положение объектов (робота и ящика).
Остановка программы здесь осуществляется с помощью служебной команды halt (см. правило stop).
ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ
1. Изучение описания работы.
2. Изучение интерфейса оболочки языка CLIPS.
3. Выполнение примеров теоретической части работы.
4. Выполнение в режиме отладки (включить просмотр правил и фактов) программы "Робот и ящик" (предварительно скопировать исходный текст программы в текстовый редактор и сохранить под именем robot.clp, затем загрузить в CLIPS).
5. Модифицировать программу "Робот и ящик" таким образом, чтобы ящик необходимо было передвинуть в комнату C. Выполнить в режиме отладки.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Каков основной принцип работы языка CLIPS?
2. Что такое факты? Приведите примеры добавления фактов в базу знаний.
3. Что такое привила? Приведите примеры правил.
4. Как происходит работа программы на языке CLIPS, какие для этого используются команды?
5. Что такое шаблоны? Приведите примеры шаблонов.
6. Как определяются функции? Приведите примеры функций.
ЛАБОРАТОРНАЯ РАБОТА №2
ОБЪЕКТНО-ОРИЕНТИРОВАННЫЕ СРЕДСТВА CLIPS
Цель работы: ознакомление с возможностями объектно-ориентированного программирования на языке CLIPS.
Технические средства: персональный компьютер с операционной системой Windows 9x/Me/NT/2000/XP
Программные средства: текстовый редактор (Блокнот, WordPad и т.п.), оболочка языка CLIPS версии 6.1 и выше
ОСНОВНЫЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ
Использование ОО средств в CLIPS позволяет значительно упростить программирование правил, поскольку для обновления данных можно применять механизм передачи и обработки сообщений методами классов.
Примерный шаблон объявления класса ("автомат газводы"):
(defclass gas-water-automate
(is-a USER)
(role concrete)
(pattern-match reactive)
(slot gas-water (type INTEGER) (create-accessor read-write))
(slot syrup (type INTEGER) (create-accessor read-write))
)
Первые три слота этого класса - системные:
* gas-water-automate - это пользовательский класс
* gas-water-automate - конкретный класс, т.е. возможно создание экземпляров этого класса (в отличие от абстрактного класса)
* экземпляры класса gas-water-automate могут быть использованы в качестве объектов данных, которые можно сопоставлять с условиями в правилах и использовать в действиях, определенных правилами.
Следующие два слота представляют свойства класса:
* слот gas-water указывает на количество воды (в стаканах), оставшееся в автомате
* слот syrup указывает на количество сиропа (на один стакан), оставшееся в автомате
Для того чтобы иметь возможность записывать в слот новое значения и считывать текущее, нужно разрешить формирование соответствующих функций доступа с помощью конструкции (create-accessor read-write).
Теперь сформируем экземпляр класса gas-water-automate:
(definstances automates
(our-automate of gas-water-automate
(gas-water 2)
(syrup 3)
)
)
Т.е. в "нашем" автомате (объект our-automate) сейчас воды ровно на 2 стакана, а сиропа - на 3 стакана.
Изменение значений свойств объектов по правилам ООП производится самими объектами, поэтому в языке CLIPS это реализовано посредством обработчиков сообщений.
Создадим обработчик сообщения, который по номиналу опущенной в автомат монеты будет наливать воды без сиропа (1 копейка) и воду с сиропом (3 копейки); если же в автомат опущена какая-либо другая монета, то выдавать предупредительное сообщение. Также предусмотрим случай, что могут закончиться как сироп, так и вода.
(defmessage-handler gas-water-automate getwater (?money)
(if (= ?money 1) then
(if (> (dynamic-get gas-water) 0) then
(dynamic-put gas-water
(- (dynamic-get gas-water) 1)
)
(printout t "Your gas-water, please" crlf)
else
(printout t "Sorry, no more gas-water" crlf)
)
else (if (= ?money 3) then
(if (and (> (dynamic-get gas-water) 0)
(> (dynamic-get syrup) 0)
) then (dynamic-put gas-water
(- (dynamic-get gas-water) 1))
(dynamic-put syrup (- (dynamic-get syrup) 1))
(printout t "Your gas-water with syrup, please" crlf)
else (printout t "Sorry, no more gas-water or syrup" crlf)
)
else (printout t "Wrong money" crlf)
)
)
)
Здесь:
* gas-water-automate - имя класса, к экземплярам которого применяется обработчик сообщения
* getwater - имя обработчика сообщения
* далее в скобках - список параметров через пробел.
Обратите внимание на новые команды:
* dynamic-get и dynamic-put - производят соответственно чтение и запись значений свойств объектов
* if ... then ... else - условный оператор
Теперь определим правило, которое будет "говорить" автомату дать воды, сообщая ему номинал монеты:
(defrule getwater
(money ?money)
=>
(send [our-automate] getwater ?money)
)
Теперь наберем команду (reset), зададим факт, что у нас монета в 3 копейки:
(assert (money 3))
и запустим программу командой (run).
А теперь попробуем заново, но с монетой в 1 копейку:
(reset)
(assert (money 1))
(run)
ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ
1. Изучение описания работы.
2. Выполнение программы (предварительно скопировать исходный текст программы частями в текстовый редактор и сохранить под именем automate.clp, затем загрузить в CLIPS).
3. Модифицировать программу таким образом, чтобы:
* в базу фактов записывался не только номинал монеты, но и тип сиропа - лимонный (limon) или вишневый (cherry);
* параметром обработчика сообщения были номинал монеты и тип сиропа;
* вместо слота syrup слотами автомата были лимонный и вишневый сиропы;
* автомат сообщал, какой сироп он наливает в стакан, или говорил, что нет такого сиропа.
Выполнить эту программу с различными начальными количествами сиропа и воды и разными номиналами монеты, чтобы охватить всевозможные варианты выдачи сообщений автоматом.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Как описываются классы на языке CLIPS? Приведите пример.
2. Как создаются экземпляры классов? Приведите пример.
3. Для чего нужны обработчики сообщений? Приведите пример простейшего обработчика сообщений.
СПИСОК ЛИТЕРАТУРЫ
1. Питер Джексон. Введение в экспертные системы. М.: Изд. дом "Вильямс", 2001, 622с.
2. Адрес языка CLIPS в Интернете: http://www.ghg.net/clips/CLIPS.html
12
Документ
Категория
Рефераты
Просмотров
132
Размер файла
81 Кб
Теги
metclips
1/--страниц
Пожаловаться на содержимое документа