Получение адреса факта
Иногда в правой части правила может понадобиться удалить из списка фактов факт, приведший к активизации правила (т. е. факт сопоставленных одному из образцов, указанных в левой части правила). Чтобы присвоить переменной адрес факта, сопоставленного образцу, имя этой переменной записывают перед образцом, отделяя от последнего стрелкой влево. Пример: 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. Правила-3
|