aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/summary
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/summary')
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/Edge.java70
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/EstimatedFeatureComparator.java53
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/Graph.java154
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/HermitSummaryFilter.java202
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/Node.java65
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java39
-rw-r--r--src/uk/ac/ox/cs/pagoda/summary/Summary.java215
7 files changed, 798 insertions, 0 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/summary/Edge.java b/src/uk/ac/ox/cs/pagoda/summary/Edge.java
new file mode 100644
index 0000000..79d3041
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/Edge.java
@@ -0,0 +1,70 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.util.Comparator;
4
5public class Edge {
6
7 Node from, to;
8 String label;
9
10 public String getLabel() { return label; }
11 public Node getFromNode() { return from; }
12 public Node getToNode() {return to; }
13 public String getFromNodeName() { return from.name; }
14 public String getToNodeName() { return to.name; }
15
16 public Edge(Node u, Node v, String stringID) {
17 from = u;
18 to = v;
19 label = stringID;
20 }
21
22 public String toString() {
23 return label + "(\n\t" + from.name + ",\n\t" + to.name + ")";
24 }
25
26 public static int compareLabels(Edge[] list1, Edge[] list2) {
27 int result = list1.length - list2.length;
28 if (result != 0) return result;
29 for (int i = 0; i < list1.length; ++i) {
30 if ((result = list1[i].label.compareTo(list2[i].label)) != 0)
31 return result;
32 }
33 return 0;
34 }
35
36 public Node getDestinationNode(boolean isOutGoingEdges) {
37 return isOutGoingEdges ? to : from;
38 }
39
40}
41
42class EdgeComparatorByNodeName implements Comparator<Edge> {
43
44 @Override
45 public int compare(Edge o1, Edge o2) {
46 int result = o1.label.compareTo(o2.label);
47 if (result != 0) return result;
48 result = o1.from.name.compareTo(o2.from.name);
49 if (result != 0) return result;
50 return o1.to.name.compareTo(o2.to.name);
51 }
52}
53
54class EdgeComparatorByNodeLabel implements Comparator<Edge> {
55
56 @Override
57 public int compare(Edge o1, Edge o2) {
58 int result = o1.label.compareTo(o2.label);
59 if (result != 0) return result;
60 result = o1.from.getLabel().compareTo(o2.from.getLabel());
61 if (result != 0) return result;
62 result = o1.to.getLabel().compareTo(o2.to.getLabel());
63 if (result != 0) return result;
64 result = o1.from.getName().compareTo(o2.from.getName());
65 if (result != 0) return result;
66 result = o1.to.getName().compareTo(o2.to.getName());
67 return result;
68 }
69}
70
diff --git a/src/uk/ac/ox/cs/pagoda/summary/EstimatedFeatureComparator.java b/src/uk/ac/ox/cs/pagoda/summary/EstimatedFeatureComparator.java
new file mode 100644
index 0000000..59fdf7f
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/EstimatedFeatureComparator.java
@@ -0,0 +1,53 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.util.Comparator;
4import java.util.HashMap;
5import java.util.HashSet;
6import java.util.Map;
7
8public class EstimatedFeatureComparator implements Comparator<Node> {
9
10 Graph graph;
11 Map<Node, EstimatedFeature> node2features = new HashMap<Node, EstimatedFeature>();
12
13 public EstimatedFeatureComparator(Graph graph) {
14 this.graph = graph;
15 EstimatedFeature feature;
16 for (Node node: graph.getNodes()) {
17 feature = new EstimatedFeature(graph, node);
18 node2features.put(node, feature);
19 }
20 }
21
22 @Override
23 public int compare(Node o1, Node o2) {
24 EstimatedFeature f1 = node2features.get(o1), f2 = node2features.get(o2);
25 int result;
26 if ((result = o1.getLabel().compareTo(o2.getLabel())) != 0) return result;
27 if ((result = f1.outGoingNodeCount - f2.outGoingNodeCount) != 0) return result;
28 if ((result = f1.inComingNodeCount - f2.inComingNodeCount) != 0) return result;
29 if ((result = Edge.compareLabels(graph.getOutGoingEdges(o1), graph.getOutGoingEdges(o2))) != 0) return result;
30 result = Edge.compareLabels(graph.getInComingEdges(o1), graph.getInComingEdges(o2));
31 return result;
32 }
33
34}
35
36class EstimatedFeature {
37
38 int outGoingNodeCount, inComingNodeCount;
39
40 public EstimatedFeature(Graph graph, Node node) {
41 HashSet<String> neighbours = new HashSet<String>();
42 for (Edge edge: graph.getOutGoingEdges(node))
43 neighbours.add(edge.getToNodeName());
44 outGoingNodeCount = neighbours.size();
45
46 neighbours.clear();
47 for (Edge edge: graph.getInComingEdges(node))
48 neighbours.add(edge.getFromNodeName());
49 inComingNodeCount = neighbours.size();
50 }
51}
52
53
diff --git a/src/uk/ac/ox/cs/pagoda/summary/Graph.java b/src/uk/ac/ox/cs/pagoda/summary/Graph.java
new file mode 100644
index 0000000..cfa94a4
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/Graph.java
@@ -0,0 +1,154 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.util.Arrays;
4import java.util.Collection;
5import java.util.Comparator;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.LinkedList;
9import java.util.Map;
10import java.util.Set;
11
12import org.semanticweb.HermiT.model.Constant;
13import org.semanticweb.HermiT.model.Individual;
14import org.semanticweb.HermiT.model.Term;
15import org.semanticweb.owlapi.model.OWLAxiom;
16import org.semanticweb.owlapi.model.OWLClass;
17import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
18import org.semanticweb.owlapi.model.OWLObjectProperty;
19import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
20import org.semanticweb.owlapi.model.OWLOntology;
21
22import uk.ac.ox.cs.JRDFox.model.GroundTerm;
23import uk.ac.ox.cs.JRDFox.model.Literal;
24import uk.ac.ox.cs.pagoda.query.AnswerTuple;
25
26public class Graph {
27
28 Set<Node> nodes = new HashSet<Node>();
29 Map<Node, Edge[]> sortedOutGoingEdges = new HashMap<Node, Edge[]>();
30 Map<Node, Edge[]> sortedInComingEdges = new HashMap<Node, Edge[]>();
31
32 public Graph(OWLOntology ontology) {
33 Map<Node, Collection<Edge>> outGoingEdges = new HashMap<Node, Collection<Edge>>();
34 Map<Node, Collection<Edge>> inComingEdges = new HashMap<Node, Collection<Edge>>();
35
36 for (OWLAxiom axiom: ontology.getABoxAxioms(true))
37 if (axiom instanceof OWLClassAssertionAxiom)
38 addClassAssertion((OWLClassAssertionAxiom) axiom);
39 else if (axiom instanceof OWLObjectPropertyAssertionAxiom)
40 addPropertyAssertion((OWLObjectPropertyAssertionAxiom) axiom, inComingEdges, outGoingEdges);
41
42 for (Node node: nodes) {
43 sortedOutGoingEdges.put(node, sort(outGoingEdges.get(node)));
44 sortedInComingEdges.put(node, sort(inComingEdges.get(node)));
45 }
46
47 outGoingEdges.clear();
48 inComingEdges.clear();
49 }
50
51 public Collection<Node> getNodes() { return nodes; }
52
53 private void addPropertyAssertion(OWLObjectPropertyAssertionAxiom axiom,
54 Map<Node, Collection<Edge>> inComingEdges, Map<Node, Collection<Edge>> outGoingEdges) {
55
56 Node u = getNode(axiom.getSubject().toStringID()), v = getNode(axiom.getObject().toStringID());
57
58 nodes.add(u);
59 nodes.add(v);
60
61 Edge e = new Edge(u, v, ((OWLObjectProperty) axiom.getProperty()).toStringID());
62
63 Collection<Edge> edges = outGoingEdges.get(u);
64 if (edges == null) {
65 edges = new LinkedList<Edge>();
66 outGoingEdges.put(u, edges);
67 }
68 edges.add(e);
69
70 edges = inComingEdges.get(v);
71 if (edges == null) {
72 edges = new LinkedList<Edge>();
73 inComingEdges.put(v, edges);
74 }
75 edges.add(e);
76 }
77
78 private void addClassAssertion(OWLClassAssertionAxiom axiom) {
79 OWLClass cls = (OWLClass) axiom.getClassExpression();
80 Node u;
81// if (cls.getIRI().toString().startsWith(HermitSummaryFilter.QueryAnswerTermPrefix))
82// u = getNode(axiom.getIndividual().toStringID(), false);
83// else
84 u = getNode(axiom.getIndividual().toStringID());
85
86 if (u == null) return ;
87 u.addConcept(cls.toStringID());
88 nodes.add(u);
89 }
90
91 public Edge[] getOutGoingEdges(Node u) {
92 return sortedOutGoingEdges.get(u);
93 }
94
95 public Edge[] getInComingEdges(Node u) {
96 return sortedInComingEdges.get(u);
97 }
98
99 Comparator<Edge> edgeComp = new EdgeComparatorByNodeLabel();
100
101 public Edge[] sort(Collection<Edge> edges) {
102 if (edges == null) return new Edge[0];
103 Edge[] sortedEdges = new Edge[edges.size()];
104 edges.toArray(sortedEdges);
105 Arrays.sort(sortedEdges, edgeComp);
106 return sortedEdges;
107 }
108
109
110 private Comparator<Node> coarseNodeComparator = null;
111
112 public Comparator<Node> getCoarseNodeComparator() {
113 if (coarseNodeComparator == null)
114 coarseNodeComparator = new EstimatedFeatureComparator(this);
115 return coarseNodeComparator;
116 }
117
118 Map<String, Node> allNodes = new HashMap<String, Node>();
119
120 private Node getNode(String nodeName) {
121 Node node = null;
122 if ((node = allNodes.get(nodeName)) == null) {
123 node = new Node(nodeName);
124 allNodes.put(nodeName, node);
125 }
126 return node;
127 }
128
129 private Node getNode(GroundTerm t) {
130 if (t instanceof uk.ac.ox.cs.JRDFox.model.Individual)
131 return getNode(((uk.ac.ox.cs.JRDFox.model.Individual) t).getIRI());
132 else {
133 Literal l = (Literal) t;
134 return getNode(l.getLexicalForm() + "^^" + l.getDatatype().getIRI());
135 }
136 }
137
138 public Node getNode(Term t) {
139 if (t instanceof Individual)
140 return getNode(((Individual) t).getIRI());
141 else if (t instanceof Constant)
142 return getNode(((Constant) t).getLexicalForm() + "^^" + ((Constant) t).getDatatypeURI());
143 return null;
144 }
145
146 public NodeTuple getNodeTuple(AnswerTuple tuple) {
147 NodeTuple ret = new NodeTuple(tuple);
148 for (int i = 0; i < tuple.getArity(); ++i)
149 ret.addNode(getNode(tuple.getGroundTerm(i)));
150 return ret;
151 }
152
153}
154
diff --git a/src/uk/ac/ox/cs/pagoda/summary/HermitSummaryFilter.java b/src/uk/ac/ox/cs/pagoda/summary/HermitSummaryFilter.java
new file mode 100644
index 0000000..a57d188
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/HermitSummaryFilter.java
@@ -0,0 +1,202 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.util.HashSet;
4import java.util.Set;
5
6import org.semanticweb.owlapi.model.IRI;
7import org.semanticweb.owlapi.model.OWLAxiom;
8import org.semanticweb.owlapi.model.OWLClass;
9import org.semanticweb.owlapi.model.OWLDataFactory;
10import org.semanticweb.owlapi.model.OWLOntology;
11import org.semanticweb.owlapi.model.OWLOntologyCreationException;
12import org.semanticweb.owlapi.model.OWLOntologyManager;
13
14import uk.ac.ox.cs.JRDFox.model.Individual;
15import uk.ac.ox.cs.pagoda.endomorph.Endomorph;
16import uk.ac.ox.cs.pagoda.owl.OWLHelper;
17import uk.ac.ox.cs.pagoda.query.AnswerTuple;
18import uk.ac.ox.cs.pagoda.query.AnswerTuples;
19import uk.ac.ox.cs.pagoda.query.AnswerTuplesImp;
20import uk.ac.ox.cs.pagoda.query.QueryRecord;
21import uk.ac.ox.cs.pagoda.query.QueryRecord.Step;
22import uk.ac.ox.cs.pagoda.reasoner.full.Checker;
23import uk.ac.ox.cs.pagoda.reasoner.full.HermitChecker;
24import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoder;
25import uk.ac.ox.cs.pagoda.util.Timer;
26import uk.ac.ox.cs.pagoda.util.Utility;
27
28public class HermitSummaryFilter implements Checker {
29
30 QueryRecord m_record;
31 Summary summary = null;
32 HermitChecker summarisedHermiT = null;
33 boolean summarisedConsistency;
34
35 Endomorph endomorphismChecker = null;
36
37 public HermitSummaryFilter(QueryRecord record) {
38 m_record = record;
39 HermitChecker hermitChecker = new HermitChecker(record.getRelevantOntology(), record);
40 endomorphismChecker = new Endomorph(record, hermitChecker);
41 hermitChecker.setDependencyGraph(endomorphismChecker.getDependencyGraph());
42 }
43
44 @Override
45 public boolean isConsistent() {
46 if (summary == null)
47 summary = new Summary(endomorphismChecker.getOntology(), endomorphismChecker.getGraph());
48
49 if (summarisedHermiT == null)
50 initialiseSummarisedReasoner();
51
52 if (summarisedConsistency) return true;
53 return endomorphismChecker.isConsistent();
54 }
55
56 private void initialiseSummarisedReasoner() {
57 Timer t = new Timer();
58 summarisedHermiT = new HermitChecker(summary.getSummary(), summary.getSummary(m_record));
59// summary.save("summarised_query" + m_record.getQueryID() + ".owl");
60 if (summarisedConsistency = summarisedHermiT.isConsistent())
61 Utility.logDebug("The summary of ABox is consistent with the TBox.");
62 else
63 Utility.logDebug("The summary of ABox is NOT consistent with the TBox.");
64 m_record.addProcessingTime(Step.Summarisation, t.duration());
65 }
66
67 @Override
68 public int check(AnswerTuples answers) {
69 Timer t = new Timer();
70 OWLOntology newOntology = addOntologyWithQueryPreciate(endomorphismChecker.getOntology(), m_record, answers);
71 summary = new Summary(newOntology);
72 initialiseSummarisedReasoner();
73
74 if (summarisedConsistency) {
75 Set<AnswerTuple> passed = new HashSet<AnswerTuple>(), succ = new HashSet<AnswerTuple>();
76 Set<AnswerTuple> falsified = new HashSet<AnswerTuple>(), fail = new HashSet<AnswerTuple>();
77
78 int counter = 0;
79 AnswerTuple representative;
80 for (AnswerTuple answer; answers.isValid(); answers.moveNext()) {
81 ++counter;
82 answer = answers.getTuple();
83 representative = summary.getSummary(answer);
84 if (fail.contains(representative))
85 falsified.add(answer);
86 else if (succ.contains(representative))
87 passed.add(answer);
88 else
89 if (summarisedHermiT.check(representative)) {
90 succ.add(representative);
91 passed.add(answer);
92 }
93 else {
94 fail.add(representative);
95 falsified.add(answer);
96 }
97 }
98 answers.dispose();
99
100 Utility.logDebug("@TIME to filter out non-answers by summarisation: " + t.duration());
101
102 m_record.removeUpperBoundAnswers(falsified);
103
104 if (m_record.processed()) {
105 m_record.setDifficulty(Step.Summarisation);
106 m_record.addProcessingTime(Step.Summarisation, t.duration());
107 return 0;
108 }
109
110 Utility.logDebug("The number of answers to be checked with HermiT: " + passed.size() + "/" + counter);
111
112 m_record.setDifficulty(Step.FullReasoning);
113 m_record.addProcessingTime(Step.Summarisation, t.duration());
114
115 return endomorphismChecker.check(new AnswerTuplesImp(m_record.getAnswerVariables(), passed));
116 }
117 else {
118 m_record.addProcessingTime(Step.Summarisation, t.duration());
119// m_record.saveRelevantOntology("fragment.owl");
120 m_record.setDifficulty(Step.FullReasoning);
121 return endomorphismChecker.check(answers);
122 }
123 }
124
125 public static final String QueryAnswerTermPrefix = TrackingRuleEncoder.QueryPredicate + "_term";
126
127 public static OWLOntology addOntologyWithQueryPreciate(OWLOntology ontology, QueryRecord record, AnswerTuples answers) {
128 OWLOntology newOntology = null;
129 OWLOntologyManager manager = ontology.getOWLOntologyManager();
130 OWLDataFactory factory = manager.getOWLDataFactory();
131 try {
132 newOntology = manager.createOntology();
133 manager.addAxioms(newOntology, ontology.getAxioms());
134
135 OWLClass[] queryClass = new OWLClass[answers.getArity()];
136 int arity = answers.getArity();
137 for (int i = 0; i < arity; ++i)
138 queryClass[i] = factory.getOWLClass(IRI.create(QueryAnswerTermPrefix + i));
139 AnswerTuple answer;
140 for (; answers.isValid(); answers.moveNext()) {
141 answer = answers.getTuple();
142 for (int i = 0; i < arity; ++i)
143 if (answer.getGroundTerm(i) instanceof Individual) {
144 String iri = ((Individual) answer.getGroundTerm(i)).getIRI();
145 if (!record.isPredicate(answer, i)) {
146 manager.addAxiom(newOntology,
147 factory.getOWLClassAssertionAxiom(
148 queryClass[i],
149 factory.getOWLNamedIndividual(IRI.create(iri))));
150 }
151 }
152 }
153 answers.reset();
154 } catch (OWLOntologyCreationException e) {
155 e.printStackTrace();
156 }
157
158 return newOntology;
159 }
160
161 public static void printRelatedABoxAxioms(OWLOntology onto, String str) {
162 if (!str.startsWith("<")) str = OWLHelper.addAngles(str);
163
164 System.out.println("Axioms in " + onto.getOntologyID().getOntologyIRI() + " related to " + str);
165
166 for (OWLAxiom axiom: onto.getABoxAxioms(true))
167 if (axiom.toString().contains(str))
168 System.out.println(axiom);
169
170 System.out.println("-----------------------------");
171 }
172
173 public static void printRelatedTBoxAxioms(OWLOntology onto, String str) {
174
175 System.out.println("Axioms in " + onto.getOntologyID().getOntologyIRI() + " related to " + str);
176
177 for (OWLAxiom axiom: onto.getTBoxAxioms(true))
178 if (axiom.toString().contains(str))
179 System.out.println(axiom);
180
181 for (OWLAxiom axiom: onto.getRBoxAxioms(true))
182 if (axiom.toString().contains(str))
183 System.out.println(axiom);
184
185 System.out.println("-----------------------------");
186 }
187
188 @Override
189 public boolean check(AnswerTuple answer) {
190 AnswerTuple representative = summary.getSummary(answer);
191 if (summarisedHermiT.isConsistent() && !summarisedHermiT.check(representative))
192 return false;
193 return endomorphismChecker.check(answer);
194 }
195
196 @Override
197 public void dispose() {
198 if (summarisedHermiT != null) summarisedHermiT.dispose();
199 endomorphismChecker.dispose();
200 }
201
202}
diff --git a/src/uk/ac/ox/cs/pagoda/summary/Node.java b/src/uk/ac/ox/cs/pagoda/summary/Node.java
new file mode 100644
index 0000000..6fca4bb
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/Node.java
@@ -0,0 +1,65 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.util.Collection;
4import java.util.Iterator;
5import java.util.TreeSet;
6
7public class Node {
8
9 String name;
10 Collection<String> concepts = new TreeSet<String>();
11 private String label;
12
13 public Node(String nodeName) {
14 name = nodeName;
15 }
16
17 public String getName() { return name; }
18
19 public void addConcept(String className) {
20 concepts.add(className);
21 label = null;
22 }
23
24 public String getLabel() {
25 if (label == null) {
26 StringBuilder sb = null;
27 for (Iterator<String> it = concepts.iterator(); it.hasNext(); ) {
28 if (sb == null) sb = new StringBuilder();
29 else sb.append("^");
30 sb.append(it.next());
31 }
32 label = sb == null ? "" : sb.toString();
33 }
34 return label;
35 }
36
37 //TODO to be removed (just used for debug) ...
38 String simplifiedLabel = null;
39
40 public String toString() {
41 if (simplifiedLabel == null)
42 simplifiedLabel = getLabel();
43 return name + "@" + simplifiedLabel;
44 }
45
46 public boolean isSubConceptOf(Node v) {
47 String s, t = "";
48 for (Iterator<String> uIter = concepts.iterator(), vIter = v.concepts.iterator(); uIter.hasNext(); ) {
49 s = uIter.next();
50 if (!vIter.hasNext()) return false;
51 while (vIter.hasNext() && !s.equals(t = vIter.next()));
52 if (!s.equals(t)) return false;
53 }
54 return true;
55 }
56
57 public Collection<String> getConcepts() {
58 return concepts;
59 }
60
61}
62
63
64
65
diff --git a/src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java b/src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java
new file mode 100644
index 0000000..bf8d55a
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java
@@ -0,0 +1,39 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.util.Collection;
4import java.util.LinkedList;
5
6import uk.ac.ox.cs.pagoda.query.AnswerTuple;
7
8public class NodeTuple {
9
10 AnswerTuple m_tuple;
11 Collection<Node> nodes = new LinkedList<Node>();
12
13 public NodeTuple(AnswerTuple tuple) {
14 m_tuple = tuple;
15 }
16
17 void addNode(Node node) {
18 nodes.add(node);
19 }
20
21 public Collection<Node> getNodes() {
22 return nodes;
23 }
24
25 public AnswerTuple getAnswerTuple() {
26 return m_tuple;
27 }
28
29
30 public String toString() {
31 StringBuilder sb = new StringBuilder("(");
32 for (Node node: nodes) {
33 if (sb.length() > 1) sb.append(", ");
34 sb.append(node.toString());
35 }
36 sb.append(")");
37 return sb.toString();
38 }
39}
diff --git a/src/uk/ac/ox/cs/pagoda/summary/Summary.java b/src/uk/ac/ox/cs/pagoda/summary/Summary.java
new file mode 100644
index 0000000..264ff76
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/summary/Summary.java
@@ -0,0 +1,215 @@
1package uk.ac.ox.cs.pagoda.summary;
2
3import java.io.File;
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.LinkedList;
7import java.util.Map;
8
9import org.semanticweb.HermiT.model.Atom;
10import org.semanticweb.HermiT.model.DLClause;
11import org.semanticweb.HermiT.model.Individual;
12import org.semanticweb.HermiT.model.Term;
13import org.semanticweb.owlapi.model.IRI;
14import org.semanticweb.owlapi.model.OWLAxiom;
15import org.semanticweb.owlapi.model.OWLClassAssertionAxiom;
16import org.semanticweb.owlapi.model.OWLDataFactory;
17import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
18import org.semanticweb.owlapi.model.OWLLiteral;
19import org.semanticweb.owlapi.model.OWLNamedIndividual;
20import org.semanticweb.owlapi.model.OWLObjectProperty;
21import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
22import org.semanticweb.owlapi.model.OWLOntology;
23import org.semanticweb.owlapi.model.OWLOntologyCreationException;
24import org.semanticweb.owlapi.model.OWLOntologyManager;
25import org.semanticweb.owlapi.model.OWLOntologyStorageException;
26
27import uk.ac.ox.cs.JRDFox.model.GroundTerm;
28import uk.ac.ox.cs.JRDFox.model.Literal;
29import uk.ac.ox.cs.pagoda.owl.OWLHelper;
30import uk.ac.ox.cs.pagoda.query.AnswerTuple;
31import uk.ac.ox.cs.pagoda.query.QueryRecord;
32import uk.ac.ox.cs.pagoda.util.Namespace;
33import uk.ac.ox.cs.pagoda.util.SparqlHelper;
34import uk.ac.ox.cs.pagoda.util.Utility;
35
36public class Summary {
37
38 OWLOntologyManager manager;
39 OWLDataFactory factory;
40 OWLOntology ontology, summarisedOntology;
41 Graph graph;
42
43 public Summary(OWLOntology ontology) {
44 OWLHelper.identifyAndChangeAnnotationAssertions(ontology);
45 this.ontology = ontology;
46 graph = new Graph(ontology);
47 factory = (manager = ontology.getOWLOntologyManager()).getOWLDataFactory();
48 }
49
50 public Summary(OWLOntology ontology, Graph graph) {
51 this.ontology = ontology;
52 this.graph = graph;
53 factory = (manager = ontology.getOWLOntologyManager()).getOWLDataFactory();
54 }
55
56 Map<String, String> label2representative = new HashMap<String, String>();
57 Map<String, String> representatives = new HashMap<String, String>();
58
59 public Collection<String> getRepresentatives() {
60 return representatives.values();
61 }
62
63 Map<String, LinkedList<String>> groups = null;
64
65 public Collection<String> getGroup(String representative) {
66 if (groups == null) {
67 groups = new HashMap<String, LinkedList<String>>();
68 LinkedList<String> group;
69 for (Map.Entry<String, String> entry: representatives.entrySet()) {
70 if ((group = groups.get(entry.getValue())) == null)
71 group = new LinkedList<String>();
72 group.add(entry.getKey());
73 }
74 }
75 return groups.get(representative);
76 }
77
78 private void process(OWLOntology ontology, OWLOntology abstractOntology) {
79 OWLOntologyManager manager = ontology.getOWLOntologyManager();
80 groupIndividualsByConcepts();
81
82 manager.addAxioms(abstractOntology, ontology.getRBoxAxioms(true));
83 manager.addAxioms(abstractOntology, ontology.getTBoxAxioms(true));
84
85 OWLAxiom newAxiom;
86 for (OWLAxiom axiom: ontology.getABoxAxioms(true)) {
87 newAxiom = summeriseAxiom(axiom);
88 manager.addAxiom(abstractOntology, newAxiom);
89 }
90
91 OWLObjectProperty sameAs = factory.getOWLObjectProperty(IRI.create(Namespace.EQUALITY));
92 for (Map.Entry<String, String> entry: representatives.entrySet())
93 if (!entry.getKey().equals(entry.getValue()))
94 manager.addAxiom(abstractOntology,
95 factory.getOWLObjectPropertyAssertionAxiom(
96 sameAs,
97 factory.getOWLNamedIndividual(IRI.create(entry.getKey())),
98 factory.getOWLNamedIndividual(IRI.create(entry.getValue()))));
99 }
100
101 private void groupIndividualsByConcepts() {
102 String name, label, representative;
103 Utility.logDebug("grouping individuals by its concepts");
104
105 for (Node node: graph.getNodes()) {
106 name = node.getName();
107 label = node.getLabel();
108
109 if ((representative = label2representative.get(label)) == null) {
110 representative = name;
111 label2representative.put(label, name);
112 }
113
114 representatives.put(name, representative);
115 }
116 }
117
118 private OWLAxiom summeriseAxiom(OWLAxiom axiom) {
119 if (axiom instanceof OWLClassAssertionAxiom) {
120 OWLClassAssertionAxiom assertion = (OWLClassAssertionAxiom) axiom;
121 OWLNamedIndividual a = getRepresentativeIndividual(assertion.getIndividual().toStringID());
122 return factory.getOWLClassAssertionAxiom(assertion.getClassExpression(), a);
123 }
124 else if (axiom instanceof OWLObjectPropertyAssertionAxiom) {
125 OWLObjectPropertyAssertionAxiom assertion = (OWLObjectPropertyAssertionAxiom) axiom;
126 OWLNamedIndividual a = getRepresentativeIndividual(assertion.getSubject().toStringID());
127 OWLNamedIndividual b = getRepresentativeIndividual(assertion.getObject().toStringID());
128 return factory.getOWLObjectPropertyAssertionAxiom(assertion.getProperty(), a, b);
129 }
130 else if (axiom instanceof OWLDataPropertyAssertionAxiom) {
131 OWLDataPropertyAssertionAxiom assertion = (OWLDataPropertyAssertionAxiom) axiom;
132 OWLNamedIndividual a = getRepresentativeIndividual(assertion.getSubject().toStringID());
133 OWLLiteral b = assertion.getObject();
134 return factory.getOWLDataPropertyAssertionAxiom(assertion.getProperty(), a, b);
135
136 }
137 else {
138 Utility.logError("Unknown axiom: " + axiom);
139 return null;
140 }
141 }
142
143 public OWLNamedIndividual getRepresentativeIndividual(String name) {
144 return factory.getOWLNamedIndividual(IRI.create(getRepresentativeName(name)));
145 }
146
147 public String getRepresentativeName(String name) {
148 String rep = representatives.get(name);
149 if (rep == null) return name;
150 return rep;
151 }
152
153 public OWLOntology getSummary() {
154 if (summarisedOntology == null) {
155 try {
156 summarisedOntology = ontology.getOWLOntologyManager().createOntology();
157 } catch (OWLOntologyCreationException e) {
158 summarisedOntology = null;
159 e.printStackTrace();
160 }
161 process(ontology, summarisedOntology);
162 }
163 return summarisedOntology;
164 }
165
166 public void save(String fileName) {
167 try {
168 manager.saveOntology(summarisedOntology, IRI.create(new File(fileName)));
169 } catch (OWLOntologyStorageException e) {
170 e.printStackTrace();
171 }
172 }
173
174 private GroundTerm getSummary(GroundTerm t) {
175 if (t instanceof Literal) return t;
176 return uk.ac.ox.cs.JRDFox.model.Individual.create(getSummary(((uk.ac.ox.cs.JRDFox.model.Individual) t).getIRI()));
177 }
178
179 public String getSummary(QueryRecord record) {
180 DLClause queryClause = getSummary(record.getClause());
181 return SparqlHelper.getSPARQLQuery(queryClause.getBodyAtoms(), record.getAnswerVariables());
182 }
183
184 public DLClause getSummary(DLClause clause) {
185 Atom[] newHeadAtoms = new Atom[clause.getHeadLength()], newBodyAtoms = new Atom[clause.getBodyLength()];
186 int index = 0;
187 for (Atom atom: clause.getHeadAtoms())
188 newHeadAtoms[index++] = getSummary(atom);
189 for (Atom atom: clause.getBodyAtoms())
190 newBodyAtoms[index++] = getSummary(atom);
191
192 return DLClause.create(newHeadAtoms, newBodyAtoms);
193 }
194
195 public Atom getSummary(Atom atom) {
196 Term[] args = new Term [atom.getArity()];
197 for (int i = 0; i < atom.getArity(); ++i)
198 if ((args[i] = atom.getArgument(i)) instanceof Individual)
199 args[i] = Individual.create(getSummary(atom.getArgument(i).toString()));
200 return Atom.create(atom.getDLPredicate(), args);
201 }
202
203 public String getSummary(String name) {
204 return getRepresentativeName(OWLHelper.removeAngles(name));
205 }
206
207 public AnswerTuple getSummary(AnswerTuple answer) {
208 int arity = answer.getArity();
209 GroundTerm[] t = new GroundTerm[arity];
210 for (int i = 0; i < arity; ++i)
211 t[i] = getSummary(answer.getGroundTerm(i));
212 return new AnswerTuple(t);
213 }
214
215}