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