Drools5 Community Training
      Sponsored by Plugtree
Module 3: Drools Expert 
     DRL Syntax
   Drools5 Community Training
      version: 1.0-SNAPSHOT
     Release Date: 03/16/2011
Under The Creative Common License
Module 3: Drools Expert 
      DRL Syntax
 Drools5 Community Training Course
  by Mauricio "Salaboy" Salatino and
  Esteban Aliverti is licensed under a
  Creative Commons Attribution 3.0
            Unported License.
Based on a work at salaboy.wordpress.
                  com.
 Permissions beyond the scope of this
   license may be available at http:
       //salaboy.wordpress.com/.
Agenda

● Introduction to Drools Expert
● Drools DRL syntax introduction
    ○ LHS Conditional Elements
    ○ RHS
    ○ Rules attributes
    ○ Queries
● Drools 5.x APIs introduction
Drools Expert Introduction

● Drools Expert is the rule engine core
● Lets us express Business Rules
● It will be in charge of making inferences to get new
  conclusions
Components interaction
Rules Execution Cycle 
Business Rule Structure
package ...
import ...
global ...

rule "My Rule"
    <Attributes>
    when <LHS>
        Song(genre == "Jazz") <CEs>
    then <RHS>
        System.out.println("Hi John!");
end
LHS - Conditional Elements

● Pattern



● e.g.
Song(genre == "Jazz")
$song: Song(genre == "Jazz" || == "Avantgarde")
$song: Song(duration > 360, $genre: genre == "Jazz")
LHS - Conditional Elements

● Field Operators



● e.g.

Song( lyrics matches "AZ-az[drink]" )
Song( authors contains "John Zorn" )
Song( author memberof $greatMusicians )
LHS - Conditional Elements

● AND



  e.g. Person( name == "John" ) AND Pet(type == "cat")
● OR


 e.g. Policewoman (age > 30) OR Fireman(age > 31)
LHS - Conditional Elements

● eval



  e.g. eval( song.isJazz() )
● not


 e.g. not( Song( genre == "Pop") )
LHS - Conditional Elements

● exists



  e.g. exists ( Song(genre == "Jazz"))
● forall


 e.g. forall ( Song()
       Song(genre == "Jazz") )
LHS - Conditional Elements

from CE


 ● e.g.
  $playlist: Playlist()
  Song() from $playlist.songs

  $playlist: Playlist()
  Song(genre == "Jazz") from $playlist.songs
LHS - Conditional Elements

● from


● e.g.
  global HibernateSession hbn;

 $playlist: Playlist()
 Song() from hbn.namedQuery("SongByArtist")
                 .setParameter("artist","John Zorn")
                 .getResultList();
LHS - Conditional Elements

● Collect




● e.g.
  $songs: ArrayList() from collect
       (Song(genre == "Jazz", year > 2000))
LHS - Conditional Elements

● Accumulate
LHS - Conditional Elements
 ● Accumulate CE:
<result pattern> from accumulate( <source pattern>,
                           init( <init code> ),
                           action( <action code> ),
                           reverse( <reverse code> ),
                           result( <result expression>))
 ● e.g.
 $playlist: Playlist()
 $jazzSongs: Number( doubleValue > 100 ) from
       accumulate( Song(playlist == $playlist, genre == "Jazz"),
                   init( double total = 0; ),
                   action( total += 1; ),
                   reverse( total -= 1; ),
                   result( total ))
LHS - Conditional Elements

 ● Accumulate Function Examples
  $playlist: Playlist()
  $total: Number( doubleValue > 100 )
from                         accumulate(
                  $song: Song(
                    playlist == $playlist,
                    genre == "Jazz"),
                 count($song))
LHS - Conditional Elements


● Accumulate out-of-the-box Functions
   ○ average
   ○ min
   ○ max
   ○ count
   ○ sum
LHS - Conditional Elements

● Accumulate custom function
$playlist: Playlist()
 $total: Number( doubleValue > 100 ) from
             accumulate( $song: Song(
                         playlist == $playlist),
                         myCustomFc($song.duration))


● We can plug our custom function here. We just need to
  implement the AccumulateFunction interface.
Nesting CEs
● Drools support nested CEs

  $petshop: PetShop()
  $total: Number( doubleValue > 10 ) from accumulate(
          $pet: Pet(petshop == $petshop,
                type == PetType.Cat)
       from $hbm.getNamedQuery("getPetsFromPetshopId")
          .setParamenter("petshopid",$petshop.getId())
          .list(), count ($pet) )
Right Hand Side
● Set of actions
● MVEL or Java (http://mvel.codehaus.org/)
● We will have a set of methods to modify the working
  memory status
   ○ insert()
   ○ modify() / update ()
   ○ retract()
           rule "Fire ! ! !"
               when
                    Fire()
               then
                    insert(new Alarm());
           end
Rule Attributes
Rule Attributes - no loop

● no-loop

i.e.
  rule "infinite activation loop"
      no-loop true
      when
           $person: Person(age > 21)
      then
           update($person){
               setName("John");
           }
  end
Rule Attributes - salience
 ● salience (higher priority first)
rule "rule with priority"
    salience 10
    when
         $song: Song()
    then
         System.out.println("Rule with higher priority Fired!");
end
rule "rule with less priority"
    salience 5

   when
          $song: Song()
   then
          System.out.println("Rule with lower priority Fired!");
end
Rule Attributes - agenda-group 
rule "Playlist ready"
          agenda-group "Create Playlist"
          when
               Playlist(size == 3)
          then
               //Set the focus to "Play playlist" agenda-group
               kcontext.getKnowledgeRuntime().getAgenda()
               .getAgendaGroup("Play playlist").setFocus();
      end

      rule "Play playlist"
          agenda-group "Play playlist"
          when
               $pl : Playlist()
          then
               $pl.play();
      end
Rule Attributes - lock-on-active

rule "Fill playlist"                rule "Number Songs"
   salience 1                          salience 2
   lock-on-active                      lock-on-active
   agenda-group "Create Playlist"      agenda-group "Create Playlist"
   when                                when
      $pl : Playlist()                    $song : Song()
      $song : Song()                   then
   then                                   modify($song){
      modify($pl){                          setName(
        addSong($song);                        index.getAndIncrement()+
      }                                        "_"+ $song.getName());
end                                       }
                                    end
Queries

Example

 query "Get Persons by Name" (String name)
  Person(name = :name)
end
Drools Expert APIs
KnowledgeBuilder
  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
// Add our rules
kbuilder.add(new ClassPathResource("rules.drl"), ResourceType.DRL);
//Check for errors during the compilation of the rules
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
   for (KnowledgeBuilderError error : errors) {
         System.err.println(error);
   }
   throw new IllegalArgumentException("Could not parse knowledge.");
 }
KnowledgeBase
  // Create the Knowledge Base
     KnowledgeBase kbase = KnowledgeBaseFactory.
newKnowledgeBase();
  // Add the binary packages (compiled rules) to the Knowledge
Base
     kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
KnowledgeSession
 // Create a StatefulSession using the KnowledgeBase that
 // contains the compiled knowledge
StatefulKnowledgeSession ksession =
                         kbase.newStatefulKnowledgeSession();

// We can add a runtime logger to understand what is going on
// inside the Engine
KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
// Insert a new Fact inside my world
FactHandle myFactHandle = ksession.insert(new Person("Myself"));
// Update a Fact using the FactHandle
ksession.update(myFactHandle, new Person("Salaboy!"));
// Retract/Remove from my world the Fact
ksession.retract(myFactHandle);
Full Picture
Hands on Labs

Projects:
 ● 01 :: Drools Expert Introduction
 ● 02 :: Drools Expert Conditional Elements
 ● 03 :: Drools Expert Rule Attributes
Briefing Up

● Covered Topics:
   ○ Rules Execution Lifecycle
   ○ DRL Syntax
      ■ Conditional Elements in the LHS
      ■ Actions in the RHS
 
              
Questions?
Enjoy! 
Questions and Feedback are always
appreciated!
Stay Tuned!
 
                     
    Contact us at
www.plugtree.com

Drools5 Community Training Module 3 Drools Expert DRL Syntax

  • 1.
        Drools5 Community Training Sponsored by Plugtree
  • 2.
    Module 3: DroolsExpert  DRL Syntax Drools5 Community Training version: 1.0-SNAPSHOT Release Date: 03/16/2011 Under The Creative Common License
  • 3.
    Module 3: DroolsExpert  DRL Syntax Drools5 Community Training Course by Mauricio "Salaboy" Salatino and Esteban Aliverti is licensed under a Creative Commons Attribution 3.0 Unported License. Based on a work at salaboy.wordpress. com. Permissions beyond the scope of this license may be available at http: //salaboy.wordpress.com/.
  • 4.
    Agenda ● Introduction toDrools Expert ● Drools DRL syntax introduction ○ LHS Conditional Elements ○ RHS ○ Rules attributes ○ Queries ● Drools 5.x APIs introduction
  • 5.
    Drools Expert Introduction ●Drools Expert is the rule engine core ● Lets us express Business Rules ● It will be in charge of making inferences to get new conclusions
  • 6.
  • 7.
  • 8.
    Business Rule Structure package... import ... global ... rule "My Rule" <Attributes> when <LHS> Song(genre == "Jazz") <CEs> then <RHS> System.out.println("Hi John!"); end
  • 9.
    LHS - ConditionalElements ● Pattern ● e.g. Song(genre == "Jazz") $song: Song(genre == "Jazz" || == "Avantgarde") $song: Song(duration > 360, $genre: genre == "Jazz")
  • 10.
    LHS - ConditionalElements ● Field Operators ● e.g. Song( lyrics matches "AZ-az[drink]" ) Song( authors contains "John Zorn" ) Song( author memberof $greatMusicians )
  • 11.
    LHS - ConditionalElements ● AND e.g. Person( name == "John" ) AND Pet(type == "cat") ● OR e.g. Policewoman (age > 30) OR Fireman(age > 31)
  • 12.
    LHS - ConditionalElements ● eval e.g. eval( song.isJazz() ) ● not e.g. not( Song( genre == "Pop") )
  • 13.
    LHS - ConditionalElements ● exists e.g. exists ( Song(genre == "Jazz")) ● forall e.g. forall ( Song() Song(genre == "Jazz") )
  • 14.
    LHS - ConditionalElements from CE ● e.g. $playlist: Playlist() Song() from $playlist.songs $playlist: Playlist() Song(genre == "Jazz") from $playlist.songs
  • 15.
    LHS - ConditionalElements ● from ● e.g. global HibernateSession hbn; $playlist: Playlist() Song() from hbn.namedQuery("SongByArtist") .setParameter("artist","John Zorn") .getResultList();
  • 16.
    LHS - ConditionalElements ● Collect ● e.g. $songs: ArrayList() from collect (Song(genre == "Jazz", year > 2000))
  • 17.
    LHS - ConditionalElements ● Accumulate
  • 18.
    LHS - ConditionalElements ● Accumulate CE: <result pattern> from accumulate( <source pattern>, init( <init code> ), action( <action code> ), reverse( <reverse code> ), result( <result expression>)) ● e.g. $playlist: Playlist() $jazzSongs: Number( doubleValue > 100 ) from accumulate( Song(playlist == $playlist, genre == "Jazz"), init( double total = 0; ), action( total += 1; ), reverse( total -= 1; ), result( total ))
  • 19.
    LHS - ConditionalElements ● Accumulate Function Examples $playlist: Playlist() $total: Number( doubleValue > 100 ) from accumulate( $song: Song( playlist == $playlist, genre == "Jazz"), count($song))
  • 20.
    LHS - ConditionalElements ● Accumulate out-of-the-box Functions ○ average ○ min ○ max ○ count ○ sum
  • 21.
    LHS - ConditionalElements ● Accumulate custom function $playlist: Playlist() $total: Number( doubleValue > 100 ) from accumulate( $song: Song( playlist == $playlist), myCustomFc($song.duration)) ● We can plug our custom function here. We just need to implement the AccumulateFunction interface.
  • 22.
    Nesting CEs ● Droolssupport nested CEs $petshop: PetShop() $total: Number( doubleValue > 10 ) from accumulate( $pet: Pet(petshop == $petshop, type == PetType.Cat) from $hbm.getNamedQuery("getPetsFromPetshopId") .setParamenter("petshopid",$petshop.getId()) .list(), count ($pet) )
  • 23.
    Right Hand Side ●Set of actions ● MVEL or Java (http://mvel.codehaus.org/) ● We will have a set of methods to modify the working memory status ○ insert() ○ modify() / update () ○ retract() rule "Fire ! ! !" when Fire() then insert(new Alarm()); end
  • 24.
  • 25.
    Rule Attributes -no loop ● no-loop i.e. rule "infinite activation loop" no-loop true when $person: Person(age > 21) then update($person){ setName("John"); } end
  • 26.
    Rule Attributes -salience ● salience (higher priority first) rule "rule with priority" salience 10 when $song: Song() then System.out.println("Rule with higher priority Fired!"); end rule "rule with less priority" salience 5 when $song: Song() then System.out.println("Rule with lower priority Fired!"); end
  • 27.
    Rule Attributes -agenda-group  rule "Playlist ready" agenda-group "Create Playlist" when Playlist(size == 3) then //Set the focus to "Play playlist" agenda-group kcontext.getKnowledgeRuntime().getAgenda() .getAgendaGroup("Play playlist").setFocus(); end rule "Play playlist" agenda-group "Play playlist" when $pl : Playlist() then $pl.play(); end
  • 28.
    Rule Attributes -lock-on-active rule "Fill playlist" rule "Number Songs" salience 1 salience 2 lock-on-active lock-on-active agenda-group "Create Playlist" agenda-group "Create Playlist" when when $pl : Playlist() $song : Song() $song : Song() then then modify($song){ modify($pl){ setName( addSong($song); index.getAndIncrement()+ } "_"+ $song.getName()); end } end
  • 29.
    Queries Example query "GetPersons by Name" (String name) Person(name = :name) end
  • 30.
  • 31.
    KnowledgeBuilder KnowledgeBuilderkbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); // Add our rules kbuilder.add(new ClassPathResource("rules.drl"), ResourceType.DRL); //Check for errors during the compilation of the rules KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error : errors) { System.err.println(error); } throw new IllegalArgumentException("Could not parse knowledge."); }
  • 32.
    KnowledgeBase //Create the Knowledge Base KnowledgeBase kbase = KnowledgeBaseFactory. newKnowledgeBase(); // Add the binary packages (compiled rules) to the Knowledge Base kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
  • 33.
    KnowledgeSession // Createa StatefulSession using the KnowledgeBase that // contains the compiled knowledge StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); // We can add a runtime logger to understand what is going on // inside the Engine KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession); // Insert a new Fact inside my world FactHandle myFactHandle = ksession.insert(new Person("Myself")); // Update a Fact using the FactHandle ksession.update(myFactHandle, new Person("Salaboy!")); // Retract/Remove from my world the Fact ksession.retract(myFactHandle);
  • 34.
  • 35.
    Hands on Labs Projects: ● 01 :: Drools Expert Introduction ● 02 :: Drools Expert Conditional Elements ● 03 :: Drools Expert Rule Attributes
  • 36.
    Briefing Up ● CoveredTopics: ○ Rules Execution Lifecycle ○ DRL Syntax ■ Conditional Elements in the LHS ■ Actions in the RHS
  • 37.
        Questions?
  • 38.
    Enjoy!  Questions and Feedbackare always appreciated! Stay Tuned!
  • 39.
        Contact us at www.plugtree.com