001package conexp.fx.core.dl; 002 003/* 004 * #%L 005 * Concept Explorer FX 006 * %% 007 * Copyright (C) 2010 - 2019 Francesco Kriegel 008 * %% 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as 011 * published by the Free Software Foundation, either version 3 of the 012 * License, or (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public 020 * License along with this program. If not, see 021 * <http://www.gnu.org/licenses/gpl-3.0.html>. 022 * #L% 023 */ 024 025import java.util.Arrays; 026import java.util.Collection; 027import java.util.Collections; 028import java.util.HashSet; 029import java.util.Iterator; 030import java.util.List; 031import java.util.Map; 032import java.util.Map.Entry; 033import java.util.Set; 034import java.util.concurrent.ConcurrentHashMap; 035import java.util.function.BiFunction; 036import java.util.function.BiPredicate; 037import java.util.function.Function; 038import java.util.function.Supplier; 039import java.util.stream.Collectors; 040import java.util.stream.IntStream; 041import java.util.stream.Stream; 042 043import org.semanticweb.owlapi.apibinding.OWLManager; 044import org.semanticweb.owlapi.model.IRI; 045import org.semanticweb.owlapi.model.OWLClass; 046import org.semanticweb.owlapi.model.OWLClassExpression; 047import org.semanticweb.owlapi.model.OWLDataFactory; 048import org.semanticweb.owlapi.model.OWLObjectIntersectionOf; 049import org.semanticweb.owlapi.model.OWLObjectProperty; 050import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; 051 052import com.google.common.collect.Collections2; 053import com.google.common.collect.HashMultimap; 054import com.google.common.collect.Multimap; 055import com.google.common.collect.Sets; 056 057import conexp.fx.core.collections.Collections3; 058import conexp.fx.core.collections.Pair; 059import conexp.fx.core.math.LatticeElement; 060import conexp.fx.core.util.UnicodeSymbols; 061 062public final class ELConceptDescription implements LatticeElement<ELConceptDescription>, Cloneable { 063 064 private static final OWLDataFactory df = OWLManager.getOWLDataFactory(); 065 066 public static final ELConceptDescription of(final OWLClassExpression concept) { 067 return new ELConceptDescription(concept); 068 } 069 070 public static final ELConceptDescription parse(final String expression) { 071 return ELParser.read(expression); 072 } 073 074 public static final ELConceptDescription bot() { 075 return new ELConceptDescription(Sets.newHashSet(df.getOWLNothing().getIRI()), HashMultimap.create()); 076 } 077 078 public static final ELConceptDescription top() { 079 return new ELConceptDescription(); 080 } 081 082 public static final ELConceptDescription conceptName(final IRI conceptName) { 083 return new ELConceptDescription(Sets.newHashSet(conceptName), HashMultimap.create()); 084 } 085 086 public static final ELConceptDescription 087 existentialRestriction(final IRI roleName, final ELConceptDescription filler) { 088 final ELConceptDescription C = new ELConceptDescription(); 089 C.getExistentialRestrictions().put(roleName, filler); 090 return C; 091 } 092 093 public static final ELConceptDescription existentialRestriction(List<IRI> rs, ELConceptDescription C) { 094 ELConceptDescription rsC = C.clone(); 095 for (IRI r : rs) 096 rsC = ELConceptDescription.existentialRestriction(r, rsC); 097 return rsC; 098 } 099 100 public static final ELConceptDescription existentialRestriction(final Entry<IRI, ELConceptDescription> entry) { 101 return entry.getValue().exists(entry.getKey()); 102 } 103 104 public static final ELConceptDescription conjunction(final ELConceptDescription... conjuncts) { 105 return conjunction(Arrays.asList(conjuncts)); 106 } 107 108 public static final ELConceptDescription conjunction(final Collection<ELConceptDescription> conjuncts) { 109 final ELConceptDescription conjunction = new ELConceptDescription(); 110 conjuncts.forEach(conjunct -> { 111 conjunction.getConceptNames().addAll(conjunct.getConceptNames()); 112 conjunction.getExistentialRestrictions().putAll(conjunct.getExistentialRestrictions()); 113 }); 114 return conjunction; 115 } 116 117 public static final ELConceptDescription 118 random(final Signature sigma, final int maxRoleDepth, final int minSize, final int maxSize) { 119 if (maxRoleDepth < 0 || minSize < 0 || maxSize < 0 || minSize > maxSize) 120 throw new IllegalArgumentException(); 121 final double p = Math.random(); 122 final double q = Math.random(); 123 final ELConceptDescription C = new ELConceptDescription(); 124 for (IRI A : sigma.getConceptNames()) 125 if (C.size() >= maxSize) 126 return C; 127 else if (Math.random() < p) 128 C.conceptNames.add(A); 129 if (maxRoleDepth > 0) 130 for (IRI r : sigma.getRoleNames()) 131 while (Math.random() < q) 132 if (C.size() >= maxSize) 133 return C; 134 else 135 C.existentialRestrictions 136 .put(r, ELConceptDescription.random(sigma, maxRoleDepth - 1, 0, maxSize - C.size())); 137 if (C.size() >= minSize) 138 return C; 139 else 140 return random(sigma, maxRoleDepth, minSize, maxSize); 141 } 142 143 public static final BiPredicate<ELConceptDescription, ELConceptDescription> quasiOrder() { 144 return (x, y) -> x.isSubsumedBy(y); 145 } 146 147 public static final BiPredicate<ELConceptDescription, ELConceptDescription> dualQuasiOrder() { 148 return (x, y) -> x.subsumes(y); 149 } 150 151 public static final BiPredicate<ELConceptDescription, ELConceptDescription> equivalence() { 152 return (x, y) -> x.isEquivalentTo(y); 153 } 154 155 public static final BiPredicate<ELConceptDescription, ELConceptDescription> neighborhood() { 156 return (x, y) -> x.isLowerNeighborOf(y); 157 } 158 159 public static final BiPredicate<ELConceptDescription, ELConceptDescription> dualNeighborhood() { 160 return (x, y) -> x.isUpperNeighborOf(y); 161 } 162 163 public static final BiFunction<ELConceptDescription, ELConceptDescription, Integer> distance() { 164 return (x, y) -> x.distanceTo(y); 165 } 166 167 private final Set<IRI> conceptNames; 168 private final Multimap<IRI, ELConceptDescription> existentialRestrictions; 169 // private final Set<Pair<IRI, ELConceptDescription>> valueRestrictions; 170 // private final Set<Pair<Pair<Integer, IRI>, ELConceptDescription>> 171 // qualifiedGreaterThanRestrictions; 172 // private final Set<Pair<Pair<Integer, IRI>, ELConceptDescription>> 173 // qualifiedSmallerThanRestrictions; 174 // private final Set<IRI> negatedConceptNames; 175 // private final Set<IRI> extistentialSelfRestrictions; 176 177 /** 178 * @param concept 179 * 180 * Creates a new EL normal form from an OWLClassExpression. 181 */ 182 public ELConceptDescription(final OWLClassExpression concept) { 183 super(); 184 this.conceptNames = new HashSet<>(); 185 this.existentialRestrictions = HashMultimap.create(); 186 if (concept.isOWLThing()) 187 return; 188 if (concept.isOWLNothing()) { 189 conceptNames.add(df.getOWLNothing().getIRI()); 190 return; 191 } 192 if (concept instanceof OWLClass) { 193 this.conceptNames.add(((OWLClass) concept).getIRI()); 194 return; 195 } 196 if (concept instanceof OWLObjectSomeValuesFrom) { 197 final OWLObjectSomeValuesFrom existentialRestriction = (OWLObjectSomeValuesFrom) concept; 198 this.existentialRestrictions 199 .put( 200 ((OWLObjectProperty) existentialRestriction.getProperty()).getIRI(), 201 new ELConceptDescription(existentialRestriction.getFiller())); 202 return; 203 } 204 if (concept instanceof OWLObjectIntersectionOf) { 205 final OWLObjectIntersectionOf conjunction = (OWLObjectIntersectionOf) concept; 206 for (OWLClassExpression conjunct : conjunction.asConjunctSet()) 207 if (conjunct instanceof OWLClass) 208 this.conceptNames.add(((OWLClass) conjunct).getIRI()); 209 else if (conjunct instanceof OWLObjectSomeValuesFrom) 210 this.existentialRestrictions 211 .put( 212 ((OWLObjectProperty) ((OWLObjectSomeValuesFrom) conjunct).getProperty()).getIRI(), 213 new ELConceptDescription(((OWLObjectSomeValuesFrom) conjunct).getFiller())); 214 else 215 throw new ELSyntaxException(); 216 return; 217 } 218 throw new ELSyntaxException(); 219 } 220 221 /** 222 * @param conceptNames 223 * @param existentialRestrictions 224 * 225 * Creates a new EL normal form. If the sets conceptNames and existentitalRestrictions are both empty, then 226 * the constructed normal form represents the top concept. 227 */ 228 public ELConceptDescription( 229 final Set<IRI> conceptNames, 230 final Multimap<IRI, ELConceptDescription> existentialRestrictions) { 231 super(); 232 this.conceptNames = conceptNames; 233 this.existentialRestrictions = existentialRestrictions; 234 } 235 236 public ELConceptDescription() { 237 this.conceptNames = Sets.newHashSet(); 238 this.existentialRestrictions = HashMultimap.create(); 239 } 240 241 public final boolean isBot() { 242 return conceptNames.contains(df.getOWLNothing().getIRI()); 243 } 244 245 public final boolean isTop() { 246 return conceptNames.isEmpty() && existentialRestrictions.isEmpty(); 247 } 248 249 public final Signature getSignature() { 250 final Signature sigma = new Signature(IRI.generateDocumentIRI()); 251 sigma.getConceptNames().addAll(getConceptNamesInSignature().collect(Collectors.toSet())); 252 sigma.getRoleNames().addAll(getRoleNamesInSignature().collect(Collectors.toSet())); 253 return sigma; 254 } 255 256 protected final Stream<IRI> getConceptNamesInSignature() { 257 return Stream 258 .concat( 259 conceptNames.parallelStream(), 260 existentialRestrictions 261 .values() 262 .parallelStream() 263 .flatMap(ELConceptDescription::getConceptNamesInSignature)); 264 } 265 266 protected final Stream<IRI> getRoleNamesInSignature() { 267 return Stream 268 .concat( 269 existentialRestrictions.keys().parallelStream(), 270 existentialRestrictions.values().parallelStream().flatMap(ELConceptDescription::getRoleNamesInSignature)); 271 } 272 273 public final Set<IRI> getConceptNames() { 274 return conceptNames; 275 } 276 277 public final Multimap<IRI, ELConceptDescription> getExistentialRestrictions() { 278 return existentialRestrictions; 279 } 280 281 public final OWLClassExpression toOWLClassExpression() { 282 if (isTop()) 283 return df.getOWLThing(); 284 if (isBot()) 285 return df.getOWLNothing(); 286 if (conceptNames.size() == 1 && existentialRestrictions.isEmpty()) 287 return df.getOWLClass(conceptNames.iterator().next()); 288 if (conceptNames.isEmpty() && existentialRestrictions.size() == 1) { 289 final Entry<IRI, ELConceptDescription> existentialRestriction = 290 existentialRestrictions.entries().iterator().next(); 291 return df 292 .getOWLObjectSomeValuesFrom( 293 df.getOWLObjectProperty(existentialRestriction.getKey()), 294 existentialRestriction.getValue().toOWLClassExpression()); 295 } 296 final Set<OWLClassExpression> conjuncts = new HashSet<>(); 297 for (IRI conceptName : conceptNames) 298 conjuncts.add(df.getOWLClass(conceptName)); 299 for (Entry<IRI, ELConceptDescription> existentialRestriction : existentialRestrictions.entries()) 300 conjuncts 301 .add( 302 df 303 .getOWLObjectSomeValuesFrom( 304 df.getOWLObjectProperty(existentialRestriction.getKey()), 305 existentialRestriction.getValue().toOWLClassExpression())); 306 return df.getOWLObjectIntersectionOf(conjuncts); 307 } 308 309 public final ELConceptDescription and(final ELConceptDescription that) { 310 return ELConceptDescription.conjunction(this, that); 311 } 312 313 public final ELConceptDescription exists(final IRI roleName) { 314 return ELConceptDescription.existentialRestriction(roleName, this); 315 } 316 317 public final ELConceptDescription lcs(final ELConceptDescription that) { 318 return ELLeastCommonSubsumer.lcsOfMutuallyIncomparable(this, that); 319 } 320 321 public final ELConceptDescription without(final ELConceptDescription that) { 322 final ELConceptDescription result = this.clone(); 323 result.getConceptNames().removeAll(that.getConceptNames()); 324 result 325 .getExistentialRestrictions() 326 .entries() 327 .removeIf(rE -> that.isSubsumedBy(ELConceptDescription.existentialRestriction(rE))); 328 return result; 329 } 330 331 public final boolean isSubsumedBy(final ELConceptDescription other) { 332 return ELReasoner.isSubsumedBy(this, other); 333 } 334 335 public final boolean subsumes(final ELConceptDescription other) { 336 return ELReasoner.subsumes(this, other); 337 } 338 339 public final boolean isEquivalentTo(final ELConceptDescription other) { 340 return Stream 341 .<Supplier<Boolean>> of(() -> this.subsumes(other), () -> other.subsumes(this)) 342 .parallel() 343 .allMatch(Supplier::get); 344 } 345 346 public final boolean isLowerNeighborOf(final ELConceptDescription other) { 347 return this.upperNeighborsReduced().parallelStream().anyMatch(other::isEquivalentTo); 348 } 349 350 public final boolean isUpperNeighborOf(final ELConceptDescription other) { 351 return other.isLowerNeighborOf(this); 352 } 353 354 public final ELConceptDescription reduce() { 355 for (Entry<IRI, ELConceptDescription> er : existentialRestrictions.entries()) 356 er.getValue().reduce(); 357 final Function<Entry<IRI, ELConceptDescription>, Stream<Pair<Entry<IRI, ELConceptDescription>, Entry<IRI, ELConceptDescription>>>> f = 358 er1 -> existentialRestrictions 359 .entries() 360 .parallelStream() 361 .filter(er2 -> er1.getKey().equals(er2.getKey())) 362 .filter(er2 -> !er1.equals(er2)) 363 .map(er2 -> Pair.of(er1, er2)); 364 final Set<Entry<IRI, ELConceptDescription>> superfluousERs = existentialRestrictions 365 .entries() 366 .parallelStream() 367 .map(f) 368 .reduce(Stream::concat) 369 .orElseGet(Stream::empty) 370 .filter(p -> p.first().getValue().isSubsumedBy(p.second().getValue())) 371 .map(Pair::second) 372 .collect(Collectors.toSet()); 373 superfluousERs.forEach(x -> existentialRestrictions.remove(x.getKey(), x.getValue())); 374 return this; 375 } 376 377 public final int roleDepth() { 378 if (existentialRestrictions.isEmpty()) 379 return 0; 380 return 1 + existentialRestrictions 381 .entries() 382 .parallelStream() 383 .map(Entry::getValue) 384 .map(ELConceptDescription::roleDepth) 385 .max(Integer::compare) 386 .orElse(0); 387 } 388 389 public final void restrictTo(final int roleDepth) { 390 if (roleDepth < 0) 391 throw new IllegalArgumentException(); 392 else if (roleDepth == 0) 393 existentialRestrictions.clear(); 394 else 395 existentialRestrictions.values().parallelStream().forEach(filler -> filler.restrictTo(roleDepth - 1)); 396 } 397 398 public final Collection<ELConceptDescription> topLevelConjuncts() { 399 return Collections3 400 .union( 401 Collections2.transform(conceptNames, ELConceptDescription::conceptName), 402 Collections2.transform(existentialRestrictions.entries(), ELConceptDescription::existentialRestriction)); 403// return Collections3.transform( 404// conceptNames, 405// GuavaIsomorphism.create(A -> ELConceptDescription.conceptName(A), A -> A.getConceptNames().iterator().next())); 406// return conceptNames.size() + existentialRestrictions.size(); 407 } 408 409 public final int size() { 410 return Math 411 .max( 412 1, 413 2 * conceptNames.size() + existentialRestrictions.size() - 1 414 + existentialRestrictions 415 .entries() 416 .parallelStream() 417 .map(Entry::getValue) 418 .map((ELConceptDescription c) -> 1 + c.size()) 419 .reduce(0, Integer::sum)); 420 } 421 422 public final int size2() { 423 return conceptNames.size() + existentialRestrictions 424 .entries() 425 .parallelStream() 426 .map(Entry::getValue) 427 .map(C -> 1 + C.size2()) 428 .reduce(0, Integer::sum); 429 } 430 431 public final long rank5() { 432 long rank = 0; 433 ELConceptDescription C = this.clone().reduce(); 434 while (!C.isTop()) { 435 C = C.oneUpperNeighbor(); 436 rank++; 437 } 438 return rank; 439 } 440 441 public final int rank() { 442 return this.clone().reduce().unreducedRank(); 443 } 444 445 public final int unreducedRank() { 446 if (this.isTop()) 447 return 0; 448 else 449 return 1 + this.oneUpperNeighbor().unreducedRank(); 450 } 451 452 private final ELConceptDescription oneUpperNeighbor() { 453 if (!this.conceptNames.isEmpty()) { 454 final ELConceptDescription upperNeighbor = this.clone(); 455 final Iterator<IRI> it = upperNeighbor.conceptNames.iterator(); 456 it.next(); 457 it.remove(); 458 return upperNeighbor; 459 } else if (!this.existentialRestrictions.isEmpty()) { 460 final ELConceptDescription upperNeighbor = this.clone(); 461 final Iterator<Entry<IRI, ELConceptDescription>> it = upperNeighbor.existentialRestrictions.entries().iterator(); 462 final Entry<IRI, ELConceptDescription> ER = it.next(); 463 it.remove(); 464 ER 465 .getValue() 466 .upperNeighborsReduced() 467 .parallelStream() 468 .filter( 469 uER -> upperNeighbor.existentialRestrictions 470 .entries() 471 .parallelStream() 472 .filter(otherER -> !otherER.equals(ER)) 473 .filter(otherER -> ER.getKey().equals(otherER.getKey())) 474 .map(Entry::getValue) 475 .noneMatch(uER::subsumes)) 476 .map(uER -> Pair.of(ER.getKey(), uER)) 477 .sequential() 478 .forEach(p -> upperNeighbor.existentialRestrictions.put(p.first(), p.second())); 479 return upperNeighbor; 480 } else 481 return null; 482 } 483 484// public final int rank2() { 485// final ELConceptDescription C = this.clone().reduce(); 486// int r = C.conceptNames.size(); 487// C.conceptNames.clear(); 488// if (C.existentialRestrictions.isEmpty()) 489// return r; 490// else if (C.existentialRestrictions.size() == 1) 491// return r + rank2existentialRestriction( 492// ELConceptDescription.existentialRestriction(C.existentialRestrictions.iterator().next())); 493// else 494// return r + rank2conjunction(C); 495// } 496// 497// private static final int rank2conjunction(final ELConceptDescription conjunction) { 498// if (!conjunction.conceptNames.isEmpty()) 499// throw new IllegalArgumentException(); 500// final Set<Pair<IRI, ELConceptDescription>> conjuncts = conjunction.existentialRestrictions; 501// if (conjuncts.isEmpty()) 502// return 0; 503// else if (conjuncts.size() == 1) 504// return rank2existentialRestriction(ELConceptDescription.existentialRestriction(conjuncts.iterator().next())); 505// else { 506// return IntStream.range(1, conjuncts.size() + 1).boxed().map(i -> { 507// return (int) (Math.pow(-1, i + 1) * Sets 508// .combinations( 509// conjuncts 510// .parallelStream() 511// .map(ELConceptDescription::existentialRestriction) 512// // .map(ELConceptDescription::clone) 513// .collect(Collectors.toSet()), 514// i) 515// .parallelStream() 516// .map(ELLeastCommonSubsumer::_of) 517// .map(ELConceptDescription::clone) 518// // .map(ELConceptDescription::getReducedForm) 519// .collect(Collectors.summingInt(ELConceptDescription::rank2conjunction))); 520// }).collect(Collectors.summingInt(Integer::intValue)); 521// } 522// } 523// 524// private static final int rank2existentialRestriction(final ELConceptDescription existentialRestriction) { 525// if (!existentialRestriction.conceptNames.isEmpty()) 526// throw new IllegalArgumentException(); 527// else if (existentialRestriction.existentialRestrictions.size() != 1) 528// throw new IllegalArgumentException(); 529// else { 530// final Pair<IRI, ELConceptDescription> rC = existentialRestriction.existentialRestrictions.iterator().next(); 531// final IRI r = rC.first(); 532// final ELConceptDescription C = rC.second(); 533// C.reduce(); 534// return 1 + rank2conjunction( 535// new ELConceptDescription( 536// new HashSet<>(), 537// C.upperNeighborsReduced().parallelStream().map(D -> Pair.of(r, D)).collect(Collectors.toSet()))); 538// } 539// } 540 541 public final int rank2() { 542 return this.clone().reduce().unreducedRank2(); 543 } 544 545 public final int unreducedRank2() { 546 return this.getConceptNames().size() + this.getExistentialRestrictions().keySet().parallelStream().map(r -> { 547 final ELConceptDescription rDs = new ELConceptDescription(); 548 rDs.getExistentialRestrictions().putAll(r, this.getExistentialRestrictions().get(r)); 549 return rDs; 550 }).mapToInt(ELConceptDescription::unreducedRank).sum(); 551 } 552 553 public final int rank3() { 554// final Set<ELConceptDescription> Us = representatives(upperNeighborsReduced(), (X, Y) -> X.isEquivalentTo(Y)); 555 final Set<ELConceptDescription> Us = upperNeighborsReduced(); 556// if (Us.parallelStream().anyMatch(X -> Us.parallelStream().filter(Y -> X != Y).anyMatch(X::isEquivalentTo))) 557// throw new RuntimeException(); 558 if (Us.isEmpty()) 559 return 0; 560 else if (Us.size() == 1) 561 return 1 + Us.iterator().next().clone().reduce().rank3(); 562 else 563 return Us.size() + ELLeastCommonSubsumer.lcs(Us).clone().reduce().rank3(); 564 } 565 566 public final int rank4() { 567 return this.clone().reduce().unreducedRank4(); 568 } 569 570 public final int unreducedRank4() { 571 return this.getConceptNames().size() + this 572 .getExistentialRestrictions() 573 .keySet() 574 .parallelStream() 575 .map(r -> this.getExistentialRestrictions().get(r)) 576 .mapToInt(ELConceptDescription::recurseUnreducedRank4) 577 .sum(); 578 } 579 580 private static final int recurseUnreducedRank4(final Collection<ELConceptDescription> Ds) { 581 if (Ds.isEmpty()) 582 return 0; 583 else if (Ds.size() == 1) 584 return 1 + recurseUnreducedRank4(Ds.iterator().next().upperNeighborsReduced()); 585 else 586 return IntStream 587 .range(1, Ds.size() + 1) 588 .boxed() 589 .map( 590 i -> (int) (Math.pow(-1, i + 1) * Sets 591 .combinations(Sets.newHashSet(Ds), i) 592 .parallelStream() 593 .map(ELLeastCommonSubsumer::lcs) 594 .map(ELConceptDescription::reduce) 595 .collect(Collectors.toSet()) 596 .parallelStream() 597 .map(Collections::singleton) 598 .collect(Collectors.summingInt(ELConceptDescription::recurseUnreducedRank4)))) 599 .collect(Collectors.summingInt(Integer::valueOf)); 600 } 601 602 public final int distanceTo(final ELConceptDescription other) { 603 final List<Integer> x = Stream 604 .<Supplier<Integer>> of( 605 () -> ELConceptDescription.conjunction(this, other).rank(), 606 () -> ELLeastCommonSubsumer.lcs(this, other).rank()) 607 .parallel() 608 .map(Supplier::get) 609 .collect(Collectors.toList()); 610 return x.get(0) - x.get(1); 611 } 612 613 public final int distanceTo2(final ELConceptDescription other) { 614 final ELConceptDescription lcs = ELLeastCommonSubsumer.lcs(this, other); 615 int distance = -1; 616 for (ELConceptDescription C = ELConceptDescription.conjunction(this, other).reduce(); C != null; C = 617 C.oneUpperNeighborBelow(lcs)) 618 distance++; 619 return distance; 620 } 621 622 private final ELConceptDescription oneUpperNeighborBelow(final ELConceptDescription other) { 623 return Stream.concat(this.conceptNames.parallelStream().map(A -> { 624 final ELConceptDescription upperNeighbor = this.clone(); 625 upperNeighbor.conceptNames.remove(A); 626 return upperNeighbor; 627 }), this.existentialRestrictions.entries().parallelStream().map(ER -> { 628 final ELConceptDescription upperNeighbor = this.clone(); 629 upperNeighbor.existentialRestrictions.remove(ER.getKey(), ER.getValue()); 630 ER 631 .getValue() 632 .upperNeighborsReduced() 633 .parallelStream() 634 .filter( 635 uER -> upperNeighbor.existentialRestrictions 636 .entries() 637 .parallelStream() 638 .filter(otherER -> !otherER.equals(ER)) 639 .filter(otherER -> ER.getKey().equals(otherER.getKey())) 640 .map(Entry::getValue) 641 .noneMatch(uER::subsumes)) 642 .map(uER -> Pair.of(ER.getKey(), uER)) 643 .sequential() 644 .forEach(p -> upperNeighbor.existentialRestrictions.put(p.first(), p.second())); 645 return upperNeighbor; 646 })).filter(other::subsumes).findAny().orElse(null); 647 } 648 649 public final Set<ELConceptDescription> neighborhood(final int radius, final Signature sigma) { 650 if (radius < 0) 651 throw new IllegalArgumentException(); 652 final Set<ELConceptDescription> next = Sets.newHashSet(this); 653 final Set<ELConceptDescription> neighborhood = Sets.newHashSet(this); 654 for (int k = 0; k < radius; k++) { 655 final Set<ELConceptDescription> news = Stream 656 .concat( 657 next.parallelStream().flatMap(C -> C.upperNeighborsReduced().parallelStream()), 658 next.parallelStream().flatMap(C -> C.lowerNeighborsReduced1(sigma).parallelStream())) 659 .collect(Collectors.toSet()); 660 next.clear(); 661 next.addAll(news); 662 next.removeAll(neighborhood); 663 neighborhood.addAll(news); 664 } 665 return neighborhood; 666 } 667 668 public final Set<ELConceptDescription> upperNeighbors() { 669 final ELConceptDescription reducedForm = this.clone().reduce(); 670 return Stream.concat(reducedForm.conceptNames.parallelStream().map(A -> { 671 final ELConceptDescription upperNeighbor = reducedForm.clone(); 672 upperNeighbor.conceptNames.remove(A); 673 return upperNeighbor; 674 }), reducedForm.existentialRestrictions.entries().parallelStream().map(ER -> { 675 final ELConceptDescription upperNeighbor = reducedForm.clone(); 676 upperNeighbor.existentialRestrictions.remove(ER.getKey(), ER.getValue()); 677 ER.getValue().upperNeighbors().forEach(uER -> upperNeighbor.existentialRestrictions.put(ER.getKey(), uER)); 678 return upperNeighbor; 679 }) 680// .filter(other -> !this.subsumes(other))) 681 ).collect(Collectors.toSet()); 682 } 683 684 public final Set<ELConceptDescription> upperNeighborsReduced() { 685 final ELConceptDescription reducedForm = this.clone().reduce(); 686 return Collections3.representatives(Stream.concat(reducedForm.conceptNames.parallelStream().map(A -> { 687 final ELConceptDescription upperNeighbor = reducedForm.clone(); 688 upperNeighbor.conceptNames.remove(A); 689 return upperNeighbor; 690 }), reducedForm.existentialRestrictions.entries().parallelStream().map(ER -> { 691 final ELConceptDescription upperNeighbor = reducedForm.clone(); 692 upperNeighbor.existentialRestrictions.remove(ER.getKey(), ER.getValue()); 693 ER 694 .getValue() 695 .upperNeighborsReduced() 696 .parallelStream() 697 .filter( 698 uER -> reducedForm.existentialRestrictions 699 .entries() 700 .parallelStream() 701 .filter(otherER -> !otherER.equals(ER)) 702 .filter(otherER -> ER.getKey().equals(otherER.getKey())) 703 .map(Entry::getValue) 704 .noneMatch(uER::subsumes)) 705 .sequential() 706 .forEach(uER -> upperNeighbor.existentialRestrictions.put(ER.getKey(), uER)); 707 return upperNeighbor; 708 }) 709// .filter(other -> !this.subsumes(other))) 710 ).collect(Collectors.toSet()), (X, Y) -> X.isEquivalentTo(Y)); 711 } 712 713 public final Set<ELConceptDescription> lowerNeighbors(final Signature sigma) { 714 final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 715 final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 716 sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 717 final ELConceptDescription lowerNeighbor = C.clone(); 718 lowerNeighbor.conceptNames.add(A); 719 return lowerNeighbor; 720 }).forEach(lowerNeighbors::add); 721 sigma.getRoleNames().parallelStream().forEach(r -> { 722 final Set<ELConceptDescription> filter = C.existentialRestrictions 723 .entries() 724 .parallelStream() 725 .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 726 .map(Entry::getValue) 727 .collect(Collectors.toSet()); 728// if (filter.isEmpty()) { 729// final ELConceptDescription lowerNeighbor = C.clone(); 730// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 731// lowerNeighbors.add(lowerNeighbor); 732// } else { 733 Sets 734 .powerSet(filter) 735 .parallelStream() 736 // .filter(FF -> !FF.isEmpty()) 737 .forEach(FF -> { 738 final Map<ELConceptDescription, Set<ELConceptDescription>> choices = new ConcurrentHashMap<>(); 739 FF.parallelStream().forEach(F -> { 740 final Set<ELConceptDescription> choicesForF = Sets.newConcurrentHashSet(); 741 choices.put(F, choicesForF); 742 F.lowerNeighbors(sigma).parallelStream().forEach(L -> { 743 // final ELConceptDescription X = L.clone(); 744 // X.getConceptNames().removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 745 // X.getExistentialRestrictions().entries().removeIf( 746 // rD -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rD))); 747 final ELConceptDescription X = L.without(F); 748 if (X.isTop()) { 749 System.out.println("F = " + F); 750 System.out.println("L = " + L); 751 System.out.println("X = " + X); 752 throw new RuntimeException(); 753 } 754 if (FF.parallelStream().filter(F1 -> !F.equals(F1)).allMatch(F1 -> F1.isSubsumedBy(X))) 755 choicesForF.add(X); 756 }); 757 }); 758 choices 759 .keySet() 760 .parallelStream() 761 .map(choices::get) 762 .reduce( 763 Collections.singleton(Collections.<ELConceptDescription> emptySet()), 764 (X, Y) -> X.parallelStream().flatMap(x -> Y.parallelStream().map(y -> { 765 final Set<ELConceptDescription> xy = Sets.newHashSet(x); 766 xy.add(y); 767 return xy; 768 })).collect(Collectors.toSet()), 769 (X, Y) -> X.parallelStream().flatMap(x -> Y.parallelStream().map(y -> { 770 final Set<ELConceptDescription> xy = Sets.newHashSet(x); 771 xy.addAll(y); 772 return xy; 773 })).collect(Collectors.toSet())) 774 .parallelStream() 775 .forEach(f -> { 776 final ELConceptDescription D = ELConceptDescription.conjunction(f); 777 if (filter.parallelStream().filter(F0 -> !FF.contains(F0)).noneMatch(F0 -> F0.isSubsumedBy(D))) { 778 final ELConceptDescription C_and_rD = C.clone(); 779 C_and_rD.getExistentialRestrictions().put(r, D.clone()); 780 lowerNeighbors.add(C_and_rD); 781 // System.out.println("new lower neighbor found: C⊓∃" + r + "." + D); 782 } 783 }); 784 }); 785// } 786 }); 787 return lowerNeighbors; 788 } 789 790 public final Set<ELConceptDescription> lowerNeighborsA(final Signature sigma) { 791 final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 792 final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 793 sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 794 final ELConceptDescription lowerNeighbor = C.clone(); 795 lowerNeighbor.conceptNames.add(A); 796 return lowerNeighbor; 797 }).forEach(lowerNeighbors::add); 798 sigma.getRoleNames().parallelStream().forEach(r -> { 799 final Set<ELConceptDescription> filter = C.existentialRestrictions 800 .entries() 801 .parallelStream() 802 .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 803 .map(Entry::getValue) 804 .collect(Collectors.toSet()); 805// if (filter.isEmpty()) { 806// final ELConceptDescription lowerNeighbor = C.clone(); 807// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 808// lowerNeighbors.add(lowerNeighbor); 809// } else { 810 final Map<ELConceptDescription, Set<ELConceptDescription>> choices = new ConcurrentHashMap<>(); 811 filter.parallelStream().forEach(F -> { 812 final Set<ELConceptDescription> choicesForF = Sets.newConcurrentHashSet(); 813 choices.put(F, choicesForF); 814 F.lowerNeighbors(sigma).parallelStream().forEach(L -> { 815 choicesForF.add(L.without(F)); 816 }); 817 }); 818 Sets 819 .powerSet(filter) 820 .parallelStream() 821 // .filter(FF -> !FF.isEmpty()) 822 .forEach(FF -> { 823 choices 824 .entrySet() 825 .parallelStream() 826 .filter(entry -> FF.contains(entry.getKey())) 827 .map( 828 entry -> Sets 829 .filter( 830 entry.getValue(), 831 X -> FF 832 .parallelStream() 833 .filter(F1 -> !entry.getKey().equals(F1)) 834 .allMatch(F1 -> F1.isSubsumedBy(X)))) 835 .reduce( 836 Collections.singleton(Collections.<ELConceptDescription> emptySet()), 837 (X, Y) -> X.parallelStream().flatMap(x -> Y.parallelStream().map(y -> { 838 final Set<ELConceptDescription> xy = Sets.newHashSet(x); 839 xy.add(y); 840 return xy; 841 })).collect(Collectors.toSet()), 842 (X, Y) -> X.parallelStream().flatMap(x -> Y.parallelStream().map(y -> { 843 final Set<ELConceptDescription> xy = Sets.newHashSet(x); 844 xy.addAll(y); 845 return xy; 846 })).collect(Collectors.toSet())) 847 .parallelStream() 848 .forEach(f -> { 849 final ELConceptDescription D = ELConceptDescription.conjunction(f); 850 if (filter.parallelStream().filter(F0 -> !FF.contains(F0)).noneMatch(F0 -> F0.isSubsumedBy(D))) { 851 final ELConceptDescription C_and_rD = C.clone(); 852 C_and_rD.getExistentialRestrictions().put(r, D.clone()); 853 lowerNeighbors.add(C_and_rD); 854 // System.out.println("new lower neighbor found: C⊓∃" + r + "." + D); 855 } 856 }); 857 }); 858// } 859 }); 860 return lowerNeighbors; 861 } 862 863 public final Set<ELConceptDescription> lowerNeighborsB(final Signature sigma) { 864 final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 865 final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 866 sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 867 final ELConceptDescription lowerNeighbor = C.clone(); 868 lowerNeighbor.conceptNames.add(A); 869 return lowerNeighbor; 870 }).forEach(lowerNeighbors::add); 871 sigma.getRoleNames().parallelStream().forEach(r -> { 872 final Set<ELConceptDescription> filter = C.existentialRestrictions 873 .entries() 874 .parallelStream() 875 .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 876 .map(Entry::getValue) 877 .collect(Collectors.toSet()); 878// if (filter.isEmpty()) { 879// final ELConceptDescription lowerNeighbor = C.clone(); 880// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 881// lowerNeighbors.add(lowerNeighbor); 882// } else { 883 final Map<ELConceptDescription, Set<ELConceptDescription>> choices = new ConcurrentHashMap<>(); 884 filter.parallelStream().forEach(F -> { 885 final Set<ELConceptDescription> choicesForF = Sets.newConcurrentHashSet(); 886 choices.put(F, choicesForF); 887 F.lowerNeighbors(sigma).parallelStream().forEach(L -> { 888 choicesForF.add(L.without(F)); 889 }); 890 }); 891 final Map<ELConceptDescription, Set<ELConceptDescription>> subsumees = new ConcurrentHashMap<>(); 892 choices.entrySet().parallelStream().forEach(entry -> { 893// final ELConceptDescription F = entry.getKey(); 894 final Set<ELConceptDescription> choicesForF = entry.getValue(); 895 choicesForF.parallelStream().forEach(X -> { 896 final Set<ELConceptDescription> subsumeesOfX = Sets.newConcurrentHashSet(); 897 subsumees.put(X, subsumeesOfX); 898 filter.parallelStream().filter(X::subsumes).forEach(subsumeesOfX::add); 899 }); 900 }); 901 Sets 902 .powerSet(filter) 903 .parallelStream() 904 // .filter(FF -> !FF.isEmpty()) 905 .forEach(FF -> { 906 choices 907 .entrySet() 908 .parallelStream() 909 .filter(entry -> FF.contains(entry.getKey())) 910 .map( 911 entry -> Sets 912 .filter( 913 entry.getValue(), 914 X -> FF 915 .parallelStream() 916 .filter(F1 -> !entry.getKey().equals(F1)) 917 .allMatch(F1 -> subsumees.get(X).contains(F1)))) 918 .reduce( 919 Collections.singleton(Collections.<ELConceptDescription> emptySet()), 920 (X, Y) -> X.parallelStream().flatMap(x -> Y.parallelStream().map(y -> { 921 final Set<ELConceptDescription> xy = Sets.newHashSet(x); 922 xy.add(y); 923 return xy; 924 })).collect(Collectors.toSet()), 925 (X, Y) -> X.parallelStream().flatMap(x -> Y.parallelStream().map(y -> { 926 final Set<ELConceptDescription> xy = Sets.newHashSet(x); 927 xy.addAll(y); 928 return xy; 929 })).collect(Collectors.toSet())) 930 .parallelStream() 931 .forEach(f -> { 932 final ELConceptDescription D = ELConceptDescription.conjunction(f); 933 if (filter 934 .parallelStream() 935 .filter(F0 -> !FF.contains(F0)) 936 .noneMatch(F0 -> f.parallelStream().allMatch(X -> subsumees.get(X).contains(F0)))) { 937 final ELConceptDescription C_and_rD = C.clone(); 938 C_and_rD.getExistentialRestrictions().put(r, D.clone()); 939 lowerNeighbors.add(C_and_rD); 940 // System.out.println("new lower neighbor found: C⊓∃" + r + "." + D); 941 } 942 }); 943 }); 944// } 945 }); 946 return lowerNeighbors; 947 } 948 949 public final Set<ELConceptDescription> lowerNeighbors1(final Signature sigma) { 950 final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 951 final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 952 sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 953 final ELConceptDescription lowerNeighbor = C.clone(); 954 lowerNeighbor.conceptNames.add(A); 955 return lowerNeighbor; 956 }).forEach(lowerNeighbors::add); 957 sigma.getRoleNames().parallelStream().forEach(r -> { 958 final Set<ELConceptDescription> filter = C.existentialRestrictions 959 .entries() 960 .parallelStream() 961 .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 962 .map(Entry::getValue) 963 .collect(Collectors.toSet()); 964 if (filter.isEmpty()) { 965 final ELConceptDescription lowerNeighbor = C.clone(); 966 lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 967 lowerNeighbors.add(lowerNeighbor); 968 } else 969 recurseLowerNeighbors1(sigma, r, C, Collections.singleton(ELConceptDescription.top()), filter, lowerNeighbors); 970 }); 971 return lowerNeighbors; 972 } 973 974 private final void recurseLowerNeighbors1( 975 final Signature sigma, 976 final IRI r, 977 final ELConceptDescription C, 978 final Set<ELConceptDescription> currentCandidates, 979 final Set<ELConceptDescription> filter, 980 final Set<ELConceptDescription> lowerNeighbors) { 981 final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 982 currentCandidates.parallelStream().forEach(D -> { 983 if (!D 984 .upperNeighborsReduced() 985 .parallelStream() 986 .allMatch(U -> C.isSubsumedBy(ELConceptDescription.existentialRestriction(r, U)))) 987 return; 988 else if (filter.parallelStream().anyMatch(F -> F.isSubsumedBy(D))) 989 D.lowerNeighbors1(sigma).parallelStream().forEach(nextCandidates::add); 990 else { 991 final ELConceptDescription X = C.clone(); 992 X.existentialRestrictions.put(r, D); 993 lowerNeighbors.add(X); 994 } 995 }); 996 if (!nextCandidates.isEmpty()) 997 recurseLowerNeighbors1(sigma, r, C, nextCandidates, filter, lowerNeighbors); 998 } 999 1000 public final Set<ELConceptDescription> lowerNeighborsReduced1(final Signature sigma) { 1001// final Set<ELConceptDescription> lowerNeighbors = lowerNeighbors(sigma); 1002// lowerNeighbors.parallelStream().forEach(ELConceptDescription::reduce); 1003 final Set<ELConceptDescription> lowerNeighbors = new HashSet<>(); 1004 for (ELConceptDescription lowerNeighbor : lowerNeighbors1(sigma)) 1005 lowerNeighbors.add(lowerNeighbor.reduce()); 1006 return lowerNeighbors; 1007 } 1008 1009// protected final Set<ELConceptDescription> lowerNeighbors2(final Signature sigma) { 1010// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1011// sigma.getConceptNames().parallelStream().filter(A -> !ELConceptDescription.this.conceptNames.contains(A)).map(A -> { 1012// final ELConceptDescription lowerNeighbor = ELConceptDescription.this.clone(); 1013// lowerNeighbor.conceptNames.add(A); 1014// return lowerNeighbor; 1015// }).forEach(lowerNeighbors::add); 1016// sigma.getRoleNames().parallelStream().forEach(r -> { 1017// final ELConceptDescription rLCS = ELLeastCommonSubsumer.lcs( 1018// ELConceptDescription.this.clone().reduce().existentialRestrictions 1019// .entries() 1020// .parallelStream() 1021// .filter(sD -> sD.getKey().equals(r)) 1022// .map(Entry::getValue) 1023// .collect(Collectors.toSet())); 1024// rLCS.reduce(); 1025//// recurseLowerNeighbors(sigma, r, new ELConceptDescription(), lowerNeighbors); 1026// recurseLowerNeighbors2a(sigma, r, rLCS, lowerNeighbors); 1027// recurseLowerNeighbors2b(sigma, r, new ELConceptDescription(), rLCS, lowerNeighbors); 1028// }); 1029// return lowerNeighbors; 1030// } 1031// 1032// private final void recurseLowerNeighbors2a( 1033// final Signature sigma, 1034// final IRI r, 1035// final ELConceptDescription D, 1036// final Set<ELConceptDescription> lowerNeighbors) { 1037// if (ELConceptDescription.this.isSubsumedBy(ELConceptDescription.existentialRestriction(r, D))) 1038// D.lowerNeighbors2(sigma).parallelStream().forEach(E -> recurseLowerNeighbors2a(sigma, r, E, lowerNeighbors)); 1039// else if (D.upperNeighborsReduced().parallelStream().allMatch( 1040// E -> ELConceptDescription.this.isSubsumedBy(ELConceptDescription.existentialRestriction(r, E)))) { 1041// final ELConceptDescription lowerNeighbor = ELConceptDescription.this.clone(); 1042// lowerNeighbor.existentialRestrictions.put(r, D); 1043// lowerNeighbors.add(lowerNeighbor); 1044// } 1045// } 1046// 1047// private final void recurseLowerNeighbors2b( 1048// final Signature sigma, 1049// final IRI r, 1050// final ELConceptDescription D, 1051// final ELConceptDescription rLCS, 1052// final Set<ELConceptDescription> lowerNeighbors) { 1053// if (rLCS.subsumes(D)) 1054// return; 1055// else if (ELConceptDescription.this.isSubsumedBy(ELConceptDescription.existentialRestriction(r, D))) 1056// D.lowerNeighbors2(sigma).parallelStream().forEach( 1057// E -> recurseLowerNeighbors2b(sigma, r, E, rLCS, lowerNeighbors)); 1058// else if (D.upperNeighborsReduced().parallelStream().allMatch( 1059// E -> ELConceptDescription.this.isSubsumedBy(ELConceptDescription.existentialRestriction(r, E)))) { 1060// final ELConceptDescription lowerNeighbor = ELConceptDescription.this.clone(); 1061// lowerNeighbor.existentialRestrictions.put(r, D); 1062// lowerNeighbors.add(lowerNeighbor); 1063// } 1064// } 1065// 1066// protected final Set<ELConceptDescription> lowerNeighbors3(final Signature sigma) { 1067// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1068// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1069// sigma.getConceptNames().parallelStream().filter(A -> !ELConceptDescription.this.conceptNames.contains(A)).map(A -> { 1070// final ELConceptDescription lowerNeighbor = C.clone(); 1071// lowerNeighbor.conceptNames.add(A); 1072// return lowerNeighbor; 1073// }).forEach(lowerNeighbors::add); 1074// sigma.getRoleNames().parallelStream().forEach(r -> { 1075// final Set<ELConceptDescription> Ds = C.existentialRestrictions 1076// .entries() 1077// .parallelStream() 1078// .filter(sD -> sD.getKey().equals(r)) 1079// .map(Entry::getValue) 1080// .collect(Collectors.toSet()); 1081// if (Ds.isEmpty()) { 1082// final ELConceptDescription X = C.clone(); 1083// X.existentialRestrictions.put(r, ELConceptDescription.top()); 1084// lowerNeighbors.add(X); 1085// } else 1086//// Stream 1087//// .concat( 1088// // Collections.<Pair<Set<ELConceptDescription>, ELConceptDescription>> emptySet().parallelStream(), 1089// Collections 1090// .singleton(Pair.of(Ds, ELConceptDescription.top())) 1091// .parallelStream() 1092// // , 1093// // Sets.powerSet(Ds).parallelStream().filter(Es -> Es.size() > 0).map(Es -> { 1094// // final ELConceptDescription lcsEs = ELLeastCommonSubsumer._of(Es); 1095// // lcsEs.reduce(); 1096// // return Pair.of(Es, lcsEs); 1097// // })) 1098// .forEach(p -> { 1099// recurseLowerNeighbors3(sigma, r, C, p.second(), p.first(), lowerNeighbors); 1100// // p.second().lowerNeighbors3(sigma).parallelStream().forEach( 1101// // E -> recurseLowerNeighbors3(sigma, r, C, E, p.first(), lowerNeighbors)); 1102// }); 1103// }); 1104// return lowerNeighbors; 1105// } 1106// 1107// private final void recurseLowerNeighbors3( 1108// final Signature sigma, 1109// final IRI r, 1110// final ELConceptDescription C, 1111// final ELConceptDescription D, 1112// final Set<ELConceptDescription> filter, 1113// final Set<ELConceptDescription> lowerNeighbors) { 1114// if (!D.upperNeighborsReduced().parallelStream().allMatch( 1115// U -> C.isSubsumedBy(ELConceptDescription.existentialRestriction(r, U)))) 1116// return; 1117// else if (filter.parallelStream().anyMatch(F -> F.isSubsumedBy(D))) 1118// D.lowerNeighbors3(sigma).parallelStream().forEach( 1119// E -> recurseLowerNeighbors3(sigma, r, C, E, filter, lowerNeighbors)); 1120//// return; 1121// else { 1122// final ELConceptDescription X = C.clone(); 1123// X.existentialRestrictions.put(r, D); 1124// lowerNeighbors.add(X); 1125// } 1126//// D 1127//// .lowerNeighbors3(sigma) 1128//// .parallelStream() 1129//// .filter(L -> filter.parallelStream().allMatch(E -> !E.isSubsumedBy(L))) 1130//// .filter( 1131//// L -> L.upperNeighborsReduced().parallelStream().allMatch( 1132//// U -> C.isSubsumedBy(ELConceptDescription.existentialRestriction(Pair.of(r, U))))) 1133//// .map(L -> { 1134//// final ELConceptDescription X = C.clone(); 1135//// X.existentialRestrictions.add(Pair.of(r, L)); 1136//// return X; 1137//// }) 1138//// .forEach(lowerNeighbors::add); 1139// } 1140// 1141//// public final Set<ELConceptDescription> lowerNeighbors2(final Signature sigma) { 1142//// this.reduce(); 1143//// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1144//// sigma.getConceptNames().parallelStream().filter(A -> !ELConceptDescription.this.conceptNames.contains(A)).map(A -> { 1145//// final ELConceptDescription lowerNeighbor = ELConceptDescription.this.clone(); 1146//// lowerNeighbor.conceptNames.add(A); 1147//// return lowerNeighbor; 1148//// }).forEach(lowerNeighbors::add); 1149//// sigma.getRoleNames().parallelStream().forEach( 1150//// r -> this.existentialRestrictions.parallelStream().filter(sD -> sD.first().equals(r)).map(Pair::second).forEach( 1151//// D -> D.lowerNeighbors2(sigma).parallelStream().forEach( 1152//// E -> recurseLowerNeighbors2(sigma, r, E, lowerNeighbors)))); 1153//// return lowerNeighbors; 1154//// } 1155//// 1156//// private final void recurseLowerNeighbors2( 1157//// final Signature sigma, 1158//// final IRI r, 1159//// final ELConceptDescription D, 1160//// final Set<ELConceptDescription> lowerNeighbors) { 1161//// if (D.upperNeighborsReduced().parallelStream().allMatch( 1162//// E -> ELConceptDescription.this.isSubsumedBy(ELConceptDescription.existentialRestriction(Pair.of(r, E))))) { 1163//// final ELConceptDescription lowerNeighbor = ELConceptDescription.this.clone(); 1164//// lowerNeighbor.existentialRestrictions.add(Pair.of(r, D)); 1165//// lowerNeighbors.add(lowerNeighbor); 1166//// } else 1167//// D.lowerNeighbors(sigma).parallelStream().forEach(E -> recurseLowerNeighbors2(sigma, r, E, lowerNeighbors)); 1168//// } 1169// 1170// public final Set<ELConceptDescription> lowerNeighbors4(final Signature sigma) { 1171// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1172// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1173// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1174// final ELConceptDescription lowerNeighbor = C.clone(); 1175// lowerNeighbor.conceptNames.add(A); 1176// return lowerNeighbor; 1177// }).forEach(lowerNeighbors::add); 1178// sigma.getRoleNames().parallelStream().forEach(r -> { 1179//// recurseLowerNeighbors4a(sigma, Collections.singletonList(r), C, lowerNeighbors); 1180// final Set<ELConceptDescription> filter = C.existentialRestrictions 1181// .entries() 1182// .parallelStream() 1183// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1184// .map(Entry::getValue) 1185// .collect(Collectors.toSet()); 1186// if (filter.isEmpty()) { 1187// final ELConceptDescription lowerNeighbor = C.clone(); 1188// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1189// lowerNeighbors.add(lowerNeighbor); 1190// } else { 1191// if (filter.size() == 1) { 1192//// final ELConceptDescription D = filter.iterator().next(); 1193//// for (ELConceptDescription E : D.lowerNeighbors4(sigma)) 1194//// if (E.reduce().topLevelConjuncts() == 1) 1195//// lowerNeighbors 1196//// .add(ELConceptDescription.conjunction(C.clone(), ELConceptDescription.existentialRestriction(r, E))); 1197// } else 1198// recurseLowerNeighbors4( 1199// sigma, 1200// r, 1201// C, 1202// Collections.singleton(ELConceptDescription.conjunction(filter).reduce()), 1203// filter, 1204// lowerNeighbors); 1205// filter.parallelStream().forEach(F -> { 1206// F.lowerNeighbors4(sigma).parallelStream().forEach(L -> { 1207// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1208// L.existentialRestrictions.entries().removeIf( 1209// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1210// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1211// if (!C.isSubsumedBy(rL)) 1212// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1213// }); 1214// }); 1215// } 1216// }); 1217// return lowerNeighbors; 1218// } 1219// 1220// private final void recurseLowerNeighbors4( 1221// final Signature sigma, 1222// final IRI r, 1223// final ELConceptDescription C, 1224// final Set<ELConceptDescription> currentCandidates, 1225// final Set<ELConceptDescription> filter, 1226// final Set<ELConceptDescription> lowerNeighbors) { 1227// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1228// currentCandidates.parallelStream().forEach(D -> { 1229//// D.reduce(); 1230// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1231//// if (!C.isSubsumedBy(ELConceptDescription.existentialRestriction(r, D))) { 1232// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1233// if (D.topLevelConjuncts() <= filter.size() 1234// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1235//// if (D.topLevelConjuncts() <= filter.size() && Us.parallelStream().allMatch(U -> C.isSubsumedBy(ELConceptDescription.existentialRestriction(r, U)))) { 1236// final ELConceptDescription X = C.clone(); 1237// X.existentialRestrictions.put(r, D); 1238// lowerNeighbors.add(X); 1239// } else 1240// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1241// // Us.parallelStream().filter(U -> !C.isSubsumedBy(ELConceptDescription.existentialRestriction(r, 1242// // U))).forEach( 1243// nextCandidates::add); 1244// } 1245// }); 1246// if (!nextCandidates.isEmpty()) 1247// recurseLowerNeighbors4(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1248// } 1249// 1250// private final void recurseLowerNeighbors4a( 1251// final Signature sigma, 1252// final List<IRI> rs, 1253// final ELConceptDescription C, 1254// final Set<ELConceptDescription> lowerNeighbors) { 1255// final ELConceptDescription rsTop = ELConceptDescription.existentialRestriction(rs, ELConceptDescription.top()); 1256// if (C.isSubsumedBy(rsTop)) { 1257// for (IRI A : sigma.getConceptNames()) { 1258// final ELConceptDescription rsA = 1259// ELConceptDescription.existentialRestriction(rs, ELConceptDescription.conceptName(A)); 1260// if (!C.isSubsumedBy(rsA)) 1261// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rsA)); 1262// } 1263// for (IRI r : sigma.getRoleNames()) { 1264// final ELConceptDescription rsrTop = ELConceptDescription 1265// .existentialRestriction(rs, ELConceptDescription.existentialRestriction(r, ELConceptDescription.top())); 1266// if (!C.isSubsumedBy(rsrTop)) 1267// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rsrTop)); 1268// final List<IRI> rsr = new LinkedList<>(rs); 1269// rsr.add(r); 1270// recurseLowerNeighbors4a(sigma, rsr, C, lowerNeighbors); 1271// } 1272// } 1273// } 1274// 1275// public final Set<ELConceptDescription> lowerNeighbors5(final Signature sigma) { 1276// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1277// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1278// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1279// final ELConceptDescription lowerNeighbor = C.clone(); 1280// lowerNeighbor.conceptNames.add(A); 1281// return lowerNeighbor; 1282// }).forEach(lowerNeighbors::add); 1283// sigma.getRoleNames().parallelStream().forEach(r -> { 1284// final Set<ELConceptDescription> filter = C.existentialRestrictions 1285// .entries() 1286// .parallelStream() 1287// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1288// .map(Entry::getValue) 1289// .collect(Collectors.toSet()); 1290// if (filter.isEmpty()) { 1291// final ELConceptDescription lowerNeighbor = C.clone(); 1292// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1293// lowerNeighbors.add(lowerNeighbor); 1294// } else { 1295// if (filter.size() > 1) { 1296// final Set<ELConceptDescription> firstCandidates = filter 1297// .parallelStream() 1298// .flatMap( 1299// F -> filter.parallelStream().filter(G -> !G.equals(F)).map( 1300// G -> ELConceptDescription.conjunction(F, G).reduce())) 1301// .collect(Collectors.toSet()); 1302// recurseLowerNeighbors5(sigma, r, C, firstCandidates, filter, lowerNeighbors); 1303// } 1304// filter.parallelStream().forEach(F -> { 1305// F.lowerNeighbors5(sigma).parallelStream().forEach(L -> { 1306// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1307// L.existentialRestrictions.entries().removeIf( 1308// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1309// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1310// if (!C.isSubsumedBy(rL)) 1311// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1312// }); 1313// }); 1314// } 1315// }); 1316// return lowerNeighbors; 1317// } 1318// 1319// private final void recurseLowerNeighbors5( 1320// final Signature sigma, 1321// final IRI r, 1322// final ELConceptDescription C, 1323// final Set<ELConceptDescription> currentCandidates, 1324// final Set<ELConceptDescription> filter, 1325// final Set<ELConceptDescription> lowerNeighbors) { 1326// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1327// currentCandidates.parallelStream().forEach(D -> { 1328//// D.reduce(); 1329// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1330// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1331// if (D.topLevelConjuncts() <= filter.size() 1332// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1333// final ELConceptDescription X = C.clone(); 1334// X.existentialRestrictions.put(r, D); 1335// lowerNeighbors.add(X); 1336// } else 1337// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1338// nextCandidates::add); 1339// } 1340// }); 1341// if (!nextCandidates.isEmpty()) 1342// recurseLowerNeighbors5(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1343// } 1344// 1345// public final Set<ELConceptDescription> lowerNeighbors6(final Signature sigma) { 1346// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1347// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1348// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1349// final ELConceptDescription lowerNeighbor = C.clone(); 1350// lowerNeighbor.conceptNames.add(A); 1351// return lowerNeighbor; 1352// }).forEach(lowerNeighbors::add); 1353// sigma.getRoleNames().parallelStream().forEach(r -> { 1354// final Set<ELConceptDescription> filter = C.existentialRestrictions 1355// .entries() 1356// .parallelStream() 1357// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1358// .map(Entry::getValue) 1359// .collect(Collectors.toSet()); 1360// if (filter.isEmpty()) { 1361// final ELConceptDescription lowerNeighbor = C.clone(); 1362// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1363// lowerNeighbors.add(lowerNeighbor); 1364// } else { 1365// if (filter.size() > 1) { 1366// final Set<ELConceptDescription> lowerNeighborsOfFilter = filter 1367// .parallelStream() 1368// .flatMap(F -> F.lowerNeighbors6(sigma).parallelStream()) 1369// .map(ELConceptDescription::reduce) 1370// .collect(Collectors.toSet()); 1371// recurseLowerNeighbors6(sigma, r, C, lowerNeighborsOfFilter, filter, lowerNeighbors); 1372// } 1373// filter.parallelStream().forEach(F -> { 1374// F.lowerNeighbors6(sigma).parallelStream().forEach(L -> { 1375// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1376// L.existentialRestrictions.entries().removeIf( 1377// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1378// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1379// if (!C.isSubsumedBy(rL)) 1380// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1381// }); 1382// }); 1383// } 1384// }); 1385// return lowerNeighbors; 1386// } 1387// 1388// private final void recurseLowerNeighbors6( 1389// final Signature sigma, 1390// final IRI r, 1391// final ELConceptDescription C, 1392// final Set<ELConceptDescription> currentCandidates, 1393// final Set<ELConceptDescription> filter, 1394// final Set<ELConceptDescription> lowerNeighbors) { 1395// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1396// currentCandidates.parallelStream().forEach(D -> { 1397//// D.reduce(); 1398// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1399// if (D.topLevelConjuncts() <= filter.size()) { 1400// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1401// if (Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1402// final ELConceptDescription X = C.clone(); 1403// X.existentialRestrictions.put(r, D); 1404// lowerNeighbors.add(X); 1405// } else 1406// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1407// nextCandidates::add); 1408// } 1409// } 1410// }); 1411// if (!nextCandidates.isEmpty()) 1412// recurseLowerNeighbors6(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1413// } 1414// 1415// public final Set<ELConceptDescription> lowerNeighbors7(final Signature sigma) { 1416// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1417// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1418// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1419// final ELConceptDescription lowerNeighbor = C.clone(); 1420// lowerNeighbor.conceptNames.add(A); 1421// return lowerNeighbor; 1422// }).forEach(lowerNeighbors::add); 1423// sigma.getRoleNames().parallelStream().forEach(r -> { 1424// final Set<ELConceptDescription> filter = C.existentialRestrictions 1425// .entries() 1426// .parallelStream() 1427// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1428// .map(Entry::getValue) 1429// .collect(Collectors.toSet()); 1430// if (filter.isEmpty()) { 1431// final ELConceptDescription lowerNeighbor = C.clone(); 1432// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1433// lowerNeighbors.add(lowerNeighbor); 1434// } else { 1435// if (filter.size() > 1) { 1436// final Set<ELConceptDescription> firstCandidates = 1437// filter.parallelStream().flatMap(F -> filter.parallelStream().filter(G -> !G.equals(F)).map(G -> { 1438// final ELConceptDescription F0 = F.clone(); 1439// final ELConceptDescription G0 = G.clone(); 1440// F0.conceptNames.removeIf(A -> G.isSubsumedBy(ELConceptDescription.conceptName(A))); 1441// G0.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1442// F0.existentialRestrictions.entries().removeIf( 1443// rE -> G.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1444// G0.existentialRestrictions.entries().removeIf( 1445// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1446// return ELConceptDescription.conjunction(F0, G0).reduce(); 1447// // final ELConceptDescription D = ELConceptDescription.conjunction(F, G); 1448// // D.reduce(); 1449// // D.conceptNames.removeIf( 1450// // A -> F.isSubsumedBy(ELConceptDescription.conceptName(A)) 1451// // && G.isSubsumedBy(ELConceptDescription.conceptName(A))); 1452// // D.existentialRestrictions.entries().removeIf( 1453// // rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue())) 1454// // && G.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1455// // return D; 1456// // final Set<IRI> commonNames = Stream 1457// // .concat( 1458// // F.getConceptNames().parallelStream().filter(A -> !G.getConceptNames().contains(A)), 1459// // G.getConceptNames().parallelStream().filter(A -> !F.getConceptNames().contains(A))) 1460// // .collect(Collectors.toSet()); 1461// // final HashMultimap<IRI, ELConceptDescription> commonExistentialRestrictions = HashMultimap.create(); 1462// // final SetMultimap<IRI, ELConceptDescription> _commonExistentialRestrictions = 1463// // Multimaps.synchronizedSetMultimap(commonExistentialRestrictions); 1464// // Stream 1465// // .concat( 1466// // F.getExistentialRestrictions().entries().parallelStream().filter( 1467// // rX -> !G 1468// // .isSubsumedBy(ELConceptDescription.existentialRestriction(rX.getKey(), rX.getValue()))), 1469// // G.getExistentialRestrictions().entries().parallelStream().filter( 1470// // rX -> !F 1471// // .isSubsumedBy(ELConceptDescription.existentialRestriction(rX.getKey(), rX.getValue())))) 1472// // .forEach(rX -> _commonExistentialRestrictions.put(rX.getKey(), rX.getValue())); 1473// // return new ELConceptDescription(commonNames, commonExistentialRestrictions).reduce(); 1474// })).collect(Collectors.toSet()); 1475// recurseLowerNeighbors7(sigma, r, C, firstCandidates, filter, lowerNeighbors); 1476// } 1477// filter.parallelStream().forEach(F -> { 1478// F.lowerNeighbors7(sigma).parallelStream().forEach(L -> { 1479// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1480// L.existentialRestrictions.entries().removeIf( 1481// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1482// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1483// if (!C.isSubsumedBy(rL)) 1484// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1485// }); 1486// }); 1487// } 1488// }); 1489// return lowerNeighbors; 1490// } 1491// 1492// private final void recurseLowerNeighbors7( 1493// final Signature sigma, 1494// final IRI r, 1495// final ELConceptDescription C, 1496// final Set<ELConceptDescription> currentCandidates, 1497// final Set<ELConceptDescription> filter, 1498// final Set<ELConceptDescription> lowerNeighbors) { 1499// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1500// currentCandidates.parallelStream().forEach(D -> { 1501//// D.reduce(); 1502// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1503// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1504// if (D.topLevelConjuncts() <= filter.size() 1505// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1506// final ELConceptDescription X = C.clone(); 1507// X.existentialRestrictions.put(r, D); 1508// lowerNeighbors.add(X); 1509// } else 1510// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1511// nextCandidates::add); 1512// } 1513// }); 1514// if (!nextCandidates.isEmpty()) 1515// recurseLowerNeighbors7(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1516// } 1517// 1518// public final Set<ELConceptDescription> lowerNeighbors8(final Signature sigma) { 1519// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1520// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1521// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1522// final ELConceptDescription lowerNeighbor = C.clone(); 1523// lowerNeighbor.conceptNames.add(A); 1524// return lowerNeighbor; 1525// }).forEach(lowerNeighbors::add); 1526// sigma.getRoleNames().parallelStream().forEach(r -> { 1527// final Set<ELConceptDescription> filter = C.existentialRestrictions 1528// .entries() 1529// .parallelStream() 1530// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1531// .map(Entry::getValue) 1532// .collect(Collectors.toSet()); 1533// if (filter.isEmpty()) { 1534// final ELConceptDescription lowerNeighbor = C.clone(); 1535// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1536// lowerNeighbors.add(lowerNeighbor); 1537// } else { 1538// if (filter.size() > 1) { 1539// final Set<ELConceptDescription> firstCandidates = Stream 1540// .concat( 1541// filter.parallelStream().flatMap(F -> F.lowerNeighbors8(sigma).parallelStream()).map( 1542// ELConceptDescription::reduce), 1543// filter.parallelStream().flatMap(F -> filter.parallelStream().filter(G -> !G.equals(F)).map(G -> { 1544// final ELConceptDescription D = ELConceptDescription.conjunction(F, G); 1545// // final ELConceptDescription lcs = ELLeastCommonSubsumer.lcsOfMutuallyIncomparable(F, G); 1546// D.reduce(); 1547// // lcs.reduce(); 1548// D.conceptNames.removeIf( 1549// A -> F.isSubsumedBy(ELConceptDescription.conceptName(A)) 1550// && G.isSubsumedBy(ELConceptDescription.conceptName(A))); 1551// D.existentialRestrictions.entries().removeIf( 1552// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue())) 1553// && G.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1554// return D; 1555// })).filter(X -> filter.parallelStream().noneMatch(L -> X.isSubsumedBy(L)))) 1556// .collect(Collectors.toSet()); 1557// recurseLowerNeighbors8(sigma, r, C, firstCandidates, filter, lowerNeighbors); 1558// } 1559// filter.parallelStream().forEach(F -> { 1560// F.lowerNeighbors8(sigma).parallelStream().forEach(L -> { 1561// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1562// L.existentialRestrictions.entries().removeIf( 1563// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1564// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1565// if (!C.isSubsumedBy(rL)) 1566// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1567// }); 1568// }); 1569// } 1570// }); 1571// return lowerNeighbors; 1572// } 1573// 1574// private final void recurseLowerNeighbors8( 1575// final Signature sigma, 1576// final IRI r, 1577// final ELConceptDescription C, 1578// final Set<ELConceptDescription> currentCandidates, 1579// final Set<ELConceptDescription> filter, 1580// final Set<ELConceptDescription> lowerNeighbors) { 1581// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1582// currentCandidates.parallelStream().forEach(D -> { 1583// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1584// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1585// if (D.topLevelConjuncts() <= filter.size() 1586// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1587// final ELConceptDescription X = C.clone(); 1588// X.existentialRestrictions.put(r, D); 1589// lowerNeighbors.add(X); 1590// } else 1591// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1592// nextCandidates::add); 1593// } 1594// }); 1595// if (!nextCandidates.isEmpty()) 1596// recurseLowerNeighbors8(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1597// } 1598// 1599// public final Set<ELConceptDescription> lowerNeighbors9(final Signature sigma) { 1600// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1601// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1602// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1603// final ELConceptDescription lowerNeighbor = C.clone(); 1604// lowerNeighbor.conceptNames.add(A); 1605// return lowerNeighbor; 1606// }).forEach(lowerNeighbors::add); 1607// sigma.getRoleNames().parallelStream().forEach(r -> { 1608// final Set<ELConceptDescription> filter = C.existentialRestrictions 1609// .entries() 1610// .parallelStream() 1611// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1612// .map(Entry::getValue) 1613// .collect(Collectors.toSet()); 1614// if (filter.isEmpty()) { 1615// final ELConceptDescription lowerNeighbor = C.clone(); 1616// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1617// lowerNeighbors.add(lowerNeighbor); 1618// } else { 1619// if (filter.size() > 1) { 1620// final ELConceptDescription firstCandidate = ELConceptDescription.conjunction(filter); 1621// firstCandidate.getConceptNames().removeIf( 1622// A -> filter.parallelStream().allMatch(F -> F.getConceptNames().contains(A))); 1623// firstCandidate.getExistentialRestrictions().entries().removeIf(rE -> { 1624// final ELConceptDescription exrE = ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 1625// return filter.parallelStream().allMatch(F -> F.isSubsumedBy(exrE)); 1626// }); 1627// recurseLowerNeighbors9(sigma, r, C, Collections.singleton(firstCandidate.reduce()), filter, lowerNeighbors); 1628// } 1629// filter.parallelStream().forEach(F -> { 1630// F.lowerNeighbors9(sigma).parallelStream().forEach(L -> { 1631// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1632// L.existentialRestrictions.entries().removeIf( 1633// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1634// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1635// if (!C.isSubsumedBy(rL)) 1636// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1637// }); 1638// }); 1639// } 1640// }); 1641// return lowerNeighbors; 1642// } 1643// 1644// private final void recurseLowerNeighbors9( 1645// final Signature sigma, 1646// final IRI r, 1647// final ELConceptDescription C, 1648// final Set<ELConceptDescription> currentCandidates, 1649// final Set<ELConceptDescription> filter, 1650// final Set<ELConceptDescription> lowerNeighbors) { 1651// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1652// currentCandidates.parallelStream().forEach(D -> { 1653// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1654// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1655// if (D.topLevelConjuncts() <= filter.size() 1656// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1657// final ELConceptDescription X = C.clone(); 1658// X.existentialRestrictions.put(r, D); 1659// lowerNeighbors.add(X); 1660// } else 1661// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1662// nextCandidates::add); 1663// } 1664// }); 1665// if (!nextCandidates.isEmpty()) 1666// recurseLowerNeighbors9(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1667// } 1668// 1669// public final Set<ELConceptDescription> lowerNeighbors10(final Signature sigma) { 1670// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1671// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1672// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1673// final ELConceptDescription lowerNeighbor = C.clone(); 1674// lowerNeighbor.conceptNames.add(A); 1675// return lowerNeighbor; 1676// }).forEach(lowerNeighbors::add); 1677// sigma.getRoleNames().parallelStream().forEach(r -> { 1678// final Set<ELConceptDescription> filter = C.existentialRestrictions 1679// .entries() 1680// .parallelStream() 1681// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1682// .map(Entry::getValue) 1683// .collect(Collectors.toSet()); 1684// if (filter.isEmpty()) { 1685// final ELConceptDescription lowerNeighbor = C.clone(); 1686// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1687// lowerNeighbors.add(lowerNeighbor); 1688// } else { 1689// if (filter.size() > 1) { 1690// final Set<IRI> forbiddenNames = filter 1691// .parallelStream() 1692// .flatMap(F -> F.getConceptNames().parallelStream()) 1693// .distinct() 1694// .filter(A -> filter.parallelStream().allMatch(FF -> FF.getConceptNames().contains(A))) 1695// .collect(Collectors.toSet()); 1696// final Set<Entry<IRI, ELConceptDescription>> forbiddenRestrictions = filter 1697// .parallelStream() 1698// .flatMap(F -> F.getExistentialRestrictions().entries().parallelStream()) 1699// .distinct() 1700// .filter(rE -> { 1701// final ELConceptDescription exrE = 1702// ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 1703// return filter.parallelStream().allMatch(FF -> FF.isSubsumedBy(exrE)); 1704// }) 1705// .collect(Collectors.toSet()); 1706// final Set<ELConceptDescription> firstCandidates = 1707// filter.parallelStream().flatMap(F -> filter.parallelStream().filter(G -> !G.equals(F)).map(G -> { 1708// final ELConceptDescription that = ELConceptDescription.conjunction(F, G).reduce(); 1709// that.getConceptNames().removeAll(forbiddenNames); 1710// that.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 1711// // that.getConceptNames().removeIf( 1712// // A -> filter.parallelStream().allMatch(FF -> FF.getConceptNames().contains(A))); 1713// // that.getExistentialRestrictions().entries().removeIf(rE -> { 1714// // final ELConceptDescription exrE = 1715// // ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 1716// // return filter.parallelStream().allMatch(FF -> FF.isSubsumedBy(exrE)); 1717// // }); 1718// return that; 1719// })).collect(Collectors.toSet()); 1720// recurseLowerNeighbors10(sigma, r, C, firstCandidates, filter, lowerNeighbors); 1721// } 1722// filter.parallelStream().forEach(F -> { 1723// F.lowerNeighbors10(sigma).parallelStream().forEach(L -> { 1724// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1725// L.existentialRestrictions.entries().removeIf( 1726// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1727// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1728// if (!C.isSubsumedBy(rL)) 1729// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 1730// }); 1731// }); 1732// } 1733// }); 1734// return lowerNeighbors; 1735// } 1736// 1737// private final void recurseLowerNeighbors10( 1738// final Signature sigma, 1739// final IRI r, 1740// final ELConceptDescription C, 1741// final Set<ELConceptDescription> currentCandidates, 1742// final Set<ELConceptDescription> filter, 1743// final Set<ELConceptDescription> lowerNeighbors) { 1744// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 1745// currentCandidates.parallelStream().forEach(D -> { 1746// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 1747// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 1748// if (D.topLevelConjuncts() <= filter.size() 1749// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 1750// final ELConceptDescription X = C.clone(); 1751// X.existentialRestrictions.put(r, D); 1752// lowerNeighbors.add(X); 1753// } else 1754// Us.parallelStream().filter(U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U))).forEach( 1755// nextCandidates::add); 1756// } 1757// }); 1758// if (!nextCandidates.isEmpty()) 1759// recurseLowerNeighbors10(sigma, r, C, nextCandidates, filter, lowerNeighbors); 1760// } 1761// 1762// public final Set<ELConceptDescription> lowerNeighbors11(final Signature sigma) { 1763// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1764// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1765// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1766// final ELConceptDescription lowerNeighbor = C.clone(); 1767// lowerNeighbor.conceptNames.add(A); 1768// return lowerNeighbor; 1769// }).forEach(lowerNeighbors::add); 1770// sigma.getRoleNames().parallelStream().forEach(r -> { 1771// final Set<ELConceptDescription> filter = C.existentialRestrictions 1772// .entries() 1773// .parallelStream() 1774// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1775// .map(Entry::getValue) 1776// .collect(Collectors.toSet()); 1777// if (filter.isEmpty()) { 1778// final ELConceptDescription lowerNeighbor = C.clone(); 1779// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1780// lowerNeighbors.add(lowerNeighbor); 1781// } else { 1782// if (filter.size() > 1) { 1783// final Set<IRI> forbiddenNames = filter 1784// .parallelStream() 1785// .flatMap(F -> F.getConceptNames().parallelStream()) 1786// .distinct() 1787// .filter(A -> filter.parallelStream().allMatch(FF -> FF.getConceptNames().contains(A))) 1788// .collect(Collectors.toSet()); 1789// final Set<Entry<IRI, ELConceptDescription>> forbiddenRestrictions = filter 1790// .parallelStream() 1791// .flatMap(F -> F.getExistentialRestrictions().entries().parallelStream()) 1792// .distinct() 1793// .filter(rE -> { 1794// final ELConceptDescription exrE = 1795// ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 1796// return filter.parallelStream().allMatch(FF -> FF.isSubsumedBy(exrE)); 1797// }) 1798// .collect(Collectors.toSet()); 1799// filter.parallelStream().map(F -> { 1800// final ELConceptDescription that = F.clone(); 1801// that.getConceptNames().removeAll(forbiddenNames); 1802// that.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 1803// return that; 1804// }).flatMap(F -> F.lowerNeighbors11(sigma).parallelStream()).forEach(L -> { 1805// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1806// if (!C.isSubsumedBy(rL)) 1807// if (L.upperNeighborsReduced().parallelStream().allMatch( 1808// U -> C.isSubsumedBy(ELConceptDescription.existentialRestriction(r, U)))) 1809// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL));// reduce 1810// }); 1811// } 1812// filter.parallelStream().forEach(F -> { 1813// F.lowerNeighbors11(sigma).parallelStream().forEach(L -> { 1814// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1815// L.existentialRestrictions.entries().removeIf( 1816// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 1817// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 1818// if (!C.isSubsumedBy(rL)) 1819// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL));// reduce 1820// }); 1821// }); 1822// } 1823// }); 1824// return lowerNeighbors; 1825// } 1826// 1827// public final Set<ELConceptDescription> lowerNeighbors12(final Signature sigma) { 1828// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1829// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1830// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1831// final ELConceptDescription lowerNeighbor = C.clone(); 1832// lowerNeighbor.conceptNames.add(A); 1833// return lowerNeighbor; 1834// }).forEach(lowerNeighbors::add); 1835// sigma.getRoleNames().parallelStream().forEach(r -> { 1836// final Set<ELConceptDescription> filter = C.existentialRestrictions 1837// .entries() 1838// .parallelStream() 1839// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1840// .map(Entry::getValue) 1841// .collect(Collectors.toSet()); 1842// if (filter.isEmpty()) { 1843// final ELConceptDescription lowerNeighbor = C.clone(); 1844// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1845// lowerNeighbors.add(lowerNeighbor); 1846// } else { 1847// if (filter.size() > 1) { 1848// final Set<IRI> forbiddenNames = filter 1849// .parallelStream() 1850// .flatMap(F -> F.getConceptNames().parallelStream()) 1851// .distinct() 1852// .filter(A -> filter.parallelStream().allMatch(FF -> FF.getConceptNames().contains(A))) 1853// .collect(Collectors.toSet()); 1854// final Set<Entry<IRI, ELConceptDescription>> forbiddenRestrictions = filter 1855// .parallelStream() 1856// .flatMap(F -> F.getExistentialRestrictions().entries().parallelStream()) 1857// .distinct() 1858// .filter(rE -> { 1859// final ELConceptDescription exrE = 1860// ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 1861// return filter.parallelStream().allMatch(FF -> FF.isSubsumedBy(exrE)); 1862// }) 1863// .collect(Collectors.toSet()); 1864// if (forbiddenNames.isEmpty() && forbiddenRestrictions.isEmpty()) { 1865// ELConceptDescription 1866// .top() 1867// .lowerNeighbors12(sigma) 1868// .parallelStream() 1869// .flatMap( 1870// X -> ELConceptDescription.top().lowerNeighbors12(sigma).parallelStream().map( 1871// Y -> X.and(Y).reduce())) 1872// .forEach(L -> { 1873// final ELConceptDescription rL = L.exists(r); 1874// if (!C.isSubsumedBy(rL)) 1875// if (L.upperNeighborsReduced().parallelStream().allMatch(U -> C.isSubsumedBy(U.exists(r)))) 1876// lowerNeighbors.add(C.clone().and(rL));// reduce 1877// }); 1878// } 1879// filter.parallelStream().flatMap(F -> filter.parallelStream().filter(G -> !F.equals(G)).map(G -> { 1880// final ELConceptDescription conj = F.and(G).reduce(); 1881// conj.getConceptNames().removeAll(forbiddenNames); 1882// conj.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 1883// final ELConceptDescription lcs = F.lcs(G).reduce(); 1884// return conj.lcs(lcs).reduce(); 1885// })) 1886// .flatMap( 1887// H -> H.lowerNeighbors12(sigma).parallelStream().flatMap( 1888// K -> K.lowerNeighbors12(sigma).parallelStream())) 1889// .forEach(L -> { 1890// final ELConceptDescription rL = L.exists(r); 1891// if (!C.isSubsumedBy(rL)) 1892// if (L.upperNeighborsReduced().parallelStream().allMatch(U -> C.isSubsumedBy(U.exists(r)))) 1893// lowerNeighbors.add(C.clone().and(rL));// reduce 1894// }); 1895//// filter.parallelStream().map(F -> { 1896//// final ELConceptDescription that = F.clone(); 1897//// that.getConceptNames().removeAll(forbiddenNames); 1898//// that.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 1899//// return that; 1900//// }).flatMap(F -> F.upperNeighborsReduced().parallelStream().flatMap(U -> filter.parallelStream().map(G -> { 1901//// final ELConceptDescription that = G.clone(); 1902//// that.getConceptNames().removeAll(forbiddenNames); 1903//// that.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 1904//// return that; 1905//// }).flatMap(G -> G.upperNeighborsReduced().parallelStream().map(V -> U.and(V).reduce())))) 1906//// // .map(H -> { 1907//// // H.getConceptNames().removeIf(A -> filter.parallelStream().allMatch(F -> 1908//// // F.getConceptNames().contains(A))); 1909//// // H.getExistentialRestrictions().entries().removeIf( 1910//// // rE -> filter.parallelStream().allMatch(F -> F.isSubsumedBy(rE.getValue().exists(rE.getKey())))); 1911//// // return H; 1912//// // }) 1913//// .forEach(L -> { 1914//// final ELConceptDescription rL = L.exists(r); 1915//// if (!C.isSubsumedBy(rL)) 1916//// if (L.upperNeighborsReduced().parallelStream().allMatch(U -> C.isSubsumedBy(U.exists(r)))) 1917//// lowerNeighbors.add(C.clone().and(rL));// reduce 1918//// }); 1919////// filter.parallelStream().flatMap(F -> filter.parallelStream().filter(G -> !G.equals(F)).map(G -> { 1920////// final ELConceptDescription that = ELConceptDescription.conjunction(F, G).reduce(); 1921////// that.getConceptNames().removeAll(forbiddenNames); 1922////// that.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 1923////// return that; 1924////// })).forEach(L -> { 1925////// final ELConceptDescription rL = L.exists(r); 1926////// if (!C.isSubsumedBy(rL)) 1927////// if (L.upperNeighborsReduced().parallelStream().allMatch(U -> C.isSubsumedBy(U.exists(r)))) 1928////// lowerNeighbors.add(C.clone().and(rL));// reduce 1929////// }); 1930// } 1931// filter.parallelStream().forEach(F -> { 1932// F.lowerNeighbors12(sigma).parallelStream().forEach(L -> { 1933// final ELConceptDescription _rL = L.clone().exists(r); 1934// if (!C.isSubsumedBy(_rL)) 1935// if (L.upperNeighborsReduced().parallelStream().allMatch(U -> C.isSubsumedBy(U.exists(r)))) 1936// lowerNeighbors.add(C.clone().and(_rL));// reduce 1937// 1938// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1939// L.existentialRestrictions.entries().removeIf(rE -> F.isSubsumedBy(rE.getValue().exists(rE.getKey()))); 1940// final ELConceptDescription rL = L.exists(r); 1941// if (!C.isSubsumedBy(rL)) 1942// lowerNeighbors.add(C.clone().and(rL));// reduce 1943// }); 1944// }); 1945// } 1946// }); 1947// return lowerNeighbors; 1948// } 1949// 1950// public final Set<ELConceptDescription> lowerNeighbors13(final Signature sigma) { 1951// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 1952// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 1953// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 1954// final ELConceptDescription lowerNeighbor = C.clone(); 1955// lowerNeighbor.conceptNames.add(A); 1956// return lowerNeighbor; 1957// }).forEach(lowerNeighbors::add); 1958// sigma.getRoleNames().parallelStream().forEach(r -> { 1959// final Set<ELConceptDescription> filter = C.existentialRestrictions 1960// .entries() 1961// .parallelStream() 1962// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 1963// .map(Entry::getValue) 1964// .collect(Collectors.toSet()); 1965// if (filter.isEmpty()) { 1966// final ELConceptDescription lowerNeighbor = C.clone(); 1967// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 1968// lowerNeighbors.add(lowerNeighbor); 1969// } else { 1970// if (filter.size() > 1) { 1971//// filter 1972//// .parallelStream() 1973//// .flatMap( 1974//// F -> F.upperNeighborsReduced().parallelStream().flatMap( 1975//// U -> filter.parallelStream().filter(G -> !F.equals(G)).flatMap( 1976//// G -> G.upperNeighborsReduced().parallelStream().map(V -> U.and(V).reduce())))) 1977// filter 1978// .parallelStream() 1979// .flatMap( 1980// F -> F.upperNeighborsReduced().parallelStream().flatMap( 1981// U -> filter.parallelStream().map(G -> G.and(U).reduce()))) 1982// .map(H -> { 1983// H.getConceptNames().removeIf( 1984// A -> filter.parallelStream().allMatch(F -> F.getConceptNames().contains(A))); 1985// H.getExistentialRestrictions().entries().removeIf( 1986// rE -> filter.parallelStream().allMatch(F -> F.isSubsumedBy(rE.getValue().exists(rE.getKey())))); 1987// return H; 1988// }) 1989// .forEach(L -> { 1990// final ELConceptDescription rL = L.exists(r); 1991// if (!C.isSubsumedBy(rL)) 1992// if (L.upperNeighborsReduced().parallelStream().allMatch(U -> C.isSubsumedBy(U.exists(r)))) 1993// lowerNeighbors.add(C.clone().and(rL));// reduce 1994// }); 1995// } 1996// filter.parallelStream().forEach(F -> { 1997// F.lowerNeighbors13(sigma).parallelStream().forEach(L -> { 1998// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 1999// L.existentialRestrictions.entries().removeIf(rE -> F.isSubsumedBy(rE.getValue().exists(rE.getKey()))); 2000// final ELConceptDescription rL = L.exists(r); 2001// if (!C.isSubsumedBy(rL)) 2002// lowerNeighbors.add(C.clone().and(rL));// reduce 2003// }); 2004// }); 2005// } 2006// }); 2007// return lowerNeighbors; 2008// } 2009// 2010// public final Set<ELConceptDescription> lowerNeighbors14(final Signature sigma) { 2011// final ELConceptDescription C = ELConceptDescription.this.clone().reduce(); 2012// final Set<ELConceptDescription> lowerNeighbors = Sets.newConcurrentHashSet(); 2013// sigma.getConceptNames().parallelStream().filter(A -> !C.conceptNames.contains(A)).map(A -> { 2014// final ELConceptDescription lowerNeighbor = C.clone(); 2015// lowerNeighbor.conceptNames.add(A); 2016// return lowerNeighbor; 2017// }).forEach(lowerNeighbors::add); 2018// sigma.getRoleNames().parallelStream().forEach(r -> { 2019// final Set<ELConceptDescription> filter = C.existentialRestrictions 2020// .entries() 2021// .parallelStream() 2022// .filter(existentialRestriction -> existentialRestriction.getKey().equals(r)) 2023// .map(Entry::getValue) 2024// .collect(Collectors.toSet()); 2025// if (filter.isEmpty()) { 2026// final ELConceptDescription lowerNeighbor = C.clone(); 2027// lowerNeighbor.existentialRestrictions.put(r, ELConceptDescription.top()); 2028// lowerNeighbors.add(lowerNeighbor); 2029// } else { 2030// if (filter.size() > 1) { 2031// final Set<IRI> forbiddenNames = filter 2032// .parallelStream() 2033// .flatMap(F -> F.getConceptNames().parallelStream()) 2034// .distinct() 2035// .filter(A -> filter.parallelStream().allMatch(FF -> FF.getConceptNames().contains(A))) 2036// .collect(Collectors.toSet()); 2037// final Set<Entry<IRI, ELConceptDescription>> forbiddenRestrictions = filter 2038// .parallelStream() 2039// .flatMap(F -> F.getExistentialRestrictions().entries().parallelStream()) 2040// .distinct() 2041// .filter(rE -> { 2042// final ELConceptDescription exrE = 2043// ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 2044// return filter.parallelStream().allMatch(FF -> FF.isSubsumedBy(exrE)); 2045// }) 2046// .collect(Collectors.toSet()); 2047// final Set<ELConceptDescription> firstCandidates = 2048// filter.parallelStream().flatMap(F -> filter.parallelStream().filter(G -> !G.equals(F)).map(G -> { 2049// final ELConceptDescription that = ELConceptDescription.conjunction(F, G).reduce(); 2050// that.getConceptNames().removeAll(forbiddenNames); 2051// that.getExistentialRestrictions().entries().removeAll(forbiddenRestrictions); 2052// // that.getConceptNames().removeIf( 2053// // A -> filter.parallelStream().allMatch(FF -> FF.getConceptNames().contains(A))); 2054// // that.getExistentialRestrictions().entries().removeIf(rE -> { 2055// // final ELConceptDescription exrE = 2056// // ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()); 2057// // return filter.parallelStream().allMatch(FF -> FF.isSubsumedBy(exrE)); 2058// // }); 2059// return that; 2060// })).collect(Collectors.toSet()); 2061// recurseLowerNeighbors14(sigma, r, C, firstCandidates, filter, lowerNeighbors); 2062// } 2063// filter.parallelStream().forEach(F -> { 2064// F.lowerNeighbors14(sigma).parallelStream().forEach(L -> { 2065// L.conceptNames.removeIf(A -> F.isSubsumedBy(ELConceptDescription.conceptName(A))); 2066// L.existentialRestrictions.entries().removeIf( 2067// rE -> F.isSubsumedBy(ELConceptDescription.existentialRestriction(rE.getKey(), rE.getValue()))); 2068// final ELConceptDescription rL = ELConceptDescription.existentialRestriction(r, L); 2069// if (!C.isSubsumedBy(rL)) 2070// lowerNeighbors.add(ELConceptDescription.conjunction(C.clone(), rL)); 2071// }); 2072// }); 2073// } 2074// }); 2075// return lowerNeighbors; 2076// } 2077// 2078// private final void recurseLowerNeighbors14( 2079// final Signature sigma, 2080// final IRI r, 2081// final ELConceptDescription C, 2082// final Set<ELConceptDescription> currentCandidates, 2083// final Set<ELConceptDescription> filter, 2084// final Set<ELConceptDescription> lowerNeighbors) { 2085// final Set<ELConceptDescription> nextCandidates = Sets.newConcurrentHashSet(); 2086// currentCandidates.parallelStream().forEach(D -> { 2087// if (filter.parallelStream().noneMatch(F -> F.isSubsumedBy(D))) { 2088// final Set<ELConceptDescription> Us = D.upperNeighborsReduced(); 2089// if (D.topLevelConjuncts() <= filter.size() 2090// && Us.parallelStream().allMatch(U -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(U)))) { 2091// final ELConceptDescription X = C.clone(); 2092// X.existentialRestrictions.put(r, D); 2093// lowerNeighbors.add(X); 2094// } else 2095// Us 2096// .parallelStream() 2097// .filter( 2098// U -> filter.parallelStream().noneMatch(F -> F.isSubsumedBy(U)) 2099// && U.upperNeighborsReduced().parallelStream().anyMatch( 2100// V -> filter.parallelStream().anyMatch(F -> F.isSubsumedBy(V)))) 2101// .forEach(nextCandidates::add); 2102// } 2103// }); 2104// if (!nextCandidates.isEmpty()) 2105// recurseLowerNeighbors14(sigma, r, C, nextCandidates, filter, lowerNeighbors); 2106// } 2107 2108 @Override 2109 public final String toString() { 2110 if (isBot()) 2111 return UnicodeSymbols.BOT; 2112 if (isTop()) 2113 return UnicodeSymbols.TOP; 2114 final StringBuilder sb = new StringBuilder(); 2115 final Iterator<IRI> it1 = conceptNames.iterator(); 2116 if (it1.hasNext()) { 2117 sb.append(it1.next().toString()); 2118 } 2119 while (it1.hasNext()) { 2120 // sb.append(" "); 2121 sb.append(UnicodeSymbols.SQCAP); 2122 // sb.append(" "); 2123 sb.append(it1.next().toString()); 2124 } 2125 if (!conceptNames.isEmpty() && !existentialRestrictions.isEmpty()) { 2126 // sb.append(" "); 2127 sb.append(UnicodeSymbols.SQCAP); 2128 // sb.append(" "); 2129 } 2130 final Iterator<Entry<IRI, ELConceptDescription>> it2 = existentialRestrictions.entries().iterator(); 2131 if (it2.hasNext()) { 2132 final Entry<IRI, ELConceptDescription> existentialRestriction = it2.next(); 2133 sb.append(UnicodeSymbols.EXISTS); 2134 // sb.append(" "); 2135 sb.append(existentialRestriction.getKey().toString()); 2136 // sb.append(" "); 2137 sb.append("."); 2138 if (existentialRestriction.getValue().conceptNames.size() 2139 + existentialRestriction.getValue().existentialRestrictions.size() <= 1) 2140 sb.append(existentialRestriction.getValue().toString()); 2141 else { 2142 sb.append("("); 2143 sb.append(existentialRestriction.getValue().toString()); 2144 sb.append(")"); 2145 } 2146 } 2147 while (it2.hasNext()) { 2148 // sb.append(" "); 2149 sb.append(UnicodeSymbols.SQCAP); 2150 final Entry<IRI, ELConceptDescription> existentialRestriction = it2.next(); 2151 // sb.append(" "); 2152 sb.append(UnicodeSymbols.EXISTS); 2153 // sb.append(" "); 2154 sb.append(existentialRestriction.getKey().toString()); 2155 // sb.append(" "); 2156 sb.append("."); 2157 if (existentialRestriction.getValue().conceptNames.size() 2158 + existentialRestriction.getValue().existentialRestrictions.size() <= 1) 2159 sb.append(existentialRestriction.getValue().toString()); 2160 else { 2161 sb.append("("); 2162 sb.append(existentialRestriction.getValue().toString()); 2163 sb.append(")"); 2164 } 2165 } 2166 return sb.toString(); 2167 } 2168 2169 private final String toShortString(IRI iri) { 2170 return iri.toString().substring(iri.toString().indexOf("#") + 1); 2171 } 2172 2173 public final String toShortString() { 2174 if (isBot()) 2175 return UnicodeSymbols.BOT; 2176 if (isTop()) 2177 return UnicodeSymbols.TOP; 2178 final StringBuilder sb = new StringBuilder(); 2179 final Iterator<IRI> it1 = conceptNames.iterator(); 2180 if (it1.hasNext()) { 2181 sb.append(toShortString(it1.next())); 2182 } 2183 while (it1.hasNext()) { 2184 // sb.append(" "); 2185 sb.append(UnicodeSymbols.SQCAP); 2186 // sb.append(" "); 2187 sb.append(toShortString(it1.next())); 2188 } 2189 if (!conceptNames.isEmpty() && !existentialRestrictions.isEmpty()) { 2190 // sb.append(" "); 2191 sb.append(UnicodeSymbols.SQCAP); 2192 // sb.append(" "); 2193 } 2194 final Iterator<Entry<IRI, ELConceptDescription>> it2 = existentialRestrictions.entries().iterator(); 2195 if (it2.hasNext()) { 2196 final Entry<IRI, ELConceptDescription> existentialRestriction = it2.next(); 2197 sb.append(UnicodeSymbols.EXISTS); 2198 // sb.append(" "); 2199 sb.append(toShortString(existentialRestriction.getKey())); 2200 // sb.append(" "); 2201 sb.append("."); 2202 if (existentialRestriction.getValue().conceptNames.size() 2203 + existentialRestriction.getValue().existentialRestrictions.size() <= 1) 2204 sb.append(existentialRestriction.getValue().toShortString()); 2205 else { 2206 sb.append("("); 2207 sb.append(existentialRestriction.getValue().toShortString()); 2208 sb.append(")"); 2209 } 2210 } 2211 while (it2.hasNext()) { 2212 // sb.append(" "); 2213 sb.append(UnicodeSymbols.SQCAP); 2214 final Entry<IRI, ELConceptDescription> existentialRestriction = it2.next(); 2215 // sb.append(" "); 2216 sb.append(UnicodeSymbols.EXISTS); 2217 // sb.append(" "); 2218 sb.append(toShortString(existentialRestriction.getKey())); 2219 // sb.append(" "); 2220 sb.append("."); 2221 if (existentialRestriction.getValue().conceptNames.size() 2222 + existentialRestriction.getValue().existentialRestrictions.size() <= 1) 2223 sb.append(existentialRestriction.getValue().toShortString()); 2224 else { 2225 sb.append("("); 2226 sb.append(existentialRestriction.getValue().toShortString()); 2227 sb.append(")"); 2228 } 2229 } 2230 return sb.toString(); 2231 } 2232 2233 public final String toLaTeXString() { 2234 if (this.isBot()) 2235 return "\\bot"; 2236 if (this.isTop()) 2237 return "\\top"; 2238 final StringBuilder sb = new StringBuilder(); 2239 final Iterator<IRI> it1 = conceptNames.iterator(); 2240 if (it1.hasNext()) { 2241 sb.append(it1.next().toString()); 2242 } 2243 while (it1.hasNext()) { 2244 sb.append(" \\sqcap "); 2245 sb.append(it1.next().toString()); 2246 } 2247 final Iterator<Entry<IRI, ELConceptDescription>> it2 = existentialRestrictions.entries().iterator(); 2248 if (conceptNames.isEmpty()) 2249 sb.append(" \\sqcap "); 2250 if (it2.hasNext()) { 2251 final Entry<IRI, ELConceptDescription> existentialRestriction = it2.next(); 2252 sb.append(" \\exists "); 2253 sb.append(existentialRestriction.getKey().toString()); 2254 sb.append(" . "); 2255 if (existentialRestriction.getValue().conceptNames.size() 2256 + existentialRestriction.getValue().existentialRestrictions.size() <= 1) 2257 sb.append(existentialRestriction.getValue().toLaTeXString()); 2258 else { 2259 sb.append(" \\left( "); 2260 sb.append(existentialRestriction.getValue().toLaTeXString()); 2261 sb.append(" \\right) "); 2262 } 2263 } 2264 while (it2.hasNext()) { 2265 final Entry<IRI, ELConceptDescription> existentialRestriction = it2.next(); 2266 sb.append(" \\sqcap "); 2267 sb.append(" \\exists "); 2268 sb.append(existentialRestriction.getKey().toString()); 2269 sb.append(" . "); 2270 if (existentialRestriction.getValue().conceptNames.size() 2271 + existentialRestriction.getValue().existentialRestrictions.size() <= 1) 2272 sb.append(existentialRestriction.getValue().toLaTeXString()); 2273 else { 2274 sb.append(" \\left( "); 2275 sb.append(existentialRestriction.getValue().toLaTeXString()); 2276 sb.append(" \\right) "); 2277 } 2278 2279 } 2280 return sb.toString(); 2281 } 2282 2283 @Override 2284 public final boolean equals(Object obj) { 2285 if (obj == null) 2286 return false; 2287 if (!(obj instanceof ELConceptDescription)) 2288 return false; 2289 final ELConceptDescription other = (ELConceptDescription) obj; 2290 return this.conceptNames.equals(other.conceptNames) 2291 && this.existentialRestrictions.equals(other.existentialRestrictions); 2292 } 2293 2294 @Override 2295 public final int hashCode() { 2296 return 2 * conceptNames.hashCode() + 3 * existentialRestrictions.hashCode(); 2297 } 2298 2299 @Override 2300 public final ELConceptDescription clone() { 2301 final ELConceptDescription clone = new ELConceptDescription(); 2302 clone.getConceptNames().addAll(this.getConceptNames()); 2303 this 2304 .getExistentialRestrictions() 2305 .entries() 2306 .parallelStream() 2307 .map(ER -> Pair.of(ER.getKey(), ER.getValue().clone())) 2308 .sequential() 2309 .forEach(ER -> clone.getExistentialRestrictions().put(ER.x(), ER.y())); 2310 return clone; 2311 } 2312 2313 @Override 2314 public final int compareTo(final ELConceptDescription other) { 2315 final List<Boolean> x = Stream 2316 .<Supplier<Boolean>> of(() -> this.subsumes(other), () -> other.subsumes(this)) 2317 .parallel() 2318 .map(Supplier::get) 2319 .collect(Collectors.toList()); 2320 if (x.get(0) && x.get(1)) 2321 return 0; 2322 else if (x.get(0)) 2323 return 1; 2324 else if (x.get(1)) 2325 return -1; 2326 else 2327 return Integer.MAX_VALUE; 2328 } 2329 2330 @Override 2331 public final boolean equivalent(final ELConceptDescription other) { 2332 return Stream 2333 .<Supplier<Boolean>> of(() -> this.subsumes(other), () -> other.subsumes(this)) 2334 .parallel() 2335 .allMatch(Supplier::get); 2336 } 2337 2338 @Override 2339 public final boolean smaller(final ELConceptDescription other) { 2340 return Stream 2341 .<Supplier<Boolean>> of(() -> !this.subsumes(other), () -> other.subsumes(this)) 2342 .parallel() 2343 .allMatch(Supplier::get); 2344 } 2345 2346 @Override 2347 public final boolean greater(final ELConceptDescription other) { 2348 return Stream 2349 .<Supplier<Boolean>> of(() -> this.subsumes(other), () -> !other.subsumes(this)) 2350 .parallel() 2351 .allMatch(Supplier::get); 2352 } 2353 2354 @Override 2355 public final boolean smallerEq(final ELConceptDescription other) { 2356 return this.isSubsumedBy(other); 2357 } 2358 2359 @Override 2360 public final boolean greaterEq(final ELConceptDescription other) { 2361 return this.subsumes(other); 2362 } 2363 2364 @Override 2365 public final boolean uncomparable(final ELConceptDescription other) { 2366 return Stream 2367 .<Supplier<Boolean>> of(() -> !this.subsumes(other), () -> !other.subsumes(this)) 2368 .parallel() 2369 .allMatch(Supplier::get); 2370 } 2371 2372 @Override 2373 public ELConceptDescription infimum(ELConceptDescription e) { 2374 return and(e); 2375 } 2376 2377 @Override 2378 public ELConceptDescription supremum(ELConceptDescription e) { 2379 return lcs(e); 2380 } 2381 2382 @Override 2383 public boolean inf(ELConceptDescription e) { 2384 if (smallerEq(e)) 2385 return false; 2386 else { 2387 conceptNames.addAll(e.conceptNames); 2388 existentialRestrictions.putAll(e.existentialRestrictions); 2389 return true; 2390 } 2391 } 2392 2393 @Override 2394 public boolean sup(ELConceptDescription e) { 2395 if (greaterEq(e)) 2396 return false; 2397 else { 2398 final ELConceptDescription supremum = supremum(e); 2399 conceptNames.clear(); 2400 existentialRestrictions.clear(); 2401 conceptNames.addAll(supremum.conceptNames); 2402 existentialRestrictions.putAll(supremum.existentialRestrictions); 2403 return true; 2404 } 2405 } 2406 2407 @Override 2408 public ELConceptDescription greatest() { 2409 return ELConceptDescription.top(); 2410 } 2411 2412 @Override 2413 public ELConceptDescription smallest() { 2414 return ELConceptDescription.bot(); 2415 } 2416 2417}