
- •Введение
- •Система обозначений
- •Переменные
- •Функция bind
- •Глобальные переменные
- •Процедурные функции
- •Функция if
- •Функция while
- •Функция switch
- •Функция loop-for-count
- •Функция break
- •Функция halt
- •Конструкция deffunction
- •Функция return
- •Конструкция deftemplate
- •Упорядоченные факты
- •Атрибуты deftemplate
- •Правила
- •Значимость
- •Рабочий список правил и выполнение программы
- •Отображение рабочего списка правил
- •Команды, применяемые для манипулирования конструкциями
- •Команда printout
Введение
CLIPS — это язык программирования, позволяющий использовать целый ряд подходов, который обеспечивает поддержку программирования на основе правил, объектно-ориентированного и процедурного программирования. Возможности логического вывода и представления, предоставляемые основанным на правилах языком программирования CLIPS, аналогичны возможностям языка OPS5, но являются более мощными. По своей синтаксической структуре правила CLIPS весьма напоминают правила, применяемые в таких языках, как Eclipse, CLIPS/R2 и Jess, но CLIPS поддерживает только правила прямого логического вывода. Этот язык не обеспечивает обратный логический вывод.
Язык CLIPS (название которого представляет собой сокращение от С Language Integrated Production System — продукционная система, интегрированная с языком С) был разработан с использованием языка программирования С в Космическом центре NASA/Джонсон. Перед разработчиками этого языка была поставлена конкретная задача — обеспечить полную переносимость, низкую стоимость и простую интеграцию с внешними системами. Но компоненты расшифровки аббревиатуры CLIPS не следует трактовать буквально. Дело в том, что первоначально CLIPS обеспечивал поддержку только программирования на основе правил (отсюда происходит часть его обозначения как "продукционной системы"). Но в версии 5.0 языка CLIPS введена поддержка процедурного и объектно-ориентированного программирования. Кроме того, может сбить с толку и часть этого сокращенного обозначения, в которой упоминается "язык С", поскольку одна из версий CLIPS разработана полностью на языке Ada.
Система обозначений
В книге для описания синтаксиса различных команд и конструкций, рассматриваемых в ходе изложения, используется одна и та же система обозначений. Эта система обозначений состоит из трех различных типов текста, подлежащего вводу.
Обозначения первого типа относятся к символам и знакам, которые должны быть введены точно так, как они показаны; к ним относятся любые текстовые надписи, не заключенные в пару знаков <>, [ ] или {}. Например, рассмотрим следующее описание синтаксиса:
(example)
Это описание синтаксиса означает, что конструкция (example) должна быть введена так, как показано. Точнее, вначале должен быть введен знак открывающей скобки (, затем выражение еxample и, наконец, знак закрывающей скобки, ).
Квадратные скобки, [ ], указывают, что содержимое в квадратных скобках является необязательным. Например, следующее описание синтаксиса показывает, что цифра 1, находящаяся в квадратных скобках, может не указываться:
(example [1])
Таким образом, следующий результат ввода является совместимым с указанным выше синтаксическим определением:
(example)
как и такой результат ввода:
(example 1)
Знаки "меньше" и "больше", вместе взятые, <>, указывают, что должна быть выполнена замена значением того типа, который обозначен содержимым, находящимся внутри знаков о. Например, следующее описание синтаксиса, в котором используются знаки "меньше" и "больше", показывает, что должна быть выполнена замена целочисленным значением:
<integer>
Продолжая предыдущие примеры, укажем, что такое описание синтаксиса:
(example <integer>)
может быть заменено следующими результатами ввода:
(example 1)
или:
(example 5)
или:
(example -20)
Еще один вариант обозначения характеризуется использованием звездочки, *, которая следует за описанием. Такое обозначение показывает, что описание может быть заменено вхождениями указанного значения в количестве от нуля или больше. После каждого вхождения некоторого значения должны быть проставлены пробелы. Например, следующее описание синтаксиса:
<integer>*
может быть заменено таким результатом ввода: 1
или таким: 1 2
или таким: 12 3
или любым другим количеством разделенных пробелами целых чисел, или же вообще оставлено пустым.
Описание, за которым следует знак "плюс", +, указывает, что вместо этого описания синтаксиса должно быть введено одно или несколько значений, заданных этим описанием. Необходимо отметить, что следующее описание синтаксиса:
<integer>+
эквивалентно такому описанию синтаксиса:
<integer> <integer>*
Вертикальная черта, |, указывает на необходимость выбора одного или нескольких элементов, разделенных вертикальными чертами. Например, следующее описание синтаксиса:
all | none | some
может быть заменено таким результатом ввода: all
или таким: попе или таким: some
Поля
В языке CLIPS предусмотрено восемь типов полей, которые принято также называть примитивными типами данных: число с плавающей точкой, целое число, символ, строка, внешний адрес, адрес факта, имя экземпляра и адрес экземпляра (float, integer, symbol, string, external-address, fact-address, instance-name, instance-address).
Числовое поле может состоять из трех частей: знак, значение и показатель степени. Знак и показатель степени являются необязательными. В качестве знака может быть указан + или -. Значение состоит из одной или нескольких цифр, между которыми может находиться единственная необязательная десятичная точка. Показатель степени состоит из буквы е или Е, за которой следует необязательный знак + или -, сопровождаемый одной или несколькими цифрами. Любое число, состоящее из необязательного знака + или -, за которым следуют только цифры, записывается в память в виде целого числа. Все другие числа хранятся как числа с плавающей точкой.
Ниже приведены примеры допустимых чисел с плавающей точкой:
1.5
1.0
0.7
9е+1
3.5е10
А следующие примеры показывают допустимые целые числа:
1
+3
-1
65
Символ — это поле, которое начинается с печатного символа ASCII и продолжается другими печатными знаками в количестве от нуля или больше. Конец символа достигается при обнаружении разграничителя. К разграничителям относятся любые непечатаемые знаки кода ASCII (включая пробелы, знаки табуляции, знаки возврата каретки и перевода строки), знак " (двойная кавычка), знак ( (открывающая круглая скобка), знак ) (закрывающая круглая скобка), знак ; (точка с запятой), знак & (амперсанд), знак | (вертикальная черта), знак ~ (тильда) и знак < (меньше). Символы не могут содержать разграничителей (за исключением знака <, который может быть первым знаком в символе). Кроме того, знак ? и последовательность знаков $? (вопросительный знак и знак доллара с вопросительным знаком) нельзя помещать в начало символа, поскольку они используются для обозначения переменных. К тому же как символ рассматривается последовательность знаков, которые не соответствуют точно формату числового поля.
Ниже приведены примеры допустимых символов.
Space-Station
February
fire
activate_sprinkler_system
notify-fire-department
shut-down-electrical-junction-387
!?#$^*
345B
346-95-6156
Интерпретатор CLIPS сохраняет в неизменном виде прописные и строчные буквы, обнаруженные им в лексемах. Таким образом, язык CLIPS предусматривает проведение различий между буквами верхнего и нижнего регистров, поэтому называется чувствительным к регистру. Например, такие символы рассматриваются в языке CLIPS как различные:
case-sensitive Case-Sensitive CASE-SENSITIVE
Следующим типом поля является строка. Строка должна начинаться и заканчиваться двойными кавычками, которые являются частью поля. Между двойными кавычками могут находиться от нуля и больше знаков, включая те, которые обычно используются в языке CLIPS как разграничители. Ниже приведены примеры допустимых строк CLIPS.
"Activate the sprinkler system."
"Shut down electrical junction 387."
"!?#$^"
"John Q. Public"
Пробелы обычно используются в языке CLIPS как разграничители для разделения полей (таких как символы) и других лексем. Дополнительные пробелы, присутствующие между лексемами, отбрасываются. Но пробелы, входящие в состав строки, сохраняются. Например, в языке CLIPS следующие четыре строки рассматриваются как различные:
"spaces"
"spaces "
" spaces"
" spaces "
Еще раз отметим, что двойные кавычки применяются для обозначения начала и конца строк, поэтому двойные кавычки нельзя непосредственно помещать в саму строку. Например, строка
" "three-tokens" "
обрабатывается интерпретатором CLIPS как три отдельные лексемы следующим образом, поскольку двойные кавычки рассматриваются и как обозначения строк, и как разграничители:
" "
three-tokens
" "
Двойные кавычки можно включать в строку с использованием знака операции переключения на другой режим обработки, т.е. обратной косой черты, \. Например, следующая строка:
"\"single-token\""
обрабатывается интерпретатором CLIPS как такое строковое поле:
""single-token""
При этом создается только одно поле, поскольку знак обратной косой черты исключает возможность обработки следующей за ним двойной кавычки как разграничителя. Сам знак обратной косой черты может быть задан в строке с использованием двух подряд идущих знаков обратной косой черты. Например, строка
"\\single-token\\"
обрабатывается интерпретатором CLIPS как такое строковое поле:
"\single-token\"
Поле внешнего адреса содержит адрес внешней структуры данных, возвращаемой функцией, определяемой пользователем. Безусловно, значение внешнего адреса невозможно задать с помощью последовательности знаков, образующих лексему, а основная немодифицированная версия CLIPS не содержит функций, возвращающих внешние адреса, поэтому в основной немодифицированной версии CLIPS невозможно создать поле такого типа.
Оставшимися тремя типами полей являются адрес факта, адрес экземпляра и имя экземпляра. Адрес факта используется для получения ссылки на конкретный факт. Как и внешний адрес, адрес факта не может быть задан с помощью последовательности знаков, образующей лексему. Но предусмотрена возможность получать адреса фактов с помощью правил в составе процесса сопоставления с шаблонами.
Еще одним сложным представлением данным, предусмотренным в языке CLIPS, являются экземпляры. На экземпляры можно ссылаться с использованием либо адреса экземпляра, либо имени экземпляра. Адрес экземпляра подобен адресу факта, но ссылается на экземпляр, а не на факт. Предусмотрена также возможность ссылаться на экземпляр с помощью имени. Имя экземпляра — это символ специального типа, который заключен в левую и правую квадратные скобки. Например, [pump-1] представляет собой имя экземпляра.
Ряды, состоящие из полей, содержащихся вместе в одной синтаксической позиции в количестве от нуля и больше, называются многозначным значением. Многозначные значения обычно создаются путем вызова некоторой функции или путем задания ряда полей. Во время вывода на внешнее устройство многозначное значение заключается в левую и правую круглые скобки. Например, многозначное значение нулевой длины выводится следующим образом:
()
а многозначное значение, содержащее символы this и that, выводится так: (this that)
Процедурное программирование
В языке CLIPS предусмотрены средства процедурного программирования, аналогичные тем, которые применяются в таких языках, как С, Ada и Pascal. Иногда бывает более удобно (и более эффективно) осуществлять некоторые операции с использованием подхода, базирующегося на процедурном программировании, а не подхода, основанного на правилах.
Функции и выражения
Язык CLIPS позволяет не только обрабатывать символические факты, но и проводить вычисления. Но всегда следует учитывать, что такой язык экспертных систем, как CLIPS, не предназначен для сложных математических расчетов. Безусловно, математические функции CLIPS являются достаточно мощными, но они в основном должны обеспечивать модификацию таких числовых значений, которые применяются для осуществления операций логического вывода с помощью прикладной программы. Элементарные арифметические операции языка CLIPS: +, -, *, /.
Для представления числовых выражений в языке CLIPS применяется такой же стиль, как в языке LISP. В языках LISP и CLIPS числовое выражение, которое обычно принято записывать как 2 + 3, должно быть записано в префиксной форме, (+ 2 3). Общепринятый способ записи числовых выражений называется инфиксной формой, поскольку в этой форме знаки математических операций записываются между операндами, или параметрами. А в префиксной форме, применяемой в языке CLIPS, знак операции должен предшествовать операндам, а числовое выражение должно быть заключено в круглые скобки.
Простейшим способом вычисления числового выражения (а также любого другого выражения) в языке CLIPS является ввод этого выражения в приглашении верхнего уровня. Например, после ввода выражения (+ 2 2) в приглашении CLIPS будет получен следующий вывод:
CLIPS> (+ 2 2)
4
CLIPS>
В приглашении верхнего уровня можно также вводить другие арифметические функции. Ниже приведены результаты, полученные при вычислении некоторых других выражений.
CLIPS> (+ 2 3)
5
CLIPS> (- 2 3)
-1
CLIPS> (* 2 3)
6
CLIPS> (/ 2 3)
0.66666667
CLIPS>
Префиксная система обозначений позволяет очень просто представить переменное количество параметров, причем переменное количество параметров принимают многие функции языка CLIPS. Параметры числового выражения в количестве больше двух могут быть указаны после функций +, -, / и *. К параметрам, количество которых превышает два, применяется одна и та же последовательность арифметических вычислений. Следующие примеры, введенные в приглашении верхнего уровня, показывают, как используются три параметра (вычисление осуществляется слева направо):
CLIPS> (+2 3 4)
9
CLIPS> (-2 3 4)
-5
CLIPS> (* 2 3 4)
24
CLIPS> (/ 2 3 4)
0.16666667
CLIPS>