# Expressions¶

This part describes all language features that are currently supported by OCL.js.

## Context¶

Every OCL rule runs in a specific context. The context constraints the execution of a rule to a specific type. Even though the type system of JavaScript is very basic, the context expression tries to guess the type as follows:

```
function Person() {} => Person
class Person {} => Person
{} => Object
function() {} => undefined
```

To make the type guessing algorithm more flexible to your needs, the function that determines the type can be overwritten by a custom implementation. Checkout the documentation of the OclEngine to see how to override the default behavior.

When calling an OCL rule like the one below, it will only apply on objects which are of type “Person”. “Type of” in context of OCL means, that the object has to be a direct instance of the given type. E.g.: class A extends B then an instance of A is type of A but not type of B.

```
context Person inv:
[...]
```

## Invariant¶

An invariant is a constraint that has to be always true. Whenever an invariant is violated, the whole OCL rule is violated. One can define multiple invariants per context which are started using the keyword inv.

```
inv: self.variable = "value"
```

## Definition¶

When one wants to define additional variables before invariants are executed, one can use the keyword def for creating variable definitions.

```
def: let name: "value"
```

## Mathematical operators¶

The operators =, <, <=, >= and <> can be used to compare literals.

Furthermore, mathematical operations like +, -, *, /, and mod are supported.

### Logic gates¶

Boolean expressions can be concatenated by using the keywords and, or, xor and implies. The way how logic gates work is the same as in all programming languages. But there are two special kinds: xor and implies

#### AND¶

and is used whenever both sides of the condition have to be fulfilled.

```
context Person
inv: self.actsAs = "student" and self.actsAs = "employee"
```

#### OR¶

or is used whenever one of both (or both) sides of the condition have to be fulfilled.

```
context Person
inv: self.actsAs = "student" or self.actsAs = "employee"
```

#### XOR¶

xor is used whenever one of two expressions have to be true. In case of the example A xor B, either A or B but not both may be true to fulfill the condition.

```
context Person
inv: self.actsAs = "student" xor self.actsAs = "employee"
```

#### Implies¶

implies is used whenever one condition leads to another truthy condition: A implies B states, that whenever A is true, B has to be true as well. If A is false, we are not interested in B at all.

```
context Person
inv: self.age >= 0 implies self.isAlive = true
```

## Literals¶

The current implementation supports String, Boolean, Number and Nil literals.

## Collection operations¶

### exists¶

Operation which checks whether a collection contains an element specified by expr.

```
self.collection->exists(item | item.name = "random")
```

### forAll¶

Runs the expression for all elements in collection and returns true if the expression is true for all, false otherwise.

```
self.collection->forAll(c | c.attribute < 10)
```

```
self.collection->forAll(c1, c2 | c1.attribute <> c2.attribute)
```

### select¶

Selects all elements from collection which fit the expr.

```
self.collection->select(item | item.name = "random")
```

### union¶

Concatenates the two given collections and returns one single collection.

```
self.collection->union(self->anotherCollection)
```