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 * Christian Schulte <schulte@gecode.org> 6 * Mikael Lagerkvist <lagerkvist@gecode.org> 7 * 8 * Copyright: 9 * Guido Tack, 2005 10 * Christian Schulte, 2005 11 * Mikael Lagerkvist, 2005 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 "test/set.hh" 39 40#include <algorithm> 41 42namespace Test { namespace Set { 43 44 CountableSet::CountableSet(const Gecode::IntSet& d0) : d(d0), cur(0) { 45 Gecode::IntSetRanges isr(d); 46 lubmax = 47 static_cast<unsigned int>(pow(static_cast<double>(2.0), 48 static_cast<int>(Gecode::Iter::Ranges::size(isr)))); 49 } 50 51 void CountableSet::operator++(void) { 52 cur++; 53 } 54 55 void CountableSet::init(const Gecode::IntSet& d0) { 56 d = d0; 57 cur = 0; 58 Gecode::IntSetRanges isr(d); 59 lubmax = 60 static_cast<unsigned int>(pow(static_cast<double>(2.0), 61 static_cast<int>(Gecode::Iter::Ranges::size(isr)))); 62 } 63 64 int CountableSet::val(void) const { 65 return cur; 66 } 67 68 SetAssignment::SetAssignment(int n0, const Gecode::IntSet& d0, int _withInt) 69 : n(n0), dsv(new CountableSet[n]), ir(_withInt, d0), done(false), lub(d0), 70 withInt(_withInt) { 71 for (int i=n; i--; ) 72 dsv[i].init(lub); 73 } 74 75 void 76 SetAssignment::operator++(void) { 77 int i = n-1; 78 while (true) { 79 ++dsv[i]; 80 if (dsv[i]()) 81 return; 82 dsv[i].init(lub); 83 --i; 84 if (i<0) { 85 if (withInt==0) { 86 done = true; 87 return; 88 } 89 ++ir; 90 if (ir()) { 91 i = n-1; 92 for (int j=n; j--; ) 93 dsv[j].init(lub); 94 } else { 95 done = true; 96 return; 97 } 98 } 99 } 100 } 101 102}} 103 104std::ostream& 105operator<<(std::ostream& os, const Test::Set::SetAssignment& a) { 106 int n = a.size(); 107 os << "{"; 108 for (int i=0; i<n; i++) { 109 Test::Set::CountableSetRanges csv(a.lub, a[i]); 110 Gecode::IntSet icsv(csv); 111 os << icsv << ((i!=n-1) ? "," : "}"); 112 } 113 if (a.withInt > 0) 114 os << a.ints(); 115 return os; 116} 117 118namespace Test { namespace Set { 119 120 SetTestSpace::SetTestSpace(int n, Gecode::IntSet& d0, int i, 121 SetTest* t, bool log) 122 : d(d0), y(*this, i, d), 123 withInt(i), r(Gecode::BoolVar(*this, 0, 1),Gecode::RM_EQV), 124 reified(false), test(t) { 125 using namespace Gecode; 126 IntSet u(Gecode::Set::Limits::min,Gecode::Set::Limits::max); 127 x = SetVarArray(*this, n, Gecode::IntSet::empty, u); 128 SetVarArgs _x(*this, n, Gecode::IntSet::empty, d); 129 if (x.size() == 1) 130 dom(*this,x[0],_x[0]); 131 else 132 dom(*this,x,_x); 133 if (opt.log && log) { 134 olog << ind(2) << "Initial: x[]=" << x; 135 olog << " y[]=" << y; 136 olog << std::endl; 137 } 138 } 139 140 SetTestSpace::SetTestSpace(int n, Gecode::IntSet& d0, int i, 141 SetTest* t, Gecode::ReifyMode rm, bool log) 142 : d(d0), x(*this, n, Gecode::IntSet::empty, d), y(*this, i, d), 143 withInt(i), r(Gecode::BoolVar(*this, 0, 1),rm), 144 reified(true), test(t) { 145 if (opt.log && log) { 146 olog << ind(2) << "Initial: x[]=" << x; 147 olog << " y[]=" << y; 148 olog << " b=" << r.var(); 149 olog << std::endl; 150 } 151 } 152 153 SetTestSpace::SetTestSpace(SetTestSpace& s) 154 : Gecode::Space(s), d(s.d), withInt(s.withInt), 155 reified(s.reified), test(s.test) { 156 x.update(*this, s.x); 157 y.update(*this, s.y); 158 Gecode::BoolVar b; 159 Gecode::BoolVar sr(s.r.var()); 160 b.update(*this, sr); 161 r.var(b); r.mode(s.r.mode()); 162 } 163 164 Gecode::Space* 165 SetTestSpace::copy(void) { 166 return new SetTestSpace(*this); 167 } 168 169 void 170 SetTestSpace::post(void) { 171 if (reified){ 172 test->post(*this,x,y,r); 173 if (opt.log) 174 olog << ind(3) << "Posting reified propagator" << std::endl; 175 } else { 176 test->post(*this,x,y); 177 if (opt.log) 178 olog << ind(3) << "Posting propagator" << std::endl; 179 } 180 } 181 182 bool 183 SetTestSpace::failed(void) { 184 if (opt.log) { 185 olog << ind(3) << "Fixpoint: x[]=" << x 186 << " y[]=" << y << std::endl; 187 bool f=(status() == Gecode::SS_FAILED); 188 olog << ind(3) << " --> x[]=" << x 189 << " y[]=" << y << std::endl; 190 return f; 191 } else { 192 return status() == Gecode::SS_FAILED; 193 } 194 } 195 196 bool 197 SetTestSpace::subsumed(bool b) { 198 return b ? (propagators() == 0) : true; 199 } 200 201 void 202 SetTestSpace::rel(int i, Gecode::SetRelType srt, const Gecode::IntSet& is) { 203 if (opt.log) { 204 olog << ind(4) << "x[" << i << "] "; 205 switch (srt) { 206 case Gecode::SRT_EQ: olog << "="; break; 207 case Gecode::SRT_LQ: olog << "<="; break; 208 case Gecode::SRT_LE: olog << "<"; break; 209 case Gecode::SRT_GQ: olog << ">="; break; 210 case Gecode::SRT_GR: olog << ">"; break; 211 case Gecode::SRT_NQ: olog << "!="; break; 212 case Gecode::SRT_SUB: olog << "sub"; break; 213 case Gecode::SRT_SUP: olog << "sup"; break; 214 case Gecode::SRT_DISJ: olog << "||"; break; 215 case Gecode::SRT_CMPL: olog << "^-1 = "; break; 216 } 217 olog << is << std::endl; 218 } 219 Gecode::dom(*this, x[i], srt, is); 220 } 221 222 void 223 SetTestSpace::cardinality(int i, int cmin, int cmax) { 224 if (opt.log) { 225 olog << ind(4) << cmin << " <= #(x[" << i << "]) <= " << cmax 226 << std::endl; 227 } 228 Gecode::cardinality(*this, x[i], cmin, cmax); 229 } 230 231 void 232 SetTestSpace::rel(int i, Gecode::IntRelType irt, int n) { 233 if (opt.log) { 234 olog << ind(4) << "y[" << i << "] "; 235 switch (irt) { 236 case Gecode::IRT_EQ: olog << "="; break; 237 case Gecode::IRT_NQ: olog << "!="; break; 238 case Gecode::IRT_LQ: olog << "<="; break; 239 case Gecode::IRT_LE: olog << "<"; break; 240 case Gecode::IRT_GQ: olog << ">="; break; 241 case Gecode::IRT_GR: olog << ">"; break; 242 } 243 olog << " " << n << std::endl; 244 } 245 Gecode::rel(*this, y[i], irt, n); 246 } 247 248 void 249 SetTestSpace::rel(bool sol) { 250 int n = sol ? 1 : 0; 251 assert(reified); 252 if (opt.log) 253 olog << ind(4) << "b = " << n << std::endl; 254 Gecode::rel(*this, r.var(), Gecode::IRT_EQ, n); 255 } 256 257 void 258 SetTestSpace::assign(const SetAssignment& a) { 259 for (int i=a.size(); i--; ) { 260 CountableSetRanges csv(a.lub, a[i]); 261 Gecode::IntSet ai(csv); 262 rel(i, Gecode::SRT_EQ, ai); 263 if (Base::fixpoint() && failed()) 264 return; 265 } 266 for (int i=withInt; i--; ) { 267 rel(i, Gecode::IRT_EQ, a.ints()[i]); 268 if (Base::fixpoint() && failed()) 269 return; 270 } 271 } 272 273 bool 274 SetTestSpace::assigned(void) const { 275 for (int i=x.size(); i--; ) 276 if (!x[i].assigned()) 277 return false; 278 for (int i=y.size(); i--; ) 279 if (!y[i].assigned()) 280 return false; 281 return true; 282 } 283 284 void 285 SetTestSpace::removeFromLub(int v, int i, const SetAssignment& a) { 286 using namespace Gecode; 287 SetVarUnknownRanges ur(x[i]); 288 CountableSetRanges air(a.lub, a[i]); 289 Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges, 290 CountableSetRanges> diff(ur, air); 291 Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Diff 292 <Gecode::SetVarUnknownRanges, CountableSetRanges> > diffV(diff); 293 for (int j=0; j<v; j++, ++diffV) {} 294 rel(i, Gecode::SRT_DISJ, Gecode::IntSet(diffV.val(), diffV.val())); 295 } 296 297 void 298 SetTestSpace::removeFromLub(int v, int i, const SetAssignment& a, 299 SetTestSpace& c) { 300 using namespace Gecode; 301 SetVarUnknownRanges ur(x[i]); 302 CountableSetRanges air(a.lub, a[i]); 303 Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges, 304 CountableSetRanges> diff(ur, air); 305 Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Diff 306 <Gecode::SetVarUnknownRanges, CountableSetRanges> > diffV(diff); 307 for (int j=0; j<v; j++, ++diffV) {} 308 rel(i, Gecode::SRT_DISJ, Gecode::IntSet(diffV.val(), diffV.val())); 309 c.rel(i, Gecode::SRT_DISJ, Gecode::IntSet(diffV.val(), diffV.val())); 310 } 311 312 void 313 SetTestSpace::addToGlb(int v, int i, const SetAssignment& a) { 314 using namespace Gecode; 315 SetVarUnknownRanges ur(x[i]); 316 CountableSetRanges air(a.lub, a[i]); 317 Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges, 318 CountableSetRanges> inter(ur, air); 319 Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Inter 320 <Gecode::SetVarUnknownRanges, CountableSetRanges> > interV(inter); 321 for (int j=0; j<v; j++, ++interV) {} 322 rel(i, Gecode::SRT_SUP, Gecode::IntSet(interV.val(), interV.val())); 323 } 324 325 void 326 SetTestSpace::addToGlb(int v, int i, const SetAssignment& a, 327 SetTestSpace& c) { 328 using namespace Gecode; 329 SetVarUnknownRanges ur(x[i]); 330 CountableSetRanges air(a.lub, a[i]); 331 Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges, 332 CountableSetRanges> inter(ur, air); 333 Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Inter 334 <Gecode::SetVarUnknownRanges, CountableSetRanges> > interV(inter); 335 for (int j=0; j<v; j++, ++interV) {} 336 rel(i, Gecode::SRT_SUP, Gecode::IntSet(interV.val(), interV.val())); 337 c.rel(i, Gecode::SRT_SUP, Gecode::IntSet(interV.val(), interV.val())); 338 } 339 340 bool 341 SetTestSpace::fixprob(void) { 342 if (failed()) 343 return true; 344 SetTestSpace* c = static_cast<SetTestSpace*>(clone()); 345 if (opt.log) 346 olog << ind(3) << "Testing fixpoint on copy" << std::endl; 347 c->post(); 348 if (c->failed()) { 349 delete c; return false; 350 } 351 352 for (int i=x.size(); i--; ) 353 if (x[i].glbSize() != c->x[i].glbSize() || 354 x[i].lubSize() != c->x[i].lubSize() || 355 x[i].cardMin() != c->x[i].cardMin() || 356 x[i].cardMax() != c->x[i].cardMax()) { 357 delete c; 358 return false; 359 } 360 for (int i=y.size(); i--; ) 361 if (y[i].size() != c->y[i].size()) { 362 delete c; return false; 363 } 364 if (reified && (r.var().size() != c->r.var().size())) { 365 delete c; return false; 366 } 367 if (opt.log) 368 olog << ind(3) << "Finished testing fixpoint on copy" << std::endl; 369 delete c; 370 return true; 371 } 372 373 bool 374 SetTestSpace::same(SetTestSpace& c) { 375 if (opt.log) 376 olog << ind(3) << "Testing whether enabled space is the same" 377 << std::endl; 378 bool f = failed(); 379 bool cf = c.failed(); 380 if (f != cf) 381 return false; 382 if (f) 383 return true; 384 385 for (int i=x.size(); i--; ) 386 if (x[i].glbSize() != c.x[i].glbSize() || 387 x[i].lubSize() != c.x[i].lubSize() || 388 x[i].cardMin() != c.x[i].cardMin() || 389 x[i].cardMax() != c.x[i].cardMax()) 390 return false; 391 392 for (int i=y.size(); i--; ) 393 if (y[i].size() != c.y[i].size()) 394 return false; 395 396 if (reified && (r.var().size() != c.r.var().size())) 397 return false; 398 if (opt.log) 399 olog << ind(3) << "Finished testing whether enabled space is the same" 400 << std::endl; 401 return true; 402 } 403 404 bool 405 SetTestSpace::prune(const SetAssignment& a) { 406 using namespace Gecode; 407 bool setsAssigned = true; 408 for (int j=x.size(); j--; ) 409 if (!x[j].assigned()) { 410 setsAssigned = false; 411 break; 412 } 413 bool intsAssigned = true; 414 for (int j=y.size(); j--; ) 415 if (!y[j].assigned()) { 416 intsAssigned = false; 417 break; 418 } 419 420 // Select variable to be pruned 421 int i; 422 if (intsAssigned) { 423 i = Base::rand(x.size()); 424 } else if (setsAssigned) { 425 i = Base::rand(y.size()); 426 } else { 427 i = Base::rand(x.size()+y.size()); 428 } 429 430 if (setsAssigned || i>=x.size()) { 431 if (i>=x.size()) 432 i = i-x.size(); 433 while (y[i].assigned()) { 434 i = (i+1) % y.size(); 435 } 436 // Prune int var 437 438 // Select mode for pruning 439 switch (Base::rand(3)) { 440 case 0: 441 if (a.ints()[i] < y[i].max()) { 442 int v=a.ints()[i]+1+ 443 Base::rand(static_cast<unsigned int>(y[i].max()-a.ints()[i])); 444 assert((v > a.ints()[i]) && (v <= y[i].max())); 445 rel(i, Gecode::IRT_LE, v); 446 } 447 break; 448 case 1: 449 if (a.ints()[i] > y[i].min()) { 450 int v=y[i].min()+ 451 Base::rand(static_cast<unsigned int>(a.ints()[i]-y[i].min())); 452 assert((v < a.ints()[i]) && (v >= y[i].min())); 453 rel(i, Gecode::IRT_GR, v); 454 } 455 break; 456 default: 457 int v; 458 Gecode::Int::ViewRanges<Gecode::Int::IntView> it(y[i]); 459 unsigned int skip = Base::rand(y[i].size()-1); 460 while (true) { 461 if (it.width() > skip) { 462 v = it.min() + skip; 463 if (v == a.ints()[i]) { 464 if (it.width() == 1) { 465 ++it; v = it.min(); 466 } else if (v < it.max()) { 467 ++v; 468 } else { 469 --v; 470 } 471 } 472 break; 473 } 474 skip -= it.width(); 475 ++it; 476 } 477 rel(i, Gecode::IRT_NQ, v); 478 } 479 return (!Base::fixpoint() || fixprob()); 480 } 481 while (x[i].assigned()) { 482 i = (i+1) % x.size(); 483 } 484 Gecode::SetVarUnknownRanges ur1(x[i]); 485 CountableSetRanges air1(a.lub, a[i]); 486 Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges, 487 CountableSetRanges> diff(ur1, air1); 488 Gecode::SetVarUnknownRanges ur2(x[i]); 489 CountableSetRanges air2(a.lub, a[i]); 490 Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges, 491 CountableSetRanges> inter(ur2, air2); 492 493 CountableSetRanges aisizer(a.lub, a[i]); 494 unsigned int aisize = Gecode::Iter::Ranges::size(aisizer); 495 496 // Select mode for pruning 497 switch (Base::rand(5)) { 498 case 0: 499 if (inter()) { 500 int v = Base::rand(Gecode::Iter::Ranges::size(inter)); 501 addToGlb(v, i, a); 502 } 503 break; 504 case 1: 505 if (diff()) { 506 int v = Base::rand(Gecode::Iter::Ranges::size(diff)); 507 removeFromLub(v, i, a); 508 } 509 break; 510 case 2: 511 if (x[i].cardMin() < aisize) { 512 unsigned int newc = x[i].cardMin() + 1 + 513 Base::rand(aisize - x[i].cardMin()); 514 assert( newc > x[i].cardMin() ); 515 assert( newc <= aisize ); 516 cardinality(i, newc, Gecode::Set::Limits::card); 517 } 518 break; 519 case 3: 520 if (x[i].cardMax() > aisize) { 521 unsigned int newc = x[i].cardMax() - 1 - 522 Base::rand(x[i].cardMax() - aisize); 523 assert( newc < x[i].cardMax() ); 524 assert( newc >= aisize ); 525 cardinality(i, 0, newc); 526 } 527 break; 528 default: 529 if (inter()) { 530 int v = Base::rand(Gecode::Iter::Ranges::size(inter)); 531 addToGlb(v, i, a); 532 } else { 533 int v = Base::rand(Gecode::Iter::Ranges::size(diff)); 534 removeFromLub(v, i, a); 535 } 536 } 537 return (!Base::fixpoint() || fixprob()); 538 } 539 540 bool 541 SetTestSpace::disabled(const SetAssignment& a, SetTestSpace& c) { 542 c.disable(); 543 using namespace Gecode; 544 bool setsAssigned = true; 545 for (int j=x.size(); j--; ) 546 if (!x[j].assigned()) { 547 setsAssigned = false; 548 break; 549 } 550 bool intsAssigned = true; 551 for (int j=y.size(); j--; ) 552 if (!y[j].assigned()) { 553 intsAssigned = false; 554 break; 555 } 556 557 // Select variable to be pruned 558 int i; 559 if (intsAssigned) { 560 i = Base::rand(x.size()); 561 } else if (setsAssigned) { 562 i = Base::rand(y.size()); 563 } else { 564 i = Base::rand(x.size()+y.size()); 565 } 566 567 if (setsAssigned || i>=x.size()) { 568 if (i>=x.size()) 569 i = i-x.size(); 570 while (y[i].assigned()) { 571 i = (i+1) % y.size(); 572 } 573 // Prune int var 574 575 // Select mode for pruning 576 switch (Base::rand(3)) { 577 case 0: 578 if (a.ints()[i] < y[i].max()) { 579 int v=a.ints()[i]+1+ 580 Base::rand(static_cast<unsigned int>(y[i].max()-a.ints()[i])); 581 assert((v > a.ints()[i]) && (v <= y[i].max())); 582 rel(i, Gecode::IRT_LE, v); 583 c.rel(i, Gecode::IRT_LE, v); 584 } 585 break; 586 case 1: 587 if (a.ints()[i] > y[i].min()) { 588 int v=y[i].min()+ 589 Base::rand(static_cast<unsigned int>(a.ints()[i]-y[i].min())); 590 assert((v < a.ints()[i]) && (v >= y[i].min())); 591 rel(i, Gecode::IRT_GR, v); 592 c.rel(i, Gecode::IRT_GR, v); 593 } 594 break; 595 default: 596 int v; 597 Gecode::Int::ViewRanges<Gecode::Int::IntView> it(y[i]); 598 unsigned int skip = Base::rand(y[i].size()-1); 599 while (true) { 600 if (it.width() > skip) { 601 v = it.min() + skip; 602 if (v == a.ints()[i]) { 603 if (it.width() == 1) { 604 ++it; v = it.min(); 605 } else if (v < it.max()) { 606 ++v; 607 } else { 608 --v; 609 } 610 } 611 break; 612 } 613 skip -= it.width(); 614 ++it; 615 } 616 rel(i, Gecode::IRT_NQ, v); 617 c.rel(i, Gecode::IRT_NQ, v); 618 } 619 c.enable(); 620 return same(c); 621 } 622 while (x[i].assigned()) { 623 i = (i+1) % x.size(); 624 } 625 Gecode::SetVarUnknownRanges ur1(x[i]); 626 CountableSetRanges air1(a.lub, a[i]); 627 Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges, 628 CountableSetRanges> diff(ur1, air1); 629 Gecode::SetVarUnknownRanges ur2(x[i]); 630 CountableSetRanges air2(a.lub, a[i]); 631 Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges, 632 CountableSetRanges> inter(ur2, air2); 633 634 CountableSetRanges aisizer(a.lub, a[i]); 635 unsigned int aisize = Gecode::Iter::Ranges::size(aisizer); 636 637 // Select mode for pruning 638 switch (Base::rand(5)) { 639 case 0: 640 if (inter()) { 641 int v = Base::rand(Gecode::Iter::Ranges::size(inter)); 642 addToGlb(v, i, a, c); 643 } 644 break; 645 case 1: 646 if (diff()) { 647 int v = Base::rand(Gecode::Iter::Ranges::size(diff)); 648 removeFromLub(v, i, a, c); 649 } 650 break; 651 case 2: 652 if (x[i].cardMin() < aisize) { 653 unsigned int newc = x[i].cardMin() + 1 + 654 Base::rand(aisize - x[i].cardMin()); 655 assert( newc > x[i].cardMin() ); 656 assert( newc <= aisize ); 657 cardinality(i, newc, Gecode::Set::Limits::card); 658 c.cardinality(i, newc, Gecode::Set::Limits::card); 659 } 660 break; 661 case 3: 662 if (x[i].cardMax() > aisize) { 663 unsigned int newc = x[i].cardMax() - 1 - 664 Base::rand(x[i].cardMax() - aisize); 665 assert( newc < x[i].cardMax() ); 666 assert( newc >= aisize ); 667 cardinality(i, 0, newc); 668 c.cardinality(i, 0, newc); 669 } 670 break; 671 default: 672 if (inter()) { 673 int v = Base::rand(Gecode::Iter::Ranges::size(inter)); 674 addToGlb(v, i, a, c); 675 } else { 676 int v = Base::rand(Gecode::Iter::Ranges::size(diff)); 677 removeFromLub(v, i, a, c); 678 } 679 } 680 c.enable(); 681 return same(c); 682 } 683 684 unsigned int 685 SetTestSpace::propagators(void) { 686 return Gecode::PropagatorGroup::all.size(*this); 687 } 688 689 void 690 SetTestSpace::enable(void) { 691 Gecode::PropagatorGroup::all.enable(*this); 692 } 693 694 void 695 SetTestSpace::disable(void) { 696 Gecode::PropagatorGroup::all.disable(*this); 697 (void) status(); 698 } 699 700 701 /// Check the test result and handle failed test 702#define CHECK_TEST(T,M) \ 703if (opt.log) \ 704 olog << ind(3) << "Check: " << (M) << std::endl; \ 705if (!(T)) { \ 706 problem = (M); delete s; goto failed; \ 707} 708 709 /// Start new test 710#define START_TEST(T) \ 711 if (opt.log) { \ 712 olog.str(""); \ 713 olog << ind(2) << "Testing: " << (T) << std::endl; \ 714 } \ 715 test = (T); 716 717 bool 718 SetTest::run(void) { 719 using namespace Gecode; 720 const char* test = "NONE"; 721 const char* problem = "NONE"; 722 723 SetAssignment* ap = new SetAssignment(arity,lub,withInt); 724 SetAssignment& a = *ap; 725 while (a()) { 726 bool is_sol = solution(a); 727 if (opt.log) 728 olog << ind(1) << "Assignment: " << a 729 << (is_sol ? " (solution)" : " (no solution)") 730 << std::endl; 731 START_TEST("Assignment (after posting)"); 732 { 733 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 734 SetTestSpace* sc = nullptr; 735 s->post(); 736 switch (Base::rand(2)) { 737 case 0: 738 if (opt.log) 739 olog << ind(3) << "No copy" << std::endl; 740 sc = s; 741 s = nullptr; 742 break; 743 case 1: 744 if (opt.log) 745 olog << ind(3) << "Copy" << std::endl; 746 if (s->status() != Gecode::SS_FAILED) { 747 sc = static_cast<SetTestSpace*>(s->clone()); 748 } else { 749 sc = s; s = nullptr; 750 } 751 break; 752 default: assert(false); 753 } 754 sc->assign(a); 755 if (is_sol) { 756 CHECK_TEST(!sc->failed(), "Failed on solution"); 757 CHECK_TEST(sc->subsumed(testsubsumed), "No subsumption"); 758 } else { 759 CHECK_TEST(sc->failed(), "Solved on non-solution"); 760 } 761 delete s; delete sc; 762 } 763 START_TEST("Assignment (after posting, disable)"); 764 { 765 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 766 s->post(); 767 s->disable(); 768 s->assign(a); 769 s->enable(); 770 if (is_sol) { 771 CHECK_TEST(!s->failed(), "Failed on solution"); 772 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 773 } else { 774 CHECK_TEST(s->failed(), "Solved on non-solution"); 775 } 776 delete s; 777 } 778 START_TEST("Assignment (before posting)"); 779 { 780 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 781 s->assign(a); 782 s->post(); 783 if (is_sol) { 784 CHECK_TEST(!s->failed(), "Failed on solution"); 785 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 786 } else { 787 CHECK_TEST(s->failed(), "Solved on non-solution"); 788 } 789 delete s; 790 } 791 START_TEST("Prune"); 792 { 793 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 794 s->post(); 795 while (!s->failed() && !s->assigned()) 796 if (!s->prune(a)) { 797 problem = "No fixpoint"; 798 delete s; 799 goto failed; 800 } 801 s->assign(a); 802 if (is_sol) { 803 CHECK_TEST(!s->failed(), "Failed on solution"); 804 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 805 } else { 806 CHECK_TEST(s->failed(), "Solved on non-solution"); 807 } 808 delete s; 809 } 810 if (disabled) { 811 START_TEST("Prune (disable)"); 812 { 813 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 814 SetTestSpace* c = new SetTestSpace(arity,lub,withInt,this); 815 s->post(); c->post(); 816 while (!s->failed() && !s->assigned()) 817 if (!s->disabled(a,*c)) { 818 problem = "Different result after re-enable"; 819 delete s; delete c; 820 goto failed; 821 } 822 s->assign(a); c->assign(a); 823 if (s->failed() != c->failed()) { 824 problem = "Different failure after re-enable"; 825 delete s; delete c; 826 goto failed; 827 } 828 delete s; delete c; 829 } 830 } 831 if (reified) { 832 START_TEST("Assignment reified (rewrite after post, <=>)"); 833 { 834 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 835 s->post(); 836 s->rel(is_sol); 837 s->assign(a); 838 CHECK_TEST(!s->failed(), "Failed"); 839 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 840 delete s; 841 } 842 START_TEST("Assignment reified (rewrite after post, =>)"); 843 { 844 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 845 s->post(); 846 s->rel(is_sol); 847 s->assign(a); 848 CHECK_TEST(!s->failed(), "Failed"); 849 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 850 delete s; 851 } 852 START_TEST("Assignment reified (rewrite after post, <=)"); 853 { 854 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 855 s->post(); 856 s->rel(is_sol); 857 s->assign(a); 858 CHECK_TEST(!s->failed(), "Failed"); 859 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 860 delete s; 861 } 862 { 863 START_TEST("Assignment reified (rewrite failure, <=>)"); 864 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 865 s->post(); 866 s->rel(!is_sol); 867 s->assign(a); 868 CHECK_TEST(s->failed(), "Not failed"); 869 delete s; 870 } 871 { 872 START_TEST("Assignment reified (rewrite failure, =>)"); 873 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 874 s->post(); 875 s->rel(!is_sol); 876 s->assign(a); 877 if (is_sol) { 878 CHECK_TEST(!s->failed(), "Failed"); 879 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 880 } else { 881 CHECK_TEST(s->failed(), "Not failed"); 882 } 883 delete s; 884 } 885 { 886 START_TEST("Assignment reified (rewrite failure, <=)"); 887 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 888 s->post(); 889 s->rel(!is_sol); 890 s->assign(a); 891 if (is_sol) { 892 CHECK_TEST(s->failed(), "Not failed"); 893 } else { 894 CHECK_TEST(!s->failed(), "Failed"); 895 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 896 } 897 delete s; 898 } 899 START_TEST("Assignment reified (immediate rewrite, <=>)"); 900 { 901 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 902 s->rel(is_sol); 903 s->post(); 904 s->assign(a); 905 CHECK_TEST(!s->failed(), "Failed"); 906 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 907 delete s; 908 } 909 START_TEST("Assignment reified (immediate rewrite, =>)"); 910 { 911 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 912 s->rel(is_sol); 913 s->post(); 914 s->assign(a); 915 CHECK_TEST(!s->failed(), "Failed"); 916 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 917 delete s; 918 } 919 START_TEST("Assignment reified (immediate rewrite, <=)"); 920 { 921 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 922 s->rel(is_sol); 923 s->post(); 924 s->assign(a); 925 CHECK_TEST(!s->failed(), "Failed"); 926 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 927 delete s; 928 } 929 START_TEST("Assignment reified (immediate failure, <=>)"); 930 { 931 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 932 s->rel(!is_sol); 933 s->post(); 934 s->assign(a); 935 CHECK_TEST(s->failed(), "Not failed"); 936 delete s; 937 } 938 START_TEST("Assignment reified (immediate failure, =>)"); 939 { 940 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 941 s->rel(!is_sol); 942 s->post(); 943 s->assign(a); 944 if (is_sol) { 945 CHECK_TEST(!s->failed(), "Failed"); 946 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 947 } else { 948 CHECK_TEST(s->failed(), "Not failed"); 949 } 950 delete s; 951 } 952 START_TEST("Assignment reified (immediate failure, <=)"); 953 { 954 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 955 s->rel(!is_sol); 956 s->post(); 957 s->assign(a); 958 if (is_sol) { 959 CHECK_TEST(s->failed(), "Not failed"); 960 } else { 961 CHECK_TEST(!s->failed(), "Failed"); 962 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 963 } 964 delete s; 965 } 966 START_TEST("Assignment reified (before posting, <=>)"); 967 { 968 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 969 s->assign(a); 970 s->post(); 971 CHECK_TEST(!s->failed(), "Failed"); 972 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 973 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 974 if (is_sol) { 975 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 976 } else { 977 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 978 } 979 delete s; 980 } 981 START_TEST("Assignment reified (before posting, =>)"); 982 { 983 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 984 s->assign(a); 985 s->post(); 986 CHECK_TEST(!s->failed(), "Failed"); 987 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 988 if (is_sol) { 989 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 990 } else { 991 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 992 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 993 } 994 delete s; 995 } 996 START_TEST("Assignment reified (before posting, <=)"); 997 { 998 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 999 s->assign(a); 1000 s->post(); 1001 CHECK_TEST(!s->failed(), "Failed"); 1002 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1003 if (is_sol) { 1004 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1005 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1006 } else { 1007 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1008 } 1009 delete s; 1010 } 1011 START_TEST("Assignment reified (after posting, <=>)"); 1012 { 1013 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 1014 s->post(); 1015 s->assign(a); 1016 CHECK_TEST(!s->failed(), "Failed"); 1017 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1018 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1019 if (is_sol) { 1020 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1021 } else { 1022 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1023 } 1024 delete s; 1025 } 1026 START_TEST("Assignment reified (after posting, =>)"); 1027 { 1028 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 1029 s->post(); 1030 s->assign(a); 1031 CHECK_TEST(!s->failed(), "Failed"); 1032 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1033 if (is_sol) { 1034 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1035 } else { 1036 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1037 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1038 } 1039 delete s; 1040 } 1041 START_TEST("Assignment reified (after posting, <=)"); 1042 { 1043 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1044 s->post(); 1045 s->assign(a); 1046 CHECK_TEST(!s->failed(), "Failed"); 1047 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1048 if (is_sol) { 1049 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1050 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1051 } else { 1052 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1053 } 1054 delete s; 1055 } 1056 START_TEST("Assignment reified (after posting, <=>, disable)"); 1057 { 1058 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 1059 s->post(); 1060 s->disable(); 1061 s->assign(a); 1062 s->enable(); 1063 CHECK_TEST(!s->failed(), "Failed"); 1064 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1065 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1066 if (is_sol) { 1067 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1068 } else { 1069 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1070 } 1071 delete s; 1072 } 1073 START_TEST("Assignment reified (after posting, =>, disable)"); 1074 { 1075 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 1076 s->post(); 1077 s->disable(); 1078 s->assign(a); 1079 s->enable(); 1080 CHECK_TEST(!s->failed(), "Failed"); 1081 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1082 if (is_sol) { 1083 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1084 } else { 1085 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1086 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1087 } 1088 delete s; 1089 } 1090 START_TEST("Assignment reified (after posting, <=, disable)"); 1091 { 1092 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1093 s->post(); 1094 s->disable(); 1095 s->assign(a); 1096 s->enable(); 1097 CHECK_TEST(!s->failed(), "Failed"); 1098 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1099 if (is_sol) { 1100 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1101 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1102 } else { 1103 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1104 } 1105 delete s; 1106 } 1107 START_TEST("Prune reified, <=>"); 1108 { 1109 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 1110 s->post(); 1111 while (!s->failed() && 1112 (!s->assigned() || !s->r.var().assigned())) 1113 if (!s->prune(a)) { 1114 problem = "No fixpoint"; 1115 delete s; 1116 goto failed; 1117 } 1118 CHECK_TEST(!s->failed(), "Failed"); 1119 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1120 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1121 if (is_sol) { 1122 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1123 } else { 1124 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1125 } 1126 delete s; 1127 } 1128 START_TEST("Prune reified, =>"); 1129 { 1130 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 1131 s->post(); 1132 while (!s->failed() && 1133 (!s->assigned() || (!is_sol && !s->r.var().assigned()))) { 1134 if (!s->prune(a)) { 1135 problem = "No fixpoint"; 1136 delete s; 1137 goto failed; 1138 } 1139 } 1140 CHECK_TEST(!s->failed(), "Failed"); 1141 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1142 if (is_sol) { 1143 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1144 } else { 1145 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1146 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1147 } 1148 delete s; 1149 } 1150 START_TEST("Prune reified, <="); 1151 { 1152 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1153 s->post(); 1154 while (!s->failed() && 1155 (!s->assigned() || (is_sol && !s->r.var().assigned()))) 1156 if (!s->prune(a)) { 1157 problem = "No fixpoint"; 1158 delete s; 1159 goto failed; 1160 } 1161 CHECK_TEST(!s->failed(), "Failed"); 1162 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1163 if (is_sol) { 1164 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1165 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1166 } else { 1167 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1168 } 1169 delete s; 1170 } 1171 } 1172 ++a; 1173 } 1174 delete ap; 1175 return true; 1176 failed: 1177 if (opt.log) 1178 olog << "FAILURE" << std::endl 1179 << ind(1) << "Test: " << test << std::endl 1180 << ind(1) << "Problem: " << problem << std::endl; 1181 if (a() && opt.log) 1182 olog << ind(1) << "Assignment: " << a << std::endl; 1183 delete ap; 1184 1185 return false; 1186 } 1187 1188 const Gecode::SetRelType SetRelTypes::srts[] = 1189 {Gecode::SRT_EQ,Gecode::SRT_NQ,Gecode::SRT_SUB, 1190 Gecode::SRT_SUP,Gecode::SRT_DISJ,Gecode::SRT_CMPL}; 1191 1192 const Gecode::SetOpType SetOpTypes::sots[] = 1193 {Gecode::SOT_UNION, Gecode::SOT_DUNION, 1194 Gecode::SOT_INTER, Gecode::SOT_MINUS}; 1195 1196}} 1197 1198#undef START_TEST 1199#undef CHECK_TEST 1200 1201// STATISTICS: test-set