openEHR logo

Expression Language and Model

Issuer: openEHR Specification Program

Release: latest

Status: DEVELOPMENT

Revision: [latest_issue]

Date: [latest_issue_date]

Keywords: openehr, expressions, rules

openEHR components
© 2016 - 2018 The openEHR Foundation

The openEHR Foundation is an independent, non-profit community organisation, facilitating the sharing of health records by consumers and clinicians via open-source, standards-based implementations.

Licence

image Creative Commons Attribution-NoDerivs 3.0 Unported. https://creativecommons.org/licenses/by-nd/3.0/

Support

Issues: https://openehr.atlassian.net/browse/SPECPR/
Web: www.openehr.org

Amendment Record

Issue Details Raiser, Implementer Completed

2.0.0

SPECBASE-3. Major rewrite. Added external model use;
added defined() and check() predicates;
refined quantifiers;
add BMM integration;
added various kinds of binding;
change 'EL Text' to 'EL Module' in most cases.

T Beale

19 Sep 2018

1.1.0

SPECPUB-6. Correct UML package nesting and paths in documents; insert base parent package; rename expressions package to expression.

T Beale

27 Nov 2017

1.0.1

Correct type of OP_DEF_EXISTS.evaluation_agent to FUNCTION<<Any>, Boolean>.

C Nanjo

31 May 2016

1.0.0

Initial writing. Taken from AOM2 2.0.6.

T Beale,
openEHR SEC

15 Feb 2016

Acknowledgements

Primary Author

  • Thomas Beale, Ars Semantica; openEHR Foundation Management Board.

1. Preface

1.1. Purpose

This document specifies the openEHR Expression Language Object Model (ELOM) and an abstract syntax, denoted the openEHR Expression Language (openEHR EL). The ELOM defines the semantics of a first order predicate style logic that can be used to express assertions (e.g. in archetypes) and rules. e.g. in decision support situations.

The intended audience includes:

  • Standards bodies producing health informatics standards;

  • Academic groups using openEHR;

  • Solution vendors.

Prerequisite documents for reading this document include:

Releated documents include:

1.3. Status

The contents of this specification were separated out from the AOM2 specification in order to provide a common model of expressions and rules structures for AOM, GDL and other specifications requiring it.

This specification is in the DEVELOPMENT state. The development version of this document can be found at www.openehr.org/releases/RM/latest/expression.html.

Known omissions or questions are indicated in the text with a 'to be determined' paragraph, as follows:

TBD: (example To Be Determined paragraph)

Users are encouraged to comment on and/or advise on these paragraphs as well as the main content. Feedback should be provided either on the technical mailing list, or on the specifications issue tracker.

1.4. Conformance

Conformance of a data or software artifact to an openEHR Reference Model specification is determined by a formal test of that artifact against the relevant openEHR Implementation Technology Specification(s) (ITSs), such as an IDL interface or an XML-schema. Since ITSs are formal, automated derivations from the Reference Model, ITS conformance indicates RM conformance.

2. Overview

The openEHR Expression Language Object Model (ELOM) defines the semantics of all of the elements of computable expressions that are used in openEHR, and are likely to be used in healthcare and life sciences computing where rules and expressions are needed. The model is designed as an extensible core formalism suitable for use and extension in other formalisms.

The openEHR Expression Language (EL) specified here is an abstract syntax counterpart to the Expression Language Object Model, and may be considered a default syntax. Other syntaxes or syntax variants are certainly possible, and other serialisation methods are possible, such as object graph serialisation into XML, JSON, YAML etc. The EL is provided firstly as a way of specifying and explaining the semantics of the ELOM, and secondly, as one way of actually authoring expressions and rules in textual form. This approach is the same as with any programming language, where the usual form for learning and programming is the abstract language form, while the computational form is an abstract syntax tree (AST) or similar.

Accordingly, the ELOM should be considered the normative definition of the openEHR Expression formalism, and indeed not all implementations need support the language: they might for example only serialse in JSON or use purely graphical visualisation.

TBD: possibly the following is no longer true.

The formalism as defined here requires extensions for use, at a minimum to provide concrete value referencing. Extensions would also typically provide more operators, functions, leaf types and other features that are needed in specific circumstances.

Key features of the formalism include:

  • variable declarations, assignments and expressions;

  • strong typing;

  • the ability to use externally defined information models;

  • standard logical operators including universal and existential quantification, as well as user-defined operators;

  • standard arithmetic and relational comparison operators, enabling the use of numerics;

  • parentheses for overridding operator precedence;

  • functions, including built-ins like current_date, standard functions like max() as well as user-defined functions.

For reasons of comprehensibility and explanation, the Expression Language is defined first in this specification.

2.1. Design Background

The openEHR Expression formalism is based on a limited first-order predicate logic language with extensions for numeric sub-expressions. It has similarities with OMG’s OCL (Object Constraint Language) syntax, and is also similar to the assertion syntax used in the [Object_Z] and [Eiffel] languages and tools for over a decade (see [Sowa], [Hein], [Kilov_Ross] for an explanation of predicate logic in information modelling). None of these languages has been used directly, for reasons including:

  • OCL has a complex type system connected to the UML meta-model, and includes some undecidable procedural semantics;

  • none have adequate variable referencing mechanisms, such as to paths and external queries.

There are also similarities with other languages developed in the health arena for expressing 'medical logic' (Arden [hl7_arden]), guidelines ([GLIF] and many others) and decision support (e.g. GELLO [hl7_gello]). These languages were not directly used, for reasons including:

  • none have an easily extensible value referencing mechanism;

  • some are too procedural (Arden, GLIF);

  • current versions of some of these languages have been made specific to the HL7v3 RIM, a particular model of health information designed for message representation (GLIF 3.x, GELLO).

Nevertheless, various elements of Arden and GELLO provided useful inspiration for the formalism described here.

Modern syntaxes that provide a more generic and minimal inspiration for the expression syntax described here include the Xpath syntax.

2.2. Requirements

The semantic requirements are for expressions including arithmetic, boolean, and relational operators, functions, logical quantifiers, operator precedence, constant values, and variables. However, there is no support in the core specification for procedural semantics or most of the other complexities of full-blown programming languages.

In addition, there is a need to be able to provide:

  • multi-lingual translations for symbolic variables, in a similar way to the openEHR Archetype Definition Language (ADL);

  • bindings that connect variables to external data sources;

  • an ability to use externally defined information models that supply types that may be used in EL statements.

2.3. Design Paradigm

The assumed execution model of the Expression language is that EL statements are evaluated by an evaluator against a data context, which determines the truth values of the expression(s). The data context is the origin for some or all of the variables mentioned in the expressions, which may be read from and written to. It may concretely be a retrieved data structure, or data via an API call to the EHR, demographics, laboratory system etc.

The data context may be specified in two ways. It may be visible within the artefact or computing context in which the EL statements appear, or it may be specified explicitly. In the first case, the EL instance is minimally a value-returning logical proposition such as $systolic_pressure > 0. This is shown below.

EL design structure implicit
Figure 1. EL design structure - implicit context

In the explicit form, an EL Module consisting of multiple statements and an explicit context definition is used, as shown below.

EL design structure explicit
Figure 2. EL design structure - explicit context

In both cases, the result of parsing into computable form for evaluation must result in an instance of the Expression Language Object Model (ELOM), which will include instances of BMM classes, as these are used to represent the definitions of which expression elements (function calls, variable references etc) are uses.

This specification first describes the elements of the EL expression syntax, then the ELOM.

2.4. Expressions and Ontic Truth

No assumption is made about whether the data context used is complete or faithful to reality. Consequently, the expression universe is technically speaking an 'open world' in the sense of the open-world assumption. However, higher-level applications or components (or users) may have sufficient knowledge about the data as to be able to treat it in a closed world fashion, for example to treat absence of X as negation of X.

3. EL Basics

3.1. Overview

The openEHR Expression Language (EL) syntax is defined in a number of layers. The core of the language defines expressions, which are value-returning entities formed by reference or invocation of declared entities such as variables, functions and constants. Expressions may be used in isolation within some larger context in an openEHR system (e.g. Plan or Guideline), with the connection of variables to real-world data being determined implicitly, as described above.

The next layer includes non-expression elements, allowing explicit declarations, assignments and control structures, including rules. These are known as statements. A collection of statements may be used within another context in the same way as bare expressions.

The fullest form of EL syntax is an EL Text which provides all of the context, terminology, meta-data and so on, enabling the representation of fully-formed guidelines and other similar artefacts.

These layers are shown below.

EL language structure
Figure 3. EL language structure

3.2. Syntax style

The syntax style used in EL is of the Pascal variety, i.e. words rather than programming symbols such as braces ({}). The intention is to provide a syntax that is more easily readable to non-IT professionals as well as IT professionals, since it is likely that healthcare professionals will be among the principle authors of EL texts. This choice leads to syntax such as the following.

    -- a universal quantifier expression
    if for_all v in $systolic_bp_samples : v <= Systolic_bp_threshold then
        -- statements
    end

    -- a when/then block
    when $systolic_bp
        matches |>= 200.0| then
            -- statements to raise emergency alert

        matches |>= 180.0| then
            -- statements to request nurse check

        ...
    end

In the above, nearly all lexical elements are words, such as if, in, when, then and so on, leading to a more natural reading experience.

Nevertheless, the style chosen here should not be regarded as fixed forever, and indeed it is a relatively simple matter to create alternative 'syntax skins', such as one for developers used to C language syntax descendants such as Java, TypeScript and so on.

The lexical style used is so-called 'snake_case' rather than so-called 'CamelCase', in common with other openEHR specifications, but either may be used in real applications. One reason for using snake-case may be to render EL Modules more readable to the non-IT professional.

3.3. Types

The Expression language is fully typed, and assumes the same set of Foundation Types as other openEHR components, namely:

  • primitive types;

  • container types:

    • List<T>, i.e. an ordered list of elements of primitive type T;

    • Set<T>, i.e. a set of elements of primitive type T;

    • Hash<K:Ordered,V>, i.e. a Hash table or dictionary;

  • an interval type:

    • Interval<T: Ordered> where T is any ordered primitive type, i.e. Integer, Real, and any of the Date/time types.

Complex types based on these types may also be used in EL.

3.3.1. Primitive Types

The primitive types are shown below.

Name Description

Boolean

Boolean value

Integer

Integer value

Real

Real value

Date

ISO8601-format date

Date_time

ISO8601-format date/time

Time

ISO8601-format time

Duration

ISO8601-format duration

String

String

Uri

Uri in IETF RFC3986 format

Terminology_code

Terminology code reference

Automatic type promotion from Integer to Real applies to all integer and real values and expressions, in the same fashion as most programming languages.

TBD: do we need Integer64 and Real64?

3.3.2. Container Types

The same container types as defined in the BASE Foundation Types specification are supported in EL, as follows.

Name Description

Container<T>

Abstract parent of List, Set and Hash types

List<T>

Linear list of items of any primitive type, allowing order and repeated membership

Set<T>

Set of items of any primitive type; no order, unique membership

Hash<K:Ordered, V>

Indexed linear container

TBD: the following is functional style; we would need keywords to enable it in the EL syntax, e.g. has etc. Also, has() can be done via there_exists().

The above types each have an assumed interface consisting of functions and procedures that apply to all members of the container, consistent with the semantics of the container. These include the following.

    has (v: T): Boolean
            -- True if container contains v

Any such method may be accessed in the usual way, using dot notation, i.e. as shown below for the method has().

    heart_rrate_samples: List<Real>
    High_threshold: Real = 200.0

    if heart_rate_samples.has (High_threshold) then
        -- statements
    end

3.3.3. Interval Type

The same Interval type as defined in the BASE Foundation Types specification is supported in EL, as follows.

Name Description

Interval<T>

Interval of any ordered primitive

Automatic type promotion from Interval<Integer> to Interval<Real> applies to all integer and real values and expressions, in the same fashion as most programming languages.

TBD: the following is functional style; we would need keywords to enable it in the EL syntax, e.g. contains, overlaps etc.

Various methods are defined for Interval<T>, as follows.

    has (v: T): Boolean
            -- True if for Interval contains v

    overlaps (other: like Current): Boolean
            -- True if this Interval overlaps other

    contains (other: like Current): Boolean
            -- True if this Interval contains other

3.3.4. Complex Types

Complex types may be implicitly accessible, or explicitly imported from formal model definitions specified in the use_model section of an EL Module. Such models need to be specified in openEHR BMM format, or any functional equivalent. The types in models included in this way become available within the formalism in the same way as the foundation types, and may be used in declarations etc in the normal way.

Access to interior elements of instances of non-primitive types is obtained using 'dot' notation, i.e. the standard way for object-oriented languages.

3.4. Function and Procedure Calls

In EL, the function and procedure calls are the primary means to make complex logic available to expressions. Both functions and procedures are supported, and are collectively known as routines, as per the openEHR Basic Meta-Model (BMM).

In EL, a function is a routine that returns a result and is assumed to have no side-effects on previously declared entities. It has a signature of the form:

    <T_arg1, T_arg2, ....>: T_result

Typical examples of function signatures:

    : Date                          -- signature of a 0-order function like current_date()
    <Real, Real>: Real              -- signature of a 2nd-order function like '*' for the domain R
    <Integer, Integer>: Integer     -- signature of a 2nd-order function like 'add' for the domain I

A procedure is a routine with a signature of the form:

    <T_arg1, T_arg2, ....>

This represents a call taking 0 or more arguments, with no return type. Typical procedure signatures include the following:

    <Real>                          -- a 1st-order procedure for the domain R
    <String, Integer>               -- signature of a procedure taking a String and an Integer argument

EL does not provide a way to programmatically define routines (i.e. it does not try to be a programming language), instead, it provides a way of declaring routine signatures, using the func and proc keywords. This is similar to the declaration of methods in interface classes in languages like C# and Java.

Functions and procedures are mapped to class methods in external libraries in the Computing Bindings section of an EL Module.

4. EL Expressions

4.1. Overview

Formally, an openEHR EL expression is any of the following value-returning entities:

  • terminal entities:

    • literals;

    • constants;

    • symbolic variables;

    • function calls;

  • predicates:

    • defined() predicate: special expression for determing validity of external variable;

  • complex expressions created from:

    • equality operator: equality operator;

    • primitive operators: arithmetic operators, relational operators, boolean operators;

    • collection operators: logical quantification operators.

Each of these is described in detail in the following sub-sections.

EL is designed syntactically as a readable language while being underpinned by fully class-based functional semantics, which are supplied either by a minimal built-in core, and mostly by bindings to external computing context. In this way, syntax elements such as the '+' operator for the Date type, or the for_all universal quantifier operator may be mapped to underlying methods such as Date.add() and Container.for_all().

EL is not intended for writing functions or classes, rather it is designed as a minimalist logic-based language in which expressions can be written, but whose programming is undertaken inside libraries in existing programming languages. Routine declarations in EL are the primary mechanism to connect external software libraries to the EL context. In EL, both functions and procedures are supported, and are collectively known as routines.

4.2. Terminal Entities

This section describes the various kinds of terminal entities that may appear in EL expressions.

4.2.1. Literals

Literal values are expressed in the ODIN syntax, with the exception of List<T> and Set<T> which are distinguished in EL with specific types of brackets.

Type Literal value Notes

Boolean

True, False

Integer

10, -4, 1024

Real

10.0, 0.345

Date

2004-08-12

ISO8601-format date

Date_time

2004-08-12T12:00:59+0100

ISO8601-format date/time

Time

12:00:59

ISO8601-format time

Duration

P39W

ISO8601-format duration

String

"this is a string"

[blood_pressure]

Extract the string value for the symbol blood_pressure from the EL terminology

Uri

https://en.wikipedia.org/wiki/Everest

Uri in IETF RFC3986 format

Terminology_code

[snomed_ct::389086002]
[snomed_ct::389086002|Hypoxia|]

Terminology code in openEHR format

List<T>

[val, val, …​]

Set<T>

{val, val, …​}

Hash<K:Ordered, V>

<
["key1"] = <val1>
["key2"] = <val2>
…​
["keyN"] = <valN>
>

A table of values of any type V,
keyed by values of any Ordered descendant K,
typically String or Integer

Interval<T>

|N..M|

the two-sided interval N >= x <= M

|>N..M|

the two-sided interval N > x <= M

|N..<M|

the two-sided interval N >= x < M

|<N|

the one-sided interval x < N

|>N|

the one-sided interval x > N

|<=N|

the one-sided interval x <= N

|>=N|

the one-sided interval x >= N

|N +/-M|

the two-sided interval of N ±M

|N±M|

the two-sided interval of N ±M

Literal values may be used in EL expressions, as follows.

    $kmh := 1.6 * $mph

4.2.2. Constants

Symbolic constants may be used in any EL expression. As with variables, constants are typed, and are either declared explicity in the EL text (see next section), or assumed to be available in the execution environment. Constants are syntactically represented using labels of whch the first letter is capitalised, and may be of any type, including complex types. The following are EL statements using constants.

    $kmh := Mph_to_kmh_factor * $mph
    Safe_glucose_limits.has ($glucose_meas)

4.2.3. Variables

Symbolic variables are of two types: local and external. Local variables are represented by plain names such as is_smoker, and are typically used as intermediate variables within a larger set of statements that generates some final value.

External variables represent data entities in the operational data context, and are either assumed from elsewhere in the computational context, or else declared in a data_context section (see next section).

Typical expressions containing variables are as follows.

    $glucose < 6.5                          -- an external variable

    age := current_date() - $date_of_birth  -- age is a local variable

4.2.4. Function Calls

In EL expressions, computational functions may be called in the same way as programming languages. The following example shows a function declaration for a function tnm_major_number() that extracts various elements of Tumour/Node/Metastasis ('TNM') cancer staging values, such as 'Tis', 'G3' and so on, and uses them in a Boolean expression whose value is assigned to the variable is_luminal_A.

    func tnm_major_number (tnm_val: String): Integer

    is_luminal_A := tnm_major_number ($tnm_t) < 3 and
                     tnm_major_number ($tnm_n) < 2 and
                     tnm_major_number ($tnm_g) < 3

To be evaluated, function calls must be mappable to class methods in external libraries that are available at EL statement execution time.

4.2.5. Built-in Functions

Some common functions are assumed to be provided in an EL environment, in order to enable EL expressions to be more standardised. These can be provided by the implementation using the above methods of declaration and external binding.

The built-in functions are listed below.

    current_date(): Date                   -- obtain today's date
    current_time(): Time                   -- obtain the current clock time
    current_date_time(): Date_time         -- obtain the current date and time

    sum (Container<T: Numeric>): T         -- compute the sum of members in a container
    min (Container<T: Numeric>): T         -- compute the minimum value in a container
    max (Container<T: Numeric>): T         -- compute the maximum value in a container
    avg (Container<T: Numeric>): T         -- compute the average value in a container

    count (Container<T>): Integer          -- compute the number of items in a container

These functions operate as a shorthand for underlying object-oriented calls defined on various kinds of objects, and would be implemented by such mappings. For example, current_date() might be mapped to a now() function on the type Date. The statistical functions sum() etc might be mapped to functions of similar names on types such as Container_numeric, derived from Container<T: Numeric>.

4.3. Predicates

EL predicates are special meta-operators that enable execution to be modified depending on the truth values and availability of referenced data items.

4.3.1. defined() Predicate

Variables that are bound to entities in the data context function differently from local variables, since their availability is predicated on the existence of the relevant entities. For example, the variable body_weight may be bound to a call that retrieves a patient weight from the EHR, via an appropriate API call. There is no guarantee that the value is available, so body_weight may therefore be undefined in a sense not applicable to local variables. In a programming language, if a variable is not explicitly set, it has either the default value of the type (e.g. 0 for Integer) or a random value of the correct type. This behaviour is appropriate for local variables, but for external variables that cannot be evaluated because the external entity does not exist, an explicit mechanism is needed to test for validity.

The approach used for EL is to allow external variables to be used freely, as for local variables, but if an external variable cannot be evaluated from the data context, an 'undefined value' exception is generated, indicating which variable could not be evaluated. The defined() predicate provides a way of making an explicit check to avoid an exception, as follows.

    if defined ($heart_rate) and defined (blood_pressure) then
        -- statements mentioning $heart_rate and blood_pressure
    end

Another difference between external and local variables is when they are evaluated. In the execution of a larger EL text containing multiple mentions of an external variable v, is v read from the data context only once, at the first mention, or is it evaluated new each time, or on some other basis? The approach used in EL is to allow the evaluation basis to be stated in the context binding section of an EL text using the currency property.

4.4. Complex Expressions

Complex expressions in EL consist of non-atomic value-returning expressions, in a familiar typed, operator-based syntax common to many programming languages and logics. In EL, the syntactic use of operators is understood as a shorthand for certain functions assumed to be available on certain types, and an EL implementation would map such operators to the appropriate methods in a class library.

4.4.1. Equality Operator

The equality operator = is special in EL as in most languages, and has two meanings. For all primitive types, the semantics are value comparison, while for container and other non-primitive types, the semantics are reference comparison.

4.4.2. Primitive Operators

Primitive operators in EL are the infix or prefix syntax form of various 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 (using syntax from Java, TypeScript and similar languages):

    T function minus<T extends Numeric> (T other)

This means that where the expression 100 - 5 is encountered in EL, what is really invoked is Integer.minus(), specifically 100.minus(5).

The operators for Numeric and Boolean types supported in EL are shown below.

Identifier Textual
Rendering
Symbolic
Rendering
Meaning

Arithmetic Operators - Numeric operands and result; descending precendence order

exp

^

^

Exponentiation

times

*

*

Multiplication

divide

/

/

Division

mod

%

%

Modulo (whole number) division

plus

+

+

Addition

minus

-

-

Subtraction

Relational Operators - Numeric, Date/time operands and Boolean result; equal precedence

eq

=

=

Value equality

ne

!=

Inequality relation

lt

<

<

Less than relation

le

<=

Less than or equal relation

gt

>

>

Greater than relation

ge

>=

Greater than or equal relation

Logical Operators - Boolean operands and result; descending precendence order

not

not, ~

Negation, "not p"

and

and

Logical conjunction, "p and q"

or

or

Logical disjunction, "p or q"

xor

xor

Exclusive or, "only one of p or q"

implies

implies

Material implication, "p implies q", or "if p then q"

Constraint Operators - Boolean result

matches

matches

Set membership, as per openEHR ADL

In addition, some operators are defined on the other primitive types, corresponding to underlying functions defined on the relevant types. These are as follows:

Operator Typical
method
Meaning

String Operators

+

append(other: String)

String concatenation, appending

Date/time arithmetic operators

+

Date.add(d: Duration): Date

Add a duration to a date

+

Time.add(d: Duration): Time

Add a duration to a time

+

Date_time.add(d: Duration): Date_time

Add a duration to a date/time

+

Duration.add(d: Duration): Duration

Add a duration to a duration

-

Date.subtract(d: Duration): Date

Subtract a duration from a date

-

Time.subtract(d: Duration): Time

Subtract a duration from a time

-

Date_time.subtract(d: Duration): Date_time

Subtract a duration from a date/time

-

Duration.subtract(d: Duration): Duration

Subtract a duration from a duration

-

Date.diff(d: Date): Duration

Difference of two dates

-

Time.diff(d: Time): Duration

Difference of two times

-

Date_time.diff(d: Date_time): Duration

Difference of two date/times

Duration arithmetic operators

+

Duration.add(d: Duration): Duration

Add a duration to a duration

-

Duration.subtract(d: Duration): Duration

Subtract a duration from a duration

Operator semantics that require further explanation are described below.

4.4.2.1. 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.

4.4.2.2. 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.

    at_risk := $systolic_bp > 140 and ($is_smoker or $is_hypertensive)

4.4.3. Collection Operators

A common need in an expression language featuring container types (i.e. sets, lists etc) is the need to perform basic reasoning over them. The two standard operators from predicate logic there exists (∃ operator) and for all (∀ operator) are defined in EL for the container types, and are kinds of Boolean-returning expressions.

The 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 expression may be used as in the following example:

    if there_exists v in $systolic_bp_samples : v > Systolic_bp_threshold then
        -- statements
    end

The for_all operator has similar syntax:

    for_all v in container_var : <Boolean expression mentioning v>

Here, the : symbol is normally read as 'it holds that' A typical use is as follows:

    if for_all v in $systolic_bp_samples : v <= Systolic_bp_threshold then
        -- statements
    end

The syntactic form of these two operators can be understood as a shorthand for the following underlying functions defined on the container types, available in most programming language libraries. The argument to both functions is a function object with signature <v:T>: Boolean.

    there_exists (test(v: T): Boolean): Boolean
            -- True if there is any v in container for which test (v) is True

    for_all (test(v: T): Boolean): Boolean
            -- True if for every v in container, test (v) is True

5. EL Statements

5.1. Overview

There are various kinds of non-expression statement in EL including declarations, assignments and control structures. None is value-returning, in contrast to the expression elements of the language. In order to represent these elements, a structure of EL statements consisting of several sections is assumed. The main statements occur in a definition section, while two other optional sections are added, enabling constants and external variable declarations respectively to be made.

The logical structure of an EL structured text is thus as follows:

reference
    <declarations of constants>

data_context
    <declarations of external '$' variables>

definition
    <statements>

The following subsections describe these elements.

5.2. Declarations

5.2.1. Constants

Constants are defined via the use of the equality operator = in type declarations in the reference section, as follows.

reference
    Mph_to_kmh_factor: Real = 1.6
    Pounds_to_kg: Real = 0.4536
    Safe_glucose_limits: Interval<Real> = |0.0..6.5|

The result of the declaration is to define the symbols Mph_to_kmh_factor and Pounds_to_kg as immutable constants.

Constants of complex types are declared using the ODIN syntax, for example, the following manifest value of type DV_QUANTITY from the openEHR Data Types Model.

reference
    Threshold_ogtt_glucose: DV_QUANTITY = <
        magnitude = <6.5>
        units = <"mmol/L">
    >

TBD: could also use archetype fragments here, as matching templates.

5.2.2. Variables

Symbolic variables are declared in two forms. The syntax name: Type is used for local variables, which are declared in the definition section.

External variables are declared in the data_context section, using the syntax in|out|in_out name: Type. The direction specifier indicates the intended use of the variable in the defnition, i.e. in = readable, out = writable, in_out = readable and writable.

In both cases, multiple variables may be declared on the same line. The following shows various declarations:

data_context
    in $date_of_birth: Date
    in $weight, height: Real
    out $bmi: Real
    in $bp_obs: OBSERVATION;

definition
    age_in_years: Integer
    heart_rate_samples: List<Real>

Every external variable must have a counterpart in the EL data context to be processable.

With explicit declarations added, the earlier there_exists examples is as follows:

reference
    Systolic_bp_threshold: Real = 160.0

data_context
    $systolic_bp_samples: List<Real>

definition
    if there_exists v in $systolic_bp_samples : v > Systolic_bp_threshold then
        -- statements
    end

5.3. Assignment

An assignment is a kind of statement used to assign the value of an expression to a writable variable using the := operator. An assignment may be made in a local variable declaration in the same way as in many programming languages. The right hand side of an assignment is any value-returning expression. Typical assignments are illustrated below.

definition
    speed_kmh: Real                             -- declaration
    speed_mph: Real := 35.0                     -- assignment in a declaration (not a constant)

    speed_kmh := speed_mph * Mph_to_kmh_factor  -- assignment

The following shows an assignment with an expression using a function and an external variable.

data_context
    in $date_of_birth: Date

definition
    age: Duration
    age := current_date() - $date_of_birth
    ...

5.4. Procedure Invocation

EL supports the invocation of procedures in the same way as for functions. Computationally both are the same, being invocations of class methods or other functions defined in bound libraries.

The following shows a typical procedure declaration and invocation.

    proc alert_user (message: String; priority: Integer)    -- a procedure that generates a user alert

    if $systolic_bp_meas > 180.0 then
        alert_user ([dangerous_blood_pressure], 1)          -- call the procedure
    end

5.5. Control Structures

A small number of control structures are provided in EL. They provide conditional logic structures from which statements (i.e. assignments and procedure calls) can be executed. Control structures may be nested in the usual way.

5.5.1. Check / then

EL provides a way of controlling execution when exceptions may occur, using a check statement, as follows.

    check $heart_rate > 0.0

The meaning of this is that if the condition evaluates to False, a check violation is generated, which may be handled by an exception handler.

The check instruction can be used in a block form to ensure certain conditions hold on entry to the block, as follows:

    check $heart_rate > 0.0 then
        -- statements mentioning $heart_rate
    end

Another typical use of check is to ensure a variable is defined before use in statements, as follows:

    check defined ($heart_rate > 0.0) then
        -- statements mentioning $heart_rate
    end

To assert that a certain part of a larger data structure exists depending on values elsewhere (usually in the same structure, but not necessarily), the following construct can be used:

    check $is_smoker = True implies defined ($smoking_details)

TBD describe exception handling.

5.5.2. If / then

In common with most programming languages, EL provides a standard 'if / then / elseif / else' structure, as follows:

data_context
    in $systolic_bp_meas: Real     -- from instrument
    in $thyroid_t3: Real           -- from EHR

definition
    if $systolic_bp_meas > 160.0 then
        alert_user ([dangerous_blood_pressure], 1)

    elseif $systolic_bp_meas > 140.0 and $thyroid_t3 > 200 then
        inform_user ([raised_bp_and_abnormal_thyroid_activity], 2)

    else
        -- other cases
    end

This structure is always evaluated in order.

5.5.3. When / then

EL provides a when / matches / then statement that is roughly equivalent to 'case' or 'switch' statements in most other languages. The when part indicates a value-returning expression (such as a variable reference), which may be of any type, while the matches parts define value intervals that are used to match the when value. The first branch matched is executed.

the syntax is as follows.

    when <expression>
        matches <value_interval_1> then
            -- statements
        matches <value_interval_2> then
            -- statements
            ...
        matches <value_interval_N> then
            -- statements

        else
            -- statements
    end

The syntax for the match intervals is the standard EL Interval type literal syntax. An example 'when / then' statement is as follows:

data_context
    in $systolic_bp_meas: Real     -- from instrument

definition
    when $systolic_bp_meas
        matches |>= 180.0| then
            alert ([dangerous_blood_pressure], 0)

        matches |>= 160.0| then
            alert ([high_blood_pressure], 1)
    end

6. EL Modules

6.1. Overview

The Expression Language may be used to write a self-standing EL Module that in addition to the EL statements, contains data context definitions, terminology and other meta-data, in a structure similar to an archetype. Such a text constitutes a sufficient input to a parser / generator to build a complete computational representation as an instance of the Expression Language Object Model (ELOM).

The core sections of an EL Module are expressed in the sections described above, i.e. reference, data_context, and definition. The data context declarations may be thought of parameter lists of input and output variables from the external world (e.g. measured from a patient) for the definition section, which contains the main logic.

The symbols used in statements are names in the fashion of any typical programming language, but are also considered codes to which linguistic definitions can be attached for use in the UI and other human-consumable renderings (e.g. documents). This is done in a terminology section of an EL Module, in the same way as for the openEHR archetype formalism. For example, the symbol $heart_rate of type Integer may have the linguistic definitions "heart rate" (English) and "frequência cardíaca" (Portuguese).

Mappings between external variables and external entities are described by bindings in a data_bindings section. For example, the expression $heart_rate > 50 is an assertion about values found in some data - i.e. $heart_rate is an external variable that may be mapped to an entity representing an actual heart rate measurement. Each data binding states where a variable’s value is obtained from (e.g. some larger data entity such as a document or message, or via an API call). This provides clear semantics for statements in the expression text that mention such variables.

In addition to these computable sections, various meta-data sections are added, including the description and language sections defined by the openEHR Resource specification, and an identification line at the top. As with archetypes, the sections other than use_model, reference, data_context, and definition are expressed in openEHR ODIN syntax.

Finally, EL Modules can be defined modularly, uniquely identified, and included into other EL Modules via the import keyword.

The structure of a self-standing EL Module is thus as follows:

<identifier>

import
    <identifier>
    <identifier>
    ...

language
    original_language = <...>
    translations = <...>

description
    <descriptive meta-data>

use_model
    <model ids>

reference
    <constant definitions>

data_context
    <declarations>

definition
    <statements>

terminology
    <symbol_definitions>

data_bindings
    <symbol bindings>

computing_bindings
    <method bindings>

An example of an EL Module representing the common clinical health measure 'BMI' (body mass index) is shown below.

openEHR-ELOM.bmi.v1

language
    original_language = <[ISO_639-1::en]>
    translations = <
        ["pt"] = <...>
    >

description
    lifecycle_state = <"unmanaged">
    original_author = <...>
    details = <
    ["pt"] = <
        language = <[ISO_639-1::pt]>
            purpose = <"Cálculo do peso do corpo">
            use = <"...">
        >
    >

use_model
    org.openehr.rm

data_context
    in $body_weight, $height: Real
    out $bmi: Real

definition
    $bmi := $body_weight / $height ^ 2

terminology
    symbol_definitions = <
        ["en"] = <
            ["body_weight"] = <
                text = <"body weight">
                description = <"weight of subject body">
            >
            ["height"] = <...>
            ["bmi"] = <
                text = <"body mass index">
                description = <"body mass index">
            >
        >
        ["pt"] = <
            ["body_weight"] = <
                text = <"peso do corpo">
                description = <"peso do corpo do sujeito">
            >
            ["height"] = <...>
            ["bmi"] = <
                text = <"índice de massa corporal">
                description = <"índice de massa corporal">
            >
        >
    >

data_bindings
    content_bindings = <
        ["openEHR-EHR-OBSERVATION.body_measurements.v1"] = <
            ["body_weight"] = <
                target = <"/data/events[id3]/data/items[id5]/value/magnitude">
                direction = <"in">
            >
            ["height"] = <
                target = <"/data/events[id3]/data/items[id6]/value/magnitude">
                direction = <"in">
            >
        >
        ["openEHR-EHR-OBSERVATION.body_mass_index.v1"] = <
            ["body_mass_index"] = <
                target = <"/data/events[id3]/data/items[id5]/value/magnitude">
                direction = <"out">
            >
        >
    >

When used within other artefacts, EL expressions may be expressed as a merger of sections normally found in a self-standing EL Module, and those of the enclosing structure. For example, EL definitions may be embedded in openEHR archetypes or templates by:

  • including the definitions in the rules section;

  • adding the EL Module symbol_definitions section to the archetype terminology section;

  • adding the data_bindings and computing_bindings as additional sections.

7. Terminology

An EL text may have a terminology defined for it, which enables natural language renderings of its symbols to be defined. This is done in exactly the same way as the definition of terms in ADL2 (semantics defined by AOM2). The only difference from terminology definition in openEHR archetypes is that instead of the code names being of the form idN, atN and acN, they are simply the symbolic variable names. Since symbolic variables are normally defined to be meaningful in their own right (i.e. in the same way as by programmers using typical programming languages), EL texts and expressions are readable in one language (just as say, Java library code published by Oracle) but additionally translatable for rendering purposes to any language for which there is a translation.

openEHR-bmi.v1

language
    original_language = <[ISO_639-1::en]>
    translations = <
        ["pt-br"] = <
            language = <[ISO_639-1::pt-br]>
            author = <
                ["name"] = <"Jussara Rözsch">
                ["organisation"] = <"OpenEHR  Foundation">
                ["email"] = <"jussara.macedo@gmail.com">
            >
            accreditation = <"Medical Doctor, Psychiarist, ...">
        >
    >

description
    ...

definition
    ...

terminology
    symbol_definitions = <
        ["en"] = <
            ["body_weight"] = <
                text = <"body weight">
                description = <"weight of subject body">
            >
            ["height"] = <...>
            ["bmi"] = <
                text = <"body mass index">
                description = <"body mass index">
            >
        >
        ["pt"] = <
            ["body_weight"] = <
                text = <"peso do corpo">
                description = <"peso do corpo do sujeito">
            >
            ["height"] = <...>
            ["bmi"] = <
                text = <"índice de massa corporal">
                description = <"índice de massa corporal">
            >
        >
    >

8. Data Bindings

Expressions in the openEHR Expression Language contain variables, which may be bound to entities in a data context. Each binding connects a symbolic variable to a data source or target in the data context.

8.1. Binding Model

The model of binding of a symbolic variable in an expression to an external entity varies, depending on specifics of system architecture. The taxonomy shown below illustrates the various forms of context that are assumed to exist. There are two essential types: execution context and content context. The first corresponds to obtaining the required data item from the current execution context, either via an API call, running a query, or interactive, i.e. via an application.

data binding taxonomy
Figure 4. Taxonomy of data binding

For variables declared as in and in_out in the EL text, in addition to binding targets, it is may be important to state the data quality, typically at least currency i.e. how recent the data must be to be valid. In the various types of binding, data quality may be specified in different ways. For example, for the content context type, data currency of the data is assumed (i.e. not stated). In the API call case, it may be explicitly specified, whilst in the query case, it will normally be specified within the query e.g. by means of a WHERE clause expression that references a relevant time-related meta-data item.

Another aspect of data quality is when a bound variable is sampled from its external context with respect to the execution of rules or expressions mentioning it. The default is that it is sampled once at the start of execution of a rule set containing expressions that mention the variable, i.e. at the point of parsing the context definition. However if a rule set is repeatedly evaluated, some variables may require sampling in real time, whereas others might only need to be sampled once, or less frequently. For example, for a rule set that is executed every minute, patient vital signs variables usually need to be sampled each time, whereas a variable like patient weight need only be sampled once per day.

In a data context definition, bindings of the various concrete types are stated. Within each type, the individual variable bindings are expressed with repect to an index context, which varies depending on the binding type. The general structure of a data bindings definition is as follows.

data_bindings
    content_bindings
        index_context_id
            var_name
                binding_definition
            var_name
                binding_definition
    api_bindings
        index_context_id
            var_name
                binding_definition
    query_bindings
        index_context_id
            var_name
                binding_definition
    interactive_bindings
        index_context_id
            var_name
                binding_definition

The binding_definition elements are data structures whose contents instantiate the model of each kind of binding. In the examples below, these are shown in ODIN syntax.

8.1.1. Content Binding

A content context corresponds to data assumed to be available within a larger data entity such as a document or other structure, being the result of a prior retrieval or data creation. In this case i.e. the variable is bound to a data item within the content structure, identified by a path or identifier.

Binding of a variable to a content context is done by mapping the variable to an item within the context, such as an openEHR archetype or template, as shown below.

data_bindings
    content_bindings = <
        ["openEHR-EHR-COMPOSITION.encounter.v1"] = <
            ["date_initial_onset"] = <
                target = <"/data[id2]/items[id3]/value[id35]/value">
            >
        >
    >

Both input (i.e. 'read') and output (i.e. 'write') variables can be mapped, as per the following that shows the mappings of the variables $body_weight, $height and $body_mass_index used in examples above. A writable (i.e. out) variable such as body_mass_index may be assigned to, and that part of the processing of such an assignment statement may be to write the result into the binding target.

data_context
    content_bindings = <
        ["openEHR-EHR-OBSERVATION.body_measurements.v1"] = <
            ["body_weight"] = <
                target = <"/data/events[id3]/data/items[id5]/value/magnitude">
            >
            ["height"] = <
                target = <"/data/events[id3]/data/items[id6]/value/magnitude">
            >
        >
        ["openEHR-EHR-OBSERVATION.body_mass_index.v1"] = <
            ["body_mass_index"] = <
                target = <"/data/events[id3]/data/items[id5]/value/magnitude">
            >
        >
    >

8.1.2. API Call Binding

A binding to an API call is used when the required value can be obtained through such a call in a defined interface. The following shows how the value for the variable systolic_bp is obtained from the API call vital_sign ($ehr_id, "systolic_pressure"), that must have been measured in the last 1 hour. In this case, the index context is the system identifier, https://oncology.health.org/cdr/ in the example.

data_bindings
    api_bindings = <
        ["https://oncology.health.org/cdr/"] = <
            ["systolic_bp"] = <
                call_name = <"vital_sign">,
                parameters = <
                    [1] = <"$ehr_id">
                    [2] = <"systolic_pressure">
                >,
                currency = <P1h>
            >
        >
    >

TBD: need to codify REST URI flavour of doing this.

8.1.3. Query Binding

A common special case of an API call is when the call is to executure a query, either stored or ad hoc. In this case, the API call name doesn’t change, and either an id (stored query case) or the text of a query is supplied. In this case, the parameters states the substitutable parameter values to be used in the query when executed, where each such value replaces a named parameter, assumed to be of the form '$param', with a provided value.

data_context
    query_bindings = <
        ["https://oncology.health.org/cdr/"] = <
            ["systolic_bp"] = <
                query_id = <"vital_signs_basic">,
                parameters = <
                    ["$type"] = <"'systolic_pressure'">
                >
            >
        >
    >

The following example shows how a Boolean variable is_diabetic is populated from a stored query has_diagnosis that takes a SNOMED CT constraint expression as an argument.

data_bindings
    query_bindings = <
        ["https://oncology.health.org/cdr/"] = <
            ["is_diabetic"] = <
                query_id = <"has_diagnosis">,
                parameters = <
                    ["$dx_expr"] = <"'<<[snomed_ct::1234567]'">
                >
            >
        >
    >

8.1.4. Interactive Binding

Rather than obtaining a data value from and API or query, it may be obtained interactively. Various parameters may apply here, as shown in the following example. Here, the index context is an application name. The special name "default" means that the identity of the application or other interactive method is determined by the enclosing context, e.g. it may be the current application or a generic decision support UI.

data_bindings
    interactive_bindings = <
        ["default"] = <
            ["is_diabetic"] = <
                visual_control_type = <"boolean">,
                prompt = <"is_diabetic_prompt">,
            >
        >
    >

9. Computing Bindings

TBD: potentially do without this section altogether, and let implementations do their own thing. However, it requires that call signatures exactly match the declarations in the definition section.

Expressions may contain user-defined functions and procedures, whose signatures are declared in the definition part of an EL text. The implementations of such routines can be developed or provided in a library in any language, e.g. TypeScript, Java, C#, Python etc. Implementations of used routines are bound to their EL declarations in the computing_bindings section of a full EL text. The following provides an example in which two libraries, one in Java and one in Python are bound to functions declared in an EL text.

computing_bindings
    library_bindings = <
        ["onco_staging_lib"] = <
            connector = <
                language = <"java8">
                library = <"onco_staging_lib.jar">
                xxx = <"xxx">  -- other connector details
            >
            bindings = <
                ["tnm_major_number"] = <"TnmCalculator::tnmNumericVal">
                ["tnm_prefix"] = <"TnmCalculator::tnmPrefixVal">
            >
        >

        ["anti_coag_lib"] = <
            connector = <
                language = <"python">
                library = <"anti_coagulation_algorithms">
                xxx = <"xxx">  -- other connector details
            >
            bindings = <
                ["chadsvasc_score"] = <"Anti_coag_lib_wrapper::CHA2DS2_VASc_score">
                ["warfarin_dose"] = <"Anti_coag_lib_wrapper::calc_warfarin_dose">
            >
        >
    >

In the above, the Java function tnmNumericVal() from the class TnmCalculator is bound to the EL-declared function tnm_major_number(). It is assumed that the two functions match in signatures, i.e. have the same number of arguments in the same order and of the same types. This is most likely to be achieved by writing a wrapper class around one or more classes that are found in existing libraries. Additionally, it must be possible for the implementation class to be instantiated with no arguments.

TBD: or else they have to be supplied in the binding

10. Module Structure

The Expression Language supports inclusion of one EL Module in another via the import keyword. This is primarily used to re-use existing definitions, including symbolic constants, routine declarations and so on, thus enabling a new EL Module to contain just the specific functionality for which it is authored.

An EL Module may also be a specialisation of another, i.e. list it as a parent. This allows direct inheritance of definitions from the parent into the namespace of the module.

10.1. EL Module Identification

TBD: xxxx

10.2. Module import

TBD: really needed to have explicit import? Since a Module parser could easily find instances of qualified refs and just look for the other modules in the system.

10.3. Module specialisation

11. The Expression Language Object Model (ELOM)

11.1. Overview

The org.openehr.base.elom package defines the Expression Language Object Model (ELOM), a structural model of the openEHR Expression language. Its elements, including statements and expressions can be used in various contexts in openEHR, including inside archetypes and in GDL guidelines. If the Expression Language or other syntax-based artefact is used, the model described here defines the parser output in the form of a computable structure. Other openEHR models designed for a particular purpose may reuse the elom package and further specialise some of its types specifically intended for extension.

The package structure of the elom package is shown below.

BASE elom packages
Figure 5. base.elom Package

The packages are described below in the same 'inside-out' order as the EL language description, corresponding to minimal to maximal use.

11.2. Expressions

The expressions part of EL is represented by the EL_EXPRESSION class and descendants, shown in the following UML.

BASE elom.expression
Figure 6. base.elom.expression Package

One class, EL_CONSTRAINT_EXPRESSION is included as a hook for specialisation in other models. This class represents a constraint matching expression of the form <expr> matches <constraint>. The concrete representation of the constraint is not modelled here, and would be supplied by subtypes.

11.2.1. Class Descriptions

11.2.1.1. EL_EXPRESSION Class

Class

EL_EXPRESSION (abstract)

Description

Abstract parent of all typed expression tree items.

Attributes

Signature

Meaning

0..1

definition: Any

The reference item from which the value of this node can be computed.

Functions

Signature

Meaning

(abstract)

type (): BMM_TYPE

The primitive type of this node, which must be determined by redefinitions in concrete classes.

(abstract)

value (): Any

The computed value of this node as a result of the nodes below it, for operator nodes, or else statically set or otherwise derived values.

11.2.1.2. EL_OPERATOR Class

Class

EL_OPERATOR (abstract)

Description

Abstract parent of operator types.

Inherit

EL_EXPRESSION

Attributes

Signature

Meaning

0..1

precedence_overridden: Boolean

True if the natural precedence of operators is overridden in the expression represented by this node of the expression tree. If True, parentheses should be introduced around the totality of the syntax expression corresponding to this operator node and its operands.

0..1

symbol: String

The symbol actually used in the expression, or intended to be used for serialisation. Must be a member of OPERATOR_DEF.symbols.

1..1
(redefined)

definition: BMM_FUNCTION

The reference item from which the value of this node can be computed.

11.2.1.3. EL_UNARY_OPERATOR Class

Class

EL_UNARY_OPERATOR

Description

Unary operator expression node.

Inherit

EL_OPERATOR

Attributes

Signature

Meaning

1..1

operand: EL_EXPRESSION

Operand node.

11.2.1.4. EL_BINARY_OPERATOR Class

Class

EL_BINARY_OPERATOR

Description

Binary operator expression node.

Inherit

EL_OPERATOR

Attributes

Signature

Meaning

1..1

left_operand: EL_EXPRESSION

Left operand node.

1..1

right_operand: EL_EXPRESSION

Right operand node.

11.2.1.5. EL_TERMINAL Class

Class

EL_TERMINAL (abstract)

Description

Expression tree leaf item representing one of:

  • a manifest constant of any primitive type;

  • a path referring to a value in the archetype;

  • a constraint;

  • a variable reference.

Inherit

EL_EXPRESSION

11.2.1.6. EL_VARIABLE_REF Class

Class

EL_VARIABLE_REF (abstract)

Description

Abstract expression terminal item representing a reference to a declared variable.

Inherit

EL_TERMINAL

Attributes

Signature

Meaning

1..1
(redefined)

definition: BMM_MUTABLE

The reference item from which the value of this node can be computed.

11.2.1.7. EL_EXTERNAL_REF Class

Class

EL_EXTERNAL_REF

Description

Inherit

EL_VARIABLE_REF

Attributes

Signature

Meaning

1..1
(redefined)

definition: BMM_PARAMETER

The reference item from which the value of this node can be computed.

11.2.1.8. EL_LOCAL_REF Class

Class

EL_LOCAL_REF

Description

Type representing a reference to a local variable.

Inherit

EL_VARIABLE_REF

Attributes

Signature

Meaning

1..1
(redefined)

definition: BMM_LOCAL

The reference item from which the value of this node can be computed.

11.2.1.9. EL_CONSTANT_REF Class

Class

EL_CONSTANT_REF

Description

Expression leaf item representing a reference to a declared constant.

Inherit

EL_TERMINAL

Attributes

Signature

Meaning

1..1
(redefined)

definition: BMM_CONSTANT

The reference item from which the value of this node can be computed.

11.2.1.10. EL_FUNCTION_CALL Class

Class

EL_FUNCTION_CALL

Description

Terminal element representing a function invocation with 0 or more arguments, keyed by name from the parameter list of the Function definition. This allows arguments to be left open, creating another EL_FUNCTION_CALL instance as a result.

Inherit

EL_TERMINAL

Attributes

Signature

Meaning

1..1
(redefined)

definition: BMM_FUNCTION

The reference item from which the value of this node can be computed.

11.2.1.11. EL_LITERAL Class

Class

EL_LITERAL

Description

Literal value expression terminal element. This can represent a literal value of any Foundation type, or any type known in the included models. Defined via a BMM_VALUE.

Inherit

EL_TERMINAL

Attributes

Signature

Meaning

1..1
(redefined)

definition: BMM_VALUE

The reference item from which the value of this node can be computed.

11.2.1.12. EL_PREDICATE Class

Class

EL_PREDICATE (abstract)

Description

Special purpose built-in functions of the EL formalism.

Inherit

EL_EXPRESSION

Attributes

Signature

Meaning

1..1

operand: EL_EXPRESSION

11.2.1.13. EL_ASSERTION Class

Class

EL_ASSERTION

Description

A built-in statement type in the form of an assertion taking one expression argument, that determines whether it is true and if not, generates an exception.

Inherit

EL_STATEMENT

Attributes

Signature

Meaning

1..1

expression: EL_EXPRESSION

11.2.1.14. EL_DEFINED Class

Class

EL_DEFINED

Description

A built-in predicate taking one external variable reference argument, that returns true if the reference is resolvable, i.e. the external value is obtainable.

Inherit

EL_PREDICATE

Attributes

Signature

Meaning

1..1
(redefined)

operand: EL_EXTERNAL_REF

11.2.1.15. EL_CONSTRAINT_EXPRESSION Class

Class

EL_CONSTRAINT_EXPRESSION

Description

Special kind of terminal element representing a constraint on values. Used with the 'matches' operator. Does not follow the ordinary model of binary operator, since the constraint is not itself a value-returning expression.

Inherit

EL_EXPRESSION

Attributes

Signature

Meaning

1..1

left_operand: EL_EXPRESSION

Left operand node.

1..1

constraint: Any

Right hand side of the constraint expression. Redefined in sub-types.

11.3. Statements

The statements part of EL is represented by the EL_STATEMENT class and descendants, which represent, respectively assignments, procedure calls, assertions (check instructions) and decision structures (i.e. if/then and when/then).

BASE elom.statement
Figure 7. base.elom.statement Package

11.3.1. Class Descriptions

11.3.1.1. EL_STATEMENT Class

Class

EL_STATEMENT (abstract)

Description

Abstract concept of any statement in a block of rule statements.

11.3.1.2. EL_ASSIGNMENT Class

Class

EL_ASSIGNMENT

Description

Statement type representing an assignment from a value-generating source to a writable entity, i.e. a variable reference.

Inherit

EL_STATEMENT

Attributes

Signature

Meaning

1..1

target: EL_VARIABLE_REF

The target variable on the notional left-hand side of this assignment.

1..1

source: EL_EXPRESSION

Source right hand side) of the assignment.

11.3.1.3. EL_ROUTINE_CALL Class

Class

EL_ROUTINE_CALL (abstract)

Description

Attributes

Signature

Meaning

0..1

arguments: Hash<String,EL_EXPRESSION>

Arguments of this function, which can be from 0 to any number. Functions with no arguments are typically used to represent real world varying values like 'current time' and so on.

11.3.1.4. EL_PROCEDURE_CALL Class

Class

EL_PROCEDURE_CALL

Description

Statement type representing a call to

Inherit

EL_STATEMENT

Attributes

Signature

Meaning

1..1

definition: BMM_PROCEDURE

11.3.1.5. EL_CHOICE_GROUP Class

Class

EL_CHOICE_GROUP (abstract)

Description

Abstract parent of multi-branch control structures.

Inherit

EL_STATEMENT

Attributes

Signature

Meaning

1..1

members: EL_CHOICE_BRANCH

11.3.1.6. EL_CHOICE_BRANCH Class

Class

EL_CHOICE_BRANCH (abstract)

Description

Abstract parent of branch in a multi-branch control structure.

Attributes

Signature

Meaning

0..1

statements: List<EL_STATEMENT>

11.3.1.7. EL_CONDITION_GROUP Class

Class

EL_CONDITION_GROUP

Description

Structural representation of an if/then statement.

Inherit

EL_CHOICE_GROUP

Attributes

Signature

Meaning

1..1
(redefined)

members: EL_CONDITION_BRANCH

The branches of the if/then decision structure.

11.3.1.8. EL_CONDITION_BRANCH Class

Class

EL_CONDITION_BRANCH

Description

Representation of one conditional branch of an if/then statement.

Inherit

EL_CHOICE_BRANCH

Attributes

Signature

Meaning

1..1

test: EL_EXPRESSION

The test expression to evaluate for this branch.

11.3.1.9. EL_DECISION_GROUP Class

Class

EL_DECISION_GROUP

Description

Structural representation of a when/then statement.

Inherit

EL_CHOICE_GROUP

Attributes

Signature

Meaning

1..1
(redefined)

members: EL_DECISION_BRANCH

11.3.1.10. EL_DECISION_BRANCH Class

Class

EL_DECISION_BRANCH

Description

Representation of one branch of a when/then statement.

Inherit

EL_CHOICE_BRANCH

Attributes

Signature

Meaning

1..1

value_constraint: EL_CONSTRAINT_EXPRESSION

Constraint expression constraining the value of a decision branch.

11.4. Module Package

The top-level construct of the ELOM is the EL_MODULE, representing a standalone module of meta-data, model and module references, statements and bindings. It is shown below.

BASE elom.module
Figure 8. base.elom.module Package

TBD: to be continued.

11.4.1. Class Descriptions

11.4.1.1. EL_MODULE Class

Class

EL_MODULE

Description

A container for a set of statements along with related BMM definitions, meta-data, terminology and bindings.

Inherit

AUTHORED_RESOURCE

Attributes

Signature

Meaning

0..1

statements: List<EL_STATEMENT>

The member statements of this statement set.

0..1

external_defs: List<BMM_PARAMETER>

0..1

local_defs: List<BMM_LOCAL>

0..1

constant_defs: List<BMM_CONSTANT>

0..1

function_defs: List<BMM_FUNCTION>

0..1

procedure_defs: List<BMM_PROCEDURE>

1..1

data_binding: EL_DATA_BINDING

1..1

module_id: String

0..1

used_models: List<EL_MODEL_REF>

0..1

imported_modules: List<EL_MODULE>

Functions

Signature

Meaning

execution_result (): Boolean

Execution result of the whole rule set. Determined by the and-ing of result values of Assertions in the rule set.

11.4.1.2. EL_MODEL_REF Class

Class

EL_MODEL_REF

Description

A reference to an included BMM Model, providing types.

Attributes

Signature

Meaning

1..1

model: BMM_MODEL

11.4.1.3. EL_DATA_BINDING Class

Class

EL_DATA_BINDING

Description

Data bindings structure for an EL Module.

Attributes

Signature

Meaning

1..1

content_bindings:

1..1

api_bindings:

1..1

query_bindings:

1..1

interactive_bindings:

Appendix A: Syntax Specification

The grammar and lexical specification for the standard Expression syntax is shown below in ANTLR4 form.

Note
this is still the old ADL grammar - the Antlr4 file has to be upgraded.  
//
//  description: Antlr4 grammar for openEHR Rules core syntax.
//  author:      Thomas Beale <thomas.beale@openehr.org>
//  support:     openEHR Specifications PR tracker <https://openehr.atlassian.net/projects/SPECPR/issues>
//  copyright:   Copyright (c) 2016 openEHR Foundation
//  license:     Apache 2.0 License <http://www.apache.org/licenses/LICENSE-2.0.html>
//

grammar base_expressions;

//
//  ============== Parser rules ==============
//

assertion: ( identifier ':' )? boolean_expr ;

//
// Expressions evaluating to boolean values
//

boolean_expr: boolean_expr boolean_binop boolean_leaf
    | boolean_leaf
    ;

boolean_leaf:
      boolean_literal
    | '(' boolean_expr ')'
    | arithmetic_relop_expr
    | SYM_NOT boolean_leaf
    ;

boolean_binop:
    | SYM_AND
    | SYM_XOR
    | SYM_OR
    | SYM_IMPLIES
    ;

boolean_literal:
      SYM_TRUE
    | SYM_FALSE
    ;

//
// Expressions evaluating to arithmetic values
//

arithmetic_relop_expr: arithmetic_arith_expr relational_binop arithmetic_arith_expr ;

arithmetic_leaf:
      integer_value
    | real_value
    | '(' arithmetic_arith_expr ')'
    | '-' arithmetic_leaf
    ;

arithmetic_arith_expr: arithmetic_arith_expr arithmetic_binop arithmetic_leaf
    | arithmetic_arith_expr '^'<assoc=right> arithmetic_leaf
    | arithmetic_leaf
    ;

relational_binop:
      SYM_EQ
    | SYM_NE
    | SYM_GT
    | SYM_LT
    | SYM_LE
    | SYM_GE
    ;

arithmetic_binop:
      '/'
    | '*'
    | '+'
    | '-'
    ;

References

General IT Publications

Articles, Books

  1. [Anderson_1996] Ross Anderson. Security in Clinical Information Systems. Available at http://www.cl.cam.ac.uk/users/rja14/policy11/policy11.html.

  2. [Booch_1994] Booch G. Object-Oriented Analysis and Design with applications. 2nd ed. Benjamin/Cummings 1994.

  3. [Eiffel] Meyer B. Eiffel the Language (2nd Ed). Prentice Hall, 1992.

  4. [Fowler_1997] Fowler M. Analysis Patterns: Reusable Object Models. Addison Wesley 1997

  5. [Fowler_Scott_2000] Fowler M, Scott K. UML Distilled (2nd Ed.). Addison Wesley Longman 2000.

  6. [Gray_reuter_1993] Gray J, Reuter A. Transaction Processing Concepts and Techniques. Morgan Kaufmann 1993.

  7. [Hein_2002] Hein J L. Discrete Structures, Logic and Computability (2nd Ed). Jones and Bartlett 2002.

  8. [Hnìtynka_2004] Hnìtynka P, Plášil F. Distributed Versioning Model for MOF. Proceedings of WISICT 2004, Cancun, Mexico, A volume in the ACM international conference proceedings series, published by Computer Science Press, Trinity College Dublin Ireland, 2004.

  9. [Kifer_Lausen_Wu_1995] Kifer M, Lausen G, Wu J. Logical Foundations of Object-Oriented and FrameBased Languages. JACM May 1995. See See ftp://ftp.cs.sunysb.edu/pub/TechReports/kifer/flogic.pdf.

  10. [Kilov_1994] Kilov H, Ross J. Information Modelling - an object-oriented approach. Prentice Hall 1994.

  11. [Maier_2000] Maier M. Architecting Principles for Systems-of-Systems. Technical Report, University of Alabama in Huntsville. 2000. Available at http://www.infoed.com/Open/PAPERS/systems.htm

  12. [Martin] Martin P. Translations between UML, OWL, KIF and the WebKB-2 languages (For-Taxonomy, Frame-CG, Formalized English). May/June 2003. Available at http://www.webkb.org/doc/model/comparisons.html as at Aug 2004.

  13. [Meyer_OOSC2] Meyer B. Object-oriented Software Construction, 2nd Ed. Prentice Hall 1997

  14. [Object_Z] Smith G. The Object Z Specification Language. Kluwer Academic Publishers 2000. See http://www.itee.uq.edu.au/~smith/objectz.html .

  15. [Richards_1998] Richards E G. Mapping Time - The Calendar and its History. Oxford University Press 1998.

  16. [Sowa_2000] Sowa J F. Knowledge Representation: Logical, philosophical and Computational Foundations. 2000, Brooks/Cole, California.

Online Resources

  1. [] Wikipedia. Covariance and contravariance. See https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) .

Standards

  1. [OCL] The Object Constraint Language 2.0. Object Management Group (OMG). Available at http://www.omg.org/cgi-bin/doc?ptc/2003-10-14 .

  2. [IEEE_828] IEEE. IEEE 828-2005: standard for Software Configuration Management Plans.

  3. [ISO_8601] ISO 8601 standard describing formats for representing times, dates, and durations. See https://en.wikipedia.org/wiki/ISO_8601.

  4. [ISO_2788] ISO. ISO 2788 Guide to Establishment and development of monolingual thesauri.

  5. [ISO_5964] ISO. ISO 5964 Guide to Establishment and development of multilingual thesauri.

  6. [Perl_regex] Perl.org. Perl Regular Expressions. Available at http://perldoc.perl.org/perlre.html .

Publications - e-Health

Articles, Books

  1. [Beale_2000] Beale T. Archetypes: Constraint-based Domain Models for Future-proof Information Systems. 2000. Available at http://www.openehr.org/files/resources/publications/archetypes/archetypes_beale_web_2000.pdf .

  2. [Beale_2002] Beale T. Archetypes: Constraint-based Domain Models for Future-proof Information Systems. Eleventh OOPSLA Workshop on Behavioral Semantics: Serving the Customer (Seattle, Washington, USA, November 4, 2002). Edited by Kenneth Baclawski and Haim Kilov. Northeastern University, Boston, 2002, pp. 16-32. Available at http://www.openehr.org/files/resources/publications/archetypes/archetypes_beale_oopsla_2002.pdf .

  3. [Beale_Heard_2007] Beale T, Heard S. An Ontology-based Model of Clinical Information. 2007. pp760-764 Proceedings MedInfo 2007, K. Kuhn et al. (Eds), IOS Publishing 2007. See http://www.openehr.org/publications/health_ict/MedInfo2007-BealeHeard.pdf.

  4. [Cimino_1997] Cimino J J. Desiderata for Controlled Medical vocabularies in the Twenty-First Century. IMIA WG6 Conference, Jacksonville, Florida, Jan 19-22, 1997.

  5. [Elstein_1987] Elstein AS, Shulman LS, Sprafka SA. Medical problem solving: an analysis of clinical reasoning. Cambridge, MA: Harvard University Press 1987.

  6. [Elstein_Schwarz_2002] Elstein AS, Schwarz A. Evidence base of clinical diagnosis: Clinical problem solving and diagnostic decision making: selective review of the cognitive literature. BMJ 2002;324;729-732.

  7. [Ingram_1995] Ingram D. The Good European Health Record Project. Laires, Laderia Christensen, Eds. Health in the New Communications Age. Amsterdam: IOS Press; 1995; pp. 66-74.

  8. [Object_Z] Smith G. The Object Z Specification Language. Kluwer Academic Publishers 2000. See http://www.itee.uq.edu.au/~smith/objectz.html .

  9. [GLIF] Lucila Ohno-Machado, John H. Gennari, Shawn N. Murphy, Nilesh L. Jain, Samson W. Tu, Diane E. Oliver, Edward Pattison-Gordon, Robert A. Greenes, Edward H. Shortliffe, and G. Octo Barnett. The GuideLine Interchange Format - A Model for Representing Guidelines. J Am Med Inform Assoc. 1998 Jul-Aug; 5(4): 357–372.

  10. [Rector_1994] Rector A L, Nowlan W A, Kay S. Foundations for an Electronic Medical Record. The IMIA Yearbook of Medical Informatics 1992 (Eds. van Bemmel J, McRay A). Stuttgart Schattauer 1994.

  11. [Rector_1999] Rector A L. Clinical terminology: why is it so hard? Methods Inf Med. 1999 Dec;38(4-5):239-52. Available at http://www.cs.man.ac.uk/~rector/papers/Why-is-terminology-hard-single-r2.pdf .

  12. [Sottile_1999] Sottile P.A., Ferrara F.M., Grimson W., Kalra D., and Scherrer J.R. The holistic healthcare information system. Toward an Electronic Health Record Europe. 1999. Nov 1999; 259-266.

  13. [Van_de_Velde_Degoulet_2003] Van de Velde R, Degoulet P. Clinical Information Systems: A Component-Based Approach. 2003. Springer-Verlag New York.

  14. [Weed_1969] Weed LL. Medical records, medical education and patient care. 6 ed. Chicago: Year Book Medical Publishers Inc. 1969.

Standards

  1. [Corbamed_PIDS] Object Management Group. Person Identification Service. March 1999. See http://www.omg.org/spec/PIDS/ .

  2. [Corbamed_LQS] Object Management Group. Lexicon Query Service. March 1999. http://www.omg.org/spec/LQS/ .

  3. [hl7_cda] HL7 International. HL7 version Clinical Document Architecture (CDA). Available at http://www.hl7.org.uk/version3group/cda.asp.

  4. [HL7v3_ballot2] HL7 International. HL7 version 3 2nd Ballot specification. Available at http://www.hl7.org.

  5. [HL7v3_data_types] Schadow G, Biron P. HL7 version 3 deliverable: Version 3 Data Types. (2nd ballot 2002 version).

  6. [hl7_v3_rim] HL7 International. HL7 v3 RIM. See http://www.hl7.org .

  7. [hl7_arden] HL7 International. HL7 Arden Syntax. See http://www.hl7.org/Special/committees/Arden/index.cfm .

  8. [hl7_gello] HL7 International. GELLO Decision Support Language. http://www.hl7.org/implement/standards/product_brief.cfm?product_id=5 .

  9. [IHTSDO_URIs] IHTSDO. SNOMED CT URI Standard. http://ihtsdo.org/fileadmin/user_upload/doc/download/doc_UriStandard_Current-en-US_INT_20140527.pdf?ok.

  10. [NLM_UML_list] National Library of Medicine. UMLS Terminologies List. http://www.nlm.nih.gov/research/umls/metaa1.html.

  11. [ISO_13606-1] ISO 13606-1 - Electronic healthcare record communication - Part 1: Extended architecture. See https://www.iso.org/standard/40784.html.

  12. [ISO_13606-2] ISO 13606-2 - Electronic healthcare record communication - Part 2: Domain term list. See https://www.iso.org/standard/50119.html.

  13. [ISO_13606-3] ISO 13606-3 - Electronic healthcare record communication - Part 3: Distribution rules. See https://www.iso.org/standard/50120.html.

  14. [ISO_13606-4] ISO 13606-4 - Electronic Healthcare Record Communication standard Part 4: Messages for the exchange of information. See https://www.iso.org/standard/50121.html.

  15. [ISO_18308] Schloeffel P. (Editor). Requirements for an Electronic Health Record Reference Architecture. See https://www.iso.org/standard/52823.html.

  16. [ISO_20514] ISO. The Integrated Care EHR. See https://www.iso.org/standard/39525.html .

  17. [ISO_13940] ISO. Health informatics - System of concepts to support continuity of care. See https://www.iso.org/standard/58102.html.

  18. [ISO_22600] ISO. Health informatics - Privilege management and access control. See https://www.iso.org/standard/62653.html.

Projects

  1. [EHCR_supA_14] Dixon R, Grubb P A, Lloyd D, and Kalra D. Consolidated List of Requirements. EHCR Support Action Deliverable 1.4. European Commission DGXIII, Brussels; May 2001 59pp Available from http://www.chime.ucl.ac.uk/HealthI/EHCR-SupA/del1-4v1_3.PDF.

  2. [EHCR_supA_35] Dixon R, Grubb P, Lloyd D. EHCR Support Action Deliverable 3.5: "Final Recommendations to CEN for future work". Oct 2000. Available at http://www.chime.ucl.ac.uk/HealthI/EHCRSupA/documents.htm.

  3. [EHCR_supA_24] Dixon R, Grubb P, Lloyd D. EHCR Support Action Deliverable 2.4 "Guidelines on Interpretation and implementation of CEN EHCRA". Oct 2000. Available at http://www.chime.ucl.ac.uk/HealthI/EHCR-SupA/documents.htm.

  4. [EHCR_supA_31_32] Lloyd D, et al. EHCR Support Action Deliverable 3.1&3.2 “Interim Report to CEN”. July 1998. Available at http://www.chime.ucl.ac.uk/HealthI/EHCR-SupA/documents.htm.

  5. [GEHR_del_4] Deliverable 4: GEHR Requirements for Clinical Comprehensiveness. GEHR Project 1992. Available at http://www.openehr.org/files/resources/related_projects/gehr/gehr_deliverable-4.pdf .

  6. [GEHR_del_7] Deliverable 7: Clinical Functional Specifications. GEHR Project 1993.

  7. [GEHR_del_8] Deliverable 8: Ethical and legal Requirements of GEHR Architecture and Systems. GEHR Project 1994. Available at http://www.openehr.org/files/resources/related_projects/gehr/gehr_deliverable-8.pdf .

  8. [GEHR_del_19_20_24] Deliverable 19,20,24: GEHR Architecture. GEHR Project 30/6/1995. Available at http://www.openehr.org/files/resources/related_projects/gehr/gehr_deliverable-19_20_24.pdf .

  9. [GeHR_AUS] Heard S, Beale T. The Good Electronic Health Record (GeHR) (Australia). See http://www.openehr.org/resources/related_projects#gehraus .

  10. [GeHR_Aus_gpcg] Heard S. GEHR Project Australia, GPCG Trial. See http://www.openehr.org/resources/related_projects#gehraus .

  11. [GeHR_Aus_req] Beale T, Heard S. GEHR Technical Requirements. See http://www.openehr.org/files/resources/related_projects/gehr_australia/gehr_requirements.pdf .

  12. [Synapses_req_A] Kalra D. (Editor). The Synapses User Requirements and Functional Specification (Part A). EU Telematics Application Programme, Brussels; 1996; The Synapses Project: Deliverable USER 1.1.1a. 6 chapters, 176 pages.

  13. [Synapses_req_B] Grimson W. and Groth T. (Editors). The Synapses User Requirements and Functional Specification (Part B). EU Telematics Application Programme, Brussels; 1996; The Synapses Project: Deliverable USER 1.1.1b.

  14. [Synapses_odp] Kalra D. (Editor). Synapses ODP Information Viewpoint. EU Telematics Application Programme, Brussels; 1998; The Synapses Project: Final Deliverable. 10 chapters, 64 pages. See http://discovery.ucl.ac.uk/66235/ .

  15. [synex] University College London. SynEx project. http://www.chime.ucl.ac.uk/HealthI/SynEx/ .