The Simple Domain Modeling Language (SDML)

Everything you need for domain modeling with SDML

The Simple Domain Modeling Language (SDML) is a small data-oriented language for constructing, documenting, and reasoning about a conceptual domain model. The SDML language comprises:

  1. a semantic model whose structure and semantics are described in RDF by an OWL ontology,
  2. a surface syntax for editing and sharing model artifacts, and
  3. a constraint language to capture model invariants not covered by the data descriptions in the surface syntax.

Language features

  1: module hospitality is
  2: 
  3:   import [ dc xsd ]
  4: 
  5:   @dc:description = "Hospitality Model"
  6:   @dc:version = "2"
  7:   @dc:dateCopyrighted = xsd:date("2023-12-21")
  8: 
  9:   entity Customer
 10: 
 11:   entity Booking is
 12:     identity booking_code -> string
 13:     customer -> Customer
 14:     property -> Property
 15:     room_style -> RoomStyle
 16:     room_rate -> Currency
 17:     dates -> DateRange
 18:     number_of_adults -> integer
 19:     number_of_children -> integer
 20:   end
 21: 
 22:   entity Property ;; fill this in later
 24: 
 25:   entity Bill is
 26:     identity transaction_id -> unknown
 27:     for_stay -> Stay
 28:     charges -> {0..} Purchase
 29:   end
 30: 
 31:   entity Stay is
 32:     identity id -> unknown
 33:     booking -> {0..1} Booking
 34:     room_number -> unsigned
 35:     room_rate -> {0..1} Currency ;; if different from booking
 36:     dates -> DateRange
 37:     tax_percent -> RatePercentage
 38:     discount_percent -> RatePercentage
 39:   end
 40: 
 41:   datatype Currency <- decimal is
 42:     @xsd:totalDigits = 9
 43:     @xsd:fractionDigits = 3
 44:   end
 45: 
 46:   datatype RatePercentage <- decimal is
 47:     @xsd:totalDigits = 5
 48:     @xsd:fractionDigits = 3
 49:   end
 50: 
 51:   enum RoomFeature of
 52:     View
 53:     NonSmoking
 54:     Smoking
 55:     Accessible
 56:     OneSingleBed
 57:     OneDoubleBed
 58:     OneQueenBed
 59:     OneKingBed
 60:     TwoSingleBeds
 61:     TwoDoubleBeds
 62:     TwoQueenBeds
 63:     TwoKingBeds
 64:     Suite
 65:     Fridge
 66:     Kitchen
 67:     Balcony
 68:   end
 69: 
 70:   structure DateRange is
 71:     assert formal_range is
 72:        self, self.starts  self.ends
 73:     end
 74: 
 75:     starts -> xsd:date
 76:     ends -> xsd:date
 77:   end
 78: 
 79:   structure Room is
 80:     number -> unsigned
 81:     floor -> unsigned
 82:     style -> RoomStyle
 83:     additional_features -> {unique 0..*} RoomFeature
 84:     rate -> Currency
 85:   end
 86: 
 87:   structure RoomStyle is
 88:     name -> string
 89:     features -> {unique 1..*} RoomFeature
 90:   end
 91: 
 92:   structure Charge
 93: 
 94:   structure Purchase
 95: 
 96:   structure Payment is
 97:     amount -> Currency
 98:     instrument -> PaymentInstrument
 99:   end
100: 
101:   union PaymentInstrument of
102:     Cash
103:     Card
104:     Credit
105:   end
106: 
107:   structure Cash
108: 
109:   structure Card
110: 
111:   structure Credit
112: 
113: end
A simple, block-structured, and regular syntax. Design choices in syntax have, and will, optimize for readability even for non-technical users.
Annotation properties for additional descriptive content and tool integration. These replace doc-comments and other added-on features in common programming languages.
Support for Domain-Driven Design processes with direct modeling of entities as major component types.
An SDML model may be valid, even if it is incomplete, allowing iterative elaboration. This makes SDML a great workshop tool, capturing models in real-time.
Events are used in SDML to denote asynchronous messaging between entities.
Annotation constraints for more complex validation rules in informal and formal languages. Formal constraints are based on ISO common logic.
As well as enumerations SDML supports Disjoint Unions which allow type-safe and simple polymorphic structures.
To provide specificity, SDML allows for the definition of new data types using the XML Schema part-2 types as a base.
SDML abstracts sequence types (lists, sets, etc) with a common mathematical notation.
The semantic foundation for the language is RDF and OWL such that every SDML module is also a valid OWL2 ontology.
SDML also supports a data-dictionary like approach to modeling with common property definitions. Fields can be defined in detail stand-alone and used by reference in multiple places.
SDML is Unicode friendly, names can be defined using an Unicode letter and some common symbols. Some operators and keywords may be replaced by corresponding Unicode characters such as →, ←, ∀, ∃, or ∈.

Tools and integrations

Visual Studio support is available in the marketplace and provides syntax highlighting, code snippets, and CLI-tool integration for diagram generation.
TextMate support includes syntax highlighting, annotation and definition snippets, symbol-list integration, and CLI-tool integration for diagram generation.
Emacs sdml-mode provides the most complete and up-to-date support including syntax highlighting based directly on the tree-sitter grammar, indentation, code-folding, and symbol prettification. It also integrates with abbreviations, ya-snippets, ispell, flycheck, and org-babel.
Sublime Text has partially supported syntax highlighting and some of the TextMate snippets included. The grammar can also be used by the bat command line tool for highlighting.
The SDML surface syntax is defined as a tree-sitter grammar. This grammar can be used via the provided C, Rust, Node, or WASM bindings and is directly supported by some tools.
The SDML command-line tool generates UML class diagrams from modules using PlantUML. These diagrams can be saved in source form allowing for further off-line editing.
The SDML command-line tool generates non-UML diagrams, such as concept diagrams, using GraphViz. These diagrams can be saved in source form allowing for further off-line editing.
The SDML command-line tool can generate an RDF representation of a module for integration with model repositories and OWL-enabled reasoning tools.
Documentation in Markdown or Emacs org-mode can be generated from modules using the SDML command-line tool.

Let's get started!

This section will demonstrate the steps necessary to install the SDML tools and integrations so you can start writing your own domain models.

Installer

A partial installer script is provided that will install necessary prerequisites and the SDML tools themselves. This script requires the Homebrew package manager; because the script was developed on, and for, Mac systems, it may work on Linux, but at this time has no Windows counterpart. The following is the easiest way to execute the installer.

$ curl https://sdml.io/install.sh | bash

The script performs the following tasks

  1. Install PlantUML, for use in producing UML diagrams.
  2. Install GraphViz, for use in producing other diagrams.
  3. Install Rustup, for the cargo command.
  4. Using cargo, install the sdml-cli package, for the sdml command.
  5. Prompt the user to install an editor and associated language support packages.

Editor

As a text language it is important that a good editor is available to help the author use SDML in an efficient manner. Extensions have been developed for a set of editors, and while not exhaustive, it covers the most popular. For new users we recommend Visual Studio Code. The installer script above will attempt to install one of the supported text editors along with the SDML integration for it. However, if you wish to do this manually, or find that the installer does not work with your development environment the following are the steps necessary for major editors.

This can be directly installed from one of:

  • the Visual Studio marketplace,
  • the Extensions View within VSCode, search for 'sdml',
  • The command line: code --install-extension SimonJohnston.sdml,
  • or manually by cloning the repository.
$ git clone  https://github.com/sdm-lang/sdml-vscode.git

TextMate, and most editors that support TextMate bundles, allow the installation of bundles simply by extracting an archive or cloning the repository into the application's bundle directory. This bundle is no different.

For TextMate itself, the easiest approach is the install shell script shown below. This will create a new folder in TextMate's bundle folder and clone the Github repository locally.

$ curl  https://raw.githubusercontent.com/sdm-lang/SDML.tmbundle/main/install.sh | sh

Alternatively, you can download a release zip file from Github (sdm-lang/SDML.tmbundle) and unzip into the TextMate bundle directory.

Currently the package is not published and so installation has to be done manually.

The install script provided will clone this repository into your Sublime Text package location and, if you have bat installed, link the repository into the bat configuration folder.

$ curl  https://raw.githubusercontent.com/sdm-lang/sdml-sublime-text/main/install.sh | sh

Alternatively, you can download a release zip file from Github (sdm-lang/sdml-sublime-text) and unzip into the Sublime Text "Packages" directory.

Command-Line Interface (CLI)

The SDML command-line tool is used to validate module source files as well as generate different representations and diagrams from the source. Once installed the option --help or the command help will guide you through the commands available.

$ sdml --help
Rust CLI for Simple Domain Modeling Language (SDML).

Usage: sdml [OPTIONS] 

Commands:
  doc        Document a module
  deps       Show module dependencies
  tags       Extract tags from a module
  highlight  Syntax highlight a module source
  convert    Convert a module into other formats
  draw       Draw diagrams from a module
  version    Show tool and library versions
  help       Print this message or the help of the given subcommand(s)

Options:
  -v, --verbose...  More output per occurrence
  -q, --quiet...    Less output per occurrence
  -h, --help        Print help
  -V, --version     Print version

If you wish to install the command-line tool on it's own, without using the install script above, it is simple using the Rust language's cargo install sdml-cli command. If you do not have cargo installed you can follow Installing Cargo in the Cargo book, or use Homebrew to install rustup-init.

To list the dependencies of a module the deps command will print them as a tree, as shown below. It can also output the dependencies as a GraphViz dot file or as RDF triples.

$ sdml deps --depth 2 --input-file rentals-5.sdm
rentals
├── xsd
├── cids
│   ├── dc
│   └── skos
├── skos
└── dc

The tags command will output a ctags file for tools that use them for determining the location of symbol definitions.

$ sdml tags --input-file rentals-5.sdm
Basic	rentals-5.sdm	436go
Booking	rentals-5.sdm	934go
Compact	rentals-5.sdm	305go
CompactUtilityVehicle	rentals-5.sdm	330go
Customer	rentals-5.sdm	859go
CustomerLevel	rentals-5.sdm	415go
...

The highlight command will output a syntax highlighted version of the input module, by default the output includes control characters to highlight for a terminal which is useful for previewing files. Alternatively the --output-format can be used to output html with inline styles.

$ sdml highlight -i cids.sdm
module cids is

  import [ dc skos ]

  @skos:prefLabel = "CIDS"
  @skos:altLabel = "Common Identifiers"

  datatype VehicleIdentificationNumber <- string

end

Diagram

Coming soon

$ sdml draw --help
Draw diagrams from an SDML module.

Usage: sdml draw [OPTIONS] --diagram  [MODULE]

Arguments:
  [MODULE]
          SDML module, loaded using the standard resolver

Options:
  -d, --diagram 
          Diagram to draw

          Possible values:
          - concepts:            Concept Overview
          - entity-relationship: Entity Relationship
          - uml-class:           UML Class

Document

Coming soon

$ sdml doc --help
Produce documentation for an SDML module.

Usage: sdml doc [OPTIONS] [MODULE]

Arguments:
  [MODULE]
          SDML module, loaded using the standard resolver

Options:
  -f, --output-format 
          Format to convert into

          [default: org-mode]

          Possible values:
          - org-mode: Emacs org-mode
          - markdown: Markdown