}
public boolean expandExistentials(boolean finalChance) {
TableauMonitor monitor=m_tableau.getTableauMonitor();
m_blockingStrategy.computeBlocking(finalChance);
boolean extensionsChanged=false;
Node node=m_tableau.getFirstTableauNode();
while (node!=null && (!extensionsChanged || !m_expandNodeAtATime)) {
if (node.isActive() && !node.isBlocked() && node.hasUnprocessedExistentials()) {
// The node's set of unprocessed existentials may be changed during operation, so make a local copy to loop over.
m_processedExistentials.clear();
m_processedExistentials.addAll(node.getUnprocessedExistentials());
for (int index=m_processedExistentials.size()-1;index>=0;index--) {
ExistentialConcept existentialConcept=m_processedExistentials.get(index);
if (existentialConcept instanceof AtLeastConcept) {
AtLeastConcept atLeastConcept=(AtLeastConcept)existentialConcept;
switch (isSatisfied(atLeastConcept,node)) {
case NOT_SATISFIED:
expandExistential(atLeastConcept,node);
extensionsChanged=true;
break;
case PERMANENTLY_SATISFIED: // not satisfied by a nominal so that the NN/NI rule can break the existential
m_existentialExpansionManager.markExistentialProcessed(existentialConcept,node);
if (monitor!=null)
monitor.existentialSatisfied(atLeastConcept,node);
break;
case CURRENTLY_SATISFIED: // satisfied until the NN/NI rule is applied and after which the existential might no longer be satisfied
// do nothing
if (monitor!=null)
monitor.existentialSatisfied(atLeastConcept,node);
break;
}
}
else if (existentialConcept instanceof ExistsDescriptionGraph) {
ExistsDescriptionGraph existsDescriptionGraph=(ExistsDescriptionGraph)existentialConcept;
if (!m_descriptionGraphManager.isSatisfied(existsDescriptionGraph,node)) {
m_descriptionGraphManager.expand(existsDescriptionGraph,node);
extensionsChanged=true;
}
else {
if (monitor!=null)
monitor.existentialSatisfied(existsDescriptionGraph,node);
}
m_existentialExpansionManager.markExistentialProcessed(existentialConcept,node);
}
else
throw new IllegalStateException("Unsupported type of existential.");
m_interruptFlag.checkInterrupt();
}
}
node=node.getNextTableauNode();
m_interruptFlag.checkInterrupt();
}
return extensionsChanged;
}