/* X - Y = k */ static int fd_minus_eq_filter(fd_constraint this) { fd_int x, y; int k; x = VAR(this, 0); y = VAR(this, 1); k = this->constants[0]; // XXX: just do bounds consistency, for now if (_fd_var_del_lt(_fd_var_min(x) - k, y) | _fd_var_del_gt(_fd_var_max(x) - k, y)) { if (fd_domain_empty(y)) return FD_NOSOLUTION; _fd_revise_connected(NULL, y); } if (_fd_var_del_lt(_fd_var_min(y) + k, x) | _fd_var_del_gt(_fd_var_max(y) + k, x)) { if (fd_domain_empty(x)) return FD_NOSOLUTION; _fd_revise_connected(NULL, x); } return FD_OK; } int fd_minus_eq_propagate2(fd_constraint this, fd_int culprit) { fd_int revise; int changed; // XXX: just do bounds consistency, for now if (culprit == VAR(this, 0)) { revise = VAR(this, 1); changed = _fd_var_del_lt(_fd_var_min(culprit) - this->constants[0], revise); changed |= _fd_var_del_gt(_fd_var_max(culprit) - this->constants[0], revise); } else { revise = VAR(this, 0); changed = _fd_var_del_lt(_fd_var_min(culprit) + this->constants[0], revise); changed |= _fd_var_del_gt(_fd_var_max(culprit) + this->constants[0], revise); } if (changed && fd_domain_empty(revise)) return FD_NOSOLUTION; if (changed) _fd_revise_connected(NULL, revise); return FD_OK; } int fd_minus_eq_propagate(fd_constraint this, fd_int revise) { fd_int other; int idx; int changed; idx = revise == VAR(this, 0) ? 0 : 1; other = VAR(this, 1 - idx); // XXX: just do bounds consistency, for now if (idx == 0) { changed = _fd_var_del_lt(_fd_var_min(other) + this->constants[0], revise); changed |= _fd_var_del_gt(_fd_var_max(other) + this->constants[0], revise); } else { changed = _fd_var_del_lt(_fd_var_min(other) - this->constants[0], revise); changed |= _fd_var_del_gt(_fd_var_max(other) - this->constants[0], revise); } if (changed && fd_domain_empty(revise)) return FD_NOSOLUTION; // XXX: enqueue further updates here? if (changed) _fd_revise_connected(this, revise); return FD_OK; } fd_constraint fd_minus_eq(fd_int x, fd_int y, int k) { fd_constraint c = _fd_constraint_new(2, 1); if (c) { c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); c->constants[0] = k; #ifdef CONSTRAINT_CLASS c->kind = FD_CONSTR_MINUS_EQ; #else /* CONSTRAINT_CLASS */ c->propagator2 = fd_minus_eq_propagate2; c->propagator = fd_minus_eq_propagate; #endif /* CONSTRAINT_CLASS */ _fd_var_add_constraint(x, c); _fd_var_add_constraint(y, c); _fd_add_constraint(c); } return c; }