next up previous

8.5.2 Method Precedence

When two or more methods are applicable to a particular generic function call, CLIPS must pick the one with highest precedence for execution. Method precedence is determined when a method is defined; the list-defmethods function can be used to examine the precedence of methods for a generic function (see section 13.10).

The precedence between two methods is determined by comparing their parameter restrictions. In general, the method with the most specific parameter restrictions has the highest precedence. For example, a method which demands an integer for a particular argument will have higher precedence than a method which only demands a number. The exact rules of precedence between two methods are given in order below; the result of the first rule which establishes precedence is taken.

1) The parameter restrictions of both methods are positionally compared from left to right. In other words, the first parameter restriction in the first method is matched against the first parameter restriction in the second method, and so on. The comparisons between these pairs of parameter restrictions from the two methods determine the overall precedence between the two methods. The result of the first pair of parameter restrictions which specifies precedence is taken. The following rules are applied in order to a parameter pair; the result of the first rule which establishes precedence is taken.

1a) A regular parameter has precedence over a wildcard parameter.
1b) The most specific type restriction on a particular parameter has priority. A class is more specific than any of its superclasses.
1c) A parameter with a query restriction has priority over one that does not.

2) The method with the greater number of regular parameters has precedence.

3) A method without a wildcard parameter has precedence over one that does

4) A method defined before another one has priority.

If there are multiple classes on a single restriction, determining specificity is slightly more complicated. Since all precedence determination is done when the new method is defined, and the actual class of the generic function argument will not be known until runtime, arbitrary (but deterministic) rules are needed for determining the precedence between two class lists. The two class lists are examined by pairs from left to right, e.g. the pair of first classes from both lists, the pair of second classes from both lists and so on. The first pair containing a class and its superclass specify precedence. The class list containing the subclass has priority. If no class pairs specify precedence, then the shorter class list has priority. Otherwise, the class lists do not specify precedence between the parameter restrictions.

Example 1

; The system operator '+' is an implicit method     ; #1
; Its definition provided by the system is:
; (defmethod + ((?a NUMBER) (?b NUMBER) ($?rest NUMBER)))
(defmethod + ((?a NUMBER) (?b INTEGER)))            ; #2
(defmethod + ((?a INTEGER) (?b INTEGER)))           ; #3
(defmethod + ((?a INTEGER) (?b NUMBER)))            ; #4
(defmethod + ((?a NUMBER) (?b NUMBER)
    ($?rest PRIMITIVE)))            ; #5
(defmethod + ((?a NUMBER)
    (?b INTEGER (> ?b 2))))          ; #6
(defmethod + ((?a INTEGER (> ?a 2))
    (?b INTEGER (> ?b 3))))          ; #7
(defmethod + ((?a INTEGER (> ?a 2))
    (?b NUMBER)))               ; #8

The precedence would be: #7,#8,#3,#4,#6,#2,#1,#5. The methods can be immediately partitioned into three groups of decreasing precedence according to their restrictions on the first parameter: A) methods which have a query restriction and a type restriction of INTEGER (#7,#8), B) methods which have a type restriction of INTEGER (#3,#4), and C) methods which have a type restriction of NUMBER (#1,#2,#5,#6). Group A has precedence over group B because parameters with query restrictions have priority over those that do not. Group B has precedence over group C because INTEGER is a subclass of NUMBER. Thus, the ordering so far is: (#7,#8),(#3,#4),(#1,#2,#5,#6). Ordering between the methods in a particular set of parentheses is not yet established.

The next step in determining precedence between these methods considers their restrictions on the second parameter. #7 has priority over #8 because INTEGER is a subclass of NUMBER. #3 has priority over #4 because INTEGER is a subclass of NUMBER. #6 and #2 have priority over #1 and #5 because INTEGER is a subclass of NUMBER. #6 has priority over #2 because it has a query restriction and #2 does not. Thus the ordering is now: #7,#8,#3,#4,#6,#2,(#1,#5).

The restriction on the wildcard argument yields that #1 (the system function implicit method) has priority over #5 since NUMBER is a sublclass of PRIMITIVE. This gives the final ordering: #7,#8,#3,#4,#6,#2,#1,#5.

Example 2

(defmethod foo ((?a NUMBER STRING)))    ; #1
(defmethod foo ((?a INTEGER LEXEME)))   ; #2

The precedence would be #2,#1. Although STRING is a subclass of LEXEME, the ordering is still #2,#1 because INTEGER is a subclass of NUMBER, and NUMBER/INTEGER is the leftmost pair in the class lists.

Example 3

(defmethod foo ((?a MULTIFIELD STRING)))    ; #1
(defmethod foo ((?a LEXEME)))   ; #2

The precedence would be #2,#1 because the classes of the first pair in the type restriction (MULTIFIELD/LEXEME) are unrelated and #2 has fewer classes in its class list.

Example 4

(defmethod foo ((?a INTEGER LEXEME)))   ; #1
(defmethod foo ((?a STRING NUMBER)))    ; #2

Both pairs of classes (INTEGER/STRING and LEXEME/NUMBER) are unrelated, and the class lists are of equal length. Thus, the precedence is taken from the order of definition: #1,#2.


next up previous