001/** 002 * Copyright (C) 2007 - 2016, Jens Lehmann 003 * 004 * This file is part of DL-Learner. 005 * 006 * DL-Learner is free software; you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation; either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * DL-Learner is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.dllearner.core; 020 021import com.google.common.collect.HashMultimap; 022import com.google.common.collect.Lists; 023import com.google.common.collect.Multimap; 024import com.google.common.collect.Sets; 025import org.dllearner.core.annotations.NoConfigOption; 026import org.dllearner.core.config.ConfigOption; 027import org.dllearner.core.owl.ClassHierarchy; 028import org.dllearner.core.owl.DatatypePropertyHierarchy; 029import org.dllearner.core.owl.ObjectPropertyHierarchy; 030import org.dllearner.core.owl.fuzzydll.FuzzyIndividual; 031import org.dllearner.reasoning.ReasonerType; 032import org.dllearner.utilities.Helper; 033import org.dllearner.utilities.OWLAPIUtils; 034import org.dllearner.utilities.datastructures.SortedSetTuple; 035import org.semanticweb.owlapi.model.*; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038import org.springframework.beans.factory.annotation.Autowired; 039import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; 040 041import java.text.NumberFormat; 042import java.text.ParseException; 043import java.util.*; 044import java.util.Map.Entry; 045import java.util.function.Function; 046import java.util.stream.Collectors; 047 048/** 049 * Abstract component representing a reasoner. Only a few reasoning operations 050 * are guaranteed to be implemented by the underlying reasoner, while a 051 * {@link ReasoningMethodUnsupportedException} is thrown for all other methods. 052 * In addition to calling the actual implementations of reasoning operations, 053 * the class also collects statistical information, which can be queried. 054 * 055 * Guidelines for extending the class: 056 * <ul> 057 * <li>add the needed method to the corresponding interface (currenty 058 * {@link BaseReasoner}, {@link SchemaReasoner}, {@link IndividualReasoner} 059 * exist)</li> 060 * <li>reasoning methods which need to be supported by all reasoners: create 061 * method() and methodImpl() here, where the former is an overridden, final 062 * method delegating to the latter abstract, protected method</li> 063 * <li>reasoning method, which do not need to be supported by all reasoners: 064 * create method() and methodImpl() as before, but this time methodImpl() is not 065 * abstract and throws a {@link ReasoningMethodUnsupportedException} </li> 066 * <li>a few very basic methods (where we do not care about statistics) do not 067 * have an "Impl" variant, e.g. getting all named classes of a KB; those are 068 * directly inherited from the reasoner interface</li> 069 * </ul> 070 * Note, that the method delegation is done to collect statistical information 071 * about reasoning performance, e.g. count how often certain methods were called 072 * and how long it took to execute them. 073 * 074 * @author Jens Lehmann 075 * 076 */ 077public abstract class AbstractReasonerComponent extends AbstractComponent implements Reasoner, ReasonerComponent { 078 079 public static Logger logger = LoggerFactory.getLogger(AbstractReasonerComponent.class); 080 081 private static final NumberFormat numberFormat = NumberFormat.getInstance(Locale.ROOT); 082 @ConfigOption(description = "whether to use single instance checks", defaultValue = "false") 083 protected boolean useInstanceChecks = false; 084 085 // statistical data for particular reasoning operations 086 private long instanceCheckReasoningTimeNs = 0; 087 private int nrOfInstanceChecks = 0; 088 private int nrOfMultiInstanceChecks = 0; 089 private long retrievalReasoningTimeNs = 0; 090 private int nrOfRetrievals = 0; 091 private long subsumptionReasoningTimeNs = 0; 092 private int nrOfSubsumptionChecks = 0; 093 private int nrOfMultiSubsumptionChecks = 0; 094 private int nrOfSubsumptionHierarchyQueries = 0; 095 096 // rest of reasoning time 097 private long otherReasoningTimeNs = 0; 098 099 // time for all reasoning requests (usually longer than the sum of all 100 // above) 101 private long overallReasoningTimeNs = 0; 102 103 // temporary variables (moved here for performance reasons) 104 private long reasoningStartTimeTmp; 105 private long reasoningDurationTmp; 106 107 // list view 108 private List<OWLClass> atomicConceptsList; 109 private List<OWLObjectProperty> atomicRolesList; 110 111 // hierarchies (they are computed the first time they are needed) 112 @NoConfigOption 113 protected ClassHierarchy subsumptionHierarchy = null; 114 @NoConfigOption 115 protected ObjectPropertyHierarchy roleHierarchy = null; 116 @NoConfigOption 117 protected DatatypePropertyHierarchy datatypePropertyHierarchy = null; 118 119 @ConfigOption(description = "if class hierarchy should be precomputed", defaultValue = "true") 120 protected boolean precomputeClassHierarchy = true; 121 @ConfigOption(defaultValue = "true") 122 protected boolean precomputeObjectPropertyHierarchy = true; 123 @ConfigOption(defaultValue = "true") 124 protected boolean precomputeDataPropertyHierarchy = true; 125 126 protected OWLDataFactory df = new OWLDataFactoryImpl(); 127 128 protected Multimap<OWLDatatype, OWLDataProperty> datatype2Properties = HashMultimap.create(); 129 protected Map<OWLDataProperty, OWLDatatype> dataproperty2datatype = new HashMap<>(); 130 131 @ConfigOption(description = "if property domains should be precomputed", defaultValue = "true") 132 protected boolean precomputePropertyDomains = true; 133 protected Map<OWLProperty, OWLClassExpression> propertyDomains = new HashMap<>(); 134 135 @ConfigOption(description = "if object property ranges should be precomputed", defaultValue = "true") 136 protected boolean precomputeObjectPropertyRanges = true; 137 protected Map<OWLObjectProperty, OWLClassExpression> objectPropertyRanges = new HashMap<>(); 138 139 /** 140 * The underlying knowledge sources. 141 */ 142 @ConfigOption(description = "the underlying knowledge sources", required = true) 143 protected Set<KnowledgeSource> sources; 144 145 public AbstractReasonerComponent(){ 146 147 } 148 /** 149 * Constructs a new reasoner component. 150 * 151 * @param sources 152 * The underlying knowledge sources. 153 */ 154 public AbstractReasonerComponent(Set<KnowledgeSource> sources) { 155 this.sources = sources; 156 } 157 158 public AbstractReasonerComponent(KnowledgeSource source) { 159 this(Collections.singleton(source)); 160 } 161 162 /** 163 * Gets the knowledge sources used by this reasoner. 164 * 165 * @return The underlying knowledge sources. 166 */ 167 public Set<KnowledgeSource> getSources() { 168 return sources; 169 } 170 171 @Autowired 172 public void setSources(Set<KnowledgeSource> sources){ 173 this.sources = sources; 174 } 175 176 @Autowired 177 public void setSources(KnowledgeSource... sources) { 178 this.sources = new HashSet<>(Arrays.asList(sources)); 179 } 180 181 /** 182 * Method to exchange the reasoner underlying the learning problem. 183 * Implementations, which do not only use the provided sources class 184 * variable, must make sure that a call to this method indeed changes them. 185 * 186 * @param sources 187 * The new knowledge sources. 188 */ 189 public void changeSources(Set<KnowledgeSource> sources) { 190 this.sources = sources; 191 } 192 193 /** 194 * Gets the type of the underlying reasoner. Although rarely necessary, 195 * applications can use this to adapt their behaviour to the reasoner. 196 * 197 * @return The reasoner type. 198 */ 199 public abstract ReasonerType getReasonerType(); 200 201 /** 202 * Reset all statistics. Usually, you do not need to call this. However, if 203 * you e.g. perform benchmarks of learning algorithms and performing 204 * reasoning operations, such as a consistency check, before starting the 205 * algorithm, you can use this method to reset all statistical values. 206 */ 207 public void resetStatistics() { 208 instanceCheckReasoningTimeNs = 0; 209 nrOfInstanceChecks = 0; 210 retrievalReasoningTimeNs = 0; 211 nrOfRetrievals = 0; 212 subsumptionReasoningTimeNs = 0; 213 nrOfSubsumptionChecks = 0; 214 // subsumptionHierarchyTimeNs = 0; 215 nrOfSubsumptionHierarchyQueries = 0; 216 otherReasoningTimeNs = 0; 217 overallReasoningTimeNs = 0; 218 } 219 220 /** 221 * Notify the reasoner component that the underlying knowledge base has 222 * changed and all caches (for named classes, subsumption hierarchies, etc.) 223 * should be invalidaded. TODO Currently, nothing is done to behave 224 * correctly after updates. 225 */ 226 @NoConfigOption 227 public void setUpdated() { 228 // TODO currently, nothing is done to behave correctly after updates 229 } 230 231 /** 232 * Call this method to release the knowledge base. Not calling the method 233 * may (depending on the underlying reasoner) result in resources for this 234 * knowledge base not being freed, which can cause memory leaks. 235 */ 236 public abstract void releaseKB(); 237 238 // we cannot expect callers of reasoning methods to reliably recover if 239 // certain reasoning methods are not implemented by the backend; we also 240 // should not require callers to build catch clauses each time they make 241 // a reasoner request => for this reasoner, we throw a runtime exception 242 // here 243 private void handleExceptions(ReasoningMethodUnsupportedException e) { 244 e.printStackTrace(); 245 throw new RuntimeException("Reasoning method not supported.", e); 246 } 247 248 @Override 249 public final Set<OWLClass> getTypes(OWLIndividual individual) { 250 Set<OWLClass> types = null; 251 try { 252 types = getTypesImpl(individual); 253 } catch (ReasoningMethodUnsupportedException e) { 254 handleExceptions(e); 255 } 256 return types; 257 } 258 259 protected Set<OWLClass> getTypesImpl(OWLIndividual individual) 260 throws ReasoningMethodUnsupportedException { 261 throw new ReasoningMethodUnsupportedException( 262 "Reasoner does not support to determine type of individual."); 263 } 264 265 @Override 266 public final boolean isSuperClassOf(OWLClassExpression superClass, OWLClassExpression subClass) { 267 reasoningStartTimeTmp = System.nanoTime(); 268 boolean result = false; 269 if(precomputeClassHierarchy) { 270 if(superClass.isAnonymous() || subClass.isAnonymous()) { 271 try { 272 result = isSuperClassOfImpl(superClass, subClass); 273 } catch (ReasoningMethodUnsupportedException e) { 274 e.printStackTrace(); 275 } 276 } else { 277 return getClassHierarchy().isSubclassOf(subClass, superClass); 278 } 279 } else { 280 try { 281 result = isSuperClassOfImpl(superClass, subClass); 282 } catch (ReasoningMethodUnsupportedException e) { 283 e.printStackTrace(); 284 } 285 } 286 nrOfSubsumptionChecks++; 287 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 288 subsumptionReasoningTimeNs += reasoningDurationTmp; 289 overallReasoningTimeNs += reasoningDurationTmp; 290 if(logger.isTraceEnabled()) { 291 logger.trace("reasoner query isSuperClassOf: " + superClass + " " + subClass + " " + result); 292 } 293 return result; 294 } 295 296 protected boolean isSuperClassOfImpl(OWLClassExpression superConcept, OWLClassExpression subConcept) 297 throws ReasoningMethodUnsupportedException { 298 throw new ReasoningMethodUnsupportedException(); 299 } 300 301 @Override 302 public final boolean isEquivalentClass(OWLClassExpression class1, OWLClassExpression class2) { 303 reasoningStartTimeTmp = System.nanoTime(); 304 boolean result = false; 305 try { 306 result = isEquivalentClassImpl(class1, class2); 307 } catch (ReasoningMethodUnsupportedException e) { 308 handleExceptions(e); 309 } 310 nrOfSubsumptionChecks+=2; 311 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 312 subsumptionReasoningTimeNs += reasoningDurationTmp; 313 overallReasoningTimeNs += reasoningDurationTmp; 314 if(logger.isTraceEnabled()) { 315 logger.trace("reasoner query isEquivalentClass: " + class1 + " " + class2 + " " + result); 316 } 317 return result; 318 } 319 320 protected boolean isEquivalentClassImpl(OWLClassExpression class1, OWLClassExpression class2) throws ReasoningMethodUnsupportedException { 321 return isSuperClassOfImpl(class1,class2) && isSuperClassOfImpl(class2,class1); 322 } 323 324 @Override 325 public final boolean isDisjoint(OWLClass class1, OWLClass class2) { 326 reasoningStartTimeTmp = System.nanoTime(); 327 boolean result = false; 328 try { 329 result = isDisjointImpl(class1, class2); 330 } catch (ReasoningMethodUnsupportedException e) { 331 handleExceptions(e); 332 } 333 nrOfSubsumptionChecks++; 334 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 335 subsumptionReasoningTimeNs += reasoningDurationTmp; 336 overallReasoningTimeNs += reasoningDurationTmp; 337 if(logger.isTraceEnabled()) { 338 logger.trace("reasoner query isDisjoint: " + class1 + " " + class2 + " " + result); 339 } 340 return result; 341 } 342 343 protected boolean isDisjointImpl(OWLClass superConcept, OWLClass subConcept) 344 throws ReasoningMethodUnsupportedException { 345 throw new ReasoningMethodUnsupportedException(); 346 } 347 348 @Override 349 public Set<OWLClassExpression> getAssertedDefinitions(OWLClass namedClass) { 350 try { 351 return getAssertedDefinitionsImpl(namedClass); 352 } catch (ReasoningMethodUnsupportedException e) { 353 handleExceptions(e); 354 return null; 355 } 356 } 357 358 protected Set<OWLClassExpression> getAssertedDefinitionsImpl(OWLClass namedClass) 359 throws ReasoningMethodUnsupportedException { 360 throw new ReasoningMethodUnsupportedException(); 361 } 362 363 @Override 364 public final Set<OWLClassExpression> isSuperClassOf(Set<OWLClassExpression> superConcepts, 365 OWLClassExpression subConcept) { 366 reasoningStartTimeTmp = System.nanoTime(); 367 Set<OWLClassExpression> result = null; 368 try { 369 result = isSuperClassOfImpl(superConcepts, subConcept); 370 } catch (ReasoningMethodUnsupportedException e) { 371 handleExceptions(e); 372 } 373 nrOfSubsumptionChecks += superConcepts.size(); 374 nrOfMultiSubsumptionChecks++; 375 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 376 subsumptionReasoningTimeNs += reasoningDurationTmp; 377 overallReasoningTimeNs += reasoningDurationTmp; 378 return result; 379 } 380 381 protected Set<OWLClassExpression> isSuperClassOfImpl(Set<OWLClassExpression> superConcepts, 382 OWLClassExpression subConcept) throws ReasoningMethodUnsupportedException { 383 Set<OWLClassExpression> returnSet = superConcepts.stream() 384 .filter(superConcept -> isSuperClassOf(superConcept, subConcept)) 385 .collect(Collectors.toSet()); 386 return returnSet; 387 } 388 389 @Override 390 public final SortedSetTuple<OWLIndividual> doubleRetrieval(OWLClassExpression concept) { 391 reasoningStartTimeTmp = System.nanoTime(); 392 SortedSetTuple<OWLIndividual> result; 393 try { 394 result = doubleRetrievalImpl(concept); 395 } catch (ReasoningMethodUnsupportedException e) { 396 handleExceptions(e); 397 return null; 398 } 399 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 400 otherReasoningTimeNs += reasoningDurationTmp; 401 overallReasoningTimeNs += reasoningDurationTmp; 402 return result; 403 } 404 405 protected SortedSetTuple<OWLIndividual> doubleRetrievalImpl(OWLClassExpression concept) 406 throws ReasoningMethodUnsupportedException { 407 throw new ReasoningMethodUnsupportedException(); 408 } 409 410 @Override 411 public final SortedSet<OWLIndividual> getIndividuals(OWLClassExpression concept) { 412 reasoningStartTimeTmp = System.nanoTime(); 413 SortedSet<OWLIndividual> result; 414 try { 415 result = getIndividualsImpl(concept); 416 } catch (ReasoningMethodUnsupportedException e) { 417 handleExceptions(e); 418 return null; 419 } 420 nrOfRetrievals++; 421 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 422 retrievalReasoningTimeNs += reasoningDurationTmp; 423 overallReasoningTimeNs += reasoningDurationTmp; 424 if(logger.isTraceEnabled()) { 425 logger.trace("reasoner query getIndividuals: " + concept + " " + result); 426 } 427 return result; 428 } 429 430 protected SortedSet<OWLIndividual> getIndividualsImpl(OWLClassExpression concept) 431 throws ReasoningMethodUnsupportedException { 432 throw new ReasoningMethodUnsupportedException(); 433 } 434 435 @Override 436 public final SortedSet<FuzzyIndividual> getFuzzyIndividuals(OWLClassExpression concept) { 437 reasoningStartTimeTmp = System.nanoTime(); 438 SortedSet<FuzzyIndividual> result; 439 try { 440 result = getFuzzyIndividualsImpl(concept); 441 } catch (ReasoningMethodUnsupportedException e) { 442 handleExceptions(e); 443 return null; 444 } 445 nrOfRetrievals++; 446 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 447 retrievalReasoningTimeNs += reasoningDurationTmp; 448 overallReasoningTimeNs += reasoningDurationTmp; 449 if(logger.isTraceEnabled()) { 450 logger.trace("reasoner query getIndividuals: " + concept + " " + result); 451 } 452 return result; 453 } 454 455 protected SortedSet<FuzzyIndividual> getFuzzyIndividualsImpl(OWLClassExpression concept) 456 throws ReasoningMethodUnsupportedException { 457 throw new ReasoningMethodUnsupportedException(); 458 } 459 460 @Override 461 public final boolean hasType(OWLClassExpression concept, OWLIndividual s) { 462 reasoningStartTimeTmp = System.nanoTime(); 463 boolean result = false; 464 try { 465 result = hasTypeImpl(concept, s); 466 } catch (ReasoningMethodUnsupportedException e) { 467 handleExceptions(e); 468 } 469 nrOfInstanceChecks++; 470 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 471 instanceCheckReasoningTimeNs += reasoningDurationTmp; 472 overallReasoningTimeNs += reasoningDurationTmp; 473 return result; 474 } 475 476 protected boolean hasTypeImpl(OWLClassExpression concept, OWLIndividual individual) 477 throws ReasoningMethodUnsupportedException { 478 throw new ReasoningMethodUnsupportedException(); 479 } 480 481 @Override 482 public final SortedSet<OWLIndividual> hasType(OWLClassExpression concept, Set<OWLIndividual> s) { 483 // logger.debug("instanceCheck "+concept.toKBSyntaxString()); 484 reasoningStartTimeTmp = System.nanoTime(); 485 SortedSet<OWLIndividual> result = null; 486 try { 487 result = hasTypeImpl(concept, s); 488 } catch (ReasoningMethodUnsupportedException e) { 489 handleExceptions(e); 490 } 491 nrOfInstanceChecks += s.size(); 492 nrOfMultiInstanceChecks++; 493 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 494 instanceCheckReasoningTimeNs += reasoningDurationTmp; 495 overallReasoningTimeNs += reasoningDurationTmp; 496 // logger.debug("instanceCheck done"); 497 return result; 498 } 499 500 protected SortedSet<OWLIndividual> hasTypeImpl(OWLClassExpression concept, Set<OWLIndividual> individuals) throws ReasoningMethodUnsupportedException { 501 SortedSet<OWLIndividual> returnSet = individuals.stream() 502 .filter(individual -> hasType(concept, individual)) 503 .collect(Collectors.toCollection(TreeSet::new)); 504 return returnSet; 505 } 506 507 @Override 508 public final Set<OWLClass> getInconsistentClasses() { 509 try { 510 return getInconsistentClassesImpl(); 511 } catch (ReasoningMethodUnsupportedException e) { 512 handleExceptions(e); 513 return null; 514 } 515 } 516 517 protected Set<OWLClass> getInconsistentClassesImpl() 518 throws ReasoningMethodUnsupportedException { 519 throw new ReasoningMethodUnsupportedException(); 520 } 521 522 @Override 523 public final boolean isSatisfiable() { 524 reasoningStartTimeTmp = System.nanoTime(); 525 boolean result; 526 try { 527 result = isSatisfiableImpl(); 528 } catch (ReasoningMethodUnsupportedException e) { 529 handleExceptions(e); 530 return false; 531 } 532 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 533 otherReasoningTimeNs += reasoningDurationTmp; 534 overallReasoningTimeNs += reasoningDurationTmp; 535 return result; 536 } 537 538 protected boolean isSatisfiableImpl() throws ReasoningMethodUnsupportedException { 539 throw new ReasoningMethodUnsupportedException(); 540 } 541 542 @Override 543 public final boolean remainsSatisfiable(OWLAxiom axiom) { 544 reasoningStartTimeTmp = System.nanoTime(); 545 boolean result; 546 try { 547 result = remainsSatisfiableImpl(axiom); 548 } catch (ReasoningMethodUnsupportedException e) { 549 handleExceptions(e); 550 return false; 551 } 552 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 553 otherReasoningTimeNs += reasoningDurationTmp; 554 overallReasoningTimeNs += reasoningDurationTmp; 555 return result; 556 } 557 558 protected boolean remainsSatisfiableImpl(OWLAxiom axiom) throws ReasoningMethodUnsupportedException { 559 throw new ReasoningMethodUnsupportedException(); 560 } 561 562 @Override 563 public final Map<OWLObjectProperty,Set<OWLIndividual>> getObjectPropertyRelationships(OWLIndividual individual) { 564 try { 565 return getObjectPropertyRelationshipsImpl(individual); 566 } catch (ReasoningMethodUnsupportedException e) { 567 handleExceptions(e); 568 return null; 569 } 570 } 571 572 protected Map<OWLObjectProperty,Set<OWLIndividual>> getObjectPropertyRelationshipsImpl(OWLIndividual individual) throws ReasoningMethodUnsupportedException { 573 throw new ReasoningMethodUnsupportedException(); 574 } 575 576 @Override 577 public final Map<OWLDataProperty, Set<OWLLiteral>> getDataPropertyRelationships(OWLIndividual individual) { 578 try { 579 return getDataPropertyRelationshipsImpl(individual); 580 } catch (ReasoningMethodUnsupportedException e) { 581 handleExceptions(e); 582 return null; 583 } 584 } 585 586 protected Map<OWLDataProperty, Set<OWLLiteral>> getDataPropertyRelationshipsImpl(OWLIndividual individual) 587 throws ReasoningMethodUnsupportedException { 588 throw new ReasoningMethodUnsupportedException(); 589 } 590 591 592 @Override 593 public final Set<OWLIndividual> getRelatedIndividuals(OWLIndividual individual, 594 OWLObjectProperty objectProperty) { 595 try { 596 return getRelatedIndividualsImpl(individual, objectProperty); 597 } catch (ReasoningMethodUnsupportedException e) { 598 handleExceptions(e); 599 return null; 600 } 601 } 602 603 protected Set<OWLIndividual> getRelatedIndividualsImpl(OWLIndividual individual, 604 OWLObjectProperty objectProperty) throws ReasoningMethodUnsupportedException { 605 throw new ReasoningMethodUnsupportedException(); 606 } 607 608 @Override 609 public final Set<OWLLiteral> getRelatedValues(OWLIndividual individual, 610 OWLDataProperty datatypeProperty) { 611 try { 612 return getRelatedValuesImpl(individual, datatypeProperty); 613 } catch (ReasoningMethodUnsupportedException e) { 614 handleExceptions(e); 615 return null; 616 } 617 } 618 619 protected Set<OWLLiteral> getRelatedValuesImpl(OWLIndividual individual, 620 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 621 throw new ReasoningMethodUnsupportedException(); 622 } 623 624 @Override 625 public final Set<OWLLiteral> getLabel(OWLEntity entity) { 626 try { 627 return getLabelImpl(entity); 628 } catch (ReasoningMethodUnsupportedException e) { 629 handleExceptions(e); 630 return null; 631 } 632 } 633 634 protected Set<OWLLiteral> getLabelImpl(OWLEntity entity) throws ReasoningMethodUnsupportedException { 635 throw new ReasoningMethodUnsupportedException(); 636 } 637 638 @Override 639 public final Map<OWLIndividual, SortedSet<OWLIndividual>> getPropertyMembers(OWLObjectProperty atomicRole) { 640 reasoningStartTimeTmp = System.nanoTime(); 641 Map<OWLIndividual, SortedSet<OWLIndividual>> result; 642 try { 643 result = getPropertyMembersImpl(atomicRole); 644 } catch (ReasoningMethodUnsupportedException e) { 645 handleExceptions(e); 646 return null; 647 } 648 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 649 otherReasoningTimeNs += reasoningDurationTmp; 650 overallReasoningTimeNs += reasoningDurationTmp; 651 return result; 652 } 653 654 protected Map<OWLIndividual, SortedSet<OWLIndividual>> getPropertyMembersImpl( 655 OWLObjectProperty atomicRole) throws ReasoningMethodUnsupportedException { 656 throw new ReasoningMethodUnsupportedException(); 657 } 658 659 @Override 660 public final Map<OWLIndividual, SortedSet<OWLLiteral>> getDatatypeMembers( 661 OWLDataProperty datatypeProperty) { 662 try { 663 return getDatatypeMembersImpl(datatypeProperty); 664 } catch (ReasoningMethodUnsupportedException e) { 665 handleExceptions(e); 666 return null; 667 } 668 } 669 670 protected Map<OWLIndividual, SortedSet<OWLLiteral>> getDatatypeMembersImpl( 671 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 672 throw new ReasoningMethodUnsupportedException(); 673 } 674 675 @Override 676 public final Map<OWLIndividual, SortedSet<Double>> getDoubleDatatypeMembers( 677 OWLDataProperty datatypeProperty) { 678 try { 679 return getDoubleDatatypeMembersImpl(datatypeProperty); 680 } catch (ReasoningMethodUnsupportedException e) { 681 handleExceptions(e); 682 return null; 683 } 684 } 685 686 protected Map<OWLIndividual, SortedSet<Double>> getDoubleDatatypeMembersImpl( 687 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 688 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 689 Map<OWLIndividual, SortedSet<Double>> ret = new TreeMap<>(); 690 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 691 SortedSet<OWLLiteral> values = e.getValue(); 692 SortedSet<Double> valuesDouble = values.stream() 693 .filter(lit -> OWLAPIUtils.floatDatatypes.contains(lit.getDatatype())) 694 .map(lit -> Double.parseDouble(lit.getLiteral())) 695 .collect(Collectors.toCollection(TreeSet::new)); 696 ret.put(e.getKey(), valuesDouble); 697 } 698 return ret; 699 } 700 701 @Override 702 public final <T extends Number> Map<OWLIndividual, SortedSet<T>> getNumericDatatypeMembers( 703 OWLDataProperty datatypeProperty, Class<T> clazz) { 704 try { 705 return getNumericDatatypeMembersImpl(datatypeProperty, clazz); 706 } catch (ReasoningMethodUnsupportedException e) { 707 handleExceptions(e); 708 return null; 709 } 710 } 711 712 protected <T extends Number> Map<OWLIndividual, SortedSet<T>> getNumericDatatypeMembersImpl( 713 OWLDataProperty datatypeProperty, Class<T> clazz) throws ReasoningMethodUnsupportedException { 714 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 715 Map<OWLIndividual, SortedSet<T>> ret = new TreeMap<>(); 716 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 717 SortedSet<OWLLiteral> values = e.getValue(); 718 SortedSet<T> numericValues = new TreeSet<>(); 719 for (OWLLiteral lit : values) { 720 try { 721 numericValues.add((T) numberFormat.parse(lit.getLiteral())); 722 } catch (ParseException e1) { 723 e1.printStackTrace(); 724 } 725 } 726 ret.put(e.getKey(), numericValues); 727 } 728 return ret; 729 } 730 731 @Override 732 public final <T extends Number & Comparable<T>> Map<OWLIndividual, SortedSet<T>> getNumericDatatypeMembers( 733 OWLDataProperty datatypeProperty) { 734 try { 735 return getNumericDatatypeMembersImpl(datatypeProperty); 736 } catch (ReasoningMethodUnsupportedException e) { 737 handleExceptions(e); 738 return null; 739 } 740 } 741 742 protected <T extends Number & Comparable<T>> Map<OWLIndividual, SortedSet<T>> getNumericDatatypeMembersImpl( 743 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 744 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 745 Map<OWLIndividual, SortedSet<T>> ret = new TreeMap<>(); 746 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> entry : mapping.entrySet()) { 747 OWLIndividual ind = entry.getKey(); 748 SortedSet<OWLLiteral> values = entry.getValue(); 749 SortedSet<T> numericValues = new TreeSet<>(); 750 for (OWLLiteral lit : values) { 751 if(OWLAPIUtils.isIntegerDatatype(lit)) { 752 numericValues.add((T) Integer.valueOf(lit.parseInteger())); 753 } else { 754 try { 755 Number number; 756 String litStr = lit.getLiteral(); 757 if(litStr.equalsIgnoreCase("NAN")) { 758 number = Double.NaN; 759 } else { 760 number = numberFormat.parse(litStr); 761 if(number instanceof Long) { 762 number = Double.valueOf(number.toString()); 763 } 764 } 765 numericValues.add((T) (number) ); 766 } catch (ParseException e) { 767 e.printStackTrace(); 768 } 769 } 770 771 } 772 ret.put(ind, numericValues); 773 } 774 return ret; 775 } 776 777 @Override 778 public final Map<OWLIndividual, SortedSet<Integer>> getIntDatatypeMembers( 779 OWLDataProperty datatypeProperty) { 780 try { 781 return getIntDatatypeMembersImpl(datatypeProperty); 782 } catch (ReasoningMethodUnsupportedException e) { 783 handleExceptions(e); 784 return null; 785 } 786 } 787 788 protected Map<OWLIndividual, SortedSet<Integer>> getIntDatatypeMembersImpl( 789 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 790 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 791 Map<OWLIndividual, SortedSet<Integer>> ret = new TreeMap<>(); 792 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 793 SortedSet<OWLLiteral> values = e.getValue(); 794 SortedSet<Integer> valuesInt = values.stream() 795 .filter(lit -> OWLAPIUtils.isIntegerDatatype(lit)) 796 .map((Function<OWLLiteral, Integer>) OWLLiteral::parseInteger) 797 .collect(Collectors.toCollection(TreeSet::new)); 798 ret.put(e.getKey(), valuesInt); 799 } 800 return ret; 801 } 802 803 @Override 804 public final Map<OWLIndividual, SortedSet<Boolean>> getBooleanDatatypeMembers( 805 OWLDataProperty datatypeProperty) { 806 try { 807 return getBooleanDatatypeMembersImpl(datatypeProperty); 808 } catch (ReasoningMethodUnsupportedException e) { 809 handleExceptions(e); 810 return null; 811 } 812 } 813 814 protected Map<OWLIndividual, SortedSet<Boolean>> getBooleanDatatypeMembersImpl( 815 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 816 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 817 Map<OWLIndividual, SortedSet<Boolean>> ret = new TreeMap<>(); 818 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 819 SortedSet<OWLLiteral> values = e.getValue(); 820 SortedSet<Boolean> valuesBoolean = new TreeSet<>(); 821 for (OWLLiteral c : values) { 822 String s = c.getLiteral(); 823 if (s.equalsIgnoreCase("true")) { 824 valuesBoolean.add(true); 825 } else if (s.equalsIgnoreCase("false")) { 826 valuesBoolean.add(false); 827 } else { 828 logger.warn("Requested to parse boolean value of property " + datatypeProperty 829 + ", but " + c + " could not be parsed successfully."); 830 } 831 } 832 ret.put(e.getKey(), valuesBoolean); 833 } 834 return ret; 835 } 836 837 @Override 838 public final SortedSet<OWLIndividual> getTrueDatatypeMembers(OWLDataProperty datatypeProperty) { 839 try { 840 return getTrueDatatypeMembersImpl(datatypeProperty); 841 } catch (ReasoningMethodUnsupportedException e) { 842 handleExceptions(e); 843 return null; 844 } 845 } 846 847 protected SortedSet<OWLIndividual> getTrueDatatypeMembersImpl(OWLDataProperty datatypeProperty) 848 throws ReasoningMethodUnsupportedException { 849 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 850 SortedSet<OWLIndividual> ret = new TreeSet<>(); 851 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 852 SortedSet<OWLLiteral> values = e.getValue(); 853 if (values.size() > 1) { 854 logger.warn("Property " + datatypeProperty + " has more than one value " + e.getValue() 855 + " for individual " + e.getKey() + ". We ignore the value."); 856 } else { 857 if (values.first().getLiteral().equalsIgnoreCase("true")) { 858 ret.add(e.getKey()); 859 } 860 } 861 } 862 return ret; 863 } 864 865 @Override 866 public final SortedSet<OWLIndividual> getFalseDatatypeMembers(OWLDataProperty datatypeProperty) { 867 try { 868 return getFalseDatatypeMembersImpl(datatypeProperty); 869 } catch (ReasoningMethodUnsupportedException e) { 870 handleExceptions(e); 871 return null; 872 } 873 } 874 875 protected SortedSet<OWLIndividual> getFalseDatatypeMembersImpl(OWLDataProperty datatypeProperty) 876 throws ReasoningMethodUnsupportedException { 877 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 878 SortedSet<OWLIndividual> ret = new TreeSet<>(); 879 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 880 SortedSet<OWLLiteral> values = e.getValue(); 881 if (values.size() > 1) { 882 logger.warn("Property " + datatypeProperty + " has value " + e.getValue() 883 + ". Cannot determine whether it is false."); 884 } else { 885 if (values.first().getLiteral().equalsIgnoreCase("false")) { 886 ret.add(e.getKey()); 887 } 888 } 889 } 890 return ret; 891 } 892 893 @Override 894 public final Map<OWLIndividual, SortedSet<String>> getStringDatatypeMembers( 895 OWLDataProperty datatypeProperty) { 896 try { 897 return getStringDatatypeMembersImpl(datatypeProperty); 898 } catch (ReasoningMethodUnsupportedException e) { 899 handleExceptions(e); 900 return null; 901 } 902 } 903 904 protected Map<OWLIndividual, SortedSet<String>> getStringDatatypeMembersImpl( 905 OWLDataProperty datatypeProperty) throws ReasoningMethodUnsupportedException { 906 Map<OWLIndividual, SortedSet<OWLLiteral>> mapping = getDatatypeMembersImpl(datatypeProperty); 907 Map<OWLIndividual, SortedSet<String>> ret = new TreeMap<>(); 908 for (Entry<OWLIndividual, SortedSet<OWLLiteral>> e : mapping.entrySet()) { 909 SortedSet<OWLLiteral> values = e.getValue(); 910 SortedSet<String> valuesString = values.stream() 911 .map(OWLLiteral::getLiteral) 912 .collect(Collectors.toCollection(TreeSet::new)); 913 ret.put(e.getKey(), valuesString); 914 } 915 return ret; 916 } 917 918 @Override 919 public final Set<OWLObjectProperty> getObjectProperties() { 920 try { 921 return getObjectPropertiesImpl(); 922 } catch (ReasoningMethodUnsupportedException e) { 923 handleExceptions(e); 924 return null; 925 } 926 } 927 928 protected Set<OWLObjectProperty> getObjectPropertiesImpl() 929 throws ReasoningMethodUnsupportedException { 930 throw new ReasoningMethodUnsupportedException(); 931 } 932 933 @Override 934 public final Set<OWLDataProperty> getDatatypeProperties() { 935 try { 936 return getDatatypePropertiesImpl(); 937 } catch (ReasoningMethodUnsupportedException e) { 938 handleExceptions(e); 939 return null; 940 } 941 } 942 943 protected Set<OWLDataProperty> getDatatypePropertiesImpl() 944 throws ReasoningMethodUnsupportedException { 945 throw new ReasoningMethodUnsupportedException(); 946 } 947 948 @Override 949 public final Set<OWLDataProperty> getBooleanDatatypeProperties() { 950 try { 951 return getBooleanDatatypePropertiesImpl(); 952 } catch (ReasoningMethodUnsupportedException e) { 953 handleExceptions(e); 954 return null; 955 } 956 } 957 958 // TODO Even if there is a small performance penalty, we could implement 959 // the method right here by iterating over all data properties and 960 // querying their ranges. At least, this should be done once we have a 961 // reasoner independent of OWL API with datatype support. 962 protected Set<OWLDataProperty> getBooleanDatatypePropertiesImpl() 963 throws ReasoningMethodUnsupportedException { 964 throw new ReasoningMethodUnsupportedException(); 965 } 966 967 @Override 968 public final Set<OWLDataProperty> getNumericDataProperties() { 969 try { 970 return getNumericDataPropertiesImpl(); 971 } catch (ReasoningMethodUnsupportedException e) { 972 handleExceptions(e); 973 return null; 974 } 975 } 976 977 protected Set<OWLDataProperty> getNumericDataPropertiesImpl() 978 throws ReasoningMethodUnsupportedException { 979 return Sets.union(getIntDatatypePropertiesImpl(), getDoubleDatatypePropertiesImpl()); 980 } 981 982 @Override 983 public final Set<OWLDataProperty> getIntDatatypeProperties() { 984 try { 985 return getIntDatatypePropertiesImpl(); 986 } catch (ReasoningMethodUnsupportedException e) { 987 handleExceptions(e); 988 return null; 989 } 990 } 991 992 protected Set<OWLDataProperty> getIntDatatypePropertiesImpl() 993 throws ReasoningMethodUnsupportedException { 994 throw new ReasoningMethodUnsupportedException(); 995 } 996 997 @Override 998 public final Set<OWLDataProperty> getDoubleDatatypeProperties() { 999 try { 1000 return getDoubleDatatypePropertiesImpl(); 1001 } catch (ReasoningMethodUnsupportedException e) { 1002 handleExceptions(e); 1003 return null; 1004 } 1005 } 1006 1007 protected Set<OWLDataProperty> getDoubleDatatypePropertiesImpl() 1008 throws ReasoningMethodUnsupportedException { 1009 throw new ReasoningMethodUnsupportedException(); 1010 } 1011 1012 @Override 1013 public final Set<OWLDataProperty> getStringDatatypeProperties() { 1014 try { 1015 return getStringDatatypePropertiesImpl(); 1016 } catch (ReasoningMethodUnsupportedException e) { 1017 handleExceptions(e); 1018 return null; 1019 } 1020 } 1021 1022 protected Set<OWLDataProperty> getStringDatatypePropertiesImpl() 1023 throws ReasoningMethodUnsupportedException { 1024 throw new ReasoningMethodUnsupportedException(); 1025 } 1026 1027 @Override 1028 public final OWLClassExpression getDomain(OWLObjectProperty objectProperty) { 1029 try { 1030 return getDomainImpl(objectProperty); 1031 } catch (ReasoningMethodUnsupportedException e) { 1032 handleExceptions(e); 1033 return null; 1034 } 1035 } 1036 1037 protected OWLClassExpression getDomainImpl(OWLObjectProperty objectProperty) 1038 throws ReasoningMethodUnsupportedException { 1039 throw new ReasoningMethodUnsupportedException(); 1040 } 1041 1042 @Override 1043 public final OWLClassExpression getDomain(OWLDataProperty datatypeProperty) { 1044 try { 1045 return getDomainImpl(datatypeProperty); 1046 } catch (ReasoningMethodUnsupportedException e) { 1047 handleExceptions(e); 1048 return null; 1049 } 1050 } 1051 1052 protected OWLClassExpression getDomainImpl(OWLDataProperty datatypeProperty) 1053 throws ReasoningMethodUnsupportedException { 1054 throw new ReasoningMethodUnsupportedException(); 1055 } 1056 1057 @Override 1058 public final OWLClassExpression getRange(OWLObjectProperty objectProperty) { 1059 try { 1060 return getRangeImpl(objectProperty); 1061 } catch (ReasoningMethodUnsupportedException e) { 1062 handleExceptions(e); 1063 return null; 1064 } 1065 } 1066 1067 protected OWLClassExpression getRangeImpl(OWLObjectProperty objectProperty) 1068 throws ReasoningMethodUnsupportedException { 1069 throw new ReasoningMethodUnsupportedException(); 1070 } 1071 1072 @Override 1073 public final OWLDataRange getRange(OWLDataProperty datatypeProperty) { 1074 try { 1075 return getRangeImpl(datatypeProperty); 1076 } catch (ReasoningMethodUnsupportedException e) { 1077 handleExceptions(e); 1078 return null; 1079 } 1080 } 1081 1082 protected OWLDataRange getRangeImpl(OWLDataProperty datatypeProperty) 1083 throws ReasoningMethodUnsupportedException { 1084 throw new ReasoningMethodUnsupportedException(); 1085 } 1086 1087 @Override 1088 public final SortedSet<OWLClassExpression> getSuperClasses(OWLClassExpression concept) { 1089 if(precomputeClassHierarchy) { 1090 return getClassHierarchy().getSuperClasses(concept, true); 1091 } else { 1092 try { 1093 return getSuperClassesImpl(concept); 1094 } catch (ReasoningMethodUnsupportedException e) { 1095 e.printStackTrace(); 1096 } 1097 } 1098 return null; 1099 } 1100 1101 protected SortedSet<OWLClassExpression> getSuperClassesImpl(OWLClassExpression concept) throws ReasoningMethodUnsupportedException { 1102 throw new ReasoningMethodUnsupportedException(); 1103 } 1104 1105 @Override 1106 public final SortedSet<OWLClassExpression> getSubClasses(OWLClassExpression concept) { 1107 if(precomputeClassHierarchy) { 1108 return getClassHierarchy().getSubClasses(concept, true); 1109 } else { 1110 try { 1111 return getSubClassesImpl(concept); 1112 } catch (ReasoningMethodUnsupportedException e) { 1113 e.printStackTrace(); 1114 } 1115 } 1116 return null; 1117 } 1118 1119 protected SortedSet<OWLClassExpression> getSubClassesImpl(OWLClassExpression concept) throws ReasoningMethodUnsupportedException { 1120 throw new ReasoningMethodUnsupportedException(); 1121 } 1122 1123 public final SortedSet<OWLClassExpression> getEquivalentClasses(OWLClassExpression concept) { 1124 return new TreeSet<>(Sets.intersection(getClassHierarchy().getSubClasses(concept), getClassHierarchy().getSuperClasses(concept))); 1125 } 1126 1127 @Override 1128 public final <T extends OWLProperty> SortedSet<T> getSuperProperties(T role) { 1129 if(OWLObjectProperty.class.isInstance(role) && precomputeObjectPropertyHierarchy) { 1130 return (SortedSet<T>) getObjectPropertyHierarchy().getMoreGeneralRoles((OWLObjectProperty) role); 1131 } else if(OWLDataProperty.class.isInstance(role) && precomputeDataPropertyHierarchy) { 1132 return (SortedSet<T>) getDatatypePropertyHierarchy().getMoreGeneralRoles((OWLDataProperty) role); 1133 } else { 1134 try { 1135 return getSuperPropertiesImpl(role); 1136 } catch (ReasoningMethodUnsupportedException e) { 1137 e.printStackTrace(); 1138 } 1139 } 1140 return null; 1141 } 1142 1143 protected <T extends OWLProperty> SortedSet<T> getSuperPropertiesImpl(T role) throws ReasoningMethodUnsupportedException { 1144 if(OWLObjectProperty.class.isInstance(role)) { 1145 return (SortedSet<T>) getSuperPropertiesImpl((OWLObjectProperty) role); 1146 } else if(OWLDataProperty.class.isInstance(role)) { 1147 return (SortedSet<T>) getSuperPropertiesImpl((OWLDataProperty) role); 1148 } 1149 throw new ReasoningMethodUnsupportedException(); 1150 } 1151 1152 @Override 1153 public final <T extends OWLProperty> SortedSet<T> getSubProperties(T role) { 1154 if(OWLObjectProperty.class.isInstance(role) && precomputeObjectPropertyHierarchy) { 1155 return (SortedSet<T>) getObjectPropertyHierarchy().getMoreSpecialRoles((OWLObjectProperty) role); 1156 } else if(OWLDataProperty.class.isInstance(role) && precomputeDataPropertyHierarchy) { 1157 return (SortedSet<T>) getDatatypePropertyHierarchy().getMoreSpecialRoles((OWLDataProperty) role); 1158 } else { 1159 try { 1160 return getSubPropertiesImpl(role); 1161 } catch (ReasoningMethodUnsupportedException e) { 1162 e.printStackTrace(); 1163 } 1164 } 1165 return null; 1166 } 1167 1168 protected <T extends OWLProperty> SortedSet<T> getSubPropertiesImpl(T role) throws ReasoningMethodUnsupportedException { 1169 if(OWLObjectProperty.class.isInstance(role)) { 1170 return (SortedSet<T>) getSubPropertiesImpl((OWLObjectProperty) role); 1171 } else if(OWLDataProperty.class.isInstance(role)) { 1172 return (SortedSet<T>) getSubPropertiesImpl((OWLDataProperty) role); 1173 } 1174 throw new ReasoningMethodUnsupportedException(); 1175 } 1176 1177 protected <T extends OWLProperty> OWLClassExpression getDomain(T role) { 1178 if(precomputePropertyDomains) { 1179 return propertyDomains.get(role); 1180 } else { 1181 try { 1182 return getDomainImpl(role); 1183 } catch (ReasoningMethodUnsupportedException e) { 1184 e.printStackTrace(); 1185 } 1186 } 1187 throw null; 1188 } 1189 1190 protected <T extends OWLProperty> OWLClassExpression getDomainImpl(T role) throws ReasoningMethodUnsupportedException { 1191 if(OWLObjectProperty.class.isInstance(role)) { 1192 return getDomainImpl((OWLObjectProperty) role); 1193 } else if(OWLDataProperty.class.isInstance(role)) { 1194 return getDomainImpl((OWLDataProperty) role); 1195 } 1196 throw new ReasoningMethodUnsupportedException(); 1197 } 1198 1199 1200 @Override 1201 public final SortedSet<OWLObjectProperty> getSuperProperties(OWLObjectProperty role) { 1202 if(precomputeObjectPropertyHierarchy) { 1203 return getObjectPropertyHierarchy().getMoreGeneralRoles(role); 1204 } else { 1205 try { 1206 return getSuperPropertiesImpl(role); 1207 } catch (ReasoningMethodUnsupportedException e) { 1208 e.printStackTrace(); 1209 } 1210 } 1211 return null; 1212 } 1213 1214 protected SortedSet<OWLObjectProperty> getSuperPropertiesImpl(OWLObjectProperty role) throws ReasoningMethodUnsupportedException { 1215 throw new ReasoningMethodUnsupportedException(); 1216 } 1217 1218 @Override 1219 public final SortedSet<OWLObjectProperty> getSubProperties(OWLObjectProperty role) { 1220 if(precomputeObjectPropertyHierarchy) { 1221 return getObjectPropertyHierarchy().getMoreSpecialRoles(role); 1222 } else { 1223 try { 1224 return getSuperPropertiesImpl(role); 1225 } catch (ReasoningMethodUnsupportedException e) { 1226 e.printStackTrace(); 1227 } 1228 } 1229 return null; 1230 } 1231 1232 protected SortedSet<OWLObjectProperty> getSubPropertiesImpl(OWLObjectProperty role) throws ReasoningMethodUnsupportedException { 1233 throw new ReasoningMethodUnsupportedException(); 1234 } 1235 1236 @Override 1237 public final SortedSet<OWLObjectProperty> getMostGeneralProperties() { 1238 return getObjectPropertyHierarchy().getMostGeneralRoles(); 1239 } 1240 1241// protected SortedSet<OWLObjectProperty> getMostGeneralPropertiesImpl(OWLOWLObjectProperty role) throws ReasoningMethodUnsupportedException { 1242// throw new ReasoningMethodUnsupportedException(); 1243// } 1244 1245 @Override 1246 public final SortedSet<OWLObjectProperty> getMostSpecialProperties() { 1247 return getObjectPropertyHierarchy().getMostSpecialRoles(); 1248 } 1249 1250// protected SortedSet<OWLObjectProperty> getMostSpecialPropertiesImpl(OWLOWLObjectProperty role) throws ReasoningMethodUnsupportedException { 1251// throw new ReasoningMethodUnsupportedException(); 1252// } 1253 1254 @Override 1255 public final SortedSet<OWLDataProperty> getSuperProperties(OWLDataProperty role) { 1256 return getDatatypePropertyHierarchy().getMoreGeneralRoles(role); 1257 } 1258 1259 protected SortedSet<OWLDataProperty> getSuperPropertiesImpl(OWLDataProperty role) throws ReasoningMethodUnsupportedException { 1260 throw new ReasoningMethodUnsupportedException(); 1261 } 1262 1263 @Override 1264 public final SortedSet<OWLDataProperty> getSubProperties(OWLDataProperty role) { 1265 return getDatatypePropertyHierarchy().getMoreSpecialRoles(role); 1266 } 1267 1268 protected SortedSet<OWLDataProperty> getSubPropertiesImpl(OWLDataProperty role) throws ReasoningMethodUnsupportedException { 1269 throw new ReasoningMethodUnsupportedException(); 1270 } 1271 1272 @Override 1273 public final SortedSet<OWLDataProperty> getMostGeneralDatatypeProperties() { 1274 return getDatatypePropertyHierarchy().getMostGeneralRoles(); 1275 } 1276 1277 @Override 1278 public final SortedSet<OWLDataProperty> getMostSpecialDatatypeProperties() { 1279 return getDatatypePropertyHierarchy().getMostSpecialRoles(); 1280 } 1281 1282 /** 1283 * Creates the class hierarchy. Invoking this method is optional (if not 1284 * called explicitly, it is called the first time, it is needed). 1285 * 1286 * @return The class hierarchy. 1287 * @throws ReasoningMethodUnsupportedException If any method needed to 1288 * create the hierarchy is not supported by the underlying reasoner. 1289 */ 1290 public ClassHierarchy prepareSubsumptionHierarchy() throws ReasoningMethodUnsupportedException { 1291 TreeMap<OWLClassExpression, SortedSet<OWLClassExpression>> subsumptionHierarchyUp = new TreeMap<>( 1292 ); 1293 TreeMap<OWLClassExpression, SortedSet<OWLClassExpression>> subsumptionHierarchyDown = new TreeMap<>( 1294 ); 1295 1296 // parents/children of top ... 1297 SortedSet<OWLClassExpression> tmp = getSubClassesImpl(df.getOWLThing()); 1298 subsumptionHierarchyUp.put(df.getOWLThing(), new TreeSet<>()); 1299 subsumptionHierarchyDown.put(df.getOWLThing(), tmp); 1300 1301 // ... bottom ... 1302 tmp = getSuperClassesImpl(df.getOWLNothing()); 1303 subsumptionHierarchyUp.put(df.getOWLNothing(), tmp); 1304 subsumptionHierarchyDown.put(df.getOWLNothing(), new TreeSet<>()); 1305 1306 // ... and named classes 1307 Set<OWLClass> atomicConcepts = getClasses(); 1308 for (OWLClass atom : atomicConcepts) { 1309 tmp = getSubClassesImpl(atom); 1310 // quality control: we explicitly check that no reasoner implementation returns null here 1311 if(tmp == null) { 1312 logger.error("Class hierarchy: getSubClasses returned null instead of empty set."); 1313 } 1314 subsumptionHierarchyDown.put(atom, tmp); 1315 1316 tmp = getSuperClassesImpl(atom); 1317 // quality control: we explicitly check that no reasoner implementation returns null here 1318 if(tmp == null) { 1319 logger.error("Class hierarchy: getSuperClasses returned null instead of empty set."); 1320 } 1321 subsumptionHierarchyUp.put(atom, tmp); 1322 } 1323 1324 return new ClassHierarchy(subsumptionHierarchyUp, subsumptionHierarchyDown); 1325 } 1326 1327 @Override 1328 public final ClassHierarchy getClassHierarchy() { 1329 // class hierarchy is created on first invocation 1330 if (subsumptionHierarchy == null) { 1331 try { 1332 subsumptionHierarchy = prepareSubsumptionHierarchy(); 1333 } catch (ReasoningMethodUnsupportedException e) { 1334 handleExceptions(e); 1335 } 1336 } 1337 return subsumptionHierarchy; 1338 } 1339 1340 /** 1341 * Creates the object property hierarchy. Invoking this method is optional 1342 * (if not called explicitly, it is called the first time, it is needed). 1343 * 1344 * @return The object property hierarchy. 1345 * @throws ReasoningMethodUnsupportedException 1346 * Thrown if a reasoning method for object property 1347 * hierarchy creation is not supported by the reasoner. 1348 */ 1349 public ObjectPropertyHierarchy prepareObjectPropertyHierarchy() 1350 throws ReasoningMethodUnsupportedException { 1351 1352 TreeMap<OWLObjectProperty, SortedSet<OWLObjectProperty>> roleHierarchyUp = new TreeMap<>( 1353 ); 1354 TreeMap<OWLObjectProperty, SortedSet<OWLObjectProperty>> roleHierarchyDown = new TreeMap<>( 1355 ); 1356 1357 Set<OWLObjectProperty> atomicRoles = getObjectProperties(); 1358 for (OWLObjectProperty role : atomicRoles) { 1359 roleHierarchyDown.put(role, getSubPropertiesImpl(role)); 1360 roleHierarchyUp.put(role, getSuperPropertiesImpl(role)); 1361 } 1362 1363 roleHierarchy = new ObjectPropertyHierarchy(roleHierarchyUp, roleHierarchyDown); 1364 return roleHierarchy; 1365 } 1366 1367 @Override 1368 public final ObjectPropertyHierarchy getObjectPropertyHierarchy() { 1369 try { 1370 if (roleHierarchy == null) { 1371 roleHierarchy = prepareObjectPropertyHierarchy(); 1372 } 1373 } catch (ReasoningMethodUnsupportedException e) { 1374 handleExceptions(e); 1375 } 1376 1377 return roleHierarchy; 1378 } 1379 1380 public boolean isSubPropertyOf(OWLProperty subProperty, OWLProperty superProperty){ 1381 if(subProperty.isOWLObjectProperty() && superProperty.isOWLObjectProperty()){ 1382 return getObjectPropertyHierarchy().isSubpropertyOf((OWLObjectProperty)subProperty, (OWLObjectProperty)superProperty); 1383 } else if(subProperty.isOWLDataProperty() && superProperty.isOWLDataProperty()){ 1384 return getDatatypePropertyHierarchy().isSubpropertyOf((OWLDataProperty)subProperty, (OWLDataProperty)superProperty); 1385 } 1386 return false; 1387 } 1388 1389 /** 1390 * Creates the data property hierarchy. Invoking this method is optional (if 1391 * not called explicitly, it is called the first time, it is needed). 1392 * 1393 * @return The data property hierarchy. 1394 * @throws ReasoningMethodUnsupportedException 1395 * Thrown if data property hierarchy creation is not supported 1396 * by the reasoner. 1397 */ 1398 public DatatypePropertyHierarchy prepareDatatypePropertyHierarchy() 1399 throws ReasoningMethodUnsupportedException { 1400 1401 TreeMap<OWLDataProperty, SortedSet<OWLDataProperty>> datatypePropertyHierarchyUp = new TreeMap<>( 1402 ); 1403 TreeMap<OWLDataProperty, SortedSet<OWLDataProperty>> datatypePropertyHierarchyDown = new TreeMap<>( 1404 ); 1405 1406 Set<OWLDataProperty> datatypeProperties = getDatatypeProperties(); 1407 for (OWLDataProperty role : datatypeProperties) { 1408 datatypePropertyHierarchyDown.put(role, getSubPropertiesImpl(role)); 1409 datatypePropertyHierarchyUp.put(role, getSuperPropertiesImpl(role)); 1410 } 1411 1412 return new DatatypePropertyHierarchy(datatypePropertyHierarchyUp, datatypePropertyHierarchyDown); 1413 } 1414 1415 @Override 1416 public final DatatypePropertyHierarchy getDatatypePropertyHierarchy() { 1417 1418 try { 1419 if (datatypePropertyHierarchy == null) { 1420 datatypePropertyHierarchy = prepareDatatypePropertyHierarchy(); 1421 } 1422 } catch (ReasoningMethodUnsupportedException e) { 1423 handleExceptions(e); 1424 } 1425 1426 return datatypePropertyHierarchy; 1427 } 1428 1429 public List<OWLClass> getAtomicConceptsList() { 1430 if (atomicConceptsList == null) 1431 atomicConceptsList = new LinkedList<>(getClasses()); 1432 return atomicConceptsList; 1433 } 1434 1435 public List<OWLClass> getAtomicConceptsList(boolean removeOWLThing) { 1436 List<OWLClass> classes = Lists.newArrayList(getAtomicConceptsList()); 1437 if (removeOWLThing) { 1438 classes.remove(df.getOWLThing()); 1439 classes.remove(df.getOWLNothing()); 1440 } 1441 return classes; 1442 } 1443 1444 public void setSubsumptionHierarchy(ClassHierarchy subsumptionHierarchy) { 1445 this.subsumptionHierarchy = subsumptionHierarchy; 1446 } 1447 1448 public List<OWLObjectProperty> getAtomicRolesList() { 1449 if (atomicRolesList == null) 1450 atomicRolesList = new LinkedList<>(getObjectProperties()); 1451 return atomicRolesList; 1452 } 1453 1454 public long getInstanceCheckReasoningTimeNs() { 1455 return instanceCheckReasoningTimeNs; 1456 } 1457 1458 public long getRetrievalReasoningTimeNs() { 1459 return retrievalReasoningTimeNs; 1460 } 1461 1462 public int getNrOfInstanceChecks() { 1463 return nrOfInstanceChecks; 1464 } 1465 1466 public int getNrOfRetrievals() { 1467 return nrOfRetrievals; 1468 } 1469 1470 public int getNrOfSubsumptionChecks() { 1471 return nrOfSubsumptionChecks; 1472 } 1473 1474 public long getSubsumptionReasoningTimeNs() { 1475 return subsumptionReasoningTimeNs; 1476 } 1477 1478 public int getNrOfSubsumptionHierarchyQueries() { 1479 return nrOfSubsumptionHierarchyQueries; 1480 } 1481 1482 public long getOverallReasoningTimeNs() { 1483 return overallReasoningTimeNs; 1484 } 1485 1486 public long getTimePerRetrievalNs() { 1487 return retrievalReasoningTimeNs / nrOfRetrievals; 1488 } 1489 1490 public long getTimePerInstanceCheckNs() { 1491 return instanceCheckReasoningTimeNs / nrOfInstanceChecks; 1492 } 1493 1494 public long getTimePerSubsumptionCheckNs() { 1495 return subsumptionReasoningTimeNs / nrOfSubsumptionChecks; 1496 } 1497 1498 public int getNrOfMultiSubsumptionChecks() { 1499 return nrOfMultiSubsumptionChecks; 1500 } 1501 1502 public int getNrOfMultiInstanceChecks() { 1503 return nrOfMultiInstanceChecks; 1504 } 1505 1506 /** 1507 * @param precomputeClassHierarchy the precomputeClassHierarchy to set 1508 */ 1509 public void setPrecomputeClassHierarchy(boolean precomputeClassHierarchy) { 1510 this.precomputeClassHierarchy = precomputeClassHierarchy; 1511 } 1512 1513 /** 1514 * @param precomputeObjectPropertyHierarchy the precomputeObjectPropertyHierarchy to set 1515 */ 1516 public void setPrecomputeObjectPropertyHierarchy(boolean precomputeObjectPropertyHierarchy) { 1517 this.precomputeObjectPropertyHierarchy = precomputeObjectPropertyHierarchy; 1518 } 1519 1520 /** 1521 * @param precomputeDataPropertyHierarchy the precomputeDataPropertyHierarchy to set 1522 */ 1523 public void setPrecomputeDataPropertyHierarchy(boolean precomputeDataPropertyHierarchy) { 1524 this.precomputeDataPropertyHierarchy = precomputeDataPropertyHierarchy; 1525 } 1526 1527 /** 1528 * @return all object properties with its domains. 1529 */ 1530 public Map<OWLObjectProperty, OWLClassExpression> getObjectPropertyDomains() { 1531 Map<OWLObjectProperty, OWLClassExpression> result = new HashMap<>(); 1532 1533 for (OWLObjectProperty op : getObjectProperties()) { 1534 OWLClassExpression domain = getDomain(op); 1535 result.put(op, domain); 1536 } 1537 1538 return result; 1539 } 1540 1541 /** 1542 * @return all object properties with its range. 1543 */ 1544 public Map<OWLObjectProperty, OWLClassExpression> getObjectPropertyRanges() { 1545 Map<OWLObjectProperty, OWLClassExpression> result = new HashMap<>(); 1546 1547 for (OWLObjectProperty op : getObjectProperties()) { 1548 OWLClassExpression range = getRange(op); 1549 result.put(op, range); 1550 } 1551 1552 return result; 1553 } 1554 1555 /** 1556 * @return all data properties with its domains. 1557 */ 1558 public Map<OWLDataProperty, OWLClassExpression> getDataPropertyDomains() { 1559 Map<OWLDataProperty, OWLClassExpression> result = new HashMap<>(); 1560 1561 for (OWLDataProperty dp : getDatatypeProperties()) { 1562 OWLClassExpression domain = getDomain(dp); 1563 result.put(dp, domain); 1564 } 1565 1566 return result; 1567 } 1568 1569 @Override 1570 public String toString() { 1571 String str = ""; 1572 if (nrOfRetrievals > 0) { 1573 str += "number of retrievals: " + nrOfRetrievals + "\n"; 1574 str += "retrieval reasoning time: " 1575 + Helper.prettyPrintNanoSeconds(retrievalReasoningTimeNs) 1576 + " ( " + Helper.prettyPrintNanoSeconds(getTimePerRetrievalNs()) 1577 + " per retrieval)" + "\n"; 1578 } 1579 if (nrOfInstanceChecks > 0) { 1580 str += "number of instance checks: " + nrOfInstanceChecks + " (" 1581 + nrOfMultiInstanceChecks + " multiple)\n"; 1582 str += "instance check reasoning time: " 1583 + Helper.prettyPrintNanoSeconds(instanceCheckReasoningTimeNs) + " ( " 1584 + Helper.prettyPrintNanoSeconds(getTimePerInstanceCheckNs()) 1585 + " per instance check)\n"; 1586 } 1587 if (nrOfSubsumptionHierarchyQueries > 0) { 1588 str += "subsumption hierarchy queries: " 1589 + nrOfSubsumptionHierarchyQueries + "\n"; 1590 } 1591 if (nrOfSubsumptionChecks > 0) { 1592 str += "(complex) subsumption checks: " + nrOfSubsumptionChecks 1593 + " (" + nrOfMultiSubsumptionChecks + " multiple)\n"; 1594 str += "subsumption reasoning time: " 1595 + Helper.prettyPrintNanoSeconds(subsumptionReasoningTimeNs) + " ( " 1596 + Helper.prettyPrintNanoSeconds(getTimePerSubsumptionCheckNs()) 1597 + " per subsumption check)\n"; 1598 } 1599 str += "overall reasoning time: " 1600 + Helper.prettyPrintNanoSeconds(overallReasoningTimeNs) + "\n"; 1601 return str; 1602 } 1603 1604 /************************************************************** 1605 * FUZZY EXTENSIONS 1606 **************************************************************/ 1607 1608 @Override 1609 public double hasTypeFuzzyMembership(OWLClassExpression description, FuzzyIndividual individual) { 1610 reasoningStartTimeTmp = System.nanoTime(); 1611 double result = -1; 1612 try { 1613 result = hasTypeFuzzyMembershipImpl(description, individual); 1614 } catch (ReasoningMethodUnsupportedException e) { 1615 handleExceptions(e); 1616 } 1617 nrOfInstanceChecks++; 1618 reasoningDurationTmp = System.nanoTime() - reasoningStartTimeTmp; 1619 instanceCheckReasoningTimeNs += reasoningDurationTmp; 1620 overallReasoningTimeNs += reasoningDurationTmp; 1621 return result; 1622 } 1623 1624 protected double hasTypeFuzzyMembershipImpl(OWLClassExpression concept, FuzzyIndividual individual) 1625 throws ReasoningMethodUnsupportedException { 1626 throw new ReasoningMethodUnsupportedException(); 1627 } 1628 1629 /** 1630 * Returns the datatype of the data property, i.e. the range if it is a datatype. 1631 * @param dp the data property 1632 * @return the datatype of the data property 1633 */ 1634 public abstract OWLDatatype getDatatype(OWLDataProperty dp); 1635 1636 /** 1637 * Enabled a synchronized mode such that all reasoner methods are supposed 1638 * to be thread safe. 1639 */ 1640 public abstract void setSynchronized(); 1641 1642 public boolean isUseInstanceChecks() { 1643 return useInstanceChecks; 1644 } 1645 1646 public void setUseInstanceChecks(boolean useInstanceChecks) { 1647 this.useInstanceChecks = useInstanceChecks; 1648 } 1649}