Пример 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")


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: