As we mentioned in the 1 Minute DRL Tutorial, the key to writing DRL files is to know how to use the different semantic modules, to keep in the Declarative Programming mindset and to abstract and encapsulate your logic into Domain Specific Languages
We're going to revisit our earlier example and dig a bit deeper into how it works. While we're digging, I'll show you where the bodies are buried.
Here's the example we used in part one:
<rule-set name="cheese rules" xmlns="http://drools.org/rules" xmlns:java="http://drools.org/semantics/java"> <rule name="Bob Likes Cheese"> <parameter identifier="bob"> <class>org.drools.examples.simple.Bob</class> </parameter> <java:condition>bob.likesCheese() == true</java:condition> <java:consequence> System.out.println( "Bob likes cheese." ); </java:consequence> </rule> </rule-set>
This DRL file uses two semantic modules--the Base Semantic Module and the Java semantic module. The xmlns attributes tell the Semantic Module Framework which semantic modules to use when parsing this DRL file. Any number of additional semantic modules can be plugged in, so you can write your own custom rule languages.
In the DRL file above, we declare a single rule, named "Bob Likes Cheese". You can add as many rule elements as you want inside the rule-set element, and each rule element must bear a name attribute, at least one parameter, at least one condition and exactly one consequence.
parameters
The first child of our rule is a parameter element from the Base Semantic Module. The parameter element is used to declare variables for use in the upcoming condition and consequence blocks. This particular parameter element looks in the working memory for instances of a java class. The name of the class is defined in the class element. Our rule looks for a org.drools.examples.simple.Bob instance in the working memory:
<parameter identifier="bob">
<class>org.drools.examples.simple.Bob</class>
</parameter>
Each parameter element fires off an implicit existential condition. If no instances of org.drools.examples.simple.Bob are present in the working memory when the rule set is executed, this rule will never reach its condition or consequence blocks. This means you don't need to check if your variable has a null value inside of your conditions.
Once you've defined a parameter, you can use it inside of your condition and consequence blocks. A rule may define one or more parameters. The parameters must have unique identifiers and are case sensitive.
conditions
If all the conditions inside of a rule evaluate to true, the consequence block of the rule will fire off. Our example defines a condition element using the Java semantic module. It checks to see if the object represented by the bob parameter likes cheese. It does this using straight-up Java code.
Java code is familiar, flexible and non-threatening, which is why we use it in this example. However, it is also capable of complex flow control, which is really a code smell in a rule base. Try not to use flow control in your condition and consequence blocks. Stick with simple, declarative logic and encapsulate more complex logic into a domain specific language.
Providing the Bob object instance represented by the bob parameter likes cheese, the rule will fire off its consequence block. If a rule contains multiple conditions, each condition must evaluate to true before the consequence will fire.
the consequence
Assuming all the conditions of the rule have been met, the consequence will fire off. Our rule uses a consequence element from the Java semantic module. This means that we can execute complex Java code inside our consequence block. One of the typical strategies used in rules is to assert a new object or value into the Working memory, which can then trigger other rules to execute. But for this simple example, we just spit some information out to the command line:
<java:consequence> System.out.println( "Bob likes cheese." ); </java:consequence>
It isn't glorious, but it's a start. In the drools-examples module in CVS we've got a handful of example applications that you can run from the command line.
Syntax used in this example:
| semantic module | element name | required? |
|---|---|---|
| base | rule-set | exactly one |
| base | rule | one or more |
| base | parameter | one or more |
| java | class | exactly one |
| java | condition | one or more |
| java | consequence | exactly one |
See Also:
1 Minute DRL Tutorial
[5 Minute DRL Tutorial] (forthcoming)


