Complex Expressions
Complex expressions in EL consist of non-atomic value-returning expressions, in a typed, operator-based syntax common to many programming languages and logics. In EL, the syntactic use of operators is understood as a shorthand for specific functions assumed to be available on types inferred from the context of the operator use. An EL implementation would therefore map such operators to the appropriate methods in a class library.
Equality Operator
The equality operator = in EL is understood as the function equal() defined on the type Any, of which every other class is a descendant. For all primitive value types (types for which use in expressions directly generates values rather than instance references), the semantics are value comparison, while for all other types, the semantics are reference comparison. For non-openEHR models, '=' will normally map to a similarly-named method, e.g. equals().
To obtain value comparison for non-value types, the function Any.is_equal(), which may be redefined in any sub-type, is used.
Primitive Operators
Primitive operators in EL are the infix or prefix syntax forms of functions available on primitive types. For example, the operator - (minus) is defined on the class Numeric (an inheritance ancestor of the classes Integer, Real etc) as the following:
|
| in class Numeric
|
subtract (other: Numeric): Numeric
alias infix '-'
|
| redefined in class Integer as
|
subtract (other: Integer): Integer
This means that where the expression 100 - 5 is encountered in EL, what is really invoked is Integer.subtract(), specifically 100.subtract(5).
For convenience, the operators for the Numeric and Boolean types from the openEHR Foundation Types are reproduced below.
| Operators | Function | Meaning |
|---|---|---|
Arithmetic Operators - Numeric operands and result; descending precendence order |
||
|
|
Exponentiation |
|
|
Multiplication |
|
|
Division |
|
|
Modulo (whole number) division |
|
|
Addition |
|
|
Subtraction |
Relational Operators - Numeric, Date/time operands and Boolean result; equal precedence |
||
|
|
Value equality |
|
|
Inequality relation |
|
|
Less than relation |
|
|
Less than or equal relation |
|
|
Greater than relation |
|
|
Greater than or equal relation |
Logical Operators - Boolean operands and result; descending precendence order |
||
|
|
Negation, "not p" |
|
|
Logical conjunction, "p and q" |
|
|
Logical disjunction, "p or q" |
|
|
Exclusive or, "only one of p or q" |
|
|
Material implication, "p implies q", or "if p then q" |
Expressions using logical operators may thus be written using standard English names or symbols, as in the following.
systolic_bp > 140 AND (is_smoker OR is_hypertensive)
systolic_bp > 140 ∧ (is_smoker ∨ is_hypertensive)
In addition, some operators are defined on the other primitive types, including the following.
| Operator | Function | Meaning |
|---|---|---|
|
||
|
|
String concatenation, appending |
|
||
|
|
Add a precise duration to a date |
|
|
Add a nominal duration to a date |
|
|
Subtract a precise duration from a date |
|
|
Subtract a nominal duration from a date |
|
|
Difference of two dates |
|
||
|
|
Add a precise duration to a date/time |
|
|
Add a nominal duration to a date/time |
|
|
Subtract a precise duration from a date/time |
|
|
Subtract a nominal duration from a date/time |
|
|
Difference of two date/times |
|
||
|
|
Add a duration to a time |
|
|
Subtract a duration from a time |
|
|
Difference of two times |
|
||
|
|
Add a duration to a duration |
|
|
Subtract a duration from a duration |
Operator semantics that require further explanation are described below.
Logical Negation
All Boolean operators take Boolean operands and generate a Boolean result. The not operator can be applied as a prefix operator to all operators returning a Boolean result as well as a parenthesised Boolean expression.
Precedence and Parentheses
The precedence of operators follows the order shown in the operator tables above. To change precedence, parentheses can be used in the fashion typical of most programming languages, as shown below.
systolic_bp > 140 AND (is_smoker OR is_hypertensive)
Higher-order Operators
Quantification Operators
The two standard quantification operators from predicate logic there exists (∃ operator) and for all (∀ operator) are defined in EL for the container types found in the openEHR Foundation Types.
The textual syntax of there exists is as follows:
there_exists v in container_var | <Boolean expression mentioning v>
Here, the | symbol is usually read in English as 'such that'. The symbolic equivalent may also be used:
∃ v : container_var | <Boolean expression mentioning v>
The above may also be expressed in EL as its functional equivalent:
list_of_reals: List<Real>
|
| an expression that will return true if list_of_reals
| contains a value greater than 140.0
|
list_of_reals.there_exists (
agent (v: Real): Boolean {
v > 140.0
}
)
The for_all operator has similar textual syntax:
for_all v in container_var | <Boolean expression mentioning v>
Here, the | symbol is normally read in English as as 'it holds that'. The symbolic equivalent may also be used:
∀ v : container_var | <Boolean expression mentioning v>
The above may also be expressed in EL as its functional equivalent:
list_of_reals: List<Real>
|
| an expression that will return true if list_of_reals
| consists of values all greater than 140.0
|
list_of_reals.for_all (
agent (v: Real): Boolean {
v > 140.0
}
)