package jrummikub.ai.fdsolver.constraint; import static jrummikub.ai.fdsolver.Satisfiability.*; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import jrummikub.ai.fdsolver.Constraint; import jrummikub.ai.fdsolver.Propagator; import jrummikub.ai.fdsolver.Satisfiability; import jrummikub.ai.fdsolver.Var; public class ComparatorConstraint extends Constraint { Var x, y; Comparator comparator, reverseComparator; ComparatorPropagator trueX, trueY, falseX, falseY; boolean allowEqual; ComparatorConstraint(final Comparator comparator, boolean allowEqual, Var x, Var y) { this.x = x; this.y = y; this.comparator = comparator; this.allowEqual = allowEqual; reverseComparator = new Comparator() { @Override public int compare(T o1, T o2) { return comparator.compare(o2, o1); } }; trueX = new ComparatorPropagator(comparator, allowEqual, x, y); trueY = new ComparatorPropagator(reverseComparator, allowEqual, y, x); falseX = new ComparatorPropagator(reverseComparator, !allowEqual, x, y); falseY = new ComparatorPropagator(comparator, !allowEqual, y, x); } @Override public Collection> getWatchedVars() { return Arrays.>asList(x,y); } @Override public Collection getPropagators(boolean negate) { if (negate) { return Arrays.asList(falseX,falseY); } else { return Arrays.asList(trueX,trueY); } } @Override public Satisfiability getSatisfiability() { T maxX = Collections.max(x.getRange(), comparator); T minY = Collections.min(y.getRange(), comparator); if (comparator.compare(maxX, minY) < (allowEqual ? 1 : 0)) { return TAUT; } T minX = Collections.min(x.getRange(), comparator); T maxY = Collections.max(y.getRange(), comparator); if (comparator.compare(maxY, minX) < (allowEqual ? 0 : 1)) { return UNSAT; } return SAT; } }