owlcs / owlapi

OWL API main repository
821 stars 315 forks source link

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

Open SimonBin opened 1 year ago

SimonBin commented 1 year ago
@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

SimonBin commented 1 year ago

same issue with for

<https://www.example.org/onto1> 
     ...
     dcterms:isVersionOf <https://www.example.org/onto1> ;
vChavezB commented 9 months ago

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

https://github.com/owlcs/owlapi/blob/b683b03cbe7587fbc8a19c4a44360cfa27a97320/parsers/src/main/java/org/semanticweb/owlapi/rdf/rdfxml/parser/OWLRDFConsumer.java#L1467-L1473

vChavezB commented 9 months ago

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

https://github.com/owlcs/owlapi/blob/b683b03cbe7587fbc8a19c4a44360cfa27a97320/parsers/src/main/java/org/semanticweb/owlapi/rdf/rdfxml/parser/TripleHandlers.java#L1545-L1550

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 :)