private boolean checkRedundancy(
     Automaton safeAutomaton,
     ConstraintsBag safeBag,
     Automaton candidateAutomaton,
     Constraint candidateCon) {
   redundancyChecksPerformed++;
   logger.trace("Checking redundancy of " + candidateCon);
   // If candidateCon is not redundant, i.e., if the language of safeAutomaton is not a subset of
   // the language of automaton, then candidateCon can be included
   if (!safeAutomaton.subsetOf(candidateAutomaton)) {
     return true;
   } else {
     logger.warn(
         candidateCon
             + " is redundant. It is already implied"
             + (safeBag.howManyConstraints()
                     < ConflictAndRedundancyResolver
                         .MAXIMUM_VISIBLE_CONSTRAINTS_FOR_REDUNDANCY_CHECK
                 ? " by " + LinearConstraintsIndexFactory.getAllConstraints(safeBag)
                 : " by the current set of constraints."));
     this.redundantConstraints.add(candidateCon);
     return false;
   }
 }
  public void init() {
    this.checking = false;
    this.conflictChecksPerformed = 0;
    this.redundancyChecksPerformed = 0;
    this.conflictingConstraints = new TreeSet<Constraint>();
    this.redundantConstraints = new TreeSet<Constraint>();
    this.redundantConstraintsAtSecondPass = new TreeSet<Constraint>();

    // Pre-processing: remove subsumption-redundant constraints, by all means
    this.originalBag = (ConstraintsBag) this.originalProcess.bag.clone();
    this.subMarker.setConstraintsBag(originalBag);
    this.subMarker.markSubsumptionRedundantConstraints();
    this.originalBag.removeMarkedConstraints();
    this.originalHierarchyUnredundantConstraints = this.originalBag.getAllConstraints();
    /*
     * The blackboard is meant to associate to all constraints a tick,
     * whenever the constraint has already been checked
     */
    this.sorter.setConstraints(originalHierarchyUnredundantConstraints);
    this.blackboard = new TreeSet<Constraint>(this.sorter.getComparator());
    ConstraintsBag safeBag = this.originalBag.getOnlyFullySupportedConstraintsInNewBag();
    //		safeBag.markSubsumptionRedundantConstraints();
    //		safeBag.removeMarkedConstraints();
    Collection<Constraint> safeConstraints = safeBag.getAllConstraints();
    this.sorter.setConstraints(safeConstraints);

    /*
     * Step 1: Consider as safe those constraints that have a support
     * of 100%: if they have a support of 100%, a model already exists for
     * them: the log itself. So, their conjunction cannot be unsatisfiable.
     */
    if (avoidingRedundancy) {
      logger.info("Checking redundancies of fully-supported constraints...");

      ConstraintsBag emptyBag = this.originalBag.createEmptyIndexedCopy();
      this.safeProcess = new ProcessModel(this.originalProcess.getTaskCharArchive(), emptyBag);
      Automaton candidateAutomaton = null;
      this.safeAutomaton = this.safeProcess.buildAlphabetAcceptingAutomaton();
      for (Constraint candidateCon : this.sorter.sort(this.rankingPolicies)) {
        logger.trace("Checking redundancy of " + candidateCon);
        candidateAutomaton = new RegExp(candidateCon.getRegularExpression()).toAutomaton();
        if (!candidateCon
                .isRedundant() // If this constraint was not already found to be redundant in some
                               // way before
            && !this.isConstraintAlreadyChecked(
                candidateCon) // If this constraint was not already checked
            && this.checkRedundancy(
                this.safeAutomaton, this.safeProcess.bag, candidateAutomaton, candidateCon)
        // and the check of redundancy has a negative response (namely, it is not redundant)
        ) {
          this.safeAutomaton = this.intersect(this.safeAutomaton, candidateAutomaton);
          this.safeProcess.bag.add(candidateCon.getBase(), candidateCon);
        }
        blackboard.add(candidateCon);
      }
    } else {
      this.safeProcess = new ProcessModel(this.originalProcess.getTaskCharArchive(), safeBag);
      this.safeAutomaton = this.safeProcess.buildAutomaton();
      for (Constraint c : LinearConstraintsIndexFactory.getAllConstraints(safeBag)) {
        // System.out.println("PRESENTATION -- The safe constraint: " + c + " supp: " + c.support +
        // "; conf: " + c.confidence + "; inf.f: " + c.interestFactor + " rex: " +
        // c.getRegularExpression());
        // System.out.println("PRESENTATION -- The safe constraint automaton: " + c + " \n" +
        // safeProcess.buildAlphabetAcceptingAutomaton().intersection(new
        // RegExp(c.getRegularExpression()).toAutomaton()).toDot());
        blackboard.add(c);
      }
    }

    // System.out.println("PRESENTATION -- The safe automaton:\n" + safeAutomaton.toDot());
    ConstraintsBag unsafeBag =
        this.originalBag.createComplementOfCopyPrunedByThreshold(Constraint.MAX_SUPPORT);
    //		for (Constraint c : LinearConstraintsIndexFactory.getAllConstraints(unsafeBag)) {
    //			blackboard.add(c);
    //		}
    this.sorter.setConstraints(unsafeBag.getAllConstraints());
    this.notSurelySafeProcessConstraints = this.sorter.sort(this.rankingPolicies);
  }