owlapy is built on the Web Ontology Language (OWL) 2 specification. Understanding these core concepts is essential for effective use of the framework.
An ontology is a formal representation of knowledge as a set of concepts and relationships. In OWL, an ontology consists of:
- TBox (Terminological Box): Class definitions and hierarchies
- ABox (Assertional Box): Individual instances and their property values
- RBox (Role Box): Property definitions and hierarchies
# SyncOntology - Recommended for most use cases
from owlapy.owl_ontology import SyncOntology
onto = SyncOntology("path/to/ontology.owl")
# Ontology - Alternative implementation
from owlapy.owl_ontology import Ontology
onto = Ontology("path/to/ontology.owl")
# NeuralOntology - For neural network-backed reasoning
from owlapy.owl_ontology import NeuralOntology
neural_onto = NeuralOntology("ontology.owl", "embeddings.pkl")Key Difference: SyncOntology is thread-safe and uses owlready2 backend, while Ontology is lighter weight.
Classes represent concepts in your domain.
from owlapy.class_expression import OWLClass
# Always use full IRI
person = OWLClass("http://example.com/onto#Person")
student = OWLClass("http://example.com/onto#Student")Individuals are instances of classes.
from owlapy.owl_individual import OWLNamedIndividual
john = OWLNamedIndividual("http://example.com/onto#John")
mary = OWLNamedIndividual("http://example.com/onto#Mary")Properties define relationships between individuals.
from owlapy.owl_property import OWLObjectProperty, OWLDataProperty
# Object properties (relate individuals to individuals)
has_parent = OWLObjectProperty("http://example.com/onto#hasParent")
knows = OWLObjectProperty("http://example.com/onto#knows")
# Data properties (relate individuals to literal values)
has_age = OWLDataProperty("http://example.com/onto#hasAge")
has_name = OWLDataProperty("http://example.com/onto#hasName")Literals are data values (strings, numbers, dates, etc.).
from owlapy.owl_literal import OWLLiteral
from owlapy.owl_datatype import IntegerOWLDatatype, DoubleOWLDatatype, StringOWLDatatype
age = OWLLiteral(value=25, datatype=IntegerOWLDatatype)
height = OWLLiteral(value=1.75, datatype=DoubleOWLDatatype)
name = OWLLiteral(value="John", datatype=StringOWLDatatype)Class expressions are complex class descriptions built from atomic classes and logical operators.
from owlapy.class_expression import OWLClass, OWLThing, OWLNothing
# Named class
person = OWLClass("http://example.com/onto#Person")
# Top class (everything)
everything = OWLThing
# Bottom class (nothing)
nothing = OWLNothingfrom owlapy.class_expression import (
OWLObjectIntersectionOf,
OWLObjectUnionOf,
OWLObjectComplementOf
)
# Intersection (AND): Teacher ⊓ Researcher
teacher_researcher = OWLObjectIntersectionOf([teacher, researcher])
# Union (OR): Student ⊔ Employee
student_or_employee = OWLObjectUnionOf([student, employee])
# Complement (NOT): ¬Male
not_male = OWLObjectComplementOf(male)from owlapy.class_expression import OWLObjectSomeValuesFrom
# ∃ hasChild.Male (has at least one male child)
has_male_child = OWLObjectSomeValuesFrom(has_child, male)
# ∃ hasParent.⊤ (has at least one parent)
has_parent = OWLObjectSomeValuesFrom(has_parent_prop, OWLThing)from owlapy.class_expression import OWLObjectAllValuesFrom
# ∀ hasChild.Male (all children are male)
only_male_children = OWLObjectAllValuesFrom(has_child, male)from owlapy.class_expression import (
OWLObjectMinCardinality,
OWLObjectMaxCardinality,
OWLObjectExactCardinality
)
# ≥2 hasChild (at least 2 children)
at_least_two_children = OWLObjectMinCardinality(2, has_child)
# ≤1 hasSpouse (at most 1 spouse)
at_most_one_spouse = OWLObjectMaxCardinality(1, has_spouse)
# =3 hasChild.Male (exactly 3 male children)
exactly_three_sons = OWLObjectExactCardinality(3, has_child, male)from owlapy.class_expression import OWLObjectHasValue
# ∃ hasParent.{John} (has John as parent)
johns_child = OWLObjectHasValue(has_parent, john)from owlapy.class_expression import OWLObjectOneOf
# {John, Mary, Bob} (exactly these three individuals)
specific_people = OWLObjectOneOf([john, mary, bob])Axioms are statements that define the structure and constraints of your ontology.
from owlapy.owl_axiom import OWLSubClassOfAxiom, OWLEquivalentClassesAxiom
# Student ⊑ Person (Student is subclass of Person)
subclass_axiom = OWLSubClassOfAxiom(student, person)
# Male ≡ Person ⊓ ¬Female
male_definition = OWLEquivalentClassesAxiom([
male,
OWLObjectIntersectionOf([person, OWLObjectComplementOf(female)])
])from owlapy.owl_axiom import (
OWLClassAssertionAxiom,
OWLObjectPropertyAssertionAxiom,
OWLDataPropertyAssertionAxiom
)
# John is a Person
class_assertion = OWLClassAssertionAxiom(john, person)
# John hasParent Mary
object_prop_assertion = OWLObjectPropertyAssertionAxiom(john, has_parent, mary)
# John hasAge 25
data_prop_assertion = OWLDataPropertyAssertionAxiom(john, has_age, age_literal)from owlapy.owl_axiom import (
OWLSubObjectPropertyOfAxiom,
OWLInverseObjectPropertiesAxiom,
OWLTransitiveObjectPropertyAxiom
)
# hasParent ⊑ hasAncestor
subproperty_axiom = OWLSubObjectPropertyOfAxiom(has_parent, has_ancestor)
# hasChild ≡ hasParent⁻
inverse_axiom = OWLInverseObjectPropertiesAxiom(has_child, has_parent)
# hasAncestor is transitive
transitive_axiom = OWLTransitiveObjectPropertyAxiom(has_ancestor)Reasoners infer implicit knowledge from explicit axioms.
# StructuralReasoner - Fast, incomplete, owlready2-based
from owlapy.owl_reasoner import StructuralReasoner
reasoner = StructuralReasoner(ontology)
# RDFLibReasoner - Pure Python, SPARQL-based, no circular dependencies
from owlapy.owl_reasoner import RDFLibReasoner
reasoner = RDFLibReasoner(ontology)
# SyncReasoner - Complete OWL 2 DL reasoning, Java-based
from owlapy.owl_reasoner import SyncReasoner
from owlapy.static_funcs import startJVM, stopJVM
startJVM()
reasoner = SyncReasoner(ontology, reasoner="HermiT")
# ... use reasoner ...
stopJVM()# Instance retrieval
instances = list(reasoner.instances(person))
# Subclass queries
subclasses = list(reasoner.sub_classes(person))
superclasses = list(reasoner.super_classes(student))
# Property value queries
children = list(reasoner.object_property_values(john, has_child))
age_values = list(reasoner.data_property_values(john, has_age))
# Type queries
types = list(reasoner.types(john))All OWL entities are identified by IRIs.
from owlapy.iri import IRI
# Create IRI
person_iri = IRI("http://example.com/onto#", "Person")
# or
person_iri = IRI.create("http://example.com/onto#Person")
# Get IRI string
iri_string = person_iri.as_str() # "http://example.com/onto#Person"
# Extract namespace and name
namespace = person_iri.get_namespace() # "http://example.com/onto#"
name = person_iri.get_short_form() # "Person"Best Practice: Always use full IRI strings in owlapy constructors:
# Correct
OWLClass("http://example.com/onto#Person")
# Incorrect
OWLClass("Person") # Missing namespaceowlapy supports different OWL 2 profiles with varying expressivity:
- Full OWL 2 expressivity
- Decidable reasoning
- Supported by: SyncReasoner (HermiT, Pellet, JFact)
- Limited to existential quantification
- Polynomial-time reasoning
- Supported by: SyncReasoner (ELK)
- Optimized for query answering
- Log-space reasoning
- Partially supported
- Rule-based reasoning
- Can be implemented with rules engines
- Partially supported
# Define "Parent" as anyone who has at least one child
parent_definition = OWLEquivalentClassesAxiom([
parent,
OWLObjectSomeValuesFrom(has_child, OWLThing)
])
ontology.add_axiom(parent_definition)from owlapy.owl_axiom import OWLDisjointClassesAxiom
# Male and Female are disjoint
disjoint = OWLDisjointClassesAxiom([male, female])
ontology.add_axiom(disjoint)from owlapy.owl_axiom import OWLSubPropertyChainOfAxiom
# hasGrandparent ← hasParent ∘ hasParent
chain = OWLSubPropertyChainOfAxiom([has_parent, has_parent], has_grandparent)
ontology.add_axiom(chain)# Standard OWL namespaces
OWL = "http://www.w3.org/2002/07/owl#"
RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
RDFS = "http://www.w3.org/2000/01/rdf-schema#"
XSD = "http://www.w3.org/2001/XMLSchema#"
# Your custom namespace
NS = "http://example.com/myontology#"- Explore ontology management
- Master class expressions
- Learn about reasoning