- •Введение
- •Арифметика
- •Ввод-вывод при работе с консолью
- •Управление средой
- •Правила
- •Управление правилами
- •Использование переменных в правилах
- •Наборы фактов
- •Конструкции
- •Правила-2 Активации и повестка
- •Диагностические сообщения
- •Получение адреса факта
- •Сложные условия
- •Правила-3 Условия с кванторами
- •Вызовы функций в качестве ограничений параметров фактов
- •Сложные ограничения на параметры фактов
- •Поддержка истинности
- •Стратегии
- •Последовательности
- •Шаблонные факты
Диагностические сообщения
В системе CLIPS можно настроить вывод диагностических сообщений о различных событиях. Для включения вывода диагностических сообщений используется команда watch, а для выключения — unwatch. Единственным параметром обеих команд должен быть символ, задающий наблюдаемые события. Среди прочих поддерживаются следующие значения этого параметра:
-
facts — наблюдение за добавлением фактов в список фактов и удалением их из него;
-
activations — наблюдение за добавлением активаций в повестку и удалением их из нее (однако удаление активаций по причине срабатывания не наблюдается).
В выводимых сообщениях добавление наблюдаемого элемента представляется стрелков вправо, а удаление — стрелкой влево.
Пример:
CLIPS> (reset)
CLIPS> (watch facts)
CLIPS> (assert (summand 7) (summand 8))
==> f-1 (summand 7)
==> f-2 (summand 8)
<Fact-2>
CLIPS> (reset)
<== f-0 (initial-fact)
<== f-1 (summand 7)
<== f-2 (summand 8)
==> f-0 (initial-fact)
CLIPS> (unwatch facts)
CLIPS> (watch activations)
CLIPS> (assert (summand 7) (summand 8))
==> Activation 0 print-sum: f-1,f-1
==> Activation 0 print-sum: f-1,f-2
==> Activation 0 print-sum: f-2,f-1
==> Activation 0 print-sum: f-2,f-2
<Fact-2>
CLIPS> (reset)
<== Activation 0 print-sum: f-2,f-1
<== Activation 0 print-sum: f-1,f-1
<== Activation 0 print-sum: f-1,f-2
<== Activation 0 print-sum: f-2,f-2
CLIPS> (unwatch activations)
Получение адреса факта
Иногда в правой части правила может понадобиться удалить из списка фактов факт, приведший к активизации правила (т. е. факт сопоставленных одному из образцов, указанных в левой части правила). Чтобы присвоить переменной адрес факта, сопоставленного образцу, имя этой переменной записывают перед образцом, отделяя от последнего стрелкой влево. Пример:
CLIPS> (clear)
CLIPS> (deffacts strings
(string "Строка 1")
(string "Строка 2")
(string "Строка 3"))
CLIPS> (defrule print-string
(string ?s)
?f <- (printing)
=>
(printout t ?s crlf)
(retract ?f))
CLIPS> (reset)
CLIPS> (assert (printing))
<Fact-4>
CLIPS> (agenda)
0 print-string: f-1,f-4
0 print-string: f-2,f-4
0 print-string: f-3,f-4
For a total of 3 activations.
CLIPS> (watch facts)
CLIPS> (watch activations)
CLIPS> (run)
Строка 1
<== f-4 (printing)
<== Activation 0 print-string: f-2,f-4
<== Activation 0 print-string: f-3,f-4
CLIPS> (agenda)
Сложные условия
В левой части правил, могут использоваться не только образцы, но и другие виды условных элементов. Все эти условные элементы также записываются в виде списка, причем первый элемент списка представляет собой символ и задает вид условия, в то время как остальные элементы задают параметры условия. Перечислим некоторые из поддерживаемых условных элементов:
-
and — конъюнкция. Параметры должны быть условными элементами. Количество параметров может быть любым. Конъюнкция обычно используется в качестве вложенного элемента, поскольку простое перечисление нескольких условных элементов в левой части правила, в сущности, задает неявную конъюнкцию;
-
or — дизъюнкция. Параметры такие же, как у конъюнкции. В пределах дизъюнкции может быть несколько присваиваний значения одной переменной, если эти присваивания находятся в различных элементах дизъюнкции. Если такую переменную необходимо использовать за пределами дизъюнкции, то каждый элемент дизъюнкции должен содержать присваивание значения этой переменной;
-
not — отрицание. Единственным параметром должен быть условный элемент. Если в отрицаемом элементе содержится присвоение переменной, то использовать эту переменную можно только в пределах этого элемента;
-
test — тест. Параметром должен быть вызов функции (т. е. команда). Условный элементы выполняется в том случае, когда функция возвращает любое значение кроме символа FALSE. Часто в элементе test используют функции сравнения, например =, <>, <, <=, >, >=, eq, neq, evenp, oddp, and, or, not.
Пример:
CLIPS> (deffacts doors
(door room-a room-b) (door room-a room-c)
(door room-b room-d)
(door room-c room-d)
(door room-d room-e)
(door room-e room-f) (door room-e room-g)
(door room-f room-h)
(door room-g room-h))
CLIPS> (defrule add-origin-room
(origin-room ?r)
=>
(assert (reachable-room FALSE ?r 0)))
CLIPS> (defrule add-nonvisited-room
(reachable-room ? ?r1 ?n1)
(or (door ?r1 ?r2) (door ?r2 ?r1))
(not (reachable-room ? ?r2 ?))
=>
(assert (reachable-room ?r1 ?r2 (+ ?n1 1))))
CLIPS> (defrule update-visited-room
(reachable-room ? ?r1 ?n1)
(or (door ?r1 ?r2) (door ?r2 ?r1))
?f <- (reachable-room ? ?r2 ?n2)
(test (< (+ ?n1 1) ?n2))
=>
(retract ?f)
(assert (reachable-room ?r1 ?r2 (+ ?n1 1))))
CLIPS> (defrule add-last-path-element
(declare (salience -1))
(target-room ?r2)
(reachable-room ?r1 ?r2 ?)
=>
(assert (path-element ?r1 ?r2)))
CLIPS> (defrule add-previous-path-element
(path-element ?r2 ?)
(reachable-room ?r1 ?r2 ?)
=>
(assert (path-element ?r1 ?r2)))
CLIPS> (defrule print-first-path-element
(path-element FALSE ?r2)
=>
(printout t ?r2)
(assert (printed ?r2)))
CLIPS> (defrule print-next-path-element
(printed ?r1)
(path-element ?r1 ?r2)
=>
(printout t " -> " ?r2)
(assert (printed ?r2)))
CLIPS> (defrule complete-path-printing
(target-room ?r2)
(printed ?r2)
=>
(printout t crlf))
CLIPS> (reset)
CLIPS> (assert (origin-room room-b))
<Fact-10>
CLIPS> (assert (target-room room-g))
<Fact-11>
CLIPS> (run)
room-b -> room-d -> room-e -> room-g
Примечание: declare — это не образец, а директива, использующаяся для задания приоритета (salience) правила. Правила всегда выполняются в порядке убывания приоритета. По умолчанию приоритет равен 0.