Practical DMN: The Basics
Blog: Method & Style (Bruce Silver)
Practical DMN: The Basics
Want to learn DMN decision modeling without training? DMN Method and Style, 2nd edition is a good place to start. But to really learn it, you need to go beyond books. You need to get your hands dirty in a tool. I suggest starting with a free trial of Trisotech DMN Modeler.
When you log in, go to the EU-Rent repository (File/Open/EU-Rent) and open the model called EU-Rent Pricing. I’ll walk you through it here. Then click File/New and try to re-create the model yourself. That might sound like busywork but, trust me, you’ll learn a lot just doing that.
This model selects the best price for a car rental request based on the type of car, length of rental, applicable promotions, and customer loyalty discount.
The Decision Requirements Diagram is shown here. In any DMN model, you start by creating the DRD.
- The rectangles are decisions. Each decision has a name, a datatype or “type”, and a value expression, a formula for calculating the decision value from the values of its inputs. T
- The ovals are input data. This is the data supplied to the model in order to calculate the decision values. Here I’ve colored them yellow, but that’s just to highlight them. You can change the color from the Fill button on the Home ribbon. Input data has a name and a type but no value expression. You enter its values on execution of the model.
- The solid arrows leading into a decision are called its information requirements, identifying the dependency of the decision’s value expression on supporting decisions and input data.
- The rectangles with clipped corners are business knowledge models, or BKMs. Here I’ve colored them blue for convenience. A BKM’s value expression is defined as a function of one or more parameters. The function is called by a decision, or possibly another BKM, identified by a dashed arrow called a knowledge requirement. For example, here Weekly Price calls the BKM Weekly Type Price by supplying values to its parameters and receiving the function result in return.
- Each decision, BKM, and input data element in the DRD is represented by a variable with the same name, used in the value expressions.
You should get in the habit of specifying the datatype of each DRD element. It’s not absolutely necessary but always best practice, so just do it. The type language for DMN is called FEEL, which is also the language of its value expressions. FEEL base types include string (text), number, boolean, date, time, date and time, and a couple duration types. A variable assigned to a base type can have any value in the domain of that type. Sometimes that’s fine, but often you want to define constraints on the domain of allowed values. A type with defined constraints is called an item definition, meaning a user-defined type. These are not special things. You will use them all the time. An item definition can also be a data structure, a list of components, each with a name and type. And finally, an item definition may be specified as a collection of another type. To see the item definitions in this model, go to the DMN ribbon and select Data Type.
There are 7 item definitions in the model. Click on the pencil for tCustomer to view its definition.
You see it is a structure with 6 components. The last component, Past Rentals, is type tRentals, a collection of type tRental, where tRental is a structure with 3 components, the last of which, CarType, is Text with an enumeration constraint. Its value can only be “Economy”, “Compact”, or “Full Size”.
To set the type of a DRD element, right-click Attributes/Input Data Type (for input data) or Output Data Type (for decision or BKM). You can select a base type, an existing type, or create a new type. Here input data Customer is type tCustomer and Rental Request is type tRental.
Let’s look at the overall decision logic. The top-level decision Best Price, a number, depends on 4 supporting decisions: Weekly Price and Daily Price, both numbers; Applicable Promotions, a 2-column table; and Discount Percent, a number representing a percent. Those dependencies are specified by the 4 information requirements into Best Price in the DRD.
If you click on the icon in the upper left corner of Best Price, you see its value expression. DMN supports a variety of value expression formats. This one, a text formula, is called a literal expression. It uses the FEEL expression language.
The syntax may look daunting at first, but it’s actually simpler than, say, Excel Formulas. FEEL was designed for business users, not programmers. It contains a number of built-in functions, including three used here:
- append(list, item1, item2, …) means append items to an existing list
- min(list) returns the minimum value of a list of numbers or dates
- decimal(number, integer) rounds a number to a specified number of decimal places
A list variable followed by an expression in square brackets represents a filter of the list. Here Applicable Promotions is a 2-column table, a list of rows with two components, Description and Price.
So Applicable Promotions.Price is the Price column of the table, a list of numbers, and the filter [item>0] here just ensures that if there are no Applicable Promotions the expression is an empty list rather than null. Reading the literal expression from the inside out, we append to the list of prices from Applicable Promotions the discounted Weekly Price and the discounted Daily Price. Then we take the minimum value of the resulting list and round it to two decimal digits following the decimal point. This style of nesting one function inside another is economical but maybe hard for beginners to understand. Alternatively, you could have separate decisions in your DRD for each part of it – the list append, finding the minimum, and rounding – or you could use another value expression type called a context to do each of those steps in a separate table entry.
The decision Weekly Price illustrates a context. We want to multiply the weekly price for the car type by the number of weeks in the rental. We could have written it as a long literal expression as in Best Price, but here we broke out the calculation of Weeks count as a separate context entry. Each context entry has a name, type, and value expression. The last row of the context is the final expression.
Weeks count subtracts the rental start date/time from the end date/time, giving a days and time duration. We divide that duration by the duration 168 hours (7 days x 24 hours), to get the number of weeks, and round that up to the next higher integer using the ceiling built-in function.
The final result multiplies Weeks count by the result of the BKM Weekly Type Price with the parameter value Rental Request.CarType, meaning the type of car rented. Weekly Type Price’s value expression is a decision table. It has one input, Car Type, type tCarType, which must match the type of the argument in the call, Rental Request.CarType.
Putting it all together, Weekly Price passes the car type to the BKM, gets back the weekly price for that car type, and multiplies that by the number of weeks in the rental.
Finally, let’s look at Applicable Promotions. EU-Rent has a list of Date Based Promotions, here modeled as a BKM decision table. When a BKM is a decision table, the table inputs specify its parameters, so there are 6 of them. The table has 2 output columns, meaning a structure with 2 components, and the table has hit policy C (Collect), meaning return a list of outputs for each matching rule. So what is returned is a list of 2-column structures, the table type tPromotions. Also note that not all outputs are specified as literal values. In the last item in Date Based Promotions, the Price component of the output is an expression calling the BKM Daily Type Price.
Applicable Promotions calls this BKM by supplying values to the 6 parameters. It is modeled as a context. The first 4 context entries use FEEL calendar type components to extract the month and day value from the rental start and end date-times. The fifth calculates the number of days in the rental. Those context entries are used in the call to the BKM in the final result expression.
Once you’ve completed a decision model you need to validate it. On the DMN ribbon select Validate. That should return no errors. A second form of validation on that ribbon is Method & Style Decision Table Analysis, which looks for gaps, overlaps, and other errors in decision tables. In this model, that validation returns 3 errors on the Discount decision table in Discount Percent.
From the table you can see the reason. Qualifying Rentals Count is really an integer, but FEEL has no integer type, only number. So the reported rule gaps are for intervals like greater than 0 but smaller than 1, impossible for integers. In a case like this you have two choices: (1) Understand the validation error and just accept it; or (2) Fix the table, even though that looks odd. The fixed table is shown below:
Now it’s time to execute the model. I don’t think I can emphasize this enough: If you cannot execute your model (and make sense of the results), you can’t have confidence that the logic is correct. Many DMN tools cannot execute the logic. Fortunately, Trisotech can.
In the Execution ribbon, select Test. On the left, you enter values for the input data, then click Run. The tool reports outputs of all decision nodes in the DRD. After a run, Save preserves the input and output values in a Test Case. When entering values in the Test panel, the Load button lets you populate the form with values from a saved Test Case. The screenshots below show the input data for Test Case 2, followed by the execution output.
An Exercise to Get Started
That’s pretty much it. We’ve talked about the DRD, datatypes, FEEL expressions, BKMs, contexts, validation, Decision Table Analysis, and execution. It’s a lot of information in a short space. Remember, I said at the top you need to get your hands dirty in the tool to really get it. So do this: If you haven’t done so already, go to https://www.trisotech.com/methodandstyletrial to get a free trial account, then log in and open EU-Rent Pricing. In the Import-Export ribbon, click HTML Documentation and print out the web page. That captures all the information in this model. Then click File/New and re-create the model from the documentation. Make sure it validates, then run it.
Help Is Available
If that seems overwhelming, I suggest the training. DMN Method and Style Basics covers DRDs and datatypes, decision tables, BKMs, simple FEEL, and decision services. DMN Method and Style Advanced dives deeper into FEEL functions and operators, contexts, calendar arithmetic, and manipulating lists and tables. They go at a slower pace, with exercises using the tool at each step of the way and post-class certification based on an online exam and mail-in exercise that you iterate until it is perfect. That is the best way to become proficient in DMN.