Open Editions

Open Editions

Come for answers. Stay for best practices. All we’re missing is you.

 View Only

DMN 1.6 comes to BAMOE 9.3.0: Enhancing Decision modeling standards

By Yeser Amer posted Mon September 29, 2025 01:00 AM

  

Article authors: @Yeser Amer, @Athira C and @Chinchu P Shaji


We’re delighted to announce support for the DMN 1.6 specification in BAMOE 9.3.0, reinforcing IBM’s roadmap and vision to provide end users with the latest features and experiences in DMN.

The official DMN 1.6 specification, including a comprehensive description of changes and new features, is available on the OMG DMN specification site1. In this article, we highlight the most notable changes that impact DMN end users.

1. A new expression language: B-FEEL

B-FEEL (Business Friendly Enough Expression Language) shares the same grammar as FEEL but alters the semantics to be friendlier to a business audience.

In FEEL, the null value is used to represent both missing data and an execution error.
In B-FEEL, null is used only to represent missing data. All operations and built-in functions that return null in FEEL when an error occurs have their semantics modified in B-FEEL to return a non-null value.
FEEL remains the default expression language in DMN 1.6.
To switch to the B-FEEL, manually update the expression language in the Global properties panel:



In detail, the new B-FEEL expression language differs from FEEL in the following points:

  1. Operator and built-in functions returning a boolean

    Removing null as an error from the result of operators and built-in functions for boolean values makes B-FEEL a two-value logic (true and false) compared to the three-value logic of FEEL (true, false, and null).

    In B-FEEL, boolean operators ( =, <=, <, >, >=, not(), and, or, in, between ) always return a true or false result (never null) even when incompatible types are used in their expression.

    In B-FEEL, an incompatible type in a boolean expression is considered false, except for the not equal (!=) where it is considered true.
    An example:

Expression

FEEL

B-FEEL

"a" = 1

null

false

  1. Built-in functions returning a number

    Several FEEL built-in functions return a numeric result. In B-FEEL, those functions’ semantics are modified to return 0 everywhere FEEL would return null for them.

    In addition, the list functions that return a number (mean(), median(), product(), stddev(), sum()), except count(), ignore non-numeric parameters passed in their input list in B-FEEL.
    An example:

Expression

FEEL

B-FEEL

decimal("a", 0)

null

0

  1. Built-in functions returning a string

    Several FEEL built-in functions return a string result. Those methods’ semantics in B-FEEL are modified to return an empty string (“”) everywhere FEEL would return null for them.
    An example:

Expression

FEEL

B-FEEL

lower case(12)

null

“”

  1. Built-in functions returning a date and time, date and time

    Several FEEL built-in functions return a date and time, date, or time result. In B-FEEL, those functions’ semantics are modified to return January 1st of the year 1970 (1970-01-01T00:00:00+00:00) value (epoch) everywhere FEEL would return null for them.

    The default values are based on the return type:

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”)

Some examples:

Expression

FEEL

B-FEEL

time("a")

null

time(“00:00:00+00:00”)

date(null)

null

date(“1970-01-01”)

date an time(true)

null

date and time(“1970-01-01T00:00:00+00:00”)

  1. Built-in functions returning a duration

    Several FEEL built-in functions return a duration result. In B-FEEL, those functions’ semantics are modified to return a duration of 0 months (years and months durations) or 0 seconds (days and time duration) everywhere FEEL would return null for them.
    An example:

Expression

FEEL

B-FEEL

duration("a")
or
years and months duration(null, null)

null

duration(“P0M”)

  1. Built-in functions returning a collection

    Several FEEL built-in functions return collection results. In B-FEEL, those functions’ semantics are modified to return an empty collection everywhere FEEL would return null for them.

    The mode function additionally ignores non-numeric parameters passed in their input list in B-FEEL.
    Some examples:

Expression

FEEL

B-FEEL

split("abc", 22)

null

[]

mode([null,null,null, 1, 1,2])

null

[1]

  1. Built-in functions returning a range

    The FEEL built-in function range() returns a range result. In B-FEEL, that function’s semantics is modified to return an empty range that does not match anything ( (0..0) ), where in FEEL it would return null.
    An example:

Expression

FEEL

B-FEEL

range("x")

null

range(“(0..0)”)

  1. Semantics of addition and subtraction

    In B-FEEL, the semantics of addition and subtraction are modified when the types of e1 and e2 do not match.

    The following rules are added :

If type(e1) or type(e2) is …

e1 + e2 /  e1 - e2

string

The non-string value is converted to a string using the string B-FEEL function and the general semantics of addition and subtraction apply. Subtraction returns an empty string.

number

The non-number value is converted to a number using the number B-FEEL function and the general semantics of addition and subtraction apply.

date and time

The non-date and time value is converted to a duration using the duration B-FEEL function and the general semantics of addition and subtraction apply.

date

The non-date value is converted to a duration using the duration B-FEEL function and the general semantics of addition and subtraction apply.

time

The non-time value is converted to a duration using the duration B-FEEL function and the general semantics of addition and subtraction apply.

years and months duration 

The non-years and months duration value is converted to a duration using the duration B-FEEL function and the general semantics of addition and subtraction apply.

days and time duration

The non-days and time duration value is converted to a duration using the duration B-FEEL function and General semantics of addition and subtraction apply.


Some examples:

Expression

FEEL

B-FEEL

"Today is " + today()

null

"Today is 2020-01-01"

"The result is: " + 1

null

"The result is: 1"

  1. Semantics of multiplication and division

    In B-FEEL, the semantics of multiplication and division are modified when the types of e1 and e2 do not match.

    The following rules are added :

If type(e1) or type(e2) is …

e1 * e2 and e1 / e2

number

The non-number type is converted to a number using the number B-FEEL function and the general semantics of multiplication and division apply.

years and months duration 

The non-years and months duration type is converted to a number using the number B-FEEL function and general semantics of multiplication and division applies.

days and time duration

The non-days and time duration type is converted to a number using the number B-FEEL function and general semantics of multiplication and division apply.


Some examples:

Expression

FEEL

B-FEEL

22 * "a"

null

0

null / 22

null

0

duration("P1Y") * null

null

duration(“P0M”)

  1. Semantics of exponentiation

    The FEEL semantics of exponentiation are used and B-FEEL further specifies that each operand is converted to a number using the number B-FEEL function.

2. Simplified InputData Assignment Across Nested Imports

DMN 1.6 introduces a key enhancement that simplifies how InputData values are assigned across models with nested or transitive imports during model evaluation. In such cases, the value is now assigned only once. This means that even if multiple models refer to the same input data through different import paths, they will consistently share the same value.

Previously, when an InputData (like Person name) was imported multiple times through different paths (Model B imports Model A, Model C imports Model A), each import path required a separate, fully qualified assignment:

Model B.Model A.Person name = "value"

Model C.Model A.Person name = "value"

With DMN 1.6, this has been streamlined. Now, the same InputData can be assigned once, using its namespace, and that value is automatically propagated across all import paths:

Person name = "value"

This change promotes cleaner model definitions and reduces redundancy, especially in complex import hierarchies. The system ensures that all references to that input data—regardless of how deeply nested or imported—receive the same value.

Importantly, the previous behavior is still supported. Users can continue assigning values using fully qualified paths if needed. This ensures:

• Existing models remain functional without modification

• Users have the flexibility to choose the assignment style that best fits their use case

 

3. Configurable Error Handling Modes – Lenient and Strict

In this version, two distinct modes for managing errors during decision model evaluation have been introduced:

  • lenient: In this mode, if an error is detected during model evaluation, it is stored and the execution continues. If other errors occur, all of them are collected. At the end of the evaluation, all the errors will be reported.

  • strict: In this mode, the model evaluation halts upon detecting the first error, which will be the only reported error.

The default error handling mode is lenient.

This enhancement applies consistently across all DMN expressions, including FEEL expressions and built-in functions.

To change the error handling mode during model evaluation, go to the Run menu and switch to the chosen mode.

4. Deprecated type `time` with timezone :

In DMN 1.6, IANA Time Zone identifiers in time literals have been officially deprecated. This change was introduced to improve consistency and reduce ambiguity in time-only representations.
In detail:

  • Time literals using the format: "HH:mm:ss@Zone" (e.g., "14:30:00@Asia/Kolkata") are now deprecated.

  • Date and time literals using IANA zones are not deprecated.

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.

The effects of this deprecation are:

  • No breaking changes. Previous usage of the time with timezone is still working.

  • A warning when deprecated time literals are used will be thrown. The warning given in the current implementation is: Usage of 'time' with a timezone is deprecated in DMN 1.6. This usage may be removed in future versions.

  • Encourage migration to FEEL-compliant expressions.

5. New version of `date and time` conversion function

As part of the deprecation of the time type with a timezone previously described, DMN now includes a new conversion function:

date and time(date, time, timezone)

• date: A date or date-time value

• time: A time value without timezone

• timezone: A string representing either a timezone offset (e.g. "Z", "+05:30") or an IANA zone identifier (e.g. "America/Costa_Rica")

This function returns a full date-time value by combining the provided date and time, and applying the specified timezone.

Input

Result

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

6. New single-parameter number() function : 

A new number() function is now available in FEEL. Its main scope is to convert a string-type input to a number type, if compatible.

  • If input is a number, it returns the number unchanged.
    Example: number(10) = 10

  • If input is a String, it attempts to parse it into a numeric value.

  • Examples: 

    • number("1.1") = 1.1

    • number("test") will return null and trigger an error

 

7. New "value" property for types `date`, `date and time`, `years and months duration`, `days and time duration`

A new value property is defined in the following types: date, date and time, years and months duration, and days and time duration.

The actual returned value depends on the field's type. In details:

  • date: Converts a calendar date to a date time value in which the time of day is UTC midnight (00:00:00).
    Example:
    date(2025, 7, 3).value → BigDecimal.valueOf(1751500800)

  • time: Converts a time of day to be represented as the number of seconds since midnight.
    Example: time("01:01:01").value → BigDecimal.valueOf(3661)

  • date and time: A date and time that has a UTC form can be represented as the number of seconds since a reference date and time, called the epoch.
    Example: date and time("2025-07-03T01:01:01Z").value → BigDecimal.valueOf(1751536861)

  • days and time duration: The value of a days and time duration can be expressed as the number of seconds.
    Example: duration("P1DT1H").value → BigDecimal.valueOf(90000)

  • years and months duration: The value of a years and months duration can be expressed as the number of months.
    Example: duration("P1Y1M").value → BigDecimal.valueOf(13)

8. New descendant operator

A descendant operator has been introduced to enhance the expressiveness of FEEL when working with nested contexts. This operator allows for recursively access to all values associated with a given property name, regardless of how deeply nested they are within a context structure.

For example, given the context:

{ a: { b: { b: 1 } } }

Using the descendant operator to access b:

{ a: { b: { b: 1 } } }...b

This expression returns:

[ { b: 1 }, 1 ]


This means it collects all instances of the key b
found at any level of nesting and returns them as a list. This is particularly useful for querying deeply structured data without needing to explicitly traverse each level.

9. Automatic type conversion from decimal to integer

DMN 1.6 introduces a new type conversion rule that enables automatic conversion from decimal numbers to integers in integer-required contexts. This enhancement ensures consistent behavior across decision models where integer values are expected, even if the input is a decimal.

This conversion is not rounded—the decimal portion is simply truncated, preserving the integer part of the number.

The following examples illustrate how the new type conversion behaves when applied in integer-required contexts.

  • Decimal input: 42.99999 → 42

  • Integer input: 42 → 42

  • Long Inputs: 423L → 423

  • Non-Numeric Input: 123" → No conversion applied

  • Null Input: null → No conversion applied

10. Single-parameter version of all rounding functions

DMN 1.6 introduces single-parameter versions of all rounding functions in FEEL. These new variants simplify usage by assuming a default scale of 0, delivering more intuitive and streamlined rounding logic and aligning FEEL functions with real-world expectations and simplifying decision logic for modellers.

Function Name

Example Input

Expected 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

 



References:

[1] https://www.omg.org/spec/DMN

0 comments
33 views

Permalink