docs: public static DiscreteFactor buildUnrestrictedBinaryDistribution(DiscreteVariable syntaxType,
        Iterable<CcgBinaryRule> rules, boolean allowComposition) {
      List<HeadedSyntacticCategory> allCategories = syntaxType.getValuesWithCast(HeadedSyntacticCategory.class);
      Set<List<Object>> validOutcomes = Sets.newHashSet();
      Set<Combinator> combinators = Sets.newHashSet();
      // Compute function application rules.
      for (HeadedSyntacticCategory functionCat : allCategories) {
        for (HeadedSyntacticCategory argumentCat : allCategories) {
          appendApplicationRules(functionCat, argumentCat, syntaxType, validOutcomes, combinators);
        }
      }
  
      if (allowComposition) {
        // Compute function composition rules.
        for (HeadedSyntacticCategory functionCat : allCategories) {
          for (HeadedSyntacticCategory argumentCat : allCategories) {
            appendCompositionRules(functionCat, argumentCat, syntaxType, validOutcomes, combinators);
          }
        }
      }
  
      appendBinaryRules(rules, syntaxType, validOutcomes, combinators);
      return buildSyntaxDistribution(syntaxType, validOutcomes, combinators);
    }