
it.unibz.inf.ontop.si.repository.impl.SemanticIndexBuilder Maven / Gradle / Ivy
package it.unibz.inf.ontop.si.repository.impl;
import it.unibz.inf.ontop.spec.ontology.*;
import it.unibz.inf.ontop.spec.ontology.ClassifiedTBox;
import org.jgrapht.DirectedGraph;
import org.jgrapht.Graphs;
import org.jgrapht.event.ConnectedComponentTraversalEvent;
import org.jgrapht.event.TraversalListenerAdapter;
import org.jgrapht.event.VertexTraversalEvent;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.EdgeReversedGraph;
import org.jgrapht.graph.SimpleDirectedGraph;
import org.jgrapht.traverse.DepthFirstIterator;
import org.jgrapht.traverse.GraphIterator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
*
* Build the indexes for the DAG
* create a map with the index and the intervals for each node in the graph
*
*
*/
public class SemanticIndexBuilder {
private final Map classRanges;
private final Map opRanges;
private final Map dpRanges;
// index_counter is changed during the traversal of all three DAGs
private int index_counter = 1;
/**
* Listener that creates the index for each node visited in depth first search.
* extends TraversalListenerAdapter from JGrapht
*
*/
private final class SemanticIndexer extends TraversalListenerAdapter {
private T reference; //last root node
private boolean newComponent = true;
private final DirectedGraph namedDAG;
private final Map ranges;
public SemanticIndexer(DirectedGraph namedDAG, Map ranges) {
this.namedDAG = namedDAG;
this.ranges = ranges;
}
@Override
public void connectedComponentStarted(ConnectedComponentTraversalEvent e) {
newComponent = true; // to record a new root
}
@Override
public void vertexTraversed(VertexTraversalEvent e) {
T vertex = e.getVertex();
if (newComponent) {
reference = vertex;
newComponent = false;
}
ranges.put(vertex, new SemanticIndexRange(index_counter));
index_counter++;
}
@Override
public void connectedComponentFinished(ConnectedComponentTraversalEvent e) {
//merge all the interval for the current root of the graph
mergeRangeNode(reference);
}
/**
* Merge the indexes of the current connected component
* @param d is the root node
* */
private void mergeRangeNode(T d) {
for (T ch : Graphs.successorListOf(namedDAG, d)) {
if (!ch.equals(d)) {
mergeRangeNode(ch);
//merge the index of the node with the index of his child
ranges.get(d).addRange(ranges.get(ch).getIntervals());
}
}
}
}
private Map createSemanticIndex(EquivalencesDAG dag) {
DirectedGraph namedDag = getNamedDAG(dag);
// reverse the named dag so that we give smallest indexes to ?
DirectedGraph reversed = new EdgeReversedGraph<>(namedDag);
LinkedList roots = new LinkedList<>();
for (T n : reversed.vertexSet())
if ((reversed.incomingEdgesOf(n)).isEmpty())
roots.add(n);
Map ranges = new HashMap<>();
for (T root: roots) {
// depth-first sort
GraphIterator orderIterator = new DepthFirstIterator<>(reversed, root);
// add Listener to create the ranges
orderIterator.addTraversalListener(new SemanticIndexer(reversed, ranges));
// System.out.println("\nIndexing:");
while (orderIterator.hasNext())
orderIterator.next();
}
return ranges;
}
/**
* Constructor for the NamedDAG
* @param dag the DAG from which we want to keep only the named descriptions
*/
public static SimpleDirectedGraph getNamedDAG(EquivalencesDAG dag) {
SimpleDirectedGraph namedDAG = new SimpleDirectedGraph<>(DefaultEdge.class);
for (Equivalences v : dag)
namedDAG.addVertex(v.getRepresentative());
for (Equivalences s : dag)
for (Equivalences t : dag.getDirectSuper(s))
namedDAG.addEdge(s.getRepresentative(), t.getRepresentative());
for (Equivalences v : dag)
if (!v.isIndexed()) {
// eliminate node
for (DefaultEdge incEdge : namedDAG.incomingEdgesOf(v.getRepresentative())) {
T source = namedDAG.getEdgeSource(incEdge);
for (DefaultEdge outEdge : namedDAG.outgoingEdgesOf(v.getRepresentative())) {
T target = namedDAG.getEdgeTarget(outEdge);
namedDAG.addEdge(source, target);
}
}
namedDAG.removeVertex(v.getRepresentative()); // removes all adjacent edges as well
}
return namedDAG;
}
/**
* Assign indexes for the named DAG, use a depth first listener over the DAG
* @param reasoner used to know ancestors and descendants of the dag
*/
public SemanticIndexBuilder(ClassifiedTBox reasoner) {
classRanges = createSemanticIndex(reasoner.classesDAG());
opRanges = createSemanticIndex(reasoner.objectPropertiesDAG());
dpRanges = createSemanticIndex(reasoner.dataPropertiesDAG());
}
public Set> getIndexedClasses() {
return classRanges.entrySet();
}
public Set> getIndexedObjectProperties() {
return opRanges.entrySet();
}
public Set> getIndexedDataProperties() {
return dpRanges.entrySet();
}
public SemanticIndexRange getRange(OClass d) {
return classRanges.get(d);
}
public SemanticIndexRange getRange(ObjectPropertyExpression d) {
return opRanges.get(d);
}
public SemanticIndexRange getRange(DataPropertyExpression d) {
return dpRanges.get(d);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy