summaryrefslogtreecommitdiffstats
path: root/src/jrummikub/ai/fdsolver/constraint/IfConstraint.java
blob: fc1b484408ea65f3066764129ed3f9836b47d74a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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 extends 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.isSatisfiable()) {
				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();
	}
	
}