The Inference Task

Silvie   Spreeuwenberg
Silvie Spreeuwenberg Founder / Director, LibRT Read Author Bio || Read All Articles by Silvie Spreeuwenberg

This column is the next in a series that provides the reader with best practices on using or choosing a rules engine.  The target audience for this series is typically the user of a rule engine, i.e., a programmer or someone with programming skills.  All coding examples should be read as pseudo-code and should be easily translated to a specific target syntax for a rule engine that supports backward and forward chaining in an object-oriented environment.

We will discuss recommendations on how to create a rule service that can infer new information based on existing information with rules using a rules engine.  We will call the task that the program performs an inference task.  In this description the following concepts are important:

  • Rule set:  a collection of rules (or rule sets) that are grouped
        The grouping can be done in various ways.

  • Infer block:  a construct that uses rules to solve a problem
        The solution algorithm may be goal driven (backward chaining) or data driven (forward chaining).

  • Inference Task:  a set of methods that are used to perform a task, using one or more infer blocks
        Besides the execution of the infer block it also takes care of the preparation and the processing of the results of the infer block.

In this column I want to emphasize the importance of keeping the infer blocks 'clean'.  This means that the infer block applies the following template:

example code
inferblock template

infer [history ]
  rule posting section
  [inference engine preparation (see column "procedural logic in the reasoning process" — when needed logic) ]
  chaining statement
  [inference engine analysis (see column "procedural logic in the reasoning process" — reactional logic) ]

The reason for doing this is that within an infer block the application 'enters a different world' of the application.  The infer statement creates an instance of the Inference Engine and you don't want to do anything else than 'inferencing' as long as the engine is active.

Definition of inference task

The definition of 'inference task' is given above.  In the following discussion I may simply refer to this as 'task'.

The task usually maps to a solution task in your design — more specifically:  a solution with the help of rules.  The inference task is the direct context of an infer block.  It usually takes care of the preparation of the case data, and it wraps up the results of the infer block(s).

I recommend that each inference task be represented as a class — a class that has a single (public) entry point, for example, 'Perform( )'.  This method has a generic implementation:

example code
inference task perform method template

if current.precondition (1)
  if current.initialize (2)
    current.inference (3)
    current.processresults (4)
    current.finish (5)
  current.whenpreconditionfailed (6)

Here is an explanation of the code lines above:

  1. precondition
  2. Do some checks for the availability of instances and/or attribute values.  If you want a special method for determination of whether or not the task is eligible to be performed, you can introduce a public class method called 'IsEligibleToPerform'.  This method is evaluated before you create an instance of the task.

  3. initialize
  4. Prepare the inference.  This method may collect extra data from the database.

  5. inference
  6. The actual inference:  this method contains the infer block.  I deliberately keep the infer statement out of this generic method because some tasks may require the use of the history option, while others don't.

  7. process results
  8. Wrap up the results of the chaining process; check the post-condition(s) of the task.

  9. finish
  10. Clean up.

  11. when precondition failed
  12. Perform error handling and/or logging

It is a good idea to have a notion of the 'client' of the task.  This client is passed to the task as a pointer to an interface class.  The pointer may be passed with the Create( ) method of the task class.

The 'Task Client Interface' defines the methods that the caller of the task has to implement.  These methods include, but are not limited to, functions to retrieve extra data, perform error handling or logging, and handle the results of the task.

Here are some examples of the TaskClientInterface methods:

  • WhenPreconditionFailed(in message is string)

  • WhenPostConditionFailed(in message is string)

  • WhenError(in errnum is TTaskError)

  • CollectSalaryDataForPeriod(in date_start is date, in date_end is date)

# # #

Standard citation for this article:

citations icon
Silvie Spreeuwenberg , "The Inference Task" Business Rules Journal, Vol. 9, No. 8, (Aug. 2008)

About our Contributor:

Silvie   Spreeuwenberg
Silvie Spreeuwenberg Founder / Director, LibRT

Silvie Spreeuwenberg has a background in artificial intelligence and is the co-founder and director of LibRT. With LibRT, she helps clients draft business rules in the most efficient and effective way possible. Her clients are characterized by a need for agility and excellence in executing their unique business strategy or policy. Silvie's experience has resulted in the development of tools and techniques to increase the quality of business rules. She writes, "We believe that one should focus on quality management of business rules to make full profit of the business rules approach." LibRT is located in the Netherlands; for more information visit &

Read All Articles by Silvie Spreeuwenberg

Online Interactive Training Series

In response to a great many requests, Business Rule Solutions now offers at-a-distance learning options. No travel, no backlogs, no hassles. Same great instructors, but with schedules, content and pricing designed to meet the special needs of busy professionals.