org.openl.ie.constrainer.consistencyChecking.OverlappingCheckerImpl2 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.openl.rules.constrainer Show documentation
Show all versions of org.openl.rules.constrainer Show documentation
OpenL Constraint Programming engine
package org.openl.ie.constrainer.consistencyChecking;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.openl.ie.constrainer.*;
public class OverlappingCheckerImpl2 implements OverlappingChecker {
private static final int MAX_OVERLOADS = 50;
private final CDecisionTable _dt;
private final List overlappings = new ArrayList<>();
private final HashSet checkedPairs = new HashSet<>();
private final boolean[] removed;
private final boolean[] hadBeenRemoved;
private int nRemoved = 0;
private void remove(int i) {
removed[i] = true;
nRemoved++;
}
private void restore(int i) {
removed[i] = false;
nRemoved--;
}
private class GoalSaveSolutions extends GoalImpl {
private static final long serialVersionUID = 4298252562811799305L;
private final List overlappingRules;
public GoalSaveSolutions(Constrainer c, List ovlRules) {
super(c);
this.overlappingRules = ovlRules;
}
@Override
public Goal execute() throws Failure {
Overlapping over = new Overlapping(_dt.getVars());
for (int i = 0; i < _dt.getRules().length; i++) {
if (removed[i]) {
continue;
}
IntBoolExp rule = _dt.getRule(i);
if (rule.bound() && rule.max() == 1) {
over.addRule(i);
}
}
if (over.amount() > 0) {
overlappingRules.add(over);
}
return null;
}
}
public OverlappingCheckerImpl2(CDecisionTable _dt) {
this._dt = _dt;
removed = new boolean[_dt.getRules().length];
hadBeenRemoved = new boolean[_dt.getRules().length];
}
public void checkInternal() {
// User will not see all overloads if there is too many of them.
// TODO Optimize algorithm and remove check for MAX_OVERLOADS. Added for EPBDS-5694
if (overlappings.size() > MAX_OVERLOADS) {
return;
}
List overlappingRules = new ArrayList<>();
IntBoolExp[] rules = _dt.getRules();
Constrainer C = rules[0].constrainer();
int stackSize = C.getStackSize();
IntExpArray ruleArray = new IntExpArray(C, rules.length - nRemoved);
for (int i = 0, r = 0; i < rules.length; i++) {
if (!removed[i]) {
ruleArray.set(rules[i], r++);
}
}
Constraint overlapping = ruleArray.sum().gt(1).asConstraint();
Goal save = new GoalSaveSolutions(C, overlappingRules);
Goal generate = new GoalGenerate(_dt.getVars());
Goal target = new GoalAnd(new GoalAnd(overlapping, generate), save);
C.execute(target, true);
C.backtrackStack(stackSize);
testPairOverlappings(overlappingRules);
}
private void testPairOverlappings(List overlappingRules) {
for (Overlapping ovl : overlappingRules) {
int[] rules = ovl.getOverlapped();
for (int i = 0; i < rules.length; i++) {
for (int j = i + 1; j < rules.length; j++) {
IntPair pair = new IntPair(rules[i], rules[j]);
if (checkedPairs.contains(pair)) {
continue;
}
checkedPairs.add(pair);
int A = _dt.isOverrideAscending() ? i : j;
int B = _dt.isOverrideAscending() ? j : i;
if (completelyOverlaps(_dt.getRule(rules[A]), _dt.getRule(rules[B]))) {
// System.out.println(" +***+ Checking " + rules[A] + " vs " + rules[B] + " = blocks");
this.overlappings
.add(new Overlapping(ovl, rules[A], rules[B], Overlapping.OverlappingStatus.BLOCK));
} else if (completelyOverlaps(_dt.getRule(rules[B]), _dt.getRule(rules[A]))) {
// System.out.println(" +***+ Checking " + rules[A] + " vs " + rules[B] + " = overrides");
this.overlappings
.add(new Overlapping(ovl, rules[A], rules[B], Overlapping.OverlappingStatus.OVERRIDE));
} else /* if (!blocks && !overrides) */ {
// System.out.println(" +***+ Checking " + rules[A] + " vs " + rules[B] + " = partial overlap");
this.overlappings
.add(new Overlapping(ovl, rules[A], rules[B], Overlapping.OverlappingStatus.PARTIAL));
}
checkWithRemove(rules[A]);
checkWithRemove(rules[B]);
}
}
}
}
private void checkWithRemove(int ind) {
if (hadBeenRemoved[ind]) {
return;
}
hadBeenRemoved[ind] = true;
remove(ind);
checkInternal();
restore(ind);
}
private boolean completelyOverlaps(IntExp exp1, IntExp exp2) {
Constrainer C = exp1.constrainer();
int stackSize = C.getStackSize();
Constraint overlaps = exp1.lt(exp2).asConstraint();
// GoalCompare compare = new GoalCompare(C, exp1, exp2);
Goal generate = new GoalGenerate(_dt.getVars());
Goal target = new GoalAnd(overlaps, generate);
boolean flag = C.execute(target, true);
C.backtrackStack(stackSize);
// boolean res = compare.result;
return !flag;
}
@Override
public List check() {
checkInternal();
return overlappings;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy