Generated on Fri Mar 20 15:56:12 2015 for Gecode by doxygen 1.6.3

int-post.cpp

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, 2002
00008  *
00009  *  Last modified:
00010  *     $Date: 2013-02-14 16:29:11 +0100 (Thu, 14 Feb 2013) $ by $Author: schulte $
00011  *     $Revision: 13292 $
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 <algorithm>
00039 
00040 #include <gecode/int/rel.hh>
00041 #include <gecode/int/linear.hh>
00042 #include <gecode/int/div.hh>
00043 
00044 namespace Gecode { namespace Int { namespace Linear {
00045 
00047   forceinline void
00048   eliminate(Term<IntView>* t, int &n, long long int& d) {
00049     for (int i=n; i--; )
00050       if (t[i].x.assigned()) {
00051         long long int ax = t[i].a * static_cast<long long int>(t[i].x.val());
00052         if (Limits::overflow_sub(d,ax))
00053           throw OutOfLimits("Int::linear");
00054         d=d-ax; t[i]=t[--n];
00055       }
00056   }
00057 
00059   forceinline void
00060   rewrite(IntRelType &irt, long long int &d,
00061           Term<IntView>* &t_p, int &n_p,
00062           Term<IntView>* &t_n, int &n_n) {
00063     switch (irt) {
00064     case IRT_EQ: case IRT_NQ: case IRT_LQ:
00065       break;
00066     case IRT_LE:
00067       d--; irt = IRT_LQ;
00068       break;
00069     case IRT_GR:
00070       d++;
00071       /* fall through */
00072     case IRT_GQ:
00073       irt = IRT_LQ;
00074       std::swap(n_p,n_n); std::swap(t_p,t_n); d = -d;
00075       break;
00076     default:
00077       throw UnknownRelation("Int::linear");
00078     }
00079   }
00080 
00082   forceinline bool
00083   precision(Term<IntView>* t_p, int n_p,
00084             Term<IntView>* t_n, int n_n,
00085             long long int d) {
00086     long long int sl = 0;
00087     long long int su = 0;
00088 
00089     for (int i = n_p; i--; ) {
00090       long long int axmin = 
00091         t_p[i].a * static_cast<long long int>(t_p[i].x.min());
00092       if (Limits::overflow_add(sl,axmin))
00093         throw OutOfLimits("Int::linear");
00094       sl = sl + axmin;
00095       long long int axmax = 
00096         t_p[i].a * static_cast<long long int>(t_p[i].x.max());
00097       if (Limits::overflow_add(sl,axmax))
00098         throw OutOfLimits("Int::linear");
00099       su = su + axmax;
00100     }
00101     for (int i = n_n; i--; ) {
00102       long long int axmax = 
00103         t_n[i].a * static_cast<long long int>(t_n[i].x.max());
00104       if (Limits::overflow_sub(sl,axmax))
00105         throw OutOfLimits("Int::linear");
00106       sl = sl - axmax;
00107       long long int axmin = 
00108         t_n[i].a * static_cast<long long int>(t_n[i].x.min());
00109       if (Limits::overflow_sub(su,axmin))
00110         throw OutOfLimits("Int::linear");
00111       su = su - axmin;
00112     }
00113 
00114     bool is_ip = (sl >= Limits::min) && (su <= Limits::max);
00115 
00116     if (Limits::overflow_sub(sl,d))
00117       throw OutOfLimits("Int::linear");
00118     sl = sl - d;
00119     if (Limits::overflow_sub(su,d))
00120       throw OutOfLimits("Int::linear");
00121     su = su - d;
00122 
00123     is_ip = is_ip && (sl >= Limits::min) && (su <= Limits::max);
00124 
00125     for (int i = n_p; i--; ) {
00126       long long int axmin = 
00127         t_p[i].a * static_cast<long long int>(t_p[i].x.min());
00128       if (Limits::overflow_sub(sl,axmin))
00129         throw OutOfLimits("Int::linear");
00130       if (sl - axmin < Limits::min)
00131         is_ip = false;
00132       long long int axmax = 
00133         t_p[i].a * static_cast<long long int>(t_p[i].x.max());
00134       if (Limits::overflow_sub(su,axmax))
00135         throw OutOfLimits("Int::linear");
00136       if (su - axmax > Limits::max)
00137         is_ip = false;
00138     }
00139     for (int i = n_n; i--; ) {
00140       long long int axmin = 
00141         t_n[i].a * static_cast<long long int>(t_n[i].x.min());
00142       if (Limits::overflow_add(sl,axmin))
00143         throw OutOfLimits("Int::linear");
00144       if (sl + axmin < Limits::min)
00145         is_ip = false;
00146       long long int axmax = 
00147         t_n[i].a * static_cast<long long int>(t_n[i].x.max());
00148       if (Limits::overflow_add(su,axmax))
00149         throw OutOfLimits("Int::linear");
00150       if (su + axmax > Limits::max)
00151         is_ip = false;
00152     }
00153     return is_ip;
00154   }
00155 
00160   template<class Val, class View>
00161   forceinline void
00162   post_nary(Home home,
00163             ViewArray<View>& x, ViewArray<View>& y, IntRelType irt, Val c) {
00164     switch (irt) {
00165     case IRT_EQ:
00166       GECODE_ES_FAIL((Eq<Val,View,View >::post(home,x,y,c)));
00167       break;
00168     case IRT_NQ:
00169       GECODE_ES_FAIL((Nq<Val,View,View >::post(home,x,y,c)));
00170       break;
00171     case IRT_LQ:
00172       GECODE_ES_FAIL((Lq<Val,View,View >::post(home,x,y,c)));
00173       break;
00174     default: GECODE_NEVER;
00175     }
00176   }
00177 
00178 
00180 #define GECODE_INT_PL_BIN(CLASS)                                             \
00181   switch (n_p) {                                                             \
00182   case 2:                                                                    \
00183     GECODE_ES_FAIL((CLASS<int,IntView,IntView>::post                         \
00184                          (home,t_p[0].x,t_p[1].x,c)));                       \
00185     break;                                                                   \
00186   case 1:                                                                    \
00187     GECODE_ES_FAIL((CLASS<int,IntView,MinusView>::post                       \
00188                          (home,t_p[0].x,MinusView(t_n[0].x),c)));            \
00189     break;                                                                   \
00190   case 0:                                                                    \
00191     GECODE_ES_FAIL((CLASS<int,MinusView,MinusView>::post                     \
00192                          (home,MinusView(t_n[0].x),MinusView(t_n[1].x),c))); \
00193     break;                                                                   \
00194   default: GECODE_NEVER;                                                     \
00195   }
00196 
00198 #define GECODE_INT_PL_TER(CLASS)                                        \
00199   switch (n_p) {                                                        \
00200   case 3:                                                               \
00201     GECODE_ES_FAIL((CLASS<int,IntView,IntView,IntView>::post            \
00202                          (home,t_p[0].x,t_p[1].x,t_p[2].x,c)));         \
00203     break;                                                              \
00204   case 2:                                                               \
00205     GECODE_ES_FAIL((CLASS<int,IntView,IntView,MinusView>::post          \
00206                          (home,t_p[0].x,t_p[1].x,                       \
00207                           MinusView(t_n[0].x),c)));                     \
00208     break;                                                              \
00209   case 1:                                                               \
00210     GECODE_ES_FAIL((CLASS<int,IntView,MinusView,MinusView>::post        \
00211                          (home,t_p[0].x,                                \
00212                           MinusView(t_n[0].x),MinusView(t_n[1].x),c))); \
00213     break;                                                              \
00214   case 0:                                                               \
00215     GECODE_ES_FAIL((CLASS<int,MinusView,MinusView,MinusView>::post      \
00216                          (home,MinusView(t_n[0].x),                     \
00217                           MinusView(t_n[1].x),MinusView(t_n[2].x),c))); \
00218     break;                                                              \
00219   default: GECODE_NEVER;                                                \
00220   }
00221 
00222   void
00223   post(Home home, Term<IntView>* t, int n, IntRelType irt, int c,
00224        IntConLevel icl) {
00225 
00226     Limits::check(c,"Int::linear");
00227 
00228     long long int d = c;
00229 
00230     eliminate(t,n,d);
00231 
00232     Term<IntView> *t_p, *t_n;
00233     int n_p, n_n, gcd=1;
00234     bool is_unit = normalize<IntView>(t,n,t_p,n_p,t_n,n_n,gcd);
00235 
00236     rewrite(irt,d,t_p,n_p,t_n,n_n);
00237 
00238     // Divide by gcd
00239     if (gcd > 1) {
00240       switch (irt) {
00241       case IRT_EQ:
00242         if ((d % gcd) != 0) {
00243           home.fail();
00244           return;
00245         }
00246         d /= gcd;
00247         break;
00248       case IRT_NQ: 
00249         if ((d % gcd) != 0)
00250           return;
00251         d /= gcd;
00252         break;
00253       case IRT_LQ:
00254         d = floor_div_xp(d,static_cast<long long int>(gcd));
00255         break;
00256       default: GECODE_NEVER;
00257       }
00258     }
00259 
00260     if (n == 0) {
00261       switch (irt) {
00262       case IRT_EQ: if (d != 0) home.fail(); break;
00263       case IRT_NQ: if (d == 0) home.fail(); break;
00264       case IRT_LQ: if (d < 0)  home.fail(); break;
00265       default: GECODE_NEVER;
00266       }
00267       return;
00268     }
00269 
00270     if (n == 1) {
00271       if (n_p == 1) {
00272         LLongScaleView y(t_p[0].a,t_p[0].x);
00273         switch (irt) {
00274         case IRT_EQ: GECODE_ME_FAIL(y.eq(home,d)); break;
00275         case IRT_NQ: GECODE_ME_FAIL(y.nq(home,d)); break;
00276         case IRT_LQ: GECODE_ME_FAIL(y.lq(home,d)); break;
00277         default: GECODE_NEVER;
00278         }
00279       } else {
00280         LLongScaleView y(t_n[0].a,t_n[0].x);
00281         switch (irt) {
00282         case IRT_EQ: GECODE_ME_FAIL(y.eq(home,-d)); break;
00283         case IRT_NQ: GECODE_ME_FAIL(y.nq(home,-d)); break;
00284         case IRT_LQ: GECODE_ME_FAIL(y.gq(home,-d)); break;
00285         default: GECODE_NEVER;
00286         }
00287       }
00288       return;
00289     }
00290 
00291     bool is_ip = precision(t_p,n_p,t_n,n_n,d);
00292 
00293     if (is_unit && is_ip && (icl != ICL_DOM)) {
00294       // Unit coefficients with integer precision
00295       c = static_cast<int>(d);
00296       if (n == 2) {
00297         switch (irt) {
00298         case IRT_EQ: GECODE_INT_PL_BIN(EqBin); break;
00299         case IRT_NQ: GECODE_INT_PL_BIN(NqBin); break;
00300         case IRT_LQ: GECODE_INT_PL_BIN(LqBin); break;
00301         default: GECODE_NEVER;
00302         }
00303       } else if (n == 3) {
00304         switch (irt) {
00305         case IRT_EQ: GECODE_INT_PL_TER(EqTer); break;
00306         case IRT_NQ: GECODE_INT_PL_TER(NqTer); break;
00307         case IRT_LQ: GECODE_INT_PL_TER(LqTer); break;
00308         default: GECODE_NEVER;
00309         }
00310       } else {
00311         ViewArray<IntView> x(home,n_p);
00312         for (int i = n_p; i--; )
00313           x[i] = t_p[i].x;
00314         ViewArray<IntView> y(home,n_n);
00315         for (int i = n_n; i--; )
00316           y[i] = t_n[i].x;
00317         post_nary<int,IntView>(home,x,y,irt,c);
00318       }
00319     } else if (is_ip) {
00320       if ((n==2) && is_unit && (icl == ICL_DOM) && (irt == IRT_EQ)) {
00321         // Binary domain-consistent equality
00322         c = static_cast<int>(d);
00323         if (c == 0) {
00324           switch (n_p) {
00325           case 2: {
00326             IntView x(t_p[0].x);
00327             MinusView y(t_p[1].x);
00328             GECODE_ES_FAIL(
00329               (Rel::EqDom<IntView,MinusView>::post(home,x,y)));
00330             break;
00331           }
00332           case 1: {
00333             IntView x(t_p[0].x);
00334             IntView y(t_n[0].x);
00335             GECODE_ES_FAIL(
00336               (Rel::EqDom<IntView,IntView>::post(home,x,y)));
00337             break;
00338           }
00339           case 0: {
00340             IntView x(t_n[0].x);
00341             MinusView y(t_n[1].x);
00342             GECODE_ES_FAIL(
00343               (Rel::EqDom<IntView,MinusView>::post(home,x,y)));
00344             break;
00345           }
00346           default:
00347             GECODE_NEVER;
00348           }
00349         } else {
00350           switch (n_p) {
00351           case 2: {
00352             MinusView x(t_p[0].x);
00353             OffsetView y(t_p[1].x, -c);
00354             GECODE_ES_FAIL(
00355               (Rel::EqDom<MinusView,OffsetView>::post(home,x,y)));
00356             break;
00357           }
00358           case 1: {
00359             IntView x(t_p[0].x);
00360             OffsetView y(t_n[0].x, c);
00361             GECODE_ES_FAIL(
00362               (Rel::EqDom<IntView,OffsetView>::post(home,x,y)));
00363             break;
00364           }
00365           case 0: {
00366             MinusView x(t_n[0].x);
00367             OffsetView y(t_n[1].x, c);
00368             GECODE_ES_FAIL(
00369               (Rel::EqDom<MinusView,OffsetView>::post(home,x,y)));
00370             break;
00371           }
00372           default:
00373             GECODE_NEVER;
00374           }          
00375         }
00376       } else {
00377         // Arbitrary coefficients with integer precision
00378         c = static_cast<int>(d);
00379         ViewArray<IntScaleView> x(home,n_p);
00380         for (int i = n_p; i--; )
00381           x[i] = IntScaleView(t_p[i].a,t_p[i].x);
00382         ViewArray<IntScaleView> y(home,n_n);
00383         for (int i = n_n; i--; )
00384           y[i] = IntScaleView(t_n[i].a,t_n[i].x);
00385         if ((icl == ICL_DOM) && (irt == IRT_EQ)) {
00386           GECODE_ES_FAIL((DomEq<int,IntScaleView>::post(home,x,y,c)));
00387         } else {
00388           post_nary<int,IntScaleView>(home,x,y,irt,c);
00389         }
00390       }
00391     } else {
00392       // Arbitrary coefficients with long long precision
00393       ViewArray<LLongScaleView> x(home,n_p);
00394       for (int i = n_p; i--; )
00395         x[i] = LLongScaleView(t_p[i].a,t_p[i].x);
00396       ViewArray<LLongScaleView> y(home,n_n);
00397       for (int i = n_n; i--; )
00398         y[i] = LLongScaleView(t_n[i].a,t_n[i].x);
00399       if ((icl == ICL_DOM) && (irt == IRT_EQ)) {
00400         GECODE_ES_FAIL((DomEq<long long int,LLongScaleView>
00401                         ::post(home,x,y,d)));
00402       } else {
00403         post_nary<long long int,LLongScaleView>(home,x,y,irt,d);
00404       }
00405     }
00406   }
00407 
00408 #undef GECODE_INT_PL_BIN
00409 #undef GECODE_INT_PL_TER
00410 
00411 
00416   template<class Val, class View>
00417   forceinline void
00418   post_nary(Home home,
00419             ViewArray<View>& x, ViewArray<View>& y,
00420             IntRelType irt, Val c, Reify r) {
00421     switch (irt) {
00422     case IRT_EQ:
00423       switch (r.mode()) {
00424       case RM_EQV:
00425         GECODE_ES_FAIL((ReEq<Val,View,View,BoolView,RM_EQV>::
00426                         post(home,x,y,c,r.var())));
00427         break;
00428       case RM_IMP:
00429         GECODE_ES_FAIL((ReEq<Val,View,View,BoolView,RM_IMP>::
00430                         post(home,x,y,c,r.var())));
00431         break;
00432       case RM_PMI:
00433         GECODE_ES_FAIL((ReEq<Val,View,View,BoolView,RM_PMI>::
00434                         post(home,x,y,c,r.var())));
00435         break;
00436       default: GECODE_NEVER;
00437       }
00438       break;
00439     case IRT_NQ:
00440       {
00441         NegBoolView n(r.var());
00442         switch (r.mode()) {
00443         case RM_EQV:
00444           GECODE_ES_FAIL((ReEq<Val,View,View,NegBoolView,RM_EQV>::
00445                           post(home,x,y,c,n)));
00446           break;
00447         case RM_IMP:
00448           GECODE_ES_FAIL((ReEq<Val,View,View,NegBoolView,RM_PMI>::
00449                           post(home,x,y,c,n)));
00450           break;
00451         case RM_PMI:
00452           GECODE_ES_FAIL((ReEq<Val,View,View,NegBoolView,RM_IMP>::
00453                           post(home,x,y,c,n)));
00454           break;
00455         default: GECODE_NEVER;
00456         }
00457       }
00458       break;
00459     case IRT_LQ:
00460         switch (r.mode()) {
00461         case RM_EQV:
00462           GECODE_ES_FAIL((ReLq<Val,View,View,RM_EQV>::
00463                           post(home,x,y,c,r.var())));
00464           break;
00465         case RM_IMP:
00466           GECODE_ES_FAIL((ReLq<Val,View,View,RM_IMP>::
00467                           post(home,x,y,c,r.var())));
00468           break;
00469         case RM_PMI:
00470           GECODE_ES_FAIL((ReLq<Val,View,View,RM_PMI>::
00471                           post(home,x,y,c,r.var())));
00472           break;
00473         default: GECODE_NEVER;
00474         }
00475       break;
00476     default: GECODE_NEVER;
00477     }
00478   }
00479 
00480   template<class CtrlView>
00481   forceinline void
00482   posteqint(Home home, IntView& x, int c, CtrlView b, ReifyMode rm,
00483             IntConLevel icl) {
00484     if (icl == ICL_DOM) {
00485       switch (rm) {
00486       case RM_EQV:
00487         GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,CtrlView,RM_EQV>::
00488                         post(home,x,c,b)));
00489         break;
00490       case RM_IMP:
00491         GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,CtrlView,RM_IMP>::
00492                         post(home,x,c,b)));
00493         break;
00494       case RM_PMI:
00495         GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,CtrlView,RM_PMI>::
00496                         post(home,x,c,b)));
00497         break;
00498       default: GECODE_NEVER;
00499       }
00500     } else {
00501       switch (rm) {
00502       case RM_EQV:
00503         GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,CtrlView,RM_EQV>::
00504                         post(home,x,c,b)));
00505         break;
00506       case RM_IMP:
00507         GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,CtrlView,RM_IMP>::
00508                         post(home,x,c,b)));
00509         break;
00510       case RM_PMI:
00511         GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,CtrlView,RM_PMI>::
00512                         post(home,x,c,b)));
00513         break;
00514       default: GECODE_NEVER;
00515       }
00516     }
00517   }
00518 
00519   void
00520   post(Home home,
00521        Term<IntView>* t, int n, IntRelType irt, int c, Reify r,
00522        IntConLevel icl) {
00523     Limits::check(c,"Int::linear");
00524     long long int d = c;
00525 
00526     eliminate(t,n,d);
00527 
00528     Term<IntView> *t_p, *t_n;
00529     int n_p, n_n, gcd=1;
00530     bool is_unit = normalize<IntView>(t,n,t_p,n_p,t_n,n_n,gcd);
00531 
00532     rewrite(irt,d,t_p,n_p,t_n,n_n);
00533 
00534     // Divide by gcd
00535     if (gcd > 1) {
00536       switch (irt) {
00537       case IRT_EQ:
00538         if ((d % gcd) != 0) {
00539           if (r.mode() != RM_PMI)
00540             GECODE_ME_FAIL(BoolView(r.var()).zero(home));
00541           return;
00542         }
00543         d /= gcd;
00544         break;
00545       case IRT_NQ: 
00546         if ((d % gcd) != 0) {
00547           if (r.mode() != RM_IMP)
00548             GECODE_ME_FAIL(BoolView(r.var()).one(home));
00549           return;
00550         }
00551         d /= gcd;
00552         break;
00553       case IRT_LQ:
00554         d = floor_div_xp(d,static_cast<long long int>(gcd));
00555         break;
00556       default: GECODE_NEVER;
00557       }
00558     }
00559 
00560     if (n == 0) {
00561       bool fail = false;
00562       switch (irt) {
00563       case IRT_EQ: fail = (d != 0); break;
00564       case IRT_NQ: fail = (d == 0); break;
00565       case IRT_LQ: fail = (0 > d); break;
00566       default: GECODE_NEVER;
00567       }
00568       if (fail) {
00569         if (r.mode() != RM_PMI)
00570           GECODE_ME_FAIL(BoolView(r.var()).zero(home));
00571       } else {
00572         if (r.mode() != RM_IMP)
00573           GECODE_ME_FAIL(BoolView(r.var()).one(home));
00574       }
00575       return;
00576     }
00577 
00578     bool is_ip = precision(t_p,n_p,t_n,n_n,d);
00579 
00580     if (is_unit && is_ip) {
00581       c = static_cast<int>(d);
00582       if (n == 1) {
00583         switch (irt) {
00584         case IRT_EQ:
00585           if (n_p == 1) {
00586             posteqint<BoolView>(home,t_p[0].x,c,r.var(),r.mode(),icl);
00587           } else {
00588             posteqint<BoolView>(home,t_p[0].x,-c,r.var(),r.mode(),icl);
00589           }
00590           break;
00591         case IRT_NQ:
00592           {
00593             NegBoolView nb(r.var());
00594             ReifyMode rm = r.mode();
00595             switch (rm) {
00596             case RM_IMP: rm = RM_PMI; break;
00597             case RM_PMI: rm = RM_IMP; break;
00598             default: ;
00599             }
00600             if (n_p == 1) {
00601               posteqint<NegBoolView>(home,t_p[0].x,c,nb,rm,icl);
00602             } else {
00603               posteqint<NegBoolView>(home,t_p[0].x,-c,nb,rm,icl);
00604             }
00605           }
00606           break;
00607         case IRT_LQ:
00608           if (n_p == 1) {
00609             switch (r.mode()) {
00610             case RM_EQV:
00611               GECODE_ES_FAIL((Rel::ReLqInt<IntView,BoolView,RM_EQV>::
00612                               post(home,t_p[0].x,c,r.var())));
00613               break;
00614             case RM_IMP:
00615               GECODE_ES_FAIL((Rel::ReLqInt<IntView,BoolView,RM_IMP>::
00616                               post(home,t_p[0].x,c,r.var())));
00617               break;
00618             case RM_PMI:
00619               GECODE_ES_FAIL((Rel::ReLqInt<IntView,BoolView,RM_PMI>::
00620                               post(home,t_p[0].x,c,r.var())));
00621               break;
00622             default: GECODE_NEVER;
00623             }
00624           } else {
00625             NegBoolView nb(r.var());
00626             switch (r.mode()) {
00627             case RM_EQV:
00628               GECODE_ES_FAIL((Rel::ReLqInt<IntView,NegBoolView,RM_EQV>::
00629                               post(home,t_n[0].x,-c-1,nb)));
00630               break;
00631             case RM_IMP:
00632               GECODE_ES_FAIL((Rel::ReLqInt<IntView,NegBoolView,RM_PMI>::
00633                               post(home,t_n[0].x,-c-1,nb)));
00634               break;
00635             case RM_PMI:
00636               GECODE_ES_FAIL((Rel::ReLqInt<IntView,NegBoolView,RM_IMP>::
00637                               post(home,t_n[0].x,-c-1,nb)));
00638               break;
00639             default: GECODE_NEVER;
00640             }
00641           }
00642           break;
00643         default: GECODE_NEVER;
00644         }
00645       } else if (n == 2) {
00646         switch (irt) {
00647         case IRT_EQ:
00648           switch (n_p) {
00649           case 2:
00650             switch (r.mode()) {
00651             case RM_EQV:
00652               GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,BoolView,RM_EQV>::
00653                               post(home,t_p[0].x,t_p[1].x,c,r.var())));
00654               break;
00655             case RM_IMP:
00656               GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,BoolView,RM_IMP>::
00657                               post(home,t_p[0].x,t_p[1].x,c,r.var())));
00658               break;
00659             case RM_PMI:
00660               GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,BoolView,RM_PMI>::
00661                               post(home,t_p[0].x,t_p[1].x,c,r.var())));
00662               break;
00663             default: GECODE_NEVER;
00664             }
00665             break;
00666           case 1:
00667             switch (r.mode()) {
00668             case RM_EQV:
00669               GECODE_ES_FAIL((ReEqBin<int,IntView,MinusView,BoolView,RM_EQV>::
00670                               post(home,t_p[0].x,MinusView(t_n[0].x),c,
00671                                    r.var())));
00672               break;
00673             case RM_IMP:
00674               GECODE_ES_FAIL((ReEqBin<int,IntView,MinusView,BoolView,RM_IMP>::
00675                               post(home,t_p[0].x,MinusView(t_n[0].x),c,
00676                                    r.var())));
00677               break;
00678             case RM_PMI:
00679               GECODE_ES_FAIL((ReEqBin<int,IntView,MinusView,BoolView,RM_PMI>::
00680                               post(home,t_p[0].x,MinusView(t_n[0].x),c,
00681                                    r.var())));
00682               break;
00683             default: GECODE_NEVER;
00684             }
00685             break;
00686           case 0:
00687             switch (r.mode()) {
00688             case RM_EQV:
00689               GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,BoolView,RM_EQV>::
00690                               post(home,t_n[0].x,t_n[1].x,-c,r.var())));
00691               break;
00692             case RM_IMP:
00693               GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,BoolView,RM_IMP>::
00694                               post(home,t_n[0].x,t_n[1].x,-c,r.var())));
00695               break;
00696             case RM_PMI:
00697               GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,BoolView,RM_PMI>::
00698                               post(home,t_n[0].x,t_n[1].x,-c,r.var())));
00699               break;
00700             default: GECODE_NEVER;
00701             }
00702             break;
00703           default: GECODE_NEVER;
00704           }
00705           break;
00706         case IRT_NQ:
00707           {
00708             NegBoolView nb(r.var());
00709             switch (n_p) {
00710             case 2:
00711               switch (r.mode()) {
00712               case RM_EQV:
00713                 GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,NegBoolView,RM_EQV>::
00714                                 post(home,t_p[0].x,t_p[1].x,c,nb)));
00715                 break;
00716               case RM_IMP:
00717                 GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,NegBoolView,RM_PMI>::
00718                                 post(home,t_p[0].x,t_p[1].x,c,nb)));
00719                 break;
00720               case RM_PMI:
00721                 GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,NegBoolView,RM_IMP>::
00722                                 post(home,t_p[0].x,t_p[1].x,c,nb)));
00723                 break;
00724               default: GECODE_NEVER;
00725               }
00726               break;
00727             case 1:
00728               switch (r.mode()) {
00729               case RM_EQV:
00730                 GECODE_ES_FAIL((ReEqBin<int,IntView,MinusView,NegBoolView,RM_EQV>::
00731                                 post(home,t_p[0].x,MinusView(t_n[0].x),c,nb)));
00732                 break;
00733               case RM_IMP:
00734                 GECODE_ES_FAIL((ReEqBin<int,IntView,MinusView,NegBoolView,RM_PMI>::
00735                                 post(home,t_p[0].x,MinusView(t_n[0].x),c,nb)));
00736                 break;
00737               case RM_PMI:
00738                 GECODE_ES_FAIL((ReEqBin<int,IntView,MinusView,NegBoolView,RM_IMP>::
00739                                 post(home,t_p[0].x,MinusView(t_n[0].x),c,nb)));
00740                 break;
00741               default: GECODE_NEVER;
00742               }
00743               break;
00744             case 0:
00745               switch (r.mode()) {
00746               case RM_EQV:
00747                 GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,NegBoolView,RM_EQV>::
00748                                 post(home,t_p[0].x,t_p[1].x,-c,nb)));
00749                 break;
00750               case RM_IMP:
00751                 GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,NegBoolView,RM_PMI>::
00752                                 post(home,t_p[0].x,t_p[1].x,-c,nb)));
00753                 break;
00754               case RM_PMI:
00755                 GECODE_ES_FAIL((ReEqBin<int,IntView,IntView,NegBoolView,RM_IMP>::
00756                                 post(home,t_p[0].x,t_p[1].x,-c,nb)));
00757                 break;
00758               default: GECODE_NEVER;
00759               }
00760               break;
00761             default: GECODE_NEVER;
00762             }
00763           }
00764           break;
00765         case IRT_LQ:
00766           switch (n_p) {
00767           case 2:
00768             switch (r.mode()) {
00769             case RM_EQV:
00770               GECODE_ES_FAIL((ReLqBin<int,IntView,IntView,RM_EQV>::
00771                               post(home,t_p[0].x,t_p[1].x,c,r.var())));
00772               break;
00773             case RM_IMP:
00774               GECODE_ES_FAIL((ReLqBin<int,IntView,IntView,RM_IMP>::
00775                               post(home,t_p[0].x,t_p[1].x,c,r.var())));
00776               break;
00777             case RM_PMI:
00778               GECODE_ES_FAIL((ReLqBin<int,IntView,IntView,RM_PMI>::
00779                               post(home,t_p[0].x,t_p[1].x,c,r.var())));
00780               break;
00781             default: GECODE_NEVER;
00782             }
00783             break;
00784           case 1:
00785             switch (r.mode()) {
00786             case RM_EQV:
00787               GECODE_ES_FAIL((ReLqBin<int,IntView,MinusView,RM_EQV>::
00788                               post(home,t_p[0].x,MinusView(t_n[0].x),c,
00789                                    r.var())));
00790               break;
00791             case RM_IMP:
00792               GECODE_ES_FAIL((ReLqBin<int,IntView,MinusView,RM_IMP>::
00793                               post(home,t_p[0].x,MinusView(t_n[0].x),c,
00794                                    r.var())));
00795               break;
00796             case RM_PMI:
00797               GECODE_ES_FAIL((ReLqBin<int,IntView,MinusView,RM_PMI>::
00798                               post(home,t_p[0].x,MinusView(t_n[0].x),c,
00799                                    r.var())));
00800               break;
00801             default: GECODE_NEVER;
00802             }
00803             break;
00804           case 0:
00805             switch (r.mode()) {
00806             case RM_EQV:
00807               GECODE_ES_FAIL((ReLqBin<int,MinusView,MinusView,RM_EQV>::
00808                               post(home,MinusView(t_n[0].x),
00809                                    MinusView(t_n[1].x),c,r.var())));
00810               break;
00811             case RM_IMP:
00812               GECODE_ES_FAIL((ReLqBin<int,MinusView,MinusView,RM_IMP>::
00813                               post(home,MinusView(t_n[0].x),
00814                                    MinusView(t_n[1].x),c,r.var())));
00815               break;
00816             case RM_PMI:
00817               GECODE_ES_FAIL((ReLqBin<int,MinusView,MinusView,RM_PMI>::
00818                               post(home,MinusView(t_n[0].x),
00819                                    MinusView(t_n[1].x),c,r.var())));
00820               break;
00821             default: GECODE_NEVER;
00822             }
00823             break;
00824           default: GECODE_NEVER;
00825           }
00826           break;
00827         default: GECODE_NEVER;
00828         }
00829       } else {
00830         ViewArray<IntView> x(home,n_p);
00831         for (int i = n_p; i--; )
00832           x[i] = t_p[i].x;
00833         ViewArray<IntView> y(home,n_n);
00834         for (int i = n_n; i--; )
00835           y[i] = t_n[i].x;
00836         post_nary<int,IntView>(home,x,y,irt,c,r);
00837       }
00838     } else if (is_ip) {
00839       // Arbitrary coefficients with integer precision
00840       c = static_cast<int>(d);
00841       ViewArray<IntScaleView> x(home,n_p);
00842       for (int i = n_p; i--; )
00843         x[i] = IntScaleView(t_p[i].a,t_p[i].x);
00844       ViewArray<IntScaleView> y(home,n_n);
00845       for (int i = n_n; i--; )
00846         y[i] = IntScaleView(t_n[i].a,t_n[i].x);
00847       post_nary<int,IntScaleView>(home,x,y,irt,c,r);
00848     } else {
00849       // Arbitrary coefficients with long long precision
00850       ViewArray<LLongScaleView> x(home,n_p);
00851       for (int i = n_p; i--; )
00852         x[i] = LLongScaleView(t_p[i].a,t_p[i].x);
00853       ViewArray<LLongScaleView> y(home,n_n);
00854       for (int i = n_n; i--; )
00855         y[i] = LLongScaleView(t_n[i].a,t_n[i].x);
00856       post_nary<long long int,LLongScaleView>(home,x,y,irt,d,r);
00857     }
00858   }
00859 
00860 }}}
00861 
00862 // STATISTICS: int-post