GELLO: A Common Expression Language, Release 2

ANSI
ANSI/HL7 V3 GELLO, R2-2010
GELLO: A Common Expression Language, Release 2
4/28/2010
Responsible Group Clinical Decision Support Work Group
HL7
Principal Contributor Margarita Sordo, Ph.D
msordo@dsg.harvard.edu
Decision Systems Group, Brigham & Women’s Hospital, Harvard Medical School, Boston, MA
Principal Contributor Omolola Ogunyemi, Ph.D.
lolaogunyemi@cdrewu.edu
Charles Drew University of Medicine and Science
Principal Contributor Aziz A. Boxwala, M.B.B.S., Ph.D.
aboxwala@ucsd.edu
Division of Biomedical Informatics, University of California at San Diego
Principal Contributor Robert A. Greenes, M.D., Ph.D.
ggreenes@asu.edu
Arizona State University
Contributor Samson Tu
swt@stanford.edu
SMI, Stanford University School of Medicine, Stanford, CA
Contributor Matt Sailors
msailors@tmhs.org
The Methodist Hospital, Houston, TX
Contributor Andrew McIntyre, M.B.B.S., F.R.A.C.P.
andrew@medical-objects.com.au
Medical-Objects Pty Ltd, Queensland, Australia
Contributor Peter R. Tattam, B.Sc (Information Science)
peter.tattam@medical-objects.com.au
Medical-Objects Pty Ltd, Queensland, Australia


Table of Contents


Introduction
    1.1 What is GELLO?
Requirements for an Expression Language in the Clinical Context
    2.1 Non-Functional Requirements
    2.2 Use Cases
    2.3 A Clinical Decision Support Data Model
    2.4 Expressions and Clinical Guidelines
GELLO: Goals and Properties
OCL
    4.1 Why OCL?
GELLO
    5.1 GELLO Types
        5.1.1 Basic Types
            5.1.1.1 Boolean
            5.1.1.2 Integer
            5.1.1.3 Real
            5.1.1.4 String
            5.1.1.5 Unknown and Null as third Boolean value
            5.1.1.6 Basic Type Hierarchy and Type Conformance Rules
        5.1.2 Model Types
            5.1.2.1 Model Type Hierarchy
        5.1.3 Collection Types
            5.1.3.1 Collections of Collections
            5.1.3.2 Collection Type Hierarchy and Type Conformance Rules
        5.1.4 Tuple Type
        5.1.5 Enumeration Types
    5.2 Names
    5.3 Properties
        5.3.1 Attributes
        5.3.2 Operations
            5.3.2.1 Operation Parameters
    5.4 Context and References to Contextual Instances
        5.4.1 Context, Self and Implicit References to Contextual Instances
            5.4.1.1 example
            5.4.1.2 example
            5.4.1.3 example
            5.4.1.4 example
        5.4.2 Package Context and Pathname
            5.4.2.1 example
            5.4.2.2 example
        5.4.3 Navigation through Associations
            5.4.3.1 example
            5.4.3.2 example
            5.4.3.3 example
    5.5 Variable Declaration
        5.5.1 example
        5.5.2 example
        5.5.3 example
        5.5.4 example
        5.5.5 example
        5.5.6 example
        5.5.7 Declaring References to Instances of Classes
            5.5.7.1 example
            5.5.7.2 example
        5.5.8 Scope of Declarations
    5.6  <<definition>> Constraint
        5.6.1 example
    5.7 Reflection
    5.8 Casting
    5.9 Built-in Operators
        5.9.1 Arithmetic Operators "+", "-", "*"
            5.9.1.1 example
        5.9.2 Arithmetic Operator "/"
            5.9.2.1 example
        5.9.3 Arithmetic Operators "div" and "mod"
            5.9.3.1 example
        5.9.4 Arithmetic Operator unary minus "-"
            5.9.4.1 example
        5.9.5 Comparison Operators "=", ">", "<", ">=", "<=", "<>"
            5.9.5.1 example
            5.9.5.2 example
            5.9.5.3 example
        5.9.6  Mathematical Operator "abs"
            5.9.6.1 example
        5.9.7  Mathematical Operator "acos"
            5.9.7.1 example
        5.9.8  Mathematical Operator "asin"
            5.9.8.1 example
        5.9.9  Mathematical Operator "atan"
            5.9.9.1 example
        5.9.10  Mathematical Operator "ceiling"
            5.9.10.1 example
        5.9.11  Mathematical Operator "cos"
            5.9.11.1 example
        5.9.12  Mathematical Operator "exp"
            5.9.12.1 example
        5.9.13  Mathematical Operator "floor"
            5.9.13.1 example
        5.9.14  Mathematical Operator "log"
            5.9.14.1 example
        5.9.15  Mathematical Operator "max"
            5.9.15.1 example
        5.9.16  Mathematical Operator "min"
            5.9.16.1 example
        5.9.17  Mathematical Operator "power"
            5.9.17.1 example
        5.9.18  Mathematical Operator "rand"
            5.9.18.1 example
        5.9.19  Mathematical Operator "sin"
            5.9.19.1 example
        5.9.20  Mathematical Operator "sqrt"
            5.9.20.1 example
        5.9.21  Mathematical Operator "tan"
            5.9.21.1 example
        5.9.22 Boolean Operators
            5.9.22.1 example
        5.9.23 String Operators "size", "concat", "toUpper", "toLower" "substring", "=" and "<>"
            5.9.23.1 example
        5.9.24 String Operators "tochar", "lpad", "rpad", "rtrim", "ltrim" and "replace"
            5.9.24.1 example
    5.10 Collection Operators
        5.10.1 The ‘Arrow’ Notation
            5.10.1.1 example
        5.10.2 Single Instances as Collections
            5.10.2.1 example
        5.10.3 Operator Select
            5.10.3.1 example
            5.10.3.2 example
            5.10.3.3 example
            5.10.3.4 example
        5.10.4 Operator Reject
            5.10.4.1 example
            5.10.4.2 example
        5.10.5 Operator Collect
            5.10.5.1 example
            5.10.5.2 example
        5.10.6 Operator ForAll
            5.10.6.1 example
            5.10.6.2 example
        5.10.7 Operator Iterate
            5.10.7.1 example
            5.10.7.2 example
        5.10.8 Operator Exists
            5.10.8.1 example
            5.10.8.2 example
        5.10.9 Operator Flatten
            5.10.9.1 example
            5.10.9.2 example
        5.10.10 Operator Size
            5.10.10.1 example
            5.10.10.2 example
        5.10.11 Operator Count
            5.10.11.1 example
            5.10.11.2 example
        5.10.12 Operators "Max" and "Min"
            5.10.12.1 example
            5.10.12.2 example
        5.10.13 Operator Includes
            5.10.13.1 example
            5.10.13.2 example
        5.10.14 Operator IncludesAll
            5.10.14.1 example
            5.10.14.2 example
        5.10.15 Operator IsEmpty
            5.10.15.1 example
            5.10.15.2 example
        5.10.16 Operator notEmpty
            5.10.16.1 example
            5.10.16.2 example
        5.10.17 Operator Sum
            5.10.17.1 example
            5.10.17.2 example
        5.10.18 Operator FirstN
            5.10.18.1 example
            5.10.18.2 example
        5.10.19 Operator LastN
            5.10.19.1 example
            5.10.19.2 example
        5.10.20 Operator ElemAt
            5.10.20.1 example
            5.10.20.2 example
        5.10.21 Operator Reverse
            5.10.21.1 example
            5.10.21.2 example
        5.10.22 Operator SortBy
            5.10.22.1 example
            5.10.22.2 example
        5.10.23 Operator Intersection
            5.10.23.1 example
            5.10.23.2 example
        5.10.24 Operator Union
            5.10.24.1 example
            5.10.24.2 example
        5.10.25 Operator Including
            5.10.25.1 example
            5.10.25.2 example
        5.10.26 Operator Excluding
            5.10.26.1 example
            5.10.26.2 example
        5.10.27 Operator Join
            5.10.27.1 example
            5.10.27.2 example
        5.10.28 Operator Average
            5.10.28.1 example
            5.10.28.2 example
        5.10.29 Operator Stdev
            5.10.29.1 example
            5.10.29.2 example
        5.10.30 Operator Variance
            5.10.30.1 example
            5.10.30.2 example
        5.10.31 Operator Median
            5.10.31.1 example
            5.10.31.2 example
        5.10.32 Operator Mode
            5.10.32.1 example
            5.10.32.2 example
        5.10.33 Operator Like
            5.10.33.1 example
            5.10.33.2 example
        5.10.34 Operator NotLike
            5.10.34.1 example
            5.10.34.2 example
        5.10.35 Operator Between
            5.10.35.1 example
            5.10.35.2 example
        5.10.36 Operator Distinct
            5.10.36.1 example
            5.10.36.2 example
    5.11 Tuple Operators
        5.11.1 Operator Size
            5.11.1.1 example
            5.11.1.2 example
        5.11.2 Operator getValue
            5.11.2.1 example
            5.11.2.2 example
        5.11.3 Operator getElemName
            5.11.3.1 example
            5.11.3.2 example
        5.11.4 Operator getElemType
            5.11.4.1 example
            5.11.4.2 example
    5.12 Date/Time Operators
        5.12.1 Operator ToDate
            5.12.1.1 example
            5.12.1.2 example
        5.12.2 Operator AddMonths, AddDate and NextDay
        5.12.3 Operator LastDay
    5.13 Precedence Rules
    5.14 If Expression
        5.14.1 example
        5.14.2 example
        5.14.3 example
GELLO Syntax
    6.1 Inferring Type Rules for Expressions
    6.2 GELLO Lexical Grammar
    6.3 GELLO BNF Syntax
        6.3.1  Root Symbol
            6.3.1.1 exhibit
        6.3.2 Literals
            6.3.2.1 exhibit
        6.3.3 Data Types
            6.3.3.1 exhibit
        6.3.4 Names
        6.3.5 Expressions
            6.3.5.1 exhibit
        6.3.6 Statements
            6.3.6.1 exhibit
        6.3.7 Reference to an Instance of a Model Class
            6.3.7.1 exhibit
        6.3.8 Literals and Identifiers
        6.3.9 Reserved Words
        6.3.10 Operators
        6.3.11 Statements
    6.4 GELLO Expressions
    6.5 Type of an Expression
    6.6 Normal and Abrupt Completion of Evaluation
        6.6.1 Type Checking
        6.6.2 Handling Exceptions
    6.7 Evaluation of Expressions
        6.7.1 Argument List
    6.8 Example of Expressions
        6.8.1 example
Examples in GELLO
    7.1 An MLM into GELLO
        7.1.1 example
        7.1.2 example
    7.2 Example of an iteration over more than one collection at a time
        7.2.1 example
    7.3 Example: Number of current anti-hypertensive Medications > 1
        7.3.1 example
    7.4 3rd Td dose before 12 months of age
        7.4.1 example
Grouping GELLO expressions into Model Processes
    8.1 example
    8.2 example
    8.3 example
Acknowledgements
10 References
Annexes
Annex A: HL7v3DataTypes
Annex B: The HL7 Reference Information Model
Annex C: The core UML OCL kernel declarations
Annex D: A Simplified Data Model
Annex E: Temporal Relations and Temporal Intervals
    E.1 Before
    E.2 After
    E.3 Meets
    E.4 Met-By
    E.5 Overlaps
    E.6 Overlapped-by
    E.7 Starts
    E.8 Started-by
    E.9 During
    E.10 Contains
    E.11 Finishes
    E.12 Finished-by
    E.13 Equals

GELLO is intended to be a standard expression language for decision support. Its specification has been developed in coordination with the HL7 Clinical Decision Support TC (CDSTC). The effort, begun in 2001, has been carried out with input from other TCs and SIGs as well, in order to take account of common needs for constraint specification and query formulation, and the following groups have been consulted in developing the specification: Control/Query, Modeling and Methodology, and Templates.

The syntax of the GELLO language can be used with any object-oriented data model. In the context of clinical decision support, such an OO data model can be any R-MIM view of the HL7 RIM. An example -- out of many possible-- of an R-MIM view of the HL7 RIM is the "virtual medical record" (or vMR), as it is referred to in the CDSTC. The vMR functions as a limited view of the multiple classes in the HL7 RIM, showing only those classes relevant to a clinical decision support application.

Based on the premise that GELLO can fully provide expression support for any properly defined view of the HL7 RIM, it has been possible for us to develop GELLO regardless of any particular specification of an OO data model. It is thus only necessary, when producing a set of decision support applications using GELLO to specify the particular object-oriented model used.

As discussed further below, GELLO is based on the Object Constraint Language (OCL). OCL is well-developed as a constraint language and has a number of features that make it desirable for use as an expression language. GELLO incorporates most of OCL functionality with the exception of some unneeded capabilities which have been removed: a) pre and post conditions for constraints – not used in GELLO and b) invariants – also for constraints. These features are not required because GELLO is designed for writing queries, and not for constraining models. The UML ITS implements the semantics of the HL7 Abstract Data Types in such a way that HL7 data types are mapped into the core UML and OCL kernel data types where such mappings are appropriate. Hence, GELLO, plus the functionality provided by UML ITS for handling HL7 Abstract Data Types, is intended to provide full expression support inasmuch as it is intended to use only standard features wherever possible.

In regard to existing standards for decision support, the evolution of Arden Syntax data references to compatibility with GELLO is already under way. GELLO is not intended to be a substitute for Arden Syntax, although it could be used to write MLMs. In addition, however, GELLO can be used to support a variety of specifications of expressions in decision support settings other than MLMs.

GELLO is a class-based, object-oriented (OO) language that is built on existing standards. GELLO expression language is based on the Object Constraint Language (OCL), developed by the Object Management Group. Relevant components of OCL have been selected and integrated into the GELLO to provide a suitable framework for manipulation of clinical data for decision support in health care.

The GELLO language can be used to:

  • Build up expressions to extract and manipulate data from medical records.
  • Construct decision criteria by building up expressions to reason about particular data features/values. These criteria can be used in decision-support knowledge bases such as those designed to provide alerts and reminders, guidelines, or other decision rules.
  • Create expressions, formulae, etc. for other applications.

GELLO has been designed in the context of a guideline execution model proposed in the HL7 CDSTC (GeM). The guideline execution model consists of a series of steps: actions, decisions, patient-state, branches and synchronization. GELLO perfectly fits in this execution model, providing a standard interface to medical record systems and other data or knowledge sources, specifying decision criteria, and abstracting or deriving summary values. The object-oriented approach for the language has the flexibility and extensibility that is needed for implementation in a broad range of applications.

The expression language is strongly typed and object-oriented. In order to facilitate the process of encoding and evaluation of expressions and more importantly, to maximize the ability to share such expressions, GELLO includes basic built-in data types (§‎5.1), while providing the necessary syntactic mechanisms to manipulate an OO data model compatible with the HL7 RIM, and access all the data model associated classes and methods. This is especially important in enabling decision rules and guidelines to successfully support different data models, inasmuch as classes and relationships specified could vary from one data model to another.

This document contains the full software specification for GELLO expression language. It is organized as follows:

Section ‎2 describes the requirements for an expression language for clinical use. Section ‎3 describes the main goals and properties of GELLO to meet such requirements. Section ‎4 briefly describes the Object Constraint Language (OCL) features.

Section ‎5 describes OCL features included in GELLO expression language, including basic data types in §‎5.1.1, model types in §‎5.1.2 (classes in the data model), collection types in §‎5.1.3, properties of model types (attributes and methods) in §‎5.3, and variables in §‎5.5. Variables are named GELLO expressions with a predefined, limited scope that can be used anywhere a GELLO expression can be used (see §‎5.5.2). In order to preserve GELLO as a side-effect-free language, the mechanisms for creating variables as instances of classes is delegated to the underlying data model. This section also describes GELLO built-in operators (see §‎5.9), and their syntax and semantics, and discusses the tuple type as an aggregation type (see §‎5.1.4) and tuple operators (see §‎5.11) supported by GELLO.

Section ‎6 describes the syntax of the GELLO grammar. Section ‎7 gives examples of GELLO expressions for retrieving information. It also describes GELLO expressions used to build decision criteria, perform abstraction or derive summary values. Finally, appendices A, B and C contain reference diagrams of the HL7 v3 Data Types, HL7 RIM, UML OCL core kernel declarations. Appendix D depicts a simple data model used to illustrate examples along the document.

This section summarizes the non-functional requirements which the GELLO expression language meet.

  1. The syntax of the expression language is object-oriented (OO).
  2. The expression language is the means for accessing and manipulating data retrieved from an object-oriented data model. In the clinical context, such data model may be a RMIM – a refined view of the HL7 RIM.
  3. Expressions can be used to retrieve information from data sources, build decision criteria, and reason about specific data/values. Expressions are text strings that must conform to the definition of an expression in the GELLO language specification (section ‎6).
  4. Temporal data can be handled by expressions containing time-related relationships. Temporal operators are part of the HL7 RIM and can be referred to using the specified notation as described in section ‎5.12 of this document.
  5. The object-oriented approach allows modularity, encapsulation and extensibility. Thus use of GELLO:
    1. Provides platform-independent support for mapping to any standard OO data model used. Therefore eliminating the need for implementation-specific encoding methods for information retrieval as part of knowledge content (guidelines, alerts, etc.).
    2. Simplifies the evaluation of clinical data objects.
    3. Facilitates sharing of decision logic and other computer expressions.

The following use cases define a goal-oriented set of interactions between GELLO and external actors. Actors are users and/or other systems that interact with GELLO. A use case is initiated by a user with a particular goal in mind, and complete successfully when such goal is satisfied. Use cases are defined in terms of actors (who) interacting with the system (what) for a particular purpose (goal) without dealing with system internals.

User profiles:

  • Medical experts not familiar with computer languages, with some basic experience with computers (e.g. word-processing, software packages)
  • Researchers not familiar with computer languages, with string scientific knowledge and some basic experience with computers (e.g. word-processing, software packages)
  • Health Economists with expertise in health economics and communication with health care providers, though not familiar with computer languages, with some basic experience with computers (e.g. word-processing, software packages)
  • Epidemiologist with expertise in public health issues. S/he may not familiar with computer languages, with some basic experience with computers (e.g. word-processing, software packages)
  • Knowledge engineers with programming experience and some basic medical knowledge.
  • Programmers with ample programming experience and no medical expertise.

Scenarios:

  • i. To write implementation-independent expressions that can be embedded in multiple clinical applications (guidelines, RIM derivation expression, template constraints, etc.) to retrieve patient information from an OO data model.
  • ii. To write implementation-independent expressions that can be embedded in multiple clinical applications (guidelines, RIM derivation expression, template constraints, etc.) for representing knowledge and decision logic in a medical context.
  • iii. To enable existing clinical applications ( guidelines, RIM derivation expression, template constraints, etc.) to be made executable and populate them with data from electronic patient records (derives from (i) and (ii))
  • iv. To allow researchers, health economists, epidemiologists and clinical and health care providers to implement expressions that can be embedded in research, clinical, public health protocols, templates, or any application that requires expressions that requires retrieval and evaluation of data from an OO data model
  • v. To ease the evaluation of clinical data objects (derives from (i) and (ii)).
  • vi. To facilitate sharing of decision logic and other computer-based expressions.
Use Case 1
Use Case 1 Expressions into clinical applications to retrieve patient-related data
Description Map clinical knowledge into multiple clinical applications by embedding implementation-independent GELLO expressions to retrieve patient information from an OO data model
Actors Clinicians, researchers, epidemiologists, knowledge engineers, programmers
Assumptions
  • Expressions are strings that comply with the GELLO specification for expressions
  • The general structure of the clinical application is correct, or there is a mechanism that validates it
  • Patient and other clinical data sources are available and in an OO format compatible with the HL7 RIM
Steps
  • GELLO expressions are embedded in the appropriate locations in the clinical application
  • GELLO expressions satisfy the GELLO syntax
  • GELLO expressions are validated by a parser
Variations
  • Parser detects errors and highlights them
  • User corrects errors
Use Case 2
Use Case 2 Expressions in clinical applications for decision logic
Description Represent knowledge and decision logic in multiple clinical applications by embedding implementation-independent GELLO expressions that can be evaluated.
Actors Clinicians, researchers, epidemiologists, knowledge engineers, programmers
Assumptions
  • Expressions are strings that comply with the GELLO specification for expressions
  • The general structure of the clinical application is correct, or there is a mechanism that validates it
  • Patient data sources are available and in an OO format compatible with the HL7 RIM
Steps
  • GELLO expressions are embedded in the appropriate locations in the clinical application
  • GELLO expressions satisfy the GELLO syntax
  • GELLO expressions are validated by a parser
Variations
  • Parser detects errors and highlights them
  • User corrects errors
Use Case 3
Use Case 3 Automatic population and execution of applications
Description Derived from Use cases 1 and 2, clinical applications that contain GELLO expressions can be populated and executed independently of the environment.
Actors Clinicians, researchers, epidemiologists, health economists
Assumptions
  • Expressions have been previously validated and they conform to the GELLO syntax
  • The general structure of the application is correct, or there is a mechanism that validates it
  • Data sources are available and in an OO format compatible with the HL7 RIM
Steps
  • Execution engine enacts clinical application
Variations
  • Validation to detect mismatched data types, classes
Use Case 4
Use Case 4 Evaluation of clinical objects
Description Derived from Use cases 1 and 2, clinical data objects can be easily evaluated independently of the environment using GELLO expressions.
Actors Clinicians, researchers, epidemiologists, knowledge engineers, programmers
Assumptions
  • Expressions have been previously validated and they conform to the GELLO syntax
  • The general structure of the clinical application is correct, or there is a mechanism that validates it
  • Patient data sources are available and in an OO format compatible with the HL7 RIM
Steps
  • Evaluate previously populated clinical data objects
Variations
  • Validation to detect mismatched data types, classes
Use Case 5
Use Case 5 Sharing decision logic and computer-based expressions
Description To facilitate sharing of decision logic and other computer-based expressions independently of the application.
Actors Clinicians, researchers, epidemiologists, helath economists, knowledge engineers, programmers
Assumptions
  • Expressions have been previously validated and they conform to the GELLO syntax
  • Patient/medical data sources are available and in an OO format compatible with the HL7 RIM
Steps
  • Reuse decision logic among applications
Variations
  • Validation to detect mismatched data types, classes

GELLO can provide full expression support for any properly defined object-oriented data model in general. In a clinical context, GELLO can interact with any HL7 RIM-based OO data model serving as intermediary to heterogeneous medical record systems.

Although this approach represents a paradigm shift in data representation, moving from time-stamped atomic data types to an object-oriented data model, it is an ongoing effort towards a standard for exchange, management and integration of clinical data much needed by the community.

The need for a language to formulate expressions to extract and manipulate clinical data is clear. Ideally such a language should be (Click here to go to appropriate reference):

  • vendor-independent
  • platform-independent
  • object-oriented and compatible with the HL7 RIM
  • easy to read/write
  • side-effect free. The result of an operation leaves the state of the system unchanged. The UML attribute isQuery will always return true for any GELLO expression.
  • flexible
  • extensible

The following section describes how GELLO complies with the above requirements and provides the mechanisms for handling clinical data stored in any OO compatible data model.

We propose GELLO as a platform-independent standard expression language for sharing and manipulating knowledge in a medical context. Specifically:

  • GELLO is targeted to clinical applications that need an expression language for decision support.
  • GELLO is vendor-independent by relying on a language specification that is not vendor-specific.
  • GELLO is platform-independent.
  • GELLO provides the mechanisms to access data through an OO data model, with strongly-typed expressions, via general purpose expression language.
  • GELLO is a declarative language; expressions have no side effects.
  • GELLO is extensible by adding new user-defined classes to the underlying OO data model.
  • GELLO can refer to any data manipulation methods explicitly defined in the OO data model. The purpose of GELLO is to provide a robust syntax for expressions so data can be easily handled.
  • GELLO expression evaluation is compatible with the v.3 RIM; hence each decision rule or guideline need not provide a separate mechanism for translation of data elements to/from host environments.
  • The object-oriented approach allows modularity, encapsulation and extensibility.

Thus use of GELLO:

  1. provides platform-independent support for mapping to an OO data model, compatible with the v.3 HL7 RIM therefore eliminating the need for implementation-specific encoding methods for information retrieval as part of knowledge content (guidelines, alerts, etc.).
  2. simplifies the creation and updating of clinical data objects, and their evaluation.
  3. facilitates sharing of decision logic and other computer expressions.
GELLOandAppsWithoutMLM.gif

GELLO and its relation to GLIF, RIM and other DSs and KBs. GELLO expression language can be embedded into various applications to provide the mechanisms for access and manipulation of OO data. The RMIM can be any view derived from the HL7 reference information model (RIM).

 4OCL

OCL is the expression language used for specifying invariant constraints and pre- and –post-conditions in object models in the Unified Modeling Language (UML). OCL is a strongly-typed pure expression language without any side effects. Although the evaluation of an OCL expression returns a value, the state of the underlying data model cannot change because of the evaluation of such an expression. OCL is the result of a consensus effort towards a standard in object-oriented modeling and design. Since OCL is not a programming language, it does not rely on a specific platform. All implementation issues are out of the scope of the language. The OCL expression language satisfies the requirements we have outlined above for GELLO, namely:

  • vendor-independent
  • platform-independent
  • object-oriented
  • easy to read/write
  • side-effect free
  • flexible
  • extensible.

In addition, OCL is:

  • concise
  • declarative.

The latest version of OCL documentation can be found at the Object Management Group website.

Besides OCL, we considered XQL, OWL and Java as options for defining a query and expression language. XQL is a query language designed specifically for XML documents. XML documents are unordered, labeled trees, with nodes representing the document entity, elements, attributes, processing instructions and comments. The implied data model behind XML neither matches that of a relational data model nor that of an object-oriented data model. XQL is a query language for XML in the same sense as SQL is a query language for relational tables. Since the HL7 RIM information model and the vMR data model are both object-oriented, it is clear that XQL is not an appropriate approach for an object-oriented query and expression language.

The Web Ontology Language (OWL) is an ongoing effort by W3C to specify a language for publishing and sharing ontologies on the Web. OWL is intended to provide a language that can be used to describe entities and inherent relations between them in Web documents and applications. OWL can be used in applications that need to understand the content. In other words, OWL is more focused on machine interpretable definitions of concepts, rather than on the evaluation of expressions that include arithmetic and user-defined operators. Given that OWL has focused on Web applications and the semantics of Web documents, we did not consider OWL a suitable approach for a language focused on query and computation of complex clinical information. (A list of current W3C recommendations and techincal documents can be found at the W3C website).

We also considered Java as an option for an expression language. Java meets most of the requirements in §‎2. Java is platform-independent, and object-oriented; it is relatively easy to read and write, and is flexible and extensible. However, Java is a full-fledged programming language with side-effects, and it is controlled by a single vendor.

As noted above, OCL has arisen as a consensus effort at creating a standard approach to object-oriented modeling and design. OCL meets all our requirements and, importantly, OCL is already been used by various TCs and SIGs within HL7.

A complete description of the OCL language can be found at the OMG website.

Features in GELLO differentiating it from OCL 2.0 are listed here:

  • extended operators for standard types
  • extended boolean value "unknown"
  • specialized syntax for join() and sort() operators
  • extended collection operators
  • implicit factory support to generate instances of complex types for use within queries
  • A GELLO expression implictly defines a query operation, whilst OCL 2.0 defines queries as additional operations within a given context

In summary, GELLO removes some OCL unneeded capabilities as a language to be used as an expression language, plus the inclusion of particular UML data types and the HL7 types to enable it to reference instances of patient-specific data rather than just model types.

GELLO was conceived as a pure, declarative, strongly-typed expression language. GELLO is free of side effects; it provides the mechanisms to access medical data through an OO data model compatible with the v.3 RIM. Several features of OCL have been incorporated into GELLO to make it a robust and flexible platform-independent language.

GELLO follows the same conventions as OCL in relationship with the UML metamodel. In other words, every GELLO expression is written in the context of a specific type. Although GELLO is a subset of OCL, not all GELLO features are OCL features. We have preserved consistency as much as possible. The majority of GELLO operators are part of OCL, with the exception of some collection operators (firstN §‎5.10.18, lastN §‎5.10.19, and join §‎5.10.27) which have been added to support the requested functionality. As for data types, all GELLO built-in data types are part of OCL including the Tuple data type §‎5.1.4 (the abstract specification for OCL data types can be found at the OMG website). In this section, the use of HL7 classes as a data model is introduced. All basic data types are provided by GELLO (§‎5.1), while model types –or classes- are defined in the underlying HL7 data model (§‎5.1.2). Variables (§‎5.4) are strongly typed named GELLO expressions that can be used at any place a GELLO expression ca be used (§‎5.5.2). In order to preserve GELLO as a side-effect free language, the creation of objects as instances of HL7 classes is delegated to the HL7 RIM. This will allow any UML based framework with a full reference implementation of RIM and data types to perform these functions as required

In summary,

GELLO incorporates most of OCL functionality with the exception of some unneeded capabilities have been removed a)pre and post conditions for constraints -not used in GELLO and b) invariants -also for constraints. The UML ITS implements the semantics of the HL7 Abstract Data Types in such a way that HL7 data types are mapped into the core UML and OCL kernel data types where such mappings are appropriate. Such functionality compatible with the HL7 RIM is used by GELLO, hence enabling it to reference instances of patient-specific data independent of platform, vendor, and data model.

GELLO is a strongly-typed language. This means that every expression must have a known type. There are two type categories: predefined types and model (user-defined) types.

Predefined types include basic types, collection types, tuple type and enumeration type.

A primitive data type is named by its reserved word. They are: Boolean, integer, real, string.

Having basic data types allows us to create literals of the form:

  • let aNum : integer = 5
  • let xNum: real = 5.6
  • let aString: string = ‘abc’ (note single quotes)
  • let aBoolean: Boolean = true
 5.1.1.1Boolean

The Boolean type in GELLO is a three-valued type. A GELLO Boolean type can have one of three possible values: true, false, and unknown. GELLO Boolean operators are described in §‎5.9.22.

 5.1.1.2Integer

Integer represents the mathematical natural numbers. Integer is a subtype of real. Arithmetic operators are described in §‎5.9.

 5.1.1.3Real

Real represents the mathematical concept of real values. Arithmetic operators are described in §‎5.9.

 5.1.1.4String

Strings are sequences of characters. Literal strings are enclosed with single quotes. The available operations for strings are described in §‎5.9.23 and §‎5.9.24.

In the previous versions of this specification there was a discrepancy between GELLO unknown and HL7 RIM Null as third Boolean value. This discrepancy has been resolved by the UML ITS data types, which map GELLO unknown into HL7 RIM Null and vice versa.

Integer is a subtype of real. Hence, integer conforms to real.

Model types refer to user-defined classes in the underlying data model. References to such types include either a full description name, e.g. PhysicalQuantity or its alias, e.g. PQ. Both examples refer to the model type PhysicalQuantity as defined in the HL7 RIM.

For any given class in the data model, if class B is a subtype of class A, then class B conforms to class A.

A GELLO collection is an abstract type with concrete collection types as subtypes. As in OCL, a GELLO collection has three types: Set, Bag and Sequence.

  • A Setis the mathematical set. It does not contain any duplicate elements. All elements have the same type.
  • A Bag is a collection of elements. Duplicates are allowed. All elements in a Bag have the same type.
  • A Sequence is a collection with ordered elements. Duplicates are allowed. All elements in a Sequence must have the same type.

Notation for collections is as follows:

  • typeOfCollection {element1, …, elementn},

Where

  • typeOfCollection is one of Set, Bag, Sequence; and {element1, …, elementn} is a list of the elements –all with the same type- separated by commas.

When creating a sequence of integers, the list of elements can be replaced by an interval specification consisting of two literals of type integer intLiteral1 and intLiteral2 separated by ‘..’: Sequence{1..5} is equivalent to Sequence{1,2,3,4,5}.

Collections can be specified by a literal –as defined above- or as a result of an operation over a collection. See §‎5.10 for collection operators.

Collections of collections are not flattened automatically. Flattening is carried out by means of an explicit function making the effect of the flattening process clear. Flattening in OCL applies to all collection types. The indicated rules for flattening can be applied recursively until the element type of the result is a non-collection type.

Set, Bag and Sequence are all subtypes of Collection.

 5.1.4Tuple Type

The tuple type is part of OCL and hence of the GELLO grammar. A tuple combines elements with different types into an aggregate type. Each tuple part has a name, a type and a value. A tuple part can be a single element or a collection. The type of a tuple part can be of a basic or a model type.

The syntax of a tuple is as follows: Tuple{ label1: type1= value1, …, labeln: typen = valuen}, Where labeli is the label of the element ith, typei and valuei are the valid type and value respectively.

Tuples can be used as a return type from expressions that retrieve information from more than one source such as joins (§‎5.10.27). GELLO provides some tuple operators to access the information returned by an expression. These operators are described in §‎5.11.

Enumeration are datatypes in UML. They define a number of literals as possible values of the enumeration.

 5.2Names

Names may be used in expressions to bind domain elements to values. If the name of an attribute or an operation appears in an expression, the class it belongs to must be explicitly referred to.

A property of a class can be an attribute (§‎5.3.1) or an operation (§‎5.3.2). The syntax for referring to a property of an instance of class is: InstanceOfClass.property, which is consistent with the ‘dot’ notation of an OO data model.

 5.3.1Attributes

Attributes are named properties of class that describe the characteristics that instances of such class can have. For example, aPerson is an instace of the class Person with an attribute FirstName, we refer to a person’s name by writing aPerson.FirstName, where aPerson is an instace of the Person class and FirstName is an attribute of that class.

 5.3.2Operations

An operation is the specification of a service that can be requested from an object of the class. The name of an operation may appear in a GELLO expression only as a part of a full method invocation expression. That is, along with the name of the operation and its arguments, the class or object it belongs to must be explicitly referred to. Operations are side effect-free, they do not change the state of any object.

The HL7 data model provides classes and associated operations. These operations provide the functionality for handling the clinical data stored in the data model.

Parameters are name argument values passed to an operation or method in a method call. If required, arguments must be included in the invocation separated by commas. The type of each value must match the type of the expected argument in each position in the argument list.

Evaluation of expressions requires a contextual instance of a specific type. The context of an expression is explicitly defined using the context expression. The syntax is as follows: context [alias:] Class. Where class indicates the ‘primary’ class in the data model from which the following expression will be evaluated. Context Statements cannot be nested. The notation is as follows:

 5.4.1.1example
Context [alias: ]Class 
GELLO expressions with a reference to either alias or class name
						

The ‘primary’ class is the class that defines the context where the given expressions are to be evaluated. For example (using the data model depicted in Annex D):

 5.4.1.2example
Context Patient
…  GELLO expressions with Patient
						

Sets up the context as all the instances of the ‘primary’ class Patient in the data model.:

The following context definition:

 5.4.1.3example
Context p: Patients
    Let PatientsOverFifty: Sequence(Patient) = p → select(p.age> 50)
						

sets the context over which later expressions will be evaluated against as all patients older than 50 years of age.

 5.4.1.4example
Context Patient
    Let Patient: Patient = Self → (ID = "123abc")
						

sets the context of a single patient with a patient ID = "123abc"over which later expressions will be evaluated against.

Note the use of self as an implicit reference to Patient.

Package context can be used to group classes, while Pathnames can be used to refer to the classes contained in them. The notation is ad follows:

 5.4.2.1example
Package packageName ::
   Context typeName :
      GELLOexpressions
EndPackage

For PathName:

 5.4.2.2example
packageName :: [packageNamei ::]* TypeName
						

Access to objects and their properties can be performed by navigating through associations of objects. The notation is as follows:

 5.4.3.1example
context Object
   self.associatedObject
						

For example:

 5.4.3.2example
context Patient
   self.Medications
					   

returns all the medications a patient is taking, while:

 5.4.3.3example
context Patient
   self.Medications["aspirin"]
						

returns all the instances of medication = aspirin for a given patient.

A variable declaration declares a variable name and binds it to a type. A variable can only hold a value of the same type. A declaration defines the name for a variable inside a program. Each variable declaration must have a scope (§‎5.5.2).

Variables are declared using the let OCL expression. The type of the variable can be either one of the basic built-in GELLO data types §‎5.1.1, GELLO collection types §‎5.1.3, GELLO tuple type §‎5.1.4, or a class from the underlying data model §‎5.1.2.. The type of the return value of an expression must match the type of the variable to which such a value is to be assigned. Once an expression is bound to a variable, it cannot be changed. The syntax for let expressions is as follows:

 5.5.1example
let varName: type = Expression.
					

Where varName is a string that is the name of the variable with type type, and Expression is a valid GELLO expression.

An example of a variable of basic type:

 5.5.2example
let threshold_for_osteodystrophy : integer = 70 			         …(1)
					

If a variable references an instance of a model type, the Expression must include the Factory static method as in: Factory.class("argument list"),where class is a class in model class. Factory takes only one string literal as argument list. As a result, it binds a name varName to an object of type class. The full notation:

 5.5.3example
let  variableName: type = Factory.class("argument list")
An example:
   let potassium: PhysicalQuantity = Factory.PhysicalQuantity("76 kg")   	…(2)
				   

An example when a variable references a collection type:

 5.5.4example
let Myobservations: set = observation →select(coded_concept= ‘abc’)		…(3)
					

An example when the variable is a tuple:

 5.5.5example
let variousPatientData : tuple = patient → join(paramList1; paramList2; CondExp; ParamList3) 	…(4)
					

In (1) threshold_for_osteodystrophy is a GELLO built-in basic type and hence we create the variable and assign the value of 70 in the same operation.

In (2), potassium has a type PhysicalQuantity which is a class in the data model, and we need to create a reference to an instance of that class before assigning it to the variable.

In (3) Myobservations is a set, which is a GELLO collection type. Observations contains all the instances of the class observation with a coded concept = ‘abc’.

In (4) variousPatientData is a tuple containing information related to the current patient. Such information is from different sources and has different types, hence it is grouped into an aggregated type tuple. See §‎5.10.27 for the full notation of the join operator.

In summary, to create a variable with a basic data type, the syntax is:

 5.5.6example
let variable : type = expression
					

Declaring a new reference to class is an operation implemented from an external factory. Although the functionality of this approach is beyond the scope of this document, below we describe the syntax of the operation. This approach satisfies both the HL7 RIM abstract specification and the UML ITS specification, and is similar to that approved by the Java-SIG.

A static factory method "Factory" takes only one string literal as argument list. As a result it binds a name (variableName) to an object of type class, where class is a model class. The notation is as follows:

 5.5.7.1example
let  variableName: type = Factory.class("argument list")
						

An example:

 5.5.7.2example
let aQuantity: PhysicalQuantity = Factory.PhysicalQuantity("76 kg")
						
Where "76 kg" is the literal form of an instance of PhysicalQuantity, 
with 76 being the value and "kg" being the code for kilogram 
in the Unified Code for Units of Measure (UCUM).
						

The scope of a declaration is the portion of a program where the declared entity is valid and can be referred to. The scoping rules are consistent with those of OCL.

<<definition>> constraints must be attached to a classifier and may only contain let definitions. All variables and operations defined in the <<definition>> constraint are known in the same context as if they were properties of the classifier, and can be used in the same manner. In a way, these <<definition>> constraints become pseudo-attributes and –operations of the classifier, and can be used in a GELLO expression in the same way attributes of a classifier are used. The notation for <<definition>> is as follows. Note the use of ‘def’ keyword:

 5.6.1example
context Patient def:
   let varName: type = Expression.
				   

Within OCL, there are properties that apply to all objects in the underlying data model. Reflection properties can be used to determine:

  • The direct type of an object/variable
  • The supertype of an object

The following operations from OCL have been incorporated into GELLO:

  • object.oclTypeOf(t: OclType): Boolean
  • The evaluation of oclTypeOf returns true if the direct type of the object and t are the same: aPerson.oclTypeOf(t: Person) returns true if Person is the direct type of aPerson.
  • object.oclKindOf(t: OclType): Boolean

Similarly, the evaluation of oclKindOf returns true if the t is either the direct type or one of the supertypes of an object: aPatient.oclKindOf(t: Person) returns true if Person is either a direct type or a supertype of aPatient.

 5.8Casting

Every expression written in GELLO must have a type that is matched to a built-in or a model type. It is possible however, to change the type of an expression into another type depending on the context in which such an expression occurs. A specific conversion from type A to type B allows an expression of type A to be treated as type B. This is called casting and OCL provides an operation that has been incorporated into GELLO: oclAsType.

Infix operators are allowed in GELLO. Operator precedence is as defined in §‎5.13 and the OCL specification (OCL). The following arithmetic operators are supported by GELLO. Other infix operators are allowed if and only if the used model type defines those operators with the correct signature.

This section presents the evaluation function for "+" and the allowed types. The types for "-", and "*" are the same as those for "+", and so is the evaluation function. The evaluation function for "+" is defined as follows:

 5.9.1.1example
	
F+(V1,V2)= V1 + V2     If V1 and V2 are both integers or reals
         = undefined   otherwise 

Types for "+":
• (integer x integer) → integer
• (integer x real) → real
• (real x integer) → real
• (real x real) → real
						

The result of a division is always a real number even if the arguments are integers.

 5.9.2.1example
		
F/ (V1,V2)= V1 / V2     If V1 and V2 are either integers or reals, and V2 <> 0
          = undefined   otherwise 

Types for "/":
• (integer x integer) → real
• (integer x real) → real
• (real x integer) → real
• (real x real) → real

The result of integer division "div", and modulus "mod" operations is always an integer number. The arguments must both be integers. The following is the evaluation function and allowed types for integer division. The same applies for modulus.

 5.9.3.1example
Fdiv(V1,V2)= V1 div V2     If V1 and V2 are both integers and V2 <> 0
           = undefined     otherwise 

Type "div" and "mod":
• (integer x integer) → integer	
					

The following are the evaluation function and allowed types for unary minus.

 5.9.4.1example
					
F-(V1)= -V1         If V1 is either an integer or a real 
      = undefined   otherwise 

Types for unary minus "-":
• (integer) → integer
• (real) → real
					

The allowed types and evaluation rule for the operators "=", ">", "<", ">=", "<=", "<>" are as follows. All these operators return undefined if one or both of the comparands is undefined.

 5.9.5.1example
					
Types for "=", ">", "<", ">=", "<=", "><":
• (real x real)→ truth_value   
• (real x integer)→ truth_value   
• (integer x real)→  truth_value   
• (integer x integer)→ truth_value
• (string x string)→ truth_value       Only valid for "=" and <> 
• (boolean x boolean)→ truth_value     Only valid for "=" and <>  
					

Definition of the evaluation function F> (V1, V2). The evaluation function is the same for the other operators:

 5.9.5.2example
F>(V1,V2)= true        If V1 and V2  are both either integers or reals and V1 > V2 
         = false       Else if V1 and V2 are both either integers or reals and V1 ≤ V2
         = undefined   otherwise 
					

Note: for the cases (real x integer) and (integer x real) there is an implicit casting of integer to real, hence both cases are evaluated as (real x real) after casting.

Definition of the evaluation function F= (V1, V2). The evaluation function is the same for F<> (V1, V2) when the operators are both strings of Booleans.

 5.9.5.3example
F=(V1,V2)= true         If V1 and V2  are both strings or Booleans  and V1 = V2 
         = false        Else if V1 and V2  are both strings or Booleans  and V1 <> V2
         = undefined    otherwise 
					

The mathematical operator "abs" returns the absolute value of a number.

 5.9.6.1example
Fabs(V1)= V1          If V1 is a positive integer or positive real number
	= -V1         Else if V1 is a negative integer or negative real number
        = undefined   otherwise 

Type "abs"
• (integer) → integer	
• (real) → real	

The mathematical operator "acos" returns the arc cosine of an angle in the range of 0.0 through pi. If the argument is not a number, is undefined or its absolute value is ">" 1, the the returning value is undefined

 5.9.7.1example
Facos(V1)= acos(V1)    If V1 is  an  integer or real number and abs(V1) ≤ 1
         = undefined   otherwise 

Type "acos"
• (integer) → real	
• (real) → real	

The mathematical operator "asin" returns the arc sine of an angle, in the range of -pi/2 through pi/2.

 5.9.8.1example
Fasin(V1)= asin(V1)    If V1 is  an  integer or real number and abs(V1) ≤ 1
         = 0           Else if V1 = 0
         = undefined   otherwise 

Type "asin"
• (integer) → real	
• (real) → real	

The mathematical operator "atan" returns the arc tangent of an angle, in the range of -pi/2 through pi/2.

 5.9.9.1example
Fatan(V1)= atan(V1)    If V1 is  an  integer or real number and abs(V1) ≤ 1
         = 0           Else if V1 = 0
         = undefined   otherwise 

Type "atan"
• (integer) → real	
• (real) → real	

The mathematical operator "ceiling" returns the smallest integer value that is not less than the argument.

 5.9.10.1example
Fceiling(V1)= ceiling(V1) If V1 is  a real
            = V1          Else if V1 an  integer 
            = 0           Else if V1 = 0
            = -0          Else if V1 < 0 and V1 > -1.0
            = undefined   otherwise 

Type "ceiling"
• (integer) → integer	
• (real) → integer	

The mathematical operator "cos" returns the trigonometric cosine of an angle.

 5.9.11.1example
Fcos(V1)= cos(V1)    If V1 is  an  integer or real number and V1 is the value of an angle in radians
        = undefined  otherwise 

Type "cos"
• (integer) → real	
• (real) → real	

The mathematical operator "exp" returns the value e^a, where e is the base of the natural logarithms..

 5.9.12.1example
Fexp(V1)= e^(V1)       If V1 is  an  integer or real number 
         = + infinity  Else if V1 is positive infinity
         = 0           Else if V1 is negative infinity
         = undefined   otherwise 

Type "exp"
• (integer) → real	
• (real) → real	

The mathematical operator "floor" returns the largest integer value that is not greater than the argument.

 5.9.13.1example
Ffloor(V1)= floor(V1)   If V1 is a real number
          = V1          Else if V1 an integer number
          = V1          Else if V1= 0 or V1= infinity
          = undefined   otherwise 

Type "floor"
• (integer) → integer	
• (real) → integer	

The mathematical operator "log" returns the natural logarithm (base e) of a number.

 5.9.14.1example
Flog(V1)= log(V1)      If V1 is  an  integer or real number > 0
        = + infinity   Else if V1 is positive infinity
        = - infinity   Else if V1 = 0
        = undefined    otherwise 

Type "log"
• (integer) → real	
• (real) → real	

The mathematical operator "max" returns the greater of two numbers.

 5.9.15.1example
Fmax(V1,V2)= V1          If V1 > V2
           = V1          Else if V1 = V2
           = V2          Else if V2 > V1
           = undefined   otherwise 

Type "max"
• (integer x integer) → integer
• (integer x real) → real
• (real x integer) → real
• (real x real) → real	

The mathematical operator "min" returns the smaller of two numbers.

 5.9.16.1example
Fmin(V1,V2)= V1          If V1 < V2
           = V1          Else if V1 = V2
           = V2          Else if V2 < V1
           = undefined   otherwise 

Type "min"
• (integer x integer) → integer
• (integer x real) → real
• (real x integer) → real
• (real x real) → real	

The mathematical operator "power" returns the value of the first argument raised to the power of the value of the second argument

 5.9.17.1example
Fpower(V1,V2)= V1^V2         If V1 and V2 are valid arguments
             = 1             Else if V2= 0
             = V1            Else if V2= 1
             = abs(V1)^V2    Else if V1< 0 and V2 is a finite even integer
             = -(abs(V1)^V2) Else if V1< 0 and V2 is a finite odd integer
             = undefined     Else if V1< 0 and V2 finite and not an integer
             = undefined     Else if V2 is undefined
             = undefined     Else if V1 is undefined and V2!= 0
             = + infinity    Else if abs(V1)> 1 and V2= + infinity 
             = + infinity    Else if V1= 0 and V2< 0 or V1= + infinity and V2> 0
             = + infinity    Else if V1= -0 and V2< 0 and V2 is negative finite odd integer  or  
                             V1= -infinity and V2> 0 and V2 != finite odd integer  
             = - infinity    Else if V1=-0 and V2 is a negative finite odd integer  or V1= -infinity and 
                             V2 is a positive finite odd integer                     
             = 0             Else if abs(V1)> 1 and V2 = -infinity or abs(V1)< 1 and V2 = +infinity
             = 0             Else if V1=0 and V2> 0 or V1=+ infinity and V2< 0
             = 0             Else if V1= -0 and V2> 0 and V2!= finite odd number  or V1= -infinity 
                             and V2< 0 and V2!= finite odd integer 
             = -0            Else if V1=-0 and  V2= positive odd number or V1= -infinity  and V2  is  
                             a negative odd integer                  
             = V2            Else if V2< V1
             = undefined     otherwise 

Type "power"
• (integer x integer) → integer
• (integer x real) → real
• (real x integer) → real
• (real x real) → real	

The mathematical operator "rand" returns a positive real number in the range [0.0, 1.0).

 5.9.18.1example
Frand()= V1   Where 0.0 ≤ V1 < 1.0

Type "rand"
• () → real

The mathematical operator "sin" returns the trigonometric sine of an angle.

 5.9.19.1example
Fsin(V1)=  sin(V1)    If V1 is an integer or real number representing the value of an angle in radians
        = 0           Else if V1 = 0
        = undefined   otherwise 

Type "sin"
• (integer) → real
• (real) → real	

The mathematical operator "sqrt" returns the square root of a number.

 5.9.20.1example
Fsqrt(V1)=  +sqrt(V1)  If V1 is an integer or real number and V1 >= 0
         = 0           Else if V1 = 0
         = undefined   Else if V1 < 0
         = undefined   otherwise 

Type "sqrt"
• (integer) → real
• (integer) → integer
• (real) → real	

The mathematical operator "tan" returns the trigonometric tangent of an angle.

 5.9.21.1example
Ftan(V1)=  tan(V1)    If V1 is an integer or real number representing the value of an angle in radians
        = 0           Else if V1 = 0
        = undefined   otherwise 

Type "tan"
• (integer) → real
• (real) → real	

The valid types and evaluation functions for Boolean operators "and", "or", "xor" and "not" are given as follows:

 5.9.22.1example
Types for "and", "or", "xor"and "implies":
(truth_value x truth_value) → truth_value

Types for "not":
(truth_value) → truth_value
					

Values of the evaluation functions (as in OCL p5.12):

Truth Values for Logic Operators
V1 V2 V1 and V2 V1 or V2 V1 xor V2 not V1 V1 implies V2
false false false false false true true
false true false true true true true
true false false true true false false
true true true true false false true
false unknown false unknown unknown true true
true unknown unknown true unknown false unknown
unknown false false unknown unknown unknown unknown
unknown true unknown true unknown unknown true
unknown unknown unknown unknown unknown unknown unknown

A note on truth values and Boolean operators: GELLO is intended to support extended truth values: true, false and unknown, while HL7 Boolean values in the HL7 RIM data model are true, false and NULL. The discrepancy between unknown and NULL is resolved by the UML ITS.

The types and evaluation functions for string operators are given as follows:

 5.9.23.1example
Type for "size"
• (string) →  integer

Definition of evaluation function for Fsize(V)
Fsize(V)= integer       If V is a string  
        = undefined 	otherwise

Type for "concat"
• (string x string) →  string

Definition of evaluation function for Fconcat(V1, V2)
Fconcat(V1, V2)= string      If V1 and V2 are both strings  
               = undefined   otherwise

Type for "toUpper", "toLower" 
• (string) →  string

Definition of evaluation function for FtoUpper(V). The same applied for "toLower" operator.
FtoUpper(V)= string all in upper characters according to upper case mapping as defined by the Unicode Standard     If V is a string  
           = undefined      otherwise

Type for "substring"
• (string x integer x iinteger) →  string

Definition of evaluation function for Fsubstring(V1,V2,V3)
Fsubstring(V1,V2,V3)=  returns a substring of length V3, at a given starting point V2. 
                     •  V1 is a string and V2 and V3 are integers
               If    •  0 ≤ V2 < size(v1)
                     •  0 ≤ V3 < size(v1)
                     •  V2 + V3 ≤ size(V1)
                    = undefined     otherwise
	                
Type for "=" and "<>"
• (string x string) →  truth_value     

Definition of the evaluation function F= (V1, V2). The evaluation function is the same for
F<> (V1, V2) when the operands are both strings.

F=(V1,V2) = true         If V1 and V2  are both strings and V1 = V2 
          = false        Else if V1 and V2 are both strings and V1 <> V2
          = undefined    otherwise
							

The types and evaluation functions for string operators are given as follows:

 5.9.24.1example
Type for "tochar"
• (integer) →  string
• (real) →  string

Definition of evaluation function for Ftochar(V)
Fsize(V)= string       If V is an integer or a real number 
        = undefined    otherwise

Type for "lpad" 
• (string x integer x string) →  string

Definition of evaluation function for Flpad(V).
Flpad(V1, V2, V3)= string     If V1 is a string that could be padded on its left, 
                              V2 is an integer denoting the length to pad the text to, 
                              and V3 is a string to pad with  
                 = undefined  otherwise

Type for "rpad" 
• (string x integer x string) →  string

Definition of evaluation function for Frpad(V).
Frpad(V1, V2, V3)= string     If V1 is a string that could be padded on its right, 
                              V2 is an integer denoting the length to pad the text to, 
                              and V3 is a string to pad with  
                 = undefined  otherwise

Type for "ltrim"
• (string x string) →  string

Definition of evaluation function for Fltrim(V1,V2).
Fltrim(V1,V2)= string     If V1 and V2 are strings. The resulting string 
                          has all the ocurrences of V2 that appear on 
                          the left removed
             = undefined  otherwise
	                
Type for "rtrim"
• (string x string) →  string

Definition of evaluation function for Frtrim(V1,V2).
Frtrim(V1,V2)= string     If V1 and V2 are strings. The resulting string 
                          has all the ocurrences of V2 that appear on 
                          the right removed
             = undefined  otherwise
	                
Type for "replace"
• (string x string x string) →  string    

Definition of the evaluation function Freplace (V1, V2,V3). 

F=(V1,V2,V3) = string       If V1, V2 and V3  are strings. The function returns a new 
                            string resulting from replacing in V1 all the ocurrences 
                            of V2 with V3
             = undefined    otherwise
							

GELLO incorporates from OCL standard operations to handle elements in collections. These operations take the elements in a collection and evaluate a GELLO expression on each of them. These operators are described in the following sections: select (§‎5.10.3), reject (§‎5.10.4), collect (§‎5.10.5), forAll (§‎5.10.6), iterate (§‎5.10.7), exists (§‎5.10.8) and flatten (§‎5.10.9).

All operations on collections in GELLO are denoted with the ‘arrow’ → notation. The ‘arrow’ notation distinguishes a collection operation from a model type operation. Hence the notation is as follows:

 5.10.1.1example
   collection → collectionOperator(parameters)
						

GELLO treats a single instance as a collection with only one element. This allows us to apply collection operators to instances. The type definition for collection operators will treat a single instance as a collection with one element, as specified in this section. The notation is the same as in (§‎5.10.1):

 5.10.2.1example
   singleInstance → collectionOperator(parameters)
						

Select is an operator to specify a selection from a specific collection. Select returns all the elements in a collection that satisfy a criterion. There are three different forms, of which the simplest one is:

 5.10.3.1example
   collection → select( boolean-expression ) 
						

The result of the select operation, in the context of a complete repository of patient records, is a collection of problem list instances with problem code = "123":

 5.10.3.2example
   patient.problemList → select(code = "123")			

This results in a collection that contains all the elements from collection for which the 
boolean-expression evaluates to true. For each element in collection the expression 
boolean-expression evaluates over a property of the elements in the collection. 
						

A more general syntax for the select expression:

 5.10.3.3example
   collection → select( v | boolean-expression-with-v )

The variable v, called the iterator, is a reference to an object in the collection. v iterates over 
the collection and the boolean-expression-with-v is evaluated for each v. The third form is an 
extension of the latest, where the type of the variable v can be specified. The notation is:

collection → select( v : Type | boolean-expression-with-v)
						

The notation for all variants is:

 5.10.3.4example
collection(select x BooleanExpression)
collection → select( v | boolean-expression-with-v)
collection →select( v : Type | boolean-expression-with-v)

Type for "select"
   (collection x Boolean Expression) → collection

Definition of evaluation function for Fselect(V,E)
Fselect(V,E)= collection     If V is a collection  and E is a valid GELLO Boolean expression. 
                             The resulting collection contains all the elements from V for which the 
                             Boolean expression E evaluates to true
            = undefined      otherwise

collection → select(v | BooleanExpression-with-v)

Type for "select"
   (collection x Iterator x Boolean Expression) → collection
   
Definition of evaluation function for Fselect(V,I,E)
Fselect(V,I,E)= collection     If V is a collection, I is the iterator referring to the object from 	
                               the collection and E is a valid GELLO Boolean expression. 	
                               The resulting collection contains all the elements from V for which the 
                               Boolean expression E evaluates to true
              = undefined      otherwise

collection → select(v:Type | BooleanExpression-with-v)

Type for "select"
(collection x  Iterator x Type x Boolean Expression)  → collection

Definition of evaluation function for Fselect(V,I,T,E)
Fselect(V,I,E)= collection      If V is a collection, I is the iterator with Type T referring to 	
                                the object from the collection and E is a valid GELLO Boolean 
                                expression. 
                                The resulting collection contains all the elements from V for which 
                                the Boolean expression E evaluates to true
              = undefined       otherwise
					 

The Boolean expression evaluates over a property of the elements in the collection, returning all the elements that do not satisfy such condition (all elements that evaluate to False).

The notation is:

 5.10.4.1example
   collection→ reject(BooleanExpression)
   collection→ reject( v : Type | boolean-expression-with-v )
   collection→ reject( v | boolean-expression-with-v )

Type for "reject"
 (collection x Boolean Expression)→ collection

Definition of evaluation function for Freject(V,E)
Freject(V,E)= collection      If V is a collection  and E is a valid GELLO Boolean 
                              expression. The resulting collection contains all the elements
                              from V for which the Boolean expression E evaluates to false
            = undefined	      otherwise

collection→ reject(v | BooleanExpression-with-v)

Type for "reject"
 (collection x Iterator x Boolean Expression)→ collection

Definition of evaluation function for Freject(V,I,E)
Freject(V,I,E)= collection      If V is a collection, I is the iterator referring to the object 
                                from the collection and E is a valid GELLO Boolean expression. 	
                                The resulting collection contains all the elements
                                from V for which the Boolean expression E evaluates to false
              = undefined       otherwise

collection → reject(v:Type | BooleanExpression-with-v)

Type for "reject"
  (collection x Iterator x Type(Boolean Expression) → collection

Definition of evaluation function for Freject(V,I,T,E)
Freject(V,I,E)= collection      If V is a collection, I is the iterator with Type T referring to
                                the object from the collection and E is a valid 
                                GELLO Boolean expression. The resulting collection contains all 
                                the elements from V for which the Boolean expression E evaluates 
                                to false                
              = undefined 	otherwise
						

The result of reject in the following example is a collection of patients who do not have problem code = "123" in their problem list:

 5.10.4.2example
   patient.problemList→ reject(code = "123")
					   

Collect iterates over a collection, computes a value for each element of the collection, and gathers the evaluated values into a new collection. The type of the elements of the resulting collection is usually different from the type of the elements in the original collection over which the operator is applied. The collect operation uses the same syntax as the select and reject operators.

The notation is:

 5.10.5.1example
   collection→ collect(Expression)
   collection→ collect( v | expression-with-v )
   collection→ collect( v : Type | expression-with-v )

Type for "collect"
   (set x Expression)→ bag
   (bag x Expression) → bag
   (sequence x Expression)→ sequence

Definition of evaluation function for Fcollect(V,E)
Fcollect(V,E)= collection     If V is a collection  and E is an expression that is 
                              evaluated for each element in to collection.
             = undefined      otherwise

Type for "collect"
   (set x Iterator x Expression) → bag
   (bag x Iterator x Expression) → bag
   (sequence x Iterator x Expression)→ sequence

Definition of evaluation function for Fcollect(V,I,E)
Fcollect(V,I,E)= collection     If V is a collection, I is the iterator referring to the 
                                object from the collection and E is a valid GELLO expression. 
                                The resulting collection contains the results of evaluating E 
                                for each element of V.
               = undefined      otherwise
     
   collection→ collect(v:Type | Expression-with-v)
 
 Type for "collect"
   (set x Iterator x Type x Expression)→ bag
   (bag x Iterator x Type x Expression)→ bag
   (sequence x Iterator x Type x Expression)→ sequence
 
 Definition of evaluation function for Fcollect(V,I,T,E)
 Fcollect(V,I,E)= collection   If V is a collection, I is the iterator with Type T referring 
                               to the object from the collection and E is a valid GELLO 
                               Expression. The resulting collection contains the result of 
                               evaluating E for each element of V.
                = undefined    otherwise
				 

The following example returns a collection lab result values for creatinine:

 5.10.5.2example
	
   LabResult→ select(code = "CRE")→ collect(value)
					   

ForAll is used to specify a Boolean expression that evaluates the value of a property over all the elements of a collection. The result of the Boolean expression is true if all the elements of the collection evaluate to true. If the Boolean expression is false for one or more elements of the collection, then the complete expression evaluates to false.

The notation is:

 5.10.6.1example
   collection→ forAll(Boolean Expression) 
   collection→ forAll( v | boolean-expression-with-v )
   collection→ forAll( v : Type | boolean-expression-with-v )

Type for "forAll"
    (collection x Boolean Expression)→ truth_value

Definition of evaluation function for FforAll(V,E)
FforAll(V,E) = true       If V is a collection  and E is a valid GELLO Boolean expression 
                          containing a property of the elements, and this expression evaluates 
                          to true for all elements in the collection
             = false      If V is a collection and E is a valid GELLO Boolean expression containing
                          a property of the elements, and there is at least one element for which 
                          the expression E evaluates to false. 
             = undefined  otherwise

   collection→ forAll(v | BooleanExpression-with-v) 
 
Type for "forAll"
   (collection x Iterator x Boolean Expression)→ truth_value

Definition of evaluation function for FforAll(V,I,E)
FforAll(V,I,E)= true       If V is a collection, I is the iterator referring to the object from the 
                           collection and E is a valid GELLO Boolean expression containing a 
                           property of the elements, and this expression evaluates to true for all
                           elements in the collection.
              = false      If V is a collection I is the iterator referring to the object from the 
                           collection and E is a valid GELLO Boolean expression containing a property 
                           of the elements, and there is at least one element for which the expression 
                           E evaluates to false. 
              = undefined  otherwise

collection → forAll(v:Type | BooleanExpression-with-v)

Type for "forAll"
   (collection x Iterator x Type(Boolean Expression) → truth_value

Definition of evaluation function for FforAll(V,I,T,E)
FforAll(V,I,E)= true         If V is a collection, I is the iterator with type T referring to the object 
                             from the collection and E is  a valid GELLO Boolean expression containing 
                             a property of the elements, and this expression evaluates to true for all 
                             elements in the collection.
              = false        If V is a collection I is the iterator referring to the object from the 
                             collection and E is a valid GELLO Boolean expression containing a 
                             property of the elements, and there is at least one element for which 
                             the expression E evaluates to false.
              = undefined    otherwise 
						

The following example returns true if all the lab results are for creatinine:

 5.10.6.2example
	
   LabResult → forAll(code = "CRE")
					   

Iterate is a generic operator. It iterates over a collection of elements elem evaluating each element against a valid GELLO expression expression-with-elem-and-result. The result of the expression-with-elem-and-result is stored in result. The initial value of result is defined by expression. Once iterate goes through the whole collection, it returns result.

The notation is:

 5.10.7.1example
   collection  → iterate(elem: Type; result: Type = expression | 
                         expression-with-elem-and-result)

Type for "iterate"
   (collection x elementName x elementType x resultName x resultType x expression x  
                         expression-with-elem-and-result)  → resultType

Definition of evaluation function for Fiterate(V,S,T1,R,T2,E1,E2)
Fiterate(V,S,T1,R,T2,E1,E2)= DataType      If V is a collection, S is an iterator variable of type T1, 
                                           R is a variable of type T2, E1 is a valid GELLO expression 
                                           defining the initial value of R and E2 is a valid GELLO 
                                           expression that is evaluated for each element S in the 
                                           collection. The evaluated value of E2 is stored in R. 
                                           The final result once the iteration is over is the value of R.
                           = undefined     otherwise
						

The following example returns the number of times creatinine occurs in the collection LabResult:

 5.10.7.2example
	
   LabResult  → iterate(code; acc: Integer = 0 | if code = "CRE" then acc + 1 else acc endif)
					   

Exists returns true if there is at least one element in the collection that satisfies the Boolean expression.

The notation is:

 5.10.8.1example
   collection → exists(BooleanExpression)
   collection → exists( v | boolean-expression-with-v )
   collection → exists( v : Type | boolean-expression-with-v)
 
 Type for "exists" 
    (collection x BooleanExpression) → truth_value 
 
Definition of evaluation function for Fexists(V,E)
Fexists(V,E)= true        If V is a collection E is a valid GELLO Boolean expression containing 
                          a property of the elements, and there is al least  one element
                          in the collection V that satisfies E.
            = false       If V is a collection E is a valid GELLO Boolean expression containing a 
                          property of the elements, and none of the elements in the collection V 
                          satisfies E.
            = undefined   otherwise

Type for "exists"
 (collection x Iterator x Boolean Expression) →  truth_value

Definition of evaluation function for Fexists(V,I,E)
Fexists(V,I,E) = true          If V is a collection, I is the iterator referring to the object 
                               from the collection and E is a valid GELLO Boolean expression 
                               containing a property of the elements and there is at least one 
                               element in the collection V for which E evaluates to true.
               = false         If V is a collection I is the iterator referring to the object from 
                               the collection and E is a valid GELLO and  there is no element in 
                               the collection V such that E evaluates to true for that element 
               = undefined     otherwise 
 
 collection → existsl(v:Type | BooleanExpression-with-v) 
 
 Type for "exists" 
     (collectionIterator x Type x Boolean Expression) → truth_value 
 
 Definition of evaluation function for Fexists(V,I,T,E) 
 Fexists(V,I,E)= true          If V is a collection, I is the iterator with type T referring 
                              to the object from the collection and E is a valid GELLO Boolean 
                              expression containing a property of the elements and there is 
                              at least one element in the collection V for which E evaluates to true.
               = false          If V is a collection I is the iterator referring to the object 
                               from the collection and E is a valid GELLO Boolean expression 
                               containing a property of the elements, and there is no element 
                               in the collection V such that E evaluates to true for that element
               = undefined     otherwise
						

The following example returns true if there is at least one lab result for creatinine:

 5.10.8.2example
	
   LabResult → exists(code = "CRE")
					   

Flatten returns a collection without any nested elements. If the resulting type is a collection, the operator is applied recursively until the return type is a collection without nested collections.

The notation is:

 5.10.9.1example
   collection → flatten()

Type for "flatten" 
   (collection)  → collection 

Definition of evaluation function for Fflatten(V) 
Fflatten(V) = collection     If V is a collection, the result is a collection containing all the 
                             elements of V.  If V is a set, bag, or sequence, then Fflatten(V) is 
                             a set, bag, or sequence respectively.
            = element        If V is not a collection.
						

The result of using flatten in the following example is the collection {1, 2, 3, 4, 5}:

 5.10.9.2example
						
   {1, 2, {3}, {{4},{5}}} → flatten()
						
 5.10.10Operator Size

The operator size returns the number of elements in a collection.

The notation is:

 5.10.10.1example
   collection → size()

Types for "size"
   (collection) → integer

Definition of evaluation function for Fsize(V)
Fsize(V) = integer          If V is a collection 
         = undefined        otherwise
						

The following example returns the number problems the patient has in his problem list:

 5.10.10.2example
						
   patient.problemList → size()
					   

Count returns the number of occurrences of object in a collection.

The notation is:

 5.10.11.1example
   collection → count(object)

Type for "count"
   (collection x object)  → integer

Definition of evaluation function for Fcount(V,O)
Fcount(V,O) = integer           If V is a collection  and O is a defined object
            = undefined 	otherwise
						

The following example returns the number of times the patient has had fever :

 5.10.11.2example
	
   patient.problemList  → collect(code) → count("fever")
					   

Max and min return the biggest and smallest value respectively in a collection. The collection must contain numbers. The following also applies for the min operator.

The notation is:

 5.10.12.1example
   collection → max()

Type for "max"
   (collection)  → number

Definition of evaluation function for Fmax(V)
Fmax(V) = number        If V is a collection of numbers (integers or reals)
        = undefined 	otherwise
						
 5.10.12.2example
	
   {2,5,1} → max()        returns 5
   {2,5,1} →  min()       returns 1
					   

Includes operator returns a true if the object is an element of the collection.

The notation is:

 5.10.13.1example
   collection → includes(object)

Type for "includes"
   (collection x object) → truth_value 
 
Definition of evaluation function for Fincludes(V,O) 
Fincludes(V,O) = true         If V is a collection  and O is an element in the collection.  
               = false        Else if V is a collection and O is not an element V.  
               = undefined    otherwise 
						 

The following example returns true if the patient has "fever" in problem list:

 5.10.13.2example
	
   patient.problemList →  collect(code) → includes("fever")
					   

IncludesAll returns true if all the elements in the parameter collection are in the current collection.

The notation is:

 5.10.14.1example
   collection → includesAll(parameterCollection)

Types for "includesAll"
   (collection x singleInstance) → truth_value
   (collection x collection ) → truth_value
 
Definition of evaluation function for FincludesAll(V,C)
FincludesAll(V,C)= true         If both V and C are collections and all the elements in C 
                                 appear in V. 
                 = false         Else if V is a collection and there is at least one element in C 
                                 that does not appear in V.
                 = undefined     otherwise
						

The following example returns true if the patient has "fever"and "rash" in problem list:

 5.10.14.2example
	
   patient.problemList → collect(code) → includesAll( Set{"fever", "rash"})
					   

isEmpty returns true if the collection contains no elements.

The notation is:

 5.10.15.1example
   collection → isEmpty()

Type for "isEmpty"
   (collection) → truth_value 

Definition of evaluation function for FisEmpty(V) 
 FisEmpty(V) = true          If V is a collection  with no elements
             = false         Else if V is a collection with one or more elements 
             = undefined     otherwise 
						

The following example returns true if the patient has no problems in problem list:

 5.10.15.2example
	
   patient.problemList → isEmpty()
					   

notEmpty returns true if the collection contains one or more elements.

The notation is:

 5.10.16.1example
   collection → notEmpty()

Type for "notEmpty" 
   (collection) → truth_value 
 
Definition of evaluation function for FnotEmpty(V) 
FnotEmpty(V) = true          If V is a collection  with one or more elements 
             = false	     Else if V is a collection with no elements 
             = undefined     otherwise 
						

The following example returns true if the patient has at least one problem in problem list:

 5.10.16.2example
						
   patient.problemList → notEmpty()
					   
 5.10.17Operator Sum

Sum adds up all the elements in a collection. The elements must be of type integer or real.

The notation is:

 5.10.17.1example
   collection  → sum()
 
Types for "sum"
   (collection_of_integers)  → integer 
   (collection_of_reals)  → real 
 
Definition of evaluation function for Fsum(V) 
Fsum(V) = V1+…+Vn           If V is a non-empty collection of n integer or 
                            real values < V1 , … , Vn > with (1≤ i ≤ n) 
        = 0	            Else if V is an empty collection  
        = undefined 	    otherwise 
						

The following example returns 15, the sum of all the values in the collection:

 5.10.17.2example
						
   {1, 2, 3, 4, 5}  → sum()
					   

firstN returns a sequence with the first n elements from the current sequence (a collection with ordered elements). firstN returns the first n elements.

The notation is:

 5.10.18.1example
   sequence → firstN(numberOfElements)

Type for "firstN"
   (sequence x integer)  → sequence

Definition of evaluation function for FfirstN(V,N)
FfirstN(V,N)= sequence        If V is an non-empty sequence and N is an integer 
                              such that 1≤ N ≤ size of V. The resulting sequence
                              is of the same type as V
            = undefined       otherwise
						

The following example returns the first 3 elements in a sequence:

 5.10.18.2example
	
   {1,2,3,4,5}  → firstN(3)      returns {1,2,3}
					   

Returns the last n elements from the current sequence. The elements are returned as a sequence of n elements.

The notation is:

 5.10.19.1example
    sequence  → lastN(numberOfElements)

Type for "lastN"
    (sequence x integer)  → sequence

Definition of evaluation function for FlastN(V,N)
FlastN(V,N)= sequence      If V is an non-empty sequence and N is an integer 
                           such that 1 ≤ N ≤ size of V.  The resulting sequence 
                           is of the same type as V 
           = undefined     otherwise 
						

The following example returns the last 3 elements in a collection:

 5.10.19.2example
	
   {1,2,3,4,5}  → lastN(3)      returns {3,4,5}
					   

Returns the element at the Nth position from the current sequence.

The notation is:

 5.10.20.1example
    sequence → elemAt(ElementPosition)


Type for "elemAt"
   (sequence x integer) → element

Definition of evaluation function for FelemAt(V,N)
FelemAt(V,N) = element     If V is an non-empty sequence and N is an integer 
                           such that 1 ≤ N ≤ size of V. The result is the  
                           element at the Nth position.
             = undefined   otherwise
						

The following example returns the element in the third position in the sequence. The positions go from 1 to size of sequence -1:

 5.10.20.2example
	
   {a, f, g, k, z} → elemAt(3)      returns g
					   

Reverse returns a sequence in reversed order. E.g. the first element of the current sequence is returned as the last and so on.

The notation is:

 5.10.21.1example
   sequence → reverse()

Type for "reverse" 
   (sequence) → sequence 

Definition of evaluation function for Freverse(V) 
Freverse(V) = sequence       If V is a single instance or a sequence. 
                             The resulting sequence is of the same 
                             type as V. 
            = undefined      otherwise 
						 

The following example returns a sequence in a reversed order:

 5.10.21.2example
	
   {a, f, g, k, z} → reverse()      returns {z, k, g, f, a}
					   

The notation is:

 5.10.22.1example
   collection  → sortBy(orderByExpression)

Types for "sortBy"
    (collection x ListOfProperties)  →sequence

Definition of evaluation function for FsortBy(V,E)
FsortBy(V,E) = sequence          If V is a single instance or a collection  
                                 and E is a GELLO expression specifying the 
                                 properties by which the current collection 
                                 should be ordered by. The result is a 
                                 sequence. 
             = undefined 	 otherwise 
						

The following example returns a collection of medications sorted in ascending order by effective time:

 5.10.22.2example
	
   Patient.Medication  → sortBy(effectiveTime.high)
					   

The intersection operator returns a collection with the elements that appear in both the current collection and the parameter collection. This operation is valid for any combination set and bag, but is not defined for sequences. The return type is a set. Set does not allow duplicates.

The notation is:

 5.10.23.1example
   collection → intersection(parameterCollection)

Types for "intersection" 
   (set x set) → set 
   (bag x bag) → set 
   (set x bag) → set 
   (bag x set) → set 

Definition of evaluation function for Fintersection(V1,V2) 
Fintersection(V1,V2) = set         If V1 and V2 are either sets or bags with 
                                   elements < V1,1, … , V1,n >  and 
                                   < V2,1, … ,V2,n >  respectively. The 
                                   resulting set contains all the elements from 
                                   V1 that also are elements of V2  (V1,i = V2,j). 
                                   If there are not common elements in V1 and V2
                                   the intersection returns an empty set. 
                     = undefined   otherwise 
						
 5.10.23.2example
   
   TDrug: a variable holding a collection of drugs, each of which has a 
   "compellingIndication" property.  aPatient is a variable referencing a 
   particular patient’s medical record:

   Drug → exists(aDrug: SubstanceAdministration | not(aDrug.compellingIndication → 
                            intersection(aPerson.problemList) → isEmpty()))
						

The union operation combines two collections into a new one. The union operation can combine a set and a bag, but a sequence only can be combined with another sequence.

The notation is:

 5.10.24.1example
   collection union(parameterCollection)

Types for "union"
   (set x bag) → bag 
   (bag x set)  → bag 
   (set x set) → set 
   (bag x bag) → bag 
   (sequence x sequence) → sequence 

 Definition of evaluation function for Funion(V1,V2) 
 Funion(V1,V2) = set             If V1 and V2 are both sets. The resulting set contains 
                                 the values   that are either in V1 or in V2. Duplicate 
                                 elements are not added. 
               = bag             If V1 and V2 are either sets or bags. The resulting bag 
                                 contains the values <  V1,1, … , V1,n > from V1 
                                 and < V2,1, … , V2,n >  from V2. 
               = sequence        Else if  V1 and V2 are both sequences. The resulting 
                                 sequence contains the values <  V1,1, … , V1,n , 
                                 V2,1, … , V2,n > such that <  V1,1, … , V1,n > are
                                 from V1 and < V2,1, … , V2,n >  are from V2
               = undefined	 otherwise 
						

The following example returns a collection times when a patient has taken any medication and has had problems:

 5.10.24.2example
						
   Patient.problemList → exists(problemList : medication.AllInstances → 
                              exists( medication.effectiveTime → union(effectiveTime))
					   

The operator including returns a collection containing all the elements of the current collection plus an element (which is added at the end if the collection is a sequence).

The notation is:

 5.10.25.1example
   collection →  including(element)

Types for "including" 
   (set x element) → set 
   (bag x element) → bag 
   (sequence x element) → set
   (sequence → element) → bag 
 
Definition of evaluation function for Fincluding(V,E)
Fincluding(V,E)= set              If V is a set and E is an element that does not exist in V. 
                                  E must be of the same type as the elements in V. The 
                                  returning result is a set V→union(Set{E}).
Fincluding(V,E)= bag              If V is a bag, the returning type of the collection is a 
                                  bag with E added to V.
Fincluding(V,E)= sequence         If V is a sequence and E is an element that does 
                                  not exist in V.  The resulting sequence has E added to the 
                                  end of V.  E must be of the same type as the elements in V.
Fincluding(V,E)= bag              If V is a sequence and E is an element that does 
                                  exist in V.  E must be of  the same type as the elements in V.
               = undefined        otherwise
						

The following example returns a set with the appended element:

 5.10.25.2example
	
   Set{7, 2, 8, 4}→ including(5)     returns  Set{7, 2, 8, 4, 5}
					   

The operator excluding returns a collection containing all the elements of the current collection minus all the occurrences of element.

The notation is:

 5.10.26.1example
   collection → excluding(element)

Types for "excluding" 
   (set x element) → set   
   (bag x (element) → bag 
   (sequence x element) → sequence 
 
Definition of evaluation function for Fexcluding(V,E) 
>Fexcluding(V,E)= collection       If V is either a set, bag or sequence and E 
                                   is an element  in V.   
                = undefined        otherwise 
						

The following example returns a bag with the deleted element:

 5.10.26.2example
	
   Bag{7, 2, 5, 8, 4, 5} → excluding(5)     returns Bag{7, 2, 8, 4}
					   
 5.10.27Operator Join

The join operator brings together data from two or more collections. The result is a collection of tuples. Each tuple contains data from each element in the specified collections where the values of the specified conditions match.

The notation is:

 5.10.27.1example
   currentCollection  → join(namesOfCollections; namesOfProperties; booleanExpression; 
         orderByExpression)

Where:
• namesOfCollections is a list of strings separated by commas, where each  
  string represents the name of a collection from where data is retrieved. 
• The name of the current collection currentCollection must appear in the list. 

Notation for namesOfCollections:
• Collection1, collection2,…collectionn;                
   E.g.   patient, labTest, …, treatment
• Alias1 in collection1, alias2 in collection2, …, aliasn in collectionn;               
   E.g.   p in patient, lt in labTest, …, t in treatment
 
• namesOfProperties is a list of strings separated by commas, where each 
  string is the full description of the properties from the objects in the
  collections we want to get in the result.  

The notation is: object.property.  E.g. [patient.ID, labTest.ID, labTest.result, 
labTest.date, treatment.ID, treatment.description].  
Or using aliases: p.ID, lt.ID, etc. 

 • booleanExpression is a valid GELLO Boolean expression containing the 
   conditions the elements from the collections defined in listOfCollections 
   must satisfy in order to be included in the result. For each pair of 
   collections there must be at least one condition related to these 
   collections in the booleanExpression. In general, the number of conditions 
   must be at least equal to the number of collections in listOfCollections-1.

• orderByExpression is a valid GELLO expression specifying the properties 
  by which the result should be ordered.   E.g. patient.ID, treatmentID or
  using aliases  p.ID, t.ID, will sort the result by patientID and 
  treatment ID. 

Types for "join"
   (collection x  parameterList x parameterList x booleanExpression x 
         OrderExpression) → bag_of_tuples  
                     *: for any type of collection if OrderExpression is 
                         not specified. 
                         
   (collection x parameterList x parameterList x booleanExpression x 
         OrderExpression) → sequence_of_tuples 
                    +: for any type of collection if OrderExpression is 
                        specified. 

 Definition of evaluation function for Fjoin(V,S1,S2,E1,E2) 
 Fjoin(V,S1,S2,E1,E2) = bag of tuples  	       If V is collection, S1 is a parameter list of 
                                               strings with the names of the collections from 
                                               where  data will be retrieved, S2 is a parameter
                                               list of strings with the full names of the properties 
                                               to be included in the result, E1 is a boolean
                                               expression containing the conditions C <C1 booleanOP 
                                               C2 … booleanOP Cn >    the returning elements must 
                                               satisfy. The number of conditions Ci in
                                                E1 ≥ [S1(size()-1].  E2 is an optional 
                                               parameter that specifies the criteria for ordering the
                                               resulting elements. If  E2 is not specified, the 
                                               result is a bag.
 Fjoin(V,S1,S2,E1,E2) = sequence of tuples     If V is collection, S1 is a parameter list of 
                                               strings with the names of the collections from 
                                               where data will be retrieved, S2 is a parameter
                                               list of strings with the full names of the properties 
                                               to be included in the result, E1 is a boolean expression 
                                               containing the conditions Ci < C1 booleanOP 
                                               C2 … booleanOP Cn  > the returning elements 
                                               must satisfy. The number of conditions Ci in 
                                               E1 ≥ [S1(size()-1].  E2 is an optional parameter 
                                               that specifies the criteria for ordering the
                                               resulting elements. If ordering is required, then 
                                               a GELLO expression specifying the  properties 
                                               by which the result should be ordered by
                                               must be defined.  The resulting collection is
                                               a sequence.
                      = undefined              otherwise
						 

The following example returns a collection of tuples containing Medication code, effective time and value, and Lab Results code, effective time and value, for all the Lab Results performed (effective time) while a patient was taking any Medication effective time):

 5.10.27.2example
	
   LabResults→ join(Medications; Medications.code, Medications.effectiveTime,
                     Medications.value, LabResults.code,  LabResults.effectiveTime, 
                     LabResults.value; Medications.effectiveTime.contains(LabResults.effectiveTime)
						

Average returns the average (arithmetic mean) of the numerical elements in a collection.

The notation is:

 5.10.28.1example
   collection → average()

Type for "average"
   (collection)  → real

Definition of evaluation function for Faverage(V)
Faverage(V) = real       If V is a collection  and all the elements in the collection 
                         are either real or integer numbers
            = undefined  otherwise
						

The following example returns the average value of the elements in a collection:

 5.10.28.2example
	
    recorded_temperatures is a collection containing the recorded temperatures 
    of a patient: {97, 98, 98.5, 99, 99, 97, 97}. 

                     So, recorded_temperatures → average()          returns: 97.92 F
					   

Stdev returns the standard deviation of the numerical elements in a collection.

The notation is:

 5.10.29.1example
   collection → stdev()

Type for "stdev"
   (collection)  → real

Definition of evaluation function for Fstdev(V)
Fstdev(V) = real        If V is a collection  and all the elements in the collection are 
                        either real or integer numbers
          = undefined 	otherwise
						

The following example returns the standard deviation of the elements in a collection:

 5.10.29.2example
	
    recorded_temperatures is a collection containing the recorded temperatures 
    of a patient: {97, 98, 98.5, 99, 99, 97, 97}. 

                     So, recorded_temperatures → stdev()          returns: 0.9322
					   

Variance returns the variance of the numerical elements in a collection.

The notation is:

 5.10.30.1example
   collection → variance()

Type for "variance"
   (collection)  → real

Definition of evaluation function for Fvariance(V)
Fvariance(V) = real         If V is a collection  and all the elements in the collection are 
                            either real or integer numbers
             = undefined    otherwise
						

The following example returns the variance of the elements in a collection:

 5.10.30.2example
	
    recorded_temperatures is a collection containing the recorded temperatures
    of a patient: {97, 98, 98.5, 99, 99, 97, 97}. 
    
                     So, recorded_temperatures → variance()          returns: 0.8690
					   

Median returns the median of the numerical elements in a collection. The median is the number in the middle of a set of numbers; that is, half the numbers have values that are greater than the median, and half have values that are less. If the number of elements is even, then the median is the average value of the two numbers in the middle.

The notation is:

 5.10.31.1example
   collection → median()

Type for "median"
   (collection)  → real

Definition of evaluation function for Fmedian(V)
Fmedian(V) = integer      If V is a collection and all the elements in the collection are 
                          integer numbers
            = real        Else if V is a collection and all the elements in the collection are 
                          either real or integer numbers
            = undefined   otherwise
						

The following example returns the median of the elements in a collection:

 5.10.31.2example
	
    recorded_temperatures is a collection containing the recorded temperatures
    of a patient: {97, 98, 98.5, 99, 99, 97, 97}. 
    
                     So,   recorded_temperatures → median()          returns: 98
					   
 5.10.32Operator Mode

Mode returns the most frequently occurring value in a collection.

The notation is:

 5.10.32.1example
   collection → mode()

Type for "mode"
   (collection)  → real

Definition of evaluation function for Fmode(V)
Fmode(V) = integer      If V is a collection and all the elements in the collection are 
                        integer numbers
         = real         Else if V is a collection and all the elements in the collection are 
                        either real or integer numbers
         = undefined 	otherwise
						

The following example returns the median of the elements in a collection:

 5.10.32.2example
	
    recorded_temperatures is a collection containing the recorded temperatures
    of a patient: {97, 98, 98.5, 99, 99, 97, 97}. 
    
                     So,   recorded_temperatures → mode()          returns: 97
					   
 5.10.33Operator Like

Like operator searches a collection of strings and returns those that match a given pattern.

The notation is:

 5.10.33.1example
   collection → like(String)

Type for "like"
   (collection x string) → collection 
 
Definition of evaluation function for Flike(V1,V2) 
Flike(V1,V2) = collection     If V1 is a collection  of strings and V2   
                              is string pattern.The result is a collection of all 
                              strings that matched the given pattern. If there 
                              are no matches, the returning collection is empty.
              = undefined     otherwise 
						 

The following example returns a collection with problems that are like "ast" (asthma, astigmatism...):

 5.10.33.2example
	
   patient.problemList →  collect(code) → like("ast")
					   

NotLike operator searches a collection of strings and returns those that do not match a given pattern.

The notation is:

 5.10.34.1example
   collection → notlike(String)

Type for "notlike"
   (collection x string) → collection 
 
Definition of evaluation function for Fnotlike(V1,V2) 
Fnotlike(V1,V2) = collection   If V1 is a collection  of strings and V2  
                               is string pattern. The result is a collection of all  
                               strings that did not match the given pattern.  
                               If there are no matches, the returning collection is empty.
                = undefined    otherwise 
						 

The following example returns a collection with problems that are not like "ast" (e.g. diabetes, COPD):

 5.10.34.2example
	
   patient.problemList →  collect(code) → notlike("ast")
					   

Between operator searches a collection of strings and returns those strings that are between a given range.

The notation is:

 5.10.35.1example
   collection → between(String1, String2)

Type for "between"
   (collection x string x string) → collection 
 
Definition of evaluation function for Fbetween(V1,V2,V3) 
Fbetween(V1,V2,V3) = collection   If V1 is a collection of strings 
                                  and V2 and V3 are both stringsdefining a 
                                  range.  The result is a collection of all  strings 
                                  that are between the given range. If there are 
                                  no matches, the returning collection is empty.
                   = undefined    otherwise 
						 

The following example returns a collection with problems that are between diabetes and reflux:

 5.10.35.2example
	
   {asthma, copd, diabetes, IRS, meningitis, reflux, UTI} → between(diabetes, reflux) 
   returns: {diabetes, IRS, meningitis, reflux}
					   

Distinct operator returns a collection (set) with no duplicate elements. Basically is a casting operation, that converts a bag or sequence into a set, hence eliminating duplicates.

The notation is:

 5.10.36.1example
   collection → distinct()

Type for "distinct"
   (collection) → set 
 
Definition of evaluation function for Fdistinct(V1) 
Fdistinct(V1) = set         If V1 is a collection  the result is a set 
              = undefined   otherwise 
						 

The following example returns a set with problems::

 5.10.36.2example
	
   {asthma, copd, diabetes, copd, UTI, IRS, reflux, UTI} → distinct() 
   returns: {asthma, copd, diabetes, UTI, IRS, reflux}
					   

A GELLO tuple is an aggregated data type formed by one or more elements with different types. As described in §‎5.1.4, each tuple part has a name and a type. GELLO provides the following operations to handle and access tuple elements. Since all elements in a tuple have unique values, we use the ‘dot’ notation to access them in the same manner as we access attributes in a class (§‎5.3.1), e.g. tupleName.elemName.

The operator size returns the number of elements in a tuple.

The notation is:

 5.11.1.1example
						
   Tuple.size()

Types for "size" 
   (tuple) → integer 

Definition of evaluation function for Fsize(T) 
Fsize(T)= integer      If T is a tuple   
        = undefined    otherwise 
						

For the Tuple personalData{name: String = ‘John Smith’, nickname: String = ‘Johnny’, age: Integer = 10} the following example returns 3:

 5.11.1.2example
						
   personalData.size()   returns 3 
						

The operator getValue returns the value of an element with name = elemName in a tuple.

The notation is:

 5.11.2.1example
						
   Tuple.getValue(elemName)

Types for "getValue" 
   (tuple(string) → PredefinedDataTypeValue 
   (tuple(string) → ModelDataTypeObject 
 
Definition of evaluation function for FgetValue(T,S)
FgetValue(T,S) = PredefinedDataTypeValue     If T is a tuple  and S is a string with the name of  
                                             an element in T, and the type of the returning  
                                             value is one of the predefined data types: 
                                             integer, real, boolean, string or one of the 
                                             collection types. 
               = ModelDataTypeObject	     Else if T is a tuple  and S is a string with the name 
                                             of an element in T, and the type of the returning 
                                             value is one of the model data types. 
               = undefined                   otherwise
						

For the Tuple personalData{name: String = ‘John Smith’, nickname: String = ‘Johnny’, age: Integer = 10} the following example returns Johnny:

 5.11.2.2example
   personalData.getValue(nickname)     returns ‘Johnny’ 
   
   this is equivalent to:   personalData.nickname 
					   

The operator getElemName returns a string with the name of the element i in the ith position in the tuple.

The notation is:

 5.11.3.1example
   Tuple.getElemName(position) 
 
Type for "getElemName"
   (tuple x integer) → string 

Definition of evaluation function for FgetElemName(T,I) 
 FgetElemName(T,I) = string       If T is a tuple  and I is an integer (1 ≤ T.size()). 
                   = undefined    otherwise 
						 

For the Tuple personalData{name: String = ‘John Smith’, nickname: String = ‘Johnny’, age: Integer = 10} the following example returns nickname:

 5.11.3.2example
	
   personalData.getElemName(2)     returns ‘nickname’
						   

The operator getElemType returns a string which represents the basic or model data type associated to an element in a tuple. GetElemType can be used by giving the position or the name of an element in the tuple.

The notation is:

 5.11.4.1example
   Tuple.getElemType(position)
   Tuple.getElemType(elemName) 
 
Types for "getElemType" 
   (tuple x integer) → string 
   (tuple x string) → string 
 
Definition of evaluation function for FgetElemType(T,I) 
FgetElemType(T,I) = PredefinedDataType     If T is a tuple  and I is an integer (1 ≤ T.size()). 
                                           The returning value is a string referring to a
                                           predefined data type: integer, real, Boolean, 
                                           string or one of the collection types. 
                  = ModelDataType          Else if T is a tuple  and I is an integer (1 ≤ T.size()). 
                                           The returning value is a string referring to a model 
                                           data type. 
                  = undefined              otherwise 
 
 Definition of evaluation function for FgetElemType(T,S)
 FgetElemType(T,S)= PredefinedDataType     If T is a tuple  and S is a string referring to the 
                                           name of an element in the tuple. The returning value 
                                           is a string referring to a basic data type: integer, 
                                           real, Boolean, string, or one of the collection types. 
                  = ModelDataType          Else if T is a tuple and S is a string referring to the 
                                           name of an element in the tuple.  The returning value
                                           is a string referring to a model data type. 
                  = undefined              otherwise 
						 

For the Tuple personalData{name: String = ‘John Smith’, nickname: String = ‘Johnny’, age: Integer = 10} the following example returns String:

 5.11.4.2example
	
   personalData.getElemType(2)     returns String

   this is equivalent to:    personalData.getElemType(‘nickname’) 
						

The following operators handle date and time objects.

The operator ToDate takes a string and returns a PointInTime object.

The notation is:

 5.12.1.1example
Type for "todate" 
• (string) →  PointInTime    (a RIM object)

Definition of evaluation function for Ftodate(V)
Ftodate(V)= PointInTime    If V is a valid string. The result is a PoinInTime object  
          = undefined      otherwise
						 

The notation for using this operator is as follows. It requires the Factory method because the returning object is an instance of a RIM Class

 5.12.1.2example
					
	The following expression creates a PointInTime object 
	with the argument string:
	
	              Let aDate: PointInTime = Factory.PointInTime(string)
					

These operations are supported by the RIM PoinInTime Class using the operator plus.

This operation is fully supported by the RIM (time) Interval Class using the operator high.

The precedence order for operations in GELLO, starting with the highest precedence, is as follows:

  • "dot" (".") and "arrow" ("→ ") operations
  • unary "not" and unary "minus"
  • "*", "/", "div" and "mod"
  • "+" and binary "-"
  • "if-then-else-endif"
  • ‘<’, ‘>’, ‘<=’, ‘>=’
  • ‘=’, ‘<>’
  • ‘and’, ‘or’ and ‘xor’
  • ‘implies’
  • Parentheses "(" and ")" can be used to change precedence.

An If Expression evaluates a condition and depending on the resulting truth value, the result is one of two possible expressions. Both expressions are mandatory. The If Expression is not intended for control flow, but as a conditional for the returning value of an expression. The syntax of an If Expression is as follows:

 5.14.1example
   if condition then 
      expression1 
   else 
      expression2
   endif 
					
 5.14.2example
Definition of the evaluation function Fif(V1, V2, V3), where V1 is the condition, 
a GELLO expression which its evaluation returns a truth value; and V2 and  V3 are 
expression1 and expression2 respectively, both valid GELLO expressions.

Fif(V1,V2,V3) =  V2            If V1 = true 
              =  V3            Else if V1 = false
              =  undefined     otherwise 
					 
 5.14.3example
   let renal_failure :Boolean = 
      if lastCreatinine.oclIsDefined() and
               lastCreatine.value.greaterThan(renal_failure_threshold)  then 
         true
      else
         false
      endif
			   

This section describes the grammar used in this specification to define the lexical and syntactic structure of GELLO expressions. A context-free grammar consists of a number of productions. Each production is formed by two parts: the left-hand side consisting of a nonterminal symbol and a right-hand side formed by a sequence of one or more nonterminal and terminal symbols.

Starting from a sentence consisting of a single nonterminal, and a set of production rules, the complete grammar is derived by means of a set of possible sequences of terminal symbols that can result from repeatedly replacing any nonterminal symbol in a sequence with its associated right-hand side sequence of a production rule.

Section §‎6.2 describes the grammar used in this specification to define the lexical and syntactic structure of GELLO expressions. For an expression to be syntactically correct it must conform to:

The BNF and lexical grammar defined in this section of the document (§‎6.3).

The context sensitive constraints:

Every expression must be type-correct. It must comply with the type definitions in §‎5.1.

Let E be a valid GELLO expression. The type of E is either a basic (Integer, Real, Boolean or String), a model type or one of the collection or tuple types. The type of E can be inferred by using the rules defined in GELLO lexical grammar §‎6.2 and GELLO BNF §‎6.3.

GELLO BNF syntax is defined in terms of the following lexical tokens. GELLO grammar is based on the grammar for OCL expressions:

A reserved word is any string that appears in double quotes in the BNF. Reserved words are case sensitive.

An atom consists of any sequence of alphanumeric characters, which begins with a letter and can contain one or more underscores. Atoms are case sensitive.

A number could be either an integer or a real.

An integer is represented by one or more digits

A real is represented by a sequence of one or more digits followed by "." followed by zero or more digits, optionally followed by "e" or "E" a sign "+" or "-" one or more digits and "d" or "D".

A single quoted string is a pair of single quote characters enclosing a sequence of zero or more characters other than comments, tabs, newlines and carriage returns.

A comment is any sequence of characters other than newlines, or carriage returns following two successive dashes -- , e.g.

-- this is a comment.

The Backus-Naur Form (BNF) syntax of GELLO assumes that text defining a GELLO expression has been converted into lexical tokens by the lexical analyzer defined in the previous section.

The following notational conventions are used throughout GELLO BNF syntax:

  • The root symbol of the syntax is <GELLOExpression>
  • Non-terminal symbols are denoted with underlined text strings, e.g. expression>
  • Left-hand side terms in production rules are nonterminal
  • Tokens are represented with text strings enclosed in angle brackets, e.g. <atom>.
  • Reserved words are represented by text strings enclosed in double quotes.
  • The grammar below uses the following conventions:
    1. (x)? denotes zero or one occurrences of x.
    2. (x)* denotes zero or more occurrences of x.
    3. (x)+ denotes one or more occurrences of x.
    4. x | y means one of either x or y.
 6.3.1.1exhibit

GELLOExpression::= OuterExpression

 6.3.2Literals
 6.3.2.1exhibit

Literal::= <STRING_LITERAL> | <INTEGER_LITERAL> | <REAL_LITERAL> | <TRUE> | <FALSE> | <UNKNOWN> | <NULL> | CollectionLiteral | TupleLiteral | "#" <ID>

CollectionLiteral::= CollectionType? "{" ( CollectionLiteralElement ( "," CollectionLiteralElement )* )? "}"

CollectionLiteralElement::= Expression ( ".." Expression )?

TupleLiteral::= <TUPLE> "{" TupleLiteralElement ( "," TupleLiteralElement )* "}"

TupleLiteralElement::= <ID> (":" DataTypes)? <EQUAL> Expression

 6.3.3Data Types
 6.3.3.1exhibit

DataTypes::= GELLOType | ModelTypes

GELLOType::= BasicType | CollectionType ("(" DataTypes ")" )? | TupleType | EnumerationType

BasicType::= <INTEGER> | <STRING> | <REAL> | <BOOLEAN>

ModelTypes::= ClassName

CollectionType::= <SET> | <BAG> | <SEQUENCE>

TupleType::= <TUPLE> "(" TupleTypeElement ( "," TupleTypeElement )* ")"

TupleTypeElement::= <ID> ":" DataTypes

EnumerationType::= <ENUM> "(" <ID> ( "," <ID> )* ")"

ClassName::= NameWithPath

 6.3.4Names

NameWithPath::= Name ( "::" Name )*

Name::= <ID> ("." <ID>)*

 6.3.5.1exhibit

Expression::= ConditionalExpression

ConditionalExpression::= OrExpression

OrExpression::= ConditionalAndExpression (<OR> ConditionalAndExpression | <XOR> ConditionalAndExpression)*

ConditionalAndExpression::= ComparisonExpression (<AND> ComparisonExpression)*

ComparisonExpression::= AddExpression (<EQUAL> AddExpression | <NEQ> AddExpression | <LT> AddExpression | <LEQ> AddExpression | <GT> AddExpression | <GEQ> AddExpression)*

AddExpression::= MultiplyExpression (<MINUS> MultiplyExpression | <PLUS> MultiplyExpression)*

MultiplyExpression::= UnaryExpression (<TIMES> UnaryExpression | <DIVIDE> UnaryExpression | <MAX> UnaryExpression | <MIN> UnaryExpression | <INTDIV> UnaryExpression | <MOD> UnaryExpression )*

UnaryExpression::= PrimaryExpression | <NOT> UnaryExpression | <MINUS> UnaryExpression | <PLUS> UnaryExpression | PrimaryExpression

PrimaryExpression::= Literal | Operand | ReferenceToInstance | IfStatement | "(" Expression ")"

ExpressionNP::= ConditionalExpressionNP

ConditionalExpressionNP::= OrExpressionNP

OrExpressionNP::= ConditionalAndExpressionNP (<OR> ConditionalAndExpression | <XOR> ConditionalAndExpression)*

ConditionalAndExpressionNP::= ComparisonExpressionNP (<AND> ComparisonExpression)*

ComparisonExpressionNP::= AddExpressionNP (<EQUAL> AddExpression | <NEQ> AddExpression | <LT> AddExpression | <LEQ> AddExpression | <GT> AddExpression | <GEQ> AddExpression)*

AddExpressionNP::= MultiplyExpressionNP(<MINUS> MultiplyExpression | <PLUS> MultiplyExpression)*

MultiplyExpressionNP::= UnaryExpressionNP (<TIMES> UnaryExpression | <DIVIDE> UnaryExpression | <MAX> UnaryExpression | <MIN> UnaryExpression | <INTDIV> UnaryExpression | <MOD> UnaryExpression )*

UnaryExpressionNP::= PrimaryExpressionNP | <NOT> UnaryExpression

PrimaryExpressionNP::= Literal | Operand | ReferenceToInstance | IfStatement

Operand::= <ID> | Operand "." <ID> | Operand "." StringOperation | Operand "." TupleOperation | Operand "." StringOrTupleSize | Operand "(" ParameterList ")" | Operand "[" ExpressionList "]" | Operand <ARROW> CollectionBody | CollectionLiteral <ARROW> CollectionBody | <SELF>

CollectionBody::= NonParamExp | SelectionExp | QuantifierExp | SingleObjExp | ListObjExp | GetExp | SetExp | IterateExp | JoinExp

SelectionExp::= <SELECT> "(" CExp ")" | <REJECT> "(" CExp ")" | <COLLECT> "(" CExp ")"

QuantifierExp::= <FORALL> "(" CExp ")" | <EXISTS> "(" CExp ")"

CExp::= ConditionalExpression | ConditionalExpressionWithIterator | ConditionalExpressionWithIteratorType

ConditionalExpressionWithIterator::= <ID> "|" ConditionalExpression

ConditionalExpressionWithIteratorType::= <ID> ":" DataTypes "|" ConditionalExpression

NonParamExp::= <SIZE> "(" ")" | <ISEMPTY> "(" ")" | <NOTEMPTY> "(" ")" | <SUM> "(" ")" | <REVERSE> "(" ")" | <MIN> "(" ")" | <MAX> "(" ")" | <FLATTEN> "(" ")" | <AVERAGE> "(" ")" | <MEAN> "(" ")" | <MEDIAN> "(" ")" | <MODE> "(" ")" | <STDEV> "(" ")" | <VARIANCE> "(" ")" | <DISTINCT> "(" ")"

SingleObjExp::= <COUNT> "(" Object ")" | <INCLUDES> "(" Object ")" | <INCLUDING> "(" Object ")" | <EXCLUDING> "(" Object ")"

ListObjExp::= <INCLUDESALL> "(" ObjectList ")" | <SORTBY> "(" PropertyList ")"

GetExp::= <FIRSTN> "(" Expression ")" | <LASTN> "(" Expression ")" | <ELEMAT> "(" Expression ")" | <LIKE> "(" Expression ")" | <NOTLIKE> "(" Expression ")" | <BETWEEN> "(" Expression "," Expression ")"

SetExp::= <INTERSECTION> "(" Expression ")" | <UNION> "(" Expression ")"

IterateExp::= <ITERATE> "(" IterateParameterList ")"

JoinExp::= <JOIN> "(" ParameterList ";" ParameterList ";" ConditionalExpression ";" ParameterList ")"

StringOperation::= StrConcat | StrToUpper | StrToLower | Substring

StringOrTupleSize::= <SIZE> "(" ")"

StrConcat::= <CONCAT> "(" Expression ")"

StrToUpper::= <TOUPPER> "(" ")"

StrToLower::= <TOLOWER> "(" ")"

Substring::= <SUBSTRING> "(" Expression "," Expression ")"

TupleOperation::= TupleGetValue | TupleGetElemName | TupleGetElemType

TupleGetValue::= <GETVALUE> "(" TupleElemName ")"

TupleGetElemName::= <GETELEMNAME> "(" Expression ")"

TupleGetElemType::= <GETELEMTYPE> "(" Expression ")"

IterateParameterList::= <ID> (":" DataTypes)? ";" <ID> ":" DataTypes <EQUAL> Expression "|" Expression

ParameterList::= ExpressionList?

ExpressionList::= Expression ("," Expression)*

ObjectList::= Object ("," Object)*

Object::= Expression

PropertyList::= Property ("," Property)*

Property::= Name

TupleElemName::= Name

 6.3.6Statements
 6.3.6.1exhibit

OuterExpression::= Declarative+ ( ExpressionNP? | <IN> Expression ) | Expression

Declarative::= LetStatement | ContextNavigationStatement

InnerExpression::= LetStatement+ (ExpressionNP | <IN> Expression) | Expression

LetStatement::= <LET> <ID> ":" DataTypes <EQUAL> Expression

IfStatement::= <IF> Expression <THEN> InnerExpression <ELSE> InnerExpression <ENDIF>

ContextNavigationStatement::= ContextStatement | PackageStatement

ContextStatement::= <CONTEXT> ContextClass ContextBlock? | <CONTEXT> Alias ":" ContextClass ContextBlock?

ContextClass::= ClassName | CollectionType "(" ContextClass ")"

ContextBlock::= DefinitionBody+

DefinitionBody::= <DEF> ":" <ID> ":" DataTypes <EQUAL> InnerExpression | <DEF> ":" <ID> "(" FormalParams? ")" ":" DataTypes <EQUAL> InnerExpression

FormalParams::= <ID> ":" DataTypes ("," FormalParams )?

Alias::= <ID>

PackageStatement::= <PACKAGE> PackageName ContextStatement+ <ENDPACKAGE>

PackageName::= Name

 6.3.7.1exhibit

ReferenceToInstance::= <FACTORY>.ClassName(ParameterList )

<#DECIMAL_LITERAL: (["0"-"9"])+ >

<#EXPONENT: ["e", "E"] (["+","-"])? (["0"-"9"])+>

<INTEGER_LITERAL: <DECIMAL_LITERAL>>

<REAL_LITERAL: <DECIMAL_LITERAL> "." (["0"-"9"])* (<EXPONENT>)? | "." (["0"-"9"])+ (<EXPONENT>)? >

<STRING_LITERAL: ('\"' (~[ '\"' , "\n", "\r"])* '\"' | "\'" (~[ "\'" , "\n", "\r"])* "\'" ) >

<ID: ["a"-"z","A"-"Z"] (["a"-"z","A"-"Z","0"-"9"] | "_"(["a"-"z","A"-"Z","0"-"9"])+)* >

<BAG: "Bag">

<BOOLEAN: "Boolean">

<ENUM: "Enum">

<INTEGER: "Integer">

<NULL: "null">

<REAL: "Real">

<SEQUENCE: "Sequence">

<SET: "Set">

<STRING: "String">

<SELF: "Self">

<TUPLE: "Tuple" >

<UNKNOWN: "unknown" | "Unknown" >

 6.3.10Operators

<AND: "&" | "and" >

<ARROW: "->" | "→" >

<AVERAGE: "average" >

<BETWEEN: "between" >

<COLLECT: "collect" >

<CONCAT: "concat" >

<COUNT: "count" >

<DEF: "Def" | "def" >

<DISTINCT: "distinct" >

<DIVIDE: "/" >

<ELEMAT: "elemat" >

<EXCLUDING: "excluding" >

<EXISTS: "exists" >

<FACTORY: "factory">

<FALSE: "false" | "False" >

<FIRSTN: "firstN" >

<FLATTEN: "flatten" >

<FORALL: "forAll" >

<EQUAL: "=" >

<GEQ: ">=" >

<GETELEMNAME: "getElemName" >

<GETELEMTYPE: "getElemType" >

<GETVALUE: "getValue" >

<GT: ">" >

<INCLUDES: "includes" >

<INCLUDESALL: "includesAll" >

<INCLUDING: "including" >

<INTDIV: "div" >

<INTERSECTION: "intersection" >

<ISEMPTY: "isEmpty" >

<ITERATE: "iterate" >

<JOIN: "join" >

<LASTN: "lastN" >

<LEQ: "<=" >

<LIKE: "like" >

<LT: "<" >

<MAX: "max" >

<MEAN: "mean" >

<MEDIAN: "median" >

<MIN: "min" >

<MINUS: "-" >

<MOD: "mod" >

<MODE: "mode" >

<NEQ: "!=" | "<>" >

<NEW: "new" >

<NOT: "!" | "not" >

<NOTEMPTY: "notEmpty" >

<NOTLIKE: "notlike" >

<OR: "|" | |or" >

<PLUS: "+" >

<REJECT: "reject" >

<REVERSE: "reverse" >

<SELECT: "select" >

<SIZE: "size" >

<SORTBY: "sortBy" >

<SDEV: "stdev" >

<SUBSTRING: "substring" >

<SUM: "sum" >

<TIMES: "*" >

<TOLOWER: "toLower" >

<TOUPPER: "toUpper">

<TRUE: "true">

<UNION: "union" >

<VARIANCE: "variance" >

<XOR: "*|" | "xor" >

 6.3.11Statements

<CONTEXT: "context" | "Context">

<ELSE: "else" >

<ENDPACKAGE: "EndPackage" | "endPackage" | "endpackage" >

<ENDIF: "endif" >

<IF: "If" | "if" >

<IN: "in" >

<LET: "Let" | "let" >

<PACKAGE: "Package" | "package">

<THEN: "then" >

A GELLO expression is any text string conforming to the definition of an expression in the GELLO language specification. GELLO expressions can be used to:

  • Access information from a repository
  • Build decision criteria
  • Abstract or derive summary values

When an expression is evaluated, the result of such evaluation is a value. The type of the result is the type of the expression.

Evaluation of an expression does not produce any side effects, although the returning value can be bound to a variable name and used by the guideline to make decisions, control execution flow, etc. If an expression can be embedded in a conditional statement, the returning value is interpreted by the application to which the conditional statement belongs.

If an expression denotes a variable or a value, then such expression has a type that must be checked for compatibility. Such variable or value must match any of GELLO predefined §‎5.1.1, collection §‎5.1.3 or tuple data types §‎5.1.4, or classes defined in the underlying data model §‎5.1.2.

If a value is bound to a variable name, both the returning value and the variable to which it is assigned must be of the same type.

Expressions are evaluated by following a series of steps. Normal completion signifies that all steps can be carried out without an exception being thrown. If, however, evaluation of an expression throws an exception, the expression is said to complete abruptly. GELLO provides basic error checking described in the following section.

GELLO was developed as a strongly-typed language in response to the requests of the CDS TC community. Both GELLO and OCL are strongly-typed, hence consistency was maintained. Since GELLO is a strongly-typed language, it checks that the types of all expressions are valid and match one of GELLO or model data types. Similarly, GELLO checks that the operands match the required types for any given operator. In other words, if an operator is applied to an incompatible operand, the return type of the function is undefined.

Although GELLO provides basic type checking, it does not provide any mechanisms for handling exceptions as a result of a type mismatch. The applications into which GELLO is embedded should provide the necessary error handling mechanisms.

Expressions are evaluated from left to right. In the case of infix operators, the evaluation order is determined by the precedence of the operators.

Argument lists included in method invocations are evaluated left-to-right.

When the following expressions are evaluated, they return a value of type Boolean. Expressions like these can be used to build decision criteria:

 6.8.1example

• calcium → notEmpty() and phosphate → notEmpty() • renal_failure and calcium_phosphate_product > threshold_for_osteodystrophy • Observation → select(coded_concept="C0428279") The expression above returns a collection of observations with a coded concept equal to "C0428279". The result of an expression can be bound to a variable name using the let operator: • let CreatinineReadings: set = Observation → select(coded_concept="C0428279")

In this section we present some examples written in GELLO.

From a MLM:

 7.1.1example
   maintenance: 
      title: Screening for elevated calcium-phosphate product;; 
   library: 
      purpose: provide an alert if the product of the blood calcium and 
         phosphorus exceeds a certain threshold in the setting of renal failure;;
      explanation: An elevated Ca-PO4 product suggests a tendency toward renal 
         osteodystrophy and predisposes to soft-tissue calcification;; 
					

Example in GELLO:

 7.1.2example
   let lastCreatinine : Observation = Observation → select(code= 
         Factory.CodedValue("SNOMED-CT", "xxxxxx")).sortedBy(efectiveTime.high).last()  
         
   let lastCalcium : Observation = Observation → select(code = 
         Factory.CodedValue("SNOMED-CT", "yyyyy")).sortedBy(efectiveTime.high).last() 
         
   let lastPhosphate : Observation = Observation → select(code= 
         Factory.CodedValue("SNOMED-CT", "zzzzz")).sortedBy(efectiveTime.high).last() 
         
   let renal_failure_threshold : PhysicalQuantity = 
         Factory.PhysicalQuantity( "2.0, mg/dl") 
   
   let threshold_for_osteodystrophy : int = 70 
   
   let renal_failure :Boolean =    if lastCreatinine <> null and 
         lastCreatine.value.greaterThan(renal_failure_threshold)  
      then          
         true   
      else
         false   
      endif 
   let calcium_phosphate_product : real = if lastCalcium 
         <> null and lastPhosphate <> null 
      then   
         lastCalcium.value *  lastPhospate.value 
      else   
         -1
      endif 

   if renal_failure and calcium_phosphate_product >  
         threshold_for_osteodystrophy then   
      "whatever action or message"
   else   
      "whatever action or message"
   endif 
					

This example shows how collection operators can be nested in expressions as long as they comply with the notation.

Statement in English (many thanks to Samson Tu):

"There exists (for a patient) an anti-hypertensive prescription (?drug) such that there exists (for the patient) a problem (?problem) such that ?problem is a compelling indication for ?drug". Where:

  • ‘a patient’ is the current patient?
  • drug is any drug in the drug database
  • ?problem is a patient’s problem

Statement in English (many thanks to Samson Tu):

 7.2.1example
   Presence of Azotemia Observation within last three months : Assumptions: 
         1. The data model has as code a generic term such as 
             SNOMED "finding" ("246188002") and the value slot has 
             the code for Azotemia. 
         2. For a diagnosis such as azotemia, the effective time is the time 
             interval during which the disease is thought to be present. 
         3. A PointInTime.NOW() function returns the current time 
 
   Example in GELLO: 
      Let month : CodedValue = Factory.CodedValue(""SNOMED-CT", "258706009")  
      Let finding : CodedValue = Factory.CodedValue("SNOMED-CT", "246188002") 
      Let azotemia : CodedValue = Factory.CodedValue ("SNOMED-CT", "371019009")
      Observation → exists(code.equal(finding) and value.implies(azotemia) and 
              effective_time.intersect(ThreeMonthsAgo, PointInTime.NOW())) 
						

Statement in English (many thanks to Samson Tu):

Number of current anti-hypertensive Medications > 1

 7.3.1example
   Example in GELLO: 
      Let hypotensive_agents : CodedValue = 
            Factory.CodedValue("SNOMED-CT", "1182007")  
            
      MedicationOrder→select(code.implies(hypotensive_agents) and 
            effectiveTime.high = null)→size() > 1 
 					

Statement in English (many thanks to Samson Tu):

3rd Td dose before 12 months of age

 7.4.1example
   Example in GELLO:
      Let month : CodedValue = Factory.CodedValue("SNOMED-CT", "258706009")
      
      Let DOBcode : CodedValue = Factory.CodedValue ("SNOMED-CT", "184099003")
      
      Let DateOfBirth : Observation= Factory.Observation→ select( 
            code.equal(DOBCode)).sortedBy(effectiveTime.high).last()
            
      Let TwelveMonthsOfAge : PointInTime = Factory.PointInTime(
            DateOfBirth.effectiveTime.high.plus(12, month)) 
            
      Let Td :CodedValue = Factory.CodedValue("SNOMED-CT", "59999009")
      
      Let ThirdTdDose : SubstanceAdministration = Factory.SubstanceAdministration→ 
            select(code.implies(Td)).sortedBy(effectiveTime.high).third() 
            ThirdTdDose.effectiveTime.high.before(TwelveMonthsOfAge) 
					

GELLO expressions can be grouped into ‘Model processes’ to perform user-defined operations upon given classes of the data model for a specific purpose.

A model process must be defined as an attribute of a stereotype class which could be:

  1. a user-defined class independent of the data model,
  2. a class dependent of a class in the data model. The latter being the ‘metaclass’ to which the user-defined stereotype class relates to. In this case the stereotype class must follow the UML class hierarchy definition (UML-OMG v1.5 p2-75)

In both cases the names of new stereotypes must not clash with the names of predefined classes in the data model. The stereotype class should not affect any of the properties of the classes in the data model, but rather, to extend such properties adding extra functionality.

Stereotypes may be assembled into ‘profiles’ –or libraries. A profile is a stereotyped package containing user-defined stereotype model elements customized for a specific domain or purpose (OCL/UML). In the following example, Package P1 is the profile where we assembled the stereotypes S1 and S2 dependent on C1 and C2 respectively. Both C1 and C2 are classes from the data model and hence S1 and S2 add extended functionality to those classes.

 8.1example
  
         Package P1
               Context S1<<stereotype>> : C1
               Context S2<<stereotype>> : C2
         EndPackage

					
 8.2example
  
Package P1
           Context Azotemia3months : Observation
             Def: checkAzotemia() : Boolean =
               Let month:CodedValue = Factory.CodedValue("SNOMED-CT", "258706009")
               Let finding: CodedValue = Factory.CodedValue("SNOMED-CT", "246188002")
               Let azotemia: CodedValue = Factory.CodedValue("SNOMED-CT", "371019009")
               Observation->exists(code.equal(finding) and value.implies(azotemia)
                                     and effective_time.intersect(ThreeMonthsAgo, PointInTime.Now()))

         EndPackage
					

In the following example, S3 is a stereotype independent of the data model located in Package P2:

 8.3example
  
         Package P2
               Context S3 <<stereotype>>
         EndPackage
 
					

As with all GELLO expressions, all model processes must be side-effect free, that is, they should not change the state of the modeled system.

The exhibit below is the UML representation for a user-defined stereotype class as an extension of a Model Class.

User-defined stereotype class as an extension of a Model Class 
[From UML-OMG v1.5Fig. 4-1]

The exhibit below is an example of the user-defined Azotemia3months as a stereotype class related to the model class Observation. CheckAzotemia is the model process containing the GELLO expressions that evaluate whether a patient has suffered from azotemia within the past 3 months.

: User-defined Azotemia3Months stereotype class. The stereotype class depends on the Observation class (metaclass) in the datamodel. The model process CheckAzotemia is an attribute of the stereotype class contraining GELLO expressions.

We would like to thank Gunther Schadow, Grahame Grieve, Dale Nelson, Bob Dolin, Anthony Malia, Mor Peleg, and Eclipsys Corporation for their valuable comments.

Support for this project has been provided by the CKBP grant and Partners Information Systems.

The following is a simplified data model included in this specification so examples of GELLO operators and operations can be illustrated and easily followed. The model upon which the simplified data model is based is the result of a feasibility study which reviewed various decision support systems within Brigham & Women’s Hospital and Massachusetts General Hospital [GR04]. The simplified data model consists of 5 model classes, each of which holds some properties that can be mapped into the HL7 RIM. These 5 classes and their equivalent in the RIM are showed in Table 1.

Classes in the Data Model Equivalent Classes in the HL7 RIM
Patient Person in the role of Patient
LabResult Observation
ProblemLIst Observation
Allergy Observation
Medication Substance Administration

Figure below depicts the data model. Each class includes some properties equivalent to those found in the RIM. The data model is by no means extensive. This data model will be used along the document to exemplify the use of GELLO operators in expressions in a simple manner.

Simplified Data Model

When referencing RIM classes directly more complex expressions can be written. Such expressions may include references to mood, and class code, in accordance with the HL7 RIM specification.

It is assumed that the HL7 v3 Data Types provides all 13 operators for handling Allen relations on temporal intervals. Such operators can be used in GELLO expressions referring to the appropriate model class and method. The 13 operators are described below for clarity.

A time interval is a set of consecutive time-stamps values during which the given information is expected to be valid. As defined in HL7 V3 Data Types (p 100), a time interval can be open or closed, infinite or undefined on either side. Graphic examples of temporal relations are depicted in Figure 2. There are thirteen fundamental relations, known as the Allen primitives, between pairs of time intervals.

E.1   Before

The notation is:

E.1.1   example
before(interval1,interval2).  

Types of "before" 
(timeInterval x timeInterval) → Boolean 

Definition of evaluation function for Fbefore(IVL1,IVL2) 
Fbefore(IVL,IVL) = true      If IVL1 and IVL2 are both time intervals and the 
						  end-point of interval1 occurs strictly earlier 
						  than the start-point of interval2. 
			  = false     Else if IVL1 and IVL2 are both time intervals 
						  and the end-point of interval1 does not occur 
						  strictly earlier than the start-point of interval2. 
			  = undefined otherwise 
				
E.2   After

The notation is:

E.2.1   example
after(interval1,interval2).  

Types of "after" 
(timeInterval x timeInterval) → Boolean 

Definition of evaluation function for Fafter(IVL1,IVL2)
Fafter(IVL,IVL) = true         If IVL1 and IVL2 are both time intervals and 
						   the start-point of interval1 occurs (starts) after 
						   the end-point of interval2. 
			= false        Else if IVL1 and IVL2 are both time intervals and 
						   the start-point of interval1 does not occur after 
						   the end-point of interval2. 
			= undefined    otherwise 
				  
E.3   Meets

The notation is:

E.3.1   example
meets(interval1,interval2).  

Types of "meets" 
(timeInterval x timeInterval) → Boolean 

Definition of evaluation function for Fmeets(IVL1,IVL2) 
Fmeets(IVL,IVL) = true          If IVL1 and IVL2 are both time intervals and 
							 the end-point of interval1 is simultaneous with 
							 the start-point of interval2. 
			= false          Else if IVL1 and IVL2 are both time intervals and 
							 end-point of interval1 is not simultaneous with 
							 the start-point of interval2.
			= undefined      otherwise 
				 
E.4   Met-By

The notation is:

E.4.1   example
met-by(interval1,interval2).  

Types of "met-by" 
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Fmet-by(IVL1,IVL2)
Fmet-by(IVL,IVL) = true      If IVL1 and IVL2 are both time intervals and the 
						 start-point of interval1 is simultaneous with the 
						 end-point of interval2.
			= false      Else if IVL1 and IVL2 are both time intervals and 
						 start-point of interval1 is not simultaneous with 
						 the end-point of interval2.
			= undefined  otherwise
			  
E.5   Overlaps

The notation is:

E.5.1   example
overlaps(interval1,interval2). 

Types of "overlaps"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Foverlaps(IVL1,IVL2)
Foverlaps(IVL,IVL) = true        If IVL1 and IVL2 are both time intervals and 
							 the start-point of interval1 is earlier than  
							 the start-point of interval2, but the end-point 
							 of interval1 occurs strictly between the 
							 start- and end-points of interval2.
			   = false       Else if IVL1 and IVL2 are both time intervals 
							 and start-point of interval1 is not earlier 
							 than the start-point of interval2, or  the 
							 end-point of interval1 does not ocurr
							 strictly between the start- and 
							 end-points of interval2.
			   = undefined  otherwise
				 

The notation is:

E.6.1   example
overlapped-by(interval1,interval2). 

Types of "overlapped-by"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Foverlapped-by(IVL1,IVL2)
Foverlapped-by(IVL,IVL) = true        If IVL1 and IVL2 are both time intervals 
								  and the start-point of interval1 occurs 
								  between the start- and end-points of 
								  interval2, but the end-point of interval1 
								  occurs later than the end-point of interval2.
					= false       Else if IVL1 and IVL2 are both time intervals 
								  and the start-point of interval1 does not 
								  occur between the start- and end-points 
								  of interval2, or the end-point of interval1 
								  occurs before the end-point of interval2.
					= undefined   otherwise
				 
E.7   Starts

The notation is:

E.7.1   example
starts(interval1,interval2). 
Types of "starts"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Fstarts(IVL1,IVL2)
Fstarts(IVL,IVL) = true       If IVL1 and IVL2 are both time intervals and the 
						   start-point of interval1 occurs simultaneously 
						   with the start-point of interval2, but the 
						   end-point of interval1 occurs before the
						   end-point of interval2.
			 = false       Else if IVL1 and IVL2 are both time intervals 
						   and the start-point of interval1 does not occur 
						   simultaneously with the start-point of interval2, 
						   or the end-point of interval1 occurs after the
						   end-point of interval2.
			 = undefined   otherwise
				 
E.8   Started-by

The notation is:

E.8.1   example
started-by(interval1,interval2). 

Types of "started-by"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Fstarted-by(IVL1,IVL2)
Fstarted-by(IVL,IVL) = true        If IVL1 and IVL2 are both time intervals and
							   the start-point if interval1 is simultaneous 
							   with the start-point of interval2, but the 
							   end-point of interval1 occurs later than the 
							   end-point of interval2.
				 = false       Else if IVL1 and IVL2 are both time 
							   intervals and the start-point if interval1 is 
							   not simultaneous with the start-point of 
							   interval2, or the end-point of interval1 
							   occurs before the end-point of interval2.
				 = undefined   otherwise
				 
E.9   During

The notation is:

E.9.1   example
during(interval1,interval2). 
				

Types of "during" (timeInterval x timeInterval) → Boolean Definition of evaluation function for Fduring(IVL1,IVL2) Fduring(IVL,IVL) = true If IVL1 and IVL2 are both time intervals and the start-point of interval1 occurs after the start-point of interval2 and the end-point of interval1 occurs earlier than the end-point of interval2. = false Else if IVL1 and IVL2 are both time intervals but the start-point of interval1 occurs before the start-point of interval2 or the end-point of interval1 occurs later than the end-point of interval2. = undefined otherwise
E.10   Contains

The notation is:

E.10.1   example
contains(interval1,interval2). 

Types of "contains"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Fcontains(IVL1,IVL2)
Fcontains(IVL,IVL) = true         If IVL1 and IVL2 are both time intervals and 
							  the start-point of interval1 is earlier than the 
							  start-point of interval2, and the end of interval1 
							  occurs later than the end-point of interval2.
			   = false        Else if IVL1 and IVL2 are both time intervals but 
							  the start-point of interval1 is later than the 
							  start-point of interval2, or the end of interval1  
							  occurs earlier than the end-point of interval2.
			   = undefined    otherwise
				  
E.11   Finishes

The notation is:

E.11.1   example
finishes(interval1,interval2). 

Types of "finishes"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Ffinishes(IVL1,IVL2)
Ffinishes(IVL,IVL) = true         If IVL1 and IVL2 are both time intervals and 
							  the end-point of interval1 is simultaneous with 
							  the end-point of interval2, but the start-point  
							  of interval1 is later than the start-point of 
							  interval2.
			   = false        Else if IVL1 and IVL2 are both time intervals 
							  but the end-point of interval1is not 
							  simultaneous with the end-point of interval2, 
							  or the start-point of interval1 is earlier than the 
							  start-point of interval2.
			   = undefined    otherwise
				  
E.12   Finished-by

The notation is:

E.12.1   example
finished-by(interval1,interval2). 

Types of "finished-by"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Ffinished-by(IVL1,IVL2)
Ffinished-by(IVL,IVL) = true         If IVL1 and IVL2 are both time intervals and
								 the end-point of interval1 is simultaneous with 
								 the end-point of interval2, but the start-point of 
								 interval1 is earlier than the start-point of interval2.
				  = false        Else if IVL1 and IVL2 are both time intervals but the 
								 end-point of interval1 is not simultaneous with 
								 the end-point of interval2, or  the start-point of 
								 interval1 is later than the start-point of interval2.
				  = undefined    otherwise
				  
E.13   Equals

The notation is:

E.13.1   example
equals(interval1,interval2). 

Types of "equals"
(timeInterval x timeInterval) → Boolean

Definition of evaluation function for Fequals(IVL1,IVL2)
Fequals(IVL,IVL) = true        If IVL1 and IVL2 are both time intervals and the 
						   start- and end-points of both interval1 and 
						   interval2 are respectively simultaneous.
			 = false       Else if IVL1 and IVL2 are both time intervals 
						   but the start- and end-points of both interval1 
						   and interval2 respectively are not simultaneous.
			 = undefined   otherwise
				  

Temporal Relations between Time Intervals

Return to top of page