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 #include <gecode/int/unary.hh>
00037 #include <gecode/int/distinct.hh>
00038
00039 #include <algorithm>
00040
00041 namespace Gecode {
00042
00043 void
00044 unary(Home home, const IntVarArgs& s, const IntArgs& p, IntPropLevel ipl) {
00045 using namespace Gecode::Int;
00046 using namespace Gecode::Int::Unary;
00047 if (same(s))
00048 throw Int::ArgumentSame("Int::unary");
00049 if (s.size() != p.size())
00050 throw Int::ArgumentSizeMismatch("Int::unary");
00051 for (int i=0; i<p.size(); i++) {
00052 Int::Limits::nonnegative(p[i],"Int::unary");
00053 Int::Limits::check(static_cast<long long int>(s[i].max()) + p[i],
00054 "Int::unary");
00055 }
00056 GECODE_POST;
00057 bool allOne = true;
00058 for (int i=0; i<p.size(); i++) {
00059 if (p[i] != 1) {
00060 allOne = false;
00061 break;
00062 }
00063 }
00064 if (allOne) {
00065 ViewArray<IntView> xv(home,s);
00066 switch (vbd(ipl)) {
00067 case IPL_BND:
00068 GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,xv));
00069 break;
00070 case IPL_DOM:
00071 GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,xv));
00072 break;
00073 default:
00074 GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,xv));
00075 }
00076 } else {
00077 TaskArray<ManFixPTask> t(home,s.size());
00078 for (int i=0; i<s.size(); i++)
00079 t[i].init(s[i],p[i]);
00080 GECODE_ES_FAIL(manpost(home,t,ipl));
00081 }
00082 }
00083
00084 void
00085 unary(Home home, const TaskTypeArgs& t,
00086 const IntVarArgs& flex, const IntArgs& fix, IntPropLevel ipl) {
00087 using namespace Gecode::Int;
00088 using namespace Gecode::Int::Unary;
00089 if ((flex.size() != fix.size()) || (flex.size() != t.size()))
00090 throw Int::ArgumentSizeMismatch("Int::unary");
00091 for (int i=0; i<fix.size(); i++) {
00092 if (t[i] == TT_FIXP)
00093 Int::Limits::nonnegative(fix[i],"Int::unary");
00094 else
00095 Int::Limits::check(fix[i],"Int::unary");
00096 Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i],
00097 "Int::unary");
00098 }
00099 GECODE_POST;
00100 bool fixp = true;
00101 for (int i=0; i<t.size(); i++)
00102 if (t[i] != TT_FIXP) {
00103 fixp = false; break;
00104 }
00105 if (fixp) {
00106 unary(home, flex, fix, ipl);
00107 } else {
00108 TaskArray<ManFixPSETask> tasks(home,flex.size());
00109 for (int i=0; i<flex.size(); i++)
00110 tasks[i].init(t[i],flex[i],fix[i]);
00111 GECODE_ES_FAIL(manpost(home,tasks,ipl));
00112 }
00113 }
00114
00115 void
00116 unary(Home home, const IntVarArgs& s, const IntArgs& p,
00117 const BoolVarArgs& m, IntPropLevel ipl) {
00118 using namespace Gecode::Int;
00119 using namespace Gecode::Int::Unary;
00120 if (same(s))
00121 throw Int::ArgumentSame("Int::unary");
00122 if ((s.size() != p.size()) || (s.size() != m.size()))
00123 throw Int::ArgumentSizeMismatch("Int::unary");
00124 for (int i=0; i<p.size(); i++) {
00125 Int::Limits::nonnegative(p[i],"Int::unary");
00126 Int::Limits::check(static_cast<long long int>(s[i].max()) + p[i],
00127 "Int::unary");
00128 }
00129 bool allMandatory = true;
00130 for (int i=0; i<m.size(); i++) {
00131 if (!m[i].one()) {
00132 allMandatory = false;
00133 break;
00134 }
00135 }
00136 if (allMandatory) {
00137 unary(home,s,p,ipl);
00138 } else {
00139 GECODE_POST;
00140 TaskArray<OptFixPTask> t(home,s.size());
00141 for (int i=0; i<s.size(); i++)
00142 t[i].init(s[i],p[i],m[i]);
00143 GECODE_ES_FAIL(optpost(home,t,ipl));
00144 }
00145 }
00146
00147 void
00148 unary(Home home, const TaskTypeArgs& t,
00149 const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m,
00150 IntPropLevel ipl) {
00151 using namespace Gecode::Int;
00152 using namespace Gecode::Int::Unary;
00153 if ((flex.size() != fix.size()) || (flex.size() != t.size()) ||
00154 (flex.size() != m.size()))
00155 throw Int::ArgumentSizeMismatch("Int::unary");
00156 bool fixp = true;
00157 for (int i=0; i<fix.size(); i++) {
00158 if (t[i] == TT_FIXP) {
00159 Int::Limits::nonnegative(fix[i],"Int::unary");
00160 } else {
00161 fixp = false;
00162 Int::Limits::check(fix[i],"Int::unary");
00163 }
00164 Int::Limits::check(static_cast<long long int>(flex[i].max()) + fix[i],
00165 "Int::unary");
00166 }
00167 GECODE_POST;
00168 bool allMandatory = true;
00169 for (int i=0; i<m.size(); i++) {
00170 if (!m[i].one()) {
00171 allMandatory = false;
00172 break;
00173 }
00174 }
00175 if (allMandatory) {
00176 unary(home,t,flex,fix,ipl);
00177 } else {
00178 if (fixp) {
00179 TaskArray<OptFixPTask> tasks(home,flex.size());
00180 for (int i=0; i<flex.size(); i++)
00181 tasks[i].init(flex[i],fix[i],m[i]);
00182 GECODE_ES_FAIL(optpost(home,tasks,ipl));
00183 } else {
00184 TaskArray<OptFixPSETask> tasks(home,flex.size());
00185 for (int i=0; i<flex.size(); i++)
00186 tasks[i].init(t[i],flex[i],fix[i],m[i]);
00187 GECODE_ES_FAIL(optpost(home,tasks,ipl));
00188 }
00189 }
00190 }
00191
00192 void
00193 unary(Home home, const IntVarArgs& s, const IntVarArgs& p,
00194 const IntVarArgs& e, IntPropLevel ipl) {
00195 using namespace Gecode::Int;
00196 using namespace Gecode::Int::Unary;
00197 if ((s.size() != p.size()) || (s.size() != e.size()))
00198 throw Int::ArgumentSizeMismatch("Int::unary");
00199 GECODE_POST;
00200 for (int i=0; i<p.size(); i++) {
00201 IntView pi(p[i]);
00202 GECODE_ME_FAIL(pi.gq(home,0));
00203 }
00204 bool fixP = true;
00205 for (int i=0; i<p.size(); i++) {
00206 if (!p[i].assigned()) {
00207 fixP = false;
00208 break;
00209 }
00210 }
00211 if (fixP) {
00212 IntArgs pp(p.size());
00213 for (int i=0; i<p.size(); i++)
00214 pp[i] = p[i].val();
00215 unary(home,s,pp,ipl);
00216 } else {
00217 TaskArray<ManFlexTask> t(home,s.size());
00218 for (int i=0; i<s.size(); i++)
00219 t[i].init(s[i],p[i],e[i]);
00220 GECODE_ES_FAIL(manpost(home,t,ipl));
00221 }
00222 }
00223
00224 void
00225 unary(Home home, const IntVarArgs& s, const IntVarArgs& p,
00226 const IntVarArgs& e, const BoolVarArgs& m, IntPropLevel ipl) {
00227 using namespace Gecode::Int;
00228 using namespace Gecode::Int::Unary;
00229 if ((s.size() != p.size()) || (s.size() != m.size()) ||
00230 (s.size() != e.size()))
00231 throw Int::ArgumentSizeMismatch("Int::unary");
00232 GECODE_POST;
00233 for (int i=0; i<p.size(); i++) {
00234 IntView pi(p[i]);
00235 GECODE_ME_FAIL(pi.gq(home,0));
00236 }
00237 bool allMandatory = true;
00238 for (int i=0; i<m.size(); i++) {
00239 if (!m[i].one()) {
00240 allMandatory = false;
00241 break;
00242 }
00243 }
00244 if (allMandatory) {
00245 unary(home,s,p,e,ipl);
00246 } else {
00247 TaskArray<OptFlexTask> t(home,s.size());
00248 for (int i=0; i<s.size(); i++)
00249 t[i].init(s[i],p[i],e[i],m[i]);
00250 GECODE_ES_FAIL(optpost(home,t,ipl));
00251 }
00252 }
00253
00254 }
00255
00256