Protege 5 New OWLPizza Tutorial V3
Protege 5 New OWLPizza Tutorial V3
net/publication/351037551
A Practical Guide to Building OWL Ontologies Using Protégé 5.5 and Plugins
CITATIONS READS
0 16,338
1 author:
Michael Debellis
19 PUBLICATIONS 139 CITATIONS
SEE PROFILE
Some of the authors of this publication are also working on these related projects:
CODO: A COviD-19 Ontology for Collection and Analysis of Data View project
All content following this page was uploaded by Michael Debellis on 21 April 2021.
This is a revised version of the Protégé 4 Tutorial version 1.3 by Matthew Horridge. Previous versions of
the tutorial were developed by Holger Knublauch , Alan Rector , Robert Stevens, Chris Wroe, Simon
Jupp, Georgina Moulton, Nick Drummond, and Sebastian Brandt.
This work was conducted using the Protégé resource, which is supported by grant GM10331601 from the
National Institute of General Medical Sciences of the United States National Institutes of Health.
Chapters 3-5 are based on the original tutorial. I have updated the tutorial to be consistent with Protégé 5.
I have also made some changes to address some of the most common issues I’ve seen new users grapple
with, to remove some of the dated information about older frame-based versions of Protégé, and various
miscellaneous changes. Chapters 6-11 are new. I have added new sections for technologies such as
SWRL, SPARQL and SHACL as well as some details on concepts such as IRIs and namespaces.
Thanks to Matthew Horridge and everyone who worked on the previous tutorials. Special thanks to
Lorenz Buehmann who helped me work out a thorny problem as I developed the revised example, to
André Wolski for help with the SHACL plugin. Special thanks to Dick Ooms and Colin Pilkington for
their excellent detailed feedback on previous versions of the tutorial. Also, thanks to everyone on the
Protégé user support email list.
Note: this document may get updates frequently. It is a good idea to check my blog at:
https://www.michaeldebellis.com/post/new-protege-pizza-tutorial to make sure you have the latest
version.
If you have questions or comments feel free to contact me at [email protected]
1
Contents
Chapter 1 Introduction .................................................................................................................................. 4
1.1 Licensing ............................................................................................................................................. 4
1.2 Conventions ........................................................................................................................................ 4
Chapter 2 Requirements and the Protégé User Interface .............................................................................. 6
Chapter 3 What are OWL Ontologies? ......................................................................................................... 6
3.1 Components of OWL Ontologies ....................................................................................................... 6
3.1.1 Individuals........................................................................................................................................ 7
3.1.2 Properties ......................................................................................................................................... 8
3.1.3 Classes.............................................................................................................................................. 8
Chapter 4 Building an OWL Ontology ....................................................................................................... 10
4.1 Named Classes .................................................................................................................................. 13
4.2 Using a Reasoner .............................................................................................................................. 15
4.4 Using Create Class Hierarchy ........................................................................................................... 17
4.5 Create a PizzaTopping Hierarchy ..................................................................................................... 19
4.6 OWL Properties ................................................................................................................................ 22
4.7 Inverse Properties.............................................................................................................................. 23
4.8 OWL Object Property Characteristics .............................................................................................. 24
4.8.1 Functional Properties ................................................................................................................. 24
4.8.2 Inverse Functional Properties..................................................................................................... 25
4.8.3 Transitive Properties .................................................................................................................. 25
4.8.4 Symmetric and Asymmetric Properties ..................................................................................... 25
4.8.5 Reflexive and Irreflexive Properties .......................................................................................... 26
4.8.6 Reasoners Automatically Enforce Property Characteristics ...................................................... 26
4.9 OWL Property Domains and Ranges ................................................................................................ 26
4.10 Describing and Defining Classes .................................................................................................... 29
4.10.1 Property restrictions ................................................................................................................. 29
4.10.2 Existential Restrictions ............................................................................................................ 31
4.10.3 Creating Subclasses of Pizza.................................................................................................... 33
4.10.4 Detecting a Class that can’t Have Members ............................................................................ 37
4.11 Primitive and Defined Classes (Necessary and Sufficient Axioms) ............................................... 38
4.12 Universal Restrictions ..................................................................................................................... 41
4.13 Automated Classification and Open World Reasoning .................................................................. 42
2
4.14 Defining an Enumerated Class........................................................................................................ 44
4.15 Adding Spiciness as a Property ....................................................................................................... 45
4.16 Cardinality Restrictions .................................................................................................................. 46
Chapter 5 Datatype Properties .................................................................................................................... 48
5.1 Defining a Data Property .................................................................................................................. 48
5.2 Customizing the Protégé User Interface ........................................................................................... 50
Chapter 6 Adding Order to an Enumerated Class ....................................................................................... 58
Chapter 7 Names: IRI’s, Labels, and Namespaces ..................................................................................... 60
Chapter 8 A Larger Ontology with some Individuals ................................................................................. 62
8.1 Get Familiar with the Larger Ontology............................................................................................. 63
Chapter 9 Queries: Description Logic and SPARQL ................................................................................. 66
9.1 Description Logic Queries ................................................................................................................ 66
9.2 SPARQL Queries .............................................................................................................................. 67
9.21 Some SPARQL Pizza Queries ........................................................................................................ 67
9.22 SPARQL and IRI Names ................................................................................................................ 70
Chapter 10 SWRL and SQWRL ................................................................................................................. 72
Chapter 11 SHACL ..................................................................................................................................... 76
11.1 OWA and Monotonic Reasoning .................................................................................................... 76
11.2 The Real World is Messy ................................................................................................................ 76
11.3 Basic SHACL Concepts .................................................................................................................. 77
11.4 The Protégé SHACL Plug-In .......................................................................................................... 77
Chapter 12 Web Protégé ............................................................................................................................. 83
Chapter 13 Conclusion: Some Personal Thoughts and Opinions ............................................................... 88
Chapter 14 Bibliography ............................................................................................................................. 89
14.1 W3C Documents ............................................................................................................................. 89
14.2 Web Sites, Tools, And Presentations. ............................................................................................. 89
14.3 Papers .............................................................................................................................................. 89
14.4 Books .............................................................................................................................................. 90
14.5 Vendors ........................................................................................................................................... 90
3
Chapter 1 Introduction
This introduces Protégé 5 for creating OWL ontologies as well as various plugins. If you have questions
specific to this tutorial, please feel free to email me directly: [email protected] However, if you
have general questions about Protégé, OWL, or plugins you should subscribe to and send an email to the
User Support for Protégé and Web Protégé email list. This list has many people (including me) who
monitor it and can contribute their knowledge to help you understand how to get the most out of this
technology. To subscribe to the list, go to: https://protege.stanford.edu/support.php and click on the first
orange Subscribe button. That will enable you to subscribe to the list and give you the email to send
questions to.
This chapter covers licensing and describes conventions used in the tutorial. Chapter 2 covers the
requirements for the tutorial and describes the Protégé user interface. Chapter 3 gives a brief overview of
the OWL ontology language. Chapter 4 focuses on building an OWL ontology with classes and object
properties. Chapter 4 also describes using a Description Logic Reasoner to check the consistency of the
ontology and automatically compute the ontology class hierarchy.
Chapter 5 describes data properties. Chapter 6 describes design patterns and shows one design pattern:
adding an order to an enumerated class. Chapter 7 describes the various concepts related to the name of
an OWL entity.
Chapter 8 introduces an extended version of the Pizza tutorial developed in chapters 1-7. This ontology
has a small number of instances and property values already created which can be used to illustrate the
tools in the later chapters for writing rules, doing queries, and defining constraints.
Chapter 9 describes two tools for doing queries: Description Logic queries and SPARQL queries. Chapter
10 introduces the Semantic Web Rule Language (SWRL) and walks you through creating SWRL and
SQWRL rules. Chapter 11 introduces the Shapes Constraint Language (SHACL) and discusses the
difference between defining logical axioms in Description Logic and data integrity constraints in
SHACL. Chapter 12 has some concluding thoughts and opinions and Chapter 13 provides a bibliography.
1.1 Licensing
This document is freely available under the Creative Commons Attribution-ShareAlike 4.0 International
Public License. I typically distribute it as a PDF but if you want to make your own version send me an
email and I will send you the Word version. For details on licensing see:
https://creativecommons.org/licenses/by-sa/4.0/legalcode
1.2 Conventions
Class, property, rule, and individual names are written in Consolas font like this. The term used for
any such construct in Protégé and in this document is an Entity. Individuals and classes can also be
referred to as objects.
Names for user interface tabs, views, menu selections, buttons, and text entry are highlighted like this.
Any time you see highlighted text such as File>Preferences or OK or PizzaTopping it refers to something
that you should or optionally could view or enter into the user interface. If you ever aren’t sure what to
do to accomplish some task look for the highlighted text. Often, as with PizzaTopping the text you
enter into a field in the Protégé UI will be the name of a class, property, etc. In those cases, where the
4
name is meant to be entered into a field it will only be highlighted rather than highlighted and printed in
Consolas font.
Menu options are shown with the name of the top-level menu, followed by a > followed by the next level
down to the desired selection. For example, to indicate how to open the Individuals by class tab under the
Tabs section in the Window menu the following text would be used: Window>Tabs> Individuals by
class.
When a word or phrase is emphasized, it is shown in italics like this.
Exercises are presented like this:
Exercise 1: Accomplish this
_____________________________________________________________________________________
1. Do this.
2. Then do this.
3. Then do this.
_____________________________________________________________________________________
Tips and suggestions related to using Protégé are presented like this.
5
Chapter 2 Requirements and the Protégé User Interface
In order to follow this tutorial, you must have Protégé 5, which is available from the Protégé website,1
and some of the Protégé Plugins which will be described in more detail below. For now, just make sure
you have the latest version of Protégé. At the time this is being written the latest version is 5.5 although
the tutorial should work for later versions as well.
The Protégé user interface is divided up into a set of major tabs. These tabs can be seen in the
Window>Tabs option. This option shows all the UI tabs that are currently loaded into the Protégé
environment. Any tabs that are currently opened have a check mark next to them. To see a tab that is not
visible just select it from the menu and it will be added to the top with the other major tabs and its menu
item will now be checked. You can add additional major tabs to your environment by loading plugins. For
example, when we load the SHACL4Protégé plugin the SHACLEditor will be added to the menu.
Each major tab consists of various panes or as Protégé calls them views. Each view can be resized or
closed using the icons in the top right corner of every view. The views can also be nested as sub-tabs
within each major tab. When there could potentially be confusion between a tab that is a screen all its own
(is under the Window>Tabs option) and a view that is a sub-tab we will call the screen tab a major tab.
There are many views that are not in the default version of Protégé that can be added via the
Window>Views option. The additional views are divided into various categories such as
Window>Views>Individual views. Section 5.2 will show an example of adding a new view to a major
tab.
Ontologies are used to capture knowledge about some domain of interest. An ontology describes the
concepts in the domain and also the relationships that hold between those concepts. Different ontology
languages provide different facilities. The most recent development in standard ontology languages is
OWL from the World Wide Web Consortium (W3C). A good primer on the basic concepts of OWL can
be found at: https://www.w3.org/TR/owl2-primer/
OWL makes it possible to describe concepts in an unambiguous manner based on set theory and logic.
Complex concepts can be built up out of simpler concepts. The logical model allows the use of a reasoner
which can check whether all of the statements and definitions in the ontology are mutually consistent and
can also recognize which concepts fit under which definitions. The reasoner can therefore help to
maintain the hierarchy correctly. This is particularly useful when dealing with cases where classes can
have more than one parent. The reasoner can also infer additional information. For example, if two
properties are inverses only one value needs to be asserted by the user and the inverse value will be
automatically inferred by the reasoner.
1
http://protege.stanford.edu
6
relations, transitive relations, and many more. An understanding of the basic concepts of set theory will
help the user get the most out of OWL but is not required. One of the benefits of Protégé is that it presents
an intuitive GUI that enables domain experts to define models without a background in set theory.
However, developers are encouraged to refresh their knowledge on logic and set theory. A good source is
the first 3 chapters in Elements of the Theory of Computation by Lewis and Papadamitrious. Another
good source is the PDF document Overview of Set Theory available at:
https://www.michaeldebellis.com/post/owl-theoretical-basics
3.1.1 Individuals
Individuals represent objects in the domain of interest. An important difference between OWL and most
programming and knowledge representation languages is that OWL does not use the Unique Name
Assumption (UNA). This means that two different names could actually refer to the same individual. For
example, “Queen Elizabeth”, “The Queen” and “Elizabeth Windsor” might all refer to the same
individual. In OWL, it must be explicitly stated that individuals are the same as each other, or different
from each other. Figure 3.1 shows a representation of some individuals in a domain of people, nations,
and relations — in this tutorial we represent individuals as diamonds.
Michael Tim
India
Jenna
livesIn
India
Biswanath
hasFriend Michael
Individuals are also known as instances. Individuals can be referred to as instances of classes.
7
3.1.2 Properties
Properties are binary relations between individuals. I.e., properties link two individuals together. For
example, the property hasFriend might link the individual Biswanath to the individual Michael, or
the property hasChild might link the individual Michael to the individual Oriana. Properties can have
inverses. For example, the inverse of hasChild is hasParent. Properties can be limited to having a
single value – i.e., to being functional. They can also be transitive or symmetric. These property
characteristics are explained in detail in Section 4.8. Figure 3.2 shows a representation of some properties.
Properties are similar to properties in Object-Oriented Programming (OOP). However, there are
important differences between properties in OWL and OOP. The most important difference is that OWL
properties are first class entities that exist independent of classes. OOP developers are encouraged to
read: https://www.w3.org/2001/sw/BestPractices/SE/ODSD/
Oriana
Italy
hasChild India
livesIn
USA
Michael
Person Country
Rover
hasPet
Dog
Buddy
3.1.3 Classes
OWL classes are sets that contain individuals. They are described using formal (mathematical)
descriptions that rigorously define the requirements for membership of the class. For example, the class
Cat would contain all the individuals that are cats in our domain of interest.2 Classes may be organized
into a superclass-subclass hierarchy, which is also known as a taxonomy. However, taxonomies are often
trees. I.e., each node has only one parent node. Class hierarchies in OWL are not restricted to be trees and
multiple inheritance can be a powerful tool to represent data in an intuitive manner.
Subclasses specialize (aka are subsumed by) their superclasses. For example, consider the classes Animal
and Dog – Dog might be a subclass of Animal (so Animal is the superclass of Dog). This says that All
dogs are animals, All members of the class Dog are members of the class Animal. OWL and Protégé
2
Individuals can belong to more than one class and classes can have more than one superclass. Unlike OOP where
multiple inheritance is typically unavailable or discouraged it is common in OWL.
8
provide a language that is called Description Logic or DL for short. One of the key features of DL is that
these superclass-subclass relationships (aka subsumption relationships) can be computed automatically by
a reasoner – more on this later. Figure 3.3 shows a representation of some classes containing individuals –
classes are represented as ovals, like sets in Venn diagrams.
In OWL classes can be built up of descriptions that specify the conditions that must be satisfied by an
individual for it to be a member of the class. How to formulate these descriptions will be explained as the
tutorial progresses.
9
Chapter 4 Building an OWL Ontology
This chapter describes how to create an ontology of Pizzas. We use Pizzas because it is something almost
everyone is familiar with.
Exercise 1: Create a new OWL Ontology
_____________________________________________________________________________________
1. Start Protégé. When Protégé opens for the first time each day it puts up a screen of all the available
plugins. You can also bring this up at any time by using File>Check for plugins. You won’t need any
plugins at this point of the tutorial so just click the Not now button.
2. The Protégé user-interface consists of several tabs such as Active ontology, Entities, etc. When you
start Protégé you should be in the Active Ontology tab. This is for overview information about the entire
ontology. Protégé always opens with a new untitled ontology you can start with. Your ontology should
have an IRI something like: http://www.semanticweb.org/yourname/ontologies/2020/4/untitled-ontology-
27 Edit the name of the ontology (the part after the last “/” in this case untitled-ontology-27) and change it
to something like PizzaTutorial. Note: the Pizza ontology IRIs shown below (e.g., figure 4.3) show the
IRI after I edited the default that Protégé generated for me. Your IRI will look different and will be based
on your name or the name of your organization.
3. Now you want to save your new ontology. Select File>Save. This should bring up a window that says:
Choose a format to use when saving the ‘PizzaTutorial’ ontology. There is a drop down menu of formats
to use. The default RDF/XML Syntax should be selected by clicking the OK button. This should bring up
the standard dialog your operating system uses for saving files. Navigate to the folder you want to use and
then type in the file name, something like Pizza Tutorial and select Save.
____________________________________________________________________________________
As with any file you work on it is a good idea to save your work at regular intervals so that if
something goes wrong you don’t lose your work. At certain points in the tutorial where saving
is especially important the tutorial will prompt you to do so but it is a good idea to save your
work often, not just when prompted.
The next step is to set some preferences related to the names of new entities. Remember than in Protégé
any class, individual, object property, data property, annotation property, or rule is referred to as an entity.
The term name in OWL can actually refer to two different concepts. It can be the last part of the IRI3 or it
can refer to the annotation property (usually rdfs:label) used to provide a more user friendly name for
the entity. We will discuss this in more detail below in chapter 7. For now, we just want to set the
parameters correctly so that future parts of the tutorial (especially the section on SPARQL queries) will
work appropriately.
3
An IRI is similar to a URL. This will be discussed in detail below in chapter 7.
10
Exercise 2: Set the Preferences for New Entities and Rendering
_____________________________________________________________________________________
1. Go to File>Preferences in Protégé. This will bring up a new window with lots and lots of different tabs.
Click on the New entities tab. This will bring up a tab that looks similar to figure 4.1. The top part of that
tab is a box labeled Entity IRI. It should be set with the parameters as shown in figure 4.1. I.e., Starts
with Active ontology IRI. Followed by #. Ends with User supplied name. If the last parameter is set to
Auto-generated name change it to User supplied name. That is the parameter most likely to be different
but also check the other two as well.
2. Now select the Renderer tab. It should look like figure 4.2. Most importantly, check that Entity
rendering is set to Render by entity IRI short name (ID) rather than Render by annotation property. Don’t
worry if this doesn’t completely make sense at this point. The issues here are a bit complex and subtle so
we defer them until after you have an understanding of the basic concepts of what an OWL ontology is.
We will have a discussion of these details below in chapter 7. For now you just need to make sure that the
preferences are set appropriately to work with the rest of the tutorial.
____________________________________________________________________________________
11
Figure 4.2 Renderer tab
12
Exercise 3: Add a Comment Annotation to Your Ontology
_____________________________________________________________________________________
1. Make sure you are in the Active Ontology tab. In the view just below the Ontology IRI and Ontology
Version IRI fields find the Annotations option and click on the + sign. This will bring up a menu to create
a new annotation on the ontology.
2. The rdfs:comment annotation should be highlighted by default. If it isn’t highlighted click on it. Then
type a new comment into the view to the right. Something like A tutorial ontology for the Pizza domain.
3. Click OK. Your Active Ontology tab should like Figure 4.3.
_____________________________________________________________________________________
Add Subclass
Delete Class
4
Each of the sub-tabs in the Entities tab also exists as its own major tab. In the tutorial we will refer to tabs like the
Class hierarchy tab or Object properties tab and it is up to the user whether to access them from the Entities tab or
to create them as independent tabs.
13
Exercise 4: Create classes: Pizza, PizzaTopping, and PizzaBase
_____________________________________________________________________________________
1. Navigate to the Entities tab5 with the Class hierarchy view selected. Make sure owl:Thing is selected.
2. Press the Add Subclass icon shown in figure 4.4. This button creates a new subclass of the selected
class. In this case we want to create a subclass of owl:Thing.
3. This should bring up a dialog titled Create a new class with a field for the name of the new class. Type
in Pizza and then select OK.
4. Repeat the previous steps to add the classes PizzaTopping and PizzaBase ensuring that
owl:Thing is selected before using the add subclass icon so that all your classes are subclasses of
owl:Thing. Your user interface should now look like figure 4.5. Don’t worry that some of the classes
are highlighted in red. That is because the reasoner hasn’t run yet. We will address this shortly.
_____________________________________________________________________________________
5
The Entities tab is a big tab that has tabs like Classes, Object properties, Data properties, etc. as sub-tabs. Each of
these sub-tabs is also a major tab (a tab accessible from the Window>Tabs option) that can be created on its own.
Since I took screen snapshots at various times I wasn’t always completely consistent. Sometimes I used Classes as a
sub-tab of the Entities tab and sometimes as a major tab on its own. Also, at different points in time I had other
tabs open depending on what other work I was doing. Thus, your UI won’t look identical to the figures. There may
be additional tabs in the figure that aren’t in your UI or vice versa.
14
There are no mandatory naming conventions for OWL entities. In chapter 7, we will discuss
names and labels in more detail. A best practice is to select one set of naming conventions and
then abide by that convention across your organization. For this tutorial we will follow the
standard where class and individual names start with a capital letter for each word and do not
contain spaces. This is known as CamelBack notation. For example: Pizza, PizzaTopping,
etc. Also, we will follow the standard that class names are always singular rather than plural.
E.g., Pizza rather than Pizzas, PizzaTopping rather than PizzaToppings.
15
5. One last thing we want to do is to configure the reasoner. By default, the reasoner does not perform all
possible inferences because some inferences can take a long time for large and complex ontologies. In
this tutorial we will always be dealing with small and simple ontologies so we want to see everything the
reasoner can do. Go to: Reasoner>Configure. This will bring up a dialog with several check boxes of
inferences that the reasoner can perform. If they aren’t all checked then check them all. You may receive
a warning that some inferences can take a lot of time, but you can ignore those since your ontology will
be small.
_____________________________________________________________________________________
16
Figure 4.6: The Disjoint Option in the Class Description View
OWL classes are assumed to overlap, i.e., by default they are not disjoint. This is often useful
because in OWL, unlike in most object-oriented models, multiple inheritance is not discouraged
and can be a powerful tool to model data. If we want classes to be disjoint, we must explicitly
declare them to be so. It is often a good development strategy to start with classes that are not
disjoint and then make them disjoint once the model is more fully fleshed out as it is not always
obvious which classes are disjoint from the beginning.
17
Figure 4.7: The Create class hierarchy wizard
Exercise 7: Use the Create class hierarchy tool to create subclasses of PizzaBase
_____________________________________________________________________________________
1. Select the class PizzaBase in the class hierarchy.
2. With PizzaBase selected use the Tools>Create class hierarchy menu option.
3. This should bring up a wizard that enables you to create a nested group of classes all at once. You
should see a window labeled Enter hierarchy where you can enter one name on each line. You can also
use the tab key to indicate that a class is a subclass of the class above it. For now we just want to enter
two subclasses of PizzaBase: ThinAndCrispyBase and DeepPanBase. One of the things the wizard
does is to automatically add a prefix or suffix for us. So just enter ThinAndCrispy, hit return and enter
DeepPan. Then in the Suffix field add Base. Your window should look like figure 4.7.
4. Select Continue. This will take you to a window that asks if you want to make sibling classes disjoint.
The default should be checked (make them disjoint) which is what we want in this case (a base can’t be
both deep pan and thin) so just select Finish. Synchronize the reasoner. Your class hierarchy should now
look like figure 4.8.
_____________________________________________________________________________________
18
Figure 4.8: The New Class Hierarchy
19
Figure 4.9 Using Create class hieararchy to create PizzaTopping subclasses
20
Figure 4.10 The New PizzaTopping Class Hierarchy
So far, we have created some simple named classes and subclasses which hopefully seem
intuitive and obvious. However, what does it actually mean to be a subclass of something in
OWL? For example, what does it mean for VegetableTopping to be a subclass of
PizzaTopping? In OWL subclass means necessary implication. I.e., if VegetableTopping is a
subclass of PizzaTopping then all instances of VegetableTopping are also instances of
PizzaTopping. It is for this reason that we try to have standards such as having all
PizzaTopping classes end with the word “Topping”. Otherwise, it might seem we are saying
that anything that is a kind of Ham like the Ham in your sandwich is a kind of MeatTopping or
PizzaTopping which is not what we mean. For large ontologies strict attention to the naming
of classes and other entities can prevent potential confusion and bugs.
21
4.6 OWL Properties
OWL Properties represent relationships. There are three types of properties, Object properties, Data
properties and Annotation properties. Object properties are relationships between two individuals. Data
properties are relations between an individual and a datatype such as xsd:string or xsd:dateTime.
Annotation properties also usually have datatypes as values although they can have objects. An
annotation property is usually meta-data such as a comment or a label. In OWL only individuals can have
values for object and data properties, but any entity can have an annotation property value since meta-data
applies to all entities. Annotation properties usually can’t be reasoned about. For example, SWRL rules
which we will cover later cannot view or change the value of annotation properties. In this chapter we
will focus on Object properties. Data properties are described in Chapter 5. In the current version of the
tutorial we are only discussing the annotation property rdfs:label (see chapter 7) however they are
fairly intuitive.
Properties may be created using the Object Properties sub-tab of the Entities tab shown in figure 4.11.
Just as all OWL classes ultimately are a subclass of owl:Thing, all properties are ultimately a sub-
property of owl:topObjectProperty. A sub-property is similar to a subclass except it is about the
tuples in a property. For example, hasFather would be a sub-property of hasParent because all the
tuples in hasFather are in hasParent but not vice versa. E.g., if Sasha hasFather Barack then she
also hasParent Barack. However, she also hasParent Michelle but it is not the case that she
hasFather Michelle. Rather she hasMother Michelle, i.e., hasMother is also a sub-property of
hasParent.
The GUI for entering properties is also similar to that for entering classes. The first icon with one box
under another creates a sub-property of the selected property. The second icon showing two boxes at the
same level creates a sibling property to the selected property and the icon with an X through a box deletes
the selected property.
Exercise 9: Create some properties
_____________________________________________________________________________________
1. Select the Object properties sub-tab of the Entities tab (see figure 4.11).
2. Make sure owl:topObjectProperty is selected. Click on the nested box icon at the left to create a
new sub-property of owl:topObjectProperty. When prompted for the name of the new property
type in hasIngredient.
3. Just as you can use a wizard to create multiple classes you can also use one to create multiple
properties. Select hasIngredient and then select Tools>Create object property hierarchy. Enter the new
property names hasTopping and hasBase. Select Continue and accept the default that the object properties
are not disjoint.
4. Synchronize the reasoner. Your window should now look like figure 4.11.
_____________________________________________________________________________________
For those familiar with the Entity-Relationship model, OWL object properties are similar to
relations and data properties are similar to attributes. Object properties are similar to
properties with a range of some class in OOP and data properties are similar to OOP properties
with a range that is a datatype.
22
Figure 4.11 Adding Some Object Properties
2. Click on the Add icon (+) next to Inverse Of in the Description view for hasIngredient. You will
be presented with a window that shows a nested view of all the current properties. Select hasIngredient to
make it the inverse of isIngredientOf.
23
3. Select isIngredientOf and then Tools>Create object property hierarchy. Enter isToppingOf then on a
new line enter isBaseOf. As before, select Continue and leave the box for disjoint properties unchecked
and select Finish. Repeat step 2 to make isToppingOf the inverse of hasTopping and isBaseOf the
inverse of hasBase.
4. Synchronize the reasoner. Your window should now look like figure 4.12.
_____________________________________________________________________________________
24
unlike many languages it does not have a unique names assumption. Unless specifically stated otherwise,
the reasoner can infer that two individuals with different names are actually the same individual. It should
be noted however, that if Peggy and Margaret were explicitly stated to be two different individuals then
the above statements would lead the reasoner to infer that there was an inconsistency in the ontology. We
will discuss names more in chapter 7.
In section 4.16 we will discuss cardinality restrictions on properties. E.g., that the hasWheel property of
the Bicycle class has a minimum of 2 (allowing for training wheels) whereas hasWheel for the
Unicycle class is defined to be exactly 1. A functional property is equivalent to a property with a
cardinality restriction that says it has a maximum of 1 value. The term functional is from mathematics
where a function is defined as a relation where each member of the domain has at most one value. For
example, the greaterThan relation is not functional since for any number X many (in fact an infinite
number) can be greaterThan X but the plusOne relation is functional since for any number X
plusOne always results in one unique value.
25
symmetric properties. If Michelle hasSpouse Barack, then Barack hasSpouse Michelle. A
symmetric property is its own inverse.
An Asymmetric property is a property that can never have symmetric values. If a property P is
asymmetric then if a is related to b via that property b cannot be related to a via that property. An example
of an asymmetric property is hasBirthMother. If Diya hasBirthMother Fatima, then it can’t be the
case that Fatima hasBirthMother Diya.
26
Exercise 11: Define the domain and range of the hasTopping property
_____________________________________________________________________________________
1. Navigate to the Object properties tab. Select the hasTopping property.
2. Click on the Add icon (+) next to Domains (intersection) in the Description view for hasTopping.
You will be presented with a window that shows several tabs. There are multiple ways to define domain
and range. For now we will use the simplest method (and the one most often used). Select the
ClassHierarchy tab. Then select Pizza from the class hierarchy. Your UI should look like figure 4.14.
Click on OK. You should now see Pizza underneath the Domains in the Description view.
3. Repeat step 2 but this time start by using the (+) icon next to the Ranges (intersection) in the
Description for hasTopping. This time select the class PizzaTopping as the range.
4. Synchronize the reasoner. Now select isToppingOf. You should see that the Domain and Range for
isToppingOf have been filled in by the reasoner (see figure 4.15). Since the two properties are inverses
the reasoner knows that the domain for one is the range for the other and vice versa. This is another
example of why frequently running the reasoner can save time and help maintain a valid model. Note that
these values are highlighted in yellow. Any information supplied by the reasoner rather than by the user is
highlighted in this way.
_____________________________________________________________________________________
27
Figure 4.15 Domain and Range inferred by the reasoner
It is possible to specify more than one class as the domain or range of a property. One of the
most common mistakes of new users is to do this and expect that the resulting domain/range is
the union of the two classes. However, note that next to the Domain and Range in the
Description view it says (intersection). This is because the semantics of having 2 or more classes
as the domain or range is the intersection of those classes not the union. E.g., if one defined the
domain for a property to be Pizza and then added another domain IceCream that would
mean that for something to be in the domain of that property it would have to be an instance of
both Pizza and IceCream not (as people often expect) the union of those two sets which
would be either the class Pizza or the class IceCream. Also, note that the domain and range
are for inferencing, they are not data integrity constraints. This distinction will be explained in
more detail below in the section on SHACL.
28
Exercise 12: Define the domain and range for the hasBase property
_____________________________________________________________________________________
1. Now we are going to repeat the same activities as in the previous exercise but for another property:
hasBase. Make sure you are still on the Object properties tab. Select the hasBase property.
2. Click on the Add icon (+) next to Domains (intersection) in the Description view for hasBase. Select
the ClassHierarchy tab. Then select Pizza from the class hierarchy..
3. Repeat step 2 but this time start by using the (+) icon next to the Ranges (intersection) in the
Description for hasBase. This time select the class PizzaBase as the range.
4. Synchronize the reasoner. Now select isBaseOf You should see that the Domain and Range for
isBaseOf have been filled in by the reasoner.
_____________________________________________________________________________________
29
The following are some examples of classes of individuals that we might want to define via property
restrictions:
• Existential restrictions describe classes of individuals that participate in at least one relation along
a specified property. For example, the class of individuals who have at least one (or some)
hasTopping relation to instances of VegetableTopping. In OWL the keyword some is used
to denote existential restrictions.
• Universal restrictions describe classes of individuals that for a given property only have relations
along a property to individuals that are members of a specific class. For example, the class of
individuals that only have hasTopping relations to instances of the class VegetableTopping.
In OWL they keyword only is used for universal restrictions.
Let’s take a closer look at an example of an existential restriction. The restriction hasTopping some
MozzarellaTopping is an existential restriction (as indicated by the some keyword), which restricts the
hasTopping property, and has a filler MozzarellaTopping. This restriction describes the class of
individuals that have at least one hasTopping relationship to an individual that is a member of the class
MozzarellaTopping.
A restriction always describes a class. Sometimes (as we will soon see) it can be a defined class.
Other times it may be an anonymous class. In all cases the class contains all of the individuals
that satisfy the restriction, i.e., all of the individuals that have the relationships required to be a
member of the class. In section 9.2 one of our SPARQL queries will return several anonymous
classes.
6
These have the same meaning as existential and universal quantification in First Order Logic.
30
The restrictions for a class are displayed and edited using the Class Description View shown in Figure
4.17. The Class Description View holds most of the information used to describe a class. The Class
Description View is a powerful way of describing and defining classes. It is one of the most important
differences between describing classes in OWL and in other models such as most object-oriented
programming languages. In other models there is no formal definition that describes why one class is a
subclass of another, in OWL there is. Indeed, the OWL classifier can actually redefine the class hierarchy
based on the logical restrictions defined by the user. We will see an example of this later in the tutorial.
Restrictions are also called axioms in OWL. This has the same meaning as in logic. An axiom is a
logical formula defined by the user rather than deduced by the reasoner. As described above,
in Protégé all axioms are shown in normal font whereas all inferences inferred by the reasoner
are highlighted in yellow.
Exercise 13: Add a restriction to Pizza that specifies a Pizza must have a PizzaBase
_____________________________________________________________________________________
1. Select Pizza from the class hierarchy on the Classes tab.
2. Click on the Add icon (+) next to the SubClass Of field in the Description view for Pizza.
3. This will bring up a new window with several tab options to define a new restriction. Select the Object
restriction creator. This tab has the Restricted property on the left and the Restriction filler on the right.
4. Expand the property hierarchy on the left and select hasBase as the property to restrict. Then in the
Restriction filler on the right select the class PizzaBase. Finally, the Restriction type at the bottom should
be set to Some (existential). This should be the default so you shouldn’t have to change anything but
double check that this is the case. Your window should look like figure 4.16 now.
5. When your UI looks like figure 4.16 click on the OK button. That should close the window. Run the
reasoner to make sure things are consistent. Your main window should now look like figure 4.17.
_____________________________________________________________________________________
31
Figure 4.16 The Object Restriction Creator Tab
32
We have described the class Pizza to be to be a subclass of Thing and a subclass of the things that have
a base which is some kind of PizzaBase. Notice that these are necessary conditions — if something is a
Pizza it is necessary for it to be a member of the class Thing (in OWL, everything is a member of the
class Thing) and necessary for it to have a kind of PizzaBase. More formally, for something to be a
Pizza it is necessary for it to be in a relationship with an individual that is a member of the class
PizzaBase via the property hasBase.
33
<control><space>. If there is only one possible completion for the string then Protégé will fill in the
appropriate name. If there are multiple possible completions Protégé will create a menu with all the
possible completions and allow you to select the one you want.
5. Click on OK to enter the new restriction.
6. Repeat steps 1-5 only this time add the restriction hasTopping some TomatoTopping. Remember to use
<control><space> to save time typing. Synchronize the reasoner to make sure things are consistent. Your
UI should now look similar to figure 4.18.
_____________________________________________________________________________________
34
Note in figure 4.18 the two classes listed under Disjoint With and highlighted in yellow. This is an
example of an inference from the reasoner. When we defined Pizza, PizzaBase, and PizzaTopping
we made those 3 classes disjoint. I.e., no individual can be a member of more than one of those classes.
Since MargheritaPizza is a subclass of Pizza it is also disjoint with PizzaBase and
PizzaTopping, so the reasoner has added this information to the definition of MargheritaPizza and
as with all inferences from the reasoner highlighted the new information in yellow.
We will now create the class to represent an AmericanaPizza, which has toppings of pepperoni,
mozzarella and tomato. Because the class AmericanaPizza is similar to the class MargheritaPizza
(i.e., an AmericanaPizza is almost the same as a MargheritaPizza but with an extra topping of
pepperoni) we will make a clone of the MargheritaPizza class and then add an extra restriction to say
that it has a topping of pepperoni.
Exercise 16: Create AmericanaPizza by Cloning MargheritaPizza and Adding Additional
Restrictions
_____________________________________________________________________________________
1. Select MargheritaPizza from the class hierarchy on the Classes tab.
2. Select Edit>Duplicate selected class. This will bring up a dialogue for you to duplicate the class. The
default is the name of the existing class so there will be a red error message when you start because you
need to enter a new name. Change the name from MargheritaPizza to AmericanaPizza. Leave all the other
options as they are and then select OK.
3. Make sure that AmericanaPizza is still selected. Click on the Add icon (+) next to the SubClass Of field
in the Description view for AmericanaPizza.
4. Use either the Object restriction creator tab or the Class expression editor tab to add the additional
restriction: hasTopping some PepperoniTopping.
5. Click on OK to enter the new restriction.
6. Edit the comment annotation on AmericanaPizza. It should currently be: A pizza that only has
Mozzarella and Tomato toppings since it was copied over from MargheritaPizza. Note that at the top
right of the comment there are three little icons, an @ sign, an X and an O. Click on the O. This icon is
the one you use to edit any existing data in Protégé. This should bring up a window where you can edit
the comment. Change it to something appropriate such as: A pizza that only has Mozzarella, Tomato, and
Pepperoni toppings. Then click on OK to enter the edit to the comment.
_____________________________________________________________________________________
35
2. A SohoPizza is almost the same as a MargheritaPizza but has additional toppings of olives and
parmesan cheese — create this by cloning MargheritaPizza and adding two existential restrictions along
the property hasTopping, one with a filler of OliveTopping, and one with a filler of ParmesanTopping.
_____________________________________________________________________________________
Exercise 18: Make Subclasses of NamedPizza Disjoint
_____________________________________________________________________________________
1. We want to make these subclasses of NamedPizza disjoint from each other. I.e., any individual can
belong to at most one of these classes. To do that first select MargheritaPizza (or any other subclass of
NamedPizza).
2. Click on the (+) sign next to Disjoint With near the bottom of the Description view. This will bring up
a Class hierarchy view. Use this to navigate to the subclasses of NamedPizza and use <control><left
click> to select all of the other sibling classes to the one you selected. Then select OK. You should now
see the appropriate disjoint axioms showing up on each subclass of NamedPizza. Synchronize the
reasoner. Your UI should look similar to figure 4.19 now.
36
4.10.4 Detecting a Class that can’t Have Members
Next, we are going to use the reasoner to detect a class with a definition that means it can never have any
members. In the current version of Protégé when the reasoner detects an inconsistency or problem on
some operating systems the UI can occasionally lock up and be hard to use. So to make sure you don’t
lose any of your work save your ontology using File>Save.
Sometimes it can be useful to create a class that we think should be impossible to instantiate to make sure
the ontology is modeled as we think it is. Such a class is called a Probe Class.
Exercise 19: Add a Probe Class called ProbeInconsistentTopping
_____________________________________________________________________________________
1. Select the class CheeseTopping from the class hierarchy.
2. Create a subclass of CheeseTopping called ProbeInconsistentTopping.
3. Click on the Add icon (+) next to the SubClass Of field in the Description view for
ProbeInconsistentTopping.
4. Select the Class hierarchy tab from the dialogue that pops up. This will bring up a small view that
looks like the class hierarchy tab you have been using to add new classes. Use this to navigate to and
select the class VegetableTopping. Click on OK.
5. Make sure to save your current ontology file. Now run the reasoner. You should see that
ProbeInconsistentTopping is now highlighted in red indicating it is inconsistent.
6. Click on ProbeInconsistentTopping to see why it is highlighted in red. Notice that at the top of the
Description view you should now see owl:Nothing under the Equivalent To field. This means that the
probe class is equivalent to owl:Nothing. The owl:Nothing class is the opposite of owl:Thing.
Whereas all individuals are instances of owl:Thing, no individual can ever be an instance of
owl:Nothing. The owl:Nothing class is equivalent to the empty set in set theory.
7. There should be a ? icon just to the right of owl:Nothing. As with any inference of the reasoner it is
possible to click on the new information and generate an explanation for it. Do that now, click on the ?
icon. This should generate a new window that looks like figure 4.20. The explanation is that
ProbeInconsistentTopping is a subclass of CheeseTopping and VegetableTopping but those
two classes are disjoint.
8. Click OK to dismiss the window. Delete the class ProbeInconsistentTopping by selecting it and then
clicking on the delete class icon at the top of the classes view (see figure 4.4).
9. Synchronize the reasoner.
_____________________________________________________________________________________
37
Figure 4.20 Explanation for why ProbeInconsistentTopping is equivalent to owl:Nothing
38
Note that if you just type a few characters, the number of possible completions may be large
resulting in an unwieldy menu. Also, Protégé doesn’t do things like type checking on possible
completions. For example, if you type “Chee” and do <control><space> you will be prompted
with CheeseTopping and CheesyPizza as possible completions even though a Pizza is not
in the range of hasTopping. This is where the reasoner can also help. If you enter a class that
is not in the range of hasTopping the reasoner will signal an inconsistency.
39
Figure 4.21 CheesyPizza as a Defined Class
40
4.12 Universal Restrictions
All of the restrictions we have created so far have been existential restrictions (defined using the some
DL keyword). Existential restrictions specify the existence of at least one relationship along a given
property to an individual that is a member of a specific class (specified by the filler). However, existential
restrictions do not mandate that the only relationships for the given property that can exist must be to
individuals that are members of the specified filler class.
For example, we could use an existential restriction hasTopping some MozzarellaTopping to
describe the individuals that have at least one relationship along the property hasTopping to an
individual that is a member of the class MozzarellaTopping. This restriction does not imply that all of
the hasTopping relationships must be to a member of the class MozzarellaTopping. To restrict the
relationships for a given property to individuals that are members of a specific class we must use a
universal restriction. Universal restrictions correspond to the symbol ∀ in First Order Logic. They
constrain the relationships along a given property to individuals that are members of a specific class. For
example, the universal restriction ∀ hasTopping VegetableTopping describes the individuals all of
whose hasTopping relationships are to members of the class VegetableTopping — the individuals do
not have a hasTopping relationship to individuals that aren’t members of the class
VegetableTopping.
Suppose we want to create a class called VegetarianPizza. Individuals that are members of this class
can only have toppings that are a CheeseTopping or VegetableTopping. To do this we can use a
universal restriction:
Exercise 22: Create a Defined Class called VegetarianPizza
_____________________________________________________________________________________
1. Select the Pizza in the Classes tab. Create a subclass of Pizza and name it VegetarianPizza.
2. Make sure VegetarianPizza is selected. Click on the Add icon (+) next to the SubClass Of field in the
Description view.
3. Select the Class expression editor tab from the pop-up window. Type in the Description Logic axiom:
hasTopping only (VegetableTopping or CheeseTopping). Click on OK.
4. Make sure VegetarianPizza is still selected. Run the Edit>Convert to defined class command.
5. VegetarianPizza should now have three horizontal lines through it just as CheesyPizza does.
Also, the Equivalent To field in the Description view should have: Pizza and (hasTopping only
(CheeseTopping or VegetableTopping)). Note that another way to create defined classes is to enter the
Description Logic axiom directly into the Equivalent To field.
6. Synchronize the reasoner.
_____________________________________________________________________________________
This means that if something is a member of the class VegetarianPizza it is necessary for it
to be a kind of Pizza and it is necessary for it to only (∀ universal quantifier) have toppings that
are kinds of CheeseTopping or kinds of VegetableTopping. In other words, all
hasTopping relationships that individuals which are members of the class VegetarianPizza
participate in must be to individuals that are either members of the class CheeseTopping or
41
VegetableTopping. The class VegetarianPizza also contains individuals that are Pizzas
and do not participate in any hasTopping relationships.
In situations like the above example, a common mistake is to use an intersection instead of a
union. For example, CheeseTopping and VegetableTopping. Although CheeseTopping
and Vegetable might be a natural thing to say in English, this logically means something that
is simultaneously a kind of CheeseTopping and VegetableTopping. This is incorrect
because we have stated that CheeseTopping and VegetableTopping are disjoint classes
and hence no individual can be an instance of both. If we used such a definition the reasoner
would detect the inconsistency.
In the above example it might have been tempting to create two universal restrictions — one
for CheeseTopping (∀ hasTopping CheeseTopping) and one for
VegetableTopping (∀ hasTopping VegetableTopping). However, when multiple
restrictions are used (for any type of restriction) the total description is taken to be the
intersection of the individual restrictions. This would have therefore been equivalent to one
restriction with a filler that is the intersection of MozzarellaTopping and TomatoTopping
— as explained above this would have been logically incorrect.
42
A closure axiom on a property consists of a universal restriction that says that a property can only be
filled by specified fillers. The restriction has a filler that is the union of the fillers that occur in the
existential restrictions for the property. For example, the closure axiom on the hasTopping property for
MargheritaPizza is a universal restriction that acts along the hasTopping property, with a filler that
is the union of MozzarellaTopping and also TomatoTopping. i.e. hasTopping only
(MozzarellaTopping or TomatoTopping).
Exercise 23: Add a Closure Axiom on the hasTopping Property for MargheritaPizza
_____________________________________________________________________________________
1. Make sure that MargheritaPizza is selected in the class hierarchy in the Classes tab.
2. Click on the Add icon (+) next to the SubClass Of field in the Description view.
3. Select the Class expression editor tab from the pop-up window. Type in the Description Logic axiom:
hasTopping only (MozzarellaTopping or TomatoTopping).
4. Click on OK.
5. Repeat steps 1-4 but this time click on SohoPizza and use the axiom: hasTopping only
(MozzarellaTopping or TomatoTopping or ParmesanTopping or OliveTopping).
6. Synchronize the reasoner.
_____________________________________________________________________________________
The previous axioms said that for example that it was necessary for any Pizza that was a
MargheritaPizza to have a MozzarellaTopping and a TomatoTopping. The new axioms say that
a MargheritaPizza can only have these toppings and similarly for SohoPizza and its toppings. This
should supply the needed information for the reasoner to now make them both subclasses of
VegetarianPizza. Go to the Class hierarchy (inferred) tab. You should now see that
MargheritaPizza and SohoPizza are both classified as subclasses of VegetarianPizza. Your UI
should now look similar to figure 4.23. Note the various axioms highlighted in yellow. Those are all
additional inferences supplied by the reasoner. For experience you might want to click on some of the ?
icons next to these inferences to see the explanations generated by the reasoner. As you develop more
complex ontologies this is a powerful tool to debug and design your ontology.
43
Figure 4.23 The Reasoner Inferred that Margherita and Soho Pizzas are subclasses of VegetarianPizza
44
property called hasSpiciness with only a few possible values ranging from Mild to Hot. In this
section we will also create the first individuals in our ontology.
Exercise 24: Create an Enumerated Class to Represent the Spiciness of a Pizza
_____________________________________________________________________________________
1. Create a new subclass of owl:Thing called Spiciness.
2. Make sure that Spiciness is selected. Click on the Add icon (+) next to the Instances field in the
Description view.
3. You will be prompted with a window that looks like figure 4.24. The diamond icon at the top is for
creating a new individual. The circle with an X through it is for deleting an individual. Use the diamond
icon to create 3 individuals: Hot, Medium, and Mild, so your UI looks like figure 4.24, then click on OK.
4. You may notice that only one of the new individuals was actually created as an instance of
Spiciness. That’s okay. The next step will supply the reasoner with enough information to make the
other two also be instances of Spiciness.
5. Make sure that Spiciness is still selected. Click on the Add icon (+) next to the Equivalent To field in
the Description view. This time we will create a defined class by directly entering the definition for the
class into this field. Select the Class expression editor tab and enter the DL axiom: {Hot, Medium, Mild}.
Select OK.
6. Now run the reasoner. You should see that Spiciness is now a defined class and all three individuals:
Hot, Medium, and Mild, are now instances of that class.
_____________________________________________________________________________________
45
Exercise 25: Create and Use the hasSpiciness Property
_____________________________________________________________________________________
1. Go to the Object properties tab. Create a new property called hasSpiciness. Define its domain to be
PizzaTopping and its range to be Spiciness. Run the reasoner so that it knows about the new property.
2. Go back to the Classes tab and select the class JalapenoPepperTopping. Click on the Add icon (+)
next to the SubClass Of field. Enter the DL axiom: hasSpiciness value Hot. Remember you can use
<control><space> to auto-complete. Click on OK.
3. Note that this is a different kind of restriction than before. Before we were defining abstract restrictions
such as some. I.e., some value from a class but the specific individual was not specified, as long as it was
an individual from that class the restriction was satisfied. Now we are defining a restriction that relates to
a specific individual, hence we use the value keyword rather than the some or only keywords.
4. Now we will use this property to define a new class of Pizza. Start by creating a new subclass of
Pizza called SpicyPizza.
5. Make sure that SpicyPizza is selected. Click on the Add icon (+) next to the SubClass Of field. Enter
the DL axiom: hasTopping some (hasSpiciness value Hot). This says that a SpicyPizza must have a
topping that hasSpiciness value of Hot.
6. Convert SpicyPizza to a defined class by selecting it and using Edit>Convert to defined class. Run the
reasoner.
_____________________________________________________________________________________
Now go to the Class hierarchy (inferred) tab in the Classes tab (see figure 4.25). You should see that
AmericanHotPizza is now classified as a subclass of SpicyPizza because it has a topping
(JalapenoPepperTopping) that has a spiciness value of Hot.
46
Figure 4.25 AmericanHotPizza classified as SpicyPizza
Go to the Class hierarchy (inferred) tab in the Classes tab and click on InterestingPizza. You should see
that there are three Pizza classes that are classified as interesting: AmericanaHotPizza, AmericanaPizza,
and SohoPizza.
47
Chapter 5 Datatype Properties
So far we have been describing object properties. These are properties that have a range that is some
class. As with most other object-oriented languages OWL also has the capability to define properties with
the range of a simple datatype such as a string or integer. Object purists will argue that everything should
be an object. However, to borrow a quote from The Amazing Spiderman: “with great power comes great
overhead”. I.e., the extra capabilities that one has with a class and an instance also means that instances
take up more space and can be slower to process than simple datatypes. For that reason, OWL comes with
a large library of pre-existing datatypes that are mostly imported from XML. That is why many of the
predefined datatypes in Protégé have a prefix of xsd for example xsd:string and xsd:integer. It is
also possible to create new basic datatypes. However, for the majority of use cases, if one needs a
datatype that doesn’t map to one of the predefined types the best solution is to usually just define a class.
A property with a range that is a simple datatype is known as a datatype property. This is analogous to the
distinction between an association and an attribute in the Unified Modeling Language (UML) OOP
modeling language. A UML association is similar to an OWL object property and a UML attribute is
similar to an OWL datatype property. It is also analogous to the distinction between relations and
attributes in entity-relation modeling. A relation in an E/R model is similar to an object property in OWL
and an attribute is similar to a datatype property. Because datatypes don’t have all the power of OWL
objects, many of the capabilities for object properties described in section 4.8 such as having an inverse or
being transitive aren’t available for datatype properties.
48
5. Click on the (+) icon next to Ranges in the Description view for hasCaloricContent. Select the Built in
datatypes tab from the pop-up menu. Select xsd:integer7 from the rather long menu of possible built-in
datatypes. This is the default datatype to use for integer data properties.
6. Click the Functional check box next to the Description view. A Pizza can only have one caloric content
and hence is functional. Data properties are often functional.
5. Select OK and run the reasoner. Your UI should look similar to figure 5.1.
_____________________________________________________________________________________
7
For historic reasons there are many datatypes that are seldom used, e.g., xsd:int which is similar to xsd:Integer.
For numbers, the default datatypes are xsd:integer for integers and xsd:decimal for real numbers. Unless you have
a good reason to use a different numeric datatype it is best to stick with these default types. E.g., when you write a
SWRL rule if you use a number SWRL will infer that any integers are xsd:integer and any rationals are xsd:decimal.
49
Note that as with object properties defining a domain and/or range is optional. In general, it is a good
practice to do so as it can lead to finding errors in your ontology during the modeling phase rather than at
run time.
8
Your particular Protégé UI may look slightly different than some of the screen snapshots depending on if your
organization or another user has already customized the Protégé UI. If you ever want to return a major tab to its
default configuration select that tab and use Window>Reset selected tab to default configuration.
50
Figure 5.2 Adding a new view to the Individuals by class tab
51
Figure 5.3 A Customized Individuals by class tab
52
Figure 5.4 Creating Our First Pizza
53
4. Your UI should now look similar to figure 5.5. Select OK to enter the new value. Run the reasoner.
_____________________________________________________________________________________
One of the most common sources of errors in ontologies is to have the wrong datatype for data
property values. The sooner you catch these errors, the easier they are to debug so it is a good
idea to run the reasoner frequently after you enter any values. Note that in some versions of
Protégé 5.5. there is a minor bug where the UI may lock up due to an inconsistent data value
(e.g., a string value in a property typed for integer). If this happens the best thing to do is save
your work if possible, quit Protégé, and then restart it. When you restart it fix the datatype
errors before you run the reasoner and then run the reasoner to make sure you actually have
fixed the error.
54
3. Make sure to create an instance of AmericanaPizza called AmericanaPizza1 that
hasCaloricContent 723.
4. Make sure to run the reasoner after creating all your instances.
_____________________________________________________________________________________
55
Figure 5.6 Defining the hasCaloricContent data property restriction
Using the datatype property, we have created, we will now create defined classes that specify a range of
interesting values. We will define a HighCaloriePizza to be any pizza that has a calorific value equal
to or higher than 400.
Exercise 32: Create a HighCaloriePizza Defined Class
_____________________________________________________________________________________
1. Navigate to the Classes tab.
2. Select the Pizza class. Create a subclass of Pizza called HighCaloriePizza.
3 Make sure HighCaloriePizza is selected. Click on the (+) icon next to the SubClass Of field in the
Description view. In the Class expression editor type hasCaloricContent some xsd:integer[>= 400] and
click OK.
4. Make sure HighCaloriePizza is still selected and use Edit>Convert to defined class to make it a defined
class.
56
5. Repeat steps 1-4 but this time create a subclass of Pizza called LowCaloriePizza and make its
definition be: hasCaloricContent some xsd:integer[< 400].
6. Run the reasoner. You should now see that each instance of Pizza that hasCaloricContent greater
than or equal to 400 is classified as a HighCaloriePizza and similarly those with less than 400 as
LowCaloriePizza. See the Description view in figure 5.7.
_____________________________________________________________________________________
57
Chapter 6 Adding Order to an Enumerated Class
In this chapter we will expand on the enumerated class that we created to model spiciness in chapter 4.14.
This chapter will highlight some of the power of object properties in OWL. We are going to create an
ordering for the instances of Spiciness. I.e., Hot isSpicierThan Medium which isSpicierThan
Mild. To start go to the Object properties tab. Create a new property that is a sub-property of
owl:topObjectProperty. Call this property isSpicierThan. Make its domain and range the Spiciness class.
Make the property transitive. Transitive means that if X isSpicierThan Y and Y isSpicierThan Z
then X isSpicierThan Z. This is of course similar to the greater than and less than relations in math.
Create another property called isMilderThan. Make one property the inverse of the other. It doesn’t matter
which one, you only have to specify that one property is the inverse of another, and the reasoner will
realize that both are inverses. Run the reasoner. You will see that the reasoner has inferred the domain and
range for isMilderThan than as well as the fact that it is transitive and the inverse of isSpicierThan.
58
Next go back to the Individuals by class tab. Go to the Individuals by type (inferred) view. You should
see the individuals that exist right now. So far we have the example Pizzas you created and the instances
of Spiciness: Hot, Medium, and Mild. Click on Hot. Notice that in the Property assertions view in the
lower right corner the title should now say: Property assertions: Hot. Click on the (+) icon next to Object
property assertions. You will be prompted with a form with two areas to input values. The name of the
property goes in the left hand side and the value in the right hand side (see figure 6.1). Type in
isSpicierThan as the name of the property. Remember you can use auto-complete so you should only
need to type isS and type <control><space> and Protégé will fill in the name of the property. Enter
Medium as the value. Your UI should look similar to figure 6.1. Select OK. Now click on Medium and
set its isSpicierThan value to be Mild. That is all the data entry you need to do. Now run the reasoner
again and click on the Hot, Medium, and Mild individuals. You should see that all the additional
isSpicierThan and isMilderThan values have been filled in for you because the reasoner knows that
the two properties are inverses and transitive. For example, Mild, which we didn’t edit at all, should have
two values for isMilderThan filled in by the reasoner.
We can use these properties in various ways to reason about the relative spiciness of things. We will show
some examples in chapter 8.
This concludes the basics of designing classes and properties with Protégé. There is also a web
version of Protégé available at https://webprotege.stanford.edu/# This takes you to a page
where you can create an account by providing an email and creating a password. Web Protégé
supports multiple users and has extra capabilities such as threaded discussions for collaborative
development of ontologies. However, it currently does not support any reasoners, so it is a
good idea to bring ontologies developed in WebProtégé into the desktop version to run the
reasoner and validate the ontology. See chapter 12 for more on Web Protégé.
59
Chapter 7 Names: IRI’s, Labels, and Namespaces
In exercise 2 we set up some parameters regarding new entity names and rendering without much of an
explanation. The concept of a name in OWL is a little complex so we wanted to wait until you had a basic
grasp of an ontology before diving into these details.
To start with remember that every entity in your ontology has a unique Internationalized Resource
Identifier (IRI)9. An IRI is similar to a URL. In fact, a URL is a kind of IRI. I.e., all URLs are IRIs but
many IRIs are not URLs. A URL is typically meant to identify a specific page meant to be viewed in a
browser. An IRI is often at a smaller level of granularity and for any kind of resource, not only those
meant to be viewed in a browser. If you go to the Active ontology tab in Protégé you will see the
Ontology IRI for your ontology. This is the base IRI that all entities have in common. In addition, each
entity has a subsequent part that comes after the base IRI that uniquely identifies the IRI for the entity.
You can see this by clicking on any entity and starting (but don’t complete) the Refactor>Rename entity
command. Click on the Pizza class. Then select Refactor>Rename entity. You will get a pop-up window
with the current name: Pizza. However, this is only the final part of the IRI. To see the full IRI click on
the check box in the lower right corner that says: Show full IRI. Your full IRI will be different but it will
look something like: http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#Pizza.
Uncheck the Show full IRI box and then Cancel the rename command.
If you recall from exercise 2 there are two options when you create a new entity. One is to use a user
supplied name. That is the option that you should have selected at the beginning of the tutorial and that
should be active now. The other is to use an auto-generated name. This option creates a Universally
Unique Identifier (UUID) for the IRI of each entity. A UUID is an ID that is generated by an algorithm
and is guaranteed to be unique. There are also two ways to display an entity. One way is to use the last
part of the IRI that typically comes after a # sign as in the Pizza example above. The other is to use an
annotation property called a label. An annotation property is meant to provide meta-data about an entity.
Object and data property values can only be asserted on Individuals. However, since all entities have
meta-data annotation properties can be asserted on to any entity. There are some annotation properties
that are included by default with any Protégé ontology. You can see these by looking at the Annotation
properties tab. Note that just as with other properties you can also add your own annotation properties but
they should be used for meta-data not for regular data. You will see rdfs:label is one of the default
annotation properties. When you use UUIDs for your entity IRIs then by default Protégé will
automatically use the name you type in for a new entity in the rdfs:label annotation property.
Although you can also configure Protégé to use other properties if you wish, using the same dialog for
entity rendering that you used in exercise 2.
There are advantages and disadvantages to both options and there are options in between such as using
both user supplied names for IRIs and using rdfs:label for more intuitive names. The details can get
complicated and there also isn’t universal agreement within the community as to which is generally
better. For your first ontology and since you will be using SPARQL I chose to use user supplied entity
names because it is the simpler option and is especially better for SPARQL queries as you will see in the
9
IRIs are also sometimes called URIs. A URI is the same as an IRI except that URIs only support ASCII characters
whereas IRIs can support other character sets such as Kanji. The term people use these days is usually IRI.
60
next section. Which option you choose for your ontology will depend on the specific requirements you
have as well as the standards established by your organization or organizations that you work with.
Finally, another name related concept you should be aware of is the concept of a namespace. If you have
worked with most modern programming languages such as Python or Java, you are already familiar with
the concept of a namespace. The concept is identical in OWL. A namespace is used to avoid naming
conflicts between different ontologies. For example, you may have a class called Network in an ontology
about telecommunications. You might also have a class called Network in an ontology about graph
theory. The two concepts are related but are different. Just as with programming languages you use
namespace prefixes to determine what specific namespace a name refers to. E.g., in this example you
might have the prefix tc for the Telecom ontology and gt for the Graph Theory ontology. Thus, when
you referred to the Network class for the Telecom ontology you would use tc:Network and
gt:Network for the graph theory class.
Note that you already have some experience with other namespaces. The OWL namespace prefix is owl
and is used to refer to classes such as owl:Thing and owl:Nothing. The Resource Description
Framework Schema (RDFS) is a model that OWL is built on top of and thus some properties that
ontologies use such as rdfs:label leverage this namespace.
In the bottom view of the Active ontology tab there is a tab called Ontology Prefixes. This tab shows all
the current namespace mappings in your ontology. There are certain concepts from OWL, RDF, RDFS,
XML and XSD that are required for every ontology, so those namespaces are by default mapped in every
new Protégé ontology. There is also a mapping to the empty string for whatever the namespace is for your
ontology. This allows you to display and refer to entities in your ontology without entering a namespace
prefix. If you look at that tab now you should see a row where the first column is blank, and the second
column has the base IRI for your ontology. It should be the same IRI as the Ontology IRI at the top of the
Active ontology tab, except it also has a # sign at the end. E.g., the Pizza tutorial developed for this
tutorial has an IRI of: http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial and the
row that has a blank first column in Ontology Prefixes has the IRI:
http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#.
61
Chapter 8 A Larger Ontology with some Individuals
The rest of the tutorial requires some data loaded into your ontology. So far, we have mostly been dealing
with defining classes and properties. This type of information is known in the semantic web community
as T-Box information. The T stands for Terminological. Individuals or instances are known as A-Box.
The A stands for Assertional as in specific facts that are asserted about the domain. Typically, there will
be a much larger amount of A-Box information than T-Box. The A-Box information is often uploaded
from spreadsheets, relational databases or other sources. One tool that is not covered in this tutorial that is
useful is called Cellfie. Cellfie is a tool that can take data from spreadsheets and upload it into an
ontology mapping the table-based data into objects and property values. For a tutorial on Cellfie see:
https://github.com/protegeproject/cellfie-plugin/wiki/Grocery-Tutorial
In addition to using Cellfie, you can use the Individuals by class tab introduced in chapter 5 to create new
instances and to create object and data property values for those instances as you did with the Hot and
Medium individuals in chapter 6. However, that can be tedious so to spare you that uninteresting work
I’ve developed a version of the Pizza ontology that has many individuals already created. That ontology
should be identical to the ontology you have developed so far except with many additional individuals.
You can find this populated Pizza ontology at: https://tinyurl.com/PizzaWDataV2 Go to this URL and
download the file to your local machine and then use File>Open. Before you do that, it is probably a good
idea to close the current file so that there is no possible confusion between the Pizza ontology you
developed and the new one with extra data.
62
8.1 Get Familiar with the Larger Ontology
Figure 8.1 Graph of Some of the New Ontology Classes and Individuals
Figure 8.1 uses the OntoGraf tab to visualize some of the new additions to the ontology. There is a new
class called Person with subclasses Employee and Customer. Employee has 5 individuals: Manager,
Chef, Waiter1, and Waiter2. Customer has 10 instances.
In addition, if you look at the Object properties tab you will see there are some new properties:
• The property purchasedByCustomer has domain Pizza and range Customer. It maps from
an individual Pizza to the Customer that purchased it. It has an inverse called
purchasedPizza.
• The property hasSpicinessPreference has domain Customer and range Spiciness. It
records the preference the Customer has for how spicy they usually like their Pizza.
63
The Data properties tab also shows some new properties:
• The hasDiscount data property has a domain of Customer and a range of xsd:decimal. This
records the discount (if any) that the Customer will get on their next purchase.
• The numberOfPizzasPurchased data property has a domain of Customer and a range of
xsd:integer. It records the number of Pizzas that each customer has purchased.
• The ssn property has a domain of Employee and a range of xsd:string. It maps from an
Employee to their social security number. In the United States this is a number that all employers
must have in order to process things such as insurance contributions and tax information.
• The hasPhone data property has a domain of Person and a range of xsd:string.
Most of these data properties have additional constraints in addition to their ranges. For example, a
discount can only be between 0 and 1 and a phone number and social security number must correspond to
a certain format.
Many of these constraints could be expressed via DL axioms that define the range. However, for reasons
that will be discussed below, it is often better to represent data integrity constraints using the SHACL
language rather than as DL axioms. The general rule of thumb is that DL axioms are for reasoning and
SHACL is for data integrity constraints. Of course, this begs the question what is the difference between
reasoning and integrity constraints and the distinction is by nature a fuzzy one. However, there are
guidelines that we will discuss in the section on SHACL which we hope will help shed some light on the
difference.
Finally, viewing the Individuals by class tab will help to understand the additional data in the ontology. If
you go to that tab, you will see many new individuals. In addition to Employees and Customers there
are instances of the Pizza class. You can see all these individuals in the Individuals by type (inferred)
view in the upper right corner.
Now with more instances you can see the value of the Individuals by type (inferred) view. You can
expand and contract various classes and see the instances for them10. Notice that the 4
HighCaloriePizzas are also instances of Pizza but they aren’t shown under Pizza because all
instances of HighCaloriePizza are always instances of the Pizza class. There is only one instance of
the Pizza class displayed because all the other instances of Pizza are also instances of subclasses of
Pizza so they are shown under those subclasses rather than under Pizza. If there are two or more
classes that an Individual is an instance of that aren’t subclasses of each other then they will all be shown.
For example, MargheritaPizza1 is an instance of both MargheritaPizza and LowCaloriePizza
and it shows up under each class because neither is a subclass of the other. It is possible for a Pizza to be
a LowCaloriePizza and not be a MargheritaPizza and vice-versa.
10
Note that if you have an instance of a class selected in the Individuals by type (inferred) view, you won’t be able
to collapse that class. E.g., in figure 8.2 we wouldn’t be able to collapse the Employee class because one of its
instances (Chef) is selected. To collapse it just select a different instance that isn’t an instance of the class you
want to collapse.
64
Figure 8.2 Viewing the New Instances in the Individuals by Class tab
65
Chapter 9 Queries: Description Logic and SPARQL
Now that we have some individuals in our ontology, we can do some interesting queries. There are
several tools for doing queries in Protégé.
5. Try some additional DL queries such as: hasTopping some (hasSpiciness value Hot) and
VegetarianPizza and (hasTopping some (hasSpiciness some (isMilderThan value Hot))). Note that with
this last query you are taking advantage of the transitive order you defined for the instances of the
Spiciness class in chapter 6.
6. You can also do queries for strings in the names of your entities. For example, first do a query simply
with Pizza in the query window. Then type in Hot in the Name contains field. This should give you all the
classes and individuals with Hot in their name.
_____________________________________________________________________________________
66
Figure 9.1 The DL Query Tab
67
To understand what is going on you first need to understand that each SPARQL query consists of two
parts. The first part at the beginning consists of several namespace prefixes. These statements consist of
the prefix used for a particular namespace as well as the IRI associated with this namespace. Recall that
these concepts were described in chapter 7. You may be wondering where all these prefixes came from
since you didn’t add them to your ontology. The answer is that every OWL ontology comes with a set of
namespaces and prefixes that are required to define the ontology.
Also, to understand SPARQL you need to “peak under the hood” of OWL. So far, we have been
discussing concepts in purely logical and set theoretic terms, i.e., at the semantic level. However, like any
language or database there is a lower level that describes how the concepts are mapped to actual data. In a
relational database the fundamental construct to represent data is a table. In OWL the fundamental
construct is a triple. OWL is actually built on top of RDFS which is a language built on top of RDF. RDF
(Resource Description Framework) is a language to describe graphs (in the mathematical sense of the
term). I.e., to describe nodes and links.
The foundation for RDF graphs are triples consisting of a subject, predicate, and object. This results in
what is called an undirected or network graph because objects can be subjects and vice versa. Whenever
you define a property in OWL you are defining a predicate. An individual can be a subject or an object
(or both). E.g., in our ontology Customer1 purchasedPizza AmericanaHotPizza1. In this example
Customer1 is the subject, purchasedPizza is the predicate and AmericanaHotPizza1 is the object.
However, classes and properties themselves are also represented as triples. So for example, when you
create the class Pizza what Protégé does for you is to add the triple: Pizza rdf:type owl:Class to
the ontology. I.e., the Pizza entity is of type (is an instance of) owl:Class. Similarly when you add
NamedPizza as a subclass of Pizza, Protégé adds the triple: NamedPizza rdfs:subClassOf
Pizza.
Hopefully, now you can make some sense of this initial query. The query is looking for all the entities
that are the subjects of triples where the predicate is rdfs:subClassOf and the object is any other
entity. The ? before a name indicates that the name is a wildcard that can match anything that fits with the
rest of the pattern. This is part of the power of SPARQL, one can match a Subject, an Object, a Predicate
or even all three. Making all 3 parts of the pattern wildcards would return every triple in the graph (in this
case our entire Pizza ontology) being searched. You may notice that in some cases the object is simply the
name of a class while in others it is a class expression with an orange circle in front of it. This is because
when defining classes using DL axioms Protégé creates anonymous classes that correspond to various DL
axioms.
The SELECT part of a SPARQL query determines what data to display. The WHERE part of a query
determines what to match in the query. If you want to display everything matched in the WHERE clause
you can just use a * for the SELECT clause. The initial default query in this tab is set up with no
knowledge of the specific ontology. I.e., it will return all the classes that are subclasses of other classes
regardless of the ontology. To get information about Pizzas the first thing we need to do is to add
another prefix to the beginning of the query. In our case the Pizza ontology has been set up with a
mapping to the prefix pizza (you can see this in the ontology prefixes tab in the Active ontology tab
discussed in chapter 7). So, add the following to the SPARQL query after the last PREFIX statement:
PREFIX pizza: <http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#>
We are almost ready to query the actual ontology. For our first query let’s find all the Pizzas purchased by
a Customer. The SPARQL code for this is:
68
SELECT * WHERE { ?customer pizza:purchasedPizza ?pizza }
Type that into the query window underneath the prefixes (of course remove the existing query). Hit
Execute. Your screen should look similar to figure 9.2.
69
SELECT * WHERE { ?pizza pizza:purchasedByCustomer ?customer}
This will show you the two pizzas where the purchase relation was asserted on the instance of Pizza rather
than on the instance of Customer.
Suppose you wanted to see all of the things that are objects of Customer? With a couple of new
constructs this is simple. First, in SPARQL a shortcut to identify the type of any entity is to use the
keyword a as the predicate. This is just shorthand for rdf:type. Second, when you have multiple
statements in a WHERE clause you need to end each one with a period.
Replace the current query with the following:
SELECT *
WHERE { ?customer a pizza:Customer.
?customer ?relation ?relatedToCustomer.}
This will provide a long list of everything in the graph that is an object of some instance of the Customer
class. I.e., any entity that is the object of a predicate with a Customer as the subject.
Suppose you wanted to count the number of Pizzas purchased by Customers so far. For this you use the
SPARQL function COUNT. Here is what it would look like:
SELECT (COUNT(?pizza) AS ?pcount)
WHERE {?customer pizza:purchasedPizza ?pizza}
Paste that into the SPARQL query view and hit Execute and you should see the returned value: 15.
However, remember this isn’t really all the Pizzas because a few of the purchases were recorded on the
Pizza rather than on the Customer. To get the full number we can take advantage of the fact that we
have recorded the number of pizzas that each customer has purchased and use the SPARQL SUM
function. That query would be:
SELECT (SUM(?pnumber) AS ?psum)
WHERE { ?customer pizza:numberOfPizzasPurchased ?pnumber}
This should give you the correct number of 17.
70
?customer ?relation ?relatedToCustomer.}
This would be much less intuitive than the user defined names. There are good reasons to use auto-
generated names, especially for large ontologies that are implemented in multiple natural languages.
However, for new users, especially those who plan to use SPARQL and SHACL, I think it is more
intuitive to start with user supplied names and then progress to auto-generated names if and when the
requirements show a true need for them. This approach to developing software incrementally rather than
to attempt to design the perfect system that can scale for all possible future requirements is known as the
Agile approach to software development. In my experience Agile methods have proven themselves in
countless real-world projects to deliver better software on time and on budget than the alternative
waterfall approach. For more on Agile methods see: https://www.agilealliance.org/agile101/
This just gives you a basic overview of some of the things that can be done with SPARQL. There is a lot
more and if you are interested you should check out DuCharme’s book or some of the many SPARQL
tools and tutorials on the web. Some of these are in the bibliography.
One final point: features of OWL and SWRL that new users frequently find frustrating are the Open
World Assumption (OWA) and lack of non-monotonic reasoning. The OWA was discussed in chapter
4.13. Non-monotonic reasoning will be discussed in section 11.1. For now, though remember that
SPARQL is not subject to either of these restrictions. With SPARQL one can do non-monotonic
reasoning and leverage the more common Closed World Assumption (CWA). E.g., one can test if the
value for a property on a specific instance exists or not and can take actions if that property does not exist.
71
Chapter 10 SWRL and SQWRL
The Semantic Web Rule Language (SWRL) was created because there are certain kinds of inferences that
can’t be done by Description Logic (DL) axioms. Also, in my experience there are also times where an
inference can be done using DL, but it can be more intuitive to define that inference as a rule.
There are actually two UI’s for SWRL in Protégé. There is the SWRL tab and there is also a Rules view
that can be added to the UI as we added a view in section 8.2. The SWRL tab is the one that is being more
actively developed and I recommend you always use that. This chapter will focus on the SWRL tab.
Everything in this chapter applies to the SWRL tab and will be slightly different in the Rules view. For an
overview of the Rules view see the SWRL Process Modeling tutorial listed at the end of this chapter.
Like all rule systems, SWRL consists of a left-hand side (called the antecedent) and a right-hand side
(called the consequent). The two are separated by an arrow created with a dash and a greater than
character like this: ->. Each expression in a SWRL rule is separated by a ^ sign. The consequent of the
rule fires if and only if every expression in the antecedent is satisfied. Since the antecedent can be
satisfied multiple times, this means that SWRL rules can do iteration. They will fire for every
combination of values that can satisfy the antecedent. All parameters (variables that are wildcards and get
bound dynamically as the rule fires) are preceded by a ?.
To begin with let’s write the first rule to give a 20% discount to all customers who have purchased more
than 2 Pizzas and prefer Hot Pizzas.
72
Exercise 34: Write Your First SWRL Rule
_____________________________________________________________________________________
1. To begin with navigate to or create the SWRLTab. If it doesn’t already exist use
Window>Tabs>SWRLTab to create and select it. If you don’t have the SWRLTab under the
Window>Tabs menu then use File>Check for plugins and select the SWRLTab plugin. Remember ifyou
do this you need to restart Protégé for the plugin to be available.
2. The SWRLTab is divided into two main views and then some buttons on the bottom of the tab that
relate to DROOLS. The question of when and how to use DROOLS confuses many new users but there is
a simple answer: don’t use it!11 As you get more experience with SWRL you will start to understand how
and when DROOLS is used but for beginners the answer is simple. Think of all those DROOLS buttons
as things for power users only. You don’t need to use them at all. That is why we installed the Pellet
reasoner in section 4.2. The Pellet reasoner supports SWRL and when you run the reasoner it will also
automatically run any SWRL rules you have. See the bibliography for a paper on DROOLS.
3. Click on the New button at the bottom of the top view. The other buttons should be grayed out since
they only apply if you have at least one rule written. This will give you a new pop-up window to write
your rule. In the Name field at the top call the rule: HotDiscountRule. You can skip the comment but if
you want to add a comment it is a good habit to get into and you can write something like: Provide a
special discount for customers who prefer hot pizzas.
4. Now go to the bottom part of the rule window and start writing the rule. To start you want to bind a
parameter to each instance of the Customer class12. To do this all you need to do is to write:
Customer(?c). Note that auto-complete should work in this window but sometimes it may not and you
may need to type the complete name. Also, you will see various hints or error messages in the Status field
as you type which you can mostly ignore for now. E.g., as you type out Customer you will see messages
like: Invalid SWRL atom predicate ‘Cus’ until you complete the name of the Customer class. Those
messages can help you understand why your rule won’t parse as you develop more rules but for now you
should be able to ignore them.
5. Now you want to bind a parameter to the number of Pizzas that each customer has ordered so far. To
do that you first add a ^ character. This stands for the logical and. I.e., the rule will fire for every set of
bindings that satisfy all of the expressions in the antecedent. To test the number of Pizzas you use the
data property numberOfPizzasPurchased. So at this point your rule should look like: Customer(?c) ^
numberOfPizzasPurchased(?c, ?np).
6. Now we want to test the object property hasSpicinessPreference. The first parameter will also be
?c. I.e., we are iterating through each instance of Customer, binding it to ?c and then testing the values
of these properties. However, in this case rather than binding the spiciness preference to a parameter we
just want to test if it is equal to the instance of Spiciness Hot. So we directly reference that instance in
the expression resulting in: ^ hasSpicinessPreference(?c, Hot).
7. As the last part of the antecedent we want to test that the Customer has purchased more than 1 Pizza.
We can use the SWRL math built-in swrlb:greaterThan. Add ^ swrlb:greaterThan(?np, 1) That is the last
11
For more on DROOLS see the paper: M. J. O'Connor (2012). A Pair of OWL 2 RL Reasoners in the bibliography.
12
This isn’t actually required. You will get the same result without the Customer(?c) expression but it is a good
example of how one can use the names of classes to iterate over their instances with SWRL.
73
part of the antecedent so we write -> to signal the beginning of the consequent. At this point your rule
should look like: Customer(?c) ^ numberOfPizzasPurchased(?c, ?np) ^ hasSpicinessPreference(?c, Hot) ^
swrlb:greaterThan(?np, 1) ->
8. Finally, we write the consequent of the rule, the part after the arrow that signifies what to do each time
the rule succeeds. We want to give these customers a 20% discount so we write: hasDiscount(?c, 0.2).
Whereas the expressions on the left hand side are tests to see if the rule should fire, the expression on the
right is an assertion of a new value to be added to the ontology. For those with a logic background the
simple way to think of this is that the antecedent is implicitly universally quantified whereas the
consequent is implicitly existentially quantified.
9. Thus the whole rule should look like: Customer(?c) ^ numberOfPizzasPurchased(?c, ?np) ^
hasSpicinessPreference(?c, Hot) ^ swrlb:greaterThan(?np, 1) -> hasDiscount(?c, 0.2). Take note that the
OK button at the bottom is only possible to select when the rule has a valid syntax. It should be
selectable now so select it. You should see the new rule show up at the top of the top most view.
_____________________________________________________________________________________
Note that there is a minor bug in SWRL where sometimes the prefix for the current ontology will be
added to all the expressions without a prefix. So at some point you may see that your expressions end up
looking like this: pizza:Customer(?c). If this happens don’t worry it won’t affect the way the rule works at
all. If at some point this happens and you want to remove the prefixes there is a way to do this described
in my blog: https://www.michaeldebellis.com/post/removing-ontology-prefixes-from-swrl-rules
Next, we want to write a second SWRL rule for other customers who have ordered more than one Pizza
but don’t prefer Hot Pizzas.
Exercise 35: Write Another SWRL Rule
_____________________________________________________________________________________
1. Make sure you are still in the SWRLTab. Click on the HotDiscountRule and select Clone
2. This should bring up the same window you used to create your first rule with the code for that rule in
the window. Change the name of this rule from S1 to LessSpicyDiscountRule.
3. Next edit the test for the Customer’s spiciness preference. Rather than just testing if it is Hot we want
to test this time if it isMilderThan Hot. This is an example of using the order relation we defined in
chapter 6. Change hasSpicinessPreference(?c, Hot) to hasSpicinessPreference(?c, ?spr). Rather than just
test if it is equal to Hot we need to bind the preference value to the parameter ?spr. Then after this add
the usual and character and the new test, so you should add: ^ isMilderThan(?spr, Hot)
4. Finally, we want to change the discount for these Customers to be 10% rather than 20%. So change the
consequent to be: hasDiscount(?c, 0.1).
5. Thus the whole rule should look like: Customer(?c) ^ numberOfPizzasPurchased(?c, ?np) ^
hasSpicinessPreference(?c, ?spr) ^ isMilderThan(?spr, Hot) ^ swrlb:greaterThan(?np, 1) ->
hasDiscount(?c, 0.1).
_____________________________________________________________________________________
Now we want to run our rules. Remember there is no need to use those DROOLS buttons. Just
synchronize the reasoner and your rules should fire just as other DL axioms that assert values based on
74
inverses, defined classes, etc. Go back to the Individuals by class tab and look at various Customers. For
example, Customer1 has ordered more than one Pizza and hasSpicinessPreference of Hot so she
has a discount of .2. Note that as with any information asserted by the reasoner, there is a ? next to the
assertion which you can click on and it will provide an explanation about why the value was asserted.
This explanation will list the appropriate rule that fired and the values that caused it to fire. If you look at
Customer6, you will see that he has no discount because he has only purchased one Pizza. Finally, if
you look at Customer2, she has a discount of .1 because she has purchased more than one Pizza but her
spiciness preference isMilderThan Hot.
In this case the consequent of our rule was to add a data property assertion to an individual. Another
possible outcome is to make an individual be an instance of a new class. E.g., if we had a subclass of
Customer called PreferredCustomer and we wanted the result of a rule be to make a Customer an
instance of PreferredCustomer we could have -> PreferredCustomer(?c) as the consequent
of the rule.
A tool that is useful to debug SWRL rules is the Semantic Query-Enhanced Web Rule Language or
SQWRL (pronounced squirrel). SQWRL rules look just like SWRL rules except in the consequent there
is a sqwrl:select statement that lists every parameter that we want to know the value of every time the
rule fires.
Exercise 36: Write a SQWRL Rule
_____________________________________________________________________________________
1. Bring up the SQWRLTab if it doesn’t already exist using Windows>Tabs>SQWRLTab. You will see
it looks almost identical to the SWRLTab.
2. Let’s say we want to see how often the HotDiscountRule fires. We can find this out very easily. To
start select the HotDiscountRule and clone it. This creates a copy of the rule called S1. Select that rule
and then select the Edit button.
3. Change the name of the rule to TestHotDiscountRule. Replace the consequent (the expression after
the arrow) with the following: sqwrl:select(?c, ?np) and select OK. Your SQWRL rule should look like:
Customer(?c) ^ numberOfPizzasPurchased(?c, ?np) ^ hasSpicinessPreference(?c, pizza:Hot) ^
swrlb:greaterThan(?np, 1) -> sqwrl:select(?c, ?np). Synchronize the reasoner.
4. Select TestHotDiscountRule then select the Run button at the bottom of the tab. This will create a new
tab in the lower view called TestHotDiscountRule. You should see that the rule fired 3 times with ?c
equal to Customer4, Customer1, and Customer8 and with ?np equal to 3, 2, and 2.
_____________________________________________________________________________________
This has been a very brief introduction to SWRL. For a somewhat more interesting example based on
process modeling see: https://www.michaeldebellis.com/post/swrl_tutorial
75
Chapter 11 SHACL
Next, we will look at a plugin for SHACL. SHACL stands for Shapes Constraint Language. Note that
shape in this context has nothing to do with geometric shapes. SHACL is somewhat newer than the other
technologies described here. However, it fills an essential gap in the Semantic Web architecture stack, and
it is gaining a lot of traction in the world of large-scale corporate development. The reason for SHACL
may at first seem a bit hard to grasp. After all many of the constraints that SHACL can define for data can
also be defined using Description Logic or SWRL which are more high level and a bit easier to use. So
why even bother with SHACL? There are two reasons that SHACL is essential for real world use of
Semantic Web and Knowledge Graph technology:
1. The need to define constraints that aren’t limited by the Open World Assumption (OWA) and
Monotonic reasoning.
2. The fact that real world data is messy!
76
I.e., it might be the case that we never get the data to satisfy every integrity constraint which would mean
the reasoner is never of any use except to tell us that the ontology is not consistent.
Thus, SHACL provides a way to define data integrity constraints that overlap to some degree with what
can be defined in OWL and SWRL. For example, both can define the number of values allowed for a
specific property. E.g., that each instance of Employee must have one and only one social security
number (ssn). If this were defined as a DL axiom, then the axiom would never fire for employees that
had no ssn because of the OWA. On the other hand, if an Employee accidentally had 2 ssn values then
the entire ontology would be inconsistent until one value was removed. SHACL on the other hand can
handle both these examples and rather than making the entire ontology inconsistent it simply logs
warnings at various levels of severity.
77
There are two shapes in this file, one for the Employee class and one for the Customer class. So, we
want to expand only the Person class in the Class hierarchy view. We will start with the Employee class
so select that class which should result in all the instances of Employee being displayed in the view
below it.
For the SHACL Editor we want the bottom view in the middle to take up as much screen real estate as
possible. So, to start we can delete the two views on the far right side of the tab by clicking on the X at the
top of each tab.
Then drag the SHACL Editor view over to the left just enough so you can see the Employee and
Customer classes and their instances. Your UI should look similar to figure 11.1.
To begin examine the code in the SHACL Editor view. Note that at the beginning there are a list of
namespaces, similar to the namespace prefixes in the SPARQL editor. After the prefixes there is the first
actual shape which is the EmployeeShape. This shape constrains values of properties on instances of
Employee. The sh:targetClass identifies the class that this shape is for. Beneath that are various nodes (as
in nodes in a graph, SHACL is also represented as triples) that constrain various properties that apply to
the Employee class. The first node constrains the cardinality of the ssn property to be exactly one
(minCount 1 and maxCount1). The next also applies to ssn and constrains the data further than just
saying it must be a string. It must be a string that matches the pattern: "^\\d{3}-\\d{2}-\\d{4}$" This is a
regex expression that means the pattern must be 3 digits (numeric characters from 0-9), followed by a
dash, followed by 2 digits, followed by a dash, followed by 4 digits.
The next 2 nodes deal with the hasPhone data property. This property must have at least one value
(although possibly more) and must also conform to a similar pattern of 3 digits followed by a dash
followed by 3 digits followed by a dash followed by 4 digits. Of course, actual phone numbers can be
more complex and varied but this is just a simple example.
78
Figure 11.1 The SHACL Editor
Now hit the Validate button. You should see several messages displayed in the long SHACL constraint
violations view at the bottom. If you had the Employee class selected when you clicked on Validate, then
this view should now read: SHACL constraint violations: 5/8. This means that there were 8 constraint
violations and 5 of them were on instances of the Employee class. You can see the violations that apply
to each Employee by clicking on each individual. You can resize the various columns in this view which
is helpful to view the information you need. The most useful data is in the Message, Path, and Value
columns. All the other columns such as Severity and Source can be made as small as possible to make
more room for those other columns. If you do this and click on the Chef individual you will see that she
has one constraint violation. See figure 11.2.
You can see that the Chef individual has 2 values for the ssn property which is more than allowed. If
you examine the Chef individual in the Individuals by class view you will see that this is indeed the case.
79
Figure 11.2 Constraint Violation for the Chef Individual
If you click on the Manager individual, you will see that he has a constraint violation because his phone
number is not in the proper format. Waiter1 has a similar problem. Waiter2 has missing data. Her
hasPhone and ssn data properties both must have values but don’t.
If you move your focus to the Customer class, you can see the remaining 3 constraint violations.
Customer10’s hasDiscount property is greater than 1 which is not allowed. This is defined by the
CustomerShape in the hasDiscount node with sh:minInclusive 0.0 and sh:maxInclusive
1.0. This is the way you define a minimum and maximum value for a numeric property (note: this
applies to the value not to the number of values). Customer2 also has a hasPhone value that doesn’t match
the defined format and finally Customer3 does not have a value for hasPhone when at least one is
required.
Recall that the SHACL constraints themselves are essentially RDF graphs. Figures 11.3 and 11.4
illustrate the Employee shape and the Customer shape used in the above example as graphed in the
Gruff tool from AllegroGraph.
80
Figure 11.3 Gruff Visualization of the EmployeeShape
81
This is just the most basic introduction to SHACL. For a more sophisticated tutorial see the Top Quadrant
tutorial: https://www.topquadrant.com/technology/shacl/tutorial/ Also, this presentation:
https://www.slideshare.net/jelabra/shacl-by-example gives much more detail on SHACL.
82
Chapter 12 Web Protégé
This tutorial has primarily focused on the desktop version of Protégé because as of this writing Web
Protégé doesn’t support any reasoners so the majority of the sophisticated capabilities of OWL and
Protégé such as defined classes and SWRL rules can’t be created in Web Protégé. However, one of my
goals in creating this tutorial was to address questions that I’ve seen frequently asked on the Protégé user
support email list and one of the most common question is the difference between Protégé and Web
Protégé. We are all used to using tools as services rather than applications installed on our local
machines, so people often go to Web Protégé as their default. While Web Protégé lacks reasoner support
it can still be extremely useful for collaborative development. This chapter explains the benefits of Web
Protégé and some best practices for using the two tools together.
To begin it is recommended that new users start with the desktop version of Protégé13. The constraints
imposed on the ontology by lack of a reasoner are significant and if one learns only using Web Protégé
they will miss many of the benefits of OWL and come away with the idea that Protégé is little more than
a traditional object modeling tool. However, once one is familiar with the desktop version it is worth
getting familiar with Web Protégé as it can be extremely useful for joint development of an ontology by 2
or more people.
To begin there are two options for Web Protégé:
1. Use the Stanford server at webprotege.stanford.edu
2. Download and install the Web Protégé software on your own local server.
13
From this point on I will refer to the Desktop version of Protégé as just Protégé.
83
you will be prompted to create a user ID (your email address) and a password. Once you do that you
should have a fresh Web Protégé workspace. Figure 12.1 shows what my Web Protégé workspace
currently looks like. Most of the projects are owned by me although note that the CODO project is owned
by my colleague Biswanath Dutta. However, I still have complete access to that ontology due to the way
Biswanath has configured my access as being able to both view and edit the ontology.
To upload the Pizza ontology, select the large Create New Project button. This will bring up the window
shown in figure 12.2. Fill out the project name and description, then select the Choose File button and
navigate to where you have the latest version of the Pizza tutorial with data. Note that in the figure I have
already done this navigation so there is a value for the file to load. You can leave the Language field
blank. Once you have all the fields set up similar to figure 12.2 click the Create New Project button on
this dialog (note this is a different button than the one you started from).
84
various links: Display, Project, Share,… Click on Project. This will give you a dropdown menu. Select
Settings from that menu. Scroll down to New Entity Settings. Change IRI Suffix from Auto-generated
Universally Unique ID (UUID) to Supplied name. Leave the rest of the settings as they are and select the
Apply button at the bottom right corner of the screen.
When you select Apply, you should return to the main Web Protégé view with the Class hierarchy tab
selected. If it doesn’t select that tab. Select the Pizza class. Your UI should look like figure 12.3.
85
should see the prompt Start new thread indicating the functionality of this icon. Make sure NamedPizza is
still selected and then click on the icon to start a new thread. This will bring up a window titled Edit
where you can begin a new thread. Type something like: We need a subclass of NamedPizza called
ChicagoPizza. It should have an axiom that requires it to have a DeepPanBase. Then hit the OK button.
Your UI should look similar to figure 12.4.
86
You might be tempted to resolve this thread (note the Resolve link at the top of the initial comment)
however, we aren’t really done. Remember that we need to not just create the class but also define the
axiom that a ChicagoPizza must have a DeepPanBase. Since we can’t add axioms in Web Protégé we
need to export our ontology back to Protégé. Typically, we would collect many more comments and
changes before exporting but we want to demonstrate how round-trip editing works between Protégé and
Web Protégé. We could of course just export the ontology from Web Protégé to Protégé and then create
another new Project, but it would be cumbersome to have to constantly create new projects every time
you want to make a change in Protégé and if we did this, we would lose our audit trail of comments and
changes. Luckily, there is a better way to do it.
To start we need to export the ontology to a file. Note that one of the tabs at the top is History. Select that
tab. This tab shows a list of each version of the ontology. There should be 2 versions labelled R1 and R2
(in the right corner of each version). The most recent version is always at the top since that is typically
what you want although it is also possible to roll back changes to previous versions. We want to export
the latest version R2. Click on the R2 icon. This should give you a drop-down menu with two options:
Revert changes in revision 2 and Download revision 2. Select Download revision 2. This will prompt you
with the standard file browser for your OS to save a zip file with the new ontology. The ontology is saved
with a zip file because ontologies can be large and since Web Protégé is working over a network we may
want to limit the network traffic for large ontologies. Select the appropriate place to save the Zip archive
file on the machine where you have Protégé. Do the standard things you would do to unzip the file and
load it into Protégé. Note that when you unzip the file it will create a directory as well, so the file won’t
be directly under whatever directory you save it to. Instead, there will be a directory titled something like
pizza-with-data-ontologies-owl-REVISION-2 that the OWL file will be in.
Load the downloaded file into Protégé. Go to the Class hierarchy tab and navigate to the new
ChicagoPizza class under NamedPizza. Add the axiom (refer back to chapter 4 if you need to remember
how to add axioms to classes) hasBase some DeepPanBase. Save the file. Now go back to Web Protégé
and your version of the Pizza ontology there. Note that in the upper right corner of the window there are
links (drop down menus) such as Display and Project. Select Project and from the drop down menu select
Apply External Edits. This will give you a small dialog titled Upload ontologies with a little button to
Choose File. Click on Choose File. That will give you the standard OS dialog for selecting a file.
Navigate to the file you saved from Protégé and select that then choose OK. That should result in a new
pop-up window titled Merge ontologies where you will see the changes (in this case only the addition of
the ChicagoPizza axiom) and a text box where you can describe the changes. Add an appropriate
Commit message or just take the default and select OK. You should get a message that says the changes
were successfully applied.
If you navigate back to ChicagoPizza you should see that it now has that axiom. You can also navigate
back to NamedPizza. In the right most column, you should see the comments about needing to add
ChicagoPizza as a subclass. Now that this has been done you can click on the Resolve link in the upper
right corner of the comment thread and the comments will be removed from NamedPizza.
87
Chapter 13 Conclusion: Some Personal Thoughts and Opinions
This tutorial is just the entry point to a technology that is entering the Slope of Enlightenment in the
Gartner technology hype cycle [Gartner Hype Cycle]. Tim Berners-Lee published his paper on the
Semantic Web [Berners-Lee 2001] way back in 2001. At least in my experience for most large US
corporations the excitement around Machine Learning seemed for a while to eclipse serious interest in
OWL, SPARQL, and other Semantic Web technologies in the United States. Then influential technology
companies such as Google [Singhal 2012], Facebook [Olanof 2013], and Amazon [Neptune 2017] started
to embrace the technology using the term Knowledge Graphs [Noy 2019] and the corporate world is
finally realizing that machine learning and knowledge graphs are complimentary not competitive
technologies.
The term knowledge graph itself can be used in different ways. The best definition I’ve heard is that an
ontology provides the vocabulary (i.e., essentially the T-Box) and a knowledge graph is an ontology
combined with data (A-Box). Although in the corporate world I often hear people simply talk about
knowledge graphs without much interest in the distinction between the vocabulary and the data.
There are a number of vendors emerging who are using the technology in very productive ways and are
providing the foundation for federated knowledge graphs that can scale to hundreds of millions of triples
or more and provide a framework for all corporate data. I’ve listed several in the bibliography but those
are only the ones I’ve had some experience with. I’m sure there are many others. One of the products I’ve
had the best experience with is the AllegroGraph triplestore and the Gruff visualization tool from Franz
Inc. Although Allegro is a commercial tool, the free version supports most of the core capabilities of the
commercial version. I’ve found the Allegro triplestore easy to use on a Windows PC with the Docker tool
to emulate a Linux server.
I first started working with classification-based languages when I worked at the Information Sciences
Institute (ISI) and used the Loom language [Macgregor 91] to develop B2B systems for the US
Department of Defense and their contractors. Since then, I’ve followed the progress of the technology,
especially the DARPA knowledge sharing initiative [Neches 91] and always thought there was great
promise in the technology. When I first discovered Protégé it was a great experience. It is one of the best
supported and most usable free tools I’ve ever seen, and it always surprised me that there weren’t more
corporate users leveraging it in major ways. I think we are finally starting to see this happen and I hope
this tutorial helps in a small way to accelerate the adoption of this powerful and robust tool.
88
Chapter 14 Bibliography
Rather than a standard bibliography, this section is divided into various categories based on resources that
will be valuable for future exploration of the technologies and methods described in this tutorial.
14.3 Papers
Berners-Lee (2001). The Semantic Web: A new form of Web content that is meaningful to computers will
unleash a revolution of new possibilities. With James Hendler and Ora Lassila. Scientific American, May
17, 2001. https://tinyurl.com/BernersLeeSemanticWeb
MacGregor, Robert (1991). "Using a description classifier to enhance knowledge representation". IEEE
Expert. 6 (3): 41–46. doi:10.1109/64.87683 https://tinyurl.com/MacGregorLoom
89
Neches, Robert (1991). Enabling Technology for Knowledge Sharing. With Richard Fikes, Tim Finin,
Thomas Gruber, Ramesh Patil, Ted Senator, and William T. Swartout. AI Magazine. Volume 12 Number
3 (1991). https://tinyurl.com/DARPAKnowledgeSharing
Noy, Natasha (2019). Industry-Scale Knowledge Graphs: Lessons and Challenges. With Yuqing Gao,
Anshu Jain, Anant Narayanan, Alan Patterson, Jamie Taylor. Communications of the ACM. Vol. 62. No.
8. August 2019. https://tinyurl.com/ACMKnowledgeGraphs
M. J. O'Connor (2012). A Pair of OWL 2 RL Reasoners. With A.K. Das. OWL: Experiences and
Directions (OWLED), 9th International Workshop, Heraklion, Greece, 2012. http://ceur-ws.org/Vol-
849/paper_31.pdf
Singhal, Amit. (2012). Introducing the Knowledge Graph: things, not strings. Google SVP, Engineering.
May 16, 2012. https://www.blog.google/products/search/introducing-knowledge-graph-things-not/
14.4 Books
DuCharme, Bob (2011). Learning SPARQL. O’Reilly Media
Lewis, Harry. (1997). Elements of the Theory of Computation. With Christos Papadimitriou. Prentice-
Hall; 2nd edition (August 7, 1997). ISBN-13: 978-0132624787
Segaran, Toby (2009). Programming the Semantic Web: Build Flexible Applications with Graph Data.
With Colin Evans and Jamie Taylor. O'Reilly Media; 1st edition (July 28, 2009).
14.5 Vendors
AllegroGraph Triplestore (Franz Inc.): https://franz.com/
Amazon Neptune: https://aws.amazon.com/neptune/
Docker: https://www.docker.com/
Dynaccurate: https://www.dynaccurate.com/
Ontotext: https://www.ontotext.com/
Pool Party: https://www.poolparty.biz/
Stardog: https://www.stardog.com/
Top Quadrant: https://www.topquadrant.com/
90