Generated on Wed Nov 1 15:04:45 2006 for Gecode by doxygen 1.4.5

set-expr.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Guido Tack <tack@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Guido Tack, 2006
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-17 16:58:48 +0200 (Thu, 17 Aug 2006) $ by $Author: tack $
00010  *     $Revision: 3548 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 #include "gecode/set/projectors.hh"
00023 #include "gecode/support/dynamic-stack.hh"
00024 
00025 using namespace Gecode::Set;
00026 
00027 namespace Gecode {
00028 
00032   class SetExpr::Node {
00033   private:
00035     unsigned int use;
00037     Node *left, *right;
00039     int signLeft, signRight;
00041     var_idx x;
00043     RelType rel;
00044   public:
00046     Node(const var_idx x);
00048     Node(Node* n0, int s0, RelType r, Node* n1, int s1);
00049     
00051     void increment(void);
00053     GECODE_SET_EXPORT bool decrement(void);
00054     
00056     void encode(SetExprCode& ret, bool monotone) const;
00058     int arity(void) const;
00059 
00061     Iter::Ranges::Virt::Iterator* iter(void);
00062     
00064     static void* operator new(size_t size);
00066     static void  operator delete(void* p,size_t size);
00067   };
00068 
00069   /*
00070    * Operations for nodes
00071    *
00072    */
00073 
00074   forceinline void*
00075   SetExpr::Node::operator new(size_t size) {
00076     return Memory::malloc(size);
00077   }
00078 
00079   forceinline void
00080   SetExpr::Node::operator delete(void* p, size_t) {
00081     Memory::free(p);
00082   }
00083 
00084 
00085   forceinline void
00086   SetExpr::Node::increment(void) { 
00087     ++use; 
00088   }
00089 
00090   forceinline
00091   SetExpr::Node::Node(const var_idx x) :
00092     use(1),
00093     left(NULL), right(NULL), signLeft(0), signRight(0), x(x) {}
00094 
00095   forceinline
00096   SetExpr::Node::Node(Node* l, int sL, RelType _rel, Node* r, int sR) :
00097     use(1),
00098     left(l), right(r), signLeft(sL), signRight(sR), rel(_rel) {
00099     if (left != NULL)
00100       left->increment();
00101     if (right != NULL)
00102       right->increment();
00103   }
00104 
00105   bool
00106   SetExpr::Node::decrement(void) {
00107     if (--use == 0) {
00108       if (left != NULL && left->decrement())
00109         delete left;
00110       if (right != NULL && right->decrement())
00111         delete right;
00112       return true;
00113     }
00114     return false;
00115   }
00116 
00117   int
00118   SetExpr::Node::arity(void) const {
00119     if (left==NULL && right==NULL)
00120       return x;
00121     return std::max( left==NULL ? 0 : left->arity(),
00122                      right==NULL ? 0 : right->arity() );
00123   }
00124 
00125   void
00126   SetExpr::Node::encode(SetExprCode& ret, bool monotone) const {
00127     if (left==NULL && right==NULL) {
00128       assert(x>=0);
00129       ret.add(SetExprCode::LAST+x);
00130       if (monotone)
00131         ret.add(SetExprCode::LUB);
00132       else
00133         ret.add(SetExprCode::GLB);
00134       return;
00135     }
00136     if (left==NULL) {
00137       ret.add(SetExprCode::UNIVERSE);
00138     } else {
00139       left->encode(ret, (signLeft==1) ? monotone : !monotone);
00140     }
00141     if (signLeft==-1)
00142       ret.add(SetExprCode::COMPLEMENT);
00143     if (right==NULL) {
00144       ret.add(SetExprCode::UNIVERSE);
00145     } else {
00146       right->encode(ret, (signRight==1) ? monotone : !monotone);
00147     }
00148     if (signRight==-1)
00149       ret.add(SetExprCode::COMPLEMENT);
00150     switch (rel) {
00151     case REL_INTER: ret.add(SetExprCode::INTER); break;
00152     case REL_UNION: ret.add(SetExprCode::UNION); break;
00153     default:
00154         GECODE_NEVER;
00155     }
00156   }
00157 
00158 
00159   /*
00160    * Operations for expressions
00161    *
00162    */
00163   
00164   SetExpr::SetExpr(var_idx v) : ax(new Node(v)), sign(1) {}
00165 
00166   SetExpr::SetExpr(const SetExpr& s, int ssign,
00167                    RelType r,
00168                    const SetExpr& t, int tsign)
00169     : ax(new Node(s.ax,s.sign*ssign,r,t.ax,t.sign*tsign)), sign(1) {}
00170 
00171   SetExpr::SetExpr(const SetExpr& s, int sign)
00172     : ax(s.ax), sign(s.sign*sign) {
00173     if (ax != NULL)
00174       ax->increment();
00175   }
00176 
00177   SetExpr::SetExpr(const SetExpr& s)
00178     : ax(s.ax), sign(s.sign) {
00179     if (ax != NULL)
00180       ax->increment();
00181   }
00182 
00183   const SetExpr&
00184   SetExpr::operator=(const SetExpr& s) {
00185     if (this != &s) {
00186       if ((ax != NULL) && ax->decrement())
00187         delete ax;
00188       ax = s.ax;
00189       sign = s.sign;
00190       if (ax != NULL)
00191         ax->increment();
00192     }
00193     return *this;
00194   }
00195 
00196   SetExpr::~SetExpr(void) {
00197     if ((ax != NULL) && ax->decrement())
00198       delete ax;
00199   }
00200 
00201   int
00202   SetExpr::arity(void) const {
00203     return (ax==NULL) ? 0 : ax->arity();
00204   }
00205 
00206   SetExprCode
00207   SetExpr::encode(void) const {
00208     SetExprCode ret;
00209     if (ax==NULL) {
00210       ret.add((sign==1) ? SetExprCode::EMPTY : SetExprCode::UNIVERSE);
00211     } else if (sign==-1) {
00212       ax->encode(ret, false);
00213       ret.add(SetExprCode::COMPLEMENT);
00214     } else {
00215       ax->encode(ret, true);
00216     }
00217     return ret;
00218   }
00219 
00220   Iter::Ranges::Virt::Iterator*
00221   codeToIterator(const ViewArray<Set::SetView>& x,
00222                  const SetExprCode& c, bool monotone) {
00223 
00224     typedef Iter::Ranges::Virt::Iterator Iterator;
00225 
00226     Support::DynamicStack<Iterator*> s;
00227 
00228     int tmp = 0;
00229     for (int i=0; i<c.size(); i++) {
00230       switch (c[i]) {
00231       case SetExprCode::COMPLEMENT:
00232         {
00233           Iterator* it = s.pop();
00234           s.push(new Iter::Ranges::Virt::Compl<Limits::Set::int_min,
00235                                                Limits::Set::int_max> (it));
00236         }
00237         break;
00238       case SetExprCode::INTER:
00239         {
00240           Iterator* ri = s.pop();
00241           Iterator* li = s.pop();
00242           s.push(new Iter::Ranges::Virt::Inter(li, ri));
00243         }
00244         break;
00245       case SetExprCode::UNION:
00246         {
00247           Iterator* ri = s.pop();
00248           Iterator* li = s.pop();
00249           s.push(new Iter::Ranges::Virt::Union(li, ri));
00250         }
00251         break;
00252       case SetExprCode::GLB:
00253         if (monotone) {
00254           GlbRanges<SetView> r(x[tmp]);
00255           s.push(new Iter::Ranges::Virt::RangesTemplate<GlbRanges<SetView> >(r));
00256         } else {
00257           LubRanges<SetView> r(x[tmp]);
00258           s.push(new Iter::Ranges::Virt::RangesTemplate<LubRanges<SetView> >(r));               
00259         }
00260         break;
00261       case SetExprCode::LUB:
00262         if (monotone) {
00263           LubRanges<SetView> r(x[tmp]);
00264           s.push(new Iter::Ranges::Virt::RangesTemplate<LubRanges<SetView> >(r));
00265         } else {
00266           GlbRanges<SetView> r(x[tmp]);
00267           s.push(new Iter::Ranges::Virt::RangesTemplate<GlbRanges<SetView> >(r));               
00268         }
00269         break;
00270       case SetExprCode::EMPTY:
00271         {
00272           Iter::Ranges::Singleton it(1,0);
00273           s.push(new Iter::Ranges::Virt::RangesTemplate<Iter::Ranges::Singleton> (it));
00274         }
00275         break;
00276       case SetExprCode::UNIVERSE:
00277         {
00278           Iter::Ranges::Singleton it(Limits::Set::int_min,
00279                                      Limits::Set::int_max);
00280           s.push(new Iter::Ranges::Virt::RangesTemplate<Iter::Ranges::Singleton> (it));
00281         }
00282         break;
00283       default:
00284         tmp = c[i]-SetExprCode::LAST;
00285         break;
00286       }
00287     }
00288 
00289     return s.top();
00290   }
00291 
00292   SetExprRanges::SetExprRanges(const ViewArray<Set::SetView>& x,
00293                                SetExpr& s,
00294                                bool monotone) {
00295     i = new Iter(codeToIterator(x, s.encode(), monotone));
00296   }
00297 
00298   SetExprRanges::SetExprRanges(const ViewArray<Set::SetView>& x,
00299                                const SetExprCode& c,
00300                                bool monotone) {
00301     i = new Iter(codeToIterator(x, c, monotone));
00302   }
00303 
00304 }
00305 
00306 // STATISTICS: set-prop