| 1071 | |
| 1072 | template<class Card> |
| 1073 | inline ExecStatus |
| 1074 | VarValGraph<Card>::min_require(Space& home, |
| 1075 | ViewArray<IntView>& x, |
| 1076 | ViewArray<Card>& k) { |
| 1077 | for (int i = n_val; i--; ) { |
| 1078 | ValNode* vln = vals[i]; |
| 1079 | if (vln->noe > 0) { |
| 1080 | if (k[i].min() == vln->noe) { |
| 1081 | // all variable nodes reachable from vln should be equal to vln->val |
| 1082 | for (Edge* e = vln->first(); e != nullptr; e = e->vnext()) { |
| 1083 | VarNode* vrn = e->getVar(); |
| 1084 | for (Edge* f = vrn->first(); f != nullptr; f = f->next()) |
| 1085 | if (f != e) { |
| 1086 | ValNode* w = f->getVal(); |
| 1087 | w->noe--; |
| 1088 | vrn->noe--; |
| 1089 | f->del_edge(); |
| 1090 | f->unlink(); |
| 1091 | } |
| 1092 | assert(vrn->noe == 1); |
| 1093 | |
| 1094 | int vi = vrn->index(); |
| 1095 | GECODE_ME_CHECK(x[vi].eq(home, vln->val)); |
| 1096 | |
| 1097 | vars[vi] = vars[--n_var]; |
| 1098 | vars[vi]->index(vi); |
| 1099 | x.move_lst(vi); |
| 1100 | n_node--; |
| 1101 | vln->noe--; |
| 1102 | } |
| 1103 | |
| 1104 | |
| 1105 | int vidx = vln->kindex(); |
| 1106 | if (Card::propagate) |
| 1107 | GECODE_ME_CHECK(k[vidx].eq(home, k[vidx].min())); |
| 1108 | |
| 1109 | k[vidx].counter(k[vidx].min()); |
| 1110 | |
| 1111 | vln->cap(UBC,0); |
| 1112 | vln->cap(LBC,0); |
| 1113 | vln->maxlow(0); |
| 1114 | |
| 1115 | if (sum_min >= k[vidx].min()) |
| 1116 | sum_min -= k[vidx].min(); |
| 1117 | if (sum_max >= k[vidx].max()) |
| 1118 | sum_max -= k[vidx].max(); |
| 1119 | } |
| 1120 | } else { |
| 1121 | vals[i]->cap(UBC,0); |
| 1122 | vals[i]->cap(LBC,0); |
| 1123 | vals[i]->maxlow(0); |
| 1124 | vals[i]->kmax(0); |
| 1125 | vals[i]->kmin(0); |
| 1126 | } |
| 1127 | |
| 1128 | if (Card::propagate && (k[i].counter() == 0)) |
| 1129 | GECODE_ME_CHECK(k[i].lq(home, vals[i]->noe)); |
| 1130 | } |