MutableInteger nodeId, int pos, double cost,
Map<DFSAState,DFSAState> stateLinks, DFSA answerLattice, CoreLabel[] docArray) {
// Add "1" prediction after the end of the sentence, if applicable:
if(tSource.isAccepting() && tSource.continuingInputs().size() == 0) {
tSource.addTransition
(new DFSATransition("", tSource, new DFSAState(-1, null), "1", "", 0));
}
// Get current label, character, and prediction:
CoreLabel curLabel = (pos < docArray.length) ? docArray[pos] : null;
String curChr = null, origSpace = null;
if(curLabel != null) {
curChr = curLabel.get(OriginalCharAnnotation.class);
assert(curChr.length() == 1);
origSpace = curLabel.get(SpaceBeforeAnnotation.class);
}
// Get set of successors in search graph:
Set inputs = tSource.continuingInputs();
// Only keep most probable transition out of initial state:
Object answerConstraint = null;
if(pos == 0) {
double minCost = Double.POSITIVE_INFINITY;
DFSATransition bestTransition = null;
for (Iterator iter = inputs.iterator(); iter.hasNext();) {
Object predictSpace = iter.next();
DFSATransition transition = tSource.transition(predictSpace);
double transitionCost = transition.score();
if(transitionCost < minCost) {
if(predictSpace != null) {
System.err.printf("mincost (%s): %e -> %e\n", predictSpace.toString(), minCost, transitionCost);
minCost = transitionCost;
answerConstraint = predictSpace;
}
}
}
}
// Follow along each transition:
for (Iterator iter = inputs.iterator(); iter.hasNext();) {
Object predictSpace = iter.next();
DFSATransition transition = tSource.transition(predictSpace);
DFSAState tDest = transition.target();
DFSAState newASource = aSource;
//System.err.printf("tsource=%s tdest=%s asource=%s pos=%d predictSpace=%s\n", tSource, tDest, newASource, pos, predictSpace);
StringBuilder newAnswer = new StringBuilder(answer.toString());
int answerLen = newAnswer.length();
String prevChr = (answerLen > 0) ? newAnswer.substring(answerLen-1) : null;
double newCost = cost;
// Ignore paths starting with zero:
if(answerConstraint != null && !answerConstraint.equals(predictSpace)) {
System.err.printf("Skipping transition %s at pos 0.\n",predictSpace.toString());
continue;
}
// Ignore paths not consistent with input segmentation:
if(flags.keepAllWhitespaces && "0".equals(predictSpace) && "1".equals(origSpace)) {
System.err.printf("Skipping non-boundary at pos %d, since space in the input.\n",pos);
continue;
}
// Ignore paths adding segment boundaries between two latin characters, or between two digits:
// (unless already present in original input)
if("1".equals(predictSpace) && "0".equals(origSpace) && prevChr != null && curChr != null) {
char p = prevChr.charAt(0), c = curChr.charAt(0);
if(isLetterASCII(p) && isLetterASCII(c)) {
System.err.printf("Not hypothesizing a boundary at pos %d, since between two ASCII letters (%s and %s).\n",
pos,prevChr,curChr);
continue;
}
if(ChineseUtils.isNumber(p) && ChineseUtils.isNumber(c)) {
System.err.printf("Not hypothesizing a boundary at pos %d, since between two numeral characters (%s and %s).\n",
pos,prevChr,curChr);
continue;
}
}
// If predictSpace==1, create a new transition in answer search graph:
if("1".equals(predictSpace)) {
if(newAnswer.toString().length() > 0) {
// If answer destination node visited before, create a new edge and leave:
if(stateLinks.containsKey(tSource)) {
DFSAState aDest = stateLinks.get(tSource);
newASource.addTransition
(new DFSATransition("", newASource, aDest, newAnswer.toString(), "", newCost));
//System.err.printf("new transition: asource=%s adest=%s edge=%s\n", newASource, aDest, newAnswer.toString());
continue;
}
// If answer destination node not visited before, create it + new edge:
nodeId.incValue(1);
DFSAState aDest = new DFSAState(nodeId.intValue(), answerLattice, 0.0);
stateLinks.put(tSource,aDest);
newASource.addTransition(new DFSATransition("", newASource, aDest, newAnswer.toString(), "", newCost));
//System.err.printf("new edge: adest=%s\n", newASource, aDest, newAnswer.toString());
//System.err.printf("new transition: asource=%s adest=%s edge=%s\n\n\n", newASource, aDest, newAnswer.toString());
// Reached an accepting state:
if(tSource.isAccepting()) {
aDest.setAccepting(true);
continue;
}
// Start new answer edge:
newASource = aDest;
newAnswer = new StringBuilder();