Tuesday, June 29, 2010

Drools JBoss World Presentation Slides

Here are the slides for my Drools presentation at JBoss World.
Drools JBoss World 2010.odp

Friday, June 25, 2010

Unstructured, Ad-Hoc Processes

Traditional business processes are well structured, specifying how to execute the process from start to finish in an imperative way. But in more complex or dynamic environments, it might be more difficult to describe your process this way. It might be up to the end user to decide what to execute and in what order? Or what about exceptional cases? Unstructured or ad-hoc processes might be the solution.

Characteristics of such ad-hoc processes include:
  • Some activities in the process might or might not need to be executed
  • Some activities might be repeated more than once
  • The order in which the activities need to be executed is not (always) described
  • Not all activities are always connected, sometimes resulting in several process fragments
  • The process (engine) does not (solely) decide what activities need to be executed, but this is rather decided by either:
    • the end user that selects which tasks he wants to execute
    • external events that might trigger certain tasks
    • the available data related to that process instance that defines what to do next
For me, this all indicates that ad-hoc processes require the process engine to give up (a little bit of) control. The engine no longer describes the entire business logic as one interconnected flow chart, but rather relies on the input of end users (i.e. the expert or knowledge worker), rules (for inspecting data related to the case) or external events.

Note however that these processes are still very similar to traditional processes in many ways, as the user still expects the same logging, management and monitoring capabilities, etc.

For example, the following screenshot shows an ad-hoc process that allows users of some social networking site (like facebook) to upgrade to the latest version. Imagine this requires the user to migrate their profile, data, contacts, etc. to the new platform. An upgrade process would offer these possibilities to the end user, but the end user would decide what to perform during the upgrade (as he might not want to migrate all data for example). The order in which these tasks are performed is also up to the user. And some tasks might even be performed multiple times (like updating your preferences if you're not yet happy).

(Click for larger image)

Drools Flow allows you to describe semi-structured processes like this, using an ad-hoc sub-process. And because the Drools project has the unique feature of combining business processes with business rules and event processing, this allows you to combine the following possibilities at runtime:
  • End users can decide what tasks to execute by signaling the engine
  • Rules can automatically trigger certain tasks based on the data related to this case (see below for an example)
  • Event processing rules can process low-level events and if necessary also trigger additional tasks
Processes and rules can really work hand in hand in this case. Rules can be associated with the ad-hoc sub-process to automatically trigger certain tasks when the sub-process is activated, or conditionally based on the available data. For example:
  • Imagine that the preferences allow you to specify that you want to automatically synchronize your LinkedIn contacts as friends on this site. This could then be achieve adding a rule that automatically signals the Import task with the relevant data whenever this preference is selected.
  • A rule could even be used to fully automate this whole upgrade process (updating the profile, preferences, data, etc. automatically) if the user has specified that he always wants to upgrade to the latest available version in his preferences.
And this is just one example. This approach could also be very useful in more data-based processes, like for example claim management. In this case, the tasks that need to be executed are largely dependent on the available case data. It might be more intuitive to model this as a number of independent process fragments (one for example to request additional information from the owner, one to delegate the claim to another person, etc.). Here, rules could again be really helpful to automatically derive the current state whenever the claim is updated.

Wednesday, June 16, 2010

Browser Based BPMN2 Authoring in Drools Guvnor (see video)

Drools Guvnor will support editable BPMN2 processes, in the browser, via Oryx. You can also synchronize those .bpmn artifacts with Eclipse, allowing BPMN2 round trip authoring between eclipse and guvnor. This could for example be used to achieve collaboration between business analysts (high-level editing using web tooling) and developers (adding execution details using Eclipse).


BPMN2 being edited in web based Guvnor



BPMN2 being edited in Eclipse


You can watch the video showing this in action here.

Great work Kris, and thank you Antoine for you help.

Monday, June 14, 2010

Write Drools Books - Packt Publishing.

After the success of the first two books, Packt Publishing are looking to do a third. They are now looking for authors, you don't have to volunteer for the entire book, you can offer to author just a single chapter. I believe they want this one to be more of an example driven cook book.

Mark

-------- Original Message --------Kshipra Singh <kshipras@packtpub.com>

Hello Everybody,

I represent Packt Publishing, the publishers of computer related books.

We are planning to expand our range of Drools books and are currently inviting Drools experts interested in writing books for Packt.
We do not expect our authors to have any past writing experience. All that you need to write for Packt is an expert knowledge of your subject, a passion to share it with others and an ability to communicate clearly in English.

So, if you love Drools and fancy writing a book, here's an opportunity for you! Send us your book ideas at author@packtpub.com. Even if you don't have a book idea and are simply interested in writing a book, we are keen to hear from you!

More details about this opportunity are available at : http://authors.packtpub.com/content/packt-invites-drools-book-ideas-authors

Thanks
Kshipra Singh
Author Relationship Manager
Packt Publishing
www.PacktPub.com

Skype: kshiprasingh15
Twitter: http://twitter.com/packtauthors

Interested in becoming an author? Visit http://authors.packtpub.com for all the information you need about writing for Packt.

Wednesday, June 09, 2010

AI Research Overview

For a recent presentation I made an overview diagram of related research areas and ideas, so people can see how things relate.



http://community.jboss.org/wiki/DroolsLanguageEnhancements

RuleML Submission Deadline in 3 days

3 days left to submit a paper to the RuleML symposium. I'll be there and so will Davide Sottara, hopefully presenting his Drools related paper "A Rule-Based Implementation of Fuzzy Tableau Reasoning. A step towards a tighter integration of rule-based and semantic reasoning"

Submission deadline for RuleML-2010 research papers in 3 days

Submission Deadline Approaching

RuleML-2010
4th International Web Rule Symposium:
Research Based and Industry Focused

Paper submission deadline: June 11, 2010

http://2010.ruleml.org/

October 21-23, 2010, Washington, DC, USA

collocated with the Business Rules Forum, the Business Analysis Forum and the Business Process Forum

Proceedings: Springer LNCS volume

Post-proceedings: Selected papers from the symposium will be published in the *International Journal of Cooperative Information
Systems* (World Scientific) and in *Artificial Intelligence and Law* (Springer).

Registration: all W3C, OASIS, OMG, ECCAI, and EPTS members will receive a 15% discount for the registration fee.

Monday, June 07, 2010

Creating pluggable operators

Drools supports creation of pluggable operators. This is a small tutorial on how to create a "str" operator that can be used to compare string values in LHS patterns. The operator adds the ability to write patterns such as:


$m : Message( routingValue str[startsWith] "R1" )


$m : Message( routingValue str[endsWith] "R2" )

or

$m : Message( routingValue str[length] 17 )

First thing that needs to be done is to write your evaluator definition. Your Definition class has to implement org.drools.base.evaluators.EvaluatorDefinition which contains all methods needed to work with this new "str" operator, so we have:

public class StrEvaluatorDefinition implements EvaluatorDefinition {
public static final Operator STR_COMPARE = Operator.addOperatorToRegistry(
"str", false);
public static final Operator NOT_STR_COMPARE = Operator
.addOperatorToRegistry("str", true);
private static final String[] SUPPORTED_IDS = { STR_COMPARE
.getOperatorString() };

public enum Operations {
startsWith, endsWith, length;
}

private Evaluator[] evaluator;

@Override
public Evaluator getEvaluator(ValueType type, Operator operator) {
return this.getEvaluator(type, operator.getOperatorString(), operator
.isNegated(), null);
}

@Override
public Evaluator getEvaluator(ValueType type, Operator operator,
String parameterText) {
return this.getEvaluator(type, operator.getOperatorString(), operator
.isNegated(), parameterText);
}

@Override
public Evaluator getEvaluator(ValueType type, String operatorId,
boolean isNegated, String parameterText) {
return getEvaluator(type, operatorId, isNegated, parameterText,
Target.FACT, Target.FACT);
}

@Override
public Evaluator getEvaluator(ValueType type, String operatorId,
boolean isNegated, String parameterText, Target leftTarget,
Target rightTarget) {
StrEvaluator evaluator = new StrEvaluator(type, isNegated);
evaluator.setParameterText(parameterText);
return evaluator;
}

@Override
public String[] getEvaluatorIds() {
return SUPPORTED_IDS;
}

@Override
public Target getTarget() {
return Target.FACT;
}

@Override
public boolean isNegatable() {
return true;
}

@Override
public boolean supportsType(ValueType type) {
return true;
}

@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
evaluator = (Evaluator[]) in.readObject();
}

@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(evaluator);
}
...
}

The first thing StrEvaluatorDefinition does is registers two operators STR_COMPARE, and NOT_STR_COMPARE using the operator id and a boolean flag which determines if this operator can be negated or not. It also defines the Operations enum which lists all possible operations we can perform (startsWith, endsWith, length). These operations are passed to the operator through angled brackets, similar to what you are already familiar with when writing Drools Fusion patterns, such as for example

this after[0, 3m] $t

The last getEvaluator method gets passed parameters type (type of the operator's operands), operatorId (self explanatory), isNegated (specifies if you can negate, or use "not" with this operator), parameterText (input parameters in the angle brackets), leftTarget (target fact on left), rightTarget (target fact on right).
This method then creates a new instance of the actual Evaluator Implemention class (StrEvaluator) and passes it the parameterText.

Next thing as you guessed it is to create the actual Evaluator implementation code which has to extend org.drools.base.BaseEvaluator:

public static class StrEvaluator extends BaseEvaluator {
private Operations parameter;

public void setParameterText(String parameterText) {
this.parameter = Operations.valueOf(parameterText);
}

public Operations getParameter() {
return parameter;
}

public StrEvaluator(final ValueType type, final boolean isNegated) {
super(type, isNegated ? NOT_STR_COMPARE : STR_COMPARE);
}

@Override
public boolean evaluate(InternalWorkingMemory workingMemory,
InternalReadAccessor extractor, Object object, FieldValue value) {
final Object objectValue = extractor
.getValue(workingMemory, object);
switch (parameter) {
case startsWith:
return this.getOperator().isNegated() ^ (((String)objectValue).startsWith( (String)value.getValue() ));
case endsWith:
return this.getOperator().isNegated() ^ (((String)objectValue).endsWith( (String)value.getValue() ));
case length:
return this.getOperator().isNegated() ^ (((String)objectValue).length() == ((Long) value.getValue()).longValue() );
default:
throw new IllegalAccessError("Illegal str comparison parameter");
}
}
...
}

The implementation code of an Evaluator defines a number of "evaluate" methods is different circumstances. You can get a more detailed description of this by looking at the code for org.drools.base.BaseEvaluator.

Next thing to do is to actually let our KnowledgeBuilder know about this new operator. For this we can just use KnowledgeBuilderConfiguration and pass it to the kbuilder instance:

KnowledgeBuilderConfiguration builderConf = KnowledgeBuilderFactory
.newKnowledgeBuilderConfiguration();
builderConf.setOption(EvaluatorOption.get("str",
new StrEvaluatorDefinition()));
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder(builderConf);

Another way of configuring this is using a configuration file in the classpath with the following path and name:

META-INF/drools.packagebuilder.conf

Doing this has the advantage of the Drools Eclipse plugin being able to discover our new operator definition and supporting it in the rules. The file itself is a regular properties file and to configure our str operator we can do:

drools.evaluator.str = com.myproject.StrEvaluatorDefinition

And that's it. Now you can use the new operator in your rules, for example:

rule routeToR1
when
$m : Message( routingValue str[startsWith] "R1" )
then
# routing to destination R1
end

or

rule routeToDefault
when
$m : Message( routingValue not str[startsWith] "R1" )
then
# routing to default destination
end

or even

rule routeToSpecial
when
$m : Message( routingValue str[startsWith] "R1" && str[endsWith] "R2" && str[length] 17)
then
# routing to super special destination
end

Sunday, June 06, 2010

Planner benchmarker: summary bar chart

Drools Planner's benchmarker allows you to run different Drools Planner configurations for different data sets and compare the results.
But comparing the results in an XML file is a pain, so for the next release it now also outputs the results as a bar chart in a summary.png file (with JFreeChart).

I ran a benchmark on the new, unfinished nurse rostering example, for 4 different configurations on 10 datasets in the medium track. Here's the result. Disclaimer: these results are not my final submission yet for the competition which will end in 2 weeks.



On the top of the chart the output notes that "higher is better". But because most planning problems have negative scores, this means that the best results have the smallest bars (and the highest score). Do you think that the "higher is better" note is helpful or do you think it is confusing?

Saturday, June 05, 2010

Guided Editor Rule Tempaltes Video

http://vimeo.com/12112602