ontology-tools / py-horned-owl

A library for Web Ontology Language in Python created using a bridge from horned-owl to python using PyO3.
https://ontology-tools.github.io/py-horned-owl/
GNU Lesser General Public License v3.0
13 stars 6 forks source link

Provide equivalent to OWL Reasoner API #16

Open cmungall opened 10 months ago

cmungall commented 10 months ago

Motivation: I would like to use the Rust version of @balhoff's Whelk, whelk.rs

Previously I was thinking the way to go would be to write a pyo3 wrapper onto whelk.rs. However, it may make more sense to have a generic wrapper for reasoners, with py-horned-owl providing the interface, just as there is one reasoner API for the OWLAPI

(it might be nice to have some features the owlapi ones lack though, that give access to some of the neater features of whelk)

jannahastings commented 10 months ago

@cmungall @phillord Do you think it might make sense to implement the actual reasoner interface and associated data transer at the level of horned-owl (directly within Rust) and then wrap the interactions with the reasoner within py-horned-owl to provide a python interface around it?

phillord commented 9 months ago

To my mind this is something that we should do at a rust level. Plugging in whelk-rs should be simple to do, although doing it in a performant way might be more challenging.

I don't know enough about the APIs to other reasoners (other than via the OWL API interface) to know how easy a generic interface would be. My own inclination, following on from the general approach I have taken with horned would be to plug in whelk first and then worry about making a more general interface when and if it is needed. That has worked quite well.

b-gehrke commented 6 months ago

I created a first draft of an interface (b-gehrke/horned-owl src/reasoner.rs), implemented it for whelk (b-gehrke/whelk-rs src/whelk/reasoner.rs), and integrated it in py-horned-owl (branch reasoner src/reasoner.rs). The file test/reasoner.py contains an example on how to use it from python.

@cmungall @phillord @balhoff What do you think of it? I would be happy if you could try it out and share your thoughts and opinions.

With this design, reasoners only work with immutable ontologies, while the OWL API supports incremental reasoning. I'm not sure on how to realize this concept in Rust, but I came up with a few approaches:

What are your thoughts on this problem and the approaches?

phillord commented 6 months ago

[like] Phillip Lord reacted to your message:


From: Björn @.> Sent: Wednesday, March 20, 2024 1:42:00 PM To: jannahastings/py-horned-owl @.> Cc: Phil Lord @.>; Mention @.> Subject: Re: [jannahastings/py-horned-owl] Provide equivalent to OWL Reasoner API (Issue #16)

⚠ External sender. Take care when opening links or attachments. Do not provide your login details.

I created a first draft of an interface (b-gehrke/horned-owl src/reasoner.rshttps://github.com/b-gehrke/horned-owl/blob/devel/src/reasoner.rs), implemented it for whelk (b-gehrke/whelk-rs src/whelk/reasoner.rshttps://github.com/b-gehrke/whelk-rs/blob/master/src/whelk/reasoner.rs#L717), and integrated it in py-horned-owl (branch reasoner src/reasoner.rshttps://github.com/jannahastings/py-horned-owl/blob/reasoner/src/reasoner.rs). The file test/reasoner.pyhttps://github.com/jannahastings/py-horned-owl/blob/reasoner/test/reasoner.py contains an example on how to use it from python.

@cmungallhttps://github.com/cmungall @phillordhttps://github.com/phillord @balhoffhttps://github.com/balhoff What do you think of it? I would be happy if you could try it out and share your thoughts and opinions.

With this design, reasoners only work with immutable ontologies, while the OWL API supports incremental reasoning. I'm not sure on how to realize this concept in Rust, but I came up with a few approaches:

What are your thoughts on this problem and the approaches?

— Reply to this email directly, view it on GitHubhttps://github.com/jannahastings/py-horned-owl/issues/16#issuecomment-2009595830, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAAWJ6VOYONQ4WNST2545Z3YZGG2RAVCNFSM6AAAAABAGRELQ6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBZGU4TKOBTGA. You are receiving this because you were mentioned.Message ID: @.***>

phillord commented 6 months ago

This looks good and it is great to see a reasoner interface added to horned-owl.

In practice, I think, I would not use any of your options, but rather an amalgam of 1 and 3. My idea would be to simply plug reasoners into ontologies through the existing OntologyIndex system. This would, effectively, signal events to the reasoner; the reasoner instance would be fully owned by the ontology; and we already have all the mechanisms we need to get access to the putative WhelkReasonerIndex into and out from an ontology. WhelkReasonerIndex could implement both OntologyIndex and your Reasoner. The Reasoner trait could simply drop the for_ontology method. If it is possible, I would move infered_axiom to return an iterator.

We could add a convenience method or two that returns an object implementing Reasoner while owning any ontology; that could be easily implemented over this interface.

Thoughts? Also, would you want this to go into horned-owl directly, or into a sub-crate?

Phil


From: Björn @.> Sent: 20 March 2024 13:42 To: jannahastings/py-horned-owl @.> Cc: Phil Lord @.>; Mention @.> Subject: Re: [jannahastings/py-horned-owl] Provide equivalent to OWL Reasoner API (Issue #16)

⚠ External sender. Take care when opening links or attachments. Do not provide your login details.

I created a first draft of an interface (b-gehrke/horned-owl src/reasoner.rshttps://github.com/b-gehrke/horned-owl/blob/devel/src/reasoner.rs), implemented it for whelk (b-gehrke/whelk-rs src/whelk/reasoner.rshttps://github.com/b-gehrke/whelk-rs/blob/master/src/whelk/reasoner.rs#L717), and integrated it in py-horned-owl (branch reasoner src/reasoner.rshttps://github.com/jannahastings/py-horned-owl/blob/reasoner/src/reasoner.rs). The file test/reasoner.pyhttps://github.com/jannahastings/py-horned-owl/blob/reasoner/test/reasoner.py contains an example on how to use it from python.

@cmungallhttps://github.com/cmungall @phillordhttps://github.com/phillord @balhoffhttps://github.com/balhoff What do you think of it? I would be happy if you could try it out and share your thoughts and opinions.

With this design, reasoners only work with immutable ontologies, while the OWL API supports incremental reasoning. I'm not sure on how to realize this concept in Rust, but I came up with a few approaches:

What are your thoughts on this problem and the approaches?

— Reply to this email directly, view it on GitHubhttps://github.com/jannahastings/py-horned-owl/issues/16#issuecomment-2009595830, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAAWJ6VOYONQ4WNST2545Z3YZGG2RAVCNFSM6AAAAABAGRELQ6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMBZGU4TKOBTGA. You are receiving this because you were mentioned.Message ID: @.***>

b-gehrke commented 6 months ago

Thank you for your feedback.

I've been looking in the OntologyIndex system, but I'm not sure I understand the concept entirely.

What is the relation of OntologyIndex and Ontology? In my understanding, an Ontology relies on one or more OntologyIndex to store Axioms/Components efficiently for lookup. As a user I would only care about using an Ontology implementation that fits my use case best - without knowing or caring about the indexes used. Is that right?

How would we add additional (reasoner-) indexes to an ontology instance?

Regarding your other points:

Thank you

b-gehrke commented 4 months ago

I've updated the horned-owl and whelk-rs forks to represent the changes and make Whelk an ontology index. But trying to use it, I run into problems. In py-horned-owl I would do something like

type WhelkIndexedOntology = TwoIndexedOntology<
    ArcStr,
    Arc<AnnotatedComponent<ArcStr>>,
    SetIndex<ArcStr, Arc<AnnotatedComponent<ArcStr>>>,
    Whelk<ArcStr>>;

#[pyclass(unsendable)]
pub struct PyWhelk(WhelkIndexedOntology);

and build expose all rust methods and additional convenience methods on this python-mapped PyWhelk class. But this leads to a problem: The reasoning methods require a mutable reference but we can only get an immutable reference the the Whelk instance with TwoIndexedOntology::j. What do you think about adding a function exposing a mutable reference to an index? Do you have other ideas?

phillord commented 4 months ago

The reason that we don't do this at the moment is that this would give an easy way to make the two indexes inconsistent; so it could be added, but with some appropriately scary documentation to say if you do change thing don't expect the other indexes to work.

Another possibility would be to allow the Whelk index to own the link to the Whelk reasoner object; or just implement OntologyIndex over the Whelk reasoner instance.