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 * 6 * Contributing authors: 7 * Christian Schulte <schulte@gecode.org> 8 * 9 * Copyright: 10 * Guido Tack, 2004 11 * Christian Schulte, 2004 12 * 13 * This file is part of Gecode, the generic constraint 14 * development environment: 15 * http://www.gecode.org 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining 18 * a copy of this software and associated documentation files (the 19 * "Software"), to deal in the Software without restriction, including 20 * without limitation the rights to use, copy, modify, merge, publish, 21 * distribute, sublicense, and/or sell copies of the Software, and to 22 * permit persons to whom the Software is furnished to do so, subject to 23 * the following conditions: 24 * 25 * The above copyright notice and this permission notice shall be 26 * included in all copies or substantial portions of the Software. 27 * 28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 * 36 */ 37 38#include <sstream> 39 40namespace Gecode { namespace Set { 41 42 template<class View> 43 forceinline 44 ComplementView<View>::ComplementView(void) {} 45 46 template<class View> 47 forceinline 48 ComplementView<View>::ComplementView(View& y) 49 : DerivedView<View>(y) {} 50 51 template<class View> 52 forceinline ModEvent 53 ComplementView<View>::me_negateset(ModEvent me) { 54 switch(me) { 55 case ME_SET_LUB : return ME_SET_GLB; 56 case ME_SET_GLB : return ME_SET_LUB; 57 case ME_SET_CLUB : return ME_SET_CGLB; 58 case ME_SET_CGLB : return ME_SET_CLUB; 59 default: return me; 60 } 61 } 62 63 template<class View> 64 forceinline PropCond 65 ComplementView<View>::pc_negateset(PropCond pc) { 66 switch(pc) { 67 case PC_SET_CLUB : return PC_SET_CGLB; 68 case PC_SET_CGLB : return PC_SET_CLUB; 69 default: return pc; 70 } 71 } 72 73 template<class View> 74 forceinline unsigned int 75 ComplementView<View>::glbSize(void) const { 76 return Limits::card - x.lubSize(); 77 } 78 79 template<class View> 80 forceinline unsigned int 81 ComplementView<View>::lubSize(void) const { 82 return Limits::card - x.glbSize(); 83 } 84 85 template<class View> 86 forceinline unsigned int 87 ComplementView<View>::unknownSize(void) const { 88 return lubSize() - glbSize(); 89 } 90 91 template<class View> 92 forceinline bool 93 ComplementView<View>::contains(int n) const { return x.notContains(n); } 94 95 template<class View> 96 forceinline bool 97 ComplementView<View>::notContains(int n) const { return x.contains(n); } 98 99 template<class View> 100 forceinline unsigned int 101 ComplementView<View>::cardMin(void) const { 102 return Limits::card - x.cardMax(); 103 } 104 105 template<class View> 106 forceinline unsigned int 107 ComplementView<View>::cardMax(void) const { 108 return Limits::card - x.cardMin(); 109 } 110 111 template<class View> 112 forceinline int 113 ComplementView<View>::lubMin(void) const { 114 GlbRanges<View> lb(x); 115 RangesCompl<GlbRanges<View> > lbc(lb); 116 if (lbc()) { 117 return lbc.min(); 118 } else { 119 return BndSet::MIN_OF_EMPTY; 120 } 121 } 122 123 template<class View> 124 forceinline int 125 ComplementView<View>::lubMax(void) const { 126 GlbRanges<View> lb(x); 127 RangesCompl<GlbRanges<View> > lbc(lb); 128 if (lbc()) { 129 while(lbc()) ++lbc; 130 return lbc.max(); 131 } else { 132 return BndSet::MAX_OF_EMPTY; 133 } 134 } 135 136 template<class View> 137 forceinline int 138 ComplementView<View>::glbMin(void) const { 139 LubRanges<View> ub(x); 140 RangesCompl<LubRanges<View> > ubc(ub); 141 if (ubc()) { 142 return ubc.min(); 143 } else { 144 return BndSet::MIN_OF_EMPTY; 145 } 146 } 147 148 template<class View> 149 forceinline int 150 ComplementView<View>::glbMax(void) const { 151 LubRanges<View> ub(x); 152 RangesCompl<LubRanges<View> > ubc(ub); 153 if (ubc()) { 154 while (ubc()) ++ubc; 155 return ubc.max(); 156 } else { 157 return BndSet::MAX_OF_EMPTY; 158 } 159 } 160 161 template<class View> 162 forceinline ModEvent 163 ComplementView<View>::cardMin(Space& home, unsigned int c) { 164 if (c < Limits::card) 165 return me_negateset(x.cardMax(home, Limits::card - c)); 166 return ME_SET_NONE; 167 } 168 169 template<class View> 170 forceinline ModEvent 171 ComplementView<View>::cardMax(Space& home, unsigned int c) { 172 if (c < Limits::card) 173 return me_negateset(x.cardMin(home, Limits::card - c)); 174 return ME_SET_NONE; 175 } 176 177 template<class View> 178 forceinline ModEvent 179 ComplementView<View>::include(Space& home, int c) { 180 return me_negateset((x.exclude(home, c))); 181 } 182 183 template<class View> 184 forceinline ModEvent 185 ComplementView<View>::exclude(Space& home, int c) { 186 return me_negateset((x.include(home, c))); 187 } 188 189 template<class View> 190 forceinline ModEvent 191 ComplementView<View>::intersect(Space& home, int c) { 192 Iter::Ranges::Singleton si(c,c); 193 RangesCompl<Iter::Ranges::Singleton> csi(si); 194 return me_negateset((x.includeI(home, csi))); 195 } 196 197 template<class View> 198 forceinline ModEvent 199 ComplementView<View>::intersect(Space& home, int i, int j) { 200 Iter::Ranges::Singleton si(i,j); 201 RangesCompl<Iter::Ranges::Singleton> csi(si); 202 return me_negateset((x.includeI(home, csi))); 203 } 204 205 template<class View> 206 forceinline ModEvent 207 ComplementView<View>::include(Space& home, int j, int k) { 208 return me_negateset(x.exclude(home,j,k)); 209 } 210 211 template<class View> 212 forceinline ModEvent 213 ComplementView<View>::exclude(Space& home, int j, int k) { 214 return me_negateset(x.include(home,j,k)); 215 } 216 217 template<class View> 218 template<class I> ModEvent 219 ComplementView<View>::excludeI(Space& home,I& iter) { 220 return me_negateset(x.includeI(home,iter)); 221 } 222 223 template<class View> 224 template<class I> ModEvent 225 ComplementView<View>::includeI(Space& home,I& iter) { 226 return me_negateset(x.excludeI(home,iter)); 227 } 228 229 template<class View> 230 template<class I> ModEvent 231 ComplementView<View>::intersectI(Space& home,I& iter) { 232 RangesCompl<I> c(iter); 233 return me_negateset(x.includeI(home,c)); 234 } 235 236 template<class View> 237 forceinline void 238 ComplementView<View>::subscribe(Space& home, Propagator& p, PropCond pc, 239 bool schedule) { 240 x.subscribe(home,p, pc_negateset(pc),schedule); 241 } 242 243 template<class View> 244 forceinline void 245 ComplementView<View>::cancel(Space& home, Propagator& p, PropCond pc) { 246 x.cancel(home,p, pc_negateset(pc)); 247 } 248 249 template<class View> 250 forceinline void 251 ComplementView<View>::subscribe(Space& home, Advisor& a) { 252 x.subscribe(home,a); 253 } 254 255 template<class View> 256 forceinline void 257 ComplementView<View>::cancel(Space& home, Advisor& a) { 258 x.cancel(home,a); 259 } 260 261 template<class View> 262 forceinline void 263 ComplementView<View>::schedule(Space& home, Propagator& p, ModEvent me) { 264 return View::schedule(home,p,me_negateset(me)); 265 } 266 template<class View> 267 forceinline ModEvent 268 ComplementView<View>::me(const ModEventDelta& med) { 269 return me_negateset(View::me(med)); 270 } 271 272 template<class View> 273 forceinline ModEventDelta 274 ComplementView<View>::med(ModEvent me) { 275 return me_negateset(View::med(me)); 276 } 277 278 /* 279 * Delta information for advisors 280 * 281 */ 282 283 template<class View> 284 forceinline ModEvent 285 ComplementView<View>::modevent(const Delta& d) { 286 return me_negateset(View::modevent(d)); 287 } 288 289 template<class View> 290 forceinline int 291 ComplementView<View>::glbMin(const Delta& d) const { 292 return x.lubMin(d); 293 } 294 295 template<class View> 296 forceinline int 297 ComplementView<View>::glbMax(const Delta& d) const { 298 return x.lubMax(d); 299 } 300 301 template<class View> 302 forceinline bool 303 ComplementView<View>::glbAny(const Delta& d) const { 304 return x.lubAny(d); 305 } 306 307 template<class View> 308 forceinline int 309 ComplementView<View>::lubMin(const Delta& d) const { 310 return x.glbMin(d); 311 } 312 313 template<class View> 314 forceinline int 315 ComplementView<View>::lubMax(const Delta& d) const { 316 return x.glbMax(d); 317 } 318 319 template<class View> 320 forceinline bool 321 ComplementView<View>::lubAny(const Delta& d) const { 322 return x.glbAny(d); 323 } 324 325 326 /** 327 * \brief %Range iterator for least upper bound of complement set views 328 * \ingroup TaskActorSetView 329 */ 330 template<class View> 331 class LubRanges<ComplementView<View> > { 332 private: 333 GlbRanges<View> lb; 334 RangesCompl<GlbRanges<View> > lbc; 335 public: 336 /// \name Constructors and initialization 337 //@{ 338 /// Default constructor 339 LubRanges(void) {} 340 /// Initialize with ranges for view \a x 341 LubRanges(const ComplementView<View>& x); 342 /// Initialize with ranges for view \a x 343 void init(const ComplementView<View>& x); 344 //@} 345 346 /// \name Iteration control 347 //@{ 348 /// Test whether iterator is still at a range or done 349 bool operator ()(void) const; 350 /// Move iterator to next range (if possible) 351 void operator ++(void); 352 //@} 353 354 /// \name Range access 355 //@{ 356 /// Return smallest value of range 357 int min(void) const; 358 /// Return largest value of range 359 int max(void) const; 360 /// Return width of ranges (distance between minimum and maximum) 361 unsigned int width(void) const; 362 //@} 363 }; 364 365 template<class View> 366 forceinline 367 LubRanges<ComplementView<View> >::LubRanges(const ComplementView<View>& s) 368 : lb(s.base()), lbc(lb) {} 369 370 template<class View> 371 forceinline void 372 LubRanges<ComplementView<View> >::init(const ComplementView<View>& s) { 373 lb.init(s.base()); 374 lbc.init(lb); 375 } 376 377 template<class View> 378 forceinline bool 379 LubRanges<ComplementView<View> >::operator ()(void) const { return lbc(); } 380 381 template<class View> 382 forceinline void 383 LubRanges<ComplementView<View> >::operator ++(void) { return ++lbc; } 384 385 template<class View> 386 forceinline int 387 LubRanges<ComplementView<View> >::min(void) const { return lbc.min(); } 388 389 template<class View> 390 forceinline int 391 LubRanges<ComplementView<View> >::max(void) const { return lbc.max(); } 392 393 template<class View> 394 forceinline unsigned int 395 LubRanges<ComplementView<View> >::width(void) const { return lbc.width(); } 396 397 /** 398 * \brief Range iterator for the least upper bound of double-complement-views 399 * 400 * This class provides (by specialization) a range iterator 401 * for the least upper bounds of complements of complement set views. 402 * 403 * \ingroup TaskActorSet 404 */ 405 template<class View> 406 class LubRanges<ComplementView<ComplementView<View> > > : 407 public LubRanges<View> { 408 public: 409 /// \name Constructors and initialization 410 //@{ 411 /// Default constructor 412 LubRanges(void) {} 413 /// Initialize with ranges for view \a x 414 LubRanges(const ComplementView<ComplementView<View> >& x); 415 /// Initialize with ranges for view \a x 416 void init(const ComplementView<ComplementView<View> >& x); 417 //@} 418 }; 419 420 template<class View> 421 forceinline 422 LubRanges<ComplementView<ComplementView<View> > >:: 423 LubRanges(const ComplementView<ComplementView<View> >& x) : 424 LubRanges<View>(x) {} 425 426 template<class View> 427 forceinline void 428 LubRanges<ComplementView<ComplementView<View> > >:: 429 init(const ComplementView<ComplementView<View> >& x) { 430 LubRanges<View>::init(x); 431 } 432 433 /** 434 * \brief %Range iterator for greatest lower bound of complement set views 435 * \ingroup TaskActorSetView 436 */ 437 template<class View> 438 class GlbRanges<ComplementView<View> > { 439 private: 440 LubRanges<View> ub; 441 RangesCompl<LubRanges<View> > ubc; 442 public: 443 /// \name Constructors and initialization 444 //@{ 445 /// Default constructor 446 GlbRanges(void) {} 447 /// Initialize with ranges for view \a x 448 GlbRanges(const ComplementView<View> & x); 449 /// Initialize with ranges for view \a x 450 void init(const ComplementView<View> & x); 451 //@} 452 453 /// \name Iteration control 454 //@{ 455 /// Test whether iterator is still at a range or done 456 bool operator ()(void) const; 457 /// Move iterator to next range (if possible) 458 void operator ++(void); 459 //@} 460 461 /// \name Range access 462 //@{ 463 /// Return smallest value of range 464 int min(void) const; 465 /// Return largest value of range 466 int max(void) const; 467 /// Return width of ranges (distance between minimum and maximum) 468 unsigned int width(void) const; 469 //@} 470 }; 471 472 template<class View> 473 forceinline 474 GlbRanges<ComplementView<View> >::GlbRanges(const ComplementView<View> & s) 475 : ub(s.base()), ubc(ub) {} 476 477 template<class View> 478 forceinline void 479 GlbRanges<ComplementView<View> >::init(const ComplementView<View> & s) { 480 ub.init(s.base()); 481 ubc.init(ub); 482 } 483 484 template<class View> 485 forceinline bool 486 GlbRanges<ComplementView<View> >::operator ()(void) const { return ubc(); } 487 488 template<class View> 489 forceinline void 490 GlbRanges<ComplementView<View> >::operator ++(void) { return ++ubc; } 491 492 template<class View> 493 forceinline int 494 GlbRanges<ComplementView<View> >::min(void) const { return ubc.min(); } 495 496 template<class View> 497 forceinline int 498 GlbRanges<ComplementView<View> >::max(void) const { return ubc.max(); } 499 500 template<class View> 501 forceinline unsigned int 502 GlbRanges<ComplementView<View> >::width(void) const { return ubc.width(); } 503 504 /** 505 * \brief Range iterator for the greatest lower bound of double-complement-views 506 * 507 * This class provides (by specialization) a range iterator 508 * for the greatest lower bounds of complements of complement set views. 509 * 510 * \ingroup TaskActorSet 511 */ 512 template<class View> 513 class GlbRanges<ComplementView<ComplementView<View> > > : 514 public GlbRanges<View> { 515 public: 516 /// \name Constructors and initialization 517 //@{ 518 /// Default constructor 519 GlbRanges(void) {} 520 /// Initialize with ranges for view \a x 521 GlbRanges(const ComplementView<ComplementView<View> >& x); 522 /// Initialize with ranges for view \a x 523 void init(const ComplementView<ComplementView<View> >& x); 524 //@} 525 }; 526 527 template<class View> 528 forceinline 529 GlbRanges<ComplementView<ComplementView<View> > >:: 530 GlbRanges(const ComplementView<ComplementView<View> >& x) : 531 GlbRanges<View>(x) {} 532 533 template<class View> 534 forceinline void 535 GlbRanges<ComplementView<ComplementView<View> > >:: 536 init(const ComplementView<ComplementView<View> >& x) { 537 GlbRanges<View>::init(x); 538 } 539 540 template<class Char, class Traits, class View> 541 std::basic_ostream<Char,Traits>& 542 operator <<(std::basic_ostream<Char,Traits>& os, 543 const ComplementView<View>& x) { 544 std::basic_ostringstream<Char,Traits> s; 545 s.copyfmt(os); s.width(0); 546 s << "(" << x.base() << ")^C"; 547 return os << s.str(); 548 } 549 550 551 template<class View> 552 forceinline bool 553 operator ==(const ComplementView<View>& x, const ComplementView<View>& y) { 554 return x.base() == y.base(); 555 } 556 557 template<class View> 558 forceinline bool 559 operator !=(const ComplementView<View>& x, const ComplementView<View>& y) { 560 return x.base() != y.base(); 561 } 562 563}} 564 565// STATISTICS: set-var