public ProcessModel resolveConflictsOrRedundancies() { logger.info("Checking redundancies and conflicts of non-fully-supported constraints"); this.checking = true; Automaton candidateAutomaton = null; for (Constraint candidateCon : this.notSurelySafeProcessConstraints) { if (!isConstraintAlreadyChecked(candidateCon)) { logger.trace("Checking consistency of " + candidateCon); // System.out.println("PRESENTATION -- The unsafe constraint: " + candidateCon + " supp: " + // candidateCon.support + "; conf: " + candidateCon.confidence + "; inf.f: " + // candidateCon.interestFactor); // System.out.println("PRESENTATION -- The unsafe constraint automaton: " + candidateCon + " // \n" + safeProcess.buildAlphabetAcceptingAutomaton().intersection(new // RegExp(candidateCon.getRegularExpression()).toAutomaton()).toDot()); candidateAutomaton = new RegExp(candidateCon.getRegularExpression()).toAutomaton(); if (!this.avoidingRedundancy || this.checkRedundancy(candidateAutomaton, candidateCon)) resolveConflictsRecursively(candidateAutomaton, candidateCon); } } // safeProcess.bag = safeProcess.bag.markSubsumptionRedundantConstraints(); // safeProcess.bag.removeMarkedConstraints(); if (this.avoidingRedundancyWithDoubleCheck) { logger.info("Checking redundant constraints in a second pass..."); this.doubleCheckRedundancies(); } this.subMarker.setConstraintsBag(this.safeProcess.bag); this.subMarker.markSubsumptionRedundantConstraints(); this.checking = false; return this.safeProcess; }
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); }
public void resolveConflictsRecursively(Automaton candidateAutomaton, Constraint candidateCon) { if (isConstraintAlreadyChecked(candidateCon)) { logger.trace(candidateCon + " was already checked"); return; } else { conflictChecksPerformed++; blackboard.add(candidateCon); } logger.trace( "Checking conflict with " + candidateCon + ": Conjuncting the safe automaton with Reg.exp: " + candidateCon.getRegularExpression()); Automaton auxAutomaton = this.intersect(this.safeAutomaton, candidateAutomaton); Constraint relaxedCon = null; if (isAutomatonEmpty(auxAutomaton)) { logger.warn(candidateCon + " conflicts with the existing safe automaton!"); // logger.warn("Current set of safe constraints: " + this.safeProcess.bag); conflictingConstraints.add(candidateCon); relaxedCon = candidateCon.getConstraintWhichThisIsBasedUpon(); if (relaxedCon == null) { relaxedCon = candidateCon.suggestConstraintWhichThisShouldBeBasedUpon(); if (relaxedCon != null) { relaxedCon = candidateCon.createConstraintWhichThisShouldBeBasedUpon(); logger.trace( relaxedCon + " included in process model as relaxation, replacing " + candidateCon); } } if (relaxedCon == null || relaxedCon == candidateCon) { logger.warn(candidateCon + " has to be removed at once"); } else { logger.trace(candidateCon + " relaxed to " + relaxedCon); resolveConflictsRecursively( new RegExp(relaxedCon.getRegularExpression()).toAutomaton(), relaxedCon); } if (candidateCon.getSubFamily().equals(RelationConstraintSubFamily.COUPLING)) { MutualRelationConstraint coCandidateCon = (MutualRelationConstraint) candidateCon; Constraint forwardCon = coCandidateCon.getForwardConstraint(), backwardCon = coCandidateCon.getBackwardConstraint(); if (forwardCon != null && backwardCon != null) { logger.trace( "Splitting the coupling relation constraint " + coCandidateCon + " into " + coCandidateCon.getForwardConstraint() + " and " + coCandidateCon.getBackwardConstraint()); this.resolveConflictsRecursively( new RegExp(forwardCon.getRegularExpression()).toAutomaton(), forwardCon); this.resolveConflictsRecursively( new RegExp(backwardCon.getRegularExpression()).toAutomaton(), backwardCon); } } } else { safeAutomaton = auxAutomaton; // System.out.println("PRESENTATION -- Safe automaton so far: " + safeAutomaton.toDot()); safeProcess.bag.add(candidateCon.getBase(), candidateCon); } }