Example #1
0
	bool propagate() {
		int64_t x_min = x.getMin(), x_max = x.getMax();
		int64_t y_min = y.getMin(), y_max = y.getMax();
		int64_t z_min = z.getMin(), z_max = z.getMax();
		
		// z >= ceil(x.min / y.max)
		setDom(z, setMin, (x_min+y_max-1)/y_max, x.getMinLit(), y.getMaxLit());
		// z <= ceil(x.max / y.min)
		setDom(z, setMax, (x_max+y_min-1)/y_min, x.getMaxLit(), y.getMinLit());

		// x >= y.min * (z.min - 1) + 1
		setDom(x, setMin, y_min*(z_min-1)+1, y.getMinLit(), z.getMinLit());
		// x <= y.max * z.max
		setDom(x, setMax, y_max*z_max, y.getMaxLit(), z.getMaxLit());

		// y >= ceil(x.min / z.max)
		if (z_max >= 1) {
			setDom(y, setMin, (x_min+z_max-1)/z_max, x.getMinLit(), z.getMaxLit());
		}

		// y <= ceil(x.max / z.min-1) - 1
		if (z_min >= 2) {
			setDom(y, setMax, (x_max+z_min-2)/(z_min-1)-1, x.getMaxLit(), z.getMinLit());
		}

		return true;
	}
Example #2
0
	bool propagate() {
		int64_t x_min = x.getMin(), x_max = x.getMax();
		int64_t y_min = y.getMin(), y_max = y.getMax();
		int64_t z_min = z.getMin(), z_max = z.getMax();
		
		// z >= x.min * y.min
		setDom(z, setMin, x_min*y_min, x.getMinLit(), y.getMinLit());
		// z <= x.max * y.max
		if (x_max * y_max < IntVar::max_limit)
		setDom(z, setMax, x_max*y_max, x.getMaxLit(), y.getMaxLit());

		// x >= ceil(z.min / y.max)
		if (y_max >= 1) {
			setDom(x, setMin, (z_min+y_max-1)/y_max, y.getMaxLit(), z.getMinLit());
		}

		// x <= floor(z.max / y.min)
		if (y_min >= 1) {
			setDom(x, setMax, z_max/y_min, y.getMinLit(), z.getMaxLit());
		}

		// y >= ceil(z.min / x.max)
		if (x_max >= 1) {
			setDom(y, setMin, (z_min+x_max-1)/x_max, x.getMaxLit(), z.getMinLit());
		}

		// y <= floor(z.max / x.min)
		if (x_min >= 1) {
			setDom(y, setMax, z_max/x_min, x.getMinLit(), z.getMaxLit());
		}

		return true;
	}
Example #3
0
	Times(IntView<U> _x, IntView<V> _y, IntView<W> _z) :
		x(_x), y(_y), z(_z) {
		priority = 1;
		assert(x.getMin() >= 0 && y.getMin() >= 0 && z.getMin() >= 0);
		x.attach(this, 0, EVENT_LU);
		y.attach(this, 1, EVENT_LU);
		z.attach(this, 2, EVENT_LU);
	}
Example #4
0
	IntElemDomain(IntView<U> _y, IntView<V> _x, vec<IntView<W> >& _a) :
		y(_y), x(_x), a(_a) {
		num_support = new Tint[y.getMax()-y.getMin()+1] - y.getMin();
		support = new int*[y.getMax()-y.getMin()+1] - y.getMin();
		temp_sup = new int[x.getMax()-x.getMin()+1];

		vec<int> temp;
		for (int v = y.getMin(); v <= y.getMax(); v++) {
			temp.clear();
			if (y.indomain(v)) {
				for (int i = x.getMin(); i <= x.getMax(); i++) {
					if (x.indomain(i) && a[i].indomain(v)) temp.push(i);
				}
			}
			num_support[v] = temp.size();
			support[v] = new int[temp.size()];
			for (int i = 0; i < temp.size(); i++) {
				support[v][i] = temp[i];
			}
		}

		for (int i = 0; i < a.size(); i++) a[i].attach(this, i, EVENT_C);
		y.attach(this, a.size(), EVENT_C);
		x.attach(this, a.size()+1, EVENT_C);
	}
Example #5
0
	bool propagate() {

		// make a less than or equal to min(max(x_i))
		setDom(y, setMax, min_max, x[min_max_var].getMaxLit());

		if (lower_change) {

			// make a greater than or equal to min(min(b_i))
			int64_t m = INT64_MAX; 
			for (int i = 0; i < sz; i++) {
				int64_t t = x[i].getMin();
				if (t < m) m = t;
			}
			if (y.setMinNotR(m)) {
				Clause *r = NULL;
				if (so.lazy) {
					r = Reason_new(sz+1);
					// Finesse lower bounds
					// Add reason ![y <= m-1] \/ [x_1 <= m-1] \/ ... \/ [x_n <= m-1] 
					for (int i = 0; i < sz; i++) (*r)[i+1] = x[i].getFMinLit(m);
//					for (int i = 0; i < sz; i++) (*r)[i+1] = x[i].getLit(m-1, 3);
				}
				if (!y.setMin(m, r)) return false;
			}

			// make b_i greater than or equal to min(a)
			m = y.getMin();
			Clause *r = NULL;
			if (so.lazy) {
				r = Reason_new(2);
				(*r)[1] = y.getMinLit();
			}				
			for (int i = 0; i < sz; i++) {
				if (x[i].setMinNotR(m)) if (!x[i].setMin(m, r)) return false;
			}
		}

		// Necessary and sufficient conditions for redundancy

		if (y.getMin() == min_max) satisfied = true;

		return true;
	}
Example #6
0
	bool propagate() {
		if (y.getMax() < k) {
			int64_t m = y.getMax()-1;
			setDom(x, setMax, m, y.getMaxLit());
		}

		int64_t m = x.getMin()+1;
		if (m > k) m = k;
		setDom(y, setMin, m, x.getMinLit());

		return true;
	}
Example #7
0
	bool propagate() {
		// make a less than or equal to min(max(b_i))

		setDom(z, setMax, x.getMax(), x.getMaxLit());
		setDom(z, setMax, y.getMax(), y.getMaxLit());

		int64_t m = (x.getMin() < y.getMin() ? x.getMin() : y.getMin());
		setDom(z, setMin, m, x.getFMinLit(m), y.getFMinLit(m));

		setDom(x, setMin, z.getMin(), z.getMinLit());
		setDom(y, setMin, z.getMin(), z.getMinLit());

		if (z.getMin() == x.getMax() || z.getMin() == y.getMax()) satisfied = true;

		return true;
	}
Example #8
0
	void wakeup(int i, int c) {
		if (i == a.size()+1 && (c & EVENT_F)) {
			fixed_index = x.getVal();
			no_min_support = no_max_support = false;
			pushInQueue();
		}
		if (fixed_index >= 0) {
			if (i == a.size() || i == fixed_index) pushInQueue();
		} else {
			if (i < a.size()) {
				if (i == min_support && a[i].getMin() > y.getMin()) no_min_support = true;
				if (i == max_support && a[i].getMax() < y.getMax()) no_max_support = true;
				pushInQueue();
			} else if (i == a.size()+1) {
				if (!x.indomain(min_support)) { no_min_support = true; pushInQueue(); }
				if (!x.indomain(max_support)) { no_max_support = true; pushInQueue(); }
			} else pushInQueue();
		}
	}
Example #9
0
	bool propagate() {

		int64_t l = x.getMin();
		int64_t u = x.getMax();

		if (l >= 0) {
			setDom(y, setMin, l, x.getMinLit());
			setDom(y, setMax, u, x.getMinLit(), x.getMaxLit());
		} else if (u <= 0) {
			setDom(y, setMin, -u, x.getMaxLit());
			setDom(y, setMax, -l, x.getMaxLit(), x.getMinLit());
		} else {
			// Finesse stronger bound
			int64_t t = (-l > u ? -l : u);
			setDom(y, setMax, t, x.getMaxLit(), x.getMinLit());
//			setDom(y, setMax, t, x.getFMaxLit(t), x.getFMinLit(-t));
//			setDom(y, setMax, t, x.getLit(t+1, 2), x.getLit(-t-1, 3));
		}


		setDom(x, setMax, y.getMax(), y.getMaxLit());
		setDom(x, setMin, -y.getMax(), y.getMaxLit());

/*
		if (x.isFixed()) {
			if (x.getVal() < 0) {
				setDom(y, setMin, -x.getVal(), x.getMaxLit());
				setDom(y, setMax, -x.getVal(), x.getMinLit());
			} else if (x.getVal() > 0) {
				setDom(y, setMin, x.getVal(), x.getMinLit());
				setDom(y, setMax, x.getVal(), x.getMaxLit());
			} else {
				setDom(y, setVal, 0, x.getMinLit(), x.getMaxLit());
			}
		}
*/

		return true;
	}
Example #10
0
	int checkSatisfied() {
		if (satisfied) return 1;
		if (y.getMin() == min_max) satisfied = true;
		return 2;
	}
Example #11
0
	int checkSatisfied() {
		if (satisfied) return 1;
		if (z.getMin() == x.getMax() || z.getMin() == y.getMax()) satisfied = true;
		return 3;
	}
Example #12
0
	bool propagate() {

		// propagate holes in y
		for (int v = y.getMin(); v <= y.getMax(); v++) {
			if (!y.indomain(v)) continue;
			assert(num_support[v] > 0);
			int *s = support[v];
			if (x.indomain(s[0]) && a[s[0]].indomain(v)) continue;
			int f = 0;
			while (!(x.indomain(s[f]) && a[s[f]].indomain(v)) && ++f < num_support[v]);
			if (f == num_support[v]) {
				// v has no support, remove from y
				Clause* r = NULL;
				if (so.lazy) {
					r = Reason_new(x.getMax() + 4 - x.getMin());
					(*r)[1] = x.getMinLit();
					(*r)[2] = x.getMaxLit();
					for (int i = x.getMin(); i <= x.getMax(); i++) {
						//(*r)[3 + i - x.getMin()] = x.indomain(i) ? ~a[i].getLit(v, 0) : ~x.getLit(i, 0);
						int reasonIndex = 3 + i - x.getMin();
						if(x.indomain(i))
						{
							Lit l = ~a[i].getLit(v, 0);
							(*r)[reasonIndex] = l;
						}
						else
						{
							Lit l = ~x.getLit(i, 0);
						 	(*r)[reasonIndex] = l;
						}
					}
				}
				if (!y.remVal(v, r)) return false;
			} else {
				// shift bad supports to back
				for (int i = 0; i < f; i++) temp_sup[i] = s[i];
				for (int i = f; i < num_support[v]; i++) {
					s[i-f] = s[i];
				}
				s += num_support[v] - f;
				for (int i = 0; i < f; i++) s[i] = temp_sup[i];
				num_support[v] -= f;
			}
		}

		// propagate holes in x
		// just ignore

		// propagate holes in a_i
		if (x.isFixed()) {
			int v = x.getVal();
			IntView<W>& f = a[v];
			setDom(y, setMin, f.getMin(), f.getMinLit(), x.getValLit());
			setDom(f, setMin, y.getMin(), y.getMinLit(), x.getValLit());
			setDom(y, setMax, f.getMax(), f.getMaxLit(), x.getValLit());
			setDom(f, setMax, y.getMax(), y.getMaxLit(), x.getValLit());
			for (typename IntView<W>::iterator i = a[v].begin(); i != a[v].end(); ) {
				int w = *i++;
				if (!y.indomain(w) && !a[v].remVal(w, so.lazy ? Reason(~y.getLit(w, 0), ~x.getLit(v, 1)) : Reason()))
					return false;
			}
		}

		return true;
	}
Example #13
0
	bool propagate() {

		// y = a[fixed_index]
		if (fixed_index >= 0) {
			assert(x.getVal() == fixed_index);
			IntView<W>& f = a[fixed_index];
			setDom(y, setMin, f.getMin(), f.getMinLit(), x.getValLit());
			setDom(f, setMin, y.getMin(), y.getMinLit(), x.getValLit());
			setDom(y, setMax, f.getMax(), f.getMaxLit(), x.getValLit());
			setDom(f, setMax, y.getMax(), y.getMaxLit(), x.getValLit());
			if (y.isFixed() && f.isFixed()) satisfied = true;
			return true;
		}

		for (int i = 0; i < a.size(); i++) {
			if (!x.indomain(i)) continue;
			if (y.getMax() < a[i].getMin()) setDom(x, remVal, i, y.getMaxLit(), a[i].getMinLit());
			if (y.getMin() > a[i].getMax()) setDom(x, remVal, i, y.getMinLit(), a[i].getMaxLit());
		}

		if (no_min_support) {
			int64_t old_m = y.getMin();
			int64_t new_m = INT64_MAX;
			int best = -1;
			for (int i = 0; i < a.size(); i++) {
				if (!x.indomain(i)) continue;
				int64_t cur_m = a[i].getMin();
				if (cur_m < new_m) {
					best = i;
					new_m = cur_m;
					if (cur_m <= old_m) break;
				}
			}
			min_support = best;
			if (y.setMinNotR(new_m)) {
				Clause *r = NULL;
				if (so.lazy) {
					r = Reason_new(a.size()+1);
					// Finesse lower bounds
					for (int i = 0; i < a.size(); i++) {
						(*r)[i+1] = x.indomain(i) ? a[i].getFMinLit(new_m) : x.getLit(i, 1);
					}
				}
				if (!y.setMin(new_m, r)) return false;
			}
			no_min_support = false;
		}

		if (no_max_support) {
			int64_t old_m = y.getMax();
			int64_t new_m = INT_MIN;
			int best = -1;
			for (int i = 0; i < a.size(); i++) {
				if (!x.indomain(i)) continue;
				int64_t cur_m = a[i].getMax();
				if (cur_m > new_m) {
					best = i;
					new_m = cur_m;
					if (cur_m >= old_m) break;
				}
			}
			max_support = best;
			if (y.setMaxNotR(new_m)) {
				Clause *r = NULL;
				if (so.lazy) {
					r = Reason_new(a.size()+1);
					// Finesse upper bounds
					for (int i = 0; i < a.size(); i++) {
						(*r)[i+1] = x.indomain(i) ? a[i].getFMaxLit(new_m) : x.getLit(i, 1);
					}
				}
				if (!y.setMax(new_m, r)) return false;
			}
			no_max_support = false;
		}

		return true;
	}