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
36using namespace Gecode;
37
38namespace Test { namespace Set {
39
40 /// %Tests for relation/operation constraints
41 namespace RelOp {
42
43 /**
44 * \defgroup TaskTestSetRelOp Relation/operation constraints
45 * \ingroup TaskTestSet
46 */
47 //@{
48
49 static IntSet ds_22(-2,2);
50 static IntSet ds_12(-1,2);
51
52 /// %Test for ternary relation constraint
53 class Rel : public SetTest {
54 private:
55 Gecode::SetOpType sot;
56 Gecode::SetRelType srt;
57 int share;
58
59 template<class I, class J>
60 bool
61 sol(I& i, J& j) const {
62 switch (srt) {
63 case SRT_EQ: return Iter::Ranges::equal(i,j);
64 case SRT_NQ: return !Iter::Ranges::equal(i,j);
65 case SRT_SUB: return Iter::Ranges::subset(i,j);
66 case SRT_SUP: return Iter::Ranges::subset(j,i);
67 case SRT_DISJ:
68 {
69 Gecode::Iter::Ranges::Inter<I,J> inter(i,j);
70 return !inter();
71 }
72 case SRT_CMPL:
73 {
74 Gecode::Set::RangesCompl<J> jc(j);
75 return Iter::Ranges::equal(i,jc);
76 }
77 default: GECODE_NEVER;
78 }
79 return false;
80 }
81
82 public:
83 /// Create and register test
84 Rel(Gecode::SetOpType sot0, Gecode::SetRelType srt0, int share0=0)
85 : SetTest("RelOp::"+str(sot0)+"::"+str(srt0)+"::S"+str(share0),
86 share0 == 0 ? 3 : 2,ds_22,false)
87 , sot(sot0), srt(srt0), share(share0) {}
88 /// %Test whether \a x is solution
89 bool solution(const SetAssignment& x) const {
90 int a=0, b=0, c=0;
91 switch (share) {
92 case 0: a=x[0]; b=x[1]; c=x[2]; break;
93 case 1: a=x[0]; b=x[0]; c=x[0]; break;
94 case 2: a=x[0]; b=x[0]; c=x[1]; break;
95 case 3: a=x[0]; b=x[1]; c=x[0]; break;
96 case 4: a=x[0]; b=x[1]; c=x[1]; break;
97 }
98 CountableSetRanges xr0(x.lub, a);
99 CountableSetRanges xr1(x.lub, b);
100 CountableSetRanges xr2(x.lub, c);
101 switch (sot) {
102 case SOT_UNION:
103 {
104 Iter::Ranges::Union<CountableSetRanges, CountableSetRanges>
105 u(xr0,xr1);
106 return sol(u,xr2);
107 }
108 break;
109 case SOT_DUNION:
110 {
111 Iter::Ranges::Inter<CountableSetRanges, CountableSetRanges>
112 inter(xr0,xr1);
113 if (inter())
114 return false;
115 Iter::Ranges::Union<CountableSetRanges, CountableSetRanges>
116 u(xr0,xr1);
117 return sol(u,xr2);
118 }
119 break;
120 case SOT_INTER:
121 {
122 Iter::Ranges::Inter<CountableSetRanges, CountableSetRanges>
123 u(xr0,xr1);
124 return sol(u,xr2);
125 }
126 break;
127 case SOT_MINUS:
128 {
129 Iter::Ranges::Diff<CountableSetRanges, CountableSetRanges>
130 u(xr0,xr1);
131 return sol(u,xr2);
132 }
133 break;
134 default: GECODE_NEVER;
135 }
136 GECODE_NEVER;
137 return false;
138 }
139 /// Post constraint on \a x
140 void post(Space& home, SetVarArray& x, IntVarArray&) {
141 SetVar a,b,c;
142 switch (share) {
143 case 0: a=x[0]; b=x[1]; c=x[2]; break;
144 case 1: a=x[0]; b=x[0]; c=x[0]; break;
145 case 2: a=x[0]; b=x[0]; c=x[1]; break;
146 case 3: a=x[0]; b=x[1]; c=x[0]; break;
147 case 4: a=x[0]; b=x[1]; c=x[1]; break;
148 }
149 Gecode::rel(home, a, sot, b, srt, c);
150 }
151 };
152
153 /// Help class to create and register tests
154 class Create {
155 public:
156 /// Perform creation and registration
157 Create(void) {
158 using namespace Gecode;
159 for (SetRelTypes srts; srts(); ++srts) {
160 for (SetOpTypes sots; sots(); ++sots) {
161 for (int i=0; i<=4; i++) {
162 (void) new Rel(sots.sot(),srts.srt(),i);
163 }
164 }
165 }
166 }
167 };
168
169 Create c;
170
171 /// %Test for n-ary partition constraint
172 class RelN : public SetTest {
173 private:
174 Gecode::SetOpType sot;
175 int n;
176 int shared;
177 bool withConst;
178 IntSet is;
179 public:
180 /// Create and register test
181 RelN(Gecode::SetOpType sot0, int n0, int shared0, bool withConst0)
182 : SetTest("RelOp::N::"+str(sot0)+"::"+str(n0)+"::S"+str(shared0)+
183 "::C"+str(withConst0 ? 1 : 0),
184 shared0 == 0 ? n0+1 : (shared0 <= 2 ? 3 : 2),ds_12,false)
185 , sot(sot0), n(n0), shared(shared0), withConst(withConst0)
186 , is(0,1) {
187 }
188 /// %Test whether \a x is solution
189 bool solution(const SetAssignment& x) const {
190 int realN = shared == 0 ? n : 3;
191
192 CountableSetRanges* isrs = new CountableSetRanges[realN];
193
194 switch (shared) {
195 case 0:
196 for (int i=realN; i--; )
197 isrs[i].init(x.lub, x[i]);
198 break;
199 case 1:
200 isrs[0].init(x.lub, x[0]);
201 isrs[1].init(x.lub, x[0]);
202 isrs[2].init(x.lub, x[1]);
203 break;
204 case 2:
205 isrs[0].init(x.lub, x[0]);
206 isrs[1].init(x.lub, x[1]);
207 isrs[2].init(x.lub, x[2]);
208 break;
209 case 3:
210 isrs[0].init(x.lub, x[0]);
211 isrs[1].init(x.lub, x[1]);
212 isrs[2].init(x.lub, x[0]);
213 break;
214 default:
215 GECODE_NEVER;
216 }
217
218 int result = shared == 0 ? x.size() - 1 : (shared <= 2 ? 2 : 0);
219 CountableSetRanges xnr(x.lub, x[result]);
220
221 switch (sot) {
222 case SOT_DUNION:
223 {
224 if (shared == 1 && (isrs[0]() || isrs[1]())) {
225 delete[] isrs; return false;
226 }
227 if (shared == 3 && (isrs[0]() || isrs[2]())) {
228 delete[] isrs; return false;
229 }
230 unsigned int cardSum = 0;
231 if (shared == 1 || shared == 3) {
232 CountableSetRanges x1r(x.lub, x[1]);
233 cardSum = Iter::Ranges::size(x1r);
234 } else {
235 for (int i=0; i<realN; i++) {
236 CountableSetRanges xir(x.lub, x[i]);
237 cardSum += Iter::Ranges::size(xir);
238 }
239 }
240 if (withConst)
241 cardSum += 2;
242 CountableSetRanges xnr2(x.lub, x[result]);
243 if (cardSum != Iter::Ranges::size(xnr2)) {
244 delete[] isrs; return false;
245 }
246 }
247 // fall through to union case
248 case SOT_UNION:
249 {
250 bool eq;
251 if (withConst) {
252 Region r;
253 Iter::Ranges::NaryUnion u(r, isrs, realN);
254 IntSetRanges isr(is);
255 Iter::Ranges::Union<IntSetRanges,
256 Iter::Ranges::NaryUnion> uu(isr, u);
257 eq = Iter::Ranges::equal(uu, xnr);
258 } else {
259 Region r;
260 Iter::Ranges::NaryUnion u(r, isrs, realN);
261 eq = Iter::Ranges::equal(u, xnr);
262 }
263 delete [] isrs;
264 return eq;
265 }
266 case SOT_INTER:
267 {
268 if (withConst) {
269 bool eq;
270 {
271 Region r;
272 Iter::Ranges::NaryInter u(r, isrs, realN);
273 IntSetRanges isr(is);
274 Iter::Ranges::Inter<IntSetRanges,
275 Iter::Ranges::NaryInter> uu(isr, u);
276 eq = (realN == 0 ? Iter::Ranges::equal(isr, xnr) :
277 Iter::Ranges::equal(uu, xnr));
278 delete [] isrs;
279 }
280 return eq;
281 } else {
282 if (realN == 0) {
283 bool ret =
284 Iter::Ranges::size(xnr) == Gecode::Set::Limits::card;
285 delete [] isrs;
286 return ret;
287 } else {
288 bool eq;
289 {
290 Region r;
291 Iter::Ranges::NaryInter u(r,isrs, realN);
292 eq = Iter::Ranges::equal(u, xnr);
293 }
294 delete [] isrs;
295 return eq;
296 }
297 }
298 }
299 default:
300 GECODE_NEVER;
301 }
302 GECODE_NEVER;
303 return false;
304 }
305 /// Post constraint on \a x
306 void post(Space& home, SetVarArray& x, IntVarArray&) {
307 int size = shared == 0 ? x.size()-1 : 3;
308 SetVarArgs xs(size);
309 SetVar xn;
310 switch (shared) {
311 case 0:
312 for (int i=x.size()-1; i--;)
313 xs[i]=x[i];
314 xn = x[x.size()-1];
315 break;
316 case 1:
317 xs[0] = x[0]; xs[1] = x[0]; xs[2] = x[1]; xn = x[2];
318 break;
319 case 2:
320 xs[0] = x[0]; xs[1] = x[1]; xs[2] = x[2]; xn = x[2];
321 break;
322 case 3:
323 xs[0] = x[0]; xs[1] = x[1]; xs[2] = x[0]; xn = x[0];
324 break;
325 default:
326 GECODE_NEVER;
327 break;
328 }
329 if (!withConst)
330 Gecode::rel(home, sot, xs, xn);
331 else
332 Gecode::rel(home, sot, xs, is, xn);
333 }
334 };
335
336 /// Help class to create and register tests
337 class CreateN {
338 public:
339 /// Perform creation and registration
340 CreateN(void) {
341 for (int wc=0; wc<=1; wc++) {
342 for (int i=0; i<=3; i++) {
343 (void) new RelN(Gecode::SOT_UNION, i, 0, wc);
344 (void) new RelN(Gecode::SOT_DUNION, i, 0, wc);
345 (void) new RelN(Gecode::SOT_INTER, i, 0, wc);
346
347 if (i>0) {
348 (void) new RelN(Gecode::SOT_UNION, 0, i, wc);
349 (void) new RelN(Gecode::SOT_DUNION, 0, i, wc);
350 (void) new RelN(Gecode::SOT_INTER, 0, i, wc);
351 }
352 }
353 }
354 }
355 };
356
357 CreateN cn;
358
359 /// %Test for n-ary partition constraint
360 class RelIntN : public SetTest {
361 private:
362 Gecode::SetOpType sot;
363 int n;
364 bool withConst;
365 IntSet is;
366 public:
367 /// Create and register test
368 RelIntN(Gecode::SetOpType sot0, int n0, bool withConst0)
369 : SetTest("RelOp::IntN::"+str(sot0)+"::"+str(n0)+
370 "::C"+str(withConst0 ? 1 : 0),
371 1,ds_12,false,n0)
372 , sot(sot0), n(n0), withConst(withConst0)
373 , is(0,1) {
374 }
375 /// %Test whether \a x is solution
376 bool solution(const SetAssignment& x) const {
377 int* isrs = new int[n];
378 for (int i=0; i<n; i++)
379 isrs[i] = x.ints()[i];
380
381 IntSet iss(isrs,n);
382 CountableSetRanges xnr(x.lub, x[0]);
383
384 switch (sot) {
385 case SOT_DUNION:
386 {
387 IntSetRanges issr(iss);
388 unsigned int cardSum = Iter::Ranges::size(issr);
389 if (cardSum != static_cast<unsigned int>(n)) {
390 delete[] isrs;
391 return false;
392 }
393 if (withConst) {
394 IntSetRanges isr(is);
395 cardSum += Iter::Ranges::size(isr);
396 }
397 CountableSetRanges xnr2(x.lub, x[0]);
398 if (cardSum != Iter::Ranges::size(xnr2)) {
399 delete[] isrs;
400 return false;
401 }
402 }
403 // fall through to union case
404 case SOT_UNION:
405 {
406 if (withConst) {
407 IntSetRanges issr(iss);
408 IntSetRanges isr(is);
409 Iter::Ranges::Union<IntSetRanges,IntSetRanges > uu(isr, issr);
410 delete[] isrs;
411 return Iter::Ranges::equal(uu, xnr);
412 } else {
413 IntSetRanges issr(iss);
414 delete[] isrs;
415 return Iter::Ranges::equal(issr, xnr);
416 }
417 }
418 case SOT_INTER:
419 {
420 bool allEqual = true;
421 for (int i=1; i<n; i++) {
422 if (isrs[i] != isrs[0]) {
423 allEqual = false;
424 break;
425 }
426 }
427 if (withConst) {
428 if (allEqual) {
429 if (n == 0) {
430 IntSetRanges isr(is);
431 delete[] isrs;
432 return Iter::Ranges::equal(isr, xnr);
433 } else {
434 Iter::Ranges::Singleton s(isrs[0],isrs[0]);
435 IntSetRanges isr(is);
436 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton>
437 uu(isr, s);
438 delete[] isrs;
439 return Iter::Ranges::equal(uu, xnr);
440 }
441 } else {
442 delete[] isrs;
443 return Iter::Ranges::size(xnr) == 0;
444 }
445 } else {
446 if (allEqual) {
447 if (n == 0) {
448 delete[] isrs;
449 return Iter::Ranges::size(xnr) == Gecode::Set::Limits::card;
450 } else {
451 Iter::Ranges::Singleton s(isrs[0],isrs[0]);
452 delete[] isrs;
453 return Iter::Ranges::equal(s, xnr);
454 }
455 } else {
456 delete[] isrs;
457 return Iter::Ranges::size(xnr) == 0;
458 }
459 }
460 }
461 default:
462 GECODE_NEVER;
463 }
464 GECODE_NEVER;
465 return false;
466 }
467 /// Post constraint on \a x
468 void post(Space& home, SetVarArray& x, IntVarArray& y) {
469 if (!withConst)
470 Gecode::rel(home, sot, y, x[0]);
471 else
472 Gecode::rel(home, sot, y, is, x[0]);
473 }
474 };
475
476 /// Help class to create and register tests
477 class CreateIntN {
478 public:
479 /// Perform creation and registration
480 CreateIntN(void) {
481 for (int wc=0; wc<=1; wc++) {
482 for (int i=0; i<=3; i++) {
483 (void) new RelIntN(Gecode::SOT_UNION, i, wc);
484 (void) new RelIntN(Gecode::SOT_DUNION, i, wc);
485 (void) new RelIntN(Gecode::SOT_INTER, i, wc);
486 }
487 }
488 }
489 };
490
491 CreateIntN intcn;
492
493 //@}
494
495}}}
496
497// STATISTICS: test-set