/* maximisation */ #include "bound.h" static int fd_max_filter(fd_constraint this) { fd_int x = VAR(this, 0); if (_fd_var_del_le(_fd_bound_value(), x)) { if (fd_domain_empty(x)) return FD_NOSOLUTION; _fd_revise_connected(this, x); } return FD_OK; } int fd_max_propagate2(fd_constraint this, fd_int culprit) { int changed = 0; changed = _fd_var_del_le(_fd_bound_value(), culprit); if (changed) { if (fd_domain_empty(culprit)) return FD_NOSOLUTION; _fd_revise_connected(this, culprit); // XXX } return FD_OK; } #ifndef USE_STORE #error "fd_max requires USE_STORE" #endif int fd_max_satisfied(fd_constraint this, _fd_store store, int *value) { int v; // XXX: `store' appears in the expansion of DOMAIN() _fd_val_single(DOMAIN(VAR(this, 0)), &v); if (value) *value = v; return v > _fd_bound_value(); } int fd_max_valid_bound(int current, int new) { return new > current; } int fd_max_compare(fd_constraint this, _fd_store s1, _fd_store s2) { int v1, v2; // XXX: `store' appears in the expansion of DOMAIN() { _fd_store store = s1; _fd_val_single(DOMAIN(VAR(this, 0)), &v1); } { _fd_store store = s2; _fd_val_single(DOMAIN(VAR(this, 0)), &v2); } return v2 - v1; } bool fd_max_bound_variable(fd_constraint this, int bound) { return _fd_var_del_le(bound, VAR(this, 0)) != 0; } fd_constraint fd_max(fd_int variable) { fd_constraint c = _fd_constraint_new(1, 0); if (c) { c->variables[0] = FD_INT2C_VAR(variable); #ifdef CONSTRAINT_CLASS c->kind = FD_CONSTR_MAX; #else /* CONSTRAINT_CLASS */ c->propagator2 = fd_max_propagate2; #endif /* CONSTRAINT_CLASS */ _fd_var_add_constraint(variable, c); _fd_add_constraint(c); } _fd_init_bound(MIN_VALUE - 1, FD_INT2C_VAR(variable), c, fd_max_satisfied, fd_max_valid_bound, fd_max_compare, fd_max_bound_variable); return c; }