code: private static void processCellCartesianProduct(final CnfGrammar grammar, final Chart inChart,
              final Chart outChart, final int start, final int end, final ChartCell outCell, final Scorer scorer) {
          // Apply binary rules.
          for (int mid = start + 1; mid <= end - 1; mid++) {
              ChartCell leftInCell = inChart.getCell(start, mid);
              ChartCell rightInCell = inChart.getCell(mid, end);
              ChartCell leftOutCell = outChart.getCell(start, mid);
              ChartCell rightOutCell = outChart.getCell(mid, end);
              
              // Loop through all possible pairs of left/right non-terminals.
              for (final int leftChildNt : leftInCell.getNts()) {
                  double leftScoreForNt = leftInCell.getScore(leftChildNt);
                  for (final int rightChildNt : rightInCell.getNts()) {
                      double rightScoreForNt = rightInCell.getScore(rightChildNt);
                      // Lookup the rules with those left/right children.
                      for (final Rule r : grammar.getBinaryRulesWithChildren(leftChildNt, rightChildNt)) {
                          double cellScoreForNt = outCell.getScore(r.getParent());
                          double score = scorer.score(r, start, mid, end);
                          // Update left cell.
                          double addendLeft = score
                                  + cellScoreForNt + rightScoreForNt;
                          leftOutCell.updateCell(leftChildNt, addendLeft, mid, r);
                          // Update right cell.
                          double addendRight = score
                                  + leftScoreForNt + cellScoreForNt;
                          rightOutCell.updateCell(rightChildNt, addendRight, mid, r);
                      }
                  }
              }
          }
      }
docs: Process a cell (binary rules only) using the Cartesian product of the children's rules.
  
  This follows the description in (Dunlop et al., 2010).