# Expressions List

You can use a variety of functions when writing an expression to compare or transform data during the processing of a rule.

The following functions are currently supported within an expression:

## Comparison functions

### Comparing data

These will compare one instance to another and will evaluate to either **True** or **False.**&#x20;

These operators are not available for all data types. The table below shows what operators can be used with what data. Operators support either a symbol representation (e.g. =) or a natural language equivalent. For [comparing dates](#comparing-dates), see the date functions.

**Data type of output:** Boolean (true/false)

<table><thead><tr><th width="281">Operator (and aliases) or function</th><th width="127" data-type="checkbox">String (text)</th><th data-type="checkbox">Number</th><th data-type="checkbox">Date</th><th data-type="checkbox">Truth</th></tr></thead><tbody><tr><td><p><strong>=</strong></p><p>equals</p><p>is equal to</p></td><td>true</td><td>true</td><td>false</td><td>true</td></tr><tr><td><p>!=</p><p>does not equal</p><p>is not equal to</p></td><td>true</td><td>true</td><td>false</td><td>true</td></tr><tr><td><p>></p><p>gt</p><p>greater than</p><p>is greater than</p></td><td>false</td><td>true</td><td>false</td><td>false</td></tr><tr><td><p>>=</p><p>gte</p><p>greater than or equal to</p><p>is greater than or equal to</p></td><td>false</td><td>true</td><td>false</td><td>false</td></tr><tr><td><p>&#x3C;</p><p>lt</p><p>less than</p><p>is less than</p></td><td>false</td><td>true</td><td>false</td><td>false</td></tr><tr><td><p>&#x3C;=</p><p>lte</p><p>less than or equal to</p><p>is less than or equal to</p></td><td>false</td><td>true</td><td>false</td><td>false</td></tr><tr><td><a href="#issubset">isSubset</a> </td><td>true</td><td>false</td><td>false</td><td>false</td></tr><tr><td><a href="#iswithinrange">isWithinRange</a></td><td>false</td><td>true</td><td>true</td><td>false</td></tr></tbody></table>

{% hint style="info" %}
Follow our [Academy](https://academy.rainbird.ai/) course on comparative expressions for detailed examples and how you can combine multiple comparative expressions.
{% endhint %}

### isWithinRange

Check whether a `number` or `date` is found within a given range.

**Data type of output:** Boolean (true/false)

{% tabs %}
{% tab title="Example 1" %}
`isWithinRange(%AGE, 0, 17)`

In this example, you can confirm if a persons age is between 0 and 17. Passing any number between (and including) 0 and 17 will result in a response of `true`.

Supports decimals. Passing in 17.01 as the age will result in `false.`
{% endtab %}

{% tab title="Example 2" %}
`isWithinRange(%NEXT_AVAILABLE_DATE, %START_DATE, %END_DATE)`

This example shows dates being used and the range being determined dynamically using variables. This confirms whether a persons next availability falls within the start and end date of an event.
{% endtab %}

{% tab title="Example 3" %}
`isWithinRange(%NEXT_AVAILABLE_DATE, today(), addDays(today(), 7))`

This example shows the use of functions to set the min and max values. This confirms whether a persons next availability is within the next 7 days from running the query.
{% endtab %}
{% endtabs %}

Supports dates and numbers (including decimal and negatives)

The minimum and maximum values are included in the range e.g. In example 1, an age of `17` would would result in `true`.

The min and max values can be either way. E.g. `isWithinRange(%AGE, 17, 0)` works the same result as `isWithinRange(%AGE, 0, 17)`

## String functions

### includes

Confirm a string contains a set of characters. Partial matching enables you to check the presence of a word or set of characters to infer facts.

**Data type of output:** Boolean (true/false)

{% tabs %}
{% tab title="Example 1" %}
`includes(%COMPANY_NAME, ‘LTD’)`

In this example you could infer a company is a Public Limited Company by checking if a company name contains 'LTD' in the name. E.g. given a company name of `Rainbird Technologies LTD` the function will evaluate to `true`.&#x20;
{% endtab %}

{% tab title="Example 2" %}
`includes(%COMPANY_NAME, %COMPANY_TYPE)`

In this example you can pass a value for company type (e.g. LTD, PLC, LLC) into the function to make it more dynamic. E.g. given a company name of `Rainbird Technologies LTD`  and a dynamic value of `LLC` the function will evaluate to `false`.&#x20;
{% endtab %}
{% endtabs %}

### startsWith

Confirm a string starts with a specified set of characters.

**Data type of output:** Boolean (true/false)

{% tabs %}
{% tab title="Example 1" %}
`startsWith(%POSTCODE, 'NR')`

In this example you could infer the location of a person or business is in the Norwich area by checking the postcode starts with NR. E.g. given a postcode of `NR1 3DT`  the function will evaluate to `true`.&#x20;
{% endtab %}

{% tab title="Example 2" %}
`startsWith(%POSTCODE, %DELIVERY_AREA)`

In this example you can pass a value for the postcode area (E.g. NR1, NR2, NR3 etc.) into the function to make it more dynamic.&#x20;

This example could be included within a rule that determines if a delivery can take place, based on whether the postcode starts with a postcode area supported by a delivery company.

To check a delivery **cannot take place**, you can simply add `= false` at the end of the expression.
{% endtab %}
{% endtabs %}

### endsWith

Confirm a string ends with a specified set of characters.

**Data type of output:** Boolean (true/false)&#x20;

{% tabs %}
{% tab title="Example 1" %}
`endsWith(%EMAIL, '@rainbird.ai')`

In this example you could infer the company a person works for, based on their email domain. E.g. given an email of `bob@rainbird.ai` the function will return `true`.
{% endtab %}

{% tab title="Example 2" %}
`endsWith(%EMAIL, %BLACKLISTED_EMAIL_DOMAIN)`

In this example you could pass a value for the email domain into the function to make it more dynamic.

This example could be included within a rule to confirm a person has a blacklisted email domain.

To confirm they are not blacklisted, you can add `= false` at the end of the expression.
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Case sensitivity & whitespace**

All of the above string functions are case sensitive and will include whitespace before, within and after the search strings.

For example:

Given a search string of  `' Ltd'` a company name of `Rainbird Technologies LTD` (uppercase) or `Rainbird TechnologiesLtd` (correct case, but no whitespace before) would evaluate to `false`.
{% endhint %}

{% hint style="success" %}
**Does not include**

To check the **absence** of a set of characters, `= false` can be added to the end of the expression.

e.g.  `includes(%COMPANY_NAME, 'LTD') = false`   will evaluate to `true` and can be used to confirm the company does **not** have LTD in the name.
{% endhint %}

### regexCount

Count how many times a regular expression matches within a string. Use this when you need flexible pattern checks beyond the basic string functions above. This enables checks to be performed and inferences to be made where the data is less structured.&#x20;

**Data type of output:** Number

**Syntax**

```
regexCount(value, regexPattern)
```

* **value**: string (e.g. `'text'`) or variable (e.g. `%TEXT`)
* **regexPattern**: a string or variable containing a JavaScript-flavoured (ECMAScript) regex in `/pattern/flags` format, e.g. `'/\b\d{5}(-\d{4})?\b/g'`
  * Regex pattern must be wrapped in forward slashes e.g. `'/`*`pattern`*`/'`
  * Flags can be added after the closing forward-slash e.g. `'/`*`pattern`*`/`*`flags`*`'`
  * Common flags:
    * `g` – global (count all matches)
    * `i` – case-insensitive

{% tabs %}
{% tab title="Example 1" %}
`regexCount('Rainbird Technologies Ltd', '/Ltd|Plc|Llc/')`

Result → `1`

or

`regexCount(%COMPANY_NAME, '/Ltd|Plc|Llc/')`  // %COMPANY\_NAME = Rainbird Technologies Ltd

Result → `1`
{% endtab %}

{% tab title="Example 2" %}
Case-insensitive check (adding the flag `i` )

`regexCount('Rainbird Technologies LTD', '/Ltd|Plc|Llc/i')`

Result → `1`

Without case-insensitive flag

`regexCount('Rainbird Technologies LTD', '/Ltd|Plc|Llc/')`

Result → `0`&#x20;
{% endtab %}

{% tab title="Example 3" %}
Counting multiple matching instances

`regexCount('The weather was sunny and warm', '/hot|warm|nice|sunny|pleasant/gi')`

Result → `2`
{% endtab %}

{% tab title="Example 4" %}
Convert the count to a boolean (so the expression is a pass or fail)

`regexCount(%TEXT, '/cat/i') >= 1`     //true if "cat" appears

`regexCount(%TEXT, '/cat/i') = 0`        // true if "cat" is absent
{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Errors

If the engine hits an error at runtime, the regexCount function returns a **negative number**:

`-1` Unsafe pattern • `-2` Evaluation failed • `-3` Invalid syntax • `-4` Pattern too long (>500 chars) • `-5` Input too long (>10,000 chars) • `-6` Invalid format (not `/pattern/flags`) • `-7` Safety check timeout.
{% endhint %}

Further guidance and examples on using the regexCount function is included in the [regexCount guide](/rainbird/knowledge-modelling/modelling-features/relationships/rules/expressions-list/regexcount-guide.md).

## String Concatenation

Join values together into a single output using the `+` operator. Concatenation enables you to combine variables with text strings to create dynamic output.

**Data type of output:** String

**Example** `%FIRST_NAME + ' ' + %LAST_NAME`

In this example you could create a full name by joining the first and last name with a space in between. E.g. given a first name of `John` and a last name of `Smith` the expression will evaluate to `John Smith`.

Concatenation can join any number of strings and variables together. E.g. '`Claim ' + %CLAIM_ID + ' has been ' + %APPROVAL_STATUS + ' with a payout amount of £' + %PAYOUT_AMOUNT` could produce `Claim CL-8932 has been APPROVED with a payout amount of £5,750`.

Dates, numbers and truth types will automatically convert to strings. Dates will display as a timestamp.

***

## Mathematical functions

The following mathematical functions are available to use with **number** concepts only.

**Data type of output:** number

| Function name | Description                                                                                                                                                                                                                                   | Example                                                       |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| Add           | <p><strong>+</strong><br>Add two numbers together</p>                                                                                                                                                                                         | 10 + 5 = 15                                                   |
| Subtract      | <p><strong>-</strong><br>Subtract one number from another</p>                                                                                                                                                                                 | 2 - 1 = 1                                                     |
| Divide        | <p><strong>/</strong><br>Divide one number by another</p>                                                                                                                                                                                     | 6 / 2 = 3                                                     |
| Multiply      | <p>\*<br>Multiple one number by another</p>                                                                                                                                                                                                   | 4 \* 2 = 8                                                    |
| Round         | <p><strong>round(%X,</strong> %Y<strong>)</strong><br>Round X to the nearest integer.<br>You can specify Y to round to Y number of places.<br>If Y is not specified, 0 is assumed. <mark style="color:$danger;">Maximum can be 15.</mark></p> | <p>round(123.4) = 123<br>or<br>round(123.4567,2) = 123.46</p> |
| Ceiling       | <p><strong>ceil(%X)</strong><br>Round X towards plus infinity</p>                                                                                                                                                                             | <p>ceil(4.2) = 5<br>ceil(-4.2) = -4</p>                       |
| Floor         | <p><strong>floor(%X)</strong><br>Round X towards minus infinity</p>                                                                                                                                                                           | <p>floor(4.2) = 4<br>floor(-4.2) = -5</p>                     |
| Absolute      | <p><strong>abs(%X)</strong><br>Calculate the absolute value of X</p>                                                                                                                                                                          | <p>abs(4.2) = 4.2<br>abs(-4.2) = 4.2</p>                      |
| Minimum       | <p><strong>min(%A,%B,%C...)</strong><br>Calculate the minimum value in a set of values</p>                                                                                                                                                    | min(6,4,2,15,11) = 2                                          |
| Maximum       | <p><strong>max(%A,%B,%C...)</strong><br>Calculate the maximum value in a set of values</p>                                                                                                                                                    | max(6,4,2,15,11) = 15                                         |
| Modulus       | <p><strong>mod(%X,%Y)</strong><br>Calculate the modulus (the remainder of an integer division) of X/Y</p>                                                                                                                                     | mod(5,2) = 1                                                  |
| Power         | <p><strong>pow(%X,%Y)</strong><br>Calculate the power of X to Y (X^Y)</p>                                                                                                                                                                     | pow(10,3) = 1000                                              |
| Square root   | <p><strong>sqrt(%X)</strong><br>Calculate the square root of X</p>                                                                                                                                                                            | sqrt(64) = 8                                                  |
| Factorial     | <p><strong>factorial(%X)</strong><br>Calculate the factorial of X</p>                                                                                                                                                                         | factorial(4) = 24                                             |
| Tangent       | <p><strong>tan(%X)</strong><br>Calculate the tangent of X</p>                                                                                                                                                                                 | tan(45) = 1.61978                                             |
| Cosecant      | <p><strong>csc(%X)</strong><br>Calculate the cosecant of X</p>                                                                                                                                                                                | csc(30) = 1.01211                                             |
| Cotangent     | <p><strong>cot(%X)</strong><br>Calculate the cotangent of X</p>                                                                                                                                                                               | cot(80) = 0.11107                                             |
| Secant        | <p><strong>sec(%X)</strong><br>Calculate the secant of X</p>                                                                                                                                                                                  | sec(60) = -1.04996                                            |

Mathematical functions can be combined using brackets.

{% hint style="warning" %}
Mathematical functions can be combined using brackets. Where mathematical calculations are being performed you should observe correct usage of brackets, otherwise the calculation will be read left to right.
{% endhint %}

***

## Date functions

Use within an expression to compare or transform dates.

These functions allow you to:

1. Retrieve the current date/time
2. Get an index for a given date
3. Add or subtract from a date
4. Calculate the difference between dates
5. Compare two dates to determine if one is in the past, present or future from the other

* Inputs to these functions must come from a concept set to a **date** type. An error will be displayed if you try to use these on data that is from a string, number or truth concept.
* Date format: YYYY-MM-DD&#x20;
* These functions may output timestamps, dates, numbers or true/false. The output data type will be mentioned for each function.

### Retrieve the current date/time

Functions to get the current date or date/time to use within other functions. For example to work out a person's age you can write an expression to calculate the number of years between a person's date-of-birth and today's date.

**Data type of output:** date/time

| Function name | Description                                                                                                                                          | Example                                                                   |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Today         | <p><strong>today()</strong><br>Current date at the point the function is executed during a query.<br><em>The time will default to midnight.</em></p> | <p>today() = 1703203200000<br><br>(translates to 2023-12-22 00:00:00)</p> |
| Now           | <p><strong>now()</strong><br>Current date <strong>and time</strong> at the point the function is executed during a query.</p>                        | <p>now() = 1703249564941<br><br>(translates to 2023-12-22 12:52:44)</p>   |

{% hint style="info" %}
These functions will output a unix timestamp, which is a machine readable datetime format. Mostly you will not see these timestamps. However, if you do come across them during building and want to see it in a human-friendly format there’s many websites you can use to convert them such as [epoch converter](https://www.epochconverter.com/).
{% endhint %}

### Get an index for a given date

Functions that take a date and return an index (number) based on the chosen function.

**Data type of output:** number

<table><thead><tr><th width="191">Function name</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>Day of week</td><td><strong>dayOfWeek(%date)</strong><br><br>Returns the nth day of the week for a given date (a number from 1 to 7 where Monday = 1 and Sunday -= 7)</td><td>dayOfWeek(2023-12-22) = 5<br><br>(it's a Friday)</td></tr><tr><td>Day of month</td><td><strong>dayOfMonth(%date)</strong><br><br>Returns the nth day of the month for a given date</td><td>dayOfMonth(2023-12-22) = 22</td></tr><tr><td>Day of year</td><td><strong>dayOfYear(%date)</strong><br><br>Returns the nth day of the year for a given date</td><td>dayOfYear(2023-12-22) = 356</td></tr><tr><td>Month of year</td><td><strong>monthOfYear(%date)</strong><br><br>Returns the nth month of the year for a given date (a number between 1-12)</td><td>monthOfYear(2023-12-22) = 12</td></tr><tr><td>Year</td><td><strong>year(%date)</strong><br><br>Returns the year of a given date</td><td>year(2023-12-22) = 2023</td></tr></tbody></table>

<br>

### Add or subtract from a date

Add or remove a number of days, weeks, months or years from a date to create a new date.

This function requires you to pass in a **date** followed by a **number** you want to add. e.g. `addDays(2023-12-22, 3)` = 2023-12-25.&#x20;

These examples use static data, but both arguments of this function can be dynamic by using variables, so long as the data used is of the correct type. E.g. addDays(%date, %number).

**Data type of output:** date/time

| Function name   | Description                                                                                | Example                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| Add days        | <p><strong>addDays(%date, n)</strong><br><br>Add n number of days to a given date.</p>     | <p>addDays(2023-12-22, 3) = </p><p>1703462400000<br><br>(converts to 2023-12-25)</p>     |
| Add weeks       | <p><strong>addWeeks(%date, n)</strong><br><br>Add n number of weeks to a given date.</p>   | <p>addWeeks(2023-12-22, 3) = 1705017600000<br><br>(converts to 2024-01-12)</p>           |
| Add months      | <p><strong>addMonths(%date, n)</strong><br><br>Add n number of months to a given date.</p> | <p>addMonths(2023-12-22), 3) = 1711065600000<br><br>(converts to 2024-03-22)</p>         |
| Add years       | <p><strong>addYears(%date, n)</strong><br><br>Add n number of years</p>                    | <p>addYears(2023-12-222, 3) = 1797897600000<br><br>(converts to 2026-12-22)</p>          |
| Subtract days   | <p>subtractDays(%date, n)<br><br>Subtract n number of days from a given date.</p>          | <p>subtractDays(2023-12-22, 3) = </p><p>1702944000<br><br>(converts to 2023-12-19)</p>   |
| Subtract weeks  | <p>subtractWeeks(%date, n)<br><br>Subtract n number of weeks from a given date.</p>        | <p>subtractWeeks(2023-12-22, 3) = </p><p>1701388800<br><br>(converts to 2023-12-01)</p>  |
| Subtract months | <p>subtractMonths(%date, n)<br><br>Subtract n number of months from a given date.</p>      | <p>subtractMonths(2023-12-22, 3) = </p><p>1695337200<br><br>(converts to 2023-09-22)</p> |
| Subtract years  | <p>subtractYears(%date, n)<br><br>Subtract n number of years from a given date.</p>        | <p>subtractYears(2023-12-22, 3) = 1608595200</p><p><br><br>(converts to 2020-12-22)</p>  |

{% hint style="info" %}
These functions output a timestamp. If the output of this function is assigned to the object of the rule (%O) then the object should be a **date** type. If the object is a number, the timestamp will be displayed in the result and/or the evidence.
{% endhint %}

### Calculate the difference between dates

Returns the difference between two dates as a number.

This function requires you to pass in two dates. Regardless of the order, it will always output a positive number.

**Data type of output:** number

<table><thead><tr><th width="178">Function name</th><th width="292">Description</th><th>Example</th></tr></thead><tbody><tr><td>Seconds between</td><td>secondsBetween(%date1, %date2)<br><br>The number of seconds between two date/times.</td><td>secondsBetween(2023-12-22 12:30:<strong>10</strong>, 2023-12-22 12:30:<strong>12</strong>) = <strong>2</strong></td></tr><tr><td>Minutes between</td><td>minutesBetween(%date1, %date2)<br><br>The number of minutes between two date/times.</td><td>minutesBetween(2023-12-22 12:<strong>30</strong>:10, 2023-12-22 12:<strong>40</strong>:12) = <strong>10</strong></td></tr><tr><td>Hours between</td><td>hoursBetween(%date1, %date2)<br><br>The number of hours between two dates/times.</td><td>hoursBetween(2023-12-22 <strong>12</strong>:30:10, 2023-12-22 <strong>14</strong>:30:12) = <strong>2</strong></td></tr><tr><td>Days between</td><td>daysBetween(%date1, %date2)<br><br>The number of days between two date/times.</td><td>daysBetween(2023-12-<strong>18</strong> 12:30:10, 2023-12-<strong>22</strong> 12:30:12) = <strong>4</strong></td></tr><tr><td>Weeks between</td><td>weeksBetween(%date1, %date2)<br><br>The number of weeksonds between two date/times.</td><td>weeksBetween(2023-11-20 12:30:10, 2023-12-22 12:30:12) = <strong>4</strong></td></tr><tr><td>Months between</td><td>monthsBetween(%date1, %date2)<br><br>The number of months between two date/times.</td><td>monthsBetween(2023-<strong>10</strong>-22 12:30:10, 2023-<strong>12</strong>-22 12:30:12) = <strong>2</strong></td></tr><tr><td>Years between</td><td>yearsBetween(%date1, %date2)<br><br>The number of years between two date/times.</td><td>yearsBetween(2023-12-22 12:30:10, 2025-07-18 12:30:12) = <strong>1</strong></td></tr></tbody></table>

### Comparing dates

Pass two dates into the function to check if one is in the past, present or future from the other.

These functions will check the dates and evaluate to true or false for the expression to either pass or fail.

**Data type of output:** Boolean (true/false)

| Function name  | Description                                                                                                                | Example                                     |
| -------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| Is before date | <p><strong>isBeforeDate(%date1, %date2)</strong><br><br>Checks if date 1 is before date 2 and returns true or false</p>    | isBeforeDate(2023-12-21, 2023-12-22) = true |
| Is same date   | <p><strong>isSameDate(%date1, %date2)</strong><br><br>Checks if date 1 is the same as date 2 and returns true or false</p> | isSameDate(2023-12-21, 2023-12-22) = false  |
| Is after date  | <p><strong>isAfterDate(%date1, %date2)</strong><br><br>Checks if date 1 is after date 2 and returns true or false</p>      | isAfterDate(2023-12-21, 2023-12-22) = false |

## List functions

Performs comparisons or transformations over a list of facts.

{% hint style="info" %}
The subject, relationship and object must be specified as arguments within these function, to enable the relevant facts to be obtained prior to performing the count/sum etc.

The facts for the relationship can be filtered using the subject or object and can accept either hard-coded instances, variables or an asterisk symbol \* to denote **all**.

Below shows the most common example that gathers all facts from a plural relationship.&#x20;

`functionName(%PERSON, 'lived in', *)`  filters the relationship by the subject and will gather a list of all countries a person has lived in before performing the chosen operation.

List functions can be used with singular relationships if it is not important to filter by the subject. For example `functionName(*, 'lived in', *)` would gather all facts for all subjects within the session before performing the operation.
{% endhint %}

{% hint style="warning" %}
Using a hard-coded value or variable on both sides of the relationship will restrict it to a single fact, making the list function redundant.

For example `functionName(%PERSON, 'lived in', %COUNTRY)` will filter the facts by person AND country, returning one fact that matches the person and country value, rather than a list of facts. In this example, replacing `%COUNTRY` with `*` would return the list of facts.&#x20;
{% endhint %}

### countRelationshipInstances

Count how many facts exist for a given relationship. This enables you to determine the number of relationships a specific entity has.

The object of the relationship can be of any type.

**Data type of output:** Number

{% tabs %}
{% tab title="Example 1" %}
`countRelationshipInstances(%ACCOUNT_ID, 'has account flags', *)`

In this example `%ACCOUNT_ID` denotes a variable where an account identifier is used to constrain the function to consider only that account. The asterisk `*` denotes all objects.

This will return the number of account flags associated with the given account. For example, if account "ACC-7823" has three flags ("Suspicious activity", "High risk", "Manual review"), the function will evaluate to `3`.
{% endtab %}

{% tab title="Example 2" %}
`countRelationshipInstances(*, 'has account flags', *)`

In this example, the first asterisk `*` denotes all subjects (all accounts), and the second asterisk `*` denotes all objects (all flags).

This will return the total number of account flags across all accounts in the session. For example, if account "ACC-7823" has three flags ("Suspicious activity", "High risk", "Manual review"), account "ACC-4519" has two flags ("Dormant", "Foreign national"), and account "ACC-9032" has one flag ("Politically exposed"), the function will evaluate to `6`.
{% endtab %}
{% endtabs %}

### sumObjects

Adds all number objects from a list and returns the total, when they share the same relationship.&#x20;

The object of the relationship must be a **number.**

**Data type of output:** number

{% tabs %}
{% tab title="Example 1" %}
`sumObjects(%COMPANY, ‘has employee salaries’, *)`

In this example `%COMPANY` denotes a variable where a company name is used to constrain the function to consider only facts for that company. The asterisk `*` denotes all objects.

This will return a sum of all employee salaries for the given company.

Note: the relationship in this example must be plural
{% endtab %}

{% tab title="Example 2" %}
`sumObjects(*, ‘has employee salaries’, *)`

In this example the subject is not being constrained to a single company as the asterisk `*` to denote all is also being used for the subject.

This will return a sum of all employee salaries for all companies.

Note: the relationship in this example can be singular or plural
{% endtab %}
{% endtabs %}

### minObjects

Returns the lowest value from a list of objects.

Supports finding the lowest number or earliest date.

The object of the relationship can be a **date** or **number.**

**Data type of output:** date or number (depending on the input data type)

{% tabs %}
{% tab title="Example 1" %}
`minObjects(%COMPANY, ‘has employee salaries’, *)`&#x20;

In this example `%COMPANY` denotes a variable where a company name is used to constrain the function to consider only that company. The asterisk `*` denotes all objects.

This will return the lowest salary for the given company.

Note: the relationship in this example must be plural
{% endtab %}

{% tab title="Example 2" %}
`minObjects(*, ‘has employee salaries’, *)`&#x20;

In this example the subject is not being constrained to a single company as the asterisk `*` to denote all is also being used for the subject.

This will return the lowest salary for all companies.

Note: the relationship in this example can be singular or plural
{% endtab %}
{% endtabs %}

### maxObjects

Returns the highest value from a list of objects.

Supports finding the highest number or latest date.

The object of the relationship can be a **date** or **number.**

**Data type of output:** date or number (depending on the input data type)

{% tabs %}
{% tab title="Example 1" %}
`maxObjects(%COMPANY, ‘has employee salaries’, *)`&#x20;

In this example `%COMPANY` denotes a variable where a company name is used to constrain the function to consider only that company. The asterisk `*` denotes all objects.

This will return the highest salary for the given company.

Note: the relationship in this example must be plural
{% endtab %}

{% tab title="Example 2" %}
`maxObjects(*, ‘has employee salaries’, *)`&#x20;

In this example the subject is not being constrained to a single company as the asterisk `*` to denote all is also being used for the subject.

This will return the highest salary for all companies.

Note: the relationship in this example can be singular or plural
{% endtab %}
{% endtabs %}

### joinObjects

Join a list of objects into a single comma-separated string.

This function helps to build string concatenated results when you want to list a set of instances in the result text.

The object of the relationship can be of any type.

**Data type of output:** string

**Example:**

`joinObjects(%S, 'has visited countries', *)`

This will collate a list of countries visited by a person and return it as a comma-separated string.

For example given the facts of:

`Simone > has visited countries > Canada`\
`Simone > has visited countries > Austria`\
`Simone > has visited counties > Germany`

The function would output a value of `Canada, Austria, Germany`.              &#x20;

<details>

<summary>How can this be used?</summary>

This value can be assigned to a variable, which can be used to create result text.

Below shows an example rule, where data is being obtained from the graph, then using [string concatenation](#string-concatenation) to construct  some result text that will list the persons favourite country, followed by a list of other countries the person has visited (assigned to the variable %OTHER\_COUNTRIES).

This enables more context to be returned with results.

<figure><img src="/files/iXSKdpWSiLtlRFKYs9AJ" alt=""><figcaption></figcaption></figure>

</details>

### isSubset

Compares one list of instances against another list and returns either True or False if the items in the 1st list are present in the 2nd list.

**Data type of output:** Boolean (true/false)

<details>

<summary>Example of isSubset</summary>

This function could be used to check that the essential skills required for a job role is a subset of the skills listed for a candidate.

To do this, the function needs to be told where to gather this data from. This is done by specifying which two relationships contain this information and which side of the relationship (the subject or object) will be compared.

These relationships should be plural.

Using the example above, we might have a rule that looks like this:

**Rule:** Candidate (%S) > is suitable for > Job role (%O)

**Expression:**

`isSubset(`<mark style="background-color:purple;">`%O, 'requires essential skills', *`</mark>`,`` `<mark style="background-color:orange;">`%S, 'has skills', *`</mark>`)`

At runtime, if we had a candidate of `Simone` and the rule was processing a job role of `Retail Financial Advisor`, the expression would do the following to determine that the 1st list is a subset of the 2nd list, confirming the candidate possesses the essential skills for the role and returning `true` from the expression.

<table data-full-width="true"><thead><tr><th width="377.046875">1. Generate 1st list</th><th width="492">2. Generate 2nd list</th></tr></thead><tbody><tr><td>%O = Retail Financial Advisor</td><td>%S = Candidate</td></tr><tr><td><p><mark style="background-color:purple;">Retail Financial Advisor > has essential skills > *</mark></p><p>(<code>*</code> denotes <em>all</em>)</p></td><td><mark style="background-color:orange;">Simone > meets > *</mark></td></tr><tr><td>The engine gathers all facts for Retail Financial Advisor > has essential skills > * and compiles a list from the objects. Shown below.</td><td>The engine gathers all facts for Simone > meets > * and compiles a list from the objects. Shown below.</td></tr><tr><td><em>1st list</em></td><td><em>2nd list</em></td></tr><tr><td><mark style="color:green;">Banking experience</mark></td><td><mark style="color:green;">Banking experience</mark></td></tr><tr><td><mark style="color:green;">Degree qualified</mark></td><td><mark style="color:red;">Multi-lingual</mark></td></tr><tr><td><mark style="color:green;">3 x A-levels</mark></td><td><mark style="color:green;">Degree qualified</mark></td></tr><tr><td><mark style="color:green;">Driving license</mark></td><td><mark style="color:green;">Driving license</mark></td></tr><tr><td></td><td><mark style="color:green;">3 x A-levels</mark></td></tr><tr><td></td><td><mark style="color:red;">Knowledge of current finance products</mark></td></tr></tbody></table>

</details>

## Logical Operators (and / or)

Combine multiple conditions within expressions to create more complex logic. Logical operators enable you to evaluate whether multiple conditions are true or whether at least one condition is true.

**Operators available:**

* `and`: All conditions must be true for the expression to evaluate to true
* `or`: At least one condition must be true for the expression to evaluate to true

**Examples**

`(includes(%POLICY_TYPE, 'Auto')) and (%CLAIM_AMOUNT > 5000)`

This example evaluates to true only when both conditions are met: the policy type contains "Auto" AND the claim amount exceeds £5,000.

`(%RISK_SCORE > 80) or (includes(%CLIENT_STATUS, 'VIP'))`

This example evaluates to true when either condition is met: the risk score is above 80 OR the client has VIP status.

Logical operators can be combined to create more complex conditions:

`((%AGE < 25) or (%DRIVING_YEARS < 3)) and (%ACCIDENT_COUNT > 0)`

This will evaluate to true when either the client is under 25 OR has less than 3 years of driving experience, AND they have had at least one accident.

**Truth table for logical operators**

| Condition 1 | Condition 2 | 1 AND 2 | 1 OR 2 |
| ----------- | ----------- | ------- | ------ |
| true        | true        | true    | true   |
| true        | false       | false   | true   |
| false       | true        | false   | true   |
| false       | false       | false   | false  |

{% hint style="warning" %}
It is important to use parentheses to control the order of evaluation when combining multiple logical operators.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rainbird.ai/rainbird/knowledge-modelling/modelling-features/relationships/rules/expressions-list.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
