this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * 6 * Copyright: 7 * Guido Tack, 2005 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#include "test/set.hh" 35#include "test/int.hh" 36#include <gecode/minimodel.hh> 37 38using namespace Gecode; 39 40namespace Test { namespace Set { 41 42 /// %Tests for combined int/set constraints 43 namespace Int { 44 45 /** 46 * \defgroup TaskTestSetInt Combined integer/set constraints 47 * \ingroup TaskTestSet 48 */ 49 //@{ 50 51 static const int d1r[4][2] = { 52 {-4,-3},{-1,-1},{1,1},{3,5} 53 }; 54 static IntSet d1(d1r,4); 55 56 static IntSet d2(-1,3); 57 static IntSet d3(0,3); 58 59 static IntSet d4(0,4); 60 61 static IntSet ds_33(-3,3); 62 63 /// %Test for cardinality constraint 64 class Card : public SetTest { 65 public: 66 /// Create and register test 67 Card(const char* t) 68 : SetTest(t,1,ds_33,true,1) {} 69 /// %Test whether \a x is solution 70 virtual bool solution(const SetAssignment& x) const { 71 unsigned int s = 0; 72 for (CountableSetRanges xr(x.lub, x[0]);xr();++xr) s+= xr.width(); 73 if (x.intval() < 0) 74 return false; 75 return s==(unsigned int)x.intval(); 76 } 77 /// Post constraint on \a x 78 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 79 Gecode::cardinality(home, x[0], y[0]); 80 } 81 /// Post reified constraint on \a x 82 virtual void post(Space& home, SetVarArray& x, IntVarArray& y, 83 Reify r) { 84 Gecode::cardinality(home, x[0], y[0], r); 85 } 86 }; 87 Card _card("Int::Card"); 88 89 /// %Test for minimal element constraint 90 class Min : public SetTest { 91 public: 92 /// Create and register test 93 Min(const char* t) 94 : SetTest(t,1,ds_33,true,1) {} 95 /// %Test whether \a x is solution 96 virtual bool solution(const SetAssignment& x) const { 97 CountableSetRanges xr0(x.lub, x[0]); 98 return xr0() && xr0.min()==x.intval(); 99 } 100 /// Post constraint on \a x 101 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 102 Gecode::min(home, x[0], y[0]); 103 } 104 /// Post reified constraint on \a x 105 virtual void post(Space& home, SetVarArray& x, IntVarArray& y, 106 Reify r) { 107 Gecode::min(home, x[0], y[0], r); 108 } 109 }; 110 Min _min("Int::Min"); 111 112 /// %Test for negated minimal element constraint 113 class NotMin : public SetTest { 114 public: 115 /// Create and register test 116 NotMin(const char* t) 117 : SetTest(t,1,ds_33,false,1) {} 118 /// %Test whether \a x is solution 119 virtual bool solution(const SetAssignment& x) const { 120 CountableSetRanges xr0(x.lub, x[0]); 121 return !(xr0() && xr0.min()==x.intval()); 122 } 123 /// Post constraint on \a x 124 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 125 Gecode::notMin(home, x[0], y[0]); 126 } 127 }; 128 NotMin _notmin("Int::NotMin"); 129 130 /// %Test for maximal element constraint 131 class Max : public SetTest { 132 public: 133 /// Create and register test 134 Max(const char* t) 135 : SetTest(t,1,ds_33,true,1) {} 136 /// %Test whether \a x is solution 137 virtual bool solution(const SetAssignment& x) const { 138 CountableSetRanges xr0(x.lub, x[0]); 139 IntSet x0(xr0); 140 return x0.ranges() > 0 && x0.max()==x.intval(); 141 } 142 /// Post constraint on \a x 143 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 144 Gecode::max(home, x[0], y[0]); 145 } 146 /// Post reified constraint on \a x 147 virtual void post(Space& home, SetVarArray& x, IntVarArray& y, 148 Reify r) { 149 Gecode::max(home, x[0], y[0], r); 150 } 151 }; 152 Max _max("Int::Max"); 153 154 /// %Test for negated maximal element constraint 155 class NotMax : public SetTest { 156 public: 157 /// Create and register test 158 NotMax(const char* t) 159 : SetTest(t,1,ds_33,false,1) {} 160 /// %Test whether \a x is solution 161 virtual bool solution(const SetAssignment& x) const { 162 CountableSetRanges xr0(x.lub, x[0]); 163 IntSet x0(xr0); 164 return !(x0.ranges() > 0 && x0.max()==x.intval()); 165 } 166 /// Post constraint on \a x 167 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 168 Gecode::notMax(home, x[0], y[0]); 169 } 170 }; 171 NotMax _notmax("Int::NotMax"); 172 173 /// %Test for element constraint 174 class Elem : public SetTest { 175 public: 176 /// Create and register test 177 Elem(const char* t) 178 : SetTest(t,1,ds_33,true,1) {} 179 /// %Test whether \a x is solution 180 virtual bool solution(const SetAssignment& x) const { 181 for (CountableSetValues xr(x.lub, x[0]);xr();++xr) 182 if (xr.val()==x.intval()) 183 return true; 184 return false; 185 } 186 /// Post constraint on \a x 187 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 188 Gecode::rel(home, x[0], SRT_SUP, y[0]); 189 } 190 /// Post reified constraint on \a x for \a b 191 virtual void post(Space& home, SetVarArray& x, IntVarArray& y, 192 Reify r) { 193 Gecode::rel(home, x[0], SRT_SUP, y[0], r); 194 } 195 }; 196 Elem _elem("Int::Elem"); 197 198 /// %Test for negated element constraint 199 class NoElem : public SetTest { 200 public: 201 /// Create and register test 202 NoElem(const char* t) 203 : SetTest(t,1,ds_33,false,1) {} 204 /// %Test whether \a x is solution 205 virtual bool solution(const SetAssignment& x) const { 206 for (CountableSetValues xr(x.lub, x[0]);xr();++xr) 207 if (xr.val()==x.intval()) 208 return false; 209 return true; 210 } 211 /// Post constraint on \a x 212 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 213 Gecode::rel(home, x[0], SRT_DISJ, y[0]); 214 } 215 }; 216 NoElem _noelem("Int::NoElem"); 217 218 /// %Test for relation constraint 219 class Rel : public SetTest { 220 private: 221 /// The set relation type 222 Gecode::SetRelType srt; 223 /// Whether relation is swapped 224 bool swapped; 225 public: 226 /// Create and register test 227 Rel(Gecode::SetRelType srt0, bool s) 228 : SetTest("Int::Rel::"+str(srt0)+(s ? "::s" : ""), 229 1,ds_33,true,1), 230 srt(srt0), swapped(s) {} 231 /// %Test whether \a x is solution 232 virtual bool solution(const SetAssignment& x) const { 233 CountableSetRanges xr(x.lub, x[0]); 234 IntSet is(x.intval(), x.intval()); 235 IntSetRanges dr(is); 236 Gecode::SetRelType rsrt = srt; 237 if (swapped) { 238 switch (srt) { 239 case SRT_SUB: rsrt = SRT_SUP; break; 240 case SRT_SUP: rsrt = SRT_SUB; break; 241 default: break; 242 } 243 } 244 switch (rsrt) { 245 case SRT_EQ: return Iter::Ranges::equal(xr, dr); 246 case SRT_NQ: return !Iter::Ranges::equal(xr, dr); 247 case SRT_SUB: return Iter::Ranges::subset(xr, dr); 248 case SRT_SUP: return Iter::Ranges::subset(dr, xr); 249 case SRT_DISJ: 250 { 251 Gecode::Iter::Ranges::Inter<CountableSetRanges,IntSetRanges> 252 inter(xr, dr); 253 return !inter(); 254 } 255 case SRT_CMPL: 256 { 257 Gecode::Set::RangesCompl<IntSetRanges> drc(dr); 258 return Iter::Ranges::equal(xr,drc); 259 } 260 default: GECODE_NEVER; 261 } 262 return false; 263 } 264 /// Post constraint on \a x 265 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 266 if (!swapped) 267 Gecode::rel(home, x[0], srt, y[0]); 268 else 269 Gecode::rel(home, y[0], srt, x[0]); 270 } 271 /// Post reified constraint on \a x for \a r 272 virtual void post(Space& home, SetVarArray& x, IntVarArray& y, 273 Reify r) { 274 if (!swapped) 275 Gecode::rel(home, x[0], srt, y[0], r); 276 else 277 Gecode::rel(home, y[0], srt, x[0], r); 278 } 279 }; 280 Rel _rel_eq(Gecode::SRT_EQ,false); 281 Rel _rel_nq(Gecode::SRT_NQ,false); 282 Rel _rel_sub(Gecode::SRT_SUB,false); 283 Rel _rel_sup(Gecode::SRT_SUP,false); 284 Rel _rel_disj(Gecode::SRT_DISJ,false); 285 Rel _rel_cmpl(Gecode::SRT_CMPL,false); 286 Rel _rel_eqs(Gecode::SRT_EQ,true); 287 Rel _rel_nqs(Gecode::SRT_NQ,true); 288 Rel _rel_subs(Gecode::SRT_SUB,true); 289 Rel _rel_sups(Gecode::SRT_SUP,true); 290 Rel _rel_disjs(Gecode::SRT_DISJ,true); 291 Rel _rel_cmpls(Gecode::SRT_CMPL,true); 292 293 /// %Test for integer relation constraint 294 class IntRel : public SetTest { 295 private: 296 /// The integer relation type 297 Gecode::IntRelType irt; 298 /// Whether the arguments are swapped 299 bool swapped; 300 public: 301 /// Create and register test 302 IntRel(Gecode::IntRelType irt0, bool s) 303 : SetTest("Int::IntRel::"+Test::Int::Test::str(irt0)+ 304 (s ? "::s" : ""),1,ds_33,true,1), 305 irt(irt0), swapped(s) { 306 testsubsumed = false; 307 } 308 /// %Test whether \a x is solution 309 virtual bool solution(const SetAssignment& x) const { 310 CountableSetValues xr(x.lub, x[0]); 311 if (!xr()) 312 return false; 313 for (; xr(); ++xr) 314 switch (irt) { 315 case Gecode::IRT_EQ: 316 if (xr.val() != x.intval()) return false; 317 break; 318 case Gecode::IRT_NQ: 319 if (xr.val() == x.intval()) return false; 320 break; 321 case Gecode::IRT_GR: 322 if (!swapped && xr.val() <= x.intval()) return false; 323 if (swapped && xr.val() >= x.intval()) return false; 324 break; 325 case Gecode::IRT_GQ: 326 if (!swapped && xr.val() < x.intval()) return false; 327 if (swapped && xr.val() > x.intval()) return false; 328 break; 329 case Gecode::IRT_LE: 330 if (!swapped && xr.val() >= x.intval()) return false; 331 if (swapped && xr.val() <= x.intval()) return false; 332 break; 333 case Gecode::IRT_LQ: 334 if (!swapped && xr.val() > x.intval()) return false; 335 if (swapped && xr.val() < x.intval()) return false; 336 break; 337 default: 338 GECODE_NEVER; 339 return false; 340 } 341 return true; 342 } 343 /// Post constraint on \a x 344 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 345 if (!swapped) 346 Gecode::rel(home, x[0], irt, y[0]); 347 else 348 Gecode::rel(home, y[0], irt, x[0]); 349 } 350 /// Post reified constraint on \a x for \a r 351 virtual void post(Space& home, SetVarArray& x, IntVarArray& y, 352 Reify r) { 353 assert((x.size() == 1) && (y.size() == 1)); 354 if ((r.mode() != Gecode::RM_EQV) || (_rand(2) != 0)) { 355 if (!swapped) 356 Gecode::rel(home, x[0], irt, y[0], r); 357 else 358 Gecode::rel(home, y[0], irt, x[0], r); 359 } else if (swapped) { 360 switch (irt) { 361 case Gecode::IRT_EQ: 362 Gecode::rel(home, (y[0] == x[0]) == r.var()); break; 363 case Gecode::IRT_NQ: 364 Gecode::rel(home, (y[0] != x[0]) == r.var()); break; 365 case Gecode::IRT_LE: 366 Gecode::rel(home, (y[0] < x[0]) == r.var()); break; 367 case Gecode::IRT_LQ: 368 Gecode::rel(home, (y[0] <= x[0]) == r.var()); break; 369 case Gecode::IRT_GR: 370 Gecode::rel(home, (y[0] > x[0]) == r.var()); break; 371 case Gecode::IRT_GQ: 372 Gecode::rel(home, (y[0] >= x[0]) == r.var()); break; 373 default: GECODE_NEVER; 374 } 375 } else { 376 switch (irt) { 377 case Gecode::IRT_EQ: 378 Gecode::rel(home, (x[0] == y[0]) == r.var()); break; 379 case Gecode::IRT_NQ: 380 Gecode::rel(home, (x[0] != y[0]) == r.var()); break; 381 case Gecode::IRT_LE: 382 Gecode::rel(home, (x[0] < y[0]) == r.var()); break; 383 case Gecode::IRT_LQ: 384 Gecode::rel(home, (x[0] <= y[0]) == r.var()); break; 385 case Gecode::IRT_GR: 386 Gecode::rel(home, (x[0] > y[0]) == r.var()); break; 387 case Gecode::IRT_GQ: 388 Gecode::rel(home, (x[0] >= y[0]) == r.var()); break; 389 default: GECODE_NEVER; 390 } 391 } 392 } 393 }; 394 IntRel _intrel_eq(Gecode::IRT_EQ,false); 395 IntRel _intrel_nq(Gecode::IRT_NQ,false); 396 IntRel _intrel_gr(Gecode::IRT_GR,false); 397 IntRel _intrel_gq(Gecode::IRT_GQ,false); 398 IntRel _intrel_le(Gecode::IRT_LE,false); 399 IntRel _intrel_lq(Gecode::IRT_LQ,false); 400 IntRel _intrel_eqs(Gecode::IRT_EQ,true); 401 IntRel _intrel_nqs(Gecode::IRT_NQ,true); 402 IntRel _intrel_grs(Gecode::IRT_GR,true); 403 IntRel _intrel_gqs(Gecode::IRT_GQ,true); 404 IntRel _intrel_les(Gecode::IRT_LE,true); 405 IntRel _intrel_lqs(Gecode::IRT_LQ,true); 406 407 408 template<class I> 409 int weightI(const IntArgs& elements, 410 const IntArgs& weights, 411 I& iter) { 412 int sum = 0; 413 int i = 0; 414 for (Iter::Ranges::ToValues<I> v(iter); v(); ++v) { 415 // Skip all elements below the current 416 while (elements[i]<v.val()) i++; 417 assert(elements[i] == v.val()); 418 sum += weights[i]; 419 } 420 return sum; 421 } 422 423 /// %Test for set weight constraint 424 class Weights : public SetTest { 425 public: 426 IntArgs elements; 427 IntArgs weights; 428 int minWeight; 429 int maxWeight; 430 /// Create and register test 431 Weights(const char* t, IntArgs& el, IntArgs& w, 432 int min = -10000, int max = 10000) 433 : SetTest(t,1,ds_33,false,1), 434 elements(el), weights(w), minWeight(min), maxWeight(max) {} 435 /// %Test whether \a x is solution 436 virtual bool solution(const SetAssignment& x) const { 437 CountableSetRanges x0(x.lub, x[0]); 438 return x.intval()==weightI(elements,weights,x0) && 439 x.intval() >= minWeight && x.intval() <= maxWeight; 440 } 441 /// Post constraint on \a x 442 virtual void post(Space& home, SetVarArray& x, IntVarArray& y) { 443 Gecode::rel(home, minWeight <= y[0]); 444 Gecode::rel(home, maxWeight >= y[0]); 445 Gecode::weights(home, elements, weights, x[0], y[0]); 446 } 447 }; 448 449 const int el1v[] = {-3,-2,-1,0,1,2,3}; 450 IntArgs el1(7,el1v); 451 const int w1v[] = {1,-2,1,1,1,6,1}; 452 IntArgs w1(7,w1v); 453 Weights _weights1("Int::Weights::1", el1, w1); 454 455 const int w2v[] = {-1,-1,-1,10,-1,-1,-1}; 456 IntArgs w2(7,w2v); 457 Weights _weights2("Int::Weights::2", el1, w2); 458 Weights _weights3("Int::Weights::3", el1, w2, 3); 459 460 const int w4v[] = {1,1,0,0,0,0,0}; 461 IntArgs w4(7,w4v); 462 Weights _weights4("Int::Weights::4", el1, w4); 463 464}}} 465 466// STATISTICS: test-set