Lab: More OWL
Lab 10: More OWL
OWL ontology programming with RDFlib.
Classes and methods
In an earlier lab, you have already used these OWL concepts:
- (sameAs, equivalentClass, equivalentProperty, differentFrom, disjointWith, inverseOf)
- (ReflexiveProperty, IrreflexiveProperty, SymmetricProperty, AsymmetricProperty, TransitiveProperty, FunctionalProperty, InverseFunctionalProperty),
In this lab you will also use the following OWL terms:
- (oneOf, unionOf, intersectionOf. complementOf)
- (Restriction, onProperty)
- (someValuesFrom, allValuesFrom, hasValue)
- (cardinality, minCardinality, maxCardinality)
- (qualifiedCardinality, minQualifiedCardinality, maxQualifiedCardinality, onClass)
Most of the tasks today involve restrictions.
We recommend refreshing your memories on restrictions and complex classes from the lecture notes When solving the tasks look at the notes, find the relevant OWL term/s, and try to use the same principles in python code.
Down below is an example solution of the first task: "anyone who is a graduate has at least one degree". It looks complicated, but once you understand it, the other tasks follow a similar pattern.P In short: Create a blank node that is an OWL.restriction on the ex.degree property. The restriction in question is a minCardinality restriction with the value 1. (e.g "at least one"). Then create another blank node that is for a List of all the criteria that makes a person a Graduate. In this case we can say that a Graduate is the intersection of a Person and the restriction we created earlier. Collection is essentially used to create lists and everything between  is what is in the list (the intersections).
# anyone who is a graduate has at least one degree br = BNode() g.add((br, RDF.type, OWL.Restriction)) g.add((br, OWL.onProperty, ex.degree)) g.add((br, OWL.minCardinality, Literal(1))) bi = BNode() Collection(g, bi, [ex.Person, br]) g.add((ex.Graduate, OWL.intersectionOf, bi))
Create or extend a previous graph into an ontology that expresses the following using concepts from OWL (and some from RDF/RDFS), you can do this either by creating the triples in Python using RDFLib or writing the triples using Turtle (or RDF/XML):
- anyone who is a graduate has at least one degree
- anyone who is a university graduate has at least one degree from a university
- a grade is either an A, B, C, D, E or F
- a straight A student is a student that has only A grades
- a graduate has no F grades
- a student has a unique student number
- each student has exactly one average grade
- a course is either a bachelor, a master or a Ph.D course
- a bachelor student takes only bachelor courses
- a master student takes only master courses, except for at most one bachelor course
- a Ph.D student takes only Ph.D courses, except for at most two masters courses
- a Ph.D. student cannot take any bachelor course
Write each of the above statements as Python code using RDFlib and OWL.
Code to get started
import owlrl from rdflib import Graph, Literal, Namespace, BNode from rdflib.namespace import RDF, OWL, RDFS from rdflib.collection import Collection g = Graph() ex = Namespace("http://example.org/") g.bind("ex", ex) g.bind("owl", OWL) # anyone who is a graduate has at least one degree br = BNode() g.add((br, RDF.type, OWL.Restriction)) g.add((br, OWL.onProperty, ex.degree)) g.add((br, OWL.minCardinality, Literal(1))) bi = BNode() Collection(g, bi, [ex.Person, br]) g.add((ex.Graduate, OWL.intersectionOf, bi)) # Continue here with the other statements: print(g.serialize(format="turtle").decode())
If You Have More Time
Populate the ontology with individals, such as:
g.add((ex.Cade, RDF.type, ex.Graduate)) g.add((ex.Cade, ex.grade, ex.A))
Try to use OWL-RL as in lab 8 to infer additional triples. IMPORANT: OWL-RL is unable to reason with general OWL Restrictions and some other concepts as well. There is a Python library for better OWL reasoning called Owlready if you want to reason with restrictions. Here is the ontology before and after the reasoning.
What has changed about Cade after using OWL-RL?
# # Write owl file before any reasoned triples g.serialize(destination="owl1.ttl", format="turtle") # Infer additional triples owl_reasoner = owlrl.CombinedClosure.RDFS_OWLRL_Semantics(g, False, False, False) owl_reasoner.closure() owl_reasoner.flush_stored_triples() # Write owl file that includes reasoned triples g.serialize(destination="owl2.ttl", format="turtle")