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::next(Gecode::Support::RandomGenerator& rand) { 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.next(rand); 90 if (ir.has_more()) { 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, Gecode::Support::RandomGenerator& rand) { 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(rand) && failed()) 264 return; 265 } 266 for (int i=withInt; i--; ) { 267 rel(i, Gecode::IRT_EQ, a.ints()[i]); 268 if (Base::fixpoint(rand) && 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, Gecode::Support::RandomGenerator& rand) { 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 = rand(x.size()); 424 } else if (setsAssigned) { 425 i = rand(y.size()); 426 } else { 427 i = 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 (rand(3)) { 440 case 0: 441 if (a.ints()[i] < y[i].max()) { 442 int v=a.ints()[i]+1+ 443 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 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 = 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(rand) || 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 (rand(5)) { 498 case 0: 499 if (inter()) { 500 int v = rand(Gecode::Iter::Ranges::size(inter)); 501 addToGlb(v, i, a); 502 } 503 break; 504 case 1: 505 if (diff()) { 506 int v = 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 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 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 = rand(Gecode::Iter::Ranges::size(inter)); 531 addToGlb(v, i, a); 532 } else { 533 int v = rand(Gecode::Iter::Ranges::size(diff)); 534 removeFromLub(v, i, a); 535 } 536 } 537 return (!Base::fixpoint(rand) || fixprob()); 538 } 539 540 bool 541 SetTestSpace::disabled(const SetAssignment& a, SetTestSpace& c, Gecode::Support::RandomGenerator& rand) { 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 = rand(x.size()); 561 } else if (setsAssigned) { 562 i = rand(y.size()); 563 } else { 564 i = 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 (rand(3)) { 577 case 0: 578 if (a.ints()[i] < y[i].max()) { 579 int v=a.ints()[i]+1+ 580 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 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 = 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 (rand(5)) { 639 case 0: 640 if (inter()) { 641 int v = rand(Gecode::Iter::Ranges::size(inter)); 642 addToGlb(v, i, a, c); 643 } 644 break; 645 case 1: 646 if (diff()) { 647 int v = 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 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 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 = rand(Gecode::Iter::Ranges::size(inter)); 674 addToGlb(v, i, a, c); 675 } else { 676 int v = 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) \ 703do { \ 704if (opt.log) \ 705 olog << ind(3) << "Check: " << (M) << std::endl; \ 706if (!(T)) { \ 707 problem = (M); delete s; goto failed; \ 708} \ 709} while (false) 710 711 /// Start new test 712#define START_TEST(T) \ 713 do { \ 714 if (opt.log) { \ 715 olog.str(""); \ 716 olog << ind(2) << "Testing: " << (T) << std::endl; \ 717 } \ 718 test = (T); \ 719 } while (false) 720 721 bool 722 SetTest::run(void) { 723 using namespace Gecode; 724 const char* test = "NONE"; 725 const char* problem = "NONE"; 726 727 SetAssignment* ap = new SetAssignment(arity,lub,withInt); 728 SetAssignment& a = *ap; 729 while (a()) { 730 bool is_sol = solution(a); 731 if (opt.log) 732 olog << ind(1) << "Assignment: " << a 733 << (is_sol ? " (solution)" : " (no solution)") 734 << std::endl; 735 START_TEST("Assignment (after posting)"); 736 { 737 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 738 SetTestSpace* sc = nullptr; 739 s->post(); 740 switch (_rand(2)) { 741 case 0: 742 if (opt.log) 743 olog << ind(3) << "No copy" << std::endl; 744 sc = s; 745 s = nullptr; 746 break; 747 case 1: 748 if (opt.log) 749 olog << ind(3) << "Copy" << std::endl; 750 if (s->status() != Gecode::SS_FAILED) { 751 sc = static_cast<SetTestSpace*>(s->clone()); 752 } else { 753 sc = s; s = nullptr; 754 } 755 break; 756 default: assert(false); 757 } 758 sc->assign(a, _rand); 759 if (is_sol) { 760 CHECK_TEST(!sc->failed(), "Failed on solution"); 761 CHECK_TEST(sc->subsumed(testsubsumed), "No subsumption"); 762 } else { 763 CHECK_TEST(sc->failed(), "Solved on non-solution"); 764 } 765 delete s; delete sc; 766 } 767 START_TEST("Assignment (after posting, disable)"); 768 { 769 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 770 s->post(); 771 s->disable(); 772 s->assign(a, _rand); 773 s->enable(); 774 if (is_sol) { 775 CHECK_TEST(!s->failed(), "Failed on solution"); 776 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 777 } else { 778 CHECK_TEST(s->failed(), "Solved on non-solution"); 779 } 780 delete s; 781 } 782 START_TEST("Assignment (before posting)"); 783 { 784 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 785 s->assign(a, _rand); 786 s->post(); 787 if (is_sol) { 788 CHECK_TEST(!s->failed(), "Failed on solution"); 789 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 790 } else { 791 CHECK_TEST(s->failed(), "Solved on non-solution"); 792 } 793 delete s; 794 } 795 START_TEST("Prune"); 796 { 797 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 798 s->post(); 799 while (!s->failed() && !s->assigned()) 800 if (!s->prune(a, _rand)) { 801 problem = "No fixpoint"; 802 delete s; 803 goto failed; 804 } 805 s->assign(a, _rand); 806 if (is_sol) { 807 CHECK_TEST(!s->failed(), "Failed on solution"); 808 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 809 } else { 810 CHECK_TEST(s->failed(), "Solved on non-solution"); 811 } 812 delete s; 813 } 814 if (disabled) { 815 START_TEST("Prune (disable)"); 816 { 817 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this); 818 SetTestSpace* c = new SetTestSpace(arity,lub,withInt,this); 819 s->post(); c->post(); 820 while (!s->failed() && !s->assigned()) 821 if (!s->disabled(a, *c, _rand)) { 822 problem = "Different result after re-enable"; 823 delete s; delete c; 824 goto failed; 825 } 826 s->assign(a, _rand); 827 c->assign(a, _rand); 828 if (s->failed() != c->failed()) { 829 problem = "Different failure after re-enable"; 830 delete s; delete c; 831 goto failed; 832 } 833 delete s; delete c; 834 } 835 } 836 if (reified) { 837 START_TEST("Assignment reified (rewrite after post, <=>)"); 838 { 839 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 840 s->post(); 841 s->rel(is_sol); 842 s->assign(a, _rand); 843 CHECK_TEST(!s->failed(), "Failed"); 844 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 845 delete s; 846 } 847 START_TEST("Assignment reified (rewrite after post, =>)"); 848 { 849 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 850 s->post(); 851 s->rel(is_sol); 852 s->assign(a, _rand); 853 CHECK_TEST(!s->failed(), "Failed"); 854 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 855 delete s; 856 } 857 START_TEST("Assignment reified (rewrite after post, <=)"); 858 { 859 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 860 s->post(); 861 s->rel(is_sol); 862 s->assign(a, _rand); 863 CHECK_TEST(!s->failed(), "Failed"); 864 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 865 delete s; 866 } 867 { 868 START_TEST("Assignment reified (rewrite failure, <=>)"); 869 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 870 s->post(); 871 s->rel(!is_sol); 872 s->assign(a, _rand); 873 CHECK_TEST(s->failed(), "Not failed"); 874 delete s; 875 } 876 { 877 START_TEST("Assignment reified (rewrite failure, =>)"); 878 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 879 s->post(); 880 s->rel(!is_sol); 881 s->assign(a, _rand); 882 if (is_sol) { 883 CHECK_TEST(!s->failed(), "Failed"); 884 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 885 } else { 886 CHECK_TEST(s->failed(), "Not failed"); 887 } 888 delete s; 889 } 890 { 891 START_TEST("Assignment reified (rewrite failure, <=)"); 892 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 893 s->post(); 894 s->rel(!is_sol); 895 s->assign(a, _rand); 896 if (is_sol) { 897 CHECK_TEST(s->failed(), "Not failed"); 898 } else { 899 CHECK_TEST(!s->failed(), "Failed"); 900 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 901 } 902 delete s; 903 } 904 START_TEST("Assignment reified (immediate rewrite, <=>)"); 905 { 906 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 907 s->rel(is_sol); 908 s->post(); 909 s->assign(a, _rand); 910 CHECK_TEST(!s->failed(), "Failed"); 911 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 912 delete s; 913 } 914 START_TEST("Assignment reified (immediate rewrite, =>)"); 915 { 916 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 917 s->rel(is_sol); 918 s->post(); 919 s->assign(a, _rand); 920 CHECK_TEST(!s->failed(), "Failed"); 921 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 922 delete s; 923 } 924 START_TEST("Assignment reified (immediate rewrite, <=)"); 925 { 926 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 927 s->rel(is_sol); 928 s->post(); 929 s->assign(a, _rand); 930 CHECK_TEST(!s->failed(), "Failed"); 931 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 932 delete s; 933 } 934 START_TEST("Assignment reified (immediate failure, <=>)"); 935 { 936 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 937 s->rel(!is_sol); 938 s->post(); 939 s->assign(a, _rand); 940 CHECK_TEST(s->failed(), "Not failed"); 941 delete s; 942 } 943 START_TEST("Assignment reified (immediate failure, =>)"); 944 { 945 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 946 s->rel(!is_sol); 947 s->post(); 948 s->assign(a, _rand); 949 if (is_sol) { 950 CHECK_TEST(!s->failed(), "Failed"); 951 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 952 } else { 953 CHECK_TEST(s->failed(), "Not failed"); 954 } 955 delete s; 956 } 957 START_TEST("Assignment reified (immediate failure, <=)"); 958 { 959 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 960 s->rel(!is_sol); 961 s->post(); 962 s->assign(a, _rand); 963 if (is_sol) { 964 CHECK_TEST(s->failed(), "Not failed"); 965 } else { 966 CHECK_TEST(!s->failed(), "Failed"); 967 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 968 } 969 delete s; 970 } 971 START_TEST("Assignment reified (before posting, <=>)"); 972 { 973 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 974 s->assign(a, _rand); 975 s->post(); 976 CHECK_TEST(!s->failed(), "Failed"); 977 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 978 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 979 if (is_sol) { 980 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 981 } else { 982 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 983 } 984 delete s; 985 } 986 START_TEST("Assignment reified (before posting, =>)"); 987 { 988 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 989 s->assign(a, _rand); 990 s->post(); 991 CHECK_TEST(!s->failed(), "Failed"); 992 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 993 if (is_sol) { 994 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 995 } else { 996 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 997 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 998 } 999 delete s; 1000 } 1001 START_TEST("Assignment reified (before posting, <=)"); 1002 { 1003 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1004 s->assign(a, _rand); 1005 s->post(); 1006 CHECK_TEST(!s->failed(), "Failed"); 1007 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1008 if (is_sol) { 1009 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1010 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1011 } else { 1012 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1013 } 1014 delete s; 1015 } 1016 START_TEST("Assignment reified (after posting, <=>)"); 1017 { 1018 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 1019 s->post(); 1020 s->assign(a, _rand); 1021 CHECK_TEST(!s->failed(), "Failed"); 1022 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1023 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1024 if (is_sol) { 1025 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1026 } else { 1027 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1028 } 1029 delete s; 1030 } 1031 START_TEST("Assignment reified (after posting, =>)"); 1032 { 1033 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 1034 s->post(); 1035 s->assign(a, _rand); 1036 CHECK_TEST(!s->failed(), "Failed"); 1037 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1038 if (is_sol) { 1039 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1040 } else { 1041 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1042 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1043 } 1044 delete s; 1045 } 1046 START_TEST("Assignment reified (after posting, <=)"); 1047 { 1048 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1049 s->post(); 1050 s->assign(a, _rand); 1051 CHECK_TEST(!s->failed(), "Failed"); 1052 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1053 if (is_sol) { 1054 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1055 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1056 } else { 1057 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1058 } 1059 delete s; 1060 } 1061 START_TEST("Assignment reified (after posting, <=>, disable)"); 1062 { 1063 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 1064 s->post(); 1065 s->disable(); 1066 s->assign(a, _rand); 1067 s->enable(); 1068 CHECK_TEST(!s->failed(), "Failed"); 1069 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1070 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1071 if (is_sol) { 1072 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1073 } else { 1074 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1075 } 1076 delete s; 1077 } 1078 START_TEST("Assignment reified (after posting, =>, disable)"); 1079 { 1080 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 1081 s->post(); 1082 s->disable(); 1083 s->assign(a, _rand); 1084 s->enable(); 1085 CHECK_TEST(!s->failed(), "Failed"); 1086 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1087 if (is_sol) { 1088 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1089 } else { 1090 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1091 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1092 } 1093 delete s; 1094 } 1095 START_TEST("Assignment reified (after posting, <=, disable)"); 1096 { 1097 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1098 s->post(); 1099 s->disable(); 1100 s->assign(a, _rand); 1101 s->enable(); 1102 CHECK_TEST(!s->failed(), "Failed"); 1103 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1104 if (is_sol) { 1105 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1106 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1107 } else { 1108 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1109 } 1110 delete s; 1111 } 1112 START_TEST("Prune reified, <=>"); 1113 { 1114 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV); 1115 s->post(); 1116 while (!s->failed() && 1117 (!s->assigned() || !s->r.var().assigned())) 1118 if (!s->prune(a, _rand)) { 1119 problem = "No fixpoint"; 1120 delete s; 1121 goto failed; 1122 } 1123 CHECK_TEST(!s->failed(), "Failed"); 1124 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1125 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1126 if (is_sol) { 1127 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1128 } else { 1129 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1130 } 1131 delete s; 1132 } 1133 START_TEST("Prune reified, =>"); 1134 { 1135 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP); 1136 s->post(); 1137 while (!s->failed() && 1138 (!s->assigned() || (!is_sol && !s->r.var().assigned()))) { 1139 if (!s->prune(a, _rand)) { 1140 problem = "No fixpoint"; 1141 delete s; 1142 goto failed; 1143 } 1144 } 1145 CHECK_TEST(!s->failed(), "Failed"); 1146 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1147 if (is_sol) { 1148 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1149 } else { 1150 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1151 CHECK_TEST(s->r.var().val()==0, "One on non-solution"); 1152 } 1153 delete s; 1154 } 1155 START_TEST("Prune reified, <="); 1156 { 1157 SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI); 1158 s->post(); 1159 while (!s->failed() && 1160 (!s->assigned() || (is_sol && !s->r.var().assigned()))) 1161 if (!s->prune(a, _rand)) { 1162 problem = "No fixpoint"; 1163 delete s; 1164 goto failed; 1165 } 1166 CHECK_TEST(!s->failed(), "Failed"); 1167 CHECK_TEST(s->subsumed(testsubsumed), "No subsumption"); 1168 if (is_sol) { 1169 CHECK_TEST(s->r.var().assigned(), "Control variable unassigned"); 1170 CHECK_TEST(s->r.var().val()==1, "Zero on solution"); 1171 } else { 1172 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned"); 1173 } 1174 delete s; 1175 } 1176 } 1177 a.next(_rand); 1178 } 1179 delete ap; 1180 return true; 1181 failed: 1182 if (opt.log) 1183 olog << "FAILURE" << std::endl 1184 << ind(1) << "Test: " << test << std::endl 1185 << ind(1) << "Problem: " << problem << std::endl; 1186 if (a() && opt.log) 1187 olog << ind(1) << "Assignment: " << a << std::endl; 1188 delete ap; 1189 1190 return false; 1191 } 1192 1193 const Gecode::SetRelType SetRelTypes::srts[] = 1194 {Gecode::SRT_EQ,Gecode::SRT_NQ,Gecode::SRT_SUB, 1195 Gecode::SRT_SUP,Gecode::SRT_DISJ,Gecode::SRT_CMPL}; 1196 1197 const Gecode::SetOpType SetOpTypes::sots[] = 1198 {Gecode::SOT_UNION, Gecode::SOT_DUNION, 1199 Gecode::SOT_INTER, Gecode::SOT_MINUS}; 1200 1201}} 1202 1203#undef START_TEST 1204#undef CHECK_TEST 1205 1206// STATISTICS: test-set