Skip to content

v0.3.0rc1

Pre-release
Pre-release
Compare
Choose a tag to compare
@b-gehrke b-gehrke released this 23 Nov 13:07
d5a1eb5

Version 0.3.0rc1

Installation

Install this prerelease with pip install py-horned-owl==0.3.0rc1

Overview - rust native types

Prior to version 0.3.0 axioms and other data types were expressed as S-Expressions-like lists of strings and converted to horned-owl types in rust. With the new version, local rust types (thin wrappers around horned-owl types) are exported directly, allowing a more pythonic way of interacting with the horned owl library. For example, consider the axiom

Class: Child
    SubClassOf: has_parent some Human

This axiom was previously written as

[
    'SubClassOf', 
    ':Child', 
    [
        'ObjectSomeValuesFrom',
        ':has_parent', 'Human'
    ]
]

Now it is written as

SubClassOf(
    Class(IRI.parse(':Child')),
    ObjectSomeValuesFrom(
        ObjectProperty(IRI.parse(':has_parent')),
        Class(IRI.parse(':Human'))
    )
)

In contrast to the S-Expression way, we now use proper types and classes. Datatypes can be created by invoking their constructor or (in case of IRI) their factory method. This does not only improve the readability but also allows type checkers to spot problems.

Type support

In addition to the types theirselves, version 0.3.0 adds python stubs for all classes, their fields and methods, and other functions. They can be used up by language servers and IDEs to further improve the developer experience.

Instance checking

With native rust types being exposed as python classes checking which kind of axiom or class expression is now as easy as checking the runtime type of any other python type using isinstanceof.

Completeness

While previously the conversation between rust and python objects was implemented manually for only a subset of all types in version 0.3.0 the conversion logic is generated by macros for each datatype. Hence, all datatypes occuring in an ontology are now accessible and manipulatable from python.

Performance

A quick comparison of performance shows major improvements in interacting with axioms: For this test, the chebi_core ontology was loaded (three times and then averaged). Then, the number of axioms was counted by iteration over all axioms in the ontology. Lastly 100.000 axioms were added to an empty ontology. Additionally, the performance of horned-owl was recorded as a baseline. Below are the performance results.

Task 0.2.2 0.3.0 horned-owl
Loading chebi 26.2704s 27.5580s 9.9989s
Iterating axioms 2.7132s 1.1928s 3.6232
Adding 100.000 axioms 4.3871s 0.6688s 0.04929ms

It is unclear, why iterating all axioms is slower in native horned-owl.

Alternative approache using JSON or other serializations

Using other serializations like serde(-json) would require creating similar wrappers as now with pyo3. Furthermore, to add the same level of type support, python classes and functions would have to be created or generated to serialize and deserialize on the python side.

Examples

import pyhornedowl
from pyhornedowl.model import *

filename = "/path/to/ontology.owl"
onto = pyhornedowl.open_ontology(filename)  # open and load an ontology
classes = onto.get_classes()  # get all defined classes
axioms = onto.get_axioms()  # get all axioms

axiom = SubClassOf(Class(onto.iri("http://example.com/A")), Class(onto.iri('http://example.com/B')))  # define a new axiom
onto.add_axiom(axiom)  # add axiom to ontology

subclassaxioms = [a for a in axioms if isinstance(a.axiom, SubClassOf)]  # get all SubClassOf axioms

Full Changelog: v0.2.2...v0.3.0rc.1