org.semanticweb.HermiT.hierarchy.Hierarchy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.semanticweb.hermit Show documentation
Show all versions of org.semanticweb.hermit Show documentation
HermiT is reasoner for ontologies written using the Web Ontology Language (OWL). Given an OWL file, HermiT can determine whether or not the ontology is consistent, identify subsumption relationships between classes, and much more.
This is the maven build of HermiT and is designed for people who wish to use HermiT from within the OWL API. It is now versioned in the main HermiT version repository, although not officially supported by the HermiT developers.
The version number of this package is a composite of the HermiT version and a value representing the OWLAPI release it is compatible with. Note that the group id for the upstream HermiT is com.hermit-reasoner, while this fork is released under net.sourceforge.owlapi.
This fork exists to allow HermiT users to use newer OWLAPI versions than the ones supported by the original HermiT codebase.
This package includes the Jautomata library (http://jautomata.sourceforge.net/), and builds with it directly. This library appears to be no longer under active development, and so a "fork" seems appropriate. No development is intended or anticipated on this code base.
The newest version!
/* Copyright 2009 by the Oxford University Computing Laboratory
This file is part of HermiT.
HermiT is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
HermiT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with HermiT. If not, see .
*/
package org.semanticweb.HermiT.hierarchy;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
* Hierarchy.
* @param type
*/
public class Hierarchy {
protected final HierarchyNode m_topNode;
protected final HierarchyNode m_bottomNode;
protected final Map> m_nodesByElements;
/**
* @param topNode topNode
* @param bottomNode bottomNode
*/
public Hierarchy(HierarchyNode topNode,HierarchyNode bottomNode) {
m_topNode=topNode;
m_bottomNode=bottomNode;
m_nodesByElements=new HashMap<>();
for (E element : m_topNode.m_equivalentElements)
m_nodesByElements.put(element,m_topNode);
for (E element : m_bottomNode.m_equivalentElements)
m_nodesByElements.put(element,m_bottomNode);
}
/**
* @return top node
*/
public HierarchyNode getTopNode() {
return m_topNode;
}
/**
* @return bottom node
*/
public HierarchyNode getBottomNode() {
return m_bottomNode;
}
/**
* @return true if empty
*/
public boolean isEmpty() {
return m_nodesByElements.size()==2 && m_topNode.m_equivalentElements.size()==1 && m_bottomNode.m_equivalentElements.size()==1;
}
/**
* @param element element
* @return node for element
*/
public HierarchyNode getNodeForElement(E element) {
return m_nodesByElements.get(element);
}
/**
* @return all nodes
*/
public Collection> getAllNodes() {
return Collections.unmodifiableCollection(m_nodesByElements.values());
}
/**
* @return all node set
*/
public Set> getAllNodesSet() {
return Collections.unmodifiableSet(new HashSet<>(m_nodesByElements.values()));
}
/**
* @return all elements
*/
public Set getAllElements() {
return Collections.unmodifiableSet(m_nodesByElements.keySet());
}
/**
* @return depth
*/
public int getDepth() {
HierarchyDepthFinder depthFinder=new HierarchyDepthFinder<>(m_bottomNode);
traverseDepthFirst(depthFinder);
return depthFinder.depth;
}
protected final class HierarchyDepthFinder implements Hierarchy.HierarchyNodeVisitor {
protected final HierarchyNode bottomNode;
protected int depth=0;
public HierarchyDepthFinder(HierarchyNode bottomNode) {
this.bottomNode=bottomNode;
}
@Override
public boolean redirect(HierarchyNode[] nodes) {
return true;
}
@Override
public void visit(int level,HierarchyNode node,HierarchyNode parentNode,boolean firstVisit) {
if (node.equals(bottomNode)&&level>depth)
depth=level;
}
}
/**
* @param transformer transformer
* @param comparator comparator
* @param type
* @return transformed hierarchy
*/
public Hierarchy transform(Transformer super E,T> transformer,Comparator comparator) {
HierarchyNodeComparator newNodeComparator=new HierarchyNodeComparator<>(comparator);
Map,HierarchyNode> oldToNew=new HashMap<>();
for (HierarchyNode oldNode : m_nodesByElements.values()) {
Set newEquivalentElements;
Set> newParentNodes;
Set> newChildNodes;
if (comparator==null) {
newEquivalentElements=new HashSet<>();
newParentNodes=new HashSet<>();
newChildNodes=new HashSet<>();
}
else {
newEquivalentElements=new TreeSet<>(comparator);
newParentNodes=new TreeSet<>(newNodeComparator);
newChildNodes=new TreeSet<>(newNodeComparator);
}
for (E oldElement : oldNode.m_equivalentElements) {
T newElement=transformer.transform(oldElement);
newEquivalentElements.add(newElement);
}
T newRepresentative=transformer.determineRepresentative(oldNode.m_representative,newEquivalentElements);
HierarchyNode newNode=new HierarchyNode<>(newRepresentative,newEquivalentElements,newParentNodes,newChildNodes);
oldToNew.put(oldNode,newNode);
}
for (HierarchyNode oldParentNode : m_nodesByElements.values()) {
HierarchyNode newParentNode=oldToNew.get(oldParentNode);
for (HierarchyNode oldChildNode : oldParentNode.m_childNodes) {
HierarchyNode newChildNode=oldToNew.get(oldChildNode);
newParentNode.m_childNodes.add(newChildNode);
newChildNode.m_parentNodes.add(newParentNode);
}
}
HierarchyNode newTopNode=oldToNew.get(m_topNode);
HierarchyNode newBottomNode=oldToNew.get(m_bottomNode);
Hierarchy newHierarchy=new Hierarchy<>(newTopNode,newBottomNode);
for (HierarchyNode newNode : oldToNew.values())
for (T newElement : newNode.m_equivalentElements)
newHierarchy.m_nodesByElements.put(newElement,newNode);
return newHierarchy;
}
/**
* @param visitor visitor
*/
@SuppressWarnings("unchecked")
public void traverseDepthFirst(HierarchyNodeVisitor visitor) {
HierarchyNode[] redirectBuffer=new HierarchyNode[2];
Set> visited=new HashSet<>();
traverseDepthFirst(visitor,0,m_topNode,null,visited,redirectBuffer);
}
protected void traverseDepthFirst(HierarchyNodeVisitor visitor,int level,HierarchyNode _node,HierarchyNode _parentNode,Set> visited,HierarchyNode[] redirectBuffer) {
HierarchyNode node=_node;
HierarchyNode parentNode=_parentNode;
redirectBuffer[0]=node;
redirectBuffer[1]=parentNode;
if (visitor.redirect(redirectBuffer)) {
node=redirectBuffer[0];
parentNode=redirectBuffer[1];
boolean firstVisit=visited.add(node);
visitor.visit(level,node,parentNode,firstVisit);
if (firstVisit)
for (HierarchyNode childNode : node.m_childNodes)
traverseDepthFirst(visitor,level+1,childNode,node,visited,redirectBuffer);
}
}
@Override
public String toString() {
StringWriter buffer=new StringWriter();
final PrintWriter output=new PrintWriter(buffer);
traverseDepthFirst(new HierarchyNodeVisitor() {
@Override
public boolean redirect(HierarchyNode[] nodes) {
return true;
}
@Override
public void visit(int level,HierarchyNode node,HierarchyNode parentNode,boolean firstVisit) {
if (!node.equals(m_bottomNode))
printNode(level,node,parentNode,firstVisit);
}
public void printNode(int level,HierarchyNode node,HierarchyNode parentNode,boolean firstVisit) {
Set equivalences=node.getEquivalentElements();
boolean printSubClasOf=parentNode!=null;
boolean printEquivalences=firstVisit && equivalences.size()>1;
if (printSubClasOf || printEquivalences) {
for (int i=4*level;i>0;--i)
output.print(' ');
output.print(node.getRepresentative().toString());
if (printEquivalences) {
output.print('[');
boolean first=true;
for (E element : equivalences) {
if (!node.getRepresentative().equals(element)) {
if (first)
first=false;
else
output.print(' ');
output.print(element);
}
}
output.print(']');
}
if (printSubClasOf) {
assert parentNode!=null;
output.print(" -> ");
output.print(parentNode.getRepresentative().toString());
}
output.println();
}
}
});
output.flush();
return buffer.toString();
}
/**
* @param elements elements
* @param topElement topElement
* @param bottomElement bottomElement
* @param type
* @return empty hierarchy
*/
public static Hierarchy emptyHierarchy(Collection elements,T topElement,T bottomElement) {
HierarchyNode topBottomNode=new HierarchyNode<>(topElement);
topBottomNode.m_equivalentElements.add(topElement);
topBottomNode.m_equivalentElements.add(bottomElement);
topBottomNode.m_equivalentElements.addAll(elements);
return new Hierarchy<>(topBottomNode,topBottomNode);
}
/**
* @param topElement topElement
* @param bottomElement bottomElement
* @param type
* @return trivial hierarchy
*/
public static Hierarchy trivialHierarchy(T topElement,T bottomElement) {
HierarchyNode topNode=new HierarchyNode<>(topElement);
topNode.m_equivalentElements.add(topElement);
HierarchyNode bottomNode=new HierarchyNode<>(bottomElement);
bottomNode.m_equivalentElements.add(bottomElement);
topNode.m_childNodes.add(bottomNode);
bottomNode.m_parentNodes.add(topNode);
return new Hierarchy<>(topNode,bottomNode);
}
protected interface HierarchyNodeVisitor {
boolean redirect(HierarchyNode[] nodes);
void visit(int level,HierarchyNode node,HierarchyNode parentNode,boolean firstVisit);
}
/**Transformer.
* @param input type
* @param return type*/
public interface Transformer {
/**
* @param element element
* @return transformed element
*/
T transform(E element);
/**
* @param oldRepresentative oldRepresentative
* @param newEquivalentElements newEquivalentElements
* @return representative
*/
T determineRepresentative(E oldRepresentative,Set newEquivalentElements);
}
protected static class HierarchyNodeComparator implements Comparator> {
protected final Comparator m_elementComparator;
public HierarchyNodeComparator(Comparator elementComparator) {
m_elementComparator=elementComparator;
}
@Override
public int compare(HierarchyNode n1,HierarchyNode n2) {
return m_elementComparator.compare(n1.m_representative,n2.m_representative);
}
}
}