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

bool.cc

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: 2008-07-11 09:33:32 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00011  *     $Revision: 7290 $
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/int/bool.hh"
00039 #include "gecode/int/rel.hh"
00040 
00041 namespace Gecode {
00042 
00043   namespace {
00044 
00045     forceinline void
00046     post_and(Space* home, BoolVar x0, BoolVar x1, BoolVar x2) {
00047       using namespace Int;
00048       NegBoolView n0(x0); NegBoolView n1(x1); NegBoolView n2(x2);
00049       GECODE_ES_FAIL(home,(Bool::Or<NegBoolView,NegBoolView,NegBoolView>
00050                            ::post(home,n0,n1,n2)));
00051     }
00052     forceinline void
00053     post_or(Space* home, BoolVar x0, BoolVar x1, BoolVar x2) {
00054       using namespace Int;
00055       GECODE_ES_FAIL(home,(Bool::Or<BoolView,BoolView,BoolView>
00056                            ::post(home,x0,x1,x2)));
00057     }
00058     forceinline void
00059     post_imp(Space* home, BoolVar x0, BoolVar x1, BoolVar x2) {
00060       using namespace Int;
00061       NegBoolView n0(x0);
00062       GECODE_ES_FAIL(home,(Bool::Or<NegBoolView,BoolView,BoolView>
00063                            ::post(home,n0,x1,x2)));
00064     }
00065     forceinline void
00066     post_eqv(Space* home, BoolVar x0, BoolVar x1, BoolVar x2) {
00067       using namespace Int;
00068       GECODE_ES_FAIL(home,(Bool::Eqv<BoolView,BoolView,BoolView>
00069                            ::post(home,x0,x1,x2)));
00070     }
00071     forceinline void
00072     post_xor(Space* home, BoolVar x0, BoolVar x1, BoolVar x2) {
00073       using namespace Int;
00074       NegBoolView n2(x2);
00075       GECODE_ES_FAIL(home,(Bool::Eqv<BoolView,BoolView,NegBoolView>
00076                            ::post(home,x0,x1,n2)));
00077     }
00078 
00079   }
00080 
00081   void
00082   rel(Space* home, BoolVar x0, IntRelType r, BoolVar x1, 
00083       IntConLevel, PropKind) {
00084     using namespace Int;
00085     if (home->failed()) return;
00086     switch (r) {
00087     case IRT_EQ:
00088       GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00089                            ::post(home,x0,x1)));
00090       break;
00091     case IRT_NQ: 
00092       {
00093         NegBoolView n1(x1);
00094         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,NegBoolView>
00095                              ::post(home,x0,n1)));
00096       }
00097       break;
00098     case IRT_GQ:
00099       GECODE_ES_FAIL(home,Bool::Lq<BoolView>::post(home,x1,x0)); 
00100       break;
00101     case IRT_LQ:
00102       GECODE_ES_FAIL(home,Bool::Lq<BoolView>::post(home,x0,x1)); 
00103       break;
00104     case IRT_GR:
00105       GECODE_ES_FAIL(home,Bool::Le<BoolView>::post(home,x1,x0)); 
00106       break;
00107     case IRT_LE:
00108       GECODE_ES_FAIL(home,Bool::Le<BoolView>::post(home,x0,x1)); 
00109       break;
00110     default:
00111       throw UnknownRelation("Int::rel");
00112     }
00113   }
00114 
00115   void
00116   rel(Space* home, BoolVar x0, IntRelType r, int n, IntConLevel, PropKind) {
00117     using namespace Int;
00118     if (home->failed()) return;
00119     BoolView x(x0);
00120     if (n == 0) {
00121       switch (r) {
00122       case IRT_LQ:
00123       case IRT_EQ:
00124         GECODE_ME_FAIL(home,x.zero(home)); break;
00125       case IRT_NQ:
00126       case IRT_GR:
00127         GECODE_ME_FAIL(home,x.one(home)); break;
00128       case IRT_LE:
00129         home->fail(); break;
00130       case IRT_GQ:
00131         break;
00132       default:
00133         throw UnknownRelation("Int::rel");
00134       }
00135     } else if (n == 1) {
00136       switch (r) {
00137       case IRT_GQ:
00138       case IRT_EQ:
00139         GECODE_ME_FAIL(home,x.one(home)); break;
00140       case IRT_NQ:
00141       case IRT_LE:
00142         GECODE_ME_FAIL(home,x.zero(home)); break;
00143       case IRT_GR:
00144         home->fail(); break;
00145       case IRT_LQ:
00146         break;
00147       default:
00148         throw UnknownRelation("Int::rel");
00149       }
00150     } else {
00151       throw NotZeroOne("Int::rel");
00152     }
00153   }
00154 
00155   void
00156   rel(Space* home, BoolVar x0, IntRelType r, BoolVar x1, BoolVar b,
00157       IntConLevel, PropKind) {
00158     using namespace Int;
00159     if (home->failed()) return;
00160     switch (r) {
00161     case IRT_EQ:
00162       GECODE_ES_FAIL(home,(Bool::Eqv<BoolView,BoolView,BoolView>
00163                            ::post(home,x0,x1,b)));
00164       break;
00165     case IRT_NQ: 
00166       {
00167         NegBoolView n(b);
00168         GECODE_ES_FAIL(home,(Bool::Eqv<BoolView,BoolView,NegBoolView>
00169                              ::post(home,x0,x1,n)));
00170       }
00171       break;
00172     case IRT_GQ:
00173       std::swap(x0,x1);
00174     case IRT_LQ:
00175       {
00176         NegBoolView n0(x0);
00177         GECODE_ES_FAIL(home,(Bool::Or<NegBoolView,BoolView,BoolView>
00178                              ::post(home,n0,x1,b))); 
00179       }
00180       break;
00181     case IRT_GR:
00182       std::swap(x0,x1);
00183     case IRT_LE:
00184       {
00185         NegBoolView n1(x1), n(b);
00186         GECODE_ES_FAIL(home,(Bool::Or<BoolView,NegBoolView,NegBoolView>
00187                              ::post(home,x0,n1,n))); 
00188       }
00189       break;
00190     default:
00191       throw UnknownRelation("Int::rel");
00192     }
00193   }
00194 
00195   void
00196   rel(Space* home, BoolVar x0, IntRelType r, int n, BoolVar b,
00197       IntConLevel, PropKind) {
00198     using namespace Int;
00199     if (home->failed()) return;
00200     BoolView x(x0);
00201     BoolView y(b);
00202     if (n == 0) {
00203       switch (r) {
00204       case IRT_LQ:
00205       case IRT_EQ:
00206         {
00207           NegBoolView z(y);
00208           GECODE_ES_FAIL(home,(Bool::Eq<BoolView,NegBoolView>
00209                                ::post(home,x,z)));
00210         }
00211         break;
00212       case IRT_NQ:
00213       case IRT_GR:
00214         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00215                              ::post(home,x,y)));
00216         break;
00217       case IRT_LE:
00218         GECODE_ME_FAIL(home,y.zero(home)); 
00219         break;
00220       case IRT_GQ:
00221         GECODE_ME_FAIL(home,y.one(home)); 
00222         break;
00223       default:
00224         throw UnknownRelation("Int::rel");
00225       }
00226     } else if (n == 1) {
00227       switch (r) {
00228       case IRT_GQ:
00229       case IRT_EQ:
00230         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00231                              ::post(home,x,y)));
00232         break;
00233       case IRT_NQ:
00234       case IRT_LE:
00235         {
00236           NegBoolView z(y);
00237           GECODE_ES_FAIL(home,(Bool::Eq<BoolView,NegBoolView>
00238                                ::post(home,x,z)));
00239         }
00240         break;
00241       case IRT_GR:
00242         GECODE_ME_FAIL(home,y.zero(home)); 
00243         break;
00244       case IRT_LQ:
00245         GECODE_ME_FAIL(home,y.one(home)); 
00246         break;
00247       default:
00248         throw UnknownRelation("Int::rel");
00249       }
00250     } else {
00251       throw NotZeroOne("Int::rel");
00252     }
00253   }
00254 
00255   void
00256   rel(Space* home, const BoolVarArgs& x, IntRelType r, BoolVar y, 
00257       IntConLevel, PropKind) {
00258     using namespace Int;
00259     if (home->failed()) return;
00260     switch (r) {
00261     case IRT_EQ:
00262       for (int i=x.size(); i--; ) {
00263         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00264                              ::post(home,x[i],y)));
00265       }
00266       break;
00267     case IRT_NQ: 
00268       {
00269         NegBoolView n(y);
00270         for (int i=x.size(); i--; ) {
00271           GECODE_ES_FAIL(home,(Bool::Eq<BoolView,NegBoolView>
00272                                ::post(home,x[i],n)));
00273         }
00274       }
00275       break;
00276     case IRT_GQ:
00277       for (int i=x.size(); i--; ) {
00278         GECODE_ES_FAIL(home,Bool::Lq<BoolView>::post(home,y,x[i])); 
00279       }
00280       break;
00281     case IRT_LQ:
00282       for (int i=x.size(); i--; ) {
00283         GECODE_ES_FAIL(home,Bool::Lq<BoolView>::post(home,x[i],y)); 
00284       }
00285       break;
00286     case IRT_GR:
00287       for (int i=x.size(); i--; ) {
00288         GECODE_ES_FAIL(home,Bool::Le<BoolView>::post(home,y,x[i])); 
00289       }
00290       break;
00291     case IRT_LE:
00292       for (int i=x.size(); i--; ) {
00293         GECODE_ES_FAIL(home,Bool::Le<BoolView>::post(home,x[i],y)); 
00294       }
00295       break;
00296     default:
00297       throw UnknownRelation("Int::rel");
00298     }
00299   }
00300 
00301   void
00302   rel(Space* home, const BoolVarArgs& x, IntRelType r, int n, 
00303       IntConLevel, PropKind) {
00304     using namespace Int;
00305     if (home->failed()) return;
00306     if (n == 0) {
00307       switch (r) {
00308       case IRT_LQ:
00309       case IRT_EQ:
00310         for (int i=x.size(); i--; ) {
00311           BoolView xi(x[i]); GECODE_ME_FAIL(home,xi.zero(home)); 
00312         }
00313         break;
00314       case IRT_NQ:
00315       case IRT_GR:
00316         for (int i=x.size(); i--; ) {
00317           BoolView xi(x[i]); GECODE_ME_FAIL(home,xi.one(home)); 
00318         }
00319         break;
00320       case IRT_LE:
00321         home->fail(); break;
00322       case IRT_GQ:
00323         break;
00324       default:
00325         throw UnknownRelation("Int::rel");
00326       }
00327     } else if (n == 1) {
00328       switch (r) {
00329       case IRT_GQ:
00330       case IRT_EQ:
00331         for (int i=x.size(); i--; ) {
00332           BoolView xi(x[i]); GECODE_ME_FAIL(home,xi.one(home)); 
00333         }
00334         break;
00335       case IRT_NQ:
00336       case IRT_LE:
00337         for (int i=x.size(); i--; ) {
00338           BoolView xi(x[i]); GECODE_ME_FAIL(home,xi.zero(home)); 
00339         }
00340         break;
00341       case IRT_GR:
00342         home->fail(); break;
00343       case IRT_LQ:
00344         break;
00345       default:
00346         throw UnknownRelation("Int::rel");
00347       }
00348     } else {
00349       throw NotZeroOne("Int::rel");
00350     }
00351   }
00352 
00353   void
00354   rel(Space* home, const BoolVarArgs& x, IntRelType r, IntConLevel, PropKind) {
00355     using namespace Int;
00356     if (home->failed() || (x.size() < 2)) return;
00357     switch (r) {
00358     case IRT_EQ:
00359       for (int i=x.size()-1; i--; )
00360         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00361                              ::post(home,x[i],x[i+1])));
00362       break;
00363     case IRT_NQ:
00364       if (x.size() == 2) {
00365         NegBoolView n(x[1]);
00366         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,NegBoolView>
00367                              ::post(home,x[0],n)));
00368       } else {
00369         home->fail();
00370       }
00371       break;
00372     case IRT_LE:
00373       if (x.size() == 2) {
00374         GECODE_ES_FAIL(home,Bool::Le<BoolView>::post(home,x[0],x[1]));
00375       } else {
00376         home->fail();
00377       }
00378       break;
00379     case IRT_LQ:
00380       for (int i=x.size()-1; i--; )
00381         GECODE_ES_FAIL(home,Bool::Lq<BoolView>::post(home,x[i],x[i+1]));
00382       break;
00383     case IRT_GR:
00384       if (x.size() == 2) {
00385         GECODE_ES_FAIL(home,Bool::Le<BoolView>::post(home,x[1],x[0]));
00386       } else {
00387         home->fail();
00388       }
00389       break;
00390     case IRT_GQ:
00391       for (int i=x.size()-1; i--; )
00392         GECODE_ES_FAIL(home,Bool::Lq<BoolView>::post(home,x[i+1],x[i]));
00393       break;
00394     default:
00395       throw UnknownRelation("Int::rel");
00396     }
00397   }
00398 
00399   void
00400   rel(Space* home, const BoolVarArgs& x, IntRelType r, const BoolVarArgs& y,
00401       IntConLevel, PropKind) {
00402     using namespace Int;
00403     if (x.size() != y.size())
00404       throw ArgumentSizeMismatch("Int::rel");
00405     if (home->failed()) return;
00406 
00407     switch (r) {
00408     case IRT_GR: 
00409       {
00410         ViewArray<BoolView> xv(home,x), yv(home,y);
00411         GECODE_ES_FAIL(home,Rel::Lex<BoolView>::post(home,yv,xv,true));
00412       }
00413       break;
00414     case IRT_LE: 
00415       {
00416         ViewArray<BoolView> xv(home,x), yv(home,y);
00417         GECODE_ES_FAIL(home,Rel::Lex<BoolView>::post(home,xv,yv,true));
00418       }
00419       break;
00420     case IRT_GQ: 
00421       {
00422         ViewArray<BoolView> xv(home,x), yv(home,y);
00423         GECODE_ES_FAIL(home,Rel::Lex<BoolView>::post(home,yv,xv,false));
00424       }
00425       break;
00426     case IRT_LQ: 
00427       {
00428         ViewArray<BoolView> xv(home,x), yv(home,y);
00429         GECODE_ES_FAIL(home,Rel::Lex<BoolView>::post(home,xv,yv,false));
00430       }
00431       break;
00432     case IRT_EQ:
00433       for (int i=x.size(); i--; ) {
00434         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00435                              ::post(home,x[i],y[i])));
00436       }
00437       break;
00438     case IRT_NQ: 
00439       {
00440         ViewArray<BoolView> b(home,x.size());
00441         for (int i=x.size(); i--; ) {
00442           BoolVar bi(home,0,1); b[i]=bi;
00443           NegBoolView n(b[i]);
00444           GECODE_ES_FAIL(home,(Bool::Eqv<BoolView,BoolView,NegBoolView>
00445                                ::post(home,x[i],y[i],n)));
00446         }
00447         GECODE_ES_FAIL(home,Bool::NaryOrTrue<BoolView>::post(home,b));
00448       }
00449       break;
00450     default:
00451       throw UnknownRelation("Int::rel");
00452     }
00453   }
00454 
00455   void
00456   rel(Space* home, BoolVar x0, BoolOpType o, BoolVar x1, BoolVar x2, 
00457       IntConLevel, PropKind) {
00458     using namespace Int;
00459     if (home->failed()) return;
00460     switch (o) {
00461     case BOT_AND: post_and(home,x0,x1,x2); break;
00462     case BOT_OR:  post_or(home,x0,x1,x2); break;
00463     case BOT_IMP: post_imp(home,x0,x1,x2); break;
00464     case BOT_EQV: post_eqv(home,x0,x1,x2); break;
00465     case BOT_XOR: post_xor(home,x0,x1,x2); break;
00466     default: throw UnknownBoolOp("Int::rel");
00467     }
00468   }
00469 
00470   void
00471   rel(Space* home, BoolVar x0, BoolOpType o, BoolVar x1, int n, 
00472       IntConLevel, PropKind) {
00473     using namespace Int;
00474     if (home->failed()) return;
00475     if (n == 0) {
00476       switch (o) {
00477       case BOT_AND:
00478         {
00479           NegBoolView n0(x0); NegBoolView n1(x1);
00480           GECODE_ES_FAIL(home,(Bool::BinOrTrue<NegBoolView,NegBoolView>
00481                                ::post(home,n0,n1)));
00482         }
00483         break;
00484       case BOT_OR:
00485         {
00486           BoolView b0(x0); BoolView b1(x1);
00487           GECODE_ME_FAIL(home,b0.zero(home));
00488           GECODE_ME_FAIL(home,b1.zero(home));
00489         }
00490         break;
00491       case BOT_IMP:
00492         {
00493           BoolView b0(x0); BoolView b1(x1);
00494           GECODE_ME_FAIL(home,b0.one(home));
00495           GECODE_ME_FAIL(home,b1.zero(home));
00496         }
00497         break;
00498       case BOT_EQV:
00499         {
00500           NegBoolView n0(x0);
00501           GECODE_ES_FAIL(home,(Bool::Eq<NegBoolView,BoolView>
00502                                ::post(home,n0,x1)));
00503         }
00504         break;
00505       case BOT_XOR:
00506         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00507                              ::post(home,x0,x1)));
00508         break;
00509       default:
00510         throw UnknownBoolOp("Int::rel");
00511       }
00512     } else if (n == 1) {
00513       switch (o) {
00514       case BOT_AND:
00515         {
00516           BoolView b0(x0); BoolView b1(x1);
00517           GECODE_ME_FAIL(home,b0.one(home));
00518           GECODE_ME_FAIL(home,b1.one(home));
00519         }
00520         break;
00521       case BOT_OR:
00522         GECODE_ES_FAIL(home,(Bool::BinOrTrue<BoolView,BoolView>
00523                              ::post(home,x0,x1)));
00524         break;
00525       case BOT_IMP:
00526         {
00527           NegBoolView n0(x0);
00528           GECODE_ES_FAIL(home,(Bool::BinOrTrue<NegBoolView,BoolView>
00529                                ::post(home,n0,x1)));
00530         }
00531         break;
00532       case BOT_EQV:
00533         GECODE_ES_FAIL(home,(Bool::Eq<BoolView,BoolView>
00534                              ::post(home,x0,x1)));
00535         break;
00536       case BOT_XOR:
00537         {
00538           NegBoolView n0(x0);
00539           GECODE_ES_FAIL(home,(Bool::Eq<NegBoolView,BoolView>
00540                                ::post(home,n0,x1)));
00541         }
00542         break;
00543       default:
00544         throw UnknownBoolOp("Int::rel");
00545       }
00546     } else {
00547       throw NotZeroOne("Int::rel");
00548     }
00549   }
00550 
00551   void
00552   rel(Space* home, BoolOpType o, const BoolVarArgs& x, BoolVar y, 
00553       IntConLevel, PropKind) {
00554     using namespace Int;
00555     if (home->failed()) return;
00556     int m = x.size();
00557     switch (o) {
00558     case BOT_AND:
00559       {
00560         ViewArray<NegBoolView> b(home,m);
00561         for (int i=m; i--; ) {
00562           NegBoolView nb(x[i]); b[i]=nb;
00563         }
00564         NegBoolView ny(y);
00565         b.unique();
00566         GECODE_ES_FAIL(home,Bool::NaryOr<NegBoolView>::post(home,b,ny));
00567       }
00568       break;
00569     case BOT_OR:
00570       {
00571         ViewArray<BoolView> b(home,x);
00572         b.unique();
00573         GECODE_ES_FAIL(home,Bool::NaryOr<BoolView>::post(home,b,y));
00574       }
00575       break;
00576     case BOT_IMP:
00577       if (m < 2) {
00578         throw TooFewArguments("Int::rel");
00579       } else {
00580         GECODE_AUTOARRAY(BoolVar,z,m);
00581         z[0]=x[0]; z[m-1]=y;
00582         for (int i=1; i<m-1; i++)
00583           z[i].init(home,0,1);
00584         for (int i=1; i<m; i++)
00585           post_imp(home,z[i-1],x[i],z[i]);
00586       }
00587       break;
00588     case BOT_EQV:
00589       if (m < 2) {
00590         throw TooFewArguments("Int::rel");
00591       } else {
00592         GECODE_AUTOARRAY(BoolVar,z,m);
00593         z[0]=x[0]; z[m-1]=y;
00594         for (int i=1; i<m-1; i++)
00595           z[i].init(home,0,1);
00596         for (int i=1; i<m; i++)
00597           post_eqv(home,z[i-1],x[i],z[i]);
00598       }
00599       break;
00600     case BOT_XOR:
00601       if (m < 2) {
00602         throw TooFewArguments("Int::rel");
00603       } else {
00604         GECODE_AUTOARRAY(BoolVar,z,m);
00605         z[0]=x[0]; z[m-1]=y;
00606         for (int i=1; i<m-1; i++)
00607           z[i].init(home,0,1);
00608         for (int i=1; i<m; i++)
00609           post_xor(home,z[i-1],x[i],z[i]);
00610       }
00611       break;
00612     default:
00613       throw UnknownBoolOp("Int::rel");
00614     }
00615   }
00616 
00617   void
00618   rel(Space* home, BoolOpType o, const BoolVarArgs& x, int n, 
00619       IntConLevel, PropKind) {
00620     using namespace Int;
00621     if ((n < 0) || (n > 1))
00622       throw NotZeroOne("Int::rel");
00623     if (home->failed()) return;
00624     int m = x.size();
00625     switch (o) {
00626     case BOT_AND:
00627       if (n == 0) {
00628         ViewArray<NegBoolView> b(home,m);
00629         for (int i=m; i--; ) {
00630           NegBoolView nb(x[i]); b[i]=nb;
00631         }
00632         b.unique();
00633         GECODE_ES_FAIL(home,Bool::NaryOrTrue<NegBoolView>::post(home,b));
00634       } else {
00635         for (int i=m; i--; ) {
00636           BoolView b(x[i]); GECODE_ME_FAIL(home,b.one(home));
00637         }
00638       }
00639       break;
00640     case BOT_OR:
00641       if (n == 0) {
00642         for (int i=m; i--; ) {
00643           BoolView b(x[i]); GECODE_ME_FAIL(home,b.zero(home));
00644         }
00645       } else {
00646         ViewArray<BoolView> b(home,x);
00647         b.unique();
00648         GECODE_ES_FAIL(home,Bool::NaryOrTrue<BoolView>::post(home,b));
00649       }
00650       break;
00651     case BOT_IMP:
00652       if (m < 2) {
00653         throw TooFewArguments("Int::rel");
00654       } else {
00655         GECODE_AUTOARRAY(BoolVar,z,m);
00656         z[0]=x[0]; z[m-1].init(home,n,n);;
00657         for (int i=1; i<m-1; i++)
00658           z[i].init(home,0,1);
00659         for (int i=1; i<m; i++)
00660           post_imp(home,z[i-1],x[i],z[i]);
00661       }
00662       break;
00663     case BOT_EQV:
00664       if (m < 2) {
00665         throw TooFewArguments("Int::rel");
00666       } else {
00667         GECODE_AUTOARRAY(BoolVar,z,m);
00668         z[0]=x[0]; z[m-1].init(home,n,n);
00669         for (int i=1; i<m-1; i++)
00670           z[i].init(home,0,1);
00671         for (int i=1; i<m; i++)
00672           post_eqv(home,z[i-1],x[i],z[i]);
00673       }
00674       break;
00675     case BOT_XOR:
00676       if (m < 2) {
00677         throw TooFewArguments("Int::rel");
00678       } else {
00679         GECODE_AUTOARRAY(BoolVar,z,m);
00680         z[0]=x[0]; z[m-1].init(home,n,n);
00681         for (int i=1; i<m-1; i++)
00682           z[i].init(home,0,1);
00683         for (int i=1; i<m; i++)
00684           post_xor(home,z[i-1],x[i],z[i]);
00685       }
00686       break;
00687     default:
00688       throw UnknownBoolOp("Int::rel");
00689     }
00690   }
00691 
00692   namespace {
00693     using namespace Int;
00694     GECODE_REGISTER2(Bool::BinOrTrue<NegBoolView, BoolView>);
00695     GECODE_REGISTER2(Bool::BinOrTrue<NegBoolView, NegBoolView>);
00696     GECODE_REGISTER2(Bool::BinOrTrue<BoolView, BoolView>);
00697     
00698     GECODE_REGISTER2(Bool::Eq<NegBoolView, BoolView>);
00699     GECODE_REGISTER2(Bool::Eq<NegBoolView, NegBoolView>);
00700     GECODE_REGISTER2(Bool::Eq<BoolView, NegBoolView>);
00701     GECODE_REGISTER2(Bool::Eq<BoolView, BoolView>);
00702     GECODE_REGISTER1(Bool::NaryEq<BoolView>);
00703     
00704     GECODE_REGISTER3(Bool::Eqv<BoolView, BoolView, NegBoolView>);
00705     GECODE_REGISTER3(Bool::Eqv<BoolView, BoolView, BoolView>);
00706     
00707     GECODE_REGISTER1(Bool::Lq<BoolView>);
00708     
00709     GECODE_REGISTER1(Bool::NaryOr<NegBoolView>);
00710     GECODE_REGISTER1(Bool::NaryOr<BoolView>);
00711     
00712     GECODE_REGISTER1(Bool::NaryOrTrue<NegBoolView>);
00713     GECODE_REGISTER1(Bool::NaryOrTrue<BoolView>);
00714     
00715     GECODE_REGISTER3(Bool::Or<NegBoolView, BoolView, BoolView>);
00716     GECODE_REGISTER3(Bool::Or<NegBoolView, NegBoolView, NegBoolView>);
00717     GECODE_REGISTER3(Bool::Or<BoolView, BoolView, BoolView>);
00718     GECODE_REGISTER3(Bool::Or<BoolView, NegBoolView, NegBoolView>);
00719     
00720     GECODE_REGISTER1(Bool::OrTrueSubsumed<NegBoolView>);
00721     GECODE_REGISTER1(Bool::OrTrueSubsumed<BoolView>);
00722     
00723     GECODE_REGISTER1(Bool::QuadOrTrue<NegBoolView>);
00724     GECODE_REGISTER1(Bool::QuadOrTrue<BoolView>);
00725     
00726     GECODE_REGISTER1(Bool::TerOrTrue<NegBoolView>);
00727     GECODE_REGISTER1(Bool::TerOrTrue<BoolView>);
00728   }
00729 
00730 }
00731 
00732 
00733 // STATISTICS: int-post
00734