MN 113-2: MMEL Data Modelling

1. Data modelling overview

1.1. General

This document specifies the data modelling facilities of the Multi-Modal Modelling Language (MMEL), as defined in MN113 . MMEL data modelling provides UML-style data structure definitions integrated with process flows, compliance tracking, and quantitative monitoring.

The data modelling subsystem of MMEL encompasses:

  • data classes -- structured type definitions identified by the #data suffix, linked to persistent data stores
  • helper classes -- reusable complex types without the #data suffix, embedded as fields within other classes
  • enumerations -- named sets of values used as field types
  • data registers -- named, persistent data stores backed by data classes

1.2. Relationship to UML class diagrams

MMEL data modelling is a superset of UML class diagram concepts. The following table maps UML class diagram concepts to their MMEL equivalents:

UML Concept MMEL Equivalent Notes
Class class Name#data { ... } Fields, types, references, cardinality
Enumeration enum Name { ... } Named enumeration with definitions
Association/Aggregation reference(Target#data) With cardinality [0..*] , [1..*]
Multiplicity [0..*] , [1..*] , [1..1] On references and nested types
Composition Nested type fields e.g. meta: DocMeta
Attribute Class field Typed or untyped (implicitly string)
Data Store (UML object) data_registry Persistent store backed by a data class
Constraint satisfy { } block Validation constraint categories on fields
Stereotype #data suffix Distinguishes data classes from helper classes

1.3. Architecture

MMEL data modelling connects data structures to process flows and compliance requirements through data registers.

class#data ──data_class──> data_registry <──output── process
                                        <──reference_data── process
                                               │
                                               v
                                        Stored documents (.sws)

A data class defines the schema of records. A data register is the persistent store for those records. Processes write to registers via output { } and read from them via reference_data_registry { } .

The full data flow from class definition to runtime storage is:

class definition (schema)
  │
  └── data_registry declaration (named store)
       │
       ├── process.output { RegistryID }  (writes records)
       │
       ├── process.reference_data_registry { RegistryID }  (reads records)
       │
       └── .sws file  (runtime data state)

2. Classes

2.1. General

Classes define data structures in MMEL. There are two kinds of classes:

  • data classes -- identified by the #data suffix, linked to data registers, representing persistent records
  • helper classes -- without the #data suffix, used as reusable complex types embedded as fields within other classes

2.2. Syntax

2.2.1. Data class syntax

class <ClassName>#data {
  <fieldName>: <type> {
    definition "Field description"
    modality SHALL
    reference {
      <ReferenceID>
    }
    satisfy {
      <constraint-category>
    }
  }
  <fieldName> {
    definition "Field description"
    modality SHOULD
  }
}
  1. Explicitly typed field with colon notation.
  2. Human-readable field definition.
  3. Optional modality keyword indicating obligation for this field.
  4. Optional normative references.
  5. Optional satisfy block specifying a validation constraint category.
  6. Untyped field (implicitly string).

2.2.2. Helper class syntax

class <ClassName> {
  <fieldName> {
    definition "Field description"
    modality SHALL
  }
  <fieldName>: <type> {
    definition "Field description"
  }
}

Helper classes follow the same syntax as data classes but without the #data suffix. They cannot be linked directly to data registers.

2.3. Explicit type vs implicit type

Fields may be declared with or without an explicit type:

  • Explicit type -- fieldName: type { ... } uses a colon followed by the type name
  • Implicit type -- fieldName { ... } omits the type, defaulting to string
class Scope#data {
  name: string {
    definition "Name/Title"
  }
  scope {
    definition "Scope"
  }
  review: datetime {
    definition "Last Reviewed"
  }
}
  1. Explicit string type.
  2. Implicit string type (no colon or type name).
  3. Explicit datetime type.

2.4. Field properties

Each class field may contain the following properties:

Property Required Description
definition no Human-readable description of the field's purpose
modality no RFC 2119 keyword indicating obligation level for this field
reference no List of reference IDs linking this field to normative sources
satisfy no Validation constraint category for tooling

2.4.1. Modality on fields

The modality property on a class field indicates the obligation level for that field within the data structure:

class RiskPlan#data {
  scope {
    definition "Scope"
    modality SHALL
    reference {
      ISO14971-doc-ref3-4
    }
  }
  Criteria {
    definition "Criteria for risk acceptability"
    modality SHALL
  }
}
  1. This field is mandatory (SHALL).
  2. This field is also mandatory (SHALL).

2.4.2. Normative references on fields

Fields can link to normative references, providing traceability from data structure elements to their source standards:

class RiskManagementFile#data {
  plan: reference(RiskPlan) {
    definition "Risk Management Plan"
    modality SHALL
    reference {
      ISO14971-doc-ref3-4
    }
  }
  hazards: reference(Hazards) {
    definition "Known and foreseeable hazards"
    modality SHALL
  }
}
  1. This field is traceable to clause 3.4 of ISO 14971.
  2. This field has no normative reference.

2.5. Data classes

Data classes are the primary data structure definitions in MMEL. The #data suffix marks a class as a data class, enabling it to be linked to a data register.

2.5.1. Example: RiskManagementFile#data

The following data class, from a medical device risk management model, defines a record that aggregates references to multiple subsidiary data classes:

class RiskManagementFile#data {
  plan: reference(RiskPlan) {
    definition "Risk Management Plan"
    modality SHALL
    reference {
      ISO14971-doc-ref3-4
    }
  }
  change: reference(ChangeRecord) {
    definition "Record of changes"
    modality SHALL
    reference {
      ISO14971-doc-ref3-4
    }
  }
  analysis: reference(RiskAnalysisRecord) {
    definition "Risk analysis"
    modality SHALL
    reference {
      ISO14971-doc-ref4-1
    }
  }
  device: reference(MedicalDevice) {
    definition "characteristics related to the safety of the medical device"
    modality SHALL
    reference {
      ISO14971-doc-ref4-2
    }
  }
  hazards: reference(Hazards) {
    definition "Known and foreseeable hazards associated with the medical device"
    modality SHALL
  }
  evaluation: reference(RiskEvaluationResult) {
    definition "Risk evaluation results"
    modality SHALL
    reference {
      ISO14971-doc-ref5
    }
  }
  control: reference(RiskControlRecord) {
    definition "Risk control records"
    modality SHALL
    reference {
      ISO14971-doc-ref6-2
    }
  }
}

This example demonstrates:

  • Multiple reference() typed fields pointing to other data classes
  • Each field carries modality SHALL indicating mandatory data
  • Most fields include normative reference links for traceability
  • Field names use the explicit type syntax ( name: type { ... })

2.5.2. Example: Scope#data

The following data class, from an ISO HLS (High-Level Structure) model, uses a mix of primitive types and references:

class Scope#data {
  name: string {
    definition "Name/Title"
  }
  scope: string {
    definition "Scope"
  }
  aspect: reference(Aspects#data) {
    definition "Performance Aspect"
  }
  review: datetime {
    definition "Last Reviewed"
  }
}

This example demonstrates:

  • string fields for textual data
  • datetime field for temporal data
  • reference(Aspects#data) for cross-class references
  • No modality keywords -- all fields are informational

2.6. Helper classes

Helper classes (also called non-data classes) define reusable complex types that can be embedded as fields within data classes. They are identified by the absence of the #data suffix and cannot be directly linked to data registers.

2.6.1. Example: DocMeta helper class

The following helper class, from a standardization management system model, defines a reusable metadata structure:

class DocMeta {
  identification {
    definition "Identification"
    modality SHALL
  }
  description {
    definition "Description"
    modality SHALL
  }
  format {
    definition "Format"
    modality SHALL
  }
  media {
    definition "Media"
    modality SHALL
  }
  review {
    definition "Review for suitability and adequacy"
    modality SHALL
  }
  approval {
    definition "Approval for suitability and adequacy"
    modality SHALL
  }
  title {
    definition "Title"
    modality MAY
    satisfy {
      description
    }
  }
  refno {
    definition "Reference number"
    modality MAY
    satisfy {
      identification
    }
  }
}

This helper class is then used as a field type in multiple data classes:

class IssueData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  issue {
    definition "Issue"
    modality SHALL
  }
  type: IssueType {
    definition "Type"
    modality SHALL
  }
}
  1. The DocMeta helper class is used as the type for the meta field.

2.6.2. Example: NonapplicableJustification helper class

class NonapplicableJustification {
  requirement {
    definition "Requirement that the organization determines is not applicable"
    modality SHALL
  }
  justification {
    definition "Justification"
    modality SHALL
  }
}

Used within a data class with cardinality:

class NonapplicableProductData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  type {
    definition "Type of products and services covered in the SMS scope"
    modality SHALL
  }
  nonApplication: NonapplicableJustification[0..*] {
    definition "Non-applicable requirements and justifications"
    modality SHALL
  }
}
  1. Helper class used as a field type with [0..*] cardinality (zero or more).

2.7. Empty classes

A class may be declared with no fields. This serves as a placeholder or marker type:

class RiskControlMeasureReview#data {
}
class Policy#data {
}

Empty data classes can still be linked to data registers and used as reference targets.

3. Enumerations

3.1. General

Enumerations define a set of named values with human-readable definitions. They are used as field types within class definitions to constrain a field to a predefined set of values.

3.2. Syntax

enum <EnumName> {
  <Value1> {
    definition "Description of value 1"
  }
  <Value2> {
    definition "Description of value 2"
  }
}

Each enumeration value is an identifier followed by a block containing a definition property.

3.3. Example: HazardType

The following enumeration, from a medical device risk management model, defines three categories of hazard:

enum HazardType {
  Physical {
    definition "Physical"
  }
  Chemical {
    definition "Chemical"
  }
  Biological {
    definition "Biological"
  }
}

3.4. Using enumerations as field types

An enumeration is used as a field type by naming the enumeration in the field declaration:

class Hazards#data {
  hazard {
    definition "Known hazards"
  }
  hazard2 {
    definition "Foreseeable hazards"
  }
  type: HazardType {
    definition "Hazard type"
  }
}
  1. The type field uses the HazardType enumeration as its type.

3.5. Example: SRating

The following enumeration, from a supply chain management model, defines a supplier rating scale:

enum SRating {
  distinctive {
    definition "Distinctive"
  }
  good {
    definition "Good"
  }
  basic {
    definition "Basic"
  }
}

Used in a data class:

class SupplierRating#data {
  supplier: reference(SupplierCapacity#data) {
    definition "Supplier's response"
  }
  rating: SRating {
    definition "Rating"
  }
}
  1. The rating field is constrained to one of distinctive, good, or basic.

3.6. Enumeration rules

  • Each enumeration value SHALL have a unique name within the enumeration.
  • Each enumeration value SHALL contain a definition property.
  • Enumeration names are case-sensitive.
  • An enumeration SHALL be defined before or after the class that uses it; the order of top-level declarations is flexible.

4. Data registries

4.1. General

Data registries define named, persistent data stores. Each registry is backed by a data class and represents a collection of records that processes can read from or write to. Data registries are the runtime containers that hold the actual document records produced during process execution.

4.2. Syntax

data_registry <RegistryName> {
  title "Human-readable title"
  data_class <ClassName>#data
}
  1. Display title for the registry.
  2. The data class defining the schema of records in this registry.

4.3. Registry vs data class distinction

A data class defines the schema (structure) of records, while a data registry defines the store (container) for those records. They are distinct concepts:

Concept Description
Data class ( class Name#data { ... } ) Defines the fields and types of a record; the schema
Data registry ( data_registry Name { ... } ) Defines the named, persistent store for records conforming to that schema

The data_class property of a registry points to the data class that defines its schema. The registry name and the data class name may be the same or different.

class RiskPlan#data {
  scope {
    definition "Scope"
    modality SHALL
  }
}
data_registry RiskPlan {
  title "Risk management plan"
  data_class RiskPlan#data
}
  1. Data class defining the schema.
  2. Data registry defining the persistent store.
  3. The registry references its backing data class.

4.4. Process bindings

Processes interact with data registries through two binding mechanisms:

4.4.1. Output binding

The output { } property of a process specifies which data registries the process writes to:

process RiskManagementFile1 {
  name "Manage Risk management file"
  actor Org
  validate_provision {
    Provision1
  }
  output {
    RiskManagementFile
  }
}
  1. This process populates the RiskManagementFile registry with new records.

4.4.2. Reference data registry binding

The reference_data_registry { } property specifies which data registries the process reads from:

process MonitorIssue {
  name "Monitor issues"
  modality SHALL
  reference_data_registry {
    IssueRegistry
  }
  validate_provision {
    MonitorIssue
  }
}
  1. This process reads existing records from the IssueRegistry registry.

4.5. Example registries

The following example, from an ISO HLS model, demonstrates a model with multiple data registries, each backed by a data class:

class Aspects#data {
  name: string {
    definition "Name/Title"
  }
  bib: reference(BibItem#data)[0..*] {
    definition "Relevant bibliographic item"
  }
}
class BibItem#data {
  id: string {
    definition "BibItem ID"
  }
  item: string {
    definition "Item"
  }
}
data_registry Aspects {
  title "Performance Aspects"
  data_class Aspects#data
}
data_registry BibItem {
  title "Bibliographic items"
  data_class BibItem#data
}
data_registry Scope {
  title "Scope"
  data_class Scope#data
}
data_registry Objective {
  title "Objectives"
  data_class Objective#data
}
data_registry Role {
  title "Roles"
  data_class Role#data
}

4.6. Registry naming

The registry identifier is used in:

  • process.output { } -- to specify which registries the process writes to
  • process.reference_data_registry { } -- to specify which registries the process reads from
  • subprocess.data { } -- to position the registry icon on the diagram

The title property provides a human-readable display name, which may differ from the identifier.

4.7. Multiple registries

A model may define any number of data registries. Each registry SHALL reference exactly one data class. Multiple registries MAY reference the same data class, though this is uncommon.

A process MAY output to multiple registries and read from multiple registries:

process DeterminePartyandReq {
  name "Determine interested parties and their requirements"
  modality SHALL
  validate_provision {
    DetermineParty
    DeterminePartyReq
  }
  output {
    PartyRequirementRegistry
    PartyRegistry
  }
}
  1. This process writes to two registries simultaneously.

5. Field types

5.1. General

Class fields in MMEL may be declared with explicit types or left untyped (implicitly string). This clause specifies all available field types.

5.2. Type reference

Type Notation Description
String string Text value
Boolean boolean True/false value
Datetime datetime Date and/or time value
Role role Reference to a system role
Reference reference(Target#data) Reference to another data class
Enumeration <EnumName> An enumeration type (e.g. HazardType )
Helper class <ClassName> A nested complex type (class without #data )
Untyped (none) Defaults to string

5.3. Primitive types

5.3.1. String

The string type represents textual data:

class TotalCostOfOwnership#data {
  price: string {
    definition "Purchase Price"
  }
  deliverCost: string {
    definition "Delivery cost"
  }
  installation: string {
    definition "Installation Cost"
  }
}

5.3.2. Boolean

The boolean type represents a true/false value:

class auditchecklist {
  bibitem: reference(BibItem#data) {
    definition "Bibitem"
  }
  clause: string {
    definition "Clause number"
  }
  evidence: string {
    definition "Evidence"
  }
  compliance: boolean {
    definition "Compliance"
  }
}
  1. The compliance field is a boolean indicating whether compliance was achieved.

5.3.3. Datetime

The datetime type represents a date and/or time value:

class audit#data {
  name: string {
    definition "Name/Title"
  }
  date: datetime {
    definition "Date/Time"
  }
}
  1. The date field stores the audit date and time.

5.3.4. Role

The role type references a system role defined in the model:

class Role#data {
  name: string {
    definition "Name/Title"
  }
  People: string {
    definition "People"
  }
  role: role {
    definition "System role"
  }
  responsibilities: string {
    definition "General responsibilities"
  }
}
  1. The role field references a system role.

5.4. Reference types

Reference types create links between data classes, enabling relational data structures. A reference field points to a record in another data class.

5.4.1. Syntax

<fieldName>: reference(<TargetClassName>#data) {
  definition "Description"
}

The target class name may include the #data suffix or omit it, depending on whether the target is a data class or helper class.

5.4.2. Single reference

A reference without cardinality denotes exactly one related record:

class Scope#data {
  name: string {
    definition "Name/Title"
  }
  aspect: reference(Aspects#data) {
    definition "Performance Aspect"
  }
}
  1. Each scope record references exactly one performance aspect.

5.4.3. Reference with cardinality

References may include cardinality to indicate collections:

class audit#data {
  persons: reference(Role#data)[0..*] {
    definition "Responsible persons"
  }
  bibitem: reference(BibItem#data)[0..*] {
    definition "Relevant bibliographic items"
  }
  standard: reference(Standards#data)[0..*] {
    definition "Relevant standards"
  }
}
  1. Zero or more responsible persons.
  2. Zero or more bibliographic items.

5.4.4. Reference to data class vs helper class

References typically point to data classes (with #data suffix), but can also reference helper classes when used as nested types:

class PartyRequirementData {
  party: reference(PartyData)[0..*] {
    definition "Requirement of interested parties"
    modality SHALL
  }
}
  1. Reference to PartyData, another class used as a data structure.

5.5. Enumeration types

An enumeration type constrains a field to a predefined set of values:

class Hazards#data {
  type: HazardType {
    definition "Hazard type"
  }
}
enum HazardType {
  Physical {
    definition "Physical"
  }
  Chemical {
    definition "Chemical"
  }
  Biological {
    definition "Biological"
  }
}
  1. The type field is constrained to Physical, Chemical, or Biological.

5.6. Helper class types

A helper class (without #data suffix) can be used as a field type to embed a nested structure:

class IssueData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  issue {
    definition "Issue"
    modality SHALL
  }
  pfactor[0..*] {
    definition "Positive factor or condition"
    modality CAN
  }
}
  1. The meta field embeds the full DocMeta structure as a nested type.

Helper class fields may also include cardinality:

class NonapplicableProductData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  nonApplication: NonapplicableJustification[0..*] {
    definition "Non-applicable requirements and justifications"
    modality SHALL
  }
}
  1. Zero or more embedded NonapplicableJustification structures.

5.7. Untyped fields

When a field declaration omits the type ( : and type name), it defaults to string:

class RiskPlan#data {
  scope {
    definition "Scope"
    modality SHALL
    reference {
      ISO14971-doc-ref3-4
    }
  }
  Assignment {
    definition "Responsibilities and authorities"
    modality SHALL
  }
}
  1. Untyped field, implicitly string.
  2. Untyped field, implicitly string.

6. Cardinality

6.1. General

Cardinality (multiplicity) notation specifies how many values a field may hold. Cardinality applies to reference types and helper class types.

6.2. Notation

Notation Meaning Example
[0..*] Zero or more (optional collection) reference(Role#data)[0..*]
[1..*] One or more (required collection) reference(BibItem#data)[1..*]
[0..1] Zero or one (optional single) reference(Traceability)[0..1]
(none) Exactly one (default) reference(RiskPlan)

6.3. Syntax

Cardinality is specified immediately after the type name, before the field property block:

<fieldName>: <type>[<lower>..<upper>] {
  definition "Description"
}

Where <lower> is an integer and <upper> is either an integer or * (meaning unbounded).

6.4. Examples

6.4.1. Optional collections

The [0..*] notation indicates that a field may have zero or more values:

class audit#data {
  name: string {
    definition "Name/Title"
  }
  persons: reference(Role#data)[0..*] {
    definition "Responsible persons"
  }
  bibitem: reference(BibItem#data)[0..*] {
    definition "Relevant bibliographic items"
  }
  checklist: auditchecklist[0..*] {
    definition "Audit Checklist"
  }
}
  1. Zero or more role references.
  2. Zero or more bibliographic item references.
  3. Zero or more embedded helper class structures.

6.4.2. Required collections

The [1..*] notation indicates that a field must have at least one value:

class Procedure#data {
  name: string {
    definition "Name/Title"
  }
  policy: reference(policy#data)[1..*] {
    definition "Relevant Policy"
  }
  bibiitem: reference(BibItem#data)[1..*] {
    definition "relevant bibliographic items"
  }
}
  1. At least one policy reference is required.
  2. At least one bibliographic item reference is required.

6.4.3. Optional single values

The [0..1] notation indicates that a field may have zero or one value:

class SMSProcessInteractionData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  process: reference(SMSProcessData)[1..*] {
    definition "Process"
    modality SHALL
  }
  sequence[0..1] {
    definition "Sequence of the processes"
    modality SHALL
  }
  interaction[0..1] {
    definition "Interaction of the processes"
    modality SHALL
  }
}
  1. Zero or one sequence field.
  2. Zero or one interaction field.

6.4.4. Default (exactly one)

When no cardinality is specified, the field holds exactly one value:

class Scope#data {
  name: string {
    definition "Name/Title"
  }
  aspect: reference(Aspects#data) {
    definition "Performance Aspect"
  }
  review: datetime {
    definition "Last Reviewed"
  }
}
  1. Exactly one string value.
  2. Exactly one reference.
  3. Exactly one datetime value.

6.5. Cardinality and modality interaction

When a field has both cardinality and modality, the modality applies to the field as a whole. For example:

  • modality SHALL with [0..*] means the field itself SHALL exist but may be empty (zero values)
  • modality SHALL with [1..*] means the field SHALL exist and SHALL contain at least one value
class PartyRequirementData {
  party: reference(PartyData)[0..*] {
    definition "Requirement of interested parties"
    modality SHALL
  }
}
  1. The party field SHALL be present but may contain zero or more references.

7. Satisfy blocks

7.1. General

A satisfy block on a class field specifies a validation constraint category. It is used by validation tooling to determine which fields fulfil which aspects of a document or data requirement.

7.2. Syntax

<fieldName> {
  definition "Field description"
  modality MAY
  satisfy {
    <constraint-category>
  }
}

The satisfy block contains a single identifier naming the constraint category that this field satisfies.

7.3. Constraint categories

Constraint categories are user-defined identifiers that name the type of constraint or requirement aspect that a field addresses. Commonly used categories include:

Category Description
description The field provides descriptive content about the data element
identification The field provides identifying information (e.g. reference numbers, codes)
format The field specifies the format or representation of the data
media The field specifies the storage or transmission medium

These categories are not predefined by MMEL; model authors may define any constraint categories appropriate to their domain.

7.4. Example: DocMeta class with satisfy blocks

The following helper class, from a standardization management system model (BS 202000), defines document metadata fields with satisfy blocks:

class DocMeta {
  identification {
    definition "Identification"
    modality SHALL
  }
  description {
    definition "Description"
    modality SHALL
  }
  format {
    definition "Format"
    modality SHALL
  }
  media {
    definition "Media"
    modality SHALL
  }
  review {
    definition "Review for suitability and adequacy"
    modality SHALL
  }
  approval {
    definition "Approval for suitability and adequacy"
    modality SHALL
  }
  title {
    definition "Title"
    modality MAY
    satisfy {
      description
    }
  }
  author {
    definition "Author"
    modality MAY
    satisfy {
      description
    }
  }
  date {
    definition "Date"
    modality MAY
    satisfy {
      description
    }
  }
  refno {
    definition "Reference number"
    modality MAY
    satisfy {
      identification
    }
  }
  language {
    definition "Language"
    modality MAY
    satisfy {
      format
    }
  }
  software {
    definition "Software version"
    modality MAY
    satisfy {
      format
    }
  }
  graphics {
    definition "Graphics"
    modality MAY
    satisfy {
      format
    }
  }
  paper {
    definition "Paper"
    modality MAY
    satisfy {
      media
    }
  }
  electronic {
    definition "Electronic"
    modality MAY
    satisfy {
      media
    }
  }
}
  1. title satisfies the description constraint category.
  2. author satisfies the description constraint category.
  3. date satisfies the description constraint category.
  4. refno satisfies the identification constraint category.
  5. language satisfies the format constraint category.
  6. software satisfies the format constraint category.
  7. graphics satisfies the format constraint category.
  8. paper satisfies the media constraint category.
  9. electronic satisfies the media constraint category.

7.5. Satisfy on data class fields

The satisfy block can also appear on fields within data classes:

class IssueData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  issue {
    definition "Issue"
    modality SHALL
  }
  type: IssueType {
    definition "Type"
    modality SHALL
  }
  pfactor[0..*] {
    definition "Positive factor or condition"
    modality CAN
    satisfy {
      issue
    }
  }
  nfactor[0..*] {
    definition "Negative factor or condition"
    modality CAN
    satisfy {
      issue
    }
  }
}
  1. pfactor satisfies the issue constraint category.
  2. nfactor satisfies the issue constraint category.

7.6. How satisfy is used by validation tooling

The satisfy block provides metadata for validation and compliance-checking tools. When a standard requires that a document have certain properties (e.g. "description", "identification", "format"), the satisfy blocks allow tooling to verify that the data class includes fields that cover each required constraint category.

The typical validation workflow is:

  1. A standard defines document requirements (e.g. a document SHALL have identification, description, format, and media properties).
  2. The model defines a class with fields, each annotated with satisfy blocks indicating which constraint category they fulfil.
  3. Validation tooling checks that for each required constraint category, at least one field with a matching satisfy block exists.

Multiple fields MAY satisfy the same constraint category. For example, in the DocMeta class above, both title , author , and date satisfy description .

8. Cross-model data references

8.1. General

MMEL supports cross-model references using the Namespace#ElementID notation. This enables data classes and references to refer to elements defined in other MMEL models, supporting model alignment and implementation traceability.

8.2. Namespace notation

Cross-model references use the format Namespace#ElementID , where:

  • Namespace -- identifies the source model by its namespace (as declared in the model's metadata.namespace field)
  • # -- separator between namespace and element identifier
  • ElementID -- the identifier of the specific element within that model

This notation is used in several contexts within data modelling:

  • reference declarations (e.g. reference BS20400#Ref35)
  • data class references (e.g. reference(BS20400#SomeData#data))
  • cross-model process references (e.g. process BS20400#LCC { ... })

8.3. Cross-model reference declarations

Reference declarations may use cross-model notation to declare references that originate from another model:

reference BS20400#Ref35 {
  document "BS20400:2017 Sustainable procurement -- Guidance"
  clause "7.2.3"
}
reference BS20400#Ref44 {
  document "BS20400:2017 Sustainable procurement -- Guidance"
  clause "7.4.1"
}

In this example, the reference identifiers use the BS20400# prefix to indicate that these references originate from the model with namespace BS20400 .

8.4. Cross-model provision and process references

When an implementation model references provisions from the standard it implements, cross-model notation is used:

provision BS20400#Provision180 {
  condition "LCC is a method that could be used to analyse the costs"
  reference {
    BS20400#Ref35
  }
}
provision BS20400#Provision181 {
  condition "When assessing the costs using an LCC approach, the organization should indicate in the procurement documents the data to be provided by the tenderers"
  reference {
    BS20400#Ref35
  }
}

These provisions are then referenced by processes in the implementation model:

process BS20400#LCC {
  name "Life Cycle Costing"
  validate_provision {
    BS20400#Provision180
    BS20400#Provision181
  }
  subprocess BS20400#Page19
}

8.5. Example: BS20400 implementation model

The following excerpt from BS20400impl(mapped).mmel demonstrates an implementation model that references elements from the BS20400 standard model:

// Cross-model start events
start_event BS20400#Start20 {
}
start_event BS20400#Start14 {
}
// Cross-model subprocess
subprocess BS20400#Page19 {
  elements {
    BS20400#Start20 {
      x -20
      y -20
    }
    totalCostOfOwnership {
      x -70
      y 120
    }
    BS20400#MonetizedExternalities {
      x -70
      y 230
    }
  }
  process_flow {
    BS20400#Edge87 {
      from BS20400#Start20
      to totalCostOfOwnership
    }
  }
  data {
    TotalCostOfOwnership {
      x -240
      y 280
    }
    ExternalCost {
      x -240
      y 400
    }
  }
}

This example demonstrates:

  • Cross-model element references ( BS20400#Start20, BS20400#Edge87)
  • Mixed references -- local elements ( totalCostOfOwnership) alongside cross-model elements ( BS20400#MonetizedExternalities)
  • Data registry positions for local registries

8.6. Cross-model data class references

Data classes may reference other data classes across models using the cross-model notation in reference fields:

class ManagementReviewData {
  meta: DocMeta {
    definition "General documented information"
    modality SHALL
  }
  changes: reference(IssueData)[0..*] {
    definition "Changes in external and internal issues"
    modality SHALL
  }
  objectives: reference(ObjectiveData)[0..*] {
    definition "The extent to which standardization objectives have been met"
    modality SHALL
  }
  process: reference(SMSProcessData)[0..*] {
    definition "Process performance and conformity"
    modality SHALL
  }
}
  1. IssueData and ObjectiveData are classes defined in the same model, but could equally be cross-model references using the NamespaceClassdata format.

8.7. Cross-model reference resolution

When a tool encounters a Namespace#ElementID reference, it:

  1. Looks up the model with the matching metadata.namespace value.
  2. Resolves the ElementID within that model's declarations.
  3. Treats the resolved element as if it were a local declaration.

If the referenced model is not available, the tool SHOULD report a resolution error but MAY continue processing with an unresolved reference placeholder.

9. Formal grammar (EBNF)

9.1. General

This clause provides a simplified EBNF grammar for the data modelling constructs of MMEL. The grammar covers classes, enumerations, data registries, field properties, cardinality, and satisfy blocks.

9.2. Grammar

(* Data modelling declarations *)
ClassDecl       ::= 'class' IDENTIFIER ('#data')? '{' ClassField* '}'
ClassField      ::= FieldName (':' FieldType)? Cardinality?
                    '{' FieldProperty* '}'
FieldName       ::= IDENTIFIER
FieldType       ::= PrimitiveType
                  | ReferenceType
                  | IDENTIFIER
PrimitiveType   ::= 'string' | 'boolean' | 'datetime' | 'role'
ReferenceType   ::= 'reference' '(' IDENTIFIER ('#data')? ')'
Cardinality     ::= '[' INT '..' ( '*' | INT ) ']'
FieldProperty   ::= 'definition' STRING
                  | 'modality' MODALITY
                  | 'reference' '{' IDENTIFIER* '}'
                  | 'satisfy' '{' IDENTIFIER '}'
EnumDecl        ::= 'enum' IDENTIFIER '{' EnumValue* '}'
EnumValue       ::= IDENTIFIER '{' 'definition' STRING '}'
DataRegistryDecl ::= 'data_registry' IDENTIFIER '{'
                     'title' STRING
                     'data_class' IDENTIFIER ('#data')? '}'
(* Shared terminals *)
MODALITY        ::= 'SHALL' | 'SHOULD' | 'MAY' | 'CAN' | 'MUST'
STRING          ::= '"' ... '"'
IDENTIFIER      ::= [a-zA-Z_][a-zA-Z0-9_'-]*
INT             ::= [0-9]+

9.3. Grammar notes

  • ClassDecl produces both data classes (with #data) and helper classes (without #data).
  • FieldType covers primitive types, reference types, and identifiers (which resolve to either enumeration names or helper class names).
  • Cardinality is optional. When absent, the field holds exactly one value.
  • FieldProperty includes satisfy, which contains a single identifier naming the constraint category.
  • IDENTIFIER allows hyphens ( -) and apostrophes ( ’ `) in addition to alphanumeric characters and underscores, supporting identifiers like risk/benefit, post-productionEvaluation, and ISO14971-doc-ref3-4.
  • The reference field property (inside FieldProperty) references normative document clauses, while the reference type (inside ReferenceType) references other data classes.