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, _rand); 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.has_more()) { 519 if (_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.next(_rand); 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.has_more()) { 570 if (_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.next(_rand); 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, Gecode::Support::RandomGenerator& rand) { 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.has_more()); 630 IntArgs tuple(arity); 631 for (int j = arity; j--; ) tuple[j] = ass[j]; 632 ts.add(tuple); 633 ass.next(rand); 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, Gecode::Support::RandomGenerator& rand) { 644 using namespace Gecode; 645 TupleSet t(n); 646 CpltAssignment ass(n, IntSet(min, max)); 647 while (ass.has_more()) { 648 if (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.next(rand); 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 // This code is executed on load, and thus a random number generator source from the supplied 665 // seed is not available. 666 // In order to get interesting data her, but still have deterministic and repeatable execution, a fixed seed 667 // is used for a local random number generator. 668 // TODO: Make this code later on test run, and use the supplied seed/random number generator. 669 Gecode::Support::RandomGenerator rand(42); 670 671 using namespace Gecode; 672 for (bool pos : { false, true }) { 673 { 674 TupleSet ts(4); 675 ts.add({2, 1, 2, 4}).add({2, 2, 1, 4}) 676 .add({4, 3, 4, 1}).add({1, 3, 2, 3}) 677 .add({3, 3, 3, 2}).add({5, 1, 4, 4}) 678 .add({2, 5, 1, 5}).add({4, 3, 5, 1}) 679 .add({1, 5, 2, 5}).add({5, 3, 3, 2}) 680 .finalize(); 681 (void) new TupleSetTest("A",pos,IntSet(0,6),ts,true); 682 } 683 { 684 TupleSet ts(4); 685 ts.finalize(); 686 (void) new TupleSetTest("Empty",pos,IntSet(1,2),ts,true); 687 } 688 { 689 TupleSet ts(4); 690 for (int n=1024*16; n--; ) 691 ts.add({1,2,3,4}); 692 ts.finalize(); 693 (void) new TupleSetTest("Assigned",pos,IntSet(1,4),ts,true); 694 } 695 { 696 TupleSet ts(1); 697 ts.add({1}).add({2}).add({3}).finalize(); 698 (void) new TupleSetTest("Single",pos,IntSet(-4,4),ts,true); 699 } 700 { 701 int m = Gecode::Int::Limits::min; 702 TupleSet ts(3); 703 ts.add({m+0,m+1,m+2}).add({m+4,m+1,m+3}) 704 .add({m+2,m+3,m+0}).add({m+2,m+3,m+0}) 705 .add({m+1,m+2,m+5}).add({m+2,m+3,m+0}) 706 .add({m+3,m+6,m+5}).finalize(); 707 (void) new TupleSetTest("Min",pos,IntSet(m,m+7),ts,true); 708 } 709 { 710 int M = Gecode::Int::Limits::max; 711 TupleSet ts(3); 712 ts.add({M-0,M-1,M-2}).add({M-4,M-1,M-3}) 713 .add({M-2,M-3,M-0}).add({M-2,M-3,M-0}) 714 .add({M-1,M-2,M-5}).add({M-2,M-3,M-0}) 715 .add({M-3,M-6,M-5}).finalize(); 716 (void) new TupleSetTest("Max",pos,IntSet(M-7,M),ts,true); 717 } 718 { 719 int m = Gecode::Int::Limits::min; 720 int M = Gecode::Int::Limits::max; 721 TupleSet ts(3); 722 ts.add({M-0,m+1,M-2}).add({m+4,M-1,M-3}) 723 .add({m+2,M-3,m+0}).add({M-2,M-3,M-0}) 724 .finalize(); 725 (void) new TupleSetTest("MinMax",pos, 726 IntSet(IntArgs({m,m+1,m+4,M-3,M-2,M})), 727 ts,true); 728 } 729 { 730 TupleSet ts(7); 731 for (int i = 0; i < 10000; i++) { 732 IntArgs tuple(7); 733 for (int j = 0; j < 7; j++) { 734 tuple[j] = rand(j+1); 735 } 736 ts.add(tuple); 737 } 738 ts.finalize(); 739 (void) new RandomTupleSetTest("Triangle",pos,IntSet(0,6),ts); 740 } 741 { 742 for (int i = 0; i <= 64*6; i+=32) 743 (void) new TupleSetTestSize(i, pos, rand); 744 } 745 { 746 (void) new RandomTupleSetTest("Rand(10,-1,2)", pos, 747 IntSet(-1,2), 748 randomTupleSet(10, -1, 2, 0.05, rand)); 749 (void) new RandomTupleSetTest("Rand(5,-10,10)", pos, 750 IntSet(-10,10), 751 randomTupleSet(5, -10, 10, 0.05, rand)); 752 } 753 { 754 TupleSet t(5); 755 CpltAssignment ass(4, IntSet(1, 4)); 756 while (ass.has_more()) { 757 IntArgs tuple(5); 758 tuple[4] = 1; 759 for (int i = 4; i--; ) tuple[i] = ass[i]; 760 t.add(tuple); 761 ass.next(rand); 762 } 763 t.add({2,2,4,3,4}); 764 t.finalize(); 765 (void) new TupleSetTest("FewLast",pos,IntSet(1,4),t,false); 766 } 767 { 768 TupleSet t(4); 769 CpltAssignment ass(4, IntSet(1, 6)); 770 while (ass.has_more()) { 771 t.add({ass[0],0,ass[1],ass[2]}); 772 ass.next(rand); 773 } 774 t.add({2,-1,3,4}); 775 t.finalize(); 776 (void) new TupleSetTest("FewMiddle",pos,IntSet(-1,6),t,false); 777 } 778 { 779 TupleSet t(10); 780 CpltAssignment ass(9, IntSet(1, 4)); 781 while (ass.has_more()) { 782 if (rand(100) <= 0.25*100) { 783 IntArgs tuple(10); 784 tuple[0] = 2; 785 for (int i = 9; i--; ) tuple[i+1] = ass[i]; 786 t.add(tuple); 787 } 788 ass.next(rand); 789 } 790 t.add({1,1,1,1,1,1,1,1,1,1}); 791 t.add({1,2,3,4,4,2,1,2,3,3}); 792 t.finalize(); 793 (void) new RandomTupleSetTest("FewHuge",pos,IntSet(1,4),t); 794 } 795 (void) new TupleSetBase(pos); 796 (void) new TupleSetLarge(0.05,pos); 797 (void) new TupleSetBool(0.3,pos); 798 } 799 } 800 }; 801 802 Create c; 803 804 RegSimpleA ra; 805 RegSimpleB rb; 806 RegSimpleC rc; 807 808 RegDistinct rd; 809 810 RegRoland rr1(1); 811 RegRoland rr2(2); 812 RegRoland rr3(3); 813 RegRoland rr4(4); 814 815 RegSharedA rsa; 816 RegSharedB rsb; 817 RegSharedC rsc; 818 RegSharedD rsd; 819 820 RegEmptyDFA redfa; 821 RegEmptyREG rereg; 822 823 RegOpt ro0(CHAR_MAX-1); 824 RegOpt ro1(CHAR_MAX); 825 RegOpt ro2(static_cast<int>(UCHAR_MAX-1)); 826 RegOpt ro3(static_cast<int>(UCHAR_MAX)); 827 RegOpt ro4(SHRT_MAX-1); 828 RegOpt ro5(SHRT_MAX); 829 RegOpt ro6(static_cast<int>(USHRT_MAX-1)); 830 RegOpt ro7(static_cast<int>(USHRT_MAX)); 831 //@} 832 833 } 834}} 835 836 837// STATISTICS: test-int