Generated on Fri Mar 20 15:56:21 2015 for Gecode by doxygen 1.6.3

set.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *     Christian Schulte <schulte@gecode.org>
00006  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00007  *
00008  *  Copyright:
00009  *     Guido Tack, 2005
00010  *     Christian Schulte, 2005
00011  *     Mikael Lagerkvist, 2005
00012  *
00013  *  Last modified:
00014  *     $Date: 2013-03-05 14:40:46 +0100 (Tue, 05 Mar 2013) $ by $Author: schulte $
00015  *     $Revision: 13435 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  Permission is hereby granted, free of charge, to any person obtaining
00022  *  a copy of this software and associated documentation files (the
00023  *  "Software"), to deal in the Software without restriction, including
00024  *  without limitation the rights to use, copy, modify, merge, publish,
00025  *  distribute, sublicense, and/or sell copies of the Software, and to
00026  *  permit persons to whom the Software is furnished to do so, subject to
00027  *  the following conditions:
00028  *
00029  *  The above copyright notice and this permission notice shall be
00030  *  included in all copies or substantial portions of the Software.
00031  *
00032  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00033  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00034  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00035  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00036  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00037  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00038  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00039  *
00040  */
00041 
00042 #include "test/set.hh"
00043 
00044 #include <algorithm>
00045 
00046 namespace Test { namespace Set {
00047 
00048   CountableSet::CountableSet(const Gecode::IntSet& d0) : d(d0), cur(0) {
00049     Gecode::IntSetRanges isr(d);
00050     lubmax =
00051       static_cast<unsigned int>(pow(static_cast<double>(2.0),
00052         static_cast<int>(Gecode::Iter::Ranges::size(isr))));
00053   }
00054 
00055   void CountableSet::operator++(void) {
00056     cur++;
00057   }
00058 
00059   void CountableSet::init(const Gecode::IntSet& d0) {
00060     d = d0;
00061     cur = 0;
00062     Gecode::IntSetRanges isr(d);
00063     lubmax =
00064       static_cast<unsigned int>(pow(static_cast<double>(2.0),
00065         static_cast<int>(Gecode::Iter::Ranges::size(isr))));
00066   }
00067 
00068   int CountableSet::val(void) const {
00069     return cur;
00070   }
00071 
00072   SetAssignment::SetAssignment(int n0, const Gecode::IntSet& d0, int _withInt)
00073     : n(n0), dsv(new CountableSet[n]), ir(_withInt, d0), done(false), lub(d0),
00074       withInt(_withInt) {
00075     for (int i=n; i--; )
00076       dsv[i].init(lub);
00077   }
00078 
00079   void
00080   SetAssignment::operator++(void) {
00081     int i = n-1;
00082     while (true) {
00083       ++dsv[i];
00084       if (dsv[i]())
00085         return;
00086       dsv[i].init(lub);
00087       --i;
00088       if (i<0) {
00089         if (withInt==0) {
00090           done = true;
00091           return;
00092         }
00093         ++ir;
00094         if (ir()) {
00095           i = n-1;
00096           for (int j=n; j--; )
00097             dsv[j].init(lub);
00098         } else {
00099           done = true;
00100           return;
00101         }
00102       }
00103     }
00104   }
00105 
00106 }}
00107 
00108 std::ostream&
00109 operator<<(std::ostream& os, const Test::Set::SetAssignment& a) {
00110   int n = a.size();
00111   os << "{";
00112   for (int i=0; i<n; i++) {
00113     Test::Set::CountableSetRanges csv(a.lub, a[i]);
00114     Gecode::IntSet icsv(csv);
00115     os << icsv << ((i!=n-1) ? "," : "}");
00116   }
00117   if (a.withInt > 0)
00118     os << a.ints();
00119   return os;
00120 }
00121 
00122 namespace Test { namespace Set {
00123 
00124   SetTestSpace::SetTestSpace(int n, Gecode::IntSet& d0, int i,
00125                              SetTest* t, bool log)
00126     : d(d0), y(*this, i, d),
00127       withInt(i), r(Gecode::BoolVar(*this, 0, 1),Gecode::RM_EQV), 
00128       reified(false), test(t) {
00129     using namespace Gecode;
00130     IntSet u(Gecode::Set::Limits::min,Gecode::Set::Limits::max);
00131     x = SetVarArray(*this, n, Gecode::IntSet::empty, u);
00132     SetVarArgs _x(*this, n, Gecode::IntSet::empty, d);
00133     if (x.size() == 1)
00134       dom(*this,x[0],_x[0]);
00135     else
00136       dom(*this,x,_x);
00137     if (opt.log && log) {
00138       olog << ind(2) << "Initial: x[]=" << x;
00139       olog << " y[]=" << y;
00140       olog << std::endl;
00141     }
00142   }
00143 
00144   SetTestSpace::SetTestSpace(int n, Gecode::IntSet& d0, int i,
00145                              SetTest* t, Gecode::ReifyMode rm, bool log)
00146     : d(d0), x(*this, n, Gecode::IntSet::empty, d), y(*this, i, d),
00147       withInt(i), r(Gecode::BoolVar(*this, 0, 1),rm), 
00148       reified(true), test(t) {
00149     if (opt.log && log) {
00150       olog << ind(2) << "Initial: x[]=" << x;
00151       olog << " y[]=" << y;
00152       olog << " b=" << r.var();
00153       olog << std::endl;
00154     }
00155   }
00156   
00157   SetTestSpace::SetTestSpace(bool share, SetTestSpace& s)
00158     : Gecode::Space(share,s), d(s.d), withInt(s.withInt),
00159       reified(s.reified), test(s.test) {
00160     x.update(*this, share, s.x);
00161     y.update(*this, share, s.y);
00162     Gecode::BoolVar b;
00163     Gecode::BoolVar sr(s.r.var());
00164     b.update(*this, share, sr);
00165     r.var(b); r.mode(s.r.mode());
00166   }
00167   
00168   Gecode::Space* 
00169   SetTestSpace::copy(bool share) {
00170     return new SetTestSpace(share,*this);
00171   }
00172   
00173   void 
00174   SetTestSpace::post(void) {
00175     if (reified){
00176       test->post(*this,x,y,r);
00177       if (opt.log)
00178         olog << ind(3) << "Posting reified propagator" << std::endl;
00179     } else {
00180       test->post(*this,x,y);
00181       if (opt.log)
00182         olog << ind(3) << "Posting propagator" << std::endl;
00183     }
00184   }
00185 
00186   bool 
00187   SetTestSpace::failed(void) {
00188     if (opt.log) {
00189       olog << ind(3) << "Fixpoint: x[]=" << x
00190            << " y[]=" << y << std::endl;
00191       bool f=(status() == Gecode::SS_FAILED);
00192       olog << ind(3) << "     -->  x[]=" << x
00193            << " y[]=" << y << std::endl;
00194       return f;
00195     } else {
00196       return status() == Gecode::SS_FAILED;
00197     }
00198   }
00199 
00200   void 
00201   SetTestSpace::rel(int i, Gecode::SetRelType srt, const Gecode::IntSet& is) {
00202     if (opt.log) {
00203       olog << ind(4) << "x[" << i << "] ";
00204       switch (srt) {
00205       case Gecode::SRT_EQ: olog << "="; break;
00206       case Gecode::SRT_LQ: olog << "<="; break;
00207       case Gecode::SRT_LE: olog << "<"; break;
00208       case Gecode::SRT_GQ: olog << ">="; break;
00209       case Gecode::SRT_GR: olog << ">"; break;
00210       case Gecode::SRT_NQ: olog << "!="; break;
00211       case Gecode::SRT_SUB: olog << "sub"; break;
00212       case Gecode::SRT_SUP: olog << "sup"; break;
00213       case Gecode::SRT_DISJ: olog << "||"; break;
00214       case Gecode::SRT_CMPL: olog << "^-1 = "; break;
00215       }
00216       olog << is << std::endl;
00217     }
00218     Gecode::dom(*this, x[i], srt, is);
00219   }
00220 
00221   void 
00222   SetTestSpace::cardinality(int i, int cmin, int cmax) {
00223     if (opt.log) {
00224       olog << ind(4) << cmin << " <= #(x[" << i << "]) <= " << cmax
00225            << std::endl;
00226     }
00227     Gecode::cardinality(*this, x[i], cmin, cmax);
00228   }
00229 
00230   void 
00231   SetTestSpace::rel(int i, Gecode::IntRelType irt, int n) {
00232     if (opt.log) {
00233       olog << ind(4) << "y[" << i << "] ";
00234       switch (irt) {
00235       case Gecode::IRT_EQ: olog << "="; break;
00236       case Gecode::IRT_NQ: olog << "!="; break;
00237       case Gecode::IRT_LQ: olog << "<="; break;
00238       case Gecode::IRT_LE: olog << "<"; break;
00239       case Gecode::IRT_GQ: olog << ">="; break;
00240       case Gecode::IRT_GR: olog << ">"; break;
00241       }
00242       olog << " " << n << std::endl;
00243     }
00244     Gecode::rel(*this, y[i], irt, n);
00245   }
00246 
00247   void 
00248   SetTestSpace::rel(bool sol) {
00249     int n = sol ? 1 : 0;
00250     assert(reified);
00251     if (opt.log)
00252       olog << ind(4) << "b = " << n << std::endl;
00253     Gecode::rel(*this, r.var(), Gecode::IRT_EQ, n);
00254   }
00255   
00256   void 
00257   SetTestSpace::assign(const SetAssignment& a) {
00258     for (int i=a.size(); i--; ) {
00259       CountableSetRanges csv(a.lub, a[i]);
00260       Gecode::IntSet ai(csv);
00261       rel(i, Gecode::SRT_EQ, ai);
00262       if (Base::fixpoint() && failed())
00263         return;
00264     }
00265     for (int i=withInt; i--; ) {
00266       rel(i, Gecode::IRT_EQ, a.ints()[i]);
00267       if (Base::fixpoint() && failed())
00268         return;
00269     }
00270   }
00271   
00272   bool 
00273   SetTestSpace::assigned(void) const {
00274     for (int i=x.size(); i--; )
00275       if (!x[i].assigned())
00276         return false;
00277     for (int i=y.size(); i--; )
00278       if (!y[i].assigned())
00279         return false;
00280     return true;
00281   }
00282 
00283   void 
00284   SetTestSpace::removeFromLub(int v, int i, const SetAssignment& a) {
00285     using namespace Gecode;
00286     SetVarUnknownRanges ur(x[i]);
00287     CountableSetRanges air(a.lub, a[i]);
00288     Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges,
00289       CountableSetRanges> diff(ur, air);
00290     Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Diff
00291       <Gecode::SetVarUnknownRanges, CountableSetRanges> > diffV(diff);
00292     for (int j=0; j<v; j++, ++diffV) {}
00293     rel(i, Gecode::SRT_DISJ, Gecode::IntSet(diffV.val(), diffV.val()));
00294   }
00295 
00296   void 
00297   SetTestSpace::addToGlb(int v, int i, const SetAssignment& a) {
00298     using namespace Gecode;
00299     SetVarUnknownRanges ur(x[i]);
00300     CountableSetRanges air(a.lub, a[i]);
00301     Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges,
00302       CountableSetRanges> inter(ur, air);
00303     Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Inter
00304       <Gecode::SetVarUnknownRanges, CountableSetRanges> > interV(inter);
00305     for (int j=0; j<v; j++, ++interV) {}
00306     rel(i, Gecode::SRT_SUP, Gecode::IntSet(interV.val(), interV.val()));
00307   }
00308 
00309   bool 
00310   SetTestSpace::fixprob(void) {
00311     if (failed())
00312       return true;
00313     SetTestSpace* c = static_cast<SetTestSpace*>(clone());
00314     if (opt.log)
00315       olog << ind(3) << "Testing fixpoint on copy" << std::endl;
00316     c->post();
00317     if (c->failed()) {
00318       delete c; return false;
00319     }
00320     
00321     for (int i=x.size(); i--; )
00322       if (x[i].glbSize() != c->x[i].glbSize() ||
00323           x[i].lubSize() != c->x[i].lubSize() ||
00324           x[i].cardMin() != c->x[i].cardMin() ||
00325           x[i].cardMax() != c->x[i].cardMax()) {
00326         delete c;
00327         return false;
00328       }
00329     for (int i=y.size(); i--; )
00330       if (y[i].size() != c->y[i].size()) {
00331         delete c; return false;
00332       }
00333     if (reified && (r.var().size() != c->r.var().size())) {
00334       delete c; return false;
00335     }
00336     if (opt.log)
00337       olog << ind(3) << "Finished testing fixpoint on copy" << std::endl;
00338     delete c;
00339     return true;
00340   }
00341 
00342   bool 
00343   SetTestSpace::prune(const SetAssignment& a) {
00344     using namespace Gecode;
00345     bool setsAssigned = true;
00346     for (int j=x.size(); j--; )
00347       if (!x[j].assigned()) {
00348         setsAssigned = false;
00349         break;
00350       }
00351     bool intsAssigned = true;
00352     for (int j=y.size(); j--; )
00353       if (!y[j].assigned()) {
00354         intsAssigned = false;
00355         break;
00356       }
00357     
00358     // Select variable to be pruned
00359     int i;
00360     if (intsAssigned) {
00361       i = Base::rand(x.size());
00362     } else if (setsAssigned) {
00363       i = Base::rand(y.size());
00364     } else {
00365       i = Base::rand(x.size()+y.size());
00366     }
00367     
00368     if (setsAssigned || i>=x.size()) {
00369       if (i>=x.size())
00370         i = i-x.size();
00371       while (y[i].assigned()) {
00372         i = (i+1) % y.size();
00373       }
00374       // Prune int var
00375       
00376       // Select mode for pruning
00377       switch (Base::rand(3)) {
00378       case 0:
00379         if (a.ints()[i] < y[i].max()) {
00380           int v=a.ints()[i]+1+
00381             Base::rand(static_cast<unsigned int>(y[i].max()-a.ints()[i]));
00382           assert((v > a.ints()[i]) && (v <= y[i].max()));
00383           rel(i, Gecode::IRT_LE, v);
00384         }
00385         break;
00386       case 1:
00387         if (a.ints()[i] > y[i].min()) {
00388           int v=y[i].min()+
00389             Base::rand(static_cast<unsigned int>(a.ints()[i]-y[i].min()));
00390           assert((v < a.ints()[i]) && (v >= y[i].min()));
00391           rel(i, Gecode::IRT_GR, v);
00392         }
00393         break;
00394       default:
00395         int v;
00396         Gecode::Int::ViewRanges<Gecode::Int::IntView> it(y[i]);
00397         unsigned int skip = Base::rand(y[i].size()-1);
00398         while (true) {
00399           if (it.width() > skip) {
00400             v = it.min() + skip;
00401             if (v == a.ints()[i]) {
00402               if (it.width() == 1) {
00403                 ++it; v = it.min();
00404               } else if (v < it.max()) {
00405                 ++v;
00406               } else {
00407                 --v;
00408               }
00409             }
00410             break;
00411           }
00412           skip -= it.width();
00413           ++it;
00414         }
00415         rel(i, Gecode::IRT_NQ, v);
00416       }
00417       return (!Base::fixpoint() || fixprob());
00418     }
00419     while (x[i].assigned()) {
00420       i = (i+1) % x.size();
00421     }
00422     Gecode::SetVarUnknownRanges ur1(x[i]);
00423     CountableSetRanges air1(a.lub, a[i]);
00424     Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges,
00425       CountableSetRanges> diff(ur1, air1);
00426     Gecode::SetVarUnknownRanges ur2(x[i]);
00427     CountableSetRanges air2(a.lub, a[i]);
00428     Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges,
00429       CountableSetRanges> inter(ur2, air2);
00430     
00431     CountableSetRanges aisizer(a.lub, a[i]);
00432     unsigned int aisize = Gecode::Iter::Ranges::size(aisizer);
00433     
00434     // Select mode for pruning
00435     switch (Base::rand(5)) {
00436     case 0:
00437       if (inter()) {
00438         int v = Base::rand(Gecode::Iter::Ranges::size(inter));
00439         addToGlb(v, i, a);
00440       }
00441       break;
00442     case 1:
00443       if (diff()) {
00444         int v = Base::rand(Gecode::Iter::Ranges::size(diff));
00445         removeFromLub(v, i, a);
00446       }
00447       break;
00448     case 2:
00449       if (x[i].cardMin() < aisize) {
00450         unsigned int newc = x[i].cardMin() + 1 +
00451           Base::rand(aisize - x[i].cardMin());
00452         assert( newc > x[i].cardMin() );
00453         assert( newc <= aisize );
00454         cardinality(i, newc, Gecode::Set::Limits::card);
00455       }
00456       break;
00457     case 3:
00458       if (x[i].cardMax() > aisize) {
00459         unsigned int newc = x[i].cardMax() - 1 -
00460           Base::rand(x[i].cardMax() - aisize);
00461         assert( newc < x[i].cardMax() );
00462         assert( newc >= aisize );
00463         cardinality(i, 0, newc);
00464       }
00465       break;
00466     default:
00467       if (inter()) {
00468         int v = Base::rand(Gecode::Iter::Ranges::size(inter));
00469         addToGlb(v, i, a);
00470       } else {
00471         int v = Base::rand(Gecode::Iter::Ranges::size(diff));
00472         removeFromLub(v, i, a);
00473       }
00474     }
00475     return (!Base::fixpoint() || fixprob());
00476   }
00477 
00478 
00480 #define CHECK_TEST(T,M)                                         \
00481 if (opt.log)                                                    \
00482   olog << ind(3) << "Check: " << (M) << std::endl;              \
00483 if (!(T)) {                                                     \
00484   problem = (M); delete s; goto failed;                         \
00485 }
00486 
00488 #define START_TEST(T)                                           \
00489   if (opt.log) {                                                \
00490      olog.str("");                                              \
00491      olog << ind(2) << "Testing: " << (T) << std::endl;         \
00492   }                                                             \
00493   test = (T);
00494 
00495   bool
00496   SetTest::run(void) {
00497     using namespace Gecode;
00498     const char* test    = "NONE";
00499     const char* problem = "NONE";
00500 
00501     SetAssignment* ap = new SetAssignment(arity,lub,withInt);
00502     SetAssignment& a = *ap;
00503     while (a()) {
00504       bool is_sol = solution(a);
00505       if (opt.log)
00506         olog << ind(1) << "Assignment: " << a
00507              << (is_sol ? " (solution)" : " (no solution)")
00508              << std::endl;
00509 
00510       START_TEST("Assignment (after posting)");
00511       {
00512         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this);
00513         SetTestSpace* sc = NULL;
00514         s->post();
00515         switch (Base::rand(3)) {
00516           case 0:
00517             if (opt.log)
00518               olog << ind(3) << "No copy" << std::endl;
00519             sc = s;
00520             s = NULL;
00521             break;
00522           case 1:
00523             if (opt.log)
00524               olog << ind(3) << "Unshared copy" << std::endl;
00525             if (s->status() != Gecode::SS_FAILED) {
00526               sc = static_cast<SetTestSpace*>(s->clone(true));
00527             } else {
00528               sc = s; s = NULL;
00529             }
00530             break;
00531           case 2:
00532             if (opt.log)
00533               olog << ind(3) << "Unshared copy" << std::endl;
00534             if (s->status() != Gecode::SS_FAILED) {
00535               sc = static_cast<SetTestSpace*>(s->clone(false));
00536             } else {
00537               sc = s; s = NULL;
00538             }
00539             break;
00540           default: assert(false);
00541         }
00542         sc->assign(a);
00543         if (is_sol) {
00544           CHECK_TEST(!sc->failed(), "Failed on solution");
00545           CHECK_TEST(sc->propagators()==0, "No subsumption");
00546         } else {
00547           CHECK_TEST(sc->failed(), "Solved on non-solution");
00548         }
00549         delete s; delete sc;
00550       }
00551       START_TEST("Assignment (before posting)");
00552       {
00553         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this);
00554         s->assign(a);
00555         s->post();
00556         if (is_sol) {
00557           CHECK_TEST(!s->failed(), "Failed on solution");
00558           CHECK_TEST(s->propagators()==0, "No subsumption");
00559         } else {
00560           CHECK_TEST(s->failed(), "Solved on non-solution");
00561         }
00562         delete s;
00563       }
00564       START_TEST("Prune");
00565       {
00566         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this);
00567         s->post();
00568         while (!s->failed() && !s->assigned())
00569            if (!s->prune(a)) {
00570              problem = "No fixpoint";
00571              delete s;
00572              goto failed;
00573            }
00574         s->assign(a);
00575         if (is_sol) {
00576           CHECK_TEST(!s->failed(), "Failed on solution");
00577           CHECK_TEST(s->propagators()==0, "No subsumption");
00578         } else {
00579           CHECK_TEST(s->failed(), "Solved on non-solution");
00580         }
00581         delete s;
00582       }
00583 
00584       if (reified) {
00585         START_TEST("Assignment reified (rewrite after post, <=>)");
00586         {
00587           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00588           s->post();
00589           s->rel(is_sol);
00590           s->assign(a);
00591           CHECK_TEST(!s->failed(), "Failed");
00592           CHECK_TEST(s->propagators()==0, "No subsumption");
00593           delete s;
00594         }
00595         START_TEST("Assignment reified (rewrite after post, =>)");
00596         {
00597           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00598           s->post();
00599           s->rel(is_sol);
00600           s->assign(a);
00601           CHECK_TEST(!s->failed(), "Failed");
00602           CHECK_TEST(s->propagators()==0, "No subsumption");
00603           delete s;
00604         }
00605         START_TEST("Assignment reified (rewrite after post, <=)");
00606         {
00607           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00608           s->post();
00609           s->rel(is_sol);
00610           s->assign(a);
00611           CHECK_TEST(!s->failed(), "Failed");
00612           CHECK_TEST(s->propagators()==0, "No subsumption");
00613           delete s;
00614         }
00615         {
00616           START_TEST("Assignment reified (rewrite failure, <=>)");
00617           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00618           s->post();
00619           s->rel(!is_sol);
00620           s->assign(a);
00621           CHECK_TEST(s->failed(), "Not failed");
00622           delete s;
00623         }
00624         {
00625           START_TEST("Assignment reified (rewrite failure, =>)");
00626           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00627           s->post();
00628           s->rel(!is_sol);
00629           s->assign(a);
00630           if (is_sol) {
00631             CHECK_TEST(!s->failed(), "Failed");
00632             CHECK_TEST(s->propagators()==0, "No subsumption");
00633           } else {
00634             CHECK_TEST(s->failed(), "Not failed");
00635           }
00636           delete s;
00637         }
00638         {
00639           START_TEST("Assignment reified (rewrite failure, <=)");
00640           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00641           s->post();
00642           s->rel(!is_sol);
00643           s->assign(a);
00644           if (is_sol) {
00645             CHECK_TEST(s->failed(), "Not failed");
00646           } else {
00647             CHECK_TEST(!s->failed(), "Failed");
00648             CHECK_TEST(s->propagators()==0, "No subsumption");
00649           }
00650           delete s;
00651         }
00652         START_TEST("Assignment reified (immediate rewrite, <=>)");
00653         {
00654           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00655           s->rel(is_sol);
00656           s->post();
00657           s->assign(a);
00658           CHECK_TEST(!s->failed(), "Failed");
00659           CHECK_TEST(s->propagators()==0, "No subsumption");
00660           delete s;
00661         }
00662         START_TEST("Assignment reified (immediate rewrite, =>)");
00663         {
00664           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00665           s->rel(is_sol);
00666           s->post();
00667           s->assign(a);
00668           CHECK_TEST(!s->failed(), "Failed");
00669           CHECK_TEST(s->propagators()==0, "No subsumption");
00670           delete s;
00671         }
00672         START_TEST("Assignment reified (immediate rewrite, <=)");
00673         {
00674           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00675           s->rel(is_sol);
00676           s->post();
00677           s->assign(a);
00678           CHECK_TEST(!s->failed(), "Failed");
00679           CHECK_TEST(s->propagators()==0, "No subsumption");
00680           delete s;
00681         }
00682         START_TEST("Assignment reified (immediate failure, <=>)");
00683         {
00684           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00685           s->rel(!is_sol);
00686           s->post();
00687           s->assign(a);
00688           CHECK_TEST(s->failed(), "Not failed");
00689           delete s;
00690         }
00691         START_TEST("Assignment reified (immediate failure, =>)");
00692         {
00693           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00694           s->rel(!is_sol);
00695           s->post();
00696           s->assign(a);
00697           if (is_sol) {
00698             CHECK_TEST(!s->failed(), "Failed");
00699             CHECK_TEST(s->propagators()==0, "No subsumption");
00700           } else {
00701             CHECK_TEST(s->failed(), "Not failed");
00702           }
00703           delete s;
00704         }
00705         START_TEST("Assignment reified (immediate failure, <=)");
00706         {
00707           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00708           s->rel(!is_sol);
00709           s->post();
00710           s->assign(a);
00711           if (is_sol) {
00712             CHECK_TEST(s->failed(), "Not failed");
00713           } else {
00714             CHECK_TEST(!s->failed(), "Failed");
00715             CHECK_TEST(s->propagators()==0, "No subsumption");
00716           }
00717           delete s;
00718         }
00719         START_TEST("Assignment reified (before posting, <=>)");
00720         {
00721           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00722           s->assign(a);
00723           s->post();
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 (is_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         START_TEST("Assignment reified (before posting, =>)");
00735         {
00736           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00737           s->assign(a);
00738           s->post();
00739           CHECK_TEST(!s->failed(), "Failed");
00740           CHECK_TEST(s->propagators()==0, "No subsumption");
00741           if (is_sol) {
00742             CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00743           } else {
00744             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00745             CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00746           }
00747           delete s;
00748         }
00749         START_TEST("Assignment reified (before posting, <=)");
00750         {
00751           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00752           s->assign(a);
00753           s->post();
00754           CHECK_TEST(!s->failed(), "Failed");
00755           CHECK_TEST(s->propagators()==0, "No subsumption");
00756           if (is_sol) {
00757             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00758             CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00759           } else {
00760             CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00761           }
00762           delete s;
00763         }
00764         START_TEST("Assignment reified (after posting, <=>)");
00765         {
00766           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00767           s->post();
00768           s->assign(a);
00769           CHECK_TEST(!s->failed(), "Failed");
00770           CHECK_TEST(s->propagators()==0, "No subsumption");
00771           CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00772           if (is_sol) {
00773             CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00774           } else {
00775             CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00776           }
00777           delete s;
00778         }
00779         START_TEST("Assignment reified (after posting, =>)");
00780         {
00781           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00782           s->post();
00783           s->assign(a);
00784           CHECK_TEST(!s->failed(), "Failed");
00785           CHECK_TEST(s->propagators()==0, "No subsumption");
00786           if (is_sol) {
00787             CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00788           } else {
00789             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00790             CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00791           }
00792           delete s;
00793         }
00794         START_TEST("Assignment reified (after posting, <=)");
00795         {
00796           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00797           s->post();
00798           s->assign(a);
00799           CHECK_TEST(!s->failed(), "Failed");
00800           CHECK_TEST(s->propagators()==0, "No subsumption");
00801           if (is_sol) {
00802             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00803             CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00804           } else {
00805             CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00806           }
00807           delete s;
00808         }
00809         START_TEST("Prune reified, <=>");
00810         {
00811           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_EQV);
00812           s->post();
00813           while (!s->failed() && 
00814                  (!s->assigned() || !s->r.var().assigned()))
00815             if (!s->prune(a)) {
00816               problem = "No fixpoint";
00817               delete s;
00818               goto failed;
00819             }
00820           CHECK_TEST(!s->failed(), "Failed");
00821           CHECK_TEST(s->propagators()==0, "No subsumption");
00822           CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00823           if (is_sol) {
00824             CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00825           } else {
00826             CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00827           }
00828           delete s;
00829         }
00830         START_TEST("Prune reified, =>");
00831         {
00832           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_IMP);
00833           s->post();
00834           while (!s->failed() && 
00835                  (!s->assigned() || (!is_sol && !s->r.var().assigned())))
00836             if (!s->prune(a)) {
00837               problem = "No fixpoint";
00838               delete s;
00839               goto failed;
00840             }
00841           CHECK_TEST(!s->failed(), "Failed");
00842           CHECK_TEST(s->propagators()==0, "No subsumption");
00843           if (is_sol) {
00844             CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00845           } else {
00846             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00847             CHECK_TEST(s->r.var().val()==0, "One on non-solution");
00848           }
00849           delete s;
00850         }
00851         START_TEST("Prune reified, <=");
00852         {
00853           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,this,RM_PMI);
00854           s->post();
00855           while (!s->failed() && 
00856                  (!s->assigned() || (is_sol && !s->r.var().assigned())))
00857             if (!s->prune(a)) {
00858               problem = "No fixpoint";
00859               delete s;
00860               goto failed;
00861             }
00862           CHECK_TEST(!s->failed(), "Failed");
00863           CHECK_TEST(s->propagators()==0, "No subsumption");
00864           if (is_sol) {
00865             CHECK_TEST(s->r.var().assigned(), "Control variable unassigned");
00866             CHECK_TEST(s->r.var().val()==1, "Zero on solution");
00867           } else {
00868             CHECK_TEST(!s->r.var().assigned(), "Control variable assigned");
00869           }
00870           delete s;
00871         }
00872       }
00873       ++a;
00874     }
00875     delete ap;
00876     return true;
00877    failed:
00878         if (opt.log)
00879           olog << "FAILURE" << std::endl
00880                << ind(1) << "Test:       " << test << std::endl
00881                << ind(1) << "Problem:    " << problem << std::endl;
00882         if (a() && opt.log)
00883           olog << ind(1) << "Assignment: " << a << std::endl;
00884      delete ap;
00885 
00886      return false;
00887   }
00888 
00889   const Gecode::SetRelType SetRelTypes::srts[] =
00890     {Gecode::SRT_EQ,Gecode::SRT_NQ,Gecode::SRT_SUB,
00891      Gecode::SRT_SUP,Gecode::SRT_DISJ,Gecode::SRT_CMPL};
00892 
00893   const Gecode::SetOpType SetOpTypes::sots[] =
00894     {Gecode::SOT_UNION, Gecode::SOT_DUNION,
00895      Gecode::SOT_INTER, Gecode::SOT_MINUS};
00896 
00897 }}
00898 
00899 #undef START_TEST
00900 #undef CHECK_TEST
00901 
00902 // STATISTICS: test-set