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

view.icc

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  *
00006  *  Contributing authors:
00007  *     Guido Tack <tack@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Christian Schulte, 2004
00011  *     Guido Tack, 2004
00012  *
00013  *  Last modified:
00014  *     $Date: 2008-07-11 09:31:51 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00015  *     $Revision: 7288 $
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 <algorithm>
00043 
00044 namespace Gecode { namespace Int { namespace Element {
00045 
00047   template<class View>
00048   class ViewToVarArg {};
00049 
00051   template<>
00052   class ViewToVarArg<IntView> {
00053   public:
00054     typedef IntVarArgs argtype;
00055   };
00057   template<>
00058   class ViewToVarArg<BoolView> {
00059   public:
00060     typedef BoolVarArgs argtype;
00061   };
00062 
00067   template <class View>
00068   class IdxView {
00069   public:
00070     int idx; View view;
00071 
00072     static IdxView* allocate(Space*, int);
00073     static IdxView* init(Space*, const typename ViewToVarArg<View>::argtype&);
00074   };
00075 
00076 
00077   template <class View>
00078   forceinline IdxView<View>*
00079   IdxView<View>::allocate(Space* home, int n) {
00080       return static_cast<IdxView<View>*>
00081         (home->alloc(sizeof(IdxView<View>)*n));
00082     }
00083 
00084   template <class View>
00085   forceinline IdxView<View>*
00086   IdxView<View>::init(Space* home, const typename ViewToVarArg<View>::argtype& x) {
00087     IdxView<View>* iv = allocate(home,x.size());
00088     for (int i = x.size(); i--; ) {
00089       iv[i].idx = i; iv[i].view = x[i];
00090     }
00091     return iv;
00092   }
00093 
00094 
00095 
00100   template <class VA, class VC>
00101   class RelTestBnd {
00102   public:
00103     RelTest operator()(VA,VC);
00104   };
00109   template <class VA>
00110   class RelTestBnd<VA,ConstIntView> {
00111   public:
00112     RelTest operator()(VA,ConstIntView);
00113   };
00114 
00119   template <class VA, class VC>
00120   class RelTestDom {
00121   public:
00122     RelTest operator()(VA,VC);
00123   };
00128   template <class VA>
00129   class RelTestDom<VA,ConstIntView> {
00130   public:
00131     RelTest operator()(VA,ConstIntView);
00132   };
00133 
00134 
00135   template <class VA, class VC>
00136   forceinline RelTest
00137   RelTestBnd<VA,VC>::operator()(VA x, VC y) {
00138     return rtest_eq_bnd(x,y);
00139   }
00140   template <class VA>
00141   forceinline RelTest
00142   RelTestBnd<VA,ConstIntView>::operator()(VA x, ConstIntView y) {
00143     return rtest_eq_bnd(x,y.val());
00144   }
00145 
00146   template <class VA, class VC>
00147   forceinline RelTest
00148   RelTestDom<VA,VC>::operator()(VA x, VC y) {
00149     return rtest_eq_dom(x,y);
00150   }
00151   template <class VA>
00152   forceinline RelTest
00153   RelTestDom<VA,ConstIntView>::operator()(VA x, ConstIntView y) {
00154     return rtest_eq_dom(x,y.val());
00155   }
00156 
00157 
00158 
00159 
00160   /*
00161    * Base class
00162    *
00163    */
00164 
00165   template <class VA, class VB, class VC, PropCond pc_ac>
00166   View<VA,VB,VC,pc_ac>::View(Space* home, IdxView<VA>* iv0, int n0,
00167                              VB y0, VC y1)
00168     : Propagator(home), iv(iv0), n(n0), x0(y0), x1(y1) {
00169     x0.subscribe(home,this,PC_INT_DOM);
00170     x1.subscribe(home,this,pc_ac);
00171     for (int i=n; i--; )
00172       iv[i].view.subscribe(home,this,pc_ac);
00173   }
00174 
00175   template <class VA, class VB, class VC, PropCond pc_ac>
00176   forceinline
00177   View<VA,VB,VC,pc_ac>::View(Space* home, bool share, View& p)
00178     : Propagator(home,share,p), n(p.n) {
00179     x0.update(home,share,p.x0);
00180     x1.update(home,share,p.x1);
00181     iv = IdxView<VA>::allocate(home,n);
00182     for (int i=n; i--; ) {
00183       iv[i].idx = p.iv[i].idx;
00184       iv[i].view.update(home,share,p.iv[i].view);
00185     }
00186   }
00187 
00188   template <class VA, class VB, class VC, PropCond pc_ac>
00189   PropCost
00190   View<VA,VB,VC,pc_ac>::cost(ModEventDelta) const {
00191     // This is required for subscribing to variables in the
00192     // above constructor, but this is then the only time this
00193     // virtual function is ever used!
00194     return PC_LINEAR_LO;
00195   }
00196 
00197   template <class VA, class VB, class VC, PropCond pc_ac>
00198   Reflection::ActorSpec
00199   View<VA,VB,VC,pc_ac>::spec(const Space* home, Reflection::VarMap& m,
00200                              const Support::Symbol& ati) const {
00201     Reflection::ActorSpec s(ati);
00202     Reflection::IntArrayArg* ai = Reflection::Arg::newIntArray(n);
00203     for (int i=n; i--;)
00204       (*ai)[i] = iv[i].idx;
00205     Reflection::ArrayArg* a = Reflection::Arg::newArray(n);
00206     for (int i=n; i--;)
00207       (*a)[i] = iv[i].view.spec(home, m);
00208     return s << x0.spec(home, m)
00209              << x1.spec(home, m)
00210              << ai
00211              << a;
00212   }
00213 
00214   template <class VA, class VB, class VC, PropCond pc_ac>
00215   forceinline size_t
00216   View<VA,VB,VC,pc_ac>::dispose(Space* home) {
00217     x0.cancel(home,this,PC_INT_DOM);
00218     x1.cancel(home,this,pc_ac);
00219     for (int i=n; i--;)
00220       iv[i].view.cancel(home,this,pc_ac);
00221     (void) Propagator::dispose(home);
00222     return sizeof(*this);
00223   }
00224 
00225 
00226 
00227 
00232   template <class View>
00233   class IterIdxView {
00234   private:
00235     const IdxView<View> *cur, *end;
00236   public:
00237     IterIdxView(void);
00238     IterIdxView(const IdxView<View>*, const IdxView<View>*);
00239     void init(const IdxView<View>*, const IdxView<View>*);
00240     bool operator()(void) const;
00241     void operator++(void);
00242     int  val(void) const;
00243   };
00244 
00245   template <class View>
00246   forceinline
00247   IterIdxView<View>::IterIdxView(void) {}
00248   template <class View>
00249   forceinline
00250   IterIdxView<View>::IterIdxView(const IdxView<View>* b,
00251                                  const IdxView<View>* e)
00252     : cur(b), end(e) {}
00253   template <class View>
00254   forceinline void
00255   IterIdxView<View>::init(const IdxView<View>* b,
00256                           const IdxView<View>* e) {
00257     cur=b; end=e;
00258   }
00259   template <class View>
00260   forceinline bool
00261   IterIdxView<View>::operator()(void) const {
00262     return cur < end;
00263   }
00264   template <class View>
00265   forceinline void
00266   IterIdxView<View>::operator++(void) {
00267     cur++;
00268   }
00269   template <class View>
00270   forceinline int
00271   IterIdxView<View>::val(void) const {
00272     return cur->idx;
00273   }
00274 
00275 
00276 
00277 
00278   /*
00279    * Generic scanning: does all but computing new domain for result
00280    * (which is specific to bounds/domain version)
00281    *
00282    */
00283 
00284   template <class VA, class VB, class VC, PropCond pc_ac, class RelTest>
00285   ExecStatus
00286   scan(Space* home, IdxView<VA>* iv, int& n,
00287        VB x0, VC x1, Propagator* p, RelTest rt) {
00288     assert(n > 1);
00289     /*
00290      * Prunes pairs of index, variable
00291      *  - checks for idx value removed
00292      *  - checks for disequal variables
00293      *
00294      */
00295     ViewValues<VB> vx0(x0);
00296     int i = 0;
00297     int j = 0;
00298     while (vx0() && (i < n)) {
00299       if (iv[i].idx < vx0.val()) {
00300         iv[i].view.cancel(home,p,pc_ac);
00301         ++i;
00302       } else if (iv[i].idx > vx0.val()) {
00303         ++vx0;
00304       } else {
00305         assert(iv[i].idx == vx0.val());
00306         switch (rt(iv[i].view,x1)) {
00307         case RT_FALSE:
00308           iv[i].view.cancel(home,p,pc_ac);
00309           break;
00310         case RT_TRUE:
00311         case RT_MAYBE:
00312           iv[j++] = iv[i];
00313           break;
00314         default: GECODE_NEVER;
00315         }
00316         ++vx0; ++i;
00317       }
00318     }
00319     while (i < n)
00320       iv[i++].view.cancel(home,p,pc_ac);
00321     bool adjust = (j<n);
00322     n = j;
00323 
00324     if (n == 0)
00325       return ES_FAILED;
00326 
00327     if (n == 1) {
00328       GECODE_ME_CHECK(x0.eq(home,iv[0].idx));
00329     } else if (adjust) {
00330       IterIdxView<VA> v(&iv[0],&iv[n]);
00331       GECODE_ME_CHECK(x0.narrow_v(home,v,false));
00332       assert(x0.size() == static_cast<unsigned int>(n));
00333     }
00334     return ES_OK;
00335   }
00336 
00337 
00338 
00339 
00340   /*
00341    * Bounds consistent propagator
00342    *
00343    */
00344 
00345   template <class VA, class VB, class VC>
00346   forceinline
00347   ViewBnd<VA,VB,VC>::ViewBnd(Space* home,
00348                              IdxView<VA>* iv, int n, VB x0, VC x1)
00349     : View<VA,VB,VC,PC_INT_BND>(home,iv,n,x0,x1) {}
00350 
00351   template <class VA, class VB, class VC>
00352   ExecStatus
00353   ViewBnd<VA,VB,VC>::post(Space* home,
00354                           IdxView<VA>* iv, int n, VB x0, VC x1) {
00355     GECODE_ME_CHECK(x0.gq(home,0));
00356     GECODE_ME_CHECK(x0.le(home,n));
00357     if (x0.assigned()) {
00358       (void) new (home) Rel::EqBnd<VA,VC>(home,iv[x0.val()].view,x1);
00359       return ES_OK;
00360     } else {
00361       assert(n>1);
00362       (void) new (home) ViewBnd<VA,VB,VC>(home,iv,n,x0,x1);
00363     }
00364     return ES_OK;
00365   }
00366 
00367 
00368   template <class VA, class VB, class VC>
00369   forceinline
00370   ViewBnd<VA,VB,VC>::ViewBnd(Space* home, bool share, ViewBnd& p)
00371     : View<VA,VB,VC,PC_INT_BND>(home,share,p) {}
00372 
00373   template <class VA, class VB, class VC>
00374   Actor*
00375   ViewBnd<VA,VB,VC>::copy(Space* home, bool share) {
00376     return new (home) ViewBnd<VA,VB,VC>(home,share,*this);
00377   }
00378 
00379   template <class VA, class VB, class VC>
00380   inline Support::Symbol
00381   ViewBnd<VA,VB,VC>::ati(void) {
00382     return Reflection::mangle<VA,VB,VC>("Gecode::Int::Element::ViewBnd");
00383   }
00384 
00385   template <class VA, class VB, class VC>
00386   Reflection::ActorSpec
00387   ViewBnd<VA,VB,VC>::spec(const Space* home, Reflection::VarMap& m) const {
00388     return View<VA,VB,VC,PC_INT_BND>::spec(home, m, ati());
00389   }
00390 
00391   template <class VA, class VB, class VC>
00392   void
00393   ViewBnd<VA,VB,VC>::post(Space* home, Reflection::VarMap& vars,
00394                           const Reflection::ActorSpec& spec)
00395   {
00396     spec.checkArity(4);
00397     VB x0(home, vars, spec[0]);
00398     VC x1(home, vars, spec[1]);
00399     Reflection::IntArrayArg* ia = spec[2]->toIntArray();
00400     GECODE_AUTOARRAY(int,idx,ia->size());
00401     for (int i=ia->size(); i--; )
00402       idx[i] = (*ia)[i];
00403     ViewArray<VA> y(home, vars, spec[3]);
00404     IdxView<VA>* iv = IdxView<VA>::allocate(home, ia->size());
00405     for (int i=ia->size(); i--; ) {
00406       iv[i].view = y[i];
00407       iv[i].idx  = idx[i];
00408     }
00409     (void) new (home) ViewBnd<VA,VB,VC>(home, iv, ia->size(), x0, x1);
00410   }
00411 
00412   template <class VA, class VB, class VC>
00413   ExecStatus
00414   ViewBnd<VA,VB,VC>::propagate(Space* home, ModEventDelta) {
00415     assert(n > 1);
00416     RelTestBnd<VA,VC> rt;
00417     GECODE_ME_CHECK((scan<VA,VB,VC,PC_INT_BND,RelTestBnd<VA,VC> >
00418                      (home,iv,n,x0,x1,this,rt)));
00419     if (n == 1) {
00420       size_t s = this->dispose(home);
00421       (void) new (home) Rel::EqBnd<VA,VC>(home,iv[0].view,x1);
00422       return ES_SUBSUMED(this,s);
00423     }
00424     assert(n > 1);
00425     // Compute new result
00426     int min = iv[n-1].view.min();
00427     int max = iv[n-1].view.max();
00428     for (int i=n-1; i--; ) {
00429       min = std::min(iv[i].view.min(),min);
00430       max = std::max(iv[i].view.max(),max);
00431     }
00432     ExecStatus es = shared(x0,x1) ? ES_NOFIX : ES_FIX;
00433     {
00434      ModEvent me = x1.lq(home,max);
00435      if (me_failed(me))
00436        return ES_FAILED;
00437      if (me_modified(me) && (x1.max() != max))
00438        es = ES_NOFIX;
00439     }
00440     {
00441      ModEvent me = x1.gq(home,min);
00442      if (me_failed(me))
00443        return ES_FAILED;
00444      if (me_modified(me) && (x1.min() != min))
00445        es = ES_NOFIX;
00446     }
00447     return (x1.assigned() && (min == max)) ? 
00448       ES_SUBSUMED(this,home) : es;
00449   }
00450 
00451 
00452 
00453 
00454 
00455   /*
00456    * Domain consistent propagator
00457    *
00458    */
00459 
00460   template <class VA, class VB, class VC>
00461   forceinline
00462   ViewDom<VA,VB,VC>::ViewDom(Space* home,
00463                              IdxView<VA>* iv, int n, VB x0, VC x1)
00464     : View<VA,VB,VC,PC_INT_DOM>(home,iv,n,x0,x1) {}
00465 
00466   template <class VA, class VB, class VC>
00467   ExecStatus
00468   ViewDom<VA,VB,VC>::post(Space* home,
00469                           IdxView<VA>* iv, int n, VB x0, VC x1){
00470     GECODE_ME_CHECK(x0.gq(home,0));
00471     GECODE_ME_CHECK(x0.le(home,n));
00472     if (x0.assigned()) {
00473       (void) new (home) Rel::EqDom<VA,VC>(home,iv[x0.val()].view,x1);
00474       return ES_OK;
00475     } else {
00476       assert(n>1);
00477       (void) new (home) ViewDom<VA,VB,VC>(home,iv,n,x0,x1);
00478     }
00479     return ES_OK;
00480   }
00481 
00482 
00483   template <class VA, class VB, class VC>
00484   forceinline
00485   ViewDom<VA,VB,VC>::ViewDom(Space* home, bool share, ViewDom& p)
00486     : View<VA,VB,VC,PC_INT_DOM>(home,share,p) {}
00487 
00488   template <class VA, class VB, class VC>
00489   Actor*
00490   ViewDom<VA,VB,VC>::copy(Space* home, bool share) {
00491     return new (home) ViewDom<VA,VB,VC>(home,share,*this);
00492   }
00493 
00494 
00495   template <class VA, class VB, class VC>
00496   PropCost
00497   ViewDom<VA,VB,VC>::cost(ModEventDelta med) const {
00498     if (VA::me(med) != ME_INT_DOM)
00499       return PC_LINEAR_LO;
00500     else
00501       return PC_LINEAR_HI;
00502   }
00503 
00504   template <class VA, class VB, class VC>
00505   inline Support::Symbol
00506   ViewDom<VA,VB,VC>::ati(void) {
00507     return Reflection::mangle<VA,VB,VC>("Gecode::Int::Element::ViewDom");
00508   }
00509 
00510   template <class VA, class VB, class VC>
00511   Reflection::ActorSpec
00512   ViewDom<VA,VB,VC>::spec(const Space* home, Reflection::VarMap& m) const {
00513     return View<VA,VB,VC,PC_INT_DOM>::spec(home, m, ati());
00514   }
00515 
00516   template <class VA, class VB, class VC>
00517   void
00518   ViewDom<VA,VB,VC>::post(Space* home, Reflection::VarMap& vars,
00519                           const Reflection::ActorSpec& spec)
00520   {
00521     spec.checkArity(4);
00522     VB x0(home, vars, spec[0]);
00523     VC x1(home, vars, spec[1]);
00524     Reflection::IntArrayArg* ia = spec[2]->toIntArray();
00525     GECODE_AUTOARRAY(int,idx,ia->size());
00526     for (int i=ia->size(); i--; )
00527       idx[i] = (*ia)[i];
00528     ViewArray<VA> y(home, vars, spec[3]);
00529     IdxView<VA>* iv = IdxView<VA>::allocate(home, ia->size());
00530     for (int i=ia->size(); i--; ) {
00531       iv[i].view = y[i];
00532       iv[i].idx  = idx[i];
00533     }
00534     (void) new (home) ViewDom<VA,VB,VC>(home, iv, ia->size(), x0, x1);
00535   }
00536 
00537   template <class VA, class VB, class VC>
00538   ExecStatus
00539   ViewDom<VA,VB,VC>::propagate(Space* home, ModEventDelta med) {
00540     assert(n > 1);
00541     if (VA::me(med) != ME_INT_DOM) {
00542       RelTestBnd<VA,VC> rt;
00543       GECODE_ME_CHECK((scan<VA,VB,VC,PC_INT_DOM,RelTestBnd<VA,VC> >
00544                        (home,iv,n,x0,x1,this,rt)));
00545       if (n == 1) {
00546         size_t s = this->dispose(home);
00547         (void) new (home) Rel::EqDom<VA,VC>(home,iv[0].view,x1);
00548         return ES_SUBSUMED(this,s);
00549       }
00550       // Compute new result
00551       int min = iv[n-1].view.min();
00552       int max = iv[n-1].view.max();
00553       for (int i=n-1; i--; ) {
00554         min = std::min(iv[i].view.min(),min);
00555         max = std::max(iv[i].view.max(),max);
00556       }
00557       GECODE_ME_CHECK(x1.lq(home,max));
00558       GECODE_ME_CHECK(x1.gq(home,min));
00559       return (x1.assigned() && (min == max)) ?
00560         ES_SUBSUMED(this,home) :
00561         ES_NOFIX_PARTIAL(this,VA::med(ME_INT_DOM));
00562     }
00563     RelTestDom<VA,VC> rt;
00564     GECODE_ME_CHECK((scan<VA,VB,VC,PC_INT_DOM,RelTestDom<VA,VC> >
00565                      (home,iv,n,x0,x1,this,rt)));
00566     if (n == 1) {
00567       size_t s = this->dispose(home);
00568       (void) new (home) Rel::EqDom<VA,VC>(home,iv[0].view,x1);
00569       return ES_SUBSUMED(this,s);
00570     }
00571     assert(n > 1);
00572     GECODE_AUTOARRAY(ViewRanges<VA>,i_view,n);
00573     for (int i = n; i--; )
00574       i_view[i].init(iv[i].view);
00575     Iter::Ranges::NaryUnion<ViewRanges<VA> > i_val(i_view, n);
00576     ModEvent me = x1.inter_r(home,i_val);
00577     GECODE_ME_CHECK(me);
00578     return (shared(x0,x1) || me_modified(me)) ? ES_NOFIX : ES_FIX;
00579   }
00580 
00581 }}}
00582 
00583 // STATISTICS: int-prop
00584