Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix repair --merge-axiom-annotations #1240

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

gouttegd
Copy link
Contributor

@gouttegd gouttegd commented Feb 6, 2025

Resolves [#1239]

  • docs/ have been added/updated
  • tests have been added/updated
  • mvn verify says all tests pass
  • mvn site says all JavaDocs correct
  • CHANGELOG.md has been updated

The RepairOperation::mergeAxiomAnnotations() method only ever looks at annotated axioms. As a result, it misses the case where the ontology contains both an unannotated axiom and one (or more) annotated version(s) of that same axiom. For example:

SubClassOf(UBERON:1 UBERON:2)
SubClassOf(Annotation(rdfs:comment "A comment") UBERON:1 UBERON:2)
SubClassOf(Annotation(rdfs:comment "Another one") UBERON:1 UBERON:2)

The last two axioms would be merged into a single one carrying the two comments, but the first axiom would remain distinct:

SubClassOf(UBERON:1 UBERON:2)
SubClassOf(Annotation(rdfs:comment "A comment"
           Annotation(rdfs:comment "Another one")
           UBERON:1 UBERON:2)

This PR fixes the issue by rewriting the method to look at all axioms, whether they are annotated or not.

Theoretically, this is slightly inefficient as axioms that are not annotated and that do not have any annotated duplicate (which probably represent the majority of axioms in most ontologies) would still be forcibly removed and then added back. However I do not think that a more elaborated approach would yield enough performance gain to be worth the increased complexity. For what it’s worth, on my machine and with Uberon, the rewritten method is about 20% slower than the original (incorrect) one (running in ~5 seconds instead of ~4 seconds).

Importantly, the test file for this feature had to be converted from RDF/XML to OFN in order to add an instance of an unannotated axiom alongside annotated duplicates of the same axiom -- something the RDF/XML format does not allow to represent).

The RepairOperation::mergeAxiomAnnotations() method only ever looks at
annotated axioms. As a result, it misses the case where the ontology
contains both an unnanotated axiom and one (or more) annotated
version(s) of that same axiom. For example:

  SubClassOf(UBERON:1 UBERON:2)
  SubClassOf(Annotation(rdfs:comment "A comment") UBERON:1 UBERON:2)
  SubClassOf(Annotation(rdfs:comment "Another one") UBERON:1 UBERON:2)

The last two axioms would be merged into a single one carrying the two
comments, but the first one would remain distinct:

  SubClassOf(UBERON:1 UBERON:2)
  SubClassOf(Annotation(rdfs:comment "A comment")
             Annotation(rdfs:comment "Another one")
             UBERON:1 UBERON:2)

We fix that by rewriting the method to forcefully look at _all_ axioms,
whether they are annotated or not.

Theoretically, this is sligthly inefficient as axioms that are not
annotated and that do not have any annotated duplicate would still be
removed and then added back. However I do not think that a more
elaborated approach would yield enough performance gain to be worth the
increased complexity.
Update the test case for `repair --merge-axiom-annotations` so that it
includes an instance of an unannotated axiom associated with annotated
duplicates.

This requires changing the format of the test case file from RDF/XML to
OFN, since RDF/XML does not allow to represent both an unannotated axiom
and an annotated version of the same axiom.
Copy link
Contributor

@matentzn matentzn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation is not only more correct, but also 100 times more readable than my old implementation. Full approve!

manager.removeAxioms(ontology, axiomsToMerge);
for (OWLAxiom axiom : origAxioms) {
annotsByAxiom
.computeIfAbsent(axiom.getAxiomWithoutAnnotations(), k -> new HashSet<>())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never seen this computeIfAbsent but it makes the code so much more compact!

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.

2 participants