Пример 10.1. Избыточные ограничения типов
(defmethod foo ((?a INTEGER NUMBER)))
Если ограничение типа удовлетворяется для некоторого аргумента, то к нему будет применено ограничение запросом (если оно задано). Ограничение запросом должно быть либо глобальной переменной, либо вызовом функции. CLIPS вычисляет заданное выражение, и если полученный результат не равен false — ограничение полагается удовлетворенным.
Так как ограничения запросом вычисляются каждый раз при поиске соответствующего метода, они не могут использоваться для произведения какого-нибудь побочного действия, потому что вычисляемое ограничение может принадлежать методу, неподходящему к данной конкретной ситуации.
Поскольку все ограничения просматриваются слева направо, запрос с несколькими параметрами должен быть записан после ограничений типов всех используемых параметров. Этим правилом обеспечивается условие удовлетворения ограничений типов всех необходимых параметров. Например, метод из примера 10.2 не вычисляет ограничение запросом до тех пор, пока не удовлетворятся два соответствующих ограничения типа.
Пример 10.2. Использование ограничения запросом с двумя параметрами
(defmethod foo ((?a INTEGER ) (?b INTEGER(> ?a ?b))))
Если аргумент удовлетворяет всем своим ограничениям, то считается, что он применим для данного метода. Если все аргументы родовой функции применимы к ограничениям метода, метод полагается применимым для данного набора аргументов. В случае если существует более одного метода, применимого для некоторого набора аргументов, процесс родового связывания определяет некоторый упорядоченный список этих методов и использует первый метод из этого списка. Для создания списка служит приоритет методов, описанный в разд. 10.4.2.
В примере 10.3 первое обращение к родовой функции + вызовет выполнение системной функции + — неявный метод, выполняющий арифметическое сложение. Второй вызов приведет к выполнению явного метода родовой функции, осуществляющего конкатенацию строк, т. к. оба аргумента являются строками. Третий вызов сгенерирует ошибку, поскольку явный метод для конкатенации строк принимает только два аргумента, а неявный метод для арифметического сложения не принимает строковые аргументы вообще.
Пример 10.3. Перегрузка системной функции +
(defmethod + ( (?а STRING) (?b STRING))
(str-cat ?a ?b) )
(+ 1 2)
(+ "foo" "bar")
(+ "foo" "bar" "woz")
Групповой параметр
В зависимости от того, задан ли групповой параметр, метод может принимать точное число параметров или число параметров не меньшее, чем некоторое заданное. Обязательные параметры определяют минимальное число аргументов, которое должно быть передано методу при его вызове. В действиях, выполняемых методом, можно ссылаться на каждый из этих параметров так же, как на обычные переменные, содержащие простые значения. Если был задан групповой параметр, то метод может принимать любое количество аргументов — большее или равное минимальному числу аргументов. Если групповой параметр не задан, то метод может принимать число аргументов, равное числу обязательных параметров. Все аргументы метода, которые не соответствуют обязательным параметрам, группируются в одно значение составного поля. Ссылаться на это значение можно, указывая символ группового параметра. Для работы с групповым параметром могут использоваться стандартные функции CLIPS, предназначенные для работы с составными полями (см.гл. 15), такие как length и nth. Определение метода может содержать только один групповой параметр.
Ограничения типом и запросом могут применяться к аргументам, сгруппированным в групповом параметре, аналогично тому, как они употребляются с основными параметрами метода. Такие ограничения задаются для каждого отдельного поля результирующего составного значения (а не для всего значения). Выражение, содержащее групповой символ, может быть применено в запросе.
Дополнительно в запросе может быть использована специальная переменная ?current-argument для ссылки на отдельные аргументы, объединенные групповым символом. Это переменная существует только в ограничении запросом и не имеет значения в теле метода. Метод из примера 10.4 иллюстрирует версию функции +, которая находит полусумму любого количества четных целых чисел.
Пример 10.4. Еще один вариант функции +
(defmethod +
(($?any INTEGER (evenp ?current-argument)))
(div (call-next-method} 2))
Ограничения по типу и запросу для группового параметра применяются к каждому аргументу, сгруппированному групповым символом, даже если для проверки используются функции для работы с составным значением. Таким образом, в примере 10.5 функции > и length$ вызываются 3 раза для каждого из трех аргументов.
Дата добавления: 2021-12-14; просмотров: 285;