aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/uk/ac/ox/cs/pagoda/approx
diff options
context:
space:
mode:
authorFederico Igne <federico.igne@cs.ox.ac.uk>2022-05-10 18:17:06 +0100
committerFederico Igne <federico.igne@cs.ox.ac.uk>2022-05-11 12:34:47 +0100
commit17bd9beaf7f358a44e5bf36a5855fe6727d506dc (patch)
tree47e9310a0cff869d9ec017dcb2c81876407782c8 /src/main/java/uk/ac/ox/cs/pagoda/approx
parent8651164cd632a5db310b457ce32d4fbc97bdc41c (diff)
downloadACQuA-17bd9beaf7f358a44e5bf36a5855fe6727d506dc.tar.gz
ACQuA-17bd9beaf7f358a44e5bf36a5855fe6727d506dc.zip
[pagoda] Move project to Scala
This commit includes a few changes: - The repository still uses Maven to manage dependency but it is now a Scala project. - The code has been ported from OWLAPI 3.4.10 to 5.1.20 - A proof of concept program using both RSAComb and PAGOdA has been added.
Diffstat (limited to 'src/main/java/uk/ac/ox/cs/pagoda/approx')
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/approx/Clause.java724
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/approx/Clausifier.java37
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java18
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/approx/RLOntology.java190
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java607
5 files changed, 1576 insertions, 0 deletions
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/approx/Clause.java b/src/main/java/uk/ac/ox/cs/pagoda/approx/Clause.java
new file mode 100644
index 0000000..3783e8c
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/approx/Clause.java
@@ -0,0 +1,724 @@
1package uk.ac.ox.cs.pagoda.approx;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.Iterator;
6import java.util.Map;
7import java.util.Set;
8
9import org.semanticweb.HermiT.model.*;
10import org.semanticweb.owlapi.model.*;
11
12import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper;
13import uk.ac.ox.cs.pagoda.util.Namespace;
14import uk.ac.ox.cs.pagoda.util.Utility;
15
16public class Clause {
17
18 Set<Atom> headAtoms;
19 Set<Atom> bodyAtoms;
20
21 Set<String> dataProperties;
22 OWLDataFactory factory;
23 // OWLClass top = null;
24
25 private Set<OWLClassExpression> superClasses = new HashSet<OWLClassExpression>();
26 private Set<OWLClassExpression> subClasses = new HashSet<OWLClassExpression>();
27
28 public Clause(Clausifier clausifier, DLClause clause) {
29 this.dataProperties = clausifier.dataProperties;
30 this.factory = clausifier.factory;
31 // top = ontology.top;
32
33 headAtoms = Utility.toSet(clause.getHeadAtoms());
34 bodyAtoms = Utility.toSet(clause.getBodyAtoms());
35
36 rollingUp();
37 }
38
39 private static final Variable X = Variable.create("X");
40
41 private void rollingUp() {
42 Map<Variable, Set<Variable>> varCliques = new HashMap<Variable, Set<Variable>>();
43
44 for (Iterator<Atom> iter = bodyAtoms.iterator(); iter.hasNext();) {
45 Atom atom = iter.next();
46 if (atom.getDLPredicate() instanceof Inequality)
47 if (atom.getArgument(0) instanceof Variable
48 && atom.getArgument(1) instanceof Variable) {
49 Variable var1 = atom.getArgumentVariable(0), var2 = atom
50 .getArgumentVariable(1);
51 Set<Variable> rep;
52 if ((rep = varCliques.get(var1)) == null)
53 if ((rep = varCliques.get(var2)) == null)
54 rep = new HashSet<Variable>();
55 rep.add(var1);
56 rep.add(var2);
57 varCliques.put(var1, rep);
58 varCliques.put(var2, rep);
59 iter.remove();
60 }
61 }
62
63 eliminateEquality();
64
65 Map<Variable, Atom> var2atom = new HashMap<Variable, Atom>();
66
67 getVariableOccurrence(var2atom, headAtoms);
68 getVariableOccurrence(var2atom, bodyAtoms);
69
70 DLPredicate predicate;
71 Term W = null;
72
73 Map<Variable, String> nom2iri = new HashMap<Variable, String>();
74 Map<Variable, Constant> nom2datatype = new HashMap<Variable, Constant>();
75
76 for (Iterator<Atom> iter = headAtoms.iterator(); iter.hasNext();) {
77 Atom tAtom = iter.next();
78 predicate = tAtom.getDLPredicate();
79 if (predicate instanceof AtomicNegationDataRange) {
80 AtomicNegationDataRange andr = (AtomicNegationDataRange) predicate;
81 AtomicDataRange adr = andr.getNegatedDataRange();
82 if (adr instanceof ConstantEnumeration) {
83 ConstantEnumeration e = (ConstantEnumeration) adr;
84 if (e.getNumberOfConstants() == 1) {
85 Variable v = tAtom.getArgumentVariable(0);
86 nom2datatype.put(v, e.getConstant(0));
87 iter.remove();
88 continue;
89 }
90 }
91 }
92 }
93
94 for (Atom atom : bodyAtoms) {
95 predicate = atom.getDLPredicate();
96 if (predicate instanceof AtomicConcept) {
97 AtomicConcept concept = (AtomicConcept) predicate;
98 Variable v = atom.getArgumentVariable(0);
99 if (v == X)
100 subClasses.add(factory.getOWLClass(IRI.create(concept.getIRI())));
101 else if (predicate.toString().startsWith("<internal:nom#"))
102 nom2iri.put(v, DLClauseHelper.getIRI4Nominal(concept));
103 } else if (predicate instanceof AtomicRole) {
104 AtomicRole role = (AtomicRole) predicate;
105
106 if (dataProperties.contains(role.getIRI())) {
107 OWLDataRange dataRange;
108 OWLDataPropertyExpression dataPropertyExp = factory
109 .getOWLDataProperty(IRI.create(role.getIRI()));
110 Term term = atom.getArgument(1);
111 if (term instanceof Constant)
112 subClasses.add(factory
113 .getOWLDataHasValue(dataPropertyExp,
114 getOWLLiteral((Constant) term)));
115 else if (term instanceof Variable) {
116 W = (Variable) term;
117 if (nom2datatype.containsKey(W)) {
118 subClasses.add(factory.getOWLDataHasValue(
119 dataPropertyExp,
120 getOWLLiteral(nom2datatype.get(W))));
121 } else if (var2atom.containsKey(W)) {
122 Atom tAtom = var2atom.get(W);
123 DLPredicate tPredicate = tAtom.getDLPredicate();
124 if (tPredicate instanceof DatatypeRestriction) {
125 DatatypeRestriction restriction = (DatatypeRestriction) tPredicate;
126 dataRange = factory.getOWLDatatype(IRI
127 .create(restriction.getDatatypeURI()));
128 }
129 // else if (tPredicate instanceof
130 // AtomicNegationDataRange) {
131 // // TODO how to deal with AtomicNegationDataRange
132 // e.g. not({ "5"^^xsd:integer })
133 //
134 // }
135 else if (tPredicate instanceof AtomicConcept) {
136 dataRange = factory.getOWLDatatype(IRI
137 .create(((AtomicConcept) tPredicate)
138 .getIRI()));
139 } else {
140 dataRange = null;
141 Utility.logError(tPredicate,
142 "strange ... -___-|||");
143 }
144
145 if (headAtoms.contains(tAtom)) {
146 superClasses.add(factory
147 .getOWLDataAllValuesFrom(
148 dataPropertyExp, dataRange));
149 subClasses.add(factory
150 .getOWLDataSomeValuesFrom(
151 dataPropertyExp,
152 factory.getTopDatatype()));
153 headAtoms.remove(tAtom);
154 } else
155 subClasses.add(factory
156 .getOWLDataSomeValuesFrom(
157 dataPropertyExp, dataRange));
158
159 } else
160 subClasses.add(factory.getOWLDataSomeValuesFrom(
161 dataPropertyExp, factory.getTopDatatype()));
162 } else {
163 Utility.logError(term, "strange ... -___-|||");
164 }
165 continue;
166 }
167
168 OWLObjectPropertyExpression roleExp = factory
169 .getOWLObjectProperty(IRI.create(role.getIRI()));
170 if ((W = atom.getArgument(1)).equals(X)) {
171 roleExp = roleExp.getInverseProperty();
172 W = atom.getArgument(0);
173 }
174
175 if (X == W)
176 subClasses.add(factory.getOWLObjectHasSelf(roleExp));
177 else if (W instanceof Individual)
178 subClasses.add(factory.getOWLObjectHasValue(roleExp, factory.getOWLNamedIndividual(IRI.create(((Individual) W).getIRI()))));
179 else {
180 AtomicConcept concept;
181 OWLClassExpression clsExp = null;
182 int number = 1;
183 Set<Variable> set = varCliques.get(W);
184 if (set != null)
185 number = set.size();
186
187 if (var2atom.containsKey(W)) {
188 Atom tAtom = var2atom.get(W);
189 DLPredicate tPredicate = tAtom.getDLPredicate();
190 if (tPredicate instanceof AtomicConcept) {
191 concept = (AtomicConcept) tPredicate;
192 clsExp = factory.getOWLClass(IRI.create(concept
193 .getIRI()));
194 if (headAtoms.contains(tAtom)) {
195 superClasses.add(factory.getOWLObjectAllValuesFrom(
196 roleExp, clsExp));
197 subClasses.add(factory.getOWLObjectSomeValuesFrom(
198 roleExp, factory.getOWLThing()));
199 headAtoms.remove(tAtom);
200 } else {
201 if (number == 1)
202 subClasses.add(factory
203 .getOWLObjectSomeValuesFrom(roleExp,
204 clsExp));
205 else
206 subClasses.add(factory
207 .getOWLObjectMinCardinality(number,
208 roleExp, clsExp));
209 }
210 } else {
211 Utility.logDebug(tAtom, "strange ... -___-|||");
212 }
213 }
214 else {
215 if (number == 1)
216 subClasses.add(factory.getOWLObjectSomeValuesFrom(
217 roleExp, factory.getOWLThing()));
218 else
219 subClasses.add(factory.getOWLObjectMinCardinality(
220 number, roleExp));
221 }
222 }
223 }
224 }
225
226 OWLObjectPropertyExpression objExp;
227 for (Atom atom : headAtoms) {
228 predicate = atom.getDLPredicate();
229 if (predicate instanceof AtomicConcept) {
230 if (atom.getArgumentVariable(0) == X)
231 superClasses
232 .add(getClassExpression((AtomicConcept) predicate));
233 } else if (predicate instanceof AtomicRole) {
234 if (!dataProperties.contains(((AtomicRole) predicate).getIRI())) {
235 objExp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) predicate).getIRI()));
236 Term V = atom.getArgument(1);
237 if (V == X) {
238 objExp = factory.getOWLObjectInverseOf(objExp.asOWLObjectProperty());
239 V = atom.getArgument(0);
240 }
241
242 if (V == X)
243 superClasses.add(factory.getOWLObjectHasSelf(objExp));
244 else if (V instanceof Individual) {
245 superClasses.add(factory.getOWLObjectHasValue(objExp,
246 factory.getOWLNamedIndividual(IRI
247 .create(((Individual) V).getIRI()))));
248 } else
249 superClasses.add(factory.getOWLObjectHasValue(objExp,
250 factory.getOWLNamedIndividual(IRI.create(nom2iri
251 .get((Variable) V)))));
252 }
253 else {
254 Constant c = (Constant) atom.getArgument(1);
255 OWLDataProperty dataProp = factory.getOWLDataProperty(IRI.create(((AtomicRole) predicate).getIRI()));
256 superClasses.add(factory.getOWLDataHasValue(dataProp, getOWLLiteral(c)));
257 }
258 } else if (predicate instanceof AtLeastConcept)
259 superClasses
260 .add(getMinCardinalityExpression((AtLeastConcept) predicate));
261 else if (predicate instanceof AtLeastDataRange)
262 superClasses
263 .add(getDataMinCardinalityExpression((AtLeastDataRange) predicate));
264
265 else {
266 Utility.logError(atom.toString(),
267 "strange head atoms left here~~~~~");
268 // superClasses.add(getDataRange(getDataRange((LiteralDataRange)
269 // predicate)));
270 }
271 }
272 }
273
274 private OWLLiteral getOWLLiteral(Constant constant) {
275 if (!constant.getDatatypeURI().equals(Namespace.RDF_PLAIN_LITERAL))
276 return factory.getOWLLiteral(constant.getLexicalForm(), factory
277 .getOWLDatatype(IRI.create(constant.getDatatypeURI())));
278 else {
279 String lexicalForm = constant.getLexicalForm();
280 int index = lexicalForm.indexOf("@");
281 return factory.getOWLLiteral(lexicalForm.substring(0, index),
282 lexicalForm.substring(index + 1));
283 }
284 }
285
286 // private OWLObjectSomeValuesFrom
287 // addSomeValuesFromAxiom(OWLObjectPropertyExpression roleExp,
288 // OWLClassExpression classExp) {
289 // return factory.getOWLObjectSomeValuesFrom(roleExp, classExp);
290 // }
291
292 private void getVariableOccurrence(Map<Variable, Atom> var2atom,
293 Set<Atom> atoms) {
294 for (Atom atom : atoms)
295 if (atom.getArity() == 1 && atom.getArgument(0) instanceof Variable
296 && !atom.getArgument(0).equals(X))
297 var2atom.put((Variable) atom.getArgumentVariable(0), atom);
298 }
299
300 private OWLClassExpression getMinCardinalityExpression(
301 AtLeastConcept atLeast) {
302 OWLObjectPropertyExpression propExp = getObjectPropertyExpression(atLeast
303 .getOnRole());
304 OWLClassExpression clsExp = getClassExpression(atLeast.getToConcept());
305 if (atLeast.getNumber() == 1)
306 return factory.getOWLObjectSomeValuesFrom(propExp, clsExp);
307 else
308 return factory.getOWLObjectMinCardinality(atLeast.getNumber(),
309 propExp, clsExp);
310 }
311
312 private OWLClassExpression getDataMinCardinalityExpression(
313 AtLeastDataRange atLeast) {
314 OWLDataPropertyExpression propExp = getDataPropertyExpression(atLeast
315 .getOnRole());
316 OWLDataRange dataRange = getDataRange(atLeast.getToDataRange());
317 if (atLeast.getNumber() == 1)
318 return factory.getOWLDataSomeValuesFrom(propExp, dataRange);
319 else
320 return factory.getOWLDataMinCardinality(atLeast.getNumber(),
321 propExp, dataRange);
322 }
323
324 public Set<OWLClassExpression> getSuperClasses() {
325 return superClasses;
326 }
327
328 public Set<OWLClassExpression> getSubClasses() {
329 return subClasses;
330 }
331
332 // public OWLClassExpression getSubClass() {
333 // if (subClasses.isEmpty())
334 // return factory.getOWLThing();
335 // if (subClasses.size() == 1)
336 // return subClasses.iterator().next();
337 //
338 // return factory.getOWLObjectIntersectionOf(subClasses);
339 // }
340
341 private void eliminateEquality() {
342 Set<Atom> eHeadAtoms = new HashSet<Atom>();
343 Set<Atom> eBodyAtoms = new HashSet<Atom>();
344 Set<Variable> eVariables = new HashSet<Variable>();
345 seperateEquality4Clause(eBodyAtoms, eHeadAtoms, eVariables);
346
347 OWLNamedIndividual individual;
348 /*
349 * remove equalities that are introduced by MaxCardinalityConstraints
350 */
351 DLPredicate predicate;
352 Map<Variable, Set<Variable>> groups = new HashMap<Variable, Set<Variable>>();
353 OWLObjectMaxCardinality maxCardinality;
354 OWLClassExpression exp;
355 Set<Variable> mVariables = new HashSet<Variable>();
356 Variable tVar, tVar1, tVar2;
357 Set<Variable> tVariables;
358
359 for (Iterator<Atom> iter = eHeadAtoms.iterator(); iter.hasNext(); ){
360 Atom atom = iter.next();
361 predicate = atom.getDLPredicate();
362 if (predicate instanceof AnnotatedEquality) {
363 superClasses.add(maxCardinality = getMaxCardinalityExpression((AnnotatedEquality)predicate));
364 if (!((exp = maxCardinality.getFiller()) instanceof OWLObjectComplementOf))
365 subClasses.add(factory.getOWLObjectSomeValuesFrom(maxCardinality.getProperty(), exp));
366 else
367 subClasses.add(factory.getOWLObjectSomeValuesFrom(maxCardinality.getProperty(), factory.getOWLThing()));
368 mVariables.add(atom.getArgumentVariable(0));
369 mVariables.add(atom.getArgumentVariable(1));
370 iter.remove();
371 }
372 else if (predicate instanceof Equality) {
373 if (atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) {
374 mVariables.add(tVar1 = atom.getArgumentVariable(0));
375 mVariables.add(tVar2 = atom.getArgumentVariable(1));
376 iter.remove();
377
378 if (tVar1.getName().compareTo(tVar2.getName()) > 0) {
379 tVar = tVar1; tVar1 = tVar2; tVar2 = tVar;
380 }
381 tVariables = groups.get(tVar1);
382 if (groups.containsKey(tVar2)) {
383 if (tVariables == null)
384 groups.put(tVar1, tVariables = groups.get(tVar2));
385 else {
386 tVariables.addAll(groups.get(tVar2));
387 groups.get(tVar2).clear();
388 groups.put(tVar2, tVariables);
389 }
390 }
391 if (tVariables == null) {
392 groups.put(tVar1, tVariables = new HashSet<Variable>());
393 groups.put(tVar2, tVariables);
394 }
395 tVariables.add(tVar1);
396 tVariables.add(tVar2);
397 }
398 }
399 }
400
401 Map<Variable, Object> maxCardToConcepts = new HashMap<Variable, Object>();
402
403 for (Iterator<Atom> iter = eBodyAtoms.iterator(); iter.hasNext(); ) {
404 Atom atom = iter.next();
405 if (atom.getArity() == 1 && atom.getArgument(0) instanceof Variable) {
406 if (mVariables.contains(tVar = atom.getArgumentVariable(0))) {
407 maxCardToConcepts.put(tVar, atom.getDLPredicate());
408 iter.remove();
409 }
410 }
411 }
412
413 for (Iterator<Atom> iter = eHeadAtoms.iterator(); iter.hasNext(); ) {
414 Atom atom = iter.next();
415 if (atom.getArity() == 1 && atom.getArgument(0) instanceof Variable) {
416 if (mVariables.contains(tVar = atom.getArgumentVariable(0))) {
417 maxCardToConcepts.put(tVar, AtomicNegationConcept.create((AtomicConcept) atom.getDLPredicate()));
418 iter.remove();
419 }
420 }
421 }
422
423 Map<Variable, Object> maxCardToProperty = new HashMap<Variable, Object>();
424
425 for (Iterator<Atom> iter = eBodyAtoms.iterator(); iter.hasNext(); ) {
426 Atom atom = iter.next();
427 if (atom.getArity() == 2 && atom.getArgument(0) instanceof Variable && atom.getArgument(1) instanceof Variable) {
428 tVar1 = atom.getArgumentVariable(0); tVar2 = atom.getArgumentVariable(1);
429 if (mVariables.contains(tVar1)) {
430 if (groups.containsKey(tVar1))
431 maxCardToProperty.put(tVar1, ((AtomicRole) atom.getDLPredicate()).getInverse());
432 iter.remove();
433 } else if (mVariables.contains(tVar2)) {
434 if (groups.containsKey(tVar2))
435 maxCardToProperty.put(tVar2, atom.getDLPredicate());
436 iter.remove();
437 }
438 }
439 }
440
441 int n;
442 Object r, A;
443 for (Variable var: groups.keySet()) {
444 if ((tVariables = groups.get(var)).isEmpty())
445 continue;
446 n = tVariables.size() - 1;
447 tVariables.clear();
448 r = maxCardToProperty.get(var);
449 if (r instanceof AtomicRole) {
450 if (isDataProperty(r)) {
451 if ((A = maxCardToConcepts.get(var)) != null) {
452 Utility.logError("Unknown data range: " + A);
453 }
454
455 superClasses.add(
456 factory.getOWLDataMaxCardinality(
457 n,
458 factory.getOWLDataProperty(IRI.create(((AtomicRole) r).getIRI()))));
459 }
460 else {
461 OWLClassExpression clsExp = null;
462 if ((A = maxCardToConcepts.get(var)) != null)
463 if (A instanceof AtomicConcept)
464 clsExp = factory.getOWLClass(IRI.create(((AtomicConcept) A).getIRI()));
465 else if (A instanceof AtomicNegationConcept)
466 clsExp = factory.getOWLObjectComplementOf(factory.getOWLClass(IRI.create(((AtomicNegationConcept) A).getNegatedAtomicConcept().getIRI())));
467 else
468 Utility.logError("Unknown to concept: " + A);
469
470 if (A == null)
471 superClasses.add(
472 factory.getOWLObjectMaxCardinality(
473 n,
474 factory.getOWLObjectProperty(IRI.create(((AtomicRole) r).getIRI()))
475 ));
476 else
477 superClasses.add(
478 factory.getOWLObjectMaxCardinality(
479 n,
480 factory.getOWLObjectProperty(IRI.create(((AtomicRole) r).getIRI())),
481 clsExp));
482 }
483 }
484 else if (r instanceof InverseRole) {
485 OWLClassExpression clsExp = null;
486 if ((A = maxCardToConcepts.get(var)) != null) {
487 if (A instanceof AtomicConcept)
488 clsExp = factory.getOWLClass(IRI.create(((AtomicConcept) A).getIRI()));
489 else if (A instanceof AtomicNegationConcept)
490 clsExp = factory.getOWLObjectComplementOf(factory.getOWLClass(IRI.create(((AtomicNegationConcept) A).getNegatedAtomicConcept().getIRI())));
491 else
492 Utility.logError("Unknown to concept: " + A);
493 }
494
495 if (A == null)
496 superClasses.add(
497 factory.getOWLObjectMaxCardinality(
498 n,
499 factory.getOWLObjectInverseOf(factory.getOWLObjectProperty(IRI.create(((InverseRole) r).getInverseOf().getIRI())))
500 ));
501 else
502 superClasses.add(
503 factory.getOWLObjectMaxCardinality(
504 n,
505 factory.getOWLObjectInverseOf(factory.getOWLObjectProperty(IRI.create(((InverseRole) r).getInverseOf().getIRI()))),
506 clsExp));
507
508 }
509 else
510 Utility.logError("Unknown property: " + r);
511 }
512
513 /*
514 * dealing with equalities of nominal
515 */
516 Map<Variable, String> nom2iri = new HashMap<Variable, String>();
517 for (Iterator<Atom> iter = eBodyAtoms.iterator(); iter.hasNext(); ) {
518 Atom atom = iter.next();
519 predicate = atom.getDLPredicate();
520 if (predicate instanceof AtomicConcept && predicate.toString().startsWith("<internal:nom#")) {
521 nom2iri.put(atom.getArgumentVariable(0), DLClauseHelper.getIRI4Nominal(predicate));
522 iter.remove();
523 }
524 }
525
526 Term first, second;
527 Map<Variable, Set<Term>> equEdges = new HashMap<Variable, Set<Term>>();
528 Set<Term> terms = new HashSet<Term>();
529 for (Atom atom: eHeadAtoms) {
530 predicate = atom.getDLPredicate();
531 if (predicate instanceof Equality) {
532 first = atom.getArgument(0);
533 second = atom.getArgument(1);
534
535 if (first instanceof Variable) {
536 if ((terms = equEdges.get(first)) == null)
537 equEdges.put((Variable) first, (terms = new HashSet<Term>()));
538 terms.add(second);
539 }
540
541 if (second instanceof Variable) {
542 if ((terms = equEdges.get(second)) == null)
543 equEdges.put((Variable) second, (terms = new HashSet<Term>()));
544 terms.add(first);
545 }
546 }
547 }
548
549 OWLObjectPropertyExpression objExp;
550
551 Set<OWLNamedIndividual> individuals = new HashSet<OWLNamedIndividual>();
552 if (equEdges.containsKey(X)) {
553 for (Term t: equEdges.get(X))
554 if (t instanceof Variable) {
555 Variable var = (Variable) t;
556 individual = factory.getOWLNamedIndividual(IRI.create(nom2iri.get(var)));
557// superClasses.add(factory.getOWLObjectOneOf(individual));
558 individuals.add(individual);
559 }
560 else if (t instanceof Individual)
561 individuals.add(factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI())));
562 }
563
564 if (individuals.size() > 0) {
565 superClasses.add(factory.getOWLObjectOneOf(individuals));
566 individuals.clear();
567 }
568
569 for (Atom atom: eBodyAtoms) {
570 predicate = atom.getDLPredicate();
571 if (predicate instanceof AtomicRole) {
572 first = atom.getArgumentVariable(0);
573 second = atom.getArgumentVariable(1);
574
575 objExp = factory.getOWLObjectProperty(IRI.create(((AtomicRole) predicate).getIRI()));
576 if (eVariables.contains(first)) {
577 second = first;
578 objExp = factory.getOWLObjectInverseOf(objExp.asOWLObjectProperty());
579 }
580
581 for (Term t: equEdges.get(second)) {
582 if (t instanceof Variable) {
583 Variable var = (Variable) t;
584 individuals.add(factory.getOWLNamedIndividual(IRI.create(nom2iri.get(var))));
585 }
586 else if (t instanceof Individual) {
587 individuals.add(factory.getOWLNamedIndividual(IRI.create(((Individual) t).getIRI())));
588 }
589 }
590 if (!individuals.isEmpty()) {
591 superClasses.add(factory.getOWLObjectAllValuesFrom(objExp, factory.getOWLObjectOneOf(individuals)));
592 individuals.clear();
593 }
594 }
595 }
596
597 }
598
599 private boolean isDataProperty(Object r) {
600 if (!(r instanceof AtomicRole)) return false;
601 String iri = ((AtomicRole) r).getIRI();
602 return dataProperties.contains(iri);
603 }
604
605 private OWLObjectMaxCardinality getMaxCardinalityExpression(
606 AnnotatedEquality equ) {
607 OWLObjectPropertyExpression propExp = getObjectPropertyExpression(equ
608 .getOnRole());
609 OWLClassExpression clsExp = getClassExpression(equ.getToConcept());
610 return factory.getOWLObjectMaxCardinality(equ.getCaridnality(),
611 propExp, clsExp);
612 }
613
614 private OWLObjectPropertyExpression getObjectPropertyExpression(Role role) {
615 if (role instanceof AtomicRole)
616 return factory.getOWLObjectProperty(IRI.create(((AtomicRole) role)
617 .getIRI()));
618 return factory.getOWLObjectProperty(
619 IRI.create(((InverseRole) role).getInverseOf().getIRI()))
620 .getInverseProperty();
621 }
622
623 private OWLDataProperty getDataPropertyExpression(Role role) {
624 return factory.getOWLDataProperty(IRI.create(((AtomicRole) role)
625 .getIRI()));
626 }
627
628 private OWLClassExpression getClassExpression(LiteralConcept concept) {
629 if (concept instanceof AtomicConcept)
630 return factory.getOWLClass(IRI.create(((AtomicConcept) concept)
631 .getIRI()));
632 return factory.getOWLClass(
633 IRI.create(((AtomicNegationConcept) concept)
634 .getNegatedAtomicConcept().getIRI()))
635 .getComplementNNF();
636 }
637
638 private OWLDataRange getDataRange(LiteralDataRange dataRange) {
639 if (dataRange instanceof InternalDatatype)
640 return factory.getOWLDatatype(IRI
641 .create(((InternalDatatype) dataRange).getIRI()));
642 if (dataRange instanceof DatatypeRestriction)
643 return factory
644 .getOWLDatatype(IRI
645 .create(((DatatypeRestriction) dataRange)
646 .getDatatypeURI()));
647 if (dataRange instanceof ConstantEnumeration) {
648 ConstantEnumeration e = (ConstantEnumeration) dataRange;
649 OWLLiteral[] values = new OWLLiteral[e.getNumberOfConstants()];
650 for (int i = 0; i < values.length; ++i) {
651 Constant c = e.getConstant(i);
652 values[i] = factory.getOWLLiteral(c.getDataValue().toString(),
653 factory.getOWLDatatype(IRI.create(c.getDatatypeURI())));
654 }
655 return factory.getOWLDataOneOf(values);
656 }
657 Utility.logError(dataRange.toString(), "strange data type!!!!");
658 return null;
659 }
660
661 public void seperateEquality4Clause(Set<Atom> eBodyAtoms,
662 Set<Atom> eHeadAtoms, Set<Variable> eVariables) {
663 Set<Variable> variables = new HashSet<Variable>();
664 DLPredicate predicate;
665 for (Atom atom : headAtoms) {
666 predicate = atom.getDLPredicate();
667 if (predicate instanceof Equality
668 || predicate instanceof AnnotatedEquality) {
669 variables.clear();
670 atom.getVariables(variables);
671 for (Variable variable : variables)
672 eVariables.add(variable);
673 }
674 }
675 eVariables.remove(X);
676
677 seperateEquality(bodyAtoms, eBodyAtoms, eVariables);
678 seperateEquality(headAtoms, eHeadAtoms, eVariables);
679 }
680
681 public void seperateEquality(Set<Atom> noEquality, Set<Atom> inEquality,
682 Set<Variable> eVariables) {
683 Set<Variable> variables = new HashSet<Variable>();
684 for (Iterator<Atom> iter = noEquality.iterator(); iter.hasNext();) {
685 Atom atom = iter.next();
686 if (atom.getDLPredicate() instanceof Equality
687 || atom.getDLPredicate() instanceof AnnotatedEquality) {
688 iter.remove();
689 inEquality.add(atom);
690 } else {
691 variables.clear();
692 atom.getVariables(variables);
693 for (Variable variable : variables)
694 if (eVariables.contains(variable)) {
695 iter.remove();
696 inEquality.add(atom);
697 break;
698 }
699 }
700 }
701 }
702
703 @Override
704 public String toString() {
705 StringBuilder ret = new StringBuilder();
706 boolean first = true;
707 for (OWLClassExpression exp : superClasses)
708 if (first) {
709 ret.append(exp.toString());
710 first = false;
711 } else
712 ret.append(" v ").append(exp.toString());
713
714 first = true;
715 for (OWLClassExpression exp : subClasses)
716 if (first) {
717 ret.append(" :- ").append(exp.toString());
718 first = false;
719 } else
720 ret.append(" ^ ").append(exp.toString());
721
722 return ret.toString();
723 }
724}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/approx/Clausifier.java b/src/main/java/uk/ac/ox/cs/pagoda/approx/Clausifier.java
new file mode 100644
index 0000000..ee23def
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/approx/Clausifier.java
@@ -0,0 +1,37 @@
1package uk.ac.ox.cs.pagoda.approx;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.Set;
6
7import org.semanticweb.HermiT.model.DLClause;
8import org.semanticweb.owlapi.model.OWLDataFactory;
9import org.semanticweb.owlapi.model.OWLDataProperty;
10import org.semanticweb.owlapi.model.OWLOntology;
11
12public class Clausifier {
13
14 OWLDataFactory factory;
15 Set<String> dataProperties = new HashSet<String>();
16
17 private Clausifier(OWLOntology ontology) {
18 factory = ontology.getOWLOntologyManager().getOWLDataFactory();
19 for (OWLDataProperty dataProperty: ontology.getDataPropertiesInSignature(true))
20 dataProperties.add(dataProperty.toStringID());
21 }
22
23 public Clause clasuify(DLClause clause) {
24 return new Clause(this, clause);
25 }
26
27 private static HashMap<OWLOntology, Clausifier> AllInstances = new HashMap<OWLOntology, Clausifier>();
28
29 public static Clausifier getInstance(OWLOntology onto) {
30 Clausifier c = AllInstances.get(onto);
31 if (c != null) return c;
32 c = new Clausifier(onto);
33 AllInstances.put(onto, c);
34 return c;
35 }
36
37}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java b/src/main/java/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java
new file mode 100644
index 0000000..4b3c057
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/approx/KnowledgeBase.java
@@ -0,0 +1,18 @@
1package uk.ac.ox.cs.pagoda.approx;
2
3import org.semanticweb.owlapi.model.OWLOntology;
4import uk.ac.ox.cs.pagoda.constraints.BottomStrategy;
5
6public interface KnowledgeBase {
7
8 void load(OWLOntology ontology, BottomStrategy botStrategy);
9
10 void transform();
11
12 void save();
13
14 String getOutputPath();
15
16 String getDirectory();
17
18}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/approx/RLOntology.java b/src/main/java/uk/ac/ox/cs/pagoda/approx/RLOntology.java
new file mode 100644
index 0000000..dba6a56
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/approx/RLOntology.java
@@ -0,0 +1,190 @@
1package uk.ac.ox.cs.pagoda.approx;
2
3import java.util.Collection;
4import java.util.HashMap;
5import java.util.HashSet;
6import java.util.LinkedList;
7import java.util.Map;
8import java.util.Set;
9
10import org.semanticweb.owlapi.model.IRI;
11import org.semanticweb.owlapi.model.OWLAxiom;
12import org.semanticweb.owlapi.model.OWLClass;
13import org.semanticweb.owlapi.model.OWLClassExpression;
14import org.semanticweb.owlapi.model.OWLIndividual;
15import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom;
16import org.semanticweb.owlapi.model.OWLObjectHasSelf;
17import org.semanticweb.owlapi.model.OWLObjectOneOf;
18import org.semanticweb.owlapi.model.OWLObjectProperty;
19import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
20
21import uk.ac.ox.cs.pagoda.owl.OWLHelper;
22import uk.ac.ox.cs.pagoda.util.Utility;
23
24public class RLOntology extends RLPlusOntology {
25
26 @Override
27 public void transform() {
28 super.transform();
29
30 eliminateSelf();
31 eliminateNominals();
32 eliminateOWLThing();
33
34 save();
35 if (aBox.getAxiomCount() != 0)
36 save(aBox);
37 }
38
39 private void eliminateSelf() {
40 Collection<OWLAxiom> axioms = new LinkedList<OWLAxiom>(outputOntology.getAxioms());
41 OWLClassExpression subExp, superExp, newSubExp, newSuperExp;
42 for (OWLAxiom axiom: axioms)
43 if (axiom instanceof OWLSubClassOfAxiom) {
44 subExp = ((OWLSubClassOfAxiom) axiom).getSubClass();
45 superExp = ((OWLSubClassOfAxiom) axiom).getSuperClass();
46 newSubExp = approximateSelf4Sub(subExp);
47 newSuperExp = approximateSelf4Super(superExp);
48 if (newSubExp != subExp || newSuperExp != superExp)
49 replaceAxiom4output(axiom, factory.getOWLSubClassOfAxiom(newSubExp, newSuperExp));
50 }
51 }
52
53 private void replaceAxiom4output(OWLAxiom oldAxiom, OWLAxiom newAxiom) {
54 manager.removeAxiom(outputOntology, oldAxiom);
55 manager.addAxiom(outputOntology, newAxiom);
56 correspondence.put(newAxiom, correspondence.remove(oldAxiom));
57 }
58
59 private boolean hasSelf(OWLClassExpression conjunction) {
60 for (OWLClassExpression conjunct: conjunction.asConjunctSet())
61 if (conjunct instanceof OWLObjectHasSelf)
62 return true;
63 return false;
64 }
65
66 private OWLClassExpression approximateSelf4Sub(OWLClassExpression exp) {
67 if (!hasSelf(exp)) return exp;
68 Set<OWLClassExpression> newConjuncts = new HashSet<OWLClassExpression>();
69 for (OWLClassExpression conjunct: exp.asConjunctSet())
70 if (conjunct instanceof OWLObjectHasSelf)
71 newConjuncts.add(factory.getOWLObjectSomeValuesFrom(((OWLObjectHasSelf) exp).getProperty(), factory.getOWLThing()));
72 else
73 newConjuncts.add(conjunct);
74 return OWLHelper.getSimplifiedConjunction(factory, newConjuncts);
75 }
76
77 private OWLClassExpression approximateSelf4Super(OWLClassExpression exp) {
78 if (!hasSelf(exp)) return exp;
79 Set<OWLClassExpression> newConjuncts = new HashSet<OWLClassExpression>();
80 for (OWLClassExpression conjunct: exp.asConjunctSet())
81 if (conjunct instanceof OWLObjectHasSelf) {
82 OWLIndividual freshNominal = getNewIndividual(outputOntology, rlCounter++);
83 newConjuncts.add(factory.getOWLObjectOneOf(freshNominal));
84 newConjuncts.add(factory.getOWLObjectHasValue(((OWLObjectHasSelf) exp).getProperty(), freshNominal));
85 }
86 else
87 newConjuncts.add(conjunct);
88
89 return OWLHelper.getSimplifiedConjunction(factory, newConjuncts);
90 }
91
92 private void eliminateNominals() {
93 Collection<OWLAxiom> axioms = new LinkedList<OWLAxiom>(outputOntology.getAxioms());
94 OWLClassExpression superExp, newSuperExp;
95 for (OWLAxiom axiom: axioms)
96 if (axiom instanceof OWLSubClassOfAxiom) {
97 superExp = ((OWLSubClassOfAxiom) axiom).getSuperClass();
98 newSuperExp = approximateNominals(superExp);
99 if (newSuperExp != superExp)
100 replaceAxiom4output(axiom, factory.getOWLSubClassOfAxiom(((OWLSubClassOfAxiom) axiom).getSubClass(), newSuperExp));
101 }
102 }
103
104 private OWLClassExpression approximateNominals(OWLClassExpression exp) {
105 if (!hasIllegalNominals(exp)) return exp;
106 Set<OWLIndividual> nominals;
107 Set<OWLClassExpression> newConjuncts = new HashSet<OWLClassExpression>();
108 for (OWLClassExpression conjunct: exp.asConjunctSet()) {
109 if (conjunct instanceof OWLObjectOneOf) {
110 nominals = ((OWLObjectOneOf) conjunct).getIndividuals();
111 newConjuncts.add(approximateNominal(nominals));
112 }
113 else if (conjunct instanceof OWLObjectAllValuesFrom) {
114 OWLObjectAllValuesFrom allValuesFrom = ((OWLObjectAllValuesFrom) conjunct);
115 if (allValuesFrom.getFiller() instanceof OWLObjectOneOf) {
116 nominals = ((OWLObjectOneOf) allValuesFrom.getFiller()).getIndividuals();
117 newConjuncts.add(factory.getOWLObjectAllValuesFrom(allValuesFrom.getProperty(),
118 approximateNominal(nominals)));
119 }
120 }
121 }
122 return OWLHelper.getSimplifiedConjunction(factory, newConjuncts);
123 }
124
125 private OWLClassExpression approximateNominal(Set<OWLIndividual> nominals) {
126 if (nominals.size() > 1) {
127 Utility.logError("Error: more than one nominal appearing in OWLObjectOneOf");
128 return null;
129 }
130 OWLIndividual nominal = nominals.iterator().next();
131 OWLObjectProperty freshProperty = getNewRole4Nominal(nominal);
132 addAxiom2output(factory.getOWLInverseFunctionalObjectPropertyAxiom(freshProperty), null);
133 manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(freshProperty, nominal, nominal));
134 return factory.getOWLObjectHasValue(freshProperty, nominal);
135 }
136
137 Map<OWLIndividual, OWLObjectProperty> role4nominal = new HashMap<OWLIndividual, OWLObjectProperty>();
138
139 private OWLObjectProperty getNewRole4Nominal(OWLIndividual nominal) {
140 OWLObjectProperty property;
141 if ((property = role4nominal.get(nominal)) == null)
142 role4nominal.put(nominal, property = getNewRole(outputOntology, rlCounter++));
143 return property;
144 }
145
146 private boolean hasIllegalNominals(OWLClassExpression exp) {
147 for (OWLClassExpression conjunct: exp.asConjunctSet()) {
148 if (conjunct instanceof OWLObjectOneOf) return true;
149 if (conjunct instanceof OWLObjectAllValuesFrom) {
150 OWLObjectAllValuesFrom allValuesFrom = ((OWLObjectAllValuesFrom) conjunct);
151 if (allValuesFrom.getFiller() instanceof OWLObjectOneOf)
152 return true;
153 }
154 }
155 return false;
156 }
157
158 private void eliminateOWLThing() {
159 OWLClassExpression subExp;
160 boolean mark = false;
161 for (Clause clause: clauses) {
162 subExp = OWLHelper.getSimplifiedConjunction(factory, clause.getSubClasses());
163 if (subExp.equals(factory.getOWLThing())) {
164 mark = true;
165 }
166 }
167
168 if (mark) {
169 Utility.logDebug("Top appears in the left of an axiom.");
170
171 OWLSubClassOfAxiom subClassAxiom;
172 OWLClass TOP = factory.getOWLClass(IRI.create(ontologyIRI + "#TOP"));
173 for (OWLAxiom axiom: new HashSet<OWLAxiom>(outputOntology.getAxioms()))
174 if (axiom instanceof OWLSubClassOfAxiom && (subClassAxiom = (OWLSubClassOfAxiom) axiom).getSubClass().equals(factory.getOWLThing()))
175 replaceAxiom4output(axiom, factory.getOWLSubClassOfAxiom(TOP, subClassAxiom.getSuperClass()));
176
177 for (OWLClass c: outputOntology.getClassesInSignature(true)) {
178 if (!c.equals(factory.getOWLThing()))
179 addAxiom2output(factory.getOWLSubClassOfAxiom(c, TOP), null);
180 else
181 addAxiom2output(factory.getOWLSubClassOfAxiom(TOP, c), null);
182 }
183 for (OWLObjectProperty p: outputOntology.getObjectPropertiesInSignature(true)) {
184 addAxiom2output(factory.getOWLObjectPropertyDomainAxiom(p, TOP), null);
185 addAxiom2output(factory.getOWLObjectPropertyRangeAxiom(p, TOP), null);
186 }
187 }
188 }
189
190}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java b/src/main/java/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java
new file mode 100644
index 0000000..53a8a9e
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/approx/RLPlusOntology.java
@@ -0,0 +1,607 @@
1package uk.ac.ox.cs.pagoda.approx;
2
3import org.apache.commons.io.FilenameUtils;
4import org.semanticweb.HermiT.Configuration;
5import org.semanticweb.HermiT.model.DLClause;
6import org.semanticweb.HermiT.model.DLOntology;
7import org.semanticweb.HermiT.structural.OWLClausification;
8import org.semanticweb.owlapi.model.*;
9import org.semanticweb.owlapi.profiles.OWL2RLProfile;
10import org.semanticweb.owlapi.profiles.OWLProfileReport;
11import org.semanticweb.owlapi.profiles.OWLProfileViolation;
12import uk.ac.ox.cs.pagoda.constraints.NullaryBottom;
13import uk.ac.ox.cs.pagoda.constraints.UnaryBottom;
14import uk.ac.ox.cs.pagoda.owl.OWLHelper;
15import uk.ac.ox.cs.pagoda.util.Namespace;
16import uk.ac.ox.cs.pagoda.util.Utility;
17
18import java.io.*;
19import java.nio.file.Paths;
20import java.util.*;
21import java.util.regex.Matcher;
22import java.util.regex.Pattern;
23
24public class RLPlusOntology implements KnowledgeBase {
25
26 private static final String DEFAULT_ONTOLOGY_FILE_EXTENSION = "owl";
27 private static final Pattern ONTOLOGY_ID_REGEX = Pattern.compile("ontologyid\\((?<id>[a-z0-9\\-]+)\\)");
28 OWLOntologyManager manager;
29 OWLDataFactory factory;
30 String ontologyIRI;
31 String corrFileName = null;
32 String outputPath, aBoxPath;
33 OWLOntology inputOntology = null;
34 OWLOntology tBox = null;
35 OWLOntology aBox = null;
36 OWLOntology restOntology = null;
37 OWLOntology outputOntology = null; //RL ontology
38 DLOntology dlOntology = null;
39 int rlCounter = 0;
40 LinkedList<Clause> clauses;
41 Map<OWLAxiom, OWLAxiom> correspondence;
42 BottomStrategy botStrategy;
43 Random random = new Random(19900114);
44 private Map<OWLClassExpression, Integer> subCounter = null;
45 private Map<OWLClass, OWLClass> atomic2negation = new HashMap<OWLClass, OWLClass>();
46
47 // TODO don't know if it is correct
48 @Override
49 public void load(OWLOntology ontology, uk.ac.ox.cs.pagoda.constraints.BottomStrategy bottomStrategy) {
50 if(bottomStrategy instanceof UnaryBottom)
51 botStrategy = BottomStrategy.UNARY;
52 else if(bottomStrategy instanceof NullaryBottom)
53 botStrategy = BottomStrategy.NULLARY;
54 else
55 botStrategy = BottomStrategy.TOREMOVE;
56
57 if(corrFileName == null)
58 corrFileName = "rlplus.crr";
59 manager = ontology.getOWLOntologyManager();
60// manager = OWLManager.createOWLOntologyManager();
61 factory = manager.getOWLDataFactory();
62 inputOntology = ontology;
63
64 try {
65 IRI ontologyIri;
66 if(ontology.isAnonymous()) {
67 Matcher matcher = ONTOLOGY_ID_REGEX.matcher(ontology.getOntologyID().toString().toLowerCase());
68 if(!matcher.matches()) throw new Error("Anonymous ontology without internal id");
69 ontologyIri =
70 IRI.create("http://www.example.org/", matcher.group("id") + "." + DEFAULT_ONTOLOGY_FILE_EXTENSION);
71 }
72 else
73 ontologyIri = inputOntology.getOntologyID().getOntologyIRI().get();
74
75 String ontologyIriPrefix = ontologyIri.getNamespace();
76 ontologyIRI = ontologyIri.toString();
77 String ontologyIriFragment = ontologyIri.getFragment();
78 String originalFileName = FilenameUtils.removeExtension(ontologyIriFragment);
79 String originalExtension = FilenameUtils.getExtension(ontologyIriFragment);
80 if(originalExtension.isEmpty()) originalExtension = DEFAULT_ONTOLOGY_FILE_EXTENSION;
81
82
83 IRI rlOntologyIRI = IRI.create(ontologyIriPrefix, originalFileName + "-RL." + originalExtension);
84 outputPath = Paths.get(Utility.getGlobalTempDirAbsolutePath(),
85 originalFileName + "-RL." + originalExtension).toString();
86 IRI rlDocumentIRI = IRI.create("file://" + outputPath);
87 outputOntology = manager.createOntology(rlOntologyIRI);
88 manager.setOntologyDocumentIRI(outputOntology, rlDocumentIRI);
89
90 String tBoxOntologyFragment = originalFileName + "-TBox." + originalExtension;
91 IRI tBoxOntologyIRI = IRI.create(ontologyIriPrefix, tBoxOntologyFragment);
92 IRI tBoxDocumentIRI =
93 IRI.create("file://" + Paths.get(Utility.getGlobalTempDirAbsolutePath(), tBoxOntologyFragment));
94
95 String aBoxOntologyFragment = originalFileName + "-ABox." + originalExtension;
96 IRI aBoxOntologyIRI = IRI.create(ontologyIriPrefix, aBoxOntologyFragment);
97 aBoxPath = Paths.get(Utility.getGlobalTempDirAbsolutePath(), aBoxOntologyFragment).toString();
98 IRI aBoxDocumentIRI =
99 IRI.create("file://" + Paths.get(Utility.getGlobalTempDirAbsolutePath(), aBoxOntologyFragment));
100
101 tBox = manager.createOntology(tBoxOntologyIRI);
102 aBox = manager.createOntology(aBoxOntologyIRI);
103 manager.setOntologyDocumentIRI(tBox, tBoxDocumentIRI);
104 manager.setOntologyDocumentIRI(aBox, aBoxDocumentIRI);
105
106 FileOutputStream aBoxOut = new FileOutputStream(aBoxPath);
107 manager.saveOntology(aBox, aBoxOut);
108 aBoxOut.close();
109
110 restOntology = manager.createOntology();
111 } catch(OWLOntologyCreationException | OWLOntologyStorageException | IOException e) {
112 e.printStackTrace();
113 System.exit(1);
114 }
115 }
116
117 public OWLOntology getTBox() {
118 return tBox;
119 }
120
121 public String getABoxPath() {
122 return aBoxPath;
123 }
124
125 public void simplify() {
126 if(simplifyABox()) {
127 save(aBox);
128// save(tBox);
129 }
130 else
131 tBox = inputOntology;
132 }
133
134 @Override
135 public void transform() {
136 simplify();
137 filter();
138 clausify();
139
140 subCounter = new HashMap<OWLClassExpression, Integer>();
141 clauses = new LinkedList<Clause>();
142 Clausifier clausifier = Clausifier.getInstance(restOntology);
143
144 for(DLClause c : dlOntology.getDLClauses()) {
145 Clause clause = new Clause(clausifier, c);
146 clauses.add(clause);
147
148 /*
149 * count the expressions in the left
150 */
151 for(OWLClassExpression exp : clause.getSubClasses()) {
152 if(exp instanceof OWLClass)
153 add2SubCounter(exp);
154 else if(exp instanceof OWLObjectSomeValuesFrom) {
155 OWLObjectSomeValuesFrom someValue = (OWLObjectSomeValuesFrom) exp;
156 add2SubCounter(factory.getOWLObjectSomeValuesFrom(someValue.getProperty(), factory.getOWLThing()));
157 add2SubCounter(someValue.getFiller());
158 }
159 else if(exp instanceof OWLObjectMinCardinality) {
160 OWLObjectMinCardinality minCard = (OWLObjectMinCardinality) exp;
161 add2SubCounter(factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing()));
162 add2SubCounter(minCard.getFiller());
163 }
164 else
165 Utility.logError("strange class expression: " + exp);
166
167 }
168 }
169
170 correspondence = new HashMap<OWLAxiom, OWLAxiom>();
171 Set<OWLAxiom> addedAxioms = new HashSet<OWLAxiom>();
172 OWLClassExpression subExp;
173 for(Clause clause : clauses) {
174 subExp = uk.ac.ox.cs.pagoda.owl.OWLHelper.getSimplifiedConjunction(factory, clause.getSubClasses());
175 addedAxioms.clear();
176 for(OWLClassExpression exp : getDisjunctionApprox0(clause.getSuperClasses())) {
177 addedAxioms.add(factory.getOWLSubClassOfAxiom(subExp, transform(exp, addedAxioms)));
178 for(OWLAxiom a : addedAxioms)
179 addAxiom2output(a, factory.getOWLSubClassOfAxiom(subExp,
180 OWLHelper.getSimplifiedDisjunction(factory, clause.getSuperClasses())));
181 }
182 }
183
184 subCounter.clear();
185 }
186
187 @Override
188 public void save() {
189 if(corrFileName != null)
190 save(correspondence, corrFileName);
191 save(outputOntology);
192 }
193
194 public OWLOntologyManager getOWLOntologyManager() {
195 return inputOntology.getOWLOntologyManager();
196 }
197
198 public String getOntologyIRI() {
199 return ontologyIRI;
200 }
201
202 public OWLOntology getOutputOntology() {
203 return outputOntology;
204 }
205
206 @Override
207 public String getOutputPath() {
208 return outputPath;
209 }
210
211 @Override
212 public String getDirectory() {
213 return outputPath.substring(0, outputPath.lastIndexOf(Utility.FILE_SEPARATOR));
214 }
215
216 public void setCorrespondenceFileLoc(String path) {
217 corrFileName = path;
218 }
219
220 private void add2SubCounter(OWLClassExpression exp) {
221 Integer count = subCounter.get(exp);
222 if(count == null) count = 0;
223 ++count;
224 subCounter.put(exp, count);
225 }
226
227 private void save(Map<OWLAxiom, OWLAxiom> map, String corrFileName) {
228 if(corrFileName == null) return;
229 ObjectOutput output;
230 try {
231 output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(corrFileName)));
232 output.writeObject(map);
233 output.close();
234 } catch(IOException e) {
235 e.printStackTrace();
236 }
237 }
238
239 protected void save(OWLOntology onto) {
240 try {
241 onto.getOWLOntologyManager().saveOntology(onto);
242 } catch(OWLOntologyStorageException e) {
243 e.printStackTrace();
244 }
245 }
246
247 /*
248 * treat disjunction as conjunction
249 */
250 private Set<OWLClassExpression> getDisjunctionApprox0(Set<OWLClassExpression> superClasses) {
251 return superClasses;
252 }
253
254 /*
255 * choose one simple class disjunct
256 */
257 @SuppressWarnings("unused")
258 private Set<OWLClassExpression> getDisjunctionApprox1(Set<OWLClassExpression> superClasses) {
259 if(superClasses.isEmpty() || superClasses.size() == 1)
260 return superClasses;
261
262 OWLClassExpression rep = null;
263 int min = Integer.MAX_VALUE, o;
264 for(OWLClassExpression exp : superClasses)
265 if(exp instanceof OWLClass && (o = getOccurrence(exp)) < min) {
266 min = o;
267 rep = exp;
268 }
269
270 if(rep == null) rep = superClasses.iterator().next();
271
272 return Collections.singleton(rep);
273 }
274
275 /*
276 * randomly choose a class expression to represent this disjunction
277 */
278 @SuppressWarnings("unused")
279 private Set<OWLClassExpression> getDisjunctionApprox2(Set<OWLClassExpression> superClasses) {
280 if(superClasses.isEmpty() || superClasses.size() == 1)
281 return superClasses;
282
283 int index = random.nextInt() % superClasses.size();
284 if(index < 0) index += superClasses.size();
285
286 int i = 0;
287 for(OWLClassExpression exp : superClasses)
288 if(i++ == index)
289 return Collections.singleton(exp);
290 return null;
291 }
292
293 /*
294 * choose the one that appears least in the l.h.s.
295 */
296 @SuppressWarnings("unused")
297 private Set<OWLClassExpression> getDisjunctionApprox3(Set<OWLClassExpression> superClasses) {
298 if(superClasses.isEmpty() || superClasses.size() == 1)
299 return superClasses;
300
301 OWLClassExpression rep = null, exp1;
302 int occurrence = Integer.MAX_VALUE, o;
303 for(OWLClassExpression exp : superClasses) {
304 o = 0;
305 exp1 = exp;
306 if(exp instanceof OWLObjectMinCardinality) {
307 OWLObjectMinCardinality minCard = (OWLObjectMinCardinality) exp;
308 if(minCard.getCardinality() == 1)
309 exp1 = factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), minCard.getFiller());
310 }
311
312 if(!subCounter.containsKey(exp1) || (o = subCounter.get(exp1)) < occurrence) {
313 rep = exp;
314 occurrence = o;
315 }
316 }
317
318 return Collections.singleton(rep);
319 }
320
321 private int getOccurrence(OWLClassExpression exp) {
322 if(!subCounter.containsKey(exp))
323 return 0;
324 return subCounter.get(exp);
325 }
326
327 @SuppressWarnings("unused")
328 private Set<OWLClassExpression> getDisjunctionApprox4(Set<OWLClassExpression> superClasses) {
329 if(superClasses.isEmpty() || superClasses.size() == 1)
330 return superClasses;
331
332 OWLClassExpression rep = null;
333 int occurrence = Integer.MAX_VALUE, o;
334 for(OWLClassExpression exp : superClasses) {
335 o = 0;
336 if(exp instanceof OWLObjectMinCardinality) {
337 OWLObjectMinCardinality minCard = (OWLObjectMinCardinality) exp;
338 if(minCard.getCardinality() == 1) {
339 o =
340 getOccurrence((factory.getOWLObjectSomeValuesFrom(minCard.getProperty(), factory.getOWLThing())));
341 o += getOccurrence(minCard.getFiller());
342// if (o < o1) o = o1;
343 }
344 }
345 else
346 o = getOccurrence(exp);
347
348 if(o < occurrence || o == occurrence && !(rep instanceof OWLClass)) {
349 rep = exp;
350 occurrence = o;
351 }
352 }
353
354 return Collections.singleton(rep);
355 }
356
357 private boolean simplifyABox() {
358 boolean flag = false;
359 Map<OWLClassExpression, OWLClass> complex2atomic = new HashMap<OWLClassExpression, OWLClass>();
360
361 OWLDatatype anyURI = factory.getOWLDatatype(IRI.create(Namespace.XSD_NS + "anyURI"));
362 OWLObjectProperty sameAs = factory.getOWLObjectProperty(IRI.create(Namespace.EQUALITY));
363 OWLObjectProperty differentFrom = factory.getOWLObjectProperty(IRI.create(Namespace.INEQUALITY));
364
365 for(OWLOntology imported : inputOntology.getImportsClosure())
366 for(OWLAxiom axiom : imported.getAxioms()) {
367 if(axiom instanceof OWLClassAssertionAxiom) {
368 flag = true;
369 OWLClassAssertionAxiom assertion = (OWLClassAssertionAxiom) axiom;
370 OWLClassExpression clsExp = assertion.getClassExpression();
371 OWLClass cls;
372 if(clsExp instanceof OWLClass) {
373 if(((OWLClass) clsExp).toStringID().startsWith("owl:"))
374 manager.addAxiom(tBox, axiom);
375 else manager.addAxiom(aBox, axiom);
376 }
377 else {
378 if((cls = complex2atomic.get(clsExp)) == null) {
379 complex2atomic.put(clsExp, cls = getNewConcept(tBox, rlCounter++));
380 manager.addAxiom(tBox, factory.getOWLSubClassOfAxiom(cls, clsExp));
381 }
382 manager.addAxiom(aBox, factory.getOWLClassAssertionAxiom(cls, assertion.getIndividual()));
383 }
384 }
385 else if(axiom instanceof OWLObjectPropertyAssertionAxiom || axiom instanceof OWLDataPropertyAssertionAxiom || axiom instanceof OWLAnnotationAssertionAxiom) {
386 if(axiom.getDataPropertiesInSignature().contains(anyURI)) continue;
387 flag = true;
388 manager.addAxiom(aBox, axiom);
389 }
390 else if(axiom instanceof OWLSameIndividualAxiom) {
391 OWLIndividual firstIndividual = null, previousIndividual = null, lastIndividual = null;
392 for(OWLIndividual next : ((OWLSameIndividualAxiom) axiom).getIndividuals()) {
393 if(firstIndividual == null) firstIndividual = previousIndividual = next;
394 else
395 manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(sameAs, previousIndividual, next));
396 previousIndividual = lastIndividual = next;
397 }
398 manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(sameAs, lastIndividual, firstIndividual));
399 }
400 else if(axiom instanceof OWLDifferentIndividualsAxiom) {
401 int index1 = 0, index2;
402 for(OWLIndividual individual1 : ((OWLDifferentIndividualsAxiom) axiom).getIndividuals()) {
403 ++index1;
404 index2 = 0;
405 for(OWLIndividual individual2 : ((OWLDifferentIndividualsAxiom) axiom).getIndividuals()) {
406 if(index2++ < index1) {
407 manager.addAxiom(aBox, factory.getOWLObjectPropertyAssertionAxiom(differentFrom, individual1, individual2));
408 }
409 else break;
410 }
411 }
412 }
413 else
414 manager.addAxiom(tBox, axiom);
415 }
416
417 return flag;
418 }
419
420 private void filter() {
421 OWL2RLProfile profile = new OWL2RLProfile();
422 OWLProfileReport report = profile.checkOntology(tBox);
423 Set<OWLAxiom> rlAxioms = tBox.getAxioms();
424 OWLAxiom axiom;
425
426 for(OWLProfileViolation violation : report.getViolations()) {
427 manager.addAxiom(restOntology, axiom = violation.getAxiom());
428 rlAxioms.remove(axiom);
429 }
430
431 for(Iterator<OWLAxiom> iter = rlAxioms.iterator(); iter.hasNext(); )
432 addAxiom2output(iter.next(), null);
433 }
434
435 private void clausify() {
436 Configuration conf = new Configuration();
437 OWLClausification clausifier = new OWLClausification(conf);
438 dlOntology = (DLOntology) clausifier.preprocessAndClausify(restOntology, null)[1];
439 clausifier = null;
440 }
441
442 protected void addAxiom2output(OWLAxiom axiom, OWLAxiom correspondingAxiom) {
443 manager.addAxiom(outputOntology, axiom);
444 if(correspondingAxiom != null)
445 correspondence.put(axiom, correspondingAxiom);
446 }
447
448 private OWLClassExpression transform(OWLClassExpression exp, Set<OWLAxiom> addedAxioms) {
449 if(exp instanceof OWLClass)
450 return exp;
451
452 if(exp instanceof OWLObjectHasValue)
453 return exp;
454
455 if(exp instanceof OWLObjectSomeValuesFrom) {
456 OWLObjectSomeValuesFrom someValueExp = (OWLObjectSomeValuesFrom) exp;
457
458 OWLClassExpression tExp = someValueExp.getFiller();
459 if(tExp.equals(factory.getOWLThing()))
460 exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty());
461 else
462 exp = factory.getOWLObjectMinCardinality(1, someValueExp.getProperty(), someValueExp.getFiller());
463 }
464
465 if(exp instanceof OWLObjectMinCardinality) {
466 OWLObjectMinCardinality minExp = (OWLObjectMinCardinality) exp;
467 OWLObjectPropertyExpression r;
468
469 if(minExp.getFiller().equals(factory.getOWLThing())) {
470 r = minExp.getProperty();
471 }
472 //TODO to be restored ...
473 //else if ((r = exists2role.get(someValueExp)) == null) {
474 // deal with r' \subseteq r & range(r') \subseteq C
475 else {
476 r = getNewRole(outputOntology, rlCounter);
477 addedAxioms.add(factory.getOWLSubObjectPropertyOfAxiom(r, minExp.getProperty()));
478 OWLClassExpression tExp = minExp.getFiller();
479 if(!(tExp instanceof OWLObjectComplementOf)) {
480 if(tExp.equals(factory.getOWLThing())) ;
481 else
482 addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, tExp));
483 }
484 else if(botStrategy != BottomStrategy.TOREMOVE) {
485 OWLClass cls = (OWLClass) tExp.getComplementNNF();
486 OWLClass neg;
487 if((neg = atomic2negation.get(cls)) == null) {
488 neg = getNewConcept(outputOntology, rlCounter);
489 addedAxioms.add(factory.getOWLDisjointClassesAxiom(neg, cls));
490 atomic2negation.put(cls, neg);
491 }
492 addedAxioms.add(factory.getOWLObjectPropertyRangeAxiom(r, neg));
493 }
494// exists2role.put(someValueExp, (OWLObjectProperty) r);
495 }
496
497 // deal with r'(x,c)
498 Set<OWLClassExpression> ret = new HashSet<OWLClassExpression>();
499 int num = minExp.getCardinality();
500
501 Set<OWLNamedIndividual> cs = new HashSet<OWLNamedIndividual>();
502 OWLNamedIndividual c;
503 for(int i = 0; i < num; ++i) {
504 c = getNewIndividual(outputOntology, rlCounter++);
505 ret.add(factory.getOWLObjectHasValue(r, c));
506 cs.add(c);
507 }
508
509 if(botStrategy != BottomStrategy.TOREMOVE && cs.size() > 1) {
510 addedAxioms.add(factory.getOWLDifferentIndividualsAxiom(cs));
511 }
512
513 return OWLHelper.getSimplifiedConjunction(factory, ret);
514 }
515
516 if(exp instanceof OWLObjectMaxCardinality) {
517 OWLObjectMaxCardinality maxExp = (OWLObjectMaxCardinality) exp;
518 OWLClassExpression tExp = maxExp.getFiller();
519 int card = maxExp.getCardinality() >= 1 ? 1 : 0;
520 if(!(tExp instanceof OWLObjectComplementOf))
521 return factory.getOWLObjectMaxCardinality(card, maxExp.getProperty(), tExp);
522 else {
523 Utility.logDebug("oh, to be tested ... ");
524 OWLClassExpression tExp1 =
525 factory.getOWLObjectAllValuesFrom(maxExp.getProperty(), tExp.getComplementNNF());
526 if(card == 0)
527 return tExp1;
528 else {
529 OWLClassExpression tExp2 = factory.getOWLObjectMaxCardinality(1, maxExp.getProperty());
530 return factory.getOWLObjectIntersectionOf(tExp1, tExp2);
531 }
532 }
533 }
534
535 if(exp instanceof OWLObjectAllValuesFrom)
536 return exp;
537
538 if(exp instanceof OWLObjectOneOf)
539 if(((OWLObjectOneOf) exp).getIndividuals().size() == 1)
540 return exp;
541 else
542 return null;
543
544 if(exp instanceof OWLDataHasValue)
545 return exp;
546
547 //TODO overapproximation - dealing with OWLDataMinCardinality
548
549 if(exp instanceof OWLDataSomeValuesFrom) {
550 return exp;
551 }
552
553 if(exp instanceof OWLDataMinCardinality) {
554 return exp;
555 }
556
557 if(exp instanceof OWLDataMaxCardinality) {
558 return exp;
559 }
560
561
562 Set<OWLClassExpression> exps = exp.asConjunctSet();
563 if(exps.size() == 1 && exps.iterator().next() == exp) {
564 Utility.logError(exp, "error in transform of Ontology~~~~");
565 }
566 Set<OWLClassExpression> nexps = new HashSet<OWLClassExpression>();
567 OWLClassExpression ne;
568 boolean changes = false;
569 for(OWLClassExpression e : exps) {
570 ne = transform(e, addedAxioms);
571 if(ne != e) changes = true;
572 nexps.add(ne);
573 }
574 if(changes)
575 return OWLHelper.getSimplifiedConjunction(factory, nexps);
576 else
577 return exp;
578 }
579
580 protected OWLNamedIndividual getNewIndividual(OWLOntology onto, int number) {
581 OWLOntologyManager manager = onto.getOWLOntologyManager();
582 OWLDataFactory factory = manager.getOWLDataFactory();
583 OWLNamedIndividual newIndividual =
584 factory.getOWLNamedIndividual(IRI.create(Namespace.PAGODA_ANONY + "NI" + number));
585 manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newIndividual));
586 return newIndividual;
587 }
588
589 protected OWLObjectProperty getNewRole(OWLOntology onto, int number) {
590 OWLOntologyManager manager = onto.getOWLOntologyManager();
591 OWLDataFactory factory = manager.getOWLDataFactory();
592 OWLObjectProperty newProperty = factory.getOWLObjectProperty(IRI.create(Namespace.PAGODA_AUX + "NR" + number));
593 manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newProperty));
594 return newProperty;
595 }
596
597 private OWLClass getNewConcept(OWLOntology onto, int number) {
598 OWLOntologyManager manager = onto.getOWLOntologyManager();
599 OWLDataFactory factory = manager.getOWLDataFactory();
600 OWLClass newClass = factory.getOWLClass(IRI.create(Namespace.PAGODA_AUX + "NC" + number));
601 manager.addAxiom(onto, factory.getOWLDeclarationAxiom(newClass));
602 return newClass;
603 }
604
605 private enum BottomStrategy {TOREMOVE, NULLARY, UNARY}
606}
607