Hi,

On 08/01/2020 20:57, Andrea Leofreddi wrote:
Hello,
I'm using Jena Fuseki 3.13.1 (with OWLFBRuleReasoner), and I have asserted (uploaded) the following triples:

    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix owl: <http://www.w3.org/2002/07/owl#> .
    @prefix f: <http://vleo.net/family#> .

    f:Bob f:hasWife f:Alice .
    f:Bob f:hasWife f:Alice2 .
    f:Alice2 f:hasHusband f:Bob2 .

    f:hasWife a owl:FunctionalProperty .
    f:hasWife a owl:InverseFunctionalProperty .
    f:hasHusband owl:inverseOf f:hasWife .


Now, If I query and ASK { f:Alice owl:sameAs f:Alice2 }, I get true. However, If I ASK { f:Bob owl:sameAs f:Bob2 }, I get false! Loading the same triples on another reasoner (owl-rl), I get the triple f:Bob owl:sameAs f:Bob2 inferred.

I have asked this very question on StackOverflow (https://stackoverflow.com/questions/59603569/jena-fuseki-missed-inference?noredirect=1#comment105379894_59603569), and I got pointed out to the owl-fb rules file. Tweaking it a bit I noticed that If I explicitly add the forward version of inverseOf, I get that f:Bob owl:sameAs f:Bob2:

    [inverseOf2b: (?P owl:inverseOf ?Q), (?X ?P ?Y) -> (?Y ?Q ?X) ]


Am I missing something?

No, that seems right.

The issue is that the default jena rules file for OWL (the fb rules) uses a mix of forward and backward rules in order to make the various performance/completeness trade-offs.

Those rules are "stratified". All the forward rules run. Then when you ask queries those use the backward rules (including extra backward rules generated by the forward rules) which expand on the results of the forward phase.

This approach allowed us to get usable performance for a range of use cases but with the risk of incomplete results in some cases where the stratification is wrong. The challenge has always been to make the right trade-off for the average use cases while leaving the areas of incompleteness understandable enough that developers can work with it.

Originally sameAs reasoning was done in the backward rules and that proved unscalable due to limitations of the engine. So the sameAs rules were moved to the forward phase. Which means that the existing inverseOf backward phase is missed.

Duplicating the inverseOf reasoning into the forward phase, in the way you've done, is one way to solve this. Since it's working for you, stick with it.

The general solution is not so clear since the cost of this simple approach is that all inverseOf implications are fully materialized in the forward phase, rather than on demand. This means that people who don't care about sameAs but do care about inverses may see a performance hit. Since equality reasoning in jena is really slow then I doubt anyone is relying on that in production whereas the simple things like inverseOf may be in use.

An alternative could be to look at augmenting the sameAs rules with some backward rules which handle the interaction with inverseOf. Should be possible.

If you'd like to create a ticket for this to track the issue that would be great. Though no promises how quickly I could look at this.

Dave

Reply via email to