00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "test/float.hh"
00043
00044 #include <algorithm>
00045 #include <iomanip>
00046
00047 namespace Test { namespace Float {
00048
00049
00050
00051
00052
00053 void
00054 CpltAssignment::operator++(void) {
00055 using namespace Gecode;
00056 int i = n-1;
00057 while (true) {
00058 FloatNum ns = dsv[i].min() + step;
00059 dsv[i] = FloatVal(ns,nextafter(ns,ns+1));
00060 if ((dsv[i].max() < d.max()) || (i == 0))
00061 return;
00062 dsv[i--] = FloatVal(d.min(),nextafter(d.min(),d.max()));
00063 }
00064 }
00065
00066
00067
00068
00069
00070 void
00071 ExtAssignment::operator++(void) {
00072 using namespace Gecode;
00073 assert(n > 1);
00074 int i = n-2;
00075 while (true) {
00076 FloatNum ns = dsv[i].min() + step;
00077 dsv[i] = FloatVal(ns,nextafter(ns,ns+1));
00078 if ((dsv[i].max() < d.max()) || (i == 0)) {
00079 if (curPb->extendAssignement(*this)) return;
00080 if ((dsv[i].max() >= d.max()) && (i == 0)) return;
00081 continue;
00082 }
00083 dsv[i--] = FloatVal(d.min(),nextafter(d.min(),d.max()));
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092 void
00093 RandomAssignment::operator++(void) {
00094 for (int i = n; i--; )
00095 vals[i]=randval();
00096 a--;
00097 }
00098
00099 }}
00100
00101 std::ostream&
00102 operator<<(std::ostream& os, const Test::Float::Assignment& a) {
00103 int n = a.size();
00104 os << "{";
00105 for (int i=0; i<n; i++)
00106 os << "[" << a[i].min() << "," << a[i].max() << "]" << ((i!=n-1) ? "," : "}");
00107 return os;
00108 }
00109
00110 namespace Test { namespace Float {
00111
00112 Gecode::FloatNum randFValDown(Gecode::FloatNum l, Gecode::FloatNum u) {
00113 using namespace Gecode;
00114 using namespace Gecode::Float;
00115 Rounding r;
00116 return
00117 r.add_down(
00118 l,
00119 r.mul_down(
00120 r.div_down(
00121 Base::rand(static_cast<unsigned int>(Int::Limits::max)),
00122 static_cast<FloatNum>(Int::Limits::max)
00123 ),
00124 r.sub_down(u,l)
00125 )
00126 );
00127 }
00128
00129 Gecode::FloatNum randFValUp(Gecode::FloatNum l, Gecode::FloatNum u) {
00130 using namespace Gecode;
00131 using namespace Gecode::Float;
00132 Rounding r;
00133 return
00134 r.sub_up(
00135 u,
00136 r.mul_down(
00137 r.div_down(
00138 Base::rand(static_cast<unsigned int>(Int::Limits::max)),
00139 static_cast<FloatNum>(Int::Limits::max)
00140 ),
00141 r.sub_down(u,l)
00142 )
00143 );
00144 }
00145
00146
00147 TestSpace::TestSpace(int n, Gecode::FloatVal& d0, Gecode::FloatNum s,
00148 Test* t)
00149 : d(d0), step(s),
00150 x(*this,n,Gecode::Float::Limits::min,Gecode::Float::Limits::max),
00151 test(t), reified(false) {
00152 Gecode::FloatVarArgs _x(*this,n,d.min(),d.max());
00153 if (x.size() == 1)
00154 Gecode::dom(*this,x[0],_x[0]);
00155 else
00156 Gecode::dom(*this,x,_x);
00157 Gecode::BoolVar b(*this,0,1);
00158 r = Gecode::Reify(b,Gecode::RM_EQV);
00159 if (opt.log)
00160 olog << ind(2) << "Initial: x[]=" << x
00161 << std::endl;
00162 }
00163
00164 TestSpace::TestSpace(int n, Gecode::FloatVal& d0, Gecode::FloatNum s,
00165 Test* t, Gecode::ReifyMode rm)
00166 : d(d0), step(s), x(*this,n,d.min(),d.max()), test(t), reified(true) {
00167 Gecode::BoolVar b(*this,0,1);
00168 r = Gecode::Reify(b,rm);
00169 if (opt.log)
00170 olog << ind(2) << "Initial: x[]=" << x
00171 << " b=" << r.var()
00172 << std::endl;
00173 }
00174
00175 TestSpace::TestSpace(bool share, TestSpace& s)
00176 : Gecode::Space(share,s), d(s.d), step(s.step), test(s.test), reified(s.reified) {
00177 x.update(*this, share, s.x);
00178 Gecode::BoolVar b;
00179 Gecode::BoolVar sr(s.r.var());
00180 b.update(*this, share, sr);
00181 r.var(b); r.mode(s.r.mode());
00182 }
00183
00184 Gecode::Space*
00185 TestSpace::copy(bool share) {
00186 return new TestSpace(share,*this);
00187 }
00188
00189 void
00190 TestSpace::enable(void) {
00191 Gecode::PropagatorGroup::all.enable(*this);
00192 }
00193
00194 void
00195 TestSpace::disable(void) {
00196 Gecode::PropagatorGroup::all.disable(*this);
00197 (void) status();
00198 }
00199
00200 void
00201 TestSpace::dropUntil(const Assignment& a) {
00202 for (int i = x.size(); i--; )
00203 Gecode::rel(*this, x[i], Gecode::FRT_GQ, a[i].min());
00204 }
00205
00206 bool
00207 TestSpace::assigned(void) const {
00208 for (int i=x.size(); i--; )
00209 if (!x[i].assigned())
00210 return false;
00211 return true;
00212 }
00213
00214 bool
00215 TestSpace::matchAssignment(const Assignment& a) const {
00216 for (int i=x.size(); i--; )
00217 if ((x[i].min() < a[i].min()) && (x[i].max() > a[i].max()))
00218 return false;
00219 return true;
00220 }
00221
00222 void
00223 TestSpace::post(void) {
00224 if (reified){
00225 test->post(*this,x,r);
00226 if (opt.log)
00227 olog << ind(3) << "Posting reified propagator" << std::endl;
00228 } else {
00229 test->post(*this,x);
00230 if (opt.log)
00231 olog << ind(3) << "Posting propagator" << std::endl;
00232 }
00233 }
00234
00235 bool
00236 TestSpace::failed(void) {
00237 if (opt.log) {
00238 olog << ind(3) << "Fixpoint: " << x;
00239 bool f=(status() == Gecode::SS_FAILED);
00240 olog << std::endl << ind(3) << " --> " << x << std::endl;
00241 return f;
00242 } else {
00243 return status() == Gecode::SS_FAILED;
00244 }
00245 }
00246
00247 void
00248 TestSpace::rel(int i, Gecode::FloatRelType frt, Gecode::FloatVal n) {
00249 if (opt.log) {
00250 olog << ind(4) << "x[" << i << "] ";
00251 switch (frt) {
00252 case Gecode::FRT_EQ: olog << "="; break;
00253 case Gecode::FRT_NQ: olog << "!="; break;
00254 case Gecode::FRT_LQ: olog << "<="; break;
00255 case Gecode::FRT_LE: olog << "<"; break;
00256 case Gecode::FRT_GQ: olog << ">="; break;
00257 case Gecode::FRT_GR: olog << ">"; break;
00258 }
00259 olog << " [" << n.min() << "," << n.max() << "]" << std::endl;
00260 }
00261 Gecode::rel(*this, x[i], frt, n);
00262 }
00263
00264 void
00265 TestSpace::rel(bool sol) {
00266 int n = sol ? 1 : 0;
00267 assert(reified);
00268 if (opt.log)
00269 olog << ind(4) << "b = " << n << std::endl;
00270 Gecode::rel(*this, r.var(), Gecode::IRT_EQ, n);
00271 }
00272
00273 void
00274 TestSpace::assign(const Assignment& a, MaybeType& sol, bool skip) {
00275 using namespace Gecode;
00276 int i = skip ? static_cast<int>(Base::rand(a.size())) : -1;
00277
00278 for (int j=a.size(); j--; )
00279 if (i != j) {
00280 if ((x[j].min() == a[j].max()) || (x[j].max() == a[j].min()))
00281 {
00282 sol = MT_MAYBE;
00283 return;
00284 }
00285 rel(j, FRT_EQ, a[j]);
00286 if (Base::fixpoint() && failed())
00287 return;
00288 }
00289 }
00290
00291 void
00292 TestSpace::bound(void) {
00293 using namespace Gecode;
00294
00295 int i = Base::rand(x.size());
00296 while (x[i].assigned()) {
00297 i = (i+1) % x.size();
00298 }
00299 bool min = Base::rand(2);
00300 if (min)
00301 rel(i, FRT_LQ, nextafter(x[i].min(), x[i].max()));
00302 else
00303 rel(i, FRT_GQ, nextafter(x[i].max(), x[i].min()));
00304 }
00305
00306 Gecode::FloatNum
00307 TestSpace::cut(int* cutDirections) {
00308 using namespace Gecode;
00309 using namespace Gecode::Float;
00310
00311 int i = 0;
00312 while (x[i].assigned()) i++;
00313 for (int j=x.size(); j--; ) {
00314 if (!x[j].assigned() && (x[j].size() > x[i].size())) i = j;
00315 }
00316 Rounding r;
00317 if (cutDirections[i]) {
00318 FloatNum m = r.div_up(r.add_up(x[i].min(),x[i].max()),2);
00319 FloatNum n = nextafter(x[i].min(), x[i].max());
00320 if (m > n)
00321 rel(i, FRT_LQ, m);
00322 else
00323 rel(i, FRT_LQ, n);
00324 } else {
00325 FloatNum m = r.div_down(r.add_down(x[i].min(),x[i].max()),2);
00326 FloatNum n = nextafter(x[i].max(), x[i].min());
00327 if (m < n)
00328 rel(i, FRT_GQ, m);
00329 else
00330 rel(i, FRT_GQ, n);
00331 }
00332 return x[i].size();
00333 }
00334
00335 void
00336 TestSpace::prune(int i) {
00337 using namespace Gecode;
00338
00339 if (Base::rand(2) && !x[i].assigned()) {
00340 Gecode::FloatNum v=randFValUp(x[i].min(),x[i].max());
00341 assert((v >= x[i].min()) && (v <= x[i].max()));
00342 rel(i, Gecode::FRT_LQ, v);
00343 }
00344 if (Base::rand(2) && !x[i].assigned()) {
00345 Gecode::FloatNum v=randFValDown(x[i].min(),x[i].max());
00346 assert((v <= x[i].max()) && (v >= x[i].min()));
00347 rel(i, Gecode::FRT_GQ, v);
00348 }
00349 }
00350
00351 void
00352 TestSpace::prune(void) {
00353 using namespace Gecode;
00354
00355 int i = Base::rand(x.size());
00356 while (x[i].assigned()) {
00357 i = (i+1) % x.size();
00358 }
00359 prune(i);
00360 }
00361
00362 bool
00363 TestSpace::prune(const Assignment& a, bool testfix) {
00364
00365 int i = Base::rand(x.size());
00366 while (x[i].assigned())
00367 i = (i+1) % x.size();
00368
00369 switch (Base::rand(2)) {
00370 case 0:
00371 if (a[i].max() < x[i].max()) {
00372 Gecode::FloatNum v=randFValDown(a[i].max(),x[i].max());
00373 if (v==x[i].max())
00374 v = a[i].max();
00375 assert((v >= a[i].max()) && (v <= x[i].max()));
00376 rel(i, Gecode::FRT_LQ, v);
00377 }
00378 break;
00379 case 1:
00380 if (a[i].min() > x[i].min()) {
00381 Gecode::FloatNum v=randFValUp(x[i].min(),a[i].min());
00382 if (v==x[i].min())
00383 v = a[i].min();
00384 assert((v <= a[i].min()) && (v >= x[i].min()));
00385 rel(i, Gecode::FRT_GQ, v);
00386 }
00387 break;
00388 }
00389 if (Base::fixpoint()) {
00390 if (failed() || !testfix)
00391 return true;
00392 TestSpace* c = static_cast<TestSpace*>(clone());
00393 if (opt.log)
00394 olog << ind(3) << "Testing fixpoint on copy" << std::endl;
00395 c->post();
00396 if (c->failed()) {
00397 delete c; return false;
00398 }
00399 for (int i=x.size(); i--; )
00400 if (x[i].size() != c->x[i].size()) {
00401 delete c; return false;
00402 }
00403 if (reified && (r.var().size() != c->r.var().size())) {
00404 delete c; return false;
00405 }
00406 if (opt.log)
00407 olog << ind(3) << "Finished testing fixpoint on copy" << std::endl;
00408 delete c;
00409 }
00410 return true;
00411 }
00412
00413 unsigned int
00414 TestSpace::propagators(void) {
00415 return Gecode::PropagatorGroup::all.size(*this);
00416 }
00417
00418
00419 const Gecode::FloatRelType FloatRelTypes::frts[] =
00420 {Gecode::FRT_EQ,Gecode::FRT_NQ,Gecode::FRT_LQ,Gecode::FRT_LE,
00421 Gecode::FRT_GQ,Gecode::FRT_GR};
00422
00423 Assignment*
00424 Test::assignment(void) const {
00425 switch (assigmentType) {
00426 case CPLT_ASSIGNMENT:
00427 return new CpltAssignment(arity,dom,step);
00428 case RANDOM_ASSIGNMENT:
00429 return new RandomAssignment(arity,dom,step);
00430 case EXTEND_ASSIGNMENT:
00431 return new ExtAssignment(arity,dom,step,this);
00432 default :
00433 GECODE_NEVER;
00434 }
00435 return NULL;
00436 }
00437
00438 bool
00439 Test::extendAssignement(Assignment&) const {
00440 GECODE_NEVER;
00441 return false;
00442 }
00443
00444 bool
00445 Test::subsumed(const TestSpace& ts) const {
00446 if (!testsubsumed) return true;
00447 if (const_cast<TestSpace&>(ts).propagators() == 0) return true;
00448 if (assigmentType == EXTEND_ASSIGNMENT) return true;
00449 return false;
00450 }
00451
00453 #define CHECK_TEST(T,M) \
00454 if (opt.log) \
00455 olog << ind(3) << "Check: " << (M) << std::endl; \
00456 if (!(T)) { \
00457 problem = (M); delete s; goto failed; \
00458 }
00459
00461 #define START_TEST(T) \
00462 if (opt.log) { \
00463 olog.str(""); \
00464 olog << ind(2) << "Testing: " << (T) << std::endl; \
00465 } \
00466 test = (T);
00467
00468 bool
00469 Test::ignore(const Assignment&) const {
00470 return false;
00471 }
00472
00473 void
00474 Test::post(Gecode::Space&, Gecode::FloatVarArray&,
00475 Gecode::Reify) {}
00476
00477 bool
00478 Test::run(void) {
00479 using namespace Gecode;
00480 const char* test = "NONE";
00481 const char* problem = "NONE";
00482
00483
00484 Assignment* ap = assignment();
00485 Assignment& a = *ap;
00486
00487
00488 TestSpace* search_s = new TestSpace(arity,dom,step,this);
00489 post(*search_s,search_s->x);
00490 branch(*search_s,search_s->x,FLOAT_VAR_NONE(),FLOAT_VAL_SPLIT_MIN());
00491 Search::Options search_o;
00492 search_o.threads = 1;
00493 DFS<TestSpace> * e_s = new DFS<TestSpace>(search_s,search_o);
00494 while (a()) {
00495 MaybeType sol = solution(a);
00496 if (opt.log) {
00497 olog << ind(1) << "Assignment: " << a;
00498 switch (sol) {
00499 case MT_TRUE: olog << " (solution)"; break;
00500 case MT_FALSE: olog << " (no solution)"; break;
00501 case MT_MAYBE: olog << " (maybe)"; break;
00502 }
00503 olog << std::endl;
00504 }
00505 START_TEST("Assignment (after posting)");
00506 {
00507 TestSpace* s = new TestSpace(arity,dom,step,this);
00508 TestSpace* sc = NULL;
00509 s->post();
00510 switch (Base::rand(3)) {
00511 case 0:
00512 if (opt.log)
00513 olog << ind(3) << "No copy" << std::endl;
00514 sc = s;
00515 s = NULL;
00516 break;
00517 case 1:
00518 if (opt.log)
00519 olog << ind(3) << "Unshared copy" << std::endl;
00520 if (s->status() != SS_FAILED) {
00521 sc = static_cast<TestSpace*>(s->clone(false));
00522 } else {
00523 sc = s; s = NULL;
00524 }
00525 break;
00526 case 2:
00527 if (opt.log)
00528 olog << ind(3) << "Shared copy" << std::endl;
00529 if (s->status() != SS_FAILED) {
00530 sc = static_cast<TestSpace*>(s->clone(true));
00531 } else {
00532 sc = s; s = NULL;
00533 }
00534 break;
00535 default: assert(false);
00536 }
00537 sc->assign(a,sol);
00538 if (sol == MT_TRUE) {
00539 CHECK_TEST(!sc->failed(), "Failed on solution");
00540 CHECK_TEST(subsumed(*sc), "No subsumption");
00541 } else if (sol == MT_FALSE) {
00542 CHECK_TEST(sc->failed(), "Solved on non-solution");
00543 }
00544 delete s; delete sc;
00545 }
00546 START_TEST("Partial assignment (after posting)");
00547 {
00548 TestSpace* s = new TestSpace(arity,dom,step,this);
00549 s->post();
00550 s->assign(a,sol,true);
00551 (void) s->failed();
00552 s->assign(a,sol);
00553 if (sol == MT_TRUE) {
00554 CHECK_TEST(!s->failed(), "Failed on solution");
00555 CHECK_TEST(subsumed(*s), "No subsumption");
00556 } else if (sol == MT_FALSE) {
00557 CHECK_TEST(s->failed(), "Solved on non-solution");
00558 }
00559 delete s;
00560 }
00561 START_TEST("Assignment (after posting, disable)");
00562 {
00563 TestSpace* s = new TestSpace(arity,dom,step,this);
00564 s->post();
00565 s->disable();
00566 s->enable();
00567 s->assign(a,sol);
00568 if (sol == MT_TRUE) {
00569 CHECK_TEST(!s->failed(), "Failed on solution");
00570 CHECK_TEST(subsumed(*s), "No subsumption");
00571 } else if (sol == MT_FALSE) {
00572 CHECK_TEST(s->failed(), "Solved on non-solution");
00573 }
00574 delete s;
00575 }
00576 START_TEST("Partial assignment (after posting, disable)");
00577 {
00578 TestSpace* s = new TestSpace(arity,dom,step,this);
00579 s->post();
00580 s->disable();
00581 s->enable();
00582 s->assign(a,sol,true);
00583 (void) s->failed();
00584 s->assign(a,sol);
00585 if (sol == MT_TRUE) {
00586 CHECK_TEST(!s->failed(), "Failed on solution");
00587 CHECK_TEST(subsumed(*s), "No subsumption");
00588 } else if (sol == MT_FALSE) {
00589 CHECK_TEST(s->failed(), "Solved on non-solution");
00590 }
00591 delete s;
00592 }
00593 START_TEST("Assignment (before posting)");
00594 {
00595 TestSpace* s = new TestSpace(arity,dom,step,this);
00596 s->assign(a,sol);
00597 s->post();
00598 if (sol == MT_TRUE) {
00599 CHECK_TEST(!s->failed(), "Failed on solution");
00600 CHECK_TEST(subsumed(*s), "No subsumption");
00601 } else if (sol == MT_FALSE) {
00602 CHECK_TEST(s->failed(), "Solved on non-solution");
00603 }
00604 delete s;
00605 }
00606 START_TEST("Partial assignment (before posting)");
00607 {
00608 TestSpace* s = new TestSpace(arity,dom,step,this);
00609 s->assign(a,sol,true);
00610 s->post();
00611 (void) s->failed();
00612 s->assign(a,sol);
00613 if (sol == MT_TRUE) {
00614 CHECK_TEST(!s->failed(), "Failed on solution");
00615 CHECK_TEST(subsumed(*s), "No subsumption");
00616 } else if (sol == MT_FALSE) {
00617 CHECK_TEST(s->failed(), "Solved on non-solution");
00618 }
00619 delete s;
00620 }
00621 START_TEST("Prune");
00622 {
00623 TestSpace* s = new TestSpace(arity,dom,step,this);
00624 s->post();
00625 while (!s->failed() && !s->assigned() && !s->matchAssignment(a))
00626 if (!s->prune(a,testfix)) {
00627 problem = "No fixpoint";
00628 delete s;
00629 goto failed;
00630 }
00631 s->assign(a,sol);
00632 if (sol == MT_TRUE) {
00633 CHECK_TEST(!s->failed(), "Failed on solution");
00634 CHECK_TEST(subsumed(*s), "No subsumption");
00635 } else if (sol == MT_FALSE) {
00636 CHECK_TEST(s->failed(), "Solved on non-solution");
00637 }
00638 delete s;
00639 }
00640 if (reified && !ignore(a) && (sol != MT_MAYBE)) {
00641 if (eqv()) {
00642 START_TEST("Assignment reified (rewrite after post, <=>)");
00643 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00644 s->post();
00645 s->rel(sol == MT_TRUE);
00646 s->assign(a,sol);
00647 CHECK_TEST(!s->failed(), "Failed");
00648 CHECK_TEST(subsumed(*s), "No subsumption");
00649 delete s;
00650 }
00651 if (imp()) {
00652 START_TEST("Assignment reified (rewrite after post, =>)");
00653 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00654 s->post();
00655 s->rel(sol == MT_TRUE);
00656 s->assign(a,sol);
00657 CHECK_TEST(!s->failed(), "Failed");
00658 CHECK_TEST(subsumed(*s), "No subsumption");
00659 delete s;
00660 }
00661 if (pmi()) {
00662 START_TEST("Assignment reified (rewrite after post, <=)");
00663 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00664 s->post();
00665 s->rel(sol == MT_TRUE);
00666 s->assign(a,sol);
00667 CHECK_TEST(!s->failed(), "Failed");
00668 CHECK_TEST(subsumed(*s), "No subsumption");
00669 delete s;
00670 }
00671 if (eqv()) {
00672 START_TEST("Assignment reified (immediate rewrite, <=>)");
00673 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00674 s->rel(sol == MT_TRUE);
00675 s->post();
00676 s->assign(a,sol);
00677 CHECK_TEST(!s->failed(), "Failed");
00678 CHECK_TEST(subsumed(*s), "No subsumption");
00679 delete s;
00680 }
00681 if (imp()) {
00682 START_TEST("Assignment reified (immediate rewrite, =>)");
00683 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00684 s->rel(sol == MT_TRUE);
00685 s->post();
00686 s->assign(a,sol);
00687 CHECK_TEST(!s->failed(), "Failed");
00688 CHECK_TEST(subsumed(*s), "No subsumption");
00689 delete s;
00690 }
00691 if (pmi()) {
00692 START_TEST("Assignment reified (immediate rewrite, <=)");
00693 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00694 s->rel(sol == MT_TRUE);
00695 s->post();
00696 s->assign(a,sol);
00697 CHECK_TEST(!s->failed(), "Failed");
00698 CHECK_TEST(subsumed(*s), "No subsumption");
00699 delete s;
00700 }
00701 if (eqv()) {
00702 START_TEST("Assignment reified (before posting, <=>)");
00703 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00704 s->assign(a,sol);
00705 s->post();
00706 CHECK_TEST(!s->failed(), "Failed");
00707 CHECK_TEST(subsumed(*s), "No subsumption");
00708 if (s->r.var().assigned()) {
00709 if (sol == MT_TRUE) {
00710 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00711 } else if (sol == MT_FALSE) {
00712 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00713 }
00714 }
00715 delete s;
00716 }
00717 if (imp()) {
00718 START_TEST("Assignment reified (before posting, =>)");
00719 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00720 s->assign(a,sol);
00721 s->post();
00722 CHECK_TEST(!s->failed(), "Failed");
00723 CHECK_TEST(subsumed(*s), "No subsumption");
00724 if (sol == MT_TRUE) {
00725 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00726 } else if ((sol = MT_FALSE) && s->r.var().assigned()) {
00727 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00728 }
00729 delete s;
00730 }
00731 if (pmi()) {
00732 START_TEST("Assignment reified (before posting, <=)");
00733 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00734 s->assign(a,sol);
00735 s->post();
00736 CHECK_TEST(!s->failed(), "Failed");
00737 CHECK_TEST(subsumed(*s), "No subsumption");
00738 if (sol == MT_TRUE) {
00739 if (s->r.var().assigned()) {
00740 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00741 }
00742 } else if (sol == MT_FALSE) {
00743 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00744 }
00745 delete s;
00746 }
00747 if (eqv()) {
00748 START_TEST("Assignment reified (after posting, <=>)");
00749 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00750 s->post();
00751 s->assign(a,sol);
00752 CHECK_TEST(!s->failed(), "Failed");
00753 CHECK_TEST(subsumed(*s), "No subsumption");
00754 if (s->r.var().assigned()) {
00755 if (sol == MT_TRUE) {
00756 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00757 } else if (sol == MT_FALSE) {
00758 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00759 }
00760 }
00761 delete s;
00762 }
00763 if (imp()) {
00764 START_TEST("Assignment reified (after posting, =>)");
00765 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00766 s->post();
00767 s->assign(a,sol);
00768 CHECK_TEST(!s->failed(), "Failed");
00769 CHECK_TEST(subsumed(*s), "No subsumption");
00770 if (sol == MT_TRUE) {
00771 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00772 } else if (s->r.var().assigned()) {
00773 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00774 }
00775 delete s;
00776 }
00777 if (pmi()) {
00778 START_TEST("Assignment reified (after posting, <=)");
00779 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00780 s->post();
00781 s->assign(a,sol);
00782 CHECK_TEST(!s->failed(), "Failed");
00783 CHECK_TEST(subsumed(*s), "No subsumption");
00784 if (sol == MT_TRUE) {
00785 if (s->r.var().assigned()) {
00786 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00787 }
00788 } else if (sol == MT_FALSE) {
00789 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00790 }
00791 delete s;
00792 }
00793 if (eqv()) {
00794 START_TEST("Prune reified, <=>");
00795 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00796 s->post();
00797 while (!s->failed() && !s->matchAssignment(a) &&
00798 (!s->assigned() || !s->r.var().assigned()))
00799 if (!s->prune(a,testfix)) {
00800 problem = "No fixpoint";
00801 delete s;
00802 goto failed;
00803 }
00804 CHECK_TEST(!s->failed(), "Failed");
00805 CHECK_TEST(subsumed(*s), "No subsumption");
00806 if (s->r.var().assigned()) {
00807 if (sol == MT_TRUE) {
00808 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00809 } else if (sol == MT_FALSE) {
00810 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00811 }
00812 }
00813 delete s;
00814 }
00815 if (imp()) {
00816 START_TEST("Prune reified, =>");
00817 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00818 s->post();
00819 while (!s->failed() && !s->matchAssignment(a) &&
00820 (!s->assigned() || ((sol == MT_FALSE) &&
00821 !s->r.var().assigned())))
00822 if (!s->prune(a,testfix)) {
00823 problem = "No fixpoint";
00824 delete s;
00825 goto failed;
00826 }
00827 CHECK_TEST(!s->failed(), "Failed");
00828 CHECK_TEST(subsumed(*s), "No subsumption");
00829 if (sol == MT_TRUE) {
00830 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00831 } else if ((sol == MT_FALSE) && s->r.var().assigned()) {
00832 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00833 }
00834 delete s;
00835 }
00836 if (pmi()) {
00837 START_TEST("Prune reified, <=");
00838 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00839 s->post();
00840 while (!s->failed() && !s->matchAssignment(a) &&
00841 (!s->assigned() || ((sol == MT_TRUE) &&
00842 !s->r.var().assigned())))
00843 if (!s->prune(a,testfix)) {
00844 problem = "No fixpoint";
00845 delete s;
00846 goto failed;
00847 }
00848 CHECK_TEST(!s->failed(), "Failed");
00849 CHECK_TEST(subsumed(*s), "No subsumption");
00850 if ((sol == MT_TRUE) && s->r.var().assigned()) {
00851 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00852 } else if (sol == MT_FALSE) {
00853 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00854 }
00855 delete s;
00856 }
00857 }
00858
00859 if (testsearch) {
00860 if (sol == MT_TRUE) {
00861 START_TEST("Search");
00862 if (!search_s->failed()) {
00863 TestSpace* ss = static_cast<TestSpace*>(search_s->clone(false));
00864 ss->dropUntil(a);
00865 delete e_s;
00866 e_s = new DFS<TestSpace>(ss,search_o);
00867 delete ss;
00868 }
00869 TestSpace* s = e_s->next();
00870 CHECK_TEST(s != NULL, "Solutions exhausted");
00871 CHECK_TEST(subsumed(*s), "No subsumption");
00872 for (int i=a.size(); i--; ) {
00873 CHECK_TEST(s->x[i].assigned(), "Unassigned variable");
00874 CHECK_TEST(Gecode::Float::overlap(a[i], s->x[i].val()), "Wrong value in solution");
00875 }
00876 delete s;
00877 }
00878 }
00879
00880 ++a;
00881 }
00882
00883 if (testsearch) {
00884 test = "Search";
00885 if (!search_s->failed()) {
00886 TestSpace* ss = static_cast<TestSpace*>(search_s->clone(false));
00887 ss->dropUntil(a);
00888 delete e_s;
00889 e_s = new DFS<TestSpace>(ss,search_o);
00890 delete ss;
00891 }
00892 if (e_s->next() != NULL) {
00893 problem = "Excess solutions";
00894 goto failed;
00895 }
00896 }
00897
00898 delete ap;
00899 delete search_s;
00900 delete e_s;
00901 return true;
00902
00903 failed:
00904 if (opt.log)
00905 olog << "FAILURE" << std::endl
00906 << ind(1) << "Test: " << test << std::endl
00907 << ind(1) << "Problem: " << problem << std::endl;
00908 if (a() && opt.log)
00909 olog << ind(1) << "Assignment: " << a << std::endl;
00910 delete ap;
00911 delete search_s;
00912 delete e_s;
00913
00914 return false;
00915 }
00916
00917 }}
00918
00919 #undef START_TEST
00920 #undef CHECK_TEST
00921
00922