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  *  Copyright:
00007  *     Christian Schulte, 2003
00008  *
00009  *  Last modified:
00010  *     $Date: 2008-07-11 09:32:27 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7289 $
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 namespace Gecode { namespace Int { namespace Count {
00039 
00040   /*
00041    * General baseclass
00042    *
00043    */
00044 
00045   template <class VX, class VY, class VZ, bool shr>
00046   forceinline
00047   BaseView<VX,VY,VZ,shr>::BaseView(Space* home,
00048                                    ViewArray<VX>& x0, VY y0, VZ z0, int c0)
00049     : Propagator(home), x(x0), y(y0), z(z0), c(c0) {
00050     x.subscribe(home,this,PC_INT_DOM);
00051     y.subscribe(home,this,PC_INT_DOM);
00052     z.subscribe(home,this,PC_INT_BND);
00053   }
00054 
00055   template <class VX, class VY, class VZ, bool shr>
00056   forceinline
00057   BaseView<VX,VY,VZ,shr>::BaseView(Space* home, bool share,
00058                                    BaseView<VX,VY,VZ,shr>& p)
00059     : Propagator(home,shr,p), c(p.c) {
00060     x.update(home,share,p.x);
00061     y.update(home,share,p.y);
00062     z.update(home,share,p.z);
00063   }
00064 
00065   template <class VX, class VY, class VZ, bool shr>
00066   PropCost
00067   BaseView<VX,VY,VZ,shr>::cost(ModEventDelta) const {
00068     return cost_lo(x.size()+1, PC_LINEAR_LO);
00069   }
00070 
00071   template <class VX, class VY, class VZ, bool shr>
00072   Reflection::ActorSpec
00073   BaseView<VX,VY,VZ,shr>::spec(const Space* home, Reflection::VarMap& m,
00074                                const Support::Symbol& ati) const {
00075     Reflection::ActorSpec s(ati);
00076     return s << x.spec(home, m)
00077              << y.spec(home, m)
00078              << z.spec(home, m)
00079              << c;
00080   }
00081 
00082   template <class VX, class VY, class VZ, bool shr>
00083   forceinline size_t
00084   BaseView<VX,VY,VZ,shr>::dispose(Space* home) {
00085     assert(!home->failed());
00086     x.cancel(home,this,PC_INT_DOM);
00087     y.cancel(home,this,PC_INT_DOM);
00088     z.cancel(home,this,PC_INT_BND);
00089     (void) Propagator::dispose(home);
00090     return sizeof(*this);
00091   }
00092 
00093   template <class VX, class VY, class VZ, bool shr>
00094   forceinline void
00095   BaseView<VX,VY,VZ,shr>::count(Space* home) {
00096     int n = x.size();
00097     for (int i=n; i--; )
00098       switch (holds(x[i],y)) {
00099       case RT_FALSE:
00100         x[i].cancel(home,this,PC_INT_DOM); x[i]=x[--n];
00101         break;
00102       case RT_TRUE:
00103         x[i].cancel(home,this,PC_INT_DOM); x[i]=x[--n];
00104         c--;
00105         break;
00106       case RT_MAYBE:
00107         break;
00108       default: 
00109         GECODE_NEVER;
00110       }
00111     x.size(n);
00112   }
00113 
00114   template <class VX, class VY, class VZ, bool shr>
00115   forceinline int
00116   BaseView<VX,VY,VZ,shr>::atleast(void) const {
00117     return -c;
00118   }
00119 
00120   template <class VX, class VY, class VZ, bool shr>
00121   forceinline int
00122   BaseView<VX,VY,VZ,shr>::atmost(void) const {
00123     return x.size()-c;
00124   }
00125 
00126   template <class VX, class VY, class VZ, bool shr>
00127   forceinline bool
00128   BaseView<VX,VY,VZ,shr>::sharing(const ViewArray<VX>& x,
00129                                   const VY& y, const VZ& z) {
00130     if (shared(y,z))
00131       return true;
00132     for (int i = x.size(); i--; )
00133       if (shared(x[i],z))
00134         return true;
00135     return false;
00136   }
00137 
00138   /*
00139    * Equality
00140    *
00141    */
00142 
00143   template <class VX, class VY, class VZ, bool shr>
00144   forceinline
00145   EqView<VX,VY,VZ,shr>::EqView(Space* home, 
00146                                ViewArray<VX>& x, VY y, VZ z, int c)
00147     : BaseView<VX,VY,VZ,shr>(home,x,y,z,c) {}
00148 
00149   template <class VX, class VY, class VZ, bool shr>
00150   ExecStatus
00151   EqView<VX,VY,VZ,shr>::post(Space* home, 
00152                              ViewArray<VX>& x, VY y, VZ z, int c) {
00153     if (z.assigned())
00154       return EqInt<VX,VY>::post(home,x,y,z.val()+c);
00155     if (sharing(x,y,z))
00156       (void) new (home) EqView<VX,VY,VZ,true>(home,x,y,z,c);
00157     else
00158       (void) new (home) EqView<VX,VY,VZ,false>(home,x,y,z,c);
00159     return ES_OK;
00160   }
00161 
00162   template <class VX, class VY, class VZ, bool shr>
00163   forceinline
00164   EqView<VX,VY,VZ,shr>::EqView(Space* home, bool share, 
00165                                EqView<VX,VY,VZ,shr>& p)
00166     : BaseView<VX,VY,VZ,shr>(home,share,p) {}
00167 
00168   template <class VX, class VY, class VZ, bool shr>
00169   Actor*
00170   EqView<VX,VY,VZ,shr>::copy(Space* home, bool share) {
00171     return new (home) EqView<VX,VY,VZ,shr>(home,share,*this);
00172   }
00173 
00174   template <class VX, class VY, class VZ, bool shr>
00175   Support::Symbol
00176   EqView<VX,VY,VZ,shr>::ati(void) {
00177     return Reflection::mangle<VX,VY,VZ>("Gecode::Int::Count::EqView",shr);
00178   }
00179 
00180   template <class VX, class VY, class VZ, bool shr>
00181   Reflection::ActorSpec
00182   EqView<VX,VY,VZ,shr>::spec(const Space* home, Reflection::VarMap& m) const {
00183     return BaseView<VX,VY,VZ,shr>::spec(home, m, ati());
00184   }
00185 
00186   template <class VX, class VY, class VZ, bool shr>
00187   void
00188   EqView<VX,VY,VZ,shr>::post(Space* home, Reflection::VarMap& vars,
00189                              const Reflection::ActorSpec& spec) {
00190     spec.checkArity(4);
00191     ViewArray<VX> x(home, vars, spec[0]);
00192     VY y(home, vars, spec[1]);
00193     VZ z(home, vars, spec[2]);
00194     int c = spec[3]->toInt();
00195     (void) new (home) EqView(home, x, y, z, c);
00196   }
00197 
00198   template <class VX, class VY, class VZ, bool shr>
00199   ExecStatus
00200   EqView<VX,VY,VZ,shr>::propagate(Space* home, ModEventDelta) {
00201     count(home);
00202 
00203     GECODE_ME_CHECK(z.gq(home,atleast()));
00204     GECODE_ME_CHECK(z.lq(home,atmost()));
00205 
00206     if (z.assigned()) {
00207       if (z.val() == atleast())
00208         return post_false(home,x,y) ? ES_FAILED : ES_SUBSUMED(this,home);
00209       if (z.val() == atmost())
00210         return post_true(home,x,y) ? ES_FAILED : ES_SUBSUMED(this,home);
00211       GECODE_REWRITE(this,(EqInt<VX,VY>::post(home,x,y,z.val()+c)));
00212     }
00213     return shr ? ES_NOFIX : ES_FIX;
00214   }
00215 
00216 
00217 
00218 
00219   /*
00220    * Disequality
00221    *
00222    */
00223 
00224   template <class VX, class VY, class VZ, bool shr>
00225   forceinline
00226   NqView<VX,VY,VZ,shr>::NqView(Space* home, 
00227                                ViewArray<VX>& x, VY y, VZ z, int c)
00228     : BaseView<VX,VY,VZ,shr>(home,x,y,z,c) {}
00229 
00230   template <class VX, class VY, class VZ, bool shr>
00231   ExecStatus
00232   NqView<VX,VY,VZ,shr>::post(Space* home, 
00233                              ViewArray<VX>& x, VY y, VZ z, int c) {
00234     if (z.assigned())
00235       return NqInt<VX,VY>::post(home,x,y,z.val()+c);
00236     (void) new (home) NqView<VX,VY,VZ,shr>(home,x,y,z,c);
00237     return ES_OK;
00238   }
00239 
00240   template <class VX, class VY, class VZ, bool shr>
00241   forceinline
00242   NqView<VX,VY,VZ,shr>::NqView(Space* home, bool share, 
00243                                NqView<VX,VY,VZ,shr>& p)
00244     : BaseView<VX,VY,VZ,shr>(home,share,p) {}
00245 
00246   template <class VX, class VY, class VZ, bool shr>
00247   Actor*
00248   NqView<VX,VY,VZ,shr>::copy(Space* home, bool share) {
00249     return new (home) NqView<VX,VY,VZ,shr>(home,share,*this);
00250   }
00251 
00252   template <class VX, class VY, class VZ, bool shr>
00253   Support::Symbol
00254   NqView<VX,VY,VZ,shr>::ati(void) {
00255     return Reflection::mangle<VX,VY,VZ>("Gecode::Int::Count::NqView",shr);
00256   }
00257 
00258   template <class VX, class VY, class VZ, bool shr>
00259   Reflection::ActorSpec
00260   NqView<VX,VY,VZ,shr>::spec(const Space* home, Reflection::VarMap& m) const {
00261     return BaseView<VX,VY,VZ,shr>::spec(home, m, ati());
00262   }
00263 
00264   template <class VX, class VY, class VZ, bool shr>
00265   void
00266   NqView<VX,VY,VZ,shr>::post(Space* home, Reflection::VarMap& vars,
00267                              const Reflection::ActorSpec& spec) {
00268     spec.checkArity(4);
00269     ViewArray<VX> x(home, vars, spec[0]);
00270     VY y(home, vars, spec[1]);
00271     VZ z(home, vars, spec[2]);
00272     int c = spec[3]->toInt();
00273     (void) new (home) NqView(home, x, y, z, c);
00274   }
00275 
00276   template <class VX, class VY, class VZ, bool shr>
00277   ExecStatus
00278   NqView<VX,VY,VZ,shr>::propagate(Space* home, ModEventDelta) {
00279     count(home);
00280     if (atleast() == atmost()) {
00281       GECODE_ME_CHECK(z.nq(home,atleast()));
00282       return ES_SUBSUMED(this,home);
00283     }
00284     if (z.max() < atleast())
00285       return ES_SUBSUMED(this,home);
00286     if (z.min() > atmost())
00287       return ES_SUBSUMED(this,home);
00288     if (z.assigned())
00289       GECODE_REWRITE(this,(NqInt<VX,VY>::post(home,x,y,z.val()+c)));
00290     return ES_FIX;
00291   }
00292 
00293 
00294 
00295   /*
00296    * Less or equal
00297    *
00298    */
00299 
00300   template <class VX, class VY, class VZ, bool shr>
00301   forceinline
00302   LqView<VX,VY,VZ,shr>::LqView(Space* home, ViewArray<VX>& x, 
00303                                VY y, VZ z, int c)
00304     : BaseView<VX,VY,VZ,shr>(home,x,y,z,c) {}
00305 
00306   template <class VX, class VY, class VZ, bool shr>
00307   ExecStatus
00308   LqView<VX,VY,VZ,shr>::post(Space* home, ViewArray<VX>& x, 
00309                              VY y, VZ z, int c) {
00310     if (z.assigned())
00311       return LqInt<VX,VY>::post(home,x,y,z.val()+c);
00312     if (sharing(x,y,z))
00313       (void) new (home) LqView<VX,VY,VZ,true>(home,x,y,z,c);
00314     else
00315       (void) new (home) LqView<VX,VY,VZ,false>(home,x,y,z,c);
00316     return ES_OK;
00317   }
00318 
00319   template <class VX, class VY, class VZ, bool shr>
00320   forceinline
00321   LqView<VX,VY,VZ,shr>::LqView(Space* home, bool share, 
00322                                LqView<VX,VY,VZ,shr>& p)
00323     : BaseView<VX,VY,VZ,shr>(home,share,p) {}
00324 
00325   template <class VX, class VY, class VZ, bool shr>
00326   Actor*
00327   LqView<VX,VY,VZ,shr>::copy(Space* home, bool share) {
00328     return new (home) LqView<VX,VY,VZ,shr>(home,share,*this);
00329   }
00330 
00331   template <class VX, class VY, class VZ, bool shr>
00332   Support::Symbol
00333   LqView<VX,VY,VZ,shr>::ati(void) {
00334     return Reflection::mangle<VX,VY,VZ>("Gecode::Int::Count::LqView",shr);
00335   }
00336 
00337   template <class VX, class VY, class VZ, bool shr>
00338   Reflection::ActorSpec
00339   LqView<VX,VY,VZ,shr>::spec(const Space* home, Reflection::VarMap& m) const {
00340     return BaseView<VX,VY,VZ,shr>::spec(home, m, ati());
00341   }
00342 
00343   template <class VX, class VY, class VZ, bool shr>
00344   void
00345   LqView<VX,VY,VZ,shr>::post(Space* home, Reflection::VarMap& vars,
00346                              const Reflection::ActorSpec& spec) {
00347     spec.checkArity(4);
00348     ViewArray<VX> x(home, vars, spec[0]);
00349     VY y(home, vars, spec[1]);
00350     VZ z(home, vars, spec[2]);
00351     int c = spec[3]->toInt();
00352     (void) new (home) LqView(home, x, y, z, c);
00353   }
00354 
00355   template <class VX, class VY, class VZ, bool shr>
00356   ExecStatus
00357   LqView<VX,VY,VZ,shr>::propagate(Space* home, ModEventDelta) {
00358     count(home);
00359     GECODE_ME_CHECK(z.gq(home,atleast()));
00360     if (z.max() == atleast())
00361       return post_false(home,x,y) ? ES_FAILED : ES_SUBSUMED(this,home);
00362     if (x.size() == 0)
00363       return ES_SUBSUMED(this,home);
00364     if (z.assigned())
00365       GECODE_REWRITE(this,(LqInt<VX,VY>::post(home,x,y,z.val()+c)));
00366     return shr ? ES_NOFIX : ES_FIX;
00367   }
00368 
00369 
00370 
00371   /*
00372    * Greater or equal
00373    *
00374    */
00375 
00376   template <class VX, class VY, class VZ, bool shr>
00377   forceinline
00378   GqView<VX,VY,VZ,shr>::GqView(Space* home, ViewArray<VX>& x, VY y, VZ z, int c)
00379     : BaseView<VX,VY,VZ,shr>(home,x,y,z,c) {}
00380 
00381   template <class VX, class VY, class VZ, bool shr>
00382   ExecStatus
00383   GqView<VX,VY,VZ,shr>::post(Space* home, 
00384                              ViewArray<VX>& x, VY y, VZ z, int c) {
00385     if (z.assigned())
00386       return GqInt<VX,VY>::post(home,x,y,z.val()+c);
00387     if (sharing(x,y,z))
00388       (void) new (home) GqView<VX,VY,VZ,true>(home,x,y,z,c);
00389     else
00390       (void) new (home) GqView<VX,VY,VZ,false>(home,x,y,z,c);
00391     return ES_OK;
00392   }
00393 
00394   template <class VX, class VY, class VZ, bool shr>
00395   forceinline
00396   GqView<VX,VY,VZ,shr>::GqView(Space* home, bool share, 
00397                                GqView<VX,VY,VZ,shr>& p)
00398     : BaseView<VX,VY,VZ,shr>(home,share,p) {}
00399 
00400   template <class VX, class VY, class VZ, bool shr>
00401   Actor*
00402   GqView<VX,VY,VZ,shr>::copy(Space* home, bool share) {
00403     return new (home) GqView<VX,VY,VZ,shr>(home,share,*this);
00404   }
00405 
00406   template <class VX, class VY, class VZ, bool shr>
00407   Support::Symbol
00408   GqView<VX,VY,VZ,shr>::ati(void) {
00409     return Reflection::mangle<VX,VY,VZ>("Gecode::Int::Count::GqView", shr);
00410   }
00411 
00412   template <class VX, class VY, class VZ, bool shr>
00413   Reflection::ActorSpec
00414   GqView<VX,VY,VZ,shr>::spec(const Space* home, Reflection::VarMap& m) const {
00415     return BaseView<VX,VY,VZ,shr>::spec(home, m, ati());
00416   }
00417 
00418   template <class VX, class VY, class VZ, bool shr>
00419   void
00420   GqView<VX,VY,VZ,shr>::post(Space* home, Reflection::VarMap& vars,
00421                              const Reflection::ActorSpec& spec) {
00422     spec.checkArity(4);
00423     ViewArray<VX> x(home, vars, spec[0]);
00424     VY y(home, vars, spec[1]);
00425     VZ z(home, vars, spec[2]);
00426     int c = spec[3]->toInt();
00427     (void) new (home) GqView(home, x, y, z, c);
00428   }
00429 
00430   template <class VX, class VY, class VZ, bool shr>
00431   ExecStatus
00432   GqView<VX,VY,VZ,shr>::propagate(Space* home, ModEventDelta) {
00433     count(home);
00434 
00435     GECODE_ME_CHECK(z.lq(home,atmost()));
00436 
00437     if (z.min() == atmost())
00438       return post_true(home,x,y) ? ES_FAILED : ES_SUBSUMED(this,home);
00439     if (x.size() == 0)
00440       return ES_SUBSUMED(this,home);
00441     if (z.assigned())
00442       GECODE_REWRITE(this,(GqInt<VX,VY>::post(home,x,y,z.val()+c)));
00443     return shr ? ES_NOFIX : ES_FIX;
00444   }
00445 
00446 }}}
00447 
00448 // STATISTICS: int-prop
00449