Thursday, June 18, 2009

Running Drools' Fabonacci Example

Drools has a nice Maven build so building from source is a good idea as it makes the source code readily available.  After completing the build, and contemplating actually running one of the included examples, I could find no precise documentation that detailed how to configure an environment that included the large, complex Drools project however, I found that I could run one of Drools' examples quickly and easily by defining a task in ANT.

After downloading and extracting the source (http://www.jboss.org/drools/downloads.html) I navigated to the root folder of all the drools projects, drools-5. Here, I ran mvn install. The 'out of memory error' prompted me to increase the memory available with the command export MAVEN_OPTS='-Xmx768m'. I reran the mvn install with no more problems.

Create the ANT file, not to build Drools again but just for a convenient way to run the example.
<project name="run-drools-examples" default="run" basedir=".">

 <path id="classpath">
  <fileset dir="drools-api/target"           includes="**/*.jar"/>
  <fileset dir="drools-clips/target"         includes="**/*.jar"/>
  <fileset dir="drools-compiler/target"      includes="**/*.jar"/>
  <fileset dir="drools-core/target"          includes="**/*.jar"/>
  <fileset dir="drools-guvnor/target"        includes="**/*.jar"/>
  <fileset dir="drools-jsr94/target"         includes="**/*.jar"/>
 </path>
 
 <target name="run">
  <java fork="true"
   classname="org.drools.examples.FibonacciExample">
   <classpath>
    <path refid="classpath"/>
    <path location = "drools-examples/drools-examples-drl/target/classes"/>
   </classpath>
  </java>
 </target>
 
</project>
Save the file as build.xml in the drools-5 folder.  Because the ANT target's name is "run" and the default of the script is also "run" the Faboancci example will run by simply entering ant but first, enter the command to create the folder needed for drools' logging.
[greg: drools-5] mkdir log
[greg: drools-5] ant
Buildfile: build.xml

run:
     [java] recurse for 10
     [java] recurse for 9
     [java] recurse for 8
     [java] recurse for 7
     [java] recurse for 6
     [java] recurse for 5
     [java] recurse for 4
     [java] recurse for 3
     [java] recurse for 2
     [java] 1 == 1
     [java] 2 == 1
     [java] 3 == 2
     [java] 4 == 3
     [java] 5 == 5
     [java] 6 == 8
     [java] 7 == 13
     [java] 8 == 21
     [java] 9 == 34
     [java] 10 == 55

BUILD SUCCESSFUL
Total time: 3 seconds
[greg: drools-5] 
To see the rule that is being run, edit the source code mate drools-examples/drools-examples-drl and view src/rules/org/drools/examples/Fibonicci.drl
package org.drools.examples

import org.drools.examples.FibonacciExample.Fibonacci;

dialect "mvel"

rule Recurse
    salience 10
    when
        not ( Fibonacci ( sequence == 1 ) )    
        f : Fibonacci ( value == -1 )
    then
        insert( new Fibonacci( f.sequence - 1 ) );
        System.out.println( "recurse for " + f.sequence );
end

rule Bootstrap
    when
        // this is a multi-restriction || on a single field
        f : Fibonacci( sequence == 1 || == 2, value == -1 ) /
    then 
        modify ( f ){ value = 1 };
        System.out.println( f.sequence + " == " + f.value );
end

rule Calculate
    when
        f1 : Fibonacci( s1 : sequence, value != -1 ) // here we bind sequence
        f2 : Fibonacci( sequence == (s1 + 1 ), value != -1 )  // here we don't, just to demonstrate 
                                                              //the different way bindings can be used
        f3 : Fibonacci( s3 : sequence == (f2.sequence + 1 ), value == -1 )              
    then    
        modify ( f3 ) { value = f1.value + f2.value };
        // see how you can access pattern and field  bindings
        System.out.println( s3 + " == " + f3.value ); 
end 
Further enlightenment may be found at
http://www.onjava.com/pub/a/onjava/2005/08/03/drools.html
http://www.onjava.com/pub/a/onjava/2005/08/24/drools.html
http://www.developer.com/java/ent/article.php/3821101
http://www.infoq.com/news/2009/06/drools-5.0-release
http://java.dzone.com/articles/solving-planning-problems-intr
http://www.oreillynet.com/onjava/blog/2007/10/does_your_bad_java_code_need_h.html
http://downloads.jboss.com/drools/docs/5.0.1.26597.FINAL/drools-expert/html_single/index.html