FEEL built-in functions
To promote interoperability, FEEL includes a library of built-in functions, described below. The built-in 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 stringas specified by XML Schema Part 2 Datatypes, for example2020-06-01 -
time stringeither-
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 stringa composite of adate stringfollowed byTand atime string, for example2012-12-25T11:00:00Z -
duration stringas 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.
-
fromof typestringofdate stringformat
date("2012-12-25") - date("2012-12-24") = duration("P1D")
date(from)
Convert from to a date, setting time components to null.
-
fromof typedate and time
date(date and time("2012-12-25T11:00:00Z")) = date("2012-12-25")
date(year, month, day)
Produce a date from year, month and day values.
-
yearof typenumber -
monthof typenumber -
dayof typenumber
date(2012, 12, 25) = date("2012-12-25")
date and time(date, time)
Produce a date and time from the given date ignoring any time components and the given time.
-
dateof typedateordate and time -
timeof typetime
date and time ("2012-12-24T23:59:00") = date and time(date("2012-12-24"), time("23:59:00"))
date and time(from)
Produce a date and time from the given string.
-
fromof typestringofdate time stringformat
date and time("2012-12-24T23:59:00") + duration("PT1M") = date and time("2012-12-25T00:00:00")
time(from)
Produce a time from the given string.
-
fromof typestringoftime stringformat
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
-
fromof typetimeordate and time
time(date and time("2012-12-25T11:00:00Z")) = time("11:00:00Z")
time(hour, minute, second, offset?)
Produce a time from the given hour, minute and second component values
-
hourof typenumber -
minuteof typenumber -
secondof typenumber -
offsetand optional parameter of typedays and time durationor 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.
-
fromof typestringrepresenting a valid number -
grouping separatorone of space (`) or comma (,) or period (.`) or null -
decimal separatoras 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.
-
froma non-null value
string(1.1) = "1.1"
string(null) = null
duration(from)
Convert from to a days and time or years and months duration.
-
fromof typestringofduration stringformat
date and time("2012-12-24T23:59:00") - date and time("2012-12-22T03: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
-
fromof typedateordate and time -
tosame type as above
years and months duration( date("2011-12-22"), date("2013-08-24") ) = duration("P1Y8M")
Boolean functions
Function for Boolean operations.
not(negand)
Perform the logical negation of the negand operand.
-
negandof 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.
-
stringof typestring -
start positionof typenumber -
lengthoptional 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
-
stringof typestring
string length("foo") = 3
string length("\U01F40Eab") = 3
upper case(string)
Produce an upper case version of the string
-
stringof typestring
upper case("aBc4") = "ABC4"
lower case(string)
Produce an lower case version of the string
-
stringof typestring
lower case("aBc4") = "abc4"
substring before(string, match)
Calculates the substring before the match
-
stringof typestring -
matchof typestring
substring before("foobar", "bar") = "foo"
substring before("foobar", "xyz") = ""
substring after(string, match)
Calculates the substring after the match
-
stringof typestring -
matchof typestring
substring after("foobar", "ob") = "ar"
substring after("", "a") = ""
replace(input, pattern, replacement, flags?)
Calculates the regular expression replacement
-
inputof typestring -
patternof typestring -
replacementof typestring -
flagsoptional 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
-
stringof typestring -
matchof typestring
contains("foobar", "of") = false
starts with(string, match)
Returns true if the string starts with the match
-
stringof typestring -
matchof typestring
starts with("foobar", "fo") = true
ends with(string, match)
Returns true if the string ends with the match
-
stringof typestring -
matchof typestring
ends with("foobar", "r") = true
matches(input, pattern, flags?)
Returns true if the input matches the regular expression
-
inputof typestring -
patternof typestring -
flagsoptional 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.
-
stringof typestring -
delimiterof typestringfor 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
-
listof typelist -
elementof any type, including null
list contains([1,2,3], 2) = true
count(list)
Counts the element in the list
-
listof typelist
count([1,2,3]) = 3
count([]) = 0
count([1,[2,3]]) = 2
min(list)
Returns the minimum comparable element in the list
-
listof 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
-
listof typelist
max(e1, e2, ..., eN)
max(1,2,3) = 3
max([]) = null
sum(list)
Returns the sum of the numbers in the list
-
listof typelistofnumberelements
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
-
listof typelistofnumberelements
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
-
listof typelistofbooleanelements
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
-
listof typelistofbooleanelements
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
-
listof typelist -
start positionof typenumber -
lengthan optional parameter of typenumber
sublist([4,5,6], 1, 2) = [4,5]
append(list, item…)
Creates a list appended with the item(s)
-
listof typelist -
itemparameters of any type
append([1], 2, 3) = [1,2,3]
concatenate(list…)
Creates a list which is the result of the concatenated lists
-
listparameters 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
-
listof typelist -
positionof typenumber -
newItemof 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
-
listof typelist -
positionof typenumber
remove([1,2,3], 2) = [1,3]
reverse(list)
Returns a reversed list
-
listof typelist
reverse([1,2,3]) = [3,2,1]
index of(list, match)
Returns indexes matching the element
-
listof typelist -
matchof 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
-
listparameters of typelist
union([1,2],[2,3]) = [1,2,3]
distinct values(list)
Returns a list without duplicates
-
listof typelist
distinct values([1,2,3,2,1]) = [1,2,3]
flatten(list)
Returns a flattened list
-
listof typelist
flatten([[1,2],[[3]], 4]) = [1,2,3,4]
product(list)
Returns the product of the numbers in the list
-
listof typelistofnumberelements
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.
-
listof typelistofnumberelements
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.
-
listof typelistofnumberelements
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.
-
listof typelistofnumberelements
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
-
nof typenumber -
scaleof anynumberin 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
-
nof typenumber
floor(1.5) = 1
floor(-1.5) = -2
ceiling(n)
Returns the smallest integer greater or equal to the number
-
nof typenumber
ceiling(1.5) = 2
ceiling(-1.5) = -1
abs(n)
Returns the absolute value
-
nof typenumber,days and time durationoryear 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).
|
-
dividendof typenumber -
divisorof 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
-
nof typenumber
sqrt( 16 ) = 4
log( number )
Returns the natural logarithm of the number
-
nof typenumber
decimal( log( 10 ), 2 ) = 2.30
exp( number )
Returns the Euler’s number e raised to the power of the number
-
nof typenumber
decimal( exp( 5 ), 2 ) = 148.41
odd( number )
Returns true if the number is odd
-
nof typenumber
odd( 5 ) = true
odd( 2 ) = false
odd( number )
Returns true if the number is even
-
nof 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
-
value1of any type -
value2of any type
is(date("2012-12-25"), time("23:00:50")) = false
is(date("2012-12-25"), date("2012-12-25")) = 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
-
dateof typedateordate 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”
-
dateof typedateordate 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”
-
dateof typedateordate 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
-
dateof typedateordate 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
-
listof typelist -
precedesof 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
-
mof typecontext -
keyof typestring
get value({key1 : "value1"}, "key1") = "value1"
get value({key1 : "value1"}, "unexistent-key") = null
get entries(m)
Computes a list of key and value pair for the given context
-
mof typecontext
get entries({key1 : "value1", key2 : "value2"}) = [ { key : "key1", value : "value1" }, {key : "key2", value : "value2"} ]