Generated on Mon Aug 25 11:35:44 2008 for Gecode by doxygen 1.5.6

set.cc

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: 2008-02-27 17:57:55 +0100 (Wed, 27 Feb 2008) $ by $Author: tack $
00015  *     $Revision: 6328 $
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 
00125   class SetTestSpace : public Gecode::Space {
00126   public:
00128     Gecode::IntSet d;
00130     Gecode::SetVarArray x;
00132     Gecode::IntVarArray y;
00134     int withInt;
00136     Gecode::BoolVar b;
00138     bool reified;
00140     SetTest* test;
00141 
00142   public:
00152     SetTestSpace(int n, Gecode::IntSet& d0, int i, bool r, SetTest* t,
00153                  bool log=true)
00154       : d(d0), x(this, n, Gecode::IntSet::empty, d), y(this, i, d), 
00155         withInt(i), b(this, 0, 1), reified(r), test(t) {
00156       if (opt.log && log) {
00157         olog << ind(2) << "Initial: x[]=" << x;
00158         olog << " y[]=" << y;
00159         if (reified)
00160           olog << " b=" << b;
00161         olog << std::endl;
00162       }
00163     }
00164     
00166     SetTestSpace(bool share, SetTestSpace& s)
00167     : Gecode::Space(share,s), d(s.d), withInt(s.withInt),
00168       reified(s.reified), test(s.test) {
00169       x.update(this, share, s.x);
00170       y.update(this, share, s.y);
00171       b.update(this, share, s.b);
00172     }
00173 
00175     virtual Gecode::Space* copy(bool share) {
00176       return new SetTestSpace(share,*this);
00177     }
00178 
00180     SetTestSpace* cloneWithReflection(void) {
00181       SetTestSpace* c = new SetTestSpace(x.size(), d, withInt, reified, test);
00182       Gecode::Reflection::VarMap vm;
00183       vm.putArray(this, x, "x");
00184       vm.putArray(this, y, "y");
00185       vm.put(this, b, "b");
00186       Gecode::Reflection::VarMap cvm;
00187       cvm.putArray(c, c->x, "x", true);
00188       cvm.putArray(c, c->y, "y", true);
00189       cvm.put(c, c->b, "b", true);
00190       Gecode::Reflection::Unreflector d(c, cvm);
00191       Gecode::Reflection::VarMapIter vmi(vm);
00192       try {
00193         for (Gecode::Reflection::ActorSpecIter si(this, vm); si(); ++si) {
00194           Gecode::Reflection::ActorSpec s = si.actor();
00195           for (; vmi(); ++vmi) {
00196             try {
00197               d.var(vmi.spec());
00198             } catch (Gecode::Reflection::ReflectionException e) {
00199               delete c;
00200               return NULL;
00201             }            
00202           }
00203           try {
00204             d.post(s);
00205           } catch (Gecode::Reflection::ReflectionException e) {
00206             delete c;
00207             return NULL;
00208           }
00209         }
00210         for (; vmi(); ++vmi) {
00211           try {
00212             d.var(vmi.spec());
00213           } catch (Gecode::Reflection::ReflectionException e) {
00214             delete c;
00215             return NULL;
00216           }
00217         }
00218         assert(c != NULL);
00219         if (failed())
00220           c->fail();
00221         return c;
00222       } catch (Gecode::Reflection::ReflectionException e) {
00223         delete c;
00224         if (status() == Gecode::SS_FAILED)
00225           return this;
00226         return static_cast<SetTestSpace*>(clone());
00227       }
00228     }
00229 
00231     void post(void) {
00232       if (reified){
00233         test->post(this,x,y,b);
00234         if (opt.log)
00235           olog << ind(3) << "Posting reified propagator" << std::endl;
00236       } else {
00237         test->post(this,x,y);
00238         if (opt.log)
00239           olog << ind(3) << "Posting propagator" << std::endl;
00240       }
00241     }
00243     bool failed(void) {
00244       if (opt.log) {
00245         olog << ind(3) << "Fixpoint: x[]=" << x
00246              << " y[]=" << y << std::endl;
00247         bool f=(status() == Gecode::SS_FAILED);
00248         olog << ind(3) << "     -->  x[]=" << x 
00249              << " y[]=" << y << std::endl;
00250         return f;
00251       } else {
00252         return status() == Gecode::SS_FAILED;
00253       }
00254     }
00255 
00257     void rel(int i, Gecode::SetRelType srt, const Gecode::IntSet& is) {
00258       if (opt.log) {
00259         olog << ind(4) << "x[" << i << "] ";
00260         switch (srt) {
00261         case Gecode::SRT_EQ: olog << "="; break;
00262         case Gecode::SRT_NQ: olog << "!="; break;
00263         case Gecode::SRT_SUB: olog << "<="; break;
00264         case Gecode::SRT_SUP: olog << ">="; break;
00265         case Gecode::SRT_DISJ: olog << "||"; break;
00266         case Gecode::SRT_CMPL: olog << "^-1 = "; break;
00267         }
00268         olog << is << std::endl;
00269       }
00270       Gecode::dom(this, x[i], srt, is);
00271     }
00273     void cardinality(int i, int cmin, int cmax) {
00274       if (opt.log) {
00275         olog << ind(4) << cmin << " <= #(x[" << i << "]) <= " << cmax
00276              << std::endl;
00277       }
00278       Gecode::cardinality(this, x[i], cmin, cmax);
00279     }
00281     void rel(int i, Gecode::IntRelType irt, int n) {
00282       if (opt.log) {
00283         olog << ind(4) << "y[" << i << "] ";
00284         switch (irt) {
00285         case Gecode::IRT_EQ: olog << "="; break;
00286         case Gecode::IRT_NQ: olog << "!="; break;
00287         case Gecode::IRT_LQ: olog << "<="; break;
00288         case Gecode::IRT_LE: olog << "<"; break;
00289         case Gecode::IRT_GQ: olog << ">="; break;
00290         case Gecode::IRT_GR: olog << ">"; break;
00291         }
00292         olog << " " << n << std::endl;
00293       }
00294       Gecode::rel(this, y[i], irt, n);
00295     }
00297     void rel(bool sol) {
00298       int n = sol ? 1 : 0;
00299       assert(reified);
00300       if (opt.log) 
00301         olog << ind(4) << "b = " << n << std::endl;
00302       Gecode::rel(this, b, Gecode::IRT_EQ, n);
00303     }
00304 
00306     void assign(const SetAssignment& a) {
00307       for (int i=a.size(); i--; ) {
00308         CountableSetRanges csv(a.lub, a[i]);
00309         Gecode::IntSet ai(csv);
00310         rel(i, Gecode::SRT_EQ, ai);
00311         if (Base::fixpoint() && failed())
00312           return;
00313       }
00314       for (int i=withInt; i--; ) {
00315         rel(i, Gecode::IRT_EQ, a.ints()[i]);
00316         if (Base::fixpoint() && failed())
00317           return;
00318       }
00319     }
00320 
00322     bool assigned(void) const {
00323       for (int i=x.size(); i--; )
00324         if (!x[i].assigned())
00325           return false;
00326       for (int i=y.size(); i--; )
00327         if (!y[i].assigned())
00328           return false;
00329       return true;
00330     }
00332     void removeFromLub(int v, int i, const SetAssignment& a) {
00333       using namespace Gecode;
00334       SetVarUnknownRanges ur(x[i]);
00335       CountableSetRanges air(a.lub, a[i]);
00336       Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges, 
00337         CountableSetRanges> diff(ur, air);
00338       Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Diff
00339         <Gecode::SetVarUnknownRanges, CountableSetRanges> > diffV(diff);
00340       for (int j=0; j<v; j++, ++diffV);
00341       rel(i, Gecode::SRT_DISJ, Gecode::IntSet(diffV.val(), diffV.val()));
00342     }
00344     void addToGlb(int v, int i, const SetAssignment& a) {
00345       using namespace Gecode;
00346       SetVarUnknownRanges ur(x[i]);
00347       CountableSetRanges air(a.lub, a[i]);
00348       Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges, 
00349         CountableSetRanges> inter(ur, air);
00350       Gecode::Iter::Ranges::ToValues<Gecode::Iter::Ranges::Inter
00351         <Gecode::SetVarUnknownRanges, CountableSetRanges> > interV(inter);
00352       for (int j=0; j<v; j++, ++interV);
00353       rel(i, Gecode::SRT_SUP, Gecode::IntSet(interV.val(), interV.val()));
00354     }
00356     bool fixprob(void) {
00357       if (failed())
00358         return true;
00359       SetTestSpace* c = static_cast<SetTestSpace*>(clone());
00360       if (opt.log)
00361         olog << ind(3) << "Testing fixpoint on copy" << std::endl;
00362       c->post();
00363       if (c->failed()) {
00364         delete c; return false;
00365       }
00366 
00367       for (int i=x.size(); i--; )
00368         if (x[i].glbSize() != c->x[i].glbSize() ||
00369             x[i].lubSize() != c->x[i].lubSize() ||
00370             x[i].cardMin() != c->x[i].cardMin() ||
00371             x[i].cardMax() != c->x[i].cardMax()) {
00372           delete c;
00373           return false;
00374         }
00375       for (int i=y.size(); i--; )
00376         if (y[i].size() != c->y[i].size()) {
00377           delete c; return false;
00378         }
00379       if (reified && (b.size() != c->b.size())) {
00380         delete c; return false;
00381       }
00382       if (opt.log)
00383         olog << ind(3) << "Finished testing fixpoint on copy" << std::endl;
00384       delete c;
00385       return true;
00386     }
00388     bool prune(const SetAssignment& a) {
00389       using namespace Gecode;
00390       bool setsAssigned = true;
00391       for (int j=x.size(); j--; )
00392         if (!x[j].assigned()) {
00393           setsAssigned = false;
00394           break;
00395         }
00396       bool intsAssigned = true;
00397       for (int j=y.size(); j--; )
00398         if (!y[j].assigned()) {
00399           intsAssigned = false;
00400           break;
00401         }
00402 
00403       // Select variable to be pruned
00404       int i;
00405       if (intsAssigned) {
00406         i = Base::rand(x.size());
00407       } else if (setsAssigned) {
00408         i = Base::rand(y.size());
00409       } else {
00410         i = Base::rand(x.size()+y.size());
00411       }
00412 
00413       if (setsAssigned || i>=x.size()) {
00414         if (i>=x.size())
00415           i = i-x.size();
00416         while (y[i].assigned()) {
00417           i = (i+1) % y.size();
00418         }
00419         // Prune int var
00420 
00421         // Select mode for pruning
00422         switch (Base::rand(3)) {
00423         case 0:
00424           if (a.ints()[i] < y[i].max()) {
00425             int v=a.ints()[i]+1+
00426               Base::rand(static_cast<unsigned int>(y[i].max()-a.ints()[i]));
00427             assert((v > a.ints()[i]) && (v <= y[i].max()));
00428             rel(i, Gecode::IRT_LE, v);
00429           }
00430           break;
00431         case 1:
00432           if (a.ints()[i] > y[i].min()) {
00433             int v=y[i].min()+
00434               Base::rand(static_cast<unsigned int>(a.ints()[i]-y[i].min()));
00435             assert((v < a.ints()[i]) && (v >= y[i].min()));
00436             rel(i, Gecode::IRT_GR, v);
00437           }
00438           break;
00439         default:
00440           int v;
00441           Gecode::Int::ViewRanges<Gecode::Int::IntView> it(y[i]);
00442           unsigned int skip = Base::rand(y[i].size()-1);
00443           while (true) {
00444             if (it.width() > skip) {
00445               v = it.min() + skip;
00446               if (v == a.ints()[i]) {
00447                 if (it.width() == 1) {
00448                   ++it; v = it.min();
00449                 } else if (v < it.max()) {
00450                   ++v;
00451                 } else {
00452                   --v;
00453                 }
00454               }
00455               break;
00456             }
00457             skip -= it.width();
00458             ++it;
00459           }
00460           rel(i, Gecode::IRT_NQ, v);
00461         }
00462         return (!Base::fixpoint() || fixprob());
00463       }
00464       while (x[i].assigned()) {
00465         i = (i+1) % x.size();
00466       }
00467       Gecode::SetVarUnknownRanges ur1(x[i]);
00468       CountableSetRanges air1(a.lub, a[i]);
00469       Gecode::Iter::Ranges::Diff<Gecode::SetVarUnknownRanges, 
00470         CountableSetRanges> diff(ur1, air1);
00471       Gecode::SetVarUnknownRanges ur2(x[i]);
00472       CountableSetRanges air2(a.lub, a[i]);
00473       Gecode::Iter::Ranges::Inter<Gecode::SetVarUnknownRanges, 
00474         CountableSetRanges> inter(ur2, air2);
00475 
00476       CountableSetRanges aisizer(a.lub, a[i]);
00477       unsigned int aisize = Gecode::Iter::Ranges::size(aisizer);
00478 
00479       // Select mode for pruning
00480       switch (Base::rand(5)) {
00481       case 0:
00482         if (inter()) {
00483           int v = Base::rand(Gecode::Iter::Ranges::size(inter));
00484           addToGlb(v, i, a);
00485         }
00486         break;
00487       case 1:
00488         if (diff()) {
00489           int v = Base::rand(Gecode::Iter::Ranges::size(diff));
00490           removeFromLub(v, i, a);
00491         }
00492         break;
00493       case 2:
00494         if (x[i].cardMin() < aisize) {
00495           unsigned int newc = x[i].cardMin() + 1 +
00496             Base::rand(aisize - x[i].cardMin());
00497           assert( newc > x[i].cardMin() );
00498           assert( newc <= aisize );
00499           cardinality(i, newc, Gecode::Set::Limits::card);
00500         }
00501         break;
00502       case 3:
00503         if (x[i].cardMax() > aisize) {
00504           unsigned int newc = x[i].cardMax() - 1 -
00505             Base::rand(x[i].cardMax() - aisize);
00506           assert( newc < x[i].cardMax() );
00507           assert( newc >= aisize );
00508           cardinality(i, 0, newc);
00509         }
00510         break;
00511       default:
00512         if (inter()) {
00513           int v = Base::rand(Gecode::Iter::Ranges::size(inter));
00514           addToGlb(v, i, a);
00515         } else {
00516           int v = Base::rand(Gecode::Iter::Ranges::size(diff));
00517           removeFromLub(v, i, a);
00518         }      
00519       }
00520       return (!Base::fixpoint() || fixprob());
00521     }
00522 
00523   };
00524 
00525 
00527 #define CHECK_TEST(T,M)                                         \
00528 if (opt.log)                                                    \
00529   olog << ind(3) << "Check: " << (M) << std::endl;              \
00530 if (!(T)) {                                                     \
00531   problem = (M); delete s; goto failed;                         \
00532 }
00533 
00535 #define START_TEST(T)                                           \
00536   if (opt.log) {                                                \
00537      olog.str("");                                              \
00538      olog << ind(2) << "Testing: " << (T) << std::endl;         \
00539   }                                                             \
00540   test = (T);
00541 
00542   bool
00543   SetTest::run(void) {
00544     const char* test    = "NONE";
00545     const char* problem = "NONE";
00546 
00547     SetAssignment* ap = new SetAssignment(arity,lub,withInt);
00548     SetAssignment& a = *ap;
00549     while (a()) {
00550       bool is_sol = solution(a);
00551       if (opt.log)
00552         olog << ind(1) << "Assignment: " << a 
00553              << (is_sol ? " (solution)" : " (no solution)")
00554              << std::endl;
00555 
00556       START_TEST("Assignment (after posting)");
00557       {
00558         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,false,this);
00559         SetTestSpace* sc = NULL;
00560         s->post();
00561         switch (Base::rand(3)) {
00562           case 0:
00563             if (opt.log)
00564               olog << ind(3) << "No copy" << std::endl;
00565             sc = s;
00566             s = NULL;
00567             break;
00568           case 1:
00569             if (opt.log)
00570               olog << ind(3) << "Unshared copy" << std::endl;
00571             if (s->status() != Gecode::SS_FAILED) {
00572               sc = static_cast<SetTestSpace*>(s->clone(true));
00573             } else {
00574               sc = s; s = NULL;
00575             }
00576             break;
00577           case 2:
00578             if (opt.log)
00579               olog << ind(3) << "Unshared copy" << std::endl;
00580             if (s->status() != Gecode::SS_FAILED) {
00581               sc = static_cast<SetTestSpace*>(s->clone(false));
00582             } else {
00583               sc = s; s = NULL;
00584             }
00585             break;
00586           default: assert(false);          
00587         }
00588         sc->assign(a);
00589         if (is_sol) {
00590           CHECK_TEST(!sc->failed(), "Failed on solution");
00591           CHECK_TEST(sc->propagators()==0, "No subsumption");
00592         } else {
00593           CHECK_TEST(sc->failed(), "Solved on non-solution");
00594         }
00595         delete s; delete sc;
00596       }
00597       if (opt.reflection) {
00598         START_TEST("Assignment (after posting + reflection)");
00599         {
00600           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,false,this);
00601           SetTestSpace* sc = NULL;
00602           s->post();
00603           if (opt.log)
00604             olog << ind(3) << "Reflection copy" << std::endl;
00605           sc = s->cloneWithReflection();
00606           if (sc == s)
00607             s = NULL;
00608           CHECK_TEST(sc != NULL, "Reflection error");
00609           sc->assign(a);
00610           if (is_sol) {
00611             CHECK_TEST(!sc->failed(), "Failed on solution");
00612             CHECK_TEST(sc->propagators()==0, "No subsumption");
00613           } else {
00614             CHECK_TEST(sc->failed(), "Solved on non-solution");
00615           }
00616           delete s; delete sc;
00617         }
00618       }
00619       START_TEST("Assignment (before posting)");
00620       {
00621         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,false,this);
00622         s->assign(a);
00623         s->post();
00624         if (is_sol) {
00625           CHECK_TEST(!s->failed(), "Failed on solution");
00626           CHECK_TEST(s->propagators()==0, "No subsumption");
00627         } else {
00628           CHECK_TEST(s->failed(), "Solved on non-solution");
00629         }
00630         delete s;
00631       }
00632       if (reified) {
00633         START_TEST("Assignment reified (before posting)");
00634         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,true,this);
00635         s->assign(a);
00636         s->post();
00637         CHECK_TEST(!s->failed(), "Failed");
00638         CHECK_TEST(s->propagators()==0, "No subsumption");
00639         CHECK_TEST(s->b.assigned(), "Control variable unassigned");
00640         if (is_sol) {
00641           CHECK_TEST(s->b.val()==1, "Zero on solution");
00642         } else {
00643           CHECK_TEST(s->b.val()==0, "One on non-solution");
00644         }
00645         delete s;
00646       }
00647       if (reified) {
00648         START_TEST("Assignment reified (after posting)");
00649         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,true,this);
00650         s->post();
00651         s->assign(a);
00652         CHECK_TEST(!s->failed(), "Failed");
00653         CHECK_TEST(s->propagators()==0, "No subsumption");
00654         CHECK_TEST(s->b.assigned(), "Control variable unassigned");
00655         if (is_sol) {
00656           CHECK_TEST(s->b.val()==1, "Zero on solution");
00657         } else {
00658           CHECK_TEST(s->b.val()==0, "One on non-solution");
00659         }
00660         delete s;
00661       }
00662       if (opt.reflection && reified) {
00663         START_TEST("Assignment reified (after posting + reflection)");
00664         {
00665           SetTestSpace* s = new SetTestSpace(arity,lub,withInt,true,this);
00666           SetTestSpace* sc = NULL;
00667           s->post();
00668           if (opt.log)
00669             olog << ind(3) << "Reflection copy" << std::endl;
00670           sc = s->cloneWithReflection();
00671           if (sc == s)
00672             s = NULL;
00673           CHECK_TEST(sc != NULL, "Reflection error");
00674           sc->assign(a);
00675           CHECK_TEST(!sc->failed(), "Failed");
00676           CHECK_TEST(sc->propagators()==0, "No subsumption");
00677           if (is_sol) {
00678             CHECK_TEST(sc->b.val()==1, "Zero on solution");
00679           } else {
00680             CHECK_TEST(sc->b.val()==0, "One on non-solution");
00681           }
00682           delete s; delete sc;
00683         }
00684       }
00685       START_TEST("Prune");
00686       {
00687         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,false,this);
00688         s->post();
00689         while (!s->failed() && !s->assigned())
00690            if (!s->prune(a)) {
00691              problem = "No fixpoint";
00692              delete s;
00693              goto failed;
00694            }
00695         s->assign(a);
00696         if (is_sol) {
00697           CHECK_TEST(!s->failed(), "Failed on solution");
00698           CHECK_TEST(s->propagators()==0, "No subsumption");
00699         } else {
00700           CHECK_TEST(s->failed(), "Solved on non-solution");
00701         }
00702         delete s;
00703       }
00704       if (reified) {
00705         START_TEST("Prune reified");
00706         SetTestSpace* s = new SetTestSpace(arity,lub,withInt,true,this);
00707         s->post();
00708         while (!s->assigned() && !s->b.assigned())
00709            if (!s->prune(a)) {
00710              problem = "No fixpoint";
00711              delete s;
00712              goto failed;
00713            }
00714         CHECK_TEST(!s->failed(), "Failed");
00715         CHECK_TEST(s->propagators()==0, "No subsumption");
00716         CHECK_TEST(s->b.assigned(), "Control variable unassigned");
00717         if (is_sol) {
00718           CHECK_TEST(s->b.val()==1, "Zero on solution");
00719         } else {
00720           CHECK_TEST(s->b.val()==0, "One on non-solution");
00721         }
00722         delete s;
00723       }
00724       ++a;
00725     }
00726     delete ap;
00727     return true;
00728    failed:
00729         if (opt.log)
00730           olog << "FAILURE" << std::endl
00731                << ind(1) << "Test:       " << test << std::endl
00732                << ind(1) << "Problem:    " << problem << std::endl;
00733         if (a() && opt.log)
00734           olog << ind(1) << "Assignment: " << a << std::endl;
00735      delete ap;
00736 
00737      return false;
00738   }
00739 
00740   const Gecode::SetRelType SetRelTypes::srts[] = 
00741     {Gecode::SRT_EQ,Gecode::SRT_NQ,Gecode::SRT_SUB,
00742      Gecode::SRT_SUP,Gecode::SRT_DISJ,Gecode::SRT_CMPL};
00743 
00744   const Gecode::SetOpType SetOpTypes::sots[] = 
00745     {Gecode::SOT_UNION, Gecode::SOT_DUNION,
00746      Gecode::SOT_INTER, Gecode::SOT_MINUS};
00747 
00748 }}
00749 
00750 #undef START_TEST
00751 #undef CHECK_TEST
00752 
00753 // STATISTICS: test-set