From 9ce65c5a963b03ee97fe9cb6c5aa65a3c04a80a8 Mon Sep 17 00:00:00 2001 From: yzhou Date: Tue, 21 Apr 2015 10:34:27 +0100 Subject: initial version --- src/uk/ac/ox/cs/pagoda/summary/Edge.java | 70 +++++++ .../pagoda/summary/EstimatedFeatureComparator.java | 53 +++++ src/uk/ac/ox/cs/pagoda/summary/Graph.java | 154 +++++++++++++++ .../ox/cs/pagoda/summary/HermitSummaryFilter.java | 202 +++++++++++++++++++ src/uk/ac/ox/cs/pagoda/summary/Node.java | 65 +++++++ src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java | 39 ++++ src/uk/ac/ox/cs/pagoda/summary/Summary.java | 215 +++++++++++++++++++++ 7 files changed, 798 insertions(+) create mode 100644 src/uk/ac/ox/cs/pagoda/summary/Edge.java create mode 100644 src/uk/ac/ox/cs/pagoda/summary/EstimatedFeatureComparator.java create mode 100644 src/uk/ac/ox/cs/pagoda/summary/Graph.java create mode 100644 src/uk/ac/ox/cs/pagoda/summary/HermitSummaryFilter.java create mode 100644 src/uk/ac/ox/cs/pagoda/summary/Node.java create mode 100644 src/uk/ac/ox/cs/pagoda/summary/NodeTuple.java create mode 100644 src/uk/ac/ox/cs/pagoda/summary/Summary.java (limited to 'src/uk/ac/ox/cs/pagoda/summary') 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.util.Comparator; + +public class Edge { + + Node from, to; + String label; + + public String getLabel() { return label; } + public Node getFromNode() { return from; } + public Node getToNode() {return to; } + public String getFromNodeName() { return from.name; } + public String getToNodeName() { return to.name; } + + public Edge(Node u, Node v, String stringID) { + from = u; + to = v; + label = stringID; + } + + public String toString() { + return label + "(\n\t" + from.name + ",\n\t" + to.name + ")"; + } + + public static int compareLabels(Edge[] list1, Edge[] list2) { + int result = list1.length - list2.length; + if (result != 0) return result; + for (int i = 0; i < list1.length; ++i) { + if ((result = list1[i].label.compareTo(list2[i].label)) != 0) + return result; + } + return 0; + } + + public Node getDestinationNode(boolean isOutGoingEdges) { + return isOutGoingEdges ? to : from; + } + +} + +class EdgeComparatorByNodeName implements Comparator { + + @Override + public int compare(Edge o1, Edge o2) { + int result = o1.label.compareTo(o2.label); + if (result != 0) return result; + result = o1.from.name.compareTo(o2.from.name); + if (result != 0) return result; + return o1.to.name.compareTo(o2.to.name); + } +} + +class EdgeComparatorByNodeLabel implements Comparator { + + @Override + public int compare(Edge o1, Edge o2) { + int result = o1.label.compareTo(o2.label); + if (result != 0) return result; + result = o1.from.getLabel().compareTo(o2.from.getLabel()); + if (result != 0) return result; + result = o1.to.getLabel().compareTo(o2.to.getLabel()); + if (result != 0) return result; + result = o1.from.getName().compareTo(o2.from.getName()); + if (result != 0) return result; + result = o1.to.getName().compareTo(o2.to.getName()); + return result; + } +} + 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +public class EstimatedFeatureComparator implements Comparator { + + Graph graph; + Map node2features = new HashMap(); + + public EstimatedFeatureComparator(Graph graph) { + this.graph = graph; + EstimatedFeature feature; + for (Node node: graph.getNodes()) { + feature = new EstimatedFeature(graph, node); + node2features.put(node, feature); + } + } + + @Override + public int compare(Node o1, Node o2) { + EstimatedFeature f1 = node2features.get(o1), f2 = node2features.get(o2); + int result; + if ((result = o1.getLabel().compareTo(o2.getLabel())) != 0) return result; + if ((result = f1.outGoingNodeCount - f2.outGoingNodeCount) != 0) return result; + if ((result = f1.inComingNodeCount - f2.inComingNodeCount) != 0) return result; + if ((result = Edge.compareLabels(graph.getOutGoingEdges(o1), graph.getOutGoingEdges(o2))) != 0) return result; + result = Edge.compareLabels(graph.getInComingEdges(o1), graph.getInComingEdges(o2)); + return result; + } + +} + +class EstimatedFeature { + + int outGoingNodeCount, inComingNodeCount; + + public EstimatedFeature(Graph graph, Node node) { + HashSet neighbours = new HashSet(); + for (Edge edge: graph.getOutGoingEdges(node)) + neighbours.add(edge.getToNodeName()); + outGoingNodeCount = neighbours.size(); + + neighbours.clear(); + for (Edge edge: graph.getInComingEdges(node)) + neighbours.add(edge.getFromNodeName()); + inComingNodeCount = neighbours.size(); + } +} + + 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import org.semanticweb.HermiT.model.Constant; +import org.semanticweb.HermiT.model.Individual; +import org.semanticweb.HermiT.model.Term; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLOntology; + +import uk.ac.ox.cs.JRDFox.model.GroundTerm; +import uk.ac.ox.cs.JRDFox.model.Literal; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; + +public class Graph { + + Set nodes = new HashSet(); + Map sortedOutGoingEdges = new HashMap(); + Map sortedInComingEdges = new HashMap(); + + public Graph(OWLOntology ontology) { + Map> outGoingEdges = new HashMap>(); + Map> inComingEdges = new HashMap>(); + + for (OWLAxiom axiom: ontology.getABoxAxioms(true)) + if (axiom instanceof OWLClassAssertionAxiom) + addClassAssertion((OWLClassAssertionAxiom) axiom); + else if (axiom instanceof OWLObjectPropertyAssertionAxiom) + addPropertyAssertion((OWLObjectPropertyAssertionAxiom) axiom, inComingEdges, outGoingEdges); + + for (Node node: nodes) { + sortedOutGoingEdges.put(node, sort(outGoingEdges.get(node))); + sortedInComingEdges.put(node, sort(inComingEdges.get(node))); + } + + outGoingEdges.clear(); + inComingEdges.clear(); + } + + public Collection getNodes() { return nodes; } + + private void addPropertyAssertion(OWLObjectPropertyAssertionAxiom axiom, + Map> inComingEdges, Map> outGoingEdges) { + + Node u = getNode(axiom.getSubject().toStringID()), v = getNode(axiom.getObject().toStringID()); + + nodes.add(u); + nodes.add(v); + + Edge e = new Edge(u, v, ((OWLObjectProperty) axiom.getProperty()).toStringID()); + + Collection edges = outGoingEdges.get(u); + if (edges == null) { + edges = new LinkedList(); + outGoingEdges.put(u, edges); + } + edges.add(e); + + edges = inComingEdges.get(v); + if (edges == null) { + edges = new LinkedList(); + inComingEdges.put(v, edges); + } + edges.add(e); + } + + private void addClassAssertion(OWLClassAssertionAxiom axiom) { + OWLClass cls = (OWLClass) axiom.getClassExpression(); + Node u; +// if (cls.getIRI().toString().startsWith(HermitSummaryFilter.QueryAnswerTermPrefix)) +// u = getNode(axiom.getIndividual().toStringID(), false); +// else + u = getNode(axiom.getIndividual().toStringID()); + + if (u == null) return ; + u.addConcept(cls.toStringID()); + nodes.add(u); + } + + public Edge[] getOutGoingEdges(Node u) { + return sortedOutGoingEdges.get(u); + } + + public Edge[] getInComingEdges(Node u) { + return sortedInComingEdges.get(u); + } + + Comparator edgeComp = new EdgeComparatorByNodeLabel(); + + public Edge[] sort(Collection edges) { + if (edges == null) return new Edge[0]; + Edge[] sortedEdges = new Edge[edges.size()]; + edges.toArray(sortedEdges); + Arrays.sort(sortedEdges, edgeComp); + return sortedEdges; + } + + + private Comparator coarseNodeComparator = null; + + public Comparator getCoarseNodeComparator() { + if (coarseNodeComparator == null) + coarseNodeComparator = new EstimatedFeatureComparator(this); + return coarseNodeComparator; + } + + Map allNodes = new HashMap(); + + private Node getNode(String nodeName) { + Node node = null; + if ((node = allNodes.get(nodeName)) == null) { + node = new Node(nodeName); + allNodes.put(nodeName, node); + } + return node; + } + + private Node getNode(GroundTerm t) { + if (t instanceof uk.ac.ox.cs.JRDFox.model.Individual) + return getNode(((uk.ac.ox.cs.JRDFox.model.Individual) t).getIRI()); + else { + Literal l = (Literal) t; + return getNode(l.getLexicalForm() + "^^" + l.getDatatype().getIRI()); + } + } + + public Node getNode(Term t) { + if (t instanceof Individual) + return getNode(((Individual) t).getIRI()); + else if (t instanceof Constant) + return getNode(((Constant) t).getLexicalForm() + "^^" + ((Constant) t).getDatatypeURI()); + return null; + } + + public NodeTuple getNodeTuple(AnswerTuple tuple) { + NodeTuple ret = new NodeTuple(tuple); + for (int i = 0; i < tuple.getArity(); ++i) + ret.addNode(getNode(tuple.getGroundTerm(i))); + return ret; + } + +} + 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.util.HashSet; +import java.util.Set; + +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; + +import uk.ac.ox.cs.JRDFox.model.Individual; +import uk.ac.ox.cs.pagoda.endomorph.Endomorph; +import uk.ac.ox.cs.pagoda.owl.OWLHelper; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; +import uk.ac.ox.cs.pagoda.query.AnswerTuples; +import uk.ac.ox.cs.pagoda.query.AnswerTuplesImp; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +import uk.ac.ox.cs.pagoda.query.QueryRecord.Step; +import uk.ac.ox.cs.pagoda.reasoner.full.Checker; +import uk.ac.ox.cs.pagoda.reasoner.full.HermitChecker; +import uk.ac.ox.cs.pagoda.tracking.TrackingRuleEncoder; +import uk.ac.ox.cs.pagoda.util.Timer; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class HermitSummaryFilter implements Checker { + + QueryRecord m_record; + Summary summary = null; + HermitChecker summarisedHermiT = null; + boolean summarisedConsistency; + + Endomorph endomorphismChecker = null; + + public HermitSummaryFilter(QueryRecord record) { + m_record = record; + HermitChecker hermitChecker = new HermitChecker(record.getRelevantOntology(), record); + endomorphismChecker = new Endomorph(record, hermitChecker); + hermitChecker.setDependencyGraph(endomorphismChecker.getDependencyGraph()); + } + + @Override + public boolean isConsistent() { + if (summary == null) + summary = new Summary(endomorphismChecker.getOntology(), endomorphismChecker.getGraph()); + + if (summarisedHermiT == null) + initialiseSummarisedReasoner(); + + if (summarisedConsistency) return true; + return endomorphismChecker.isConsistent(); + } + + private void initialiseSummarisedReasoner() { + Timer t = new Timer(); + summarisedHermiT = new HermitChecker(summary.getSummary(), summary.getSummary(m_record)); +// summary.save("summarised_query" + m_record.getQueryID() + ".owl"); + if (summarisedConsistency = summarisedHermiT.isConsistent()) + Utility.logDebug("The summary of ABox is consistent with the TBox."); + else + Utility.logDebug("The summary of ABox is NOT consistent with the TBox."); + m_record.addProcessingTime(Step.Summarisation, t.duration()); + } + + @Override + public int check(AnswerTuples answers) { + Timer t = new Timer(); + OWLOntology newOntology = addOntologyWithQueryPreciate(endomorphismChecker.getOntology(), m_record, answers); + summary = new Summary(newOntology); + initialiseSummarisedReasoner(); + + if (summarisedConsistency) { + Set passed = new HashSet(), succ = new HashSet(); + Set falsified = new HashSet(), fail = new HashSet(); + + int counter = 0; + AnswerTuple representative; + for (AnswerTuple answer; answers.isValid(); answers.moveNext()) { + ++counter; + answer = answers.getTuple(); + representative = summary.getSummary(answer); + if (fail.contains(representative)) + falsified.add(answer); + else if (succ.contains(representative)) + passed.add(answer); + else + if (summarisedHermiT.check(representative)) { + succ.add(representative); + passed.add(answer); + } + else { + fail.add(representative); + falsified.add(answer); + } + } + answers.dispose(); + + Utility.logDebug("@TIME to filter out non-answers by summarisation: " + t.duration()); + + m_record.removeUpperBoundAnswers(falsified); + + if (m_record.processed()) { + m_record.setDifficulty(Step.Summarisation); + m_record.addProcessingTime(Step.Summarisation, t.duration()); + return 0; + } + + Utility.logDebug("The number of answers to be checked with HermiT: " + passed.size() + "/" + counter); + + m_record.setDifficulty(Step.FullReasoning); + m_record.addProcessingTime(Step.Summarisation, t.duration()); + + return endomorphismChecker.check(new AnswerTuplesImp(m_record.getAnswerVariables(), passed)); + } + else { + m_record.addProcessingTime(Step.Summarisation, t.duration()); +// m_record.saveRelevantOntology("fragment.owl"); + m_record.setDifficulty(Step.FullReasoning); + return endomorphismChecker.check(answers); + } + } + + public static final String QueryAnswerTermPrefix = TrackingRuleEncoder.QueryPredicate + "_term"; + + public static OWLOntology addOntologyWithQueryPreciate(OWLOntology ontology, QueryRecord record, AnswerTuples answers) { + OWLOntology newOntology = null; + OWLOntologyManager manager = ontology.getOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + try { + newOntology = manager.createOntology(); + manager.addAxioms(newOntology, ontology.getAxioms()); + + OWLClass[] queryClass = new OWLClass[answers.getArity()]; + int arity = answers.getArity(); + for (int i = 0; i < arity; ++i) + queryClass[i] = factory.getOWLClass(IRI.create(QueryAnswerTermPrefix + i)); + AnswerTuple answer; + for (; answers.isValid(); answers.moveNext()) { + answer = answers.getTuple(); + for (int i = 0; i < arity; ++i) + if (answer.getGroundTerm(i) instanceof Individual) { + String iri = ((Individual) answer.getGroundTerm(i)).getIRI(); + if (!record.isPredicate(answer, i)) { + manager.addAxiom(newOntology, + factory.getOWLClassAssertionAxiom( + queryClass[i], + factory.getOWLNamedIndividual(IRI.create(iri)))); + } + } + } + answers.reset(); + } catch (OWLOntologyCreationException e) { + e.printStackTrace(); + } + + return newOntology; + } + + public static void printRelatedABoxAxioms(OWLOntology onto, String str) { + if (!str.startsWith("<")) str = OWLHelper.addAngles(str); + + System.out.println("Axioms in " + onto.getOntologyID().getOntologyIRI() + " related to " + str); + + for (OWLAxiom axiom: onto.getABoxAxioms(true)) + if (axiom.toString().contains(str)) + System.out.println(axiom); + + System.out.println("-----------------------------"); + } + + public static void printRelatedTBoxAxioms(OWLOntology onto, String str) { + + System.out.println("Axioms in " + onto.getOntologyID().getOntologyIRI() + " related to " + str); + + for (OWLAxiom axiom: onto.getTBoxAxioms(true)) + if (axiom.toString().contains(str)) + System.out.println(axiom); + + for (OWLAxiom axiom: onto.getRBoxAxioms(true)) + if (axiom.toString().contains(str)) + System.out.println(axiom); + + System.out.println("-----------------------------"); + } + + @Override + public boolean check(AnswerTuple answer) { + AnswerTuple representative = summary.getSummary(answer); + if (summarisedHermiT.isConsistent() && !summarisedHermiT.check(representative)) + return false; + return endomorphismChecker.check(answer); + } + + @Override + public void dispose() { + if (summarisedHermiT != null) summarisedHermiT.dispose(); + endomorphismChecker.dispose(); + } + +} 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.util.Collection; +import java.util.Iterator; +import java.util.TreeSet; + +public class Node { + + String name; + Collection concepts = new TreeSet(); + private String label; + + public Node(String nodeName) { + name = nodeName; + } + + public String getName() { return name; } + + public void addConcept(String className) { + concepts.add(className); + label = null; + } + + public String getLabel() { + if (label == null) { + StringBuilder sb = null; + for (Iterator it = concepts.iterator(); it.hasNext(); ) { + if (sb == null) sb = new StringBuilder(); + else sb.append("^"); + sb.append(it.next()); + } + label = sb == null ? "" : sb.toString(); + } + return label; + } + + //TODO to be removed (just used for debug) ... + String simplifiedLabel = null; + + public String toString() { + if (simplifiedLabel == null) + simplifiedLabel = getLabel(); + return name + "@" + simplifiedLabel; + } + + public boolean isSubConceptOf(Node v) { + String s, t = ""; + for (Iterator uIter = concepts.iterator(), vIter = v.concepts.iterator(); uIter.hasNext(); ) { + s = uIter.next(); + if (!vIter.hasNext()) return false; + while (vIter.hasNext() && !s.equals(t = vIter.next())); + if (!s.equals(t)) return false; + } + return true; + } + + public Collection getConcepts() { + return concepts; + } + +} + + + + 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.util.Collection; +import java.util.LinkedList; + +import uk.ac.ox.cs.pagoda.query.AnswerTuple; + +public class NodeTuple { + + AnswerTuple m_tuple; + Collection nodes = new LinkedList(); + + public NodeTuple(AnswerTuple tuple) { + m_tuple = tuple; + } + + void addNode(Node node) { + nodes.add(node); + } + + public Collection getNodes() { + return nodes; + } + + public AnswerTuple getAnswerTuple() { + return m_tuple; + } + + + public String toString() { + StringBuilder sb = new StringBuilder("("); + for (Node node: nodes) { + if (sb.length() > 1) sb.append(", "); + sb.append(node.toString()); + } + sb.append(")"); + return sb.toString(); + } +} 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 @@ +package uk.ac.ox.cs.pagoda.summary; + +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +import org.semanticweb.HermiT.model.Atom; +import org.semanticweb.HermiT.model.DLClause; +import org.semanticweb.HermiT.model.Individual; +import org.semanticweb.HermiT.model.Term; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLLiteral; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.OWLOntologyStorageException; + +import uk.ac.ox.cs.JRDFox.model.GroundTerm; +import uk.ac.ox.cs.JRDFox.model.Literal; +import uk.ac.ox.cs.pagoda.owl.OWLHelper; +import uk.ac.ox.cs.pagoda.query.AnswerTuple; +import uk.ac.ox.cs.pagoda.query.QueryRecord; +import uk.ac.ox.cs.pagoda.util.Namespace; +import uk.ac.ox.cs.pagoda.util.SparqlHelper; +import uk.ac.ox.cs.pagoda.util.Utility; + +public class Summary { + + OWLOntologyManager manager; + OWLDataFactory factory; + OWLOntology ontology, summarisedOntology; + Graph graph; + + public Summary(OWLOntology ontology) { + OWLHelper.identifyAndChangeAnnotationAssertions(ontology); + this.ontology = ontology; + graph = new Graph(ontology); + factory = (manager = ontology.getOWLOntologyManager()).getOWLDataFactory(); + } + + public Summary(OWLOntology ontology, Graph graph) { + this.ontology = ontology; + this.graph = graph; + factory = (manager = ontology.getOWLOntologyManager()).getOWLDataFactory(); + } + + Map label2representative = new HashMap(); + Map representatives = new HashMap(); + + public Collection getRepresentatives() { + return representatives.values(); + } + + Map> groups = null; + + public Collection getGroup(String representative) { + if (groups == null) { + groups = new HashMap>(); + LinkedList group; + for (Map.Entry entry: representatives.entrySet()) { + if ((group = groups.get(entry.getValue())) == null) + group = new LinkedList(); + group.add(entry.getKey()); + } + } + return groups.get(representative); + } + + private void process(OWLOntology ontology, OWLOntology abstractOntology) { + OWLOntologyManager manager = ontology.getOWLOntologyManager(); + groupIndividualsByConcepts(); + + manager.addAxioms(abstractOntology, ontology.getRBoxAxioms(true)); + manager.addAxioms(abstractOntology, ontology.getTBoxAxioms(true)); + + OWLAxiom newAxiom; + for (OWLAxiom axiom: ontology.getABoxAxioms(true)) { + newAxiom = summeriseAxiom(axiom); + manager.addAxiom(abstractOntology, newAxiom); + } + + OWLObjectProperty sameAs = factory.getOWLObjectProperty(IRI.create(Namespace.EQUALITY)); + for (Map.Entry entry: representatives.entrySet()) + if (!entry.getKey().equals(entry.getValue())) + manager.addAxiom(abstractOntology, + factory.getOWLObjectPropertyAssertionAxiom( + sameAs, + factory.getOWLNamedIndividual(IRI.create(entry.getKey())), + factory.getOWLNamedIndividual(IRI.create(entry.getValue())))); + } + + private void groupIndividualsByConcepts() { + String name, label, representative; + Utility.logDebug("grouping individuals by its concepts"); + + for (Node node: graph.getNodes()) { + name = node.getName(); + label = node.getLabel(); + + if ((representative = label2representative.get(label)) == null) { + representative = name; + label2representative.put(label, name); + } + + representatives.put(name, representative); + } + } + + private OWLAxiom summeriseAxiom(OWLAxiom axiom) { + if (axiom instanceof OWLClassAssertionAxiom) { + OWLClassAssertionAxiom assertion = (OWLClassAssertionAxiom) axiom; + OWLNamedIndividual a = getRepresentativeIndividual(assertion.getIndividual().toStringID()); + return factory.getOWLClassAssertionAxiom(assertion.getClassExpression(), a); + } + else if (axiom instanceof OWLObjectPropertyAssertionAxiom) { + OWLObjectPropertyAssertionAxiom assertion = (OWLObjectPropertyAssertionAxiom) axiom; + OWLNamedIndividual a = getRepresentativeIndividual(assertion.getSubject().toStringID()); + OWLNamedIndividual b = getRepresentativeIndividual(assertion.getObject().toStringID()); + return factory.getOWLObjectPropertyAssertionAxiom(assertion.getProperty(), a, b); + } + else if (axiom instanceof OWLDataPropertyAssertionAxiom) { + OWLDataPropertyAssertionAxiom assertion = (OWLDataPropertyAssertionAxiom) axiom; + OWLNamedIndividual a = getRepresentativeIndividual(assertion.getSubject().toStringID()); + OWLLiteral b = assertion.getObject(); + return factory.getOWLDataPropertyAssertionAxiom(assertion.getProperty(), a, b); + + } + else { + Utility.logError("Unknown axiom: " + axiom); + return null; + } + } + + public OWLNamedIndividual getRepresentativeIndividual(String name) { + return factory.getOWLNamedIndividual(IRI.create(getRepresentativeName(name))); + } + + public String getRepresentativeName(String name) { + String rep = representatives.get(name); + if (rep == null) return name; + return rep; + } + + public OWLOntology getSummary() { + if (summarisedOntology == null) { + try { + summarisedOntology = ontology.getOWLOntologyManager().createOntology(); + } catch (OWLOntologyCreationException e) { + summarisedOntology = null; + e.printStackTrace(); + } + process(ontology, summarisedOntology); + } + return summarisedOntology; + } + + public void save(String fileName) { + try { + manager.saveOntology(summarisedOntology, IRI.create(new File(fileName))); + } catch (OWLOntologyStorageException e) { + e.printStackTrace(); + } + } + + private GroundTerm getSummary(GroundTerm t) { + if (t instanceof Literal) return t; + return uk.ac.ox.cs.JRDFox.model.Individual.create(getSummary(((uk.ac.ox.cs.JRDFox.model.Individual) t).getIRI())); + } + + public String getSummary(QueryRecord record) { + DLClause queryClause = getSummary(record.getClause()); + return SparqlHelper.getSPARQLQuery(queryClause.getBodyAtoms(), record.getAnswerVariables()); + } + + public DLClause getSummary(DLClause clause) { + Atom[] newHeadAtoms = new Atom[clause.getHeadLength()], newBodyAtoms = new Atom[clause.getBodyLength()]; + int index = 0; + for (Atom atom: clause.getHeadAtoms()) + newHeadAtoms[index++] = getSummary(atom); + for (Atom atom: clause.getBodyAtoms()) + newBodyAtoms[index++] = getSummary(atom); + + return DLClause.create(newHeadAtoms, newBodyAtoms); + } + + public Atom getSummary(Atom atom) { + Term[] args = new Term [atom.getArity()]; + for (int i = 0; i < atom.getArity(); ++i) + if ((args[i] = atom.getArgument(i)) instanceof Individual) + args[i] = Individual.create(getSummary(atom.getArgument(i).toString())); + return Atom.create(atom.getDLPredicate(), args); + } + + public String getSummary(String name) { + return getRepresentativeName(OWLHelper.removeAngles(name)); + } + + public AnswerTuple getSummary(AnswerTuple answer) { + int arity = answer.getArity(); + GroundTerm[] t = new GroundTerm[arity]; + for (int i = 0; i < arity; ++i) + t[i] = getSummary(answer.getGroundTerm(i)); + return new AnswerTuple(t); + } + +} -- cgit v1.2.3