Queue<Boolean> currentRedFromPta = new LinkedList<Boolean>();// FIFO queue containing true if the red node comes from a branch of a PTA which has been previously already merged into the machine
currentExplorationBoundary.add(origPair);currentRedFromPta.add(false);
while(!currentExplorationBoundary.isEmpty())
{
StatePair currentPair = currentExplorationBoundary.remove();Boolean redFromPta = currentRedFromPta.remove();
boolean RedAndBlueToBeMerged = false;// this one is set to true if states in the current pair have to be merged.
// This will be so for all state pairs where a blue node can
// make moves which the red one cannot match. The term "merged" does not refer to whether
// two nodes are actually merged - they have to be anyway, however if there are sequences of
// nodes with identical moves, PTA nodes do not contribute to anything - we only need
// to consider those which branch. mergedVertices is only updated when we find a blue vertex which
// can accept input a red node cannot accept.
if (!AbstractLearnerGraph.checkCompatible(currentPair.getQ(),currentPair.getR(),coregraph.pairCompatibility))
return -1;// incompatible states
if (!redFromPta.booleanValue())
++score;
Map<Label,CmpVertex> targetBlue = coregraph.transitionMatrix.get(currentPair.getQ());
for(Entry<Label,CmpVertex> blueEntry:targetBlue.entrySet())
{
CmpVertex nextRedState = coregraph.transitionMatrix.get(currentPair.getR()).get(blueEntry.getKey());
if (nextRedState != null)
{// both states can make a transition - this would be the case of "non-determinism" for Merge&Determinize
boolean newRedFromPta = redFromPta;
// PTA does not have loops, but the original automaton has
// and one of those loops is not on the transition diagram, namely the one related to B=A
if (nextRedState == origPair.getQ())
{
nextRedState = origPair.getR(); // emulates the new loop
newRedFromPta = coregraph.config.getLearnerScoreMode() != Configuration.ScoreMode.COMPATIBILITY; // and since the original score computation algorithm cannot do this, we pretend to be unable to do this either
// The problem is that since we effectively merge the
// states at this point, a loop introduced by merging
// adjacent states may suck many PTA states into it,
// so that two transitions which would not normally be
// near each other will be merged. For this reason, it
// is possible that our score computation will deliver
// a higher value that the conventional matching
// (where in the considered situation we'll be
// matching PTA with itself and PTA may be sparse).
}
if (coregraph.config.getScoreCompatibilityScoreComputationBugEmulation())
redFromPta = newRedFromPta;
StatePair nextStatePair = new StatePair(blueEntry.getValue(),nextRedState);
currentExplorationBoundary.offer(nextStatePair);currentRedFromPta.offer(newRedFromPta);
}
else
{// the current red state cannot make a transition, perhaps PTA states associated with it can
nextRedState = findNextRed(mergedVertices,currentPair.getR(),blueEntry.getKey());
if (nextRedState != null)
{// both states can make a transition - this would be the case of "non-determinism" for Merge&Determinize
// The red state is the one originally from a previously-merged PTA branch, so here we are merging PTA with itself.
// Since we are merging PTA with itself and PTA does not have loops, we cannot reenter the original blue state. Moreover,
// since we called findNextRed, we are looking at transitions from the PTA states. For this reason, we cannot enter the
// blue state since PTA does not have loops.
assert nextRedState != origPair.getQ() : "inconsistent PTA";
StatePair nextStatePair = new StatePair(blueEntry.getValue(),nextRedState);
currentExplorationBoundary.offer(nextStatePair);currentRedFromPta.offer(coregraph.config.getLearnerScoreMode() != Configuration.ScoreMode.COMPATIBILITY);// from now on, no increments to the score
}
else
{
// If the blue can make a move, but the red one cannot, it means that the blue vertex has