Skip to content

Commit 958567c

Browse files
committed
ont-api: add ObjectPropertySearcher (a graph-optimization for OWLOntology#objectPropertiesInSignature(); issue #15) + related refactoring of other searchers
1 parent 2983248 commit 958567c

File tree

7 files changed

+351
-59
lines changed

7 files changed

+351
-59
lines changed

src/main/java/com/github/owlcs/ontapi/internal/InternalReadModel.java

+83-4
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,48 @@
1818
import com.github.owlcs.ontapi.ID;
1919
import com.github.owlcs.ontapi.OntApiException;
2020
import com.github.owlcs.ontapi.internal.axioms.AbstractNaryTranslator;
21-
import com.github.owlcs.ontapi.internal.searchers.axioms.*;
21+
import com.github.owlcs.ontapi.internal.searchers.axioms.AnnotationAssertionBySubject;
22+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByAnnotationProperty;
23+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByAnonymousIndividual;
24+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByClass;
25+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByDataProperty;
26+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByDatatype;
27+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByIRI;
28+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByLiteral;
29+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByNamedIndividual;
30+
import com.github.owlcs.ontapi.internal.searchers.axioms.ByObjectProperty;
31+
import com.github.owlcs.ontapi.internal.searchers.axioms.ClassAssertionByObject;
32+
import com.github.owlcs.ontapi.internal.searchers.axioms.ClassAssertionBySubject;
33+
import com.github.owlcs.ontapi.internal.searchers.axioms.DataAssertionBySubject;
34+
import com.github.owlcs.ontapi.internal.searchers.axioms.DeclarationByEntity;
35+
import com.github.owlcs.ontapi.internal.searchers.axioms.DisjointClassesByOperand;
36+
import com.github.owlcs.ontapi.internal.searchers.axioms.EquivalentClassesByOperand;
37+
import com.github.owlcs.ontapi.internal.searchers.axioms.ObjectAssertionBySubject;
38+
import com.github.owlcs.ontapi.internal.searchers.axioms.ObjectPropertyDomainBySubject;
39+
import com.github.owlcs.ontapi.internal.searchers.axioms.ObjectPropertyRangeBySubject;
40+
import com.github.owlcs.ontapi.internal.searchers.axioms.SubClassOfByObject;
41+
import com.github.owlcs.ontapi.internal.searchers.axioms.SubClassOfBySubject;
2242
import com.github.owlcs.ontapi.internal.searchers.objects.ClassSearcher;
2343
import com.github.owlcs.ontapi.internal.searchers.objects.NamedIndividualSearcher;
44+
import com.github.owlcs.ontapi.internal.searchers.objects.ObjectPropertySearcher;
2445
import com.github.owlcs.ontapi.jena.OntJenaException;
2546
import com.github.owlcs.ontapi.jena.RWLockedGraph;
2647
import com.github.owlcs.ontapi.jena.impl.OntGraphModelImpl;
2748
import com.github.owlcs.ontapi.jena.impl.conf.OntPersonality;
28-
import com.github.owlcs.ontapi.jena.model.*;
49+
import com.github.owlcs.ontapi.jena.model.OntAnnotationProperty;
50+
import com.github.owlcs.ontapi.jena.model.OntClass;
51+
import com.github.owlcs.ontapi.jena.model.OntDataProperty;
52+
import com.github.owlcs.ontapi.jena.model.OntDataRange;
53+
import com.github.owlcs.ontapi.jena.model.OntEntity;
54+
import com.github.owlcs.ontapi.jena.model.OntID;
55+
import com.github.owlcs.ontapi.jena.model.OntIndividual;
56+
import com.github.owlcs.ontapi.jena.model.OntModel;
57+
import com.github.owlcs.ontapi.jena.model.OntObject;
58+
import com.github.owlcs.ontapi.jena.model.OntObjectProperty;
59+
import com.github.owlcs.ontapi.jena.model.OntStatement;
2960
import com.github.owlcs.ontapi.jena.vocabulary.OWL;
3061
import com.github.owlcs.ontapi.jena.vocabulary.RDF;
62+
3163
import org.apache.commons.lang3.StringUtils;
3264
import org.apache.jena.graph.Graph;
3365
import org.apache.jena.graph.Node;
@@ -36,14 +68,57 @@
3668
import org.apache.jena.rdf.model.Resource;
3769
import org.apache.jena.shared.Lock;
3870
import org.apache.jena.util.iterator.ExtendedIterator;
39-
import org.semanticweb.owlapi.model.*;
71+
import org.semanticweb.owlapi.model.AxiomType;
72+
import org.semanticweb.owlapi.model.IRI;
73+
import org.semanticweb.owlapi.model.OWLAnnotation;
74+
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
75+
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
76+
import org.semanticweb.owlapi.model.OWLAnnotationSubject;
77+
import org.semanticweb.owlapi.model.OWLAnonymousIndividual;
78+
import org.semanticweb.owlapi.model.OWLAxiom;
79+
import org.semanticweb.owlapi.model.OWLClass;
80+
import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
81+
import org.semanticweb.owlapi.model.OWLClassExpression;
82+
import org.semanticweb.owlapi.model.OWLDataProperty;
83+
import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
84+
import org.semanticweb.owlapi.model.OWLDatatype;
85+
import org.semanticweb.owlapi.model.OWLDeclarationAxiom;
86+
import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom;
87+
import org.semanticweb.owlapi.model.OWLEntity;
88+
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
89+
import org.semanticweb.owlapi.model.OWLImportsDeclaration;
90+
import org.semanticweb.owlapi.model.OWLIndividual;
91+
import org.semanticweb.owlapi.model.OWLLiteral;
92+
import org.semanticweb.owlapi.model.OWLLogicalAxiom;
93+
import org.semanticweb.owlapi.model.OWLNamedIndividual;
94+
import org.semanticweb.owlapi.model.OWLNaryAxiom;
95+
import org.semanticweb.owlapi.model.OWLObject;
96+
import org.semanticweb.owlapi.model.OWLObjectProperty;
97+
import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
98+
import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom;
99+
import org.semanticweb.owlapi.model.OWLObjectPropertyExpression;
100+
import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom;
101+
import org.semanticweb.owlapi.model.OWLPrimitive;
102+
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
40103
import org.slf4j.Logger;
41104
import org.slf4j.LoggerFactory;
42105

43106
import javax.annotation.Nonnull;
107+
44108
import java.time.Duration;
45109
import java.time.Instant;
46-
import java.util.*;
110+
import java.util.ArrayList;
111+
import java.util.Arrays;
112+
import java.util.Collections;
113+
import java.util.EnumMap;
114+
import java.util.HashSet;
115+
import java.util.Iterator;
116+
import java.util.List;
117+
import java.util.Locale;
118+
import java.util.Map;
119+
import java.util.Objects;
120+
import java.util.Optional;
121+
import java.util.Set;
47122
import java.util.function.BiPredicate;
48123
import java.util.function.Function;
49124
import java.util.function.Predicate;
@@ -148,6 +223,7 @@ abstract class InternalReadModel extends OntGraphModelImpl implements ListAxioms
148223
// To search OWLObjects
149224
protected final ObjectsSearcher<OWLClass> classSearcher = new ClassSearcher();
150225
protected final ObjectsSearcher<OWLNamedIndividual> individualSearcher = new NamedIndividualSearcher();
226+
protected final ObjectsSearcher<OWLObjectProperty> objectPropertySearcher = new ObjectPropertySearcher();
151227

152228
InternalReadModel(Graph base,
153229
OntPersonality personality,
@@ -892,6 +968,9 @@ private ObjectsSearcher<OWLObject> getEntitySearcher(OWLComponentType type) {
892968
if (OWLComponentType.NAMED_INDIVIDUAL == type) {
893969
return BaseSearcher.cast(individualSearcher);
894970
}
971+
if (OWLComponentType.NAMED_OBJECT_PROPERTY == type) {
972+
return BaseSearcher.cast(objectPropertySearcher);
973+
}
895974
// TODO: support other types (see https://github.com/owlcs/ont-api/issues/15)
896975
return null;
897976
}

src/main/java/com/github/owlcs/ontapi/internal/searchers/objects/ClassSearcher.java

+28-43
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,43 @@
1616

1717
import com.github.owlcs.ontapi.OntApiException;
1818
import com.github.owlcs.ontapi.config.AxiomsSettings;
19-
import com.github.owlcs.ontapi.internal.*;
19+
import com.github.owlcs.ontapi.internal.AxiomTranslator;
20+
import com.github.owlcs.ontapi.internal.ModelObjectFactory;
21+
import com.github.owlcs.ontapi.internal.ONTObject;
22+
import com.github.owlcs.ontapi.internal.ONTObjectFactory;
23+
import com.github.owlcs.ontapi.internal.OWLComponentType;
24+
import com.github.owlcs.ontapi.internal.ObjectsSearcher;
2025
import com.github.owlcs.ontapi.internal.searchers.axioms.ByClass;
2126
import com.github.owlcs.ontapi.jena.model.OntModel;
2227
import com.github.owlcs.ontapi.jena.model.OntStatement;
2328
import com.github.owlcs.ontapi.jena.utils.Iter;
24-
import com.github.owlcs.ontapi.jena.utils.OntModels;
2529
import com.github.owlcs.ontapi.jena.vocabulary.OWL;
26-
import com.github.owlcs.ontapi.jena.vocabulary.RDF;
27-
import org.apache.jena.rdf.model.RDFNode;
30+
31+
import org.apache.jena.graph.Node;
2832
import org.apache.jena.rdf.model.Resource;
29-
import org.apache.jena.rdf.model.Statement;
3033
import org.apache.jena.util.iterator.ExtendedIterator;
3134
import org.semanticweb.owlapi.model.OWLAxiom;
3235
import org.semanticweb.owlapi.model.OWLClass;
3336

34-
import java.util.HashSet;
3537
import java.util.Set;
3638

3739
/**
3840
* An {@link ObjectsSearcher} that retrieves {@link OWLClass OWL-API Class}es.
3941
* Created by @ssz on 19.04.2020.
4042
*/
41-
public class ClassSearcher extends EntitySearcher<OWLClass> {
43+
public class ClassSearcher extends WithBuiltins<OWLClass> {
4244
private static final Set<AxiomTranslator<OWLAxiom>> TRANSLATORS = selectTranslators(OWLComponentType.CLASS);
4345

46+
@Override
47+
protected Resource getEntityType() {
48+
return OWL.Class;
49+
}
50+
51+
@Override
52+
protected ExtendedIterator<? extends AxiomTranslator<OWLAxiom>> listTranslators() {
53+
return Iter.create(TRANSLATORS);
54+
}
55+
4456
@Override
4557
protected ONTObject<OWLClass> createEntity(String uri, OntModel model, ONTObjectFactory factory) {
4658
return factory.getClass(OntApiException.mustNotBeNull(model.getOntClass(uri)));
@@ -51,69 +63,42 @@ protected ONTObject<OWLClass> createEntity(String uri, ModelObjectFactory factor
5163
return factory.getClass(uri);
5264
}
5365

54-
@Override
55-
protected ExtendedIterator<? extends AxiomTranslator<OWLAxiom>> listTranslators() {
56-
return Iter.create(TRANSLATORS);
57-
}
58-
5966
@Override
6067
protected boolean containsEntity(String uri, OntModel m, AxiomsSettings conf) {
61-
Resource clazz = m.getResource(uri);
62-
if (getBuiltins(m).getClasses().contains(clazz.asNode())) {
68+
Resource clazz = toResource(m, uri);
69+
if (containsBuiltin(m, clazz)) {
6370
if (OWL.Thing.equals(clazz)) {
6471
if (containsAxiom(Iter.flatMap(listImplicitStatements(m), s -> listRootStatements(m, s)), conf)) {
6572
return true;
6673
}
6774
}
6875
return containsInAxiom(clazz, m, conf);
6976
}
70-
if (m.independent()) {
71-
return m.getBaseGraph().contains(clazz.asNode(), RDF.type.asNode(), OWL.Class.asNode());
72-
}
73-
if (!m.contains(clazz, RDF.type, OWL.Class)) {
74-
return false;
75-
}
76-
return containsInAxiom(clazz, m, conf);
77+
return containsDeclaration(clazz, m, conf);
7778
}
7879

7980
@Override
8081
protected ExtendedIterator<String> listEntities(OntModel m, AxiomsSettings conf) {
81-
Set<String> builtins = new HashSet<>();
82-
getBuiltins(m).getClasses().forEach(x -> {
83-
if (containsInAxiom(x.getURI(), m, conf)) {
84-
builtins.add(x.getURI());
85-
}
86-
});
82+
Set<String> builtins = getBuiltins(m, conf);
8783
if (!builtins.contains(OWL.Thing.getURI())) {
8884
if (containsAxiom(Iter.flatMap(listImplicitStatements(m), s -> listRootStatements(m, s)), conf)) {
8985
builtins.add(OWL.Thing.getURI());
9086
}
9187
}
92-
ExtendedIterator<String> explicit = listByPredicateAndObject(m, RDF.type, OWL.Class)
93-
.mapWith(x -> x.getSubject().getURI())
94-
.filterKeep(x -> x != null && !builtins.contains(x));
95-
ExtendedIterator<String> res = Iter.concat(explicit, Iter.create(builtins));
96-
if (!m.independent()) {
97-
ExtendedIterator<String> shared = listClassesFromImports(m)
98-
.filterKeep(x -> containsInAxiom(x, m, conf));
99-
res = Iter.concat(res, shared);
100-
}
101-
return res;
88+
return listEntities(m, builtins, conf);
10289
}
10390

10491
protected ExtendedIterator<OntStatement> listImplicitStatements(OntModel m) {
10592
return Iter.flatMap(Iter.of(OWL.cardinality, OWL.maxCardinality, OWL.minCardinality), p -> listByPredicate(m, p))
10693
.filterKeep(this::isCardinalityRestriction);
10794
}
10895

109-
protected ExtendedIterator<String> listClassesFromImports(OntModel m) {
110-
ExtendedIterator<OntModel> imports = OntModels.listImports(m);
111-
return Iter.distinct(Iter.flatMap(imports, i -> i.listStatements(null, RDF.type, OWL.Class))
112-
.mapWith(Statement::getSubject).filterKeep(RDFNode::isURIResource).mapWith(Resource::getURI));
113-
}
114-
11596
protected boolean isCardinalityRestriction(OntStatement s) {
11697
return ByClass.OBJECT_CARDINALITY_TYPES.stream().anyMatch(t -> s.getSubject().canAs(t));
11798
}
11899

100+
@Override
101+
protected Set<Node> getBuiltins(OntModel m) {
102+
return getBuiltinsVocabulary(m).getClasses();
103+
}
119104
}

src/main/java/com/github/owlcs/ontapi/internal/searchers/objects/EntitySearcher.java

+36-8
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,22 @@
1515
package com.github.owlcs.ontapi.internal.searchers.objects;
1616

1717
import com.github.owlcs.ontapi.config.AxiomsSettings;
18-
import com.github.owlcs.ontapi.internal.*;
18+
import com.github.owlcs.ontapi.internal.AxiomTranslator;
19+
import com.github.owlcs.ontapi.internal.ModelObjectFactory;
20+
import com.github.owlcs.ontapi.internal.ONTObject;
21+
import com.github.owlcs.ontapi.internal.ONTObjectFactory;
22+
import com.github.owlcs.ontapi.internal.ObjectsSearcher;
1923
import com.github.owlcs.ontapi.internal.searchers.WithRootStatement;
2024
import com.github.owlcs.ontapi.jena.impl.PersonalityModel;
21-
import com.github.owlcs.ontapi.jena.impl.conf.OntPersonality;
2225
import com.github.owlcs.ontapi.jena.model.OntModel;
2326
import com.github.owlcs.ontapi.jena.model.OntStatement;
2427
import com.github.owlcs.ontapi.jena.utils.Iter;
28+
import com.github.owlcs.ontapi.jena.utils.OntModels;
29+
import com.github.owlcs.ontapi.jena.vocabulary.RDF;
30+
31+
import org.apache.jena.rdf.model.RDFNode;
2532
import org.apache.jena.rdf.model.Resource;
33+
import org.apache.jena.rdf.model.Statement;
2634
import org.apache.jena.util.iterator.ExtendedIterator;
2735
import org.semanticweb.owlapi.model.OWLAxiom;
2836
import org.semanticweb.owlapi.model.OWLEntity;
@@ -31,16 +39,13 @@
3139
import java.util.function.Function;
3240

3341
/**
42+
* An abstract {@link OWLEntity} searcher.
3443
* Created by @ssz on 30.06.2020.
3544
*
3645
* @param <E> - subtype of {@link OWLEntity}
3746
*/
3847
abstract class EntitySearcher<E extends OWLEntity> extends WithRootStatement implements ObjectsSearcher<E> {
3948

40-
protected static OntPersonality.Builtins getBuiltins(OntModel m) {
41-
return asPersonalityModel(m).getOntPersonality().getBuiltins();
42-
}
43-
4449
static PersonalityModel asPersonalityModel(OntModel m) {
4550
return PersonalityModel.asPersonalityModel(m);
4651
}
@@ -79,6 +84,8 @@ public final Optional<ONTObject<E>> findONTObject(E object,
7984

8085
protected abstract ONTObject<E> createEntity(String uri, ModelObjectFactory factory);
8186

87+
protected abstract Resource getEntityType();
88+
8289
final ONTObject<E> createONTEntity(String uri, OntModel model, ONTObjectFactory factory) {
8390
if (factory instanceof ModelObjectFactory) {
8491
return createEntity(uri, (ModelObjectFactory) factory);
@@ -99,8 +106,14 @@ protected final ExtendedIterator<? extends AxiomTranslator<OWLAxiom>> listTransl
99106
return listTranslators().filterKeep(t -> t.testStatement(statement, conf));
100107
}
101108

109+
protected ExtendedIterator<String> listFromImports(OntModel m) {
110+
ExtendedIterator<OntModel> imports = OntModels.listImports(m);
111+
return Iter.distinct(Iter.flatMap(imports, i -> i.listStatements(null, RDF.type, getEntityType()))
112+
.mapWith(Statement::getSubject).filterKeep(RDFNode::isURIResource).mapWith(Resource::getURI));
113+
}
114+
102115
protected final boolean containsInAxiom(String uri, OntModel m, AxiomsSettings conf) {
103-
return containsInAxiom(m.getResource(uri), m, conf);
116+
return containsInAxiom(toResource(m, uri), m, conf);
104117
}
105118

106119
protected boolean containsInAxiom(Resource uri, OntModel m, AxiomsSettings conf) {
@@ -111,7 +124,22 @@ protected final boolean containsAxiom(ExtendedIterator<OntStatement> roots, Axio
111124
return Iter.anyMatch(roots, s -> Iter.findFirst(listTranslators(s, conf)).isPresent());
112125
}
113126

114-
private ExtendedIterator<OntStatement> listRootStatements(OntModel m, Resource uri) {
127+
protected ExtendedIterator<OntStatement> listRootStatements(OntModel m, Resource uri) {
115128
return Iter.concat(listBySubject(m, uri), Iter.flatMap(listByObject(m, uri), s -> listRootStatements(m, s)));
116129
}
130+
131+
protected Resource toResource(OntModel m, String uri) {
132+
return m.getResource(uri);
133+
}
134+
135+
final boolean containsDeclaration(Resource uri, OntModel m, AxiomsSettings conf) {
136+
Resource type = getEntityType();
137+
if (m.independent()) {
138+
return m.getBaseGraph().contains(uri.asNode(), RDF.type.asNode(), type.asNode());
139+
}
140+
if (!m.contains(uri, RDF.type, type)) {
141+
return false;
142+
}
143+
return containsInAxiom(uri, m, conf);
144+
}
117145
}

0 commit comments

Comments
 (0)