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