Имя переменной должно быть значением типа symbol и обязательно начинаться с буквы. В имени переменной не разрешается использовать кавычки, т. е. строка не может использоваться как имя переменной или ее часть.
Правила сопоставления образцов при использовании переменных в ограничениях образца аналогичны правилам, использующимся для групповых символов. В момент первого появления имени переменной она ведет себя так же, как и соответствующий групповой символ. В этот момент CLIPS связывает значения поля с заданной переменной. Эта связь будет действовать только в рамках правила, в котором она возникла. Каждое правило имеет свой собственный список имен переменных со значениями, связанными с ними, эти переменные локальны для правил.
Связанные переменные могут быть использованы во внешних функциях. Символ $ имеет особое значение в левой части правил — этот оператор отображает, что некоторая, возможно пустая, последовательность полей требует сопоставления. В правой части правила символ $ ставится перед переменной для обозначения того, что перед использованием переменной в качестве аргумента функции необходимо раскрыть последовательность полей, содержащихся в переменной. Таким образом, при использовании переменных в качестве параметров функций (как в левой, так и правой части правил) перед именем переменной, содержащей значение составного поля, не должен стоять символ $ (за исключением случаев, когда требуется раскрыть последовательность полей). При использовании переменной, содержащей значение составного поля, в других случаях, перед ее именем должен стоять символ $. Нельзя применять переменную составного поля при операциях с простым полем образца шаблона или объекта.
В качестве примера введите в среду CLIPS следующее правило:
Пример 6.14. Правило Find-data
(defrule Find-data
(data ? blue ?x $?y) =>
(printout t "Found data (data ? blue " ?x " " ?y ")" crlf))
Выполните команды reset и run. Если правило было введено в систему без ошибок, то на экране появится следующий результат:
Пример 6.15. Результат работы правила Find-data
Found data (data ? blue red (6.9))
Found data (data ? blue RED ())
Found data (data ? blue red ()}
Found data (data ? blue red ()}
Образцу, заданному в правиле, удовлетворяют четыре факта с индексами 1, 3, 4, 5. В результате активации правило выводит на экран свойства фактов, активировавших правило. Значение переменной, содержащей значение из составного поля, выводится в скобках. Кроме первого случая (факта с индексом 5), переменная содержит пустое значение. Переменную составного поля не обязательно использовать в качестве последнего ограничения. Рассмотрим следующее правило:
Пример 6.16. Модифицированное правило Find-data
(defrule Find-data
(data ?x $?y ?z) =>
(printout t "x=" ?x " y=" ?y " z=" ?z crlf))
Заданному образцу удовлетворяют все факты data, но обратите внимание, каким образом связываются значения с переменной у в разных случаях:
Пример 6.17. Результат работы модифицированного правила Find-data
х=1.0 y=(blue) z=red
х=1 у=() z=blue
х=1 y=(blue) z=red
х=1 y=(blue) z=RED
х=1 y=(blue red) z=6.9
После того как произошло связывание переменной со значением, все ссылки на эту переменную возвращают значение, с которым переменная была связана. Это действительно как для переменных, связанных с составными полями, так и для переменных, связанных с простыми полями. Кроме того, допустимы ссылки между образцами в одном правиле.
Приведенное выше правило Find-2-Coevai-person выведет на экран всевозможные пары имен людей (все перестановки) одинакового возраста. Как научить это правило не выводить эквивалентные по смыслу или бессмысленные пары одинаковых имен (Bob-Bob), мы увидим в следующих разделах.