Skip to content

Commit

Permalink
MAINT-1848 Fix #1 Add support for concrete domains.
Browse files Browse the repository at this point in the history
  • Loading branch information
kaicode committed Jan 6, 2022
1 parent 3a4e91e commit 3d33afb
Show file tree
Hide file tree
Showing 13 changed files with 617 additions and 679 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ log.log
/SnomedCT_*
*.jar
target
output
output*
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,9 @@ public void run(String[] argsArray) throws OWLException, ReasonerException, IOEx
long startTime = System.currentTimeMillis();
if(customRedundancyOptions.isEmpty()) { //with default redundancy elimination on both authoring and NNF definitions (RECOMMENDED)
generator.computeSubontology(outputRF2);
}
else if(defaultAuthoringForm) { //default authoring form, custom nnf
} else if(defaultAuthoringForm) { //default authoring form, custom nnf
generator.computeSubontology(outputRF2, customRedundancyOptions);
}
else { //custom authoring and nnf (NOT RECOMMENDED)
} else { //custom authoring and nnf (NOT RECOMMENDED)
//with non-default redundancy elimination options specified by user
generator.computeSubontology(outputRF2, customRedundancyOptions, defaultAuthoringForm);
}
Expand Down Expand Up @@ -166,10 +164,12 @@ else if(defaultAuthoringForm) { //default authoring form, custom nnf
else {
System.out.println("org.snomed.ontology.extraction.Verification passed.");
System.out.println("Input ontology num axioms: " + sourceOntology.getLogicalAxiomCount());
System.out.println("Input ontology num classes: " + sourceOntology.getClassesInSignature().size() + " and properties: " + sourceOntology.getObjectPropertiesInSignature().size());
System.out.println("Input ontology num classes: " + sourceOntology.getClassesInSignature().size() + ", " +
"object properties: " + sourceOntology.getObjectPropertiesInSignature().size() + " and data properties: " + sourceOntology.getDataPropertiesInSignature().size());
System.out.println("Subontology Stats");
System.out.println("Num axioms: " + subOntology.getLogicalAxiomCount());
System.out.println("Num classes: " + subOntology.getClassesInSignature().size() + " and properties: " + subOntology.getObjectPropertiesInSignature().size());
System.out.println("Num classes: " + subOntology.getClassesInSignature().size() + ", " +
"object properties: " + subOntology.getObjectPropertiesInSignature().size() + " and data properties: " + subOntology.getDataPropertiesInSignature().size());
System.out.println("Focus classes: " + conceptsToDefine.size());
System.out.println("Supporting classes: " + (subOntology.getClassesInSignature().size() - conceptsToDefine.size()));
System.out.println("---------------------");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
package org.snomed.ontology.extraction.classification;

import org.snomed.ontology.extraction.exception.ReasonerException;
import org.semanticweb.elk.owlapi.ElkReasonerFactory;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.reasoner.*;
import org.semanticweb.owlapi.util.InferredEquivalentClassAxiomGenerator;
import org.semanticweb.owlapi.util.InferredOntologyGenerator;
import org.semanticweb.owlapi.util.InferredSubClassAxiomGenerator;
import org.snomed.ontology.extraction.exception.ReasonerException;

import java.util.*;

public class OntologyReasoningService {

private OWLReasoner reasoner;
private final OWLReasonerConfiguration configuration = new SimpleConfiguration(new ConsoleProgressMonitor());
private String reasonerName;
private final OWLReasonerFactory reasonerFactory;

public OntologyReasoningService(OWLOntology inputOntology) throws ReasonerException {
this(inputOntology, "org.semanticweb.elk.owlapi.ElkReasonerFactory");
}
public OntologyReasoningService(OWLOntology inputOntology, String reasonerFactoryName) throws ReasonerException {
//this.inputOntology = inputOntology;
reasoner = getReasonerFactory(reasonerFactoryName).createReasoner(inputOntology, configuration);
reasonerName = reasonerFactoryName;
public OntologyReasoningService(OWLOntology inputOntology) {
reasonerFactory = new ElkReasonerFactory();
reasoner = reasonerFactory.createReasoner(inputOntology, configuration);
}

public void classifyOntology() {
Expand All @@ -33,7 +30,7 @@ public void classifyOntology() {

public OWLOntology getClassifiedOntology() throws OWLOntologyCreationException {
InferredOntologyGenerator classifiedOntologyGenerator = new InferredOntologyGenerator(reasoner, Arrays.asList(new InferredSubClassAxiomGenerator(),
new InferredEquivalentClassAxiomGenerator()));
new InferredEquivalentClassAxiomGenerator()));
OWLOntologyManager man = OWLManager.createOWLOntologyManager();
OWLDataFactory df = man.getOWLDataFactory();

Expand All @@ -43,28 +40,12 @@ public OWLOntology getClassifiedOntology() throws OWLOntologyCreationException {
return classifiedOntology;
}

private OWLReasonerFactory getReasonerFactory(String reasonerFactoryName) throws ReasonerException {
Class<?> reasonerFactoryClass = null;
try {
reasonerFactoryClass = Class.forName(reasonerFactoryName);
return (OWLReasonerFactory) reasonerFactoryClass.newInstance();
} catch (ClassNotFoundException e) {
throw new ReasonerException(String.format("Requested reasoner class '%s' not found.", reasonerFactoryName), e);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new ReasonerException(String.format("Requested reasoner class '%s' not found.", reasonerFactoryName), e);
} catch (InstantiationException e) {
e.printStackTrace();
throw new ReasonerException("Reasoner instantiation exception.", e);
}
}

public Map<OWLClass, Set<OWLClass>> getEquivalentClassesMap() {
OWLOntology rootOntology = reasoner.getRootOntology();
System.out.println("Computing equivalent classes map for ontology: " + rootOntology.getOntologyID().toString());
Map<OWLClass, Set<OWLClass>> equivalentClassesMap = new HashMap<>();
for(OWLClass cls:rootOntology.getClassesInSignature()) {
equivalentClassesMap.computeIfAbsent(cls, s -> this.getEquivalentClasses(s));
for (OWLClass cls : rootOntology.getClassesInSignature()) {
equivalentClassesMap.computeIfAbsent(cls, this::getEquivalentClasses);
}
return equivalentClassesMap;
}
Expand Down Expand Up @@ -106,15 +87,15 @@ public Set<OWLObjectPropertyExpression> getDirectDescendants(OWLObjectPropertyEx
*/
//start at s <= r, then move down through t <= s etc, to return t, s etc for role r
public Set<OWLObjectPropertyExpression> getDescendantProperties(OWLObjectPropertyExpression role) {
ListIterator<OWLObjectPropertyExpression> rolesIterator = new ArrayList<OWLObjectPropertyExpression>(Arrays.asList(role)).listIterator();
Set<OWLObjectPropertyExpression> descendantProperties = new HashSet<OWLObjectPropertyExpression>();
ListIterator<OWLObjectPropertyExpression> rolesIterator = new ArrayList<>(Collections.singletonList(role)).listIterator();
Set<OWLObjectPropertyExpression> descendantProperties = new HashSet<>();

//recursively add all subproperties of reflexive properties as reflexive (ELK does not support finding superproperties)
while(rolesIterator.hasNext()) {
while (rolesIterator.hasNext()) {
OWLObjectPropertyExpression prop = rolesIterator.next();
System.out.println("Current prop: " + prop.toString());

for(OWLSubObjectPropertyOfAxiom propAx:reasoner.getRootOntology().getObjectSubPropertyAxiomsForSuperProperty(prop)) {
for (OWLSubObjectPropertyOfAxiom propAx : reasoner.getRootOntology().getObjectSubPropertyAxiomsForSuperProperty(prop)) {
descendantProperties.add(propAx.getSubProperty());
rolesIterator.add(propAx.getSubProperty());
rolesIterator.previous();
Expand Down Expand Up @@ -153,17 +134,16 @@ public Set<OWLClass> getDescendants(OWLClass cls, boolean getSelf) {
*/

public OWLClass getTopClass() {
ArrayList<OWLEntity> topEntities = new ArrayList<OWLEntity>(reasoner.getTopClassNode().getEntities());
ArrayList<OWLEntity> topEntities = new ArrayList<>(reasoner.getTopClassNode().getEntities());

OWLClass topClass = topEntities.get(0).asOWLClass();
return topClass;
return topEntities.get(0).asOWLClass();
}

// Currently assumes no equivalent classes: would be problematic if we have equivalent named classes or PVs, since this will mean both are removed. //TODO: detect equivalent cases, remove only one.
public Set<OWLClass> eliminateWeakerClasses(Set<OWLClass> inputClassSet) {
Set<OWLClass> redundantClasses = new HashSet<OWLClass>();
Set<OWLClass> redundantClasses = new HashSet<>();

Set<OWLClass> otherClasses = new HashSet<OWLClass>(inputClassSet);
Set<OWLClass> otherClasses = new HashSet<>(inputClassSet);
for (OWLClass cls : inputClassSet) {
otherClasses.remove(cls);
if (weakerThanAtLeastOneOf(cls, otherClasses)) {
Expand All @@ -177,9 +157,9 @@ public Set<OWLClass> eliminateWeakerClasses(Set<OWLClass> inputClassSet) {
}

public Set<OWLClass> eliminateStrongerClasses(Set<OWLClass> inputClassSet) {
Set<OWLClass> redundantClasses = new HashSet<OWLClass>();
Set<OWLClass> redundantClasses = new HashSet<>();

Set<OWLClass> otherClasses = new HashSet<OWLClass>(inputClassSet);
Set<OWLClass> otherClasses = new HashSet<>(inputClassSet);
for (OWLClass cls : inputClassSet) {
otherClasses.remove(cls);
if (strongerThanAtLeastOneOf(cls, otherClasses)) {
Expand Down Expand Up @@ -212,22 +192,16 @@ public Set<OWLObjectPropertyExpression> eliminateWeakerRoles(Set<OWLObjectProper
*/

public boolean isPrimitive(OWLClass cls) {
if(reasoner.getRootOntology().getEquivalentClassesAxioms(cls).isEmpty()) {
return true;
}
return false;
return reasoner.getRootOntology().getEquivalentClassesAxioms(cls).isEmpty();
}

public boolean isStrongerThan(OWLClass classBeingChecked, OWLClass classCheckedAgainst) {
if(this.getAncestors(classBeingChecked).contains(classCheckedAgainst)) {
return true;
}
return false;
return this.getAncestors(classBeingChecked).contains(classCheckedAgainst);
}

public boolean weakerThanAtLeastOneOf(OWLClass classBeingChecked, Set<OWLClass> setCheckedAgainst) {
for(OWLClass classCheckedAgainst:setCheckedAgainst) {
if(this.getAncestors(classCheckedAgainst).contains(classBeingChecked)) {
for (OWLClass classCheckedAgainst : setCheckedAgainst) {
if (this.getAncestors(classCheckedAgainst).contains(classBeingChecked)) {
return true;
}
}
Expand All @@ -246,8 +220,8 @@ public boolean weakerThanAtLeastOneOf(OWLObjectPropertyExpression roleBeingCheck
*/

public boolean strongerThanAtLeastOneOf(OWLClass classBeingChecked, Set<OWLClass> setCheckedAgainst) {
for(OWLClass classCheckedAgainst:setCheckedAgainst) {
if(this.getDescendants(classCheckedAgainst).contains(classBeingChecked)) {
for (OWLClass classCheckedAgainst : setCheckedAgainst) {
if (this.getDescendants(classCheckedAgainst).contains(classBeingChecked)) {
return true;
}
}
Expand All @@ -264,7 +238,7 @@ public boolean entails(OWLAxiom ax) {

public void setNewSourceOntologyAndClassify(OWLOntology newSourceOntology) throws ReasonerException {
reasoner.dispose();
reasoner = getReasonerFactory(reasonerName).createReasoner(newSourceOntology, configuration);
reasoner = reasonerFactory.createReasoner(newSourceOntology, configuration);
this.classifyOntology();
}

Expand Down
Loading

0 comments on commit 3d33afb

Please sign in to comment.