You are on page 1of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

Rule-based Expert Systems


A practical example
Artificial Intelligence and Intelligent Systems

November 2005
Niels Peter Strandberg
ITU
060570-1841
Teacher: Prof. Henning Christiansen

1 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

What is a Rule engine?


Rule engines (interference engines) are a great way to collect complex decision-making logic
and work with data sets too large for humans to effectively use. A rule engine can make
decisions based on hundreds of thousands of facts, quickly, reliably and repeatedly. It works
by decomposing large sets of rules into a very efficient network of nodes, which can process
and react to facts far more efficiently than can be programmed manually. A Rule engine
scales extremely well, almost linearly, with increases in rules and facts. In business, the
extremely complex interplay of hundreds or even hundreds of thousands of rules operating on
tens of thousands of concurrent facts can influence the outcome of important decisions. Those
decisions can be difficult or impossible to program using procedural or imperative
programming techniques. Copied from [1].
Knowledge is represented as a set of rules and data is represented as a set of facts. The rule
engine compares each rule in the knowledge base (the rules) with the facts. If a rule marches a
fact (conditions is for filled), the rule is said to fire, and the then action (consequence) is
executed [2].
There are two ways in which rules are executed. Forward and backward chaining. Forward
chaining is data-driven reasoning, it starts with the available data and uses the rules to extract
more data until it has reached it goal. Which is opposite to backward chaining that is goaldriven, where the system has a goal and uses the rule engine to try to find the evidence to
prove it.

Rules and Java


One of the really annoying things to program in an Object oriented language, like Java, is
rules. They are often described as a series of nested if-statement. When you have enough
nesting, it gets really tough to see what is really going on in the code. And no least the
difficulty to change the code when a new rule should be added or a rule should be changed,
which requires a recompilation of the code. I have been one of those frustrated programmers,
programming rules in Java that after some time looks like spaghetti code.
A typical Java program describing some business rules, could look like this:
if ((user.isMemberOf(AdministratorGroup)
&& user.isMemberOf(teleworkerGroup))
|| user.isSuperUser(){
// more checks for specific cases
if((expenseRequest.code().equals("B203")
||(expenseRequest.code().equals("A903")
&&(totalExpenses<200)
&&(bossSignOff> totalExpenses))
&&(deptBudget.notExceeded)) {
//issue payments
} else if {
//check lots of other conditions

2 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

}
} else {
// even more business logic
}
Source: www.onjava.com/pub/a/onjava/2005/08/03/drools.html?page=1

This above example shows that rules is hard to program and maintain in Java. Another
problem is that of role. What if a businessperson wants to change the B203 into a B204?
Should the programmer be involved every time a business rule changes? This is not
sustainable. By having the rules separated from the source code, the businessperson can
actually read and understand the rules, and change them to reflect changes in business.

Use Case PetShop


In this assignment I will look at a use case called PetShop, which is on-line shop where you
can buy Gold fish, fish tank and fish food. All the rules are fired when the customer checks
out. We will use forward chaining. PetShop is an example application that is part of the
Drools distribution. In the classroom presentation, I will demonstrate how easy it is to add
your own rules. I have added a rule for discount on sales for a given month.

The interface to the PetShop

3 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

The PetShop has the following business rules:


Fish Food Sample
IF (shopping cart do not contain item Fish Food) AND (shopping cart do not contain Fish
Food Sample) AND (item is a Gold Fish) THEN (add item Fish Food Sample to
shopping cart)
Suggest Tank
IF (we have not suggested a Fish Tank before) AND (the shopping cart contains 5 or more
Gold Fish items) AND (there is no Fish Tank in the shopping cart) THEN (suggest a
Fish Tank)
Apply 5% Discount
IF (gross cost is greater or equals to 10.00) AND (gross cost is less than 20.00) THEN (add
5% discount to the shopping cart)
Apply 10% Discount
IF (gross cost is greater or equals to 20.00) THEN (add 10% discount to the shopping cart)

Drools - a Rule engine


The tool that I have looked at for this assignment is Drools [3]. Drools interference engine is
based on the Rete [4] algorithm developed by Charles Forgy. The algorithm is not explained
in this assignment, since it is not necessary to know about the Rete algorithm to understand
the concept of Rule engines. Drools are a forward chaining inference expert system.
Drools is programmed in Java, but support several other languages. Rules are described in
XML files and Java (or Python, Groovy).
Example from the PetShop Apply 5% Discount rule:
<!-- ************************************************* -->
<!-- Give 5% discount if gross cost is more than 20.00 -->
<!-- ************************************************* -->

4 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

<rule name="Apply 5% Discount">


<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<java:condition>cart.getGrossCost() &gt;= 10.00</java:condition>
<java:condition>cart.getGrossCost() &lt; 20.00</java:condition>
<java:condition>cart.getDiscount() &lt; 0.05</java:condition>
<java:consequence>
System.out.println( "Applying 5% discount to cart" );
cart.setDiscount( 0.05 );
</java:consequence>
</rule>

The XML file can include many rules. The parameter tag <parameter
identifier="cart"> is a named reference to an actual Java class. The reference is used in
the <java:condition> tag. The method cart.getGrossCost() is actually called by this
condition. All conditions has to be met for the <java:consequence> to be executed.
This is how you load the rules:
RuleBase ruleBase = RuleBaseLoader.loadFromReader(new
FileReader(abc.drl));

After the rules are loaded, we create a WorkingMemory. It is where all knowledge or
facts is kept.
WorkingMemory workingMemory = ruleBase.newWorkingMemory();

The WorkingMemory can be manipulated in various ways. You can add (assertObject),
modify (modifyObject) and remove (retractObject) facts from the WorkingMemory. In this
example we will only add facts to the WorkingMemory.
We add the shopping cart as a fact, so that the engine is aware of it existence.
workingMemory.assertObject(cart);

Now that we have loaded the rules and facts, let us fire all the rules.
workingMemory.fireAllRules();

that's it ;-)

5 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

Drools of cause offers more features that I have described in this short report. But it will get
you started.

Conflict Resolution
A common problem is if several rules have been activated, what rule should be fired first.
Drools offer several strategies [5] to solve this problem. I will not describe them all, but the
on PetShop uses. The solution used in the PetShop is Salience. Salience is a kind of
priority. You can specify a priority for each rule in the XML file. You add an attribute to the
rule tag:
<rule name="Apply 2% Sales Discount" salience="-5">

It has to be an Integer value. The higher the number the higher priority the rule has. In this
example, it is important that this rule fires last after all the other rules. So this rule has to have
the lowest salience.
The following rule:
<rule name="Explode Cart" salience="20">
<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<java:condition>cart.getState( "Exploded" ) == false</java:condition>
<java:consequence>
import java.util.Iterator;
System.out.println( "Examining each item in the shopping cart." );
Iterator itemIter = cart.getItems().iterator();
while ( itemIter.hasNext() )
{
drools.assertObject( itemIter.next() );
}
cart.setState( "Exploded", true);
drools.modifyObject( cart );
</java:consequence>
</rule>

It has the highest priority (20), since the other rules will fail if this rule has not been fired first.

6 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

Conclusion
I believe that the separation of rules and code is important when you are building application
that contain many rules. And that makes Drools are a very interesting application. Drools has
been adopted by JBoss as the rule engine for their J2EE application server, so that properly
means that we will hear more about Drools, and that it will be in continuous development. I
will certainly try to use rule engines after experimenting with Drools.

References
[1] Why Use Rules, http://drools.org/Why+Use+Rules
[2] Page 35, 2.6, Artificial Intelligence, Michael Negnevitsky.
[3] Drools, http://drools.org
[4] Rete algorithm, http://en.wikipedia.org/wiki/Rete_algorithm
[5] Conflict Resolution Strategies, http://drools.org/Conflict+Resolution

Appendix
This appendix will only include the extension I have made to the original PetShop example.
The PetShop example can be downloaded from http://drools.org/Project+Downloads.
If you would the PetShop project as an Eclipse project, please send me an email at
nielspeter@npstrandberg.com. And I will send it to you, including my extension to the
PetShop.
Addition to the rule XML file:
<!-- ************************************************* -->
<!-- Give 2% Sales month discount -->
<!-- ************************************************* -->
<rule name="Apply 2% Sales Discount" salience="-5">
<parameter identifier="sales">
<class>org.drools.examples.petstore.SalesMonthDiscount</class>
</parameter>
<parameter identifier="cart">
<class>org.drools.examples.petstore.ShoppingCart</class>
</parameter>
<java:condition>cart.getGrossCost() &gt; 0.00</java:condition>
<java:condition>sales.getSales(11) == true</java:condition>

7 of 8

Artificial Intelligence and Intelligent Systems

Rule-based Expert Systems A practical example

<java:consequence>
System.out.println( "Applying 2% Month Sales discount to cart" );
cart.setDiscount( 0.02 );
</java:consequence>
</rule>

SalesMonthDiscount.java source:
package org.drools.examples.petstore;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class SalesMonthDiscount {
public boolean getSales(int month) {
month = month -1;
GregorianCalendar gc1 = new GregorianCalendar(2005,
Calendar.JANUARY, 1);
GregorianCalendar gc2 = new GregorianCalendar(2005,
Calendar.JANUARY, 30);
Calendar today = new GregorianCalendar();
gc1.set(GregorianCalendar.MONTH, month);
gc2.set(GregorianCalendar.MONTH, month);
if (today.after(gc1) && today.before(gc2)) {
return true;
} else {
return false;
}
}
}

8 of 8

You might also like