Skip to content

Commit

Permalink
Merge pull request #533 from balhoff/issue-518
Browse files Browse the repository at this point in the history
Some refactoring of ReasonOperation.
  • Loading branch information
jamesaoverton authored Jul 19, 2019
2 parents c6110be + 3b69a76 commit 2564ddd
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 76 deletions.
76 changes: 12 additions & 64 deletions robot-core/src/main/java/org/obolibrary/robot/ReasonOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.obolibrary.robot.exceptions.*;
import org.obolibrary.robot.reason.EquivalentClassReasoning;
import org.obolibrary.robot.reason.EquivalentClassReasoningMode;
import org.obolibrary.robot.reason.InferredSubClassAxiomGeneratorIncludingIndirect;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.model.parameters.Imports;
Expand Down Expand Up @@ -233,8 +234,9 @@ private static List<InferredAxiomGenerator<? extends OWLAxiom>> getInferredAxiom
Map<String, String> options) {
String axGeneratorString = OptionsHelper.getOption(options, "axiom-generators", "subclass");
List<String> axGenerators = Arrays.asList(axGeneratorString.split(" "));
boolean direct = !OptionsHelper.optionIsTrue(options, "include-indirect");
List<InferredAxiomGenerator<? extends OWLAxiom>> gens =
ReasonerHelper.getInferredAxiomGenerators(axGenerators);
ReasonerHelper.getInferredAxiomGenerators(axGenerators, direct);
logger.info("Using these axiom generators:");
for (InferredAxiomGenerator<?> inf : gens) {
logger.info(" " + inf);
Expand Down Expand Up @@ -263,38 +265,28 @@ private static OWLOntology getNewAxiomOntology(
OWLOntologyManager manager = ontology.getOWLOntologyManager();
OWLDataFactory dataFactory = manager.getOWLDataFactory();
boolean direct = !OptionsHelper.optionIsTrue(options, "include-indirect");

boolean subClass = false;
boolean classAssertion = false;
boolean subObjectProperty = false;
for (InferredAxiomGenerator g : gens) {
if (g instanceof InferredSubClassAxiomGenerator) {
subClass = true;
} else if (g instanceof InferredClassAssertionAxiomGenerator) {
classAssertion = true;
} else if (g instanceof InferredSubObjectPropertyAxiomGenerator) {
subObjectProperty = true;
}
}
boolean subClass =
gens.stream()
.anyMatch(
g ->
(g instanceof InferredSubClassAxiomGenerator)
|| (g instanceof InferredSubClassAxiomGeneratorIncludingIndirect));

// we first place all inferred axioms into a new ontology;
// these will be later transferred into the main ontology,
// unless the create new ontology option is passed
OWLOntology newAxiomOntology;
newAxiomOntology = manager.createOntology();

OWLOntology newAxiomOntology = manager.createOntology();
InferredOntologyGenerator generator = new InferredOntologyGenerator(reasoner, gens);
generator.fillOntology(dataFactory, newAxiomOntology);

// If EMR, add expressions instead of just classes, etc...
ExpressionMaterializingReasoner emr = null;
if (reasoner instanceof ExpressionMaterializingReasoner) {
logger.info("Creating expression materializing reasoner...");
emr = (ExpressionMaterializingReasoner) reasoner;
ExpressionMaterializingReasoner emr = (ExpressionMaterializingReasoner) reasoner;
emr.materializeExpressions();
// Maybe add direct/indirect class expressions
if (subClass) {
for (OWLClass c : ontology.getClassesInSignature()) {
for (OWLClass c : ontology.getClassesInSignature(Imports.INCLUDED)) {
// Look at the superclasses because otherwise we would lose the anonymous exprs
Set<OWLClassExpression> sces = emr.getSuperClassExpressions(c, direct);
for (OWLClassExpression sce : sces) {
Expand All @@ -306,50 +298,6 @@ private static OWLOntology getNewAxiomOntology(
}
}
}
} else if (subClass) {
// if not EMR and still using subclasses, do not use expressions
for (OWLClass c : ontology.getClassesInSignature()) {
Set<OWLClass> scs = reasoner.getSubClasses(c, direct).getFlattened();
for (OWLClass sc : scs) {
if (!sc.isOWLNothing()) {
OWLAxiom ax = dataFactory.getOWLSubClassOfAxiom(sc, c);
logger.debug("NEW:" + ax);
manager.addAxiom(newAxiomOntology, ax);
}
}
}
}

// Maybe add direct/indirect class assertions
if (classAssertion) {
for (OWLClass c : ontology.getClassesInSignature()) {
Set<OWLNamedIndividual> inds = reasoner.getInstances(c, direct).getFlattened();
for (OWLNamedIndividual i : inds) {
OWLAxiom ax = dataFactory.getOWLClassAssertionAxiom(c, i);
logger.debug("NEW:" + ax);
manager.addAxiom(newAxiomOntology, ax);
}
}
}

// Maybe add direct/indirect object property expressions
if (subObjectProperty) {
for (OWLObjectProperty op : ontology.getObjectPropertiesInSignature()) {
// Look at superproperties so we can get the expressions
Set<OWLObjectPropertyExpression> sopes;
if (emr != null) {
sopes = emr.getSuperObjectProperties(op, direct).getFlattened();
} else {
sopes = reasoner.getSuperObjectProperties(op, direct).getFlattened();
}
for (OWLObjectPropertyExpression sope : sopes) {
if (!sope.getSignature().contains(dataFactory.getOWLTopObjectProperty())) {
OWLAxiom ax = dataFactory.getOWLSubObjectPropertyOfAxiom(op, sope);
logger.debug("NEW:" + ax);
manager.addAxiom(newAxiomOntology, ax);
}
}
}
}

return newAxiomOntology;
Expand Down
57 changes: 51 additions & 6 deletions robot-core/src/main/java/org/obolibrary/robot/ReasonerHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import org.obolibrary.robot.exceptions.IncoherentRBoxException;
import org.obolibrary.robot.exceptions.IncoherentTBoxException;
import org.obolibrary.robot.exceptions.InconsistentOntologyException;
import org.obolibrary.robot.reason.InferredClassAssertionAxiomGeneratorDirectOnly;
import org.obolibrary.robot.reason.InferredSubClassAxiomGeneratorIncludingIndirect;
import org.obolibrary.robot.reason.InferredSubObjectPropertyAxiomGeneratorIncludingIndirect;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.model.parameters.Imports;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
Expand Down Expand Up @@ -233,21 +236,38 @@ private static OWLOntology createIncoherentModule(
* Given a list of axiom generator strings, return a list of InferredAxiomGenerator objects.
*
* @param axGenerators list of strings to get InferredAxiomGenerators
* @param direct return axiom generators which include only direct
* superclass/superproperties/types
* @return list of InferredAxiomGenerators
*/
public static List<InferredAxiomGenerator<? extends OWLAxiom>> getInferredAxiomGenerators(
List<String> axGenerators) {
List<String> axGenerators, boolean direct) {
List<InferredAxiomGenerator<? extends OWLAxiom>> gens = new ArrayList<>();
if (axGenerators == null || axGenerators.isEmpty()) {
gens.add(new InferredSubClassAxiomGenerator());
if (direct) {
gens.add(new InferredSubClassAxiomGenerator());
} else {
gens.add(new InferredSubClassAxiomGeneratorIncludingIndirect());
}
return gens;
}
for (String ax : axGenerators) {
gens.add(getInferredAxiomGenerator(ax));
gens.add(getInferredAxiomGenerator(ax, direct));
}
return gens;
}

/**
* Given a list of axiom generator strings, return a list of InferredAxiomGenerator objects.
*
* @param axGenerators list of strings to get InferredAxiomGenerators
* @return list of InferredAxiomGenerators
*/
public static List<InferredAxiomGenerator<? extends OWLAxiom>> getInferredAxiomGenerators(
List<String> axGenerators) {
return getInferredAxiomGenerators(axGenerators, true);
}

/**
* Given an axiom generator as a string, return the InferredAxiomGenerator object.
*
Expand All @@ -256,10 +276,27 @@ public static List<InferredAxiomGenerator<? extends OWLAxiom>> getInferredAxiomG
*/
public static InferredAxiomGenerator<? extends OWLAxiom> getInferredAxiomGenerator(
String axGenerator) {
return getInferredAxiomGenerator(axGenerator, true);
}

/**
* Given an axiom generator as a string, return the InferredAxiomGenerator object.
*
* @param axGenerator name of InferredAxiomGenerator
* @param direct return axiom generators which include only direct
* superclass/superproperties/types
* @return InferredAxiomGenerator
*/
public static InferredAxiomGenerator<? extends OWLAxiom> getInferredAxiomGenerator(
String axGenerator, boolean direct) {
switch (axGenerator.toLowerCase()) {
case "subclass":
case "":
return new InferredSubClassAxiomGenerator();
if (direct) {
return new InferredSubClassAxiomGenerator();
} else {
return new InferredSubClassAxiomGeneratorIncludingIndirect();
}
case "disjointclasses":
return new InferredDisjointClassesAxiomGenerator();
case "equivalentclass":
Expand All @@ -271,7 +308,11 @@ public static InferredAxiomGenerator<? extends OWLAxiom> getInferredAxiomGenerat
case "subdataproperty":
return new InferredSubDataPropertyAxiomGenerator();
case "classassertion":
return new InferredClassAssertionAxiomGenerator();
if (direct) {
return new InferredClassAssertionAxiomGeneratorDirectOnly();
} else {
return new InferredClassAssertionAxiomGenerator();
}
case "propertyassertion":
return new InferredPropertyAssertionGenerator();
case "equivalentobjectproperty":
Expand All @@ -281,7 +322,11 @@ public static InferredAxiomGenerator<? extends OWLAxiom> getInferredAxiomGenerat
case "objectpropertycharacteristic":
return new InferredObjectPropertyCharacteristicAxiomGenerator();
case "subobjectproperty":
return new InferredSubObjectPropertyAxiomGenerator();
if (direct) {
return new InferredSubObjectPropertyAxiomGenerator();
} else {
return new InferredSubObjectPropertyAxiomGeneratorIncludingIndirect();
}
default:
throw new IllegalArgumentException(String.format(axiomGeneratorError, axGenerator));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.obolibrary.robot.reason;

import java.util.Set;
import javax.annotation.Nonnull;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.util.InferredIndividualAxiomGenerator;

/** An InferredAxiomGenerator which returns only direct class assettion axioms. */
public class InferredClassAssertionAxiomGeneratorDirectOnly
extends InferredIndividualAxiomGenerator<OWLClassAssertionAxiom> {

@Override
protected void addAxioms(
@Nonnull OWLNamedIndividual entity,
@Nonnull OWLReasoner reasoner,
@Nonnull OWLDataFactory dataFactory,
@Nonnull Set<OWLClassAssertionAxiom> result) {
for (OWLClass type : reasoner.getTypes(entity, true).getFlattened()) {
result.add(dataFactory.getOWLClassAssertionAxiom(type, entity));
}
}

@Override
public String getLabel() {
return "Class assertions (individual direct types)";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.obolibrary.robot.reason;

import java.util.Set;
import javax.annotation.Nonnull;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.util.InferredClassAxiomGenerator;

/** An InferredAxiomGenerator which returns both direct and indirect inferred subclass axioms. */
public class InferredSubClassAxiomGeneratorIncludingIndirect
extends InferredClassAxiomGenerator<OWLSubClassOfAxiom> {

@Override
protected void addAxioms(
@Nonnull OWLClass entity,
@Nonnull OWLReasoner reasoner,
@Nonnull OWLDataFactory dataFactory,
@Nonnull Set<OWLSubClassOfAxiom> result) {
if (reasoner.isSatisfiable(entity)) {
for (OWLClass superclass : reasoner.getSuperClasses(entity, false).getFlattened()) {
result.add(dataFactory.getOWLSubClassOfAxiom(entity, superclass));
}
} else {
result.add(dataFactory.getOWLSubClassOfAxiom(entity, dataFactory.getOWLNothing()));
}
}

@Override
public String getLabel() {
return "Subclasses including indirect";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.obolibrary.robot.reason;

import java.util.Set;
import javax.annotation.Nonnull;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.util.InferredObjectPropertyAxiomGenerator;

/**
* An InferredAxiomGenerator which returns both direct and indirect inferred subobjectproperty
* axioms.
*/
public class InferredSubObjectPropertyAxiomGeneratorIncludingIndirect
extends InferredObjectPropertyAxiomGenerator<OWLSubObjectPropertyOfAxiom> {

@Override
protected void addAxioms(
@Nonnull OWLObjectProperty entity,
@Nonnull OWLReasoner reasoner,
@Nonnull OWLDataFactory dataFactory,
@Nonnull Set<OWLSubObjectPropertyOfAxiom> result,
@Nonnull Set<OWLObjectPropertyExpression> nonSimpleProperties) {
for (OWLObjectPropertyExpression prop :
reasoner.getSuperObjectProperties(entity, false).getFlattened()) {
result.add(dataFactory.getOWLSubObjectPropertyOfAxiom(entity, prop));
}
}

@Override
public String getLabel() {
return "Sub object properties including indirect";
}
}
Loading

0 comments on commit 2564ddd

Please sign in to comment.