Can we exchange rules without exchanging rule engines ?

Rules are data: their definition can be saved into a database, loaded back or send over the wire to be shared across applications. But rules are code too: their execution is supposed to produce a predictable output. Therefore interchange of rules relies on an execution engine shared by the parties.

One question which comes up immediately is: what is the set of features that this engine must support to make rule execution consistent ?

Historically, the term "Rule" has been used in a very loaded way. It often refers to production rules, executed within the context of a forward-chaining engine. That's the famous RETE algorithm.

Our experience in large-scale rules applications — processing hundreds of millions of transactions a day — that the RETE algorithm has a significant production impact. Using two industrial implementations of the RETE and a sequential engine, both coming from the same vendor, we found a x10 factor degradation in performance, start-up time and used memory. Do we really need RETE ?

Forward-chaining is often presented as an enabler of declarative programming. But one may argue that any language is a form of declarative programming: everything is matter of level of abstraction and target problem to model.

For instance Mathematical Programming, Decision Trees or even Assembly Code can be very declarative languages for certain class of problems. Perl is very declarative to process text, Java is very declarative for Object Modeling and Functional Programming. A rule base may seem very declarative for monitoring or diagnosis system, but for some transaction-processing applications the uncontrolled order of execution and the chaining between rules may lead to an obscure behavior from the business manager perspective — therefore defeating the purpose of "declarative programming".

We believe many transactional, stateless systems are best suited with simple sequential rules processing that do not require forward-chaining.

For instance, an underwriting applications may require to accept a loan that:
* at least one eligibility rule should be true
* no disqualifying rule should be true

As another example, a rating engine may require that:
* only one promotion is applicable for a given product
* the best promotion for the customers should be always be applied

In those examples, the system will look the most declarative to the rules author / policy manager only if the rules are executed in a sequential way, as atomic components, and the system (or application code) has some hard-coded conflict resolution strategy to take care of the algorithmic complexity. We don't need the business users to specify "meta-rules" to control the execution of the rules.

Performance optimization can be made in the application code by taking advantage of the properties of the system. In the load underwriting example, rule processing can be ended as soon as one disqualifying rule is proven to be true. In the rating engine example, rule processing can be skipped as soon as 100% discount is reached.

Beside those performance issues, in some cases the conflict resolution cannot be implemented using meta-rules. Let's go back to the rating engine example: if the promotions are cross-products, it is common to not allow overlapping between them. Selecting the promotions providing the best fee for the user require the resolution of a set-covering problem — something definitively out of scope of a forward-chaining engine.

This conflict resolution strategy is what we call the "contract" between the application and the rule engine. It defines the boundaries of what flexibility the application can accommodate, and the rule engine must enforces it. The system does not rely on rules properly written to be consistent. If consistent does not mean "business efficient", this design makes ease the authoring of rules, facilitate the testing and clearly communicate between the development team and the business users how much flexibility is expected.

From an interchange perspective, it means that both parties must have some knowledge of the contract assumed by the rules. Two strategies are possible:
- find a formal definition of the contract and bundle it with the rules too; in our mind, we should leverage existing process description language
- assume the contract has already been implemented within each parties, and provide a identifier when rules are exchange

So, to answer the title of this paper, we believe that rules exchange also requires rule engine exchange (directly or by reference). We cannot assume all parties involved in rule exchange will share a universal, generic rules engine supporting a particular formalism. Using a contract-based approach can help bridge the gap between simple table-driven business rules and sophisticated forward-chaining mechanism, therefore increasing the adoption of business rules for some applications.