DMN conformance levels
The DMN specification defines three incremental levels of conformance in a software implementation. A product that claims compliance at one level must also be compliant with any preceding levels. For example, a conformance level 3 implementation must also include the supported components in conformance levels 1 and 2. For the formal definitions of each conformance level, see the OMG Decision Model and Notation (DMN) specification.
The following list summarizes the three DMN conformance levels:
- Conformance level 1
-
A DMN conformance level 1 implementation supports decision requirement diagrams (DRDs), decision logic, and Decision Tables, but decision models are not executable. Any language can be used to define the expressions, including natural, unstructured languages.
- Conformance level 2
-
A DMN conformance level 2 implementation includes the requirements in conformance level 1, and supports Simplified Friendly Enough Expression Language (S-FEEL) expressions and fully executable decision models.
- Conformance level 3
-
A DMN conformance level 3 implementation includes the requirements in conformance levels 1 and 2, and supports Friendly Enough Expression Language (FEEL) and The Business Friendly Enough Expression Language (B-FEEL) expressions, the full set of boxed expressions, and fully executable decision models.
IBM BAMOE provides runtime support for DMN 1.1, 1.2, 1.3, 1.4, 1.5 and 1.6 models at conformance level 3 and design support for DMN 1.2 with DMN Editor (classic), and 1.6 with the DMN Editor at conformance level 3. You can design your DMN models with BAMOE Canvas or BAMOE Developer Tools for VS Code, or import existing DMN models into your Business Service projects for deployment and execution. Any DMN models that you import and open in the DMN Editor, are converted to DMN 1.2 or 1.6 models.
The following table summarizes the design and runtime support for each DMN version in IBM BAMOE:
DMN version |
DMN engine support |
DMN Editor (classic) support |
DMN Editor support |
||
|---|---|---|---|---|---|
Execution |
Open |
Save |
Open |
Save |
|
DMN 1.1 |
|
|
|
|
|
DMN 1.2 |
|
|
|
|
|
DMN 1.3 |
|
|
|
|
|
DMN 1.4 |
|
|
|
|
|
DMN 1.5 |
|
|
|
|
|
DMN 1.6 |
|
|
|
|
|
In addition to all DMN conformance level 3 requirements, IBM BAMOE also includes enhancements and fixes to FEEL and DMN model components to optimize the experience of implementing DMN decision services with IBM BAMOE.
DMN decision requirements diagram (DRD) components
A decision requirements diagram (DRD) is a visual representation of your DMN model. A DRD can represent part or all of the overall decision requirements graph (DRG) for the DMN model. DRDs trace business decisions using decision nodes, business knowledge models, sources of business knowledge, input data, and decision services.
The following table summarizes the components in a DRD:
| Component | Description | Notation | |
|---|---|---|---|
Elements |
Decision |
Node where one or more input elements determine an output based on defined decision logic. |
|
Business knowledge model |
Reusable function with one or more decision elements. Decisions that have the same logic but depend on different sub-input data or sub-decisions use business knowledge models to determine which procedure to follow. |
|
|
Knowledge source |
External authorities, documents, committees, or policies that regulate a decision or business knowledge model. Knowledge sources are references to real-world factors rather than executable business rules. |
|
|
Input data |
Information used in a decision node or a business knowledge model. Input data usually includes business-level concepts or objects relevant to the business, such as loan applicant data used in a lending strategy. |
|
|
Decision service |
Top-level decision containing a set of reusable decisions published as a service for invocation. A decision service can be invoked from an external application or a BPMN business process. |
|
|
Requirement connectors |
Information requirement |
Connection from an input data node or decision node to another decision node that requires the information. |
|
Knowledge requirement |
Connection from a business knowledge model to a decision node or to another business knowledge model that invokes the decision logic. |
|
|
Authority requirement |
Connection from an input data node or a decision node to a dependent knowledge source or from a knowledge source to a decision node, business knowledge model, or another knowledge source. |
|
|
Artifacts |
Text annotation |
Explanatory note associated with an input data node, decision node, business knowledge model, or knowledge source. |
|
Association |
Connection from an input data node, decision node, business knowledge model, or knowledge source to a text annotation. |
|
|
The following table summarizes the permitted connectors between DRD elements:
| Starts from | Connects to | Connection type | Example |
|---|---|---|---|
Decision |
Decision |
Information requirement |
|
Business knowledge model |
Decision |
Knowledge requirement |
|
Business knowledge model |
|
||
Decision service |
Decision |
Knowledge requirement |
|
Business knowledge model |
|
||
Input data |
Decision |
Information requirement |
|
Knowledge source |
Authority requirement |
|
|
Knowledge source |
Decision |
Authority requirement |
|
Business knowledge model |
|
||
Knowledge source |
|
||
Decision |
Text annotation |
Association |
|
Business knowledge model |
|
||
Knowledge source |
|
||
Input data |
|
The following example DRD illustrates some of these DMN components in practice:
Rule expressions in FEEL
Friendly Enough Expression Language (FEEL) is an expression language defined by the Object Management Group (OMG) DMN specification. FEEL expressions define the logic of a decision in a DMN model. FEEL is designed to facilitate both decision modeling and execution by assigning semantics to the decision model constructs. FEEL expressions in decision requirements diagrams (DRDs) occupy table cells in boxed expressions for decision nodes and business knowledge models.
For more information about FEEL in DMN, see:
Data types in FEEL
Friendly Enough Expression Language (FEEL) supports the following data types:
|
Note
|
The DMN specification currently does not provide an explicit way of declaring a variable as a function, context, range, or list, but IBM BAMOE extends the DMN built-in types to support variables of these types.
|
The following list describes each data type:
- Numbers
-
Numbers in FEEL are based on the IEEE 754-2008 Decimal 128 format, with 34 digits of precision. Internally, numbers are represented in Java as
BigDecimalswithMathContext DECIMAL128. FEEL supports only one number data type, so the same type is used to represent both integers and floating point numbers.FEEL numbers use a dot (
.) as a decimal separator. FEEL does not support-INF,+INF, orNaN. FEEL usesnullto represent invalid numbers.IBM BAMOE extends the DMN specification and supports additional number notations:
-
Scientific: You can use scientific notation with the suffix
e<exp>orE<exp>. For example,1.2e3is the same as writing the expression1.2*10**3, but is a literal instead of an expression. -
Hexadecimal: You can use hexadecimal numbers with the prefix
0x. For example,0xffis the same as the decimal number255. Both uppercase and lowercase letters are supported. For example,0XFFis the same as0xff. -
Type suffixes: You can use the type suffixes
f,F,d,D,l, andL. These suffixes are ignored.
-
- Strings
-
Strings in FEEL are any sequence of characters delimited by double quotation marks.
Example"John Doe"
- Boolean values
-
FEEL uses three-valued boolean logic, so a boolean logic expression may have values
true,false, ornull. - Dates
-
Date literals are not supported in FEEL, but you can use the built-in
date()function to construct date values. Date strings in FEEL follow the format defined in the XML Schema Part 2: Datatypes document. The format is"YYYY-MM-DD"whereYYYYis the year with four digits,MMis the number of the month with two digits, andDDis the number of the day.Example:
date( "2017-06-23" )
Date objects have time equal to
"00:00:00", which is midnight. The dates are considered to be local, without a timezone. - Time
-
Time literals are not supported in FEEL, but you can use the built-in
time()function to construct time values. Time strings in FEEL follow the format defined in the XML Schema Part 2: Datatypes document. The format is"hh:mm:ss[.uuu][(+-)hh:mm]"wherehhis the hour of the day (from00to23),mmis the minutes in the hour, andssis the number of seconds in the minute. Optionally, the string may define the number of milliseconds (uuu) within the second and contain a positive (+) or negative (-) offset from UTC time to define its timezone. Instead of using an offset, you can use the letterzto represent the UTC time, which is the same as an offset of-00:00. If no offset is defined, the time is considered to be local.Examples:
time( "04:25:12" ) time( "14:10:00+02:00" ) time( "22:35:40.345-05:00" ) time( "15:00:30z" )
Time values that define an offset or a timezone cannot be compared to local times that do not define an offset or a timezone.
- Date and time
-
Date and time literals are not supported in FEEL, but you can use the built-in
date and time()function to construct date and time values. Date and time strings in FEEL follow the format defined in the XML Schema Part 2: Datatypes document. The format is"<date>T<time>", where<date>and<time>follow the prescribed XML schema formatting, conjoined byT.Examples:
date and time( "2017-10-22T23:59:00" ) date and time( "2017-06-13T14:10:00+02:00" ) date and time( "2017-02-05T22:35:40.345-05:00" ) date and time( "2017-06-13T15:00:30z" )
Date and time values that define an offset or a timezone cannot be compared to local date and time values that do not define an offset or a timezone.
ImportantIf your implementation of the DMN specification does not support spaces in the XML schema, use the keyword dateTimeas a synonym ofdate and time. - Days and time duration
-
Days and time duration literals are not supported in FEEL, but you can use the built-in
duration()function to construct days and time duration values. Days and time duration strings in FEEL follow the format defined in the XML Schema Part 2: Datatypes document, but are restricted to only days, hours, minutes and seconds. Months and years are not supported.Examples:
duration( "P1DT23H12M30S" ) duration( "P23D" ) duration( "PT12H" ) duration( "PT35M" )
ImportantIf your implementation of the DMN specification does not support spaces in the XML schema, use the keyword dayTimeDurationas a synonym ofdays and time duration. - Years and months duration
-
Years and months duration literals are not supported in FEEL, but you can use the built-in
duration()function to construct days and time duration values. Years and months duration strings in FEEL follow the format defined in the XML Schema Part 2: Datatypes document, but are restricted to only years and months. Days, hours, minutes, or seconds are not supported.Examples:
duration( "P3Y5M" ) duration( "P2Y" ) duration( "P10M" ) duration( "P25M" )
ImportantIf your implementation of the DMN specification does not support spaces in the XML schema, use the keyword yearMonthDurationas a synonym ofyears and months duration. - Functions
-
FEEL has
functionliterals (or anonymous functions) that you can use to create functions. The DMN specification currently does not provide an explicit way of declaring a variable as afunction, but IBM BAMOE extends the DMN built-in types to support variables of functions.Example:
function(a, b) a + b
In this example, the FEEL expression creates a function that adds the parameters
aandband returns the result. - Contexts
-
FEEL has
contextliterals that you can use to create contexts. Acontextin FEEL is a list of key and value pairs, similar to maps in languages like Java. The DMN specification currently does not provide an explicit way of declaring a variable as acontext, but IBM BAMOE extends the DMN built-in types to support variables of contexts.Example:
{ x : 5, y : 3 }In this example, the expression creates a context with two entries,
xandy, representing a coordinate in a chart.In DMN 1.2, another way to create contexts is to create an item definition that contains the list of keys as attributes, and then declare the variable as having that item definition type.
The IBM BAMOE DMN API supports DMN
ItemDefinitionstructural types in aDMNContextrepresented in two ways:-
User-defined Java type: Must be a valid JavaBeans object defining properties and getters for each of the components in the DMN
ItemDefinition. If necessary, you can also use the@FEELPropertyannotation for those getters representing a component name which would result in an invalid Java identifier. -
java.util.Mapinterface: The map needs to define the appropriate entries, with the keys corresponding to the component name in the DMNItemDefinition.
-
- Ranges (or intervals)
-
FEEL has
rangeliterals that you can use to create ranges or intervals. Arangein FEEL is a value that defines a lower and an upper bound, where either can be open or closed. The DMN specification currently does not provide an explicit way of declaring a variable as arange, but IBM BAMOE extends the DMN built-in types to support variables of ranges.The syntax of a range is defined in the following formats:
range := interval_start endpoint '..' endpoint interval_end interval_start := open_start | closed_start open_start := '(' | ']' closed_start := '[' interval_end := open_end | closed_end open_end := ')' | '[' closed_end := ']' endpoint := expressionThe expression for the endpoint must return a comparable value, and the lower bound endpoint must be lower than the upper bound endpoint.
For example, the following literal expression defines an interval between
1and10, including the boundaries (a closed interval on both endpoints):[ 1 .. 10 ]
The following literal expression defines an interval between 1 hour and 12 hours, including the lower boundary (a closed interval), but excluding the upper boundary (an open interval):
[ duration("PT1H") .. duration("PT12H") )You can use ranges in Decision Tables to test for ranges of values, or use ranges in simple literal expressions. For example, the following literal expression returns
trueif the value of a variablexis between0and100:x in [ 1 .. 100 ]
- Lists
-
FEEL has
listliterals that you can use to create lists of items. Alistin FEEL is represented by a comma-separated list of values enclosed in square brackets. The DMN specification currently does not provide an explicit way of declaring a variable as alist, but IBM BAMOE extends the DMN built-in types to support variables of lists.Example:
[ 2, 3, 4, 5 ]
All lists in FEEL contain elements of the same type and are immutable. Elements in a list can be accessed by index, where the first element is
1. Negative indexes can access elements starting from the end of the list so that-1is the last element.For example, the following expression returns the second element of a list
x:x[2]
The following expression returns the second-to-last element of a list
x:x[-2]
Elements in a list can also be counted by the function
count, which uses the list of elements as the parameter.For example, the following expression returns
4:count([ 2, 3, 4, 5 ])
Variable and function names in FEEL
Unlike many traditional expression languages, Friendly Enough Expression Language (FEEL) supports spaces and a few special characters as part of variable and function names. A FEEL name must start with a letter, ?, or _ element. The unicode letter characters are also allowed. Variable names cannot start with a language keyword, such as and, true, or every. The remaining characters in a variable name can be any of the starting characters, as well as digits, white spaces, and special characters such as +, -, /, *, ', and ..
For example, the following names are all valid FEEL names:
-
Age
-
Birth Date
-
Flight 234 pre-check procedure
Several limitations apply to variable and function names in FEEL:
- Ambiguity
-
The use of spaces, keywords, and other special characters as part of names can make FEEL ambiguous. The ambiguities are resolved in the context of the expression, matching names from left to right. The parser resolves the variable name as the longest name matched in scope. You can use
( )to disambiguate names if necessary. - Spaces in names
-
The DMN specification limits the use of spaces in FEEL names. According to the DMN specification, names can contain multiple spaces but not two consecutive spaces.
In order to make the language easier to use and avoid common errors due to spaces, IBM BAMOE removes the limitation on the use of consecutive spaces. IBM BAMOE supports variable names with any number of consecutive spaces, but normalizes them into a single space. For example, the variable references
First Namewith one space andFirst Namewith two spaces are both acceptable in IBM BAMOE.IBM BAMOE also normalizes the use of other white spaces, like the non-breakable white space that is common in web pages, tabs, and line breaks. From a IBM BAMOE FEEL engine perspective, all of these characters are normalized into a single white space before processing.
- The keyword
in -
The keyword
inis the only keyword in the language that cannot be used as part of a variable name. Although the specifications allow the use of keywords in the middle of variable names, the use ofinin variable names conflicts with the grammar definition offor,everyandsomeexpression constructs.
B-FEEL vs FEEL
The Business Friendly Enough Expression Language (B-FEEL) is a variant of FEEL that retains its grammar but modifies its semantics to improve usability. B-FEEL eliminates ambiguity by using null solely to represent missing data, whereas FEEL uses null for both missing data and execution errors. B-FEEL redefines the behavior of operations and built-in functions that would return null in FEEL due to errors, ensuring they return non-null values instead.
To activate B-FEEL in a DMN model, modelers must set the expression language to https://www.omg.org/spec/DMN/20240513/B-FEEL/.
|
Note
|
Modelers can configure the expression language either globally or at the expression-specific level (for example, within a literalExpression). By default, the language is set to FEEL. When both global and expression-specific configurations exist, the engine prioritizes the expression-specific setting during evaluation.
|
The B-FEEL expression language differ from the FEEL by the following semantics:
B-FEEL simplifies boolean logic by removing null as a possible result from operators and built-in functions. It enforces a two-value logic system—true and false—instead of the three-value logic used in FEEL (true, false, and null).
Boolean operators such as =, ⇐, <, >, >=, not(), and, or, in, and between always return either true or false, even when the expression involves incompatible types. In these cases, B-FEEL treats the result as false, except for the != operator, which returns true.
The following examples demonstrate how B-FEEL evaluates boolean expressions:
| Expression | FEEL | B-FEEL |
|---|---|---|
"a" = 1 |
null |
false |
"a" < 1 |
null |
false |
"a" ⇐ null |
null |
false |
"a" > 1 |
null |
false |
null >= 1 |
null |
false |
not("a") |
null |
false |
true and "x" |
null |
false |
false or "x" |
null |
false |
"a" in [1..100] |
null |
false |
null between 1 and 100 |
null |
false |
"a" != 1 |
null |
true |
B-FEEL also modifies the behavior of boolean-returning built-in functions. Instead of returning null when encountering errors or incompatible types, these functions return false.
| Expression | FEEL | B-FEEL |
|---|---|---|
matches("bad pattern", "[0-9") |
null |
false |
before(date("2021-01-01"), null) |
null |
false |
all(true, "x", true) |
null |
false |
any(null) |
null |
false |
B-FEEL modifies the behavior of numeric-returning functions to improve reliability and consistency. Instead of returning null when encountering errors or incompatible input, these functions now return 0.
B-FEEL also adjusts list-based numeric functions—such as mean(), median(), product(), stddev(), and sum()—to ignore non-numeric values in their input lists. The count() function remains unchanged and includes all values, including null.
The following examples illustrate how B-FEEL handles numeric expressions compared to FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
decimal("a", 0) |
null |
0 |
round up("5.5", 0) |
null |
0 |
string length(22) |
null |
0 |
day of year("a") |
null |
0 |
count([1, null, 3]) |
3 |
3 |
sum([1, null, 3]) |
null |
4 |
sum([1, "1", 3]) |
null |
4 |
sum([]) |
null |
0 |
mean(["a"]) |
null |
0 |
mean([1, "a", 3]) |
null |
2 |
B-FEEL modifies string-returning functions to improve consistency and eliminate ambiguity. Instead of returning null when encountering errors or incompatible input, these functions now return an empty string ("").
The following examples show how B-FEEL handles string expressions compared to FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
lower case(12) |
null |
"" |
string(null) |
null |
"" |
day of week("a") |
null |
"" |
substring("a", "z") |
null |
"" |
B-FEEL modifies the behavior of functions that return date, time, or, date and time values. Instead of returning a 'null' when encountering errors or invalid input, these functions now return a default value based on the type. B-FEEL uses January 1st, 1970 as the standard fallback (epoch).
The engine applies the following default values:
| Type | Default Value |
|---|---|
Date and time |
date and time("1970-01-01T00:00:00+00:00") |
Date |
date("1970-01-01") |
Time |
time("00:00:00+00:00") |
The examples below show how B-FEEL handles expressions that would return null in FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
time("a") |
null |
time("00:00:00+00:00") |
date(null) |
null |
date("1970-01-01") |
date and time(true) |
null |
date and time("1970-01-01T00:00:00+00:00") |
B-FEEL modifies duration-returning functions to ensure consistent behavior. Instead of returning null when encountering invalid input or errors, these functions now return a default duration value.
-
For years and months durations, B-FEEL returns
duration("P0M"), representing zero months. -
For days and time durations, B-FEEL also returns
duration("P0M"), representing zero time.
The following examples illustrate how B-FEEL handles duration expressions compared to FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
duration("a") |
null |
duration("P0M") |
years and months duration(null, null) |
null |
duration("P0M") |
B-FEEL modifies the behavior of collection-returning functions to ensure predictable results. Instead of returning null when encountering invalid input or errors, these functions now return an empty collection ([]).
Additionally, B-FEEL updates the mode function to ignore non-numeric values in its input list, allowing it to compute results more reliably.
The following examples demonstrate how B-FEEL handles collection expressions compared to FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
split("abc", 22) |
null |
[] |
mode([null, null, null, 1, 1, 2]) |
null |
[1] |
B-FEEL modifies the behavior of the range() function to ensure consistent and predictable results. Instead of returning null when the input is invalid or incompatible, the function returns an empty range that matches no values—specifically, (0..0).
The following example illustrates how B-FEEL handles range expressions compared to FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
range("x") |
null |
range("(0..0)") |
In B-FEEL, the semantics of addition and subtraction are modified when the types of e1 and e2 do not match. B-FEEL applies these rules based on the type of either operand:
| Type (e1 or e2) | Expression (e1 + e2 / e1 - e2) |
|---|---|
String |
Converts the non-string value to a string using the string B-FEEL function. Applies general semantics. Subtraction returns an empty string. |
Number |
Converts the non-number value to a number using the number B-FEEL function. Applies general semantics. |
Date and Time |
Converts the non-date/time value to a duration using the duration B-FEEL function. Applies general semantics. |
Date |
Converts the non-date value to a duration using the duration B-FEEL function. Applies general semantics. |
Time |
Converts the non-time value to a duration using the duration B-FEEL function. Applies general semantics. |
Years and Months Duration |
Converts the non-duration value to a duration using the duration B-FEEL function. Applies general semantics. |
Days and Time Duration |
Converts the non-duration value to a duration using the duration B-FEEL function. Applies general semantics. |
The following examples illustrate how B-FEEL evaluates expressions differently from FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
"Today is " + today() |
null |
"Today is 2020-01-01" |
"The result is: " + 1 |
null |
"The result is: 1" |
5 + " minutes" |
null |
5 + " minutes" |
"This is " + null |
null |
"This is " |
1 + null |
null |
1 |
null - 6 |
null |
-6 |
date("2021-01-01") + 7 |
null |
7 |
"abc" - 2 |
null |
"" |
In B-FEEL, the semantics of multiplication and division are modified when the types of e1 and e2 do not match.
B-FEEL applies these rules based on the type of either operand:
| Type (e1 or e2) | Expression (e1 * e2 and e1 / e2) |
|---|---|
Number |
Converts the non-number value to a number using the number B-FEEL function. Applies general semantics. |
Years and Months Duration |
Converts the non-duration value to a number using the number B-FEEL function. Applies general semantics. |
Days and Time Duration |
Converts the non-duration value to a number using the number B-FEEL function. Applies general semantics. |
The following examples illustrate how B-FEEL evaluates multiplication and division differently from FEEL:
| Expression | FEEL | B-FEEL |
|---|---|---|
22 * "a" |
null |
0 |
null / 22 |
null |
0 |
duration("P1Y") * null |
null |
duration("P0M") |
B-FEEL uses FEEL semantics for exponentiation but ensures both operands are converted to numbers using the B-FEEL number function.
DMN 1.5 features
BAMOE version 9.1.x introduce support for DMN 1.5.
The following are the new features:
Before this version, it was not possible to use the following declaration:
-duration("PT1H")
Implemented the following specification:
| Definitions | Parameters | Behaviour | Examples |
|---|---|---|---|
list replace(list, position, newItem) list replace(list, match, newItem) |
list, number or boolean function(item, newItem), any element including null |
return new list with newItem replaced at position (if position is a number) or return a new list where newItem is replaced at all positions where the match function returned true |
list replace( [2, 4, 7, 8], 3, 6) = [2, 4, 6, 8] list replace ( [2, 4, 7, 8], function(item, newItem) item < newItem, 5) = [5, 5, 7, 8] |
An iteration context can either be an expression that returns a list of elements, or two expressions that return integers connected by "..".
Example of valid iteration contexts is:
[…]
@”2021-01-01”..@”2022-01-01”
Before this modification, it was not possible to import a DMN file into another DMN file, specifying an empty string in the name attribute for the import. With this feature, the following snippet become valid:
<semantic:import xmlns:drools="http://www.drools.org/kie/dmn/1.1"
xmlns:triso="http://www.trisotech.com/2015/triso/modeling"
importType="http://www.omg.org/spec/DMN1-2Alpha/20160929/MODEL"
namespace="http://www.trisotech.com/dmn/definitions/_f27bb64b-6fc7-4e1f-9848-11ba35e0df36"
name="" />
and all the definitions from the imported model get registered as belonging to the importing model.
In implicit type conversions, the data type is converted automatically without loss of information. There are several possible implicit type conversions:
-
[…] -
From date to date and time: When the type of the expression is date and the target type is date and time, the expression is converted to a date time value in which the time of day is UTC midnight (00:00:00).
Implemented the following specification:
| Definition | Behaviour |
|---|---|
useAlternativeInputDataShape: Boolean [0..1] |
If the DMNShape depicts an Input Data element then it is represented either using the paper sheet symbol, harmonized with BPMN and CMMN notations (true) or using the backwards compatible oval symbol (false). |
Implemented the following specification:
| Definition | Behaviour |
|---|---|
typeConstraint: UnaryTests [0..1] |
This attribute is a UnaryTests that restricts the values in the base type that are allowed in this ItemDefinition. In case of a collection, it directly constrains the collection and is not projected on the collection elements. |
These new feature allows an interesting use case, i.e. filtering a base type based on its value, and then filtering a collection of the above element based on size (or other attribute) of the collection itself.
Example
<dmn:itemDefinition label="tInterest" name="tInterest">
<dmn:typeRef>string</dmn:typeRef>
<dmn:typeConstraint>
<dmn:text>"Golf","Computer","Hockey","Jogging"</dmn:text>
</dmn:typeConstraint>
</dmn:itemDefinition>
<dmn:itemDefinition isCollection="true" label="tInterests" name="tInterests">
<dmn:typeRef>tInterest</dmn:typeRef>
<dmn:typeConstraint>
<dmn:text> count (?) = 1 </dmn:text>
</dmn:typeConstraint>
</dmn:itemDefinition>
|
Note
|
The allowedValues tag has been deprecated in the 1.5 DMN version.
|
For official DMN specifications, see the OMG Decision Model and Notation (DMN) specification.
DMN 1.6 features
The DMN Editor and execution engine support the following DMN 1.6 features:
B-FEEL supported as an expression language
The Decision Engine now supports B-FEEL (Business Friendly Enough Expression Language) as an expression language. B-FEEL shares the same grammar as FEEL but alters the semantics to be friendlier. For more information about the key differences in Expression Language, see the B-FEEL vs FEEL.
Simplified InputData assignment across nested imports
The DMN 1.6 enhancement simplifies how InputData values are assigned across models with nested or transitive imports. When an InputData element is reused across multiple models through different import paths, the engine now assigns its value only once. All models referencing the same InputData share the same value consistently, regardless of how deeply nested or imported the reference is.
Previously, each import path required a separate, fully qualified assignment. For example, consider the following import structure:
Model B.Model A.Person name = "value"
Model C.Model A.Person name = "value"
With DMN 1.6, this process is streamlined. You can now assign the value once using the namespace:
Person name = "value"
The engine automatically propagates this value across all import paths. This change promotes cleaner model definitions and reduces redundancy in complex import hierarchies. Instead of specifying values separately for each import path, modelers only need to define the value once, and the system ensures consistent assignment across all references.
Users can continue assigning values using fully qualified paths if needed. This ensures that existing models remain functional without modification and gives users the flexibility to choose the assignment style that best fits their use case.
Improve consistency and usability of boxed filter and boxed iterator expressions
The consistency and usability of boxed filter and boxed iterator expressions are improved in DMN 1.6. These updates ensure that expressions not explicitly returning collections are still processed correctly through implicit coercion into singleton lists.
In boxed filters, the expression in the top part must evaluate to a collection. If the expression returns a single value—such as a number or string—the engine implicitly converts it into a list containing that value. Similarly, in boxed iterators, the expression in the in row must also evaluate to a collection, and singleton values are automatically wrapped into lists.
Updated Collect hit policy behavior for DMN decision tables
The DMN 1.6 clarifies the behavior of the Collect hit policy in decision tables. When this policy is used, the engine either returns all matched rule outputs in arbitrary order or applies a simple aggregation function to them, depending on the presence of an operator.
If no operator is specified, the engine returns a list containing the output entries of all matched rules. If an operator is present, the engine applies the corresponding function to the list and returns a single aggregated value.
The supported operators and their behaviors are:
-
+(sum): returns the sum of all matched outputs -
<(min): returns the smallest value among the outputs -
>(max): returns the largest value among the outputs -
#(count): returns the number of matched outputs
This update also allows implicit conversion of single values into singleton lists, ensuring consistent behavior even when only one rule matches.
Deprecation of IANA Time Zone identifiers in time literals
In DMN 1.6 the use of IANA Time Zone identifiers in time-only literals is deprecated to improve consistency and reduce ambiguity in time representations. The format "HH:mm:ss@Zone" (for example, 14:30:00@Asia/Kolkata) is no longer recommended for use in time literals.
This change does not affect date and time literals that use IANA zones. The recommended approach is to use the FEEL function date and time(date, time, timezone) instead of relying on implicit parsing of time strings with zones. When deprecated time literals are used, the engine logs a warning.
This feature encourages migration to FEEL-compliant expressions and ensures more predictable and standards-aligned behavior in decision models.
Support single parameter invoke() method
The NumberFunction class now supports a single parameter invoke() method that dynamically handles both String and Number formats.
This improves the FEEL compliance and robustness, aligning with the OMG DMN RTF specification.
The engine returns the input unchanged if it is already a Number. If the input is a String, it attempts to parse it into a numeric value. For example, the engine converts "1.1" to a BigDecimal. If the string is invalid, such as "test" or "1 2 3", it returns null and triggers an error.
This enhancement simplifies decision logic by allowing flexible input handling while maintaining strict validation for non-numeric strings.
Single parameter versions of all rounding functions in FEEL
The DMN 1.6 introduces single-parameter versions of all rounding functions in FEEL. These variants simplify usage by assuming a default scale of 0, which aligns with intuitive expectations for whole-number rounding and streamlines decision logic for modelers.
The following functions are now supported with a single numeric argument:
| Function name | Example input | Example output |
|---|---|---|
round up(x) |
round up(5.5) |
6 |
round down(x) |
round down(5.5) |
5 |
round half up(x) |
round half up(5.5) |
6 |
round half down(x) |
round half down(5.5) |
5 |
Support type conversion from decimal to integer
The DMN 1.6 conversion rule automatically converts decimal numbers to integers in contexts where integer values are required. This rule ensures consistent behavior across decision models by aligning input types with expected output formats. The conversion truncates the decimal portion without rounding, preserving only the integer part of the number.
The engine converts the input to an integer if it is an instance of Number. If the input is not a Number, it returns the value unchanged. It discards the decimal part without applying rounding. This conversion applies automatically in all scenarios where an integer is expected, including integer-valued expressions, type-constrained variables, and FEEL function parameters that require integers.
For example, the engine converts 42.50, 42.009, and 42.99999 to 42 by discarding the decimal portion. For integer and long inputs (42 and 423L) it returns unchanged (42 and 423), as they are already integers. It does not apply conversion to "123" because the input is a string, and it ignores null values without producing a result.
The engine truncates numeric inputs to integers when required and safely bypasses non-numeric and null inputs, ensuring robust and predictable behavior in decision models.
Flexible referencing styles within a single DMN file
The DMN 1.6 permits two distinct styles for referencing decisions within a single DMN file, allowing modelers to structure decision logic modularly and reuse decision definitions across different contexts or files. The engine supports both external and local referencing styles. When referencing a decision within the same DMN file, modelers can use a local reference without a namespace URI, employing a fragment identifier (prefixed with #) to point to the decision by its ID. Alternatively, when referencing a decision defined in a separate DMN file, modelers can use an external reference with a namespace URI, including the full URI of the external file along with the decision’s ID fragment. The engine supports both referencing styles, ensuring flexibility and consistency in model authoring and referencing.
Support new version of date and time conversion function
DMN 1.6 includes a new conversion function- date and time(date, time, timezone). This function constructs a full date-time value by combining the provided date and time and applying the specified timezone.
| Input | Output |
|---|---|
date and time(date("2024-12-24"), time("23:59:00"), "Z") |
2024-12-24T23:59:00Z |
date and time(date("2024-12-24"), time("23:59:00"), "America/Costa_Rica") |
2024-12-24T23:59:00@America/Costa_Rica |
Configurable error handling modes
The DMN 1.6 introduces the following two distinct modes for managing errors during decision model evaluation:
-
lenient
-
strict
The error handling mode is configured during the initiation of the decision model evaluation, with lenient being the default mode. The default error handling mode is lenient.
In lenient error mode, the engine collects errors and continues execution, accumulating errors detected in child DRG Elements for the parent element.
In contrast, strict error mode halts model evaluation upon detecting the first error, reports the error, and returns null. This configured error handling mode also applies to the handling of errors during the evaluation of literal expressions, such as FEEL expressions, where built-in functions encountering input outside their defined domain report diagnostic information and return null.
New value property defined for variable types
In DMN 1.6, a new value property is defined in the following variable types:
-
date: Converts a calendar date into a date-time value where the time is set to UTC midnight. For example,
date(2025, 7, 3).valuereturnsBigDecimal.valueOf(1719028057). -
Time: Converts a specific time of day into the total number of seconds since midnight. For example,
time("01:01:01").valuereturnsBigDecimal.valueOf(3661). -
Date and time: Converts a full date and time in UTC format into the number of seconds since the epoch, which is a fixed reference point in time. This representation is commonly used for timestamping and time arithmetic. For example,
date and time("2025-07-03T01:01:01Z").valuereturnsBigDecimal.valueOf(1759449661). -
days and time duration: Converts a duration expressed in days and time into its equivalent number of seconds. For example,
duration("P1DT1H").valuereturnsBigDecimal.valueOf(90000). -
Years and months duration: Converts a duration expressed in years and months into its equivalent number of months. For example,
duration("P1Y1M").valuereturnsBigDecimal.valueOf(13).This property allows for the conversion of these types to a numeric value.
New Descendant Operator
The DMN 1.6 descendant operator to enhance the expressiveness of FEEL when working with nested contexts. This operator allows for the repetitive access of all values associated with a given property name, regardless of how deeply nested they are within a context structure. For example, given the following context:
{ a: { b: { b: 1 } } }
Using the descendant operator to access b:
{ a: { b: { b: 1 } } }...b
Returns the following expression:
[ { b: 1 }, 1 ]
The descendant operator collects all instances of the key b found at any level of nesting and returns them as a list.

