Model Overview

The model described here is a pure object-oriented model that can be used with archetype parsers and software that manipulates archetypes and templates in memory. It is typically the output of a parser of any serialised form of archetypes.

Used BASE Component Packages

The AOM is dependent on various packages from the openEHR BASE component. The first of these is the base.foundation_types package, which defines the various 'leaf' types assumed by the AOM as well as other utility types and basic data structures, such as the Interval<T> type. These types are documented in the openEHR Foundation Types specification and reproduced below for convenience.

BASE foundation types leaf types
Figure 1. base.foundation_types - 'leaf' types
BASE foundation types.interval
Figure 2. base.foundation_types.interval Package
the above types do not constitute a formal part of this specification. Any implementation of the AOM will typically have to use concrete versions of these types found within languages and/or libraries.

In addition, various definitions from the base.base_types.definitions package are reused, which are shown below.

BASE base types.definitions
Figure 3. base.base_types.definitions Package

The enumeration type VALIDITY_KIND is provided in order to define standard values representing mandatory, optional, or disallowed in any model. It is used in this model in classes such as C_DATE , C_TIME and C_DATE_TIME. The VERSION_STATUS enumeration type serves a similar function within various AOM types.

Other classes used from the BASE Component include the base.resource package, which includes the class AUTHORED_RESOURCE and subordinate classes. These are shown by inclusion in the AOM Archetype package diagram below.

Finally, classes from the BASE Component base.expressions package is used by the rules part of the AOM. This is documented in the relevant section below.

AOM2 Package Structure

The Archetype Object Model is defined by the package am.aom2 and subordinate packages, as illustrated in Package Overview.

AM aom2 packages
Figure 4. Package Overview

Definition and Utility Classes

Overview

Various definitional constants are used in the AOM. These are defined in the aom2.definitions package from the AM component and are shown below.

AM aom2.definitions
Figure 5. Definition Package

ADL_CODE_DEFINITIONS Class

  • Definition

  • Effective

  • BMM

  • UML

Class

ADL_CODE_DEFINITIONS

Description

Definitions relating to the internal code system of archetypes.

Constants

Signature

Meaning

1..1

Id_code_leader: String = "id"

String leader of ‘identifier’ codes, i.e. codes used to identify archetype nodes.

1..1

Value_code_leader: String = "at"

String leader of ‘value’ codes, i.e. codes used to identify codes values, including value set members.

1..1

Value_set_code_leader: String = "ac"

String leader of ‘value set’ codes, i.e. codes used to identify value sets.

1..1

Specialisation_separator: Character = '.'

Character used to separate numeric parts of codes belonging to different specialisation levels.

1..1

Code_regex_pattern: `String = "(0

[1-9][0-9]*)(\.(0

[1-9]))"`

Regex used to define the legal numeric part of any archetype code. Corresponds to the simple pattern of dotted numbers, as used in typical multi-level numbering schemes.

1..1

Root_code_regex_pattern: String = "^id1(\.1)*$"

Regex pattern of the root id code of any archetype. Corresponds to codes of the form id1, id1.1, id1.1.1 etc..

1..1

Primitive_node_id: String = "id9999"

Code id used for C_PRIMITIVE_OBJECT nodes on creation.

Functions

Signature

Meaning

1..1

codes_conformant (
a_child_code: String[1],
a_parent_code: String[1]
): Boolean

True if a_child_code conforms to a_parent_code in the sense of specialisation, i.e. is a_child_code the same as or more specialised than a_parent_code?

1..1

is_adl_code (
a_code: String[1]
): Boolean

Post: Result = is_id_code (a_code) or else is_value_code (a_code) or else is_value_set_code (a_code)

True if a_code is any kind of ADL archetype local code.

1..1

is_id_code (
a_code: String[1]
): Boolean

Post: Result = a_code.starts_with (Id_code_leader)

True if a_code is an 'id' code.

1..1

is_value_code (
a_code: String[1]
): Boolean

Post: Result = a_code.starts_with (Value_code_leader)

True if a_code is an 'at' code, i.e. a code representing a single terminology item.

1..1

is_value_set_code (
a_code: String[1]
): Boolean

Post: Result = a_code.starts_with (Value_set_code_leader)

True if a_code is an 'ac' code, i.e. a code referring to a terminology value set.

1..1

is_redefined_code (
a_code: String[1]
): Boolean

A code has been specialised if there is a non-zero code index anywhere above the last index e.g.

  • at0.0.1 → False

  • at1.0.1 → True

1..1

ADL_CODE_DEFINITIONS

Definitions relating to the internal code system of archetypes.

Constants

Id_code_leader: String = "id" [1..1]

String leader of ‘identifier’ codes, i.e. codes used to identify archetype nodes.

Value_code_leader: String = "at" [1..1]

String leader of ‘value’ codes, i.e. codes used to identify codes values, including value set members.

Value_set_code_leader: String = "ac" [1..1]

String leader of ‘value set’ codes, i.e. codes used to identify value sets.

Specialisation_separator: Character = '.' [1..1]

Character used to separate numeric parts of codes belonging to different specialisation levels.

Code_regex_pattern: `String = "(0

[1-9][0-9]*)(\.(0

[1-9]))"` [1..1]

Regex used to define the legal numeric part of any archetype code. Corresponds to the simple pattern of dotted numbers, as used in typical multi-level numbering schemes.

Root_code_regex_pattern: String = "^id1(\.1)*$" [1..1]

Regex pattern of the root id code of any archetype. Corresponds to codes of the form id1, id1.1, id1.1.1 etc..

Primitive_node_id: String = "id9999" [1..1]

Code id used for C_PRIMITIVE_OBJECT nodes on creation.

Functions

codes_conformant (
a_child_code: String[1],
a_parent_code: String[1]
): Boolean [1..1]

True if a_child_code conforms to a_parent_code in the sense of specialisation, i.e. is a_child_code the same as or more specialised than a_parent_code?

is_adl_code (
a_code: String[1]
): Boolean

Post: Result = is_id_code (a_code) or else is_value_code (a_code) or else is_value_set_code (a_code) [1..1]

True if a_code is any kind of ADL archetype local code.

is_id_code (
a_code: String[1]
): Boolean

Post: Result = a_code.starts_with (Id_code_leader) [1..1]

True if a_code is an 'id' code.

is_value_code (
a_code: String[1]
): Boolean

Post: Result = a_code.starts_with (Value_code_leader) [1..1]

True if a_code is an 'at' code, i.e. a code representing a single terminology item.

is_value_set_code (
a_code: String[1]
): Boolean

Post: Result = a_code.starts_with (Value_set_code_leader) [1..1]

True if a_code is an 'ac' code, i.e. a code referring to a terminology value set.

is_redefined_code (
a_code: String[1]
): Boolean [1..1]

A code has been specialised if there is a non-zero code index anywhere above the last index e.g.

  • at0.0.1 → False

  • at1.0.1 → True

code_exists_at_level (
a-code: String[1],
a_level: Integer[1]
): Boolean [1..1]

Is a_code valid at level a_level or less, i.e. if we remove its trailing specialised part corresponding to specialisation below a_level, and then any trailing '.0' pieces, do we end up with a valid code? If so it means that the code corresponds to a real node from a_level or higher.

{
    "name": "ADL_CODE_DEFINITIONS",
    "documentation": "Definitions relating to the internal code system of archetypes.",
    "constants": {
        "Id_code_leader": {
            "name": "Id_code_leader",
            "documentation": "String leader of ‘identifier’ codes, i.e. codes used to identify archetype nodes.",
            "type": "String",
            "value": "\"id\""
        },
        "Value_code_leader": {
            "name": "Value_code_leader",
            "documentation": "String leader of ‘value’ codes, i.e. codes used to identify codes values, including value set members.",
            "type": "String",
            "value": "\"at\""
        },
        "Value_set_code_leader": {
            "name": "Value_set_code_leader",
            "documentation": "String leader of ‘value set’ codes, i.e. codes used to identify value sets.",
            "type": "String",
            "value": "\"ac\""
        },
        "Specialisation_separator": {
            "name": "Specialisation_separator",
            "documentation": "Character used to separate numeric parts of codes belonging to different specialisation levels.",
            "type": "Character",
            "value": "'.'"
        },
        "Code_regex_pattern": {
            "name": "Code_regex_pattern",
            "documentation": "Regex used to define the legal numeric part of any archetype code. Corresponds to the simple pattern of dotted numbers, as used in typical multi-level numbering schemes.",
            "type": "String",
            "value": "\"(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*))*\""
        },
        "Root_code_regex_pattern": {
            "name": "Root_code_regex_pattern",
            "documentation": "Regex pattern of the root id code of any archetype. Corresponds to codes of the form `id1`, `id1.1`, `id1.1.1` etc..",
            "type": "String",
            "value": "\"^id1(\\.1)*$\""
        },
        "Primitive_node_id": {
            "name": "Primitive_node_id",
            "documentation": "Code id used for `C_PRIMITIVE_OBJECT` nodes on creation.",
            "type": "String",
            "value": "\"id9999\""
        }
    },
    "functions": {
        "codes_conformant": {
            "name": "codes_conformant",
            "documentation": "True if `_a_child_code_` conforms to `_a_parent_code_` in the sense of specialisation, i.e. is `_a_child_code_` the same as or more specialised than `_a_parent_code_`?",
            "parameters": {
                "a_child_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_child_code",
                    "type": "String"
                },
                "a_parent_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_parent_code",
                    "type": "String"
                }
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        },
        "is_adl_code": {
            "name": "is_adl_code",
            "documentation": "True if `_a_code_` is any kind of ADL archetype local code.",
            "parameters": {
                "a_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_code",
                    "type": "String"
                }
            },
            "post_conditions": {
                "Post": "Result = is_id_code (a_code) or else is_value_code (a_code) or else is_value_set_code (a_code)"
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        },
        "is_id_code": {
            "name": "is_id_code",
            "documentation": "True if `_a_code_` is an 'id' code.",
            "parameters": {
                "a_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_code",
                    "type": "String"
                }
            },
            "post_conditions": {
                "Post": "Result = a_code.starts_with (Id_code_leader)"
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        },
        "is_value_code": {
            "name": "is_value_code",
            "documentation": "True if `_a_code_` is an 'at' code, i.e. a code representing a single terminology item.",
            "parameters": {
                "a_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_code",
                    "type": "String"
                }
            },
            "post_conditions": {
                "Post": "Result = a_code.starts_with (Value_code_leader)"
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        },
        "is_value_set_code": {
            "name": "is_value_set_code",
            "documentation": "True if `_a_code_` is an 'ac' code, i.e. a code referring to a terminology value set.",
            "parameters": {
                "a_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_code",
                    "type": "String"
                }
            },
            "post_conditions": {
                "Post": "Result = a_code.starts_with (Value_set_code_leader)"
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        },
        "is_redefined_code": {
            "name": "is_redefined_code",
            "documentation": "A code has been specialised if there is a non-zero code index anywhere above the last index e.g. \n\n* `at0.0.1` -> False\n* `at1.0.1` -> True",
            "parameters": {
                "a_code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_code",
                    "type": "String"
                }
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        },
        "code_exists_at_level": {
            "name": "code_exists_at_level",
            "documentation": "Is `_a_code_` valid at level `_a_level_` or less, i.e. if we remove its trailing specialised part corresponding to specialisation below `_a_level_`, and then any trailing '.0' pieces, do we end up with a valid code? If so it means that the code corresponds to a real node from `_a_level_` or higher.",
            "parameters": {
                "a-code": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a-code",
                    "type": "String"
                },
                "a_level": {
                    "_type": "P_BMM_SINGLE_FUNCTION_PARAMETER",
                    "name": "a_level",
                    "type": "Integer"
                }
            },
            "result": {
                "_type": "P_BMM_SIMPLE_TYPE",
                "type": "Boolean"
            }
        }
    }
}
ADL_CODE_DEFINITIONS

Utility Algorithms

Useful utility algorithms from the above class, referenced elsewhere in this specification are shown below.

    codes_conformant (a_child_code, a_parent_code: String): Boolean
            -- True if `a_child_code' conforms to `a_parent_code' in the sense of specialisation, i.e.
            -- is `a_child_code' the same as or more specialised than `a_parent_code'
        do
            Result := is_valid_code (a_child_code) and then a_child_code.starts_with (a_parent_code) and then
                (a_child_code.count = a_parent_code.count or else
                a_child_code.item (a_parent_code.count + 1) = Specialisation_separator)
        end