Generated on Thu Mar 22 10:39:41 2012 for Gecode by doxygen 1.6.3

unary.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  *     Guido Tack <tack@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Christian Schulte, 2009
00009  *     Guido Tack, 2010
00010  *
00011  *  Last modified:
00012  *     $Date: 2011-07-13 18:51:41 +0200 (Wed, 13 Jul 2011) $ by $Author: tack $
00013  *     $Revision: 12193 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include <gecode/int/unary.hh>
00041 #include <gecode/int/distinct.hh>
00042 
00043 #include <algorithm>
00044 
00045 namespace Gecode {
00046 
00047   void
00048   unary(Home home, const IntVarArgs& s, const IntArgs& p, IntConLevel icl) {
00049     using namespace Gecode::Int;
00050     using namespace Gecode::Int::Unary;
00051     if (s.same(home))
00052       throw Int::ArgumentSame("Int::unary");
00053     if (s.size() != p.size())
00054       throw Int::ArgumentSizeMismatch("Int::unary");
00055     for (int i=p.size(); i--; ) {
00056       Int::Limits::nonnegative(p[i],"Int::unary");
00057       Int::Limits::check(static_cast<double>(s[i].max()) + p[i],
00058                          "Int::unary");
00059     }
00060     if (home.failed()) return;
00061     bool allOne = true;
00062     for (int i=p.size(); i--;) {
00063       if (p[i] != 1) {
00064         allOne = false;
00065         break;
00066       }
00067     }
00068     if (allOne) {
00069       ViewArray<IntView> xv(home,s);
00070       switch (icl) {
00071       case ICL_BND:
00072         GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv));
00073         break;
00074       case ICL_DOM:
00075         GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv));
00076         break;
00077       default:
00078         GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv));
00079       }
00080     } else {
00081       TaskArray<ManFixPTask> t(home,s.size());
00082       for (int i=s.size(); i--; )
00083         t[i].init(s[i],p[i]);
00084       GECODE_ES_FAIL(ManProp<ManFixPTask>::post(home,t));
00085     }
00086   }
00087 
00088   void
00089   unary(Home home, const TaskTypeArgs& t,
00090         const IntVarArgs& flex, const IntArgs& fix, IntConLevel icl) {
00091     using namespace Gecode::Int;
00092     using namespace Gecode::Int::Unary;
00093     if ((flex.size() != fix.size()) || (flex.size() != t.size()))
00094       throw Int::ArgumentSizeMismatch("Int::unary");
00095     for (int i=fix.size(); i--; ) {
00096       if (t[i] == TT_FIXP)
00097         Int::Limits::nonnegative(fix[i],"Int::unary");
00098       else
00099         Int::Limits::check(fix[i],"Int::unary");
00100       Int::Limits::check(static_cast<double>(flex[i].max()) + fix[i],
00101                          "Int::unary");
00102     }
00103     if (home.failed()) return;
00104     bool fixp = true;
00105     for (int i=t.size(); i--;)
00106       if (t[i] != TT_FIXP) {
00107         fixp = false; break;
00108       }
00109     if (fixp) {
00110       unary(home, flex, fix, icl);
00111     } else {
00112       TaskArray<ManFixPSETask> tasks(home,flex.size());
00113       for (int i=flex.size(); i--;)
00114         tasks[i].init(t[i],flex[i],fix[i]);
00115       GECODE_ES_FAIL(ManProp<ManFixPSETask>::post(home,tasks));
00116     }
00117   }
00118 
00119   void
00120   unary(Home home, const IntVarArgs& s, const IntArgs& p, 
00121         const BoolVarArgs& m, IntConLevel icl) {
00122     using namespace Gecode::Int;
00123     using namespace Gecode::Int::Unary;
00124     if (s.same(home))
00125       throw Int::ArgumentSame("Int::unary");
00126     if ((s.size() != p.size()) || (s.size() != m.size()))
00127       throw Int::ArgumentSizeMismatch("Int::unary");
00128     for (int i=p.size(); i--; ) {
00129       Int::Limits::nonnegative(p[i],"Int::unary");
00130       Int::Limits::check(static_cast<double>(s[i].max()) + p[i],
00131                          "Int::unary");
00132     }
00133     bool allMandatory = true;
00134     for (int i=m.size(); i--;) {
00135       if (!m[i].one()) {
00136         allMandatory = false;
00137         break;
00138       }
00139     }
00140     if (allMandatory) {
00141       unary(home,s,p,icl);
00142     } else {
00143       if (home.failed()) return;
00144       TaskArray<OptFixPTask> t(home,s.size());
00145       for (int i=s.size(); i--; )
00146         t[i].init(s[i],p[i],m[i]);
00147       GECODE_ES_FAIL(OptProp<OptFixPTask>::post(home,t));
00148     }
00149   }
00150 
00151   void
00152   unary(Home home, const TaskTypeArgs& t,
00153         const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m, 
00154         IntConLevel icl) {
00155     using namespace Gecode::Int;
00156     using namespace Gecode::Int::Unary;
00157     if ((flex.size() != fix.size()) || (flex.size() != t.size()) ||
00158         (flex.size() != m.size()))
00159       throw Int::ArgumentSizeMismatch("Int::unary");
00160     bool fixp = true;
00161     for (int i=fix.size(); i--; ) {
00162       if (t[i] == TT_FIXP) {
00163         Int::Limits::nonnegative(fix[i],"Int::unary");
00164       } else {
00165         fixp = false;
00166         Int::Limits::check(fix[i],"Int::unary");
00167       }
00168       Int::Limits::check(static_cast<double>(flex[i].max()) + fix[i],
00169                          "Int::unary");
00170     }
00171     if (home.failed()) return;
00172     bool allMandatory = true;
00173     for (int i=m.size(); i--;) {
00174       if (!m[i].one()) {
00175         allMandatory = false;
00176         break;
00177       }
00178     }
00179     if (allMandatory) {
00180       unary(home,t,flex,fix,icl);
00181     } else {
00182       if (fixp) {
00183         TaskArray<OptFixPTask> tasks(home,flex.size());
00184         for (int i=flex.size(); i--; )
00185           tasks[i].init(flex[i],fix[i],m[i]);
00186         GECODE_ES_FAIL(OptProp<OptFixPTask>::post(home,tasks));
00187       } else {
00188         TaskArray<OptFixPSETask> tasks(home,flex.size());
00189         for (int i=flex.size(); i--;)
00190           tasks[i].init(t[i],flex[i],fix[i],m[i]);
00191         GECODE_ES_FAIL(OptProp<OptFixPSETask>::post(home,tasks));
00192       }
00193     }
00194   }
00195 
00196   void
00197   unary(Home home, const IntVarArgs& s, const IntVarArgs& p,
00198         const IntVarArgs& e, IntConLevel icl) {
00199     using namespace Gecode::Int;
00200     using namespace Gecode::Int::Unary;
00201     if ((s.size() != p.size()) || (s.size() != e.size()))
00202       throw Int::ArgumentSizeMismatch("Int::unary");
00203     if (home.failed()) return;
00204     for (int i=p.size(); i--; ) {
00205       rel(home, p[i], IRT_GQ, 0);
00206     }
00207     bool fixP = true;
00208     for (int i=p.size(); i--;) {
00209       if (!p[i].assigned()) {
00210         fixP = false;
00211         break;
00212       }
00213     }
00214     if (fixP) {
00215       IntArgs pp(p.size());
00216       for (int i=p.size(); i--;)
00217         pp[i] = p[i].val();
00218       unary(home,s,pp,icl);
00219     } else {
00220       TaskArray<ManFlexTask> t(home,s.size());
00221       for (int i=s.size(); i--; )
00222         t[i].init(s[i],p[i],e[i]);
00223       GECODE_ES_FAIL(ManProp<ManFlexTask>::post(home,t));
00224     }
00225   }
00226 
00227   void
00228   unary(Home home, const IntVarArgs& s, const IntVarArgs& p, 
00229         const IntVarArgs& e, const BoolVarArgs& m, IntConLevel icl) {
00230     using namespace Gecode::Int;
00231     using namespace Gecode::Int::Unary;
00232     if ((s.size() != p.size()) || (s.size() != m.size()) ||
00233         (s.size() != e.size()))
00234       throw Int::ArgumentSizeMismatch("Int::unary");
00235     if (home.failed()) return;
00236     for (int i=p.size(); i--; ) {
00237       rel(home, p[i], IRT_GQ, 0);
00238     }
00239     bool allMandatory = true;
00240     for (int i=m.size(); i--;) {
00241       if (!m[i].one()) {
00242         allMandatory = false;
00243         break;
00244       }
00245     }
00246     if (allMandatory) {
00247       unary(home,s,p,e,icl);
00248     } else {
00249       TaskArray<OptFlexTask> t(home,s.size());
00250       for (int i=s.size(); i--; )
00251         t[i].init(s[i],p[i],e[i],m[i]);
00252       GECODE_ES_FAIL(OptProp<OptFlexTask>::post(home,t));
00253     }
00254   }
00255 
00256 }
00257 
00258 // STATISTICS: int-post