Skip to content

Fix #1080: preserve ontology IRI when it is both import subject and annotation value - #1179

Closed
Artemis-IA wants to merge 1 commit into
owlcs:version5from
Artemis-IA:fix-1080-clean
Closed

Fix #1080: preserve ontology IRI when it is both import subject and annotation value#1179
Artemis-IA wants to merge 1 commit into
owlcs:version5from
Artemis-IA:fix-1080-clean

Conversation

@Artemis-IA

@Artemis-IA Artemis-IA commented Sep 2, 2026

Copy link
Copy Markdown

Summary

Fixes #1080 — when an ontology declares owl:imports and has a self-referencing annotation (an annotation whose IRI value equals the ontology IRI, e.g. rdfs:isDefinedBy → <ontology-iri>), the RDF/XML parser incorrectly assigns an imported ontology's IRI as the main ontology IRI.

Problem

When parsing RDF/XML, OWLRDFConsumer.chooseAndSetOntologyIRI() selects the ontology IRI from candidate IRIs. When multiple candidates exist (the ontology IRI + imported ontology IRIs), it removes any candidate that also appears as the value of an ontology annotation:

ontology.annotations().forEach(a -> a.getValue().asIRI().ifPresent(iri -> {
    if (ontologyIRIs.contains(iri)) {
        candidateIRIs.remove(iri);
    }
}));

This is meant to avoid picking an IRI that is merely an annotation value. However, the subject of an owl:imports triple (i.e. the importing ontology itself) is also added to ontologyIRIs by TPImportsHandler. If that same IRI appears as an annotation value (a self-referencing annotation), it gets incorrectly removed from candidates, and an imported ontology's IRI is chosen instead.

Self-referencing annotations are valid and standard semantic web practice:

  • rdfs:isDefinedBy → <ontology-iri>
  • omv:URI → <ontology-iri>
  • omv:resourceLocator → <ontology-iri>
  • rdfs:seeAlso → <ontology-iri>

Root Cause Analysis

The bug requires both conditions simultaneously:

  1. The ontology has at least one owl:imports declaration
  2. The ontology has at least one annotation whose IRI value equals the ontology IRI

If only one condition is met, the bug does not trigger (verified by tests).

Why some ontologies are not affected

OSO 1.0.0 has both conditions but is not affected by coincidence: its imports (rdfs#, owl#, skos/core#, foaf/) are also declared as values of omv:useImports annotations with exactly the same IRIs. This causes all candidates to be removed, leaving candidateIRIs empty — in which case the parser does not change the ontology IRI (it stays correct).

OSO 1.1.0 and 1.2.0 have imports (prov-o, wgs84_pos, skos/core, foaf/) that do not all appear as annotation values, so some candidates survive and an imported IRI is wrongly selected.

Fix

Three minimal changes across two files:

OWLRDFConsumer.java

  1. New field ontologySubImportIRIs to track IRIs that are subjects of owl:imports triples.
  2. New overload addOntology(IRI, boolean isImportSubject) that adds to ontologySubImportIRIs when isImportSubject is true.
  3. In chooseAndSetOntologyIRI(), skip removal of candidates that are in ontologySubImportIRIs:
if (ontologyIRIs.contains(iri) && !ontologySubImportIRIs.contains(iri)) {
    candidateIRIs.remove(iri);
}

TripleHandlers.java

  1. TPImportsHandler.handleTriple() calls consumer.addOntology(s, true) instead of consumer.addOntology(s) to mark the import subject.

Tests

7 regression tests in SelfReferenceAnnotationImportsTestCase:

Test Without fix With fix
testSelfReferenceWithImports ❌ FAIL ✅ PASS
testMultipleSelfReferencesWithImports ❌ FAIL ✅ PASS
testVersionIRIPreservedWithSelfRef ❌ FAIL ✅ PASS
testImportsWithoutSelfReference ✅ PASS ✅ PASS
testSelfReferenceWithoutImports ✅ PASS ✅ PASS
testSelfReferenceAsLiteral ✅ PASS ✅ PASS
testAnnotationWithDifferentIRI ✅ PASS ✅ PASS

3 tests fail without the fix and pass with it. 4 pass in both cases (no regression).

Broader Validation

Beyond unit tests, the fix was validated against:

  • 3 OSO ontology versions (1.0.0, 1.1.0, 1.2.0): 1.1.0 and 1.2.0 were broken (returned prov-o instead of OSO), now fixed. 1.0.0 was unaffected by coincidence, remains correct.
  • 9 real-world ontologies (DCAT2, SSN, PROV-O, GeoNames, GoodRelations, FOAF, IAO, RO, BFO): all return identical results before and after the fix — no regression.
  • 8 edge cases (partial import matches, multiple self-refs, self-import, version IRI, no type declaration, multiple ontologies, literal self-ref, 20 imports): all handled correctly.

Impact

This bug affects any OWL API consumer that loads ontologies with both owl:imports and self-referencing annotations. Known affected consumers include:

  • WebVOWL/OWL2VOWL — displays the wrong ontology IRI
  • Protégé (reported in #1181)
  • EarthPortal/AgroPortal ingestion pipelines

Test plan

  • 7 unit tests pass with fix (3 fail without)
  • 3 OSO versions tested (2 fixed, 1 no regression)
  • 9 real-world ontologies tested (no regression)
  • 8 edge cases tested (6 fixed, 2 no regression)

…and annotation value

When an ontology declares owl:imports and has a self-referencing annotation
(an annotation whose IRI value equals the ontology IRI, e.g.
rdfs:isDefinedBy → <ontology-iri>), the RDF/XML parser incorrectly
assigns an imported ontology's IRI as the main ontology IRI.

Root cause: in OWLRDFConsumer.chooseAndSetOntologyIRI(), when multiple
ontology IRI candidates exist, the parser removes any candidate that
appears as the value of an ontology annotation. However, the subject of
an owl:imports triple (i.e. the importing ontology itself) should never
be removed from candidates, even if it also appears as an annotation
value.

Fix: track IRIs that are subjects of owl:imports triples in a new
ontologySubImportIRIs set. In chooseAndSetOntologyIRI(), skip removal
of candidates that are in this set. The TPImportsHandler is updated to
call addOntology(s, true) to mark import subjects.

Self-referencing annotations (rdfs:isDefinedBy, omv:URI,
omv:resourceLocator, rdfs:seeAlso) are valid and standard semantic web
practice. This fix allows ontologies that use them to be parsed correctly
without removing the annotations.

Tests: 7 regression tests in SelfReferenceAnnotationImportsTestCase.
3 tests fail without the fix and pass with it; 4 pass in both cases.
Verified against 3 OSO ontology versions (1.0.0, 1.1.0, 1.2.0) and
9 real-world ontologies (DCAT2, SSN, PROV-O, GeoNames, GoodRelations,
FOAF, IAO, RO, BFO) with no regressions.
Artemis-IA pushed a commit to Artemis-IA/OWL2VOWL that referenced this pull request Sep 2, 2026
Use JitPack build of Artemis-IA/owlapi fix-1080-clean branch which
patches OWL API issue #1080: ontology IRI was incorrectly set to an
imported ontology's IRI when the ontology had both owl:imports and
self-referencing annotations (e.g. rdfs:isDefinedBy → ontology IRI).

This fixes WebVOWL displaying the wrong ontology IRI for affected
ontologies such as OSO 1.1.0 and 1.2.0.

The JitPack artifact is com.github.Artemis-IA.owlapi:owlapi-distribution:f39fc42
built from the same OWL API 5.1.1 source with only the #1080 fix applied.

Once the upstream PR (owlcs/owlapi#1179) is merged, this dependency
should be updated to the official release.
Artemis-IA pushed a commit to Artemis-IA/WebVOWL that referenced this pull request Sep 2, 2026
Build OWL2VOWL from Artemis-IA/OWL2VOWL fix-owlapi-1080 branch which
uses a patched OWL API 5.1.1 that fixes issue #1080: ontology IRI was
incorrectly set to an imported ontology's IRI when the ontology had
both owl:imports and self-referencing annotations.

This fixes WebVOWL displaying the wrong ontology IRI for affected
ontologies such as OSO 1.1.0 and 1.2.0.

End-to-end validation:
- OSO 1.0.0: IRI=https://w3id.org/earthsemantics/OSO, 205 classes, 285 properties
- OSO 1.1.0: IRI=https://w3id.org/earthsemantics/OSO, 199 classes, 286 properties (was prov-o)
- OSO 1.2.0: IRI=https://w3id.org/earthsemantics/OSO, 192 classes, 280 properties (was prov-o)

Once the upstream PRs are merged (owlcs/owlapi#1179 and
VisualDataWeb/OWL2VOWL#76), this should be reverted to use the
official OWL2VOWL master branch.
@Artemis-IA

Copy link
Copy Markdown
Author

Closing this PR as the fix has already been merged upstream in commit b1768cd ("Fixed ontology iri parsing when annotation imports same iri") by @chavez-bermudez.

The upstream fix uses the same approach as this PR:

  • New ontologySubImportIRIs set to track owl:imports subjects
  • addOntology(IRI, boolean) overload
  • !ontologySubImportIRIs.contains(iri) condition in chooseAndSetOntologyIRI()
  • TPImportsHandler calls addOntology(s, true)

The regression tests in this PR may still be useful for validation. Thank you.

@Artemis-IA Artemis-IA closed this Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant