public String renderOutput(OutputType type) { switch (type) { case ASCII: return renderASCIITable(); case CSV: return renderCSVTable(); case INSTANCES: return renderInstanceList(); case STATISTICS: return StatStore.getInstance().getCSVString(); case TIMES: return TimeTracker.getInstance().createEvaluation(); default: return "WARNING: output type not supported"; } }
public class CanonicalInterpretationGenerator implements IInterpretationGenerator { private static final String LOCAL_LOGGER_NAME = "CanonicalModel-Logger"; private static final TimeTracker TRACKER = TimeTracker.getInstance(); private static final StatStore STAT = StatStore.getInstance(); OWLClassExpression m_referenceExpression; OWLClass m_referenceClass; OntologyOperator m_ontologyOperator; private Map<OWLClass, OWLNamedIndividual> m_classAssociations; CanonicalDomain m_domain; boolean m_keepSmall; boolean m_normalize; protected Map<OWLClassExpression, Set<OWLClass>> m_superClassBuffer; protected Map<OWLClassExpression, Set<OWLClass>> m_equivalentClassBuffer; protected Map<OWLClassExpression, Set<OWLClass>> m_subClassBuffer; protected boolean m_useBuffer; Logger LOG; /** @deprecated you should use the iterative generators */ public CanonicalInterpretationGenerator() { this(true); } /** @deprecated you should use the iterative generators */ public CanonicalInterpretationGenerator(OWLClassExpression expr) { this(expr, true); } /** @deprecated you should use the iterative generators */ public CanonicalInterpretationGenerator(boolean normalizing) { this(null, normalizing); } /** @deprecated you should use the iterative generators */ public CanonicalInterpretationGenerator(OWLClassExpression expr, boolean normalizing) { this.m_referenceExpression = expr; this.m_classAssociations = new HashMap<OWLClass, OWLNamedIndividual>(); m_keepSmall = true; m_normalize = normalizing; LOG = Logger.getLogger(LOCAL_LOGGER_NAME); m_useBuffer = false; m_superClassBuffer = new HashMap<OWLClassExpression, Set<OWLClass>>(); m_subClassBuffer = new HashMap<OWLClassExpression, Set<OWLClass>>(); m_equivalentClassBuffer = new HashMap<OWLClassExpression, Set<OWLClass>>(); } @Override public CanonicalInterpretation generate(OWLOntology ontology) { CanonicalInterpretation canonInterpretation = new CanonicalInterpretation(); m_domain = new CanonicalDomain(); canonInterpretation.initDomain(m_domain); m_ontologyOperator = OntologyOperator.getOntologyOperator(ontology); IDomainElementGenerator elemGen; if (isKBMode()) { elemGen = new KBDomainElementGenerator(); } else { elemGen = new TBoxDomainElementGenerator(); } if (!isKBMode()) { // TBox + Query mode // define class Q as equivalence to the reference expression (query) m_referenceClass = getFreshQueryClass("Q"); insertQueryAxiom(m_referenceClass); ((TBoxDomainElementGenerator) elemGen).registerConcept(m_referenceClass); } OWLAxiomFlatteningTransformer exRestStore = m_ontologyOperator.getFlatteningTransformer(); // flattens here m_ontologyOperator.getReasoner(isKBMode()); // precomputes inferences // the element generator creates all necessary domain elements and adds their instantiators elemGen.generate(this, m_keepSmall); LOG.info("a total of " + m_classAssociations.size() + " classes are mapped to individuals"); TRACKER.start(StaticValues.TIME_DOMAIN_SUCCESSORS); if (!isKBMode()) { // TBox + Query mode // add all successor relations by iterating all known existential restrictions for (OWLObjectSomeValuesFrom some : exRestStore.getRestrictions()) { addEntailedTBoxSuccessors(some, m_normalize); } } else { // KB mode (ABox + TBox) // add all ABox property assertion successors for (OWLAxiom ax : m_ontologyOperator.getOntology().getABoxAxioms(true)) { if (ax instanceof OWLObjectPropertyAssertionAxiom) { // LOG.fine("Adding role assertion successor: " + ax); OWLObjectPropertyAssertionAxiom pAx = (OWLObjectPropertyAssertionAxiom) ax; getDomainElement(pAx.getSubject()) .addSuccessor( (OWLObjectProperty) pAx.getProperty(), getDomainElement(pAx.getObject())); } } // add all successor relations by iterating all known existential restrictions int exR = 1; for (OWLObjectSomeValuesFrom some : m_ontologyOperator.getFlatteningTransformer().getRestrictions()) { if (exR % 1000 == 0) { System.out.println(exR + " restrictions handled"); } addEntailedKBSuccessors(some); exR++; } LOG.info("TOTAL TIME FOR INSTANCE RETRIEVAL: " + sum + " ms"); // normalize later // if(m_normalize){ startSimulationComputation(); } } TRACKER.stop(StaticValues.TIME_DOMAIN_SUCCESSORS); /* ************* TEST SPECIFIC STUFF ************** */ // LOG.info("Start checking for useless domain nodes ..."); // Map<OWLClassExpression, DomainNode<OWLClassExpression>> conceptDomainNodes = // canonInterpretation.getDomain().getConceptElements(); // Set<DomainNode<OWLClassExpression>> noPredecessors = new // HashSet<DomainNode<OWLClassExpression>>(); // noPredecessors.addAll(conceptDomainNodes.values()); // for(OWLClassExpression ce : conceptDomainNodes.keySet()){ // for(OWLObjectProperty r : conceptDomainNodes.get(ce).getSuccessorRoles()){ // noPredecessors.removeAll(conceptDomainNodes.get(ce).getSuccessors(r)); // } // // NodeSet<OWLClass> subClasses = // m_ontologyOperator.getReasoner().getSubClasses(ce.asOWLClass(), false); // Node<OWLClass> eqClasses = // m_ontologyOperator.getReasoner().getEquivalentClasses(ce.asOWLClass()); // for(OWLClassExpression ce2 : conceptDomainNodes.keySet()){ // if(!ce.equals(ce2)){ // if(subClasses.containsEntity(ce2.asOWLClass())){ // LOG.info("Domain node " + conceptDomainNodes.get(ce2) + " represents something more // specific than " + conceptDomainNodes.get(ce)); // }else if(eqClasses.contains(ce2.asOWLClass())){ // LOG.info("Domain node " + conceptDomainNodes.get(ce2) + " is equivalent to " + // conceptDomainNodes.get(ce)); // } // } // } // } // for(DomainNode<OWLClassExpression> d : noPredecessors){ // LOG.info(d + " does not have any predecessors."); // if(d.getSuccessorObjects().isEmpty()) // LOG.info(d + " is not connected to the model at all!"); // } /* ************ END TEST ***************** */ return canonInterpretation; } protected NodeSet<OWLClass> currentIdSubClasses; protected NodeSet<OWLClass> currentIdSuperClasses; protected Node<OWLClass> currentIdEqClasses; private void addEntailedTBoxSuccessors(OWLObjectSomeValuesFrom some, boolean doNormalizing) { // StatStore.getInstance().enterValue("lookup " + some.getFiller(), 1.0); // StatStore.getInstance().enterValue("restrictions handled", 1.0); TRACKER.start(StaticValues.TIME_TBOX_SUCCESSORS, BlockOutputMode.COMPLETE, true); // TRACKER.start("fetch domain element and intermediary", BlockOutputMode.COMPLETE, true); DomainNode<?> toNode = getDomainElement(some.getFiller()); // the super class, intermediary stands for (some r B) OWLClass superClass = m_ontologyOperator.getFlatteningTransformer().getIntermediary(some); // TRACKER.stop("fetch domain element and intermediary"); // add successors from all // TRACKER.start("query elk", BlockOutputMode.COMPLETE, true); // StatStore.getInstance().enterValue("subclass accessing", 1.0); NodeSet<OWLClass> classes = m_ontologyOperator.getReasoner().getSubClasses(superClass, false); // fill current class relations from Id // StatStore.getInstance().enterValue("subclass accessing", 1.0); currentIdSubClasses = m_ontologyOperator.getReasoner().getSubClasses(some.getFiller(), false); // StatStore.getInstance().enterValue("superclass accessing", 1.0); currentIdSuperClasses = m_ontologyOperator.getReasoner().getSuperClasses(some.getFiller(), false); // StatStore.getInstance().enterValue("equivalent classes accessing", 1.0); currentIdEqClasses = m_ontologyOperator.getReasoner().getEquivalentClasses(some.getFiller()); // TRACKER.stop("query elk"); // LOG.fine(" creating successors to " + some + ": " + classes.toString()); Iterator<Node<OWLClass>> nodeIt = classes.iterator(); while (nodeIt.hasNext()) { Iterator<OWLClass> it = nodeIt.next().iterator(); while (it.hasNext()) { DomainNode<?> node = m_domain.getDomainNode(it.next()); // if it.next() yields no domain node, there exists an ABox identity for it // and this case is covered by addEntailedKBSuccessors if (node != null) { if (doNormalizing) { // if(!isSuccessorRepresented(node, (OWLObjectProperty)some.getProperty(), // some.getFiller())){ TRACKER.start("normalizing and adding", BlockOutputMode.COMPLETE, true); if (!isSuccessorRepresented(node, toNode, (OWLObjectProperty) some.getProperty())) { removeIncludedSuccessors( (OWLObjectProperty) some.getProperty(), node, some.getFiller()); node.addSuccessor((OWLObjectProperty) some.getProperty(), toNode); } TRACKER.stop("normalizing and adding"); } else { node.addSuccessor((OWLObjectProperty) some.getProperty(), toNode); } } } } // add all equivalent class successors // TRACKER.start("query elk", BlockOutputMode.COMPLETE, true); Iterator<OWLClass> cIt = m_ontologyOperator.getReasoner().getEquivalentClasses(superClass).iterator(); // TRACKER.stop("query elk"); while (cIt.hasNext()) { DomainNode<?> node = m_domain.getDomainNode(cIt.next()); if (node != null) { if (doNormalizing) { // if(!isSuccessorRepresented(node, (OWLObjectProperty)some.getProperty(), // some.getFiller())){ TRACKER.start("normalizing and adding", BlockOutputMode.COMPLETE, true); if (!isSuccessorRepresented(node, toNode, (OWLObjectProperty) some.getProperty())) { removeIncludedSuccessors( (OWLObjectProperty) some.getProperty(), node, some.getFiller()); node.addSuccessor((OWLObjectProperty) some.getProperty(), toNode); } TRACKER.stop("normalizing and adding"); } else { node.addSuccessor((OWLObjectProperty) some.getProperty(), toNode); } } } TRACKER.stop(StaticValues.TIME_TBOX_SUCCESSORS); } private long sum = 0; private void addEntailedKBSuccessors(OWLObjectSomeValuesFrom some) { TRACKER.start(StaticValues.TIME_KB_SUCCESSORS, BlockOutputMode.COMPLETE, true); // add all role-successors entailed by the TBox addEntailedTBoxSuccessors(some, m_normalize); // for KB mode only normalize TBox contained roles DomainNode<?> toNode = getDomainElement(some.getFiller()); OWLClass someClass = m_ontologyOperator.getFlatteningTransformer().getIntermediary(some); long start = System.currentTimeMillis(); // StatStore.getInstance().enterValue("instance accessing", 1.0); NodeSet<OWLNamedIndividual> instances = m_ontologyOperator.getReasoner().getInstances(someClass, false); sum += System.currentTimeMillis() - start; // NodeSet<OWLNamedIndividual> instances = // m_ontologyOperator.getReasoner().getInstances(getClassRepresentation(some), false); // LOG.fine(" creating successors to " + some + " from instances: " + instances.toString()); Iterator<Node<OWLNamedIndividual>> it1 = instances.iterator(); while (it1.hasNext()) { Iterator<OWLNamedIndividual> it2 = it1.next().iterator(); while (it2.hasNext()) { DomainNode<?> from = m_domain.getDomainNode(it2.next()); if (from != null) { // if(!isSuccessorRepresented(from, getDomainElement(some.getFiller()), // (OWLObjectProperty)some.getProperty())){ from.addSuccessor((OWLObjectProperty) some.getProperty(), toNode); // } } } } TRACKER.stop(StaticValues.TIME_KB_SUCCESSORS); } protected boolean isSuccessorRepresented( DomainNode<?> from, DomainNode<?> to, OWLObjectProperty property) { if (from.getId() instanceof OWLClassExpression && to.getId() instanceof OWLClassExpression) { Set<DomainNode<?>> successors = from.getSuccessors(property); // StatStore.getInstance().enterValue("subclass accessing", 1.0); // NodeSet<OWLClass> subClasses = // m_ontologyOperator.getReasoner().getSubClasses((OWLClass)to.getId(), false); NodeSet<OWLClass> subClasses = currentIdSubClasses; Node<OWLClass> eqClasses = currentIdEqClasses; for (DomainNode<?> succ : successors) { // only compare successors to other class domain elements if (succ.getId() instanceof OWLClass) { // if(succ.getInstantiators().containsAll(to.getInstantiators())){ // could be done // with reasoner if (m_useBuffer) { if (m_subClassBuffer.get((OWLClass) to.getId()).contains((OWLClass) succ.getId()) || m_equivalentClassBuffer .get((OWLClass) to.getId()) .contains((OWLClass) succ.getId())) { return true; } } else { if (subClasses.containsEntity((OWLClass) succ.getId()) || eqClasses.contains( (OWLClass) succ.getId())) { // if there exists a successors more (or equally) specific // than the new one return true; } } } } } return false; } /* private boolean isSuccessorRepresented(DomainNode<?> d, OWLObjectProperty property, OWLClassExpression filler) { Set<DomainNode<?>> successors = d.getSuccessors(property); if(successors == null) return false; for(DomainNode<?> succ : successors){ if(succ.getId() instanceof OWLClassExpression){ if(m_ontologyOperator.getReasoner().getSubClasses(filler, false) .containsEntity(getClassRepresentation((OWLClassExpression)succ.getId())) || m_ontologyOperator.getReasoner().getEquivalentClasses(filler) .contains(getClassRepresentation((OWLClassExpression)succ.getId())) ){ return true; } } } return false; }*/ protected Set<DomainNode<OWLClassExpression>> removeIncludedSuccessors( OWLObjectProperty property, DomainNode<?> d, OWLClassExpression newSucc) { Set<DomainNode<OWLClassExpression>> removed = new HashSet<DomainNode<OWLClassExpression>>(); Set<DomainNode<?>> successors = d.getSuccessors(property); // StatStore.getInstance().enterValue("superclass accessing", 1.0); // NodeSet<OWLClass> superClasses = m_ontologyOperator.getReasoner().getSuperClasses(newSucc, // false); // Node<OWLClass> eqClasses = m_ontologyOperator.getReasoner().getEquivalentClasses(newSucc); NodeSet<OWLClass> superClasses = currentIdSuperClasses; if (successors != null) { // Set<DomainNode<?>> mark_removed = new HashSet<DomainNode<?>>(); Iterator<DomainNode<?>> it = successors.iterator(); // for(DomainNode<?> succ : successors){ while (it.hasNext()) { DomainNode<?> succ = it.next(); if (succ.getId() instanceof OWLClassExpression) { // only inspect class to class relations OWLClass succClass = getClassRepresentation((OWLClassExpression) succ.getId()); // if newSucc is more specific than succ, remove succ if (m_useBuffer) { if (m_superClassBuffer.get(newSucc).contains(succClass)) { it.remove(); removed.add(m_domain.getDomainNode((OWLClassExpression) succ.getId())); } } else { if (superClasses.containsEntity(succClass)) { it.remove(); removed.add(m_domain.getDomainNode((OWLClassExpression) succ.getId())); // mark_removed.add(succ); } } } // else what about individual domain elements } // successors.removeAll(mark_removed); } return removed; } protected OWLClass getFreshQueryClass(String base) { long cnt = 0; String iriString = base; while (m_ontologyOperator.getOntology().containsClassInSignature(IRI.create(iriString))) { iriString = base + (cnt++); // not guaranteed to succeed.. however |long| amount of possibilities } return OWLManager.getOWLDataFactory().getOWLClass(IRI.create(iriString)); } protected void insertQueryAxiom(OWLClass queryClass) { // Main.getOntologyManager().addAxiom(m_ontologyOperator.getOntology(), // OWLManager.getOWLDataFactory().getOWLEquivalentClassesAxiom(queryClass, // m_referenceExpression)); m_ontologyOperator .getOntology() .getOWLOntologyManager() .addAxiom( m_ontologyOperator.getOntology(), // OWLManager.getOWLDataFactory().getOWLEquivalentClassesAxiom( OWLManager.getOWLDataFactory() .getOWLSubClassOfAxiom( queryClass, m_referenceExpression.accept( m_ontologyOperator.getFlatteningTransformer().getVisitor()))); m_ontologyOperator .getOntology() .getOWLOntologyManager() .applyChanges(m_ontologyOperator.getFlatteningTransformer().getVisitor().getChanges()); m_ontologyOperator.getFlatteningTransformer().getVisitor().resetChangeList(); m_ontologyOperator.ontologyChanged(); } public OWLClass getClassRepresentation(OWLClassExpression ex) { if (ex != null && ex.equals( m_referenceExpression)) // before OWLClass check, in case referenceExpression is also a // class return m_referenceClass; if (ex instanceof OWLClass) { return (OWLClass) ex; } return m_ontologyOperator.getFlatteningTransformer().getIntermediary(ex); } public DomainNode<?> getDomainElement(Object o) { Object searchFor = o; if (o instanceof OWLClassExpression) { OWLClass c = getClassRepresentation((OWLClassExpression) o); STAT.enterValue(StaticValues.STAT_ASSOCIATION_CONTAINS_CHECKS, 1.0); searchFor = m_classAssociations.get(c); if (searchFor == null) searchFor = o; } return m_domain.getDomainNode(searchFor); } public boolean isKBMode() { return m_referenceExpression == null; } public boolean isRestrictedInstantiator(OWLClass c) { return c == null || c.isTopEntity() || m_ontologyOperator.getFlatteningTransformer().isIntermediary(c) || c.equals(m_referenceClass); } public CanonicalDomain getDomain() { return m_domain; } public OntologyOperator getOntologyOperator() { return m_ontologyOperator; } public void addAssociation(OWLClass c, OWLNamedIndividual i) { m_classAssociations.put(c, i); } /** * If set to true, the generator attempts to associate OWLClass domain nodes with * OWLNamedIndividual domain nodes if they are an instance of the class, because they would behave * exactly the same. This keeps the model smaller. * * @param keepSmall */ public void setSmallCreationFlag(boolean keepSmall) { this.m_keepSmall = keepSmall; } /** * If set to true, the generator will normalize role successors as they are generated. This * consists of two extra steps:<br> * 1. check if the new role is already 'represented' by another role, if not do 2. + 3.<br> * 2. remove all roles that will be 'represented' by the new one<br> * 3. add the role<br> * This has the effect of directly creating a normalized canonical interpretation, however when * removing property assertions from the ABox, the interpretation may not be a model anymore. * * @param normalize */ public void setNormalizingFlag(boolean normalize) { this.m_normalize = normalize; } public void setUseBuffer(boolean buffer) { m_useBuffer = buffer; } /** * Initialize your own logger for the generator. If not actively specified, default logger will be * used. Call with null to disable logging for the generator. * * @param log */ public void setLogger(Logger log) { if (log == null) { this.LOG.setLevel(Level.OFF); } else { this.LOG = log; } } public Logger getLogger() { return LOG; } }