Skip to content

Commit ea48dc9

Browse files
authored
Merge pull request #27 from dice-group/develop
New Release
2 parents 8ee155b + c48e40d commit ea48dc9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1620
-1038
lines changed

README.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# OWLAPY
22

3+
OWLAPY is a Python Framework that serves as a base structure for creating and manipulating
4+
OWL Ontologies.
5+
6+
Have a look at the [Documentation](https://dice-group.github.io/owlapy/).
7+
38
## Installation
49
<details><summary> Click me! </summary>
510

@@ -21,42 +26,39 @@ In this example we start with a simple atomic class expression and move to some
2126
ones and finally render and print the last of them in description logics syntax.
2227

2328
```python
24-
from owlapy.iri import IRI
2529
from owlapy.class_expression import OWLClass, OWLObjectIntersectionOf, OWLObjectSomeValuesFrom
2630
from owlapy.owl_property import OWLObjectProperty
27-
from owlapy.owl2sparql.converter import owl_expression_to_sparql
28-
from owlapy.render import owl_expression_to_dl
31+
from owlapy import owl_expression_to_sparql, owl_expression_to_dl
32+
2933
# Create the male class
3034
male = OWLClass("http://example.com/society#male")
3135

3236
# Create an object property using the iri as a string for 'hasChild' property.
3337
hasChild = OWLObjectProperty("http://example.com/society#hasChild")
3438

3539
# Create an existential restrictions
36-
males_with_children = OWLObjectSomeValuesFrom(hasChild, male)
40+
hasChild_male = OWLObjectSomeValuesFrom(hasChild, male)
3741

3842
# Let's make it more complex by intersecting with another class
3943
teacher = OWLClass("http://example.com/society#teacher")
40-
male_teachers_with_children = OWLObjectIntersectionOf([males_with_children, teacher])
44+
teacher_that_hasChild_male = OWLObjectIntersectionOf([hasChild_male, teacher])
4145

4246
# You can render and print owl class expressions in description logics syntax (and vice-versa)
43-
print(owl_expression_to_dl(male_teachers_with_children))
47+
print(owl_expression_to_dl(teacher_that_hasChild_male))
4448
# (∃ hasChild.male) ⊓ teacher
45-
print(owl_expression_to_sparql("?x", male_teachers_with_children))
49+
print(owl_expression_to_sparql("?x", teacher_that_hasChild_male))
4650
# SELECT DISTINCT ?x WHERE { ?x <http://example.com/society#hasChild> ?s_1 . ?s_1 a <http://example.com/society#male> . ?x a <http://example.com/society#teacher> . } }
4751
```
48-
For more, you can check the [API documentation](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/#module-owlapy).
49-
5052

5153
Every OWL object that can be used to classify individuals, is considered a class expression and
52-
inherits from [OWLClassExpression](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/model/#owlapy.model.OWLClassExpression)
54+
inherits from [OWLClassExpression](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/class_expression/index.html#owlapy.class_expression.class_expression.OWLClassExpression)
5355
class. In the above examples we have introduced 3 types of class expressions:
54-
- [OWLClass](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/model/#owlapy.model.OWLClass),
55-
- [OWLObjectSomeValuesFrom](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/model/#owlapy.model.OWLObjectSomeValuesFrom)
56-
- [OWLObjectIntersectionOf](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/model/#owlapy.model.OWLObjectIntersectionOf).
56+
- [OWLClass](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/owl_class/index.html#owlapy.class_expression.owl_class.OWLClass),
57+
- [OWLObjectSomeValuesFrom](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/restriction/index.html#owlapy.class_expression.restriction.OWLObjectSomeValuesFrom)
58+
- [OWLObjectIntersectionOf](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/nary_boolean_expression/index.html#owlapy.class_expression.nary_boolean_expression.OWLObjectIntersectionOf).
5759

5860
Like we showed in this example, you can create all kinds of class expressions using the
59-
OWL objects in [owlapy model](https://ontolearn-docs-dice-group.netlify.app/autoapi/owlapy/model/#module-owlapy.model).
61+
OWL objects in [owlapy api](https://dice-group.github.io/owlapy/autoapi/owlapy/index.html).
6062
</details>
6163

6264
## How to cite

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ Welcome to OWLAPY!
1111
:caption: Contents:
1212

1313
usage/main
14+
usage/usage_examples
1415
autoapi/owlapy/index

docs/usage/main.md

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,58 @@
1-
# OWLAPY
1+
# About owlapy
22

3-
placeholder
3+
**Version:** owlapy 1.0.0
4+
5+
**GitHub repository:** [https://github.com/dice-group/owlapy](https://github.com/dice-group/owlapy)
6+
7+
**Publisher and maintainer:** [DICE](https://dice-research.org/) - data science research group of [Paderborn University](https://www.uni-paderborn.de/en/university).
8+
9+
**Contact**: [onto-learn@lists.uni-paderborn.de](mailto:onto-learn@lists.uni-paderborn.de)
10+
11+
**License:** GNU Affero General Public License v3 or later (AGPLv3+)
12+
13+
--------------------------------------------------------------------------------------------
14+
## What is owlapy?
15+
Owlapy is an open-source software library in python that is used to represent entities
16+
in OWL 2 Web Ontology Language.
17+
18+
We identified the gap of having a library that will serve as a base structure
19+
for representing OWL entities in python and like that, owlapy was created. Owlapy
20+
is loosely based on its java-counterpart, _owlapi_. Owlapy is currently utilized
21+
by powerful libraries such as [Ontolearn](https://github.com/dice-group/Ontolearn)
22+
and [OntoSample](https://github.com/alkidbaci/OntoSample).
23+
24+
Owlapy is the perfect choice for machine learning projects that are built in python and
25+
focus on knowledge graphs and class expression learnings.
26+
27+
---------------------------------------
28+
29+
## What does owlapy have to offer?
30+
31+
- Represent every notation in
32+
[OWL 2 Structural Specification and Functional-Style Syntax](https://www.w3.org/TR/owl2-syntax/)
33+
including:
34+
- Entities, Literals, and Anonymous Individuals
35+
- Property Expressions
36+
- Data Ranges
37+
- Class Expressions
38+
- Axioms
39+
- Annotations
40+
- Construct complex class expressions.
41+
- Provide interfaces for OWL Ontology, Ontology manager and Reasoner.
42+
- Convert owl expression to SPARQL queries.
43+
- Render owl expression to Description Logics or Manchester syntax.
44+
- Parse Description Logics or Manchester expression to owl expression.
45+
46+
47+
## How to install?
48+
49+
Installation from source:
50+
``` bash
51+
git clone https://github.com/dice-group/owlapy
52+
conda create -n temp_owlapy python=3.10.13 --no-default-packages && conda activate temp_owlapy && pip3 install -e .
53+
```
54+
55+
or using PyPI:
56+
```bash
57+
pip3 install owlapy
58+
```

docs/usage/usage_examples.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Usage
2+
3+
The main usage for owlapy is to use it for class expression construction. Class
4+
expression learning algorithms require such basic structure to work upon. Let's walk
5+
through an example of constructing some class expressions.
6+
7+
In this example we will be using the _family_ ontology,
8+
a simple ontology with namespace: `http://example.com/family#`.
9+
Here is a hierarchical diagram that shows the classes and their relationship:
10+
11+
Thing
12+
|
13+
person
14+
/ |
15+
male female
16+
17+
It contains only one object property which is `hasChild` and in total there
18+
are six persons (individuals), of which four are males and two are females.
19+
20+
## Atomic Classes
21+
22+
To represent the classes `male`, `female`, and `person` we can simply use the
23+
class [OWLClass](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/owl_class/index.html#owlapy.class_expression.owl_class.OWLClass):
24+
25+
```python
26+
from owlapy.class_expression import OWLClass
27+
from owlapy.iri import IRI
28+
29+
namespace = "http://example.com/family#"
30+
31+
male = OWLClass(IRI(namespace, "male"))
32+
female = OWLClass(IRI(namespace, "female"))
33+
person = OWLClass(IRI(namespace, "person"))
34+
35+
```
36+
37+
Notice that we created an `IRI` object for every class. [IRI](https://dice-group.github.io/owlapy/autoapi/owlapy/iri/index.html#owlapy.iri.IRI)
38+
is used to represent an _IRI_. Every named entity requires an IRI, whereas Anonymous entities does not.
39+
However, in owlapy you can create an _OWLClass_ by passing the _IRI_ directly as a string, like so:
40+
41+
```python
42+
male = OWLClass("http://example.com/family#male")
43+
```
44+
45+
## Object Property
46+
47+
To represent the object property `hasChild` we can use the class
48+
[OWLObjectProperty](https://dice-group.github.io/owlapy/autoapi/owlapy/owl_property/index.html#owlapy.owl_property.OWLObjectProperty):
49+
50+
```python
51+
from owlapy.owl_property import OWLObjectProperty
52+
53+
hasChild = OWLObjectProperty("http://example.com/family#hasChild")
54+
```
55+
56+
> **Tip:** In owlapy the naming of the classes is made in accordance with the notations from
57+
> OWL 2 specification but with the word _"OWL"_ in the beginning. Example: _"OWLObjectProperty"_
58+
> represents the notation _"ObjectProperty"_.
59+
60+
## Complex class expressions
61+
62+
Now that we have these atomic entities, we can construct more complex class
63+
expressions. Let's say we want to represent all individuals which are `male`
64+
and have at least 1 child.
65+
66+
We already have the concept of `male`. We need to find the appropriate class
67+
for the second part: _"have at least 1 child"_. In OWL 2 specification that would be
68+
[ObjectMinCardinality](https://www.w3.org/TR/owl2-syntax/#Minimum_Cardinality). In owlapy,
69+
as we said, we simply add the word _"OWL"_ upfront to find the correct class:
70+
71+
```python
72+
from owlapy.class_expression import OWLObjectMinCardinality
73+
74+
has_at_least_one_child = OWLObjectMinCardinality(
75+
cardinality = 1,
76+
property = hasChild,
77+
filler = person
78+
)
79+
```
80+
As you can see, to create an object of class [OWLObjectMinCardinality](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/restriction/index.html#owlapy.class_expression.restriction.OWLObjectMinCardinality)
81+
is as easy as that. You specify the cardinality which in this case is `1`, the object property where we apply this
82+
cardinality restriction and the filler class in case you want to restrict the domain of the class expression. In this
83+
case we used `person`.
84+
85+
Now let's merge both class expressions together using [OWLObjectIntersectionOf](https://dice-group.github.io/owlapy/autoapi/owlapy/class_expression/nary_boolean_expression/index.html#owlapy.class_expression.nary_boolean_expression.OWLObjectIntersectionOf):
86+
87+
```python
88+
from owlapy.class_expression import OWLObjectIntersectionOf
89+
90+
ce = OWLObjectIntersectionOf([male, has_at_least_one_child])
91+
```
92+
93+
## Convert to SPARQL, DL or Manchester syntax
94+
95+
Owlapy is not just a library to represent OWL entities, you can also
96+
use it to convert owl expressions into other formats:
97+
98+
```python
99+
from owlapy import owl_expression_to_sparql, owl_expression_to_dl, owl_expression_to_manchester
100+
101+
print(owl_expression_to_dl(ce))
102+
# Result: male ⊓ (≥ 1 hasChild.person)
103+
104+
print(owl_expression_to_sparql(expression=ce))
105+
# Result: SELECT DISTINCT ?x WHERE { ?x a <http://example.com/family#male> . { SELECT ?x WHERE { ?x <http://example.com/family#hasChild> ?s_1 . ?s_1 a <http://example.com/family#person> . } GROUP BY ?x HAVING ( COUNT ( ?s_1 ) >= 1 ) } }
106+
107+
print(owl_expression_to_manchester(ce))
108+
# Result: male and (hasChild min 1 person)
109+
```
110+
111+
To parse a DL or Manchester expression to owl expression you can use the
112+
following convenient methods:
113+
114+
```python
115+
from owlapy import dl_to_owl_expression, manchester_to_owl_expression
116+
117+
print(dl_to_owl_expression("∃ hasChild.male", namespace))
118+
# Result: OWLObjectSomeValuesFrom(property=OWLObjectProperty(IRI('http://example.com/family#','hasChild')),filler=OWLClass(IRI('http://example.com/family#','male')))
119+
120+
print(manchester_to_owl_expression("female and (hasChild max 2 person)", namespace))
121+
# Result: OWLObjectIntersectionOf((OWLClass(IRI('http://example.com/family#','female')), OWLObjectMaxCardinality(property=OWLObjectProperty(IRI('http://example.com/family#','hasChild')),2,filler=OWLClass(IRI('http://example.com/family#','person')))))
122+
123+
```
124+
125+
In these examples we showed a fraction of **owlapy**. You can explore the
126+
[api documentation](owlapy) to learn more about all classes in owlapy.

owlapy/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
__version__ = '0.1.3'
1+
from .render import owl_expression_to_dl, owl_expression_to_manchester
2+
from .parser import dl_to_owl_expression, manchester_to_owl_expression
3+
from .converter import owl_expression_to_sparql
4+
__version__ = '1.0.0'

owlapy/_utils.py

Lines changed: 0 additions & 14 deletions
This file was deleted.

owlapy/class_expression/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
"""https://www.w3.org/TR/owl2-syntax/#Class_Expressions
1+
""" OWL Class Expressions
2+
https://www.w3.org/TR/owl2-syntax/#Class_Expressions
23
ClassExpression :=
34
owl_class.py:
45
Class
@@ -36,5 +37,5 @@
3637
from typing import Final
3738
from ..vocab import OWLRDFVocabulary
3839

39-
OWLThing: Final = OWLClass(OWLRDFVocabulary.OWL_THING.get_iri()) #: : :The OWL Class corresponding to owl:Thing
40-
OWLNothing: Final = OWLClass(OWLRDFVocabulary.OWL_NOTHING.get_iri()) #: : :The OWL Class corresponding to owl:Nothing
40+
OWLThing: Final = OWLClass(OWLRDFVocabulary.OWL_THING.iri) #: : :The OWL Class corresponding to owl:Thing
41+
OWLNothing: Final = OWLClass(OWLRDFVocabulary.OWL_NOTHING.iri) #: : :The OWL Class corresponding to owl:Nothing

owlapy/class_expression/class_expression.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
"""OWL Base Classes Expressions"""
12
from abc import abstractmethod, ABCMeta
2-
from ..data_ranges import OWLPropertyRange, OWLDataRange
3+
from ..owl_data_ranges import OWLPropertyRange
34
from ..meta_classes import HasOperands
45

56
from typing import Final, Iterable
7+
8+
69
class OWLClassExpression(OWLPropertyRange):
7-
"""An OWL 2 Class Expression (https://www.w3.org/TR/owl2-syntax/#Class_Expressions) """
10+
"""OWL Class expressions represent sets of individuals by formally specifying conditions on the individuals' properties;
11+
individuals satisfying these conditions are said to be instances of the respective class expressions.
12+
In the structural specification of OWL 2, class expressions are represented by ClassExpression.
13+
(https://www.w3.org/TR/owl2-syntax/#Class_Expressions)
14+
"""
815
__slots__ = ()
916

1017
@abstractmethod

owlapy/class_expression/nary_boolean_expression.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
"""OWL nary boolean expressions"""
12
from .class_expression import OWLClassExpression, OWLBooleanClassExpression
23
from ..meta_classes import HasOperands
34
from typing import Final, Sequence, Iterable
5+
6+
47
class OWLNaryBooleanClassExpression(OWLBooleanClassExpression, HasOperands[OWLClassExpression]):
58
"""OWLNaryBooleanClassExpression."""
69
__slots__ = ()
@@ -30,18 +33,22 @@ def __hash__(self):
3033
return hash(self._operands)
3134

3235

33-
34-
3536
class OWLObjectUnionOf(OWLNaryBooleanClassExpression):
36-
"""Represents an ObjectUnionOf class expression in the OWL 2 Specification."""
37+
"""A union class expression ObjectUnionOf( CE1 ... CEn ) contains all individuals that are instances
38+
of at least one class expression CEi for 1 ≤ i ≤ n.
39+
(https://www.w3.org/TR/owl2-syntax/#Union_of_Class_Expressions)
40+
"""
3741
__slots__ = '_operands'
3842
type_index: Final = 3002
3943

4044
_operands: Sequence[OWLClassExpression]
4145

4246

4347
class OWLObjectIntersectionOf(OWLNaryBooleanClassExpression):
44-
"""Represents an OWLObjectIntersectionOf class expression in the OWL 2 Specification."""
48+
"""An intersection class expression ObjectIntersectionOf( CE1 ... CEn ) contains all individuals that are instances
49+
of all class expressions CEi for 1 ≤ i ≤ n.
50+
(https://www.w3.org/TR/owl2-syntax/#Intersection_of_Class_Expressions)
51+
"""
4552
__slots__ = '_operands'
4653
type_index: Final = 3001
4754

0 commit comments

Comments
 (0)