public static Tree buildTree(Rule rule,List<HGNode> tailNodes,int maxDepth){
  Tree tree=getFragmentFromYield(rule.getEnglishWords());
  if (tree == null) {
    tree=new Tree(String.format("(%s %s)",Vocabulary.word(rule.getLHS()),rule.getEnglishWords()));
  }
 else {
    tree=tree.shallowClone();
  }
  if (tree != null && tailNodes != null && tailNodes.size() > 0 && maxDepth > 0) {
    List<Tree> frontier=tree.getNonterminalYield();
    ArrayList<Integer> tailIndices=new ArrayList<>();
    int[] englishInts=rule.getEnglish();
    for (    int englishInt : englishInts)     if (englishInt < 0)     tailIndices.add(-1 * englishInt - 1);
    for (int i=0; i < tailNodes.size(); i++) {
      try {
        Tree frontierTree=frontier.get(tailIndices.get(i));
        frontierTree.setBoundary(true);
        HyperEdge edge=tailNodes.get(i).bestHyperedge;
        if (edge != null) {
          Tree childTree=buildTree(edge.getRule(),edge.getTailNodes(),maxDepth - 1);
          if (childTree != null)           frontierTree.children=childTree.children;
        }
 else {
          frontierTree.children=tree.children;
        }
      }
 catch (      IndexOutOfBoundsException e) {
        LOG.error("ERROR at index {}",i);
        LOG.error("RULE: {}  TREE: {}",rule.getEnglishWords(),tree);
        LOG.error("  FRONTIER:");
        for (        Tree kid : frontier) {
          LOG.error("    {}",kid);
        }
        throw new RuntimeException(String.format("ERROR at index %d",i),e);
      }
    }
  }
  return tree;
}

public static Tree buildTree ( Rule rule , List < HGNode > tailNodes , int maxDepth ) { Tree tree = getFragmentFromYield ( rule . getEnglishWords ( ) ) ; if ( tree == null ) { tree = new Tree ( String . format ( "(%s %s)" , Vocabulary . word ( rule . getLHS ( ) ) , rule . getEnglishWords ( ) ) ) ; } else { tree = tree . shallowClone ( ) ; } if ( tree != null && tailNodes != null && tailNodes . size ( ) > 0 && maxDepth > 0 ) { List < Tree > frontier = tree . getNonterminalYield ( ) ; ArrayList < Integer > tailIndices = new ArrayList < > ( ) ; int [ ] englishInts = rule . getEnglish ( ) ; for ( int englishInt : englishInts ) if ( englishInt < 0 ) tailIndices . add ( - 1 * englishInt - 1 ) ; for ( int i = 0 ; i < tailNodes . size ( ) ; i ++ ) { try { Tree frontierTree = frontier . get ( tailIndices . get ( i ) ) ; frontierTree . setBoundary ( true ) ; HyperEdge edge = tailNodes . get ( i ) . bestHyperedge ; if ( edge != null ) { Tree childTree = buildTree ( edge . getRule ( ) , edge . getTailNodes ( ) , maxDepth - 1 ) ; if ( childTree != null ) frontierTree . children = childTree . children ; } else { frontierTree . children = tree . children ; } } catch ( IndexOutOfBoundsException e ) { LOG . error ( "ERROR at index {}" , i ) ; LOG . error ( "RULE: {}  TREE: {}" , rule . getEnglishWords ( ) , tree ) ; LOG . error ( "  FRONTIER:" ) ; for ( Tree kid : frontier ) { LOG . error ( "    {}" , kid ) ; } throw new RuntimeException ( String . format ( "ERROR at index %d" , i ) , e ) ; } } } return tree ; }
takes a rule and its tail pointers and recursively constructs a tree ( up to maxdepth ) . this could be implemented by using the other buildtree ( ) function and using the 1 - best derivationstate .
