from owlready2 import *
# Create or load ontology
onto = get_ontology("http://example.org/my_ontology")
# Define classes
class Person(Thing):
namespace = onto
class Student(Person):
pass
class Course(Thing):
namespace = onto
# Define properties
class enrolledIn(ObjectProperty):
domain = [Student]
range = [Course]
class hasGPA(DataProperty, FunctionalProperty):
domain = [Student]
range = [float]
# Create individuals
john = Student("john")
math101 = Course("math101")
# Set property values
john.enrolledIn = [math101]
john.hasGPA = 3.7
# Save ontology
onto.save(file="my_ontology.owl")Python Ontology Tools
Working with ontologies using Python libraries
Python provides powerful libraries for working with ontologies programmatically. This guide covers the main tools available in this project.
Available Libraries
1. OWLready2
The most comprehensive Python library for OWL ontologies:
- Load and manipulate OWL files
- Create classes, properties, and individuals
- Perform reasoning with external reasoners
- SPARQL query support
2. RDFLib
Core library for RDF graph manipulation:
- Multiple serialization formats (Turtle, RDF/XML, JSON-LD)
- SPARQL endpoint queries
- Graph operations and transformations
- Custom namespace management
3. SymPy
Symbolic mathematics for logical reasoning:
- First-order logic expressions
- Quantifier manipulation
- Logical inference and proofs
- Integration with ontology reasoning
Getting Started
Installation
# Install core dependencies
pip install -r requirements-cpu.txt
# Or for GPU support
pip install -r requirements-gpu.txtProject Structure
from ontology_study.core import OntologyManager
from ontology_study.utils import load_config
from ontology_study import cliWorking with OWLready2
Basic Ontology Operations
Advanced Features
# Complex class expressions
class GoodStudent(Student):
equivalent_to = [Student & hasGPA.some(ConstrainedDatatype(float, min_inclusive=3.5))]
# Property characteristics
class hasParent(ObjectProperty, TransitiveProperty):
pass
class hasSibling(ObjectProperty, SymmetricProperty):
pass
# Reasoning with HermiT
with onto:
sync_reasoner()
# Check for inconsistencies
print("Inconsistent classes:", list(onto.inconsistent_classes()))RDFLib Integration
Graph Operations
from rdflib import Graph, Namespace, RDF, RDFS, OWL, Literal
from rdflib.namespace import FOAF
# Create graph
g = Graph()
# Define namespaces
EX = Namespace("http://example.org/")
g.bind("ex", EX)
g.bind("foaf", FOAF)
# Add triples
g.add((EX.john, RDF.type, FOAF.Person))
g.add((EX.john, FOAF.name, Literal("John Doe")))
g.add((EX.john, FOAF.age, Literal(25)))
# Serialize in different formats
print("Turtle format:")
print(g.serialize(format="turtle"))
print("\nJSON-LD format:")
print(g.serialize(format="json-ld"))SPARQL Queries
# Query the graph
query = """
SELECT ?person ?name ?age
WHERE {
?person rdf:type foaf:Person .
?person foaf:name ?name .
?person foaf:age ?age .
FILTER (?age > 18)
}
"""
results = g.query(query)
for row in results:
print(f"Person: {row.person}, Name: {row.name}, Age: {row.age}")SymPy for Logical Reasoning
First-Order Logic
from sympy.logic.boolalg import *
from sympy import symbols
# Define predicates
P, Q, R = symbols('P Q R')
# Create logical expressions
expr1 = Implies(P, Q) # P → Q
expr2 = Implies(Q, R) # Q → R
expr3 = Implies(P, R) # P → R (should follow from 1,2)
# Check logical equivalence
from sympy.logic.inference import satisfiable
premise = And(expr1, expr2)
conclusion = expr3
# Verify: if premise is true, is conclusion true?
combined = Implies(premise, conclusion)
print(f"Valid inference: {combined.is_tautology}")Quantified Logic
from sympy.logic.predicates import *
# Define predicates with variables
x, y = symbols('x y')
Human = Predicate('Human')
Mortal = Predicate('Mortal')
# Universal quantification: ∀x (Human(x) → Mortal(x))
universal_stmt = ForAll(x, Implies(Human(x), Mortal(x)))
# Existential quantification: ∃x Human(x)
existential_stmt = Exists(x, Human(x))
print(f"Universal: {universal_stmt}")
print(f"Existential: {existential_stmt}")Project Examples
1. Human-Mortal Classic Example
# From ontology_study/human_mortal.py
from owlready2 import *
def create_human_mortal_ontology():
onto = get_ontology("http://example.org/human_mortal")
with onto:
class LivingThing(Thing): pass
class Human(LivingThing): pass
class Mortal(Thing): pass
# All humans are mortal
Human.is_a.append(Mortal)
# Create individual
socrates = Human("socrates")
# Reasoning
with onto:
sync_reasoner()
# Check if Socrates is mortal
print(f"Socrates is mortal: {Mortal in socrates.is_a}")
return onto
onto = create_human_mortal_ontology()2. SPARQL Endpoint Integration
# From ontology_study/sparql_endpoint.py
from SPARQLWrapper import SPARQLWrapper, JSON
def query_dbpedia(query_string):
sparql = SPARQLWrapper("http://dbpedia.org/sparql")
sparql.setQuery(query_string)
sparql.setReturnFormat(JSON)
results = sparql.query().convert()
return results["results"]["bindings"]
# Example: Find famous scientists
query = """
SELECT ?scientist ?name WHERE {
?scientist dbo:occupation dbr:Scientist .
?scientist foaf:name ?name .
}
LIMIT 10
"""
scientists = query_dbpedia(query)
for scientist in scientists:
print(f"{scientist['name']['value']}")CLI Interface
The project includes a rich command-line interface:
# Navigate to Python directory
cd python/ontology_study/
# Show available commands
python cli.py --help
# Run specific examples
python cli.py human-mortal
python cli.py owlready2-demo
python cli.py sparql-query
python cli.py quantifiers-studyCLI Features
- Rich formatting: Colored output and tables
- Interactive prompts: Guided ontology creation
- Progress tracking: For long-running operations
- Export options: Multiple output formats
Integration with Protégé
Export from Python to Protégé
# Create ontology in Python
onto = get_ontology("http://example.org/my_ontology")
# ... define classes, properties, individuals ...
# Save for Protégé
onto.save(file="for_protege.owl", format="rdfxml")
# Open in Protégé Desktop
# File → Open → for_protege.owlImport from Protégé to Python
# Load ontology created in Protégé
onto = get_ontology("file://path/to/protege_ontology.owl").load()
# Access Protégé-defined entities
for cls in onto.classes():
print(f"Class: {cls.name}")
for prop in onto.object_properties():
print(f"Object Property: {prop.name}")
for individual in onto.individuals():
print(f"Individual: {individual.name}")Best Practices
1. Code Organization
# Recommended project structure
ontology_study/
├── core/
│ ├── __init__.py
│ ├── ontology_manager.py
│ └── reasoner.py
├── utils/
│ ├── __init__.py
│ ├── config.py
│ └── helpers.py
├── examples/
│ ├── human_mortal.py
│ └── pizza_ontology.py
└── cli.py2. Configuration Management
# utils/config.py
import yaml
def load_config(config_file="config.yml"):
with open(config_file, 'r') as f:
return yaml.safe_load(f)
# Configuration file example
config = {
'reasoner': 'hermit',
'output_format': 'turtle',
'sparql_endpoint': 'http://localhost:7200/repositories/test',
'namespaces': {
'ex': 'http://example.org/',
'foaf': 'http://xmlns.com/foaf/0.1/'
}
}3. Error Handling
from owlready2 import OwlReadyError
def safe_ontology_operation(ontology_file):
try:
onto = get_ontology(ontology_file).load()
sync_reasoner()
return onto
except OwlReadyError as e:
print(f"OWL error: {e}")
return None
except Exception as e:
print(f"Unexpected error: {e}")
return NonePerformance Tips
1. Large Ontologies
# For large ontologies, use streaming
def process_large_ontology(file_path):
# Don't load entire ontology into memory
onto = get_ontology(file_path)
# Process in chunks
for i, cls in enumerate(onto.classes()):
if i % 1000 == 0:
print(f"Processed {i} classes")
# Process class...2. Reasoning Optimization
# Use faster reasoners for development
set_default_reasoner(HermiT) # Slow but complete
# set_default_reasoner(Pellet) # Faster alternative
# Disable reasoning for bulk operations
with onto:
# Create many individuals without reasoning
for i in range(1000):
Person(f"person_{i}")
# Reason once at the end
sync_reasoner()Next Steps
- Explore Examples: Run all CLI examples to see features
- Build Custom Tools: Extend the CLI with your own commands
- Integration: Connect Python tools with Protégé workflows
- Advanced Reasoning: Experiment with different reasoners
- SPARQL Mastery: Learn complex query patterns
- Performance: Optimize for your specific use cases