FEEL builtin functions
To promote interoperability, FEEL includes a library of builtin functions, described below. The builtin functions are implemented and available to be used in the Drools DMN engine; this document provides and overall description and helpful examples. The formal specification of these functions can be referenced in the original DMN Specification document from OMG.
Conversion functions
These functions support conversion between values of different types. Some specific string formats are used, such as:

date string
as specified by XML Schema Part 2 Datatypes, for example20200601

time string
either
as specified by XML Schema Part 2 Datatypes, for example
23:59:00z

a local time as specified by ISO 8601 followed by
@
and a IANA Timezone, for example00:01:00@Etc/UTC


date time string
a composite of adate string
followed byT
and atime string
, for example20121225T11:00:00Z

duration string
as a date time duration or year month duration as specified by the XQuery 1.0 and XPath 2.0 Data Model, for exampleP1Y2M
date(from)
Convert from
to a date
.

from
of typestring
ofdate string
format
date("20121225")  date("20121224") = duration("P1D")
date(from)
Convert from
to a date
, setting time components to null.

from
of typedate and time
date(date and time("20121225T11:00:00Z")) = date("20121225")
date(year, month, day)
Produce a date
from year, month and day values.

year
of typenumber

month
of typenumber

day
of typenumber
date(2012, 12, 25) = date("20121225")
date and time(date, time)
Produce a date and time
from the given date ignoring any time components and the given time.

date
of typedate
ordate and time

time
of typetime
date and time ("20121224T23:59:00") = date and time(date("20121224"), time("23:59:00"))
date and time(from)
Produce a date and time
from the given string.

from
of typestring
ofdate time string
format
date and time("20121224T23:59:00") + duration("PT1M") = date and time("20121225T00:00:00")
time(from)
Produce a time
from the given string.

from
of typestring
oftime string
format
time("23:59:00z") + duration("PT2M") = time("00:01:00@Etc/UTC")
time(from)
Produce a time
from the given parameter, ignoring any date components

from
of typetime
ordate and time
time(date and time("20121225T11:00:00Z")) = time("11:00:00Z")
time(hour, minute, second, offset?)
Produce a time
from the given hour, minute and second component values

hour
of typenumber

minute
of typenumber

second
of typenumber

offset
and optional parameter of typedays and time duration
or null
time("23:59:00z") = time(23, 59, 0, duration("PT0H"))
number(from, grouping separator, decimal separator)
Converts from
into a number
using the specified separators.

from
of typestring
representing a valid number 
grouping separator
one of space (`) or comma (
,) or period (
.`) or null 
decimal separator
as above, but different from the group separator, or also null
number("1 000,0", " ", ",") = number("1,000.0", ",", ".")
string(from)
Provide a string representation of the supplied parameter.

from
a nonnull value
string(1.1) = "1.1"
string(null) = null
duration(from)
Convert from
to a days and time
or years and months duration
.

from
of typestring
ofduration string
format
date and time("20121224T23:59:00")  date and time("20121222T03:45:00") = duration("P2DT20H14M")
duration("P2Y2M") = duration("P26M")
years and months duration(from, to)
Calculate the years and months duration between the two supplied parameters

from
of typedate
ordate and time

to
same type as above
years and months duration( date("20111222"), date("20130824") ) = duration("P1Y8M")
Boolean functions
Function for Boolean operations.
not(negand)
Perform the logical negation of the negand
operand.

negand
of typeboolean
not(true) = false
not(null) = null
String functions
Functions for string operations.
Note

in FEEL, Unicode characters are counted using their codepoints. 
substring(string, start position, length?)
Returns the substring from start position for the given length; the first character is at position value 1
.

string
of typestring

start position
of typenumber

length
optional parameter of typenumber
substring("foobar",3) = "obar"
substring("foobar",3,3) = "oba"
substring("foobar", 2, 1) = "a"
substring("\U01F40Eab", 2) = "ab"
Note

in FEEL the string literal "\U01F40Eab" is the 🐎ab string

string length(string)
Calculates the length of the string

string
of typestring
string length("foo") = 3
string length("\U01F40Eab") = 3
upper case(string)
Produce an upper case version of the string

string
of typestring
upper case("aBc4") = "ABC4"
lower case(string)
Produce an lower case version of the string

string
of typestring
lower case("aBc4") = "abc4"
substring before(string, match)
Calculates the substring before the match

string
of typestring

match
of typestring
substring before("foobar", "bar") = "foo"
substring before("foobar", "xyz") = ""
substring after(string, match)
Calculates the substring after the match

string
of typestring

match
of typestring
substring after("foobar", "ob") = "ar"
substring after("", "a") = ""
replace(input, pattern, replacement, flags?)
Calculates the regular expression replacement

input
of typestring

pattern
of typestring

replacement
of typestring

flags
optional parameter of typestring
Note

uses regular expression parameters as defined in XQuery 1.0 and XPath 2.0 
replace("abcd", "(ab)(a)", "[1=$1][2=$2]") = "[1=ab][2=]cd"
contains(string, match)
Returns true if the string contains the match

string
of typestring

match
of typestring
contains("foobar", "of") = false
starts with(string, match)
Returns true if the string starts with the match

string
of typestring

match
of typestring
starts with("foobar", "fo") = true
ends with(string, match)
Returns true if the string ends with the match

string
of typestring

match
of typestring
ends with("foobar", "r") = true
matches(input, pattern, flags?)
Returns true if the input matches the regular expression

input
of typestring

pattern
of typestring

flags
optional parameter of typestring
Note

uses regular expression parameters as defined in XQuery 1.0 and XPath 2.0 
matches("foobar", "^fo*b") = true
split(string, delimiter)
Returns a list of the original string, splitted at the delimiter regexp pattern.

string
of typestring

delimiter
of typestring
for a regular expression pattern
Note

uses regular expression parameters as defined in XQuery 1.0 and XPath 2.0 
split( "John Doe", "\\s" ) = ["John", "Doe"]
split( "a;b;c;;", ";" ) = ["a","b","c","",""]
List functions
Functions for list operations.
Note

in FEEL, the index of the first elements in a list is 1 , the index of the last element in a list cab also be identified as 1 .

list contains(list, element)
Returns true if the list contains the element

list
of typelist

element
of any type, including null
list contains([1,2,3], 2) = true
count(list)
Counts the element in the list

list
of typelist
count([1,2,3]) = 3
count([]) = 0
count([1,[2,3]]) = 2
min(list)
Returns the minimum comparable element in the list

list
of typelist
min(e1, e2, ..., eN)
min([1,2,3]) = 1
min(1) = 1
min([1]) = 1
max(list)
Returns the maximum comparable element in the list

list
of typelist
max(e1, e2, ..., eN)
max(1,2,3) = 3
max([]) = null
sum(list)
Returns the sum of the numbers in the list

list
of typelist
ofnumber
elements
sum(n1, n2, ..., nN)
sum([1,2,3]) = 6
sum(1,2,3) = 6
sum(1) = 1
sum([]) = null
mean(list)
Calculates the average (arithmetic mean) of the element in the list

list
of typelist
ofnumber
elements
mean(n1, n2, ..., nN)
mean([1,2,3]) = 2
mean(1,2,3) = 2
mean(1) = 1
mean([]) = null
all(list)
Returns true if and only if all elements in the list are true

list
of typelist
ofboolean
elements
all(b1, b2, ..., bN)
all([false,null,true]) = false
all(true) = true
all([true]) = true
all([]) = true
all(0) = null
any(list)
Returns true if any of the elements in the list is true

list
of typelist
ofboolean
elements
any(b1, b2, ..., bN)
any([false,null,true]) = true
any(false) = false
any([]) = false
any(0) = null
sublist(list, start position, length?)
Returns the sublist from start position, limited to length elements

list
of typelist

start position
of typenumber

length
an optional parameter of typenumber
sublist([4,5,6], 1, 2) = [4,5]
append(list, item…)
Creates a list appended with the item(s)

list
of typelist

item
parameters of any type
append([1], 2, 3) = [1,2,3]
concatenate(list…)
Creates a list which is the result of the concatenated lists

list
parameters of typelist
concatenate([1,2],[3]) = [1,2,3]
insert before(list, position, newItem)
Creates a list with the newItem inserted at the specified position

list
of typelist

position
of typenumber

newItem
of any type
insert before([1,3],1,2) = [2,1,3]
remove(list, position)
Creates a list which the removed element from the specified position

list
of typelist

position
of typenumber
remove([1,2,3], 2) = [1,3]
reverse(list)
Returns a reversed list

list
of typelist
reverse([1,2,3]) = [3,2,1]
index of(list, match)
Returns indexes matching the element

list
of typelist

match
of any type
index of([1,2,3,2],2) = [2,4]
union(list…)
Returns a list of all the elements from the lists without duplicates

list
parameters of typelist
union([1,2],[2,3]) = [1,2,3]
distinct values(list)
Returns a list without duplicates

list
of typelist
distinct values([1,2,3,2,1]) = [1,2,3]
flatten(list)
Returns a flattened list

list
of typelist
flatten([[1,2],[[3]], 4]) = [1,2,3,4]
product(list)
Returns the product of the numbers in the list

list
of typelist
ofnumber
elements
product(n1, n2, ..., nN)
product([2, 3, 4]) = 24
product(2, 3, 4) = 24
median( list )
Returns the median of the numbers in the list. After sorting the elements, in the case of an odd number of elements, the result is the middle element; in the case of even number of elements, the result is the average of the two middle elements.

list
of typelist
ofnumber
elements
median(n1, n2, ..., nN)
median( 8, 2, 5, 3, 4 ) = 4
median( [6, 1, 2, 3] ) = 2.5
median( [ ] ) = null
stddev( list )
Returns the sample standard deviation of the numbers in the list.

list
of typelist
ofnumber
elements
stddev(n1, n2, ..., nN)
stddev( 2, 4, 7, 5 ) = 2.081665999466132735282297706979931
stddev( [ 47 ] ) = null
stddev( 47 ) = null
stddev( [ ] ) = null
mode( list )
Returns the mode of the numbers in the list; in case of multiple elements, these are returned in their ascending order.

list
of typelist
ofnumber
elements
mode(n1, n2, ..., nN)
mode( 6, 3, 9, 6, 6 ) = [ 6 ]
mode( [6, 1, 9, 6, 1] ) = [ 1, 6 ]
mode( [ ] ) = [ ]
Numeric functions
Functions for number operations.
decimal(n, scale)
Returns number with the given scale

n
of typenumber

scale
of anynumber
in the range ` [−6111..6176]`
decimal(1/3, 2) = .33
decimal(1.5, 0) = 2
decimal(2.5, 0) = 2
floor(n)
Returns the greatest integer less or equal to the number

n
of typenumber
floor(1.5) = 1
floor(1.5) = 2
ceiling(n)
Returns the smallest integer greater or equal to the number

n
of typenumber
ceiling(1.5) = 2
ceiling(1.5) = 1
abs(n)
Returns the absolute value

n
of typenumber
,days and time duration
oryear and month duration
abs( 10 ) = 10
abs( 10 ) = 10
abs(@"PT5H") = @"PT5H"
abs(@"PT5H") = @"PT5H"
modulo( dividend, divisor )
Returns the remainder of the division of the dividend by divisor. In the case either dividend or divisor is negative, the result will be of the same sign as the divisor.
Note

this can be equivalently be exprssed as: modulo(dividend, divisor) = dividend  divisor*floor(dividen d/divisor) .


dividend
of typenumber

divisor
of typenumber
modulo( 12, 5 ) = 2
modulo(12,5)= 3
modulo(12,5)= 3
modulo(12,5)= 2
modulo(10.1, 4.5)= 1.1
modulo(10.1, 4.5)= 3.4
modulo(10.1, 4.5)= 3.4
modulo(10.1, 4.5)= 1.1
sqrt( number )
Returns the square root of the number

n
of typenumber
sqrt( 16 ) = 4
log( number )
Returns the natural logarithm of the number

n
of typenumber
decimal( log( 10 ), 2 ) = 2.30
exp( number )
Returns the Euler’s number e raised to the power of the number

n
of typenumber
decimal( exp( 5 ), 2 ) = 148.41
odd( number )
Returns true if the number is odd

n
of typenumber
odd( 5 ) = true
odd( 2 ) = false
odd( number )
Returns true if the number is even

n
of typenumber
even( 5 ) = false
even ( 2 ) = true
Date and time functions
Functions for date and time specific operations.
is(value1, value2)
Returns true if both values are the same element in the FEEL semantic domain

value1
of any type 
value2
of any type
is(date("20121225"), time("23:00:50")) = false
is(date("20121225"), date("20121225")) = true
is(time("23:00:50z"), time("23:00:50")) = false
Range functions
Temporal ordering functions to establish relationships between single scalar values and ranges of such values. These functions are heavily inspired by their equivalent in the HL7 CQL (Clinical Quality Language) standard version 1.4.
before()
A before B

before(point1 point2)

before(point range)

before(range point)

before(range1,range2)

point1 < point2

point < range.start or (point = range.start and not(range.start included) )

range.end < point or (range.end = point and not(range.end included) )

range1.end < range2.start or not(range1.end included) or not(range2.start included and range1.end = range2.start)
before( 1, 10 ) = true
before( 10, 1 ) = false
before( 1, [1..10] ) = false
before( 1, (1..10] ) = true
before( 1, [5..10] ) = true
before( [1..10], 10 ) = false
before( [1..10), 10 ) = true
before( [1..10], 15 ) = true
before( [1..10], [15..20] ) = true
before( [1..10], [10..20] ) = false
before( [1..10), [10..20] ) = true
before( [1..10], (10..20] ) = true
after()
A after B

after(point1 point2)

after(point range)

after(range, point)

after(range1 range2)

point1 > point2

point > range.end or (point = range.end and not(range.end included) )

range.start > point or (range.start = point and not(range.start included) )

range1.start > range2.end or (( not(range1.start included) or not(range2.end included) ) and range1.start = range2.end)
after( 10, 5 ) = true
after( 5, 10 ) = false
after( 12, [1..10] ) = true
after( 10, [1..10) ) = true
after( 10, [1..10] ) = false
after( [11..20], 12 ) = false
after( [11..20], 10 ) = true
after( (11..20], 11 ) = true
after( [11..20], 11 ) = false
after( [11..20], [1..10] ) = true
after( [1..10], [11..20] ) = false
after( [11..20], [1..11) ) = true
after( (11..20], [1..11] ) = true
meets()
A meets B

meets(range1, range2)

range1.end included and range2.start included and range1.end = range2.start
meets( [1..5], [5..10] ) = true
meets( [1..5), [5..10] ) = false
meets( [1..5], (5..10] ) = false
meets( [1..5], [6..10] ) = false
met by()
A met by B

met by(range1, range2)

range1.start included and range2.end included and range1.start = range2.end
met by( [5..10], [1..5] ) = true
met by( [5..10], [1..5) ) = false
met by( (5..10], [1..5] ) = false
met by( [6..10], [1..5] ) = false
overlaps()
A overlaps B

overlaps(range1, range2)

(range1.end > range2.start or (range1.end = range2.start and (range1.end included or range2.end included))) and (range1.start < range2.end or (range1.start = range2.end and range1.start included and range2.end included))
overlaps( [1..5], [3..8] ) = true
overlaps( [3..8], [1..5] ) = true
overlaps( [1..8], [3..5] ) = true
overlaps( [3..5], [1..8] ) = true
overlaps( [1..5], [6..8] ) = false
overlaps( [6..8], [1..5] ) = false
overlaps( [1..5], [5..8] ) = true
overlaps( [1..5], (5..8] ) = false
overlaps( [1..5), [5..8] ) = false
overlaps( [1..5), (5..8] ) = false
overlaps( [5..8], [1..5] ) = true
overlaps( (5..8], [1..5] ) = false
overlaps( [5..8], [1..5) ) = false
overlaps( (5..8], [1..5) ) = false
overlaps before()
A overlaps before B

overlaps before(range1 range2)

(range1.start < range2.start or (range1.start = range2.start and range1.start included and range2.start included)) and (range1.end > range2.start or (range1.end = range2.start and range1.end included and range2.start included)) and (range1.end < range2.end or (range1.end = range2.end and (not(range1.end included) or range2.end included )))
overlaps before( [1..5], [3..8] ) = true
overlaps before( [1..5], [6..8] ) = false
overlaps before( [1..5], [5..8] ) = true
overlaps before( [1..5], (5..8] ) = false
overlaps before( [1..5), [5..8] ) = false
overlaps before( [1..5), (1..5] ) = true
overlaps before( [1..5], (1..5] ) = true
overlaps before( [1..5), [1..5] ) = false
overlaps before( [1..5], [1..5] ) = false
overlaps after()
A overlaps after B

overlaps after(range1 range2)

(range2.start < range1.start or (range2.start = range1.start and range2.start included and not( range1.start included))) and (range2.end > range1.start or (range2.end = range1.start and range2.end included and range1.start included )) and (range2.end < range1.end or (range2.end = range1.end and (not(range2.end included) or range1.end included)))
overlaps after( [3..8], [1..5] )= true
overlaps after( [6..8], [1..5] )= false
overlaps after( [5..8], [1..5] )= true
overlaps after( (5..8], [1..5] )= false
overlaps after( [5..8], [1..5) )= false
overlaps after( (1..5], [1..5) )= true
overlaps after( (1..5], [1..5] )= true
overlaps after( [1..5], [1..5) )= false
overlaps after( [1..5], [1..5] )= false
overlaps after( (1..5), [1..5] )= false
overlaps after( (1..5], [1..6] )= false
overlaps after( (1..5], (1..5] )= false
overlaps after( (1..5], [2..5] )= false
finishes()
A finishes B

finishes(point, range)

finishes(range1, range2)

range.end included and range.end = point

range1.end included = range2.end included and range1.end = range2.end and (range1.start > range2.start or (range1.start = range2.start and (not(range1.start included) or range2.start included)))
finishes( 10, [1..10] ) = true
finishes( 10, [1..10) ) = false
finishes( [5..10], [1..10] ) = true
finishes( [5..10), [1..10] ) = false
finishes( [5..10), [1..10) ) = true
finishes( [1..10], [1..10] ) = true
finishes( (1..10], [1..10] ) = true
finished by()
A finished by B

finished by(range, point)

finished by(range1 range2)

range.end included and range.end = point

range1.end included = range2.end included and range1.end = range2.end and (range1.start < range2.start or (range1.start = range2.start and (range1.start included or not(range2.start included))))
finished by( [1..10], 10 ) = true
finished by( [1..10), 10 ) = false
finished by( [1..10], [5..10] ) = true
finished by( [1..10], [5..10) ) = false
finished by( [1..10), [5..10) ) = true
finished by( [1..10], [1..10] ) = true
finished by( [1..10], (1..10] ) = true
includes()
A includes B

includes(range, point)

includes(range1, range2)

(range.start < point and range.end > point) or (range.start = point and range.start included) or (range.end = point and range.end included)

(range1.start < range2.start or (range1.start = range2.start and (range1.start included or not(range2.start included)))) and (range1.end > range2.end or (range1.end = range2.end and (range1.end included or not(range2.end included))))
includes( [1..10], 5 ) = true
includes( [1..10], 12 ) = false
includes( [1..10], 1 ) = true
includes( [1..10], 10 ) = true
includes( (1..10], 1 ) = false
includes( [1..10), 10 ) = false
includes( [1..10], [4..6] ) = true
includes( [1..10], [1..5] ) = true
includes( (1..10], (1..5] ) = true
includes( [1..10], (1..10) ) = true
includes( [1..10), [5..10) ) = true
includes( [1..10], [1..10) ) = true
includes( [1..10], (1..10] ) = true
includes( [1..10], [1..10] ) = true
during()
A during B

during(point, range)

during(range1 range2)

(range.start < point and range.end > point) or (range.start = point and range.start included) or (range.end = point and range.end included)

(range2.start < range1.start or (range2.start = range1.start and (range2.start included or not(range1.start included)))) and (range2.end > range1.end or (range2.end = range1.end and (range2.end included or not(range1.end included))))
during( 5, [1..10] ) = true
during( 12, [1..10] ) = false
during( 1, [1..10] ) = true
during( 10, [1..10] ) = true
during( 1, (1..10] ) = false
during( 10, [1..10) ) = false
during( [4..6], [1..10] ) = true
during( [1..5], [1..10] ) = true
during( (1..5], (1..10] ) = true
during( (1..10), [1..10] ) = true
during( [5..10), [1..10) ) = true
during( [1..10), [1..10] ) = true
during( (1..10], [1..10] ) = true
during( [1..10], [1..10] ) = true
starts()
A starts B

starts(point, range)

starts(range1, range2)

range.start = point and range.start included

range1.start = range2.start and range1.start included = range2.start included and (range1.end < range2.end or (range1.end = range2.end and (not(range1.end included) or range2.end included)))
starts( 1, [1..10] ) = true
starts( 1, (1..10] ) = false
starts( 2, [1..10] ) = false
starts( [1..5], [1..10] ) = true
starts( (1..5], (1..10] ) = true
starts( (1..5], [1..10] ) = false
starts( [1..5], (1..10] ) = false
starts( [1..10], [1..10] ) = true
starts( [1..10), [1..10] ) = true
starts( (1..10), (1..10) ) = true
started by()
A started by B

started by(range, point)

started by(range1, range2)

range.start = point and range.start included

range1.start = range2.start and range1.start included = range2.start included and (range2.end < range1.end or (range2.end = range1.end and (not(range2.end included) or range1.end included)))
started by( [1..10], 1 ) = true
started by( (1..10], 1 ) = false
started by( [1..10], 2 ) = false
started by( [1..10], [1..5] ) = true
started by( (1..10], (1..5] ) = true
started by( [1..10], (1..5] ) = false
started by( (1..10], [1..5] ) = false
started by( [1..10], [1..10] ) = true
started by( [1..10], [1..10) ) = true
started by( (1..10), (1..10) ) = true
coincides()
A coincides B

coincides(point1, point2)

coincides(range1, range2)

point1 = point2

range1.start = range2.start and range1.start included = range2.start included and range1.end = range2.end and range1.end included = range2.end included
coincides( 5, 5 ) = true
coincides( 3, 4 ) = false
coincides( [1..5], [1..5] ) = true
coincides( (1..5), [1..5] ) = false
coincides( [1..5], [2..6] ) = false
Temporal functions
Functions for general temporal operations.
day of year( date )
Returns the Gregorian number of the day of the year

date
of typedate
ordate and time
day of year( date(2019, 9, 17) ) = 260
day of year( date )
Returns the Gregorian day of the week, either of “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”, “Sunday”

date
of typedate
ordate and time
day of week( date(2019, 9, 17) ) = "Tuesday"
month of year( date )
Returns the Gregorian month, either of “January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”

date
of typedate
ordate and time
month of year( date(2019, 9, 17) ) = "September"
month of year( date )
Returns the Gregorian week of the year accordingly to ISO 8601

date
of typedate
ordate and time
week of year( date(2019, 9, 17) ) = 38
week of year( date(2003, 12, 29) ) = 1
week of year( date(2004, 1, 4) ) = 1
week of year( date(2005, 1, 1) ) = 53
week of year( date(2005, 1, 3) ) = 1
week of year( date(2005, 1, 9) ) = 1
Sort function
Function for sorting operations.
sort(list, precedes)
Returns a list of the same elements but ordered accordingly to the sorting function

list
of typelist

precedes
of typefunction
sort(list: [3,1,4,5,2], precedes: function(x,y) x < y) = [1,2,3,4,5]
Context functions
Function for context operations.
get value(m, key)
Returns the value from the context, for the specified entry key

m
of typecontext

key
of typestring
get value({key1 : "value1"}, "key1") = "value1"
get value({key1 : "value1"}, "unexistentkey") = null
get entries(m)
Computes a list of key and value pair for the given context

m
of typecontext
get entries({key1 : "value1", key2 : "value2"}) = [ { key : "key1", value : "value1" }, {key : "key2", value : "value2"} ]