Условный элемент not может отрицать только одно выражение. Несколько условных элементов нужно отрицать с помощью нескольких элементов not. Тщательно следите за комбинациями not с or или and; результат не всегда очевиден!
Пример 6.30. Применение условного элемента not
(defrule high-flow-rate
(temp high)
(valve open)
(not (error-status confirmed))
=>
(printout t "Recommend closing of valve due to high temp" crlf))
В логическом элементе not можно использовать связанные переменные, так же как и в других условных элементах:
Пример 6.31. Правило check-value
(defrule check-valve
(check-status ?valve)
(not (valve-broken ?valve))
=>
(printout t "Device " ?valve " is OK" crlf))
С помощью условного элемента not можно, наконец, довести до совершенства наше правило Find-2-coeval-Person, последняя версия которого была приведена в разд. 6.5.1. Если вы помните, это правило выводит всевозможные пары персон одинакового возраста. Чтобы данное правило не выводило эквивалентные по смыслу пары имен (например, Bob-Sue и Sue-Bob), преобразуем нашу программу следующим образом:
Пример 6.32. Улучшенное правило Find-2-coeval-Person
Обратите внимание на произведенные изменения. Во-первых, с помощью конструктора deftemplate был Добавлен дополнительный шаблон person-pair. В фактах, соответствующих данному шаблону, будет храниться информация об уже найденных парах ровесников. Кроме того, было сильно изменено и само правило. В его левой части было добавлено два условия:
Эти условные элементы проверяют наличие фактов типа person-pair и, тем самым отслеживают, была ли уже обработана данная пара или ее перестановка. Если эти факты отсутствуют, то это означает, что обработка еще не была выполнена. В этом случае правило активируется, и выполняются действия, описанные в правой части правила. А именно выводится на экран сообщение о найденной паре ровесников и добавляется соответствующий факт person-pair, утверждающий, что данная пара уже была обработана. Для запуска программы выполните команды reset и run. Программа выведет на экран следующую информацию:
Пример 6.33. Результат работы правила Find-2-Coeval-Person
name=Sue name=Bob age=20
name=Sue name=Joe age=20
name=Sue name=Joe age=34
name=Bob name=Joe age=20
Если вы внимательно посмотрите на полученный результат и исходные данные, то обнаружите, что это именно то, что нам было нужно. Это список всевозможных ровесников без повторений и с исключением того факта, что все люди являются ровесниками сами себе. Теперь наше правило достигло полного совершенства! Обратите внимание на тот факт, что если вы повторно попробуете выполнить команду run, то ничего не увидите. Это происходит потому, что в списке фактов содержится информация обо всех обработанных парах, оставшаяся после первого запуска. Для того чтобы повторно запускать данный пример, выполняйте команду reset перед каждой командой run.