The Decision Model editor in PCS (Process Cloud Service) or the later OIC (Oracle Integration Cloud) supports the DMN (Decision Modeling Notation) standard version 1.1, and uses FEEL (Friendly Enough Expression Language) to make decision modeling easier and more intuitive.
In DMN all decision logic is represented as ‘boxed expressions’. A ‘boxed expression’ is a graphical notation for decision logic. Within OIC we recognize the following boxed expressions:
The expressions in the boxes are FEEL expressions. A Decision Model is a tree of simple decisions notated as FEEL expressions. In the remainder of this blog we will give an example of the various boxed expressions.
The first example is a boolean expression with the name ‘SmallPizza’. The expression is true when the size of the pizza is ‘Small’. Otherwise it’s false.
In the second example we have the named (crustArea) expression to calculate the pizza crust area.
Next we have the if-then-else construction. Actually, this is no more than a combination of 3 expressions. The first determines which of the following 2 is returned as a result.
This construction could also be defined with the following single expression
The Decision Table is by far the most complex and ridge boxed expression. In this post we limit ourselves to a single example and an explanation of the available hit policies.
The following table returns the required baking time for each type of pizza. The baking time is independent of the size, except for the Quattro Stagioni, the Small pizza requires a minute less than the other sizes. To get the correct outcome from the Decision Table we have to set the hit policy. By default it is set to U(nique). But that will not work for this. There are 2 rules that a small Quarttro Stagioni meets. We want the first rule to be met. We do this by setting the hit policy to F(irst) in the upper left corner.
The following list shows the available Hit Policies. Here we are not going to treat them in detail.
The Unique hit policy is used when at most 1 rule can match the input
The Any hit policy is used when multiple rules can match the input, but the output value is the same for all matching rules
The First hit policy is used when multiple rules can match the input. The first hit by rule order is returned.
The Priority hit policy is used when multiple rules can match the input.The matching rule with the highest output priority is returned.The priority is defined by the order of output values in the decision table output column header
The Collect hit policy is used when multiple rules can match the input, and a list of output values for all the matching rules is desired
The Collect with sum hit policy is used when multiple rules can match the input, and the sum of the output values for all the matching rules is desired
The Collect with min hit policy is used when multiple rules can match the input, and the smallest output value for all matching rules is desired
The Collect with max hit policy is used when multiple rules can match the input, and the largest output value for all matching rules is desired
The Collect with count hit policy is used when multiple rules can match the input, and the count of the matching rules is desired
Next we come to the context box. A context is a list of key-value pairs.
In this example a list of 'constants'. The key must be unique, when duplicated, only the last one survives. In the example we used expressions, but it is possible to use any type that suits your needs, for example decision tables. In a context it is possible to reference entries that are defined higher in the context (like the fullname, that is using size and name).
A context is a list of key-value pairs and a list is a list of values without the key. It’s pretty straight forward.
Next is a relation. A relation is a shorthand for multiple contexts (a list of contexts).
Let’s convert this relation into a flat FEEL expression. We will do this in two steps. The first step is to present the relation as a list.
The next / second step is to transform this list into one single expression.
The last one is the function. Functions are used to get a reusable piece of code. You can feed them with parameters. A function can contain any of the other boxed types in its body. But that is not that special. Without explicitly mentioning it we already did it before. In the context we used nested expressions.
The following function checks whether the pizza size is 'Small', 'Medium' or 'Large'. If that is the case, the cooking time is calculated. For a 'Small' pizza that is 2, a 'Medium' 3 and for a 'Large' it is 4 minutes.
The ‘index of’ function returns all occurrences of the size in the list. For our solution this could only be one occurrence. We get this single occurrence as an entry in a list. That’s why the first entry is selected and convert to a string and thereafter into a number.
In this function we used a few of the available build-in functions. We won’t get into details about all of them in this blog. In a later blog we will pay special attention to these build-in functions.