private void initializeChart(Lattice lr) {
    for (LatticeEdge edge : lr) {
      int start = edge.start;
      int end = edge.end;
      String word = edge.word;

      // Add pre-terminals, augmented with edge weights
      for (int state = 0; state < numStates; state++) {
        if (isTag[state]) {
          IntTaggedWord itw = new IntTaggedWord(wordNumberer.number(word), Numberer.translate(stateSpace, "tags", state));

          float newScore = lex.score(itw, start) + (float) edge.weight;
          if (newScore > iScore[start][end][state]) {
            iScore[start][end][state] = newScore;
            narrowRExtent[start][state] = Math.min(end, narrowRExtent[start][state]);
            narrowLExtent[end][state] = Math.max(start, narrowLExtent[end][state]);
            wideRExtent[start][state] = Math.max(end, wideRExtent[start][state]);
            wideLExtent[end][state] = Math.min(start, wideLExtent[end][state]);
          }
        }
      }

      // Give scores to all tags if the parse fails (more flexible tagging)
      if (floodTags && (!Test.noRecoveryTagging)) {
        for (int state = 0; state < numStates; state++) {
          float iS = iScore[start][end][state];
          if (isTag[state] && iS == Float.NEGATIVE_INFINITY) {
            iScore[start][end][state] = -1000.0f + (float) edge.weight;
            narrowRExtent[start][state] = end;
            narrowLExtent[end][state] = start;
            wideRExtent[start][state] = end;
            wideLExtent[end][state] = start;
          }
        }
      }

      // Add unary rules (possibly chains) that terminate in POS tags
      for (int state = 0; state < numStates; state++) {
        float iS = iScore[start][end][state];
        if (iS == Float.NEGATIVE_INFINITY) {
          continue;
        }
        UnaryRule[] unaries = ug.closedRulesByChild(state);
        for (UnaryRule ur : unaries) {
          int parentState = ur.parent;
          float pS = ur.score;
          float tot = iS + pS;
          if (tot > iScore[start][end][parentState]) {
            iScore[start][end][parentState] = tot;
            narrowRExtent[start][parentState] = Math.min(end, narrowRExtent[start][parentState]);
            narrowLExtent[end][parentState] = Math.max(start, narrowLExtent[end][parentState]);
            wideRExtent[start][parentState] = Math.max(end, wideRExtent[start][parentState]);
            wideLExtent[end][parentState] = Math.min(start, wideLExtent[end][parentState]);
//            narrowRExtent[start][parentState] = start + 1; //end
//            narrowLExtent[end][parentState] = end - 1; //start
//            wideRExtent[start][parentState] = start + 1; //end
//            wideLExtent[end][parentState] = end - 1; //start
          }
        }
      }
    }
  }