public boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException {
currentAction.getAction(actionContainers);
int trans = transActionContainer.getActionCode();
PlanarConfig planarConfig = (PlanarConfig)config;
DependencyNode stackPeek = planarConfig.getStack().peek();
DependencyNode inputPeek = planarConfig.getInput().peek();
DependencyStructure dg = planarConfig.getDependencyGraph();
//int rootHandling = planarConfig.getRootHandling();
boolean singleHeadConstraint = planarConfig.requiresSingleHead();
boolean noCoveredRootsConstraint = planarConfig.requiresNoCoveredRoots();
boolean acyclicityConstraint = planarConfig.requiresAcyclicity();
boolean connectednessConstraintOnReduce = planarConfig.requiresConnectednessCheckOnReduce();
boolean connectednessConstraintOnShift = planarConfig.requiresConnectednessCheckOnShift();
if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
return false;
}
//if ((trans == LEFTARC || trans == REDUCE) && stackPeek.isRoot()) {
// return false;
//}
if (trans == LEFTARC) {
//avoid making root child of something
if ( stackPeek.isRoot() )
return false;
//enforce single-head constraint if present
if ( stackPeek.hasHead() && singleHeadConstraint )
return false;
//avoid two links being created from and to the same node
if ( stackPeek.hasHead() && dg.getTokenNode(stackPeek.getIndex()).getHead().getIndex() == inputPeek.getIndex() )
return false;
//enforce acyclicity constraint if present
if ( acyclicityConstraint && stackPeek.findComponent().getIndex() == inputPeek.findComponent().getIndex() )
return false;
}
if (trans == RIGHTARC) {
//enforce single-head constraint if present
if ( inputPeek.hasHead() && singleHeadConstraint )
return false;
//avoid two links being created from and to the same node
if ( inputPeek.hasHead() && dg.getTokenNode(inputPeek.getIndex()).getHead().getIndex() == stackPeek.getIndex() )
return false;
//enforce acyclicity constraint if present
if ( acyclicityConstraint && stackPeek.findComponent().getIndex() == inputPeek.findComponent().getIndex() )
return false;
}
if (trans == REDUCE) {
//do not reduce the dummy root
if ( stackPeek.isRoot() )
return false;
//enforce no-covered-roots constraint if present
if ( !stackPeek.hasHead() && noCoveredRootsConstraint )
return false;
//TODO does this line still make sense? (from Nivre arc-eager)
//if ( !stackPeek.hasHead() && rootHandling == PlanarConfig.STRICT )
// return false;
//enforce connectedness constraint if present
if ( connectednessConstraintOnReduce )
{
boolean path1 = ( stackPeek.findComponent().getIndex() == inputPeek.findComponent().getIndex() );
boolean path2;
if ( planarConfig.getStack().size() < 2 ) path2=false;
else
{
DependencyNode stackPrev = planarConfig.getStack().get(planarConfig.getStack().size()-2);
path2 = stackPrev.findComponent().getIndex() == stackPeek.findComponent().getIndex();
}
return path1 || path2;
}
}
if ( trans == SHIFT )