Value Lists

This data story presents the idiomatic approach for modeling value lists.

1. Source data

We will create a knowledge model and information model for the following source data, recording the status of buildings:

Building IDBuilding Status
001In use
002Not in use
003Not in use
004In use

To keep this report somewhat simple, we will not model the buildings themselves, but only their statuses.

2. Knowledge layer

For the knowledge layer we need to represent the meaning of the values "In use" and "Not in use".

2.1 Model individual values

The unique values "In use" and "Not in use" can be modeled as SKOS concepts. For example, we can model the "In use" value as follows:

prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix con: <https://triplydb.com/Triply/example/model/con/>

con:buildingInUse
  a skos:Concept;
  skos:prefLabel
    'building in use'@en,
    'pand in gebruik'@nl.

Notice the use of prefix con: for concepts. This is part of the Triply IRI Strategy.

Each value is modeled in the same way; for example, this is how "Not in use" is modeled:

prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix con: <https://triplydb.com/Triply/example/model/con/>

con:buildingNotInUse
  a skos:Concept;
  skos:prefLabel
    'building not in use'@en;
    'pand buiten gebruiken'@nl.

2.2 Modeling multiple values

We can model the individual values for "In use" and "Not in use", but we also want to model that they belong together. We use a SKOS Concept Scheme for this:

prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix scheme: <https://triplydb.com/Triply/example/model/scheme/>

scheme:BuildingStatus
  a skos:ConceptScheme;
  skos:prefLabel
    'building status'@en,
    'pand status'@nl.

Notice the use of the scheme: prefix to note concept schemes. This is part of the Triply IRI Strategy.

Once the concept scheme is in place, each individual value must be related to it:

prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix con: <https://triplydb.com/Triply/example/model/con/>
prefix scheme: <https://triplydb.com/Triply/example/model/scheme/>

con:buildingInUse skos:inScheme scheme:BuildingStatus.
con:buildingNotInUse skos:inScheme scheme:BuildingStatus.

2.3 Modeling a corresponding class

A downside of modeling value lists as SKOS concept schemes is that they cannot be directly used in property definitions.

For example, buildings can have a def:status property whose object terms must be values for the modeled value list.

prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix def: <https://triplydb.com/Triply/example/model/def/>

def:status
  a owl:ObjectProperty;
  rdfs:domain def:Building;
  rdfs:range def:BuildingStatus.

Notice the use of def: to denote properties and classes. This is in line with the Triply IRI Strategy. Notice also that def:BuildingStatus is an OWL class and not a SKOS concept scheme.

Luckily, OWL allows us to define an OWL class that perfectly encapsulates out SKOS concept scheme. This is done through an OWL restriction:

prefix owl: <http://www.w3.org/2002/07/owl#>
prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix def: <https://triplydb.com/Triply/example/model/def/>
prefix scheme: <https://triplydb.com/Triply/example/model/scheme/>

def:BuildingStatus
  a owl:Restriction;
  owl:onProperty skos:inScheme;
  owl:hasValue scheme:BuildingStatus.

The above OWL notation means:

The class (OWL) of building statuses is the set of things that are in the building status concept scheme (SKOS).

Notice that this restriction creates a 'semantic bridge' between OWL (formal logic) and SKOS (informal conceptualization). This is a generic pattern that can be used to encapsulate any concept scheme in a corresponding class. This pattern allows the values of a concept scheme to be specified in the range of a property.

3. Information layer

In addition to the knowledge layer, we also want to represent the value list in the information layer. This allows us to validate whether the value list is applied correctly in the data that we publish. Notice that the information layer following the knowledge layer: it does not add new meaning to our data consumers; it only makes the criteria for internal data publication strict enough to ensure that the meaning expressed in the knowledge layers is published correctly.

prefix sh: <http://www.w3.org/ns/shacl#>
prefix con: <https://triplydb.com/Triply/example/model/con/>
prefix def: <https://triplydb.com/Triply/example/model/def/>
prefix shp: <https://triplydb.com/Triply/example/model/shp/>

shp:Building
  a sh:NodeShape;
  sh:property shp:Building_status;
  sh:targetClass def:Building.

shp:Building_status
  a sh:PropertyShape;
  sh:class def:BuildingStatus;
  sh:in
    ( con:buildingInUse
      con:buildingNotInUse );
  sh:nodeKind sh:IRI;
  sh:path def:status.

Notice the use of shp: to denote SHACL shapes. This is in line with the Triply IRI Strategy.

4. Application to instance data

With the knowledge model and information model in place, we can now assert the instance data that corresponds our original source table:

prefix building: <https://triplydb.com/Triply/example/id/building/>
prefix con: <https://triplydb.com/Triply/example/model/con/>
prefix def: <https://triplydb.com/Triply/example/model/def/>

building:001 def:status con:buildingInUse.
building:002 def:status con:buildingNotInUse.
building:003 def:status con:buildingNotInUse.
building:004 def:status con:buildingInUse.

The original table is repeated here for convenience:

Building IDBuilding Status
001In use
002Not in use
003Not in use
004In use