summaryrefslogtreecommitdiffstats
path: root/src/jrummikub/ai/fdsolver/constraint/IfConstraint.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jrummikub/ai/fdsolver/constraint/IfConstraint.java')
-rw-r--r--src/jrummikub/ai/fdsolver/constraint/IfConstraint.java108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/jrummikub/ai/fdsolver/constraint/IfConstraint.java b/src/jrummikub/ai/fdsolver/constraint/IfConstraint.java
new file mode 100644
index 0000000..802acc2
--- /dev/null
+++ b/src/jrummikub/ai/fdsolver/constraint/IfConstraint.java
@@ -0,0 +1,108 @@
+package jrummikub.ai.fdsolver.constraint;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.locks.Condition;
+
+
+import jrummikub.ai.fdsolver.Constraint;
+import jrummikub.ai.fdsolver.Propagator;
+import jrummikub.ai.fdsolver.Satisfiability;
+import jrummikub.ai.fdsolver.Var;
+
+public class IfConstraint implements Constraint {
+ Var<Boolean> condition;
+ Constraint child;
+ Collection<Var<?>> vars;
+ boolean negateCond;
+
+ public IfConstraint(boolean negateCond, Var<Boolean> condition, Constraint child) {
+ this.condition = condition;
+ this.child = child;
+ this.negateCond = negateCond;
+ vars = new ArrayList<Var<?>>();
+ vars.addAll(child.getWatchedVars());
+ vars.add(condition);
+ }
+
+ @Override
+ public Collection<Var<?>> getWatchedVars() {
+ return vars;
+ }
+
+ private class IfPropagator implements Propagator {
+ Propagator child;
+ Collection<Var<?>> vars;
+ public IfPropagator(Propagator child) {
+ this.child = child;
+ vars = new ArrayList<Var<?>>();
+ vars.addAll(child.getWatchedVars());
+ vars.add(condition);
+ }
+
+ @Override
+ public Collection<Var<?>> getWatchedVars() {
+ return vars;
+ }
+
+ @Override
+ public void propagate() {
+ if(condition.getRange().contains(negateCond)) {
+ return;
+ }
+ child.propagate();
+ }
+ }
+
+ private class FailPropagator implements Propagator {
+ @Override
+ public Collection<Var<?>> getWatchedVars() {
+ return child.getWatchedVars();
+ }
+
+ @Override
+ public void propagate() {
+ if (child.getSatisfiability() == Satisfiability.UNSAT) {
+ condition.invalidate(!negateCond);
+ }
+ }
+ }
+
+ @Override
+ public Collection<Propagator> getPropagators(boolean negate) {
+ List<Propagator> props = new ArrayList<Propagator>();
+ if (negate) {
+ props.add(new FilterPropagator<Boolean>(new Filter<Boolean>() {
+ @Override
+ public boolean accept(Boolean value) {
+ return value ^ negateCond;
+ }
+ }, condition));
+ props.addAll(child.getPropagators(true));
+ } else {
+ for (Propagator p : child.getPropagators(false)) {
+ props.add(new IfPropagator(p));
+ }
+ props.add(new FailPropagator());
+ }
+ return props;
+ }
+
+ @Override
+ public Satisfiability getSatisfiability() {
+ if (condition.getRange().contains(negateCond)) {
+ if (condition.getRange().size() == 1) {
+ return Satisfiability.TAUT;
+ } else {
+ if (child.getSatisfiability() == Satisfiability.TAUT) {
+ return Satisfiability.TAUT;
+ } else {
+ return Satisfiability.SAT;
+ }
+ }
+ }
+ return child.getSatisfiability();
+ }
+
+}