public static void topDownRuleInduction(List examples) {
    { List positive = List.newList();
      List allPositives = List.newList();
      List negative = List.newList();
      List uncovered = null;
      List covered = List.newList();
      Cons antecedent = Stella.NIL;
      List linkedAntecedents = null;
      Symbol concept = ((TrainingExample)(examples.first())).concept;
      int numRules = 0;
      int loopCheck = 0;
      boolean signaturesP = Logic.$INDUCE_RULES_FROM_SIGNATURES$;
      Vector consProps = null;
      List props = List.newList();
      Vector propositionVector = null;

      Logic.$INDUCED_DECISION_RULES$ = List.newList();
      if (((TrainingExample)(Logic.$TRAINING_EXAMPLES$.first())).module != null) {
        ((TrainingExample)(Logic.$TRAINING_EXAMPLES$.first())).module.changeModule();
      }
      props = Logic.getClassificationRelations(((TrainingExample)(Logic.$TRAINING_EXAMPLES$.first())).query);
      consProps = Vector.newVector(props.length());
      propositionVector = Vector.newVector(props.length());
      { int i = Stella.NULL_INTEGER;
        int iter000 = 0;
        int upperBound000 = props.length() - 1;
        Proposition prop = null;
        Cons iter001 = props.theConsList;

        for (;(iter000 <= upperBound000) &&
                  (!(iter001 == Stella.NIL)); iter000 = iter000 + 1, iter001 = iter001.rest) {
          i = iter000;
          prop = ((Proposition)(iter001.value));
          (propositionVector.theArray)[i] = prop;
          (consProps.theArray)[i] = (Proposition.propositionToCons(prop));
        }
      }
      { TrainingExample example = null;
        Cons iter002 = examples.theConsList;

        for (;!(iter002 == Stella.NIL); iter002 = iter002.rest) {
          example = ((TrainingExample)(iter002.value));
          if (BooleanWrapper.coerceWrappedBooleanToBoolean(((BooleanWrapper)(example.output)))) {
            {
              positive.push(example);
              allPositives.push(example);
            }
          }
          else {
            negative.push(example);
          }
        }
      }
      System.out.println("Starting rule induction with " + positive.length() + " positive and " + negative.length() + " negative examples");
      loop002 : while (!positive.emptyP()) {
        {
          System.out.println();
          System.out.println(positive.length() + " positive examples left to be covered");
        }
;
        covered = List.newList();
        linkedAntecedents = List.list(Cons.cons(Stella.NIL, Stella.NIL));
        if (Logic.$INDUCE_RULES_FROM_SIGNATURES$) {
          if (Logic.$SIGNATURE_STRATEGY$ == Logic.KWD_BOTTOM_UP) {
            antecedent = Logic.learnOneRuleBottomUpFromSignatures(positive, negative, covered, consProps);
            linkedAntecedents = Logic.linkVariablesInInducedRule(antecedent, covered, consProps);
          }
          else if (Logic.$SIGNATURE_STRATEGY$ == Logic.KWD_DECISION_TREE) {
            uncovered = List.newList();
            { TrainingExample example = null;
              Cons iter003 = positive.theConsList;

              for (;!(iter003 == Stella.NIL); iter003 = iter003.rest) {
                example = ((TrainingExample)(iter003.value));
                uncovered.push(example);
              }
            }
            { TrainingExample example = null;
              Cons iter004 = negative.theConsList;

              for (;!(iter004 == Stella.NIL); iter004 = iter004.rest) {
                example = ((TrainingExample)(iter004.value));
                uncovered.push(example);
              }
            }
            { Cons treeRule = null;
              Cons iter005 = Logic.getRulesFromTree(((TrainingExample)(uncovered.first())).query, Logic.induceDecisionTree(uncovered)).theConsList;
              Cons collect000 = null;

              for (;!(iter005 == Stella.NIL); iter005 = iter005.rest) {
                treeRule = ((Cons)(iter005.value));
                if (BooleanWrapper.coerceWrappedBooleanToBoolean(((BooleanWrapper)(treeRule.value)))) {
                  if (collect000 == null) {
                    {
                      collect000 = Cons.cons(treeRule.rest, Stella.NIL);
                      if (linkedAntecedents.theConsList == Stella.NIL) {
                        linkedAntecedents.theConsList = collect000;
                      }
                      else {
                        Cons.addConsToEndOfConsList(linkedAntecedents.theConsList, collect000);
                      }
                    }
                  }
                  else {
                    {
                      collect000.rest = Cons.cons(treeRule.rest, Stella.NIL);
                      collect000 = collect000.rest;
                    }
                  }
                }
              }
            }
            linkedAntecedents = ((List)(linkedAntecedents.remove(Stella.NIL)));
          }
          else if (Logic.$SIGNATURE_STRATEGY$ == Logic.KWD_TOP_DOWN) {
            antecedent = Logic.learnOneRuleTopDownFromSignatures(positive, negative, covered, consProps);
            linkedAntecedents = Logic.linkVariablesInInducedRule(antecedent, covered, consProps);
          }
          else {
            { OutputStringStream stream000 = OutputStringStream.newOutputStringStream();

              stream000.nativeStream.print("`" + Logic.$SIGNATURE_STRATEGY$ + "' is not a valid case option");
              throw ((StellaException)(StellaException.newStellaException(stream000.theStringReader()).fillInStackTrace()));
            }
          }
        }
        { Cons ant = null;
          Cons iter006 = linkedAntecedents.theConsList;

          for (;!(iter006 == Stella.NIL); iter006 = iter006.rest) {
            ant = ((Cons)(iter006.value));
            covered = Logic.getCoveredExamples(ant, negative);
            if ((covered.length() < 10) ||
                ((covered.length() < positive.length()) ||
                 (ant == Stella.NIL))) {
              if (covered.length() > 0) {
                ant = Logic.specializeRule(ant, Logic.$CANDIDATE_CLAUSES$, positive, covered);
                loopCheck = 0;
                loop007 : while ((!(ant == Stella.NIL)) &&
                    Logic.ruleCoversAnyExampleP(ant, negative)) {
                  loopCheck = loopCheck + 1;
                  if (loopCheck == 4) {
                    ant = Stella.NIL;
                    covered = negative;
                    break loop007;
                  }
                  ant = Logic.specializeRule(ant, Logic.$CANDIDATE_CLAUSES$, positive, covered);
                }
                if (!(ant == Stella.NIL)) {
                  covered = null;
                }
              }
              if ((covered == null) ||
                  covered.emptyP()) {
                covered = Logic.getCoveredExamples(ant, positive);
                { TrainingExample example = null;
                  Cons iter007 = covered.theConsList;

                  for (;!(iter007 == Stella.NIL); iter007 = iter007.rest) {
                    example = ((TrainingExample)(iter007.value));
                    positive = ((List)(positive.remove(example)));
                  }
                }
                if (covered.length() == 0) {
                  System.out.println("No Positives Covered by" + ant);
                }
                if (covered.length() > 0) {
                  Logic.$INDUCED_DECISION_RULES$.push(Cons.list$(Cons.cons(Logic.SYM_STELLA_eg, Cons.cons(Cons.cons(Logic.SYM_STELLA_AND, ((Cons)(Stella_Object.copyConsTree(ant))).reverse().concatenate(Stella.NIL, Stella.NIL)), Cons.cons(Cons.cons(concept, Cons.cons(Logic.SYM_LOGIC_pY, Stella.NIL)), Cons.cons(Stella.NIL, Stella.NIL))))));
                  System.out.println("Adding rule to cover " + covered.length() + " examples");
                }
              }
            }
          }
        }
        if (Logic.$INDUCED_DECISION_RULES$.length() == numRules) {
          {
            if (!Logic.$INDUCE_RULES_FROM_SIGNATURES$) {
              System.out.println("Stopping with " + positive.length() + " examples uncovered");
              break loop002;
            }
            System.out.println(positive.length() + " examples uncovered, switching to full query-based induction");
            Logic.$INDUCE_RULES_FROM_SIGNATURES$ = false;
          }
        }
        else {
          Logic.$INDUCE_RULES_FROM_SIGNATURES$ = signaturesP;
        }
        numRules = Logic.$INDUCED_DECISION_RULES$.length();
      }
      Logic.$INDUCE_RULES_FROM_SIGNATURES$ = signaturesP;
      {
        System.out.println();
        System.out.println("PowerLoom has induced the following rules");
        System.out.println();
      }
;
      { Cons rule = null;
        Cons iter008 = Logic.$INDUCED_DECISION_RULES$.theConsList;

        for (;!(iter008 == Stella.NIL); iter008 = iter008.rest) {
          rule = ((Cons)(iter008.value));
          System.out.println(rule);
        }
      }
    }
  }