public static void modularInduceInferenceRules(Symbol relationName, Symbol className, List modules) {
    Logic.clearTrainingExamples();
    Logic.clearCases();
    { Surrogate renamed_Class = Logic.getDescription(className).surrogateValueInverse;
      Surrogate relation = Logic.getDescription(relationName).surrogateValueInverse;
      List ilist = List.newList();
      Module home = ((Module)(Stella.$MODULE$.get()));
      boolean failUnbound = Logic.$FAIL_UNBOUND_CLAUSESp$;
      int num = ilist.length();
      Vector instanceVec = Vector.newVector(modules.length());
      Vector instances = null;

      Logic.$FAIL_UNBOUND_CLAUSESp$ = true;
      if (!Logic.$ALLOW_RECURSIVE_DECISION_NODES$) {
        Logic.$TABOO_OPERATORS$.insertNew(relation);
      }
      if (Logic.$RULE_INDUCTION_STRATEGY$ == Logic.KWD_TOP_DOWN) {
        System.out.println("Building Classification Rule");
        Logic.$ENABLE_USER_THING$ = true;
        { Module module = null;
          Cons iter000 = modules.theConsList;
          int j = Stella.NULL_INTEGER;
          int iter001 = 0;

          for (;!(iter000 == Stella.NIL); iter000 = iter000.rest, iter001 = iter001 + 1) {
            module = ((Module)(iter000.value));
            j = iter001;
            module.changeModule();
            ilist = Logic.allClassInstances(renamed_Class).listify();
            num = ilist.length();
            instances = Vector.newVector(num);
            { Stella_Object instance = null;
              Cons iter002 = ilist.theConsList;
              int i = Stella.NULL_INTEGER;
              int iter003 = 0;

              for (;!(iter002 == Stella.NIL); iter002 = iter002.rest, iter003 = iter003 + 1) {
                instance = iter002.value;
                i = iter003;
                (instances.theArray)[i] = (((LogicObject)(instance)));
              }
            }
            (instanceVec.theArray)[j] = instances;
            Logic.generateClassificationRule(instances, relationName, className, false);
          }
        }
        home.changeModule();
        Logic.buildClassificationRule(relationName, className);
        { List clauses = ((List)(Logic.$CASE_ANTECEDENT_TABLE$.lookup(className.symbolName + "-match")));

          Logic.$CANDIDATE_CLAUSES$ = Vector.newVector(clauses.length());
          { Cons clause = null;
            Cons iter004 = clauses.theConsList;
            int i = Stella.NULL_INTEGER;
            int iter005 = 0;

            for (;!(iter004 == Stella.NIL); iter004 = iter004.rest, iter005 = iter005 + 1) {
              clause = ((Cons)(iter004.value));
              i = iter005;
              (Logic.$CANDIDATE_CLAUSES$.theArray)[i] = clause;
            }
          }
        }
        System.out.println("Generating Training Examples");
        { Module module = null;
          Cons iter006 = modules.theConsList;
          Vector vec = null;
          Vector vector000 = instanceVec;
          int index000 = 0;
          int length000 = vector000.length();

          for (;(!(iter006 == Stella.NIL)) &&
                    (index000 < length000); iter006 = iter006.rest, index000 = index000 + 1) {
            module = ((Module)(iter006.value));
            vec = ((Vector)((vector000.theArray)[index000]));
            module.changeModule();
            Logic.generateClassificationTrainingExamples(vec, relation, true);
          }
        }
        System.out.println("Generating Inference Rules");
        Logic.topDownRuleInduction(Logic.$TRAINING_EXAMPLES$);
        Logic.$FAIL_UNBOUND_CLAUSESp$ = failUnbound;
      }
      else if (Logic.$RULE_INDUCTION_STRATEGY$ == Logic.KWD_BOTTOM_UP) {
        Logic.$ENABLE_USER_THING$ = false;
        { Module module = null;
          Cons iter007 = modules.theConsList;
          Vector vec = null;
          Vector vector001 = instanceVec;
          int index001 = 0;
          int length001 = vector001.length();

          for (;(!(iter007 == Stella.NIL)) &&
                    (index001 < length001); iter007 = iter007.rest, index001 = index001 + 1) {
            module = ((Module)(iter007.value));
            vec = ((Vector)((vector001.theArray)[index001]));
            vec = vec;
            module.changeModule();
            Logic.generateTrainingExamples(instances, relation);
          }
        }
        Logic.$OPTIMIZE_INDUCED_QUERIES$ = true;
        Logic.bottomUpRuleInduction(Logic.$TRAINING_EXAMPLES$, Logic.$SIMPLIFY_RULE_ANTECEDENTp$);
      }
      else {
        { OutputStringStream stream000 = OutputStringStream.newOutputStringStream();

          stream000.nativeStream.print("`" + Logic.$RULE_INDUCTION_STRATEGY$ + "' is not a valid case option");
          throw ((StellaException)(StellaException.newStellaException(stream000.theStringReader()).fillInStackTrace()));
        }
      }
    }
  }