Register   Login   About   Study   Enterprise   Share
Internet / AI Technology University (ITU/AITU)
Fast Login - available after registration







|

Top Links: >> 80. Technology >> Internet Technology Summit Program >> 7. Enterprise, Knowledge Architecture, IoT, AI and ML >> 7.2. Rules and Knowledge-Driven Applications
Current Topic: 7.2.4. DRools Basics
Sub-Topics: 7.2.4.1. Truth Maintenance System | 7.2.4.2. Drools Plugin to Eclipse | 7.2.4.3. JBoss Business Rules Management System - jBRMS
-- Scroll to check for more content below...
You have a privilege to create a quiz (QnA) related to this subject and obtain creativity score...
DRools Basics

The overall structure of a rule file in DRools is as follows:


package package-name
imports
// globals
// functions
// queries
// rules


rule "name"
// attributes: ruleflow-group "name"

when
LHS (Left Hand Side: Conditions)
then
RHS (Right Hand Side: Conclusion)
end

rule "another name"
// attributes: ruleflow-group "name"

when
LHS (Left Hand Side: Conditions)
then
RHS (Right Hand Side: Conclusion)
end

…. More rules …


Rule Keywords

To avoid confusions we do not name data with the same names as keywords.
There are hard keywords that absolutely prohibited to use as data.

• true
• false
• null


There are soft keywords, which can be recognized in their context.
It is still recommended to avoid them if possible, while naming data objects.

• lock-on-active – This attribute is used when we do not want the rules to be iterative for changes
• date-effective – Checks the effective date for the rule
• date-expires - A rule cannot activate if the current date and time is after the date-expires attribute
• no-loop – Also used to cut down the iterative rules on change
• auto-focus – when there is no focus group set, the rule with auto-focus is given the focus
• activation-group – If we want to execute only one rule for a set of rules, whichever evaluates first
• agenda-group – Attribute used to apply rules only to a given set
• ruleflow-group – Defines the flow of the execution of rules
• entry-point – If we have multiple partitions in a Working Memory and you can choose which one you are inserting into
• duration – It is used to fire a rule after a stipulated amount of time
• package – Keyword which holds the package information in which the drl files resides
• import – Keyword which holds the object details which are used in the drl files
• dialect – defines the language in which the rules can be defined
• salience – holds the priority of the rules
• enabled – By default this attribute is true for all rules
• attributes – built in functions of the drool rule language
• rule – keyword against which the rule name is defined
• extend – keyword to extend the rule behavior
• when – considered as the LHS of the rule
• then - considered as the RHS of the rule
• template – Keyword used to define the rule templates within a file
• query – Used to run a query through the rule evaluation
• declare – Keyword used to create new types within the rule file
• function - Functions are a way to put semantic code in your rule source file
• global – used to define any of the global variables in the drl file
• eval – Its a constraint used to any valid dialect expression as long as it results to a primitive boolean
• not – Negation expression for a rule
• in – Used to evaluate a condition within a collection
• or – The OR conditional evaluation
• and – The AND condition evaluation
• exists – Checks whether a particular condition exists in a collection or not
• forall - evaluates to true when all facts that match the first pattern match all the remaining patterns
• accumulate – Used to iterate over a collection of objects, executing custom actions for each of the elements, and at the end it returns a result object
• collect - allows rules to reason over a collection of objects obtained from the given source or from the working memory
• from – to evaluate values by using the content within a collection or object
• action - this is a semantic block of code in the selected dialect that will be executed for each of the source objects
• reverse - if present will be executed for each source object that no longer matches the source pattern
• result - this is a semantic expression in the selected dialect that is executed after all source objects are iterated
• end – Denotes the end of the rule syntax
• over – To check if certain value is OVER the specified value
• init - this is a semantic block of code in the selected dialect that will be executed once for each tuple


Comments

Comments are sections of text that are ignored by the rule engine.

Single line comment


rule "Testing Comments"

when
// this is a single line comment
eval( true ) // this is a comment in the same line of a pattern
then
// this is a comment inside a semantic code block
end


Multi-line comment example:


rule "Test Multi-line Comments"
when
/* this is a multi-line comment
in the left hand side of a rule */
eval( true )
then
/* and this is a multi-line comment
in the right hand side of a rule */
end


Syntax Error Samples

1: package org.drools;
2: rule
3: when
4: Object()
5: then
6: System.out.println("A RHS");
7: end

Now the above code generates this message:
• [ERR 101] Line 3:2 no viable alternative at input 'WHEN'
This message means that the parser encountered the token WHEN, actually a hard keyword, but it's in the wrong place since the the rule name is missing

1: rule simple_rule
2: when
3: Student( name == "Andy )
4: then
5: end

The above code misses to close the quotes around Andy

1: package org.drools;
2:
3: rule "Avoid NPE on wrong syntax"
4: when
5: not( Person( ( name == "Jeff", phone == 1234567890 ) || ( name == "Julie") from $guestList )
6: then
7: System.out.println("OK");
8: end

In this case to fix the error we need to replace comma with "&&"

5: not( Person( ( name == "Jeff" && phone == 1234567890 ) || ( name == "Julie") from $guestList )

The error below is caused by meaningless line 7.
Was it clear so far?

1: package nesting;
2: dialect "mvel"
3:
4: import org.drools.Person
5: import org.drools.Address
6:
7: fdsfdsfds // error line!!!
8:
9: rule "test something"
10: when
11: p: Person( name=="Michael" )
12: then
13: p.name = "other";
14: System.out.println(p.name);
15: end

The fdsfdsfds text is invalid and we need to remove this line.

Trailing semi-colon not allowed

This error is associated with the eval clause, where its expression may not be terminated with a semicolon. Check this example:

1: rule simple_rule
2: when
3: eval(abc();)
4: then
5: end

Due to the trailing semicolon within eval, we get this error message:
• [ERR 104] Line 3:4 trailing semi-colon not allowed in rule simple_rule
This problem is simple to fix: just remove the semi-colon.

Import statements work like import statements in Java. You need to specify the fully qualified paths and type names for any objects you want to use in the rules. Drools automatically imports classes
from the Java package of the same name, and also from the package java.lang.

With global you can define global variables. They are used to make application objects available to the rules. Typically, they are used to provide data or services that the rules use, especially application services used in rule consequences, and to return data from the rules, like logs or values added in rule consequences, or for the rules to interact with the application, doing callbacks.

Globals are not inserted into the Working Memory, and therefore a global should never be used to establish conditions in rules except when it has a constant immutable value.


global java.util.List myGlobalList;
rule "Using a global"
when
eval( true )
then
myGlobalList.add( "Hello World" );
end


It is the best practice to set all global values before asserting any fact to the working memory.

Example:

List list = new ArrayList();
WorkingMemory wm = rulebase.newStatefulSession();
wm.setGlobal( "myGlobalList", list );

To use function is the way to put code in your rule source file, instead of normal Java classes.
Example:

function String hello(String name) {
return "Hello "+name+"!";
}


Rule Example:


rule "Approve if not rejected"
salience -100
ruleflow-group "approval"
when
not Rejection()
p : Policy(approved == false, policyState:status)
exists Driver(age > 25)
Process(status == policyState)
then
log("APPROVED: due to no objections.");
p.setApproved(true);
end


Rule attributes

no-loop
default value: false
type: Boolean
When a rule's consequence modifies a fact it may cause the rule to activate again, causing
an infinite loop. Setting no-loop to true will skip the creation of another Activation for the rule
with the current set of facts.

ruleflow-group
default value: N/A
type: String
Ruleflow is a Drools feature that lets you exercise control over the firing of rules. Rules that
are assembled by the same ruleflow-group identifier fire only when their group is active.

lock-on-active
default value: false
type: Boolean
Whenever a ruleflow-group becomes active or an agenda-group receives the focus, any rule within that group that has lock-on-active set to true will not be activated any more

salience
default value: 0
type: integer
Each rule has an integer salience attribute which defaults to zero and can be negative or positive.
Salience is a form of priority where rules with higher salience values are given higher priority when ordered in the Activation queue.

dialect
default value: as specified by the package
type: String
possible values: "java" or "mvel"
The dialect species the language to be used for any code expressions in the LHS or the RHS code block.

Pattern with a binding variable

rule ...
when
$p : Person()
then
System.out.println( "Person " + $p );
End


The prefixed dollar symbol ($) is just a convention; it can be useful in complex rules where it helps to easily differentiate between variables and fields, but it is not mandatory.

Example with a Java class and a rule that uses this class

In Java code

public static class Person {
private String firstName;
private String lastName;
private String sex;
}


Example of a rule:

rule "Every person named Mario is a male" when
$person : Person( firstName == "Mario" )
then
modify ( $person ) { setSex( “male” ) }
end


There is no need to add the no-loop attribute to it in order to avoid an infinite recursion because the engine recognizes that the pattern matching is done on the 'firstName' property while the RHS of the rule modifies the 'male' one.

Assignments:

1. Answer QnAs
2. Create two QnA with the rule source similar to QnA2, see the sample below and email to the instructor.
Question: "What output is produced by this rule?"
... source ...
Answer: ...(correct answer first)...
Answer: .. wrong answer ...
Answer: ... wrong answer ...

| Check Your Progress | Propose QnA | Have a question or comments for open discussion?
<br/>package package-name
<br/>imports
<br/>// globals
<br/>// functions
<br/>// queries
<br/>// rules
<br/>
<br/>
<br/>rule "name"
<br/>// attributes: ruleflow-group "name"
<br/>
<br/>when
<br/>LHS (Left Hand Side: Conditions)
<br/>then
<br/>RHS (Right Hand Side: Conclusion)
<br/>end
<br/>
<br/>rule "another name"
<br/>// attributes: ruleflow-group "name"
<br/>
<br/>when
<br/>LHS (Left Hand Side: Conditions)
<br/>then
<br/>RHS (Right Hand Side: Conclusion)
<br/>end
<br/>
<br/>…. More rules …
<br/>


Rule Keywords

To avoid confusions we do not name data with the same names as keywords.
There are hard keywords that absolutely prohibited to use as data.

• true
• false
• null


There are soft keywords, which can be recognized in their context.
It is still recommended to avoid them if possible, while naming data objects.

• lock-on-active – This attribute is used when we do not want the rules to be iterative for changes
• date-effective – Checks the effective date for the rule
• date-expires - A rule cannot activate if the current date and time is after the date-expires attribute
• no-loop – Also used to cut down the iterative rules on change
• auto-focus – when there is no focus group set, the rule with auto-focus is given the focus
• activation-group – If we want to execute only one rule for a set of rules, whichever evaluates first
• agenda-group – Attribute used to apply rules only to a given set
• ruleflow-group – Defines the flow of the execution of rules
• entry-point – If we have multiple partitions in a Working Memory and you can choose which one you are inserting into
• duration – It is used to fire a rule after a stipulated amount of time
• package – Keyword which holds the package information in which the drl files resides
• import – Keyword which holds the object details which are used in the drl files
• dialect – defines the language in which the rules can be defined
• salience – holds the priority of the rules
• enabled – By default this attribute is true for all rules
• attributes – built in functions of the drool rule language
• rule – keyword against which the rule name is defined
• extend – keyword to extend the rule behavior
• when – considered as the LHS of the rule
• then - considered as the RHS of the rule
• template – Keyword used to define the rule templates within a file
• query – Used to run a query through the rule evaluation
• declare – Keyword used to create new types within the rule file
• function - Functions are a way to put semantic code in your rule source file
• global – used to define any of the global variables in the drl file
• eval – Its a constraint used to any valid dialect expression as long as it results to a primitive boolean
• not – Negation expression for a rule
• in – Used to evaluate a condition within a collection
• or – The OR conditional evaluation
• and – The AND condition evaluation
• exists – Checks whether a particular condition exists in a collection or not
• forall - evaluates to true when all facts that match the first pattern match all the remaining patterns
• accumulate – Used to iterate over a collection of objects, executing custom actions for each of the elements, and at the end it returns a result object
• collect - allows rules to reason over a collection of objects obtained from the given source or from the working memory
• from – to evaluate values by using the content within a collection or object
• action - this is a semantic block of code in the selected dialect that will be executed for each of the source objects
• reverse - if present will be executed for each source object that no longer matches the source pattern
• result - this is a semantic expression in the selected dialect that is executed after all source objects are iterated
• end – Denotes the end of the rule syntax
• over – To check if certain value is OVER the specified value
• init - this is a semantic block of code in the selected dialect that will be executed once for each tuple


Comments

Comments are sections of text that are ignored by the rule engine.

Single line comment

<br/>rule "Testing Comments"
<br/>
<br/>when
<br/>// this is a single line comment
<br/>eval( true ) // this is a comment in the same line of a pattern
<br/>then
<br/>// this is a comment inside a semantic code block
<br/>end
<br/>


Multi-line comment example:

<br/>rule "Test Multi-line Comments"
<br/>when
<br/>/* this is a multi-line comment
<br/>in the left hand side of a rule */
<br/>eval( true )
<br/>then
<br/>/* and this is a multi-line comment
<br/>in the right hand side of a rule */
<br/>end
<br/>


Syntax Error Samples

1: package org.drools;
2: rule
3: when
4: Object()
5: then
6: System.out.println("A RHS");
7: end

Now the above code generates this message:
• [ERR 101] Line 3:2 no viable alternative at input 'WHEN'
This message means that the parser encountered the token WHEN, actually a hard keyword, but it's in the wrong place since the the rule name is missing

1: rule simple_rule
2: when
3: Student( name == "Andy )
4: then
5: end

The above code misses to close the quotes around Andy

1: package org.drools;
2:
3: rule "Avoid NPE on wrong syntax"
4: when
5: not( Person( ( name == "Jeff", phone == 1234567890 ) || ( name == "Julie") from $guestList )
6: then
7: System.out.println("OK");
8: end

In this case to fix the error we need to replace comma with "&&"

5: not( Person( ( name == "Jeff" && phone == 1234567890 ) || ( name == "Julie") from $guestList )

The error below is caused by meaningless line 7.






Was it clear so far?


1: package nesting;
2: dialect "mvel"
3:
4: import org.drools.Person
5: import org.drools.Address
6:
7: fdsfdsfds // error line!!!
8:
9: rule "test something"
10: when
11: p: Person( name=="Michael" )
12: then
13: p.name = "other";
14: System.out.println(p.name);
15: end

The fdsfdsfds text is invalid and we need to remove this line.

Trailing semi-colon not allowed

This error is associated with the eval clause, where its expression may not be terminated with a semicolon. Check this example:

1: rule simple_rule
2: when
3: eval(abc();)
4: then
5: end

Due to the trailing semicolon within eval, we get this error message:
• [ERR 104] Line 3:4 trailing semi-colon not allowed in rule simple_rule
This problem is simple to fix: just remove the semi-colon.

Import statements work like import statements in Java. You need to specify the fully qualified paths and type names for any objects you want to use in the rules. Drools automatically imports classes
from the Java package of the same name, and also from the package java.lang.

With global you can define global variables. They are used to make application objects available to the rules. Typically, they are used to provide data or services that the rules use, especially application services used in rule consequences, and to return data from the rules, like logs or values added in rule consequences, or for the rules to interact with the application, doing callbacks.

Globals are not inserted into the Working Memory, and therefore a global should never be used to establish conditions in rules except when it has a constant immutable value.

<br/>global java.util.List myGlobalList;
<br/>rule "Using a global"
<br/>when
<br/>eval( true )
<br/>then
<br/>myGlobalList.add( "Hello World" );
<br/>end
<br/>


It is the best practice to set all global values before asserting any fact to the working memory.

Example:

List list = new ArrayList();
WorkingMemory wm = rulebase.newStatefulSession();
wm.setGlobal( "myGlobalList", list );

To use function is the way to put code in your rule source file, instead of normal Java classes.
Example:

function String hello(String name) {
return "Hello "+name+"!";
}


Rule Example:

<br/>rule "Approve if not rejected"
<br/>salience -100
<br/>ruleflow-group "approval"
<br/>when
<br/>not Rejection()
<br/>p : Policy(approved == false, policyState:status)
<br/>exists Driver(age > 25)
<br/>Process(status == policyState)
<br/>then
<br/>log("APPROVED: due to no objections.");
<br/>p.setApproved(true);
<br/>end
<br/>


Rule attributes

no-loop
default value: false
type: Boolean
When a rule's consequence modifies a fact it may cause the rule to activate again, causing
an infinite loop. Setting no-loop to true will skip the creation of another Activation for the rule
with the current set of facts.

ruleflow-group
default value: N/A
type: String
Ruleflow is a Drools feature that lets you exercise control over the firing of rules. Rules that
are assembled by the same ruleflow-group identifier fire only when their group is active.

lock-on-active
default value: false
type: Boolean
Whenever a ruleflow-group becomes active or an agenda-group receives the focus, any rule within that group that has lock-on-active set to true will not be activated any more

salience
default value: 0
type: integer
Each rule has an integer salience attribute which defaults to zero and can be negative or positive.
Salience is a form of priority where rules with higher salience values are given higher priority when ordered in the Activation queue.

dialect
default value: as specified by the package
type: String
possible values: "java" or "mvel"
The dialect species the language to be used for any code expressions in the LHS or the RHS code block.

Pattern with a binding variable
<br/>rule ...
<br/>when
<br/>$p : Person()
<br/>then
<br/>System.out.println( "Person " + $p );
<br/>End
<br/>


The prefixed dollar symbol ($) is just a convention; it can be useful in complex rules where it helps to easily differentiate between variables and fields, but it is not mandatory.

Example with a Java class and a rule that uses this class

In Java code
<br/>public static class Person {
<br/>private String firstName;
<br/>private String lastName;
<br/>private String sex;
<br/>}
<br/>


Example of a rule:
<br/>rule "Every person named Mario is a male" when
<br/>$person : Person( firstName == "Mario" )
<br/>then
<br/>modify ( $person ) { setSex( “male” ) }
<br/>end
<br/>


There is no need to add the no-loop attribute to it in order to avoid an infinite recursion because the engine recognizes that the pattern matching is done on the 'firstName' property while the RHS of the rule modifies the 'male' one.

Assignments:

1. Answer QnAs
2. Create two QnA with the rule source similar to QnA2, see the sample below and email to the instructor.
Question: "What output is produced by this rule?"
... source ...
Answer: ...(correct answer first)...
Answer: .. wrong answer ...
Answer: ... wrong answer ...


| Check Your Progress | Propose QnA | Have a question or comments for open discussion?

Have a suggestion? - shoot an email
Looking for something special? - Talk to me
Read: IT of the future: AI and Semantic Cloud Architecture | Fixing Education
Do you want to move from theory to practice and become a magician? Learn and work with us at Internet Technology University (ITU) - JavaSchool.com.

Technology that we offer and How this works: English | Spanish | Russian | French

Internet Technology University | JavaSchool.com | Copyrights © Since 1997 | All Rights Reserved
Patents: US10956676, US7032006, US7774751, US7966093, US8051026, US8863234
Including conversational semantic decision support systems (CSDS) and bringing us closer to The message from 2040
Privacy Policy