this repo has no description
at develop 29 kB view raw
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Mikael Lagerkvist <lagerkvist@gecode.org> 5 * Linnea Ingmar <linnea.ingmar@hotmail.com> 6 * Christian Schulte <schulte@gecode.org> 7 * 8 * Copyright: 9 * Linnea Ingmar, 2017 10 * Mikael Lagerkvist, 2007 11 * Christian Schulte, 2005 12 * 13 * This file is part of Gecode, the generic constraint 14 * development environment: 15 * http://www.gecode.org 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining 18 * a copy of this software and associated documentation files (the 19 * "Software"), to deal in the Software without restriction, including 20 * without limitation the rights to use, copy, modify, merge, publish, 21 * distribute, sublicense, and/or sell copies of the Software, and to 22 * permit persons to whom the Software is furnished to do so, subject to 23 * the following conditions: 24 * 25 * The above copyright notice and this permission notice shall be 26 * included in all copies or substantial portions of the Software. 27 * 28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 * 36 */ 37 38#include "test/int.hh" 39 40#include <gecode/minimodel.hh> 41#include <climits> 42 43namespace Test { namespace Int { 44 45 /// %Tests for extensional (relation) constraints 46 namespace Extensional { 47 48 /** 49 * \defgroup TaskTestIntExtensional Extensional (relation) constraints 50 * \ingroup TaskTestInt 51 */ 52 //@{ 53 /// %Test with simple regular expression 54 class RegSimpleA : public Test { 55 public: 56 /// Create and register test 57 RegSimpleA(void) : Test("Extensional::Reg::Simple::A",4,2,2) {} 58 /// %Test whether \a x is solution 59 virtual bool solution(const Assignment& x) const { 60 return (((x[0] == 0) || (x[0] == 2)) && 61 ((x[1] == -1) || (x[1] == 1)) && 62 ((x[2] == 0) || (x[2] == 1)) && 63 ((x[3] == 0) || (x[3] == 1))); 64 } 65 /// Post constraint on \a x 66 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 67 using namespace Gecode; 68 extensional(home, x, 69 (REG(0) | REG(2)) + 70 (REG(-1) | REG(1)) + 71 (REG(7) | REG(0) | REG(1)) + 72 (REG(0) | REG(1))); 73 } 74 }; 75 76 /// %Test with simple regular expression 77 class RegSimpleB : public Test { 78 public: 79 /// Create and register test 80 RegSimpleB(void) : Test("Extensional::Reg::Simple::B",4,2,2) {} 81 /// %Test whether \a x is solution 82 virtual bool solution(const Assignment& x) const { 83 return (x[0]<x[1]) && (x[1]<x[2]) && (x[2]<x[3]); 84 } 85 /// Post constraint on \a x 86 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 87 using namespace Gecode; 88 extensional(home, x, 89 (REG(-2) + REG(-1) + REG(0) + REG(1)) | 90 (REG(-2) + REG(-1) + REG(0) + REG(2)) | 91 (REG(-2) + REG(-1) + REG(1) + REG(2)) | 92 (REG(-2) + REG(0) + REG(1) + REG(2)) | 93 (REG(-1) + REG(0) + REG(1) + REG(2))); 94 } 95 }; 96 97 /// %Test with simple regular expression 98 class RegSimpleC : public Test { 99 public: 100 /// Create and register test 101 RegSimpleC(void) : Test("Extensional::Reg::Simple::C",6,0,1) {} 102 /// %Test whether \a x is solution 103 virtual bool solution(const Assignment& x) const { 104 int pos = 0; 105 int s = x.size(); 106 107 while (pos < s && x[pos] == 0) ++pos; 108 if (pos + 4 > s) return false; 109 110 for (int i = 0; i < 2; ++i, ++pos) 111 if (x[pos] != 1) return false; 112 if (pos + 2 > s) return false; 113 114 for (int i = 0; i < 1; ++i, ++pos) 115 if (x[pos] != 0) return false; 116 while (pos < s && x[pos] == 0) ++pos; 117 if (pos + 1 > s) return false; 118 119 for (int i = 0; i < 1; ++i, ++pos) 120 if (x[pos] != 1) return false; 121 while (pos < s) if (x[pos++] != 0) return false; 122 return true; 123 124 } 125 /// Post constraint on \a x 126 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 127 using namespace Gecode; 128 extensional(home, x, 129 *REG(0) + REG(1)(2,2) + +REG(0) + REG(1)(1,1) + *REG(0)); 130 } 131 }; 132 133 /// %Test with regular expression for distinct constraint 134 class RegDistinct : public Test { 135 public: 136 /// Create and register test 137 RegDistinct(void) : Test("Extensional::Reg::Distinct",4,-1,4) {} 138 /// %Test whether \a x is solution 139 virtual bool solution(const Assignment& x) const { 140 for (int i=0; i<x.size(); i++) { 141 if ((x[i] < 0) || (x[i] > 3)) 142 return false; 143 for (int j=i+1; j<x.size(); j++) 144 if (x[i]==x[j]) 145 return false; 146 } 147 return true; 148 } 149 /// Post constraint on \a x 150 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 151 using namespace Gecode; 152 extensional(home, x, 153 (REG(0)+REG(1)+REG(2)+REG(3)) | 154 (REG(0)+REG(1)+REG(3)+REG(2)) | 155 (REG(0)+REG(2)+REG(1)+REG(3)) | 156 (REG(0)+REG(2)+REG(3)+REG(1)) | 157 (REG(0)+REG(3)+REG(1)+REG(2)) | 158 (REG(0)+REG(3)+REG(2)+REG(1)) | 159 (REG(1)+REG(0)+REG(2)+REG(3)) | 160 (REG(1)+REG(0)+REG(3)+REG(2)) | 161 (REG(1)+REG(2)+REG(0)+REG(3)) | 162 (REG(1)+REG(2)+REG(3)+REG(0)) | 163 (REG(1)+REG(3)+REG(0)+REG(2)) | 164 (REG(1)+REG(3)+REG(2)+REG(0)) | 165 (REG(2)+REG(0)+REG(1)+REG(3)) | 166 (REG(2)+REG(0)+REG(3)+REG(1)) | 167 (REG(2)+REG(1)+REG(0)+REG(3)) | 168 (REG(2)+REG(1)+REG(3)+REG(0)) | 169 (REG(2)+REG(3)+REG(0)+REG(1)) | 170 (REG(2)+REG(3)+REG(1)+REG(0)) | 171 (REG(3)+REG(0)+REG(1)+REG(2)) | 172 (REG(3)+REG(0)+REG(2)+REG(1)) | 173 (REG(3)+REG(1)+REG(0)+REG(2)) | 174 (REG(3)+REG(1)+REG(2)+REG(0)) | 175 (REG(3)+REG(2)+REG(0)+REG(1)) | 176 (REG(3)+REG(2)+REG(1)+REG(0))); 177 } 178 }; 179 180 /// %Test with simple regular expression from Roland Yap 181 class RegRoland : public Test { 182 public: 183 /// Create and register test 184 RegRoland(int n) 185 : Test("Extensional::Reg::Roland::"+str(n),n,0,1) {} 186 /// %Test whether \a x is solution 187 virtual bool solution(const Assignment& x) const { 188 int n = x.size(); 189 return 190 ((n > 1) && (x[n-2] == 0)) || 191 ((n > 0) && (x[n-1] == 0)); 192 } 193 /// Post constraint on \a x 194 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 195 using namespace Gecode; 196 REG r0(0), r1(1); 197 REG r01 = r0 | r1; 198 extensional(home, x, *r01 + r0 + r01(0,1)); 199 } 200 }; 201 202 /// %Test with simple regular expression and shared variables (uses unsharing) 203 class RegSharedA : public Test { 204 public: 205 /// Create and register test 206 RegSharedA(void) : Test("Extensional::Reg::Shared::A",4,2,2) {} 207 /// %Test whether \a x is solution 208 virtual bool solution(const Assignment& x) const { 209 return (((x[0] == 0) || (x[0] == 2)) && 210 ((x[1] == -1) || (x[1] == 1)) && 211 ((x[2] == 0) || (x[2] == 1)) && 212 ((x[3] == 0) || (x[3] == 1))); 213 } 214 /// Post constraint on \a x 215 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 216 using namespace Gecode; 217 IntVarArgs y(8); 218 for (int i=0; i<4; i++) 219 y[i]=y[i+4]=x[i]; 220 unshare(home,y); 221 extensional(home, y, 222 ((REG(0) | REG(2)) + 223 (REG(-1) | REG(1)) + 224 (REG(7) | REG(0) | REG(1)) + 225 (REG(0) | REG(1)))(2,2)); 226 } 227 }; 228 229 /// %Test with simple regular expression and shared variables (uses unsharing) 230 class RegSharedB : public Test { 231 public: 232 /// Create and register test 233 RegSharedB(void) : Test("Extensional::Reg::Shared::B",4,2,2) {} 234 /// %Test whether \a x is solution 235 virtual bool solution(const Assignment& x) const { 236 return (((x[0] == 0) || (x[0] == 2)) && 237 ((x[1] == -1) || (x[1] == 1)) && 238 ((x[2] == 0) || (x[2] == 1)) && 239 ((x[3] == 0) || (x[3] == 1))); 240 } 241 /// Post constraint on \a x 242 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 243 using namespace Gecode; 244 IntVarArgs y(12); 245 for (int i=0; i<4; i++) 246 y[i]=y[i+4]=y[i+8]=x[i]; 247 unshare(home,y); 248 extensional(home, y, 249 ((REG(0) | REG(2)) + 250 (REG(-1) | REG(1)) + 251 (REG(7) | REG(0) | REG(1)) + 252 (REG(0) | REG(1)))(3,3)); 253 } 254 }; 255 256 /// %Test with simple regular expression and shared variables (uses unsharing) 257 class RegSharedC : public Test { 258 public: 259 /// Create and register test 260 RegSharedC(void) : Test("Extensional::Reg::Shared::C",4,0,1) {} 261 /// %Test whether \a x is solution 262 virtual bool solution(const Assignment& x) const { 263 return (x[1]==1) && (x[2]==0) && (x[3]==1); 264 } 265 /// Post constraint on \a x 266 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 267 using namespace Gecode; 268 Gecode::BoolVarArgs y(8); 269 for (int i=0; i<4; i++) 270 y[i]=y[i+4]=channel(home,x[i]); 271 unshare(home,y); 272 extensional(home,y, 273 ((REG(0) | REG(1)) + REG(1) + REG(0) + REG(1))(2,2)); 274 } 275 }; 276 277 /// %Test with simple regular expression and shared variables (uses unsharing) 278 class RegSharedD : public Test { 279 public: 280 /// Create and register test 281 RegSharedD(void) : Test("Extensional::Reg::Shared::D",4,0,1) {} 282 /// %Test whether \a x is solution 283 virtual bool solution(const Assignment& x) const { 284 return (x[1]==1) && (x[2]==0) && (x[3]==1); 285 } 286 /// Post constraint on \a x 287 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 288 using namespace Gecode; 289 Gecode::BoolVarArgs y(12); 290 for (int i=0; i<4; i++) 291 y[i]=y[i+4]=y[i+8]=channel(home,x[i]); 292 unshare(home, y); 293 extensional(home, y, 294 ((REG(0) | REG(1)) + REG(1) + REG(0) + REG(1))(3,3)); 295 } 296 }; 297 298 /// %Test for empty DFA 299 class RegEmptyDFA : public Test { 300 public: 301 /// Create and register test 302 RegEmptyDFA(void) : Test("Extensional::Reg::Empty::DFA",1,0,0) { 303 testsearch = false; 304 } 305 /// %Test whether \a x is solution 306 virtual bool solution(const Assignment& x) const { 307 (void)x; 308 return false; 309 } 310 /// Post constraint on \a x 311 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 312 Gecode::DFA d; 313 Gecode::extensional(home, x, d); 314 } 315 }; 316 317 /// %Test for empty regular expression 318 class RegEmptyREG : public Test { 319 public: 320 /// Create and register test 321 RegEmptyREG(void) : Test("Extensional::Reg::Empty::REG",1,0,0) { 322 testsearch = false; 323 } 324 /// %Test whether \a x is solution 325 virtual bool solution(const Assignment& x) const { 326 (void)x; 327 return false; 328 } 329 /// Post constraint on \a x 330 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 331 Gecode::REG r; 332 Gecode::extensional(home, x, r); 333 } 334 }; 335 336 /// %Test for optimizations 337 class RegOpt : public Test { 338 protected: 339 /// DFA size characteristic 340 int n; 341 public: 342 /// Create and register test 343 RegOpt(int n0) 344 : Test("Extensional::Reg::Opt::"+str(n0),1,0,15), n(n0) {} 345 /// %Test whether \a x is solution 346 virtual bool solution(const Assignment& x) const { 347 return (x[0] < n) && ((x[0] & 1) == 0); 348 } 349 /// Post constraint on \a x 350 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 351 using namespace Gecode; 352 DFA::Transition* t = new DFA::Transition[n+1]; 353 DFA::Transition* ti = t; 354 int* f = new int[n+1]; 355 int* fi = f; 356 for (int i=0; i<n; i++) { 357 ti->i_state = 0; 358 ti->symbol = i; 359 ti->o_state = i+1; 360 ti++; 361 if ((i & 1) == 0) { 362 *fi = i+1; fi++; 363 } 364 } 365 ti->i_state = -1; 366 *fi = -1; 367 DFA d(0, t, f, false); 368 delete [] t; 369 delete [] f; 370 extensional(home, x, d); 371 } 372 373 }; 374 375 ///% Transform a TupleSet into a DFA 376 Gecode::DFA tupleset2dfa(Gecode::TupleSet ts) { 377 using namespace Gecode; 378 REG expression; 379 for (int i = 0; i<ts.tuples(); i++) { 380 REG r; 381 for (int j = 0; j<ts.arity(); j++) { 382 r += REG(ts[i][j]); 383 } 384 expression |= r; 385 } 386 DFA dfa(expression); 387 return dfa; 388 } 389 390 /// %Test with tuple set 391 class TupleSetBase : public Test { 392 protected: 393 /// Simple test tupleset 394 Gecode::TupleSet t; 395 /// Whether the table is positive or negative 396 bool pos; 397 public: 398 /// Create and register test 399 TupleSetBase(bool p) 400 : Test("Extensional::TupleSet::" + str(p) + "::Base", 401 4,1,5,true,Gecode::IPL_DOM), t(4), pos(p) { 402 using namespace Gecode; 403 IntArgs t1({2, 1, 2, 4}); 404 IntArgs t2({2, 2, 1, 4}); 405 IntArgs t3({4, 3, 4, 1}); 406 IntArgs t4({1, 3, 2, 3}); 407 IntArgs t5({3, 3, 3, 2}); 408 t.add(t1).add(t1).add(t2).add(t2) 409 .add(t3).add(t3).add(t4).add(t4) 410 .add(t5).add(t5).add(t5).add(t5) 411 .add(t5).add(t5).add(t5).add(t5) 412 .add(t1).add(t1).add(t2).add(t2) 413 .add(t3).add(t3).add(t4).add(t4) 414 .add(t5).add(t5).add(t5).add(t5) 415 .add(t5).add(t5).add(t5).add(t5) 416 .finalize(); 417 } 418 /// %Test whether \a x is solution 419 virtual bool solution(const Assignment& x) const { 420 return pos == ((x[0] == 1 && x[1] == 3 && x[2] == 2 && x[3] == 3) || 421 (x[0] == 2 && x[1] == 1 && x[2] == 2 && x[3] == 4) || 422 (x[0] == 2 && x[1] == 2 && x[2] == 1 && x[3] == 4) || 423 (x[0] == 3 && x[1] == 3 && x[2] == 3 && x[3] == 2) || 424 (x[0] == 4 && x[1] == 3 && x[2] == 4 && x[3] == 1)); 425 } 426 /// Post constraint on \a x 427 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 428 using namespace Gecode; 429 TupleSet ts = TupleSet(t.arity(),tupleset2dfa(t)); 430 assert(t == ts); 431 extensional(home, x, t, pos, ipl); 432 } 433 /// Post reified constraint on \a x for \a r 434 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x, 435 Gecode::Reify r) { 436 extensional(home, x, t, pos, r, ipl); 437 } 438 }; 439 440 /// %Test with tuple set 441 class TupleSetTest : public Test { 442 protected: 443 /// Whether the table is positive or negative 444 bool pos; 445 /// The tuple set to use 446 Gecode::TupleSet ts; 447 /// Whether to validate dfa2tupleset 448 bool toDFA; 449 public: 450 /// Create and register test 451 TupleSetTest(const std::string& s, bool p, 452 Gecode::IntSet d0, Gecode::TupleSet ts0, bool td) 453 : Test("Extensional::TupleSet::" + str(p) + "::" + s, 454 ts0.arity(),d0,true,Gecode::IPL_DOM), 455 pos(p), ts(ts0), toDFA(td) { 456 } 457 /// %Test whether \a x is solution 458 virtual bool solution(const Assignment& x) const { 459 using namespace Gecode; 460 for (int i=ts.tuples(); i--; ) { 461 TupleSet::Tuple t = ts[i]; 462 bool same = true; 463 for (int j=0; (j < ts.arity()) && same; j++) 464 if (t[j] != x[j]) 465 same = false; 466 if (same) 467 return pos; 468 } 469 return !pos; 470 } 471 /// Post constraint on \a x 472 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 473 using namespace Gecode; 474 if (toDFA) { 475 TupleSet t = TupleSet(ts.arity(),tupleset2dfa(ts)); 476 assert(ts == t); 477 } 478 extensional(home, x, ts, pos, ipl); 479 } 480 /// Post reified constraint on \a x for \a r 481 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x, 482 Gecode::Reify r) { 483 using namespace Gecode; 484 extensional(home, x, ts, pos, r, ipl); 485 } 486 }; 487 488 class RandomTupleSetTest : public TupleSetTest { 489 public: 490 /// Create and register test 491 RandomTupleSetTest(const std::string& s, bool p, 492 Gecode::IntSet d0, Gecode::TupleSet ts0) 493 : TupleSetTest(s,p,d0,ts0,false) { 494 testsearch = false; 495 } 496 /// Create and register initial assignment 497 virtual Assignment* assignment(void) const { 498 using namespace Gecode; 499 return new RandomAssignment(arity,dom,1000); 500 } 501 }; 502 503 /// %Test with large tuple set 504 class TupleSetLarge : public Test { 505 protected: 506 /// Whether the table is positive or negative 507 bool pos; 508 /// Tupleset used for testing 509 mutable Gecode::TupleSet t; 510 public: 511 /// Create and register test 512 TupleSetLarge(double prob, bool p) 513 : Test("Extensional::TupleSet::" + str(p) + "::Large", 514 5,1,5,true,Gecode::IPL_DOM), pos(p), t(5) { 515 using namespace Gecode; 516 517 CpltAssignment ass(5, IntSet(1, 5)); 518 while (ass()) { 519 if (Base::rand(100) <= prob*100) { 520 IntArgs tuple(5); 521 for (int i = 5; i--; ) tuple[i] = ass[i]; 522 t.add(tuple); 523 } 524 ++ass; 525 } 526 t.finalize(); 527 } 528 /// %Test whether \a x is solution 529 virtual bool solution(const Assignment& x) const { 530 using namespace Gecode; 531 for (int i = 0; i < t.tuples(); ++i) { 532 TupleSet::Tuple l = t[i]; 533 bool same = true; 534 for (int j = 0; j < t.arity() && same; ++j) 535 if (l[j] != x[j]) same = false; 536 if (same) 537 return pos; 538 } 539 return !pos; 540 } 541 /// Post constraint on \a x 542 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 543 using namespace Gecode; 544 extensional(home, x, t, pos, ipl); 545 } 546 /// Post reified constraint on \a x for \a r 547 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x, 548 Gecode::Reify r) { 549 using namespace Gecode; 550 extensional(home, x, t, pos, r, ipl); 551 } 552 }; 553 554 /// %Test with bool tuple set 555 class TupleSetBool : public Test { 556 protected: 557 /// Whether the table is positive or negative 558 bool pos; 559 /// Tupleset used for testing 560 mutable Gecode::TupleSet t; 561 public: 562 /// Create and register test 563 TupleSetBool(double prob, bool p) 564 : Test("Extensional::TupleSet::" + str(p) + "::Bool", 565 5,0,1,true), pos(p), t(5) { 566 using namespace Gecode; 567 568 CpltAssignment ass(5, IntSet(0, 1)); 569 while (ass()) { 570 if (Base::rand(100) <= prob*100) { 571 IntArgs tuple(5); 572 for (int i = 5; i--; ) tuple[i] = ass[i]; 573 t.add(tuple); 574 } 575 ++ass; 576 } 577 t.finalize(); 578 } 579 /// %Test whether \a x is solution 580 virtual bool solution(const Assignment& x) const { 581 using namespace Gecode; 582 for (int i = 0; i < t.tuples(); ++i) { 583 TupleSet::Tuple l = t[i]; 584 bool same = true; 585 for (int j = 0; j < t.arity() && same; ++j) 586 if (l[j] != x[j]) 587 same = false; 588 if (same) 589 return pos; 590 } 591 return !pos; 592 } 593 /// Post constraint on \a x 594 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x) { 595 using namespace Gecode; 596 BoolVarArgs y(x.size()); 597 for (int i = x.size(); i--; ) 598 y[i] = channel(home, x[i]); 599 extensional(home, y, t, pos, ipl); 600 } 601 /// Post reified constraint on \a x for \a r 602 virtual void post(Gecode::Space& home, Gecode::IntVarArray& x, 603 Gecode::Reify r) { 604 using namespace Gecode; 605 BoolVarArgs y(x.size()); 606 for (int i = x.size(); i--; ) 607 y[i] = channel(home, x[i]); 608 extensional(home, y, t, pos, r, ipl); 609 } 610 }; 611 612 /// Help class to create and register tests with a fixed table size 613 class TupleSetTestSize { 614 public: 615 /// Perform creation and registration 616 TupleSetTestSize(int size, bool pos) { 617 using namespace Gecode; 618 /// Find the arity needed for creating sufficient number of tuples 619 int arity = 2; 620 int n_tuples = 5*5; 621 while (n_tuples < size) { 622 arity++; 623 n_tuples*=5; 624 } 625 /// Build TupleSet 626 TupleSet ts(arity); 627 CpltAssignment ass(arity, IntSet(0, 4)); 628 for (int i = size; i--; ) { 629 assert(ass()); 630 IntArgs tuple(arity); 631 for (int j = arity; j--; ) tuple[j] = ass[j]; 632 ts.add(tuple); 633 ++ass; 634 } 635 ts.finalize(); 636 assert(ts.tuples() == size); 637 // Create and register test 638 (void) new TupleSetTest(std::to_string(size),pos,IntSet(0,4),ts, 639 size <= 128); 640 } 641 }; 642 643 Gecode::TupleSet randomTupleSet(int n, int min, int max, double prob) { 644 using namespace Gecode; 645 TupleSet t(n); 646 CpltAssignment ass(n, IntSet(min, max)); 647 while (ass()) { 648 if (Base::rand(100) <= prob*100) { 649 IntArgs tuple(n); 650 for (int i = n; i--; ) tuple[i] = ass[i]; 651 t.add(tuple); 652 } 653 ++ass; 654 } 655 t.finalize(); 656 return t; 657 } 658 659 /// Help class to create and register tests 660 class Create { 661 public: 662 /// Perform creation and registration 663 Create(void) { 664 using namespace Gecode; 665 for (bool pos : { false, true }) { 666 { 667 TupleSet ts(4); 668 ts.add({2, 1, 2, 4}).add({2, 2, 1, 4}) 669 .add({4, 3, 4, 1}).add({1, 3, 2, 3}) 670 .add({3, 3, 3, 2}).add({5, 1, 4, 4}) 671 .add({2, 5, 1, 5}).add({4, 3, 5, 1}) 672 .add({1, 5, 2, 5}).add({5, 3, 3, 2}) 673 .finalize(); 674 (void) new TupleSetTest("A",pos,IntSet(0,6),ts,true); 675 } 676 { 677 TupleSet ts(4); 678 ts.finalize(); 679 (void) new TupleSetTest("Empty",pos,IntSet(1,2),ts,true); 680 } 681 { 682 TupleSet ts(4); 683 for (int n=1024*16; n--; ) 684 ts.add({1,2,3,4}); 685 ts.finalize(); 686 (void) new TupleSetTest("Assigned",pos,IntSet(1,4),ts,true); 687 } 688 { 689 TupleSet ts(1); 690 ts.add({1}).add({2}).add({3}).finalize(); 691 (void) new TupleSetTest("Single",pos,IntSet(-4,4),ts,true); 692 } 693 { 694 int m = Gecode::Int::Limits::min; 695 TupleSet ts(3); 696 ts.add({m+0,m+1,m+2}).add({m+4,m+1,m+3}) 697 .add({m+2,m+3,m+0}).add({m+2,m+3,m+0}) 698 .add({m+1,m+2,m+5}).add({m+2,m+3,m+0}) 699 .add({m+3,m+6,m+5}).finalize(); 700 (void) new TupleSetTest("Min",pos,IntSet(m,m+7),ts,true); 701 } 702 { 703 int M = Gecode::Int::Limits::max; 704 TupleSet ts(3); 705 ts.add({M-0,M-1,M-2}).add({M-4,M-1,M-3}) 706 .add({M-2,M-3,M-0}).add({M-2,M-3,M-0}) 707 .add({M-1,M-2,M-5}).add({M-2,M-3,M-0}) 708 .add({M-3,M-6,M-5}).finalize(); 709 (void) new TupleSetTest("Max",pos,IntSet(M-7,M),ts,true); 710 } 711 { 712 int m = Gecode::Int::Limits::min; 713 int M = Gecode::Int::Limits::max; 714 TupleSet ts(3); 715 ts.add({M-0,m+1,M-2}).add({m+4,M-1,M-3}) 716 .add({m+2,M-3,m+0}).add({M-2,M-3,M-0}) 717 .finalize(); 718 (void) new TupleSetTest("MinMax",pos, 719 IntSet(IntArgs({m,m+1,m+4,M-3,M-2,M})), 720 ts,true); 721 } 722 { 723 TupleSet ts(7); 724 for (int i = 0; i < 10000; i++) { 725 IntArgs tuple(7); 726 for (int j = 0; j < 7; j++) { 727 tuple[j] = Base::rand(j+1); 728 } 729 ts.add(tuple); 730 } 731 ts.finalize(); 732 (void) new RandomTupleSetTest("Triangle",pos,IntSet(0,6),ts); 733 } 734 { 735 for (int i = 0; i <= 64*6; i+=32) 736 (void) new TupleSetTestSize(i,pos); 737 } 738 { 739 (void) new RandomTupleSetTest("Rand(10,-1,2)", pos, 740 IntSet(-1,2), 741 randomTupleSet(10,-1,2,0.05)); 742 (void) new RandomTupleSetTest("Rand(5,-10,10)", pos, 743 IntSet(-10,10), 744 randomTupleSet(5,-10,10,0.05)); 745 } 746 { 747 TupleSet t(5); 748 CpltAssignment ass(4, IntSet(1, 4)); 749 while (ass()) { 750 IntArgs tuple(5); 751 tuple[4] = 1; 752 for (int i = 4; i--; ) tuple[i] = ass[i]; 753 t.add(tuple); 754 ++ass; 755 } 756 t.add({2,2,4,3,4}); 757 t.finalize(); 758 (void) new TupleSetTest("FewLast",pos,IntSet(1,4),t,false); 759 } 760 { 761 TupleSet t(4); 762 CpltAssignment ass(4, IntSet(1, 6)); 763 while (ass()) { 764 t.add({ass[0],0,ass[1],ass[2]}); 765 ++ass; 766 } 767 t.add({2,-1,3,4}); 768 t.finalize(); 769 (void) new TupleSetTest("FewMiddle",pos,IntSet(-1,6),t,false); 770 } 771 { 772 TupleSet t(10); 773 CpltAssignment ass(9, IntSet(1, 4)); 774 while (ass()) { 775 if (Base::rand(100) <= 0.25*100) { 776 IntArgs tuple(10); 777 tuple[0] = 2; 778 for (int i = 9; i--; ) tuple[i+1] = ass[i]; 779 t.add(tuple); 780 } 781 ++ass; 782 } 783 t.add({1,1,1,1,1,1,1,1,1,1}); 784 t.add({1,2,3,4,4,2,1,2,3,3}); 785 t.finalize(); 786 (void) new RandomTupleSetTest("FewHuge",pos,IntSet(1,4),t); 787 } 788 (void) new TupleSetBase(pos); 789 (void) new TupleSetLarge(0.05,pos); 790 (void) new TupleSetBool(0.3,pos); 791 } 792 } 793 }; 794 795 Create c; 796 797 RegSimpleA ra; 798 RegSimpleB rb; 799 RegSimpleC rc; 800 801 RegDistinct rd; 802 803 RegRoland rr1(1); 804 RegRoland rr2(2); 805 RegRoland rr3(3); 806 RegRoland rr4(4); 807 808 RegSharedA rsa; 809 RegSharedB rsb; 810 RegSharedC rsc; 811 RegSharedD rsd; 812 813 RegEmptyDFA redfa; 814 RegEmptyREG rereg; 815 816 RegOpt ro0(CHAR_MAX-1); 817 RegOpt ro1(CHAR_MAX); 818 RegOpt ro2(static_cast<int>(UCHAR_MAX-1)); 819 RegOpt ro3(static_cast<int>(UCHAR_MAX)); 820 RegOpt ro4(SHRT_MAX-1); 821 RegOpt ro5(SHRT_MAX); 822 RegOpt ro6(static_cast<int>(USHRT_MAX-1)); 823 RegOpt ro7(static_cast<int>(USHRT_MAX)); 824 //@} 825 826 } 827}} 828 829 830// STATISTICS: test-int