RuleWorks

Rules' Left-Hand Sides: Condition Elements

The left-hand side (LHS) is the "if" part of a rule. It specifies the conditions in working memory that must be true before the rule can fire. The LHS is composed of condition elements, each of which can match objects of a particular class (and its subclasses, if any). Condition elements can also test for particular attribute values, and bind variables to those values. The variables can be used only later in the same rule.

Condition elements (CEs) must be enclosed in parentheses. CEs can be positive, stating that certain conditions are true; or negative, stating that certain conditions are false. A negative CE has a minus sign (-) before its opening parenthesis. The first CE on an LHS must be positive.

RuleWorks performs an implicit conjunction (a logical AND operation) on all the CEs on an LHS. A rule is eligible to fire when there are objects that match all of its positive CEs, and there are no objects that match any of its negative CEs. It is also possible to specify a disjunction (a logical OR operation) of CEs.

Matching the Object Class

The first item in each CE must be the name of a declared object class. The class name is the only required item. In the example below, the CE (start) matches the object made in the ON-ENTRY statement.

Example 3-1. Object Class - ON-ENTRY

(entry-block main)

(end-block main)

Example 3-2 shows some OBJECT-CLASS declarations from the sample configuration program, KIWI.RUL.

Example 3-2. Sample OBJECT-CLASS Declarations

(object-class part

)

(object-class option

)

(object-class hardware-option

)

(object-class memory

)

When the class name in a CE is a parent class, objects of any of its inheriting subclasses can also match the CE. Given the OBJECT-CLASS declarations in Example 3-2, Table 3-1 shows which objects match each class. For example, an object of class MEMORY can match a CE that specifies any of the declared class names shown, but only an object of class PART can match a CE that specifies the class name PART.

Table 3-1. Matching Object Classes

An Object of Class Matches a Condition Element of Class
PARTOPTIONHARDWARE
-OPTION
MEMORY
PARTYesNoNoNo
OPTIONYesYesNoNo
HARDWARE-OPTIONYesYesYesNo
MEMORYYesYesYesYes

An object of any visible user-declared class matches a CE that specifies the built-in top-level class $ROOT.

Rules can refer only to classes that are visible to the entry block or rule block that contains them. See Chapter 5 for information on making object classes visible to more than one block.

Rules can refer to a parent class or to a specific subclass. In Example 3-3, the rule VERIFY-CONFIGURATION:APPLICATION-NEEDS-KIWOS applies to any one of the software applications: KiWindows, KiwiCalc, or KiwiTalk. Conversely, rule VERIFY-CONFIGURATION:KIWITALK-NEEDS-NETWORK applies only to KiwiTalk, not to KiWindows or KiwiCalc.

Example 3-3. Object Class Match Rules

(rule verify-configuration:application-needs-kiwos

)

(rule verify-configuration:kiwitalk-needs-network

)

Note: Any attribute accessed in a rule must either be declared in the class itself or be inherited from a parent class. RuleWorks generates a compile-time error if this requirement is not followed.

Writing Attribute-Value Tests

After the required class name, a CE can contain any number of attribute-value tests. These are the patterns that objects in working memory must match in order for the rule to fire. Attribute-value tests consist of an attribute name, a predicate, and a value. You can make combinations of tests on a single attribute by using conjunctions and disjunctions, which are similar to AND and OR operators.

The number of attribute-value tests on the LHS determines the test specificity of a rule. Test specificity is one of the principles used during conflict resolution (see Test Specificity).

Attribute Names

The attribute name in an attribute-value test must be one of the following constructs:

The attribute operator (^) must precede the attribute name.

Given the declarations in Example 3-2, the following are valid CEs:

The following CEs are not valid because the attributes have not been declared for the object classes:

The built-in attribute names are ^$INSTANCE-OF (see Matching the Exact Class and Matching the Instance Identifier).

Matching the Exact Class

If you want to match, or bind a variable to, the exact subclass of which an object is an instance, you can use the built-in, read-only attribute ^$INSTANCE-OF. In the following code fragment, the second CE binds the value of the ^$INSTANCE-OF attribute to the variable <OPTION>. This variable is then used in the MODIFY action.

Example 3-4. Matching the Exact Class

...

In this example, <OPTION> might be bound to the symbol MEMORY.

Matching the Instance Identifier

The built-in, read-only attribute ^$ID stores the INSTANCE-ID value of the object. If you want to copy, modify, or remove an object on the RHS, you usually first bind a variable to its identifier on the LHS. Such a variable is called a $ID variable. $ID variables give you a handle on the object that matched a CE. $ID variables in RuleWorks are similar to element variables in previous versions of OPS.

You can use variables bound to values of type INSTANCE-ID as pointers to maintain links between objects. Example 3-5 shows a RuleWorks program that uses such pointers to build a doubly linked list of objects. Note that the variables <FIRST-DATA> and <LAST-DATA> are $ID variables, but the variable <PREVIOUS-DATA> is not. Variable <NEW-DATA>, which is bound on the right-hand side, is not a $ID variable. Variables <PREVIOUS-DATA> and <NEW-DATA> cannot be used in MODIFY actions as variables <FIRST-DATA> and <LAST-DATA> are.

Example 3-5. Using $ID Variables as Pointers

(entry-block pointer-demo)