Friday, August 31, 2007

Drools vs JRules Performance and Future R&D

We have had fantastic feedback on Drools 4.0.1, showing that we have real enterprise class performance.

One user just reported on the mailing list that their application, that uses large number of field constraints (more than 4) in a pattern, is over 200x faster in Drools 4.0.1 than in 4.0.0 :)

Some of you may remember my previous blog titled "JBoss Drools vs ILog JRules - an anecdotal story"; where the user had 1300 rules executing in an high volume transaction environment. I've since had further feedback that even after guidance on optimising their JRules implementation, trying both "optimised" and"sequential" modes, that Drools out of the box using the same rules and data is 4 times faster than JRules' best efforts. They have sent me the following results:


Sequential Rete
Jrules Drools Jrules Drools
Average 16.45 3.53 14.53 3.71

5 4

Timings were based on making 1000 rule execution calls.
  • There are 5 data set, randomly selected for each rule execution call.
  • Each data set contains about 100 elements.
  • For each execution call, up to 100 rules would fire.
  • Same rule set containing 1219 rules (simple rules) was used for all execution calls.
  • For JRules, the same instance of IlrContext was used and reset after each call. For Drools, a stateless session was created from the same RuleBase and was discarded after each call.
  • I am using JRules 6.6.1, with JIT enabled and calling IlrRuleSet().optimize with hasherGeneration set and wmModifiedByCode unset.
Prior to "optimised" mode our standard Rete was 27 times faster than their standard Rete. JRules "optimised" mode optimises the network, where possible, to execute sequential and with a static agenda - it does not allow dynamic runtime rule additions to the rulebase.

Sequential (seconds)
Jrules Drools
Jrules Drools
16.04 3.44
95.85 3.5

16.035/3.440 = 5
95.852/3.500 = 27

I must stress that this is just one users story and the information is provided anonymously, thus making it anecdotal, and other users mileage may vary :) But I tell you the story as is, engineer to engineer, with no slight of hand and we have done nothing to help them "tweak" Drools further than any other user gets out of the box. The academic, open and transparent nature to Drools ensures an openness in these sorts of discussions. To be balanced the author said Drools consumed a lot more memory during rule serialisation of rules than JRules. This is due to our reliance on Java serialisation which is not very efficient with graphs and storing byte[]s for class generation in memory, we will address this in the future. We did however consume less memory during runtime execution. Further to that Drools' management system needs to mature more, before a completion transition:
"The top reasons for us to select Drools over JRules is not performance: the #1 is the open API's that allows us to do what is required, #2 is the active community and the support. Exceptional performance is #3, but may gain more weight when time to convert existing projects. I believe both will exist in our company for the near future until Drools' management system matures."

To wet everyone's appetite I have detailed our future performance R&D to show that we are not done yet.

Lazy latch nodes
Parent nodes do not propagate unless there is something to join against in the child node. For small systems this has little impact, but for large, wide, systems it can save memory and provide an increase in performance.

Network disconnection for RuleFlow Groups and Agenda Groups
When data is asserted into the network all patterns for all rules are evaluated, regardless of whether that rule is able to fire. If a rule is not in a ruleflow-group or agenda-group that is currently in focus and active it should be disconnected from the network at the attachment points where there is no node sharing. For truly large systems it should also be possibly to page those detached rules to disk, until their ruleflow-group and/or agenda-group has the focus and is active.

Partial Network Paging to Disk
For really large networks it may be desirable not to have the entire network in memory. Instead the network can be paged to disk, and will only page into memory when data attempts to propagate to that part of the network. This can be applied to the "Network Disconnection" optimisation to page out entire ruleflow-groups and agenda-groups when they are not in-focus and not active. Java serialisation is not very efficient, especially for graphs, so this would need to be combined with a custom wire protocol for marshalling.

Lazy Latch Querries
For queries with no parameters we can add the DroolsQuery pattern to the end of the network for that Rule, instead of the beginning. We then find either the last unshared node or the root beta node and put in a "block" semaphore, that means no data will propagate that is specific to the query rule. When the DroolsQuery object is propagated to the JoinNode it signals the "block" semaphore to propagate all its data. This allows queries to share with existing rule data.

No Memory storage for Querries
As querries are effectively stateless we do not need to store any left input memory for the join nodes. The root part of the query should mark the Tuple as not requiring left input memory storage, so that left memory is not used during propagation. This increases query performance and uses less memory. We may even be able to modify sequential mode so that they both use the same technique to avoid left memory storage.

Isolation and Sharing of the Right Input for a BetaNode
Currently we either share, or or do not share, a whole beta node dependant on whether the entire parent chain is identical. If we can isolate the right input a little more we can, in some situations, allow sharing of that right input. Those situations would be where there is either no indexing, or the indexing is the same, for the beta node. Further to this, for situations with no indexing, we could probably look to just use the parent node as also the right input node. This reduces memory usage and slightly less needed network propagations.

Composite index Alpha Node Hashing
We already have composite index hashing for beta nodes, to a maximum depth of three columns. currently alpha node indexing only works on the a single literal value, composite would allow us to index multiple literal constraints combinations, again a maximum depth would need to be provided to avoid this becomes too expensive. Further to this there may be times when single indexing is preferably, as this is based on literals whether to composite or single should be deterministic at compile time, based on some level of cost analysis.

Node Collapsing
Currently each alpha node constraint is in it's own node, this is needed for dynamic rulebases where rules can be attached at a later date. If we know the rulebase is not going to change, like with stateless sessions, we can collapse similar shared node groups into single execution units; most likely with optional bytecode JIT. For standard Rete execution we will need a property, or method call, for the user to state the rulebase will not change so we can apply this optimisation.

Alpha Node Reordering
Alpha nodes can be re-ordered to maximise node sharing, this will make "Node Collapsing" optimisations even more efficient. Again we would need some indicator that the RuleBase building is complete and that the optimisation can now be applied.

Closed World Assumptions
Allow some data to be marked as "closed world". This means the data will only ever be created inside of the working memory. This way we can analyse the rules and handle the life cycle of the data and allow us to auto-unpropagate it back to the object type node when we know it will have no further impact on resulting conflict sets. This reduces the size of the working memory network and the number of wasteful cross product attempts.

Network Re-Writing via Analysis
I haven't put too much thought into this one, but it must be possible to recognise some patterns where the network can be re-organised to provide better execution, by failing the propagation earlier on. This is similar to network eager-filtering, where we can stop certain facts propagating at an earlier stage in the network, than the join later in the network dictates.

Sub-System threading
While this won't address parallel execution and evaluation of a rule engine (which I consider a very large R&D effort and out of scope for this blog, which focuses on low hanging fruit), it should be possible to identify some sub systems that would benefit from execution in their own thread, without too much complexity - the Agenda sub system is an idea candidate for this.

Whole Bucket Joining
I'm not entirely sure how or if this would work, but the basic idea is instead of joining each tuple with each fact on the right input to form a new tuple, the tuple instead just references the bucket for the matching index for the constraints. The actual tuple joining is delayed until we reach the terminal node, where those buckets are evaluated. We may only be able to apply this to some limited situations, but it will avoid a lot of wasted cross product join attempts if we can make it work.

Indexing for Number Ranges
Indexing number ranges is really only useful for environments where the data doesn't change that often, otherwise the re-balancing of the data structure can outweigh the benefits of indexing. For this reason it will probably need to be combined with some ability to annotate field constraints with the desire to apply the indexing for number ranges.

Reduce the Number of Generated Classes
For the Java dialect we currently generate a single Class for all the expressions and blocks in that rule. However, due to the need to use interfaces in the engine, we generate an Invoker Class for each expression and block, to allow the engine to call that expression or block via the interface. We can instead provide an integer index value per expression and block and allow that integer to be passed via the invoker interface. This means we can generate a single class that implements all expression and block interfaces using the integer value to determine which expression or block we actually call. A single switch statement can be used to determine this, which should have no noticeable impact on execution. This should also mean faster building times as less classes have to be resolved.


User configured chioce lists & 4.0.1 (Michael Neale)

One often requested thing which didn't quite make it into 4.0 BRMS was the ability to let people define lists that are shown as drop down items to choose from in rules. (Data driven enumerations I call them). Well fresh after having a holiday (no thanks too everyone who voted I shouldn't have another one) it was pretty obvious that it was easy to do, so I did it for 4.0.1.

These lists show up as drop downs (duh) in the guided editor. The lists are stored as assets themselves in the repository.

(below you will see what it looks like to setup some enumerations).

This means that the only valid values for the fact "Board" field called "type" are Short, Long, MM and Boogie (notice the use of the "=" to indicate that you want display a different value to what the rule really cares about). Note it is possible to have it call a bit of code that (for example) loads a list from the database (there is some info on that in the manual).

Also, a more arcane feature is the ability to filter or select what items get included when you build a package. This is something you have to setup on the server, but once it is setup you can enter the name of a "selector" configuration and only the selected items will be built (once again, more details are in the manual).

Finally, for those that have heard of JBoss Seam - Seam now can inject rulebases from the RuleAgent. This means you can configure the rule agent to load rules from the BRMS etc in the components.xml config. You can then do :

@In RuleBase ruleBase1;

And Seam will inject the rulebase from the agent configuration called "ruleBase1".

Thursday, August 30, 2007

Drools 4.0.1 Released

We just released Drools version 4.0.1. This is a maintenance release whose focus was to address community feedback regarding the previous 4.0.0 release.
There are a lot of fixes and a bunch of minor improvements, and so, we strongly advise the update from 4.0.0 to 4.0.1. There are no expected backward compatibility issues.

Downloads, as usual from:

Happy Drooling.
Drools Team

Release Notes: Drools 4.0.1


Feature Request

  • [ JBRULES-322 ] Allow the conversion of normal Java projects to Drools projects
  • [ JBRULES-642 ] Extract solver configuration
  • [ JBRULES-981 ] Milestone
  • [ JBRULES-1020 ] BRMS Custom Rule Selector for Creating Deployable Packages
  • [ JBRULES-1039 ] Add Number Guess example with Rule Flow
  • [ JBRULES-1041 ] Subflow
  • [ JBRULES-1042 ] Integrate ruleflows in drools build
  • [ JBRULES-1043 ] Enhanced Java completion proposals
  • [ JBRULES-1051 ] Guided Editor does not remmeber the folder location for new editors
  • [ JBRULES-1061 ] jsr94 constants wrong package builder config constant, same name as rulebase config constant
  • [ JBRULES-1067 ] Allow RuleAgent to take a RuleBaseConfiguration to configure the RuleBase it creates
  • [ JBRULES-1077 ] Decision tables to have ruleflow-group attribute column
  • [ JBRULES-1084 ] Provide case insentive completions in eth DRL Editor for MVEL and Java completions
  • [ JBRULES-1090 ] Simple data field enums in BRMS
  • [ JBRULES-1120 ] Implement Step Over for mvel debugger
  • [ JBRULES-1123 ] Custom Consequence Exception handlers


  • [ JBRULES-849 ] DynamicRulesTest fails with JDK 1.6
  • [ JBRULES-992 ] Optional dependencies not marked as optional in maven pom xmls
  • [ JBRULES-1027 ] unable to use moderately complicated expression in from
  • [ JBRULES-1030 ] NPE Building Rule with inexistent field
  • [ JBRULES-1031 ] only 4 equality checks are made for fact
  • [ JBRULES-1032 ] NPE in HashKey.equals when LHS checks for null object, the object is null, and there are more than 3 rules
  • [ JBRULES-1033 ] clearAgenda removes scheduled activations twice, resulting in a NullPointerException
  • [ JBRULES-1034 ] NullPointerException in a simple test
  • [ JBRULES-1035 ] Deploy sources jars on mvn deploy
  • [ JBRULES-1036 ] dialect errors if after import declarations
  • [ JBRULES-1037 ] Ruleflow RF file does not correctly generate RFM
  • [ JBRULES-1038 ] addRuleFlow throws Exceptions
  • [ JBRULES-1044 ] dialect appears to be a reserved keyword, not allowed in package name
  • [ JBRULES-1045 ] Predicate Null Pointer exception when using Java 5 Enum
  • [ JBRULES-1046 ] Business Object returns null due to Shadow Fact, unless declared final
  • [ JBRULES-1047 ] class Cast Exception when using OR (||)
  • [ JBRULES-1048 ] Context assist is not working for DSLs in Eclipse
  • [ JBRULES-1049 ] WorkingMemory.iterateFactHandles() generates endless loop with 4.0GA.
  • [ JBRULES-1050 ] Extra space between variable and field name in LHS causes crash
  • [ JBRULES-1052 ] When Inserting a fact cannot set a String field
  • [ JBRULES-1053 ] Import collision when static inner classes of 2 different classes have same name
  • [ JBRULES-1054 ] DSL-Editor: "Add" button does not work
  • [ JBRULES-1055 ] Regex-Special characters can not be used in DSLs.
  • [ JBRULES-1056 ] Performance of RuleBase().addPackage(.) goes down on sub sequent instances of RuleBase with large number of packages.
  • [ JBRULES-1057 ] properties keyword list is missing memberof
  • [ JBRULES-1058 ] nested accessors with Sets - "not contains" is not a valid operator for MVEL
  • [ JBRULES-1063 ] Failing location determination tests
  • [ JBRULES-1064 ] "->" notation for predicates missing in documentation
  • [ JBRULES-1065 ] Unable to return Declaration for identifier
  • [ JBRULES-1066 ] org.drools.reteoo.ReteooWorkingMemory$WorkingMemoryReteAssertAction is not serializable
  • [ JBRULES-1069 ] DSL sentence widget is too small and combobox with sentences should not be expanded
  • [ JBRULES-1070 ] Exception with "not in" condition with (int-values)
  • [ JBRULES-1071 ] BinaryRuleBaseLoader doesn't accept custom ClassLoader
  • [ JBRULES-1073 ] CompositeContextEntry is raising NPE
  • [ JBRULES-1079 ] Problem with "!=" field constraint
  • [ JBRULES-1083 ] Brackets are not always optional for non-existential quantifier "not"
  • [ JBRULES-1085 ] Rule fires before calling fireAllRules
  • [ JBRULES-1086 ] InitialFact should not be shadowed
  • [ JBRULES-1087 ] Context Assistant that shows list of filtered DSL does not work on DRL editor
  • [ JBRULES-1089 ] Getting "could not access property ('=')" for a valid rule.
  • [ JBRULES-1091 ] NullPointerException when the 'result' block of an 'accumulate' function returns null
  • [ JBRULES-1092 ] Invalid Java code generated from 'accumulate' function with nested classes
  • [ JBRULES-1093 ] ClassObjectFilter is not accepting subclasses of the given class
  • [ JBRULES-1094 ] PackageBuilderConfiguration.setDialectConfiguration() method is not correctly setting dialect configurations
  • [ JBRULES-1096 ] NPE when using "exists" with "from"
  • [ JBRULES-1097 ] Manual html_single does not have TOC entry for Chapter 9 BRMS
  • [ JBRULES-1100 ] BRMS Bug on view source in weblogic
  • [ JBRULES-1101 ] MVEL direct property accessors being converted to a ReturnValueConstraint
  • [ JBRULES-1102 ] Bug in DefaultBetaConstraint class indexing to never turn on
  • [ JBRULES-1104 ] Inserted internal Objects (like InitialFactImpl) are lost if no matching ObjectTypeNodes
  • [ JBRULES-1105 ] web.xml does not conform web-app_2_3.dtd
  • [ JBRULES-1106 ] Copied rules using a guided DSL in BRMS produce duplicate rule names in built binary packages.
  • [ JBRULES-1113 ] renaming a package messes up the assets in it
  • [ JBRULES-1114 ] Rule compilation not thread-safe
  • [ JBRULES-1115 ] Modifications to list objects contained within a bean and carried out during the execution of a rule are not reflected in the original list i.e. the changes are lost between the instance available within the rule and that of the original bean
  • [ JBRULES-1116 ] "not" doesn't work for StatelessSessions
  • [ JBRULES-1125 ] Java Step over is broken
  • [ JBRULES-1126 ] Step over in MVEL is broken
  • [ JBRULES-1127 ] External vars do not appear if you hve a break point on the first line
  • [ JBRULES-1129 ] import does not work with code competion
  • [ JBRULES-1131 ] Errors not including line numbers
  • [ JBRULES-1134 ] drools variable appears twice in context assist
  • [ JBRULES-1136 ] Rule not firing when expression contains nested accessors
  • [ JBRULES-1137 ] Rules are not removed when they have shared nodes
  • [ JBRULES-1139 ] code completion doesn't work as you type
  • [ JBRULES-1140 ] Context Assist does not show available declarations and globals
  • [ JBRULES-1142 ] nested accessors on the lhs of the memberOf (or not memberOf) operator lead to an exception
  • [ JBRULES-1149 ] Parser is only saving last CE for prefixed AND/OR


  • [ JBRULES-678 ] Remove spring dependency
  • [ JBRULES-1028 ] importing .brxml into the application
  • [ JBRULES-1059 ] Online typos in Section 1
  • [ JBRULES-1062 ] Include DefaultSpecificationEntries and DefaultImplementationEntries in jar manifests
  • [ JBRULES-1076 ] Typos, Build Instruction problems in Ref Manual, revision 14125 in Section 3.4
  • [ JBRULES-1088 ] Spelling check on docs


  • [ JBRULES-1128 ] Xstream should be optional for drools-core and it should use the non-legacy groupId


Friday, August 24, 2007

Featured Drools Jobs in Brazil and UK

We've just had two new job postings placed on our Drools job board, Remember you can see the last 5 job posting in the job board widget in the right side panel of this blog.

Red Hat, UK - Senior Drools Consultant
The JBoss consulting services team is looking for a JBoss Rules expert to join our team on a contracting basis. We are part of JBoss, a division of Red Hat and work closely with the R&D team in cutting edge JBoss technologies.

The consulting team works on site with a range of strategic and key accounts to provide product specific support to customers at an architect level. Responsibilities includes problem identification, system architecture definition, hardware/software specification and/or design, implementation, testing, client training, and deployment of open source solutions. He or she will be the main point-of-contact for Red Hat technical, strategic and development information and will be responsible for project management including project status, issues and time reporting.

Auster Solutions, Soa Paulo, Brazil - Drools developer
Auster Solutions is working with large telecom companies in Brazil and we are looking to expand our team for internal development of products and customer environment integration. We are focused on high performance and high volume processing products and solutions development, using leading edge technologies, a vast amount of creativity and also a lot of research projects and proof of concepts. This means candidates will have the opportunity to learn many different frameworks, with a business orientation philosophy.

Telecom Billing downstream processing (Mediation, Guiding, Rating, Billing, Invoicing, Collections) knowledge is desired although is not required.

Wednesday, August 22, 2007

Drools features and screenshot page

With all the juicy new stuff in Drools 4.0 we have put up a promo features and screenshots page, to give a glancing taste of all the Drools goodness :)

There you'll find images like these:

Drools 4.0 downloads are going strong for August, its only the 22nd, and for this month we now have (K is for downloads in the thousands, 12.5K is 12500 downloads):
Just a reminder that drools can be downloaded here which also provides details of the Eclipse update site which is here The manual also gives details on how to use the Eclipse update site which can be found here.

Drools 4.0.1 is out the end of this week. We've worked furiously to fix a lot of errors and things are now looking very stable, thanks to the great community feedback we have received. Once that is out we'll branch and the exciting work for the next major release will begin.

Sunday, August 19, 2007

Drools Puzzle Round 2: The Familiy Puzzle

Submission start: August 20th, 2007
Submission deadline: September 14th, 2007
Please read this before you start to solve the puzzle: Participation Rules
Please post your solution to:

Puzzle from Dr. Gernot Starke, the winner of last round:
Difficulty level: Settler
  • Three men, Abel, Locker and Snyder are married to Edith, Doris and Luisa, but not necessarily in this order.
  • Each couple has one son.
  • The sons are called Albert, Henry and Victor.
  • Snyder is nor married to Luisa, neither is he Henry's father.
  • Edit is not married to Locker and not Albert's mother.
  • If Alberts father is either Locker or Snyder, then Luisa is Victor's mother.
  • If Luisa is married to Locker, then Doris is not Albert's mother.

Who is married to whom and what are their sons called?

Taken from the German book "Denken als Spiel" by Willy Hochkeppel, 1973 (Thinking as a Game).


Saturday, August 18, 2007

Drools Puzzle Round 1: Ages of the Sons

Start date: August 1st, 2008. Submission deadline: August 15th, 2008.

Please post your solution to:

Participation Rules

Ages of the Sons

Difficulty level: settler

An old man asked a mathematician to guess the ages of his three sons.

Old man said: “The product of their ages is 36.”
Mathematician said: “I need more information.”

Old man said:”Over there you can see a building. The sum of their ages
equals the number of the windows in that building.”
After a short while the mathematician said: “I need more information.”

Old man said: “The oldest son has blue eyes.”
Mathematician said: “I got it.”

What are the ages of the three sons of the old man?

Result Report

The rule in the first sentence of the old man is obvious. The mathematician cannot decide the solution after he was told the second condition. This indicates that there are more than one triple of numbers whose products are 36 and sums are the same. The third condition tells that the greatest number in the triple has only one occurrence. So there is nothing really fancy in the rule definition files.

The solution space of this puzzle is so tiny that the brute force search is good enough. Indeed, all participators implemented brute force search for this puzzle. Very interestingly there are three slightly different variants of this brute force search in the submissions.

This time we got totally five solutions from 4 participators. The first correct solution was from Chris Barham. Chris showed very good discipline on software engineering in his submission. The program files are well packaged and the readme file is concise and clear. I strongly suggest every participator in the future take a look at this solution from Chris and package her programs similarly. His readme file is a perfect example, future participators can use it as a template. The in his solution is in fact a solution object. This class adds more structure to the algorithm. This class can be generalized to a “Solution” object and be used in any back tracking solvers. It is a little bit closer to the “Taseree” approach.

private static void assertAllFacts(WorkingMemory workingMemory) {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 36; j++) {
Son son = new Son((char)(i + 64), j);

This is plain brute force without any pre-filtering in the main class.

We received the second correct solution from Elmo Nazareno. His rules definition is the most concise and clear one among the all submissions. This rules definition file is an excellent example of concise, clear and correct rules. In addition, there is some smart pre-filering prior to the working memory insertion in his

for (int i = 1; i <= 36; i++) {
// this is just to limit the number of assertions
if ((36 % i) == 0) workingMemory.insert(new Son(i));

This pre-filtering is without loss of correctness.

The third and fourth solution were from Dr. Gernot Starke. Gernot’s code has excellent inline documentation. This is a good example how readable code should look like. He also did a pre-filtering prior to the working memory insertion:

int i;
for (i = 0; i < 19; i++)
session.insert(new Son(i));

However there is a correctness problem with this filtering rule. The solution candidate “36, 1, 1″ is missing in the search space. Although the program finally gives out the right answer to this puzzle: 9 years old, 2 years old, 2 years old, the logic in the main class is not really correct. And so is the prolog solution since the prolog program also does not search up to 36 years old ;-).

So far, Chris’ solution has the best packaging the readme, and most sophisticated structure of the algorithm, Elmo’s solution has the best pre-filtering rule, Gernot’s solution has the best documentation and most efficient testing code in the main class (not counting the problematic pre-filtering logic). Elmo’s and Gernot’s rules definition files are essentially the same.

Now the performance.

Testing environment:

  • Hardware: AMD Athlon 64 bit Dual Core 4200+; 2GB memory.
  • Software: Debian Lenny for AMD 64 bit multi core. Java 1.6.0 b105 Sun HotSpot VM. Drools 4.0.0 snapshot from CVS 2007-08-03. Eclipse core_3.3.0.v_771 for rules compilation.

All the valid solutions are edited slightly for testing purpose. Please pay attention to the main classes. Participators in the future should write performance measurement code following this template (based on Gernot’s solution):

// timer
final long setupBegin = System.currentTimeMillis();

final PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl(new InputStreamReader(

final RuleBase ruleBase = RuleBaseFactory.newRuleBase();

final StatefulSession session = ruleBase.newStatefulSession();

final long insertionBegin = System.currentTimeMillis();

// int i;
//for (i = 0; i <>
// session.insert(new Son(i));

final long end = System.currentTimeMillis();

long setupTime = insertionBegin - setupBegin;
long problemSolvingTime = end - insertionBegin;
long totalTime = end - setupBegin;

System.out.print("Setting up the rule base took: " + setupTime + " ms");
System.out.println("Finding the solution took " + problemSolvingTime + " ms");
System.out.println("Total run time: " + totalTime + " ms");

Elmo wanted to use Janino compiler in his code but I edited his main class slightly to make the evaluation fair for all participators. Participators in the future please do not specify the compiler for your rules. All solutions will use the same rule compiler in evaluator’s machine.

I gave each submission 5 runs and took the best result of the five. So here is the best run-time result of three participators (setup time, problem-solving time):

  • Chris Barham: 2330 ms, 195 ms
  • Elmo Nazareno: 2345 ms, 215 ms
  • Gernot Starke: 2367ms, 134 ms

This time I ingored the RuleBase setup and initialization time, only took problem-solving time into account. It’s clear who’s the performance winner. :-)

Now comes the final scoring. Each submission is scored with respect to correctness, performance, testability, code quality, documentation quality (be it inline or separated), packaging quality and user interface quality. Each aspect (except performance) has possible scores from 1 to 5. 5 means excellent, 4 means good, 3 means so so, 2 means questionable, 1 means problematic. The performance score is calculated with this rule: The best one gets 10 points. Let’s call the time used Tb. Formula for calculating other people’s performance scores:

PerformanceScore_i = 10 / (Ti / Tb), with Ti meaning a time used of a submission.

Final scores:

Participator Correctness Performance Testability Code Q. Docu. Q. Packaging Q. UI Q. Total
Chris Barham 5 6.87 5 5 5 5 4 35.87
Elmo Nazareno 5 6.23 5 5 4 3 4 32.23
Gernot Starke 4 10 5 5 5 3 4 36.0

Both Elmo and Gernot pasted their code in the email body that’s why each of them got 2 points away from the packaging quality. ;)

Congratulations to Dr. Starke and let’s wait for the puzzle from him for next round. ;-) Since he himself cannot compete in the next round, he will get the average score of next round to make things fair.

Happy Drooling!

PS: Dr. Dirk Farin also submitted a solution but was not eligible to official evaluation since his code is in C++. The unfortunate fact to all Droolers is, Dirk’s C++ program, which also used plain brute force without any pre-optimization, took only less than 3 ms from initialization to finish.


Drools Puzzle

(updated on June 01, 2008)

Drools Puzzle is a periodic puzzle-solving contest. Anybody can compete in a round except the puzzle poster himself. Time for problem-solving cycle is adapted to the difficulty of the puzzle, varies from two weeks to several months. Puzzles are chosen by the winner of last round or the organizer. A participator can post her solution to

for evaluation. If the solution has very big size, you can upload it to any FTP server and post the download link to the email address above.

The evaluator must evaluate all submissions within two days of the submission deadline and post the result report within three days after the evaluation. All solutions should be evaluated on a same computer, under the same software configuration.

Every participator gets accumulated scores, even if she does not win. After each ten rounds, the top one on the score list will earn a “Drools Puzzle Cracker” award and there will be materialized prize from the Drools team too. Since the score is accumulated, it’s possible for a person to win this award if she participates in every round but never really won. The evaluator(s) should try their best to quantify the quality of the submissions as reasonable and analytical as possible.

If any bug in the Drools framework is caught during your solving of the Drools Puzzle, please report it and you will get a T-shirt from the Drools team.

Rule for participation:

  • The solution (the core algorithm) must be written in Drools. Eligible Drools version changes over the time and should be decided by the puzzle poster. For now, it’s recommended for all participators to write rules against Drools 4.0.0, so that there is much less work for the evaluator. Employment of any component in the Drools project is allowed. For example, the use of drools-solver is welcome.
  • In the rule definition file, any dialect of the expression language is allowed. You can declare rules in Java, MVEL, … and even mix them in a single rules definition file. Any DSL is allowed but you have to provide the language adapter.
  • Any kind of user interface is allowed. You can even submit a .ear file or .war file. Evaluators know how to measure the performance for your core algorithm. Any overhead for fancy UI rendering in your program will be ignored.
  • The solution program should be as easy to test as possible. Testability also counts in the evaluation.
  • Please provide a readme file with instructions about how to run your program. It is especially important if you submit a .war file or .ear file, you must tell the evaluator which web container to use and how to deploy it.
  • Please do not paste your code in the email body, package your program files and the readme file and attach it in your email.
  • In principle, this contest is for native droolers. However, if you are really interested in the puzzle and want to send in solutions in, let's say, CLIPS, or Lisp, or Prolog, or C/C++, or Ruby, yes, your solution will be evaluated and commented, since compilers and runtime of all the above languages are not difficult to get. But please add one line or two in your readme file about how to run your program.

The purposes of this contest:

  • To learn from each other in the Drools community. Improve our programming skill and learn good algorithms and good implementations.
  • To encourage people to explore features of Drools.
  • For fun.

Guideline for winnders:

  • Please consider a proper difficult level for the puzzle you are going to post. It should neither be too difficult nor too easy, and it should be easy for yourself to test the solutions. Puzzles like “Please prove that integrating and configuring software components using Drools is better than using xxxx-ESB” might be doable conceptually but you will need a whole suite of existing components and a whole stack of complex use cases to test the solutions.
  • The puzzles do not have to be backward-tracking-driven (goal-driven) logic puzzles. You may well post a forward-tracking-driven (data-driven) problem and provide an initial data configuration.

That’s it for now. Constructive advice and suggestion about this contest from the community will be taken here.

List of past rounds (including current one)
  1. Round 1: Ages of the Sons (With result report)

  2. Round 2: The Family Puzzl
    , and the result report.


Drools used in Unreal Tournament Agent

Pogamut 2 is an agent platform for Unreal Tournament, free for non-commercial use. They have recently made an announcement where they mention that Drools can be used:

I'm really excited to see that posting as I've always wanted to expand Drools as a platform so that it becomes useful for games programming - good to see that this is finally happening :)

Thursday, August 16, 2007

Drools Presentation at Brazilian JUG SouJava

Yesterday we had a JBoss night at the Brazilian JUG SouJava, where we did a presentation of the newest features on Drools 4, specially the BRMS. It was a nice presentation with full house. Some pictures:

Fernando (right) and me (left). Beginning of the presentation.

The audience.

Fernando is presenting the BRMS

Edgar (Solutions Architect, left), Flávia (JBossAOP, right) and the happy winner of a JBoss Training Course.

Happy Drooling.

Drools download stats

We are now half way through the month, so I thought I would checkout the download stats for August, the results are very promising :)


For our next major release we are trying for a short release period, before the end of this year, where we are focusing on Decision Services, which should help give us an even broader appeal as we become an important piece of software in any SOA strategy. I'll provide more details on this later but the release will include analytics, testing and decision tables for the BRMS as well as a number of wizards and form editors to help with end to end automation with close to zero code.

Tuesday, August 14, 2007

Drools in Antarctica (Michael Neale)

I am a regular listener to the JavaPosse - if you listen to podcasts, I strongly recommend them (I listen to them when at the gym - as their episode lengths are perfect for that).

They had a very interesting interview with Josh Reed - a hacker who spent some time working in Antarctica (!). He is the developer of PSICAT - a graphical application that is used to record the rock strata from drill cores (in Antarctica) - ie an important scientific tool (and open source). He built this using Eclipse RCP, and Drools was mentioned as providing data analysis (he mentioned Eclipse RCP with GEF and Drools as the key technologies).

Once again, this is an application of rules that I struggle to understand, but can appreciate the importance of. Kudos to Josh for making this an open source tool for the greater good of the scientific community in its exploration of Antarctica (for NON OIL purposes !).

PSICAT is also an award winning RCP app - well done !

On an unrelated note, I just returned to work from 3 weeks holiday - I don't remember the last time I had 3 weeks off in a row, and my brain is taking its time getting back into gear, but it is good to be back (must have been a good holiday then). I am looking forward to getting stuck into the testing and analysis/QA components.

Thursday, August 09, 2007

JBoss Drools vs ILog JRules - an anecdotal story

A user recently contacted me to share their experience with ILog JRules and investigations into a possible Drools migration. I've pasted part of the conversation below (with permission), and it makes nice anecdotal reading, I've removed a lot of the more ranting criticism of JRules, many of which surprised me, just to avoid this becoming too controversial :)

You can also read my previous blog article to see more user success stories Drools Success Stories - quotes from the mailing list

Snippets pasted from user email
X is one of the largest ILOG users, paying millions for license fees ...snip... We are satisfied about the rules engine (JRules) performance, but disappointed about the quality of rules management platform and their support ...snip... I have been on the user email (Drools) list for a while, and am very impressed at the energy and expertise you and other core team members demonstrated.
I reviewed Drools 4.0.0 right before the GA release, and created a benchmark to test the engine. The rules used in the benchmark were translated from one of the most critical ILOG rule set in production, about 1,300 rules. I was also pleased to find that the declarative DRL in the new release was so rich that it made converting IRL to DRL a relatively easy task. The same data set used in ILOG benchmark were used in this benchmark, and as I expressed in the previous message, the initial result was very good ...snip... I would say that the benchmarks were very close to "Apple to Apple".
I look at open source offering such as Drools as the perfect fit for us. We did a lot of reverse engineering trying to understand how JRules works and used many of the un-documented API's for some special business and technical requirements. It would be much easier if the source code were available.

Wednesday, August 08, 2007

Featured Drools Job - Tier One Investment Bank

Caspian One is the first company to place a job advert on the Drools Job Board, as such I thought I'd give it wider promotion :)

Intro: Caspian One is working with a tier one investment bank who is looking to recruit a Java Developer to work within the Credit Derivatives Front Office. Project description the successful candidate will be given the opportunity to develop MiFID integration feeds in the Drools framework. The team is responsible for hands on development of implementation, feeds, integration and database infrastructure for an in-house MiFID solution. This is all using SOA strategies, JBoss Drools framework, JDBC, relational database design and SQL coding with either MS SQL or Sybase. Also an essential is good knowledge of modern Java development; Spring /Hibernate. The candidate must have a proven track record of being able to work in a highly dynamic environment with some experience in investment banking. As such we are looking for candidates with good Java skills, who can design database using either MS SQL coding or Sybase and the must is good experience using Drools.

Sales bit: The successful candidate will gain excellent exposure to investment banking business areas, as well as the opportunity to work in a technically challenging, delivery focused environment, within a fast moving business areas.

You can view and apply for this this role at the Drools Job Board here.

Wednesday, August 01, 2007

Drools RuleFlow gains subflow and milestone support

Drools 4.0.1 will include SubFlow and Milestone support, below shows a screenshot of the new pallet. For more information on WorkFlow patterns see

Drools 4.0.1 will also include a new Number Guess example that shows a recursive rule flow.

Here you can see the Rule Flow branch constraint editor with context assist. As mentioned before our constraint editor gives you full access to the Drools "when" conditional language and that constraint lives as an actual rule reasoning over the Working Memory, allowing for very powerful constraints to be expressed.

Finally here you can see how easy it is to add rules in the drl to a ruleflow-group, its just a simple attribute. Complex process behavioural modelling has never been so easy :)