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

Cyclic imports and missing declarations cause parsing error #798

Open
daltontc opened this issue Oct 30, 2018 · 26 comments
Open

Cyclic imports and missing declarations cause parsing error #798

daltontc opened this issue Oct 30, 2018 · 26 comments
Labels

Comments

@daltontc
Copy link
Contributor

If I have 2 ontologies that import each other and one of them has AnnotationAxioms, the ontology with AnnotationAxioms will not resolve properly due to how the ontologies are compared for equivalency. The first time an ontology is evaluated to see if it is equivalent, the object used is without the AnnotationAxioms. After it passes and is renamed, it is added to the list of ontologies in the closure. Then, after the fact, the AnnotationAxioms are added back into that ontology in the list. When the ontology is evaluated again later, it fails because the ontologies aren't equal because the object passed in doesn't have AnnotationAxiom whilst the one in the list of ontologies does.

Is this the intended design? Not processing AnnotationAxioms in the config is not an option for me either.

@ignazio1977
Copy link
Contributor

Do you have an example to share? There are recent bug fixes in the area which have not been released yet.

@daltontc
Copy link
Contributor Author

ImportsHasAnnotationAxiom.txt
HasAnnotationAxiom.txt

Github wouldn't let me upload .ttl files so I changed the extension to.txt.

When I try to process HasAnnotationAxiom with a config of private final OWLOntologyLoaderConfiguration config = new OWLOntologyLoaderConfiguration().setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT);, I get a stacktrace of:

Caused by: org.semanticweb.owlapi.model.OWLOntologyRenameException: Could not rename ontology. An ontology with this ID already exists: OntologyID(OntologyIRI(<https://mobi.com/ontologies/10/2018/HasAnnotationAxiom>) VersionIRI(<null>))
	at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.checkForOntologyIDChange(OWLOntologyManagerImpl.java:734) ~[?:?]
	at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.enactChangeApplication(OWLOntologyManagerImpl.java:593) ~[?:?]
	at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.actuallyApply(OWLOntologyManagerImpl.java:641) ~[?:?]
	at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.applyChangesAndGetDetails(OWLOntologyManagerImpl.java:610) ~[?:?]
	at org.semanticweb.owlapi.model.HasApplyChanges.applyChanges(HasApplyChanges.java:37) ~[?:?]
	at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.applyChange(OWLOntologyManagerImpl.java:689) ~[?:?]
	at org.semanticweb.owlapi.model.OWLOntology.applyChange(OWLOntology.java:92) ~[?:?]
	at uk.ac.manchester.cs.owl.owlapi.concurrent.ConcurrentOWLOntologyImpl.applyChange(ConcurrentOWLOntologyImpl.java:2489) ~[?:?]
	at org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer.chooseAndSetOntologyIRI(OWLRDFConsumer.java:1491) ~[?:?]
	at org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer.endModel(OWLRDFConsumer.java:1409) ~[?:?]
	at org.semanticweb.owlapi.rio.RioOWLRDFConsumerAdapter.endRDF(RioOWLRDFConsumerAdapter.java:80) ~[?:?]
	at org.semanticweb.owlapi.rio.RioParserImpl$RioParserRDFHandler.endRDF(RioParserImpl.java:278) ~[?:?]
	at org.semanticweb.owlapi.rio.RioParserImpl.parse(RioParserImpl.java:123) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntology.createOntologyFromSesameModel(SimpleOntology.java:303) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntology.<init>(SimpleOntology.java:207) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.createOntology(SimpleOntologyManager.java:213) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.createOntologyFromCommit(SimpleOntologyManager.java:518) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.getOntology(SimpleOntologyManager.java:498) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.lambda$retrieveOntology$1(SimpleOntologyManager.java:281) ~[?:?]
	at java.util.Optional.flatMap(Optional.java:241) ~[?:?]
	at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.retrieveOntology(SimpleOntologyManager.java:281) ~[?:?]
	at com.mobi.ontology.rest.impl.OntologyRestImpl.getOntology(OntologyRestImpl.java:1152) ~[?:?]
	at com.mobi.ontology.rest.impl.OntologyRestImpl.getOntology(OntologyRestImpl.java:227) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]```

@ignazio1977
Copy link
Contributor

#788 exhibited a similar stack trace and #791 fixed issues related to the order in which ontology annotations are parsed. With the latest version5 code, I do not get the exception any more, so I assume these bug fixes sorted this issue as well.

The fix will be included in 5.1.8 once it is released.

@daltontc
Copy link
Contributor Author

daltontc commented Jan 8, 2019

bao_core.owl.txt
bao_complete.owl.txt

This issue is still happening with the circular dependency between bao_core and bao_complete from Bioassay

@daltontc
Copy link
Contributor Author

daltontc commented Jan 8, 2019

I am using 5.1.9

@daltontc
Copy link
Contributor Author

daltontc commented Jan 8, 2019

@ignazio1977 Can I use this issue still or should I create a new issue?

@ignazio1977 ignazio1977 reopened this Jan 8, 2019
@ignazio1977
Copy link
Contributor

This one is fine

@daltontc
Copy link
Contributor Author

Has there been any updates on this? Have you been able to replicate the issue with the provided ontologies?

@ignazio1977
Copy link
Contributor

I've tried to replicate this but failed again.

I've added some debug calls and, at the point where the stack trace above, the ontologies being compared have the same annotation axioms:

import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat;
import org.semanticweb.owlapi.io.IRIDocumentSource;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.util.VersionInfo;

public class bao {
public static void main(String[] args) throws OWLOntologyCreationException {
    System.out.println("bao.main() " + VersionInfo.getVersionInfo());
    OWLManager.createOWLOntologyManager()
        .loadOntologyFromOntologyDocument(new IRIDocumentSource(
            IRI.create("http://www.bioassayontology.org/bao/bao_core.owl"),
            new RDFXMLDocumentFormat(), null));
}
}


bao.main() The OWL API (version 5.1.10-SNAPSHOT)
HasAxiomsByType.equalAxioms() 
Ontology(OntologyID(Anonymous-2)) [Axioms: 876 Logical Axioms: 467] First 20 axioms: {...}
Ontology(OntologyID(OntologyIRI(<http://www.bioassayontology.org/bao/bao_core.owl>) VersionIRI(<http://www.bioassayontology.org/bao/bao_core.owl>))) [Axioms: 876 Logical Axioms: 467] First 20 axioms: {...}

Would you mind running the code above in your setup, just to confirm there is only one OWLAPI version in your path?

@ignazio1977
Copy link
Contributor

Looking at the stack trace line numbers, I believe your first error came from OWLAPI 5.1.7. I've tried running my code with that version, but still cannot replicate the problem.

At the bottom of the stack trace, the classes involved appear to use a Sesame model as source for the ontology. Maybe the translation causes the order in which triples are seen to be different, and that's what's triggering the exception. Can you share that code?

@daltontc
Copy link
Contributor Author

The first error was from OWLAPI 5.1.7. The newer error with BAO is definitely 5.1.9. It looks like the error stems from the VersionIRI matching the OntologyIRI in bao_complete.owl.

Caused by: org.semanticweb.owlapi.model.OWLOntologyRenameException: Could not rename ontology. An ontology with this ID already exists: OntologyID(OntologyIRI(<http://www.bioassayontology.org/bao/bao_complete.owl>) VersionIRI(<http://www.bioassayontology.org/bao/bao_complete.owl>))
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.checkForOntologyIDChange(OWLOntologyManagerImpl.java:736) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.enactChangeApplication(OWLOntologyManagerImpl.java:595) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.actuallyApply(OWLOntologyManagerImpl.java:643) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.applyChangesAndGetDetails(OWLOntologyManagerImpl.java:612) ~[?:?]
        at org.semanticweb.owlapi.model.HasApplyChanges.applyChanges(HasApplyChanges.java:37) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.applyChange(OWLOntologyManagerImpl.java:691) ~[?:?]
        at org.semanticweb.owlapi.model.OWLOntology.applyChange(OWLOntology.java:92) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.concurrent.ConcurrentOWLOntologyImpl.lambda$applyChange$174(ConcurrentOWLOntologyImpl.java:1516) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.concurrent.ConcurrentOWLOntologyImpl.withWriteLock(ConcurrentOWLOntologyImpl.java:161) ~[?:?]
        at uk.ac.manchester.cs.owl.owlapi.concurrent.ConcurrentOWLOntologyImpl.applyChange(ConcurrentOWLOntologyImpl.java:1516) ~[?:?]
        at org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer.chooseAndSetOntologyIRI(OWLRDFConsumer.java:1490) ~[?:?]
        at org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer.endModel(OWLRDFConsumer.java:1406) ~[?:?]
        at org.semanticweb.owlapi.rio.RioOWLRDFConsumerAdapter.endRDF(RioOWLRDFConsumerAdapter.java:80) ~[?:?]
        at org.semanticweb.owlapi.rio.RioParserImpl$RioParserRDFHandler.endRDF(RioParserImpl.java:279) ~[?:?]
        at org.semanticweb.owlapi.rio.RioParserImpl.parse(RioParserImpl.java:123) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntology.createOntologyFromSesameModel(SimpleOntology.java:303) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntology.<init>(SimpleOntology.java:207) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.createOntology(SimpleOntologyManager.java:227) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.createOntologyFromCommit(SimpleOntologyManager.java:556) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.getOntology(SimpleOntologyManager.java:536) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.lambda$retrieveOntology$1(SimpleOntologyManager.java:297) ~[?:?]
        at java.util.Optional.flatMap(Optional.java:241) ~[?:?]
        at com.mobi.ontology.core.impl.owlapi.SimpleOntologyManager.retrieveOntology(SimpleOntologyManager.java:297) ~[?:?]
        at com.mobi.ontology.rest.impl.OntologyRestImpl.getOntology(OntologyRestImpl.java:1157) ~[?:?]
        at com.mobi.ontology.rest.impl.OntologyRestImpl.getOntology(OntologyRestImpl.java:228) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
        at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.internal.Errors.process(Errors.java:267) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223) ~[15:com.eclipsesource.jaxrs.jersey-min:2.22.1]
        at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service(ServletContainerBridge.java:76) ~[?:?]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841) ~[?:?]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650) ~[?:?]
        at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206) ~[?:?]
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637) ~[?:?]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533) ~[?:?]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) ~[?:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[?:?]
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) ~[?:?]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[?:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190) ~[?:?]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) ~[?:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) ~[?:?]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253) ~[?:?]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:293) ~[?:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) ~[?:?]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) ~[?:?]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) ~[?:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) ~[?:?]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155) ~[?:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[?:?]
        at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80) ~[?:?]
        ... 17 more

@daltontc
Copy link
Contributor Author

First Pass
change = {SetOntologyID@15974} "SetOntologyID(OntologyID(OntologyIRI(<http://www.bioassayontology.org/bao/bao_complete.owl>) VersionIRI(<http://www.bioassayontology.org/bao/bao_complete.owl>)) OntologyID(OntologyID(Anonymous-108)))"
o = {ConcurrentOWLOntologyImpl@15957} "Ontology(OntologyID(Anonymous-108)) [Axioms: 11349 Logical Axioms: 364] First 20 axioms: {Declaration(Class(<http://purl.obolibrary.org/obo/CHEBI_33281>)) Declaration(Class(<http://purl.obolibrary.org/obo/GO_0030334>)) Declaration(Class(<http://purl.obolibrary.org/obo/GO_0000302>)) Declaration(Class(<http://purl.obolibrary.org/obo/GO_0016301>)) Declaration(Class(<http://purl.obolibrary.org/obo/CLO_0000001>)) Declaration(Class(<http://purl.obolibrary.org/obo/GO_0060964>)) Declaration(Class(<http://www.bioassayontology.org/bao#BAO_0003052>)) Declaration(Class(<http://www.bioassayontology.org/bao#BAO_0000862>)) Declaration(Class(<http://www.bioassayontology.org/bao#BAO_0002925>)) Declaration(Class(<http://purl.obolibrary.org/obo/GO_0001591>)) Declaration(Class(<http://www.bioassayontology.org/bao#BAO_0000916>)) Declaration(Class(<http://www.bioassayontology.org/bao#BAO_0001216>)) Declaration(Class(<http://www.bioassayontology.org/bao#BAO_0003075>)) Declaration(Class(<http://purl.obolibrar"… View

Second
change = {SetOntologyID@16112} "SetOntologyID(OntologyID(OntologyIRI(<http://www.bioassayontology.org/bao/bao_complete.owl>) VersionIRI(<http://www.bioassayontology.org/bao/bao_complete.owl>)) OntologyID(OntologyID(Anonymous-82)))"
o = {ConcurrentOWLOntologyImpl@16110} "Ontology(OntologyID(Anonymous-82)) [Axioms: 11345 Logical Axioms: 364] First 20 axioms: {EquivalentClasses(<http://www.bioassayontology.org/bao#BAO_0000021> ObjectSomeValuesFrom(<http://www.bioassayontology.org/bao#BAO_0000135> <http://purl.obolibrary.org/obo/GO_0005764>) ) EquivalentClasses(<http://www.bioassayontology.org/bao#BAO_0003014> ObjectIntersectionOf(<http://www.bioassayontology.org/bao#BAO_0003006> ObjectSomeValuesFrom(<http://www.bioassayontology.org/bao#BAO_0000212> <http://www.bioassayontology.org/bao#BAO_0000151>) ObjectSomeValuesFrom(<http://www.bioassayontology.org/bao#BAO_0002009> ObjectUnionOf(<http://purl.obolibrary.org/obo/GO_0006355> <http://www.bioassayontology.org/bao#BAO_0002890>))) ) EquivalentClasses(<http://www.bioassayontology.org/bao#BAO_0002594> ObjectIntersectionOf(<http://www.bioassayontology.org/bao#BAO_0002593> ObjectSomeValuesFrom(<http://www.bioassayontology.org/bao#BAO_0000207> <http://www.bioassayontology.org/bao#BAO_0000045>) ObjectSomeValuesFro"… View

It seems like there are 4 axioms different when comparing ontologies?

@daltontc
Copy link
Contributor Author

Sorry if I didn't communicate this well before. The issue is with http://www.bioassayontology.org/bao/bao_complete.owl. I ran the code you provided and that is fine, but when I switch the IRI to bao_complete, then the issue reveals itself.

I believe that bao_complete imports bao_core which imports bao_complete. The circular import is where the issue is.

@ignazio1977
Copy link
Contributor

The issue is with http://www.bioassayontology.org/bao/bao_complete.owl. I ran the code you provided and that is fine, but when I switch the IRI to bao_complete, then the issue reveals itself.

Thanks, that finally allowed me to replicate the failure. I'm also seeing another issue - I get random errors stating the XML is not well formed, always at different lines. This disappears if I open the connection, read all content into a local buffer and then parse from the buffer, making me wonder if the issue is related to timeouts happening while the parsing is ongoing.

@ignazio1977
Copy link
Contributor

Switching on logging at the error level, turns out there are four axioms that cannot be parsed properly on the first pass, this causes them to be parsed with #ErrorX IRIs - this ultimately causes the mismatch.

My guess at this point is that there are properties declared in the import closure but the circular dependency gets in the way of proper resolution.

2019-02-28 19:52:11:457 +0000 [main] ERROR org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer - Entity not properly recognized, missing triples in input? #Error1 for type Class
2019-02-28 19:52:11:485 +0000 [main] ERROR org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer - Entity not properly recognized, missing triples in input? #Error2 for type Class
2019-02-28 19:52:11:486 +0000 [main] ERROR org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer - Entity not properly recognized, missing triples in input? #Error3 for type Class
2019-02-28 19:52:11:488 +0000 [main] ERROR org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer - Entity not properly recognized, missing triples in input? #Error4 for type Class
2019-02-28 19:52:18:926 +0000 [main] ERROR uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl - OWLOntologyManagerImpl.checkForOntologyIDChange() only in existing:[
EquivalentClasses(<bao#BAO_0000178> ObjectIntersectionOf(ObjectAllValuesFrom(<bao#BAO_0090004> <bao#BAO_0000015>) <#Error3>) )
EquivalentClasses(<bao#BAO_0002114> ObjectIntersectionOf(<#Error4> <bao#BAO_0000179> ObjectSomeValuesFrom(<bao#BAO_0002668> <obo/UO_0000003>) ObjectAllValuesFrom(<bao#BAO_0002668> <obo/UO_0000003>)) ), 
EquivalentClasses(<bao#BAO_0000180> ObjectIntersectionOf(<#Error2> <bao#BAO_0000179> ObjectSomeValuesFrom(<bao#BAO_0000183> <obo/UO_0000051>) ObjectAllValuesFrom(<bao#BAO_0000183> <obo/UO_0000051>)) ), 
EquivalentClasses(<bao#BAO_0000585> ObjectIntersectionOf(<#Error1> <bao#BAO_0000179> ObjectSomeValuesFrom(<bao#BAO_0000097> <obo/UO_0000005>) ObjectAllValuesFrom(<bao#BAO_0000097> <obo/UO_0000005>)) ), 
]

2019-02-28 19:52:18:929 +0000 [main] ERROR uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl - OWLOntologyManagerImpl.checkForOntologyIDChange() only in new:[
EquivalentClasses(<bao#BAO_0000178> ObjectIntersectionOf(ObjectAllValuesFrom(<bao#BAO_0090004> <bao#BAO_0000015>) ObjectMinCardinality(1 <bao#BAO_0090004> <bao#BAO_0000015>)) ), 
EquivalentClasses(<bao#BAO_0000585> ObjectIntersectionOf(<bao#BAO_0000179> ObjectSomeValuesFrom(<bao#BAO_0000097> <obo/UO_0000005>) ObjectAllValuesFrom(<bao#BAO_0000097> <obo/UO_0000005>) DataExactCardinality(1 <bao#BAO_0000109> xsd:float)) ), 
EquivalentClasses(<bao#BAO_0000180> ObjectIntersectionOf(<bao#BAO_0000179> ObjectSomeValuesFrom(<bao#BAO_0000183> <obo/UO_0000051>) ObjectAllValuesFrom(<bao#BAO_0000183> <obo/UO_0000051>) DataExactCardinality(1 <bao#BAO_0002666> xsd:float)) ), 
EquivalentClasses(<bao#BAO_0002114> ObjectIntersectionOf(<bao#BAO_0000179> ObjectSomeValuesFrom(<bao#BAO_0002668> <obo/UO_0000003>) ObjectAllValuesFrom(<bao#BAO_0002668> <obo/UO_0000003>) DataExactCardinality(1 <bao#BAO_0002669> xsd:float)) )
]

@ignazio1977
Copy link
Contributor

It is difficult to design a general solution: with non cyclic imports, it is sufficient to parse the imported ontologies before the current ontology, recursively, to guarantee that all relevant declarations have been seen. But with a cyclic import, it is necessary to parse all ontologies to make sure all entity declarations have been seen, before all axioms can be successfully parsed. The current strategy fails because the declarations are in the ontologies standing between the two occurrences of bao_complete.owl. These ontologies have not been parsed yet when the second instance of bao_complete is parsed, so the entities declared only there are unknown - but become known when parsing the first occurrence, which is why the existing ontology has Error1, 2, 3, 4 and the new ontology does not.

It's a pretty big refactor of all the parsers to allow axiom parsing to be delayed until all ontologies have been parsed, so I'm not sure how long it is going to take to address.

In the meantime, a workaround would be to add the missing declarations to the ontology - duplicate declarations in the import closure do not cause errors, not until there are changes to be made, anyway. Another workaround would be to remove the cycle - is it correct for bao_core to import bao_complete? From the names, I'd think bao_core would be a subset of bao.

@daltontc
Copy link
Contributor Author

Unfortunately I do not manage bao_complete.owl and someone wants to upload it into our tool. Would you perhaps be able to give a rough estimate how long the refactor would take?

@ignazio1977 ignazio1977 changed the title AnnotationAxioms aren't used in Ontology equivalency Cyclic imports and missing declarations cause parsing error Mar 3, 2019
ignazio1977 added a commit that referenced this issue Mar 3, 2019
Ontology A imports ontology B, ontology B imports ontoloy A and ontology
C, ontology C provides declaration for property P, ontology A uses
property P.

When loading A through its IRI, an ontology rename failure exception is
raised. the reason is that A is parsed twice, once before and once after
ontology C is parsed. However, when ontology C has yet to be parsed,
there is no declaration available for P. This means that P is assumed to
be an annotation property (only possible assumption, as the alternative
is to throw a parsing error), and when the parsing of A completes, its
id needs to be set with the value read from the ontology.

However, at this point the two ontologies have the same id but not the
same content - P has one guessed type and one parsed type, and the
corresponding axioms differ. Hence, the api interprets this as two
diffrent ontologies with the same id - which cannot coexist in the same
manager.

The full solution for this is for the parsers to work on two levels:
ontology imports closure and entity declarations parsing, and axiom
parsing. The ontologies to import and the declarations in each ontology
would be parsed first, and once the closure has been computed, each
ontology can be parsed with full knowledge of the entities declared -
this removes the source of the error, in that there won't be any more
cases of entities being used when their declaration has not been
processed yet due to imports resolution and cycles. (This is how parsing
is outlined in the specs, but it's not working exactly this way in
practice and it's a considerable refactor for the current parsers.)

(Other root issue: cycles in imports, this is not an indicator of a
healthy ontology structure. It's allowed in OWL 2, but I cannot think of
a scenario where the ontolgies wouldn't be easier to work with with
imports refactored to not be cyclic).

Luckily, when loading by IRIs, it's easy to avoid double parsing by
adding the root ontology used at load time to the map of ontologies
being imported, which is currently used to skip ultiple imports in the
imports closure. The root was not included in this mechanism, for some
reason - it should have been. Removing double parsing removes both
issues, however the problem remains for root ontologies loaded from file
or stream.
ignazio1977 added a commit that referenced this issue Mar 3, 2019
Ontology A imports ontology B, ontology B imports ontoloy A and ontology
C, ontology C provides declaration for property P, ontology A uses
property P.

When loading A through its IRI, an ontology rename failure exception is
raised. the reason is that A is parsed twice, once before and once after
ontology C is parsed. However, when ontology C has yet to be parsed,
there is no declaration available for P. This means that P is assumed to
be an annotation property (only possible assumption, as the alternative
is to throw a parsing error), and when the parsing of A completes, its
id needs to be set with the value read from the ontology.

However, at this point the two ontologies have the same id but not the
same content - P has one guessed type and one parsed type, and the
corresponding axioms differ. Hence, the api interprets this as two
diffrent ontologies with the same id - which cannot coexist in the same
manager.

The full solution for this is for the parsers to work on two levels:
ontology imports closure and entity declarations parsing, and axiom
parsing. The ontologies to import and the declarations in each ontology
would be parsed first, and once the closure has been computed, each
ontology can be parsed with full knowledge of the entities declared -
this removes the source of the error, in that there won't be any more
cases of entities being used when their declaration has not been
processed yet due to imports resolution and cycles. (This is how parsing
is outlined in the specs, but it's not working exactly this way in
practice and it's a considerable refactor for the current parsers.)

(Other root issue: cycles in imports, this is not an indicator of a
healthy ontology structure. It's allowed in OWL 2, but I cannot think of
a scenario where the ontolgies wouldn't be easier to work with with
imports refactored to not be cyclic).

Luckily, when loading by IRIs, it's easy to avoid double parsing by
adding the root ontology used at load time to the map of ontologies
being imported, which is currently used to skip ultiple imports in the
imports closure. The root was not included in this mechanism, for some
reason - it should have been. Removing double parsing removes both
issues, however the problem remains for root ontologies loaded from file
or stream.
ignazio1977 added a commit that referenced this issue Mar 4, 2019
Ontology A imports ontology B, ontology B imports ontoloy A and ontology
C, ontology C provides declaration for property P, ontology A uses
property P.

When loading A through its IRI, an ontology rename failure exception is
raised. the reason is that A is parsed twice, once before and once after
ontology C is parsed. However, when ontology C has yet to be parsed,
there is no declaration available for P. This means that P is assumed to
be an annotation property (only possible assumption, as the alternative
is to throw a parsing error), and when the parsing of A completes, its
id needs to be set with the value read from the ontology.

However, at this point the two ontologies have the same id but not the
same content - P has one guessed type and one parsed type, and the
corresponding axioms differ. Hence, the api interprets this as two
diffrent ontologies with the same id - which cannot coexist in the same
manager.

The full solution for this is for the parsers to work on two levels:
ontology imports closure and entity declarations parsing, and axiom
parsing. The ontologies to import and the declarations in each ontology
would be parsed first, and once the closure has been computed, each
ontology can be parsed with full knowledge of the entities declared -
this removes the source of the error, in that there won't be any more
cases of entities being used when their declaration has not been
processed yet due to imports resolution and cycles. (This is how parsing
is outlined in the specs, but it's not working exactly this way in
practice and it's a considerable refactor for the current parsers.)

(Other root issue: cycles in imports, this is not an indicator of a
healthy ontology structure. It's allowed in OWL 2, but I cannot think of
a scenario where the ontolgies wouldn't be easier to work with with
imports refactored to not be cyclic).

Luckily, when loading by IRIs, it's easy to avoid double parsing by
adding the root ontology used at load time to the map of ontologies
being imported, which is currently used to skip ultiple imports in the
imports closure. The root was not included in this mechanism, for some
reason - it should have been. Removing double parsing removes both
issues, however the problem remains for root ontologies loaded from file
or stream.
@ignazio1977
Copy link
Contributor

Unfortunately I do not manage bao_complete.owl and someone wants to upload it into our tool.

If your tool works via the load*(IRI) methods, this fix will allow it to load the ontology correctly. I can't guess at how long it will take to do the complete fix.

@ignazio1977
Copy link
Contributor

This fix is in release 5.1.10, which should now be on maven central.

@daltontc
Copy link
Contributor Author

daltontc commented Mar 5, 2019

We actually use the RioParser to parse a sesame model where this is breaking so I don't believe this fix will help us just yet :(

@ignazio1977
Copy link
Contributor

Uhm...

Loading any ontology included in the cycle yields the same imports closure, so what happens if instead of trying to upload bao_complete you try to upload bao_core? Bao_complete should be pulled in as an imports closure member, and saving the ontology by default adds missing declarations, so after the first load and save things might work all right.

Similarly, loading manually with code like mine and saving a local copy should create a corrected file, which could then be uploaded to your tool, or modified as needed.

@ignazio1977 ignazio1977 added bug and removed duplicate labels Mar 10, 2019
ignazio1977 added a commit that referenced this issue Sep 24, 2022
Ontology A imports ontology B, ontology B imports ontoloy A and ontology
C, ontology C provides declaration for property P, ontology A uses
property P.

When loading A through its IRI, an ontology rename failure exception is
raised. the reason is that A is parsed twice, once before and once after
ontology C is parsed. However, when ontology C has yet to be parsed,
there is no declaration available for P. This means that P is assumed to
be an annotation property (only possible assumption, as the alternative
is to throw a parsing error), and when the parsing of A completes, its
id needs to be set with the value read from the ontology.

However, at this point the two ontologies have the same id but not the
same content - P has one guessed type and one parsed type, and the
corresponding axioms differ. Hence, the api interprets this as two
diffrent ontologies with the same id - which cannot coexist in the same
manager.

The full solution for this is for the parsers to work on two levels:
ontology imports closure and entity declarations parsing, and axiom
parsing. The ontologies to import and the declarations in each ontology
would be parsed first, and once the closure has been computed, each
ontology can be parsed with full knowledge of the entities declared -
this removes the source of the error, in that there won't be any more
cases of entities being used when their declaration has not been
processed yet due to imports resolution and cycles. (This is how parsing
is outlined in the specs, but it's not working exactly this way in
practice and it's a considerable refactor for the current parsers.)

(Other root issue: cycles in imports, this is not an indicator of a
healthy ontology structure. It's allowed in OWL 2, but I cannot think of
a scenario where the ontolgies wouldn't be easier to work with with
imports refactored to not be cyclic).

Luckily, when loading by IRIs, it's easy to avoid double parsing by
adding the root ontology used at load time to the map of ontologies
being imported, which is currently used to skip ultiple imports in the
imports closure. The root was not included in this mechanism, for some
reason - it should have been. Removing double parsing removes both
issues, however the problem remains for root ontologies loaded from file
or stream.
@giacomoronconiobda
Copy link

giacomoronconiobda commented Nov 4, 2022

I have the same problem with the Ontopia ontology.

ontopia.zip

I cannot understand how is it possible that the ontology is imported correctly in Protege. However it seems that the Ontology IRIs are parsed in a wrong way.
199458516-e5632946-cb7a-440f-a343-96c9872357b3

199522457-58b18b7f-0f35-44a4-a1e2-ff13e7c30ed9

@vChavezB
Copy link

I have the same problem with the Ontopia ontology.

ontopia.zip

I cannot understand how is it possible that the ontology is imported correctly in Protege. However it seems that the Ontology IRIs are parsed in a wrong way. 199458516-e5632946-cb7a-440f-a343-96c9872357b3

199522457-58b18b7f-0f35-44a4-a1e2-ff13e7c30ed9

I have made a PR to try to solve this. Please check #1117 and protegeproject/protege#1181 (comment)

@giacomoronconiobda
Copy link

Thanks but actually I use the owlapi directly from java. I reimplemented the import mechanism by myself...

@vChavezB
Copy link

vChavezB commented Nov 26, 2023

Thanks but actually I use the owlapi directly from java. I reimplemented the import mechanism by myself...

Ah ok. Yes the PR is actually to fix this in the owl api which in turn I use in protege.

Edit: Ok i just saw your PR #1060
Good to know!

Regards

@vChavezB
Copy link

issue should be solved, with fff1319

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants