|
| 1 | +# Getting Started with owlapy |
| 2 | + |
| 3 | +## Installation |
| 4 | + |
| 5 | +### Basic Installation |
| 6 | + |
| 7 | +```bash |
| 8 | +pip install owlapy |
| 9 | +``` |
| 10 | + |
| 11 | +### Installation from Source |
| 12 | + |
| 13 | +```bash |
| 14 | +git clone https://github.com/dice-group/owlapy |
| 15 | +cd owlapy |
| 16 | +conda create -n owlapy_env python=3.11 --no-default-packages |
| 17 | +conda activate owlapy_env |
| 18 | +pip install -e . |
| 19 | +``` |
| 20 | + |
| 21 | +### Development Installation |
| 22 | + |
| 23 | +```bash |
| 24 | +pip install -e '.[dev]' |
| 25 | +``` |
| 26 | + |
| 27 | +This includes additional dependencies for: |
| 28 | +- Testing (pytest, coverage) |
| 29 | +- Linting (ruff) |
| 30 | +- Documentation (sphinx) |
| 31 | + |
| 32 | +### Optional Dependencies |
| 33 | + |
| 34 | +**For LLM-based ontology generation (AGenKG):** |
| 35 | +```bash |
| 36 | +pip install owlapy[agentic] |
| 37 | +# or |
| 38 | +pip install 'dspy>=3.0.3,<4.0.0' |
| 39 | +``` |
| 40 | + |
| 41 | +**For Java-based reasoners (HermiT, Pellet, etc.):** |
| 42 | +- JPype1 is automatically installed |
| 43 | +- Java JRE/JDK 8+ must be installed on your system |
| 44 | + |
| 45 | +## System Requirements |
| 46 | + |
| 47 | +- **Python:** 3.11 or higher |
| 48 | +- **Operating System:** Linux, macOS, Windows |
| 49 | +- **Memory:** Minimum 4GB RAM (8GB+ recommended for large ontologies) |
| 50 | +- **Java (optional):** JRE/JDK 8+ for HermiT, Pellet, JFact, ELK, Openllet reasoners |
| 51 | + |
| 52 | +## Quick Start |
| 53 | + |
| 54 | +### 1. Load an Ontology |
| 55 | + |
| 56 | +```python |
| 57 | +from owlapy.owl_ontology import SyncOntology |
| 58 | + |
| 59 | +# Load from file |
| 60 | +ontology = SyncOntology("path/to/ontology.owl") |
| 61 | + |
| 62 | +# Or from URL |
| 63 | +ontology = SyncOntology("http://example.com/ontology.owl") |
| 64 | +``` |
| 65 | + |
| 66 | +### 2. Create a Reasoner |
| 67 | + |
| 68 | +```python |
| 69 | +from owlapy.owl_reasoner import RDFLibReasoner |
| 70 | + |
| 71 | +# Pure Python reasoner (recommended for most use cases) |
| 72 | +reasoner = RDFLibReasoner(ontology) |
| 73 | +``` |
| 74 | + |
| 75 | +### 3. Query Instances |
| 76 | + |
| 77 | +```python |
| 78 | +from owlapy.class_expression import OWLClass |
| 79 | + |
| 80 | +# Define a class |
| 81 | +person_class = OWLClass("http://example.com/onto#Person") |
| 82 | + |
| 83 | +# Get all instances |
| 84 | +persons = list(reasoner.instances(person_class)) |
| 85 | +print(f"Found {len(persons)} persons") |
| 86 | + |
| 87 | +for person in persons: |
| 88 | + print(f" - {person.str}") |
| 89 | +``` |
| 90 | + |
| 91 | +### 4. Build Class Expressions |
| 92 | + |
| 93 | +```python |
| 94 | +from owlapy.class_expression import ( |
| 95 | + OWLClass, |
| 96 | + OWLObjectSomeValuesFrom, |
| 97 | + OWLObjectIntersectionOf |
| 98 | +) |
| 99 | +from owlapy.owl_property import OWLObjectProperty |
| 100 | + |
| 101 | +# Create complex class expression: |
| 102 | +# Parent ⊓ (∃ hasChild.Male) |
| 103 | +parent_class = OWLClass("http://example.com/onto#Parent") |
| 104 | +has_child_prop = OWLObjectProperty("http://example.com/onto#hasChild") |
| 105 | +male_class = OWLClass("http://example.com/onto#Male") |
| 106 | + |
| 107 | +parent_with_male_child = OWLObjectIntersectionOf([ |
| 108 | + parent_class, |
| 109 | + OWLObjectSomeValuesFrom(has_child_prop, male_class) |
| 110 | +]) |
| 111 | + |
| 112 | +# Query instances of complex expression |
| 113 | +parents = list(reasoner.instances(parent_with_male_child)) |
| 114 | +print(f"Found {len(parents)} parents with male children") |
| 115 | +``` |
| 116 | + |
| 117 | +### 5. Convert to Different Syntaxes |
| 118 | + |
| 119 | +```python |
| 120 | +from owlapy import owl_expression_to_dl, owl_expression_to_manchester |
| 121 | + |
| 122 | +# Convert to Description Logic syntax |
| 123 | +dl_syntax = owl_expression_to_dl(parent_with_male_child) |
| 124 | +print(f"DL: {dl_syntax}") |
| 125 | +# Output: Parent ⊓ (∃ hasChild.Male) |
| 126 | + |
| 127 | +# Convert to Manchester syntax |
| 128 | +manchester = owl_expression_to_manchester(parent_with_male_child) |
| 129 | +print(f"Manchester: {manchester}") |
| 130 | +# Output: Parent and (hasChild some Male) |
| 131 | +``` |
| 132 | + |
| 133 | +## Complete Example: Family Ontology |
| 134 | + |
| 135 | +```python |
| 136 | +from owlapy.owl_ontology import SyncOntology |
| 137 | +from owlapy.owl_reasoner import RDFLibReasoner |
| 138 | +from owlapy.class_expression import ( |
| 139 | + OWLClass, |
| 140 | + OWLObjectSomeValuesFrom, |
| 141 | + OWLObjectIntersectionOf, |
| 142 | + OWLObjectUnionOf |
| 143 | +) |
| 144 | +from owlapy.owl_property import OWLObjectProperty |
| 145 | +from owlapy import owl_expression_to_dl |
| 146 | + |
| 147 | +# 1. Load ontology |
| 148 | +onto = SyncOntology("family.owl") |
| 149 | + |
| 150 | +# 2. Create reasoner |
| 151 | +reasoner = RDFLibReasoner(onto) |
| 152 | + |
| 153 | +# 3. Define namespace |
| 154 | +NS = "http://example.com/family#" |
| 155 | + |
| 156 | +# 4. Define classes and properties |
| 157 | +person = OWLClass(NS + "Person") |
| 158 | +male = OWLClass(NS + "Male") |
| 159 | +female = OWLClass(NS + "Female") |
| 160 | +has_child = OWLObjectProperty(NS + "hasChild") |
| 161 | + |
| 162 | +# 5. Query simple classes |
| 163 | +all_males = list(reasoner.instances(male)) |
| 164 | +print(f"Males: {[m.str.split('#')[-1] for m in all_males]}") |
| 165 | + |
| 166 | +# 6. Build complex expression: parents with female children |
| 167 | +# Parent ⊓ (∃ hasChild.Female) |
| 168 | +parents_with_daughters = OWLObjectIntersectionOf([ |
| 169 | + person, |
| 170 | + OWLObjectSomeValuesFrom(has_child, female) |
| 171 | +]) |
| 172 | + |
| 173 | +# 7. Query complex expression |
| 174 | +result = list(reasoner.instances(parents_with_daughters)) |
| 175 | +print(f"Parents with daughters: {[r.str.split('#')[-1] for r in result]}") |
| 176 | +print(f"DL syntax: {owl_expression_to_dl(parents_with_daughters)}") |
| 177 | + |
| 178 | +# 8. Get class hierarchy |
| 179 | +all_subclasses = list(reasoner.sub_classes(person)) |
| 180 | +print(f"Subclasses of Person: {[c.str.split('#')[-1] for c in all_subclasses]}") |
| 181 | +``` |
| 182 | + |
| 183 | +## Next Steps |
| 184 | + |
| 185 | +- Learn about [core concepts](02_core_concepts.md) in owlapy |
| 186 | +- Explore [ontology management](03_ontology_management.md) |
| 187 | +- Master [class expressions](04_class_expressions.md) |
| 188 | +- Dive into [reasoning](05_reasoning.md) capabilities |
| 189 | +- Check [common patterns](08_common_patterns.md) for best practices |
| 190 | + |
| 191 | +## Troubleshooting |
| 192 | + |
| 193 | +### Import Errors |
| 194 | + |
| 195 | +**Problem:** `ModuleNotFoundError: No module named 'owlapy'` |
| 196 | + |
| 197 | +**Solution:** |
| 198 | +```bash |
| 199 | +pip install owlapy |
| 200 | +# Or if installed from source: |
| 201 | +pip install -e . |
| 202 | +``` |
| 203 | + |
| 204 | +### Java Reasoner Errors |
| 205 | + |
| 206 | +**Problem:** `JVMNotFoundException` when using SyncReasoner |
| 207 | + |
| 208 | +**Solution:** Install Java JRE/JDK 8+ and ensure it's in your PATH |
| 209 | + |
| 210 | +### Memory Issues |
| 211 | + |
| 212 | +**Problem:** `MemoryError` when loading large ontologies |
| 213 | + |
| 214 | +**Solution:** |
| 215 | +- Use RDFLibReasoner instead of StructuralReasoner (more memory efficient) |
| 216 | +- Increase Python memory limit |
| 217 | +- Load only necessary parts of the ontology |
| 218 | + |
| 219 | +### IRI Errors |
| 220 | + |
| 221 | +**Problem:** `ValueError: Invalid IRI` |
| 222 | + |
| 223 | +**Solution:** Always use full IRI strings: |
| 224 | +```python |
| 225 | +# Correct |
| 226 | +OWLClass("http://example.com/onto#Person") |
| 227 | + |
| 228 | +# Incorrect |
| 229 | +OWLClass("Person") # Missing namespace |
| 230 | +``` |
0 commit comments