diff --git a/kie-dmn/FEELbuiltinfunctions.adoc b/kie-dmn/FEELbuiltinfunctions.adoc
new file mode 100644
index 00000000000..09e4a532ecb
--- /dev/null
+++ b/kie-dmn/FEELbuiltinfunctions.adoc
@@ -0,0 +1,1596 @@
+// If changing name, location, and structure of this document, align with Docs team
+
+= 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 string` as specified by XML Schema Part 2 Datatypes, for example `2020-06-01`
+* `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 example `00:01:00@Etc/UTC`
+* `date time string` a composite of a `date string` followed by `T` and a `time string`, for example `2012-12-25T11: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 example `P1Y2M`
+
+=== date(from)
+
+Convert `from` to a `date`.
+
+.Parameters
+* `from` of type `string` of `date string` format
+
+.Examples
+[source,FEEL]
+----
+date("2012-12-25") - date("2012-12-24") = duration("P1D")
+----
+
+// ----------------------------------------------------------------------------
+
+=== date(from)
+
+Convert `from` to a `date`, setting time components to null.
+
+.Parameters
+* `from` of type `date and time`
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `year` of type `number`
+* `month` of type `number`
+* `day` of type `number`
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `date` of type `date` or `date and time`
+* `time` of type `time`
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `from` of type `string` of `date time string` format
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `from` of type `string` of `time string` format
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `from` of type `time` or `date and time`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `hour` of type `number`
+* `minute` of type `number`
+* `second` of type `number`
+* `offset` and optional parameter of type `days and time duration` or null
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `from` of type `string` 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
+
+.Examples
+[source,FEEL]
+----
+number("1 000,0", " ", ",") = number("1,000.0", ",", ".")
+----
+
+// ----------------------------------------------------------------------------
+
+=== string(from)
+
+Provide a string representation of the supplied parameter.
+
+.Parameters
+* `from` a non-null value
+
+.Examples
+[source,FEEL]
+----
+string(1.1) = "1.1"
+string(null) = null
+----
+
+// ----------------------------------------------------------------------------
+
+=== duration(from)
+
+Convert `from` to a `days and time` or `years and months duration`.
+
+.Parameters
+* `from` of type `string` of `duration string` format
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `from` of type `date` or `date and time`
+* `to` same type as above
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `negand` of type `boolean`
+
+.Examples
+[source,FEEL]
+----
+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`.
+
+.Parameters
+* `string` of type `string`
+* `start position` of type `number`
+* `length` optional parameter of type `number`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `string` of type `string`
+
+.Examples
+[source,FEEL]
+----
+string length("foo") = 3
+string length("\U01F40Eab") = 3
+----
+
+// ----------------------------------------------------------------------------
+
+=== upper case(string)
+
+Produce an upper case version of the string
+
+.Parameters
+* `string` of type `string`
+
+.Examples
+[source,FEEL]
+----
+upper case("aBc4") = "ABC4"
+----
+
+// ----------------------------------------------------------------------------
+
+=== lower case(string)
+
+Produce an lower case version of the string
+
+.Parameters
+* `string` of type `string`
+
+.Examples
+[source,FEEL]
+----
+lower case("aBc4") = "abc4"
+----
+
+// ----------------------------------------------------------------------------
+
+=== substring before(string, match)
+
+Calculates the substring before the match
+
+.Parameters
+* `string` of type `string`
+* `match` of type `string`
+
+.Examples
+[source,FEEL]
+----
+substring before("foobar", "bar") = "foo"
+substring before("foobar", "xyz") = ""
+----
+
+// ----------------------------------------------------------------------------
+
+=== substring after(string, match)
+
+Calculates the substring after the match
+
+.Parameters
+* `string` of type `string`
+* `match` of type `string`
+
+.Examples
+[source,FEEL]
+----
+substring after("foobar", "ob") = "ar"
+substring after("", "a") = ""
+----
+
+// ----------------------------------------------------------------------------
+
+=== replace(input, pattern, replacement, flags?)
+
+Calculates the regular expression replacement
+
+.Parameters
+* `input` of type `string`
+* `pattern` of type `string`
+* `replacement` of type `string`
+* `flags` optional parameter of type `string`
+
+NOTE: uses regular expression parameters as defined in XQuery 1.0 and XPath 2.0
+
+.Examples
+[source,FEEL]
+----
+replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") = "[1=ab][2=]cd"
+----
+
+// ----------------------------------------------------------------------------
+
+=== contains(string, match)
+
+Returns true if the string contains the match
+
+.Parameters
+* `string` of type `string`
+* `match` of type `string`
+
+.Examples
+[source,FEEL]
+----
+contains("foobar", "of") = false
+----
+
+// ----------------------------------------------------------------------------
+
+=== starts with(string, match)
+
+Returns true if the string starts with the match
+
+.Parameters
+* `string` of type `string`
+* `match` of type `string`
+
+.Examples
+[source,FEEL]
+----
+starts with("foobar", "fo") = true
+----
+
+// ----------------------------------------------------------------------------
+
+=== ends with(string, match)
+
+Returns true if the string ends with the match
+
+.Parameters
+* `string` of type `string`
+* `match` of type `string`
+
+.Examples
+[source,FEEL]
+----
+ends with("foobar", "r") = true
+----
+
+// ----------------------------------------------------------------------------
+
+=== matches(input, pattern, flags?)
+
+Returns true if the input matches the regular expression
+
+.Parameters
+* `input` of type `string`
+* `pattern` of type `string`
+* `flags` optional parameter of type `string`
+
+NOTE: uses regular expression parameters as defined in XQuery 1.0 and XPath 2.0
+
+.Examples
+[source,FEEL]
+----
+matches("foobar", "^fo*b") = true
+----
+
+// ----------------------------------------------------------------------------
+
+=== split(string, delimiter)
+
+Returns a list of the original string, splitted at the delimiter regexp pattern.
+
+.Parameters
+* `string` of type `string`
+* `delimiter` of type `string` for a regular expression pattern
+
+NOTE: uses regular expression parameters as defined in XQuery 1.0 and XPath 2.0
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `list` of type `list`
+* `element` of any type, including null
+
+.Examples
+[source,FEEL]
+----
+list contains([1,2,3], 2) = true
+----
+
+// ----------------------------------------------------------------------------
+
+=== count(list)
+
+Counts the element in the list
+
+.Parameters
+* `list` of type `list`
+
+.Examples
+[source,FEEL]
+----
+count([1,2,3]) = 3
+count([]) = 0
+count([1,[2,3]]) = 2
+----
+
+// ----------------------------------------------------------------------------
+
+=== min(list)
+
+Returns the minimum comparable element in the list
+
+.Parameters
+* `list` of type `list`
+
+.Alternative signature
+----
+min(e1, e2, ..., eN)
+----
+
+.Examples
+[source,FEEL]
+----
+min([1,2,3]) = 1
+min(1) = 1
+min([1]) = 1
+----
+
+// ----------------------------------------------------------------------------
+
+=== max(list)
+
+Returns the maximum comparable element in the list
+
+.Parameters
+* `list` of type `list`
+
+.Alternative signature
+----
+max(e1, e2, ..., eN)
+----
+
+.Examples
+[source,FEEL]
+----
+max(1,2,3) = 3
+max([]) = null
+----
+
+// ----------------------------------------------------------------------------
+
+=== sum(list)
+
+Returns the sum of the numbers in the list
+
+.Parameters
+* `list` of type `list` of `number` elements
+
+.Alternative signature
+----
+sum(n1, n2, ..., nN)
+----
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `list` of type `list` of `number` elements
+
+.Alternative signature
+----
+mean(n1, n2, ..., nN)
+----
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `list` of type `list` of `boolean` elements
+
+.Alternative signature
+----
+all(b1, b2, ..., bN)
+----
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `list` of type `list` of `boolean` elements
+
+.Alternative signature
+----
+any(b1, b2, ..., bN)
+----
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `list` of type `list`
+* `start position` of type `number`
+* `length` an optional parameter of type `number`
+
+.Examples
+[source,FEEL]
+----
+sublist([4,5,6], 1, 2) = [4,5]
+----
+
+// ----------------------------------------------------------------------------
+
+=== append(list, item...)
+
+Creates a list appended with the item(s)
+
+.Parameters
+* `list` of type `list`
+* `item` parameters of any type
+
+.Examples
+[source,FEEL]
+----
+append([1], 2, 3) = [1,2,3]
+----
+
+// ----------------------------------------------------------------------------
+
+=== concatenate(list...)
+
+Creates a list which is the result of the concatenated lists
+
+.Parameters
+* `list` parameters of type `list`
+
+.Examples
+[source,FEEL]
+----
+concatenate([1,2],[3]) = [1,2,3]
+----
+
+// ----------------------------------------------------------------------------
+
+=== insert before(list, position, newItem)
+
+Creates a list with the newItem inserted at the specified position
+
+.Parameters
+* `list` of type `list`
+* `position` of type `number`
+* `newItem` of any type
+
+.Examples
+[source,FEEL]
+----
+insert before([1,3],1,2) = [2,1,3]
+----
+
+// ----------------------------------------------------------------------------
+
+=== remove(list, position)
+
+Creates a list which the removed element from the specified position
+
+.Parameters
+* `list` of type `list`
+* `position` of type `number`
+
+.Examples
+[source,FEEL]
+----
+remove([1,2,3], 2) = [1,3]
+----
+
+// ----------------------------------------------------------------------------
+
+=== reverse(list)
+
+Returns a reversed list
+
+.Parameters
+* `list` of type `list`
+
+.Examples
+[source,FEEL]
+----
+reverse([1,2,3]) = [3,2,1]
+----
+
+// ----------------------------------------------------------------------------
+
+=== index of(list, match)
+
+Returns indexes matching the element
+
+.Parameters
+* `list` of type `list`
+* `match` of any type
+
+.Examples
+[source,FEEL]
+----
+index of([1,2,3,2],2) = [2,4]
+----
+
+// ----------------------------------------------------------------------------
+
+=== union(list...)
+
+Returns a list of all the elements from the lists without duplicates
+
+.Parameters
+* `list` parameters of type `list`
+
+.Examples
+[source,FEEL]
+----
+union([1,2],[2,3]) = [1,2,3]
+----
+
+// ----------------------------------------------------------------------------
+
+=== distinct values(list)
+
+Returns a list without duplicates
+
+.Parameters
+* `list` of type `list`
+
+.Examples
+[source,FEEL]
+----
+distinct values([1,2,3,2,1]) = [1,2,3]
+----
+
+// ----------------------------------------------------------------------------
+
+=== flatten(list)
+
+Returns a flattened list
+
+.Parameters
+* `list` of type `list`
+
+.Examples
+[source,FEEL]
+----
+flatten([[1,2],[[3]], 4]) = [1,2,3,4]
+----
+
+// ----------------------------------------------------------------------------
+
+=== product(list)
+
+Returns the product of the numbers in the list
+
+.Parameters
+* `list` of type `list` of `number` elements
+
+.Alternative signature
+----
+product(n1, n2, ..., nN)
+----
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `list` of type `list` of `number` elements
+
+.Alternative signature
+----
+median(n1, n2, ..., nN)
+----
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `list` of type `list` of `number` elements
+
+.Alternative signature
+----
+stddev(n1, n2, ..., nN)
+----
+
+.Examples
+[source,FEEL]
+----
+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.
+
+.Parameters
+* `list` of type `list` of `number` elements
+
+.Alternative signature
+----
+mode(n1, n2, ..., nN)
+----
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `n` of type `number`
+* `scale` of any `number` in the range ` [−6111..6176]`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+floor(1.5) = 1
+floor(-1.5) = -2
+----
+
+// ----------------------------------------------------------------------------
+
+=== ceiling(n)
+
+Returns the smallest integer greater or equal to the number
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+ceiling(1.5) = 2
+ceiling(-1.5) = -1
+----
+
+// ----------------------------------------------------------------------------
+
+=== abs(n)
+
+Returns the absolute value
+
+.Parameters
+* `n` of type `number`, `days and time duration` or `year and month duration`
+
+.Examples
+[source,FEEL]
+----
+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)`.
+
+.Parameters
+* `dividend` of type `number`
+* `divisor` of type `number`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+sqrt( 16 ) = 4
+----
+
+// ----------------------------------------------------------------------------
+
+=== log( number )
+
+Returns the natural logarithm of the number
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+decimal( log( 10 ), 2 ) = 2.30
+----
+
+// ----------------------------------------------------------------------------
+
+=== exp( number )
+
+Returns the Euler’s number e raised to the power of the number
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+decimal( exp( 5 ), 2 ) = 148.41
+----
+
+// ----------------------------------------------------------------------------
+
+=== odd( number )
+
+Returns true if the number is odd
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+odd( 5 ) = true
+odd( 2 ) = false
+----
+
+// ----------------------------------------------------------------------------
+
+=== odd( number )
+
+Returns true if the number is even
+
+.Parameters
+* `n` of type `number`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `value1` of any type
+* `value2` of any type
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. before(point1 point2)
+b. before(point range)
+c. before(range point)
+d. before(range1,range2)
+
+.Evaluates to true if and only if
+a. `point1 < point2`
+b. `point < range.start or (point = range.start and not(range.start included) )`
+c. `range.end < point or (range.end = point and not(range.end included) )`
+d. `range1.end < range2.start or (( not(range1.end included) or not(range2.start included)) and range1.end = range2.start)`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. after(point1 point2)
+b. after(point range)
+c. after(range, point)
+d. after(range1 range2)
+
+.Evaluates to true if and only if
+a. `point1 > point2`
+b. `point > range.end or (point = range.end and not(range.end included) )`
+c. `range.start > point or (range.start = point and not(range.start included) )`
+d. `range1.start > range2.end or (( not(range1.start included) or not(range2.end included) ) and range1.start = range2.end)`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. meets(range1, range2)
+
+.Evaluates to true if and only if
+a. `range1.end included and range2.start included and range1.end = range2.start`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. met by(range1, range2)
+
+.Evaluates to true if and only if
+a. `range1.start included and range2.end included and range1.start = range2.end`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. overlaps(range1, range2)
+
+.Evaluates to true if and only if
+a. `(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))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. overlaps before(range1 range2)
+
+.Evaluates to true if and only if
+a. `(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 )))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. overlaps after(range1 range2)
+
+.Evaluates to true if and only if
+a. `(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)))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. finishes(point, range)
+b. finishes(range1, range2)
+
+.Evaluates to true if and only if
+a. `range.end included and range.end = point`
+b. `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)))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. finished by(range, point)
+b. finished by(range1 range2)
+
+.Evaluates to true if and only if
+a. `range.end included and range.end = point`
+b. `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))))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. includes(range, point)
+b. includes(range1, range2)
+
+.Evaluates to true if and only if
+a. `(range.start < point and range.end > point) or (range.start = point and range.start included) or (range.end = point and range.end included)`
+b. `(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))))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. during(point, range)
+b. during(range1 range2)
+
+.Evaluates to true if and only if
+a. `(range.start < point and range.end > point) or (range.start = point and range.start included) or (range.end = point and range.end included)`
+b. `(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))))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. starts(point, range)
+b. starts(range1, range2)
+
+.Evaluates to true if and only if
+a. `range.start = point and range.start included`
+b. `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)))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. started by(range, point)
+b. started by(range1, range2)
+
+.Evaluates to true if and only if
+a. `range.start = point and range.start included`
+b. `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)))`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Signatures
+a. coincides(point1, point2)
+b. coincides(range1, range2)
+
+.Evaluates to true if and only if
+a. `point1 = point2`
+b. `range1.start = range2.start and range1.start included = range2.start included and range1.end = range2.end and range1.end included = range2.end included`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `date` of type `date` or `date and time`
+
+.Examples
+[source,FEEL]
+----
+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”
+
+.Parameters
+* `date` of type `date` or `date and time`
+
+.Examples
+[source,FEEL]
+----
+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”
+
+.Parameters
+* `date` of type `date` or `date and time`
+
+.Examples
+[source,FEEL]
+----
+month of year( date(2019, 9, 17) ) = "September"
+----
+
+// ----------------------------------------------------------------------------
+
+=== month of year( date )
+
+Returns the Gregorian week of the year accordingly to ISO 8601
+
+.Parameters
+* `date` of type `date` or `date and time`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `list` of type `list`
+* `precedes` of type `function`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `m` of type `context`
+* `key` of type `string`
+
+.Examples
+[source,FEEL]
+----
+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
+
+.Parameters
+* `m` of type `context`
+
+.Examples
+[source,FEEL]
+----
+get entries({key1 : "value1", key2 : "value2"}) = [ { key : "key1", value : "value1" }, {key : "key2", value : "value2"} ]
+----
+
+// ----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/kie-dmn/kie-dmn-feel/pom.xml b/kie-dmn/kie-dmn-feel/pom.xml
index e2a0efc57a2..d68ad8777b0 100644
--- a/kie-dmn/kie-dmn-feel/pom.xml
+++ b/kie-dmn/kie-dmn-feel/pom.xml
@@ -111,10 +111,27 @@
yasson
test
+
+ org.asciidoctor
+ asciidoctorj
+ test
+
+
+
+ ${project.basedir}/src/test/resources
+
+
+ ${project.basedir}/../
+
+ FEELbuiltinfunctions.adoc
+
+ false
+
+
org.apache.felix
diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/documentation/ADocFEELExamplesTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/documentation/ADocFEELExamplesTest.java
new file mode 100644
index 00000000000..3406db087ee
--- /dev/null
+++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/documentation/ADocFEELExamplesTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2020 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.kie.dmn.feel.documentation;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.OptionsBuilder;
+import org.asciidoctor.ast.Block;
+import org.asciidoctor.ast.ContentNode;
+import org.asciidoctor.ast.Document;
+import org.asciidoctor.ast.Section;
+import org.asciidoctor.ast.StructuralNode;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Test;
+import org.kie.dmn.feel.FEEL;
+import org.kie.dmn.feel.lang.FEELProfile;
+import org.kie.dmn.feel.parser.feel11.profiles.KieExtendedFEELProfile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ADocFEELExamplesTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ADocFEELExamplesTest.class);
+ private static final List profiles = new ArrayList<>();
+ {
+ profiles.add(new KieExtendedFEELProfile());
+ }
+ private final FEEL feel = FEEL.newInstance(profiles);
+
+ /**
+ * Dev notes: the availability of the .adoc resource to this test and its refresh is governed by Maven.
+ * You might want to execute this test from CLI if the IDE is not able handle the maven build refresh properly, for example as:
+ * $ mvn test -Dtest=org.kie.dmn.feel.documentation.ADocFEELExamplesTest
+ */
+ @Test
+ public void test() throws URISyntaxException {
+ Asciidoctor asciidoctor = Asciidoctor.Factory.create();
+ URL resource = this.getClass().getResource("/FEELbuiltinfunctions.adoc");
+ URI uri = resource.toURI();
+ LOG.debug("{}", uri);
+ File src = new File(uri);
+ Document loadFile = asciidoctor.loadFile(src, OptionsBuilder.options().asMap());
+ processBlock(loadFile);
+ }
+
+ private void processBlock(StructuralNode block) {
+ List blocks = block.getBlocks();
+
+ for (int i = 0; i < blocks.size(); i++) {
+ final StructuralNode currentBlock = blocks.get(i);
+ if (currentBlock instanceof StructuralNode) {
+ if ("listing".equals(currentBlock.getContext())) {
+ Block b = (Block) currentBlock;
+ List lines = b.getLines();
+ LOG.trace("{}", lines);
+ LOG.trace("{}", b.getAttributes());
+ ContentNode parent = b.getParent();
+ String sectionTitle = "";
+ if (parent instanceof Section) {
+ Section section = (Section) parent;
+ sectionTitle = section.getTitle();
+ }
+ if (b.getAttribute("language", "unknown").equals("FEEL")) {
+ for (String l : lines) {
+ String titled = sectionTitle + ": " + l;
+ LOG.info("checking DOC {}", titled);
+ Object FEELResult = feel.evaluate(l);
+ Assert.assertThat(titled, FEELResult, Matchers.is(true));
+ }
+ } else {
+ LOG.trace("This block is not FEEL true predicate snippets: {}", b);
+ }
+ } else {
+ processBlock(currentBlock);
+ }
+ }
+ }
+ }
+
+
+}