Rules --> Advanced Expressions -->

using Brackets

Brackets should be used to separate the different calculations within expressions. In the same way that mathematics works, they are used to indicate that a part of the expression must be solved independently before any other calculations are carried out.

Brackets are essential for Rainbird to process expressions accurately. If no brackets are used Rainbird will simply read the expression from left to right, calculating as it goes, which could affect your calculation and therefore your logic. 

 

Consider the following expression:

Figure 1: Expression with brackets

 

The sum in each set of brackets is calculated first, replacing each bracket with a single number in the overall equation. Our expression with brackets translates to:

10 * 20 / 10 – 10 = 10

 

Now consider the same expression without brackets:


Figure 2: Expression without brackets

 

The expression would translate to:

20 / 2 * 10 + 10 / 2 * 5 – 12 – 2 = 261

As you can see, the two values returned are markedly different!

 

Brackets for Boolean Operators

The boolean operators ‘and’ / ‘or’ can be used to link parts of an expression together. Brackets are then used to confine parts of the expressions which are separated by ‘and’ / ‘or’.

For example, consider the following map, to find out the eligibility of a person for a bus pass:

Figure 3: Depending on Age and Occupation Status a person is eligible for a Pass

You might want the eligibility criteria to be that if a person is aged over 60 AND retired, they will be eligible for a bus pass. This could be expressed with the boolean operator ‘and’.

 

Here’s what this would look like:

Figure 4: combining two expressions with ‘and’

 

You can see that the two elements (‘age is greater than 60’ and ‘occupation status is equal to retired’) have been separated with brackets but linked with the boolean ‘and’.

You might want to broaden the eligibility criteria for the bus pass. For example, a person could be eligible for a bus pass when they are aged over 60, OR when they are retired. After all, somebody may be retired but under the age of 60. We would use the ‘or’ boolean function instead.

Here’s what this would look like:

Figure 5: Combining two expressions with ‘or’

You can add a third piece of criteria by adding in extra brackets to accommodate the extra piece of information and to group different elements of an expression accordingly:

Figure 6: Using multiple expressions with AND/OR Conditions


In the example expression above, extra brackets have been used around the first two elements (‘%AGE is greater than 60’ and ‘%AGE is less than 80’) to confine these together and separate them from the third element (‘%OCCUPATION_STATUS is equal to ‘retired’). 

Confining the elements in brackets as above tells Rainbird that in order for the condition to be satisfied the %AGE must be greater than 60 and less than 80 – or, if either of these two pieces of criteria is not met, then the person must have an occupation status of ‘Retired’.

 

When using the boolean operator ‘and’, all elements must be true in order for the overall value to be considered true. If one or all elements are false, then the overall value will be considered false.

This is demonstrated in the following truth table:

Figure 7: Truth table for ‘and’

 

When using the boolean operator ‘or’, only one element is required to be true in order for the overall value to be considered true.

Figure 8: Truth table for ‘or’

 

The RBLang below will generate the example map used in the the article. Click on ‘Export .rbird’ to download the knowledge map, or ‘copy RBLang’ and paste the code directly into Rainbird.

Query and Results

When using the map generated by the RBLang below, run the query on the ‘is eligible for’ relationship for an example of a query that uses expressions with brackets.

 

<?xml version="1.0" encoding="utf-8"?>
<rbl:kb xmlns:rbl="http://rbl.io/schema/RBLang">

<!-- ================ CONCEPTS ================ -->

    <concept name="Customer" type="string" />
    <concept name="Discount" type="string" />
    <concept name="Vehicle" type="string" />
    
    
<!-- ================ RELATIONSHIP ================ -->

    <rel name="entitled to" subject="Customer" object="Discount" plural="true" allowUnknown="false" askable="all" />
    <rel name="owns vehicle" subject="Customer" object="Vehicle" plural="true" allowUnknown="false" askable="all" />    
    
    
<!-- ================ RULES ================ -->
    
<!-- This rule counts the amount of cars the customer owns, if the result is one, the customer can not claim for multi-car insurance -->
     <relinst type="entitled to" cf="100">
         <condition expression="countRelationshipInstances(%S,owns vehicle,*) = 1"  weight="100" behaviour="mandatory" />
    	 <condition expression="'Sorry, you are not entitled to multi-car discount.'" value="%O" weight="100" behaviour="mandatory"  />
     </relinst>

<!-- The customer is entitled for a multicar insurance, if the count of cars greater than 1 -->
     <relinst type="entitled to" object="multi-car discount" cf="100" >
         <condition expression="countRelationshipInstances(%S,owns vehicle,*) gt 1"  weight="100" behaviour="mandatory" />
     </relinst>

<!-- ================ CONCEPT INSTANCES ================ -->
	
    <concinst name="multi-car discount" type="Discount" />
    
	<concinst name="Vehicle 1" type="Vehicle" />
	<concinst name="Vehicle 2" type="Vehicle" />
	<concinst name="Vehicle 3" type="Vehicle" />

</rbl:kb><?xml version="1.0" encoding="utf-8"?>
<rbl:kb xmlns:rbl="http://rbl.io/schema/RBLang">

<!-- ========================= CONCEPTS ========================= -->

  <concept name="Person" type="string"/>
  <concept name="Age" type="number"/>
  <concept name="Pass" type="string"/>
  <concept name="Occupation Status" type="string"/>
  
<!-- ========================= RELATIONSHIPS ========================= -->

  <rel name="is aged" subject="Person" object="Age" askable="secondFormObject">
    <secondFormObject>How old is %S?</secondFormObject>
  </rel>
  
  <rel name="has occupation status" subject="Person" object="Occupation Status" askable="secondFormObject">
    <secondFormObject>What is the occupation status of %S?</secondFormObject>
  </rel>
  
  <rel name="is eligible for" subject="Person" object="Pass" askable="none"/>
  
<!-- ========================= RULES ========================= -->

<!-- Rule using OR -->  
  <relinst type="is eligible for" object="Bus Pass" cf="100">
        <condition rel="is aged" subject="%S" object="%AGE"/>
        <condition rel="has occupation status" subject="%S" object="%OCCUPATION_STATUS"/>
        <condition expression="(%AGE is greater than 60) or (%OCCUPATION_STATUS is equal to 'Retired')"/>
  </relinst>

<!-- Rule using AND and OR -->
  <relinst type="is eligible for" object="Bus Pass" cf="100">
        <condition rel="is aged" subject="%S" object="%AGE"/>
        <condition rel="has occupation status" subject="%S" object="%OCCUPATION_STATUS"/>
        <condition expression="((%AGE is greater than 60) and (%AGE is less than 80)) or (%OCCUPATION_STATUS is equal to 'Retired')"/>
  </relinst>
  
<!-- ========================= CONCEPT INSTANCES ========================= -->
  
  <concinst name="Bus Pass" type="Pass"/>
  <concinst name="Retired" type="Occupation Status"/>
  
  
  
</rbl:kb>

Version 1.01 – Last Update: 23/02/2021

Bitnami