owlcs/owlapi

circular property ( like rdfs:isDefinedBy or dcterms:isVersionOf ) in .ttl causes owl:imports to overwrite OntologyIRI

SimonBin opened this issue · 3 comments

@prefix : <https://www.example.org/onto1> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@base <https://www.example.org/onto1> .

<https://www.example.org/onto1> rdf:type owl:Ontology ;
                                owl:imports <https://www.example.org/onto2> ;
                                rdfs:isDefinedBy <https://www.example.org/onto1> .

###  Generated by the OWL API (version 4.5.22.2022-05-07T21:32:11Z) https://github.com/owlcs/owlapi

expected: https://www.example.org/onto1
result: https://www.example.org/onto2

image

same issue with for

<https://www.example.org/onto1> 
     ...
     dcterms:isVersionOf <https://www.example.org/onto1> ;

I encountered this error as well. After debugging the owl api it seems this happens because the OWLRDFConsumer ignores any IRI that is used for annotation

// Choose one that isn't the object of an annotation assertion
Set<IRI> candidateIRIs = createSet(ontologyIRIs);
ontology.annotations().forEach(a -> a.getValue().asIRI().ifPresent(iri -> {
if (ontologyIRIs.contains(iri)) {
candidateIRIs.remove(iri);
}
}));

I think this could be solved if the IRI used as subject for the predicate owl:imports is taken into account as possible IRI.

@Override
public void handleTriple(IRI s, IRI p, IRI o) {
consume(s, p, o);
consumer.addOntology(s);
consumer.addOntology(o);

The in the code I mentioned above in OWLRDFConsumer, do not remove it from candidateIRIS if the IRI is used as subject for imports:

TripleHandler

 public void handleTriple(IRI s, IRI p, IRI o) { 
     consume(s, p, o); 
    // add a second parameter to indicate the IRI is a possible ontology IRI 
    // since its the subject
     consumer.addOntology(s,true); 
     consumer.addOntology(o,false); 
 } 

OWLRDFConsumer

    protected void addOntology(IRI iri,bool subjectIRI) {
        if (ontologyIRIs.isEmpty()) {
            firstOntologyIRI = iri;
        }
        ontologyIRIs.add(iri);
        if (subjectIRI) {
           importsubjectIRI.add(iri)
        }
    }
 ontology.annotations().forEach(a -> a.getValue().asIRI().ifPresent(iri -> { 
     if (ontologyIRIs.contains(iri) && importSubjectIRI != iri) { 
         candidateIRIs.remove(iri); 
     } 
 })); 

Disclaimer: I am not familiar with java syntax. Take this suggestion just as an idea but feel free to improve it :)