owlcs / owlapi

OWL API main repository
826 stars 314 forks source link

Extend OWLReasoner to allow inferred axiom events #567

Open ShishkinDmitriy opened 8 years ago

ShishkinDmitriy commented 8 years ago

Hello, I have some defined classes with restriction on some property and I want to change this property and catch event about classAssertion. Is any solution to catch events from reasoner about added/removed inferred axioms? Even if I have 2 ontologies (one for asserted axioms and second for inferred) I can catch addition events, but not removal.

Best regards, Dmitriy

ykazakov commented 8 years ago

You can register OWLOntologyChangeListener to listen to (syntactic) changes in OWLOntologies, but, to the best of my knowledge, there is no way to listen to changes for the inferred axioms since there is no such a thing like "ontology consisting of inferred axioms". The reasoner may compute inferences only when they are explicitly queried by the methods like getInstances(). There is a method precomputeInferences() of OWLReasoner, but it is just a hint for the reasoner that the user is interested in particular types of queries, and the reasoner contract does not require to do anything in this case. In my opinion, this is one of the serious limitations of OWL API that it is not possible to effectively monitor changes in the entailed axioms (like class hierarchy and instances).

ignazio1977 commented 7 years ago

We can extend OWLReasoner to allow for this (in version 5) with default methods, however it will be up to the reasoners to provide data this way - which, from past experience, means that it will take a while before they all provide comparable data :-)

ykazakov commented 7 years ago

@ignazio1977 do you have a concrete suggestion for extension of an interface? Using some kind of entailment change listener? How to tell a reasoner which entailments it should "maintain"? ELK (and I guess most reasoners) already keep track of the taxonomy and instance taxonomy, so reporting changes in these objects should not be much of a problem. But reporting changes to arbitrary entailments can be problematic as the number of potential entailments is infinite.

ignazio1977 commented 7 years ago

Not a concrete example, more of a thought. I was thinking a listener for the same kind of entailment that can be materialized by the inferred axiom generators, with a guarantee of correctness not completeness. Same for loss of entailments - I think this would be even harder to track exactly, since there would be work required to figure out what no longer is there.

A very expensive implementation, for testing purposes only, would be to run the inferred axiom generators before and after a change, and diff the outputs to figure out what the results should be.

ykazakov commented 7 years ago

I think OWL API should provide proper interfaces for class/object property/instance taxonomies since these are most commonly used reasoning results. Instead of precomputing taxonomies there should be just a method to get the taxonomy object (which may still be initialised lazily). Then one can register various change listeners to taxonomy in a similar way as listeners to owl api ontology. ELK, for example, internally uses such taxonomy objects. See here https://github.com/liveontologies/elk-reasoner/tree/master/elk-reasoner/src/main/java/org/semanticweb/elk/reasoner/taxonomy/model. The interface hierarchy is roughly as follows:

interface Node {

 Set<T> getMembers();

}

interface TaxonomyNode<T, N extends Node> extends Node {

 Collection<N> getSubNodes();

 Collection<N> getSuperNodes();

}

interface TypeNode<T, I, N extends Node, IN extends Node> extends TaxonomyNode {

 Collection<IN> getInstances();

}

interface InstanceNode<T, I, N extends Node> extends Node {

Collection<N> getTypes();

}

interface NodeStore<T, N extends Node> {

Collection<N> getNodes();

// returns the node containing a given member
N getNode(T member);

}

interface Taxonomy<T, N extends TaxonomyNode> extends NodeStore<T, N> {

  N getTopNode();

  N getBottomNode();

}

interface InstanceTaxonomy<T, I, N extends TypeNode<T, I, N, IN>, IN extends InstanceNode<T, I, N>> extends Taxonomy<T, N> {

Collection<IN> getInstanceNodes();

IN getInstanceNode(I member);

}

Then these generic interfaces can be "projected" with particular type values, e.g.,

OWLClassNode extends TaxonomyNode {

}

OWLObjectPropertyNode extends TaxonomyNode {

}

OWLTypeNode extends TypeNode<OWLClass, OWLIndividual, OWLTypeNode, OWLInstanceNode> {

}

OWLInstanceNode extends InstanceNode<OWLClass, OWLIndividual, OWLTypeNode> {

}

interface OWLClassTaxonomy extends Taxonomy<OWLClass, OWLClassNode> {

}

interface OWLObjectPropertyTaxonomy extends Taxonomy<OWLObjectProperty, OWLObjectPropertyNode> {

}

interface OWLInstanceTaxonomy extends InstanceTaxonomy<OWLClass, OWLIndividual, OWLTypeNode, OWLInstanceNode> {

}

ykazakov commented 7 years ago

Also one can provide similar objects for (complex) class queries and entailment queries in which one can register change listeners.

apeteri commented 7 years ago

It would also be helpful to treat the input taxonomy as the initial state until the first (pre-)computation run succeeds, at which point inferences could be reported through the change listener mechanism.