code: public Pair<GallicWeight, GallicWeight> factorize(GallicWeight weight) {
      Preconditions.checkArgument(isNotZero(weight), "cannot factorize a zero weight");
      IntArrayList labels = weight.getLabels();
      if (labels.isEmpty()) {
        return Pair.of(GallicWeight.createEmptyLabels(weight.getWeight()), one());
      }
      if (labels.size() == 1) {
        return Pair.of(GallicWeight.createSingleLabel(labels.get(0), weight.getWeight()), one());
      }
      IntArrayList prefix = new IntArrayList(1);
      IntArrayList suffix = new IntArrayList(labels.size() - 1);
      prefix.add(labels.get(0));
      for (int i = 1; i < labels.size(); i++) {
        suffix.add(labels.get(i));
      }
      return Pair.of(GallicWeight.create(prefix, weight.getWeight()), GallicWeight.create(suffix, weightSemiring.one()));
    }
docs: Factorize a gallic weight into the (head x weight, rest x One); the contract of factorize is that:
  val (factor1, factor2) = factorize(weight) implies weight = times(factor1, factor2)
  (see openfst's GallicFactor)
  @param weight gallic weight to factorize
  @return