Expression

◷ Reading Time: 16 minutes

An expression is a combination of explicit values, variables, operators, and functions that are evaluated according to particular rules and then produce new values.

For evaluating an expression ExpressionEval should be used. If a variable is required an instance of VariableContainer must be passed.

An expression is the building block of writing rules and conditions. There are some other models (e.g., Decision Table) that support more expression formats as well as normal expressions.

Values

Value is an expression evaluating it will return the same result. The evaluation engine can process the following value types:

Type Format Sample
String “test string value”
Parameterized String Prefix $ $”test is {adj} cool” —> adj is a parameter of logic.
Integer Suffix i 23i
DecimalSuffix m 67m
Double Suffix d 0d
Long Suffix l 20l
Boolean true false
Undefined null
DateTime # date_time_string # #23-04-2009 3:9 pm#
DateTime with Format specifier # date_time_string | formatter_string # #23-04-2009 | dd-MM-yyyy#
TimeSpan #{day.hour:minute:second}# #{3:45}#
Array [value1, value2,… ] [1,2,’test’,4]
Dictionary { key1:value1, key2:value2… } {person: {name:’Joe’, age:10}}
DateTime format specifier
Below is the list of formatted:

Year
y: The year, from 0 to 99
yy: The year, from 00 to 99
yyy: The year, with a minimum of three digits
yyyy: The year as a four-digit number

Month
M: The month, from 1 through 12
MM: The month, from 01 through 12
MMM: The abbreviated name of the month
MMMM: The full name of the month

Day
d: The day of the month, from 1 through 31
dd: The day of the month, from 01 through 31
ddd: The day of the month, from 01 through 31
dddd: The full name of the day of the week

Hour
h: The hour, using a 12-hour clock from 1 to 12
hh: The hour, using a 12-hour clock from 01 to 12
H: The hour, using a 24-hour clock from 0 to 23
HH: The hour, using a 24-hour clock from 00 to 23

Minute
m: The minute, from 0 through 59
mm: The minute, from 00 through 59

Second
s: The second, from 0 through 59
ss: The second, from 00 through 59

AM/PM
t: The first character of the AM/PM designator
tt: The AM/PM designator

For example: MM/dd/YYYY shows the abbreviated name of the month, the day of the month, from 01 through 31 and the year as a four-digit number separated with /

Array

An array is a list that can hold multiple values. The list can be manipulated using collection functions.

An array can be initialized using Native Complex Value or array function.

Variables

Variables can be defined with a name,

  • Short variable name: alphabetic numeric _ $
    • x
    • abc3
    • point_x
    • $value
  • Long variable name: { variable name }
    • {applicant name}
    • {risk factor}
    • {person’s father name}

Variables in different logic are defined as parameters. You can define them in the following types of rules and logic:

  • Procedural rules
  • Flow logic
  • Validation rules
  • Workflow logic
  • Inference rules
  • Decision

Operators

All the execution routing conditions in the rules and logic are based on expression evaluation. An expression is shown below:

Mathematical operators

Name Sign Sample
Addition +23+4
Subtraction 2.1-5.76
Division /914/74
Multiplication *48*6
Reminder %78%4
Power **2**8
Increment++x++
Decrement– –x- –

Assignment operator

Name Sign Description Sample Version
Assignment
=
Assign a value to a parameter. 
Parameter must exist in the current context.
x=y.

GetCordinate().X/2 
approved=true 

applicant.GetDoc(‘system’,true).IsValid=system.Validity
8
Declare and Assign :=Assign a value to a parameter. 
Parameter will be registered in the context if does not exist.
y := 23+x/345*pi() 

approved :=true
8
Addition assignment += Adds the right side value to the variable and assigns the result to the same variablex = 2
x += 3
result:
x = 5

y = “Hello”
y += ” World”
result:
y = “Hello World”
8
Subtraction assignment-=Substracts the right side value from the variable and assigns the result to the same variable x = 3
x -= 1
result:
x = 2

y = 4
y -= 5
result:
y = -1
8
Multiplication assignment*=Multiplies the right side value by the variable and assigns the result to the same variable x = 3
x *= 1
result:
x = 3

y = 4
y *= -5
result:
y = -20
8
Division assignment/=Devides the variable by the right side value and assigns the result to the same variable x = 50
x /= 5
result:
x = 10

y = 26
y /= -2
result:
y = -13
8
Remainder assignment%=Devides the variable by the right side value and assigns the remainder to the same variable x = 10
x %= 4
result:
x = 2

y = 23
y %= 5
result:
y = 3
8
Null-coalescing assignment??=Checks whether the variable is null. If it is null, assigns the right side value to the variable, if not, keeps the variable valuex = null
x ??= 3
result:
x = 3

y = “Hello”
y ??= “Hi”
result:
y = “Hello”
8.1 +
Null-coalesce ?? Checks whether the variable is null x = null
x??5
result:
5

x = 3
x??5
result:
3
8.1 +

Assignment operator format:

expression = expression 

In this case, the left-hand-side expression must finish with a Property or Field of an object

variable = expression

Boolean operators

Name Sign Sample
And && 
and
(age<18) && (i>10) 
(age<18) and (i>10)
Or || 
or
(Age lt 15) || (Male==true) 
(Age lt 15) or (Male==true)
Negate ! !(Age lt 15)
Format:  (LEFT-BOOLEAN-EXPRESSION) [boolean operator] (RIGHT-BOOEALN-EXPRESSION)

Please note you MUST use parentheses around both sides of a boolean operator to make sure you prioritize the evaluation on the left and right side of the boolean operator.

Comparing operators

Name Sign Sample
Equality ==
eq
Age==18
Inequality !=
neq
Gender != Female
Less than
lt
(Age < 15) 
(Age lt 15)
Smaller than or equal <= 
le
(Age <= 15) 
(Age le 15)
Greater than
gt
(Age > 15) 
(Age gt 15)
Greater than or equal >= 
ge
(Age >= 15) 
(Age ge 15)

Case insensitive

Name Sign Sample Result
Equality ===
is
‘test’===’TEST’ true
Inequality !==
isnt
‘abcd’ !== ‘Abcd’false

Priority operator

Sub-expression evaluation based on priority:

  • Begin (
  • End )
(1-risk)*applicantAge

Object members operators

Access to objects (variable) members:

  • Method (.)
  • Property (.)
  • Indexer, Array, list item access ([) and (])
applicant.Age*applicant.CalculateRiskFactor("A")
Null-Aware Property

Properties and Fields of data can be null, and the normal . throws exception.

If you want to handle that exception, you may need to have if, then, else as follows.

if person != null and person.Parent !=null and person.Parent.Name !=null 
then person.Parent.Name.Length
else null

In FlexRule, to avoid repeating!= null, you can use the accesses operator ?.  as follows which does the exact same thing in above if,then else expression.

person?.Parent?.Name?.Length

Condition operator

Inline condition operator
Name Sign Sample
Condition ?
Alternatives :2.1-5.76

For example:

(3==4)?'this is cool':'what are you talking about?'
If-Then-Else

The alternative of an inline condition operator is to use if-then-else format:

if condition then result else other-result

For example, the above example can be written as:

if 3==4 then 'this is cool' else 'what are you talking about?'

Also, they can be nested:

if Product Type == 'STANDARD LOAN'
then 20.00d
else if Product Type == 'SPECIAL LOAN'
then 25.00d
else null

Methods

A Method is a procedure associated with an object. This is the interface an object presents to the outside world. When a variable parameter is defined that holds an object, then the method of the object can be called using. operator. Parentheses are required at the end of the method and input arguments are comma-separated.

Example: Assume x and b are defined parameters, the expression ‘x.Calculate(2i, b)’ calls Calculate method of the x and pass integer 2 and variable b as input arguments.

String to Expression

You can use the @ sign to get the value of an expression in String format.

For example, to generate the results, we will be reading each value from keylist and use them in zip function. There, in zip function, its parameter requires a string value. Therefore, we have added 'keylist[x]' expression with a @ to retrieve its value.

keylist =  ["a", "b", "c"]
values = [1,2,3]
results = zip(range(0,keylist|count())|select(x,{@'keylist[x]':values[x]}))

results =  {
    "a" : 1,
    "b" : 2,
    "c" : 3
} 

This is another example:

Username= "John"
Message = "Hello " + @'Username'

Message = "Hello John"

Functions

Functions are expressions that relate inputs (arguments) to outputs (function result). There are two types of functions in FlexRule:

  1. Built-in functions
  2. Static methods
  3. Your specific custom code as a function

When a function is defined it has the format shown below:

FunctionName(p1, p2, p3, ...)

where p1, p2, p3… are the parameters of the function which during the usage the values (Arguments) have to be passed to those parameters.

Or a function may have no parameters at all

FunctionName()

In both cases, the function can return a value as a result of the call which can be stored in a parameter using an assignment operator.

parameter = Function(value1, value2, ...)

Functions are very similar to methods, but the difference is that these do not belong to any specific variable. They are global in the whole expression evaluation context. For example, let’s consider the following expression:

in(age, array(3,4,56,60,3,10))

As you can see in and an array is accepting arguments with parentheses. These are comma-separated, exactly like methods, but there is no. operator involved. Functions can be defined at the application/rule level and they are a way to extend the functionality at the expression evaluation level.

Check API for built-in functions.

Decision Table Expressions

In a Decision Table, there are some more expression formats that can be used to simplify the value-based rules. In general, when a value is entered in a data section of a Decision Table, it dynamically resolves its type based on the column type and template expression.

Type of Value Sample Expression description
Negate not: 2-3-4 Prefix with not:
String blah blah blah
Explicit String “blah blah blah” or ‘blah…’ String quotes (double or single)
Numbers 23 or 4i or 3.4d No prefix (all expression rules in above sections apply)
Expression : applicant.GetLastAttendanceDate()  :
Range [23, 45] 
(43, 50) 
[39;456) 
[1 .. 456)
Square brackets [] for inclusion and Parentheses exclusion in value ranges and they are comma (,) or semicolon (;) or double dot (..) split.
Multi-Values 12,3,4 

34,3d,’string value’, true, var2.Length
Multi values are ‘,’ split. They can be a combination of different values and variable references.

For example, in the second example, we have defined multiple values as 34 (integer number), 3.0 (decimal number), true (boolean value) and var2.Length (as Length property of a variable reference named var2)Note: Multi values must explicitly specify their types on each element separated by a comma.
Contains/In in {“VIC”, “SA”} in { LIST } where LIST is a set of expression values separated by comma.

Pipe

Pipes are types of functions that you can chain together and pass previous results to the next one.
Functions that are used with Pipe are called Monads.

|pipeName (arg1, arg2, arg3...)

For example, the result of people |count() is an integer that is the length of the people list. In this example, the count function receives people as its input and its result as a number (integer).

var list = new List<DecisionAgeTests.Person>()
{
    new DecisionAgeTests.Person("arash", 38, DecisionAgeTests.Gender.Male),
    new DecisionAgeTests.Person("Parsa", 6, DecisionAgeTests.Gender.Male),
    new DecisionAgeTests.Person("Pooya", 3, DecisionAgeTests.Gender.Male),
    new DecisionAgeTests.Person("Shah", 3, DecisionAgeTests.Gender.Female)
};
 
var vc = new VariableContainer();
vc.RegisterVariable("people", list);
 
var res = ExpressionEval.Default.Compute(vc, "people |count ()");
 
Assert.AreEqual(list.Count, (int)res); 

XML

When you are working with XML-based data/information, you need to read and manipulate XML.

For more details, visit Xml API help

Comments

When it is required to add descriptions and comments to describe the expressions, there are multiple ways you can do this in FlexRule. This link contains more information on that.

A comment section must start with /* and end with */

Learn more about adding Comments.

Examples

Here are a couple of examples with different types of expressions.

Calculation

(a+b)+(2 * c)-d

Comparison

a < 10
(a+b) gt 23
a<=(c+d)

Assignment

a = b + c
str = 'hello FlexRule expressions'

Storing the result of comparison into ‘r’

r = (b+c)<d

In the below expression, age will be declared at runtime and the value of 18 will be assigned.

age := 18

On assignment of properties, when the parameter is null, an empty object automatically will be created.

Person := null
Person.Name = "ABC"

Method Call

When obj is an object reference which is not null

a = obj.CalculateSum()+20-b

Access Value

In below example, obj is an instance of an object

b = obj.Name + '-' + obj.Family

Evaluating Expression in Code

Here is an example of how you can evaluate an expression containing some variables:

Evaluating expressions on FlexRule:

x := 5
y := 'a test string'
result := (x lt 3) ? x : (x+y.Length)

Evaluating FlexRule’s expression using C#:

var variables = new VariableContainer();
 
variables.Compute("x := 5");
variables.Compute("y := 'a test string'");
 
var res = variables.Compute("result := (x lt 3) ? x : (x+y.Length)");
// res, variables["result"] are both equal to 18

Video

Updated on April 14, 2023

Was this article helpful?

Related Articles