Creating an Ontology

In this article, we will create a mini ontology in the banking domain. We will go through the design following some of the key concepts and also visualising it in some of the tools for the purpose.

Mini Banking Ontology (OWL)

The banking.owl file we are going to create is a mini‑ontology which will be written in OWL Functional Syntax. It will define the core concepts of a simple banking domain: customers, accounts, transactions, and the relationships between them. Before we create the file, let us look at how it is going to be structured. There is a brief explanation of every part of the ontology so that it is easy to understand how it works and how Protégé interprets it.

What the Ontology is about

It’s a small conceptual model of a banking system. It defines:

  • Classes (types of things)
  • Object properties (relationships between things)
  • Data properties (attributes with literal values)
  • Individuals (example instances)
  • Restrictions (domain/range rules)
  • Hierarchy (subclass relationships)

1. Ontology Header

This part sets the namespace and declares that this is an OWL ontology.

Ontology(<http://example.org/banking>

The prefix is a shorthand for a long URL (IRI). The prefixes help shorten the resource identifier. So, : is a shortcut for http://example.org/banking#. :BankAccount really means http://example.org/banking#BankAccount.

The other urls in the header give access to additional vocabulary – rdf: for basic RDF vocabulary, rdfs: for schema vocabulary etc.

2. Class declarations

These define the types of things in the banking domain.

Core classes

  • BankCustomer
  • BankAccount
  • Transaction

Subclasses

These refine the main classes:

  • CurrentAccount ⟶ BankAccount
  • SavingsAccount ⟶ BankAccount
  • Deposit ⟶ Transaction
  • Withdrawal ⟶ Transaction
  • Payment ⟶ Transaction

This creates a clean hierarchy.

3. Object properties (relationships between individuals)

These describe how entities relate:

  • hasAccount — customer → account
  • hasOwner — account → customer
  • hasSourceAccount — transaction → account
  • hasTargetAccount — transaction → account

These are essential for answering banking competency questions like:

  • “Which accounts belong to a customer?”
  • “Which account was the source of a payment?”

4. Data properties (literal attributes)

These attach literal values (numbers, dates) to individuals:

  • balance — decimal value on BankAccount
  • amount — decimal value on Transaction
  • transactionDate — dateTime value on Transaction

These allow queries like:

  • “What is the balance of Alice’s savings account?”
  • “What transactions occurred on 2025‑01‑15?”

5. Domain and range axioms

These tell Protégé where each property is allowed to be used. For example:

ObjectPropertyDomain(:hasAccount :BankCustomer)
ObjectPropertyRange(:hasAccount :BankAccount)

Means:

  • Only BankCustomers can have accounts
  • Only BankAccounts can be the target of hasAccount

These axioms help the reasoner detect modelling errors.

6. Class hierarchy

This defines inheritance:

SubClassOf(:CurrentAccount :BankAccount)
SubClassOf(:SavingsAccount :BankAccount)

Protégé will infer:

  • Every SavingsAccount is also a BankAccount
  • Every Deposit is also a Transaction

This is how OWL builds semantic structure.

7. Individuals (example data)

The ontology includes sample individuals to help you experiment: For example, Customer:

Alice rdf:type BankCustomer

8. banking.ttl (save this to the local folder)

Prefix(:=<http://example.org/banking#>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Ontology(<http://example.org/banking>
Declaration(Class(:BankCustomer))
Declaration(Class(:BankAccount))
Declaration(Class(:CurrentAccount))
Declaration(Class(:SavingsAccount))
Declaration(Class(:Transaction))
Declaration(Class(:Deposit))
Declaration(Class(:Withdrawal))
Declaration(Class(:Payment))
Declaration(ObjectProperty(:hasAccount))
Declaration(ObjectProperty(:hasOwner))
Declaration(ObjectProperty(:hasSourceAccount))
Declaration(ObjectProperty(:hasTargetAccount))
Declaration(DataProperty(:balance))
Declaration(DataProperty(:amount))
Declaration(DataProperty(:transactionDate))
############################
# Class hierarchy
############################
SubClassOf(:CurrentAccount :BankAccount)
SubClassOf(:SavingsAccount :BankAccount)
SubClassOf(:Deposit :Transaction)
SubClassOf(:Withdrawal :Transaction)
SubClassOf(:Payment :Transaction)
############################
# Domain / range
############################
ObjectPropertyDomain(:hasAccount :BankCustomer)
ObjectPropertyRange(:hasAccount :BankAccount)
ObjectPropertyDomain(:hasOwner :BankAccount)
ObjectPropertyRange(:hasOwner :BankCustomer)
ObjectPropertyDomain(:hasSourceAccount :Transaction)
ObjectPropertyRange(:hasSourceAccount :BankAccount)
ObjectPropertyDomain(:hasTargetAccount :Transaction)
ObjectPropertyRange(:hasTargetAccount :BankAccount)
DataPropertyDomain(:balance :BankAccount)
DataPropertyRange(:balance xsd:decimal)
DataPropertyDomain(:amount :Transaction)
DataPropertyRange(:amount xsd:decimal)
DataPropertyDomain(:transactionDate :Transaction)
DataPropertyRange(:transactionDate xsd:dateTime)
############################
# Example individuals
############################
Declaration(NamedIndividual(:Alice))
ClassAssertion(:BankCustomer :Alice)
Declaration(NamedIndividual(:AliceSavings))
ClassAssertion(:SavingsAccount :AliceSavings)
ObjectPropertyAssertion(:hasOwner :AliceSavings :Alice)
DataPropertyAssertion(:balance :AliceSavings "5000.00"^^xsd:decimal)
Declaration(NamedIndividual(:Deposit1))
ClassAssertion(:Deposit :Deposit1)
ObjectPropertyAssertion(:hasTargetAccount :Deposit1 :AliceSavings)
DataPropertyAssertion(:amount :Deposit1 "250.00"^^xsd:decimal)
DataPropertyAssertion(:transactionDate :Deposit1 "2025-01-15T10:30:00"^^xsd:dateTime)
)

Save the above as “banking.owl” in one of your local directories.

View and validate the Ontology

Step‑by‑step: loading this ontology into Protégé

1. Install Protégé

  • Download: Search for “Protégé ontology editor” and download the latest desktop version.
  • Install: Run the installer and open Protégé.

2. Create a new OWL ontology

  • Step 1: Open Protégé.
  • Step 2: Go to File → New…
  • Step 3: Choose OWL ontology (if asked).
  • Step 4: Click OK; you’ll get an empty ontology.

3. Switch to the “Entities” / “Classes” view

  • In the left panel, make sure you see:
    • Classes
    • Object properties
    • Data properties
    • Individuals

4. From the “Active Ontology” tab,

  • In panel below the second half,
  • Click the Direct Import (+) button. Refer to the Figure 1.
Figure 1: Importing banking.owl into protege.

Continue with the workflow until the file is imported. The ontology can be explored from the entities tab.

Exploring banking.owl ontology.

Selecting the “CurrentAccount” displays the details on the right pane.

Validating the Ontology

We have created the ontology and also imported it into Protege to visualise it and for further editing. Before we proceed further, we can do a validation of the structure for any contradictions in its definition.

In protege, go to “Reasoner” menu and click “Start Reasoner”. This will perform two things: It will validate the owl class for any syntax errors, logical inconsistencies, or direct contradictions.

The “Reasoner” does much more than mere validation, but we will discuss that in another article.

Comments

Leave a Reply

Check also

View Archive [ -> ]

Discover more from ANALYTI

Subscribe now to keep reading and get access to the full archive.

Continue reading