public static Map<KLabel, KLabel> collectionFor(Module m) {
   return stream(m.productions())
       .filter(p -> p.att().contains(Attribute.ASSOCIATIVE_KEY))
       .flatMap(
           p -> {
             Set<Tuple2<KLabel, KLabel>> set = new HashSet<>();
             set.add(Tuple2.apply(p.klabel().get(), p.klabel().get()));
             if (p.att().contains(Attribute.UNIT_KEY)) {
               set.add(
                   Tuple2.apply(
                       KLabel(p.att().<String>get(Attribute.UNIT_KEY).get()), p.klabel().get()));
             }
             if (p.att().contains("element")) {
               set.add(
                   Tuple2.apply(KLabel(p.att().<String>get("element").get()), p.klabel().get()));
             }
             if (p.att().contains("wrapElement")) {
               set.add(
                   Tuple2.apply(
                       KLabel(p.att().<String>get("wrapElement").get()), p.klabel().get()));
             }
             return set.stream();
           })
       .distinct()
       .collect(Collectors.toMap(Tuple2::_1, Tuple2::_2));
 }
 /**
  * For the cell bag sorts with multiplicity *, add the single-element wrapper around individual
  * cells.
  */
 private K infer(K term, KLabel collectionLabel) {
   Optional<String> wrapElement =
       m.attributesFor().apply(collectionLabel).<String>getOptional("wrapElement");
   if (wrapElement.isPresent()) {
     KLabel wrappedLabel = KLabel(wrapElement.get());
     return new TransformK() {
       @Override
       public K apply(KApply k) {
         if (k.klabel().equals(wrappedLabel)) {
           KLabel elementLabel =
               KLabel(m.attributesFor().apply(collectionLabel).<String>get("element").get());
           return KApply(elementLabel, super.apply(k));
         }
         return super.apply(k);
       }
     }.apply(term);
   } else {
     return term;
   }
 }
 public Module gen(Module mod) {
   Set<Sentence> res = new HashSet<>();
   for (Sort sort : iterable(mod.definedSorts())) {
     Production prod =
         Production(
             "is" + sort.name(),
             Sorts.Bool(),
             Seq(
                 Terminal("is" + sort.name()),
                 Terminal("("),
                 NonTerminal(Sorts.K()),
                 Terminal(")")),
             Att().add(Attribute.FUNCTION_KEY).add(Attribute.PREDICATE_KEY, sort.name()));
     if (!mod.productions().contains(prod)) res.add(prod);
   }
   return Module(
       mod.name(),
       mod.imports(),
       (scala.collection.immutable.Set<Sentence>) mod.localSentences().$bar(immutable(res)),
       mod.att());
 }