# Using advanced literal expressions (functions in DMN decision elements)¶

In case you have modeled your first DMN diagram, you are already familiar with DMN expressions for decision logic, e.g. in the form of a simple smaller than statement. These expressions are explained in the chapter Creating and editing DMN diagrams.

You might remember that you selected the corresponding operator from a drop-down list in the Decision Table Editor. The ‘operator’ drop-down list

In many cases, these basic operators are not sufficient.

A simple example is determining a discount based on the total value of a list of purchased objects.

To determine the sum, we need to use Signavio’s advanced literal expressions. The expressions are based on FEEL, the friendly enough expression language specified as part of the DMN standard, which you can download as PDF at http://www.omg.org/spec/DMN/1.0/PDF.

The single commands can be used in combination, like in the following example:

`Product((1 - DiscountRate) * Sum(ListOfItemPrices))`

In the example, we calculate the total purchase sum of a list of items, considering a discount. The variables used here correspond to the data types defined in Input Data element’s attributes and can be set when simulating the DMN diagram.

The documentation of all available expressions can be found at Documentation of all literal expressions.

Of course, you can also use standard operators (`+`, `-`, `*`, `/`, `and`, `or`) within literal expressions.

Consequently, the example above can be expressed more concisely:

`(1 - DiscountRate) * Sum(ListOfItemPrices)`

## Using literal expressions in Decision Tables¶

In our example, we want to determine - as already mentioned above - a discount based on the total value of all purchased items.

First, create the Purchased items Data Input element. The input should be a list of numbers of the type currency: Create a Data Input element and configure it according to the screenshot.

Now create a Decision, connect it to the data input and label it Determine discount. Click the table icon in the upper left corner of the Decision element to open the Decision Table Editor. Create a Decision, reference the Data Input element and open the decision table editor.

To activate the literal expression input, click the header and delete the input reference in the table: Delete the input reference to be able to insert a literal expression.

Type in =. An overview over available variables and functions is displayed: After inserting an initial ‘=’ sign, available variables and functions are displayed.

Suggestions appear as you type. Type in Sum and select the Sum function. Then, insert the variable PurchasedItems as a parameter of Sum: Insert the literal expression ‘Sum(PurchasedItems)’.

Now, the decision logic’s Input Data is the sum of all purchased items. You can define the decision logic as usual (see: Editing diagrams).

Please mind the first hit policy in our example: decision logic for determining a discount based on the total sum of purchased items

## Using literal expressions instead of Decision Tables¶

You can also use literal expressions instead of Decision Tables.

For example, you can split a decision into two daisy-chained elements, one with a decision table and another one with literal expression logic. ‘Calculate total sum’ and ‘Determine discount’ as two separate Decision elements.

• The first element calculates the total sum of purchased items.
• The second element determines the discount based on the total sum.

We can model the first decision without using a decision table.

Open the decision table editor and switch to the Literal expressions tab. There, insert the literal expression to calculate the sum of items: Open the ‘Literal expression tab’ and insert the literal expression.

Now, the decision element returns the sum of items as a Data Output and can be referenced by the following Decision element.

If we create complex literal expressions, we can define variables - so called boxed contexts and reference them in our decision function: Manage complex expressions with boxed contexts.

This improves the readability of our literal expressions.

Important

If a literal expression is defined, it supersedes the decision logic in the decision table.

## Documentation of all literal expressions¶

This section lists all available literal expressions, grouped by operation type.

### Arithmetic operations¶

#### Abs¶

`Abs(number):NUMERIC`

Returns the absolute value of a number.

Example: `Abs(-5)` returns `5`.

#### Count¶

`Count([num1 ,num2, num3]):NUMERIC`

Returns the number of elements of the given list.

Example: `Count(["item1", "item2", "item3"])` returns `3`.

#### Round¶

`Round(number,digits):NUMERIC`

Returns a number rounded to the corresponding number of digits.

Example: `Round(3.44,1)` returns `3.4`.

#### Ceiling¶

`Ceiling(number):NUMERIC`

Returns a number rounded up to the next integer.

Example: `Ceiling(1.3)` returns `2`.

#### Floor¶

`Floor(number):NUMERIC`

Returns a number rounded down to the next integer.

Example: `Floor(1.6)` returns `1`.

#### Integer¶

`Integer(number): NUMERIC`

Returns the integer part of a number.

Example: `Integer(1.34)` returns `1`.

#### Modulo¶

`Modulo(divident, divisor):NUMERIC`

Returns the remainder of the divident divided by the divisor.

Example: `Modulo(4, 3)` returns `1`.

#### Percent¶

`Percent(number):NUMERIC`

Returns the number divided by 100.

Example: `Percent(10)` returns `0.1`.

#### Power¶

`Power(base, exponent):NUMERIC`

Returns the base raised to the power of the exponent.

Example: `Power(2, 3)` returns `8`.

#### Product¶

`Product([factor1, factor2, factor3]):NUMERIC`

Returns the product of a list of factors.

Example: `Product([2, 3, 4])` returns `24`.

#### RoundDown¶

`RoundDown(number, digits):NUMERIC`

Returns a number rounded down to the corresponding number of digits.

Example: `RoundDown(1.3674, 2)` returns `1.36`.

#### RoundUp¶

`RoundUp(number, digits):NUMERIC`

Returns a number rounded up to the corresponding number of digits.

Example: `Abs(1.344, 2)` returns `1.35`.

#### Sum¶

`Sum([number1, number2, number3]):NUMERIC`

Returns the sum of a list of values.

Example: `Sum([1, 2, 3, 4, 5])` returns `15`.

### Date & time operations¶

#### Day¶

`Day(datetime):NUMERIC`

Returns the day part of a datetime.

Example: `Day(2015-12-24T12:15:00.000+01:00)` returns `24`.

`DayAdd(datetime, days to add):DATE`

Returns the date plus the provided number of days.

Example: `DayAdd(2015-12-24T12:15:00.000+01:00, 1)` returns `2015-12-25T12:15:00.000+01:00`.

#### DayDiff¶

`DayDiff(datetime1, datetime2):NUMERIC`

Returns the amount of full days between two dates.

Example: `DayDiff(2015-12-24T12:15:00.000+01:00, 2015-12-25T12:15:00.000+01:00)` returns `1`.

#### Date¶

`Date(year, month, day):DATE`

Returns a date using the standard parameters of a date: year, month, day

Example: `Date(2015, 12, 25)` returns `2015-12-25`.

#### DateTime¶

`DateTime(day, month, year, hour, minute, second, hourOffsett):DATE`

Returns the dateTime using the standard parameters of a data time. The last parameter ‘hourOffset’ is optional.

Example: `DateTime(25, 12, 2015, 12, 15, 0, 1)` returns `2015-12-24T12:15:00.000+01:00`.

#### Hour¶

`Hour(datetime):NUMERIC`

Returns the hour part of a datetime.

Example: `Hour(2015-12-24T12:15:00.000+01:00)` returns `12`.

#### HourDiff¶

`Hour(time):NUMERIC`

Returns the amount of full hours between two dates.

Example: `HourDiff(2015-12-24T12:15:00.000+01:00, 2015-12-24T14:15:00.000+01:00)` returns `2`.

#### Minute¶

`Minute(time):NUMERIC`

Returns the minute part of a datetime.

Example: `Minute(2015-12-24T12:15:00.000+01:00)` returns `15`.

#### MinutesDiff¶

`MinutesDiff(datetimes1, date2times):NUMERIC`

Returns the amount of full minutes between two dates.

Example: `MinutesDiff(2015-12-24T12:15:00.000+01:00, 2015-12-24T13:15:00.000+01:00)` returns `60`.

#### Month¶

`Month(datetime):NUMERIC`

Returns the month part of a datetime.

Example: `Month(2015-12-24T12:15:00.000+01:00)` returns `12`.

`MonthAdd(datetime, months_to_add):DATE`

Returns the datetime plus the number of months.

Example: `MonthAdd(2015-10-10T12:15:00.000+01:00, 1)` returns `2015-11-10T12:15:00.000+01:00`.

#### MonthDiff¶

`MonthDiff(datetime1, datetime2):NUMERIC`

Returns the amount of full months between two dates.

Example: `MonthDiff(2015-10-10T12:15:00.000+01:00, 2015-11-10T12:15:00.000+01:00)` returns `1`.

#### Now¶

`Now():DATE`

Returns current datetime.

Example: `Now()` could have returned `2015-11-10T12:15:00.000+01:00`.

#### Today¶

`Today():DATE`

Returns the current date.

Example: `Today()` could have returned `2015-11-10`.

#### Weekday¶

`Weekday(datetime):NUMERIC`

Returns a number (1 to 7) representing the day of the week.

Example: `weekday(2016-02-09T12:15:00.000+01:00)` returns `3`.

#### Year¶

`Year(datetime):NUMERIC`

Returns the year part of a datetime.

Example: `Year(2016-02-09T12:15:00.000+01:00)` returns `2016`.

`YearAdd(datetime, years_to_add):DATE`

Returns the datetime plus the number of years.

Example: `YearAdd(2016-02-09T12:15:00.000+01:00, 1)` returns `2017-02-09T12:15:00.000+01:00`.

#### YearDiff¶

`YearDiff(datetime1, datetime2):NUMERIC`

Returns the amount of full years between two dates.

Example: `YearDiff(2016-02-09T12:15:00.000+01:00, 2017-02-09T12:15:00.000+01:00)` returns `1`.

### List operations¶

#### Append¶

`Append(list, element): LIST`

Adds the element to a copy of the provided list. Returns the manipulated copy.

Example: `Append([2.5, 5.8, 4.3], 6.7)` returns `[2.5, 5.8, 4.3, 6.7]`.

#### AppendAll¶

`AppendAll(list1, list2): LIST`

Adds all elements from the second provided list to a copy of the first one. Returns the manipulated copy.

Example: `AppendAll([2.5, 5.8, 4.3], [2.1, 3.5, 7.4])` returns `[2.5, 5.8, 4.3, 2.1, 3.5, 7.4]`.

#### Zip¶

`Zip(attributes, values1, ..., valuesN): LIST`

Assembles a list of objects out of a list of attributes and multiple lists of values.

Example: `Zip(["id", "value"], [23a3e98, c45da1b], [40, 120])` returns `[{id: 23a3e98, value: 40},{ id: c45da1b, value: 120}]`.

Important

Before version 10.11.0 of the Decision Manager, the values were passed to the function as a list of lists, for example:

`Zip(["id", "value"], [[23a3e98, c45da1b], [40, 120]])`

Literal expressions that used the old `Zip` function have been automatically transformed to the new syntax.

#### NotContainsAny¶

`NotContainsAny(list1, list2): BOOLEAN`

Determines whether `list1` contains any element of `list2`.

Example: `NotContainsAny(["item1", "item2"], ["item2", "item3"])` returns `false`.

#### ContainsOnly¶

`ContainsOnly(list1, list2): BOOLEAN`

Determines whether `list1` contains only elements of `list2`.

Example: `ContainsOnly(["item1", "item2"], ["item2", "item3"])` returns `false`.

#### AreElementsOf¶

`AreElementsOf(list1, list2): BOOLEAN`

Determines whether `list2` contains all elements of `list1`.

Example: `AreElementsOf(["item2, item3"], ["item1", "item2", "item3"])` returns `true`.

#### Remove¶

This expression is available only in the Literal Expressions Editor (not in the Decision Table Editor).

`Remove(list, element): LIST`

Removes the specified `element` from the specified `list`.

Example: `Remove(["item1", "item2"], "item1")` returns `["item2"]`.

#### RemoveAll¶

This expression is available only in the Literal Expressions Editor (not in the Decision Table Editor).

`RemoveAll(list1, list2): LIST`

Removes all elements of `list2` from `list1`.

Example: `Remove(["item1", "item2", "item3"], ["item1", "item2"])` returns `["item3"]`.

### Statistical operations¶

#### Avg¶

`Avg([number1, number2, number3]):NUMERIC`

Returns the average of the values of the given list.

Example: `Avg([3,5])` returns `4`.

#### Max¶

`Max([number1, number2, number3]):NUMERIC`

Returns the maximum value of the given list.

Example: `Max([5, 4, 10])` returns `10`.

#### Median¶

`Median([number1, number2, number3]):NUMERIC`

Returns the median value of the given list.

Example: `Median([2, 5, 10, 12, 34, 35])` returns `11`.

#### Min¶

`Min([number1, number2, number3]):NUMERIC`

Returns the minimum value of the given list.

Example: `Min([5, 4, 10])` returns `4`.

#### Mode¶

`Mode([number1, number2, number3]):NUMERIC`

Returns the most frequently occurring value of the given list. Returns the first (most left) most frequent value, if several values occur most frequently (e.g. two values appear each two times).

Example: `Mode([1, 2, 4, 4, 5, 6])` returns `4`.

### Text handling¶

#### Concat¶

`Concat([text1, text2, text3]):TEXT`

Returns the concatenation of the given list of text values.

Example: `Concat(["Hello ", "World", "!"])` returns `"Hello World!"`.

#### IsAlpha¶

`IsAlpha(text):BOOLEAN`

Determines whether the text contains only alphabetic characters (A-Z, a-z). Umlauts and similar characters (e.g. `Ä`, `Å` `ß`) must not be included.

Example: `IsAlpha("abcdefg5")` returns `false`.

#### IsAlphanumeric¶

`IsAlphanumeric(text):BOOLEAN`

Determines whether the text contains only alphanumeric characters (A-Z, a-z, 0-9). Umlauts and similar characters (e.g. `Ä`, `Å` `ß`) must not be included.

Example: `isAlphanumeric("abcdefg5")` returns `true`.

#### IsNumeric¶

`IsNumeric(text):BOOLEAN`

Determines whether the text is a valid number containing only plus or minus sign, digits, commas, and decimal points.

Example: `IsNumeric("2.3.5")` returns `false`

#### IsSpaces¶

`IsSpaces(text):BOOLEAN`

Determines whether the text contains only spaces.

Example: `IsSpaces("     ")` returns `true`.

#### Len¶

`Len(text):NUMERIC`

Returns the number of characters in a text string.

Example: `Len("five")` returns `4`.

#### Lower¶

`Lower(text):TEXT`

Returns the text string with all letters converted to lowercase.

Example: `Lower("UPPER")` returns `upper`.

#### Trim¶

`Trim(text):TEXT`

Returns the text string with all spaces removed except single spaces between words.

Example: `Trim("Hello         World! ")` returns `"Hello World!"`.

#### Upper¶

`Upper(text):TEXT`

Returns the text string with all letters converted to uppercase.

Example: `Upper("lower")` returns `"LOWER"`.

#### Number¶

`Number(text):NUMERIC`

Returns the numerical value represented in the text string. Only a period (`.`) is allowed as a separator.

Example: `Number("5")` returns `5`.

#### Number¶

`Number(text, default_value):NUMERIC`

Returns the numerical value represented in the text string. Only a period (`.`) is allowed as a separator. Returns `default_value` if unable to convert text into number.

Example: `Number("5,5", 10)` returns `10` (`Number("5.5", 10)` returns `5.5`).

#### Mid¶

`Mid(text, start, num_chars):TEXT`

Returns the character sequence of the length `num_chars` from the corresponding starting position of a text string.

Example: `Mid("Hello World!", 6, 5)` returns `"World"`.

#### Left¶

`Left(text, num_chars):TEXT`

Returns the character sequence of the length `num_chars` from the start of a text string.

Example: `Left("Hello World!", 5)` returns `"Hello"`.

#### Text¶

`Text(num, format_text):TEXT`

Returns a numeric value as a text string in a specific format. The format is specified by the placeholders `#` and `0` and a decimal point `.`.

Example: `Text(1, "#.000")` returns `"1.000"`.

#### TextOccurrences¶

`TextOccurrences(find_text, within_text):NUMERIC`

Returns the number of occurrences of `find_text` within `within_text`.

Example: `TextOccurrences("can", "Can you can a can as a canner can can a can?")` returns `6`.

#### Contains¶

`Contains(text, substring): BOOLEAN`

Determines whether `text``contains the ``substring`.

Example: `Contains("Hello World!", "o World")` returns `true`.

#### StartsWith¶

`StartsWith(text, prefix): BOOLEAN`

Determines whether `text``starts with the ``prefix`.

Example: `StartsWith("Hello World!", "Hello")` returns `true`.

#### EndsWith¶

`EndsWith(text, suffix): BOOLEAN`

Determines whether `text` ends with the `suffix`.

Example: `endsWith("Hello World!", "!")` returns `true`.

### Logical operators¶

#### Not¶

`Not(boolean): BOOLEAN`

Negates the input boolean.

Example: `Not(true)` returns `false`.