aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/uk/ac/ox/cs/pagoda/hermit
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/hermit
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/hermit')
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/hermit/DLClauseHelper.java480
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java173
-rw-r--r--src/main/java/uk/ac/ox/cs/pagoda/hermit/TermGraph.java258
3 files changed, 911 insertions, 0 deletions
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/hermit/DLClauseHelper.java b/src/main/java/uk/ac/ox/cs/pagoda/hermit/DLClauseHelper.java
new file mode 100644
index 0000000..c3f7a2a
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/hermit/DLClauseHelper.java
@@ -0,0 +1,480 @@
1package uk.ac.ox.cs.pagoda.hermit;
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.HermiT.Prefixes;
11import org.semanticweb.HermiT.model.AnnotatedEquality;
12import org.semanticweb.HermiT.model.AtLeastDataRange;
13import org.semanticweb.HermiT.model.Atom;
14import org.semanticweb.HermiT.model.AtomicConcept;
15import org.semanticweb.HermiT.model.AtomicDataRange;
16import org.semanticweb.HermiT.model.AtomicNegationDataRange;
17import org.semanticweb.HermiT.model.AtomicRole;
18import org.semanticweb.HermiT.model.Constant;
19import org.semanticweb.HermiT.model.ConstantEnumeration;
20import org.semanticweb.HermiT.model.DLClause;
21import org.semanticweb.HermiT.model.DLPredicate;
22import org.semanticweb.HermiT.model.Equality;
23import org.semanticweb.HermiT.model.Individual;
24import org.semanticweb.HermiT.model.Inequality;
25import org.semanticweb.HermiT.model.Term;
26import org.semanticweb.HermiT.model.Variable;
27
28import uk.ac.ox.cs.pagoda.owl.OWLHelper;
29import uk.ac.ox.cs.pagoda.util.Namespace;
30import uk.ac.ox.cs.pagoda.util.SparqlHelper;
31import uk.ac.ox.cs.pagoda.util.Utility;
32
33public class DLClauseHelper {
34
35 public static String getIRI4Nominal(DLPredicate predicate) {
36 return ((AtomicConcept) predicate).getIRI().replace("internal:nom#", "");
37 }
38
39 public static DLClause removeNominalConcept(DLClause clause) {
40 boolean hasNominals = false;
41 Map<Variable, String> nom2iri = new HashMap<Variable, String>();
42 DLPredicate predicate;
43 Collection<Atom> remainingBodyAtoms = new LinkedList<Atom>();
44 for (Atom atom: clause.getBodyAtoms()) {
45 predicate = atom.getDLPredicate();
46 if (predicate instanceof AtomicConcept && predicate.toString().startsWith("<internal:nom#")) {
47 nom2iri.put(atom.getArgumentVariable(0), getIRI4Nominal(predicate));
48 hasNominals = true;
49 }
50 else remainingBodyAtoms.add(atom);
51 }
52
53 if (!hasNominals) return clause;
54
55 Atom[] newHeadAtoms = new Atom[clause.getHeadLength()];
56 int i = 0;
57 for (Atom atom: clause.getHeadAtoms()) {
58 newHeadAtoms[i++] = getNewAtom(atom, nom2iri);
59 }
60
61 Atom[] newBodyAtoms = new Atom[remainingBodyAtoms.size()];
62 i = 0;
63 for (Atom atom: remainingBodyAtoms) {
64 newBodyAtoms[i++] = getNewAtom(atom, nom2iri);
65 }
66
67 return DLClause.create(newHeadAtoms, newBodyAtoms);
68 }
69
70 public static Atom getNewAtom(Atom atom, Map<Variable, String> nom2iri) {
71 String iri;
72 DLPredicate predicate = atom.getDLPredicate();
73 if (predicate instanceof AtomicRole) {
74 boolean updated = false;
75 Term newArg0 = atom.getArgument(0), newArg1 = atom.getArgument(1);
76 if (newArg0 instanceof Variable && ((iri = nom2iri.get((Variable) newArg0)) != null)) {
77 newArg0 = Individual.create(iri);
78 updated = true;
79 }
80 if (newArg1 instanceof Variable && ((iri = nom2iri.get((Variable) newArg1)) != null)) {
81 newArg1 = Individual.create(iri);
82 updated = true;
83 }
84 if (updated) {
85 return Atom.create(atom.getDLPredicate(), newArg0, newArg1);
86 }
87 }
88 else if (predicate instanceof Equality || predicate instanceof AnnotatedEquality) {
89// System.out.println("To be removed ... \n" + atom);
90 Term two[] = new Term[] { atom.getArgument(0), atom.getArgument(1) };
91 Term t;
92 for (int i = 0; i < 2; ++i) {
93 t = atom.getArgument(i);
94 if (t != null && t instanceof Variable && (iri = nom2iri.get((Variable) t)) != null) {
95 two[i] = Individual.create(iri);
96 }
97 }
98 return Atom.create(Equality.INSTANCE, two);
99 }
100
101 return atom;
102 }
103
104 /**
105 * This is a preprocess for StatOil:
106 *
107 * if (AtomicNegationDataRange o (ConstantEnumerate (value))) (Z)
108 * appears the head, then replace all Z in the clause by value.
109 *
110 *
111 * @param clause
112 */
113 public static DLClause replaceWithDataValue(DLClause clause) {
114 Map<Variable, Constant> var2dataValue = new HashMap<Variable, Constant>();
115
116 boolean update = false;
117 LinkedList<Atom> newHeadAtoms = new LinkedList<Atom>();
118 for (Atom cAtom: clause.getHeadAtoms()) {
119 DLPredicate dlPredicate = cAtom.getDLPredicate();
120 if (dlPredicate instanceof AtomicNegationDataRange) {
121 AtomicDataRange atomicDataRange = ((AtomicNegationDataRange) dlPredicate).getNegatedDataRange();
122 if (atomicDataRange instanceof ConstantEnumeration) {
123 ConstantEnumeration enumeration = (ConstantEnumeration) atomicDataRange;
124 if (enumeration.getNumberOfConstants() == 1) {
125 Constant constant = enumeration.getConstant(0);
126 //TODO replace unsupported datatypes
127// if (constant.getDatatypeURI().endsWith("boolean"))
128// constant = Constant.create(constant.getLexicalForm(), constant.getDatatypeURI().replace("boolean", "string"));
129 var2dataValue.put(cAtom.getArgumentVariable(0), constant);
130 }
131 }
132 }
133 else if (dlPredicate instanceof ConstantEnumeration) {
134 ConstantEnumeration enu = (ConstantEnumeration) dlPredicate;
135 for (int i = 0; i < enu.getNumberOfConstants(); ++i)
136 newHeadAtoms.add(Atom.create(Equality.INSTANCE, cAtom.getArgument(0), enu.getConstant(i)));
137 update = true;
138 }
139 else if (dlPredicate instanceof AtLeastDataRange && ((AtLeastDataRange) dlPredicate).getToDataRange() instanceof ConstantEnumeration) {
140 AtLeastDataRange atLeast = (AtLeastDataRange) dlPredicate;
141 ConstantEnumeration enu = (ConstantEnumeration) atLeast.getToDataRange();
142 for (int i = 0; i < enu.getNumberOfConstants(); ++i)
143 newHeadAtoms.add(Atom.create((AtomicRole) atLeast.getOnRole(), cAtom.getArgument(0), enu.getConstant(i)));
144 update = true;
145 }
146 else
147 newHeadAtoms.add(cAtom);
148 }
149
150 if (var2dataValue.isEmpty()) return update ? DLClause.create(newHeadAtoms.toArray(new Atom[0]), clause.getBodyAtoms()) : clause;
151
152 Atom[] newBodyAtoms = new Atom[clause.getBodyLength()];
153 Term[] newArgs;
154 int index = 0;
155 boolean atomUpdated;
156 for (Atom bodyAtom: clause.getBodyAtoms()) {
157 newBodyAtoms[index] = bodyAtom;
158 atomUpdated = false;
159 newArgs = new Term[bodyAtom.getArity()];
160 for (int i = 0; i < newArgs.length; ++i) {
161 newArgs[i] = bodyAtom.getArgument(i);
162 if (newArgs[i] instanceof Variable && var2dataValue.containsKey(newArgs[i])) {
163 newArgs[i] = var2dataValue.get(newArgs[i]);
164 atomUpdated = true;
165 }
166 }
167 if (atomUpdated)
168 newBodyAtoms[index] = Atom.create(bodyAtom.getDLPredicate(), newArgs);
169 ++index;
170 }
171
172 return DLClause.create(newHeadAtoms.toArray(new Atom[0]), newBodyAtoms);
173 }
174
175 public static DLClause simplified(DLClause clause) {
176 TermGraph termGraph = new TermGraph(clause);
177 return termGraph.simplify();
178 }
179
180 public static DLClause contructor_differentFrom(Individual u, Individual v) {
181 Atom equalityAtom = Atom.create(AtomicRole.create(Namespace.EQUALITY), u, v);
182 return DLClause.create(new Atom[0], new Atom[] {equalityAtom});
183 }
184
185 public static String toString(Collection<DLClause> clauses) {
186 StringBuilder buf = new StringBuilder();
187 for (DLClause cls: clauses) {
188 buf.append(RuleHelper.getText(cls));
189 buf.append(Utility.LINE_SEPARATOR);
190 }
191 return buf.toString();
192 }
193
194 public static DLClause getInstance(DLClause queryClause, Map<Variable, Term> assignment) {
195 Atom[] newBodyAtoms = new Atom[queryClause.getBodyLength()];
196 int index = 0;
197 for (Atom atom: queryClause.getBodyAtoms()) {
198 newBodyAtoms[index++] = getInstance(atom, assignment);
199 }
200 return DLClause.create(queryClause.getHeadAtoms(), newBodyAtoms);
201 }
202
203 public static Atom getInstance(Atom atom, Map<Variable, Term> assignment) {
204 Term[] args = getArguments(atom);
205 for (int i = 0; i < args.length; ++i)
206 args[i] = getInstance(args[i], assignment);
207 return Atom.create(atom.getDLPredicate(), args);
208 }
209
210 private static Term getInstance(Term t, Map<Variable, Term> assignment) {
211 if (t instanceof Variable && assignment.containsKey((Variable) t))
212 return assignment.get(t);
213 return t;
214 }
215
216 public static Term[] getArguments(Atom atom) {
217 int len = atom.getArity();
218 if (len >= 2) len = 2;
219 Term[] args = new Term[len];
220 for (int i = 0; i < len; ++i)
221 args[i] = atom.getArgument(i);
222 return args;
223 }
224
225 public static DLClause getQuery(String queryText, Collection<String> answerVariables) {
226 Collection<Atom> bodyAtoms = new LinkedList<Atom>();
227 SparqlHelper.parse(queryText.replace("_:", "?"), answerVariables, bodyAtoms);
228 return DLClause.create(new Atom[0], bodyAtoms.toArray(new Atom[0]));
229 }
230
231 public static DLClause getQuery_old(String queryText, Collection<String> answerVariables) {
232 String key, value;
233 Prefixes prefixes = new Prefixes();
234 if (answerVariables != null)
235 answerVariables.clear();
236 String[] temp;
237 Term subject, object;
238 LinkedList<Atom> bodyAtoms = new LinkedList<Atom>();
239
240 for (String line: queryText.split("\n")) {
241 line = line.trim();
242 if (line.startsWith("PREFIX")) {
243 key = line.substring(7, line.indexOf(':') + 1);
244 value = line.substring(line.indexOf('<') + 1, line.length() - 1);
245 prefixes.declarePrefix(key, value);
246 }
247 else if (line.startsWith("SELECT")) {
248 if (answerVariables == null)
249 continue;
250 temp = line.split(" ");
251 for (int i = 1; i < temp.length; ++i)
252 answerVariables.add(temp[i].substring(1));
253 }
254 else if (line.startsWith("WHERE"))
255 ;
256 else if (line.startsWith("}"))
257 ;
258 else {
259 temp = line.split(" ");
260 subject = getTerm(getAbsoluteIRI(temp[0], prefixes));
261 temp[1] = getAbsoluteIRI(temp[1], prefixes);
262 temp[2] = getAbsoluteIRI(temp[2], prefixes);
263 if (temp[1].equals(Namespace.RDF_TYPE)) {
264 temp[2] = getAbsoluteIRI(temp[2], prefixes);
265 bodyAtoms.add(Atom.create(AtomicConcept.create(temp[2]), subject));
266 } else {
267 object = getTerm(temp[2]);
268 Term[] args = {subject, object};
269 bodyAtoms.add(Atom.create(AtomicRole.create(temp[1]), args));
270 }
271 }
272 }
273
274 return DLClause.create(new Atom[0], bodyAtoms.toArray(new Atom[0]));
275 }
276
277 private static String getAbsoluteIRI(String iri, Prefixes prefixes) {
278 if (prefixes.canBeExpanded(iri))
279 return prefixes.expandAbbreviatedIRI(iri);
280 if (iri.startsWith("<"))
281 return OWLHelper.removeAngles(iri);
282 return iri;
283 }
284
285 private static Term getTerm(String iri) {
286 if (iri.startsWith("?"))
287 return Variable.create(iri.substring(1));
288 else if (iri.contains("http"))
289 return Individual.create(iri);
290 else
291 return getConstant(iri);
292 }
293
294 private static Constant getConstant(String iri) {
295 String lexicalForm, datatypeIRI;
296 int index = iri.indexOf("^^");
297 if (index == -1) {
298 lexicalForm = iri;
299 int atPos = iri.indexOf("@");
300 datatypeIRI = atPos == -1 ? Namespace.XSD_STRING : Namespace.RDF_PLAIN_LITERAL;
301 }
302 else {
303 if (iri.charAt(index + 2) == '<')
304 datatypeIRI = iri.substring(index + 3, iri.length() - 1);
305 else
306 datatypeIRI = iri.substring(index + 2);
307 lexicalForm = iri.substring(1, index - 1);
308 }
309 return Constant.create(lexicalForm, datatypeIRI);
310 }
311
312 public static boolean isFunctionalDataPropertyAxioms(DLClause dlClause) {
313 if (dlClause.getBodyLength()==2 && dlClause.getHeadLength()==1) {
314 DLPredicate atomicRole=dlClause.getBodyAtom(0).getDLPredicate();
315 if (atomicRole instanceof AtomicRole) {
316 if (dlClause.getBodyAtom(1).getDLPredicate().equals(atomicRole) &&
317 (dlClause.getHeadAtom(0).getDLPredicate() instanceof Equality ||
318 dlClause.getHeadAtom(0).getDLPredicate() instanceof AnnotatedEquality)) {
319 Variable x=dlClause.getBodyAtom(0).getArgumentVariable(0);
320 if (x!=null && x.equals(dlClause.getBodyAtom(1).getArgument(0))) {
321 Variable y1=dlClause.getBodyAtom(0).getArgumentVariable(1);
322 Variable y2=dlClause.getBodyAtom(1).getArgumentVariable(1);
323 Variable headY1=dlClause.getHeadAtom(0).getArgumentVariable(0);
324 Variable headY2=dlClause.getHeadAtom(0).getArgumentVariable(1);
325 if (y1!=null && y2!=null && !y1.equals(y2) && headY1!=null && headY2!=null && ((y1.equals(headY1) && y2.equals(headY2)) || (y1.equals(headY2) && y2.equals(headY1))))
326 return true;
327 }
328 }
329 }
330 }
331 return false;
332 }
333
334 /**
335 *
336 * @param dlClause
337 * @return 000 -> 111 R \circ S \sqsubseteq T if R, S, T is inverse. -1 if it is not a role composition axiom.
338 */
339 public static int isRoleCompositionAxioms(DLClause dlClause) {
340 if (dlClause.getBodyLength()==2 && dlClause.getHeadLength()==1) {
341 Atom body1 = dlClause.getBodyAtom(0), body2 = dlClause.getBodyAtom(1);
342 Atom head = dlClause.getHeadAtom(0);
343 if (!(head.getDLPredicate() instanceof AtomicRole)) return -1;
344 if (!(body1.getDLPredicate() instanceof AtomicRole)) return -1;
345 if (!(body2.getDLPredicate() instanceof AtomicRole)) return -1;
346 if (!(head.getArgument(0) instanceof Variable)) return -1;
347 if (!(head.getArgument(1) instanceof Variable)) return -1;
348 if (!(body1.getArgument(0) instanceof Variable)) return -1;
349 if (!(body1.getArgument(1) instanceof Variable)) return -1;
350 if (!(body2.getArgument(0) instanceof Variable)) return -1;
351 if (!(body2.getArgument(1) instanceof Variable)) return -1;
352 Variable rx, ry, sx, sy, tx, ty;
353 tx = head.getArgumentVariable(0); ty = head.getArgumentVariable(1);
354 rx = body1.getArgumentVariable(0); ry = body1.getArgumentVariable(1);
355 sx = body2.getArgumentVariable(0); sy = body2.getArgumentVariable(1);
356
357 if (rx.equals(tx))
358 if (ry.equals(sx))
359 if (sy.equals(ty)) return 0;
360 else return -1;
361 else if (ry.equals(sy))
362 if (sx.equals(ty)) return 2;
363 else return -1;
364 else
365 return -1;
366 else if (rx.equals(ty))
367 if (ry.equals(sx))
368 if (sy.equals(tx)) return 1;
369 else return -1;
370 else if (ry.equals(sy))
371 if (sx.equals(tx)) return 3;
372 else return -1;
373 else
374 return -1;
375 else if (ry.equals(tx))
376 if (rx.equals(sx))
377 if (sy.equals(ty)) return 4;
378 else return -1;
379 else if (rx.equals(sy))
380 if (sx.equals(ty)) return 6;
381 else return -1;
382 else
383 return -1;
384 else if (ry.equals(ty))
385 if (rx.equals(sx))
386 if (sy.equals(tx)) return 5;
387 else return -1;
388 else if (rx.equals(sy))
389 if (sx.equals(tx)) return 7;
390 else return -1;
391 else return -1;
392 else
393 return -1;
394 }
395 return -1;
396 }
397
398 public static boolean isGround(Atom tHeadAtom) {
399 for (int i = 0; i < tHeadAtom.getArity(); ++i)
400 if (tHeadAtom.getArgument(i) instanceof Variable)
401 return false;
402 return true;
403 }
404 /**
405 * true if a \subseteq b
406 * @param a
407 * @param b
408 * @return
409 */
410 private static boolean hasSubsetAtoms(Atom[] a, Atom[] b) {
411 Set<String> atoms = new HashSet<String>();
412 for (int i = 0; i < b.length; ++i)
413 atoms.add(b[i].toString());
414
415 for (int i = 0; i < a.length; ++i)
416 if (!atoms.remove(a[i].toString()))
417 return false;
418
419 return true;
420 }
421
422 public static boolean hasSubsetBodyAtoms(DLClause c1, DLClause c2) {
423 return hasSubsetAtoms(c1.getBodyAtoms(), c2.getBodyAtoms());
424 }
425
426 public static DLClause replaceOtherBottom(DLClause dlClause) {
427 Atom[] newHeadAtoms = dlClause.getHeadAtoms(), newBodyAtoms = dlClause.getBodyAtoms();
428 if (containsOtherBottom(newHeadAtoms))
429 newHeadAtoms = replaceOtherBottom(newHeadAtoms);
430 if (containsOtherBottom(newBodyAtoms))
431 newBodyAtoms = replaceOtherBottom(newBodyAtoms);
432
433 if (newHeadAtoms == dlClause.getHeadAtoms() && newBodyAtoms == dlClause.getBodyAtoms())
434 return dlClause;
435
436 return DLClause.create(newHeadAtoms, newBodyAtoms);
437 }
438
439 private static Atom[] replaceOtherBottom(Atom[] atoms) {
440 Atom[] newAtoms = new Atom[atoms.length];
441 int index = 0;
442 for (Atom atom: atoms)
443 if (isOtherBottom(atom.getDLPredicate()))
444 newAtoms[index++] = Atom.create(AtomicConcept.NOTHING, atom.getArgument(0));
445 else
446 newAtoms[index++] = atom;
447 return newAtoms;
448 }
449
450 private static boolean isOtherBottom(DLPredicate p) {
451 if (!(p instanceof AtomicConcept)) return false;
452
453 String name = p.toString();
454 int index;
455 char ch;
456 if ((index = name.indexOf("owl:Nothing")) != -1) {
457 index += 11;
458 if (name.length() <= index) return true;
459 if ((ch = name.charAt(index)) == '_') return true;
460 if (ch >= '0' && ch <= '9') return true;
461 }
462 return false;
463 }
464
465 private static boolean containsOtherBottom(Atom[] atoms) {
466 for (Atom atom: atoms)
467 if (isOtherBottom(atom.getDLPredicate()))
468 return true;
469 return false;
470 }
471
472 public static boolean isTautologyAboutDifferentFrom(DLClause clause) {
473 if (clause.getHeadLength() > 1 || clause.getBodyLength() != 1) return false;
474 if (clause.getHeadLength() == 1 && !clause.getHeadAtom(0).getDLPredicate().toString().contains(AtomicConcept.NOTHING.toString()))
475 return false;
476 Atom bodyAtom = clause.getBodyAtom(0);
477 return (bodyAtom.getDLPredicate() instanceof Inequality) && bodyAtom.getArgument(0).equals(bodyAtom.getArgument(1));
478 }
479
480}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java b/src/main/java/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java
new file mode 100644
index 0000000..43c5849
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/hermit/RuleHelper.java
@@ -0,0 +1,173 @@
1package uk.ac.ox.cs.pagoda.hermit;
2
3import org.semanticweb.HermiT.model.*;
4import uk.ac.ox.cs.pagoda.MyPrefixes;
5import uk.ac.ox.cs.pagoda.owl.OWLHelper;
6import uk.ac.ox.cs.pagoda.util.Namespace;
7
8import java.security.InvalidParameterException;
9import java.util.ArrayList;
10
11public class RuleHelper {
12 private static final String OR = "|";
13 private static final String IF = ":-";
14 private static final String AND = ",";
15
16// public static String abbreviateIRI(String text) {
17// String prefixName, prefixIRI;
18// int start = -1, ends = -1;
19// while (true) {
20// start = text.indexOf('<', ends + 1);
21// if (start == -1) return text;
22// ends = text.indexOf('>', start + 1);
23// if (ends == -1) return text;
24// String sub = text.substring(start, ends + 1), newSub = text.substring(start + 1, ends);
25//
26// int index = splitPoint(newSub);
27// if (index >= 0) {
28// prefixIRI = newSub.substring(0, index + 1);
29// if ((prefixName = MyPrefixes.PAGOdAPrefixes.getPrefixName(prefixIRI)) == null) {
30// prefixName = getNewPrefixName();
31// MyPrefixes.PAGOdAPrefixes.declarePrefix(prefixName, prefixIRI);
32// }
33// newSub = newSub.replace(prefixIRI, prefixName);
34// text = text.replaceAll(sub, newSub);
35// ends -= sub.length() - newSub.length();
36// }
37// }
38// }
39
40 public static String getText(DLClause clause) {
41 StringBuffer buf = new StringBuffer();
42 String atomText;
43
44 boolean lastSpace = true;
45 for (Atom headAtom: clause.getHeadAtoms()) {
46 if ((atomText = getText(headAtom)) == null) continue;
47 if (!lastSpace) buf.append(" ").append(OR).append(" ");
48 buf.append(atomText);
49 lastSpace = false;
50 }
51 buf.append(" ").append(IF).append(" ");
52 lastSpace = true;
53 for (Atom bodyAtom: clause.getBodyAtoms()) {
54// for (String str: strs[1].split(", ")) {
55 if ((atomText = getText(bodyAtom)) == null) continue;
56 if (!lastSpace) buf.append(AND).append(" ");
57 buf.append(atomText);
58 lastSpace = false;
59 }
60 buf.append('.');
61 return buf.toString();
62 }
63
64
65 private static String getText(Atom atom) {
66 if (atom.getDLPredicate() instanceof NodeIDsAscendingOrEqual ||
67 atom.getDLPredicate() instanceof NodeIDLessEqualThan)
68 return null;
69
70 StringBuilder builder = new StringBuilder();
71 if (atom.getArity() == 1) {
72 builder.append(getText(atom.getDLPredicate()));
73 builder.append("(");
74 builder.append(getText(atom.getArgument(0)));
75 builder.append(")");
76 }
77 else {
78 DLPredicate p = atom.getDLPredicate();
79 if (p instanceof Equality || p instanceof AnnotatedEquality) builder.append(Namespace.EQUALITY_ABBR);
80 else if (p instanceof Inequality) builder.append(Namespace.INEQUALITY_ABBR);
81 else builder.append(getText(p));
82 builder.append("(");
83 builder.append(getText(atom.getArgument(0)));
84 builder.append(",");
85 builder.append(getText(atom.getArgument(1)));
86 builder.append(")");
87 }
88 return builder.toString();
89 }
90
91 public static String getText(DLPredicate p) {
92 if (p instanceof Equality || p instanceof AnnotatedEquality) return Namespace.EQUALITY_ABBR;
93 if (p instanceof Inequality) return Namespace.INEQUALITY_ABBR;
94 if (p instanceof AtomicRole && ((AtomicRole) p).getIRI().startsWith("?"))
95 return ((AtomicRole) p).getIRI();
96 return MyPrefixes.PAGOdAPrefixes.abbreviateIRI(p.toString());
97 }
98
99 public static String getText(Term t) {
100 if (t instanceof Variable)
101 return "?" + ((Variable) t).getName();
102 return MyPrefixes.PAGOdAPrefixes.abbreviateIRI(t.toString());
103 }
104
105 public static Term parseTerm(String s) {
106 s = s.trim();
107 if(s.startsWith("?")) return Variable.create(s.substring(1));
108 return Individual.create(MyPrefixes.PAGOdAPrefixes.expandIRI(s));
109 }
110
111 public static Atom parseAtom(String s) {
112 s = s.trim();
113
114 String[] split = s.split("\\(");
115 String predicateIri = OWLHelper.removeAngles(MyPrefixes.PAGOdAPrefixes.expandText(split[0]));
116 String[] predicateArgs = split[1].substring(0, split[1].length() - 1).split(",");
117 int numOfargs = predicateArgs.length;
118 Term terms[] = new Term[predicateArgs.length];
119 for (int i = 0; i < terms.length; i++)
120 terms[i] = parseTerm(predicateArgs[i]);
121 if(numOfargs == 1) {
122 AtomicConcept atomicConcept = AtomicConcept.create(predicateIri);
123 return Atom.create(atomicConcept, terms);
124 }
125 else if(numOfargs == 2) {
126 AtomicRole atomicRole = AtomicRole.create(predicateIri);
127 return Atom.create(atomicRole, terms);
128 }
129 else
130 throw new InvalidParameterException();
131 // TODO? add equality (owl:sameAs)?
132 }
133
134 public static DLClause parseClause(String s) {
135 s = s.trim();
136 if(s.endsWith(".")) s = s.substring(0, s.length()-1).trim();
137
138 String[] headAndBody = s.split(IF);
139 String[] headAtomsStr = splitAtoms(headAndBody[0], OR);
140 String[] bodyAtomsStr = splitAtoms(headAndBody[1], AND);
141
142 Atom[] headAtoms = new Atom[headAtomsStr.length];
143 Atom[] bodyAtoms = new Atom[bodyAtomsStr.length];
144 for (int i = 0; i < headAtoms.length; i++)
145 headAtoms[i] = parseAtom(headAtomsStr[i]);
146 for (int i = 0; i < bodyAtoms.length; i++)
147 bodyAtoms[i] = parseAtom(bodyAtomsStr[i]);
148
149 return DLClause.create(headAtoms, bodyAtoms);
150 }
151
152 private static String[] splitAtoms(String s, String operator) {
153 char op = operator.charAt(0);
154 ArrayList<String> result = new ArrayList<>();
155
156 int b = 0;
157 boolean betweenParenthesis = false;
158 for (int i = 0; i < s.length(); i++) {
159 if(s.charAt(i) == '(')
160 betweenParenthesis = true;
161 else if(s.charAt(i) == ')')
162 betweenParenthesis = false;
163 else if(s.charAt(i) == op && !betweenParenthesis) {
164 result.add(s.substring(b, i));
165 b = i + 1;
166 }
167 }
168 if(b < s.length()) result.add(s.substring(b));
169
170 return result.toArray(new String[0]);
171 }
172
173}
diff --git a/src/main/java/uk/ac/ox/cs/pagoda/hermit/TermGraph.java b/src/main/java/uk/ac/ox/cs/pagoda/hermit/TermGraph.java
new file mode 100644
index 0000000..0041cca
--- /dev/null
+++ b/src/main/java/uk/ac/ox/cs/pagoda/hermit/TermGraph.java
@@ -0,0 +1,258 @@
1package uk.ac.ox.cs.pagoda.hermit;
2
3import java.util.Collection;
4import java.util.Comparator;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.Iterator;
8import java.util.Map;
9import java.util.PriorityQueue;
10import java.util.Set;
11
12import org.semanticweb.HermiT.model.AnnotatedEquality;
13import org.semanticweb.HermiT.model.Atom;
14import org.semanticweb.HermiT.model.AtomicConcept;
15import org.semanticweb.HermiT.model.AtomicRole;
16import org.semanticweb.HermiT.model.Constant;
17import org.semanticweb.HermiT.model.DLClause;
18import org.semanticweb.HermiT.model.DLPredicate;
19import org.semanticweb.HermiT.model.DatatypeRestriction;
20import org.semanticweb.HermiT.model.Equality;
21import org.semanticweb.HermiT.model.Individual;
22import org.semanticweb.HermiT.model.NodeIDLessEqualThan;
23import org.semanticweb.HermiT.model.NodeIDsAscendingOrEqual;
24import org.semanticweb.HermiT.model.Term;
25import org.semanticweb.HermiT.model.Variable;
26
27import uk.ac.ox.cs.pagoda.util.Namespace;
28import uk.ac.ox.cs.pagoda.util.Utility;
29
30public class TermGraph {
31
32 Map<Term, Collection<Edge>> graph = new HashMap<Term, Collection<Edge>>();
33 Map<Term, Collection<AtomicConcept>> term2concepts = new HashMap<Term, Collection<AtomicConcept>>();
34 Set<Term> choosen = new HashSet<Term>(), allTerms = new HashSet<Term>();
35 DLClause clause;
36 Set<Atom> newBodyAtoms = new HashSet<Atom>();
37
38 public TermGraph(DLClause clause) {
39 this.clause = clause;
40 for (Atom atom: clause.getHeadAtoms())
41 for (int i = 0; i < atom.getArity(); ++i)
42 allTerms.add(atom.getArgument(i));
43 for (Atom atom: clause.getBodyAtoms())
44 for (int i = 0; i < atom.getArity(); ++i)
45 allTerms.add(atom.getArgument(i));
46 }
47
48 public DLClause simplify() {
49 constructGraph();
50 chooseTerms();
51
52 PriorityQueue<Term> queue = new PriorityQueue<Term>(allTerms.size(), new Comparator<Term>() {
53
54 @Override
55 public int compare(Term o1, Term o2) {
56 int diff = 0;
57 @SuppressWarnings("rawtypes")
58 Collection set1 = term2concepts.get(o1), set2 = term2concepts.get(o2);
59 int num1 = size(set1), num2 = size(set2);
60
61 if ((diff = num2 - num1) != 0)
62 return diff;
63
64 set1 = graph.get(o1); set2 = graph.get(o2);
65 num1 = size(set1); num2 = size(set2);
66
67 return num2 - num1;
68 }
69
70 private int size(@SuppressWarnings("rawtypes") Collection c) {
71 return c == null ? 0 : c.size();
72 }
73
74 });
75
76 for (Term term: allTerms)
77 queue.add(term);
78
79 while (!queue.isEmpty()) {
80 Term term = queue.remove();
81 if (!choosen.contains(term) && isRepresentative(term))
82 choosen.add(term);
83 }
84
85 boolean flag;
86 for (Iterator<Atom> iter = newBodyAtoms.iterator(); iter.hasNext(); ) {
87 flag = true;
88 Atom atom = iter.next();
89 for (int i = 0; i < atom.getArity(); ++i) {
90 if (!choosen.contains(atom.getArgument(i))) {
91 flag = false;
92 break;
93 }
94 }
95 if (!flag) iter.remove();
96 }
97
98 return DLClause.create(clause.getHeadAtoms(), newBodyAtoms.toArray(new Atom[0]));
99 }
100
101 private boolean isRepresentative(Term term) {
102 boolean flag = true;
103 for (Term otherTerm: choosen)
104 if (!term.equals(otherTerm) && isSubsumedBy(term, otherTerm)) {
105 flag = false;
106 }
107 return flag;
108 }
109
110 private boolean isSubsumedBy(Term t1, Term t2) {
111 Collection<AtomicConcept> set1 = term2concepts.get(t1);
112 Collection<AtomicConcept> set2 = term2concepts.get(t2);
113
114 if (set1 != null)
115 if (set2 == null)
116 return false;
117 else if (!set2.containsAll(set1))
118 return false;
119
120 Collection<Edge> edgeSet1 = graph.get(t1);
121 Collection<Edge> edgeSet2 = graph.get(t2);
122 if (edgeSet1 != null)
123 if (edgeSet2 == null)
124 return false;
125 else {
126 if (!edgeSet2.containsAll(edgeSet1))
127 return false;
128// else {
129// Collection<Edge> restEdge1 = new HashSet<Edge>();
130// for (Edge edge: edgeSet1)
131// if (edge.term == t2);
132// else restEdge1.add(edge);
133//
134// Collection<Edge> restEdge2 = new HashSet<Edge>();
135// for (Edge edge: edgeSet2)
136// if (edge.term == t1);
137// else restEdge2.add(edge);
138//
139// return restEdge2.containsAll(edgeSet1);
140// }
141 }
142
143 return true;
144 }
145
146 private void chooseTerms() {
147 Set<Variable> headVariables = new HashSet<Variable>();
148 for (Atom atom: clause.getHeadAtoms()) {
149 atom.getVariables(headVariables);
150 }
151 choosen.addAll(headVariables);
152
153 for (Term term: allTerms)
154 if (term instanceof Constant || term instanceof Individual)
155 choosen.add(term);
156
157 if (choosen.isEmpty()) choosen.add(Variable.create("X"));
158// propagate();
159 }
160
161// private void propagate() {
162// LinkedList<Term> queue = new LinkedList<Term>(choosen);
163// Term term;
164// while (!queue.isEmpty()) {
165// term = queue.pop();
166// if (graph.containsKey(term))
167// for (Edge edge: graph.get(term))
168// if (!choosen.contains(edge.term)) {
169// choosen.add(edge.term);
170// queue.add(term);
171// }
172// }
173// }
174
175 private void constructGraph() {
176 DLPredicate p;
177 for (Atom bodyAtom: clause.getBodyAtoms()) {
178 p = bodyAtom.getDLPredicate();
179 if (p instanceof AtomicConcept) {
180 newBodyAtoms.add(bodyAtom);
181 addConcept(bodyAtom.getArgument(0), (AtomicConcept) p);
182 }
183 else if (p instanceof AtomicRole) {
184 newBodyAtoms.add(bodyAtom);
185 addEdges(bodyAtom.getArgument(0), bodyAtom.getArgument(1), (AtomicRole) p);
186 }
187 else if (p instanceof DatatypeRestriction)
188 newBodyAtoms.add(bodyAtom);
189 else if (p instanceof NodeIDLessEqualThan || p instanceof NodeIDsAscendingOrEqual);
190 else if (p instanceof Equality || p instanceof AnnotatedEquality) {
191 newBodyAtoms.add(bodyAtom);
192 addEdges(bodyAtom.getArgument(0), bodyAtom.getArgument(1), AtomicRole.create(Namespace.EQUALITY));
193 } else {
194 Utility.logError("Unknown DLPredicate in TermGraph: " + p);
195 }
196 }
197 }
198
199 private void addEdges(Term t1, Term t2, AtomicRole p) {
200 addEdge(t1, new Edge(p, t2, false));
201 addEdge(t2, new Edge(p, t1, true));
202 }
203
204 private void addEdge(Term t, Edge edge) {
205 Collection<Edge> edges;
206 if ((edges = graph.get(t)) == null) {
207 graph.put(t, edges = new HashSet<Edge>());
208 }
209 edges.add(edge);
210 }
211
212 private void addConcept(Term t, AtomicConcept p) {
213 Collection<AtomicConcept> concepts;
214 if ((concepts = term2concepts.get(t)) == null) {
215 term2concepts.put(t, concepts = new HashSet<AtomicConcept>());
216 }
217 concepts.add(p);
218 }
219
220 public boolean mark(Term t) {
221 return choosen.add(t);
222 }
223
224}
225
226class Edge {
227 boolean isInverse;
228 AtomicRole role;
229 Term term;
230
231 public Edge(AtomicRole role, Term term, boolean isInverse) {
232 this.role = role;
233 this.term = term;
234 this.isInverse = isInverse;
235 }
236
237 @Override
238 public int hashCode() {
239 return role.hashCode() * 1997 + term.hashCode() * 2 + (isInverse ? 1 : 0);
240 }
241
242 @Override
243 public boolean equals(Object obj) {
244 if (!(obj instanceof Edge)) return false;
245 Edge other = (Edge) obj;
246 return isInverse == other.isInverse && role.equals(other.role) && term.equals(other.term);
247 }
248
249 @Override
250 public String toString() {
251 if (isInverse)
252 return "inv_" + role.toString() + "_" + term.toString();
253 return role.toString() + "_" + term.toString();
254 }
255
256}
257
258