synchronized (currentExplorationBoundary)
{
if (!sourceData.contains(sourcePair))
{
sourceData.add(sourcePair);
currentExplorationBoundary.add(new StatePair(srcB,srcA));
}
}
}
}
}
}// if intersects
else
if (incompatiblePairs[currentStatePair] != PAIR_INCOMPATIBLE) // it is not possible for this loop to set this -
// we are going through the vertices sequentially, but it could have been set by whoever called us.
incompatiblePairs[currentStatePair]=PAIR_OK;// potentially compatible pair
if (stateB.getKey().equals(entryA.getKey())) break; // we only process a triangular subset.
}// B-loop
}
});
performRowTasks(handlerList, ThreadNumber, matrixForward.transitionMatrix, filter,
GDLearnerGraph.partitionWorkLoadTriangular(ThreadNumber,matrixForward.transitionMatrix.size()));
//inputsAccepted=null;inputsRejected=null;
// At this point, we've marked all clearly incompatible pairs of states and need to propagate
// this information further, to states which have transitions leading to the currently considered set of states.
// This part is not run in parallel on multiple CPUs (we expect it to do little most of the time),
// hence no need to split the processing and/or lock currentExplorationBoundary
while(!currentExplorationBoundary.isEmpty())
{
StatePair pair = currentExplorationBoundary.remove();
int currentStatePair = vertexToIntNR(pair.firstElem,pair.secondElem);
incompatiblePairs[currentStatePair]=PAIR_INCOMPATIBLE;
Map<Label,List<CmpVertex>> rowB = matrixInverse.transitionMatrix.get(pair.secondElem);
for(Entry<Label,List<CmpVertex>> outLabel:matrixInverse.transitionMatrix.get(pair.firstElem).entrySet())
{
List<CmpVertex> to = rowB.get(outLabel.getKey());
if (to != null)
{// matched pair of transitions, now we need to build a cross-product
// of the states leading to the current pair of states, that is,
// to (entryA.getKey(),stateB)
for(CmpVertex srcA:outLabel.getValue())
for(CmpVertex srcB:to)
{
// It is possible that for the same inputs (srcA,srcB)=(A,B) and (B,A)
// in this case, we have to avoid including (B,A) in the list, but
// it is not known in advance if any such case occurs, so we have to store
// the pairs we encountered and eliminate them. Happily, this is handled by
// incompatiblePairs[sourcePair]=PAIR_INCOMPATIBLE
int sourcePair = vertexToIntNR(srcA, srcB);
if (incompatiblePairs[sourcePair] == PAIR_OK)
{
currentExplorationBoundary.offer(new StatePair(srcA,srcB)); // append to the list
incompatiblePairs[sourcePair]=PAIR_INCOMPATIBLE;
}
}
}
}