Appendix 5: AMDL Methods

Several of the variable types within AMDL have methods attached to them. All of the methods described below are case insensitive. For example, "some string".endsWithIgnoreCase("ING") is the same as "some string".endswithIgnorecase("ING") (see String.endsWithIgnoreCase(suffix)).

String Methods

The following group of methods can be applied to strings. If applied to something which isn't a string, the AMDL expression stops the evaluation. Implementation of these methods mostly follows the Apache commons-lang StringUtils public class (see https://commons.apache.org > StringUtils). Where details are not given, refer to the StringUtils documentation. Terms such as "lowercase" and "uppercase" are used according to the definitions given by the Unicode consortium (see https://docs.oracle.com > Characters).

This section is divided into:

  • General string methods (below);

  • Date-time methods for manipulating dates and date-times (see Date-time methods);

  • String similarity methods for calculating quantitative measures of string similarity (see String similarity);

  • Password methods for storing and checking hashed passwords (see Passwords)

  • Compression methods for compressing and decompressing strings (see Compression).

String.abbreviate(maxWidth)

Where there is a requirement to abbreviate long strings in code, strings can be of a length less than or equal to the provided maxWidth. If abbreviated, the method uses ellipses instead of the maxWidth.

Copy
rules.alwaysTrue:
"some string".abbreviate(11) == "some string" &&
"some string".abbreviate(7) == "some..."

String.capitalize()

If the first letter is alphabetical, it is capitalised, otherwise the method leaves the string alone. This is useful, for example, for matching text that is capitalised/not capitalised in a data feed.

Copy
rules.alwaysTrue:
"some_string".capitalize() == "Some_string" &&
"1some_string".capitalize() == "1some_string" &&
"Some_string".capitalize() == "Some_string"

String.center(size)

Centres a string inside a larger string of a size. Extra characters are evaluated by the method as spaces " ".

Copy
rules.alwaysTrue: "some string".center(15) == " some string "

String.charAt(n)

Returns the character at position n in the string (first character is at index 0).

Copy
rules.alwaysTrue: "some string".charat(5) == "s"

String.chomp()

Removes one newline from the end of the string if one exists, otherwise the method leaves the string alone.

Copy
rules.alwaysTrue:
"Some string
".chomp() == "Some string".chomp()

String.contains(substr)

Checks whether the substring substr is present within the string.

Copy
rules.alwaysTrue:
"some string".contains("str") == true &&
"some string".contains("foo") == false

String.containsIgnoreCase(substr)

Checks whether the substring substr is present within the string, irrespective of case.

Copy
rules.alwaysTrue:
"some string".containsIgnoreCase("STR") == true &&
"some string".containsIgnoreCase("FOO") == false

String.containsAnyChars(chars)

Checks whether any of the characters in the chars string are present in the string.

Copy
rules.alwaysTrue:
"some string".containsAnyChars("sr") == true &&
"some string".containsAnyChars("x1") == false

String.containsNoneChars(chars)

Checks that none of the characters in the chars string are present in the string. This method is the opposite of String.containsanychars(chars).

Copy
rules.alwaysTrue:
"some string".containsNoneChars("x1") == true &&
"some string".containsNoneChars("sr") == false

String.countMatches(substr)

Counts how many times the substring substr appears in the string.

Copy
rules.alwaysTrue: "some strange string".countMatches("tr") == 2

String.difference(string2)

Compares the string with string2 and returns the remainder of string2 from the point where the two strings differ.

Copy
rules.alwaysTrue:
"some string".difference("something else") == "thing else" &&
"some string".difference("string") == "tring" &&
"some string".difference("other") == "other"

String.endsWith(suffix)

Checks whether the string ends with the provided suffix.

Copy
rules.alwaysTrue: "some string".endsWith("ing") == true

String.endsWithIgnoreCase(suffix)

Checks whether the string ends with the provided suffix, irrespective of case.

Copy
rules.alwaysTrue: "some string".endsWithIgnoreCase("ING") == true

String.entropy()

Returns the ideal Shannon entropy of the string. The Shannon entropy is an information theory to measure the uncertainty of a random process.

Copy
rules.alwaysTrue: "fooBAR123".entropy() > 1
Copy
rules.alwaysTrue: "foofoofoo".entropy() < "fooBAR123".entropy()

String.equals(str)

Compares the string with the argument string, returning true if they represent identical sequences of characters.

Copy
rules.alwaysTrue: "some string".equals("some string") == true

String.equalsIgnoreCase(str)

Compares the string with the argument string, returning true if they represent equal sequences of characters, irrespective of case.

Copy
rules.alwaysTrue: "some string".equalsIgnoreCase("Some String") == true

String.format(args)

Requires the string to be a valid format string. The method then uses the arguments args in the format string according to Java.lang.String.format() (standard Java formatting, see https://docs.oracle.com: Java Development Kit version 11 API Specification).

If there are more arguments than format specifiers, the extra arguments are ignored. The number of arguments is variable and may be zero.

Copy
rules.alwaysTrue:
"a: %s, b: %s, c: %s".format("example",1,"???") == "a: example, b: 1, c:
???"

String.geodistance( lat1, long1, lat2, long2)

Returns the distance (in km) between two points on the Earth's surface specified by latitude and longitude (in degrees). This is where lat1 and long1 are the latitude and longitude of point 1, and lat2 and long2 are the latitude and longitude of point 2. The string that this method operates on is not used (you may simply use an empty string).

Copy
rules.alwaysTrue: "".geodistance(90, 0, -90, 0) == 20015.086796020572

String.isAllLowercase()

Checks if the string contains only lowercase letters.

Copy
rules.alwaysTrue:
"somestring".isAllLowercase() == true &&
"someString".isAllLowercase() == false &&
"some string".isAllLowercase() == false &&
"somestring1".isAllLowercase() == false

String.isAllUppercase()

Checks if the string contains only uppercase letters.

Copy
rules.alwaysTrue:
"SOMESTRING".isAllUppercase() == true &&
"SomeString".isAllUppercase() == false &&
"SOME STRING".isAllUppercase() == false &&
"SOMESTRING1".isAllUppercase() == false

String.isAlpha()

Checks if the string contains only Unicode letters.

Copy
rules.alwaysTrue: "SomeString".isAlpha() == true &&
"Some String1".isAlpha() == false

String.isAlphanumeric()

Checks if the string contains only Unicode letters or digits.

Copy
rules.alwaysTrue:
"SomeString1".isAlphanumeric() == true &&
"Some String1".isAlphanumeric() == false

String.isAlphanumericSpace()

Checks if the string contains only Unicode letters, digits, or spaces.

Copy
rules.alwaysTrue:
"Some String1".isAlphanumericSpace() == true &&
"Some String1&".isAlphanumericSpace() == false

String.isAlphaSpace()

Checks if the string contains only Unicode letters or spaces. This does not check for any digits in the string (unlike String.isAlphaSpace()).

Copy
rules.alwaysTrue:
"Some String".isAlphaSpace() == true &&
"Some String1".isAlphaSpace() == false

String.isAsciiPrintable()

Checks if the string contains only ASCII printable characters. ASCII printable characters are the 85 characters in ASCII format that can printed on paper or displayed on a screen.

Copy
rules.alwaysTrue: "Some ASCII".isAsciiPrintable() == true

String.isBlank()

Checks if the string is whitespace or empty. Note that, unlike StringUtils, null evaluation of the string results in non-evaluation of the rule.

Copy
rules.alwaysTrue:
"".isBlank() == true &&
" ".isBlank() == true &&
" some string".isBlank() == false

String.isEmpty()

Checks if the string is empty.

Copy
rules.alwaysTrue:
"".isEmpty() == true &&
" ".isEmpty() == false

String.isNotBlank()

Checks if the string is not empty and not whitespace only. This method is the opposite of String.isblank ().

Copy
rules.alwaysTrue:
" some string".isNotBlank() == true &&
" ".isNotBlank() == false &&
"".isNotBlank() == false

String.isNotEmpty()

Checks if the string is not empty. This method is the opposite of String.isempty().

Copy
rules.alwaysTrue:
" ".isNotEmpty() == true &&
"".isNotEmpty() == false

String.isNumeric()

Checks if the string contains only Unicode digits.

Copy
rules.alwaysTrue:
"123456".isNumeric() == true &&
"string123".isNumeric() == false

String.isNumericSpace()

Checks if the string contains only Unicode digits or spaces.

Copy
rules.alwaysTrue:
"123 456".isNumericSpace() == true &&
"string 123".isNumericSpace() == false

String.isWhitespace()

Checks if the string contains only whitespace.

Copy
rules.alwaysTrue:
"".isWhitespace() == true &&
" ".isWhitespace() == true &&
"some string".isWhitespace() == false

String.left(len)

Returns the leftmost len characters of the string.

Copy
rules.alwaysTrue: "some string".left(7) == "some st"

String.leftPad(n)

Left pad the string with spaces, up to a total length n.

Copy
rules.alwaysTrue: "abc".leftPad(6) = " abc"

String.length()

Returns the number of characters in the string.

Copy
rules.alwaysTrue: "some_string".length() == 11

String.lowercase()

Converts alphabetical characters in the string to lower case.

Copy
rules.alwaysTrue: "Mr. Smith".lowercase() == "mr. smith"

String.md5()

Returns the MD5 checksum of the string.

Copy
rules.alwaysTrue: "some str".md5() == "e05679f1d1deca304db99ce2cc19a7c9"

String.ngram(n, accepted_characters)

Implicitly normalises the string as described in String.normaliseChars(accepted_ characters), before returning a collection of possible n-grams contained within the normalised string.

Copy
rules.alwaysTrue: "FOOBAR123".ngram(3, "fba") ~# "fba"
Copy
rules.alwaysTrue:
"AbCdEaBcDe".ngram(2, "ace") == ["ac", "ce", "ea", "ac", "ce"]

String.normaliseChars(accepted_characters)

Converts alphabetical characters in the string to lower case. The method then removes any characters that are not in the argument string accepted_characters.

Copy
rules.alwaysTrue: "FOOBAR123".normaliseChars("for") == "foor"
Copy
rules.alwaysTrue: "AbCdE12345aBcDe".normaliseChars("abd31") == "abd13abd"

String.remove(substr)

Removes all appearances of the substring substr from the string.

Copy
rules.alwaysTrue: "some strange string".remove("tr") == "some sange sing"

String.removeEnd (substr)

Removes substring substr from the end of the string if it appears at the end.

Copy
rules.alwaysTrue: "starting string".removeEnd("ing") ==
"starting str"

String.removeEndIgnoreCase(substr)

Removes substring substr from the end of the string if it appears at the end, irrespective of case.

Copy
rules.alwaysTrue:
"starting string".removeEndIgnoreCase("ING") == "starting str"

String.removePattern(patt)

Removes each substring of the string that matches the given regular expression patt using dotall mode (matches any character, including line terminators).

Copy
rules.alwaysTrue: "some string".removePattern("[sgi]") == "ome
trn"

String.removePunctuation()

Removes punctuation characters from the string.

Copy
rules.alwaysTrue:
"!some.,punc{tu'ation?".removePunctuation() == "somepunctuation"

String.removeStart(substr)

Removes substring substr from the start of the string if it appears at the start.

Copy
rules.alwaysTrue: "starting string".removeStart("st") ==
"arting string"

String.removeStartIgnoreCase(substr)

Removes substring substr from the start of the string if it appears at the start, irrespective of case.

Copy
rules.alwaysTrue:
"starting string".removeStartIgnoreCase("ST") == "arting string"

String.repeat(n)

Repeats the string n times as in a new string.

Copy
rules.alwaysTrue: "abc".repeat(2) == "abcabc"

String.replace(a, b)

Replaces all occurrences of string a with string b.

Copy
rules.alwaysTrue: "abc".repeat(2) == "abcabc"

String.replacePattern(pat, rep)

Replaces each substring substr of the string that matches regular expression pat with the replacement rep using dotall mode (matches any character, including line terminators).

Copy
rules.alwaysTrue:
"some string".replacePattern("ing$", "obe") == "some strobe"

String.reverse()

Reverses the order of the characters in the string.

Copy
rules.alwaysTrue: "abcdefg".reverse() == "gfedcba"

String.reverseDelimited(delimiter)

Reverses a string separated by delimiter delimiter. The strings between the delimiters are not reversed.

Copy
rules.alwaysTrue: "a.b.c.d".reverseDelimited(".") == "d.c.b.a"

String.right(len)

Returns the rightmost len characters of the string.

Copy
rules.alwaysTrue: "some string".right(4) == "ring"

String.rightPad(n)

Right pad the string with spaces, up to a total length of n.

Copy
rules.alwaysTrue: "abc".rightPad(6) == "abc "

String.sha256()

Returns the SHA-256 hash of the string.

Copy
rules.alwaysTrue:
"some str".sha256() ==
"4ad27ac64e74640fbe5f24e205abdbf30effb67ddcced744ba05d8455cb7eb8a"

String.sequenceProbability(probabilities, accepted_characters)

Given a NxN probability matrix (such as a 2D array) and an accepted_characters string of length N, this method returns the Markov transition probability from the string. The NxN probability matrix is used for calculating outcomes based on the positions of a table. The Markov transition probability calculates future states based on transition from the current state.

Copy
rules.alwaysTrue:
"fooBAR123".sequenceProbability([[0.3, 0.7], [0.2, 0.4]], "fr") > 0.1

String.split(delimiter)

Splits the string by the delimiter delimiter into an ordered collection of strings.

Copy
rules.alwaysTrue: "some string".split("st") == [ "some,", "ring" ]

String.splitByChars(chars)

Splits the string by any of the specified characters chars into an ordered collection of strings.

Copy
rules.alwaysTrue:
"some string".splitByChars("si") == [ "ome ", "tr", "ng" ]

String.splitByCharacterType()

Splits the string by character type into an ordered collection of strings.

Copy
rules.alwaysTrue:
"string123!".splitByCharacterType() == [ "string", "123", "!" ]

String.splitByCharacterTypeCamelCase()

Splits the string by character type (including camel case words) into an ordered collection of strings.

Copy
rules.alwaysTrue:
"SStringString123".splitByCharacterTypeCamelCase() == [ "S", "String",
"String", "123" ]

String.startsWith(prefix)

Checks whether the string starts with the provided prefix.

Copy
rules.alwaysTrue: "some string".startsWith("som") == true

String.startsWithIgnoreCase(prefix)

Checks whether the string starts with the provided prefix, irrespective of case.

Copy
rules.alwaysTrue: "some string".startsWithIgnoreCase("SO") ==
true

String.strip()

Removes whitespace from the start and end of the string.

Copy
rules.alwaysTrue: " some string ".strip() == "some string"

String.stripAccents()

Removes diacritics from the string.

Copy
rules.alwaysTrue: "Et ça sera sa moitié.".stripAccents() == "Et
ca sera sa moitie."

String.stripCharsStart(chars)

Strips any of the provided characters chars from the start of the string.

Copy
rules.alwaysTrue: "some string".stripCharsStart("os") == "me
string"

String.stripCharsEnd(chars)

Strips any of the provided characters chars from the end of the string.

Copy
rules.alwaysTrue: "some string".stripCharsStart("os") == "me
string"

String.substring(start)

Returns the substring substr after index start.

Copy
rules.alwaysTrue: "abcdefghi".substring(3) == "defghi"

String.substring(start, end)

Returns the substring substr between indices start and end.

Copy
rules.alwaysTrue: "abcdefghi".substring(3, 7) == "defg"

String.substringAfter(sep)

Returns the substring substr after the first occurrence of the separator sep.

Copy
rules.alwaysTrue: "a.b.c".substringAfter(".") == "b.c"

String.substringAfterLast(sep)

Returns the substring substr after the last occurrence of the separator sep.

Copy
rules.alwaysTrue: "a.b.c".substringAfterLast(".") == "c"

String.substringBefore(sep)

Returns the substring substr before the first occurrence of the separator sep.

Copy
rules.alwaysTrue: "a.b.c".substringBefore(".") == "a"

String.substringBeforeLast(sep)

Returns the substring substr before the last occurrence of the separator sep.

Copy
rules.alwaysTrue: "a.b.c".substringBeforeLast(".") == "a.b"

String.substringBetween(arg1)

Returns the substring substr nested between the first two instances of arg1.

Copy
rules.alwaysTrue: "abcdefabcdef".substringBetween("ab") ==
"cdef"

String.substringBetween(arg1, arg2)

Returns the substring substr nested between the first instances of arg1 and arg2.

Copy
rules.alwaysTrue: "abcdefghi".substringBetween("bc", "h") ==
"defg"

String.swapCase()

Swaps the case of each string character, changing lower case characters to upper case and vice versa.

Copy
rules.alwaysTrue:
"a string".swapCase() == "A STRING" &&
"A STRING".swapCase() == "a string" &&
"a StRiNg".swapCase() == "A sTrInG"

String.trim()

Removes start and end characters below ASCII code 32 from the string.

Copy
rules.alwaysTrue: "some string ".trim() == "some string"

String.uncapitalize()

If the first letter of the string is alphabetical, it is changed to lower case, otherwise it is left alone.

Copy
rules.alwaysTrue: "Some string".uncapitalize() == "some string"

String.uppercase()

Converts alphabetical characters in the string to upper case.

Copy
rules.alwaysTrue: "Some string".uppercase() == "SOME STRING"

Date-time Methods

These methods can be used on strings which represent a timestamp. The methods accept an optional format argument, which defines the format of the string the method is acting on (and any date-time arguments) and how it should be parsed, as well as the format of any date-time output. Without this, ISO-8601 format and UTC is assumed. The format argument can be any of the following:

  • A format string using Java's DataTimeFormatter syntax (see https://docs.oracle.com: Java API Specification > DateTimeFormatter).

  • "iso8601" for ISO-8601 format.

  • "epoch" for a timestamp expressed as a number of milliseconds since the Unix epoch (midnight UTC on 1st Jan 1970).

  • "epochsec" for a timestamp expressed as a number of seconds since the Unix epoch.

String.isTimeAfter(time)

Returns true if the timestamp string is after the date-time time. The method otherwise returns false.

Copy
rules.alwaysTrue:
"2024-01-01T01:00:00Z".isTimeAfter( "2024-01-01T00:00:00Z" ) == true
Copy
rules.alwaysTrue:
"2024/01/01 01:00".isTimeAfter( "2024/01/01 00:00", "yyyy/MM/dd HH:mm" )
== true

String.isTimeBefore(time)

Returns true if the timestamp string is before the date-time time. The method otherwise returns false.

Copy
rules.alwaysTrue:
"2024-01-01T00:00:00Z".isTimeBefore( "2024-01-01T00:30:00Z" ) == true
Copy
rules.alwaysTrue:
"2024/01/01 00:00".isTimeBefore( "2024/01/01 00:10", "yyyy/MM/dd HH:mm" )
== true

String.timeAddMilli(ms)

Adds a number of millisecond to the timestamp string.

Copy
rules.alwaysTrue:
"2024/01/01 01:00".timeAddMili(100, "dd/MM/yy HH:mm:ss:SSS") == "01/01/24 00:00:00:100"

String.timeAddSec(s)

Adds a number of seconds to the timestamp string.

Copy
rules.alwaysTrue:
"2024/01/01 01:00".timeAddSec(10, "dd/MM/yy HH:mm:ss") == "01/01/24 00:00:10"

String.timeAddMin(mins)

Adds a number of minutes to the timestamp string.

Copy
rules.alwaysTrue:
"2024/01/01 01:00".timeAddMin(50) == "2024-01-01T01:50:00Z"

String.timeAddHour(hours)

Adds a number of hours to the timestamp string.

Copy
rules.alwaysTrue:
"2024/01/01 01:00".timeAddHour(12) == "2024-01-01T12:00:00Z"

String.timeAddDay(days)

Adds a number of days to the timestamp string.

Copy
rules.alwaysTrue:
"2024/01/01 01:00".timeAddDay(10, "dd/MM/yy HH:mm") == "11/01/24 00:00"

String.timeDiffMilli(time)

Returns the time between the timestamp string and the argument, in the units specified (rounded down to the nearest integer). This method is for miliseconds.

Copy
rules.alwaysTrue:
"01/01/24 00:00:00".timeDiffMili("01/01/24 00:00:00:100", "dd/MM/yy HH:mm:ss:SSS")
== 100

String.timeDiffSec(time)

Returns the time between the timestamp string and the argument, in the units specified (rounded down to the nearest integer). This method is for seconds.

Copy
rules.alwaysTrue:
"01/01/24 00:00:00".timeDiffSec("01/01/24 00:10:30", "dd/MM/yy HH:mm:ss")
== 630

String.timeDiffMin(time)

Returns the time between the timestamp string and the argument, in the units specified (rounded down to the nearest integer). This method is for minutes.

Copy
rules.alwaysTrue:
"01/01/24 00:00:00".timeDiffMin("01/01/24 00:05:00", "dd/MM/yy HH:mm:ss")
== 5

String.timeDiffHour(time)

Returns the time between the timestamp string and the argument, in the units specified (rounded down to the nearest integer). This method is for hours.

Copy
rules.alwaysTrue:
"2024-01-01T00:00:00Z".timeDiffhour("2024-01-05T12:00:00Z") == 108

String.timeDiffDay(time)

Returns the time between the timestamp string and the argument, in the units specified (rounded down to the nearest integer). This method is for days.

Copy
rules.alwaysTrue:
"2024/01/01 01:00".timeDiffDay("2024/01/10 01:00") == 10

String.timeFormat(format)

Returns the timestamp string, formatted according to the format string specified. If a second format string is specified, this represents the format of the timestamp string to be converted. Note that this format string has the same possible values as the optional format string that can be added to any of these date-time methods.

Copy
rules.alwaysTrue:
"2024-04-02T01:23:00Z".timeFormat("yyyy MM dd HH:mm") == "2024 Apr 2
01:23"
Copy
rules.alwaysTrue:
"2024/04/02 01:23".timeFormat("utc", "yyyy/MM/dd HH:mm") == "2024-04-
02T01:23:00Z"

String.timeGetMilli()

Gets the timestamp string in miliseconds.

Copy
rules.alwaysTrue:
"03:11:54:100 1 Jan 24".timeGetMili("HH:mm:ss:SSS d MMM yy") == 100

String.timeGetSec()

Gets the timestamp string in seconds.

Copy
rules.alwaysTrue:
"02:50:40 1 Jan 24".timeGetSec("HH:mm:ss d MMM yy") == 40

String.timeGetMin()

Gets the timestamp string in minutes.

Copy
rules.alwaysTrue:
"01:30:25 1 Jan 24".timeGetMin("HH:mm:ss d MMM yy") == 30

String.timeGetHour()

Gets the timestamp string in hours.

Copy
rules.alwaysTrue:
"2024-01-01T01:30:25Z".timeGetHour() == 1

String.timeGetDay()

Returns the millisecond, second, minute, hour and day part of the string timestamp.

Copy
rules.alwaysTrue:
"2024-01-11T01:30:25Z".timeGetDay() == 11

String.timeGetField()

Returns any of the standard set of Java temporal fields (see docs.oracle.com: Java API Specification > ChronoField) from the string timestamp.

Copy
rules.alwaysTrue:
"2024-04-02T01:23:45".timeGetField("DAY_OF_YEAR") == 92
Copy
rules.alwaysTrue:
"2024/04/02 01:23".timeGetField("DAY_OF_YEAR", "yyyy/MM/dd HH:mm") == 92

String.timeNow()

Returns the current time (using the format specified by the argument if provided —defaulting to ISO-8601). The string operated on has no effect on the return value, so the empty string can be used.

Copy
rules.trueOn10thApril2023: "".timeNow("d MMM yyyy") == "10 Apr
2023"

String.timeZoneChange(zone)

Returns the timestamp string, but with the time zone changed to the time zone zone.

Copy
rules.alwaysTrue:
"2023-04-02T01:23:00Z".timeZoneChange("+05:00") == "2023-04-
02T01:23:00+05:00"

String Similarity

String.cosineDistance(str)

Returns the cosine distance cosineDistance between the string and str. This is calculated as 1 which is the cosine similarity of the two strings, with each string represented as a set of 3-shingles (trigrams).

Copy
rules.alwaysTrue:
"Some string".cosineDistance("Another string") > 0.5 &&
"some string".cosineDistance("Some other string") < 0.32

String.cosineDistanceIgnoreCase(str)

Returns the cosine distance cosineDistance between the string and str, ignoring case.

Copy
rules.alwaysTrue:
"Some string".cosineDistanceIgnoreCase("Another string") > 0.5 &&
"Some string".cosineDistanceIgnoreCase("Some other string") < 0.32

String.jaccardIndexDistance(str)

Returns the Jaccard index distance jaccardIndexDistance between the string and str, calculated as 1 which is the Jaccard index for the two strings. Each string represented as a set of 3-shingles (trigrams).

Copy
rules.alwaysTrue:
"Some string".jaccardIndexDistance("Another string") > 0.68 &&
"Some string".jaccardIndexDistance("Some other string") <= 0.5

String.jaccardIndexDistanceIgnoreCase(str)

Returns the Jaccard index distance jaccardIndexDistance between the string and str, ignoring case. The Jaccard index is a statistic used for gauging the similarity and diversity of sample sets.

Copy
rules.alwaysTrue:
"SOME STRING".jaccardIndexDistanceIgnoreCase("Another string") > 0.68 &&
"SOME STRING".jaccardIndexDistanceIgnoreCase("Some other string") <= 0.5

String.jaroWinklerDistance(str)

Returns the Jaro-Winkler distance jaroWinklerDistance between the string and str, calculated as 1 which is the Jaro-Winkler similarity for the two strings. Jaro-Winkler is a string distance function used in statistics.

Copy
rules.alwaysTrue:
"Some string".jaroWinklerDistance("Another string") > 0.25 &&
"Some string".jaroWinklerDistance("Some other string") <= 0.25

String.jaroWinklerDistanceIgnoreCase(str)

Returns the Jaro-Winkler distance jaroWinklerDistance between the string and str, ignoring case.

Copy
rules.alwaysTrue:
"SOME STRING".jaroWinklerDistanceIgnoreCase("Another string") > 0.25 &&
"SOME STRING".jaroWinklerDistanceIgnoreCase("Some other string") <= 0.25

String.levenshtein(str)

Returns the Levenshtein levenshtein distance between the string and str.

Copy
rules.alwaysTrue: "Some String!".levenshtein("same sprung") == 6
rules.alwaysTrue: "Some String!".levenshtein("same sprung", true) == 0.5

String.levenshtein(str,normalised)

If normalised is true, returns the Levenshtein levenshtein distance between the string and str, normalised to [0-1] by dividing by the length of the longer of the two strings (the maximum possible value of the Levenshtein distance).

Copy
rules.alwaysTrue: "Some String!".levenshtein("same sprung") == 6
rules.alwaysTrue: "Some String!".levenshtein("same sprung", true) == 0.5

String.levenshteinIgnoreCase(str)

Returns the Levenshtein levenshtein distance between the string and str, ignoring character case. Levenshtein is a string distance function used for measuring the difference between two sequences.

Copy
rules.alwaysTrue: "Some String!".levenshteinIgnoreCase("same sprung!") == 3
rules.alwaysTrue: "Some String!".levenshteinIgnoreCase("same sprung!",
true) == 0.25

String.levenshteinIgnoreCase(str,normalised)

If normalised is true, returns the Levenshtein levenshtein distance between the string and str, ignoring character case and normalised to [0-1] as above.

Copy
rules.alwaysTrue: "Some String!".levenshteinIgnoreCase("same sprung!") == 3
rules.alwaysTrue: "Some String!".levenshteinIgnoreCase("same sprung!",
true) == 0.25

String.ratcliffObershelpDistance(str)

Returns the Ratcliff/Obershelp ratcliffObershelpDistance between the string and str, calculated as 1 which is the Ratcliff/Obershelp similarity of the two strings. Ratcliff/Obershelp is a string-matching algorithm for determining the similarity of two strings

Copy
rules.alwaysTrue:
"Some string".ratcliffObershelpDistance("Another string") > 0.25 &&
"Some string".ratcliffObershelpDistance("Some other string") <= 0.25

String.ratcliffObershelpDistanceIgnoreCase(str)

Returns the Ratcliff/Obershelp ratcliffObershelpDistance distance between the string and str, ignoring case.

Copy
rules.alwaysTrue:
"SOME STRING".ratcliffObershelpDistanceIgnoreCase("Another string") > 0.25
&&
"SOME STRING".ratcliffObershelpDistanceIgnoreCase("The string") <= 0.25

String.sorensenDiceDistance(str)

Returns the Sørensen-Dice distance sørensenDiceDistance between the string and str, calculated as 1, which is the Sørensen-Dice coefficient for the two strings. Each string represented as a set of 3- shingles (trigrams). Sorensen-Dice is a statistic used to gauge the similarity of two samples.

Copy
rules.alwaysTrue:
"Some string".sorensenDiceDistance("Another string") > 0.5 &&
"Some string".sorensenDiceDistance("Some other string") <= 0.35

String.sorensenDiceDistanceIgnoreCase(str)

Returns the Sørensen-Dice sørensenDiceDistance distance between the string and str, ignoring case.

Copy
rules.alwaysTrue:
"SOME STRING".sorensenDiceDistanceIgnoreCase("Another string") > 0.5 &&
"SOME STRING".sorensenDiceDistanceIgnoreCase("Some other string") <= 0.35

Passwords

String.hashPassword()

Returns the PBKDF2 hash of the string. Note that the result of this is different every time.

Copy
rules.alwaysTrue:
"mypassword".hashpassword() ==
"D7CV2UeshEN8C9Lw9U7GVw$q814S6B77dNj5DfhUeU10D4FQKR0ZkaVJw_cNN4oUz8"

String.checkPassword(arg)

Validates the supplied password against the hash argument.

Copy
rules.alwaysTrue:
"mypassword".checkpassword
("D7CV2UeshEN8C9Lw9U7GVw$q814S6B77dNj5DfhUeU10D4FQKR0ZkaVJw_cNN4oUz8") ==
true

Compression

String.compress()

Compresses the string using Java Deflator.

Copy
rules.alwaysTrue:
"long string [...]".compress() == "y8nPS1coLinKBFLRenp6sQA"

String.decompress()

Decompresses the string using Java Deflator.

Copy
rules.alwaysTrue:
"y8nPS1coLinKBFLRenp6sQA".decompress() == "long string [...]"

Number Methods

The following group of methods can be applied to numbers. If the method subject is not a number, expression evaluation will be stopped. Implementation of these methods mostly follows the Java Math library (see docs.oracle.com: Java Specifications > Math).

Number.abs()

Returns the absolute value of the number.

Copy
rules.alwaysTrue: -3.abs() == 3

Number.acos()

Returns the arc cosine of the value. The returned angle is in the range 0 - π.

Copy
rules.alwaysTrue: 1.acos() == 0

Number.asin()

Returns the arc sine of the value. The returned angle is in the range - π/2 - π /2.

Copy
rules.alwaysTrue: 0.asin() == 0

Number.atan()

Returns the arc tangent of a value. The returned angle is in the range -π /2 - π /2.

Copy
rules.alwaysTrue: 0.atan() == 0

Number.cbrt()

Returns the cube root of the number.

Copy
rules.alwaysTrue: 8.cbrt() == 2

Number.ceil()

Returns the smallest (closest to negative infinity) integer value that is greater than or equal to the number.

Copy
rules.alwaysTrue: 2.718.ceil() == 3

Number.cos()

Returns the trigonometric cosine of the value.

Copy
rules.alwaysTrue: 0.cos() == 1

Number.cosh()

Returns the hyperbolic cosine of the value.

Copy
rules.alwaysTrue: 0.cosh() == 1

Number.exp()

Returns Euler's number e raised to the power of the subject number.

Copy
rules.alwaysTrue: 0.exp() == 1

Number.expm1()

Returns Euler's number e raised to the power of the subject number minus one.

Copy
rules.alwaysTrue: 0.expm1() == 0

Number.floor()

Returns the largest (closest to positive infinity) integer value that is less than or equal to the number.

Copy
rules.alwaysTrue: 2.718.floor() == 2

Number.log()

Returns the natural logarithm of the number.

Copy
rules.alwaysTrue: 1.log() == 0

Number.log10()

Returns the logarithm (base 10) of the number.

Copy
rules.alwaysTrue: 100.log10() == 2

Number.max(n)

Returns the greater of the subject number and the argument n.

Copy
rules.alwaysTrue: 8.max(5) == 8

Number.min(n)

Returns the smaller of the subject number and the argument n.

Copy
rules.alwaysTrue: 8.min(5) == 5

Number.mod(n)

Returns the remainder when the subject number is divided by the argument n.

Copy
rules.alwaysTrue: 27.mod(5) == 2

Number.pow(n)

Raises the number to the power of n.

Copy
rules.alwaysTrue: 6.pow(2) == 36

Number.random()

Not recommended for use in production (see below).

Returns a random number greater than or equal to 0.0 and less than the subject number. The subject number must be positive.

Copy
rules.alwaysTrue: 5.random() < 5

Number.randomInt()

Not recommended for use in production (see below).

Returns a random integer greater than or equal to 0 and less than the subject number. The subject number must be positive.

Copy
rules.alwaysTrue: 5.randomint() < 5

Methods such as random() and randomint() that give non-deterministic results should only be used for testing, and not in production Business Rules. Non-deterministic methods can result in discrepancies between the real-time and asynchronous responses. This is because the output from the method is different when the event is processed synchronously to produce the real-time response, and when it is processed asynchronously by the fraud system.

Number.round(n)

Rounds the number to n decimal places. If no argument is specified, the method rounds to the nearest integer, with ties rounding up. If the number if already specified to less than n decimal places, the method returns the original number.

Copy
rules.alwaysTrue: 2.718.round() == 3

Number.signum()

Returns the signum function of the value, where:

Copy
rules.alwaysTrue: 6.signum() == 1

Number.sin()

Returns the trigonometric sine of the value.

Copy
rules.alwaysTrue: 0.sin() == 0

Number.sinh()

Returns the hyperbolic sine of the value.

Copy
rules.alwaysTrue: 0.sinh() == 0

Number.sqrt()

Returns the square root of the number.

Copy
rules.alwaysTrue: 25.sqrt() == 5

Number.tan()

Returns the trigonometric tangent of the value.

Copy
rules.alwaysTrue: 1.57.tan() > 1000

Number.tanh()

Returns the hyperbolic tangent of the value.

Copy
rules.alwaysTrue: 0.tanh() == 0

Number.toDegrees()

Converts the number from radians to degrees.

Copy
rules.alwaysTrue: 1.67.toDegrees() > 89

Number.toRadians()

Converts the number from degrees to radians.

Copy
rules.alwaysTrue: 89.toRadians() > 1.55

Collection Methods

AMDL supports some common collection methods as well as statistical methods:

Note that statistical methods cause the expression execution to stop if the collection contains non-numerical values.

In addition, there are some methods which can only be applied to ordered collections (see Ordered Collection Methods).

Common Collection Methods

Collection.concat(another_collection)

Returns an ordered collection consisting of the original collection with all elements of another_collection appended.

Copy
rules.alwaysTrue: {"method1", "method2"}.concat({"method2",>
"method3"}) == ["method1", "method2", "method2", "method3"]

Collection.difference(another_collection)

Returns an unordered collection consisting of all elements in the first collection not present in another_collection.

Copy
rules.alwaysTrue: {"method1", "method2"}.difference({"method2", "method3"})
== {"method1"}

Collection.intersection(another_collection)

Returns an unordered collection consisting of all elements present in both collections.

Copy
rules.alwaysTrue: {"method1", "method2"}.intersection({"method2",
"method3"}) == {"method2"}

Collection.isEmpty()

Checks whether there are any values in the collection.

Copy
rules.alwaysTrue: [ "something", "here" ].isempty() == false

Collection.join(delimiter)

Concatenates all values in the collection into a string. If an argument is provided, it uses this as a delimiter. If no argument is provided, no delimiter is used.

Copy
rules.alwaysTrue:
[ "this", "is", "a", "collection" ].join (" ") == "this is a collection"
[ "this", "is", "a", "collection" ].join () == "thissacollection"

Collection.single()

Concatenates all values in the collection into a string. If an argument is provided, it uses this as a delimiter. If no argument is provided, no delimiter is used.

Copy
rules.alwaysTrue:
[ "this", "is", "a", "collection" ].join (" ") == "this is a collection"
[ "this", "is", "a", "collection" ].join () == "thissacollection"

Collection.size()

Returns the number of elements in the collection.

Copy
rules.alwaysTrue: [ "this", "is", "a", "collection" ].size() == 4

Collection.sorted( )

Returns an ordered collection in sorted order. If the values are strings, alphabetical sorting is used. If, however, the values are numbers, numerical sorting is used.

Copy
rules.alwaysTrue: [ 2, 1, 3 ].sorted() == [ 1, 2, 3 ]

Collection.symmetricDifference(another_collection)

Returns an unordered collection consisting of all elements present in the current collection and not in another_collection. The method also returns all elements present in another_collection and not the current collection.

Copy
rules.alwaysTrue: {"method1", "method2"}.symmetricDifference
({"method2", "method3"}) == {"method1", "method3"}

Collection.total()

Returns the sum of the values in the collection. If any non-numeric values are present in the collection, expression execution stops.

Copy
rules.alwaysTrue: [ 1, 3, 9 ].total() == 13

Collection.union(another_collection)

Returns an unordered set consisting of all the unique values in either collection.

Copy
rules.alwaysTrue: {"method1", "method2"}.union({"method2", "method3"}) ==
["method1", "method2", "method3"]

Statistical Methods

Collection.geometricMean()

Returns the geometric mean geometricMean of the values in the collection. If any non-number values are present or the collection is empty, the method returns null. Note that this does not return an exact amount for integer solutions.

Copy
rules.alwaysTrue: [ 1, 3, 9 ].geometricmean() > 2.9999
&& [ 1, 3, 9 ].geometricmean() < 3.0001

Collection.kurtosis()

Returns the kurtosis of the values in the collection.

Copy
rules.alwaysTrue: [ 1, 3, 9, 3, 1 ].kurtosis() > 3.25
&& [ 1, 3, 9, 3, 1 ].kurtosis() < 3.26

Collection.max()

Returns the maximum value max in the collection.

Copy
rules.alwaysTrue: [ 1, 3, 9 ].max() == 9

Collection.mean()

Returns the arithmetic mean of the values in the collection.

Copy
rules.alwaysTrue: [ 10, 20, 30 ].mean() == 20

Collection.median()

Returns the median of the values in the collection.

Copy
rules.alwaysTrue: [ 1, 2, 3, 4, 1000, 2000, 3000 ].median() == 4

Collection.min()

Returns the minimum value in the collection.

Copy
rules.alwaysTrue: [ 1, 3, 9 ].min() == 1

Collection.percentile(p)

Returns an estimate for the pth percentile of the values in the collection.

Copy
rules.alwaysTrue: [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3 ].percentile(20) ==
1

Collection.populationVariance()

Returns the population variance populationVariance of the values in the collection.

Copy
rules.alwaysTrue: [ 1, 1, 4 ].populationvariance() == 1

Collection.quadraticMean()

Returns the quadratic mean quadraticmean (also known as root-mean-square) of the values in the collection.

Copy
rules.alwaysTrue: [ 1, 3, 9 ].quadraticmean() > 5
[ 1, 3, 9 ].quadraticmean() <6

Collection.secondMoment()

Returns the second central moment secondMoment of the values in the collection (the sum of squared deviations from the sample mean).

Copy
rules.alwaysTrue: [ 1, 3, 9 ].secondmoment() == 2

Collection.skewness()

Returns the skewness of the values in the collection, using the following definition:

This definition consists of n as the number of elements, xi, as the collection, μ as the mean and σ as the standard deviation.

Copy
rules.alwaysTrue: [ 1, 3, 9, 3, 1 ].skewness() > 1.73
[ 1, 3, 9, 3, 1 ].skewness() < 1.74

Collection.stdDev()

Returns the standard deviation stddev of the values in the collection, based upon the sample variance.

Copy
rules.alwaysTrue: [ 3, 4, 5 ].stddev() == 1

Collection.sumOfLogs()

Returns the sum of the natural logs of the values in the collection.

Copy
rules.alwaysTrue: [ 2.718, 2.718, 2.718 ].sumoflogs() > 2.999
&& [ 2.718, 2.718, 2.718 ].sumoflogs() < 3.001

Collection.sumOfSquares()

Returns the sum of the squares of the values in the collection.

Copy
rules.alwaysTrue: [ 1, 3, 9 ].sumofsquares() == 91

Collection.variance()

Returns the (sample) variance of the values in the collection. This method returns the bias-corrected sample variance (using n - 1 in the denominator).

Copy
rules.alwaysTrue: [ 1, 1, 4 ].variance() == 3

Ordered Collection Methods

OrderedCollection.reverse()

Returns the collection in reversed order.

Copy
rules.alwaysTrue: [ "a", "c", "b", "d"].reverse() == [ "d",
"b", "c", "a" ]

OrderedCollection.shuffle()

Randomly permutes the collection using a default source of randomness.

Copy
rules.alwaysTrue: [[ "a", "b" ], [ "b", "a" ]] ~# [ "a", "b" ].shuffle()

OrderedCollection.sublist(a)

Returns the sublist of all elements with an index greater than or equal to the parameter a.

Copy
rules.alwaysTrue: [ 1, 2, 3, 4, 5 ].sublist(2) == [ 3, 4, 5 ]

OrderedCollection.sublist(a, b)

Returns the sublist of all elements with an index greater than or equal to the parameter a and less than the parameter b.

Copy
rules.alwaysTrue: [ 1, 2, 3, 4, 5 ].sublist(2, 4) == [ 3, 4 ]