## Introduction

Several special grammatical structures within ClauseBase allow you to write conditions.

For example, in the following conditional text, the condition `#applicable-law^name`

expresses the objective that the text that follows after the colon should only be shown if the datafield name of concept `#applicable-law`

is equal to the word `“belgian”`

.

{ #applicable-law^name = "belgian" : ... }

For a list of examples, go to *assemble document* mode and click “help”. Then navigate to “clause samples” and you will be given a link to access the samples library. This library contains a number of examples that explain how certain kinds of conditions work.

## General structure

In their most basic appearance, conditions follow the structure:

*left value comparison operator right value*

### Value types

The left value and right value can be any of the following value types:

type | explanation | examples |

number | whole number, or floating-point number (with decimal part) | `51234` |

text | either between single quotes (‘) or double quotes (“) | `‘Brussels’` |

date | should be expressed as year_month_day | `2000_12_23` (23 Dec 2000)`2016_1_5` (5 Jan 2016) |

currency | a (potentially fractional) number and one of the supported currencies (EUR, USD, JPY or GBP) | `5 EUR` |

duration | a number and a time unit (week, year, day, quarter, or year) | `5 weeks` |

true/false | the truth value true or false | `true` |

list | a uniform or mixed list of elements | `@list(5, 6, 7)` `@list(‘Brussels, ‘Amsterdam’)` `@list(5, ‘Brussels’, 6 days)` |

Floating-point numbers and currencies are supported with up to four numbers after the decimal operator. (You can type in more decimal numbers than four, but they will be ignored. For example, when * 5.34789* would be typed in, ClauseBase will use

*5.3478*.)

The maximum number ClauseBase can store is 99.999.999.999,9999 (99 billion etc).

### Comparison operator

The **comparison operator** can be any of the following:

type | description | example |

= | equal to | `#applicable-law^name = ‘belgian’` |

!= | not equal to | `#parties^amount != 2` |

< | smaller than | `#contract^value < 2000 EUR` |

> | larger than | `#contract^value > 2000 EUR` |

<= | smaller than, or equal to | `#contract^value <= 2000 EUR` |

>= | larger than, or equal to | `#contract^value >= 2000 EUR` |

in | present in the list | `#competent-court^name in @list(‘Brussels’, ‘Amsterdam’)` |

!in | not present in the list | `#product^type !in @list(‘typeA’, ‘typeB’, ‘typeC’)` |

## Datafields

When building conditions for clauses, you can either use **static values** (e.g., `5 weeks`

or `234.5 EUR`

), or use **dynamic values** by referring to datafields through the syntax `#concept^datafield`

(e.g., `#applicable-law^name`

).

Dynamic values can also be obtained through the advanced topic of Data-expressions.

Unlike a static value, the actual value of a datafield is not known by the clause author, and will instead be determined by the clause user — e.g., by submitting a value in the data dashboard, or by selecting a value in a Q&A session. At the moment ClauseBase is about to show a clause, it will look up the current value, and use it in subsequent calculations.

Datafields will always take on one of the value types above (number, text, currency, duration, etc.). This value type needs to be selected upfront when constructing a Concept.

When the user has not yet assigned a value to a datafield, the value of that datafield is said to be *undefined*. When drafting clauses, you should take into account the possibility of such undefined values.

## Mathematical operations

Numerical values can be combined in larger structures through the basic mathematical operations (+, -, / and *). Examples:

```
#contract^value < 5000 EUR + 2400 EUR
#contract^value < 5000 EUR - #liability^cap
(#contract^value * 1.2) < 5000 EUR
```

Note that parentheses can be used to clarify which parts of the formula should be taken first. If no parentheses are used, then the well-known mathematical rules of precedence are used — i.e., multiplication and division take precedence over addition and subtraction, so that `1 + 2 * 3`

is equal to 7 (not 9).

## Details

### Shorthand comparisons

If the operator and right value of a comparison are omitted, then the comparison will result in *true *if the left value:

- is equal to true
- is equal to a non-empty text value
- is equal to a number or currency that is different from zero
- is equal to a duration higher than zero
- is equal to a non-empty list

In other words, the comparison will be *false* if the left value:

- is undefined
- is equal to false
- is equal to empty text (“”)
- is equal to a number or currency that is equal to zero
- is an empty list

This allows you to for example write the following shorthand conditions:

```
{ #contract^value: ... }
{ #contract^duration: ... }
{ #employee^name: ... }
```

In all of these examples, the … will only be shown if the preceding datafield is assigned a decent value. If in the first example the contract value would not have been assigned, or be equal to zero, then the … will not be shown. Similarly, if the duration would not have been assigned, or be equal to zero, or if the employee’s name would not have been assigned, or be set to an empty text, then the … will not be shown in the second and third example.

### Supported mathematical conversions

To a limited extent, values of different types can be combined with each other in comparisons or mathematical operations. The following rules apply:

VALUE TYPE 1 | VALUE TYPE 2 | RESULT | DESCRIPTION OR EXAMPLE |

number | currency | currency | `3000 EUR + 200` results in `3200 EUR` |

duration | duration | duration, with the time unit converted to the most relevant one (*) | `5 months + 3 months` results in `8 months` `1 month + 3 days` results in `34 days` `1 year + 1 month` results in `13 months` `1 year + 3 days` results in `368 days` |

date | duration | date | `2018_7_1 + 1 month` results in `2018_8_1` , while `2018_7_1 + 2 weeks + 1 year` results in `2019_7_15` |

Be aware that chains of mathematical operations on durations can lead to multiple conversions, which can lead to multiple rounding errors.

(*) For example, `1 year + 1 month + 1 day`

will be evaluated in two steps, ultimately resulting in *396 days*.

– first `1 year + 1 month`

(= converted to 13 months)

– then `13 months + 1 day`

(= (13 * average of 30.417 days) + 1 = *396 days*)

### Disallowed mathematical operations

The following mathematical operations will lead to errors in ClauseBase.

- dividing a number by zero
- mixing different currencies (e.g.,
`300 EUR + 500 USD`

) - adding or subtracting dates (e.g.,
`2018_7_15 + 2018_1_1`

*)* - mixing a date/duration and a number (e.g.,
`2018_7_15 + 14`

*,*or`5 weeks + 6`

) - mixing texts with other types (e.g.,
`5 July 2018 + ‘Brussels’`

, or`500 EUR + ‘2 cents’`

)

While it is not possible to perform mathematical operations with dates, it is possible to perform mathematical calculations between dates and durations, and compare the result.

For example, if you would have two dates available and would like to check whether the duration between them is beyond a certain threshold, you could write `#concept^date1 + 3 months < #concept^date2`

.

### Conversion of undefined values

ClauseBase will automatically convert undefined values to values that make sense in comparisons or mathematical operations:

OTHER TYPE | UNDEFINED WILL BE CONVERTED INTO | EXAMPLE |

number | 0 | `5 + undefined` results in `5` `5 * undefined` results in 0 |

currency | 0 (same valuta) | `5 EUR + undefined ` results in 5 EUR results in `5 EUR * undefined` 0 EUR |

duration | duration with length 0 | `5 days + undefined` results in 5 days |

text | empty text | is true`” = undefined` |

list | empty list | `@empty-list() = undefined is true` |

It is not possible to compare a date to an undefined value. (After all, a “zero date” makes little sense…)

### Combining sub-conditions: AND/OR/NOT

Different sub-conditions can be combined through AND, OR and NOT.

For example, the following combination of sub-conditions will only apply if Dutch law applies, and the competent court is simultaneously set to Amsterdam:

`#applicable-law^name = 'belgian' AND #competent-court^location = 'Amsterdam'`

Computer users who first encounter AND/OR conditions, are often confused by them, because they seem to express the opposite of common language.

For example, the sentence *“Marie will go to the city when it is Tuesday and when John calls” *will usually be understood as *“Marie will go on Tuesday, but will also go on other days when John calls”*. Hence, in everyday language, the word “and” can sometimes express that something applies when any of the sub-parts apply. Whether this is indeed the case — or whether “and” should instead be interpreted as *“only apply when both sub-parts apply at the same time”* — can usually be inferred from the context.

In most situations, this linguistical ambiguity is not a problem, because the context will be clear or because the consequences of the wrong interpretation are negligible. However, such ambiguities are sometimes also found in contracts and laws, and then the context may not always be clear, and/or the consequences may be significant

When building conditions in ClauseBase, such ambiguities will not arise, because the word “AND” means *“both sub-conditions must apply”*, and is thereby clearly opposed to the word “OR”, which means *“it is sufficient if any of the sub-conditions applies”*.

Much more complex combinations of sub-conditions are possible. The following combination will only apply if **either **of the following two bullets applies:

- Dutch law applies and the competent court is simultaneously set to Amsterdam; or
- the contract value is higher than 5.000 EUR

`(#applicable-law^name = 'belgian' AND #competent-court^location = 'Amsterdam') OR (#contract^value > 5000 EUR)`

Please note that the way parentheses are used, is very important. The following example is identical to the previous one, with the exception of the parentheses:

`#applicable-law^name = 'belgian' AND (#competent-court^location = 'Amsterdam' OR #contract^value > 5000 EUR)`

The change in parentheses causes a significant change in meaning, because the sub-conditions between parentheses will be evaluated first, before evaluating the other sub-conditions. The combination of sub-conditions will now only apply if **both **of the following sub-conditions simultaneously apply:

- the applicable law is Belgian
- the competent court is Amsterdam AND, in addition, the contract value is higher than 5000 EUR

There is no need to put parentheses within a “chain” of AND sub-conditions. For example:`#applicable-law^name = ‘belgian’ AND #competent-court^location = ‘Brussels’ AND #contract^value > 5000 EUR`

Similarly, it is also fine to create a chain of OR conditions without any parentheses.

What is problematic, however, is to chain AND and OR conditions without parentheses. For example:`#applicable-law^name = ‘belgian’ AND #competent-court^location = ‘Brussels’ OR #contract^value > 5000 EUR`

Should this be understood as: “apply in **any **of the following situations: (1) Belgian law applies and simultaneously the competent court is Brussels; (2) the contract value is higher than 5000 EUR”, or should it instead be understood as “only apply when **both **of the following situations apply: (1) Belgian law applies; (2) either the court of Brussels is competent, or the contract value is 5000 EUR”?

There are rules of precedence that dictate how the software will evaluate this combination of sub-conditions. However, these rules are rather counter-intuitive, so that it is always better to uses parentheses with any mix of AND and OR.

NOT sub-conditions should always be surrounded by parentheses. Example:

```
NOT (#applicable-law^name = 'belgian' AND
#competent-court^location = 'Brussels' AND #contract^value > 5000 EUR)
```

This combination of sub-conditions will apply when the following combination of situations does ** not **simultaneously apply:

- Belgian law applies
- the competent court is Brussels
- the contract value is higher than 5000 EUR

In other words, this combination of sub-conditions will apply when Belgian law would not apply, or when the competent could would not be Brussels, or when the contract value would be lower than (or equal to) 5000 EUR.

Note that AND / OR can always be converted to each other with the help of NOT:`NOT(A OR B)`

is equal to `((NOT A) AND (NOT B))`

`NOT(A AND B)`

is equal to `((NOT A) OR (NOT B))`

The previous example with a chain of ANDs can therefore also be converted to a chain of OR, with the operators (= and >) reversed:`#applicable-law^name != ‘belgian’ OR #competent-court^location != ‘Brussels’ OR #contract^value <= 5000 EUR`

### “Short-circuiting” of conditions

Please note that ClauseBase will stop evaluating a condition as soon as it can.

In the example below, the second part (“beta”) will never be used, because:

- either the contract value is higher than 5000, in which case the first part (“alpha”) will be used and the second part subsequently gets ignored
- or the contract value is lower than 5000, in which case both the first and second part will be skipped

`{#contract^value > 5000: alpha | #contract^value > 5000 and #applicable-law^name = 'belgian': beta}`

New users of ClauseBase are sometimes confused by this behaviour, but this so-called “short-circuiting” is actually a handy feature you can make use of. For instance, when testing with certain clauses or conditions, you can quickly prepend a `true: ...`

condition to temporarily avoid that any of the other conditions would get evaluated. In the example below, the second and third part will be completely ignored by the software, because the first part (the short-hand condition `true`

) will always be true, so the software can immediately stop its evaluation of the condition.

`{true: xxxx | #contract^value > 5000: alpha | #applicable-law^name = 'belgian': beta}`

Similarly, you can for safely write

`{#contract^interest != 0 AND (#contract^value / #contract^units > 5000): ... }`

Without the short-circuiting functionality, the software would throw a “divide by zero” error when the interest would happen to be equal to zero. With the short-circuiting functionality, however, you can rest assured that the second limb of the AND will be completely skipped when the interest would happen to be zero, because in such case the software knows that an AND-condition will result in `false`

as soon as one of its limbs is false.

Of course, the same is not true for an OR-condition: the software needs to evaluate each of the limbs of an OR-expression to search for any limb that happens to be `true`

.