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

int-bin.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:28:48 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7285 $
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 Linear {
00039 
00040   /*
00041    * Binary linear propagators
00042    *
00043    */
00044   template <class Val, class A, class B, PropCond pc>
00045   forceinline
00046   LinBin<Val,A,B,pc>::LinBin(Space* home, A y0, B y1, Val c0)
00047     : Propagator(home), x0(y0), x1(y1), c(c0) {
00048     x0.subscribe(home,this,pc);
00049     x1.subscribe(home,this,pc);
00050   }
00051 
00052   template <class Val, class A, class B, PropCond pc>
00053   forceinline
00054   LinBin<Val,A,B,pc>::LinBin(Space* home, bool share, LinBin<Val,A,B,pc>& p)
00055     : Propagator(home,share,p), c(p.c) {
00056     x0.update(home,share,p.x0);
00057     x1.update(home,share,p.x1);
00058   }
00059 
00060   template <class Val, class A, class B, PropCond pc>
00061   forceinline
00062   LinBin<Val,A,B,pc>::LinBin(Space* home, bool share, Propagator& p,
00063                              A y0, B y1, Val c0)
00064     : Propagator(home,share,p), c(c0) {
00065     x0.update(home,share,y0);
00066     x1.update(home,share,y1);
00067   }
00068 
00069   template <class Val, class A, class B, PropCond pc>
00070   PropCost
00071   LinBin<Val,A,B,pc>::cost(ModEventDelta) const {
00072     return PC_BINARY_LO;
00073   }
00074 
00075   template <class Val, class A, class B, PropCond pc>
00076   Reflection::ActorSpec
00077   LinBin<Val,A,B,pc>::spec(const Space* home, Reflection::VarMap& m,
00078                            const Support::Symbol& ati) const {
00079     Reflection::ActorSpec s(ati);
00080     return s << x0.spec(home, m)
00081              << x1.spec(home, m)
00082              << c;
00083   }
00084 
00085 
00086   template <class Val, class A, class B, PropCond pc>
00087   forceinline size_t
00088   LinBin<Val,A,B,pc>::dispose(Space* home) {
00089     assert(!home->failed());
00090     x0.cancel(home,this,pc);
00091     x1.cancel(home,this,pc);
00092     (void) Propagator::dispose(home);
00093     return sizeof(*this);
00094   }
00095 
00096 
00097   /*
00098    * Binary reified linear propagators
00099    *
00100    */
00101   template <class Val, class A, class B, PropCond pc, class Ctrl>
00102   forceinline
00103   ReLinBin<Val,A,B,pc,Ctrl>::ReLinBin(Space* home, A y0, B y1, Val c0, Ctrl b0)
00104     : Propagator(home), x0(y0), x1(y1), c(c0), b(b0) {
00105     x0.subscribe(home,this,pc);
00106     x1.subscribe(home,this,pc);
00107     b.subscribe(home,this,PC_INT_VAL);
00108   }
00109 
00110   template <class Val, class A, class B, PropCond pc, class Ctrl>
00111   forceinline
00112   ReLinBin<Val,A,B,pc,Ctrl>::ReLinBin(Space* home, bool share,
00113                                       ReLinBin<Val,A,B,pc,Ctrl>& p)
00114     : Propagator(home,share,p), c(p.c) {
00115     x0.update(home,share,p.x0);
00116     x1.update(home,share,p.x1);
00117     b.update(home,share,p.b);
00118   }
00119 
00120   template <class Val, class A, class B, PropCond pc, class Ctrl>
00121   PropCost
00122   ReLinBin<Val,A,B,pc,Ctrl>::cost(ModEventDelta) const {
00123     return PC_BINARY_LO;
00124   }
00125 
00126   template <class Val, class A, class B, PropCond pc, class Ctrl>
00127   forceinline size_t
00128   ReLinBin<Val,A,B,pc,Ctrl>::dispose(Space* home) {
00129     assert(!home->failed());
00130     x0.cancel(home,this,pc);
00131     x1.cancel(home,this,pc);
00132     b.cancel(home,this,PC_BOOL_VAL);
00133     (void) Propagator::dispose(home);
00134     return sizeof(*this);
00135   }
00136 
00137   template <class Val, class A, class B, PropCond pc, class Ctrl>
00138   Reflection::ActorSpec
00139   ReLinBin<Val,A,B,pc,Ctrl>::spec(const Space* home, Reflection::VarMap& m,
00140                                   const Support::Symbol& ati) const {
00141     Reflection::ActorSpec s(ati);
00142     return s << x0.spec(home, m)
00143              << x1.spec(home, m)
00144              << c
00145              << b.spec(home, m);
00146   }
00147 
00148   /*
00149    * Binary bounds consistent linear equality
00150    *
00151    */
00152 
00153   template <class Val, class A, class B>
00154   forceinline
00155   EqBin<Val,A,B>::EqBin(Space* home, A x0, B x1, Val c)
00156     : LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c) {}
00157 
00158   template <class Val, class A, class B>
00159   ExecStatus
00160   EqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00161     (void) new (home) EqBin<Val,A,B>(home,x0,x1,c);
00162     return ES_OK;
00163   }
00164 
00165 
00166   template <class Val, class A, class B>
00167   forceinline
00168   EqBin<Val,A,B>::EqBin(Space* home, bool share, EqBin<Val,A,B>& p)
00169     : LinBin<Val,A,B,PC_INT_BND>(home,share,p) {}
00170 
00171   template <class Val, class A, class B>
00172   forceinline
00173   EqBin<Val,A,B>::EqBin(Space* home, bool share, Propagator& p,
00174                         A x0, B x1, Val c)
00175     : LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c) {}
00176 
00177   template <class Val, class A, class B>
00178   Actor*
00179   EqBin<Val,A,B>::copy(Space* home, bool share) {
00180     return new (home) EqBin<Val,A,B>(home,share,*this);
00181   }
00182 
00183   template <class Val, class A, class B>
00184   inline Support::Symbol
00185   EqBin<Val,A,B>::ati(void) {
00186     return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::EqBin");
00187   }
00188 
00189   template <class Val, class A, class B>
00190   Reflection::ActorSpec
00191   EqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00192     return LinBin<Val,A,B,PC_INT_BND>::spec(home, m, ati());
00193   }
00194 
00195   template <class Val, class A, class B>
00196   void
00197   EqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00198                        const Reflection::ActorSpec& spec) {
00199     spec.checkArity(3);
00200     A x(home, vars, spec[0]);
00201     B y(home, vars, spec[1]);
00202     Val c = spec[2]->toInt();
00203     (void) new (home) EqBin<Val,A,B>(home, x, y, c);
00204   }
00205 
00207   enum BinMod {
00208     BM_X0_MIN = 1<<0,
00209     BM_X0_MAX = 1<<1,
00210     BM_X1_MIN = 1<<2,
00211     BM_X1_MAX = 1<<3,
00212     BM_ALL    = BM_X0_MIN|BM_X0_MAX|BM_X1_MIN|BM_X1_MAX
00213   };
00214 
00215 #define GECODE_INT_PV(CASE,TELL,UPDATE)         \
00216   if (bm & (CASE)) {                            \
00217     bm -= (CASE); ModEvent me = (TELL);         \
00218     if (me_failed(me))   return ES_FAILED;      \
00219     if (me_modified(me)) bm |= (UPDATE);        \
00220   }
00221 
00222   template <class Val, class A, class B>
00223   ExecStatus
00224   EqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00225     int bm = BM_ALL;
00226     do {
00227       GECODE_INT_PV(BM_X0_MIN, x0.gq(home,c-x1.max()), BM_X1_MAX);
00228       GECODE_INT_PV(BM_X1_MIN, x1.gq(home,c-x0.max()), BM_X0_MAX);
00229       GECODE_INT_PV(BM_X0_MAX, x0.lq(home,c-x1.min()), BM_X1_MIN);
00230       GECODE_INT_PV(BM_X1_MAX, x1.lq(home,c-x0.min()), BM_X0_MIN);
00231     } while (bm);
00232     return x0.assigned() ? ES_SUBSUMED(this,sizeof(*this)) : ES_FIX;
00233   }
00234 
00235 #undef GECODE_INT_PV
00236 
00237 
00238 
00239 
00240 
00241   /*
00242    * Reified binary bounds consistent linear equality
00243    *
00244    */
00245 
00246   template <class Val, class A, class B, class Ctrl>
00247   forceinline
00248   ReEqBin<Val,A,B,Ctrl>::ReEqBin(Space* home, A x0, B x1, Val c, Ctrl b)
00249     : ReLinBin<Val,A,B,PC_INT_BND,Ctrl>(home,x0,x1,c,b) {}
00250 
00251   template <class Val, class A, class B, class Ctrl>
00252   ExecStatus
00253   ReEqBin<Val,A,B,Ctrl>::post(Space* home, A x0, B x1, Val c, Ctrl b) {
00254     (void) new (home) ReEqBin<Val,A,B,Ctrl>(home,x0,x1,c,b);
00255     return ES_OK;
00256   }
00257 
00258 
00259   template <class Val, class A, class B, class Ctrl>
00260   forceinline
00261   ReEqBin<Val,A,B,Ctrl>::ReEqBin(Space* home, bool share,
00262                                  ReEqBin<Val,A,B,Ctrl>& p)
00263     : ReLinBin<Val,A,B,PC_INT_BND,Ctrl>(home,share,p) {}
00264 
00265   template <class Val, class A, class B, class Ctrl>
00266   Actor*
00267   ReEqBin<Val,A,B,Ctrl>::copy(Space* home, bool share) {
00268     return new (home) ReEqBin<Val,A,B,Ctrl>(home,share,*this);
00269   }
00270 
00271   template <class Val, class A, class B, class Ctrl>
00272   inline Support::Symbol
00273   ReEqBin<Val,A,B,Ctrl>::ati(void) {
00274     return Reflection::mangle<Val,A,B,Ctrl>("Gecode::Int::Linear::ReEqBin");
00275   }
00276 
00277   template <class Val, class A, class B, class Ctrl>
00278   Reflection::ActorSpec
00279   ReEqBin<Val,A,B,Ctrl>::spec(const Space* home,
00280                               Reflection::VarMap& m) const {
00281     return ReLinBin<Val,A,B,PC_INT_BND,Ctrl>::spec(home, m, ati());
00282   }
00283 
00284   template <class Val, class A, class B, class Ctrl>
00285   void
00286   ReEqBin<Val,A,B,Ctrl>::post(Space* home, Reflection::VarMap& vars,
00287                               const Reflection::ActorSpec& spec) {
00288     spec.checkArity(4);
00289     A x(home, vars, spec[0]);
00290     B y(home, vars, spec[1]);
00291     Val c = spec[2]->toInt();
00292     Ctrl b(home, vars, spec[3]);
00293     (void) new (home) ReEqBin<Val,A,B,Ctrl>(home, x, y, c, b);
00294   }
00295 
00296   template <class Val, class A, class B, class Ctrl>
00297   ExecStatus
00298   ReEqBin<Val,A,B,Ctrl>::propagate(Space* home, ModEventDelta) {
00299     if (b.zero())
00300       GECODE_REWRITE(this,(NqBin<Val,A,B>::post(home,x0,x1,c)));
00301     if (b.one())
00302       GECODE_REWRITE(this,(EqBin<Val,A,B>::post(home,x0,x1,c)));
00303     if ((x0.min() + x1.min() > c) || (x0.max() + x1.max() < c)) {
00304       GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(this,home);
00305     }
00306     if (x0.assigned() && x1.assigned()) {
00307       assert(x0.val() + x1.val() == c);
00308       GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(this,home);
00309     }
00310     return ES_FIX;
00311   }
00312 
00313 
00314 
00315 
00316   /*
00317    * Binary domain consistent linear disequality
00318    *
00319    */
00320   template <class Val, class A, class B>
00321   forceinline
00322   NqBin<Val,A,B>::NqBin(Space* home, A x0, B x1, Val c)
00323     : LinBin<Val,A,B,PC_INT_VAL>(home,x0,x1,c) {}
00324 
00325   template <class Val, class A, class B>
00326   ExecStatus
00327   NqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00328     (void) new (home) NqBin<Val,A,B>(home,x0,x1,c);
00329     return ES_OK;
00330   }
00331 
00332 
00333   template <class Val, class A, class B>
00334   forceinline
00335   NqBin<Val,A,B>::NqBin(Space* home, bool share, NqBin<Val,A,B>& p)
00336     : LinBin<Val,A,B,PC_INT_VAL>(home,share,p) {}
00337 
00338   template <class Val, class A, class B>
00339   Actor*
00340   NqBin<Val,A,B>::copy(Space* home, bool share) {
00341     return new (home) NqBin<Val,A,B>(home,share,*this);
00342   }
00343 
00344   template <class Val, class A, class B>
00345   forceinline
00346   NqBin<Val,A,B>::NqBin(Space* home, bool share, Propagator& p,
00347                         A x0, B x1, Val c)
00348     : LinBin<Val,A,B,PC_INT_VAL>(home,share,p,x0,x1,c) {}
00349 
00350 
00351 
00352   template <class Val, class A, class B>
00353   PropCost
00354   NqBin<Val,A,B>::cost(ModEventDelta) const {
00355     return PC_UNARY_LO;
00356   }
00357 
00358   template <class Val, class A, class B>
00359   inline Support::Symbol
00360   NqBin<Val,A,B>::ati(void) {
00361     return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::NqBin");
00362   }
00363 
00364   template <class Val, class A, class B>
00365   Reflection::ActorSpec
00366   NqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00367     return LinBin<Val,A,B,PC_INT_VAL>::spec(home, m, ati());
00368   }
00369 
00370   template <class Val, class A, class B>
00371   void
00372   NqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00373                        const Reflection::ActorSpec& spec) {
00374     spec.checkArity(3);
00375     A x(home, vars, spec[0]);
00376     B y(home, vars, spec[1]);
00377     Val c = spec[2]->toInt();
00378     (void) new (home) NqBin<Val,A,B>(home, x, y, c);
00379   }
00380 
00381   template <class Val, class A, class B>
00382   ExecStatus
00383   NqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00384     if (x0.assigned()) {
00385       GECODE_ME_CHECK(x1.nq(home,c-x0.val()));
00386     } else {
00387       assert(x1.assigned());
00388       GECODE_ME_CHECK(x0.nq(home,c-x1.val()));
00389     }
00390     return ES_SUBSUMED(this,home);
00391   }
00392 
00393 
00394   /*
00395    * Binary domain consistent less equal
00396    *
00397    */
00398 
00399   template <class Val, class A, class B>
00400   forceinline
00401   LqBin<Val,A,B>::LqBin(Space* home, A x0, B x1, Val c)
00402     : LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c) {}
00403 
00404   template <class Val, class A, class B>
00405   ExecStatus
00406   LqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00407     (void) new (home) LqBin<Val,A,B>(home,x0,x1,c);
00408     return ES_OK;
00409   }
00410 
00411 
00412   template <class Val, class A, class B>
00413   forceinline
00414   LqBin<Val,A,B>::LqBin(Space* home, bool share, LqBin<Val,A,B>& p)
00415     : LinBin<Val,A,B,PC_INT_BND>(home,share,p) {}
00416 
00417   template <class Val, class A, class B>
00418   Actor*
00419   LqBin<Val,A,B>::copy(Space* home, bool share) {
00420     return new (home) LqBin<Val,A,B>(home,share,*this);
00421   }
00422 
00423   template <class Val, class A, class B>
00424   forceinline
00425   LqBin<Val,A,B>::LqBin(Space* home, bool share, Propagator& p,
00426                         A x0, B x1, Val c)
00427     : LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c) {}
00428 
00429   template <class Val, class A, class B>
00430   inline Support::Symbol
00431   LqBin<Val,A,B>::ati(void) {
00432     return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::LqBin");
00433   }
00434 
00435   template <class Val, class A, class B>
00436   Reflection::ActorSpec
00437   LqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00438     return LinBin<Val,A,B,PC_INT_BND>::spec(home, m, ati());
00439   }
00440 
00441   template <class Val, class A, class B>
00442   void
00443   LqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00444                        const Reflection::ActorSpec& spec) {
00445     spec.checkArity(3);
00446     A x(home, vars, spec[0]);
00447     B y(home, vars, spec[1]);
00448     Val c = spec[2]->toInt();
00449     (void) new (home) LqBin<Val,A,B>(home, x, y, c);
00450   }
00451 
00452   template <class Val, class A, class B>
00453   ExecStatus
00454   LqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00455     GECODE_ME_CHECK(x0.lq(home,c-x1.min()));
00456     GECODE_ME_CHECK(x1.lq(home,c-x0.min()));
00457     return (x0.max()+x1.max() <= c) ? ES_SUBSUMED(this,home) : ES_FIX;
00458   }
00459 
00460 
00461 
00462 
00463   /*
00464    * Binary domain consistent greater equal
00465    *
00466    */
00467 
00468   template <class Val, class A, class B>
00469   forceinline
00470   GqBin<Val,A,B>::GqBin(Space* home, A x0, B x1, Val c)
00471     : LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c) {}
00472 
00473   template <class Val, class A, class B>
00474   ExecStatus
00475   GqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c) {
00476     (void) new (home) GqBin<Val,A,B>(home,x0,x1,c);
00477     return ES_OK;
00478   }
00479 
00480 
00481   template <class Val, class A, class B>
00482   forceinline
00483   GqBin<Val,A,B>::GqBin(Space* home, bool share, GqBin<Val,A,B>& p)
00484     : LinBin<Val,A,B,PC_INT_BND>(home,share,p) {}
00485 
00486   template <class Val, class A, class B>
00487   Actor*
00488   GqBin<Val,A,B>::copy(Space* home, bool share) {
00489     return new (home) GqBin<Val,A,B>(home,share,*this);
00490   }
00491 
00492   template <class Val, class A, class B>
00493   forceinline
00494   GqBin<Val,A,B>::GqBin(Space* home, bool share, Propagator& p,
00495                         A x0, B x1, Val c)
00496     : LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c) {}
00497 
00498   template <class Val, class A, class B>
00499   inline Support::Symbol
00500   GqBin<Val,A,B>::ati(void) {
00501     return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::GqBin");
00502   }
00503 
00504   template <class Val, class A, class B>
00505   Reflection::ActorSpec
00506   GqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00507     return LinBin<Val,A,B,PC_INT_BND>::spec(home, m, ati());
00508   }
00509 
00510   template <class Val, class A, class B>
00511   void
00512   GqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00513                        const Reflection::ActorSpec& spec) {
00514     spec.checkArity(3);
00515     A x(home, vars, spec[0]);
00516     B y(home, vars, spec[1]);
00517     Val c = spec[2]->toInt();
00518     (void) new (home) GqBin<Val,A,B>(home, x, y, c);
00519   }
00520 
00521   template <class Val, class A, class B>
00522   ExecStatus
00523   GqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00524     GECODE_ME_CHECK(x0.gq(home,c-x1.max()));
00525     GECODE_ME_CHECK(x1.gq(home,c-x0.max()));
00526     return (x0.min()+x1.min() >= c) ? ES_SUBSUMED(this,home) : ES_FIX;
00527   }
00528 
00529 
00530 
00531 
00532   /*
00533    * Reified binary domain consistent less equal
00534    *
00535    */
00536 
00537   template <class Val, class A, class B>
00538   forceinline
00539   ReLqBin<Val,A,B>::ReLqBin(Space* home, A x0, B x1, Val c, BoolView b)
00540     : ReLinBin<Val,A,B,PC_INT_BND,BoolView>(home,x0,x1,c,b) {}
00541 
00542   template <class Val, class A, class B>
00543   ExecStatus
00544   ReLqBin<Val,A,B>::post(Space* home, A x0, B x1, Val c, BoolView b) {
00545     (void) new (home) ReLqBin<Val,A,B>(home,x0,x1,c,b);
00546     return ES_OK;
00547   }
00548 
00549 
00550   template <class Val, class A, class B>
00551   forceinline
00552   ReLqBin<Val,A,B>::ReLqBin(Space* home, bool share, ReLqBin<Val,A,B>& p)
00553     : ReLinBin<Val,A,B,PC_INT_BND,BoolView>(home,share,p) {}
00554 
00555   template <class Val, class A, class B>
00556   Actor*
00557   ReLqBin<Val,A,B>::copy(Space* home, bool share) {
00558     return new (home) ReLqBin<Val,A,B>(home,share,*this);
00559   }
00560 
00561   template <class Val, class A, class B>
00562   Support::Symbol
00563   ReLqBin<Val,A,B>::ati(void) {
00564     return Reflection::mangle<Val,A,B>("Gecode::Int::Linear::ReLqBin");
00565   }
00566 
00567   template <class Val, class A, class B>
00568   Reflection::ActorSpec
00569   ReLqBin<Val,A,B>::spec(const Space* home, Reflection::VarMap& m) const {
00570     return ReLinBin<Val,A,B,PC_INT_BND,BoolView>::spec(home, m, ati());
00571   }
00572 
00573   template <class Val, class A, class B>
00574   void
00575   ReLqBin<Val,A,B>::post(Space* home, Reflection::VarMap& vars,
00576                          const Reflection::ActorSpec& spec) {
00577     spec.checkArity(4);
00578     A x(home, vars, spec[0]);
00579     B y(home, vars, spec[1]);
00580     Val c = spec[2]->toInt();
00581     BoolView b(home, vars, spec[3]);
00582     (void) new (home) ReLqBin<Val,A,B>(home, x, y, c, b);
00583   }
00584 
00585 
00586   template <class Val, class A, class B>
00587   ExecStatus
00588   ReLqBin<Val,A,B>::propagate(Space* home, ModEventDelta) {
00589     if (b.one())
00590       GECODE_REWRITE(this,(LqBin<Val,A,B>::post(home,x0,x1,c)));
00591     if (b.zero())
00592       GECODE_REWRITE(this,(GqBin<Val,A,B>::post(home,x0,x1,c+1)));
00593     if (x0.max() + x1.max() <= c) {
00594       GECODE_ME_CHECK(b.one_none(home)); return ES_SUBSUMED(this,home);
00595     }
00596     if (x0.min() + x1.min() > c) {
00597       GECODE_ME_CHECK(b.zero_none(home)); return ES_SUBSUMED(this,home);
00598     }
00599     return ES_FIX;
00600   }
00601 
00602 }}}
00603 
00604 // STATISTICS: int-prop
00605