All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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