/* x <= y */ static int fd_le_filter(fd_constraint this) { fd_int x, y; x = VAR(this, 0); y = VAR(this, 1); #ifndef DISABLE_ENTAILED if (_fd_var_max(x) <= _fd_var_min(y)) { fd__constraint_set_entailed(this); return FD_OK; } #endif if (_fd_var_del_lt(_fd_var_min(x), y)) { if (fd_domain_empty(y)) return FD_NOSOLUTION; _fd_revise_connected(this, y); } if (_fd_var_del_gt(_fd_var_max(y), x)) { if (fd_domain_empty(x)) return FD_NOSOLUTION; _fd_revise_connected(this, x); } #ifndef DISABLE_ENTAILED if (_fd_var_max(x) <= _fd_var_min(y)) fd__constraint_set_entailed(this); #endif return FD_OK; } static int fd_le_propagate2(fd_constraint this, fd_int culprit) { fd_int x, y; int vmax, vmin; fd_int revise; int changed = 0; x = VAR(this, 0); y = VAR(this, 1); #ifndef DISABLE_ENTAILED vmax = _fd_var_max(x); vmin = _fd_var_min(y); if (vmax <= vmin) { fd__constraint_set_entailed(this); return FD_OK; } #endif if (culprit == x) { revise = y; vmin = _fd_var_min(x); changed = _fd_var_del_lt(vmin, y); } else { revise = x; vmax = _fd_var_max(y); changed = _fd_var_del_gt(vmax, x); } if (changed) { if (fd_domain_empty(revise)) return FD_NOSOLUTION; _fd_revise_connected(this, revise); #ifndef DISABLE_ENTAILED // see if the culprit's domain is a singleton if (vmin == vmax) fd__constraint_set_entailed(this); #endif } return FD_OK; } static int fd_le_propagate(fd_constraint this, fd_int revise) { int changed = 0; if (revise == VAR(this, 0)) changed = _fd_var_del_gt(_fd_var_max(VAR(this, 1)), revise); else changed = _fd_var_del_lt(_fd_var_min(VAR(this, 0)), revise); if (changed && fd_domain_empty(revise)) return FD_NOSOLUTION; #ifdef USE_ENTAILED if (_fd_var_max(VAR(this, 0)) <= _fd_var_min(VAR(this, 1))) fd__constraint_set_entailed(this); #endif // XXX: enqueue further updates here? if (changed) _fd_revise_connected(this, revise); return FD_OK; } fd_constraint fd_le(fd_int x, fd_int y) { fd_constraint c = fd__constraint_new(2, 0); if (c) { c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); c->kind = FD_CONSTR_LE; _fd_var_add_constraint(x, c); _fd_var_add_constraint(y, c); _fd_add_constraint(c); } return c; }