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::dropUntil(const Assignment& a) {
00191 for (int i = x.size(); i--; )
00192 Gecode::rel(*this, x[i], Gecode::FRT_GQ, a[i].min());
00193 }
00194
00195 bool
00196 TestSpace::assigned(void) const {
00197 for (int i=x.size(); i--; )
00198 if (!x[i].assigned())
00199 return false;
00200 return true;
00201 }
00202
00203 bool
00204 TestSpace::matchAssignment(const Assignment& a) const {
00205 for (int i=x.size(); i--; )
00206 if ((x[i].min() < a[i].min()) && (x[i].max() > a[i].max()))
00207 return false;
00208 return true;
00209 }
00210
00211 void
00212 TestSpace::post(void) {
00213 if (reified){
00214 test->post(*this,x,r);
00215 if (opt.log)
00216 olog << ind(3) << "Posting reified propagator" << std::endl;
00217 } else {
00218 test->post(*this,x);
00219 if (opt.log)
00220 olog << ind(3) << "Posting propagator" << std::endl;
00221 }
00222 }
00223
00224 bool
00225 TestSpace::failed(void) {
00226 if (opt.log) {
00227 olog << ind(3) << "Fixpoint: " << x;
00228 bool f=(status() == Gecode::SS_FAILED);
00229 olog << std::endl << ind(3) << " --> " << x << std::endl;
00230 return f;
00231 } else {
00232 return status() == Gecode::SS_FAILED;
00233 }
00234 }
00235
00236 void
00237 TestSpace::rel(int i, Gecode::FloatRelType frt, Gecode::FloatVal n) {
00238 if (opt.log) {
00239 olog << ind(4) << "x[" << i << "] ";
00240 switch (frt) {
00241 case Gecode::FRT_EQ: olog << "="; break;
00242 case Gecode::FRT_NQ: olog << "!="; break;
00243 case Gecode::FRT_LQ: olog << "<="; break;
00244 case Gecode::FRT_LE: olog << "<"; break;
00245 case Gecode::FRT_GQ: olog << ">="; break;
00246 case Gecode::FRT_GR: olog << ">"; break;
00247 }
00248 olog << " [" << n.min() << "," << n.max() << "]" << std::endl;
00249 }
00250 Gecode::rel(*this, x[i], frt, n);
00251 }
00252
00253 void
00254 TestSpace::rel(bool sol) {
00255 int n = sol ? 1 : 0;
00256 assert(reified);
00257 if (opt.log)
00258 olog << ind(4) << "b = " << n << std::endl;
00259 Gecode::rel(*this, r.var(), Gecode::IRT_EQ, n);
00260 }
00261
00262 void
00263 TestSpace::assign(const Assignment& a, MaybeType& sol, bool skip) {
00264 using namespace Gecode;
00265 int i = skip ? static_cast<int>(Base::rand(a.size())) : -1;
00266
00267 for (int j=a.size(); j--; )
00268 if (i != j) {
00269 if ((x[j].min() == a[j].max()) || (x[j].max() == a[j].min()))
00270 {
00271 sol = MT_MAYBE;
00272 return;
00273 }
00274 rel(j, FRT_EQ, a[j]);
00275 if (Base::fixpoint() && failed())
00276 return;
00277 }
00278 }
00279
00280 void
00281 TestSpace::bound(void) {
00282 using namespace Gecode;
00283
00284 int i = Base::rand(x.size());
00285 while (x[i].assigned()) {
00286 i = (i+1) % x.size();
00287 }
00288 bool min = Base::rand(2);
00289 if (min)
00290 rel(i, FRT_LQ, nextafter(x[i].min(), x[i].max()));
00291 else
00292 rel(i, FRT_GQ, nextafter(x[i].max(), x[i].min()));
00293 }
00294
00295 Gecode::FloatNum
00296 TestSpace::cut(int* cutDirections) {
00297 using namespace Gecode;
00298 using namespace Gecode::Float;
00299
00300 int i = 0;
00301 while (x[i].assigned()) i++;
00302 for (int j=x.size(); j--; ) {
00303 if (!x[j].assigned() && (x[j].size() > x[i].size())) i = j;
00304 }
00305 Rounding r;
00306 if (cutDirections[i]) {
00307 FloatNum m = r.div_up(r.add_up(x[i].min(),x[i].max()),2);
00308 FloatNum n = nextafter(x[i].min(), x[i].max());
00309 if (m > n)
00310 rel(i, FRT_LQ, m);
00311 else
00312 rel(i, FRT_LQ, n);
00313 } else {
00314 FloatNum m = r.div_down(r.add_down(x[i].min(),x[i].max()),2);
00315 FloatNum n = nextafter(x[i].max(), x[i].min());
00316 if (m < n)
00317 rel(i, FRT_GQ, m);
00318 else
00319 rel(i, FRT_GQ, n);
00320 }
00321 return x[i].size();
00322 }
00323
00324 void
00325 TestSpace::prune(int i) {
00326 using namespace Gecode;
00327
00328 if (Base::rand(2) && !x[i].assigned()) {
00329 Gecode::FloatNum v=randFValUp(x[i].min(),x[i].max());
00330 assert((v >= x[i].min()) && (v <= x[i].max()));
00331 rel(i, Gecode::FRT_LQ, v);
00332 }
00333 if (Base::rand(2) && !x[i].assigned()) {
00334 Gecode::FloatNum v=randFValDown(x[i].min(),x[i].max());
00335 assert((v <= x[i].max()) && (v >= x[i].min()));
00336 rel(i, Gecode::FRT_GQ, v);
00337 }
00338 }
00339
00340 void
00341 TestSpace::prune(void) {
00342 using namespace Gecode;
00343
00344 int i = Base::rand(x.size());
00345 while (x[i].assigned()) {
00346 i = (i+1) % x.size();
00347 }
00348 prune(i);
00349 }
00350
00351 bool
00352 TestSpace::prune(const Assignment& a, bool testfix) {
00353
00354 int i = Base::rand(x.size());
00355 while (x[i].assigned())
00356 i = (i+1) % x.size();
00357
00358 switch (Base::rand(2)) {
00359 case 0:
00360 if (a[i].max() < x[i].max()) {
00361 Gecode::FloatNum v=randFValDown(a[i].max(),x[i].max());
00362 if (v==x[i].max())
00363 v = a[i].max();
00364 assert((v >= a[i].max()) && (v <= x[i].max()));
00365 rel(i, Gecode::FRT_LQ, v);
00366 }
00367 break;
00368 case 1:
00369 if (a[i].min() > x[i].min()) {
00370 Gecode::FloatNum v=randFValUp(x[i].min(),a[i].min());
00371 if (v==x[i].min())
00372 v = a[i].min();
00373 assert((v <= a[i].min()) && (v >= x[i].min()));
00374 rel(i, Gecode::FRT_GQ, v);
00375 }
00376 break;
00377 }
00378 if (Base::fixpoint()) {
00379 if (failed() || !testfix)
00380 return true;
00381 TestSpace* c = static_cast<TestSpace*>(clone());
00382 if (opt.log)
00383 olog << ind(3) << "Testing fixpoint on copy" << std::endl;
00384 c->post();
00385 if (c->failed()) {
00386 delete c; return false;
00387 }
00388 for (int i=x.size(); i--; )
00389 if (x[i].size() != c->x[i].size()) {
00390 delete c; return false;
00391 }
00392 if (reified && (r.var().size() != c->r.var().size())) {
00393 delete c; return false;
00394 }
00395 if (opt.log)
00396 olog << ind(3) << "Finished testing fixpoint on copy" << std::endl;
00397 delete c;
00398 }
00399 return true;
00400 }
00401
00402
00403 const Gecode::FloatRelType FloatRelTypes::frts[] =
00404 {Gecode::FRT_EQ,Gecode::FRT_NQ,Gecode::FRT_LQ,Gecode::FRT_LE,
00405 Gecode::FRT_GQ,Gecode::FRT_GR};
00406
00407 Assignment*
00408 Test::assignment(void) const {
00409 switch (assigmentType) {
00410 case CPLT_ASSIGNMENT:
00411 return new CpltAssignment(arity,dom,step);
00412 case RANDOM_ASSIGNMENT:
00413 return new RandomAssignment(arity,dom,step);
00414 case EXTEND_ASSIGNMENT:
00415 return new ExtAssignment(arity,dom,step,this);
00416 default :
00417 GECODE_NEVER;
00418 }
00419 return NULL;
00420 }
00421
00422 bool
00423 Test::extendAssignement(Assignment&) const {
00424 GECODE_NEVER;
00425 return false;
00426 }
00427
00428 bool
00429 Test::subsumed(const TestSpace& ts) const {
00430 if (!testsubsumed) return true;
00431 if (ts.propagators()==0) return true;
00432 if (assigmentType == EXTEND_ASSIGNMENT) return true;
00433 return false;
00434 }
00435
00437 #define CHECK_TEST(T,M) \
00438 if (opt.log) \
00439 olog << ind(3) << "Check: " << (M) << std::endl; \
00440 if (!(T)) { \
00441 problem = (M); delete s; goto failed; \
00442 }
00443
00445 #define START_TEST(T) \
00446 if (opt.log) { \
00447 olog.str(""); \
00448 olog << ind(2) << "Testing: " << (T) << std::endl; \
00449 } \
00450 test = (T);
00451
00452 bool
00453 Test::ignore(const Assignment&) const {
00454 return false;
00455 }
00456
00457 void
00458 Test::post(Gecode::Space&, Gecode::FloatVarArray&,
00459 Gecode::Reify) {}
00460
00461 bool
00462 Test::run(void) {
00463 using namespace Gecode;
00464 const char* test = "NONE";
00465 const char* problem = "NONE";
00466
00467
00468 Assignment* ap = assignment();
00469 Assignment& a = *ap;
00470
00471
00472 TestSpace* search_s = new TestSpace(arity,dom,step,this);
00473 post(*search_s,search_s->x);
00474 branch(*search_s,search_s->x,FLOAT_VAR_NONE(),FLOAT_VAL_SPLIT_MIN());
00475 Search::Options search_o;
00476 search_o.threads = 1;
00477 DFS<TestSpace> * e_s = new DFS<TestSpace>(search_s,search_o);
00478 while (a()) {
00479 MaybeType sol = solution(a);
00480 if (opt.log) {
00481 olog << ind(1) << "Assignment: " << a;
00482 switch (sol) {
00483 case MT_TRUE: olog << " (solution)"; break;
00484 case MT_FALSE: olog << " (no solution)"; break;
00485 case MT_MAYBE: olog << " (maybe)"; break;
00486 }
00487 olog << std::endl;
00488 }
00489 START_TEST("Assignment (after posting)");
00490 {
00491 TestSpace* s = new TestSpace(arity,dom,step,this);
00492 TestSpace* sc = NULL;
00493 s->post();
00494 switch (Base::rand(3)) {
00495 case 0:
00496 if (opt.log)
00497 olog << ind(3) << "No copy" << std::endl;
00498 sc = s;
00499 s = NULL;
00500 break;
00501 case 1:
00502 if (opt.log)
00503 olog << ind(3) << "Unshared copy" << std::endl;
00504 if (s->status() != SS_FAILED) {
00505 sc = static_cast<TestSpace*>(s->clone(false));
00506 } else {
00507 sc = s; s = NULL;
00508 }
00509 break;
00510 case 2:
00511 if (opt.log)
00512 olog << ind(3) << "Shared copy" << std::endl;
00513 if (s->status() != SS_FAILED) {
00514 sc = static_cast<TestSpace*>(s->clone(true));
00515 } else {
00516 sc = s; s = NULL;
00517 }
00518 break;
00519 default: assert(false);
00520 }
00521 sc->assign(a,sol);
00522 if (sol == MT_TRUE) {
00523 CHECK_TEST(!sc->failed(), "Failed on solution");
00524 CHECK_TEST(subsumed(*sc), "No subsumption");
00525 } else if (sol == MT_FALSE) {
00526 CHECK_TEST(sc->failed(), "Solved on non-solution");
00527 }
00528 delete s; delete sc;
00529 }
00530 START_TEST("Partial assignment (after posting)");
00531 {
00532 TestSpace* s = new TestSpace(arity,dom,step,this);
00533 s->post();
00534 s->assign(a,sol,true);
00535 (void) s->failed();
00536 s->assign(a,sol);
00537 if (sol == MT_TRUE) {
00538 CHECK_TEST(!s->failed(), "Failed on solution");
00539 CHECK_TEST(subsumed(*s), "No subsumption");
00540 } else if (sol == MT_FALSE) {
00541 CHECK_TEST(s->failed(), "Solved on non-solution");
00542 }
00543 delete s;
00544 }
00545 START_TEST("Assignment (before posting)");
00546 {
00547 TestSpace* s = new TestSpace(arity,dom,step,this);
00548 s->assign(a,sol);
00549 s->post();
00550 if (sol == MT_TRUE) {
00551 CHECK_TEST(!s->failed(), "Failed on solution");
00552 CHECK_TEST(subsumed(*s), "No subsumption");
00553 } else if (sol == MT_FALSE) {
00554 CHECK_TEST(s->failed(), "Solved on non-solution");
00555 }
00556 delete s;
00557 }
00558 START_TEST("Partial assignment (before posting)");
00559 {
00560 TestSpace* s = new TestSpace(arity,dom,step,this);
00561 s->assign(a,sol,true);
00562 s->post();
00563 (void) s->failed();
00564 s->assign(a,sol);
00565 if (sol == MT_TRUE) {
00566 CHECK_TEST(!s->failed(), "Failed on solution");
00567 CHECK_TEST(subsumed(*s), "No subsumption");
00568 } else if (sol == MT_FALSE) {
00569 CHECK_TEST(s->failed(), "Solved on non-solution");
00570 }
00571 delete s;
00572 }
00573 START_TEST("Prune");
00574 {
00575 TestSpace* s = new TestSpace(arity,dom,step,this);
00576 s->post();
00577 while (!s->failed() && !s->assigned() && !s->matchAssignment(a))
00578 if (!s->prune(a,testfix)) {
00579 problem = "No fixpoint";
00580 delete s;
00581 goto failed;
00582 }
00583 s->assign(a,sol);
00584 if (sol == MT_TRUE) {
00585 CHECK_TEST(!s->failed(), "Failed on solution");
00586 CHECK_TEST(subsumed(*s), "No subsumption");
00587 } else if (sol == MT_FALSE) {
00588 CHECK_TEST(s->failed(), "Solved on non-solution");
00589 }
00590 delete s;
00591 }
00592
00593 if (reified && !ignore(a) && (sol != MT_MAYBE)) {
00594 if (eqv()) {
00595 START_TEST("Assignment reified (rewrite after post, <=>)");
00596 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00597 s->post();
00598 s->rel(sol == MT_TRUE);
00599 s->assign(a,sol);
00600 CHECK_TEST(!s->failed(), "Failed");
00601 CHECK_TEST(subsumed(*s), "No subsumption");
00602 delete s;
00603 }
00604 if (imp()) {
00605 START_TEST("Assignment reified (rewrite after post, =>)");
00606 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00607 s->post();
00608 s->rel(sol == MT_TRUE);
00609 s->assign(a,sol);
00610 CHECK_TEST(!s->failed(), "Failed");
00611 CHECK_TEST(subsumed(*s), "No subsumption");
00612 delete s;
00613 }
00614 if (pmi()) {
00615 START_TEST("Assignment reified (rewrite after post, <=)");
00616 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00617 s->post();
00618 s->rel(sol == MT_TRUE);
00619 s->assign(a,sol);
00620 CHECK_TEST(!s->failed(), "Failed");
00621 CHECK_TEST(subsumed(*s), "No subsumption");
00622 delete s;
00623 }
00624 if (eqv()) {
00625 START_TEST("Assignment reified (immediate rewrite, <=>)");
00626 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00627 s->rel(sol == MT_TRUE);
00628 s->post();
00629 s->assign(a,sol);
00630 CHECK_TEST(!s->failed(), "Failed");
00631 CHECK_TEST(subsumed(*s), "No subsumption");
00632 delete s;
00633 }
00634 if (imp()) {
00635 START_TEST("Assignment reified (immediate rewrite, =>)");
00636 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00637 s->rel(sol == MT_TRUE);
00638 s->post();
00639 s->assign(a,sol);
00640 CHECK_TEST(!s->failed(), "Failed");
00641 CHECK_TEST(subsumed(*s), "No subsumption");
00642 delete s;
00643 }
00644 if (pmi()) {
00645 START_TEST("Assignment reified (immediate rewrite, <=)");
00646 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00647 s->rel(sol == MT_TRUE);
00648 s->post();
00649 s->assign(a,sol);
00650 CHECK_TEST(!s->failed(), "Failed");
00651 CHECK_TEST(subsumed(*s), "No subsumption");
00652 delete s;
00653 }
00654 if (eqv()) {
00655 START_TEST("Assignment reified (before posting, <=>)");
00656 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00657 s->assign(a,sol);
00658 s->post();
00659 CHECK_TEST(!s->failed(), "Failed");
00660 CHECK_TEST(subsumed(*s), "No subsumption");
00661 if (s->r.var().assigned()) {
00662 if (sol == MT_TRUE) {
00663 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00664 } else if (sol == MT_FALSE) {
00665 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00666 }
00667 }
00668 delete s;
00669 }
00670 if (imp()) {
00671 START_TEST("Assignment reified (before posting, =>)");
00672 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00673 s->assign(a,sol);
00674 s->post();
00675 CHECK_TEST(!s->failed(), "Failed");
00676 CHECK_TEST(subsumed(*s), "No subsumption");
00677 if (sol == MT_TRUE) {
00678 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00679 } else if ((sol = MT_FALSE) && s->r.var().assigned()) {
00680 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00681 }
00682 delete s;
00683 }
00684 if (pmi()) {
00685 START_TEST("Assignment reified (before posting, <=)");
00686 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00687 s->assign(a,sol);
00688 s->post();
00689 CHECK_TEST(!s->failed(), "Failed");
00690 CHECK_TEST(subsumed(*s), "No subsumption");
00691 if (sol == MT_TRUE) {
00692 if (s->r.var().assigned()) {
00693 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00694 }
00695 } else if (sol == MT_FALSE) {
00696 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00697 }
00698 delete s;
00699 }
00700 if (eqv()) {
00701 START_TEST("Assignment reified (after posting, <=>)");
00702 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00703 s->post();
00704 s->assign(a,sol);
00705 CHECK_TEST(!s->failed(), "Failed");
00706 CHECK_TEST(subsumed(*s), "No subsumption");
00707 if (s->r.var().assigned()) {
00708 if (sol == MT_TRUE) {
00709 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00710 } else if (sol == MT_FALSE) {
00711 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00712 }
00713 }
00714 delete s;
00715 }
00716 if (imp()) {
00717 START_TEST("Assignment reified (after posting, =>)");
00718 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00719 s->post();
00720 s->assign(a,sol);
00721 CHECK_TEST(!s->failed(), "Failed");
00722 CHECK_TEST(subsumed(*s), "No subsumption");
00723 if (sol == MT_TRUE) {
00724 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00725 } else if (s->r.var().assigned()) {
00726 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00727 }
00728 delete s;
00729 }
00730 if (pmi()) {
00731 START_TEST("Assignment reified (after posting, <=)");
00732 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00733 s->post();
00734 s->assign(a,sol);
00735 CHECK_TEST(!s->failed(), "Failed");
00736 CHECK_TEST(subsumed(*s), "No subsumption");
00737 if (sol == MT_TRUE) {
00738 if (s->r.var().assigned()) {
00739 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00740 }
00741 } else if (sol == MT_FALSE) {
00742 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00743 }
00744 delete s;
00745 }
00746 if (eqv()) {
00747 START_TEST("Prune reified, <=>");
00748 TestSpace* s = new TestSpace(arity,dom,step,this,RM_EQV);
00749 s->post();
00750 while (!s->failed() && !s->matchAssignment(a) &&
00751 (!s->assigned() || !s->r.var().assigned()))
00752 if (!s->prune(a,testfix)) {
00753 problem = "No fixpoint";
00754 delete s;
00755 goto failed;
00756 }
00757 CHECK_TEST(!s->failed(), "Failed");
00758 CHECK_TEST(subsumed(*s), "No subsumption");
00759 if (s->r.var().assigned()) {
00760 if (sol == MT_TRUE) {
00761 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00762 } else if (sol == MT_FALSE) {
00763 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00764 }
00765 }
00766 delete s;
00767 }
00768 if (imp()) {
00769 START_TEST("Prune reified, =>");
00770 TestSpace* s = new TestSpace(arity,dom,step,this,RM_IMP);
00771 s->post();
00772 while (!s->failed() && !s->matchAssignment(a) &&
00773 (!s->assigned() || ((sol == MT_FALSE) &&
00774 !s->r.var().assigned())))
00775 if (!s->prune(a,testfix)) {
00776 problem = "No fixpoint";
00777 delete s;
00778 goto failed;
00779 }
00780 CHECK_TEST(!s->failed(), "Failed");
00781 CHECK_TEST(subsumed(*s), "No subsumption");
00782 if (sol == MT_TRUE) {
00783 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00784 } else if ((sol == MT_FALSE) && s->r.var().assigned()) {
00785 CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00786 }
00787 delete s;
00788 }
00789 if (pmi()) {
00790 START_TEST("Prune reified, <=");
00791 TestSpace* s = new TestSpace(arity,dom,step,this,RM_PMI);
00792 s->post();
00793 while (!s->failed() && !s->matchAssignment(a) &&
00794 (!s->assigned() || ((sol == MT_TRUE) &&
00795 !s->r.var().assigned())))
00796 if (!s->prune(a,testfix)) {
00797 problem = "No fixpoint";
00798 delete s;
00799 goto failed;
00800 }
00801 CHECK_TEST(!s->failed(), "Failed");
00802 CHECK_TEST(subsumed(*s), "No subsumption");
00803 if ((sol == MT_TRUE) && s->r.var().assigned()) {
00804 CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00805 } else if (sol == MT_FALSE) {
00806 CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00807 }
00808 delete s;
00809 }
00810 }
00811
00812 if (testsearch) {
00813 if (sol == MT_TRUE) {
00814 START_TEST("Search");
00815 if (!search_s->failed()) {
00816 TestSpace* ss = static_cast<TestSpace*>(search_s->clone(false));
00817 ss->dropUntil(a);
00818 delete e_s;
00819 e_s = new DFS<TestSpace>(ss,search_o);
00820 delete ss;
00821 }
00822 TestSpace* s = e_s->next();
00823 CHECK_TEST(s != NULL, "Solutions exhausted");
00824 CHECK_TEST(subsumed(*s), "No subsumption");
00825 for (int i=a.size(); i--; ) {
00826 CHECK_TEST(s->x[i].assigned(), "Unassigned variable");
00827 CHECK_TEST(Gecode::Float::overlap(a[i], s->x[i].val()), "Wrong value in solution");
00828 }
00829 delete s;
00830 }
00831 }
00832
00833 ++a;
00834 }
00835
00836 if (testsearch) {
00837 test = "Search";
00838 if (!search_s->failed()) {
00839 TestSpace* ss = static_cast<TestSpace*>(search_s->clone(false));
00840 ss->dropUntil(a);
00841 delete e_s;
00842 e_s = new DFS<TestSpace>(ss,search_o);
00843 delete ss;
00844 }
00845 if (e_s->next() != NULL) {
00846 problem = "Excess solutions";
00847 goto failed;
00848 }
00849 }
00850
00851 delete ap;
00852 delete search_s;
00853 delete e_s;
00854 return true;
00855
00856 failed:
00857 if (opt.log)
00858 olog << "FAILURE" << std::endl
00859 << ind(1) << "Test: " << test << std::endl
00860 << ind(1) << "Problem: " << problem << std::endl;
00861 if (a() && opt.log)
00862 olog << ind(1) << "Assignment: " << a << std::endl;
00863 delete ap;
00864 delete search_s;
00865 delete e_s;
00866
00867 return false;
00868 }
00869
00870 }}
00871
00872 #undef START_TEST
00873 #undef CHECK_TEST
00874
00875