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));
 }