From 589a2de0a8b205d48c2a49ba8620e26d6f31cd6c Mon Sep 17 00:00:00 2001 From: Julian Mendez Date: Mon, 30 Nov 2015 20:24:33 +0100 Subject: [PATCH] Use jcel 0.22.0 --- gel/pom.xml | 12 +- .../tudresden/inf/lat/gel/GelProcessor.java | 4 +- .../core/algorithm/cel/CelProcessorX.java | 811 ++++++++++++++++++ 3 files changed, 819 insertions(+), 8 deletions(-) create mode 100644 gel/src/main/java/de/tudresden/inf/lat/jcel/core/algorithm/cel/CelProcessorX.java diff --git a/gel/pom.xml b/gel/pom.xml index bed9c5a..b72c1de 100644 --- a/gel/pom.xml +++ b/gel/pom.xml @@ -15,7 +15,7 @@ de.tu-dresden.inf.lat.jcel jcel-owlapi - 0.23.0 + 0.22.0 @@ -153,11 +153,11 @@ ${import.package} {maven-resources}, {maven-dependencies}, - @jcel-coreontology-0.23.0.jar, - @jcel-core-0.23.0.jar, - @jcel-ontology-0.23.0.jar, - @jcel-reasoner-0.23.0.jar, - @jcel-owlapi-0.23.0.jar + @jcel-coreontology-0.22.0.jar, + @jcel-core-0.22.0.jar, + @jcel-ontology-0.22.0.jar, + @jcel-reasoner-0.22.0.jar, + @jcel-owlapi-0.22.0.jar ${require.bundle} diff --git a/gel/src/main/java/de/tudresden/inf/lat/gel/GelProcessor.java b/gel/src/main/java/de/tudresden/inf/lat/gel/GelProcessor.java index 61d53e4..4df49cc 100644 --- a/gel/src/main/java/de/tudresden/inf/lat/gel/GelProcessor.java +++ b/gel/src/main/java/de/tudresden/inf/lat/gel/GelProcessor.java @@ -6,7 +6,7 @@ import java.util.TreeMap; import de.tudresden.inf.lat.jcel.core.algorithm.cel.CelExtendedOntology; -import de.tudresden.inf.lat.jcel.core.algorithm.cel.CelProcessor; +import de.tudresden.inf.lat.jcel.core.algorithm.cel.CelProcessorX; import de.tudresden.inf.lat.jcel.core.graph.IntegerBinaryRelation; import de.tudresden.inf.lat.jcel.core.graph.IntegerSubsumerGraph; import de.tudresden.inf.lat.jcel.core.graph.IntegerSubsumerGraphImpl; @@ -17,7 +17,7 @@ import de.tudresden.inf.lat.jcel.ontology.axiom.extension.IntegerOntologyObjectFactory; import de.tudresden.inf.lat.jcel.ontology.normalization.OntologyNormalizer; -public class GelProcessor extends CelProcessor { +public class GelProcessor extends CelProcessorX { private IntegerSubsumerGraph classGraph; private IntegerSubsumerGraph objectPropertyGraph; private Map relationGraph; diff --git a/gel/src/main/java/de/tudresden/inf/lat/jcel/core/algorithm/cel/CelProcessorX.java b/gel/src/main/java/de/tudresden/inf/lat/jcel/core/algorithm/cel/CelProcessorX.java new file mode 100644 index 0000000..03b01f1 --- /dev/null +++ b/gel/src/main/java/de/tudresden/inf/lat/jcel/core/algorithm/cel/CelProcessorX.java @@ -0,0 +1,811 @@ +/* + * + * Copyright (C) 2009-2015 Julian Mendez + * + * + * This file is part of jcel. + * + * + * The contents of this file are subject to the GNU Lesser General Public License + * version 3 + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * + * Alternatively, the contents of this file may be used under the terms + * of the Apache License, Version 2.0, in which case the + * provisions of the Apache License, Version 2.0 are applicable instead of those + * above. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package de.tudresden.inf.lat.jcel.core.algorithm.cel; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +import de.tudresden.inf.lat.jcel.core.algorithm.common.Processor; +import de.tudresden.inf.lat.jcel.core.algorithm.common.UnclassifiedOntologyException; +import de.tudresden.inf.lat.jcel.core.graph.IntegerBinaryRelation; +import de.tudresden.inf.lat.jcel.core.graph.IntegerHierarchicalGraph; +import de.tudresden.inf.lat.jcel.core.graph.IntegerHierarchicalGraphImpl; +import de.tudresden.inf.lat.jcel.core.graph.IntegerRelationMapImpl; +import de.tudresden.inf.lat.jcel.core.graph.IntegerSubsumerGraph; +import de.tudresden.inf.lat.jcel.core.graph.IntegerSubsumerGraphImpl; +import de.tudresden.inf.lat.jcel.coreontology.axiom.NormalizedIntegerAxiom; +import de.tudresden.inf.lat.jcel.coreontology.axiom.NormalizedIntegerAxiomFactory; +import de.tudresden.inf.lat.jcel.coreontology.axiom.RI2Axiom; +import de.tudresden.inf.lat.jcel.coreontology.axiom.RI3Axiom; +import de.tudresden.inf.lat.jcel.coreontology.datatype.IntegerEntityManager; +import de.tudresden.inf.lat.jcel.coreontology.datatype.IntegerEntityType; + +/** + * Classifies an ontology using the CEL algorithm. The rules are: + * + *
    + *
  • CR1 : if A1, … , An ∈ S(X) + * and A1 \u2293 … \u2293 An \u2291 B ∈ + * O and B ∉ S(X) then S(X) := S(X) ∪ {B}
  • + *
  • CR2 : if A ∈ S(X) and A \u2291 ∃ r . B + * ∈ O and (X,B) ∉ R(r) then R(r) := R(r) ∪{(X,B)}
  • + *
  • CR3 : if (X,Y) ∈ R(r) and A ∈ S(Y) and + * ∃ r . A \u2291 B ∈ O and B ∉ S(X) then + * S(X) := S(X) ∪ {B}
  • + *
  • CR4 : if (X,Y) ∈ R(r) and ⊥ ∈ S(Y) + * and ⊥ ∉ S(X) then S(X) := S(X) ∪ {⊥}
  • + *
  • CR5 : if (X,Y) ∈ R(r) and r \u2291 s ∈ O + * and (X,Y) ∉ R(s) then R(s) := R(s) ∪ {(X,Y)}
  • + *
  • CR6 : if (X,Y) ∈ R(r) and (Y,Z) ∈ R(s) and + * r \u2218 s \u2291 t ∈ O and (X,Z) ∉ R(t) then R(t) + * := R(t) ∪ {(X,Z)}
  • + *
+ * + * @author Julian Mendez + */ +public class CelProcessorX implements Processor { + + private static final Integer bottomClassId = IntegerEntityManager.bottomClassId; + private static final Integer bottomObjectPropertyId = IntegerEntityManager.bottomObjectPropertyId; + private static final Logger logger = Logger.getLogger(CelProcessor.class + .getName()); + private static final Integer topClassId = IntegerEntityManager.topClassId; + private static final Integer topObjectPropertyId = IntegerEntityManager.topObjectPropertyId; + + private final NormalizedIntegerAxiomFactory axiomFactory; + private IntegerSubsumerGraphImpl classGraph = null; + private IntegerHierarchicalGraph classHierarchy = null; + private IntegerHierarchicalGraph dataPropertyHierarchy = null; + private Map> directTypes = null; + private final IntegerEntityManager entityManager; + private CelExtendedOntology extendedOntology = null; + private boolean isReady = false; + private IntegerSubsumerGraphImpl objectPropertyGraph = null; + private IntegerHierarchicalGraph objectPropertyHierarchy = null; + private Map> propertyUsedByClass = null; + private final Deque queueEntries = new ArrayDeque(); + private final Deque queueKeys = new ArrayDeque(); + private IntegerRelationMapImpl relationSet = null; + private Map> sameIndividualMap = null; + private Map> transitiveSubsumed = null; + + /** + * Constructs a new CEL processor. + * + * @param originalObjectProperties + * set of object properties + * @param originalClasses + * set of classes + * @param normalizedAxiomSet + * set of axioms + * @param factory + * factory + * @param entityManager + * entity manager + */ + public CelProcessorX(Set originalObjectProperties, + Set originalClasses, + Set normalizedAxiomSet, + NormalizedIntegerAxiomFactory factory, + IntegerEntityManager entityManager) { + if (originalObjectProperties == null) { + throw new IllegalArgumentException("Null argument."); + } + if (originalClasses == null) { + throw new IllegalArgumentException("Null argument."); + } + if (normalizedAxiomSet == null) { + throw new IllegalArgumentException("Null argument."); + } + if (factory == null) { + throw new IllegalArgumentException("Null argument."); + } + if (entityManager == null) { + throw new IllegalArgumentException("Null argument."); + } + + this.axiomFactory = factory; + this.entityManager = entityManager; + preProcess(originalObjectProperties, originalClasses, + normalizedAxiomSet); + } + + private void addToQueue(Integer className, + Collection entrySet) { + for (ExtensionEntry entry : entrySet) { + this.queueKeys.push(className); + this.queueEntries.push(entry); + } + } + + /** + * @param hierarchicalGraph + * graph containing direct subsumers + * @return a map with all the direct types for each individual. + */ + private Map> computeDirectTypes( + IntegerHierarchicalGraph hierarchicalGraph) { + Map> ret = new HashMap>(); + Set individuals = getEntityManager().getEntities( + IntegerEntityType.INDIVIDUAL, false); + for (Integer indiv : individuals) { + Set subsumers = hierarchicalGraph + .getParents(getEntityManager().getAuxiliaryNominal(indiv)); + for (Integer elem : subsumers) { + if (getEntityManager().getAuxiliaryNominals().contains(elem)) { + throw new IllegalStateException( + "An individual has another individual as direct subsumer."); + } + } + ret.put(indiv, Collections.unmodifiableSet(subsumers)); + } + return ret; + } + + private Map> computeSameIndividualMap( + IntegerHierarchicalGraph hierarchicalGraph) { + Map> ret = new HashMap>(); + Set individuals = getEntityManager().getEntities( + IntegerEntityType.INDIVIDUAL, false); + for (Integer indiv : individuals) { + Set equivalentClasses = hierarchicalGraph + .getEquivalents(getEntityManager().getAuxiliaryNominal( + indiv)); + Set equivalents = new HashSet(); + for (Integer elem : equivalentClasses) { + if (getEntityManager().getAuxiliaryNominals().contains(elem)) { + equivalents.add(getEntityManager().getIndividual(elem)); + } + } + ret.put(indiv, Collections.unmodifiableSet(equivalents)); + } + return ret; + } + + private IntegerSubsumerGraphImpl createClassGraph( + Set originalClassSet, Set axiomSet) { + + Set classIdSet = new HashSet(); + classIdSet.addAll(originalClassSet); + for (NormalizedIntegerAxiom axiom : axiomSet) { + classIdSet.addAll(axiom.getClassesInSignature()); + } + IntegerSubsumerGraphImpl ret = new IntegerSubsumerGraphImpl( + bottomClassId, topClassId); + for (Integer index : classIdSet) { + ret.addAncestor(index, topClassId); + } + ret.addAncestor(topClassId, topClassId); + return ret; + } + + private IntegerSubsumerGraphImpl createObjectPropertyGraph( + Set originalPropertySet, + Set axiomSet) { + IntegerSubsumerGraphImpl ret = new IntegerSubsumerGraphImpl( + bottomObjectPropertyId, topObjectPropertyId); + Set propertyIdSet = new HashSet(); + propertyIdSet.addAll(originalPropertySet); + for (NormalizedIntegerAxiom axiom : axiomSet) { + propertyIdSet.addAll(axiom.getObjectPropertiesInSignature()); + } + for (Integer index : propertyIdSet) { + ret.addAncestor(index, topObjectPropertyId); + } + for (NormalizedIntegerAxiom axiom : axiomSet) { + if (axiom instanceof RI2Axiom) { + RI2Axiom current = (RI2Axiom) axiom; + ret.addAncestor(current.getSubProperty(), + current.getSuperProperty()); + } + } + makeTransitiveClosure(ret); + return ret; + } + + private Map> createPropertyUseMap() { + Map> ret = new HashMap>(); + for (Integer cA : getClassGraph().getElements()) { + Set propertySet = new HashSet(); + for (Integer r : getObjectPropertyGraph().getElements()) { + if (!(this.relationSet.getBySecond(r, cA).isEmpty())) { + propertySet.add(r); + } + } + ret.put(cA, propertySet); + } + return ret; + } + + private IntegerRelationMapImpl createRelationSet( + Collection collection) { + IntegerRelationMapImpl ret = new IntegerRelationMapImpl(); + for (Integer index : collection) { + ret.add(index); + } + return ret; + } + + private Map> createTransitiveSubsumed() { + Map> ret = new HashMap>(); + for (Integer r : getObjectPropertyGraph().getElements()) { + Set related = new HashSet(); + for (Integer s : getObjectPropertyGraph().getElements()) { + if (isReflexiveTransitiveSubsumed(r, s)) { + related.add(s); + } + } + ret.put(r, related); + } + return ret; + } + + /** + * Returns the class graph. + * + * @return the class graph. + */ + protected IntegerSubsumerGraph getClassGraph() { + return this.classGraph; + } + + @Override + public IntegerHierarchicalGraph getClassHierarchy() { + if (!isReady()) { + throw new UnclassifiedOntologyException(); + } + return this.classHierarchy; + } + + @Override + public IntegerHierarchicalGraph getDataPropertyHierarchy() + throws UnclassifiedOntologyException { + if (!isReady()) { + throw new UnclassifiedOntologyException(); + } + return this.dataPropertyHierarchy; + } + + /** + * Computes the descendants using only a hierarchical graph. + * + * @param hierarchicalGraph + * a hierarchical graph containing parents and children + * @param vertex + * starting vertex to compute the descendants + * @return the descendants according the graph + */ + private Set getDescendants( + IntegerHierarchicalGraph hierarchicalGraph, Integer vertex) { + Set visited = new HashSet(); + Set queue = new HashSet(); + queue.add(vertex); + while (!queue.isEmpty()) { + Integer elem = queue.iterator().next(); + queue.remove(elem); + visited.add(elem); + Set children = new HashSet(); + children.addAll(hierarchicalGraph.getChildren(elem)); + children.removeAll(visited); + queue.addAll(children); + } + return visited; + } + + @Override + public Map> getDirectTypes() { + if (!isReady()) { + throw new UnclassifiedOntologyException(); + } + return Collections.unmodifiableMap(this.directTypes); + } + + /** + * Returns the id generator. + * + * @return the id generator. + */ + protected IntegerEntityManager getEntityManager() { + return this.entityManager; + } + + protected CelExtendedOntology getExtendedOntology() { + return this.extendedOntology; + } + + protected IntegerSubsumerGraph getObjectPropertyGraph() { + return this.objectPropertyGraph; + } + + @Override + public IntegerHierarchicalGraph getObjectPropertyHierarchy() { + if (!isReady()) { + throw new UnclassifiedOntologyException(); + } + return this.objectPropertyHierarchy; + } + + public NormalizedIntegerAxiomFactory getOntologyObjectFactory() { + return this.axiomFactory; + } + + private Set getPropertyUsedByClass(Integer cA) { + return this.propertyUsedByClass.get(cA); + } + + /** + * Returns the binary relation for a given id, or and empty relation if the + * id is unknown. + * + * @param relationId + * relation id + * @return the binary relation for the given id, or an empty relation if no + * relation is already defined + */ + protected IntegerBinaryRelation getRelation(Integer relationId) { + if (relationId == null) { + throw new IllegalArgumentException("Null argument."); + } + + return this.relationSet.get(relationId); + } + + /** + * Returns a set containing all relation ids. + * + * @return the set of all relation ids + */ + protected Set getRelationIdSet() { + return Collections.unmodifiableSet(this.relationSet.getElements()); + } + + @Override + public Map> getSameIndividualMap() { + if (!isReady()) { + throw new UnclassifiedOntologyException(); + } + return Collections.unmodifiableMap(this.sameIndividualMap); + } + + /** + * This is a graph reachability algorithm that tests whether an element d is + * reachable from an element c using a path where each segment is from any + * of the properties in R. + * + * @param c + * first element in the path + * @param d + * last element in the path + * @return true if it is possible to reach d from c using any + * possible segment, false otherwise + */ + private boolean isConnectedTo(Integer c, Integer d) { + Set visited = new HashSet(); + Set toVisit = new HashSet(); + toVisit.add(c); + while (!toVisit.isEmpty()) { + Integer elem = toVisit.iterator().next(); + toVisit.remove(elem); + visited.add(elem); + Set newToVisit = new HashSet(); + for (Integer r : getPropertyUsedByClass(elem)) { + IntegerBinaryRelation relation = this.relationSet.get(r); + newToVisit.addAll(relation.getByFirst(elem)); + } + newToVisit.removeAll(visited); + toVisit.addAll(newToVisit); + } + return visited.contains(d); + } + + @Override + public boolean isReady() { + return this.isReady; + } + + private boolean isReflexiveTransitiveSubsumed(Integer leftPropertyName, + Integer rightPropertyName) { + return (this.objectPropertyGraph != null) + && this.objectPropertyGraph.containsPair(leftPropertyName, + rightPropertyName); + } + + private void makeTransitiveClosure(IntegerSubsumerGraphImpl graph) { + boolean hasChanged = true; + while (hasChanged) { + hasChanged = false; + for (Integer elem : graph.getElements()) { + Collection subsumerSet = graph.getSubsumers(elem); + Set allSubsumers = new HashSet(); + allSubsumers.add(elem); + for (Integer otherElem : subsumerSet) { + allSubsumers.addAll(graph.getSubsumers(otherElem)); + } + allSubsumers.removeAll(subsumerSet); + if (!allSubsumers.isEmpty()) { + hasChanged = true; + for (Integer subsumer : allSubsumers) { + graph.addAncestor(elem, subsumer); + } + } + } + } + } + + /** + * Post processes the data after the classification phase. + */ + protected void postProcess() { + removeAuxiliaryObjectProperties(); + this.objectPropertyHierarchy = new IntegerHierarchicalGraphImpl( + this.objectPropertyGraph); + this.objectPropertyGraph = null; + + removeAuxiliaryClassesExceptNominals(); + IntegerHierarchicalGraph hierarchicalGraph = new IntegerHierarchicalGraphImpl( + this.classGraph); + processNominals(hierarchicalGraph); + this.directTypes = computeDirectTypes(hierarchicalGraph); + this.sameIndividualMap = computeSameIndividualMap(hierarchicalGraph); + + removeAuxiliaryNominals(); + this.classHierarchy = new IntegerHierarchicalGraphImpl(this.classGraph); + this.classGraph = null; + } + + private void prepareQueue(CelExtendedOntology ontology) { + Set classNameSet = new HashSet(); + classNameSet.addAll(ontology.getClassSet()); + for (Integer className : classNameSet) { + addToQueue(className, ontology.getClassEntries(className)); + addToQueue(className, ontology.getClassEntries(topClassId)); + } + } + + /** + * The configuration follows the following steps: + *
    + *
  • normalizes the ontology creating auxiliary entities
  • + *
  • creates an extended ontonlogy based on the normalized ontology
  • + *
  • adds the classes
  • + *
  • creates the property hierarchy
  • + *
  • prepares all the queues to run the algorithm
  • + *
+ * + * @param originalObjectProperties + * set of object properties + * @param originalClasses + * set of classes + * @param normalizedAxiomSet + * set of axioms, i.e. the ontology + * + */ + protected void preProcess(Set originalObjectProperties, + Set originalClasses, + Set normalizedAxiomSet) { + if (originalObjectProperties == null) { + throw new IllegalArgumentException("Null argument."); + } + if (originalClasses == null) { + throw new IllegalArgumentException("Null argument."); + } + if (normalizedAxiomSet == null) { + throw new IllegalArgumentException("Null argument."); + } + + this.isReady = false; + + logger.fine("using " + getClass().getSimpleName() + " ..."); + + logger.fine("configuring processor ..."); + + this.dataPropertyHierarchy = new IntegerHierarchicalGraphImpl( + new IntegerSubsumerGraphImpl( + IntegerEntityManager.bottomDataPropertyId, + IntegerEntityManager.topDataPropertyId)); + + // These sets include the declared entities that are not present in the + // normalized axioms. + Set originalClassSet = new HashSet(); + originalClassSet.addAll(originalClasses); + originalClassSet.add(bottomClassId); + originalClassSet.add(topClassId); + + Set originalObjectPropertySet = new HashSet(); + originalObjectPropertySet.addAll(originalObjectProperties); + originalObjectPropertySet.add(bottomObjectPropertyId); + originalObjectPropertySet.add(topObjectPropertyId); + + logger.finer("normalizing ontology ..."); + Set ontology = new HashSet(); + ontology.addAll(normalizedAxiomSet); + + logger.finer("auxiliary classes created (including nominals) : " + + getEntityManager().getEntities(IntegerEntityType.CLASS, true) + .size()); + logger.finer("auxiliary classes created for nominals : " + + (getEntityManager().getIndividuals().size())); + logger.finer("auxiliary object properties created : " + + getEntityManager().getEntities( + IntegerEntityType.OBJECT_PROPERTY, true).size()); + + logger.finer("creating extended ontology ..."); + this.extendedOntology = new CelExtendedOntology(); + this.extendedOntology.load(ontology); + + logger.finer("creating class graph ..."); + this.classGraph = createClassGraph(originalClassSet, ontology); + + logger.finer("creating property graph ..."); + this.objectPropertyGraph = createObjectPropertyGraph( + originalObjectPropertySet, ontology); + + this.relationSet = createRelationSet(this.objectPropertyGraph + .getElements()); + + this.propertyUsedByClass = createPropertyUseMap(); + + this.transitiveSubsumed = createTransitiveSubsumed(); + + logger.finer("preparing queue ..."); + this.queueKeys.clear(); + this.queueEntries.clear(); + prepareQueue(this.extendedOntology); + + logger.fine("processor configured."); + } + + @Override + public boolean process() { + if (!this.isReady) { + if (!this.queueKeys.isEmpty()) { + process(this.queueKeys.pop(), this.queueEntries.pop()); + } else if (!this.isReady) { + postProcess(); + this.isReady = true; + } + } + return !this.isReady; + } + + private void process(Integer cA, ExtensionEntry eX) { + if (eX.isImplication()) { + processImplication(cA, eX.asImplication()); + } else if (eX.isExistential()) { + processExistential(cA, eX.asExistential()); + } else { + throw new RuntimeException( + "Internal error: entry was not recognized " + eX); + } + } + + private void processBottom(Integer className) { + this.classGraph.addAncestor(className, bottomClassId); + + for (Integer relation : this.relationSet.getElements()) { + for (Integer firstComponent : this.relationSet.getBySecond( + relation, className)) { + if (!this.classGraph + .containsPair(firstComponent, bottomClassId)) { + processBottom(firstComponent); + } + } + } + } + + private void processExistential(Integer cA, ExistentialEntry eX) { + Integer r = eX.getPropertyId(); + Integer cB = eX.getClassId(); + Integer bottom = bottomClassId; + + if (!this.relationSet.contains(r, cA, cB)) { + + if (this.classGraph.containsPair(cB, bottom) + && !this.classGraph.containsPair(cA, bottom)) { + + processBottom(cA); + + } + + processNewEdge(cA, r, cB); + } + } + + private void processImplication(Integer cA, ImplicationEntry eX) { + Set vecB = eX.getOperands(); + Integer cB = eX.getSuperClass(); + Collection sSofA = this.classGraph.getSubsumers(cA); + Integer bottom = bottomClassId; + + if (sSofA.containsAll(vecB) && !sSofA.contains(cB)) { + + if (cB.equals(bottom)) { + + processBottom(cA); + + } else { + + this.classGraph.addAncestor(cA, cB); + + addToQueue(cA, getExtendedOntology().getClassEntries(cB)); + + Set propertySet = getPropertyUsedByClass(cA); + + for (Integer r : propertySet) { + + Set existentialEntries = getExtendedOntology() + .getExistentialEntries(r, cB); + + Collection classSet = this.relationSet + .getBySecond(r, cA); + + for (Integer cAprime : classSet) { + + addToQueue(cAprime, existentialEntries); + } + } + } + } + } + + private void processNewEdge(Integer cA, Integer r, Integer cB) { + for (Integer s : this.transitiveSubsumed.get(r)) { + + this.relationSet.add(s, cA, cB); + getPropertyUsedByClass(cB).add(s); + + for (Integer cBprime : this.classGraph.getSubsumers(cB)) { + addToQueue(cA, + getExtendedOntology().getExistentialEntries(s, cBprime)); + } + + for (RI3Axiom axiom : getExtendedOntology() + .getSubPropertyAxiomSetByRight(s)) { + + Integer t = axiom.getLeftSubProperty(); + Integer u = axiom.getSuperProperty(); + + Collection classSet = this.relationSet.getBySecond(t, + cA); + + for (Integer cAprime : classSet) { + + if (!this.relationSet.contains(u, cAprime, cB)) { + processNewEdge(cAprime, u, cB); + } + } + } + + for (RI3Axiom axiom : getExtendedOntology() + .getSubPropertyAxiomSetByLeft(s)) { + + Integer t = axiom.getRightSubProperty(); + Integer u = axiom.getSuperProperty(); + + Collection classSet = this.relationSet.getByFirst(t, + cB); + + for (Integer cBprime : classSet) { + + if (!this.relationSet.contains(u, cA, cBprime)) { + processNewEdge(cA, u, cBprime); + } + } + } + } + } + + /** + * Processes the nominals after the execution of the classification + * algorithm. It requires a hierarchical graph to get the descendants. + * + * @param hierarchicalGraph + * the hierarchical graph + */ + private void processNominals(IntegerHierarchicalGraph hierarchicalGraph) { + Set nominals = getEntityManager().getAuxiliaryNominals(); + for (Integer indiv : nominals) { + Set descendants = getDescendants(hierarchicalGraph, indiv); + for (Integer c : descendants) { + for (Integer d : descendants) { + Collection sC = getClassGraph().getSubsumers(c); + Collection sD = getClassGraph().getSubsumers(d); + if (!(sD.containsAll(sC))) { + if (isConnectedTo(c, d)) { + for (Integer elem : sD) { + this.classGraph.addAncestor(c, elem); + } + } + for (Integer nominal : nominals) { + if (isConnectedTo(nominal, d)) { + for (Integer elem : sD) { + this.classGraph.addAncestor(c, elem); + } + } + } + } + } + } + } + } + + private void removeAuxiliaryClassesExceptNominals() { + Set reqClasses = new HashSet(); + for (Integer elem : getClassGraph().getElements()) { + if (!getEntityManager().isAuxiliary(elem)) { + reqClasses.add(elem); + } + } + reqClasses.addAll(getEntityManager().getAuxiliaryNominals()); + this.classGraph.retainAll(reqClasses); + } + + private void removeAuxiliaryNominals() { + Set reqClasses = new HashSet(); + reqClasses.addAll(getClassGraph().getElements()); + reqClasses.removeAll(getEntityManager().getAuxiliaryNominals()); + this.classGraph.retainAll(reqClasses); + } + + private void removeAuxiliaryObjectProperties() { + Set reqObjectProperties = new HashSet(); + for (Integer elem : getObjectPropertyGraph().getElements()) { + if (!getEntityManager().isAuxiliary(elem)) { + reqObjectProperties.add(elem); + } + } + this.objectPropertyGraph.retainAll(reqObjectProperties); + } + +}