The OpenRulesTM Tutorials         Home   PREV TOP NEXT User's Guide
Divider

Decision Tables

  Introducing Simple Rules Table
How Rules Tables Are Organized
How Rules Tables Are Executed
     
Basic Execution Logic
      Simple AND and OR Conditions
     
Multi-Hit and Single-Hit Rules Tables
Using RuleTemplates
Using Expressions Inside Rules Tables
     
Natural Language Expressions
     
Java Expressions

      Using Java to Represent IF-THEN-ELSE Rules
Horizontal and Vertical Rule Tables
Separating Business and Technical Information [T]
Merging Cells
Data Types for Rules Tables [T]
Hide/Show Technical Information
Columns with Multiple Sub-Columns
Defining Comparison Operators Inside Rule Tables

Comparing Dates
Using Boolean Values
 

OpenRules supports several ways to represent business rules inside Excel tables.  A decision table is the most popular way to present sets of related business rules.  Decision tables are used to describe and analyze decision situations, where the state of a number of conditions determines the execution of a set of actions.  OpenRules allows a user to configure different types of decision tables directly in Excel.  The user also may use simple IF-THEN-ELSE statements to describe rules logic inside tables of type "Method".

Introducing Simple Rules Table  ►top

Let's consider a simple set of HelloWorld rules that can be used to generate a string like "Good Morning, World!" based on the actual time of the day.  How one understands such concepts as "morning", "afternoon", "evening", and "night" is defined in this simple decision table:

Hopefully, this decision table is self explanatory. It states that if the current hour is between 0 and 11, the greeting should be "Good Morning", etc. You may change Hour From or Hour To if you want to customize the definition of "morning" or "evening". This decision table is oriented to a business user. However, its first row already includes some technical information (a table signature):

              Rules void helloWorld(int hour)

Here "Rules" is the OpenRules keyword to recognize a table type as a decision table; "helloWorld" is a name of this particular decision table. It tells an external program or other rules how to launch this rule table. Actually, this is a typical description of a programming method (its signature) that has one integer parameter and returns nothing (the type "void"). The integer parameter "hour" is expected to contain the current time of the day. While you always can hide this information from a business user, it is an important specification of this decision table.

You may wonder where is the implementation logic for this decision table? All decision tables include additional hidden rows (usually password protected) that you can see if you click on the buttons "+" or open the Technical view. For example, click on the button "+" in the opened HelloWorld.xls file, and you will see the following additional rows:

This part of the rule table is oriented to a technical user, who is not expected to be a programming guru but rather a person with a basic knowledge of the "C" family of languages which includes Java.  Let's walk through these rows step by step:

The same table can be defined a little bit differently using one condition code for both columns "min" and "max":

How Decision Tables Are Organized [T]  ►top

As you have seen in the previous section, decision tables have the following structure:

Row # Content Description
1 Signature Rules void tableName(Type1 par1, Type2 par2, ..)  - Multi-Hit Rules Table
Rules <JavaClass> tableName(Type1 par1, Type2 par2, ..)  - Single-Hit Rules Table
2 Condition/Action Indicators The condition column indicator is a word starting with “C”.
The action column indicator is a word starting with “A”.
All other starting characters are ignored and the whole column is considered as a comment
3 Code The cells in each column (or merged cells for several columns) contain Java Snippets in the language defined in the table Environment (the default language configuration is openrules.java).
Condition codes should contain expressions that return Boolean values..
If an action code contains any correct Java snippet, the return type is irrelevant.
4 Parameters Each condition/action may have from 0 to N parameters. Usually there is only one parameter description and it consists of two words:
     parameterType parameterName   (for example: int min)

parameterName is a standard one word name that corresponds to Java identification rules.
parameterType
can be represented using the following Java types:
  • Basic Java types: boolean, char, int, long, double, String, Date  
  • Standard Java classes: java.lang.Boolean, java.lang.Integer, java.lang.Long, java.lang.Double, java.lang.Character, java.lang.String, java.util.Date
  • Any custom Java class with a public constructor that has a String parameter
  • One-dimensional arrays of the above types. Multiple parameters can be used in the situations when one code is used for several columns. See the standard example Loan1.xls
5 Columns Display Values Text is used to give the column a definition that would be meaningful to another reader (there are no restrictions on what text may be used)
6 and below Rules with concrete values in cells Cells in these rows usually contain literals that correspond to the parameter types.

For Boolean parameters you may enter the values "TRUE" or "FALSE" (or equally "Yes" or "No") without quotations.

Empty cells inside rules means "whatever" and the proper condition is automatically considered satisfied.  An action with an empty value will be ignored.  If the parameter has type String and you want to enter a space character, you must explicitly enter one of the following expressions:  :=" " or '=" " or { " "; }

Cells with Dates can be specified using java.util.Date. OpenRules uses java.text.DateFormat.SHORT to convert a text defined inside a cell into java.util.Date.  Before OpenRules 4.1 we recommended our customers  not to use Excel's Date format and define Date fields in Excel as Text fields.  The reason was the notorious Excel problem inherited from a wrong assumption that 1900 was a leap year.  As a result, a date entered in Excel as 02/15/2004 could be interpreted by OpenRules as 02/16/2004.  Starting with release 4.1 OpenRules correctly interprets both Date and Text Excel Date formats.

Valid Java expression (Java snippets) may be put inside table cells by one of two ways:

  • by surrounding the expression in curly brackets, for example: { driver.age+1; }
  • by putting ":=" in front of your Java expression, for example: :=driver.age+1

Make sure that the expression's type corresponds to the parameter type.

 

How Decision Tables Are Executed  ►top 

Basic Execution Logic  ►top

The rules inside decision tables are executed one-by-one in the order they are placed in the table. The execution logic of one rule (row in the vertical table) is the following:

            IF ALL conditions are satisfied  THEN execute ALL actions.

If at least one condition is violated (evaluation of the code produces false), all other conditions in the same rule (row) are ignored and are not evaluated.  The absence of a parameter in a condition cell means the condition is always true.  Actions are evaluated only if all conditions in the same row evaluated to be true and the action has non-empty parameters. Action columns with no parameters are ignored.

For the default vertical decision tables, all rules are executed in top-down order.  There could be situations when all conditions in two or more rules (rows) are satisfied.  In that case, the actions of all rules (rows) will be executed, and the actions in the rows below can override the actions of the rows above.

For horizontal decision tables, all rules (columns) are executed in left-to-right order.

Multi-Hit and Single-Hit Decision Tables  ►top

Let's consider how the OpenRulesEngine executes some very simple rules that define a salutation "Mr.", "Mrs.", or "Ms." based on a customer's gender and marital status:

Rules void defineSalutation(Customer customer, Response response)
Gender Marital Status Set Salutation
Male   Mr.
Female Married Mrs.
Female Single Ms.

If a customer is a married female the conditions of the second rules are satisfied and the salutation "Mrs." will be selected.  This is only a business view of the rules table.  The complete view including the hidden implementation details ("Java snippets") are presented below:

Rules void defineSalutation(Customer customer, Response response)
C1 C2 A1
customer.gender.equals(gender) customer.maritalStatus.equals(status) response.map.put("salutation",salutation); 
String gender String status String salutation
Gender Marital Status Set Salutation
Male   Mr.
Female Married Mrs.
Female Single Ms.

The OpenRulesEngine will execute rules (all 3 "white" rows) one after another. For each row if conditions C1 and C2 are satisfied then the action A1 will be executed with the selected "salutation".

Please note that for this table conditions for all 3 rules will be examined before executing any actions. This is an example of so-called "multi-hit" rules table that executes all rules it may "hit". We may add one more rules at the very end of this table:

Rules void defineSalutation(Customer customer, Response response)
Gender Marital Status Set Salutation
Male   Mr.
Female Married Mrs.
Female Single Ms.
    ???

In this case, after executing the second rule OpenRulesEngine will also execute the new 4th rule and will override a salutation "Mrs." with "???".  Obviously this is not a desirable result.  However, sometimes it may have a positive effect by avoiding undefined values in cases when the previous rules did not cover all possible situations.  What if our customer is a Divorced Female?!

How can this multi-hit effect be avoided?  What if we want to produce "???" only when no other rules have been satisfied.  To achieve this you may use a  so-called "single-hit" table that is specified by putting any return type except "void" after the keyword "Rules".  The following is an example of a single-hit rules table that will do exactly what we need:

Rules String defineSalutation(Customer customer, Response response)
Gender Marital Status Set Salutation
Male   Mr.
Female Married Mrs.
Female Single Ms.
    ???

Another positive effect of such "single-hitness" may be observed in connection with large tables with say 1000 rows: if the OpenRulesEngine obtains a hit on rule #10 it would not bother to check the validity of the remaining 990 rules.

Having rules tables with a return value may also simplify your interface.  For example, we do not really need the special object Response in which we used to write our defined salutation.  Our simplified rules table produces a salutation without an additional special object:

Rules String defineSalutation(Customer customer)
C1 C2 A1
customer.gender.equals(gender) customer.maritalStatus.equals(status) return salutation; 
String gender String status String salutation
Gender Marital Status Set Salutation
Male   Mr.
Female Married Mrs.
Female Single Ms.
    ???

Please note that the last action in the table should return a value that has the same type as the entire single-hit table.  The single-hit table may return any standard or custom Java class such as String or Customer.  Instead of basic Java types such as "int" you should use the proper Java classes such as Integer in the table signature.

Here is an example of Java code that creates an OpenRulesEngine and executes the latest rules table "defineSalutation":


public static void main(String[] args) {
    String fileName = "file:rules/main/HelloCustomer.xls";
    OpenRulesEngine engine = new OpenRulesEngine(fileName);
    Customer customer = new Customer();
    customer.setName("Robinson");
    customer.setGender("Female");
    customer.setMaritalStatus("Married");
    String salutation = (String) engine.run("defineSalutation", customer);
    System.out.println(salutation);
}
 

To learn more about OpenRules execution logic click here.  The standard OpenRules's installation contains many examples that demonstrate how to invoke OpenRulesEngine from regular Java applications (see projects HelloJava, HelloJsr94, HelloXMLCustomer) as well as from web-based applications (see projects HelloJsp, HelloForms, and HelloWS). 

Simple AND and OR Conditions  ►top

All conditions inside the same row (rule) are considered from left to right using the AND logic. For example, to express

if (A>5 && B >10) {do something}

you may use the rules table:

Rules void testAND(int a, int b) 

C1

C2

A1

a > 5 b>10

System.out.println(text)

String x

String x

String text

A > 5

B > 10

Do

X

Something

 

 

 

To express the OR logic

if (A>5 || B >10) {do something}

you may use the rules table:

Rules void testOR(int a, int b) 

C1

C2

A1

a > 5 b>10

System.out.println(text)

String x

String x

String text

A > 5

B > 10

Do

X

 

Something

 

X

 

 

 

Instead you always may execute directly a simple method:

Method void testOR(int a, int b) 

If (a > 5 || b>10)  System.out.println("Something");

 

Using Templates  ►top 

Rule Templates introduced in the OpenRules-5 allow rule designers to completely hide implementation details from business users. Rule templates are regular decision tables such as the "defineGreeting" table described above.  However, if we want to use this table as a template for many other tables with the same structure but different rules, it is enough to use only the first 5 rows:

Rules void defineGreeting(App app, int hour) - Signature with parameters
C1 A1 - Conditions and Actions identifiers
min <= hour && hour <= max

app.greeting = greeting; 

- Java snippets describe condition/action semantics
int min int max String greeting - Parameter types and names
Hour From Hour To Set Greeting - Business names for conditions and actions

We may use this decision table as a template to define different greeting rules for summer and winter time. An actual decision table implements the template table with particular rules:

Rules summerGreeting implements defineGreeting
Hour From Hour To Set Greeting
0 10 Good Morning
11 18 Good Afternoon
19 22 Good Evening
23 24 Good Night

and

Rules winterGreeting implements defineGreeting
Hour From Hour To Set Greeting
0 11 Good Morning
12 17 Good Afternoon
18 22 Good Evening
23 24 Good Night

Note that Rules tables "summerGreeting" and "winterGreeting" do not have technical information at all - Java snippets and a signature are defined only once and reside in the template-table "defineGreeting".

Click here to learn more about Rule Templates.

 

Using Expressions Inside Decision Tables  ►top

OpenRules allows a rules designer to use two types of expressions inside decision table cells:

  1. Natural Language Expressions
  2. Java Expressions

Natural Language Expressions     ►top

Starting with OpenRules release 4, a rules designer may use plain English expressions to define possible values of different decision variables inside rule tables.  Instead of creating multiple columns for defining different ranges for integer and real values, a business user may define from-to intervals in practically unlimited English using such phrases as:  "500-1000", "between 500 and 1000",  "Less than 16", "More or equals to 17", "17 and older", "< 50", ">= 10,000", "70+", "from 9 to 17", "[12;14)", etc.  Here is a simple example of a condition that specifies different credit scores:

Condition-2
interval.contains(c.outsideCreditScore)
FromToInt interval
AND
Outside Credit Score
<= 100
(100;550]
more than 550 and less or equal to 900
greater than 550 but less than 901
551 - 900
551-900
551-900
551-900
from 551 to 900
between 551 and 900

To read a detailed tutorial wit examples that describes how to apply natural language inside rule tables please click here.

Java Expressions   ►top

The use of Java expressions provides a powerful ability to perform calculations and test for complex logical conditions.  While the writing of expressions requires some technical knowledge, it does not require the skills of a programmer.  Real-world experience shows that business analysts frequently have a need to write these expressions themselves.  It is up to the decision table designer to decide whether to show the expressions to business people or to hide them from view.  Let's consider a decision table for "Income Validation" from the provided example Loan1.xls:

Rules void ValidateIncomeRules(LoanRequest loan, Customer customer)
C1 A1
customer.monthlyIncome * 0.8 - customer.monthlyDebt > loan.amount/loan.term loan.incomeValidationResult = result;
boolean condition String result
IF
Income is Sufficient for the Loan
THEN
Set Income Vaidation Result