public static Triple<Set<DefaultRule>, Set<Clause>, List<Set<Constant>>> preprocessConstants(
     Collection<DefaultRule> rules,
     Collection<Clause> hardRules,
     List<Set<Constant>> interchangeable) {
   final Map<Term, Term> typedConstants = new HashMap<Term, Term>();
   List<Set<Constant>> retInterchangeable = new ArrayList<Set<Constant>>();
   for (Set<Constant> set : interchangeable) {
     String type = min(set).name();
     Set<Constant> newSet = new HashSet<Constant>();
     for (Constant c : set) {
       Constant typedConstant = Constant.construct(c.name(), type);
       typedConstants.put(c, typedConstant);
       newSet.add(typedConstant);
     }
     retInterchangeable.add(newSet);
   }
   Collection<DefaultRule> retDefaultRules =
       Sugar.funcall(
           rules,
           new Sugar.Fun<DefaultRule, DefaultRule>() {
             @Override
             public DefaultRule apply(DefaultRule defaultRule) {
               return DefaultTransformationUtils.substitute(defaultRule, typedConstants);
             }
           });
   Collection<Clause> retHardRules =
       Sugar.funcall(
           hardRules,
           new Sugar.Fun<Clause, Clause>() {
             @Override
             public Clause apply(Clause hardRule) {
               return LogicUtils.substitute(hardRule, typedConstants);
             }
           });
   return new Triple<Set<DefaultRule>, Set<Clause>, List<Set<Constant>>>(
       Sugar.setFromCollections(retDefaultRules),
       Sugar.setFromCollections(retHardRules),
       Sugar.listFromCollections(retInterchangeable));
 }
 public static List<Set<Constant>> partitionInterchangeableConstants(
     Collection<DefaultRule> rules, Collection<Clause> hardRules) {
   List<Set<Constant>> retVal = new ArrayList<Set<Constant>>();
   Collection<DefaultRule> dummyRules =
       Sugar.<Clause, DefaultRule>funcall(
           hardRules,
           new Sugar.Fun<Clause, DefaultRule>() {
             @Override
             public DefaultRule apply(Clause clause) {
               return new DefaultRule(new Clause(Sugar.<Literal>list()), clause);
             }
           });
   for (List<Set<Constant>> list :
       partitionExchangeable_impl(Sugar.union(rules, dummyRules)).values()) {
     retVal.addAll(list);
   }
   return retVal;
 }