aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/rules/Program.java
diff options
context:
space:
mode:
authoryzhou <yujiao.zhou@gmail.com>2015-04-21 10:34:27 +0100
committeryzhou <yujiao.zhou@gmail.com>2015-04-21 10:34:27 +0100
commit9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8 (patch)
tree47511c0fb89dccff0db4b5990522e04f294d795b /src/uk/ac/ox/cs/pagoda/rules/Program.java
parentb1ac207612ee8b045244253fb94b866104bc34f2 (diff)
downloadACQuA-9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8.tar.gz
ACQuA-9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8.zip
initial version
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/rules/Program.java')
-rw-r--r--src/uk/ac/ox/cs/pagoda/rules/Program.java388
1 files changed, 388 insertions, 0 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/rules/Program.java b/src/uk/ac/ox/cs/pagoda/rules/Program.java
new file mode 100644
index 0000000..b533e50
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/rules/Program.java
@@ -0,0 +1,388 @@
1package uk.ac.ox.cs.pagoda.rules;
2
3import java.io.BufferedWriter;
4import java.io.File;
5import java.io.FileNotFoundException;
6import java.io.FileOutputStream;
7import java.io.IOException;
8import java.io.OutputStreamWriter;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.Iterator;
13import java.util.LinkedList;
14import java.util.List;
15import java.util.Map;
16import java.util.Set;
17
18import org.semanticweb.HermiT.Configuration;
19import org.semanticweb.HermiT.model.AnnotatedEquality;
20import org.semanticweb.HermiT.model.Atom;
21import org.semanticweb.HermiT.model.AtomicConcept;
22import org.semanticweb.HermiT.model.AtomicDataRange;
23import org.semanticweb.HermiT.model.AtomicNegationDataRange;
24import org.semanticweb.HermiT.model.AtomicRole;
25import org.semanticweb.HermiT.model.ConstantEnumeration;
26import org.semanticweb.HermiT.model.DLClause;
27import org.semanticweb.HermiT.model.DLOntology;
28import org.semanticweb.HermiT.model.DLPredicate;
29import org.semanticweb.HermiT.model.Equality;
30import org.semanticweb.HermiT.model.Inequality;
31import org.semanticweb.HermiT.model.InverseRole;
32import org.semanticweb.HermiT.model.Term;
33import org.semanticweb.HermiT.model.Variable;
34import org.semanticweb.HermiT.structural.OWLClausification;
35import org.semanticweb.owlapi.model.*;
36
37import uk.ac.ox.cs.pagoda.MyPrefixes;
38import uk.ac.ox.cs.pagoda.approx.KnowledgeBase;
39import uk.ac.ox.cs.pagoda.approx.RLPlusOntology;
40import uk.ac.ox.cs.pagoda.constraints.BottomStrategy;
41import uk.ac.ox.cs.pagoda.constraints.NullaryBottom;
42import uk.ac.ox.cs.pagoda.constraints.PredicateDependency;
43import uk.ac.ox.cs.pagoda.hermit.DLClauseHelper;
44import uk.ac.ox.cs.pagoda.owl.OWLHelper;
45import uk.ac.ox.cs.pagoda.util.Utility;
46
47import org.semanticweb.simpleETL.SimpleETL;
48
49public abstract class Program implements KnowledgeBase {
50
51 protected String ontologyDirectory = null;
52 protected OWLOntology ontology;
53 protected DLOntology dlOntology;
54 protected BottomStrategy botStrategy;
55
56 private String additionalDataFile = null;
57
58 protected Collection<DLClause> clauses = new HashSet<DLClause>();
59// protected Set<DLClause> used = new HashSet<DLClause>();
60 protected PredicateDependency dependencyGraph;
61
62 /**
63 * clone all information of another program after load()
64 *
65 * @param program
66 */
67 void clone(Program program) {
68 this.ontologyDirectory = program.ontologyDirectory;
69 this.ontology = program.ontology;
70 this.dlOntology = program.dlOntology;
71 this.botStrategy = program.botStrategy;
72 this.additionalDataFile = program.additionalDataFile;
73 this.transitiveAxioms = program.transitiveAxioms;
74 this.transitiveClauses = program.transitiveClauses;
75 this.subPropChainAxioms = program.subPropChainAxioms;
76 this.subPropChainClauses = program.subPropChainClauses;
77 }
78
79 public void load(OWLOntology o, BottomStrategy botStrategy) {
80 this.botStrategy = botStrategy;
81 RLPlusOntology owlOntology = new RLPlusOntology();
82 owlOntology.load(o, new NullaryBottom());
83 owlOntology.simplify();
84
85 ontology = owlOntology.getTBox();
86 String ontologyPath = OWLHelper.getOntologyPath(ontology);
87 ontologyDirectory = ontologyPath.substring(0, ontologyPath.lastIndexOf(Utility.JAVA_FILE_SEPARATOR));
88 clausify();
89
90 String aboxOWLFile = owlOntology.getABoxPath();
91 OWLOntology abox = OWLHelper.loadOntology(aboxOWLFile);
92 OWLOntologyManager manager = abox.getOWLOntologyManager();
93 OWLAxiom axiom;
94 for (Atom atom: dlOntology.getPositiveFacts()) {
95 if ((axiom = OWLHelper.getABoxAssertion(manager.getOWLDataFactory(), atom)) != null)
96 manager.addAxiom(abox, axiom);
97 }
98
99 try {
100 FileOutputStream out = new FileOutputStream(aboxOWLFile);
101 manager.saveOntology(abox, out);
102 out.close();
103 } catch (OWLOntologyStorageException e) {
104 // TODO Auto-generated catch block
105 e.printStackTrace();
106 } catch (FileNotFoundException e) {
107 // TODO Auto-generated catch block
108 e.printStackTrace();
109 } catch (IOException e) {
110 // TODO Auto-generated catch block
111 e.printStackTrace();
112 }
113
114 if (!abox.isEmpty()) {
115 SimpleETL rewriter = new SimpleETL(owlOntology.getOntologyIRI(), aboxOWLFile);
116 try {
117 rewriter.rewrite();
118 } catch (Exception e) {
119 e.printStackTrace();
120 }
121 additionalDataFile = rewriter.getExportedFile();
122 new File(aboxOWLFile).delete();
123 }
124
125 }
126
127 private void clausify() {
128 Configuration conf = new Configuration();
129 OWLClausification clausifier = new OWLClausification(conf);
130 OWLOntology filteredOntology = null;
131 OWLOntologyManager manager = ontology.getOWLOntologyManager();
132 try {
133 filteredOntology = manager.createOntology();
134 } catch (OWLOntologyCreationException e) {
135 e.printStackTrace();
136 }
137
138 transitiveAxioms = new LinkedList<OWLTransitiveObjectPropertyAxiom>();
139 subPropChainAxioms = new LinkedList<OWLSubPropertyChainOfAxiom>();
140
141 OWLEntity date = ontology.getOWLOntologyManager().getOWLDataFactory().getOWLDatatype(IRI.create("http://www.w3.org/2001/XMLSchema#date"));
142 int noOfDataPropertyRangeAxioms = 0, noOfAxioms = 0;
143 for (OWLOntology onto: ontology.getImportsClosure())
144 for (OWLAxiom axiom: onto.getAxioms()) {
145 if (axiom instanceof OWLTransitiveObjectPropertyAxiom)
146 transitiveAxioms.add((OWLTransitiveObjectPropertyAxiom) axiom);
147 else if (axiom instanceof OWLSubPropertyChainOfAxiom)
148 subPropChainAxioms.add((OWLSubPropertyChainOfAxiom) axiom);
149 // TODO to filter out datatype axioms
150 else if (axiom instanceof OWLDataPropertyRangeAxiom) {
151 ++noOfDataPropertyRangeAxioms;
152 Utility.logInfo("The axiom: " + axiom + " is being ignored.");
153 }
154 else {
155 if (axiom.containsEntityInSignature(date)) {
156 Utility.logInfo("The axiom: " + axiom + " is being ignored.");
157 }
158 else manager.addAxiom(filteredOntology, axiom);
159 }
160
161 if (axiom instanceof OWLAnnotationAssertionAxiom ||
162 axiom instanceof OWLSubAnnotationPropertyOfAxiom ||
163 axiom instanceof OWLDeclarationAxiom ||
164 axiom instanceof OWLDataPropertyRangeAxiom) {
165 }
166 else {
167// System.out.println(axiom);
168 ++noOfAxioms;
169 }
170
171 }
172 Utility.logInfo("The number of data property range axioms that are ignored: " + noOfDataPropertyRangeAxioms + "(" + noOfAxioms + ")");
173
174 dlOntology = (DLOntology)clausifier.preprocessAndClausify(filteredOntology, null)[1];
175 clausifier = null;
176 }
177
178 public String getAdditionalDataFile() {
179 return additionalDataFile;
180 }
181
182 protected LinkedList<OWLTransitiveObjectPropertyAxiom> transitiveAxioms;
183 protected LinkedList<DLClause> transitiveClauses;
184
185 protected LinkedList<OWLSubPropertyChainOfAxiom> subPropChainAxioms;
186 protected LinkedList<DLClause> subPropChainClauses;
187
188 @Override
189 public void transform() {
190 for (DLClause dlClause: dlOntology.getDLClauses()) {
191 DLClause simplifiedDLClause = DLClauseHelper.removeNominalConcept(dlClause);
192 simplifiedDLClause = removeAuxiliaryBodyAtoms(simplifiedDLClause);
193 simplifiedDLClause = DLClauseHelper.replaceWithDataValue(simplifiedDLClause);
194 convert(simplifiedDLClause);
195 }
196
197 addingTransitiveAxioms();
198 addingSubPropertyChainAxioms();
199
200 Collection<DLClause> botRelated = new LinkedList<DLClause>();
201 Variable X = Variable.create("X");
202 botRelated.add(DLClause.create(new Atom[0], new Atom[] {Atom.create(Inequality.INSTANCE, X, X)}));
203 clauses.addAll(botStrategy.process(botRelated));
204
205 if (this instanceof GeneralProgram)
206 Utility.logInfo("The number of rules: " + (clauses.size() - 1));
207 }
208
209 private DLClause removeAuxiliaryBodyAtoms(DLClause dlClause) {
210 Collection<Atom> newBodyAtoms = new LinkedList<Atom>();
211 DLPredicate p;
212 for (Atom bodyAtom: dlClause.getBodyAtoms()) {
213 p = bodyAtom.getDLPredicate();
214 if (p instanceof AtomicConcept ||
215 p instanceof AtomicRole || p instanceof InverseRole ||
216 p instanceof Equality || p instanceof AnnotatedEquality || p instanceof Inequality)
217 newBodyAtoms.add(bodyAtom);
218 }
219 LinkedList<Atom> newHeadAtoms = new LinkedList<Atom>();
220 Map<Variable, Term> assign = new HashMap<Variable, Term>();
221 for (Atom headAtom: dlClause.getHeadAtoms()) {
222 p = headAtom.getDLPredicate();
223 if (p instanceof AtomicNegationDataRange) {
224 AtomicDataRange positive = ((AtomicNegationDataRange) p).getNegatedDataRange();
225 if (!(positive instanceof ConstantEnumeration))
226 newBodyAtoms.add(Atom.create(positive, headAtom.getArgument(0)));
227 else if (((ConstantEnumeration) positive).getNumberOfConstants() == 1) {
228 assign.put((Variable) headAtom.getArgument(0), ((ConstantEnumeration) positive).getConstant(0));
229// newBodyAtoms.add(Atom.create(Equality.INSTANCE, headAtom.getArgument(0), ((ConstantEnumeration) positive).getConstant(0)));
230 }
231 else newHeadAtoms.add(headAtom);
232 }
233 else
234 newHeadAtoms.add(headAtom);
235 }
236
237 if (assign.isEmpty() && newHeadAtoms.isEmpty() && newBodyAtoms.size() == dlClause.getBodyLength())
238 return dlClause;
239
240 Atom[] headArray = newHeadAtoms.size() == dlClause.getHeadLength() ? dlClause.getHeadAtoms() : newHeadAtoms.toArray(new Atom[0]);
241 Atom[] bodyArray = newBodyAtoms.size() == dlClause.getBodyLength() ? dlClause.getBodyAtoms() : newBodyAtoms.toArray(new Atom[0]);
242 if (!assign.isEmpty()) {
243 for (int i = 0; i < headArray.length; ++i)
244 headArray[i] = DLClauseHelper.getInstance(headArray[i], assign);
245 for (int i = 0; i < bodyArray.length; ++i)
246 bodyArray[i] = DLClauseHelper.getInstance(bodyArray[i], assign);
247 }
248 return DLClause.create(headArray, bodyArray);
249 }
250
251 private void addingTransitiveAxioms() {
252 DLClause transitiveClause;
253 Atom headAtom;
254 Variable X = Variable.create("X"), Y = Variable.create("Y"), Z = Variable.create("Z");
255 transitiveClauses = new LinkedList<DLClause>();
256 for (OWLTransitiveObjectPropertyAxiom axiom: transitiveAxioms) {
257 OWLObjectPropertyExpression objExp = axiom.getProperty();
258 headAtom = getAtom(objExp, X, Z);
259 Atom[] bodyAtoms = new Atom[2];
260 bodyAtoms[0] = getAtom(objExp, X, Y);
261 bodyAtoms[1] = getAtom(objExp, Y, Z);
262 transitiveClause = DLClause.create(new Atom[] {headAtom}, bodyAtoms);
263 clauses.add(transitiveClause);
264 transitiveClauses.add(transitiveClause);
265 }
266 }
267
268 private Atom getAtom(OWLObjectPropertyExpression exp, Variable x, Variable y) {
269 if (exp instanceof OWLObjectProperty)
270 return Atom.create(AtomicRole.create(((OWLObjectProperty) exp).toStringID()), x, y);
271 OWLObjectInverseOf inverseOf;
272 if (exp instanceof OWLObjectInverseOf && (inverseOf = (OWLObjectInverseOf) exp).getInverse() instanceof OWLObjectProperty)
273 return Atom.create(AtomicRole.create(((OWLObjectProperty) inverseOf).toStringID()), x, y);
274 return null;
275 }
276
277 private void addingSubPropertyChainAxioms() {
278 DLClause dlClause;
279 subPropChainClauses = new LinkedList<DLClause>();
280 Atom headAtom;
281 Iterator<OWLObjectPropertyExpression> iterExp;
282 OWLObjectPropertyExpression objExp;
283 for (OWLSubPropertyChainOfAxiom axiom: subPropChainAxioms) {
284 objExp = axiom.getSuperProperty();
285 List<OWLObjectPropertyExpression> objs = axiom.getPropertyChain();
286 headAtom = getAtom(objExp, Variable.create("X"), Variable.create("X" + objs.size()));
287 iterExp = objs.iterator();
288 int index = 1;
289 Atom[] bodyAtoms = new Atom[objs.size()];
290 bodyAtoms[0] = getAtom(iterExp.next(), Variable.create("X"), Variable.create("X1"));
291 while (index < objs.size()) {
292 bodyAtoms[index] = getAtom(iterExp.next(), Variable.create("X" + index), Variable.create("X" + (index + 1)));
293 ++index;
294 }
295 dlClause = DLClause.create(new Atom[] {headAtom}, bodyAtoms);
296 clauses.add(dlClause);
297 subPropChainClauses.add(dlClause);
298 }
299 }
300
301 @Override
302 public void save() {
303 try {
304 BufferedWriter ruleWriter = new BufferedWriter(new OutputStreamWriter(
305 new FileOutputStream(getOutputPath())));
306 ruleWriter.write(toString());
307 ruleWriter.close();
308 } catch (IOException e) {
309 e.printStackTrace();
310 }
311 Utility.logDebug("The rules are saved in " + getOutputPath() + ".");
312 }
313
314 @Override
315 public String toString() {
316 return toString(clauses);
317 }
318
319 public static String toString(Collection<DLClause> clauses) {
320 StringBuilder sb = new StringBuilder(DLClauseHelper.toString(clauses));
321 sb.insert(0, MyPrefixes.PAGOdAPrefixes.prefixesText());
322 return sb.toString();
323 }
324
325 public final void convert(DLClause clause) {
326 Collection<DLClause> tempClauses = convert2Clauses(clause);
327 clauses.addAll(tempClauses);
328 }
329
330 public abstract Collection<DLClause> convert2Clauses(DLClause clause);
331
332 public abstract String getOutputPath();
333
334
335 public OWLOntology getOntology() {
336 return ontology;
337 }
338
339 public Collection<DLClause> getClauses() {
340 return clauses;
341 }
342
343 public Collection<DLClause> getClauses(DLClause queryClause) {
344// if (true) return new HashSet<DLClause>(clauses);
345 Set<DLPredicate> predicates = new HashSet<DLPredicate>();
346 predicates.addAll(dependencyGraph.collectPredicate(queryClause.getBodyAtoms()));
347
348 Set<DLPredicate> dependence = new HashSet<DLPredicate>();
349 for (DLPredicate predicate: predicates)
350 dependence.addAll(dependencyGraph.getAncesters(predicate));
351
352 Collection<DLClause> relevantClauses = new LinkedList<DLClause>();
353 for (DLClause clause: clauses) {
354 if (relevant(clause, dependence))
355 relevantClauses.add(clause);
356
357 }
358 return relevantClauses;
359 }
360
361 private boolean relevant(DLClause clause, Set<DLPredicate> set) {
362 for (DLPredicate p: dependencyGraph.collectPredicate(clause.getHeadAtoms()))
363 if (set.contains(p))
364 return true;
365 return false;
366 }
367
368 public PredicateDependency buildDependencyGraph() {
369 if (dependencyGraph == null)
370 return dependencyGraph = new PredicateDependency(clauses);
371 else
372 return dependencyGraph;
373 }
374
375 public void getDependencyGraph(PredicateDependency g) {
376 dependencyGraph = g;
377 }
378
379 public final String getDirectory() {
380 return Utility.TempDirectory;
381 }
382
383 public void deleteABoxTurtleFile() {
384 if (additionalDataFile != null)
385 new File(additionalDataFile).delete();
386 }
387
388}