Generated on Tue Apr 18 10:22:01 2017 for Gecode by doxygen 1.6.3

int.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Christian Schulte, 2005
00009  *     Mikael Lagerkvist, 2005
00010  *
00011  *  Last modified:
00012  *     $Date: 2016-10-25 12:52:26 +0200 (Tue, 25 Oct 2016) $ by $Author: schulte $
00013  *     $Revision: 15233 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include "test/int.hh"
00041 
00042 #include <algorithm>
00043 
00044 namespace Test { namespace Int {
00045 
00046 
00047   /*
00048    * Complete assignments
00049    *
00050    */
00051   void
00052   CpltAssignment::operator++(void) {
00053     int i = n-1;
00054     while (true) {
00055       ++dsv[i];
00056       if (dsv[i]() || (i == 0))
00057         return;
00058       dsv[i--].init(d);
00059     }
00060   }
00061 
00062   /*
00063    * Random assignments
00064    *
00065    */
00066   void
00067   RandomAssignment::operator++(void) {
00068     for (int i = n; i--; )
00069       vals[i]=randval();
00070     a--;
00071   }
00072 
00073   void
00074   RandomMixAssignment::operator++(void) {
00075     for (int i=n-_n1; i--; )
00076       vals[i] = randval(d);
00077     for (int i=_n1; i--; )
00078       vals[n-_n1+i] = randval(_d1);
00079     a--;
00080   }
00081 
00082 }}
00083 
00084 std::ostream&
00085 operator<<(std::ostream& os, const Test::Int::Assignment& a) {
00086   int n = a.size();
00087   os << "{";
00088   for (int i=0; i<n; i++)
00089     os << a[i] << ((i!=n-1) ? "," : "}");
00090   return os;
00091 }
00092 
00093 namespace Test { namespace Int {
00094 
00095   TestSpace::TestSpace(int n, Gecode::IntSet& d0, Test* t)
00096     : d(d0), x(*this,n,Gecode::Int::Limits::min,Gecode::Int::Limits::max),
00097       test(t), reified(false) {
00098     Gecode::IntVarArgs _x(*this,n,d);
00099     if (x.size() == 1)
00100       Gecode::dom(*this,x[0],_x[0]);
00101     else
00102       Gecode::dom(*this,x,_x);
00103     Gecode::BoolVar b(*this,0,1);
00104     r = Gecode::Reify(b,Gecode::RM_EQV);
00105     if (opt.log)
00106       olog << ind(2) << "Initial: x[]=" << x
00107            << std::endl;
00108   }
00109 
00110   TestSpace::TestSpace(int n, Gecode::IntSet& d0, Test* t,
00111                        Gecode::ReifyMode rm)
00112     : d(d0), x(*this,n,Gecode::Int::Limits::min,Gecode::Int::Limits::max),
00113       test(t), reified(true) {
00114     Gecode::IntVarArgs _x(*this,n,d);
00115     if (x.size() == 1)
00116       Gecode::dom(*this,x[0],_x[0]);
00117     else
00118       Gecode::dom(*this,x,_x);
00119     Gecode::BoolVar b(*this,0,1);
00120     r = Gecode::Reify(b,rm);
00121     if (opt.log)
00122       olog << ind(2) << "Initial: x[]=" << x
00123            << " b=" << r.var() << std::endl;
00124   }
00125 
00126   TestSpace::TestSpace(bool share, TestSpace& s)
00127     : Gecode::Space(share,s), d(s.d), test(s.test), reified(s.reified) {
00128     x.update(*this, share, s.x);
00129     Gecode::BoolVar b;
00130     Gecode::BoolVar sr(s.r.var());
00131     b.update(*this, share, sr);
00132     r.var(b); r.mode(s.r.mode());
00133   }
00134 
00135   Gecode::Space*
00136   TestSpace::copy(bool share) {
00137     return new TestSpace(share,*this);
00138   }
00139 
00140   bool
00141   TestSpace::assigned(void) const {
00142     for (int i=x.size(); i--; )
00143       if (!x[i].assigned())
00144         return false;
00145     return true;
00146   }
00147 
00148   void
00149   TestSpace::post(void) {
00150     if (reified){
00151       test->post(*this,x,r);
00152       if (opt.log)
00153         olog << ind(3) << "Posting reified propagator" << std::endl;
00154     } else {
00155       test->post(*this,x);
00156       if (opt.log)
00157         olog << ind(3) << "Posting propagator" << std::endl;
00158     }
00159   }
00160 
00161   bool
00162   TestSpace::failed(void) {
00163     if (opt.log) {
00164       olog << ind(3) << "Fixpoint: " << x;
00165       bool f=(status() == Gecode::SS_FAILED);
00166       olog << std::endl << ind(3) << "     -->  " << x << std::endl;
00167       return f;
00168     } else {
00169       return status() == Gecode::SS_FAILED;
00170     }
00171   }
00172 
00173   int
00174   TestSpace::rndvar(void) {
00175     assert(!assigned());
00176     // Select variable to be pruned
00177     int i = Base::rand(x.size());
00178     while (x[i].assigned()) {
00179       i = (i+1) % x.size();
00180     }
00181     return i;
00182   }
00183 
00184   void
00185   TestSpace::rndrel(const Assignment& a, int i,
00186                     Gecode::IntRelType& irt, int& v) {
00187     using namespace Gecode;
00188     // Select mode for pruning
00189     irt = IRT_EQ; // Means do nothing!
00190     switch (Base::rand(3)) {
00191     case 0:
00192       if (a[i] < x[i].max()) {
00193         v=a[i]+1+Base::rand(static_cast
00194                             <unsigned int>(x[i].max()-a[i]));
00195         assert((v > a[i]) && (v <= x[i].max()));
00196         irt = IRT_LE;
00197       }
00198       break;
00199     case 1:
00200       if (a[i] > x[i].min()) {
00201         v=x[i].min()+Base::rand(static_cast
00202                                 <unsigned int>(a[i]-x[i].min()));
00203         assert((v < a[i]) && (v >= x[i].min()));
00204         irt = IRT_GR;
00205       }
00206       break;
00207     default:
00208       {
00209         Gecode::Int::ViewRanges<Gecode::Int::IntView> it(x[i]);
00210         unsigned int skip = Base::rand(x[i].size()-1);
00211         while (true) {
00212           if (it.width() > skip) {
00213             v = it.min() + skip;
00214             if (v == a[i]) {
00215               if (it.width() == 1) {
00216                 ++it; v = it.min();
00217               } else if (v < it.max()) {
00218                 ++v;
00219               } else {
00220                 --v;
00221               }
00222             }
00223             break;
00224           }
00225           skip -= it.width(); ++it;
00226         }
00227         irt = IRT_NQ;
00228         break;
00229       }
00230     }
00231   }
00232 
00233   void
00234   TestSpace::rel(int i, Gecode::IntRelType irt, int n) {
00235     if (opt.log) {
00236       olog << ind(4) << "x[" << i << "] ";
00237       switch (irt) {
00238       case Gecode::IRT_EQ: olog << "="; break;
00239       case Gecode::IRT_NQ: olog << "!="; break;
00240       case Gecode::IRT_LQ: olog << "<="; break;
00241       case Gecode::IRT_LE: olog << "<"; break;
00242       case Gecode::IRT_GQ: olog << ">="; break;
00243       case Gecode::IRT_GR: olog << ">"; break;
00244       }
00245       olog << " " << n << std::endl;
00246     }
00247     Gecode::rel(*this, x[i], irt, n);
00248   }
00249 
00250   void
00251   TestSpace::rel(bool sol) {
00252     int n = sol ? 1 : 0;
00253     assert(reified);
00254     if (opt.log)
00255       olog << ind(4) << "b = " << n << std::endl;
00256     Gecode::rel(*this, r.var(), Gecode::IRT_EQ, n);
00257   }
00258 
00259   void
00260   TestSpace::assign(const Assignment& a, bool skip) {
00261     using namespace Gecode;
00262     int i = skip ? static_cast<int>(Base::rand(a.size())) : -1;
00263     for (int j=a.size(); j--; )
00264       if (i != j) {
00265         rel(j, IRT_EQ, a[j]);
00266         if (Base::fixpoint() && failed())
00267           return;
00268       }
00269   }
00270 
00271   void
00272   TestSpace::bound(void) {
00273     using namespace Gecode;
00274     int i = rndvar();
00275     bool min = Base::rand(2);
00276     rel(i, IRT_EQ, min ? x[i].min() : x[i].max());
00277   }
00278 
00279   void
00280   TestSpace::prune(int i, bool bounds_only) {
00281     using namespace Gecode;
00282     // Prune values
00283     if (bounds_only) {
00284       if (Base::rand(2) && !x[i].assigned()) {
00285         int v=x[i].min()+1+Base::rand(static_cast
00286                                       <unsigned int>(x[i].max()-x[i].min()));
00287         assert((v > x[i].min()) && (v <= x[i].max()));
00288         rel(i, Gecode::IRT_LE, v);
00289       }
00290       if (Base::rand(2) && !x[i].assigned()) {
00291         int v=x[i].min()+Base::rand(static_cast
00292                                     <unsigned int>(x[i].max()-x[i].min()));
00293         assert((v < x[i].max()) && (v >= x[i].min()));
00294         rel(i, Gecode::IRT_GR, v);
00295       }
00296     } else {
00297       for (int vals = Base::rand(x[i].size()-1)+1; vals--; ) {
00298         int v;
00299         Gecode::Int::ViewRanges<Gecode::Int::IntView> it(x[i]);
00300         unsigned int skip = Base::rand(x[i].size()-1);
00301         while (true) {
00302           if (it.width() > skip) {
00303             v = it.min() + skip; break;
00304           }
00305           skip -= it.width(); ++it;
00306         }
00307         rel(i, IRT_NQ, v);
00308       }
00309     }
00310   }
00311 
00312   void
00313   TestSpace::prune(void) {
00314     prune(rndvar(), false);
00315   }
00316 
00317   bool
00318   TestSpace::prune(const Assignment& a, bool testfix) {
00319     using namespace Gecode;
00320     // Select variable to be pruned
00321     int i = rndvar();
00322     // Select mode for pruning
00323     IntRelType irt;
00324     int v;
00325     rndrel(a,i,irt,v);
00326     if (irt != IRT_EQ)
00327       rel(i, irt, v);
00328     if (Base::fixpoint()) {
00329       if (failed() || !testfix)
00330         return true;
00331       TestSpace* c = static_cast<TestSpace*>(clone());
00332       if (opt.log)
00333         olog << ind(3) << "Testing fixpoint on copy" << std::endl;
00334       c->post();
00335       if (c->failed()) {
00336         if (opt.log)
00337           olog << ind(4) << "Copy failed after posting" << std::endl;
00338         delete c; return false;
00339       }
00340       for (int i=x.size(); i--; )
00341         if (x[i].size() != c->x[i].size()) {
00342           if (opt.log)
00343             olog << ind(4) << "Different domain size" << std::endl;
00344           delete c; return false;
00345         }
00346       if (reified && (r.var().size() != c->r.var().size())) {
00347         if (opt.log)
00348           olog << ind(4) << "Different control variable" << std::endl;
00349         delete c; return false;
00350       }
00351       if (opt.log)
00352         olog << ind(3) << "Finished testing fixpoint on copy" << std::endl;
00353       delete c;
00354     }
00355     return true;
00356   }
00357 
00358   void
00359   TestSpace::enable(void) {
00360     Gecode::PropagatorGroup::all.enable(*this);
00361   }
00362 
00363   void
00364   TestSpace::disable(void) {
00365     Gecode::PropagatorGroup::all.disable(*this);
00366     (void) status();
00367   }
00368 
00369   bool
00370   TestSpace::disabled(const Assignment& a, TestSpace& c,
00371                       bool testfix) {
00372     using namespace Gecode;
00373     // Disable propagators
00374     c.disable();
00375     // Select variable to be pruned
00376     int i = rndvar();
00377     // Select mode for pruning
00378     IntRelType irt;
00379     int v;
00380     rndrel(a,i,irt,v);
00381     if (irt != IRT_EQ) {
00382       rel(i, irt, v);
00383       c.rel(i, irt, v);
00384     }
00385     // Enable propagators
00386     c.enable();
00387     if (!testfix)
00388       return true;
00389     if (failed()) {
00390       if (!c.failed()) {
00391         if (opt.log)
00392           olog << ind(3) << "No failure on disabled copy" << std::endl;
00393         return false;
00394       }
00395       return true;
00396     }
00397     if (c.failed()) {
00398       if (opt.log)
00399         olog << ind(3) << "Failure on disabled copy" << std::endl;
00400       return false;
00401     }
00402     for (int i=x.size(); i--; ) {
00403       if (x[i].size() != c.x[i].size()) {
00404         if (opt.log)
00405           olog << ind(4) << "Different domain size" << std::endl;
00406         return false;
00407       }
00408       if (reified && (r.var().size() != c.r.var().size())) {
00409         if (opt.log)
00410           olog << ind(4) << "Different control variable" << std::endl;
00411         return false;
00412       }
00413     }
00414     return true;
00415   }
00416 
00417   unsigned int
00418   TestSpace::propagators(void) {
00419     return Gecode::PropagatorGroup::all.size(*this);
00420   }
00421 
00422   const Gecode::IntPropLevel IntPropLevels::ipls[] =
00423     {Gecode::IPL_DOM,Gecode::IPL_BND,Gecode::IPL_VAL};
00424 
00425   const Gecode::IntPropLevel IntPropBasicAdvanced::ipls[] =
00426     {Gecode::IPL_BASIC_ADVANCED,Gecode::IPL_ADVANCED,Gecode::IPL_BASIC};
00427 
00428   const Gecode::IntRelType IntRelTypes::irts[] =
00429     {Gecode::IRT_EQ,Gecode::IRT_NQ,Gecode::IRT_LQ,
00430      Gecode::IRT_LE,Gecode::IRT_GQ,Gecode::IRT_GR};
00431 
00432   const Gecode::BoolOpType BoolOpTypes::bots[] =
00433     {Gecode::BOT_AND,Gecode::BOT_OR,Gecode::BOT_IMP,
00434      Gecode::BOT_EQV,Gecode::BOT_XOR};
00435 
00436   Assignment*
00437   Test::assignment(void) const {
00438     return new CpltAssignment(arity,dom);
00439   }
00440 
00441 
00443 #define CHECK_TEST(T,M)                                         \
00444 if (opt.log)                                                    \
00445   olog << ind(3) << "Check: " << (M) << std::endl;              \
00446 if (!(T)) {                                                     \
00447   problem = (M); delete s; goto failed;                         \
00448 }
00449 
00451 #define START_TEST(T)                                           \
00452   if (opt.log) {                                                \
00453      olog.str("");                                              \
00454      olog << ind(2) << "Testing: " << (T) << std::endl;         \
00455   }                                                             \
00456   test = (T);
00457 
00458   bool
00459   Test::ignore(const Assignment&) const {
00460     return false;
00461   }
00462 
00463   void
00464   Test::post(Gecode::Space&, Gecode::IntVarArray&,
00465              Gecode::Reify) {}
00466 
00467   bool
00468   Test::run(void) {
00469     using namespace Gecode;
00470     const char* test    = "NONE";
00471     const char* problem = "NONE";
00472 
00473     // Set up assignments
00474     Assignment* ap = assignment();
00475     Assignment& a = *ap;
00476 
00477     // Set up space for all solution search
00478     TestSpace* search_s = new TestSpace(arity,dom,this);
00479     post(*search_s,search_s->x);
00480     branch(*search_s,search_s->x,INT_VAR_NONE(),INT_VAL_MIN());
00481     Search::Options search_o;
00482     search_o.threads = 1;
00483     DFS<TestSpace> e_s(search_s,search_o);
00484     delete search_s;
00485 
00486     while (a()) {
00487       bool sol = solution(a);
00488       if (opt.log) {
00489         olog << ind(1) << "Assignment: " << a
00490              << (sol ? " (solution)" : " (no solution)")
00491              << std::endl;
00492       }
00493 
00494       START_TEST("Assignment (after posting)");
00495       {
00496         TestSpace* s = new TestSpace(arity,dom,this);
00497         TestSpace* sc = NULL;
00498         s->post();
00499         switch (Base::rand(3)) {
00500           case 0:
00501             if (opt.log)
00502               olog << ind(3) << "No copy" << std::endl;
00503             sc = s;
00504             s = NULL;
00505             break;
00506           case 1:
00507             if (opt.log)
00508               olog << ind(3) << "Unshared copy" << std::endl;
00509             if (s->status() != SS_FAILED) {
00510               sc = static_cast<TestSpace*>(s->clone(false));
00511             } else {
00512               sc = s; s = NULL;
00513             }
00514             break;
00515           case 2:
00516             if (opt.log)
00517               olog << ind(3) << "Shared copy" << std::endl;
00518             if (s->status() != SS_FAILED) {
00519               sc = static_cast<TestSpace*>(s->clone(true));
00520             } else {
00521               sc = s; s = NULL;
00522             }
00523             break;
00524           default: assert(false);
00525         }
00526         sc->assign(a);
00527         if (sol) {
00528           CHECK_TEST(!sc->failed(), "Failed on solution");
00529           CHECK_TEST(sc->propagators()==0, "No subsumption");
00530         } else {
00531           CHECK_TEST(sc->failed(), "Solved on non-solution");
00532         }
00533         delete s; delete sc;
00534       }
00535       START_TEST("Partial assignment (after posting)");
00536       {
00537         TestSpace* s = new TestSpace(arity,dom,this);
00538         s->post();
00539         s->assign(a,true);
00540         (void) s->failed();
00541         s->assign(a);
00542         if (sol) {
00543           CHECK_TEST(!s->failed(), "Failed on solution");
00544           CHECK_TEST(s->propagators()==0, "No subsumption");
00545         } else {
00546           CHECK_TEST(s->failed(), "Solved on non-solution");
00547         }
00548         delete s;
00549       }
00550       START_TEST("Assignment (after posting, disable)");
00551       {
00552         TestSpace* s = new TestSpace(arity,dom,this);
00553         s->post();
00554         s->disable();
00555         s->assign(a);
00556         s->enable();
00557         if (sol) {
00558           CHECK_TEST(!s->failed(), "Failed on solution");
00559           CHECK_TEST(s->propagators()==0, "No subsumption");
00560         } else {
00561           CHECK_TEST(s->failed(), "Solved on non-solution");
00562         }
00563         delete s;
00564       }
00565       START_TEST("Partial assignment (after posting, disable)");
00566       {
00567         TestSpace* s = new TestSpace(arity,dom,this);
00568         s->post();
00569         s->assign(a,true);
00570         s->disable();
00571         (void) s->failed();
00572         s->assign(a);
00573         s->enable();
00574         if (sol) {
00575           CHECK_TEST(!s->failed(), "Failed on solution");
00576           CHECK_TEST(s->propagators()==0, "No subsumption");
00577         } else {
00578           CHECK_TEST(s->failed(), "Solved on non-solution");
00579         }
00580         delete s;
00581       }
00582       START_TEST("Assignment (before posting)");
00583       {
00584         TestSpace* s = new TestSpace(arity,dom,this);
00585         s->assign(a);
00586         s->post();
00587         if (sol) {
00588           CHECK_TEST(!s->failed(), "Failed on solution");
00589           CHECK_TEST(s->propagators()==0, "No subsumption");
00590         } else {
00591           CHECK_TEST(s->failed(), "Solved on non-solution");
00592         }
00593         delete s;
00594       }
00595       START_TEST("Partial assignment (before posting)");
00596       {
00597         TestSpace* s = new TestSpace(arity,dom,this);
00598         s->assign(a,true);
00599         s->post();
00600         (void) s->failed();
00601         s->assign(a);
00602         if (sol) {
00603           CHECK_TEST(!s->failed(), "Failed on solution");
00604           CHECK_TEST(s->propagators()==0, "No subsumption");
00605         } else {
00606           CHECK_TEST(s->failed(), "Solved on non-solution");
00607         }
00608         delete s;
00609       }
00610       START_TEST("Prune");
00611       {
00612         TestSpace* s = new TestSpace(arity,dom,this);
00613         s->post();
00614         while (!s->failed() && !s->assigned())
00615           if (!s->prune(a,testfix)) {
00616             problem = "No fixpoint";
00617             delete s;
00618             goto failed;
00619           }
00620         s->assign(a);
00621         if (sol) {
00622           CHECK_TEST(!s->failed(), "Failed on solution");
00623           CHECK_TEST(s->propagators()==0, "No subsumption");
00624         } else {
00625           CHECK_TEST(s->failed(), "Solved on non-solution");
00626         }
00627         delete s;
00628       }
00629       START_TEST("Prune (disable)");
00630       {
00631         TestSpace* s = new TestSpace(arity,dom,this);
00632         TestSpace* c = static_cast<TestSpace*>(s->clone());
00633         s->post(); c->post();
00634         while (!s->failed() && !s->assigned())
00635           if (!s->disabled(a,*c,testfix)) {
00636             problem = "Different result after re-enable";
00637             delete s; delete c;
00638             goto failed;
00639           }
00640         if (testfix && (s->failed() != c->failed())) {
00641             problem = "Different failure after re-enable";
00642             delete s; delete c;
00643             goto failed;
00644         }
00645         delete s; delete c;
00646       }
00647       if (!ignore(a)) {
00648         if (eqv()) {
00649           {
00650             START_TEST("Assignment reified (rewrite after post, <=>)");
00651             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00652             s->post();
00653             s->rel(sol);
00654             s->assign(a);
00655             CHECK_TEST(!s->failed(), "Failed");
00656             CHECK_TEST(s->propagators()==0, "No subsumption");
00657             delete s;
00658           }
00659           {
00660             START_TEST("Assignment reified (rewrite failure, <=>)");
00661             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00662             s->post();
00663             s->rel(!sol);
00664             s->assign(a);
00665             CHECK_TEST(s->failed(), "Not failed");
00666             delete s;
00667           }
00668           {
00669             START_TEST("Assignment reified (immediate rewrite, <=>)");
00670             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00671             s->rel(sol);
00672             s->post();
00673             s->assign(a);
00674             CHECK_TEST(!s->failed(), "Failed");
00675             CHECK_TEST(s->propagators()==0, "No subsumption");
00676             delete s;
00677           }
00678           {
00679             START_TEST("Assignment reified (immediate failure, <=>)");
00680             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00681             s->rel(!sol);
00682             s->post();
00683             s->assign(a);
00684             CHECK_TEST(s->failed(), "Not failed");
00685             delete s;
00686           }
00687           {
00688             START_TEST("Assignment reified (before posting, <=>)");
00689             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00690             s->assign(a);
00691             s->post();
00692             CHECK_TEST(!s->failed(), "Failed");
00693             CHECK_TEST(s->propagators()==0, "No subsumption");
00694             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00695             if (sol) {
00696               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00697             } else {
00698               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00699             }
00700             delete s;
00701           }
00702           {
00703             START_TEST("Assignment reified (after posting, <=>)");
00704             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00705             s->post();
00706             s->assign(a);
00707             CHECK_TEST(!s->failed(), "Failed");
00708             CHECK_TEST(s->propagators()==0, "No subsumption");
00709             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00710             if (sol) {
00711               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00712             } else {
00713               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00714             }
00715             delete s;
00716           }
00717           {
00718             START_TEST("Assignment reified (after posting, <=>, disable)");
00719             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00720             s->post();
00721             s->disable();
00722             s->assign(a);
00723             s->enable();
00724             CHECK_TEST(!s->failed(), "Failed");
00725             CHECK_TEST(s->propagators()==0, "No subsumption");
00726             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00727             if (sol) {
00728               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00729             } else {
00730               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00731             }
00732             delete s;
00733           }
00734           {
00735             START_TEST("Prune reified, <=>");
00736             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00737             s->post();
00738             while (!s->failed() &&
00739                    (!s->assigned() || !s->r.var().assigned()))
00740               if (!s->prune(a,testfix)) {
00741                 problem = "No fixpoint";
00742                 delete s;
00743                 goto failed;
00744               }
00745             CHECK_TEST(!s->failed(), "Failed");
00746             CHECK_TEST(s->propagators()==0, "No subsumption");
00747             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00748             if (sol) {
00749               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00750             } else {
00751               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00752             }
00753             delete s;
00754           }
00755           {
00756             START_TEST("Prune reified, <=>, disable");
00757             TestSpace* s = new TestSpace(arity,dom,this,RM_EQV);
00758             TestSpace* c = static_cast<TestSpace*>(s->clone());
00759             s->post(); c->post();
00760             while (!s->failed() &&
00761                    (!s->assigned() || !s->r.var().assigned()))
00762               if (!s->disabled(a,*c,testfix)) {
00763                 problem = "No fixpoint";
00764                 delete s;
00765                 delete c;
00766                 goto failed;
00767               }
00768             CHECK_TEST(!c->failed(), "Failed");
00769             CHECK_TEST(c->propagators()==0, "No subsumption");
00770             CHECK_TEST(c->r.var().assigned(), "Control variable unassigned");
00771             if (sol) {
00772               CHECK_TEST(c->r.var().val()==1, "Zero on solution");
00773             } else {
00774               CHECK_TEST(c->r.var().val()==0, "One on non-solution");
00775             }
00776             delete s;
00777             delete c;
00778           }
00779         }
00780 
00781         if (imp()) {
00782           {
00783             START_TEST("Assignment reified (rewrite after post, =>)");
00784             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00785             s->post();
00786             s->rel(sol);
00787             s->assign(a);
00788             CHECK_TEST(!s->failed(), "Failed");
00789             CHECK_TEST(s->propagators()==0, "No subsumption");
00790             delete s;
00791           }
00792           {
00793             START_TEST("Assignment reified (rewrite failure, =>)");
00794             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00795             s->post();
00796             s->rel(!sol);
00797             s->assign(a);
00798             if (sol) {
00799               CHECK_TEST(!s->failed(), "Failed");
00800               CHECK_TEST(s->propagators()==0, "No subsumption");
00801             } else {
00802               CHECK_TEST(s->failed(), "Not failed");
00803             }
00804             delete s;
00805           }
00806           {
00807             START_TEST("Assignment reified (immediate rewrite, =>)");
00808             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00809             s->rel(sol);
00810             s->post();
00811             s->assign(a);
00812             CHECK_TEST(!s->failed(), "Failed");
00813             CHECK_TEST(s->propagators()==0, "No subsumption");
00814             delete s;
00815           }
00816           {
00817             START_TEST("Assignment reified (immediate failure, =>)");
00818             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00819             s->rel(!sol);
00820             s->post();
00821             s->assign(a);
00822             if (sol) {
00823               CHECK_TEST(!s->failed(), "Failed");
00824               CHECK_TEST(s->propagators()==0, "No subsumption");
00825             } else {
00826               CHECK_TEST(s->failed(), "Not failed");
00827             }
00828             delete s;
00829           }
00830           {
00831             START_TEST("Assignment reified (before posting, =>)");
00832             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00833             s->assign(a);
00834             s->post();
00835             CHECK_TEST(!s->failed(), "Failed");
00836             CHECK_TEST(s->propagators()==0, "No subsumption");
00837             if (sol) {
00838               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00839             } else {
00840               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00841               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00842             }
00843             delete s;
00844           }
00845           {
00846             START_TEST("Assignment reified (after posting, =>)");
00847             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00848             s->post();
00849             s->assign(a);
00850             CHECK_TEST(!s->failed(), "Failed");
00851             CHECK_TEST(s->propagators()==0, "No subsumption");
00852             if (sol) {
00853               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00854             } else {
00855               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00856               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00857             }
00858             delete s;
00859           }
00860           {
00861             START_TEST("Assignment reified (after posting, =>, disable)");
00862             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00863             s->post();
00864             s->disable();
00865             s->assign(a);
00866             s->enable();
00867             CHECK_TEST(!s->failed(), "Failed");
00868             CHECK_TEST(s->propagators()==0, "No subsumption");
00869             if (sol) {
00870               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00871             } else {
00872               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00873               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00874             }
00875             delete s;
00876           }
00877           {
00878             START_TEST("Prune reified, =>");
00879             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00880             s->post();
00881             while (!s->failed() &&
00882                    (!s->assigned() || (!sol && !s->r.var().assigned())))
00883               if (!s->prune(a,testfix)) {
00884                 problem = "No fixpoint";
00885                 delete s;
00886                 goto failed;
00887               }
00888             CHECK_TEST(!s->failed(), "Failed");
00889             CHECK_TEST(s->propagators()==0, "No subsumption");
00890             if (sol) {
00891               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00892             } else {
00893               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00894               CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00895             }
00896             delete s;
00897           }
00898           {
00899             START_TEST("Prune reified, =>, disable");
00900             TestSpace* s = new TestSpace(arity,dom,this,RM_IMP);
00901             TestSpace* c = static_cast<TestSpace*>(s->clone());
00902             s->post(); c->post();
00903             while (!s->failed() &&
00904                    (!s->assigned() || (!sol && !s->r.var().assigned())))
00905               if (!s->disabled(a,*c,testfix)) {
00906                 problem = "No fixpoint";
00907                 delete s;
00908                 delete c;
00909                 goto failed;
00910               }
00911             CHECK_TEST(!c->failed(), "Failed");
00912             CHECK_TEST(c->propagators()==0, "No subsumption");
00913             if (sol) {
00914               CHECK_TEST(!c->r.var().assigned(), "Control variable assigned");
00915             } else {
00916               CHECK_TEST(c->r.var().assigned(), "Control variable unassigned");
00917               CHECK_TEST(c->r.var().val()==0, "One on non-solution");
00918             }
00919             delete s;
00920             delete c;
00921           }
00922         }
00923 
00924         if (pmi()) {
00925           {
00926             START_TEST("Assignment reified (rewrite after post, <=)");
00927             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
00928             s->post();
00929             s->rel(sol);
00930             s->assign(a);
00931             CHECK_TEST(!s->failed(), "Failed");
00932             CHECK_TEST(s->propagators()==0, "No subsumption");
00933             delete s;
00934           }
00935           {
00936             START_TEST("Assignment reified (rewrite failure, <=)");
00937             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
00938             s->post();
00939             s->rel(!sol);
00940             s->assign(a);
00941             if (sol) {
00942               CHECK_TEST(s->failed(), "Not failed");
00943             } else {
00944               CHECK_TEST(!s->failed(), "Failed");
00945               CHECK_TEST(s->propagators()==0, "No subsumption");
00946             }
00947             delete s;
00948           }
00949           {
00950             START_TEST("Assignment reified (immediate rewrite, <=)");
00951             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
00952             s->rel(sol);
00953             s->post();
00954             s->assign(a);
00955             CHECK_TEST(!s->failed(), "Failed");
00956             CHECK_TEST(s->propagators()==0, "No subsumption");
00957             delete s;
00958           }
00959           {
00960             START_TEST("Assignment reified (immediate failure, <=)");
00961             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
00962             s->rel(!sol);
00963             s->post();
00964             s->assign(a);
00965             if (sol) {
00966               CHECK_TEST(s->failed(), "Not failed");
00967             } else {
00968               CHECK_TEST(!s->failed(), "Failed");
00969               CHECK_TEST(s->propagators()==0, "No subsumption");
00970             }
00971             delete s;
00972           }
00973           {
00974             START_TEST("Assignment reified (before posting, <=)");
00975             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
00976             s->assign(a);
00977             s->post();
00978             CHECK_TEST(!s->failed(), "Failed");
00979             CHECK_TEST(s->propagators()==0, "No subsumption");
00980             if (sol) {
00981               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00982               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00983             } else {
00984               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00985             }
00986             delete s;
00987           }
00988           {
00989             START_TEST("Assignment reified (after posting, <=)");
00990             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
00991             s->post();
00992             s->assign(a);
00993             CHECK_TEST(!s->failed(), "Failed");
00994             CHECK_TEST(s->propagators()==0, "No subsumption");
00995             if (sol) {
00996               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00997               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00998             } else {
00999               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
01000             }
01001             delete s;
01002           }
01003           {
01004             START_TEST("Assignment reified (after posting, <=, disable)");
01005             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
01006             s->post();
01007             s->disable();
01008             s->assign(a);
01009             s->enable();
01010             CHECK_TEST(!s->failed(), "Failed");
01011             CHECK_TEST(s->propagators()==0, "No subsumption");
01012             if (sol) {
01013               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
01014               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
01015             } else {
01016               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
01017             }
01018             delete s;
01019           }
01020           {
01021             START_TEST("Prune reified, <=");
01022             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
01023             s->post();
01024             while (!s->failed() &&
01025                    (!s->assigned() || (sol && !s->r.var().assigned())))
01026               if (!s->prune(a,testfix)) {
01027                 problem = "No fixpoint";
01028                 delete s;
01029                 goto failed;
01030               }
01031             CHECK_TEST(!s->failed(), "Failed");
01032             CHECK_TEST(s->propagators()==0, "No subsumption");
01033             if (sol) {
01034               CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
01035               CHECK_TEST(s->r.var().val()==1, "Zero on solution");
01036             } else {
01037               CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
01038             }
01039             delete s;
01040           }
01041           {
01042             START_TEST("Prune reified, <=, disable");
01043             TestSpace* s = new TestSpace(arity,dom,this,RM_PMI);
01044             TestSpace* c = static_cast<TestSpace*>(s->clone());
01045             s->post(); c->post();
01046             while (!s->failed() &&
01047                    (!s->assigned() || (sol && !s->r.var().assigned())))
01048               if (!s->disabled(a,*c,testfix)) {
01049                 problem = "No fixpoint";
01050                 delete s;
01051                 delete c;
01052                 goto failed;
01053               }
01054             CHECK_TEST(!c->failed(), "Failed");
01055             CHECK_TEST(c->propagators()==0, "No subsumption");
01056             if (sol) {
01057               CHECK_TEST(c->r.var().assigned(), "Control variable unassigned");
01058               CHECK_TEST(c->r.var().val()==1, "Zero on solution");
01059             } else {
01060               CHECK_TEST(!c->r.var().assigned(), "Control variable assigned");
01061             }
01062             delete s;
01063             delete c;
01064           }
01065         }
01066       }
01067 
01068       if (testsearch) {
01069         if (sol) {
01070           START_TEST("Search");
01071           TestSpace* s = e_s.next();
01072           CHECK_TEST(s != NULL, "Solutions exhausted");
01073           CHECK_TEST(s->propagators()==0, "No subsumption");
01074           for (int i=a.size(); i--; ) {
01075             CHECK_TEST(s->x[i].assigned(), "Unassigned variable");
01076             CHECK_TEST(a[i] == s->x[i].val(), "Wrong value in solution");
01077           }
01078           delete s;
01079         }
01080       }
01081 
01082       ++a;
01083     }
01084 
01085     if (testsearch) {
01086       test = "Search";
01087       if (e_s.next() != NULL) {
01088         problem = "Excess solutions";
01089         goto failed;
01090       }
01091     }
01092 
01093     switch (contest) {
01094     case CTL_NONE: break;
01095     case CTL_DOMAIN: {
01096       START_TEST("Full domain consistency");
01097       TestSpace* s = new TestSpace(arity,dom,this);
01098       s->post();
01099       if (!s->failed()) {
01100         while (!s->failed() && !s->assigned())
01101           s->prune();
01102         CHECK_TEST(!s->failed(), "Failed");
01103         CHECK_TEST(s->propagators()==0, "No subsumption");
01104       }
01105       delete s;
01106       // Fall-through -- domain implies bounds(d) and bounds(z)
01107     }
01108     case CTL_BOUNDS_D: {
01109       START_TEST("Bounds(D)-consistency");
01110       TestSpace* s = new TestSpace(arity,dom,this);
01111       s->post();
01112       for (int i = s->x.size(); i--; )
01113         s->prune(i, false);
01114       if (!s->failed()) {
01115         while (!s->failed() && !s->assigned())
01116           s->bound();
01117         CHECK_TEST(!s->failed(), "Failed");
01118         CHECK_TEST(s->propagators()==0, "No subsumption");
01119       }
01120       delete s;
01121       // Fall-through -- bounds(d) implies bounds(z)
01122     }
01123     case CTL_BOUNDS_Z: {
01124       START_TEST("Bounds(Z)-consistency");
01125       TestSpace* s = new TestSpace(arity,dom,this);
01126       s->post();
01127       for (int i = s->x.size(); i--; )
01128         s->prune(i, true);
01129       if (!s->failed()) {
01130         while (!s->failed() && !s->assigned())
01131           s->bound();
01132         CHECK_TEST(!s->failed(), "Failed");
01133         CHECK_TEST(s->propagators()==0, "No subsumption");
01134       }
01135       delete s;
01136       break;
01137     }
01138     }
01139 
01140     delete ap;
01141     return true;
01142 
01143   failed:
01144     if (opt.log)
01145       olog << "FAILURE" << std::endl
01146            << ind(1) << "Test:       " << test << std::endl
01147            << ind(1) << "Problem:    " << problem << std::endl;
01148     if (a() && opt.log)
01149       olog << ind(1) << "Assignment: " << a << std::endl;
01150     delete ap;
01151 
01152     return false;
01153   }
01154 
01155 }}
01156 
01157 #undef START_TEST
01158 #undef CHECK_TEST
01159 
01160 // STATISTICS: test-int