Modeling decision table

From FlexRule Wiki
Jump to: navigation, search

The Result Decision Table

In this example of modeling a Decision Table, we picked the table from a previous article.

Destination Age IsWeekDay MoreThan6 Discount
Group1 100
India Group2 Y 40
India Group2 N 50
Group3 Y N 0
Group3 Y Y 10
India Group3 N Y 30
India Group3 N N 20
Asia Group2 Y Y 50
Asia Group2 Y N 40
Asia Group2 N Y 75
Asia Group2 N N 65
Asia Group3 N Y 35
Asia Group3 N N 25

With a slight change (adding a row) to this table, the model is ready.

Decision Table in a Spreadsheet

So far the prepared table has the following:

  1. All the conditions required for the decision (Check Conditions)
  2. An action for each rule (Check Actions)
  3. Column names

In order to execute the decision, there are some additional rows that need to be added to the table in order to make it executable:

Question: What is the input of this Decision Table?

Answer: The data type we prepared for the decision that encapsulates all of the columns of the table (excluding the action columns) as properties of the type. Let's call it model

Additional row: Input model


Question: What is the goal of this Decision Table? What does it try to achieve?

Answer: The discount percentage for different scenarios.

Additional row: Output discount


Question: How does the data in the table relate to the model?

Answer: The attributes of the model are the properties shown in each column. The actions (goals of the decision) are located in the last column.

Additional rows:

Destination Age IsWeekDay MoreThan6 Discount
Condition Condition Condition Condition Action
model.Destination Age IsWeekDay MoreThan6 discount

Note that in the last new row we added, we connected the data to the Input and Output of the Decision Table. You can use $value as a replacement for the cell values from your table.

In the condition column you can use expressions to establish the relationship between the values and the condition. As we are simply going to set the discount value in the Action column, we use assignment expression to assign a value to discount. Now you can understand where those rows originate.

Modeling Using Excel

In a spreadsheet (e.g., MS Excel-based Decision Tables), the properties of a Decision Table can be defined as shown below:

  1. Title
  2. Header
    1. Input
    2. Output (optional)
    3. Import (optional)
  3. Column Type
  4. Expression (formula)
  5. Column Name
  6. Empty row
  7. Data rows (values/expressions)

You can have all of the rows above defined in an Excel-based Decision Table

Title

The Decision Table must start with a Decision keyword and then a name in the first row.

Format: Decision [decision name]

To finalize the signature part of the Decision Table, after the row containing the column name, there must be an empty row and then your data in the table may begin. All done. The decision table is modeled.

Header

Input

Allows adding input parameters with series of comma-separated variable names

Format: Input v1,v2,v3...

Output

Allows defining output [parameter] with adding a series or comma-separated variable names

Format: Output v1, v2, v3...

Import

Allows the addition of a type parameter and usage of the Type's static members

Format: Import fullTypeName

For example, Import System.DateTime will enable you to use DateTime.Now in your rules expression

Building Sample

You can build an Excel spreadsheet that has the following structure:

Decision discount percentage
Input model
Output discount
Condition Condition Condition Condition Action
model.Destination model.Age model.IsWeekDay model.MoreThan6 discount
Destination Age IsWeekDay MoreThan6 Discount
         
Group1 100
India Group2 Y 40
India Group2 N 50
Group3 Y N 0
Group3 Y Y 10
India Group3 N Y 30
India Group3 N N 20
Asia Group2 Y Y 50
Asia Group2 Y N 40
Asia Group2 N Y 75
Asia Group2 N N 65
Asia Group3 N Y 35
Asia Group3 N N 25

Default Compare Operator

As you can see in the condition columns, we just compare the properties value of the object to the cell values. Where is the compare operator? By default, in condition columns, the compare operation is the equal operator or ==, which can be eliminated. So for example in the first column (condition for Destination), instead of writing model.Destination==$value we can just write model.Destination.

This default operator behaviour can simplify the Decision Tables a lot.

Cell Values

Cells can simply be values or expressions: The Decision Table can have many different expressions:

  1. Simple values
  2. Partial conditions
  3. Range expressions
  4. ... and more, which you can learn about at Decision Table Expressions.

Authoring Decision Table

Using Excel

Simply copy and paste the table into MS Excel or Google Documents, for instance. Save the Excel spreadsheet to something like DecisionTable.xlsx.


MS Excel application on desktop computer authoring rules
Use MS Excel for Authoring


If you don't have MS Excel, you can use Google Documents and create a spreadsheet to author the rule.


Online Google Document for authoring rules
Use Google Document for Authoring

Using Visual Designer

Using Decision Table Editor over a generic Spreadsheet document has its own advantages.

  1. You can simple validate the document and find any overlaps by pressing the validate button on the FlexRule Designer. Please have a look at Model Validation to see how it works.
  2. Allows expression builder to help you build the values and expressions
  3. Has information and context about the whole rule project and relations of the logic and how it fits into scenarios (e.g., IN DMN for Flow scenario).
  4. You can link back and forth to the Decision Table and trace and track its usages

A picture of the Decision Table Editor is shown below:

Dt-editor.png

Using XML

In XML language, you need to fill the following structure.

  1. <DecisionTable name="discount percentage">
  2.   <Declaration>
  3.     <!-- Input, Output and Type definitions come here -->
  4.   </Declaration>
  5.   <Columns>
  6.     <!-- Table signature comes here -->
  7.   </Columns>
  8.   <Data>
  9.     <!-- Table data comes here between series of 'Row' and 'Value' elements 
  10.          in which each row contains multiple value entries as a text element
  11.          The data section represents the condition's expressions. 
  12.          These can be as simple values (data) or as complex expressions.
  13.      -->
  14.   </Data>
  15. </DecisionTable>

For this example, the following Xml is the completed model:

  1. <DecisionTable name="discount percentage">
  2.   <Declaration>
  3.     <Define name="model" direction="in"/>
  4.     <Define name="discount" direction="out"/>
  5.   </Declaration>
  6.   <Columns>
  7.     <Condition name="Destination" expression="model.Destination"/>
  8.     <Condition name="Age" expression="model.Age"/>
  9.     <Condition name="IsWeekDay" expression="model.IsWeekDay"/>
  10.     <Condition name="MoreThan6" expression="model.MoreThan6"/>
  11.  
  12.     <Action name="Discount" expression="discount"/>
  13.   </Columns>
  14.   <Data>
  15.     <Row><Value></Value><Value>Group1</Value><Value></Value><Value></Value><Value>100</Value></Row>
  16.     <Row><Value>India</Value><Value>Group2</Value><Value></Value><Value>Y</Value><Value>40</Value></Row>
  17.     <Row><Value>India</Value><Value>Group2</Value><Value></Value><Value>N</Value><Value>50</Value></Row>
  18.     <Row><Value></Value><Value>Group3</Value><Value>Y</Value><Value>N</Value><Value>0</Value></Row>
  19.     <Row><Value></Value><Value>Group3</Value><Value>Y</Value><Value>Y</Value><Value>10</Value></Row>
  20.     <Row><Value>India</Value><Value>Group3</Value><Value>N</Value><Value>Y</Value><Value>30</Value></Row>
  21.     <Row><Value>India</Value><Value>Group3</Value><Value>N</Value><Value>N</Value><Value>20</Value></Row>
  22.     <Row><Value>Asia</Value><Value>Group2</Value><Value>Y</Value><Value>Y</Value><Value>50</Value></Row>
  23.     <Row><Value>Asia</Value><Value>Group2</Value><Value>Y</Value><Value>N</Value><Value>40</Value></Row>
  24.     <Row><Value>Asia</Value><Value>Group2</Value><Value>N</Value><Value>Y</Value><Value>75</Value></Row>
  25.     <Row><Value>Asia</Value><Value>Group2</Value><Value>N</Value><Value>N</Value><Value>65</Value></Row>
  26.     <Row><Value>Asia</Value><Value>Group3</Value><Value>N</Value><Value>Y</Value><Value>35</Value></Row>
  27.     <Row><Value>Asia</Value><Value>Group3</Value><Value>N</Value><Value>N</Value><Value>25</Value></Row>
  28.   </Data>
  29. </DecisionTable>


Now you are able to read the model by using XmlTableReader

  1. private static IIterable<IElementModel> LoadDecisionTableModel()
  2. {
  3.     // Load the excel document
  4.     var reader = new XmlTableReader(File.ReadAllBytes(@"DecisionTable.xml"));
  5.     reader.Entries.Add("Y", "true", true);
  6.     reader.Entries.Add("N", "false", true);
  7.  
  8.     // Reads all the tables in a specific sheet
  9.     IIterable<ITable> tables = reader.GetTables();
  10.  
  11.     // Create parser for table
  12.     ITableParser tableParser = TableParser.CreateParser();
  13.  
  14.     // Parse the tables to model
  15.     return tableParser.Parse(tables);
  16. }

Executing a Decision Table Model

By defining the aging group as an enum type

  1. enum AgeGroup
  2. {
  3.     Group1,
  4.     Group2,
  5.     Group3
  6. }

Executing the Decision Table is simple. What you need to do is create an execution plan and engine, then execute and retrieve the discount value.

  1. // Load an engine instance and configure custom entries (when required)
  2. var engine = RuntimeEngine.FromSpreadSheet(File.OpenRead(@"YOUR_EXCEL_FILE.xlsx"), "YOUR_SHEET_IN_EXCEL");
  3. engine.OnRunning = (ae) => ae.Context.VariableContainer.RegisterFunction(typeof(AgeExtensions));
  4.  
  5. // Note you can load the custom entries from config file as well.
  6. engine.Entries.Add("Y", "true", true);
  7. engine.Entries.Add("N", "false", true);
  8.  
  9. // Creating the input model 
  10. var sampleData = new 
  11.     {
  12.         Age = AgeGroup.Group3,
  13.         Destination = "India",
  14.         MoreThan6 = false,
  15.         IsWeekDay = false,
  16.     };
  17.  
  18. // Call run method of engine and pass your input object
  19. var result = engine.Run(new object[] { model });
  20.  
  21. // Reading the discount value from the result that is returned by the Run method
  22. var discount = result.VariableContainer["discount"];

Logic Model Reflection

And you are ready to read the table as a model in your application by using ExcelTableReader.

  1. private IIterable<IElementModel> LoadDecisionTableModel()
  2. {
  3.     // Load the excel document
  4.     var reader = new ExcelTableReader(@"DecisionTable.xlsx", "Sheet1");
  5.     reader.Entries.Add("Y", "true", true);
  6.     reader.Entries.Add("N", "false", true);
  7.  
  8.     // Reads all the tables in a specific sheet
  9.     IIterable<ITable> tables = reader.GetTables();
  10.  
  11.     // Create parser for table
  12.     ITableParser tableParser = TableParser.CreateParser();
  13.  
  14.     // Parse the tables to model
  15.     return tableParser.Parse(tables);
  16. }

Please note: The application that is executing the code DOES NOT need to have any Excel application or third-party component installed.

What's next?

  1. Introduction to decision table
  2. Preparing decision table
  3. Modeling decision table
  4. Decision Model and Notation - decision table
  5. Check overlaps
  6. Decision Table final logic
  7. Multilingual decision table
  8. Decision Table 101

Tutorials

  1. Decision Table Hello World