(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")