Basic Meta-Model (BMM)
Issuer: openEHR Specification Program | |
---|---|
Release: BASE Release-1.0.4 |
Status: TRIAL |
Revision: [latest_issue] |
Date: [latest_issue_date] |
Keywords: reflection, meta-model, UML |
© 2016 - 2022 The openEHR Foundation | |
---|---|
The openEHR Foundation is an independent, non-profit foundation, facilitating the sharing of health records by consumers and clinicians via open specifications, clinical models and open platform implementations. |
|
Licence |
Creative Commons Attribution-NoDerivs 3.0 Unported. https://creativecommons.org/licenses/by-nd/3.0/ |
Support |
Issues: Problem Reports |
Amendment Record
Issue | Details | Raiser | Completed |
---|---|---|---|
Separate |
T Beale |
||
2.2.2 |
Improve and update introductory text in the Overview section. |
E Sundvall, |
03 Nov 2017 |
2.2.1 |
Remove |
C Nanjo, |
02 Mar 2017 |
2.2.0 |
Rename |
T Beale |
20 Jun 2016 |
2.1.0 |
Initial writing based on ADL Workbench implementation. |
T Beale |
08 Feb 2016 |
Acknowledgements
Contributors
This specification has benefited from formal and informal input from the openEHR and wider health informatics community. The openEHR Foundation would like to recognise the following people for their contributions.
-
Patrick Langford, NeuronSong LLC, Utah, USA
-
Claude Nanjo MA African Studies., M Public Health, Cognitive Medical Systems Inc., California, USA
-
Harold Solbrig, Mayo Clinic, Rochester, USA
-
Erik Sundvall PhD, Linkoping University, Sweden
Trademarks
-
'openEHR' is a registered trademark of the openEHR Foundation;
-
'Java' is a registered trademark of Oracle Corporation;
-
'C#' is a registered trademark of Microsoft;
-
'OMG' and 'UML' are registered trademarks of the Object Management Group;
-
'MagicDraw' is a registered trademark of NoMagic Inc;
-
'Rational Software Architect' is a registered trademark of IBM Corporation.
1. Preface
1.1. Purpose
This document describes the Basic Meta-Model (BMM), a model of object models. It may be considered as an approximate replacement for the UML XMI. It is human-readable and writable, and supports generic types (open and closed), container types, and multiple inheritance.
1.2. Status
This specification is in the TRIAL state. The development version of this document can be found at {openehr_base_bmm}[www.openehr.org/releases/BASE/latest/bmm.html].
Known omissions or questions are indicated in the text with a 'to be determined' paragraph, as follows:
TBD: (example To Be Determined paragraph)
1.3. Feedback
Feedback may be provided on the openEHR languages specifications forum.
Issues may be raised on the specifications Problem Report tracker.
To see changes made due to previously reported issues, see the BASE component Change Request tracker.
1.4. Conformance
Conformance of a data or software artifact to an openEHR specification is determined by a formal test of that artifact against the relevant openEHR Implementation Technology Specification(s) (ITSs), such as an IDL interface or an XML-schema. Since ITSs are formal derivations from underlying models, ITS conformance indicates model conformance.
1.5. A Note on Language
The elements of meta-models are sometimes named confusingly in the literature and within various programming language technologies. In this specification, we have used the following terms:
- feature (of a class)
-
any stored or computed element of a class, including constants, attributes (properties) and routines (methods);
- property
-
a stored class feature; also known as 'attribute';
- routine
-
a computed class feature that may be either value-returning (a function) or work-performing (a procedure);
- function
-
a routine that computes and returns a value; typically causes no side-effects in the object;
- procedure
-
a routine that performs a computation; typically has side-effects;
- generic (class or type)
-
a kind of class or type that has parameters of other types; known as 'template' type in some programming languages.
1.6. Tooling
The openEHR Archie Library fully implements this specification in Java and may be used to build UI tools for compiling, viewing and editing BMM models.
The openEHR ADL Workbench (AWB) fully implements this specification, and provides a convenient way of illustrating BMM semantics. The screenshots used in this specification are all from the ADL Workbench. The tool is written in the Eiffel language, and is available as open source on Github. The BMM libraries can be found in the EOMF Github repository.
2. Overview
2.1. Introduction
One of the key needs in any open computing environment is a computable representation of its own models. This is for a number of purposes, including reasoning about them, performing validation and consistency checking, building software and generating documentation. This is particularly true of openEHR and other archetype-based frameworks, where a further need is to be able to validate archetypes and templates with respect to the reference model, and also to validate runtime instance data against operational templates and the reference model.
A number of computable representations of the openEHR published models have been available in the past. Currently models are represented in two computable forms, namely UML and BMM (i.e. the format described in this specification).
The primary use of the UML expression is for specification publishing. In this role, UML diagrams and static models are built, and then post-processed to correct signatures of class properties and functions. The post-processing corrects UML’s shortcomings and errors in non-singular relations, generic (template) types, and qualified attributes. The result can be used for publishing documentation with feature signatures that are formally correct and will be understood by developers in most programming languages. It can also be serialised and used computably, e.g. in other visualisation or modelling tools. UML’s own serial format, XMI is thus generally unsuitable for such uses, due to the formal errors, as well as its excessive complexity. XMI is also notoriously non-standard across UML tools.
As a result, openEHR introduced the Basic Meta-Model (BMM) in 2009 as a way of representing correct object-oriented semantics of information models for use in tools, along with a serial format by default expressed in the openEHR ODIN syntax.
The BMM provides a standalone alternative to UML/XMI which correctly represents all types, including open and closed generic types, inheritance of generic types, and various other problems with UML. As a meta-model it is adapted to the task, i.e. representing entity types that can appear in object models, rather than the over-generalised semantics of the UML meta-model. This reduced scope, and the fact that it contains no diagram semantics enables its serial form to be very human-readable.
Note
|
Other than for working with particular tools designed to use BMM, BMM is not a required formalism for implementing openEHR, and other methods of accessing models computably may be used, including UML and software implementations of the openEHR Reference Model. |
2.2. Current State of the Art
2.2.1. UML
One would expect that the IT industry would have fully computable representations of models and diagramming solved, but it is not yet the case. UML 2.x and its associated serialisation format XMI 2.x should in theory mean that complete, interoperable machine expressions of object models would be available in all tools. However the evolution of UML and XMI has not been toward a clear meta-model and language for each of its sub-languages (i.e. static class model, state machine, interaction diagram etc) but rather toward a single universal model of everything in which elements of all of its needs are confusingly buried.
The UML 2.x specifications are exceedingly complex: UML 2.1.2 was specified by two documents, 'Superstructure' (738pp) and 'Infrastructure' (224pp); the UML 2.5.1 specification is only slightly smaller at 796 pages (see the {uml}[OMG UML page] for current specifications). The XMI 2.x specification is correspondingly complex, which seems to have so far prevented reliable tool interoperability (recognised as a critical issue by OMG in 2015). Despite the complexity, there are significant holes in the UML meta-model, including: the notion of 'type' is not formalised and the meta-model of generic types and container properties is problematic and does not map well to object programming languages. The Design By Contract (DbC) concept (i.e. pre-, post-conditions, class invariants), crucial for proper specifications, is in theory supported via the use of OCL 2.0 constraints in class definitions, but OCL suffers from the underlying semantic weaknesses as UML.
Experience with various UML tools (up till 2015) highlighted the following problems:
-
poor support for OCL and design by contract in most tools;
-
variable support for generic (i.e. template) classes; even those tools that properly implement the UML 2.5 specification are still very hard to use for defining generic classes because of problems in the specification that remain unaddressed;
-
problems with qualified attributes, which are used to represent identifier references to objects rather than direct references;
-
variable support for XSD generation across tools, where the results are wildly wrong in some tools;
-
in some tools, it is impossible to define an abstract formal model - the only option is to select a particular programming language profile such as Java or C# and thus get locked into the limitations of those languages (messy type systems, weak inheritance semantics, language-specific notion of types such as
Array<T>
,List<T>
, etc.).
Since 2015, the quality of UML tools has improved, and the XMI generated by some is more reliable. However, XMI generated by different tools is not the same for identical models, and some XMI importers offer numerous switches in order to process the XMI of another tool properly. XMI thus still needs to be processed with care.
Nevertheless, a small number of tools, including MagicDraw (currently used for representing openEHR models for the specifications) and Rational Software Architect (RSA), appear to implement UML 2.5 faithfully. This means that despite the limitations of UML 2.5 (as noted above), models expressed in it can be mostly correctly interpreted and post-processed for purposes such as code generation.
Note
|
Other tools may well perform as well or better, and in any case, all tools change over time. No endorsement of a particular tool is intended here. |
2.2.2. XML Schema
For some, XML-schema represents a way of expressing object models, but it is not semantically suitable for this purpose, primarily due to its problematic non-object-oriented inheritance semantics, lack of generic classes, no representation of non-data members, and only marginal support for design by contract. It can be and is often used (including in openEHR) as a derivative serialisation representation.
2.3. Design Approach
The Basic Meta-Model supports the representation of object models in the ISO RM/ODP information point of view. It is designed to enable both human authoring and machine extraction (e.g. from a UML tool or programming language classes) of textual schemas. The semantics of the model are heavily influenced by the formal approach to object-orientation described by Bertrand Meyer in Object-oriented Software Construction [Meyer_OOSC2] and also the Eiffel language, which is significantly better match to object modelling than the UML 2.x meta-model.
Currently the BMM supports only the information point of view, i.e. no methods. It is oriented toward developing models of data. Tools that use the BMM can provide views of an object model expressed in BMM that are particularly useful to information modelling, such as 'closure' view show below. This is a computed reachability graph of a fully inheritance-flattened class and all properties, including recursive references.
One of the main uses of the BMM in the ADL Workbench and other similar tools is to provide a computable form of the information model for use with domain-level content models, such as archetypes. The following shows an archetype for which each node has its class shown (in colour), and additionally, the inclusion of non-archetyped attributes from the classes of the archetype nodes.
2.4. Specification Structure
This specification defines a BMM object model, i.e. the in-memory object structure of a BMM. The related {openehr_base_bmm_persistence}[BMM Persistence specification] defines an object model for a serialised schema form. The latter enables serialisation of a BMM into a concrete syntax such as ODIN, JSON or XML.
The BMM packages are as follows:
-
bmm
: the BMM-
rm_access
: the interface to most features including schema load/reload, generally used by an application as a reflection library; -
core
: the core BMM classes used for in-memory representation of an object model;
-
These are illustrated below.
3. Model Access Package
3.1. Overview
Note
|
This package is considered informative within this specification, not normative. |
The model_access
package provides an interface for the application to load BMM schemas and convert them to BMM model form, and is shown below. In this model, a schema is a concrete serial form of a model or part of a model. One or more schema files are parsed, validated and then converted to create a single BMM_MODEL
instance.
More than one format for representing serialised BMM models is possible, each having its load, validation and error-reporting logic. The common elements of the load, validate and convert logic are defined by the non format-specific classes in the package, with specific forms of the classes BMM_SCHEMA_DESCRIPTOR
and BMM_SCHEMA
required for each concrete format. The package above shows the relevant classes for the P_BMM
version 2.x format, which is normally saved in .bmm
files. Other formats may be saved in files with different extensions.
The singleton class BMM_MODEL_ACCESS
acts as the entry point for client software to obtain access to loaded BMM models. Since the latter start as schema files which are typically nested according to an 'include' hierarchy, they must be parsed, validated and merged to create each 'top-level' model. The schemas are accessed via instances of the BMM_SCHEMA_DESCRIPTOR
object, one for each schema file. The load()
routine loads a BMM schema file by direct deserialisation.
If the file is structurally correct (say ODIN, JSON etc), an in-memory schema instance will result (e.g. P_BMM_SCHEMA
in the case of the P_BMM
format), and its validate_created
method called. If this succeeds, SCHEMA_DESCRIPTOR.schema
will be set to this instance. Subsequently, schema.merge()
will be called repeatedly, which results in each schema
instance being the merged result of its include children and itself. After merging, BMM_SCHEMA_DESCRIPTOR.validate_merged()
will be called, and if successful, a call to create_model()
will result in BMM_SCHEMA_DESCRIPTOR.model
being populated.
Each successfully loaded model is thus instantiated as a BMM_MODEL
, and referenceable via BMM_MODEL_ACCESS.valid_models
, which keys models by model identifiers (BMM_SCHEMA_CORE.identifier
). The methods model_for_namespace()
and model_for_namespace()
are used to access a given model for a namespace to which the model applies.
The following screenshot shows the BMM schema configuration dialog in the AWB, including some meta-data, validation status etc, and also the schema nesting structure. A single hierarchy of schemas corresponds to a single instantiated BMM model.
The screenshot below shows a number of merged BMM models loaded into the AWB, including some of the packages and classes for the openehr_ehr_extract_1.0.4
model.
3.2. Class Definitions
3.2.1. BMM_MODEL_ACCESS Class
Class |
BMM_MODEL_ACCESS |
|
---|---|---|
Description |
Access to BMM models that have been loaded and validated from one or more schema sets. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
List of directories where all the schemas loaded here are found. |
|
0..1 |
all_schemas: |
All schemas found and loaded from |
0..1 |
Top-level (root) schemas in use. Table is keyed by |
|
0..1 |
|
|
Functions |
Signature |
Meaning |
0..1 |
initialise_with_load_list ( |
Initialise with a specific schema load list, usually a sub-set of schemas that will be found in a specified directories |
0..1 |
Load all schemas found in a specified directories |
|
0..1 |
reload_schemas |
Reload BMM schemas. |
1..1 |
Return ref model containing the model key which is a |
|
1..1 |
True if a model for a |
3.2.2. BMM_SCHEMA_DESCRIPTOR Class
Class |
BMM_SCHEMA_DESCRIPTOR (abstract) |
|
---|---|---|
Description |
Descriptor for a BMM schema. Contains a meta-data table of attributes obtained from a mini-ODIN parse of the schema file. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
bmm_schema: |
Persistent form of model. |
0..1 |
bmm_model: |
Computable form of model. |
1..1 |
schema_id: |
Schema id, formed from:
e.g. |
1..1 |
Table of |
|
0..1 |
Identifiers of schemas included by this schema. |
|
Functions |
Signature |
Meaning |
1..1 |
is_top_level (): |
True if this is a top-level schema, i.e. not included by some other schema. |
1..1 |
is_bmm_compatible (): |
True if the BMM version found in the schema (or assumed, if none) is compatible with that in this software. |
0..1 |
load |
Load schema into in-memory form, i.e. a |
0..1 |
validate_merged |
Validate loaded schema and report errors. |
0..1 |
Validate includes list for this schema, to see if each mentioned schema exists in |
|
0..1 |
create_model |
Create |
3.2.3. BMM_MODEL_METADATA Class
Class |
BMM_MODEL_METADATA |
|
---|---|---|
Description |
Core properties of |
|
Attributes |
Signature |
Meaning |
1..1 |
rm_publisher: |
Publisher of model expressed in the schema. |
1..1 |
rm_release: |
Release of model expressed in the schema as a 3-part numeric, e.g. "3.1.0" . |
3.2.4. BMM_SCHEMA Class
Class |
BMM_SCHEMA (abstract) |
|
---|---|---|
Description |
Parent of pesistable forms of |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
bmm_version: |
Version of BMM model, enabling schema evolution reasoning. Persisted attribute. |
0..1 |
primitive_types: |
Primitive type definitions. Persisted attribute. |
0..1 |
class_definitions: |
Class definitions. Persisted attribute. |
0..1 |
includes: |
Inclusion list, in the form of a hash of individual include specifications, each of which at least specifies the id of another schema, and may specify a namespace via which types from the included schemas are known in this schema. Persisted attribute. |
0..1 |
bmm_schema: |
Generated by create_bmm_schema from persisted elements. |
1..1 |
state: |
Current processing state. |
0..1 |
model_name: |
Name of this model, if this schema is a model root point. Not set for sub-schemas that are not considered models on their own. |
1..1 |
schema_name: |
Name of model expressed in schema; a 'schema' usually contains all of the packages of one 'model' of a publisher. A publisher with more than one model can have multiple schemas. |
1..1 |
schema_revision: |
Revision of schema. |
1..1 |
schema_lifecycle_state: |
Schema development lifecycle state. |
1..1 |
schema_author: |
Primary author of schema. |
1..1 |
schema_description: |
Description of schema. |
0..1 |
Contributing authors of schema. |
|
Functions |
Signature |
Meaning |
0..1 |
validate_created |
Do some basic validation post initial creation
|
0..1 |
load_finalise |
Finalisation work:
|
0..1 |
merge ( |
Merge in class and package definitions from |
0..1 |
validate |
Main validation prior to generation of |
0..1 |
create_bmm_model |
Populate |
1..1 |
read_to_validate (): |
|
1..1 |
schema_id (): |
Identifier of this schema, used for stating inclusions and identifying files. Formed as:
E.g. |
3.2.5. BMM_SCHEMA_STATE Enumeration
Enumeration |
BMM_SCHEMA_STATE |
|
---|---|---|
Description |
Enumeration of processing states of a |
|
Attributes |
Signature |
Meaning |
State_created |
Initial state directly after instantiation of schema. |
|
State_validated_created |
Initial validation pass after instantiation. |
|
State_includes_pending |
State of schema processing if there are still included schemas to process. |
|
State_includes_processed |
State when all included schemas have been processed. |
3.2.6. BMM_INCLUDE_SPEC Class
Class |
BMM_INCLUDE_SPEC |
|
---|---|---|
Description |
Schema inclusion structure. |
|
Attributes |
Signature |
Meaning |
1..1 |
id: |
Full identifier of the included schema, e.g. "openehr_primitive_types_1.0.2". |
3.2.7. P_BMM_SCHEMA_DESCRIPTOR Class
Class |
P_BMM_SCHEMA_DESCRIPTOR |
|
---|---|---|
Description |
Concrete descendant of |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
bmm_schema: |
Persistent form of model. |
3.2.8. P_BMM_SCHEMA Class
Class |
P_BMM_SCHEMA |
|
---|---|---|
Description |
Persisted form of |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
primitive_types: |
Primitive type definitions. Persisted attribute. |
0..1 |
class_definitions: |
Class definitions. Persisted attribute. |
0..1 |
includes: |
Inclusion list, in the form of a hash of individual include specifications, each of which at least specifies the id of another schema, and may specify a namespace via which types from the included schemas are known in this schema. Persisted attribute. |
Functions |
Signature |
Meaning |
0..1 |
validate_created |
Implementation of |
0..1 |
load_finalise |
Implementation of |
0..1 |
merge ( |
Implementation of |
0..1 |
validate |
Implementation of |
0..1 |
create_bmm_model |
Implementation of |
1..1 |
canonical_packages (): |
Package structure in which all top-level qualified package names like |
4. BMM Structure
4.1. Overview
The core
package defines the main BMM model. The following figure shows it in overview.
A BMM model is structured in the same basic way as a UML model, i.e. with a hierarchical package containment structure and a set of class definitions. Class definitions consist of property definitions, each of which refers to a type, which in turn refers to a 'base class'.
4.2. Naming Convention
In a BMM model, names typically appear in the common case-sensitive form used by the model users, and may therefore follow one of a number of common conventions, including 'camel case', 'snake-case' and so on. When used computationally within an instantiated BMM model, it is assumed that case-insensitive matching is used. This means that the class name "Hashable"
refers to the same class as "HASHABLE"
. Note however that underscores are not removed during matching, so that the classes "HashMap"
and "HASH_MAP"
are understood as different classes.
Note
|
a future version of BMM may provide an option to import schemas using differing naming styles, with transformation into a single style for the target model. |
4.3. Packages
In BMM, packages have the same role as in UML - as non-semantic organisational logical containers of classes, usually corresponding to file system folders in software implementations. They provide an organisational convenience, and in an instantiated BMM model, contain references to class definitions. A model validity checker ensures that every class is contained within exactly one package.
Package paths are only used in BMM to specify package structures in the serialsed form in an efficient way, i.e. by using paths to avoid defining a hierarchy in which only lower packages contain classes. They are not used as namespaces as in UML. Consequently, all classes in a BMM model should be uniquely named.
4.4. Documentation
A documentation
attribute is inherited from BMM_MODEL_ELEMENT
into BMM_CLASS
, BMM_PROPERTY
, BMM_MODEL
and BMM_PACKAGE
(the latter two via BMM_PACKAGE_CONTAINER
), enabling packages, classes and properties to be individually documented.
TBD: expand to be of type Hash<String,Any>
or similar?
4.5. Model
The BMM_MODEL
class defines the single instance of each distinct BMM model that may exist within a collection of models, such as shown in the model_access
package above. It provides an interface that enables any class definition to be retrieved, as well as various accessor functions to interrogate the model. A BMM Model has a name (model_name
attribute) that is used to identify the model as a whole within a system using multiple models. It contains a number of other meta-data attributes describing authorship etc, and otherwise contains a list of package and class definitions.
4.6. Class Definitions
4.6.1. BMM_DEFINITIONS Class
Class |
BMM_DEFINITIONS |
|
---|---|---|
Description |
Definitions used by all BMM packages. |
|
Constants |
Signature |
Meaning |
1..1 |
Bmm_internal_version: |
Current internal version of BMM meta-model, used to determine if a given schema can be processed by a given implementation of the model. |
1..1 |
Schema_name_delimiter: |
Delimiter used to separate schema id from package path in a fully qualified path. |
1..1 |
Package_name_delimiter: |
Delimiter used to separate package names in a package path. |
1..1 |
Bmm_schema_file_extension: |
Extension used for BMM files. |
4.6.2. BMM_MODEL_ELEMENT Class
Class |
BMM_MODEL_ELEMENT (abstract) |
|
---|---|---|
Description |
Ancestor class of most BMM model elements. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
documentation: |
Optional documentation of this element. |
4.6.3. BMM_PACKAGE_CONTAINER Class
Class |
BMM_PACKAGE_CONTAINER |
|
---|---|---|
Description |
A BMM model component that contains packages and classes. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
packages: |
Child packages; keys all in upper case for guaranteed matching. |
Functions |
Signature |
Meaning |
0..1 |
package_at_path ( |
Package at the path |
0..1 |
do_recursive_packages ( |
Recursively execute |
1..1 |
True if there is a package at the path |
4.6.4. BMM_PACKAGE Class
Class |
BMM_PACKAGE |
|
---|---|---|
Description |
Abstraction of a package as a tree structure whose nodes can contain other packages and classes. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
name: |
Name of this package. This name may be qualified if it is a top-level package. |
0..1 |
Classes listed as being in this package. |
|
Functions |
Signature |
Meaning |
0..1 |
Obtain the set of top-level classes in this package, either from this package itself or by recursing into the structure until classes are obtained from child packages. Recurse into each child only far enough to find the first level of classes. |
|
1..1 |
path (): |
Full path of this package back to root package. |
4.6.5. BMM_MODEL Class
Class |
BMM_MODEL |
|
---|---|---|
Description |
Definition of the root of a BMM model (along with what is inherited from |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
All classes in this schema, keyed by type name. |
|
1..1 |
model_name: |
Name of this model. |
Functions |
Signature |
Meaning |
1..1 |
model_id (): |
Identifier of this model, lower-case, formed from:
E.g. |
1..1 |
Retrieve the class definition corresponding to |
|
1..1 |
type_definition (): |
Retrieve the class definition corresponding to |
1..1 |
True if |
|
1..1 |
True if |
|
1..1 |
enumeration_definition ( |
Retrieve the enumeration definition corresponding to |
0..1 |
List of keys in |
|
0..1 |
List of keys in |
|
1..1 |
property_definition (): |
Retrieve the property definition for |
1..1 |
ms_conformant_property_type ( |
True if |
1..1 |
property_definition_at_path (): |
Retrieve the property definition for |
1..1 |
class_definition_at_path ( |
Retrieve the class definition for the class that owns the terminal attribute in |
0..1 |
Return all ancestor types of |
|
1..1 |
is_descendant_of ( |
True if |
1..1 |
type_conforms_to ( |
Check conformance of Conformance is found if:
|
1..1 |
any_class_definition (): |
|
1..1 |
any_type_definition (): |
5. BMM Entities
5.1. Overview
The following UML diagram shows the semantically important part of the BMM, defining classes and types, known collectively as entities.
The general structure of a BMM consists of a set of classes, whose properties are each typed by an instance of BMM_TYPE
, as shown below. Structures specific to generic and container types are shown in relevant sections below.
5.2. The Class / Type Division
One of the foundational distinctions in the BMM is between class and type, in common with the type systems of the modern forms of most object-oriented languages, but in contrast to the UML meta-model. Classes are definitional entities, while 'type' has two meanings:
-
as the static (design time) type of a class feature (property or function result), and
-
as the dynamic (run-time) type of the object referred to by or computed by that feature.
In a static model, types are references. For simple types, they refer to the corresponding simple class definition, but for generic types, they refer to a particular usage of a generic class definition. A generic class may generate numerous types.
This central division is reflected in the two classes BMM_CLASS
and BMM_TYPE
. The common parent class BMM_ENTITY
defines a small number of properties that classify both classes and types in a model: entity_metatype
, is_abstract
and is_primitive
. These are combined to produce a String classifier entity_category
, which can be used to help visualise elements of a BMM model.
The Boolean attribute is_abstract
on an entity indicates an abstract class in a BMM model, or a type based on an abstract class. The attribute is_primitive
indicates that a class in a BMM model is considered to be part of a primitive type set (typically corresponding to primitive types in another type system); for types, it is derived from the setting of the base_class
. Primitive status has no effect on BMM model semantics, and is provided as a convenience for visualisation and type-system mapping.
The taxonomy represented by BMM_ENTITY.entity_category
is illustrated below.
5.3. Class Definitions
5.3.1. BMM_ENTITY Class
Class |
BMM_ENTITY (abstract) |
|
---|---|---|
Description |
Abstract parent of type and class meta-types. |
|
Inherit |
||
Constants |
Signature |
Meaning |
1..1 |
Entity_metatype_simple: |
Category of a simple entity, other than enumerated types. |
1..1 |
Entity_metatype_enumeration: |
Category of any enumeration entity. |
1..1 |
Entity_metatype_generic: |
Category of any generic entity that is not a container entity. |
1..1 |
Entity_metatype_parameter: |
Category of a formal generic parameter entity. |
1..1 |
Entity_metatype_container: |
Category of any container entity. |
1..1 |
Entity_category_modifier_abstract: |
Category modifier indicating an entity is formally defined as abstract, i.e. not-directly instantiable within a BMM model. |
1..1 |
Entity_category_modifier_primitive: |
Category modifier indicating that an entity is considered to be primitive within the type system of a given BMM model. Has no semantic consequences within the BMM. |
Functions |
Signature |
Meaning |
1..1 |
entity_category (): |
Generate a category code-string to use in visualisation, that indicates:
The code is structured as: entity_metatype [ '-' abstract_modifier ] [ '-' primitive_modifier ] |
1..1 |
entity_metatype (): |
Meta-type of entity, which classifies it according to the kind of formal entity it represents from the following:
These meta-types don’t exactly match the |
1..1 |
is_abstract (): |
If true, indicates an abstract class in a BMM model, or a type based on an abstract class, i.e. a type that cannot be directly instantiated. |
1..1 |
is_primitive (): |
If True, indicates that the entity in a BMM model is considered to relate to a primitive type set, i.e. be a primitive type, or be a definer of one. |
6. Types
6.1. Overview
Types are used for three purposes in a BMM model:
-
to define the type of a property;
-
to define formal type parameters in a generic class;
-
to define type(s) of inheritance ancestors of class definitions.
Every type entity can be mapped back to its generating class(es), which provide the definitional basis for the type. The BMM class BMM_TYPE
and its descendants define the kinds of types available in a BMM model. The BMM_TYPE
class includes features common to all meta-types:
-
effective_base_class: a reference to the effective generating class;
-
type_name: the effective type name of an entity; for simple classes, this will just be the class name (
BMM_CLASS.name
); for generic and container classes it will be generic name such asList<T>
,Interval<T>
etc; for feature types it will be the declared type, i.e. a simple name, an open type name (e.g.T
) or a generic type name (e.g.Interval<Time>
); -
type_signature: a form of the type name that can be used as a fully-defined type signature, which for generic classes includes generic constrainer types, giving a signature such as
Interval<T:Ordered>
.
Below BMM_TYPE
are the abstract meta-type BMM_UNITARY_TYPE
and the concrete meta-type BMM_CONTAINER_TYPE
and its specialisation BMM_INDEXED_CONTAINER_TYPE
. BMM_UNITARY_TYPE
corresponds to meta-types whose instances are unitary i.e. singular, while the container meta-types correspond to collections of instances. The latter are further described below. This division is made to enable BMM to directly support collections in the type system.
Unitary meta-types are further distinguished as either formal generic parameters (BMM_PARAMETER TYPE
) and defined types, i.e. types with class definitions, via the abstract meta-type BMM_DEFINED_TYPE
. The subtypes of the BMM defined meta-type are BMM_SIMPLE_TYPE
and BMM_GENERIC TYPE
, corresponding to the standard notions of type familiar in modern programming languages. The class definitions of instances (i.e. BMM model class deifintions) of these meta-types are available via the property _base_class
, of meta-type BMM_CLASS
for a BMM simple type, and BMM_GENERIC_CLASS
for BMM generic type.
6.2. Simple Type
A simple type is a type based only on a simple class, which is a class with no formal generic parameters. An instance of a simple type is fully described by the class on which it is based, with the ony difference being the usual object-oriented possibility of polymorphic attachments of sub-objects whose dynamic types conform to their static type counterparts in the original simle type. Thus, for example, a class Organisation
may have a property managers
of static type List<Person>
. An instance of the simple type Organisation
might have its managers
property attached to an instance of List<Manager>
, which is legal as long as Manager
conforms to Person
, which it will do it the same-named classes inherit in the usual sense.
6.3. Generic Type
A generic type is any type based on a generic class, which has one or more open type parameters that are substituted for actual types in its declaration. For example, the generic type Interval<Quantity>
can be used in a model that contains the generic class Interval<T:Ordered>
and Quantity
. A typical programmatic usage of such a type, and its instantiated BMM model structure are shown below.
The parameters of a generic type may be:
-
a substitution of a formal parameter from the generic class with a concrete type, including other generic types and container types;
-
an unsubstituted formal parameter.
Consequently, a generic type may be:
-
fully closed: all formal parameters substituted e.g.
Interval<Quantity>
; -
partially closed: at least one formal parameter is substituted e.g.
Document<ClinicalContent, U>
; -
fully open: no formal parameters substituted, e.g.
Document<T, U>
.
The feature is_partially_closed ()
defined on BMM_GENERIC_TYPE
can be used to distinguish the latter two cases.
The following diagram shows the BMM instance structure created for a generic type based on a generic class and another generic type.
The following shows the BMM instance structure of a generic type that is fully open.
6.4. Container Types
In object-oriented type theory, 'container' types are generic types whose outer class happens to have the semantics of a container object, such as a list, set etc. Container types such as List<T>
and Set<T>
are used ubiquitously in object models. In the BMM, containers and non-container generic types are distinguished via the meta-classes BMM_GENERIC_TYPE
and BMM_CONTAINER_TYPE
. This allows the BMM to treat container types in a special way. A BMM_CONTAINER_TYPE
can be thought of as a 1:N counterpart to a BMM_UNITARY_TYPE
, such as the type List<Paragraph>
with respect to Paragraph
. BMM_GENERIC_TYPE
is typically used for objects considered to be singular, but whose types are a product of the base class and one or more parameter types, e.g. Interval<Quantity>
.
The explicit provision of BMM_CONTAINER_TYPE
enables BMM models to mention logical linear container types such as Array<T>
, List<T>
and Set<T>
, on the assumption of their standard semantics in computer science , without worrying about providing concrete types which may be numerous and also variable across programming languages, e.g. ArrayedList<T>
, LinkedSet<T>
, ArrayedStack<T>
and so on. (This corrects one of the errors in UML, which does not represent containment via typing, but via cardinality, and uniqueness constraints.)
The following diagram shows how the container type List<Paragraph>
is represented in a BMM model.
One other container type is also ubiquitous in object models and object-oriented programming: indexed containers, commonly known under the type name Hash<K,V>
, HashMap<K,V>
, HashTable<K,V>
, Dictionary<K,V>
and so on. This type always takes two parameters, a key type and a value type. The key type must be such that hash values can be generated, and may be any type, but practically speaking, is almost always a String
or Integer
, or a Date/Time type if such exists.
The indexed container is represented by the meta-type BMM_INDEXED_CONTAINER_TYPE
, which inherits from BMM_CONTAINER_TYPE
, and adds the property index_type
. The following diagram shows how the container type Hash<String, Person>
is represented in a BMM model.
6.5. Type Conformance
In object-oriented theory, the important relationship between types is substitutability, which governs which instances may be dynamically attached to property references of particular declared static types. In the BMM, a type is conformant to another type if the base classes of its constituent elements are inheritance descendants of the corresponding elements of the other type. This is known in object-oriented type theory as covariant conformance.
An algorithm to determine conformance of two type-names (e.g. to implement BMM_MODEL.type_conforms_to()
) is as follows:
Boolean type_conforms_to (String this_type, other_type) {
BMM_TYPE_NAME this_type_name, other_type_name;
if attached create_type_name_from_string (a_this_type) as this_type_name and
attached create_type_name_from_string (other_type) as other_type_name
{
this_base_class = this_type_name.name;
other_base_class = other_type_name.name;
if (this_base_class.is_case_insensitive_equal (other_base_class) or else
class_definition (this_base_class).has_ancestor_class (other_base_class))
{
// handle case where formal generic names appear in type name
BMM_DEFINED_CLASS this_bmm_def_class = class_definition (this_base_class);
if (valid_generic_type_name (this_type) and this_bmm_def_class instanceOf BMM_GENERIC_CLASS) {
// in the case of both being generic, we need to compare generics
// to start with, the number of generics must match
BMM_DEFINED_CLASS other_bmm_def_class = class_definition (other_base_class);
if (valid_generic_type_name (other_type) and other_bmm_def_class instanceOf BMM_GENERIC_CLASS) {
this_type_gen_params = this_type_name.generic_parameters_type_list;
other_type_gen_params = other_type_name.generic_parameters_type_list;
if (this_type_gen_params.count = other_type_gen_params.count) {
Iterator<String> this_gen_parms_it = this_type_gen_params.iterator();
Iterator<String> other_gen_parms_it = other_type_gen_params.iterator();
Boolean result = True;
String this_type_gen_type, other_type_gen_type;
while (this_gen_parms_it.hasNext() && other_gen_parms_it.hasNext() || !result) {
// first we convert any open generic parameters to their conformance types
// We assume type names of 1 letter are open parameters
String this_gen_parm = this_gen_parms_it.next();
String other_gen_parm = other_gen_parms_it.next();
if (formal_generic_parameter_name (this_gen_parm))
this_type_gen_type = this_bmm_gen_class.generic_parameter_conformance_type (this_gen_parm);
else
this_type_gen_type = this_gen_parm;
if (formal_generic_parameter_name (other_gen_parm))
other_type_gen_type = other_bmm_gen_class.generic_parameter_conformance_type (other_gen_parm);
else
other_type_gen_type = other_gen_parm;
-- now do the test
result = type_conforms_to (this_type_gen_type, other_type_gen_type);
}
return result;
}
// Conforms - case where anc type is not provided in generic form, but desc is
// e.g. Interval<Integer> conforms to Interval
else
return True;
// in the following case, the descendant type is not generic,
// so the ancestor type cannot be either, for conformance
else
return not valid_generic_type_name (other_type);
}
}
}
6.6. Class Definitions
6.6.1. BMM_TYPE Class
Class |
BMM_TYPE (abstract) |
|
---|---|---|
Description |
Abstract idea of specifying a type in some context. This is not the same as 'defining' a class. A type specification is essentially a reference of some kind, that defines the type of an attribute, or function result or argument. It may include generic parameters that might or might not be bound. See subtypes. |
|
Inherit |
||
Functions |
Signature |
Meaning |
1..1 |
effective_base_class (): |
Effective underlying class for this type, abstracting away any container type. |
1..1 |
type_name (): |
Formal string form of the type as per UML. |
1..1 |
has_subtypes (): |
Determine if there are any type substitutions. |
1..1 |
List of type substitutions if any available for this type within the current BMM model. |
|
1..1 |
Completely flattened list of type names, flattening out all generic parameters. |
|
1..1 |
type_signature (): |
Signature form of the type, which for generics includes generic parameter constrainer types E.g. Generally useful for display purposes. |
1..1 |
is_primitive (): |
True if |
1..1 |
entity_metatype (): |
Meta-type of type is by default assumed to be the meta-type of its |
6.6.2. BMM_UNITARY_TYPE Class
Class |
BMM_UNITARY_TYPE (abstract) |
|
---|---|---|
Description |
Parent of meta-types that may be used as the type of any instantiated object that is not a container object. |
|
Inherit |
6.6.3. BMM_SIMPLE_TYPE Class
Class |
BMM_SIMPLE_TYPE |
|
---|---|---|
Description |
Type reference to a single type i.e. not generic or container type. |
|
Inherit |
||
Functions |
Signature |
Meaning |
1..1 |
type_name (): |
Result is |
1..1 |
is_abstract (): |
Result is |
1..1 |
Result is |
|
1..1 |
Result is |
|
1..1 |
has_subtypes (): |
True if |
1..1 |
effective_base_class (): |
Main design class for this type, from which properties etc can be extracted. |
6.6.4. BMM_CONTAINER_TYPE Class
Class |
BMM_CONTAINER_TYPE |
|
---|---|---|
Description |
Type that specifies linear containers with a generic parameter corresponding to the type of contained item, and whose container type is a generic type such as |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
container_class: |
The type of the container. This converts to the |
1..1 |
base_type: |
The target type; this converts to the first parameter in |
Functions |
Signature |
Meaning |
1..1 |
type_name (): |
Return full type name, e.g. |
1..1 |
effective_base_class (): |
Result is |
1..1 |
is_abstract (): |
True if |
1..1 |
entity_metatype (): |
Meta-type of container type is |
1..1 |
Completely flattened list of type names, flattening out all generic parameters. |
|
1..1 |
Result is all permutations of current container type and its descendants with the current |
|
1..1 |
has_subtypes (): |
Determine if there are any type substitutions. |
6.6.5. BMM_INDEXED_CONTAINER_TYPE Class
Class |
BMM_INDEXED_CONTAINER_TYPE |
|
---|---|---|
Description |
Type of linear container that indexes the contained items in the manner of a standard Hash table, map or dictionary. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
index_type: |
Type of the element index, typically |
6.6.6. BMM_GENERIC_TYPE Class
Class |
BMM_GENERIC_TYPE |
|
---|---|---|
Description |
Type reference based on a generic class, e.g. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
generic_parameters: |
Generic parameters of the |
1..1 |
base_class: |
The target type; this converts to the first parameter in |
Functions |
Signature |
Meaning |
1..1 |
type_name (): |
Return the full name of the type including generic parameters, e.g. |
1..1 |
type_signature (): |
Signature form of the type, which for generics includes generic parameter constrainer types E.g. |
1..1 |
is_abstract (): |
True if |
1..1 |
Result is |
|
1..1 |
Result is the permutation of the base class type and type substitutions of all generic parameters. |
|
1..1 |
has_subtypes (): |
True if |
1..1 |
is_partially_closed (): |
Returns True if there is any substituted generic parameter. |
1..1 |
effective_base_class (): |
Effective underlying class for this type, abstracting away any container type. |
6.6.7. BMM_PARAMETER_TYPE Class
Class |
BMM_PARAMETER_TYPE |
|
---|---|---|
Description |
Definition of a generic parameter in a class definition of a generic type. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
name: |
Name of the parameter, e.g. 'T' etc. The name is limited to 1 character and upper-case. |
0..1 |
type_constraint: |
Optional conformance constraint that must be another valid class name. |
0..1 |
inheritance_precursor: |
If set, is the corresponding generic parameter definition in an ancestor class. |
Functions |
Signature |
Meaning |
1..1 |
flattened_conforms_to_type (): |
Result is either |
1..1 |
effective_conforms_to_type (): |
Generate ultimate conformance type, which is either |
1..1 |
type_signature (): |
Signature form of the open type, including constrainer type if there is one, e.g. |
1..1 |
is_primitive (): |
Result = |
1..1 |
is_abstract (): |
Result = |
1..1 |
entity_metatype (): |
Meta-type of a container type is |
1..1 |
effective_base_class (): |
The effective conformance type of this parameter, or the 'Any' class if none. |
1..1 |
has_subtypes (): |
True if |
1..1 |
Result is |
|
1..1 |
type_name (): |
Result is |
1..1 |
Result is either |
|
Invariants |
Inv_generic_name: |
7. Classes
7.1. Overview
Class definitions are the core of any BMM model. BMM distinguishes between simple and generic class definitions via two descendants of BMM_CLASS
, i.e. BMM_SIMPLE_CLASS
and BMM_GENERIC_CLASS
, with the first providing a concrete form of BMM_CLASS
that applies to non-generic classes, and the latter defining the additional semantics of generic classes. The meta-type BMM_ENUMERATION
is a specialisation of BMM_SIMPLE_CLASS
used to represent enumeration classes in BMM models.
Class properties are defined using the generic class BMM_PROPERTY <T: BMM_TYPE>
. The use of a generic meta-type provides a formal way of expressing the semantics of meta-types described in the section on types. The generic parameter is one of the following BMM_TYPE
descendants:
-
a
BMM_SIMPLE_TYPE
- corresponds to a simple type such asDocument
; -
a
BMM_GENERIC_TYPE
- a type generated by the use of a generic class with one or more filled type parameters, e.g.Interval<Time>
,Packet<T,Payload>
; -
a
BMM_CONTAINER_TYPE
- a type generated by the use of a linear container type such asList<T>
,Hash<T,U>
with actual generic parameters; -
a
BMM_PARAMETER_TYPE
- corresponds to a generic parameter type from the class type definition, e.g.T
,U
etc.
In modelling or programming terms, the properties of a class constitute the features it introduces with respect to its inheritance parent(s). We can think of this list of properties as the differential set. A 'top-level' class with no declared inheritance ancestor is considered to inherit by default from the Any
class, and its property set is relationally differential to the top class.
In contrast, the effective set of properties for an instance at runtime is the result of evaluating these lists of properties down the inheritance hierarchy to obtain the flat set of properties. The features properties and flat_properties defined on BMM_CLASS
provide access to these two lists for any class.
7.2. Primitive Classes
As noted above, class definitions can be marked as being 'primitive' within a BMM model, enabling them to be visualised and queried as a separate group without otherwise impacting on the semantics of the entity in BMM meta-type system. The following shows part of a BMM model in which a number of classes are classified as primitive (shown in light and dark grey).
Primitive classes are normal BMM classes, other than being marked primitive for convenience, and do not have different semantics.
7.3. Enumeration Classes
The enumeration meta-type adds a set of enumeration labels and optional String
or Integer
values, in the manner of contemporary languages such as Java and C#. This meta-type allows classes to be declared in a BMM to be enumerations without either having to manufacture a representation from simple class definitions, or having to replicate the representation of enumerations in some target language. The following screenshot shows how a BMM integer enumeration class appears within a BMM model.
The types String
and Integer
are assumed to be defined via primitive classes of the same names.
7.4. Generic Classes
The generic class meta-type BMM_GENERIC_CLASS
adds generic parameters to BMM_CLASS
, enabling formal generic parameters to be represented. Each such parameter is expressed using an instance of BMM_PARAMETER_TYPE
which names the parameter and optionally allows a type constraint to be associated with it, in the usual object-oriented fashion. In BMM, formal parameters have single-letter names, such as 'T', 'U' etc, following typical usage in programming languages. The following example shows a generic class Interval<T:Ordered>
, which is a class Interval
with one formal parameter T
constrained to be of type Ordered
or any descendant.
7.5. Properties
Properties in BMM class definitions occur in two flavours, corresponding to the unitary and container type meta-types. The BMM_PROPERTY<T:BMM_TYPE>
meta-type defines semantics common all properties, including name
and is_mandatory
, and type
, a generically typed reference to the property type in a BMM model. Properties also include two other Boolean meta-data items, is_im_runtime
and is_im_infrastructure
, which can be used to classify property values in a model according to use in runtime systems. These may be individually set, or both may be False. The three meaningful value settings are as follows:
-
both False: the value of the property is considered to be design-time constrainable;
-
is IM runtime: True if the property value is only knowable at runtime, as is typically the case for identifiers, dates etc;
-
is infrastructure: True if the property is not a user- or business-oriented property, but something required by software design, e.g instance identifier, meta-data etc.
Unitary properties in a BMM model are instances of the types BMM_PROPERTY<BMM_SIMPLE_TYPE>
and so on. Container properties are instances of the type BMM_CONTAINER_PROPERTY
, which inherits from BMM_PROPERTY<BMM_CONTAINER_TYPE>
, in order to add the meta-data item cardinality
, which enables the possible number of container elements to be constrained, corresponding to the multiplicities used at the end of UML associations.
The following example shows a BMM class in a model whose flat properties have different settings of the is_im_runtime
and is_im_infrastructure
meta-data flags: property names in black are neither; those in grey are IM runtime, and those in light grey are infrastructure properties.
7.6. Class Definitions
7.6.1. BMM_CLASS Class
Class |
BMM_CLASS (abstract) |
|
---|---|---|
Description |
Meta-type defining a class definition in an object model. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
name: |
Name of this class. Note that unlike UML, names of classes are just the root name, even if the class is generic. Use |
0..1 |
ancestors: |
List of immediate inheritance parents. |
1..1 |
package: |
Package this class belongs to. |
0..1 |
properties: |
List of attributes defined in this class. |
1..1 |
source_schema_id: |
Reference to original source schema defining this class. Useful for UI tools to determine which original schema file to open for a given class for manual editing. |
0..1 |
List of references to base classes of immediate inheritance descendants. |
|
1..1 |
is_override: |
True if this definition overrides a class of the same name in an included schema. |
Functions |
Signature |
Meaning |
0..1 |
List of all inheritance parent class names, recursively. |
|
0..1 |
Compute all descendants by following |
|
0..1 |
List of names of immediate supplier classes, including concrete generic parameters, concrete descendants of abstract statically defined types, and inherited suppliers. (Where generics are unconstrained, no class name is added, since logically it would be |
|
0..1 |
Same as |
|
0..1 |
List of names of all classes in full supplier closure, including concrete generic parameters; (where generics are unconstrained, no class name is added, since logically it would be |
|
1..1 |
package_path (): |
Fully qualified package name, of form: |
1..1 |
class_path (): |
Fully qualified class name, of form: |
0..1 |
flat_properties (): |
List of all properties due to current and ancestor classes, keyed by property name. |
1..1 |
is_primitive (): |
True if this class is designated a primitive type within the overall type system of the schema. Set from schema. |
1..1 |
is_abstract (): |
True if this class is abstract in its model. Value provided from an underlying data property set at creation or construction time. |
1..1 |
type (): |
Generate a type object that represents the type of this class. |
7.6.2. BMM_SIMPLE_CLASS Class
Class |
BMM_SIMPLE_CLASS |
|
---|---|---|
Description |
Definition of a simple class, i.e. a class that has no generic parameters and is 1:1 with the type it generates. |
|
Inherit |
||
Functions |
Signature |
Meaning |
1..1 |
type (): |
Generate a type object that represents the type of this class. Can only be an instance of |
1..1 |
entity_metatype (): |
Meta-type of |
7.6.3. BMM_ENUMERATION Class
Class |
BMM_ENUMERATION<T> |
|
---|---|---|
Description |
Definition of an enumeration type. In the BMM system, an 'enumeration' type is understood as an underlying basic type and a set of named constants of that type. It is designed so that the default type is Integer, and the default constants are numbered 0, 1, … Optional model elements can be specified to override the values and / or the type. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
The list of names of the enumeration. If no values are supplied, the integer values 0, 1, 2, … are assumed. |
|
0..1 |
item_values: |
Optional list of specific values. Must be 1:1 with |
1..1 |
underlying_type_name: |
Name of type any concrete |
Functions |
Signature |
Meaning |
1..1 |
entity_metatype (): |
Meta-type of |
1..1 |
Map of |
7.6.4. BMM_ENUMERATION_STRING Class
Class |
BMM_ENUMERATION_STRING |
|
---|---|---|
Description |
String-based enumeration type. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
underlying_type_name: |
Name of type any concrete |
7.6.5. BMM_ENUMERATION_INTEGER Class
Class |
BMM_ENUMERATION_INTEGER |
|
---|---|---|
Description |
Integer-based enumeration type. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
underlying_type_name: |
Name of type any concrete |
7.6.6. BMM_GENERIC_CLASS Class
Class |
BMM_GENERIC_CLASS |
|
---|---|---|
Description |
Definition of a generic class in an object model. |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
generic_parameters: |
List of generic parameter definitions, keyed by name of generic parameter; these are defined either directly on this class or by the addition of an ancestor class which is generic. |
Functions |
Signature |
Meaning |
0..1 |
Add suppliers from generic parameters. |
|
1..1 |
entity_metatype (): |
Meta-type of |
1..1 |
type (): |
Generate a fully open |
1..1 |
generic_parameter_conformance_type ( |
For a generic class, type to which generic parameter |
7.6.7. BMM_PROPERTY Class
Class |
BMM_PROPERTY<T> |
|
---|---|---|
Description |
Model of a property definition within a class definition of an object model. The generic parameter accommodates the possible meta-type variant descendants of |
|
Inherit |
||
Attributes |
Signature |
Meaning |
1..1 |
name: |
Name of this property in the model. |
0..1 |
is_mandatory: |
True if this property is mandatory in its class. |
0..1 |
is_computed: |
True if this property is computed rather than stored in objects of this class. |
1..1 |
type: |
Formal type of this property. |
0..1 |
is_im_runtime: |
True if this property is marked with info model |
0..1 |
is_im_infrastructure: |
True if this property was marked with info model |
0..1 |
is_synthesised_generic: |
True if this property was synthesised due to generic substitution in an inherited type, or further constraining of a formal generic parameter. |
Functions |
Signature |
Meaning |
1..1 |
existence (): |
Interval form of |
1..1 |
display_name (): |
Name of this property to display in UI. |
7.6.8. BMM_CONTAINER_PROPERTY Class
Class |
BMM_CONTAINER_PROPERTY |
|
---|---|---|
Description |
Subtype of |
|
Inherit |
||
Attributes |
Signature |
Meaning |
0..1 |
cardinality: |
Cardinality of this container. |
1..1 |
type: |
|
Functions |
Signature |
Meaning |
1..1 |
display_name (): |
Name of this property in form |
8. Model Semantics
8.1. Simple Inheritance
The BMM supports single and multiple inheritance, although it does not distinguish between different types of inheritance relation as some programming languages do. Inheritance is formally defined to be between a class definition (an instance of BMM_CLASS
) and a defined type, i.e. a BMM_SIMPLE_TYPE
or BMM_GENERIC_TYPE
. This is because the inheritance parents of a class may be any of:
-
a simple class;
-
a generic class;
-
a class type, i.e. the effective class definition corresponding to an effective generic type, which has one or more formal parameters substituted.
The general case for all three is represented by the corresponding type, i.e., a simple type or generic type.
The evaluation of inheritance relations defined in a BMM model results in an acyclic graph such that ancestors and descendants can be visualised for any class. The following screen shot shows the ancestors view of a class OBSERVATION
.
The next screenshot shows the descendants view of one of the ancestor classes of the same class.
8.2. Generic Inheritance
Inheritance between generic classes works in the same way as for simple classes, with the additional semantics of formal parameter inheritance, which are as follows:
-
each unsubstituted formal parameter of the parent type must have a same-named counterpart in the formal parameters of the inheriting class;
-
the formal parameters of the inheriting class may further constrain any of the ancestor type’s formal parameters.
The following example shows the class DV_INTERVAL<T:DV_ORDERED>
inheriting from Interval<T:Ordered>
. Here the number of open generic parameters remains unchanged, while the type constraint Ordered
is being covariantly narrowed to DV_ORDERED
, which inherits from the Ordered
type.
A simple class may also inherit from a closed generic type, with the parameters of the latter fixed to specific type(s), as shown in the following example.
The general case is that any number of formal generic parameters may be substituted or left open down the inheritance lineage, as shown by the variants in the following example.
8.3. Multiple Inheritance
Multiple inheritance is typically used in the definition of classes that have a Liskov substitution inheritance relation as well as a re-use inheritance relation. The following shows a class DV_INTERVAL<T>
multiply inheriting from Interval<T>
and DATA_VALUE
, where the latter is considered the substitutable type, and the former an interface re-use.