Skip to: Site menu | Main content

Drools

Java Rules Engine

Forward Vs Backward chaining Print

First off, I'm bias, so take this with a big grain of salt.

For those new to rule chaining, the advantages/dis-advantages of forward, backward and bi-directional chaining can be a bit confusing. Here is a quick definition of the terms.

  • Forward chaining - When one or more conditions are shared between rules, they are considered "chained." Chaining refers to sharing conditions between rules, so that the same condition is evaluated once for all rules.
  • Backward chaining - Backward chaining is very similar to forward chaining with one difference. Backward chaining engines query for new facts, whereas forward chaining relies on the application asserting facts to the rule engine. Backward chaining rule engines will implicitly create subgoals and use those subgoals to execute queries.
  • Bi-directional chaining - When rules operate in both modes, it is considered bi-directional.

One of the benefits of backward chaining is the user doesn't have to explicitly write rules for the subgoals. The rule engine implicitly generate the subgoal for each object. This is generally done when the rules are loaded into the rule engine. As the conditions of each subgoal is met, a backward chaining rule engine will execute additional queries.

In my mind, it's better to write rules with explicit subgoals. A rule engine only knows what's in the rule and does not understand the business context. Let's say I use a backward chaining engine. Every time the engine queries the database, it takes at minimum 1-10ms depending on the query and dataset size. This is assuming database connection pooling is used. If the rule engine makes a new connection, it will take 50ms to connection + 1-10ms to run the query.

In the case of "in-memory" data store like caches in the JVM, there's no performance impact. One argument for backward chaining is reading extremely large datasets. In practice it's bad to load 10 million rows of data repeatedly be it forward or backward chaining. It is much better to summarize the data in aggregates or in summary tables. In those cases, the difference is having the rule engine query for the data or having the application assert it. When one considers modern rule engines like JESS support forward and backward chaining, the direction of the chaining isn't as important as the rules.

Backward chaining rule engines can be more forgiving than forward chaining rule engines in certain cases. For example, if someone naively writes a rule that loads 100K rows of data, a backward chaining rule engine maybe less likely to get an OutOfMemoryException. But there's a catch. Writing rules that way results in poorly written rules, which may not scale well. If scalability and efficiency are important, explicitly writing the subgoals is safer and more manageable.

Unfortunately, the only way to know how a rule will behave is to profile it and understand the business case. Many people make the mistake of thinking a rule engine will magically solve their problems. Writing high performance rules is not easy or intuitive. The best way to build efficient applications using rule engines is to take the time to learn how each approach works and use both techniques. Although it increases the learning curve, the choice between forward and backward chaining isn't something that can be summed up in 2-3 sentences. It's crucial to consider the intent of the rule, size of the dataset and performance requirements.

Peter Lin