Creating and extending ontology

Telicent CORE can support any RDF-based ontology. However, there will be times where you need to make extensions to existing ontologies e.g. extending an ontology that has a class called RoadVehicle to support specific subtypes e.g. Van, EstateCar etc. You may also want to utilize other ontologies other than the default ontologies that come out-of-the-box with CORE. In both these cases, the specification of new ontology splits into two concerns:

  1. The actual RDF specification of classes and properties some of which might be extensions of other ontologies.
  2. The specification of ontology styles, used to prescribe how data using an ontology appears within the Telicent Apps e.g. icons and colors.

Here we will explain how to do both, and how to get these two types of specification, into CORE.

Specifying Ontology (new classes and properties)

Creating an ontology from scratch is a significant undertaking, so starting with one of the existing ontologies supported by Telicent CORE can be a practical choice. Whether you choose IES4 or another, you might find they do not offer sufficiently specific classes to meet your needs. Most formal ontologies cater for a large number of domains making them wide in scope but not necessarily deep in any one area. For example, IES4 includes a class called Ship. However if you might need something more specific like PassengerShip, you need to make an extension of Ship. This guide will walk you through the practical steps of extending an ontology. We’ll use IES4 as an example, but these steps can be applied to extending any ontology.

If you’re interested in learning more about extending IES4 specifically, including considerations on where to make your extensions in the IES4 hierarchy, you can find additional information here.

Step-by-step guide

First we need to create RDF that defines a new resource; which could be either a class or a property. This RDF will define the name of the new resource and what it is an extension of. When either extending or creating a new ontology, we need to choose a namespace for all of its resources. When choosing a namespace for your ontology, choose a descriptive name and use a domain that you control (or one that is not already in use). See Sir Tim Berners-Lee article on selecting good namespaces and URIs here. Remember, all namespaces end with either / or #, after which you can place the name of your new resource.

For each resource we want to add to our ontology, we need to specify in our RDF at least three triples:

  1. A triple which specifies what kind of resource we are defining by using the predicate rdf:type.
    • For classes this will be either rdfs:Class or owl:Class.
    • For properties that relate one resource to another i.e. a relationship, this will be either rdfs:Property or owl:ObjectProperty
    • For properties that add literals to a resource i.e. an attribute, this will be either rdfs:Literal or owl:DataProperty. Note, OWL has many others. You should generally follow what has already been used in any ontology you intend to extend. We generally find using RDFS is a lot more straightforward than using OWL.
  2. A triple to specify what your extension is from. Note, a resource can extend more than one other resource:
    • For classes this is defined using the property rdfs:subClassOf
    • For all types of property, this is defined using the property rdfs:subPropertyOf Note, there are no OWL alternatives to these.
  3. A triple to provide a human-readable key for the resource. For all resources this is using the property rdfs:label or skos:prefLabel.

So to illustrate the above, using a new namespace for our ontology of http://example.com/local-ontology#, our definition of the new classes of PassengerShip and CargoShip as extensions of IES4, would look like this:

# Using Turtle Syntax
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ies:  <http://ies.data.gov.uk/ontology/ies4#> .
@prefix ont:  <http://example.com/local-ontology#> .

ont:PassengerShip   rdf:type          rdfs:Class .
ont:PassengerShip   rdfs:subClassOf   ies:Ship .
ont:PassengerShip   rdfs:label        "Passenger Ship" .

ont:CargoShip       rdf:type          rdfs:Class .
ont:CargoShip       rdfs:subClassOf   ies:Ship .
ont:CargoShip       rdfs:label        "Cargo Ship" . 

An example of adding a property is provided below:

# Using Turtle Syntax
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix ies:  <http://ies.data.gov.uk/ontology/ies4#> .
@prefix ont:  <http://example.com/local-ontology#> .

ont:isMotherOf rdf:type             owl:ObjectProperty .
ont:isMotherOf rdfs:subPropertyOf   ies:isParentOf .
ont:isMotherOf rdfs:label           "is mother of" . 

Specifying Ontology Styles

Now that we have defined our extension(s) we can think about the appearance of the new classes in CORE. Note, we normally do not style properties. We specify the styles for a given class by added a fourth and final triple to the RDF specification of a class. This triple uses the predicate <http://telicent.io/ontology/style> and has an object literal which is a stringified JSON of style information. So for our ont:PassengerShip example, the full definition for the class including style information looks like this:

# Using Turtle Syntax
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ies:  <http://ies.data.gov.uk/ontology/ies4#> .
@prefix ont:  <http://example.com/local-ontology#> .
@prefix tont:  <http://telicent.io/ontology/> .

ont:PassengerShip   rdf:type          rdfs:Class .
ont:PassengerShip   rdfs:subClassOf   ies:Ship .
ont:PassengerShip   rdfs:label        "Passenger Ship" .
ont:PassengerShip   tont:style        "{\"defaultStyles\": {\"dark\": {\"backgroundColor\": ... }}" . # etc

The JSON object used as the object of the triple looks like the below:

{
  "defaultStyles": {
    "dark": {
      "backgroundColor": "#242400",
      "color": "#FFFD04"
    },
    "light": {
      "backgroundColor": "#242400",
      "color": "#FFFD04"
    },
    "shape": "round-circle",
    "borderRadius": "9999px",
    "borderWidth": "2px",
    "selectedBorderWidth": "3px"
  },
  "defaultIcons": {
    "riIcon": "ri-meteor-line",
    "faIcon": "fa-solid fa-ship",
    "faUnicode": "\uf21a",
    "faClass": "fa-solid"
  }
}

Below we provide a description of each of the fields in this JSON object.

Key Value Example Description
backgroundColor #242400 The dark colour for styling a class, the inside of a node
color #FFFD04 The light colour for styling a class, the icon and node outline
size M The size of the node (S, M, L)
shape circle The shape of the node
faIcon fa-solid fa-ship The Font Awesome icon for the node
faUnicode \uf21a The Font Awesome unicode for the icon. This must be from the free set.
faClass fa-solid The Font Awesome icon type. This must be from the free set.
The above JSON values will style a node in Telicent Graph and Telicent Search like this:
Ship in CORE

We also provide the JSON schema for this structure below:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "defaultStyles": {
      "type": "object",
      "properties": {
        "dark": {
          "type": "object",
          "properties": {
            "backgroundColor": { "type": "string" },
            "color": { "type": "string" }
          },
          "required": ["backgroundColor", "color"]
        },
        "light": {
          "type": "object",
          "properties": {
            "backgroundColor": { "type": "string" },
            "color": { "type": "string" }
          },
          "required": ["backgroundColor", "color"]
        },
        "shape": { "type": "string" },
        "borderRadius": { "type": "string" },
        "borderWidth": { "type": "string" },
        "selectedBorderWidth": { "type": "string" }
      },
      "required": ["dark", "light", "shape", "borderRadius", "borderWidth", "selectedBorderWidth"]
    },
    "defaultIcons": {
      "type": "object",
      "properties": {
        "riIcon": { "type": "string" },
        "faIcon": { "type": "string" },
        "faUnicode": { "type": "string" },
        "faClass": { "type": "string" }
      },
      "required": ["riIcon", "faIcon", "faUnicode", "faClass"]
    }
  },
  "required": ["defaultStyles", "defaultIcons"]
}

Get your new ontology and styles into CORE

Once you have your ontology and ontology styles serialized as RDF, you can use an adapter to get both into CORE. There is a dedicated ontology topic for such.


[EARLY DRAFT RELEASE] Copyright 2020-2025 Telicent Limited. All rights reserved