this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * Gabor Szokoli <szokoli@gecode.org> 6 * 7 * Contributing authors: 8 * Christian Schulte <schulte@gecode.org> 9 * 10 * Copyright: 11 * Guido Tack, 2004 12 * Christian Schulte, 2004 13 * Gabor Szokoli, 2004 14 * 15 * This file is part of Gecode, the generic constraint 16 * development environment: 17 * http://www.gecode.org 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining 20 * a copy of this software and associated documentation files (the 21 * "Software"), to deal in the Software without restriction, including 22 * without limitation the rights to use, copy, modify, merge, publish, 23 * distribute, sublicense, and/or sell copies of the Software, and to 24 * permit persons to whom the Software is furnished to do so, subject to 25 * the following conditions: 26 * 27 * The above copyright notice and this permission notice shall be 28 * included in all copies or substantial portions of the Software. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 * 38 */ 39 40namespace Gecode { namespace Set { 41 42 /* 43 * Creation of new variable implementations 44 * 45 */ 46 47 forceinline 48 SetVarImp::SetVarImp(Space& home) 49 : SetVarImpBase(home), lub(home), glb(home) { 50 lub.card(Limits::card); 51 assert(lub.card()==lub.size()); 52 } 53 54 forceinline 55 SetVarImp::SetVarImp(Space& home,int lbMin,int lbMax,int ubMin,int ubMax, 56 unsigned int cardMin, unsigned int cardMax) 57 : SetVarImpBase(home), 58 lub(home,ubMin,ubMax), glb(home,lbMin,lbMax) { 59 glb.card(std::max(cardMin, glb.size() )); 60 lub.card(std::min(cardMax, lub.size() )); 61 } 62 63 forceinline 64 SetVarImp::SetVarImp(Space& home, 65 const IntSet& theGlb,int ubMin,int ubMax, 66 unsigned int cardMin, unsigned int cardMax) 67 : SetVarImpBase(home), 68 lub(home,ubMin,ubMax), glb(home,theGlb) { 69 glb.card(std::max(cardMin, glb.size() )); 70 lub.card(std::min(cardMax, lub.size() )); 71 } 72 73 forceinline 74 SetVarImp::SetVarImp(Space& home, 75 int lbMin,int lbMax,const IntSet& theLub, 76 unsigned int cardMin, unsigned int cardMax) 77 : SetVarImpBase(home), 78 lub(home,theLub), glb(home,lbMin,lbMax) { 79 glb.card(std::max(cardMin, glb.size() )); 80 lub.card(std::min(cardMax, lub.size() )); 81 } 82 83 forceinline 84 SetVarImp::SetVarImp(Space& home, 85 const IntSet& theGlb,const IntSet& theLub, 86 unsigned int cardMin, unsigned int cardMax) 87 : SetVarImpBase(home), lub(home,theLub), glb(home,theGlb) { 88 glb.card(std::max(cardMin, glb.size() )); 89 lub.card(std::min(cardMax, lub.size() )); 90 } 91 92 93 forceinline bool 94 SetVarImp::assigned(void) const { 95 return glb.size() == lub.size(); 96 } 97 98 forceinline unsigned int 99 SetVarImp::cardMin(void) const { return glb.card(); } 100 101 forceinline unsigned int 102 SetVarImp::cardMax(void) const { return lub.card(); } 103 104 forceinline bool 105 SetVarImp::knownIn(int i) const { return (glb.in(i)); } 106 107 forceinline bool 108 SetVarImp::knownOut(int i) const { return !(lub.in(i)); } 109 110 forceinline int 111 SetVarImp::lubMin(void) const { return lub.min(); } 112 113 forceinline int 114 SetVarImp::lubMax(void) const { return lub.max(); } 115 116 forceinline int 117 SetVarImp::lubMinN(unsigned int n) const { return lub.minN(n); } 118 119 forceinline int 120 SetVarImp::glbMin(void) const { return glb.min(); } 121 122 forceinline int 123 SetVarImp::glbMax(void) const { return glb.max(); } 124 125 forceinline unsigned int 126 SetVarImp::glbSize() const { return glb.size(); } 127 128 forceinline unsigned int 129 SetVarImp::lubSize() const { return lub.size(); } 130 131 /* 132 * Support for delta information 133 * 134 */ 135 forceinline int 136 SetVarImp::glbMin(const Delta& d) { 137 return static_cast<const SetDelta&>(d).glbMin(); 138 } 139 forceinline int 140 SetVarImp::glbMax(const Delta& d) { 141 return static_cast<const SetDelta&>(d).glbMax(); 142 } 143 forceinline bool 144 SetVarImp::glbAny(const Delta& d) { 145 return static_cast<const SetDelta&>(d).glbAny(); 146 } 147 forceinline int 148 SetVarImp::lubMin(const Delta& d) { 149 return static_cast<const SetDelta&>(d).lubMin(); 150 } 151 forceinline int 152 SetVarImp::lubMax(const Delta& d) { 153 return static_cast<const SetDelta&>(d).lubMax(); 154 } 155 forceinline bool 156 SetVarImp::lubAny(const Delta& d) { 157 return static_cast<const SetDelta&>(d).lubAny(); 158 } 159 160 forceinline ModEvent 161 SetVarImp::cardMin(Space& home,unsigned int newMin) { 162 if (cardMin() >= newMin) 163 return ME_SET_NONE; 164 if (newMin > cardMax()) 165 return fail(home); 166 glb.card(newMin); 167 return cardMin_full(home); 168 } 169 170 forceinline ModEvent 171 SetVarImp::cardMax(Space& home,unsigned int newMax) { 172 if (cardMax() <= newMax) 173 return ME_SET_NONE; 174 if (cardMin() > newMax) 175 return fail(home); 176 lub.card(newMax); 177 return cardMax_full(home); 178 } 179 180 forceinline ModEvent 181 SetVarImp::intersect(Space& home,int i, int j) { 182 BndSetRanges lb(glb); 183 Iter::Ranges::Singleton s(i,j); 184 Iter::Ranges::Diff<BndSetRanges, Iter::Ranges::Singleton> probe(lb, s); 185 if (probe()) 186 return fail(home); 187 if (assigned()) 188 return ME_SET_NONE; 189 int oldMin = lub.min(); 190 int oldMax = lub.max(); 191 if (lub.intersect(home, i, j)) { 192 SetDelta d; 193 if (i == oldMin) { 194 d._lubMin = lub.max()+1; 195 d._lubMax = oldMax; 196 } else if (j == oldMax) { 197 d._lubMin = oldMin; 198 d._lubMax = lub.min()-1; 199 } 200 return processLubChange(home, d); 201 } 202 return ME_SET_NONE; 203 } 204 205 forceinline ModEvent 206 SetVarImp::intersect(Space& home,int i) { 207 return intersect(home, i, i); 208 } 209 210 template<class I> 211 inline ModEvent 212 SetVarImp::intersectI(Space& home, I& iterator) { 213 if (assigned()) { 214 BndSetRanges lbi(glb); 215 Iter::Ranges::Diff<BndSetRanges,I> probe(lbi,iterator); 216 if (probe()) 217 return fail(home); 218 return ME_SET_NONE; 219 } 220 if (!iterator()) { 221 if (cardMin() > 0) 222 return fail(home); 223 lub.card(0); 224 SetDelta d(1, 0, lub.min(), lub.max()); 225 lub.excludeAll(home); 226 return notify(home, ME_SET_VAL, d); 227 } 228 int mi=iterator.min(); 229 int ma=iterator.max(); 230 ++iterator; 231 if (iterator()) 232 return intersectI_full(home, mi, ma, iterator); 233 else 234 return intersect(home, mi, ma); 235 } 236 237 template<class I> 238 ModEvent 239 SetVarImp::intersectI_full(Space& home, int mi, int ma, I& iterator) { 240 Iter::Ranges::SingletonAppend<I> si(mi,ma,iterator); 241 if (lub.intersectI(home, si)) { 242 BndSetRanges ub(lub); 243 BndSetRanges lb(glb); 244 if (!Iter::Ranges::subset(lb,ub)) { 245 glb.become(home, lub); 246 glb.card(glb.size()); 247 lub.card(glb.size()); 248 return fail(home); 249 } 250 ModEvent me = ME_SET_LUB; 251 if (cardMax() > lub.size()) { 252 lub.card(lub.size()); 253 if (cardMin() > cardMax()) { 254 glb.become(home, lub); 255 glb.card(glb.size()); 256 lub.card(glb.size()); 257 return fail(home); 258 } 259 me = ME_SET_CLUB; 260 } 261 if (cardMax() == lub.size() && cardMin() == cardMax()) { 262 glb.become(home, lub); 263 me = ME_SET_VAL; 264 } 265 SetDelta d; 266 return notify(home, me, d); 267 } 268 return ME_SET_NONE; 269 } 270 271 forceinline ModEvent 272 SetVarImp::include(Space& home, int i, int j) { 273 if (j<i) 274 return ME_SET_NONE; 275 BndSetRanges ub(lub); 276 Iter::Ranges::Singleton sij(i,j); 277 if (!Iter::Ranges::subset(sij,ub)) { 278 return fail(home); 279 } 280 SetDelta d; 281 if (glb.include(home, i, j, d)) 282 return processGlbChange(home, d); 283 return ME_SET_NONE; 284 } 285 286 forceinline ModEvent 287 SetVarImp::include(Space& home, int i) { 288 return include(home, i, i); 289 } 290 291 template<class I> forceinline ModEvent 292 SetVarImp::includeI(Space& home, I& iterator) { 293 if (!iterator()) { 294 return ME_SET_NONE; 295 } 296 if (assigned()) { 297 BndSetRanges lbi(glb); 298 Iter::Ranges::Diff<I,BndSetRanges> 299 probe(iterator,lbi); 300 return probe() ? fail(home) : ME_SET_NONE; 301 } 302 int mi=iterator.min(); 303 int ma=iterator.max(); 304 ++iterator; 305 if (iterator()) 306 return includeI_full(home, mi, ma, iterator); 307 else 308 return include(home, mi, ma); 309 } 310 311 template<class I> 312 ModEvent 313 SetVarImp::includeI_full(Space& home, int mi, int ma, I& iterator) { 314 Iter::Ranges::SingletonAppend<I> si(mi,ma,iterator); 315 if (glb.includeI(home, si)) { 316 BndSetRanges ub(lub); 317 BndSetRanges lb(glb); 318 if (!Iter::Ranges::subset(lb,ub)) { 319 glb.become(home, lub); 320 glb.card(glb.size()); 321 lub.card(glb.size()); 322 return fail(home); 323 } 324 ModEvent me = ME_SET_GLB; 325 if (cardMin() < glb.size()) { 326 glb.card(glb.size()); 327 if (cardMin() > cardMax()) { 328 glb.become(home, lub); 329 glb.card(glb.size()); 330 lub.card(glb.size()); 331 return fail(home); 332 } 333 me = ME_SET_CGLB; 334 } 335 if (cardMin() == glb.size() && cardMin() == cardMax()) { 336 lub.become(home, glb); 337 me = ME_SET_VAL; 338 } 339 SetDelta d; 340 return notify(home, me, d); 341 } 342 return ME_SET_NONE; 343 } 344 345 forceinline ModEvent 346 SetVarImp::exclude(Space& home, int i, int j) { 347 if (j<i) 348 return ME_SET_NONE; 349 Iter::Ranges::Singleton sij(i,j); 350 BndSetRanges lb(glb); 351 Iter::Ranges::Inter<Iter::Ranges::Singleton,BndSetRanges> probe(sij,lb); 352 if (probe()) 353 return fail(home); 354 SetDelta d; 355 if (lub.exclude(home, i, j, d)) 356 return processLubChange(home, d); 357 return ME_SET_NONE; 358 } 359 360 forceinline ModEvent 361 SetVarImp::exclude(Space& home, int i) { 362 return exclude(home, i, i); 363 } 364 365 template<class I> 366 inline ModEvent 367 SetVarImp::excludeI(Space& home, I& iterator) { 368 if (!iterator()) 369 return ME_SET_NONE; 370 if (assigned()) { 371 BndSetRanges ubi(lub); 372 Iter::Ranges::Inter<BndSetRanges,I> probe(ubi,iterator); 373 return probe() ? fail(home) : ME_SET_NONE; 374 } 375 int mi=iterator.min(); 376 int ma=iterator.max(); 377 ++iterator; 378 if (iterator()) 379 return excludeI_full(home, mi, ma, iterator); 380 else 381 return exclude(home, mi, ma); 382 } 383 384 template<class I> 385 ModEvent 386 SetVarImp::excludeI_full(Space& home, int mi, int ma, I& iterator) { 387 Iter::Ranges::SingletonAppend<I> si(mi,ma,iterator); 388 if (lub.excludeI(home, si)) { 389 BndSetRanges ub(lub); 390 BndSetRanges lb(glb); 391 if (!Iter::Ranges::subset(lb,ub)) { 392 glb.become(home, lub); 393 glb.card(glb.size()); 394 lub.card(glb.size()); 395 return fail(home); 396 } 397 ModEvent me = ME_SET_LUB; 398 if (cardMax() > lub.size()) { 399 lub.card(lub.size()); 400 if (cardMin() > cardMax()) { 401 glb.become(home, lub); 402 glb.card(glb.size()); 403 lub.card(glb.size()); 404 return fail(home); 405 } 406 me = ME_SET_CLUB; 407 } 408 if (cardMax() == lub.size() && cardMin() == cardMax()) { 409 glb.become(home, lub); 410 me = ME_SET_VAL; 411 } 412 SetDelta d; 413 return notify(home, me, d); 414 } 415 return ME_SET_NONE; 416 } 417 418 /* 419 * Copying a variable 420 * 421 */ 422 423 forceinline SetVarImp* 424 SetVarImp::copy(Space& home) { 425 return copied() ? 426 static_cast<SetVarImp*>(forward()) : 427 perform_copy(home); 428 } 429 430 /* 431 * Iterator specializations 432 * 433 */ 434 435 /** 436 * \brief Range iterator for the least upper bound of a set variable implementation 437 * 438 * This class provides (by specialization) a range iterator 439 * for the least upper bounds of set variable implementations. 440 * 441 * \ingroup TaskActorSet 442 */ 443 template<> 444 class LubRanges<SetVarImp*> : public BndSetRanges { 445 public: 446 /// \name Constructors and initialization 447 //@{ 448 /// Default constructor 449 LubRanges(void); 450 /// Initialize with ranges for variable implementation \a x 451 LubRanges(const SetVarImp*); 452 /// Initialize with ranges for variable implementation \a x 453 void init(const SetVarImp*); 454 //@} 455 }; 456 457 forceinline 458 LubRanges<SetVarImp*>::LubRanges(void) {} 459 460 forceinline 461 LubRanges<SetVarImp*>::LubRanges(const SetVarImp* x) 462 : BndSetRanges(x->lub) {} 463 464 forceinline void 465 LubRanges<SetVarImp*>::init(const SetVarImp* x) { 466 BndSetRanges::init(x->lub); 467 } 468 469 /** 470 * \brief Range iterator for the greatest lower bound of a set variable implementation 471 * 472 * This class provides (by specialization) a range iterator 473 * for the greatest lower bounds of set variable implementations. 474 * 475 * \ingroup TaskActorSet 476 */ 477 template<> 478 class GlbRanges<SetVarImp*> : public BndSetRanges { 479 public: 480 /// \name Constructors and initialization 481 //@{ 482 /// Default constructor 483 GlbRanges(void); 484 /// Initialize with ranges for variable implementation \a x 485 GlbRanges(const SetVarImp* x); 486 /// Initialize with ranges for variable implementation \a x 487 void init(const SetVarImp*); 488 //@} 489 }; 490 491 forceinline 492 GlbRanges<SetVarImp*>::GlbRanges(void) {} 493 494 forceinline 495 GlbRanges<SetVarImp*>::GlbRanges(const SetVarImp* x) 496 : BndSetRanges(x->glb) {} 497 498 forceinline void 499 GlbRanges<SetVarImp*>::init(const SetVarImp* x) { 500 BndSetRanges::init(x->glb); 501 } 502 503}} 504 505// STATISTICS: set-var