Определение 8.1. Синтаксис конструктора deffunction 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Определение 8.1. Синтаксис конструктора deffunction



(deffunction <имя-функции>

[<комментарии>]

<обязательные-параметры>

[<групповой-параметр>]

<действия>)

<обязательные-параметры>::= <выражение-простое-поле>
<групповой-параметр>    ::= <выражение-составное-поле>

Функция, создаваемая с помощью конструктора deffunction, должна иметь уникальное имя, не совпадающее с именами других внешних и внутренних функций. Функция, созданная с помощью deffunction, не может быть пере­гружена (см. гл. 10). Конструктор deffunction должен быть объявлен до пер­вого использования создаваемой им функции. Исключения составляют только рекурсивные функции.

В зависимости от того, задан ли групповой параметр, функция, созданная конструктором, может принимать точное число параметров или число па­раметров не меньшее, чем некоторое заданное. Обязательные параметры определяют минимальное число аргументов, которое должно быть передано функции при ее вызове. В действиях функции можно ссылаться на каждый из этих параметров как на обычные переменные, содержащие простые зна­чения. Если был задан групповой параметр, то функция может принимать любое количество аргументов большее или равное минимальному числу. Если групповой параметр не задан, то функция может принимать число ар­гументов точно равное числу обязательных параметров. Все аргументы функции, которые не соответствуют обязательным параметрам, группируются в одно значение составного поля. Ссылаться на это значение можно, используя символ группового параметра. Для работы с групповым парамет­ром могут использоваться стандартные функции CLIPS, предназначенные для работы с составными полями (см. гл. 15), такие как length и nth. Определение функции может содержать только один групповой параметр.

Приведенный пример 8.1 демонстрирует описанные выше возможности работы с групповыми параметрами.

Пример 8.1. Использование группового параметра

 

(deffunction print-args (?a?b $?c)

(printout t?a “ “?b “ and “ (length?c) “ extras: “?c

crlf))

(print-args 1 2)

(print-args a b c d)

(print-args a)

В данном примере с помощью конструктора deffunction определяется функция print-args, которая принимает два обязательных параметра:?а и?b, и имеет групповой параметр $?с. Функция выводит на экран свои обязательные параметры, а также число полей в составном параметре и его содержимое. Результат выполнения данного примера приведен на рис. 8.1.

Рис. 8.1. Результат работы функции print-args

Обратите внимание, что вызов функции с числом параметров, меньшим минимального, приводит к сообщению об ошибке.

При вызове функции интерпретатор CLIPS последовательно выполняет действия в порядке, заданном конструктором. Функция возвращает значе­ние, равное значению, которое вернуло последнее действие или вычислен­ное выражение. Если последнее действие не вернуло никакого результата, то выполняемая функция также не вернет результата (как в приведенном выше примере). Если функция не выполняет никаких действий, то возвра­щенное значение равно false. В случае возникновения ошибки при выпол­нении очередного действия выполнение функции будет прервано и возвра­щенным значением также будет false.

Функции могут быть само- и взаимно рекурсивными. Саморекурсивная функция просто вызывает сама себя из списка своих собственных действий. В качестве примера можно привести функцию, вычисляющую факториал.

Пример 8.2. Использование рекурсии для вычисления факториала

(deffunction factorial (?a)

(if (or (not (integerp?a)) (<?a 0)) then

(printout t "Factorial Error!" crlf)

else

(if (=?a 0) then

1

else

(*?a (factorial (-?a 1))))))

Взаимная рекурсия между двумя функциями требует предварительного объ­явления одной из этих функций. Для предварительного объявления функ­ции в CLIPS используется конструктор deffunction с пустым списком дей­ствий. В следующем примере функция foo предварительно объявлена и та­ким образом может быть вызвана из функции bar. Окончательная реализация функции foo выполнена конструктором после объявления функции bar.

Пример 8.3. Создание взаимно рекурсивных функций

 

(deffunction foo ())

(deffunction bar ()

(foo))

(deffunction foo ()

(bar))

Внимательно следите за рекурсивными вызовами функций, слишком боль­шой уровень рекурсии может привести к переполнению стека памяти. Например, приведенный выше пример с функциями bar и foo приводит к результату, представленному на рис. 8.2, и аварийному завершению CLIPS.

 

Рис. 8.2. Переполнение стека

Обратите внимание, что на рис. 8.2 в главном окне CLIPS выводится информация о запуске каждой функции. Для установки этого режима восполь­зуйтесь диалоговым окном Watch Options. Для этого откройте диалоговое окно, выбрав пункт Watch из меню Execution, и установите флажок Deffunc tions, как показано на рис. 8.3. Этот режим также позволяет просматривать аргументы, которые использовались при каждом конкретном вызове функции.

Рис. 8.3. Установка режима просмотра вызова функций

Так же как и для правил, предопределенных фактов, глобальных перемен­ных Windows-версия CLIPS предоставляет специальный инструмент для ра­боты с функциями — Deffunction Manager (Менеджер функций). Для запус­ка этого инструмента воспользуйтесь пунктом Deffunction Manager из меню Browse. В случае если в CLIPS не определена ни одна функция, данный пункт меню недоступен. Менеджер функций, отображающий функции, соз­данные нами в этой главе, изображен на рис. 8.4.

Рис. 8.4. Окно менеджера функций

Общее количество внешних функций отображается в заголовке окна менеджера — Deffunction Manager — 4 Items. С его помощью можно распечатать определение функции, удалить ее, а также установить режим просмотра вызова для отдельно выбранной функции.

 



Поделиться:


Последнее изменение этой страницы: 2021-03-10; просмотров: 37; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.17.75.227 (0.006 с.)