package org.mindswap.swoop.reasoner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.mindswap.swoop.utils.ExpressivityChecker;
import org.mindswap.swoop.utils.SetUtils;
import org.mindswap.swoop.utils.owlapi.OntologyIndices;
import org.mindswap.swoop.utils.owlapi.QNameShortFormProvider;
import org.semanticweb.owl.io.ShortFormProvider;
import org.semanticweb.owl.model.OWLAnd;
import org.semanticweb.owl.model.OWLAnnotationProperty;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLClassAxiom;
import org.semanticweb.owl.model.OWLDataProperty;
import org.semanticweb.owl.model.OWLDescription;
import org.semanticweb.owl.model.OWLDisjointClassesAxiom;
import org.semanticweb.owl.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owl.model.OWLEquivalentPropertiesAxiom;
import org.semanticweb.owl.model.OWLException;
import org.semanticweb.owl.model.OWLIndividual;
import org.semanticweb.owl.model.OWLIndividualAxiom;
import org.semanticweb.owl.model.OWLNot;
import org.semanticweb.owl.model.OWLObjectProperty;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOr;
import org.semanticweb.owl.model.OWLProperty;
import org.semanticweb.owl.model.OWLPropertyAxiom;
import org.semanticweb.owl.model.OWLSameIndividualsAxiom;
import org.semanticweb.owl.model.OWLSubClassAxiom;
import org.semanticweb.owl.model.OWLSubPropertyAxiom;
import org.semanticweb.owl.model.helper.OntologyHelper;
/**
* @author Aditya Kalyanpur
*/
public class SwoopRDFSReasoner implements SwoopReasoner {
public static boolean DEBUG = false; // for debugging purposes only
boolean loadImports = true;
private Set ontologies;
private OWLOntology ontology;
private List classes, properties, individuals;
private List classAxioms, propAxioms, indAxioms;
private ShortFormProvider shortForms = new QNameShortFormProvider();
private Map incLinks, outLinks, equivalents, complements, disjoints;
private Map classInds, sameAs, differentFrom;
private Map inverses;
private OntologyIndices indices;
public void setOntology(OWLOntology ont) throws OWLException {
ontology = ont;
if(loadImports)
ontologies = OntologyHelper.importClosure(ontology);
else
ontologies = Collections.singleton(ontology);
classify();
buildIndices();
}
/**
* Check if a subclass relationship between two OWL descriptions subClass(subC, supC)
* needs to be added to the incoming/outgoing links hashmaps. Check
* 1. If both subC, supC are OWL Classes
* 2. If subC is a OWL Class and supC is an OWLAnd
* 3. If subC is an OWLOr and supC is a OWL Class
* @param subC
* @param supC
* @throws OWLException
*/
public void subClassCheck(OWLDescription subC, OWLDescription supC) throws OWLException {
if (subC instanceof OWLClass) {
if (supC instanceof OWLClass) this.addSubSuperClass((OWLClass) subC, (OWLClass) supC);
else
// if A subCof (B AND C) -> (A subCOf B) and (A subCOf C)
if (supC instanceof OWLAnd) {
for (Iterator iter = ((OWLAnd) supC).getOperands().iterator(); iter.hasNext(); ) {
OWLDescription desc = (OWLDescription) iter.next();
if (desc instanceof OWLClass) addSubSuperClass((OWLClass) subC, (OWLClass) desc);
}
}
}
else
if (subC instanceof OWLOr && supC instanceof OWLClass) {
// if (A OR B) subCOf C -> (A subCOf C) and (B subCOf C)
for (Iterator iter = ((OWLOr) subC).getOperands().iterator(); iter.hasNext(); ) {
OWLDescription desc = (OWLDescription) iter.next();
if (desc instanceof OWLClass) addSubSuperClass((OWLClass) desc, (OWLClass) supC);
}
}
}
/**
* Compute subclass, equivalence, complement and disjoint relations
* for all classes in ontology and add it to corresponding HashMaps
* 1. check direct assertions (sub/equ)
* 2. check class axioms (GCIS) (sub/equ/dis)
* @throws OWLException
*/
private void computeClassRelations() throws OWLException {
// handle class assertions
// superClass and equivalentClass
for(int i = 0; i < classes.size(); i++) {
OWLClass c = (OWLClass) classes.get(i);
Iterator supers = c.getSuperClasses(ontologies).iterator();
while(supers.hasNext()) {
OWLDescription sup = (OWLDescription) supers.next();
this.subClassCheck(c, sup);
}
Iterator equs = c.getEquivalentClasses(ontologies).iterator();
while(equs.hasNext()) {
OWLDescription equ = (OWLDescription) equs.next();
this.addEquivalentClass(c, equ);
}
}
// handle class axioms
// OWLSubClass, OWLEquivalentClasses and OWLDisjointClasses
for (int i=0; i<classAxioms.size(); i++) {
OWLClassAxiom axiom = (OWLClassAxiom) classAxioms.get(i);
if (axiom instanceof OWLSubClassAxiom) {
OWLSubClassAxiom subAxiom = (OWLSubClassAxiom) axiom;
this.subClassCheck(subAxiom.getSubClass(), subAxiom.getSuperClass());
}
else if (axiom instanceof OWLEquivalentClassesAxiom) {
OWLEquivalentClassesAxiom equAxiom = (OWLEquivalentClassesAxiom) axiom;
Set equs = equAxiom.getEquivalentClasses();
for (Iterator iter = equs.iterator(); iter.hasNext(); ) {
OWLDescription desc = (OWLDescription) iter.next();
if (desc instanceof OWLClass) {
Set copyEqus = new HashSet(equs);
copyEqus.remove(desc);
for (Iterator iter2 = copyEqus.iterator(); iter2.hasNext(); ) {
OWLDescription desc2 = (OWLDescription) iter2.next();
this.addEquivalentClass((OWLClass) desc, desc2);
}
}
}
}
else if (axiom instanceof OWLDisjointClassesAxiom) {
OWLDisjointClassesAxiom disAxiom = (OWLDisjointClassesAxiom) axiom;
Set dis = disAxiom.getDisjointClasses();
for (Iterator iter = dis.iterator(); iter.hasNext(); ) {
OWLDescription desc = (OWLDescription) iter.next();
if (desc instanceof OWLClass) {
Set copyDis = new HashSet(dis);
copyDis.remove(desc);
for (Iterator iter2 = copyDis.iterator(); iter2.hasNext(); ) {
OWLDescription desc2 = (OWLDescription) iter2.next();
if (desc2 instanceof OWLClass) {
// add disjoint between desc and desc2 when both are classes
this.addDisjointClass((OWLClass) desc, (OWLClass) desc2);
}
}
}
}
}
}
}
/*
* Add complement assertion between two classes to the corresponding hashmap
*/
private void addComplementClass(OWLClass c1, OWLClass c2) {
Set compSet1 = new HashSet(); // complements of c1
Set compSet2 = new HashSet(); // complements of c2
if (complements.containsKey(c1)) compSet1.addAll((HashSet) complements.get(c1));
if (complements.containsKey(c2)) compSet2.addAll((HashSet) complements.get(c2));
complements.put(c1, compSet1);
complements.put(c2, compSet2);
}
/*
* Add disjoint assertion between two classes to the corresponding hashmap
*/
private void addDisjointClass(OWLClass c1, OWLClass c2) {
Set disSet1 = new HashSet(); // disjoints of c1
Set disSet2 = new HashSet(); // disjoints of c2
if (disjoints.containsKey(c1)) disSet1.addAll((HashSet) disjoints.get(c1));
if (disjoints.containsKey(c2)) disSet2.addAll((HashSet) disjoints.get(c2));
disjoints.put(c1, disSet1);
disjoints.put(c2, disSet2);
}
/**
* Add equivalent class relation to the hashmap - equivalents.
* Also perform special check for: A = (B and C) -> A subCOf B..
* @param cla - class
* @param desc - equivalent class description
* @throws OWLException
*/
private void addEquivalentClass(OWLClass cla, OWLDescription desc) throws OWLException {
Set equMap = new HashSet();
equMap.add(cla); // add class itself to its equivalents map
// get existing map, if any
if (equivalents.containsKey(cla)) equMap.addAll((HashSet) equivalents.get(cla));
// add only class to map (no descriptions)
if (desc instanceof OWLClass) {
equMap.add(desc);
// get equivalents of desc as well
if (equivalents.containsKey(desc)) equMap.addAll((HashSet) equivalents.get(desc));
}
else if (desc instanceof OWLAnd) {
// if A = (B AND C); A subCOf B, A subCOf C
for (Iterator iter = ((OWLAnd) desc).getOperands().iterator(); iter.hasNext(); ) {
OWLDescription equ = (OWLDescription) iter.next();
if (equ instanceof OWLClass) {
this.addSubSuperClass(cla, (OWLClass) equ);
}
else if (equ instanceof OWLAnd) {
// check for nested intersections!
this.addEquivalentClass(cla, equ);
}
}
}
else if (desc instanceof OWLNot) {
// if complement, put in separate hashmap
OWLNot not = (OWLNot) desc;
if (not.getOperand() instanceof OWLClass)
this.addComplementClass(cla, (OWLClass) not.getOperand());
}
// put the equivalents for each class in equMap
for (Iterator iter = equMap.iterator(); iter.hasNext();) {
OWLClass equCla = (OWLClass) iter.next();
equivalents.put(equCla, equMap);
}
}
private void addSubSuperProperty(OWLProperty subProp, OWLProperty superProp) {
// get existing superset if any
Set superSet = new HashSet();
if (outLinks.containsKey(subProp)) superSet = (HashSet) outLinks.get(subProp);
superSet.add(superProp);
outLinks.put(subProp, superSet);
// get existing subset if any
Set subSet = new HashSet();
if (incLinks.containsKey(superProp)) subSet = (HashSet) incLinks.get(superProp);
subSet.add(subProp);
incLinks.put(superProp, subSet);
}
private void addEquivalentProperty(OWLProperty prop1, OWLProperty prop2) throws OWLException {
if (prop1.equals(prop2)) return;
Set equSet = new HashSet();
equSet.add(prop1); // add property itself to equivalent set
if (equivalents.containsKey(prop1)) equSet.addAll((HashSet) equivalents.get(prop1));
equSet.add(prop2);
// put same equivalents set for each property in hashmap
for (Iterator iter = equSet.iterator(); iter.hasNext();) {
OWLProperty prop = (OWLProperty) iter.next();
equivalents.put(prop, equSet);
}
}
/**
* Add sub-super class relationship links to the two hashmaps :-
* incoming links (incLinks) and outgoing links (outLinks).
*
* @param subClass - subclass description
* @param superClass - super class description
* @throws OWLException
*/
private void addSubSuperClass(OWLClass subClass, OWLClass superClass) throws OWLException {
// get existing superset if any
Set superSet = new HashSet();
if (outLinks.containsKey(subClass)) superSet = (HashSet) outLinks.get(subClass);
// get existing subset if any
Set subSet = new HashSet();
if (incLinks.containsKey(superClass)) subSet = (HashSet) incLinks.get(superClass);
superSet.add(superClass);
subSet.add(subClass);
// add to outgoing and incoming links maps respectively
outLinks.put(subClass, superSet);
incLinks.put(superClass, subSet);
}
private void init() throws OWLException {
Set classSet = new HashSet();
Set propSet = new HashSet();
individuals = new ArrayList();
classAxioms = new ArrayList();
propAxioms = new ArrayList();
indAxioms = new ArrayList();
incLinks = new HashMap();
outLinks = new HashMap();
equivalents = new HashMap();
complements = new HashMap();
disjoints = new HashMap();
classInds = new HashMap();
sameAs = new HashMap();
differentFrom = new HashMap();
inverses = new HashMap();
Iterator ont = ontologies.iterator();
while(ont.hasNext()) {
OWLOntology o = (OWLOntology) ont.next();
classSet.addAll(o.getClasses());
propSet.addAll(o.getObjectProperties());
propSet.addAll(o.getDataProperties());
propSet.addAll(o.getAnnotationProperties());
individuals.addAll(o.getIndividuals());
classAxioms.addAll(o.getClassAxioms());
propAxioms.addAll(o.getPropertyAxioms());
indAxioms.addAll(o.getIndividualAxioms());
}
classes = new ArrayList(classSet.size() + 1);
properties = new ArrayList(propSet);
OWLClass thing = ontology.getOWLDataFactory().getOWLThing();
OWLClass nothing = ontology.getOWLDataFactory().getOWLNothing();
// we want owl:Thing and owl:Nothing to be always at the beginning
classes.add(thing);
classes.add(nothing);
// remove multiple copies if exists
classSet.remove(thing);
classSet.remove(nothing);
classes.addAll(classSet);
}
/**
* Compute subproperty and equivalence relations for all properties
* in ontology and add it to corresponding HashMaps
* 1. check direct assertions (sub/equ)
* 2. check property axioms (GCIS) (sub/equ)
* @throws OWLException
*/
private void computePropertyRelations() throws OWLException {
for(int i = 0; i < properties.size(); i++) {
OWLProperty p = (OWLProperty) properties.get(i);
// handle super properties
Iterator supers = p.getSuperProperties(ontologies).iterator();
while(supers.hasNext()) {
OWLProperty sup = (OWLProperty) supers.next();
this.addSubSuperProperty(p, sup);
}
// handle inverse properties
if (p instanceof OWLObjectProperty) {
for (Iterator invIter = ((OWLObjectProperty) p).getInverses(ontologies).iterator(); invIter.hasNext();) {
OWLObjectProperty invP = (OWLObjectProperty) invIter.next();
// add inverses to set of each property
this.addInverse((OWLObjectProperty) p, invP);
this.addInverse(invP, (OWLObjectProperty) p);
}
}
}
// handle explicit axioms
for (int i=0; i<propAxioms.size(); i++) {
OWLPropertyAxiom axiom = (OWLPropertyAxiom) propAxioms.get(i);
if (axiom instanceof OWLSubPropertyAxiom) {
OWLSubPropertyAxiom subAxiom = (OWLSubPropertyAxiom) axiom;
this.addSubSuperProperty(subAxiom.getSubProperty(), subAxiom.getSuperProperty());
}
else if (axiom instanceof OWLEquivalentPropertiesAxiom) {
OWLEquivalentPropertiesAxiom equAxiom = (OWLEquivalentPropertiesAxiom) axiom;
Set equs = equAxiom.getProperties();
for (Iterator iter = equs.iterator(); iter.hasNext(); ) {
OWLProperty prop = (OWLProperty) iter.next();
Set copyEqus = new HashSet(equs);
copyEqus.remove(prop);
for (Iterator iter2 = copyEqus.iterator(); iter2.hasNext(); ) {
OWLProperty prop2 = (OWLProperty) iter2.next();
this.addEquivalentProperty(prop, prop2);
}
}
}
}
}
private void addInverse(OWLObjectProperty p1, OWLObjectProperty p2) {
Set invSet = new HashSet();
if (this.inverses.get(p1)!=null) invSet.addAll((HashSet) inverses.get(p1));
invSet.add(p2);
this.inverses.put(p1, invSet);
}
/**
* Compute top-level classes in the ontology and owl:Thing as their superclass
* @throws OWLException
*/
private void computeTopClasses() throws OWLException {
OWLClass thing = ontology.getOWLDataFactory().getOWLThing();
OWLClass nothing = ontology.getOWLDataFactory().getOWLNothing();
// get set of classes that have atleast one outgoing (subClassOf) link
Set subclasses = outLinks.keySet();
Set topClasses = new HashSet(classes);
// remove subclasses from total set of classes to get top level classes
topClasses.removeAll(subclasses);
topClasses.remove(thing);
topClasses.remove(nothing);
// add owl:Thing as an outgoing link for topClasses alone
for (Iterator iter = topClasses.iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
// also check if equivalents of topClasses have outgoing links
boolean isTop = true;
Set equ = this.equivalentClassesOf(cla);
equ.add(cla);
for (Iterator iter2 = equ.iterator(); iter2.hasNext();) {
OWLClass equCla = (OWLClass) iter2.next();
// check if outgoing links don't come back to equivalent class (cycle)
if (outLinks.containsKey(equCla)) {
Set out = new HashSet((HashSet) outLinks.get(equCla));
out.add(equCla);
isTop = SetUtils.subset(equ, out);
}
}
if (isTop) this.addSubSuperClass(cla, thing);
}
}
private void removeSubSuperClass(OWLClass cl, OWLClass supCl) throws OWLException
{
Set equ = this.equivalentClassesOf(cl);
equ.add(cl);
Set equ2 = this.equivalentClassesOf(supCl);
equ2.add(supCl);
// remove supCl (and all its equivalents) from outLinks
// for key cl (and all its equivalents)
for (Iterator iter = equ.iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
if (outLinks.containsKey(cla)) {
((HashSet) outLinks.get(cla)).removeAll(equ2);
if (((HashSet) outLinks.get(cla)).size()==0) outLinks.remove(cla);
}
}
// remove cl (and all its equivalents) from incLinks
// for key supCl (and all its equivalents)
for (Iterator iter = equ2.iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
if (incLinks.containsKey(cla)) {
((HashSet) incLinks.get(cla)).removeAll(equ);
if (((HashSet) incLinks.get(cla)).size()==0) incLinks.remove(cla);
}
}
}
private void removeSubSuperProperty(OWLProperty p, OWLProperty supP) throws OWLException {
Set equ = this.equivalentPropertiesOf(p);
equ.add(p);
Set equ2 = this.equivalentPropertiesOf(supP);
equ2.add(supP);
// remove supP (and all its equivalents) from outLinks
// for key p (and all its equivalents)
for (Iterator iter = equ.iterator(); iter.hasNext();) {
OWLProperty prop = (OWLProperty) iter.next();
if (outLinks.containsKey(prop)) {
((HashSet) outLinks.get(prop)).removeAll(equ2);
}
}
// remove p (and all its equivalents) from incLinks
// for key supP (and all its equivalents)
for (Iterator iter = equ2.iterator(); iter.hasNext();) {
OWLProperty prop = (OWLProperty) iter.next();
if (incLinks.containsKey(prop)) {
((HashSet) incLinks.get(prop)).removeAll(equ);
}
}
}
/*
* Check for multiple paths in the class/property hierarchy and
* eliminate redundant path(s). This prevents the class/property node
* from occuring twice in the class/property tree along the same hierarchical chain
*/
private void computeMultiplePaths() throws OWLException {
// check multiple subClass hierarchies
// and keep only the lowest hanging class node
// eg. A->B->C and A->C => remove A->C
for (Iterator iter = classes.iterator(); iter.hasNext();) {
// for each class in the ontology
OWLClass cla = (OWLClass) iter.next();
// get set of equivalent superclass sets
Set setOfSets = this.superClassesOf(cla);
for (Iterator iter2=setOfSets.iterator(); iter2.hasNext();) {
// for each superClass set (1)
Set supSet = (HashSet) iter2.next();
// take all *other* superclasses (2)
Set others = new HashSet(setOfSets);
others.remove(supSet);
others = SetUtils.union(others);
// and check for subClass relationship for every class pair (1, 2)
for (Iterator iter3 = supSet.iterator(); iter3.hasNext();) {
Object owlObj = iter3.next();
if (!(owlObj instanceof OWLClass)) continue;
OWLClass supCla = (OWLClass) owlObj;
// check for loops A subCOf B, B subCOf A
if (outLinks.get(supCla)!=null) {
if (((HashSet) outLinks.get(supCla)).contains(cla))
{
this.removeSubSuperClass(cla, supCla);
this.removeSubSuperClass(supCla, cla);
this.addEquivalentClass(cla, supCla);
continue;
}
}
// check for A subCOf B and A=B
if (equivalents.get(cla)!=null) {
if (((HashSet) equivalents.get(cla)).contains(supCla))
{
this.removeSubSuperClass(cla, supCla);
continue;
}
}
// finally check for alternate paths
for (Iterator iter4 = others.iterator(); iter4.hasNext();)
{
OWLClass remCla = (OWLClass) iter4.next();
if (this.isSubClassOf(supCla, remCla))
{
// check to see if cla and remCla are on a circle (if true, don't remove it)
Set sub1 = this.descendantClassesOf( cla );
Set sub2 = this.descendantClassesOf( remCla );
sub1.retainAll( sub2 );
if ( sub1.size() > 0 )
continue;
this.removeSubSuperClass(cla, remCla);
}
}
}
}
}
// do the same for the property hierarchy
for (Iterator iter = properties.iterator(); iter.hasNext();) {
// for each property in the ontology
OWLProperty prop = (OWLProperty) iter.next();
// get set of equivalent superproperty sets
Set setOfSets = this.superPropertiesOf(prop);
for (Iterator iter2=setOfSets.iterator(); iter2.hasNext();) {
// for each superClass set (1)
Set supSet = (HashSet) iter2.next();
// take all *other* superproperty sets (2)
Set others = new HashSet(setOfSets);
others.remove(supSet);
others = SetUtils.union(others);
// and check for subProperty relationship for every property pair (1, 2)
for (Iterator iter3 = supSet.iterator(); iter3.hasNext();) {
Object owlObj = iter3.next();
if (!(owlObj instanceof OWLProperty)) continue;
OWLProperty supProp = (OWLProperty) owlObj;
// check for loops A subPOf B, B subPOf A
if (outLinks.get(supProp)!=null) {
if (((HashSet) outLinks.get(supProp)).contains(prop)) {
this.removeSubSuperProperty(prop, supProp);
this.removeSubSuperProperty(supProp, prop);
this.addEquivalentProperty(prop, supProp);
}
}
for (Iterator iter4 = others.iterator(); iter4.hasNext();) {
OWLProperty remProp = (OWLProperty) iter4.next();
if (this.isSubPropertyOf(supProp, remProp)) {
this.removeSubSuperProperty(prop, remProp);
}
}
}
}
}
}
private void classify() {
try {
init();
this.computeClassRelations();
this.computeMultiplePaths();
this.computeTopClasses();
this.computePropertyRelations();
this.computeIndividualRelations();
}
catch (OWLException e) {
e.printStackTrace();
}
}
public Set getSameAsIndividuals(OWLIndividual ind) {
if (sameAs.containsKey(ind)) return (HashSet) sameAs.get(ind);
else return new HashSet();
}
public Set getDifferentFromIndividuals(OWLIndividual ind) {
if (differentFrom.containsKey(ind)) return (HashSet) differentFrom.get(ind);
else return new HashSet();
}
/**
* Check for assertions/relations involving all individuals in the ontology:
* 1. instance types (assertions)
* 2. sameAs or differentFrom (axioms)
*
*/
private void computeIndividualRelations() throws OWLException {
// check types of individuals
OWLClass thing = ontology.getOWLDataFactory().getOWLThing();
// add owl:Thing as a default type of every individual
Set allindSet = new HashSet();
allindSet.addAll(individuals);
classInds.put(thing, allindSet);
for (Iterator iter = individuals.iterator(); iter.hasNext();) {
OWLIndividual ind = (OWLIndividual) iter.next();
Set types = ind.getTypes(ontologies);
for (Iterator iter2 = types.iterator(); iter2.hasNext();) {
OWLDescription desc = (OWLDescription) iter2.next();
Set indSet = new HashSet();
if (classInds.containsKey(desc)) indSet = (HashSet) classInds.get(desc);
indSet.add(ind);
classInds.put(desc, indSet);
}
}
// iterate through each ontology
Iterator ont = ontologies.iterator();
// check axioms for sameAs and differentFrom assertions b/w individuals
while(ont.hasNext()) {
OWLOntology o = (OWLOntology) ont.next();
// get individual axioms for each ontology
for (Iterator iter = o.getIndividualAxioms().iterator(); iter.hasNext(); ){
OWLIndividualAxiom indAxiom = (OWLIndividualAxiom) iter.next();
// get the set of individuals participating in each axiom
Set inds = indAxiom.getIndividuals();
Map map = null;
if (indAxiom instanceof OWLSameIndividualsAxiom) map = sameAs;
else map = differentFrom;
// add it to the corresponding map
for (Iterator iter2 = inds.iterator(); iter2.hasNext(); ) {
Set copyInds = new HashSet(inds); // create copy of set
OWLIndividual ind = (OWLIndividual) iter2.next();
copyInds.remove(ind);
if (map.get(ind)==null) {
// put new set
map.put(ind, copyInds);
}
else {
// add to existing set
Set current = (HashSet) map.get(ind);
current.addAll(copyInds);
map.put(ind, current);
}
}
}
}
}
public String getName() {
return "RDFS-like";
}
/**
* refreshOntology
*
*
*/
private void refreshOntology() throws OWLException {
if(ontology != null) setOntology(ontology);
}
public void setLoadImports(boolean useImports, boolean refresh) throws OWLException {
this.loadImports = useImports;
if (refresh) this.refreshOntology();
}
public boolean loadImports() {
return this.loadImports;
}
public boolean isConsistent() {
return true;
}
public boolean isConsistent(OWLClass c) throws OWLException {
return true;
}
public Set typesOf(OWLIndividual ind) throws OWLException {
Set types = ind.getTypes(ontologies);
// remove unnamed types
for (Iterator iter = new HashSet(types).iterator(); iter.hasNext();) {
OWLDescription desc = (OWLDescription) iter.next();
if (!(desc instanceof OWLClass)) types.remove(desc);
}
return this.getSetofEquivalentSets(types);
}
public String getExpressivity() throws OWLException {
if (indices!=null) {
String expressivity = indices.getExpressivity(ontology);
return ExpressivityChecker.getExplanation(expressivity);
}
return "Unable to determine";
}
public Set allTypesOf(OWLIndividual ind) throws OWLException {
Set types = ind.getTypes(ontologies);
Set copy = new HashSet(types);
for (Iterator iter = copy.iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
List classTracker = new ArrayList();
Set resultSet = this.getClassHierarchy(cla, classTracker, "SUPER");
types.addAll(resultSet);
}
// return set of sets
return this.getSetofEquivalentSets(types);
}
public Set disjointClassesOf(OWLClass c) throws OWLException {
if (disjoints.containsKey(c))
return this.getSetofEquivalentSets((HashSet) disjoints.get(c));
else return new HashSet();
}
public Set complementClassesOf(OWLClass c) throws OWLException {
if (complements.containsKey(c))
return this.getSetofEquivalentSets((HashSet) complements.get(c));
else return new HashSet();
}
public Set getOntologies() {
return this.ontologies;
}
public Set getClasses() {
return new HashSet(classes);
}
public Set getProperties() {
return new HashSet(properties);
}
public Set getObjectProperties() {
Set set = new HashSet();
for(int i = 0; i < properties.size(); i++)
if(properties.get(i) instanceof OWLObjectProperty)
set.add(properties.get(i));
return set;
}
public Set getDataProperties() {
Set set = new HashSet();
for(int i = 0; i < properties.size(); i++)
if(properties.get(i) instanceof OWLDataProperty)
set.add(properties.get(i));
return set;
}
public Set getAnnotationProperties() {
Set set = new HashSet();
for(int i = 0; i < properties.size(); i++)
if(properties.get(i) instanceof OWLAnnotationProperty)
set.add(properties.get(i));
return set;
}
public Set getIndividuals() {
return new HashSet(individuals);
}
public boolean supportsExplanation() {
return false;
}
public void setDoExplanation(boolean explain) {
}
public boolean getDoExplanation() {
return false;
}
public String getExplanation(ShortFormProvider shortForms) {
return null;
}
public Set getExplanationSet() {
return null;
}
public Set instancesOf(OWLClass c) throws OWLException {
return this.instancesOf((OWLDescription) c);
}
public Set allInstancesOf(OWLClass c) throws OWLException {
// get all descendents of class c
List classTracker = new ArrayList();
Set descendants = this.getClassHierarchy(c, classTracker, "SUB");
descendants.add(c);
Set resultSet = new HashSet();
for (Iterator iter = descendants.iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
resultSet.addAll(this.instancesOf(cla));
}
return resultSet;
}
public OWLOntology getOntology() throws OWLException {
return ontology;
}
public boolean isSubClassOf(OWLDescription d1, OWLDescription d2) throws OWLException {
if (d1 instanceof OWLClass && d2 instanceof OWLClass) {
OWLClass cl = (OWLClass) d1;
List classTracker = new ArrayList();
Set ancestors = this.getClassHierarchy(cl, classTracker, "SUPER");
return (ancestors.contains(d2));
}
else return false;
}
public boolean isEquivalentClass(OWLDescription d1, OWLDescription d2) throws OWLException {
if (this.equivalents.containsKey(d1)) {
return ((HashSet) equivalents.get(d1)).contains(d2);
}
else return false;
}
public boolean isConsistent(OWLDescription d1) throws OWLException {
return true;
}
public Set superClassesOf(OWLDescription d) throws OWLException {
Set resultSet = new HashSet();
Set claSet = new HashSet();
claSet.add(d);
// also find equivalents
if (equivalents.containsKey(d)) {
claSet.addAll((HashSet) equivalents.get(d));
}
// get direct superclasses of all classes in claSet
for (Iterator iter = claSet.iterator(); iter.hasNext();) {
OWLDescription desc = (OWLDescription) iter.next();
if (desc instanceof OWLClass && outLinks.containsKey(desc)) {
Set superClaSet = (HashSet) this.outLinks.get(desc);
resultSet.addAll(this.getSetofEquivalentSets(superClaSet));
}
}
return resultSet;
}
public Set ancestorClassesOf(OWLDescription d) throws OWLException {
Set resultSet = new HashSet();
if (d instanceof OWLClass) {
OWLClass cl = (OWLClass) d;
List classTracker = new ArrayList();
resultSet = this.getClassHierarchy(cl, classTracker, "SUPER");
}
return this.getSetofEquivalentSets(resultSet);
}
public Set getClassHierarchy(OWLClass cl, List tracker, String dirn) throws OWLException {
Set setOfSets = new HashSet();
if (dirn.equals("SUPER")) setOfSets = this.superClassesOf(cl); // return superclass sets
else setOfSets = this.subClassesOf(cl); // return subclass sets
for (Iterator iter = setOfSets.iterator(); iter.hasNext();) {
Set set = (HashSet) iter.next(); // get each equivalent superClass set
for (Iterator iter2=set.iterator(); iter2.hasNext();) {
OWLClass cla = (OWLClass) iter2.next();
if (!tracker.contains(cla)) {
tracker.add(cla);
// recurse
getClassHierarchy(cla, tracker, dirn);
}
else {
// cycle found!
// verify cycle: check for a subclass from supCla to cl
// i.e. check if owl:Thing is one of the links inbetween
int pos1 = tracker.indexOf(cla);
int pos2 = tracker.indexOf(cl);
boolean cycle = true;
OWLClass thing = ontology.getOWLDataFactory().getOWLThing();
OWLClass nothing = ontology.getOWLDataFactory().getOWLNothing();
for (int i=pos1; i<pos2; i++) {
if (dirn.equals("SUPER")) {
if (tracker.get(i).equals(thing)) cycle = false;
}
else {
if (tracker.get(i).equals(nothing)) cycle = false;
}
}
if (cycle)
{
this.addEquivalentClass( cl, cla );
}
}
}
}
return new HashSet(tracker);
}
public Set subClassesOf(OWLDescription d) throws OWLException {
Set resultSet = new HashSet();
Set claSet = new HashSet();
claSet.add(d);
// also find equivalents
if (equivalents.containsKey(d)) {
claSet.addAll((HashSet) equivalents.get(d));
}
// get direct subclasses of all classes in claSet
for (Iterator iter = claSet.iterator(); iter.hasNext();) {
OWLDescription desc = (OWLDescription) iter.next();
if (desc instanceof OWLClass && incLinks.containsKey(desc))
{
Set subClaSet = (HashSet) this.incLinks.get(desc);
resultSet.addAll(this.getSetofEquivalentSets(subClaSet));
}
}
return resultSet;
}
public Set descendantClassesOf(OWLDescription d) throws OWLException {
Set resultSet = new HashSet();
if (d instanceof OWLClass) {
OWLClass cl = (OWLClass) d;
List classTracker = new ArrayList();
resultSet = this.getClassHierarchy(cl, classTracker, "SUB");
}
return this.getSetofEquivalentSets(resultSet);
}
public Set equivalentClassesOf(OWLDescription d) throws OWLException {
if (d instanceof OWLClass && equivalents.containsKey(d)) {
Set equSet = new HashSet((HashSet) equivalents.get(d));
equSet.remove(d);
return equSet;
}
return new HashSet();
}
public boolean isInstanceOf(OWLIndividual i, OWLDescription d) throws OWLException {
return false;
}
public Set instancesOf(OWLDescription d) throws OWLException {
Set resultSet = new HashSet();
Set claSet = new HashSet();
claSet.add(d);
// also find equivalents
if (equivalents.containsKey(d)) {
claSet.addAll((HashSet) equivalents.get(d));
}
// get individuals of all classes in claSet
for (Iterator iter = claSet.iterator(); iter.hasNext();) {
OWLClass cla = (OWLClass) iter.next();
if (classInds.containsKey(cla)) {
Set inds = (HashSet) classInds.get(cla);
resultSet.addAll(inds);
}
}
return resultSet;
}
public boolean isSubPropertyOf(OWLProperty p1, OWLProperty p2) throws OWLException {
Set ancestors = this.getPropertyHierarchy(p1, new ArrayList(), "SUPER");
return ancestors.contains(p2);
}
public Set superPropertiesOf(OWLProperty prop) throws OWLException {
Set resultSet = new HashSet();
Set propSet = new HashSet();
propSet.add(prop);
// also find equivalents
if (equivalents.containsKey(prop)) {
propSet.addAll((HashSet) equivalents.get(prop));
}
// get direct superproperties of all properties in propSet
for (Iterator iter = propSet.iterator(); iter.hasNext();) {
OWLProperty p = (OWLProperty) iter.next();
if (outLinks.containsKey(p)) {
Set subPropSet = (HashSet) this.outLinks.get(p);
resultSet.addAll(this.getSetofEquivalentSets(subPropSet));
}
}
return resultSet;
}
public Set ancestorPropertiesOf(OWLProperty prop) throws OWLException {
List propTracker = new ArrayList();
Set ancestors = this.getPropertyHierarchy(prop, propTracker, "SUPER");
return this.getSetofEquivalentSets(ancestors);
}
public Set getPropertyHierarchy(OWLProperty p, List tracker, String dirn) throws OWLException {
Set setOfSets = new HashSet();
if (dirn.equals("SUPER")) setOfSets = this.superPropertiesOf(p); // return superclass sets
else setOfSets = this.subPropertiesOf(p); // return subclass sets
for (Iterator iter = setOfSets.iterator(); iter.hasNext();) {
Set set = (HashSet) iter.next(); // get each equivalent superClass set
for (Iterator iter2=set.iterator(); iter2.hasNext();) {
OWLProperty prop = (OWLProperty) iter2.next();
if (!tracker.contains(prop)) {
tracker.add(prop);
// recurse
getPropertyHierarchy(prop, tracker, dirn);
}
else {
// cycle found!
}
}
}
return new HashSet(tracker);
}
/**
* Return a 'set of equivalent sets' given a set of objects i.e. for each
* object 'obj' in the input set, get its equivalent set (using the hashmap
* 'equivalents') and add it to result set
* @param set - set of objects whose equivalents have to be determined
* @return
*/
public Set getSetofEquivalentSets(Set set) {
Set resultSet = new HashSet();
for (Iterator iter = set.iterator(); iter.hasNext(); ) {
Object obj = iter.next();
Set equObjs = new HashSet();
equObjs.add(obj);
if (equivalents.containsKey(obj)) equObjs = (HashSet) equivalents.get(obj);
resultSet.add(equObjs);
}
return resultSet;
}
public Set subPropertiesOf(OWLProperty prop) throws OWLException {
Set resultSet = new HashSet();
Set propSet = new HashSet();
propSet.add(prop);
// also find equivalents
if (equivalents.containsKey(prop)) {
propSet.addAll((HashSet) equivalents.get(prop));
}
// get direct subproperties of all properties in propSet
for (Iterator iter = propSet.iterator(); iter.hasNext();) {
OWLProperty p = (OWLProperty) iter.next();
if (incLinks.containsKey(p)) {
Set subPropSet = (HashSet) this.incLinks.get(p);
resultSet.addAll(this.getSetofEquivalentSets(subPropSet));
}
}
return resultSet;
}
public Set descendantPropertiesOf(OWLProperty prop) throws OWLException {
List propTracker = new ArrayList();
Set descendents = this.getPropertyHierarchy(prop, propTracker, "SUB");
return this.getSetofEquivalentSets(descendents);
}
public Set equivalentPropertiesOf(OWLProperty prop) throws OWLException {
if (equivalents.containsKey(prop)) {
Set equSet = new HashSet((HashSet) equivalents.get(prop));
equSet.remove(prop);
return equSet;
}
return new HashSet();
}
public Set inversePropertiesOf(OWLObjectProperty prop) throws OWLException {
if (this.inverses.containsKey(prop)) {
Set inverses = (Set) this.inverses.get(prop);
return this.getSetofEquivalentSets(inverses);
}
else return this.getSetofEquivalentSets(new HashSet());
}
public Set rangesOf(OWLProperty prop) throws OWLException {
Set ranges = prop.getRanges(ontologies);
// return ranges;
return SetUtils.union(this.getSetofEquivalentSets(ranges));
}
public Set domainsOf(OWLProperty prop) throws OWLException {
Set domains = prop.getDomains(ontologies);
// return domains;
return SetUtils.union(this.getSetofEquivalentSets(domains));
}
public Set superClassesOf(OWLClass cl) throws OWLException {
return this.superClassesOf((OWLDescription) cl);
}
public Set ancestorClassesOf(OWLClass cl) throws OWLException {
return this.ancestorClassesOf((OWLDescription) cl);
}
public Set subClassesOf(OWLClass cl) throws OWLException {
return this.subClassesOf((OWLDescription) cl);
}
public Set descendantClassesOf(OWLClass cl) throws OWLException {
return this.descendantClassesOf((OWLDescription) cl);
}
public Set equivalentClassesOf(OWLClass cl) throws OWLException {
return this.equivalentClassesOf((OWLDescription) cl);
}
public void buildIndices() {
indices = new OntologyIndices(this);
indices.buildIndex(ontology, loadImports, true);
// System.out.println("Expressivity:" +indices.getExpressivity(ontology));
}
public Map getDataPropertyValues(OWLIndividual ind) throws OWLException {
return ind.getDataPropertyValues( getOntologies() );
}
public Map getObjectPropertyValues(OWLIndividual ind) throws OWLException{
return ind.getObjectPropertyValues( getOntologies() );
}
}