public double validateBinarizedTree(Tree tree, int start) {
    if (tree.isLeaf()) {
      return 0.0;
    }
    float epsilon = 0.0001f;
    if (tree.isPreTerminal()) {
      int tag = Numberer.number("tags", tree.label().value());
      int word = Numberer.number("words", tree.children()[0].label().value());
      IntTaggedWord iTW = new IntTaggedWord(word, tag);
      float score = lex.score(iTW, start);
      float bound = iScore[start][start + 1][Numberer.number(stateSpace, tree.label().value())];
      if (score > bound + epsilon) {
        System.out.println("Invalid tagging:");
        System.out.println("  Tag: " + tree.label().value());
        System.out.println("  Word: " + tree.children()[0].label().value());
        System.out.println("  Score: " + score);
        System.out.println("  Bound: " + bound);
      }
      return score;
    }
    int parent = Numberer.number(stateSpace, tree.label().value());
    int firstChild = Numberer.number(stateSpace, tree.children()[0].label().value());
    if (tree.numChildren() == 1) {
      UnaryRule ur = new UnaryRule();
      ur.parent = parent;
      ur.child = firstChild;
      double score = SloppyMath.max(ug.scoreRule(ur), -10000.0) + validateBinarizedTree(tree.children()[0], start);
      double bound = iScore[start][start + tree.yield().size()][parent];
      if (score > bound + epsilon) {
        System.out.println("Invalid unary:");
        System.out.println("  Parent: " + tree.label().value());
        System.out.println("  Child: " + tree.children()[0].label().value());
        System.out.println("  Start: " + start);
        System.out.println("  End: " + (start + tree.yield().size()));
        System.out.println("  Score: " + score);
        System.out.println("  Bound: " + bound);
      }
      return score;
    }
    BinaryRule br = new BinaryRule();
    br.parent = parent;
    br.leftChild = firstChild;
    br.rightChild = Numberer.number(stateSpace, tree.children()[1].label().value());
    double score = SloppyMath.max(bg.scoreRule(br), -10000.0) + validateBinarizedTree(tree.children()[0], start) + validateBinarizedTree(tree.children()[1], start + tree.children()[0].yield().size());
    double bound = iScore[start][start + tree.yield().size()][parent];
    if (score > bound + epsilon) {
      System.out.println("Invalid binary:");
      System.out.println("  Parent: " + tree.label().value());
      System.out.println("  LChild: " + tree.children()[0].label().value());
      System.out.println("  RChild: " + tree.children()[1].label().value());
      System.out.println("  Start: " + start);
      System.out.println("  End: " + (start + tree.yield().size()));
      System.out.println("  Score: " + score);
      System.out.println("  Bound: " + bound);
    }
    return score;
  }