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

set-expr.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  *
00006  *  Copyright:
00007  *     Guido Tack, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-02-27 18:06:13 +0100 (Wed, 27 Feb 2008) $ by $Author: tack $
00011  *     $Revision: 6332 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00035  *
00036  */
00037 
00038 #include "gecode/set/projectors.hh"
00039 
00040 using namespace Gecode::Set;
00041 
00042 namespace Gecode {
00043 
00047   class SetExpr::Node {
00048   private:
00050     unsigned int use;
00052     Node *left, *right;
00054     int signLeft, signRight;
00056     var_idx x;
00058     RelType rel;
00059   public:
00061     Node(const var_idx x);
00063     Node(Node* n0, int s0, RelType r, Node* n1, int s1);
00064     
00066     void increment(void);
00068     GECODE_SET_EXPORT bool decrement(void);
00069     
00071     void encode(SetExprCode::Stream& ret, bool monotone) const;
00073     int arity(void) const;
00074 
00076     Iter::Ranges::Virt::Iterator* iter(void);
00077     
00079     static void* operator new(size_t size);
00081     static void  operator delete(void* p,size_t size);
00082   };
00083 
00084   /*
00085    * Operations for nodes
00086    *
00087    */
00088 
00089   forceinline void*
00090   SetExpr::Node::operator new(size_t size) {
00091     return Memory::malloc(size);
00092   }
00093 
00094   forceinline void
00095   SetExpr::Node::operator delete(void* p, size_t) {
00096     Memory::free(p);
00097   }
00098 
00099 
00100   forceinline void
00101   SetExpr::Node::increment(void) { 
00102     ++use; 
00103   }
00104 
00105   forceinline
00106   SetExpr::Node::Node(const var_idx x) :
00107     use(1),
00108     left(NULL), right(NULL), signLeft(0), signRight(0), x(x) {}
00109 
00110   forceinline
00111   SetExpr::Node::Node(Node* l, int sL, RelType _rel, Node* r, int sR) :
00112     use(1),
00113     left(l), right(r), signLeft(sL), signRight(sR), rel(_rel) {
00114     if (left != NULL)
00115       left->increment();
00116     if (right != NULL)
00117       right->increment();
00118   }
00119 
00120   bool
00121   SetExpr::Node::decrement(void) {
00122     if (--use == 0) {
00123       if (left != NULL && left->decrement())
00124         delete left;
00125       if (right != NULL && right->decrement())
00126         delete right;
00127       return true;
00128     }
00129     return false;
00130   }
00131 
00132   int
00133   SetExpr::Node::arity(void) const {
00134     if (left==NULL && right==NULL)
00135       return x;
00136     return std::max( left==NULL ? 0 : left->arity(),
00137                      right==NULL ? 0 : right->arity() );
00138   }
00139 
00140   void
00141   SetExpr::Node::encode(SetExprCode::Stream& ret, bool monotone) const {
00142     if (left==NULL && right==NULL) {
00143       assert(x>=0);
00144       ret.add(SetExprCode::LAST+x);
00145       if (monotone)
00146         ret.add(SetExprCode::LUB);
00147       else
00148         ret.add(SetExprCode::GLB);
00149       return;
00150     }
00151     if (left==NULL) {
00152       ret.add(SetExprCode::UNIVERSE);
00153     } else {
00154       left->encode(ret, (signLeft==1) ? monotone : !monotone);
00155     }
00156     if (signLeft==-1)
00157       ret.add(SetExprCode::COMPLEMENT);
00158     if (right==NULL) {
00159       ret.add(SetExprCode::UNIVERSE);
00160     } else {
00161       right->encode(ret, (signRight==1) ? monotone : !monotone);
00162     }
00163     if (signRight==-1)
00164       ret.add(SetExprCode::COMPLEMENT);
00165     switch (rel) {
00166     case REL_INTER: ret.add(SetExprCode::INTER); break;
00167     case REL_UNION: ret.add(SetExprCode::UNION); break;
00168     default:
00169         GECODE_NEVER;
00170     }
00171   }
00172 
00173 
00174   /*
00175    * Operations for expressions
00176    *
00177    */
00178   
00179   SetExpr::SetExpr(var_idx v) : ax(new Node(v)), sign(1) {}
00180 
00181   SetExpr::SetExpr(const SetExpr& s, int ssign,
00182                    RelType r,
00183                    const SetExpr& t, int tsign)
00184     : ax(new Node(s.ax,s.sign*ssign,r,t.ax,t.sign*tsign)), sign(1) {}
00185 
00186   SetExpr::SetExpr(const SetExpr& s, int sign)
00187     : ax(s.ax), sign(s.sign*sign) {
00188     if (ax != NULL)
00189       ax->increment();
00190   }
00191 
00192   SetExpr::SetExpr(const SetExpr& s)
00193     : ax(s.ax), sign(s.sign) {
00194     if (ax != NULL)
00195       ax->increment();
00196   }
00197 
00198   const SetExpr&
00199   SetExpr::operator=(const SetExpr& s) {
00200     if (this != &s) {
00201       if ((ax != NULL) && ax->decrement())
00202         delete ax;
00203       ax = s.ax;
00204       sign = s.sign;
00205       if (ax != NULL)
00206         ax->increment();
00207     }
00208     return *this;
00209   }
00210 
00211   SetExpr::~SetExpr(void) {
00212     if ((ax != NULL) && ax->decrement())
00213       delete ax;
00214   }
00215 
00216   int
00217   SetExpr::arity(void) const {
00218     return (ax==NULL) ? 0 : ax->arity();
00219   }
00220 
00221   SetExprCode
00222   SetExpr::encode(void) const {
00223     SetExprCode::Stream s;
00224     if (ax==NULL) {
00225       s.add((sign==1) ? SetExprCode::EMPTY : SetExprCode::UNIVERSE);
00226     } else if (sign==-1) {
00227       ax->encode(s, false);
00228       s.add(SetExprCode::COMPLEMENT);
00229     } else {
00230       ax->encode(s, true);
00231     }
00232     SetExprCode ret(s);
00233     return ret;
00234   }
00235 
00236   Iter::Ranges::Virt::Iterator*
00237   codeToIterator(const ViewArray<Set::SetView>& x,
00238                  const SetExprCode& c, bool monotone) {
00239 
00240     typedef Iter::Ranges::Virt::Iterator Iterator;
00241 
00242     Support::DynamicStack<Iterator*> s;
00243 
00244     int tmp = 0;
00245     for (int i=0; i<c.size(); i++) {
00246       switch (c[i]) {
00247       case SetExprCode::COMPLEMENT:
00248         {
00249           Iterator* it = s.pop();
00250           s.push(new Iter::Ranges::Virt::Compl<Limits::min,
00251                                                Limits::max> (it));
00252         }
00253         break;
00254       case SetExprCode::INTER:
00255         {
00256           Iterator* ri = s.pop();
00257           Iterator* li = s.pop();
00258           s.push(new Iter::Ranges::Virt::Inter(li, ri));
00259         }
00260               break;
00261       case SetExprCode::UNION:
00262         {
00263           Iterator* ri = s.pop();
00264           Iterator* li = s.pop();
00265           s.push(new Iter::Ranges::Virt::Union(li, ri));
00266         }
00267         break;
00268       case SetExprCode::GLB:
00269         if (monotone) {
00270           GlbRanges<SetView> r(x[tmp]);
00271           s.push(new Iter::Ranges::Virt::RangesTemplate<GlbRanges<SetView> >(r));
00272         } else {
00273           LubRanges<SetView> r(x[tmp]);
00274           s.push(new Iter::Ranges::Virt::RangesTemplate<LubRanges<SetView> >(r));                
00275         }
00276         break;
00277       case SetExprCode::LUB:
00278         if (monotone) {
00279           LubRanges<SetView> r(x[tmp]);
00280           s.push(new Iter::Ranges::Virt::RangesTemplate<LubRanges<SetView> >(r));
00281         } else {
00282           GlbRanges<SetView> r(x[tmp]);
00283           s.push(new Iter::Ranges::Virt::RangesTemplate<GlbRanges<SetView> >(r));                
00284         }
00285         break;
00286       case SetExprCode::EMPTY:
00287         {
00288           Iter::Ranges::Singleton it(1,0);
00289           s.push(new Iter::Ranges::Virt::RangesTemplate<Iter::Ranges::Singleton> (it));
00290         }
00291         break;
00292       case SetExprCode::UNIVERSE:
00293         {
00294           Iter::Ranges::Singleton it(Limits::min,
00295                                      Limits::max);
00296           s.push(new Iter::Ranges::Virt::RangesTemplate<Iter::Ranges::Singleton> (it));
00297         }
00298         break;
00299       default:
00300         tmp = c[i]-SetExprCode::LAST;
00301         break;
00302       }
00303     }
00304 
00305     return s.top();
00306   }
00307 
00308   SetExprRanges::SetExprRanges(const ViewArray<Set::SetView>& x,
00309                                SetExpr& s,
00310                                bool monotone) {
00311     i = new Iter(codeToIterator(x, s.encode(), monotone));
00312   }
00313 
00314   SetExprRanges::SetExprRanges(const ViewArray<Set::SetView>& x,
00315                                const SetExprCode& c,
00316                                bool monotone) {
00317     i = new Iter(codeToIterator(x, c, monotone));
00318   }
00319 
00320 }
00321 
00322 std::ostream&
00323 operator<<(std::ostream& os, const Gecode::SetExprCode& sec) {
00324   for (int i=0; i<sec.size(); i++) {
00325     switch (sec[i]) {
00326     case Gecode::SetExprCode::COMPLEMENT: os << " CMPL "; break;
00327     case Gecode::SetExprCode::INTER: os << " INTER "; break;
00328     case Gecode::SetExprCode::UNION: os << " UNION "; break;
00329     case Gecode::SetExprCode::GLB: os << " GLB "; break;
00330     case Gecode::SetExprCode::LUB: os << " LUB "; break;
00331     case Gecode::SetExprCode::EMPTY: os << " EMPTY "; break;
00332     case Gecode::SetExprCode::UNIVERSE: os << " UNIVERSE "; break;
00333     default: os << " x[" << sec[i]-Gecode::SetExprCode::LAST << "] "; break;
00334     }
00335   }
00336   return os;
00337 }
00338 
00339 // STATISTICS: set-prop