Skip to content

Commit fa1bbd5

Browse files
committed
ont-api: add OWLOntology#classAssertionAxioms(OWLClassExpression) optimization (issue #12) + tests
1 parent f0964c5 commit fa1bbd5

File tree

8 files changed

+113
-24
lines changed

8 files changed

+113
-24
lines changed

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

+14-3
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,10 @@ public class InternalModel extends OntGraphModelImpl
168168
= new EquivalentClassesByOperand();
169169
protected final ByObjectSearcher<OWLDisjointClassesAxiom, OWLClass> disjointClassesByClass
170170
= new DisjointClassesByOperand();
171-
protected final ByObjectSearcher<OWLClassAssertionAxiom, OWLIndividual> classAssertionsBySubject
172-
= new ClassAssertionByIndividual();
171+
protected final ByObjectSearcher<OWLClassAssertionAxiom, OWLIndividual> classAssertionsByIndividual
172+
= new ClassAssertionBySubject();
173+
protected final ByObjectSearcher<OWLClassAssertionAxiom, OWLClassExpression> classAssertionsByClass
174+
= new ClassAssertionByObject();
173175

174176
// To search OWLObjects
175177
protected final ObjectsSearcher<OWLClass> classSearcher = new ClassSearcher();
@@ -683,7 +685,16 @@ public Stream<OWLClassAssertionAxiom> listOWLClassAssertionAxioms(OWLIndividual
683685
if (!useAxiomsSearchOptimization(config)) {
684686
return ListAxioms.super.listOWLClassAssertionAxioms(subject);
685687
}
686-
return listOWLAxioms(classAssertionsBySubject, OWLClassAssertionAxiom.class, subject, config);
688+
return listOWLAxioms(classAssertionsByIndividual, OWLClassAssertionAxiom.class, subject, config);
689+
}
690+
691+
@Override
692+
public Stream<OWLClassAssertionAxiom> listOWLClassAssertionAxioms(OWLClassExpression object) {
693+
InternalConfig config = getConfig();
694+
if (!ClassAssertionByObject.isSupported(object) || !useAxiomsSearchOptimization(config)) {
695+
return ListAxioms.super.listOWLClassAssertionAxioms(object);
696+
}
697+
return listOWLAxioms(classAssertionsByClass, OWLClassAssertionAxiom.class, object, config);
687698
}
688699

689700
@Override

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

+6
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ default Stream<OWLHasKeyAxiom> listOWLHasKeyAxioms(OWLClass subject) {
105105
return listOWLAxioms(OWLHasKeyAxiom.class).filter(x -> Objects.equals(subject, x.getClassExpression()));
106106
}
107107

108+
/**
109+
* Lists {@link OWLClassAssertionAxiom ClassAssertion Axiom}s by the given {@link OWLClassExpression class}-object.
110+
*
111+
* @param object {@link OWLClassExpression}, not {@code null}
112+
* @return a {@code Stream} of {@link OWLClassAssertionAxiom}s
113+
*/
108114
default Stream<OWLClassAssertionAxiom> listOWLClassAssertionAxioms(OWLClassExpression object) {
109115
return listOWLAxioms(OWLClassAssertionAxiom.class).filter(x -> Objects.equals(object, x.getClassExpression()));
110116
}

src/main/java/com/github/owlcs/ontapi/internal/searchers/axioms/BaseByObject.java

+18
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414

1515
package com.github.owlcs.ontapi.internal.searchers.axioms;
1616

17+
import com.github.owlcs.ontapi.OntApiException;
1718
import com.github.owlcs.ontapi.internal.ByObjectSearcher;
1819
import com.github.owlcs.ontapi.internal.WriteHelper;
20+
import com.github.owlcs.ontapi.internal.objects.ONTExpressionImpl;
1921
import com.github.owlcs.ontapi.internal.searchers.WithRootStatement;
2022
import com.github.owlcs.ontapi.jena.model.OntEntity;
2123
import org.apache.jena.rdf.model.Resource;
24+
import org.apache.jena.rdf.model.impl.ResourceImpl;
2225
import org.semanticweb.owlapi.model.*;
2326

2427
/**
@@ -47,4 +50,19 @@ static Resource asResource(OWLAnnotationSubject subject) {
4750
return WriteHelper.toResource(subject);
4851
}
4952

53+
static Resource asResource(OWLClass clazz) {
54+
return asResource((OWLEntity) clazz);
55+
}
56+
57+
static Resource asResource(OWLClassExpression clazz) {
58+
if (clazz.isOWLClass()) return asResource(clazz.asOWLClass());
59+
if (clazz instanceof ONTExpressionImpl) {
60+
return new ResourceImpl(((ONTExpressionImpl<?>) clazz).asNode(), null);
61+
}
62+
throw new OntApiException.Unsupported("Unsupported class-expression " + clazz);
63+
}
64+
65+
public static boolean isSupported(OWLClassExpression clazz) {
66+
return clazz.isOWLClass() || clazz instanceof ONTExpressionImpl;
67+
}
5068
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* This file is part of the ONT API.
3+
* The contents of this file are subject to the LGPL License, Version 3.0.
4+
* Copyright (c) 2020, The University of Manchester, owl.cs group.
5+
*
6+
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
7+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8+
* You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
9+
*
10+
* Alternatively, the contents of this file may be used under the terms of the Apache License, Version 2.0 in which case, the provisions of the Apache License Version 2.0 are applicable instead of those above.
11+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
12+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
13+
*/
14+
15+
package com.github.owlcs.ontapi.internal.searchers.axioms;
16+
17+
import com.github.owlcs.ontapi.jena.model.OntModel;
18+
import com.github.owlcs.ontapi.jena.model.OntStatement;
19+
import com.github.owlcs.ontapi.jena.vocabulary.RDF;
20+
import org.apache.jena.util.iterator.ExtendedIterator;
21+
import org.semanticweb.owlapi.model.OWLClassExpression;
22+
23+
/**
24+
* Created by @ssz on 17.05.2020.
25+
*/
26+
public class ClassAssertionByObject extends ClassAssertionByOperand<OWLClassExpression> {
27+
28+
@Override
29+
protected ExtendedIterator<OntStatement> listStatements(OntModel model, OWLClassExpression clazz) {
30+
return listByPredicateAndObject(model, RDF.type, asResource(clazz));
31+
}
32+
33+
}

src/main/java/com/github/owlcs/ontapi/internal/searchers/axioms/ClassAssertionByIndividual.java renamed to src/main/java/com/github/owlcs/ontapi/internal/searchers/axioms/ClassAssertionBySubject.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
/**
2424
* Created by @ssz on 17.05.2020.
2525
*/
26-
public class ClassAssertionByIndividual extends ClassAssertionByOperand<OWLIndividual> {
26+
public class ClassAssertionBySubject extends ClassAssertionByOperand<OWLIndividual> {
2727

2828
@Override
2929
protected ExtendedIterator<OntStatement> listStatements(OntModel model, OWLIndividual individual) {

src/test/java/com/github/owlcs/ontapi/tests/model/ByPrimitiveTester.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import org.junit.Assert;
1919
import org.semanticweb.owlapi.model.OWLObject;
2020
import org.semanticweb.owlapi.model.OWLOntology;
21-
import org.semanticweb.owlapi.model.OWLPrimitive;
2221

2322
import java.util.Objects;
2423
import java.util.Set;
@@ -36,11 +35,11 @@
3635
class ByPrimitiveTester {
3736
final long count;
3837
final String type;
39-
final BiFunction<OWLOntology, OWLPrimitive, Stream<? extends OWLObject>> listAxioms;
38+
final BiFunction<OWLOntology, OWLObject, Stream<? extends OWLObject>> listAxioms;
4039

4140
ByPrimitiveTester(String type,
4241
long count,
43-
BiFunction<OWLOntology, OWLPrimitive, Stream<? extends OWLObject>> listAxioms) {
42+
BiFunction<OWLOntology, OWLObject, Stream<? extends OWLObject>> listAxioms) {
4443
this.type = Objects.requireNonNull(type);
4544
this.listAxioms = Objects.requireNonNull(listAxioms);
4645
this.count = count;
@@ -51,12 +50,12 @@ static long toLong(OWLObject ax) {
5150
ax.toString().replaceAll("\\s_:[a-z\\d\\-]+", " _:x").hashCode() : ax.hashCode();
5251
}
5352

54-
private long axiomsCount(OWLOntology ont, OWLPrimitive x) {
53+
private long axiomsCount(OWLOntology ont, OWLObject x) {
5554
return listAxioms.apply(ont, x).mapToLong(ByPrimitiveTester::toLong).sum();
5655
}
5756

58-
void testAxiomsCounts(OWLOntology ont, Function<OWLOntology, Stream<? extends OWLPrimitive>> getPrimitives) {
59-
Set<OWLPrimitive> primitives = getPrimitives.apply(ont).collect(Collectors.toSet());
57+
void testAxiomsCounts(OWLOntology ont, Function<OWLOntology, Stream<? extends OWLObject>> getPrimitives) {
58+
Set<OWLObject> primitives = getPrimitives.apply(ont).collect(Collectors.toSet());
6059
if (ont instanceof Ontology) { // to be sure that graph optimization is used
6160
((Ontology) ont).clearCache();
6261
}

src/test/java/com/github/owlcs/ontapi/tests/model/ReferencingAxiomsTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ public ByPrimitiveTester getTester(T type) {
249249

250250
void doTest(T type, Function<OWLOntology, Stream<? extends OWLPrimitive>> getPrimitives) {
251251
OWLOntology ont = load(newManager());
252-
getTester(type).testAxiomsCounts(ont, getPrimitives);
252+
getTester(type).testAxiomsCounts(ont, getPrimitives::apply);
253253
}
254254

255255
public OWLOntology load(OWLOntologyManager manager) {
@@ -266,7 +266,7 @@ private ByPrimitiveTester of() {
266266
}
267267

268268
private ByPrimitiveTester of(long count) {
269-
return new ByPrimitiveTester(name(), count, OWLAxiomCollection::referencingAxioms);
269+
return new ByPrimitiveTester(name(), count, (o, x) -> o.referencingAxioms((OWLPrimitive) x));
270270
}
271271
}
272272

src/test/java/com/github/owlcs/ontapi/tests/model/SearchByObjectTest.java

+34-12
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public void testClassAssertionAxiomsForIndividual() {
104104
x -> Stream.concat(x.individualsInSignature(), x.anonymousIndividuals()));
105105
}
106106

107+
@Test
108+
public void testClassAssertionAxiomsForClassExpression() {
109+
data.doTest(T.CLASS_ASSERTION_BY_OBJECT, OWLObject::nestedClassExpressions);
110+
}
111+
107112
enum TestData {
108113
PIZZA(ModelData.PIZZA,
109114
T.DECLARATIONS.of(-5190508530L),
@@ -114,7 +119,8 @@ enum TestData {
114119
T.DISJOINT_CLASS_BY_OPERAND.of(39992865656L),
115120
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
116121
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
117-
T.CLASS_ASSERTION_BY_SUBJECT.of(-3513486065L)
122+
T.CLASS_ASSERTION_BY_SUBJECT.of(-3513486065L),
123+
T.CLASS_ASSERTION_BY_OBJECT.of(-3513486065L)
118124
),
119125
FAMILY(ModelData.FAMILY,
120126
T.DECLARATIONS.of(34226271096L),
@@ -125,7 +131,8 @@ enum TestData {
125131
T.DISJOINT_CLASS_BY_OPERAND.of(-5870114142L),
126132
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(-46062903685L),
127133
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(-44647629109L),
128-
T.CLASS_ASSERTION_BY_SUBJECT.of(-2344424939L)
134+
T.CLASS_ASSERTION_BY_SUBJECT.of(-2344424939L),
135+
T.CLASS_ASSERTION_BY_OBJECT.of(-2344424939L)
129136
),
130137
PEOPLE(ModelData.PEOPLE,
131138
T.DECLARATIONS.of(-31040926516L),
@@ -136,7 +143,8 @@ enum TestData {
136143
T.DISJOINT_CLASS_BY_OPERAND.of(5151062994L),
137144
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
138145
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(-1008566325L),
139-
T.CLASS_ASSERTION_BY_SUBJECT.of(295642609L)
146+
T.CLASS_ASSERTION_BY_SUBJECT.of(295642609L),
147+
T.CLASS_ASSERTION_BY_OBJECT.of(295642609L) // see https://github.com/owlcs/owlapi/issues/930
140148
),
141149
CAMERA(ModelData.CAMERA,
142150
T.DECLARATIONS.of(2967944221L),
@@ -147,7 +155,8 @@ enum TestData {
147155
T.DISJOINT_CLASS_BY_OPERAND.of(),
148156
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
149157
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
150-
T.CLASS_ASSERTION_BY_SUBJECT.of(-546744276L)
158+
T.CLASS_ASSERTION_BY_SUBJECT.of(-546744276L),
159+
T.CLASS_ASSERTION_BY_OBJECT.of(-546744276L)
151160
),
152161
KOALA(ModelData.KOALA,
153162
T.DECLARATIONS.of(6488467972L),
@@ -158,7 +167,8 @@ enum TestData {
158167
T.DISJOINT_CLASS_BY_OPERAND.of(3827692310L),
159168
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
160169
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
161-
T.CLASS_ASSERTION_BY_SUBJECT.of(-6315703213L)
170+
T.CLASS_ASSERTION_BY_SUBJECT.of(-6315703213L),
171+
T.CLASS_ASSERTION_BY_OBJECT.of(-6315703213L)
162172
),
163173
TRAVEL(ModelData.TRAVEL,
164174
T.DECLARATIONS.of(-25825023334L),
@@ -169,7 +179,8 @@ enum TestData {
169179
T.DISJOINT_CLASS_BY_OPERAND.of(13371010920L),
170180
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
171181
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(1580148819L),
172-
T.CLASS_ASSERTION_BY_SUBJECT.of(156661309L)
182+
T.CLASS_ASSERTION_BY_SUBJECT.of(156661309L),
183+
T.CLASS_ASSERTION_BY_OBJECT.of(156661309L)
173184
),
174185
WINE(ModelData.WINE,
175186
T.DECLARATIONS.of(20065711780L),
@@ -180,7 +191,8 @@ enum TestData {
180191
T.DISJOINT_CLASS_BY_OPERAND.of(-2886827780L),
181192
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(2039350484L),
182193
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(24229827352L),
183-
T.CLASS_ASSERTION_BY_SUBJECT.of(-13302103928L)
194+
T.CLASS_ASSERTION_BY_SUBJECT.of(-13302103928L),
195+
T.CLASS_ASSERTION_BY_OBJECT.of(-13302103928L)
184196
),
185197
FOOD(ModelData.FOOD,
186198
T.DECLARATIONS.of(6794851452L),
@@ -191,7 +203,8 @@ enum TestData {
191203
T.DISJOINT_CLASS_BY_OPERAND.of(14957310010L),
192204
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
193205
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
194-
T.CLASS_ASSERTION_BY_SUBJECT.of(696330992L)
206+
T.CLASS_ASSERTION_BY_SUBJECT.of(696330992L),
207+
T.CLASS_ASSERTION_BY_OBJECT.of(696330992L)
195208
),
196209
NCBITAXON_CUT(ModelData.NCBITAXON_CUT,
197210
T.DECLARATIONS.of(244310200631L),
@@ -202,7 +215,8 @@ enum TestData {
202215
T.DISJOINT_CLASS_BY_OPERAND.of(-5419911878L),
203216
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(-22700580140L),
204217
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
205-
T.CLASS_ASSERTION_BY_SUBJECT.of()
218+
T.CLASS_ASSERTION_BY_SUBJECT.of(),
219+
T.CLASS_ASSERTION_BY_OBJECT.of()
206220
),
207221
HP_CUT(ModelData.HP_CUT,
208222
T.DECLARATIONS.of(-14640456193L),
@@ -213,7 +227,8 @@ enum TestData {
213227
T.DISJOINT_CLASS_BY_OPERAND.of(),
214228
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(),
215229
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
216-
T.CLASS_ASSERTION_BY_SUBJECT.of()
230+
T.CLASS_ASSERTION_BY_SUBJECT.of(),
231+
T.CLASS_ASSERTION_BY_OBJECT.of()
217232
),
218233
FAMILY_PEOPLE_UNION(ModelData.FAMILY_PEOPLE_UNION,
219234
T.DECLARATIONS.of(-637777500L),
@@ -224,7 +239,8 @@ enum TestData {
224239
T.DISJOINT_CLASS_BY_OPERAND.of(),
225240
T.DATA_PROPERTY_ASSERTION_BY_SUBJECT.of(-2596921457L),
226241
T.OBJECT_PROPERTY_ASSERTION_BY_SUBJECT.of(),
227-
T.CLASS_ASSERTION_BY_SUBJECT.of(-25907713L)
242+
T.CLASS_ASSERTION_BY_SUBJECT.of(-25907713L),
243+
T.CLASS_ASSERTION_BY_OBJECT.of(-25907713L)
228244
),
229245
;
230246
private final ModelData resource;
@@ -241,7 +257,7 @@ public ByPrimitiveTester getTester(T type) {
241257
.findFirst().orElseThrow(IllegalArgumentException::new);
242258
}
243259

244-
void doTest(T type, Function<OWLOntology, Stream<? extends OWLPrimitive>> getPrimitives) {
260+
void doTest(T type, Function<OWLOntology, Stream<? extends OWLObject>> getPrimitives) {
245261
OWLOntology ont = load(newManager());
246262
getTester(type).testAxiomsCounts(ont, getPrimitives);
247263
}
@@ -306,6 +322,12 @@ Stream<? extends OWLObject> listAxioms(OWLOntology ont, OWLObject param) {
306322
return ont.classAssertionAxioms((OWLIndividual) param);
307323
}
308324
},
325+
CLASS_ASSERTION_BY_OBJECT {
326+
@Override
327+
Stream<? extends OWLObject> listAxioms(OWLOntology ont, OWLObject param) {
328+
return ont.classAssertionAxioms((OWLClassExpression) param);
329+
}
330+
},
309331
;
310332

311333
private ByPrimitiveTester of() {

0 commit comments

Comments
 (0)