/* * Created on Feb 14, 2005 * */ package org.mindswap.swoop.utils.owlapi; import java.io.Serializable; 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.SwoopModel; import org.mindswap.swoop.reasoner.SwoopRDFSReasoner; import org.mindswap.swoop.reasoner.SwoopReasoner; import org.mindswap.swoop.renderer.entity.ConciseFormatEntityRenderer; import org.mindswap.swoop.utils.SetUtils; import org.mindswap.swoop.utils.graph.hierarchy.popup.ConcisePlainVisitor; import org.semanticweb.owl.model.OWLAnd; import org.semanticweb.owl.model.OWLCardinalityRestriction; import org.semanticweb.owl.model.OWLClass; import org.semanticweb.owl.model.OWLClassAxiom; import org.semanticweb.owl.model.OWLDataAllRestriction; import org.semanticweb.owl.model.OWLDataCardinalityRestriction; import org.semanticweb.owl.model.OWLDataEnumeration; import org.semanticweb.owl.model.OWLDataProperty; import org.semanticweb.owl.model.OWLDataQuantifiedRestriction; import org.semanticweb.owl.model.OWLDataRange; import org.semanticweb.owl.model.OWLDataType; import org.semanticweb.owl.model.OWLDataValueRestriction; import org.semanticweb.owl.model.OWLDescription; import org.semanticweb.owl.model.OWLDisjointClassesAxiom; import org.semanticweb.owl.model.OWLEntity; import org.semanticweb.owl.model.OWLEnumeration; 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.OWLNaryBooleanDescription; import org.semanticweb.owl.model.OWLNot; import org.semanticweb.owl.model.OWLObject; import org.semanticweb.owl.model.OWLObjectAllRestriction; import org.semanticweb.owl.model.OWLObjectCardinalityRestriction; import org.semanticweb.owl.model.OWLObjectProperty; import org.semanticweb.owl.model.OWLObjectQuantifiedRestriction; import org.semanticweb.owl.model.OWLObjectRestriction; import org.semanticweb.owl.model.OWLObjectValueRestriction; 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.OWLRestriction; import org.semanticweb.owl.model.OWLSubClassAxiom; import org.semanticweb.owl.model.OWLSubPropertyAxiom; import org.semanticweb.owl.model.helper.OntologyHelper; /** * @author Aditya * * Defines what types of cross-references need to be indexed * for a particular ontology. Used in BuildIndices.java where ontology * and the computed indices are finally stored */ public class OntologyIndices implements Serializable { private Set ontologies; // current ontology set being indexed private List classes, properties, individuals; private List classAxioms, propAxioms, indAxioms; public Set unions, intersections, disjointAxioms; public Set descriptions; public Map descriptionToEntity; //Key: description, Value: any named entity - Class, Property, Individual where the description appears public Map restrictionToEntity; //Key: restriction, Value: any named entity - Class, Property, Individual where the restriction appears public Map equivalents; //Key: OWL Object, Value: OWL Object public Map classesToPropertiesRestriction;//Key: elements of classes in Restrictions //Content: properties in those restrictions public Map individualsToPropertiesRestriction;//Key: Elements of individualsInRestriction //Content: properties in those restrictions public Map individualsToPropertiesAssertions; // key: Individuals b, // Value: properties related to it by abox assertions // *** but R(a,b) *** public Map individualsInEnumerations; // key - a, value - enumeration which contains a public Map propToIndividualAssertions; //key: property R, value: individual a, such that R(a,b) public Map propToDescriptionRestrictions; // key: property R, value: Description C which is a restriction on property R public Map classesToDomain; //Key: Classes and class descriptions that are domain of some property //Value: The properties they are domain of public Map classesToRange; // analogous to domain public Map classesInUnions; // Class descriptions appearing in Unions public Map classesInIntersections; // Class Descriptions appearing in intersections public Map nestedRestrictions; // Key: An object property R // Value: A Set S1,...,Sn of object properties // Means that S1,...,Sn appear in a restriction nested inside a restriction on R public SwoopReasoner reasoner; // need the below to obtain sub/super for descriptions as well // cannot use reasoner because it returns only named classes // and no need to use OWLDescriptionFinder because it will loop // over all entities/axioms again public Map subClasses, superClasses, subProperties, superProperties, instancesOf; // This is for computing expressivity boolean hasNegation = false; boolean hasTransitivity = false; boolean hasRoleHierarchy = false; boolean hasInverse = false; boolean hasNominals = false; boolean hasCardinality = false; boolean hasFunctionality = false; boolean hasDatatype = false; boolean hasUnion = false; boolean hasIntersection = false; boolean hasRange = false; boolean hasComplexRestriction = false; boolean isDLLite = true; boolean isRDFS = true; boolean isEL = true; boolean isELpp = true; //EL++ // DEBUGGING TAGS (construct tags) boolean DEBUG_NOMINALS = false; boolean DEBUG_NEGATIONS = false; boolean DEBUG_UNIONS = false; boolean DEBUG_HASCOMPLEXRESTRICTION = false; // DEBUGGING TAGS (expressivity tags) boolean DEBUG_IS_EL = false; public OntologyIndices(SwoopReasoner reasoner) { if (reasoner==null) this.reasoner = new SwoopRDFSReasoner(); else this.reasoner = reasoner; } public void buildIndex( OWLOntology ontology, boolean indexImports, // consider imported ontologies? boolean skipReasoning // can be called by reasoner directly after it does its classification ) { if (!skipReasoning) { try { // set reasoner to classify ontology reasoner.setOntology(ontology); } catch (OWLException e2) { e2.printStackTrace(); } } // first determine set of ontologies if (indexImports) try { ontologies = OntologyHelper.importClosure(ontology); } catch (OWLException e) { e.printStackTrace(); } else ontologies = Collections.singleton(ontology); try { // initialize to get list of entities and axioms in ontologies // also reset all maps this.init(); // parse ontology and build corresponding indices this.parseOntology(); } catch (OWLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } /** * Compute expressivity for a single OWL ontology according to the information * in the Maps * @param ontology */ public String getExpressivity(OWLOntology ont) { String dl = ""; if(isRDFS == true){ dl = "RDFS(DL)"; return dl; } if(isDLLite == true){ dl= "DL-Lite"; return dl; } if ( (isELpp) && (isEL == false)) return "EL++"; if((isEL == true)){ dl = "EL"; if(hasUnion == true) dl += "U"; if(hasInverse == true) dl += "I"; if(hasRoleHierarchy == true) dl += "H"; if(hasCardinality == true) dl += "N"; else if(hasFunctionality == true) dl += "F"; if(hasDatatype == true) dl += "(D)"; return dl; } if(hasNegation==true || hasUnion ==true || hasComplexRestriction == true) dl = "ALC"; else dl = "AL"; if(hasTransitivity == true) dl += "R+"; if(dl.equals("ALCR+")) dl = "S"; if(hasRoleHierarchy == true) dl += "H"; if(hasInverse == true) dl += "I"; if(hasNominals == true) dl += "O"; if(hasCardinality == true) dl += "N"; else if(hasFunctionality == true) dl += "F"; if(hasDatatype == true) dl += "(D)"; return dl; } /** * Obtain classes, properties, individuals and axioms in the set * of ontologies to be indexed. Also, reset all index maps * @throws OWLException */ private void init() throws OWLException { classes = new ArrayList(); properties = new ArrayList(); individuals = new ArrayList(); classAxioms = new ArrayList(); propAxioms = new ArrayList(); indAxioms = new ArrayList(); Iterator ont = ontologies.iterator(); while(ont.hasNext()) { OWLOntology o = (OWLOntology) ont.next(); classes.addAll(o.getClasses()); properties.addAll(o.getObjectProperties()); properties.addAll(o.getDataProperties()); individuals.addAll(o.getIndividuals()); classAxioms.addAll(o.getClassAxioms()); propAxioms.addAll(o.getPropertyAxioms()); indAxioms.addAll(o.getIndividualAxioms()); //For expressivity if(!(o.getDataProperties().isEmpty())) hasDatatype = true; } // reset all index maps this.descriptions = new HashSet(); this.unions = new HashSet(); this.intersections = new HashSet(); this.disjointAxioms = new HashSet(); this.descriptionToEntity = new HashMap(); this.restrictionToEntity = new HashMap(); this.equivalents = new HashMap(); this.classesToPropertiesRestriction = new HashMap(); this.individualsToPropertiesRestriction = new HashMap(); this.individualsToPropertiesAssertions = new HashMap(); this.individualsInEnumerations = new HashMap(); this.propToIndividualAssertions = new HashMap(); this.propToDescriptionRestrictions = new HashMap(); this.classesInIntersections = new HashMap(); this.classesInUnions = new HashMap(); this.classesToDomain = new HashMap(); this.classesToRange = new HashMap(); this.nestedRestrictions = new HashMap(); this.subClasses = new HashMap(); this.superClasses = new HashMap(); this.subProperties = new HashMap(); this.superProperties = new HashMap(); this.instancesOf = new HashMap(); } private void parseOntology() throws OWLException{ Iterator it = classes.iterator(); while(it.hasNext()){ OWLClass cla = (OWLClass)it.next(); // handle class equivalents Set eqs = cla.getEquivalentClasses(ontologies); // add to equivalentClasses map this.addEquivalentSet(eqs, cla); Iterator i = eqs.iterator(); while(i.hasNext()) { OWLDescription desc = (OWLDescription) i.next(); lookInsideDescription(desc, cla); } // handle subclasses http://www.gnowsis.org/ont/vcard Set subs = cla.getSubClasses(ontologies); // add to subClasses map this.addToMap(this.subClasses, cla, subs); Iterator j = subs.iterator(); while(j.hasNext()) { OWLDescription desc = (OWLDescription) j.next(); lookInsideDescription(desc, cla); } // handle superclasses Set sups = cla.getSuperClasses(ontologies); // add to superClasses map this.addToMap(this.superClasses, cla, sups); Iterator k = sups.iterator(); while(k.hasNext()) { OWLDescription desc = (OWLDescription) k.next(); lookInsideDescription(desc, cla); } // adding enumerations checking (tw7) Set enumerations = cla.getEnumerations(ontologies); Iterator l = enumerations.iterator(); while(l.hasNext()) { OWLDescription desc = (OWLDescription) l.next(); lookInsideDescription(desc, cla); } } // handle class axioms for (Iterator iter = classAxioms.iterator(); iter.hasNext();) { OWLClassAxiom axiom = (OWLClassAxiom) iter.next(); if (axiom instanceof OWLSubClassAxiom) { OWLSubClassAxiom subAxiom = (OWLSubClassAxiom) axiom; OWLDescription sub = subAxiom.getSubClass(); OWLDescription sup = subAxiom.getSuperClass(); // add to sub/super classes map this.addToMap(this.subClasses, sup, sub); this.addToMap(this.superClasses, sub, sup); descriptions.add(sub); descriptions.add(sup); // and also look inside description lookInsideDescription(sub, null); lookInsideDescription(sup, null); } else if (axiom instanceof OWLEquivalentClassesAxiom) { OWLEquivalentClassesAxiom equAxiom = (OWLEquivalentClassesAxiom) axiom; // add to equivalentClasses map this.addEquivalentSet(equAxiom.getEquivalentClasses(), null); this.lookInsideSet(equAxiom.getEquivalentClasses()); } else if (axiom instanceof OWLDisjointClassesAxiom) { //OWLDIsjointClassAxiom implies existence of OWL:ComplementOf // Note that we can have disjoints without having disjoint axioms // if we have GCIs. e.g. (intersection(C,D) subclassOf OWL:Nothing) // this says that C and D are disjoint. No negation used. //For expressivity this.hasNegation = true; this.isRDFS = false; // no disjoint construct if (DEBUG_IS_EL) System.out.println("Not EL! Disjoint Axiom Found: in " + axiom); this.isEL = false; //EL has no bottom concept // add to disjointAxioms set this.disjointAxioms.add(axiom); OWLDisjointClassesAxiom disAxiom = (OWLDisjointClassesAxiom) axiom; this.lookInsideSet(disAxiom.getDisjointClasses()); } } // handle property domains/ranges Iterator t = properties.iterator(); while(t.hasNext()) { OWLProperty prop = (OWLProperty)t.next(); //For expressivity if (prop instanceof OWLObjectProperty){ if(((OWLObjectProperty)prop).isTransitive(ontologies)) { isDLLite = false; isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! Transitivity Found: in " + prop ); isEL = false; hasTransitivity = true; } if(((OWLObjectProperty)prop).isSymmetric(ontologies)){ hasInverse = true; isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! Symmetry Found: in " + prop ); isEL = false; isELpp = false; } if(!(((OWLObjectProperty)prop).getInverses(ontologies).isEmpty())){ hasInverse = true; isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! Inverse Found: in " + prop ); isEL = false; isELpp = false; } if(((OWLObjectProperty)prop).isFunctional(ontologies)){ isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! Functionality Found: in " + prop ); isEL = false; isELpp = false; hasFunctionality = true; } /* tw7 * Inverse functional can be simulated using a property that has * an inverse, and that inverse is functional. * * */ if (((OWLObjectProperty)prop).isInverseFunctional(ontologies)) { hasFunctionality = true; hasInverse = true; isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! InverseFunctionality Found: in " + prop ); isEL = false; isELpp = false; } } /* else { // also check for datatype properties // though for OWL Lite and DL, datatype properties are not supposed to // be transitive, symmetric, inverse, or inverse functional // OWLAPI does not provide methods for these attributes, only functional // (tw7) if(((OWLDataProperty)prop).isFunctional(ontologies)){ hasFunctionality = true; if (DEBUG_IS_EL) System.out.println("Not EL! Functionality Found: in " + prop ); isEL = false; isELpp = false; isRDFS = false; } } */ // handle prop domains and ranges Iterator g = prop.getDomains(ontologies).iterator(); while(g.hasNext()){ OWLDescription desc = (OWLDescription)g.next(); lookInsideDescription(desc, prop, true, false, false); } Iterator b = prop.getRanges(ontologies).iterator(); if(prop instanceof OWLObjectProperty) { while(b.hasNext()) { //expressivity hasRange = true; OWLDescription desc = (OWLDescription)b.next(); lookInsideDescription(desc, prop, false, true, false); } } // get superprops and add it to corresponding maps Set supProp = prop.getSuperProperties(ontologies); this.addToMap(this.superProperties, prop, supProp); for (Iterator iter = supProp.iterator(); iter.hasNext();) { OWLProperty sup = (OWLProperty) iter.next(); this.addToMap(this.subProperties, sup, prop); } } // handle property axioms for (Iterator iter = propAxioms.iterator(); iter.hasNext();) { OWLPropertyAxiom axiom = (OWLPropertyAxiom) iter.next(); //For expressivity this.isDLLite = false; this.hasRoleHierarchy = true; // add subproperty axiom info to hashmaps if (axiom instanceof OWLSubPropertyAxiom) { OWLSubPropertyAxiom subAxiom = (OWLSubPropertyAxiom) axiom; this.addToMap(this.superProperties, subAxiom.getSubProperty(), subAxiom.getSuperProperty()); this.addToMap(this.subProperties, subAxiom.getSuperProperty(), subAxiom.getSubProperty()); } // add equivalent props axiom info to hashmap if (axiom instanceof OWLEquivalentPropertiesAxiom) { OWLEquivalentPropertiesAxiom equAxiom = (OWLEquivalentPropertiesAxiom) axiom; this.addEquivalentPropSet(equAxiom.getProperties()); } } // handle individuals for (Iterator iter = individuals.iterator(); iter.hasNext(); ) { OWLIndividual ind = (OWLIndividual) iter.next(); // get types Set types = ind.getTypes(ontologies); for (Iterator iter2= types.iterator(); iter2.hasNext();) { OWLDescription desc = (OWLDescription) iter2.next(); //Test descriptions.add(desc); this.addToMap(this.instancesOf, desc, ind); } // get object property-value assertions Map oValues = ind.getObjectPropertyValues(ontologies); for (Iterator iter2 = oValues.keySet().iterator(); iter2.hasNext();) { OWLObjectProperty prop = (OWLObjectProperty) iter2.next(); // add to prop->ind map this.addToMap(this.propToIndividualAssertions, prop, ind); Set vals = (HashSet) oValues.get(prop); for (Iterator iter3 = vals.iterator(); iter3.hasNext();) { OWLIndividual valueInd = (OWLIndividual) iter3.next(); // add to ind->prop map such that R(b,a): b->R this.addToMap(this.individualsToPropertiesAssertions, valueInd, prop); } } // get data property-value assertions Map dValues = ind.getDataPropertyValues(ontologies); for (Iterator iter2 = dValues.keySet().iterator(); iter2.hasNext();) { OWLDataProperty prop = (OWLDataProperty) iter2.next(); // add to prop->ind map this.addToMap(this.propToIndividualAssertions, prop, ind); } } //expressivity; if(hasInverse == false && hasRange == true) { if (DEBUG_IS_EL) System.out.println("Not EL! Has no Inverse, but has Range."); isEL = false; } } private void lookInsideDescription(OWLDescription desc, OWLEntity entity) throws OWLException { this.lookInsideDescription(desc, entity, false, false, false); } private void lookInsideDescription( OWLDescription desc, OWLEntity entity, boolean checkingDomain, boolean checkingRange, boolean checkingNestedRestriction ) throws OWLException { OWLClass owlThing = reasoner.getOntology().getOWLDataFactory().getOWLThing(); OWLClass owlNothing = reasoner.getOntology().getOWLDataFactory().getOWLNothing(); try { // add to description set anyway this.descriptions.add(desc); // add to Description->Entity map if (entity!=null) this.addToMap(this.descriptionToEntity, desc, entity); // add to Classes/Descriptions -> property map for domain/range if (entity!=null && entity instanceof OWLProperty) { if (checkingDomain) { this.addToMap(this.classesToDomain, desc, entity); // also if P has domain C, then any subproperty of P has domain C Set descendants = SetUtils.union(reasoner.descendantPropertiesOf((OWLProperty) entity)); for (Iterator iter = descendants.iterator(); iter.hasNext();) { this.addToMap(this.classesToDomain, desc, (OWLProperty) iter.next()); } } if (checkingRange) { this.addToMap(this.classesToRange, desc, entity); // also if P has range C, then any subproperty of P has range C Set descendants = SetUtils.union(reasoner.descendantPropertiesOf((OWLProperty) entity)); for (Iterator iter = descendants.iterator(); iter.hasNext();) { this.addToMap(this.classesToRange, desc, (OWLProperty) iter.next()); } } // also check and add to nestedRestrictions map if (checkingNestedRestriction && desc instanceof OWLObjectRestriction) { this.addToMap(this.nestedRestrictions, entity, ((OWLObjectRestriction) desc).getObjectProperty()); //For expressivity this.isDLLite = false; this.isRDFS = false; } } if(desc instanceof OWLAnd){ this.intersections.add(desc); Iterator it = ((OWLNaryBooleanDescription)desc).getOperands().iterator(); while(it.hasNext()) { // add to classes in intersections map OWLDescription andOperand = (OWLDescription) it.next(); this.addToMap(this.classesInIntersections, andOperand, desc); lookInsideDescription(andOperand, entity, checkingDomain, checkingRange, checkingNestedRestriction); } } if(desc instanceof OWLOr){ this.unions.add(desc); //For expressivity this.isDLLite = false; this.isEL = false; this.isELpp = false; this.isRDFS = false; if (DEBUG_UNIONS) System.out.println("<Has Union>: in " + entity + " using " + desc); this.hasUnion = true; // Iterator it = ((OWLNaryBooleanDescription)desc).getOperands().iterator(); while(it.hasNext()) { // add to classes in unions map OWLDescription orOperand = (OWLDescription) it.next(); this.addToMap(this.classesInUnions, orOperand, desc); lookInsideDescription(orOperand, entity, checkingDomain, checkingRange, checkingNestedRestriction); } } if(desc instanceof OWLNot){ //For expressivity OWLDescription de = ((OWLNot)desc).getOperand(); if(!(de instanceof OWLClass)){ this.isDLLite = false; } // OWLNothing complementOf OWLThing does not count for 'hasNegation' tw7 if ( ( de instanceof OWLClass ) && ( entity instanceof OWLClass )) { OWLClass a = (OWLClass)entity; OWLClass b = (OWLClass)de; if (! ((a.equals(owlThing) && b.equals(owlNothing)) || (a.equals(owlNothing) && b.equals(owlThing))) ) { if (DEBUG_NEGATIONS) System.out.println("<Has Negation>: in " + a + " using " + b); this.hasNegation = true; this.isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! Complement Found: in " + entity + " using " +de ); this.isEL = false; this.isELpp = false; } } else { if (DEBUG_NEGATIONS) System.out.println("<Has Negation>: in " + entity + " using " + desc ); this.hasNegation = true; this.isRDFS = false; if (DEBUG_IS_EL) System.out.println("Not EL! Complement Found: in " + entity + " using " +de ); this.isEL = false; this.isELpp = false; } lookInsideDescription(((OWLNot)desc).getOperand(), entity, checkingDomain, checkingRange, checkingNestedRestriction); } if (desc instanceof OWLEnumeration) { // add individual->enumeration to corresponding hashmap OWLEnumeration enu = (OWLEnumeration) desc; if ( DEBUG_NOMINALS ) { System.out.println( "<Nominals>: " + entity + " Has Enumeration " + desc); Set inds = enu.getIndividuals(); for ( Iterator it = inds.iterator(); it.hasNext();) { OWLIndividual ind = (OWLIndividual)it.next(); System.out.println(" " + ind.toString() ); } /* ConcisePlainVisitor visitor = new ConcisePlainVisitor( new ConciseFormatEntityRenderer(), null); desc.accept( visitor ); String str = visitor.result(); System.out.println( " = " + str); */ } //For expressivity this.isRDFS = false; this.isDLLite = false; this.hasNominals = true; if (DEBUG_IS_EL) System.out.println( entity + "Not EL! has Enumeration: " + desc ); this.isEL = false; if ( enu.getIndividuals().size() > 1) { if (DEBUG_UNIONS) System.out.println("<Has Union>: Enumeration in " + entity + " using " + desc); this.hasUnion = true; //(tw7) OneOf that has more than 1 element is disjunction this.isELpp = false; //(tw7) EL++ only allows for enum of single element } // for (Iterator iter = enu.getIndividuals().iterator(); iter.hasNext();) { OWLIndividual ind = (OWLIndividual) iter.next(); this.addToMap(this.individualsInEnumerations, ind, desc); } } if(desc instanceof OWLRestriction){ // add to prop->Description map OWLProperty prop = ((OWLRestriction) desc).getProperty(); //For expressivity this.isRDFS = false; //RDFS has no restrictions // only check for object restrictions because datatype restrictins are handled // by datatype reasoners and don't necessaritly cause compexity jump (?) (from Bijan) if ( desc instanceof OWLObjectQuantifiedRestriction) { if ( desc instanceof OWLObjectQuantifiedRestriction ) { if(!(((OWLObjectQuantifiedRestriction)desc).getDescription().equals(owlThing))) this.isDLLite = false; } if ((desc instanceof OWLObjectAllRestriction) || (desc instanceof OWLDataQuantifiedRestriction)) { this.isDLLite = false; // causes intractability (tw7) if (DEBUG_IS_EL) System.out.println("Not EL! AllValue Restriction Found: in " + entity ); this.isEL = false; // causes intractability this.isELpp = false; // causes intractability (tw7) } } else if ( desc instanceof OWLObjectValueRestriction ) { if ( DEBUG_NOMINALS ) System.out.println( "<Nominals>: " + entity + " Has ValueRestriction" + desc); this.isDLLite = false; this.hasNominals = true; if (DEBUG_IS_EL) System.out.println("Not EL! Nominals Found: in " + entity ); this.isEL = false; } else if(desc instanceof OWLCardinalityRestriction ) { if (DEBUG_IS_EL) System.out.println("Not EL! Card Restriction Found: in " + entity ); isEL = false; //EL has no functionality construct // ELF is not tractable (tw7) isELpp = false; // causes intracability (tw7) isRDFS = false; //RDFS has no functional or cardinality restrictions (tw7) if(((OWLCardinalityRestriction)desc).isAtMost()){ int m = ((OWLCardinalityRestriction)desc).getAtMost(); if(m <= 1) { if (! (desc instanceof OWLDataCardinalityRestriction) ) hasFunctionality = true; } else { hasCardinality = true; isDLLite = false; //DLLite has no cardinality construct // (DLLite is subset of OWL Lite) (tw7) } } if(((OWLCardinalityRestriction)desc).isAtLeast()){ int m = ((OWLCardinalityRestriction)desc).getAtLeast(); // [BUGBUG] need to check if user is using Not(atLeast(2)) to represent less than 2. if(m <= 1 ) { if (! (desc instanceof OWLDataCardinalityRestriction) ) hasFunctionality = true; } else { hasCardinality = true ; isDLLite = false; //DLLite has no cardinality construct // (DLLite is subset of OWL Lite) (tw7) } } } //end expressivity this.addToMap(this.propToDescriptionRestrictions, prop, desc); this.lookInsideRestriction((OWLRestriction) desc, entity); } } catch (OWLException ex) { ex.printStackTrace(); } } private void lookInsideRestriction(OWLRestriction rest, OWLEntity entity) { // add to Restriction->Entity map this.addToMap(this.restrictionToEntity, rest, entity); if (rest instanceof OWLObjectQuantifiedRestriction) { try { // add to Class->Properties in Restriction map OWLDescription d = ((OWLObjectQuantifiedRestriction) rest).getDescription(); // also add it to the main descriptions set this.descriptions.add(d); //for expressivity if(!(d instanceof OWLClass)) { if (DEBUG_HASCOMPLEXRESTRICTION) System.out.println("<Has Complex Restriction>: in " + entity + " using " + d); hasComplexRestriction = true; isDLLite = false; } // this.addToMap(this.classesToPropertiesRestriction, d, rest.getProperty()); // also look inside descriptions which appear in some/all restrictions on object properties this.lookInsideDescription(d, entity, false, false, false); // finally, also compute nestedRestrictions map here // ** set checkingNestedRestriction = true here ** this.lookInsideDescription(d, rest.getProperty(), false, false, true); } catch (OWLException e) { e.printStackTrace(); } } else if (rest instanceof OWLObjectValueRestriction) { try { // add to Individual->Properties in Restriction map OWLIndividual ind = ((OWLObjectValueRestriction) rest).getIndividual(); this.addToMap(this.individualsToPropertiesRestriction, ind, rest.getProperty()); } catch (OWLException e) { e.printStackTrace(); } } } /** * Given a map and a key-value pair, add the value to the hashset * indexed by the key in the map. * @param map * @param key * @param value */ private void addToMap(Map map, Object key, Object value) { Set index = new HashSet(); if (map.containsKey(key)) index.addAll((HashSet) map.get(key)); if (value instanceof Set) index.addAll((HashSet) value); else index.add(value); map.put(key, index); } /** * Look inside all the descriptions inside a set and obtain * all pair-wise cross-references. Used for equivalent and disjoint sets * specified as OWLClassAxioms * @param set */ private void lookInsideSet(Set set) throws OWLException { for (Iterator iter = set.iterator(); iter.hasNext();) { OWLDescription desc = (OWLDescription) iter.next(); this.lookInsideDescription(desc, null); // descriptions.add(desc); // Set copy = new HashSet(set); // copy.remove(desc); // for (Iterator iter2=copy.iterator(); iter2.hasNext();) { // OWLDescription desc2 = (OWLDescription) iter2.next(); // if (desc instanceof OWLClass) this.lookInsideDescription(desc2, (OWLClass) desc); // if (desc2 instanceof OWLClass) this.lookInsideDescription(desc, (OWLClass) desc2); // } } } /** * For a given set of equivalent descriptions, add each equivalent * pairwise to the hashmap - equivalentClasses. * @param set */ private void addEquivalentSet(Set origSet, OWLDescription cla) { Set set = new HashSet(origSet); if (cla!=null) set.add(cla); for (Iterator iter = set.iterator(); iter.hasNext();) { OWLDescription desc = (OWLDescription) iter.next(); Set copy = new HashSet(set); copy.remove(desc); for (Iterator iter2=copy.iterator(); iter2.hasNext();) { OWLDescription desc2 = (OWLDescription) iter2.next(); this.addToMap(this.equivalents, desc, desc2); } } } private void addEquivalentPropSet(Set origSet) { Set set = new HashSet(origSet); for (Iterator iter = set.iterator(); iter.hasNext();) { OWLProperty prop = (OWLProperty) iter.next(); Set copy = new HashSet(set); copy.remove(prop); for (Iterator iter2=copy.iterator(); iter2.hasNext();) { OWLProperty prop2 = (OWLProperty) iter2.next(); this.addToMap(this.equivalents, prop, prop2); } } } }