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 stringinputstarting at the character at indexstartto the end, or to the indexendif it is specified.replace(input, regex, value)will replace all matches of the regular expressionregexwithin the stringinputby the value given as the third argument. If needed, performs the conversion ofinputto a string.contains(input, searchedStr)will return true if the stringinputcontains the stringsearchedStr.matches(input, pattern)will return true if the stringinputmatches the regular expression given bypattern.
Conversion functions
toInt(input)will convert the value ofinputto an integer (if possible).toDouble(input)will convert the value ofinputto a double (if possible).toString(input [, format])will convert the value ofinputto a string value. You can use the optionalformatargument 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 ofinputto a date/time. If input is a string, you can use the optionalformatargument 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 returnvalueIfTrueif the value oftestis greater or equals than 0.5 (don't forget that we are dealing with fuzzy logic, so there is no real true or false), orvalueIfFalseotherwise.case(sourceValue, case1, valueIfCase1, ... caseN, valueIfCaseN [, valueOtherwise])will returnvalueIfCase1if the value ofsourceValueis equal tocase1, orvalueIfCaseNifsourceValueequals 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 returnvalueif it is possible to evaluate, ordefaultValueif 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 factorfactorNamefor the entity referred byvar, or 0.0.scaledFactor(var, "factorName")will return the value of factorfactorNamemultiplied 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 byvarif it is tagged as#tag.isKnownBySource(var, sourceName)will return the probability of the entity or relation referred byvarif 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 ifvar1represents 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 tagtagand 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 theseparatorargument.
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. Thefieldcan be any ofyear,month,day,hour,minuteorsecond(or their plural), or their first letter (Mfor month,mfor 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 typeDoubleand 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 betweencolorAandcolorB(gradient), using the valuevaluebetween the boundsvalueAandvalueB. 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 thedataparameter (= 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 thesaturationandlightnessparameters, 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.