00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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