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

ldsb.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christopher Mears <chris.mears@monash.edu>
00005  *
00006  *  Copyright:
00007  *     Christopher Mears, 2012
00008  *
00009  *  Last modified:
00010  *     $Date: 2013-05-15 20:32:39 +0200 (Wed, 15 May 2013) $ by $Author: schulte $
00011  *     $Revision: 13639 $
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/ldsb.hh>
00039 #include <gecode/int/branch.hh>
00040 
00041 #include <map>
00042 
00043 namespace Gecode { namespace Int { namespace LDSB {
00044 
00045   std::pair<int,int>
00046   findVar(int *indices, unsigned int n_values, unsigned int seq_size, int index) {
00047     unsigned int seq = 0;
00048     unsigned int pos = 0;
00049     for (unsigned int i = 0 ; i < n_values ; i++) {
00050       if (indices[i] == index)
00051         return std::pair<int,int>(seq,pos);
00052       pos++;
00053       if (pos == seq_size) {
00054         pos = 0;
00055         seq++;
00056       }
00057     }
00058     return std::pair<int,int>(-1,-1);
00059   }
00060 
00061 }}}
00062 
00063 namespace Gecode {
00064   using namespace Int::LDSB;
00065   
00066   SymmetryHandle VariableSymmetry(const IntVarArgs& vars) {
00067     ArgArray<VarImpBase*> a(vars.size());
00068     for (int i = 0 ; i < vars.size() ; i++)
00069       a[i] = vars[i].varimp();
00070     return SymmetryHandle(new VariableSymmetryObject(a));
00071   }
00072   SymmetryHandle VariableSymmetry(const BoolVarArgs& vars) {
00073     ArgArray<VarImpBase*> a(vars.size());
00074     for (int i = 0 ; i < vars.size() ; i++)
00075       a[i] = vars[i].varimp();
00076     return SymmetryHandle(new VariableSymmetryObject(a));
00077   }
00078   SymmetryHandle VariableSymmetry(const IntVarArgs& x,
00079                                   const IntArgs& indices) {
00080     IntVarArgs xs(indices.size());
00081     for (int i = 0 ; i < indices.size() ; i++)
00082       xs[i] = x[indices[i]];
00083     return VariableSymmetry(xs);
00084   }
00085   SymmetryHandle ValueSymmetry(const IntArgs& vs) {
00086     return SymmetryHandle(new ValueSymmetryObject(IntSet(vs)));
00087   }
00088   SymmetryHandle ValueSymmetry(const IntSet& vs) {
00089     return SymmetryHandle(new ValueSymmetryObject(vs));
00090   }
00091   SymmetryHandle ValueSymmetry(IntVar x) {
00092     return ValueSymmetry(IntSet(x.min(), x.max()));
00093   }
00094   SymmetryHandle VariableSequenceSymmetry(const IntVarArgs& vars, int ss) {
00095     ArgArray<VarImpBase*> a(vars.size());
00096     for (int i = 0 ; i < vars.size() ; i++)
00097       a[i] = vars[i].varimp();
00098     return SymmetryHandle(new VariableSequenceSymmetryObject(a, ss));
00099   }
00100   SymmetryHandle VariableSequenceSymmetry(const BoolVarArgs& vars, int ss) {
00101     ArgArray<VarImpBase*> a(vars.size());
00102     for (int i = 0 ; i < vars.size() ; i++)
00103       a[i] = vars[i].varimp();
00104     return SymmetryHandle(new VariableSequenceSymmetryObject(a, ss));
00105   }
00106   SymmetryHandle ValueSequenceSymmetry(const IntArgs& vs, int ss) {
00107     return SymmetryHandle(new ValueSequenceSymmetryObject(vs, ss));
00108   }
00109 
00110   SymmetryHandle values_reflect(int lower, int upper) {
00111     int n = (upper-lower+1)/2;
00112     IntArgs a(n*2);
00113     int i = lower;
00114     int j = upper;
00115     int k = 0;
00116     while (i < j) {
00117       a[k]   = j;
00118       a[n+k] = i;
00119       i++;
00120       j--;
00121       k++;
00122     }
00123     return ValueSequenceSymmetry(a,n);
00124   }
00125   SymmetryHandle values_reflect(const IntVar& x) {
00126     return values_reflect(x.min(), x.max());
00127   }
00128 }
00129 
00130 
00131 namespace Gecode { namespace Int { namespace LDSB {
00132 
00134   class VariableMap : public std::map<VarImpBase*,int> {};
00135 
00136   /*
00137    * The duplication in createIntSym/createBoolSym is undesirable,
00138    * and so is the use of dynamic_cast to tell the symmetries
00139    * apart.
00140    */
00141 
00143   SymmetryImp<IntView>*
00144   createIntSym(Space& home, const SymmetryHandle& s,
00145                VariableMap variableMap) {
00146     VariableSymmetryObject* varref    = 
00147       dynamic_cast<VariableSymmetryObject*>(s.ref);
00148     ValueSymmetryObject* valref    =  
00149       dynamic_cast<ValueSymmetryObject*>(s.ref);
00150     VariableSequenceSymmetryObject* varseqref = 
00151       dynamic_cast<VariableSequenceSymmetryObject*>(s.ref);
00152     ValueSequenceSymmetryObject* valseqref =  
00153       dynamic_cast<ValueSequenceSymmetryObject*>(s.ref);
00154     if (varref) {
00155       int n = varref->nxs;
00156       int* indices = home.alloc<int>(n);
00157       for (int i = 0 ; i < n ; i++) {
00158         VariableMap::const_iterator index = variableMap.find(varref->xs[i]);
00159         if (index == variableMap.end())
00160           throw LDSBUnbranchedVariable("VariableSymmetryObject::createInt");
00161         indices[i] = index->second;
00162       }
00163       return new (home) VariableSymmetryImp<IntView>(home, indices, n);
00164     }
00165     if (valref) {
00166       int n = valref->values.size();
00167       int *vs = home.alloc<int>(n);
00168       int i = 0;
00169       for (IntSetValues v(valref->values) ; v() ; ++v) {
00170         vs[i] = v.val();
00171         i++;
00172       }
00173       return new (home) ValueSymmetryImp<IntView>(home, vs, n);
00174     }
00175     if (varseqref) {
00176       int n = varseqref->nxs;
00177       int* indices = home.alloc<int>(n);
00178       for (int i = 0 ; i < n ; i++) {
00179         VariableMap::const_iterator index = 
00180           variableMap.find(varseqref->xs[i]);
00181         if (index == variableMap.end())
00182           throw LDSBUnbranchedVariable("VariableSequenceSymmetryObject::createInt");
00183         indices[i] = index->second;
00184       }
00185       return new (home) VariableSequenceSymmetryImp<IntView>(home, indices, n, 
00186         varseqref->seq_size);
00187     }
00188     if (valseqref) {
00189       unsigned int n = valseqref->values.size();
00190       int *vs = home.alloc<int>(n);
00191       for (unsigned int i = 0 ; i < n ; i++)
00192         vs[i] = valseqref->values[i];
00193       return new (home) ValueSequenceSymmetryImp<IntView>(home, vs, n, 
00194         valseqref->seq_size);
00195     }
00196     GECODE_NEVER;
00197     return NULL;
00198   }
00199 
00201   SymmetryImp<BoolView>* createBoolSym(Space& home, const SymmetryHandle& s,
00202                                        VariableMap variableMap) {
00203     VariableSymmetryObject* varref    = 
00204       dynamic_cast<VariableSymmetryObject*>(s.ref);
00205     ValueSymmetryObject* valref    = 
00206       dynamic_cast<ValueSymmetryObject*>(s.ref);
00207     VariableSequenceSymmetryObject* varseqref = 
00208       dynamic_cast<VariableSequenceSymmetryObject*>(s.ref);
00209     ValueSequenceSymmetryObject* valseqref =  
00210       dynamic_cast<ValueSequenceSymmetryObject*>(s.ref);
00211     if (varref) {
00212       int n = varref->nxs;
00213       int* indices = home.alloc<int>(n);
00214       for (int i = 0 ; i < n ; i++) {
00215         VariableMap::const_iterator index = variableMap.find(varref->xs[i]);
00216         if (index == variableMap.end())
00217           throw LDSBUnbranchedVariable("VariableSymmetryObject::createBool");
00218         indices[i] = index->second;
00219       }
00220       return new (home) VariableSymmetryImp<BoolView>(home, indices, n);
00221     }
00222     if (valref) {
00223       int n = valref->values.size();
00224       int *vs = home.alloc<int>(n);
00225       int i = 0;
00226       for (IntSetValues v(valref->values) ; v() ; ++v) {
00227         vs[i] = v.val();
00228         i++;
00229       }
00230       return new (home) ValueSymmetryImp<BoolView>(home, vs, n);
00231     }
00232     if (varseqref) {
00233       int n = varseqref->nxs;
00234       int* indices = home.alloc<int>(n);
00235       for (int i = 0 ; i < n ; i++) {
00236         VariableMap::const_iterator index = 
00237           variableMap.find(varseqref->xs[i]);
00238         if (index == variableMap.end())
00239           throw LDSBUnbranchedVariable("VariableSequenceSymmetryObject::createBool");
00240         indices[i] = index->second;
00241       }
00242       return new (home) VariableSequenceSymmetryImp<BoolView>(home, indices, 
00243         n, varseqref->seq_size);
00244     }
00245     if (valseqref) {
00246       unsigned int n = valseqref->values.size();
00247       int *vs = home.alloc<int>(n);
00248       for (unsigned int i = 0 ; i < n ; i++)
00249         vs[i] = valseqref->values[i];
00250       return new (home) ValueSequenceSymmetryImp<BoolView>(home, vs, n, 
00251         valseqref->seq_size);
00252     }
00253     GECODE_NEVER;
00254     return NULL;
00255   }
00256 }}}
00257 
00258 namespace Gecode {
00259 
00260   using namespace Int::LDSB;
00261 
00262   BrancherHandle
00263   branch(Home home, const IntVarArgs& x,
00264          IntVarBranch vars, IntValBranch vals,
00265          const Symmetries& syms, 
00266          IntBranchFilter bf, IntVarValPrint vvp) {
00267     using namespace Int;
00268     if (home.failed()) return BrancherHandle();
00269     vars.expand(home,x);
00270     ViewArray<IntView> xv(home,x);
00271     ViewSel<IntView>* vs[1] = { 
00272       Branch::viewselint(home,vars) 
00273     };
00274     switch (vals.select()) {
00275     case IntValBranch::SEL_SPLIT_MIN:
00276     case IntValBranch::SEL_SPLIT_MAX:
00277     case IntValBranch::SEL_RANGE_MIN:
00278     case IntValBranch::SEL_RANGE_MAX:
00279     case IntValBranch::SEL_VALUES_MIN:
00280     case IntValBranch::SEL_VALUES_MAX:
00281       throw LDSBBadValueSelection("Int::LDSB::branch");
00282       break;
00283     case IntValBranch::SEL_VAL_COMMIT:
00284       if (vals.commit() != NULL)
00285         throw LDSBBadValueSelection("Int::LDSB::branch");
00286       // If vals.commit() returns NULL, it means it will commit with
00287       // binary branching, which is OK for LDSB, so we fall through.
00288     default:
00289       // Construct mapping from each variable in the array to its index
00290       // in the array.
00291       VariableMap variableMap;
00292       for (int i = 0 ; i < x.size() ; i++)
00293         variableMap[x[i].varimp()] = i;
00294 
00295       // Convert the modelling-level Symmetries object into an array of
00296       // SymmetryImp objects.
00297       int n = syms.size();
00298       SymmetryImp<IntView>** array =
00299         static_cast<Space&>(home).alloc<SymmetryImp<IntView>* >(n);
00300       for (int i = 0 ; i < n ; i++) {
00301         array[i] = createIntSym(home, syms[i], variableMap);
00302       }
00303 
00304       return LDSBBrancher<IntView,1,int,2>::post
00305         (home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00306          array,n,bf,vvp);
00307     }
00308   }
00309 
00310   BrancherHandle
00311   branch(Home home, const IntVarArgs& x,
00312          TieBreak<IntVarBranch> vars, IntValBranch vals,
00313          const Symmetries& syms, 
00314          IntBranchFilter bf, IntVarValPrint vvp) {
00315     using namespace Int;
00316     if (home.failed()) return BrancherHandle();
00317     vars.a.expand(home,x);
00318     if ((vars.a.select() == IntVarBranch::SEL_NONE) ||
00319         (vars.a.select() == IntVarBranch::SEL_RND))
00320       vars.b = INT_VAR_NONE();
00321     vars.b.expand(home,x);
00322     if ((vars.b.select() == IntVarBranch::SEL_NONE) ||
00323         (vars.b.select() == IntVarBranch::SEL_RND))
00324       vars.c = INT_VAR_NONE();
00325     vars.c.expand(home,x);
00326     if ((vars.c.select() == IntVarBranch::SEL_NONE) ||
00327         (vars.c.select() == IntVarBranch::SEL_RND))
00328       vars.d = INT_VAR_NONE();
00329     vars.d.expand(home,x);
00330     if (vars.b.select() == IntVarBranch::SEL_NONE) {
00331       return branch(home,x,vars.a,vals,syms,bf,vvp);
00332     } else {
00333       // Construct mapping from each variable in the array to its index
00334       // in the array.
00335       VariableMap variableMap;
00336       for (int i = 0 ; i < x.size() ; i++)
00337         variableMap[x[i].varimp()] = i;
00338 
00339       // Convert the modelling-level Symmetries object into an array of
00340       // SymmetryImp objects.
00341       int n = syms.size();
00342       SymmetryImp<IntView>** array =
00343         static_cast<Space&>(home).alloc<SymmetryImp<IntView>* >(n);
00344       for (int i = 0 ; i < n ; i++) {
00345         array[i] = createIntSym(home, syms[i], variableMap);
00346       }
00347 
00348       ViewArray<IntView> xv(home,x);
00349       if (vars.c.select() == IntVarBranch::SEL_NONE) {
00350         ViewSel<IntView>* vs[2] = {
00351           Branch::viewselint(home,vars.a),Branch::viewselint(home,vars.b)
00352         };
00353         switch (vals.select()) {
00354         case IntValBranch::SEL_SPLIT_MIN:
00355         case IntValBranch::SEL_SPLIT_MAX:
00356         case IntValBranch::SEL_RANGE_MIN:
00357         case IntValBranch::SEL_RANGE_MAX:
00358         case IntValBranch::SEL_VALUES_MIN:
00359         case IntValBranch::SEL_VALUES_MAX:
00360           throw LDSBBadValueSelection("Int::LDSB::branch");
00361           break;
00362         case IntValBranch::SEL_VAL_COMMIT:
00363           if (vals.commit() != NULL)
00364             throw LDSBBadValueSelection("Int::LDSB::branch");
00365           // If vals.commit() returns NULL, it means it will commit with
00366           // binary branching, which is OK for LDSB, so we fall through.
00367         default:
00368           return LDSBBrancher<IntView,2,int,2>
00369             ::post(home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00370                    array,n,bf,vvp);
00371         }
00372       } else if (vars.d.select() == IntVarBranch::SEL_NONE) {
00373         ViewSel<IntView>* vs[3] = {
00374           Branch::viewselint(home,vars.a),Branch::viewselint(home,vars.b),
00375           Branch::viewselint(home,vars.c)
00376         };
00377         switch (vals.select()) {
00378         case IntValBranch::SEL_SPLIT_MIN:
00379         case IntValBranch::SEL_SPLIT_MAX:
00380         case IntValBranch::SEL_RANGE_MIN:
00381         case IntValBranch::SEL_RANGE_MAX:
00382         case IntValBranch::SEL_VALUES_MIN:
00383         case IntValBranch::SEL_VALUES_MAX:
00384           throw LDSBBadValueSelection("Int::LDSB::branch");
00385           break;
00386         case IntValBranch::SEL_VAL_COMMIT:
00387           if (vals.commit() != NULL)
00388             throw LDSBBadValueSelection("Int::LDSB::branch");
00389           // If vals.commit() returns NULL, it means it will commit with
00390           // binary branching, which is OK for LDSB, so we fall through.
00391         default:
00392           return LDSBBrancher<IntView,3,int,2>
00393             ::post(home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00394                    array,n,bf,vvp);
00395         }
00396       } else {
00397         ViewSel<IntView>* vs[4] = {
00398           Branch::viewselint(home,vars.a),Branch::viewselint(home,vars.b),
00399           Branch::viewselint(home,vars.c),Branch::viewselint(home,vars.d)
00400         };
00401         switch (vals.select()) {
00402         case IntValBranch::SEL_SPLIT_MIN:
00403         case IntValBranch::SEL_SPLIT_MAX:
00404         case IntValBranch::SEL_RANGE_MIN:
00405         case IntValBranch::SEL_RANGE_MAX:
00406         case IntValBranch::SEL_VALUES_MIN:
00407         case IntValBranch::SEL_VALUES_MAX:
00408           throw LDSBBadValueSelection("Int::LDSB::branch");
00409           break;
00410         case IntValBranch::SEL_VAL_COMMIT:
00411           if (vals.commit() != NULL)
00412             throw LDSBBadValueSelection("Int::LDSB::branch");
00413           // If vals.commit() returns NULL, it means it will commit with
00414           // binary branching, which is OK for LDSB, so we fall through.
00415         default:
00416           return LDSBBrancher<IntView,4,int,2>
00417             ::post(home,xv,vs,Branch::valselcommitint(home,x.size(),vals),
00418                    array,n,bf,vvp);
00419         }
00420       }
00421     }
00422     GECODE_NEVER;
00423     return BrancherHandle();
00424   }
00425 
00426   BrancherHandle
00427   branch(Home home, const BoolVarArgs& x,
00428          IntVarBranch vars, IntValBranch vals,
00429          const Symmetries& syms, 
00430          BoolBranchFilter bf, BoolVarValPrint vvp) {
00431     using namespace Int;
00432     if (home.failed()) return BrancherHandle();
00433     vars.expand(home,x);
00434     ViewArray<BoolView> xv(home,x);
00435     ViewSel<BoolView>* vs[1] = { 
00436       Branch::viewselbool(home,vars) 
00437     };
00438 
00439     // Construct mapping from each variable in the array to its index
00440     // in the array.
00441     VariableMap variableMap;
00442     for (int i = 0 ; i < x.size() ; i++)
00443       variableMap[x[i].varimp()] = i;
00444 
00445     // Convert the modelling-level Symmetries object into an array of
00446     // SymmetryImp objects.
00447     int n = syms.size();
00448     SymmetryImp<BoolView>** array =
00449       static_cast<Space&>(home).alloc<SymmetryImp<BoolView>* >(n);
00450     for (int i = 0 ; i < n ; i++) {
00451       array[i] = createBoolSym(home, syms[i], variableMap);
00452     }
00453 
00454     // Technically these "bad" value selection could in fact work with
00455     // LDSB, because they degenerate to binary splitting for
00456     // Booleans.  Nonetheless, we explicitly forbid them for
00457     // consistency with the integer version.
00458     switch (vals.select()) {
00459     case IntValBranch::SEL_SPLIT_MIN:
00460     case IntValBranch::SEL_SPLIT_MAX:
00461     case IntValBranch::SEL_RANGE_MIN:
00462     case IntValBranch::SEL_RANGE_MAX:
00463     case IntValBranch::SEL_VALUES_MIN:
00464     case IntValBranch::SEL_VALUES_MAX:
00465       throw LDSBBadValueSelection("Int::LDSB::branch");
00466       break;
00467     case IntValBranch::SEL_VAL_COMMIT:
00468       if (vals.commit() != NULL)
00469         throw LDSBBadValueSelection("Int::LDSB::branch");
00470       // If vals.commit() returns NULL, it means it will commit with
00471       // binary branching, which is OK for LDSB, so we fall through.
00472     default:
00473       return LDSBBrancher<BoolView,1,int,2>::post
00474         (home,xv,vs,Branch::valselcommitbool(home,x.size(),vals),array,n,bf,vvp);
00475     }
00476     GECODE_NEVER;
00477     return BrancherHandle();
00478   }
00479 
00480 
00481   BrancherHandle
00482   branch(Home home, const BoolVarArgs& x,
00483          TieBreak<IntVarBranch> vars, IntValBranch vals,
00484          const Symmetries& syms, 
00485          BoolBranchFilter bf, BoolVarValPrint vvp) {
00486     using namespace Int;
00487     if (home.failed()) return BrancherHandle();
00488     vars.a.expand(home,x);
00489     if ((vars.a.select() == IntVarBranch::SEL_NONE) ||
00490         (vars.a.select() == IntVarBranch::SEL_RND))
00491       vars.b = INT_VAR_NONE();
00492     vars.b.expand(home,x);
00493     if ((vars.b.select() == IntVarBranch::SEL_NONE) ||
00494         (vars.b.select() == IntVarBranch::SEL_RND))
00495       vars.c = INT_VAR_NONE();
00496     vars.c.expand(home,x);
00497     if ((vars.c.select() == IntVarBranch::SEL_NONE) ||
00498         (vars.c.select() == IntVarBranch::SEL_RND))
00499       vars.d = INT_VAR_NONE();
00500     vars.d.expand(home,x);
00501     if (vars.b.select() == IntVarBranch::SEL_NONE) {
00502       return branch(home,x,vars.a,vals,syms,bf,vvp);
00503     } else {
00504       // Construct mapping from each variable in the array to its index
00505       // in the array.
00506       VariableMap variableMap;
00507       for (int i = 0 ; i < x.size() ; i++)
00508         variableMap[x[i].varimp()] = i;
00509 
00510       // Convert the modelling-level Symmetries object into an array of
00511       // SymmetryImp objects.
00512       int n = syms.size();
00513       SymmetryImp<BoolView>** array =
00514         static_cast<Space&>(home).alloc<SymmetryImp<BoolView>* >(n);
00515       for (int i = 0 ; i < n ; i++) {
00516         array[i] = createBoolSym(home, syms[i], variableMap);
00517       }
00518 
00519       // Technically these "bad" value selection could in fact work with
00520       // LDSB, because they degenerate to binary splitting for
00521       // Booleans.  Nonetheless, we explicitly forbid them for
00522       // consistency with the integer version.
00523       switch (vals.select()) {
00524       case IntValBranch::SEL_SPLIT_MIN:
00525       case IntValBranch::SEL_SPLIT_MAX:
00526       case IntValBranch::SEL_RANGE_MIN:
00527       case IntValBranch::SEL_RANGE_MAX:
00528       case IntValBranch::SEL_VALUES_MIN:
00529       case IntValBranch::SEL_VALUES_MAX:
00530         throw LDSBBadValueSelection("Int::LDSB::branch");
00531         break;
00532       case IntValBranch::SEL_VAL_COMMIT:
00533         if (vals.commit() != NULL)
00534           throw LDSBBadValueSelection("Int::LDSB::branch");
00535         // If vals.commit() returns NULL, it means it will commit with
00536         // binary branching, which is OK for LDSB, so we fall through.
00537       default:
00538         ;
00539         // Do nothing and continue.
00540       }
00541 
00542       ViewArray<BoolView> xv(home,x);
00543       ValSelCommitBase<BoolView,int>* 
00544         vsc = Branch::valselcommitbool(home,x.size(),vals); 
00545       if (vars.c.select() == IntVarBranch::SEL_NONE) {
00546         ViewSel<BoolView>* vs[2] = { 
00547           Branch::viewselbool(home,vars.a),Branch::viewselbool(home,vars.b)
00548         };
00549         return 
00550           LDSBBrancher<BoolView,2,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00551       } else if (vars.d.select() == IntVarBranch::SEL_NONE) {
00552         ViewSel<BoolView>* vs[3] = { 
00553           Branch::viewselbool(home,vars.a),Branch::viewselbool(home,vars.b),
00554           Branch::viewselbool(home,vars.c)
00555         };
00556         return 
00557           LDSBBrancher<BoolView,3,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00558       } else {
00559         ViewSel<BoolView>* vs[4] = { 
00560           Branch::viewselbool(home,vars.a),Branch::viewselbool(home,vars.b),
00561           Branch::viewselbool(home,vars.c),Branch::viewselbool(home,vars.d)
00562         };
00563         return 
00564           LDSBBrancher<BoolView,4,int,2>::post(home,xv,vs,vsc,array,n,bf,vvp);
00565       }
00566     }
00567     GECODE_NEVER;
00568     return BrancherHandle();
00569   }
00570 
00571 }
00572 
00573 
00574 
00575 // STATISTICS: int-branch