diff options
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/summary')
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/Edge.java | 70 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/EstimatedFeatureComparator.java | 53 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/Graph.java | 154 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/HermitSummaryFilter.java | 202 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/Node.java | 65 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java | 39 | ||||
| -rw-r--r-- | src/uk/ac/ox/cs/pagoda/summary/Summary.java | 215 |
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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.util.Comparator; | ||
| 4 | |||
| 5 | public 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 | |||
| 42 | class 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 | |||
| 54 | class 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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.util.Comparator; | ||
| 4 | import java.util.HashMap; | ||
| 5 | import java.util.HashSet; | ||
| 6 | import java.util.Map; | ||
| 7 | |||
| 8 | public 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 | |||
| 36 | class 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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.util.Arrays; | ||
| 4 | import java.util.Collection; | ||
| 5 | import java.util.Comparator; | ||
| 6 | import java.util.HashMap; | ||
| 7 | import java.util.HashSet; | ||
| 8 | import java.util.LinkedList; | ||
| 9 | import java.util.Map; | ||
| 10 | import java.util.Set; | ||
| 11 | |||
| 12 | import org.semanticweb.HermiT.model.Constant; | ||
| 13 | import org.semanticweb.HermiT.model.Individual; | ||
| 14 | import org.semanticweb.HermiT.model.Term; | ||
| 15 | import org.semanticweb.owlapi.model.OWLAxiom; | ||
| 16 | import org.semanticweb.owlapi.model.OWLClass; | ||
| 17 | import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; | ||
| 18 | import org.semanticweb.owlapi.model.OWLObjectProperty; | ||
| 19 | import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; | ||
| 20 | import org.semanticweb.owlapi.model.OWLOntology; | ||
| 21 | |||
| 22 | import uk.ac.ox.cs.JRDFox.model.GroundTerm; | ||
| 23 | import uk.ac.ox.cs.JRDFox.model.Literal; | ||
| 24 | import uk.ac.ox.cs.pagoda.query.AnswerTuple; | ||
| 25 | |||
| 26 | public 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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.util.HashSet; | ||
| 4 | import java.util.Set; | ||
| 5 | |||
| 6 | import org.semanticweb.owlapi.model.IRI; | ||
| 7 | import org.semanticweb.owlapi.model.OWLAxiom; | ||
| 8 | import org.semanticweb.owlapi.model.OWLClass; | ||
| 9 | import org.semanticweb.owlapi.model.OWLDataFactory; | ||
| 10 | import org.semanticweb.owlapi.model.OWLOntology; | ||
| 11 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; | ||
| 12 | import org.semanticweb.owlapi.model.OWLOntologyManager; | ||
| 13 | |||
| 14 | import uk.ac.ox.cs.JRDFox.model.Individual; | ||
| 15 | import uk.ac.ox.cs.pagoda.endomorph.Endomorph; | ||
| 16 | import uk.ac.ox.cs.pagoda.owl.OWLHelper; | ||
| 17 | import uk.ac.ox.cs.pagoda.query.AnswerTuple; | ||
| 18 | import uk.ac.ox.cs.pagoda.query.AnswerTuples; | ||
| 19 | import uk.ac.ox.cs.pagoda.query.AnswerTuplesImp; | ||
| 20 | import uk.ac.ox.cs.pagoda.query.QueryRecord; | ||
| 21 | import uk.ac.ox.cs.pagoda.query.QueryRecord.Step; | ||
| 22 | import uk.ac.ox.cs.pagoda.reasoner.full.Checker; | ||
| 23 | import uk.ac.ox.cs.pagoda.reasoner.full.HermitChecker; | ||
| 24 | import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoder; | ||
| 25 | import uk.ac.ox.cs.pagoda.util.Timer; | ||
| 26 | import uk.ac.ox.cs.pagoda.util.Utility; | ||
| 27 | |||
| 28 | public 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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.util.Collection; | ||
| 4 | import java.util.Iterator; | ||
| 5 | import java.util.TreeSet; | ||
| 6 | |||
| 7 | public 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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.util.Collection; | ||
| 4 | import java.util.LinkedList; | ||
| 5 | |||
| 6 | import uk.ac.ox.cs.pagoda.query.AnswerTuple; | ||
| 7 | |||
| 8 | public 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 @@ | |||
| 1 | package uk.ac.ox.cs.pagoda.summary; | ||
| 2 | |||
| 3 | import java.io.File; | ||
| 4 | import java.util.Collection; | ||
| 5 | import java.util.HashMap; | ||
| 6 | import java.util.LinkedList; | ||
| 7 | import java.util.Map; | ||
| 8 | |||
| 9 | import org.semanticweb.HermiT.model.Atom; | ||
| 10 | import org.semanticweb.HermiT.model.DLClause; | ||
| 11 | import org.semanticweb.HermiT.model.Individual; | ||
| 12 | import org.semanticweb.HermiT.model.Term; | ||
| 13 | import org.semanticweb.owlapi.model.IRI; | ||
| 14 | import org.semanticweb.owlapi.model.OWLAxiom; | ||
| 15 | import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; | ||
| 16 | import org.semanticweb.owlapi.model.OWLDataFactory; | ||
| 17 | import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; | ||
| 18 | import org.semanticweb.owlapi.model.OWLLiteral; | ||
| 19 | import org.semanticweb.owlapi.model.OWLNamedIndividual; | ||
| 20 | import org.semanticweb.owlapi.model.OWLObjectProperty; | ||
| 21 | import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; | ||
| 22 | import org.semanticweb.owlapi.model.OWLOntology; | ||
| 23 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; | ||
| 24 | import org.semanticweb.owlapi.model.OWLOntologyManager; | ||
| 25 | import org.semanticweb.owlapi.model.OWLOntologyStorageException; | ||
| 26 | |||
| 27 | import uk.ac.ox.cs.JRDFox.model.GroundTerm; | ||
| 28 | import uk.ac.ox.cs.JRDFox.model.Literal; | ||
| 29 | import uk.ac.ox.cs.pagoda.owl.OWLHelper; | ||
| 30 | import uk.ac.ox.cs.pagoda.query.AnswerTuple; | ||
| 31 | import uk.ac.ox.cs.pagoda.query.QueryRecord; | ||
| 32 | import uk.ac.ox.cs.pagoda.util.Namespace; | ||
| 33 | import uk.ac.ox.cs.pagoda.util.SparqlHelper; | ||
| 34 | import uk.ac.ox.cs.pagoda.util.Utility; | ||
| 35 | |||
| 36 | public 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 | } | ||
