Skip to content

Commit f31c6c7

Browse files
committed
Revisit parents/children of terms to make sure none were missed
When using a limited reasoner (i.e. none or transitive), some of the ancestors or descendants of a term may be missed. To compensate for that, do a few additional direct checks.
1 parent 6f62477 commit f31c6c7

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/ubic/basecode/ontology/jena/JenaUtils.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.hp.hpl.jena.util.iterator.Filter;
99
import com.hp.hpl.jena.util.iterator.UniqueExtendedIterator;
1010
import org.apache.commons.lang3.time.StopWatch;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
1113

1214
import javax.annotation.Nullable;
1315
import java.util.*;
@@ -18,7 +20,25 @@
1820

1921
class JenaUtils {
2022

23+
protected static Logger log = LoggerFactory.getLogger( JenaUtils.class );
24+
2125
public static Collection<OntClass> getParents( OntModel model, Collection<OntClass> ontClasses, boolean direct, @Nullable Set<Restriction> additionalRestrictions ) {
26+
Collection<OntClass> parents = getParentsInternal( model, ontClasses, direct, additionalRestrictions );
27+
if ( !direct && !parents.isEmpty() && additionalRestrictions != null && !supportsAdditionalPropertyInference( model ) ) {
28+
// if there are some missing direct parents, revisit the hierarchy
29+
Set<OntClass> parentsToRevisit = new HashSet<>( parents );
30+
while ( !parentsToRevisit.isEmpty() ) {
31+
log.debug( "Revisiting the direct parents of {} terms...", parentsToRevisit.size() );
32+
parentsToRevisit = new HashSet<>( getParentsInternal( model, parentsToRevisit, true, additionalRestrictions ) );
33+
parentsToRevisit.removeAll( parents );
34+
log.debug( "Found {} missed parents.", parentsToRevisit.size() );
35+
parents.addAll( parentsToRevisit );
36+
}
37+
}
38+
return ontClasses;
39+
}
40+
41+
private static Collection<OntClass> getParentsInternal( OntModel model, Collection<OntClass> ontClasses, boolean direct, @Nullable Set<Restriction> additionalRestrictions ) {
2242
ontClasses = ontClasses.stream()
2343
.map( t -> t.inModel( model ) )
2444
.filter( t -> t.canAs( OntClass.class ) )
@@ -65,6 +85,23 @@ public static Collection<OntClass> getParents( OntModel model, Collection<OntCla
6585
}
6686

6787
public static Collection<OntClass> getChildren( OntModel model, Collection<OntClass> terms, boolean direct, @Nullable Set<Restriction> additionalRestrictions ) {
88+
Collection<OntClass> children = getChildrenInternal( model, terms, direct, additionalRestrictions );
89+
// collect any remaining children, this is useful if inference is incomplete (i.e. if not using a suitable OWL reasoner)
90+
if ( !direct && !children.isEmpty() && additionalRestrictions != null && !supportsAdditionalPropertyInference( model ) ) {
91+
// if there are some missing direct children, revisit the hierarchy
92+
Set<OntClass> childrenToRevisit = new HashSet<>( children );
93+
while ( !childrenToRevisit.isEmpty() ) {
94+
log.debug( "Revisiting the direct parents of {} terms...", childrenToRevisit.size() );
95+
childrenToRevisit = new HashSet<>( JenaUtils.getChildrenInternal( model, childrenToRevisit, true, additionalRestrictions ) );
96+
childrenToRevisit.removeAll( children );
97+
log.debug( "Found {} missed children.", childrenToRevisit.size() );
98+
children.addAll( childrenToRevisit );
99+
}
100+
}
101+
return children;
102+
}
103+
104+
public static Collection<OntClass> getChildrenInternal( OntModel model, Collection<OntClass> terms, boolean direct, @Nullable Set<Restriction> additionalRestrictions ) {
68105
terms = terms.stream()
69106
.map( t -> t.inModel( model ) )
70107
.filter( t -> t.canAs( OntClass.class ) )
@@ -103,6 +140,11 @@ public static Collection<OntClass> getChildren( OntModel model, Collection<OntCl
103140
return result;
104141
}
105142

143+
private static boolean supportsAdditionalPropertyInference( OntModel model ) {
144+
return model.getReasoner().supportsProperty( model.getProfile().SOME_VALUES_FROM() )
145+
&& model.getReasoner().supportsProperty( model.getProfile().ALL_VALUES_FROM() );
146+
}
147+
106148
public static Resource getRestrictionValue( Restriction r ) {
107149
if ( r.isSomeValuesFromRestriction() ) {
108150
return r.asSomeValuesFromRestriction().getSomeValuesFrom();

0 commit comments

Comments
 (0)