001package conexp.fx.core.dl.deprecated; 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.ArrayList; 026import java.util.Arrays; 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.Optional; 034import java.util.Set; 035import java.util.concurrent.ConcurrentHashMap; 036import java.util.function.BiPredicate; 037import java.util.stream.Collectors; 038import java.util.stream.Stream; 039 040import org.semanticweb.elk.util.collections.Triple; 041import org.semanticweb.owlapi.apibinding.OWLManager; 042import org.semanticweb.owlapi.model.AddAxiom; 043import org.semanticweb.owlapi.model.IRI; 044import org.semanticweb.owlapi.model.OWLClass; 045import org.semanticweb.owlapi.model.OWLClassExpression; 046import org.semanticweb.owlapi.model.OWLDataFactory; 047import org.semanticweb.owlapi.model.OWLObjectAllValuesFrom; 048import org.semanticweb.owlapi.model.OWLObjectComplementOf; 049import org.semanticweb.owlapi.model.OWLObjectExactCardinality; 050import org.semanticweb.owlapi.model.OWLObjectHasSelf; 051import org.semanticweb.owlapi.model.OWLObjectIntersectionOf; 052import org.semanticweb.owlapi.model.OWLObjectMaxCardinality; 053import org.semanticweb.owlapi.model.OWLObjectMinCardinality; 054import org.semanticweb.owlapi.model.OWLObjectProperty; 055import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; 056import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; 057import org.semanticweb.owlapi.model.OWLOntology; 058import org.semanticweb.owlapi.model.OWLOntologyCreationException; 059import org.semanticweb.owlapi.model.OWLOntologyManager; 060import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; 061import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom; 062import org.semanticweb.owlapi.model.parameters.Imports; 063 064import com.google.common.collect.Collections2; 065import com.google.common.collect.Sets; 066 067import conexp.fx.core.algorithm.nextclosures.NextClosures1; 068import conexp.fx.core.algorithm.nextclosures.NextClosures1.Result; 069import conexp.fx.core.algorithm.nextclosures.NextClosures1C; 070import conexp.fx.core.algorithm.nextclosures.NextClosures1C.ResultC; 071import conexp.fx.core.collections.Pair; 072import conexp.fx.core.collections.setlist.HashSetArrayList; 073import conexp.fx.core.collections.setlist.SetList; 074import conexp.fx.core.context.Context; 075import conexp.fx.core.context.Implication; 076import conexp.fx.core.context.SparseContext; 077import conexp.fx.core.dl.ELConceptDescription; 078import conexp.fx.core.dl.ELLeastCommonSubsumer; 079import conexp.fx.core.dl.ELReasoner; 080import conexp.fx.core.dl.ELSyntaxException; 081import conexp.fx.core.dl.Signature; 082import conexp.fx.core.math.SetClosureOperator; 083import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl; 084import uk.ac.manchester.cs.owl.owlapi.OWLObjectComplementOfImpl; 085import uk.ac.manchester.cs.owl.owlapi.OWLObjectIntersectionOfImpl; 086 087//import org.semanticweb.owlapi.model.parameters.Imports; 088 089@Deprecated 090public class OWLInterpretation extends AInterpretation<OWLClassExpression, OWLSubClassOfAxiom, OWLOntology> { 091 092 public OWLInterpretation(final IRI baseIRI) { 093 super(baseIRI); 094 } 095 096 public OWLInterpretation(final Signature signature) { 097 super(signature); 098 } 099 100 public OWLInterpretation(final Signature signature, final Set<IRI> domain) { 101 super(signature, domain); 102 } 103 104 public final OWLDataFactory df = OWLManager.getOWLDataFactory(); 105 106 @Override 107 public final boolean isInstanceOf(final IRI individual, final OWLClassExpression conceptExpression) { 108 if (conceptExpression.isOWLNothing()) 109 return false; 110 if (conceptExpression.isOWLThing()) 111 return true; 112 if (conceptExpression instanceof OWLClass) 113 return getConceptNameExtension(((OWLClass) conceptExpression).getIRI()).contains(individual); 114 if (conceptExpression instanceof OWLObjectIntersectionOf) 115 return ((OWLObjectIntersectionOf) conceptExpression) 116 .asConjunctSet() 117 .parallelStream() 118 .allMatch(c -> isInstanceOf(individual, c)); 119 if (conceptExpression instanceof OWLObjectSomeValuesFrom) { 120 final OWLObjectSomeValuesFrom existentialRestriction = (OWLObjectSomeValuesFrom) conceptExpression; 121 return getRoleSuccessorStream(((OWLObjectProperty) existentialRestriction.getProperty()).getIRI(), individual) 122 .anyMatch(succ -> isInstanceOf(succ, existentialRestriction.getFiller())); 123 } 124 if (conceptExpression instanceof OWLObjectAllValuesFrom) { 125 final OWLObjectAllValuesFrom valueRestriction = (OWLObjectAllValuesFrom) conceptExpression; 126 return getRoleSuccessorStream(((OWLObjectProperty) valueRestriction.getProperty()).getIRI(), individual) 127 .allMatch(succ -> isInstanceOf(succ, valueRestriction.getFiller())); 128 } 129 if (conceptExpression instanceof OWLObjectHasSelf) { 130 final OWLObjectHasSelf existentialSelfRestriction = (OWLObjectHasSelf) conceptExpression; 131 return getRoleNameExtension(((OWLObjectProperty) existentialSelfRestriction.getProperty()).getIRI()) 132 .contains(Pair.of(individual, individual)); 133 } 134 if (conceptExpression instanceof OWLObjectMinCardinality) { 135 final OWLObjectMinCardinality qualifiedNumberRestriction = (OWLObjectMinCardinality) conceptExpression; 136 return getRoleSuccessorStream(((OWLObjectProperty) qualifiedNumberRestriction.getProperty()).getIRI(), individual) 137 .filter(succ -> isInstanceOf(succ, qualifiedNumberRestriction.getFiller())) 138 .skip(qualifiedNumberRestriction.getCardinality() - 1) 139 .findAny() 140 .isPresent(); 141 } 142 if (conceptExpression instanceof OWLObjectMaxCardinality) { 143 final OWLObjectMaxCardinality qualifiedNumberRestriction = (OWLObjectMaxCardinality) conceptExpression; 144 return !getRoleSuccessorStream( 145 ((OWLObjectProperty) qualifiedNumberRestriction.getProperty()).getIRI(), 146 individual) 147 .filter(succ -> isInstanceOf(succ, qualifiedNumberRestriction.getFiller())) 148 .skip(qualifiedNumberRestriction.getCardinality()) 149 .findAny() 150 .isPresent(); 151 } 152 if (conceptExpression instanceof OWLObjectExactCardinality) { 153 final OWLObjectExactCardinality qualifiedNumberRestriction = (OWLObjectExactCardinality) conceptExpression; 154 return getRoleSuccessorStream(((OWLObjectProperty) qualifiedNumberRestriction.getProperty()).getIRI(), individual) 155 .filter(succ -> isInstanceOf(succ, qualifiedNumberRestriction.getFiller())) 156 .skip(qualifiedNumberRestriction.getCardinality() - 1) 157 .findAny() 158 .isPresent() 159 && !getRoleSuccessorStream( 160 ((OWLObjectProperty) qualifiedNumberRestriction.getProperty()).getIRI(), 161 individual) 162 .filter(succ -> isInstanceOf(succ, qualifiedNumberRestriction.getFiller())) 163 .skip(qualifiedNumberRestriction.getCardinality()) 164 .findAny() 165 .isPresent(); 166 } 167 if (conceptExpression instanceof OWLObjectComplementOf) { 168 final OWLObjectComplementOf primitiveNegation = (OWLObjectComplementOf) conceptExpression; 169 if (primitiveNegation.isClassExpressionLiteral()) 170 return !isInstanceOf(individual, (OWLClass) primitiveNegation.getOperand()); 171 } 172 throw new ELSyntaxException(); 173 } 174 175// @Override 176// public Set<IRI> getConceptExpressionExtension(final OWLClassExpression conceptExpression) { 177// if (conceptExpression.isOWLNothing()) 178// return Collections.emptySet(); 179// if (conceptExpression.isOWLThing()) 180// return getDomain(); 181// if (conceptExpression instanceof OWLClass) { 182// return Sets.newHashSet(getConceptNameExtension(((OWLClass) conceptExpression).getIRI())); 183// } 184// if (conceptExpression instanceof OWLObjectIntersectionOf) { 185// final OWLObjectIntersectionOf conjunction = (OWLObjectIntersectionOf) conceptExpression; 186// final Set<IRI> extension = new HashSet<IRI>(); 187// extension.addAll(getDomain()); 188// for (OWLClassExpression conjunct : conjunction.asConjunctSet()) { 189// extension.retainAll(getConceptExpressionExtension(conjunct)); 190// } 191// return extension; 192// } 193// if (conceptExpression instanceof OWLObjectSomeValuesFrom) { 194// final OWLObjectSomeValuesFrom existentialRestriction = (OWLObjectSomeValuesFrom) conceptExpression; 195// final Set<IRI> extension = new HashSet<IRI>(); 196// for (Pair<IRI, IRI> pair : getRoleNameExtension(((OWLObjectProperty) existentialRestriction.getProperty()) 197// .getIRI())) 198// if (getConceptExpressionExtension(existentialRestriction.getFiller()).contains(pair.y())) 199// extension.add(pair.x()); 200// return extension; 201// } 202// throw new ELSyntaxException(); 203// } 204 205 @Override 206 public final boolean satisfies(final OWLSubClassOfAxiom gci) { 207 return isSubsumedBy(gci.getSubClass(), gci.getSuperClass()); 208 } 209 210 @Override 211 public final boolean models(final OWLOntology tBox) { 212 return tBox.getTBoxAxioms(Imports.INCLUDED) 213// .getTBoxAxioms(true) 214 .parallelStream() 215 .allMatch(gci -> (gci instanceof OWLSubClassOfAxiom) ? satisfies((OWLSubClassOfAxiom) gci) : true); 216 } 217 218 public OWLClassExpression getMostSpecificConceptALQ( 219 final IRI individual, 220 final int roleDepth, 221 final int maxCardinality, 222 final Constructor... constructors) { 223 return getMostSpecificConceptALQ(Collections.singleton(individual), roleDepth, maxCardinality, constructors); 224 } 225 226 public OWLClassExpression getMostSpecificConceptALQ( 227 final Set<IRI> individuals, 228 final int roleDepth, 229 final int maxCardinality, 230 final Constructor... constructors) { 231 checkRoleDepth(roleDepth); 232 if (individuals.isEmpty()) 233 return df.getOWLNothing(); 234 final Set<OWLClassExpression> conjuncts = new HashSet<OWLClassExpression>(); 235 for (IRI conceptName : conceptNameExtensions.keySet()) 236 if (getConceptNameExtension(conceptName).containsAll(individuals)) 237 conjuncts.add(new OWLClassImpl(conceptName)); 238 else if (Arrays.asList(constructors).contains(Constructor.PRIMITIVE_NEGATION) && Collections2 239 .filter(getDomain(), d -> !getConceptNameExtension(conceptName).contains(d)) 240 .containsAll(individuals)) 241 conjuncts.add(new OWLObjectComplementOfImpl(new OWLClassImpl(conceptName))); 242 if (roleDepth > 0) { 243 for (IRI roleName : signature.getRoleNames()) { 244 final OWLObjectProperty property = df.getOWLObjectProperty(roleName); 245 if (Arrays.asList(constructors).contains(Constructor.EXISTENTIAL_SELF_RESTRICTION)) { 246 if (individuals 247 .parallelStream() 248 .allMatch(individual -> getRoleNameExtension(roleName).contains(Pair.of(individual, individual)))) 249 conjuncts.add(df.getOWLObjectHasSelf(property)); 250 } 251 if (Arrays.asList(constructors).contains(Constructor.EXISTENTIAL_RESTRICTION)) { 252 for (Set<IRI> successors : getSuccessorSetsER(individuals, roleName)) 253 conjuncts 254 .add( 255 df 256 .getOWLObjectSomeValuesFrom( 257 property, 258 getMostSpecificConceptALQ(successors, roleDepth - 1, maxCardinality, constructors))); 259 } 260 if (Arrays.asList(constructors).contains(Constructor.VALUE_RESTRICTION)) { 261// for (Set<IRI> successors : getSuccessorSetsVR(individuals, roleName)) 262 conjuncts 263 .add( 264 df 265 .getOWLObjectAllValuesFrom( 266 property, 267 getMostSpecificConceptALQ( 268 getAllSuccessors(individuals, roleName), 269 roleDepth - 1, 270 maxCardinality, 271 constructors))); 272 } 273 if (Arrays.asList(constructors).contains(Constructor.UNQUALIFIED_AT_MOST_RESTRICTION)) { 274 for (int cardinality = 1; cardinality < maxCardinality; cardinality++) 275 for (Set<IRI> successors : getSuccessorSetsQLR(individuals, roleName, cardinality)) 276 conjuncts 277 .add( 278 df 279 .getOWLObjectMaxCardinality( 280 cardinality, 281 property, 282 getMostSpecificConceptALQ(successors, roleDepth - 1, maxCardinality, constructors))); 283 } 284 if (Arrays.asList(constructors).contains(Constructor.QUALIFIED_AT_LEAST_RESTRICTION)) { 285 for (int cardinality = 2; cardinality < maxCardinality; cardinality++) 286 for (Set<IRI> successors : getSuccessorSetsQGR(individuals, roleName, cardinality)) 287 conjuncts 288 .add( 289 df 290 .getOWLObjectMinCardinality( 291 cardinality, 292 property, 293 getMostSpecificConceptALQ(successors, roleDepth - 1, maxCardinality, constructors))); 294 } 295 // TODO 296 } 297 } 298 if (conjuncts.isEmpty()) 299 return df.getOWLThing(); 300 if (conjuncts.size() == 1) 301 return conjuncts.iterator().next(); 302 return new OWLObjectIntersectionOfImpl(conjuncts); 303 } 304 305 protected final Set<IRI> getAllSuccessors(final Set<IRI> individuals, final IRI roleName) { 306 if (individuals.isEmpty()) 307 return Collections.emptySet(); 308 final Optional<Stream<IRI>> optional = individuals 309 .parallelStream() 310 .map(individual -> getRoleSuccessorStream(roleName, individual)) 311 .reduce(Stream::concat); 312 if (optional.isPresent()) 313 return optional.get().collect(Collectors.toSet()); 314 System.out.println("optional is not present"); 315 System.out.println(getRoleSuccessors(roleName, individuals.iterator().next())); 316 return Collections.emptySet(); 317 } 318 319 protected final Set<Set<IRI>> getSuccessorSetsER(final Set<IRI> individuals, final IRI roleName) { 320 return filterMinimal( 321 Sets 322 .powerSet(getAllSuccessors(individuals, roleName)) 323 .parallelStream() 324 .filter( 325 successors -> individuals 326 .parallelStream() 327 .allMatch( 328 individual -> successors 329 .parallelStream() 330 .anyMatch( 331 successor -> getRoleNameExtension(roleName).contains(Pair.of(individual, successor))))) 332 .collect(Collectors.toSet())); 333 } 334 335 protected final Set<Set<IRI>> getSuccessorSetsER2(final Set<IRI> individuals, final IRI roleName) { 336 // this method should not filter the powerset, which is a costly operation, but instead create the minimal 337 // successors directly 338 Set<Set<IRI>> successorSets = Collections.emptySet(); 339 final Iterator<IRI> it = individuals.iterator(); 340 if (it.hasNext()) { 341 successorSets = firstSuccessorSetsER(it.next(), roleName); 342 } 343 while (it.hasNext()) { 344 successorSets = extendSuccessorSetsER(successorSets, it.next(), roleName); 345 } 346 return filterMinimal(successorSets); 347 } 348 349 private final Set<Set<IRI>> firstSuccessorSetsER(final IRI individual, final IRI roleName) { 350 return getRoleSuccessorStream(roleName, individual) 351 .map(successor -> Sets.newHashSet(successor)) 352 .collect(Collectors.toSet()); 353 } 354 355 private final Set<Set<IRI>> 356 extendSuccessorSetsER(final Set<Set<IRI>> successorSets, final IRI individual, final IRI roleName) { 357 final Set<Set<IRI>> extendedSets = new HashSet<Set<IRI>>(); 358 final Set<Set<IRI>> extendedSetsP = Collections.synchronizedSet(extendedSets); 359 successorSets.parallelStream().forEach(successorSet -> { 360 getRoleSuccessorStream(roleName, individual).forEach(successor -> { 361 final Set<IRI> extendedSet = new HashSet<IRI>(); 362 extendedSet.addAll(successorSet); 363 extendedSet.add(successor); 364 extendedSetsP.add(extendedSet); 365 }); 366 }); 367 return extendedSets; 368 } 369 370 public static final <T> Set<Set<T>> filterMinimal(final Set<Set<T>> sets) { 371 return OWLMinimizer.filterMinimalParallel(sets, (set1, set2) -> set1.containsAll(set2)); 372// return sets.parallelStream().filter( 373// set1 -> !sets.parallelStream().anyMatch( 374// set2 -> !set1.equals(set2) && set1.containsAll(set2))).collect( 375// Collectors.toSet()); 376// final Set<Set<T>> minSets = new HashSet<Set<T>>(); 377// for (Set<T> set1 : sets) { 378// boolean isMinimal = true; 379// for (Set<T> set2 : sets) 380// if (!set1.equals(set2)) 381// if (set1.containsAll(set2)) { 382// isMinimal = false; 383// break; 384// } 385// if (isMinimal) 386// minSets.add(set1); 387// } 388// return minSets; 389 } 390 391 private final Set<Set<IRI>> 392 getSuccessorSetsQGR(final Set<IRI> individuals, final IRI roleName, final int cardinality) { 393 return filterMinimal( 394 Sets 395 .powerSet(getAllSuccessors(individuals, roleName)) 396 .parallelStream() 397 .filter( 398 successors -> individuals 399 .parallelStream() 400 .allMatch( 401 individual -> successors 402 .parallelStream() 403 .filter( 404 successor -> getRoleNameExtension(roleName).contains(Pair.of(individual, successor))) 405 .skip(cardinality - 1) 406 .findAny() 407 .isPresent())) 408 .collect(Collectors.toSet())); 409 } 410 411 private final Set<Set<IRI>> 412 getSuccessorSetsQLR(final Set<IRI> individuals, final IRI roleName, final int cardinality) { 413 return filterMinimal( 414 Sets 415 .powerSet(getAllSuccessors(individuals, roleName)) 416 .parallelStream() 417 .filter( 418 successors -> individuals 419 .parallelStream() 420 .allMatch( 421 individual -> !successors 422 .parallelStream() 423 .filter( 424 successor -> getRoleNameExtension(roleName).contains(Pair.of(individual, successor))) 425 .skip(cardinality) 426 .findAny() 427 .isPresent())) 428 .collect(Collectors.toSet())); 429 } 430 431 @Override 432 public OWLClassExpression getMostSpecificConcept( 433 final IRI individual, 434 final int roleDepth, 435 final int maxCardinality, 436 final Constructor... constructors) { 437 return getMostSpecificConcept(Collections.singleton(individual), roleDepth, maxCardinality, constructors); 438 } 439 440 private final Map<Set<IRI>, OWLClassExpression> cache = new ConcurrentHashMap<>(); 441 442 @Override 443 public OWLClassExpression getMostSpecificConcept( 444 final Set<IRI> individuals, 445 final int roleDepth, 446 final int maxCardinality, 447 final Constructor... constructors) { 448 if (cache.containsKey(individuals)) 449 return cache.get(individuals); 450 final OWLClassExpression mmsc = getMostSpecificConceptALQ(individuals, roleDepth, maxCardinality, constructors); 451 cache.put(individuals, mmsc); 452 return mmsc; 453 } 454 455 public OWLClassExpression _getMostSpecificConcept(final IRI individual, final int roleDepth) { 456 checkRoleDepth(roleDepth); 457 final Set<OWLClassExpression> conjuncts = new HashSet<OWLClassExpression>(); 458 for (IRI conceptName : conceptNameExtensions.keySet()) 459 if (getConceptNameExtension(conceptName).contains(individual)) 460 conjuncts.add(new OWLClassImpl(conceptName)); 461 if (roleDepth > 0) 462 for (IRI roleName : roleNameExtensions.keySet()) 463 for (Pair<IRI, IRI> pair : getRoleNameExtension(roleName)) 464 if (pair.x().equals(individual)) 465 conjuncts 466 .add( 467 df 468 .getOWLObjectSomeValuesFrom( 469 df.getOWLObjectProperty(roleName), 470 getMostSpecificConcept(pair.y(), 0, roleDepth - 1))); 471 if (conjuncts.isEmpty()) 472 return df.getOWLThing(); 473 if (conjuncts.size() == 1) 474 return conjuncts.iterator().next(); 475 return new OWLObjectIntersectionOfImpl(conjuncts); 476 } 477 478 public final OWLClassExpression _getMostSpecificConcept(final Set<IRI> individuals, final int roleDepth) { 479 checkRoleDepth(roleDepth); 480 return ELLeastCommonSubsumer.of(Collections2.transform(individuals, individual -> { 481 return getMostSpecificConcept(individual, 0, roleDepth); 482 })); 483 } 484 485// private Set<OWLClassExpression> getAllMostSpecificConcepts(final int roleDepth) { 486// System.out.println("Computing all mmscs..."); 487// final Set<OWLClassExpression> result = new HashSet<OWLClassExpression>(); 488// if (roleDepth > -1) { 489// final Map<IRI, OWLClassExpression> mmscs = new HashMap<IRI, OWLClassExpression>(); 490// final Map<Integer, Map<Set<IRI>, OWLClassExpression>> _mmscs = 491// new HashMap<Integer, Map<Set<IRI>, OWLClassExpression>>(); 492// for (IRI individual : getDomain()) 493// mmscs.put(individual, getMostSpecificConcept(individual, roleDepth)); 494// for (int i = 2; i < getDomain().size(); i++) { 495// System.out.println("cardinality " + i); 496// final HashMap<Set<IRI>, OWLClassExpression> map = new HashMap<Set<IRI>, OWLClassExpression>(); 497// _mmscs.put(i, map); 498// if (i == 2) { 499// for (Entry<IRI, OWLClassExpression> e1 : mmscs.entrySet()) 500// for (Entry<IRI, OWLClassExpression> e2 : mmscs.entrySet()) 501// if (!e1.getKey().equals(e2.getKey())) { 502// final HashSet<IRI> key = Sets.newHashSet(e1.getKey(), e2.getKey()); 503// if (!map.containsKey(key)) { 504// map.put(key, ELLeastCommonSubsumer.of(e1.getValue(), e2.getValue())); 505// System.out.print("."); 506// } 507// } 508// } else { 509// for (Entry<IRI, OWLClassExpression> e1 : mmscs.entrySet()) 510// for (Entry<Set<IRI>, OWLClassExpression> e2 : _mmscs.get(i - 1).entrySet()) 511// if (!e2.getKey().contains(e1.getKey())) { 512// final HashSet<IRI> key = Sets.newHashSet(Sets.union(e2.getKey(), Collections.singleton(e1.getKey()))); 513// if (!map.containsKey(key)) { 514// map.put(key, ELLeastCommonSubsumer.of(e1.getValue(), e2.getValue())); 515// System.out.print("."); 516// } 517// } 518// } 519// } 520// result.addAll(mmscs.values()); 521// for (Entry<Integer, Map<Set<IRI>, OWLClassExpression>> entry : _mmscs.entrySet()) 522// result.addAll(entry.getValue().values()); 523// } 524// return result; 525// } 526 527 @Override 528 protected final SetList<OWLClassExpression> getAttributeSetForInducedContext( 529 final int roleDepth, 530 final int maxCardinality, 531 final Constructor... constructors) { 532 final Set<OWLClassExpression> mmscs = roleDepth > 0 533 ? getAllMostSpecificConcepts(roleDepth - 1, maxCardinality, constructors) : Collections.emptySet(); 534 final SetList<OWLClassExpression> _codomain = new HashSetArrayList<OWLClassExpression>(); 535 _codomain.add(df.getOWLNothing()); 536 _codomain.addAll(Collections2.transform(signature.getConceptNames(), df::getOWLClass)); 537 if (Arrays.asList(constructors).contains(Constructor.PRIMITIVE_NEGATION)) 538 _codomain 539 .addAll( 540 Collections2 541 .transform( 542 signature.getConceptNames(), 543 conceptName -> df.getOWLObjectComplementOf(df.getOWLClass(conceptName)))); 544 for (IRI roleName : signature.getRoleNames()) 545 for (Constructor c : constructors) 546 switch (c) { 547 case EXISTENTIAL_RESTRICTION: 548 _codomain.addAll(Collections2.transform(mmscs, mmsc -> { 549 return df.getOWLObjectSomeValuesFrom(df.getOWLObjectProperty(roleName), mmsc); 550 })); 551 break; 552 case VALUE_RESTRICTION: 553 _codomain.addAll(Collections2.transform(mmscs, mmsc -> { 554 return df.getOWLObjectAllValuesFrom(df.getOWLObjectProperty(roleName), mmsc); 555 })); 556 break; 557 case QUALIFIED_AT_LEAST_RESTRICTION: 558 Stream 559 .iterate(0, n -> n + 1) 560 .limit(maxCardinality) 561 .skip(2) 562 .map( 563 cardinality -> Collections2 564 .transform( 565 mmscs, 566 mmsc -> df.getOWLObjectMinCardinality(cardinality, df.getOWLObjectProperty(roleName), mmsc)) 567 .stream()) 568 .reduce(Stream::concat) 569 .ifPresent(stream -> _codomain.addAll(stream.collect(Collectors.toSet()))); 570 break; 571 case UNQUALIFIED_AT_MOST_RESTRICTION: 572 Stream 573 .iterate(0, n -> n + 1) 574 .limit(maxCardinality) 575 .map(cardinality -> df.getOWLObjectMaxCardinality(cardinality, df.getOWLObjectProperty(roleName))) 576 .forEach(_codomain::add); 577// Stream.iterate( 578// 0, 579// n -> n + 1).limit( 580// maxCardinality).skip( 581// 1).map( 582// cardinality -> Collections2.transform( 583// mmscs, 584// mmsc -> df.getOWLObjectMaxCardinality( 585// cardinality, 586// df.getOWLObjectProperty(roleName), 587// mmsc)).stream()).reduce( 588// Stream::concat).ifPresent( 589// stream -> _codomain.addAll(stream.collect(Collectors.toSet()))); 590 break; 591 case EXISTENTIAL_SELF_RESTRICTION: 592 _codomain.add(df.getOWLObjectHasSelf(df.getOWLObjectProperty(roleName))); 593 break; 594 } 595 return _codomain; 596 }; 597 598 @Override 599 protected final Set<Implication<IRI, OWLClassExpression>> getBackgroundImplications( 600 final Context<IRI, OWLClassExpression> inducedContext, 601 final OWLOntology backgroundOntology) { 602 final BiPredicate<OWLClassExpression, OWLClassExpression> subsumptionTest; 603 if (backgroundOntology == null) 604 subsumptionTest = (concept1, concept2) -> ELReasoner.isSubsumedBy(concept1, concept2); 605 else 606 subsumptionTest = (concept1, concept2) -> ELReasoner.isSubsumedBy(concept1, concept2, backgroundOntology); 607 final Set<Implication<IRI, OWLClassExpression>> backgroundImplications = 608 new HashSet<Implication<IRI, OWLClassExpression>>(); 609 for (OWLClassExpression concept1 : inducedContext.colHeads()) 610 for (OWLClassExpression concept2 : inducedContext.colHeads()) 611 if (!concept1.equals(concept2)) { 612 if (subsumptionTest.test(concept1, concept2)) 613 backgroundImplications 614 .add( 615 new Implication<IRI, OWLClassExpression>( 616 Collections.singleton(concept1), 617 Collections.singleton(concept2), 618 Collections.emptySet())); 619 } 620 return backgroundImplications; 621 } 622 623 @Override 624 public final OWLOntology computeTBoxBase( 625 final int roleDepth, 626 final int maxCardinality, 627 final OWLOntology backgroundOntology, 628 final Constructor... constructors) throws OWLOntologyCreationException { 629 checkRoleDepth(roleDepth); 630 final OWLOntologyManager om = OWLManager.createOWLOntologyManager(); 631 final OWLOntology ontology = om.createOntology(); 632 final Context<IRI, OWLClassExpression> inducedContext = 633 getInducedContext(domain, roleDepth, maxCardinality, constructors); 634 final Set<Implication<IRI, OWLClassExpression>> backgroundImplications = 635 getBackgroundImplications(inducedContext, backgroundOntology); 636 final ResultC<IRI, OWLClassExpression> result = 637 NextClosures1C.computeWithBackgroundImplications(inducedContext, backgroundImplications, true); 638 for (Entry<Set<OWLClassExpression>, Set<OWLClassExpression>> entry : result.implications.entrySet()) 639 om 640 .applyChange( 641 new AddAxiom( 642 ontology, 643 df 644 .getOWLSubClassOfAxiom( 645 ELConceptDescription 646 .of(df.getOWLObjectIntersectionOf(entry.getKey())) 647 .clone() 648 .reduce() 649 .toOWLClassExpression(), 650 ELConceptDescription 651 .of(df.getOWLObjectIntersectionOf(entry.getValue())) 652 .clone() 653 .reduce() 654 .toOWLClassExpression()))); 655 return ontology; 656 } 657 658 public final class Variable { 659 660 final int index; 661 662 public Variable(final int index) { 663 super(); 664 this.index = index; 665 } 666 } 667 668 private final SetList<ArrayList<IRI>> getFirstFunctions() { 669 final SetList<ArrayList<IRI>> fs = new HashSetArrayList<ArrayList<IRI>>(); 670 for (IRI individual : getDomain()) { 671 final ArrayList<IRI> f = new ArrayList<IRI>(); 672 f.add(individual); 673 fs.add(f); 674 } 675 return fs; 676 } 677 678 private final SetList<ArrayList<IRI>> getNextFunctions(final SetList<ArrayList<IRI>> _fs) { 679 final SetList<ArrayList<IRI>> fs = new HashSetArrayList<ArrayList<IRI>>(); 680 for (ArrayList<IRI> _f : _fs) { 681 for (IRI individual : getDomain()) { 682 final ArrayList<IRI> f = new ArrayList<IRI>(_f); 683 f.add(individual); 684 fs.add(f); 685 } 686 } 687 return fs; 688 } 689 690 private final SetList<ArrayList<IRI>> getFunctions(final int roleDepth) { 691 SetList<ArrayList<IRI>> fs = new HashSetArrayList<ArrayList<IRI>>(); 692 fs.add(new ArrayList<IRI>()); 693 for (int i = 0; i <= roleDepth; i++) { 694 fs = getNextFunctions(fs); 695 } 696 return fs; 697 } 698 699 private final boolean applies(final ArrayList<IRI> f, final Triple<Integer, IRI, Integer> t) { 700 final IRI d = f.get(t.getFirst()); 701 final IRI r = t.getSecond(); 702 final IRI e = f.get(t.getThird()); 703 return roleNameExtensions.get(r).contains(Pair.of(d, e)); 704 } 705 706 public final SparseContext<ArrayList<IRI>, Triple<Integer, IRI, Integer>> getInducedRoleContext(final int roleDepth) { 707 final SetList<ArrayList<IRI>> _domain = getFunctions(roleDepth + 1); 708 709 final SetList<Triple<Integer, IRI, Integer>> _codomain = new HashSetArrayList<Triple<Integer, IRI, Integer>>(); 710 for (IRI roleName : signature.getRoleNames()) { 711 for (int i = 2; i <= roleDepth; i++) 712 for (int j = 1; j <= i; j++) { 713 _codomain.add(new Triple<Integer, IRI, Integer>(j, roleName, j + 1)); 714 if (i != 1) 715 _codomain.add(new Triple<Integer, IRI, Integer>(1, roleName, j + 1)); 716 } 717 718 } 719 final SparseContext<ArrayList<IRI>, Triple<Integer, IRI, Integer>> inducedRoleContext = 720 new SparseContext<ArrayList<IRI>, Triple<Integer, IRI, Integer>>(_domain, _codomain, false); 721 722 for (ArrayList<IRI> o : _domain) 723 for (Triple<Integer, IRI, Integer> a : _codomain) { 724 if (applies(o, a)) 725 inducedRoleContext.add(o, a); 726 } 727 728 return inducedRoleContext; 729 } 730 731 public final Set<OWLSubPropertyChainOfAxiom> getRoleInclusionBase(final int roleDepth) { 732 final Set<OWLSubPropertyChainOfAxiom> base = new HashSet<OWLSubPropertyChainOfAxiom>(); 733 734 final SparseContext<ArrayList<IRI>, Triple<Integer, IRI, Integer>> cxt = getInducedRoleContext(roleDepth); 735 final SetClosureOperator<Triple<Integer, IRI, Integer>> clop = new SetClosureOperator<Triple<Integer, IRI, Integer>>() { 736 737 @Override 738 public Set<Triple<Integer, IRI, Integer>> closure(Set<Triple<Integer, IRI, Integer>> set) { 739 return set; 740// if (set.parallelStream().anyMatch( 741// t -> t.getFirst().equals( 742// 1) && t.getThird().equals( 743// 2))) 744// return new HashSet<Triple<Integer, IRI, Integer>>(set); 745// return new HashSet<Triple<Integer, IRI, Integer>>(cxt.colHeads()); 746 } 747 748 }; 749 final Result<ArrayList<IRI>, Triple<Integer, IRI, Integer>> result = NextClosures1 750 .compute( 751 cxt, 752 // clop, 753 true); 754 for (Entry<Set<Triple<Integer, IRI, Integer>>, Set<Triple<Integer, IRI, Integer>>> e : result.implications 755 .entrySet()) { 756 final List<Triple<Integer, IRI, Integer>> chain = new ArrayList<Triple<Integer, IRI, Integer>>(roleDepth); 757 final Triple<Integer, IRI, Integer> conclusion; 758 boolean chainEnded = false; 759 int i; 760 for (i = 1; !chainEnded || i <= roleDepth; i++) { 761 final int j = i; 762 final Optional<Triple<Integer, IRI, Integer>> opt = 763 e.getKey().parallelStream().filter(t -> t.getFirst().equals(j) && t.getThird().equals(j + 1)).findFirst(); 764 if (opt.isPresent()) 765 chain.add(opt.get()); 766 else 767 chainEnded = true; 768 } 769 if (!chain.isEmpty()) 770 System.out.println("found chain of size " + chain.size() + " " + chain); 771 final int j = chain.size() + 1;// i; 772 final Optional<Triple<Integer, IRI, Integer>> opt = 773 e.getValue().parallelStream().filter(t -> t.getFirst().equals(1) && t.getThird().equals(j)).findFirst(); 774 if (opt.isPresent()) 775 conclusion = opt.get(); 776 else 777 conclusion = null; 778 if (conclusion != null) { 779 final List<OWLObjectPropertyExpression> subProperty = 780 chain.stream().map(t -> df.getOWLObjectProperty(t.getSecond())).collect(Collectors.toList()); 781 base.add(df.getOWLSubPropertyChainOfAxiom(subProperty, df.getOWLObjectProperty(conclusion.getSecond()))); 782 } 783 } 784 return base; 785 } 786}