Expressions
An expression is way to calculate or implement a specific logic. Expressions can for example be used for factors calculation, filtering of records in a knowledge source, or in conditions or search parameters of roots of a prepared query etc.
Basics
Expressions are evaluated statements that give a result. They are not strongly typed, meaning that the expression evaluation engine will always try to find the most adequate data type to be able to give a result.
A basic expression can be :
3.14
Which obviously simply evaluates to the double constant 3.14
Simple arithmetic formulas can also be used :
(2 + 3) * 5
Will use standard precedence to calculate the final integer result 25
The four standard arithmetic operators are available : +
, -
, *
and /
, and can be combined with any depth of parenthesis.
Functions can also be used, for example mathematical functions :
max(2,3) * 5
Will result to 15 as the result of max(2,3) is obviously 3.
Syntax for typed data
- Numeric types are simply referred as numeric constants.
- Strings can be used by using double quotes. If a double quote must be part of the string, it can be escaped by doubling it :
"This is a ""quote"" in a quote"
Variables
Variables can be used in an expression, using one of the following formats:
Named references
When working with named entities of relations (e.g. in an assertion, where the subjects have a variable name), you can refer to them directly using their variable name, and access the value of an entity data using a dotted notation. Example:
S.data + 2
The result will depend on the type of the entity data type data
. If it is a numeric type (integer or double), the result will be an arithmetic addition between 2 and the value of this data in the entity referred as S. If it is a string value, the result will be the concatenation of the original string and the character "2".
Unnamed references to a record
In certain situations, you don't have a variable name (e.g. when loading data from a knowledge source), but you have to access a particular named field of the current record. In that situation, you can use an anonymous reference as follows:
@."fieldRef" * 3
Which will take the value of fieldRef in the current context, try to convert it as a number, and multiply it by 3.
Unnamed references to an entity
When using an expression in a filter or in calculated factors, you don't have a variable name for the current entity. You can then use the @
symbol to refer to the current entity:
hasTag(@, #mytag)
Completely anonymous value
When using an expression in a field adapter, you don't have a field name either. You just have an input, that can be referred as the dollar sign `$
.
$ + 2
The result will depend on the type of the current value. If it is a numeric type (integer or double), the result will be an arithmetic addition between 2 and the current value. If it is a string value, the result will be the concatenation of the original string and the character "2".
Global variable
You can also refer to a global variable using the following syntax:
${global.variable.name}
The reference will then be replaced by the type and content of the global variable identified by its name.
If the name of the global variable name should be "calculated", you also can use the function:
globalVar("global.variable.name" [, defaultValue])
The default value will be returned if the global variable does not exist. It is optional.
Tests
Expressions can (and in some cases must) have a boolean result. This is especially used when working with expressions in filters.
Operators
The standard operators ==
(equals), !=
(not equals), <
(smaller than), >
(greater than), <=
(smaller than or equal to), >=
(greater than or equal to) can be used.
S.type == "UNKNOWN"
Will return true when the data value type
of the entity referred as S
equals the string UNKNOWN. More precisely, as we are dealing with fuzzy logic, the result will be the probability of S.
To test for a value among a list, the IN
operator can also be used:
S.city IN ["Paris", "New-York"]
Will return true only if the data value city
of the entity referred as S
equals either Paris or New-York. You can add as many data values as you want, but at least one must be present.
Negations can naturally also be used with the !
sign.
!(@."usageCount" < 2)
Boolean operators &&
(logical AND) and ||
(logical OR) can also be used to write more complex expressions:
(@."size" > 10) && (@."active" == "Y")
Will return true only if the value of the field size
in the current record is greater than 10 and the string active
is exactly equal to the string Y
.
Functions
Mathematical functions
min(x, y)
will return the smallest number among x and y.max(x, y)
will return the greatest number among x and y.
String functions
substring(input, start [, end])
will return the part of the stringinput
starting at the character at indexstart
to the end, or to the indexend
if it is specified.replace(input, regex, value)
will replace all matches of the regular expressionregex
within the stringinput
by the value given as the third argument. If needed, performs the conversion ofinput
to a string.contains(input, searchedStr)
will return true if the stringinput
contains the stringsearchedStr
.matches(input, pattern)
will return true if the stringinput
matches the regular expression given bypattern
.
Conversion functions
toInt(input)
will convert the value ofinput
to an integer (if possible).toDouble(input)
will convert the value ofinput
to a double (if possible).toString(input [, format])
will convert the value ofinput
to a string value. You can use the optionalformat
argument to specify how to format the input (number, string or date formatting). The syntax for the format function is the Java formatting syntaxtoDateTime(input [,format])
will convert the value ofinput
to a date/time. If input is a string, you can use the optionalformat
argument to specify how the input is formatted. The syntax for the date format is also based on Java time format.
Conditional functions
if(test, valueIfTrue, valueIfFalse)
will returnvalueIfTrue
if the value oftest
is greater or equals than 0.5 (don't forget that we are dealing with fuzzy logic, so there is no real true or false), orvalueIfFalse
otherwise.case(sourceValue, case1, valueIfCase1, ... caseN, valueIfCaseN [, valueOtherwise])
will returnvalueIfCase1
if the value ofsourceValue
is equal tocase1
, orvalueIfCaseN
ifsourceValue
equals tocaseN
. You can use as many cases as you want. The default value is optional, and will be returned if no case matched.try(value, defaultValue)
will returnvalue
if it is possible to evaluate, ordefaultValue
if it is not the case. Warning: this function may hide syntax errors. For example, you may use an inexisting variable of property name invalue
, in which case the default value would be always returned.
Model functions
probability(var)
will return the probability (double between 0.0 and 1.0) of the entity referred byvar
.factor(var, "factorName")
will return the value of factorfactorName
for the entity referred byvar
, or 0.0.scaledFactor(var, "factorName")
will return the value of factorfactorName
multiplied by its display scale (multiplier) for the entity referred byvar
, or 0.0.hasTag(var, #tag)
will return the probability of the entity or relation referred byvar
if it is tagged as#tag
.isKnownBySource(var, sourceName)
will return the probability of the entity or relation referred byvar
if it is known by the knowledge source whose name is given by the stringsourceName
.isEntityOfType(var, entityTypeName)
will return the probability of the entity referred byvar<
if its type isentityTypeName
, or one of its descendent types.areSameEntities(var1, var2)
will return 1.0 ifvar1
represents the same entity asvar2
.metadata(var, [tag], type, [secondaryId, [separator]])
will return the value of a specific metadata stored for the entity or relation referenced byvar
, of typetype
, and optionally stored for the tagtag
and having the optional secondary IDsecondaryId
, if it exists. If multiple metadatas matching the arguments are found (e.g. if you don't specify a secondaryId but multiple exist), the the values will be concatenated, with a space by default, or the string given by theseparator
argument.
Date functions
now()
returns the current date and time.today()
returns the current date, at midnight.date(year, month, day)
returns the date specified, at midnight.dateAdd(date, field, delta)
returns thedate
, with a delta (integer) applied to the specified field. Thefield
can be any ofyear
,month
,day
,hour
,minute
orsecond
(or their plural), or their first letter (M
for month,m
for minute). The field is specified as a string value, e.g. :dateAdd(date, "days", -2)
returns the date two days ago at the same time as the original date.
Color functions
rgb(red, green, blue [, alpha])
will return a HTML color under the form#rrggbbaa
, where the characters are hexadecimal numbers. If all values are of the typeDouble
and less or equal to 1.0, then all values are considered to be between 0.0 and 1.0. If any value is greater than one, then all values must be between 0 and 255.interpolateColor(colorA, colorB, valueA, valueB, value)
will return an interpolated color betweencolorA
andcolorB
(gradient), using the valuevalue
between the boundsvalueA
andvalueB
. The closer the value is tovalueA
, the closer the resulting color will be fromcolorA
.closeColor(reference, range)
will create a random HTML color close to thereference
, by adjusting its hue, saturation and lightness with an amplitude given by therange
. For example,closeColor("#ff0000", 0.1)
will generate a random color close to a pure red.hashColor(data [, saturation [, lightness]])
calculates a color from thedata
parameter (= a random color but that will always be the same for this value). By default, the hue, saturation and lightness will all be random, but if you want to stick with specific ranges (e.g. pastel colors), you can fix thesaturation
andlightness
parameters, given as double values between 0 and 1.
Special functions
In the context of an assertion evaluation, if you have defined aggregators on subjects, you can refer to their value using the simple following syntax: aggregator(name)
. Please refer to assertions documentation for more information about aggregators in assertions.