this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Copyright:
7 * Christian Schulte, 2002
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 <gecode/int/rel.hh>
35#include <gecode/int/bool.hh>
36
37#include <algorithm>
38
39namespace Gecode {
40
41 void
42 rel(Home home, IntVar x0, IntRelType irt, int n, IntPropLevel) {
43 using namespace Int;
44 Limits::check(n,"Int::rel");
45 GECODE_POST;
46 IntView x(x0);
47 switch (irt) {
48 case IRT_EQ: GECODE_ME_FAIL(x.eq(home,n)); break;
49 case IRT_NQ: GECODE_ME_FAIL(x.nq(home,n)); break;
50 case IRT_LQ: GECODE_ME_FAIL(x.lq(home,n)); break;
51 case IRT_LE: GECODE_ME_FAIL(x.le(home,n)); break;
52 case IRT_GQ: GECODE_ME_FAIL(x.gq(home,n)); break;
53 case IRT_GR: GECODE_ME_FAIL(x.gr(home,n)); break;
54 default: throw UnknownRelation("Int::rel");
55 }
56 }
57
58 void
59 rel(Home home, const IntVarArgs& x, IntRelType irt, int n, IntPropLevel) {
60 using namespace Int;
61 Limits::check(n,"Int::rel");
62 GECODE_POST;
63 switch (irt) {
64 case IRT_EQ:
65 for (int i=0; i<x.size(); i++) {
66 IntView xi(x[i]); GECODE_ME_FAIL(xi.eq(home,n));
67 }
68 break;
69 case IRT_NQ:
70 for (int i=0; i<x.size(); i++) {
71 IntView xi(x[i]); GECODE_ME_FAIL(xi.nq(home,n));
72 }
73 break;
74 case IRT_LQ:
75 for (int i=0; i<x.size(); i++) {
76 IntView xi(x[i]); GECODE_ME_FAIL(xi.lq(home,n));
77 }
78 break;
79 case IRT_LE:
80 for (int i=0; i<x.size(); i++) {
81 IntView xi(x[i]); GECODE_ME_FAIL(xi.le(home,n));
82 }
83 break;
84 case IRT_GQ:
85 for (int i=0; i<x.size(); i++) {
86 IntView xi(x[i]); GECODE_ME_FAIL(xi.gq(home,n));
87 }
88 break;
89 case IRT_GR:
90 for (int i=0; i<x.size(); i++) {
91 IntView xi(x[i]); GECODE_ME_FAIL(xi.gr(home,n));
92 }
93 break;
94 default:
95 throw UnknownRelation("Int::rel");
96 }
97 }
98
99 void
100 rel(Home home, IntVar x0, IntRelType irt, IntVar x1, IntPropLevel ipl) {
101 using namespace Int;
102 GECODE_POST;
103 switch (irt) {
104 case IRT_EQ:
105 if ((vbd(ipl) == IPL_DOM) || (vbd(ipl) == IPL_DEF)) {
106 GECODE_ES_FAIL((Rel::EqDom<IntView,IntView>::post(home,x0,x1)));
107 } else {
108 GECODE_ES_FAIL((Rel::EqBnd<IntView,IntView>::post(home,x0,x1)));
109 }
110 break;
111 case IRT_NQ:
112 GECODE_ES_FAIL((Rel::Nq<IntView,IntView>::post(home,x0,x1))); break;
113 case IRT_GQ:
114 std::swap(x0,x1); // Fall through
115 case IRT_LQ:
116 GECODE_ES_FAIL((Rel::Lq<IntView,IntView>::post(home,x0,x1))); break;
117 case IRT_GR:
118 std::swap(x0,x1); // Fall through
119 case IRT_LE:
120 GECODE_ES_FAIL((Rel::Le<IntView,IntView>::post(home,x0,x1))); break;
121 default:
122 throw UnknownRelation("Int::rel");
123 }
124 }
125
126 void
127 rel(Home home, const IntVarArgs& x, IntRelType irt, IntVar y,
128 IntPropLevel ipl) {
129 using namespace Int;
130 GECODE_POST;
131 switch (irt) {
132 case IRT_EQ:
133 {
134 ViewArray<IntView> xv(home,x.size()+1);
135 xv[x.size()]=y;
136 for (int i=0; i<x.size(); i++)
137 xv[i]=x[i];
138 if ((vbd(ipl) == IPL_DOM) || (vbd(ipl) == IPL_DEF)) {
139 GECODE_ES_FAIL(Rel::NaryEqDom<IntView>::post(home,xv));
140 } else {
141 GECODE_ES_FAIL(Rel::NaryEqBnd<IntView>::post(home,xv));
142 }
143 }
144 break;
145 case IRT_NQ:
146 for (int i=0; i<x.size(); i++) {
147 GECODE_ES_FAIL((Rel::Nq<IntView,IntView>::post(home,x[i],y)));
148 }
149 break;
150 case IRT_GQ:
151 for (int i=0; i<x.size(); i++) {
152 GECODE_ES_FAIL((Rel::Lq<IntView,IntView>::post(home,y,x[i])));
153 }
154 break;
155 case IRT_LQ:
156 for (int i=0; i<x.size(); i++) {
157 GECODE_ES_FAIL((Rel::Lq<IntView,IntView>::post(home,x[i],y)));
158 }
159 break;
160 case IRT_GR:
161 for (int i=0; i<x.size(); i++) {
162 GECODE_ES_FAIL((Rel::Le<IntView,IntView>::post(home,y,x[i])));
163 }
164 break;
165 case IRT_LE:
166 for (int i=0; i<x.size(); i++) {
167 GECODE_ES_FAIL((Rel::Le<IntView,IntView>::post(home,x[i],y)));
168 }
169 break;
170 default:
171 throw UnknownRelation("Int::rel");
172 }
173 }
174
175
176 void
177 rel(Home home, IntVar x0, IntRelType irt, IntVar x1, Reify r,
178 IntPropLevel ipl) {
179 using namespace Int;
180 GECODE_POST;
181 switch (irt) {
182 case IRT_EQ:
183 if ((vbd(ipl) == IPL_DOM) || (vbd(ipl) == IPL_DEF)) {
184 switch (r.mode()) {
185 case RM_EQV:
186 GECODE_ES_FAIL((Rel::ReEqDom<IntView,BoolView,RM_EQV>
187 ::post(home,x0,x1,r.var())));
188 break;
189 case RM_IMP:
190 GECODE_ES_FAIL((Rel::ReEqDom<IntView,BoolView,RM_IMP>
191 ::post(home,x0,x1,r.var())));
192 break;
193 case RM_PMI:
194 GECODE_ES_FAIL((Rel::ReEqDom<IntView,BoolView,RM_PMI>
195 ::post(home,x0,x1,r.var())));
196 break;
197 default: throw UnknownReifyMode("Int::rel");
198 }
199 } else {
200 switch (r.mode()) {
201 case RM_EQV:
202 GECODE_ES_FAIL((Rel::ReEqBnd<IntView,BoolView,RM_EQV>
203 ::post(home,x0,x1,r.var())));
204 break;
205 case RM_IMP:
206 GECODE_ES_FAIL((Rel::ReEqBnd<IntView,BoolView,RM_IMP>
207 ::post(home,x0,x1,r.var())));
208 break;
209 case RM_PMI:
210 GECODE_ES_FAIL((Rel::ReEqBnd<IntView,BoolView,RM_PMI>
211 ::post(home,x0,x1,r.var())));
212 break;
213 default: throw UnknownReifyMode("Int::rel");
214 }
215 }
216 break;
217 case IRT_NQ:
218 {
219 NegBoolView n(r.var());
220 if (vbd(ipl) == IPL_BND) {
221 switch (r.mode()) {
222 case RM_EQV:
223 GECODE_ES_FAIL((Rel::ReEqBnd<IntView,NegBoolView,RM_EQV>
224 ::post(home,x0,x1,n)));
225 break;
226 case RM_IMP:
227 GECODE_ES_FAIL((Rel::ReEqBnd<IntView,NegBoolView,RM_PMI>
228 ::post(home,x0,x1,n)));
229 break;
230 case RM_PMI:
231 GECODE_ES_FAIL((Rel::ReEqBnd<IntView,NegBoolView,RM_IMP>
232 ::post(home,x0,x1,n)));
233 break;
234 default: throw UnknownReifyMode("Int::rel");
235 }
236 } else {
237 switch (r.mode()) {
238 case RM_EQV:
239 GECODE_ES_FAIL((Rel::ReEqDom<IntView,NegBoolView,RM_EQV>
240 ::post(home,x0,x1,n)));
241 break;
242 case RM_IMP:
243 GECODE_ES_FAIL((Rel::ReEqDom<IntView,NegBoolView,RM_PMI>
244 ::post(home,x0,x1,n)));
245 break;
246 case RM_PMI:
247 GECODE_ES_FAIL((Rel::ReEqDom<IntView,NegBoolView,RM_IMP>
248 ::post(home,x0,x1,n)));
249 break;
250 default: throw UnknownReifyMode("Int::rel");
251 }
252 }
253 }
254 break;
255 case IRT_GQ:
256 std::swap(x0,x1); // Fall through
257 case IRT_LQ:
258 switch (r.mode()) {
259 case RM_EQV:
260 GECODE_ES_FAIL((Rel::ReLq<IntView,BoolView,RM_EQV>
261 ::post(home,x0,x1,r.var())));
262 break;
263 case RM_IMP:
264 GECODE_ES_FAIL((Rel::ReLq<IntView,BoolView,RM_IMP>
265 ::post(home,x0,x1,r.var())));
266 break;
267 case RM_PMI:
268 GECODE_ES_FAIL((Rel::ReLq<IntView,BoolView,RM_PMI>
269 ::post(home,x0,x1,r.var())));
270 break;
271 default: throw UnknownReifyMode("Int::rel");
272 }
273 break;
274 case IRT_LE:
275 std::swap(x0,x1); // Fall through
276 case IRT_GR:
277 {
278 NegBoolView n(r.var());
279 switch (r.mode()) {
280 case RM_EQV:
281 GECODE_ES_FAIL((Rel::ReLq<IntView,NegBoolView,RM_EQV>
282 ::post(home,x0,x1,n)));
283 break;
284 case RM_IMP:
285 GECODE_ES_FAIL((Rel::ReLq<IntView,NegBoolView,RM_PMI>
286 ::post(home,x0,x1,n)));
287 break;
288 case RM_PMI:
289 GECODE_ES_FAIL((Rel::ReLq<IntView,NegBoolView,RM_IMP>
290 ::post(home,x0,x1,n)));
291 break;
292 default: throw UnknownReifyMode("Int::rel");
293 }
294 }
295 break;
296 default:
297 throw UnknownRelation("Int::rel");
298 }
299 }
300
301 void
302 rel(Home home, IntVar x, IntRelType irt, int n, Reify r,
303 IntPropLevel ipl) {
304 using namespace Int;
305 Limits::check(n,"Int::rel");
306 GECODE_POST;
307 switch (irt) {
308 case IRT_EQ:
309 if ((vbd(ipl) == IPL_DOM) || (vbd(ipl) == IPL_DEF)) {
310 switch (r.mode()) {
311 case RM_EQV:
312 GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,BoolView,RM_EQV>
313 ::post(home,x,n,r.var())));
314 break;
315 case RM_IMP:
316 GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,BoolView,RM_IMP>
317 ::post(home,x,n,r.var())));
318 break;
319 case RM_PMI:
320 GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,BoolView,RM_PMI>
321 ::post(home,x,n,r.var())));
322 break;
323 default: throw UnknownReifyMode("Int::rel");
324 }
325 } else {
326 switch (r.mode()) {
327 case RM_EQV:
328 GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,BoolView,RM_EQV>
329 ::post(home,x,n,r.var())));
330 break;
331 case RM_IMP:
332 GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,BoolView,RM_IMP>
333 ::post(home,x,n,r.var())));
334 break;
335 case RM_PMI:
336 GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,BoolView,RM_PMI>
337 ::post(home,x,n,r.var())));
338 break;
339 default: throw UnknownReifyMode("Int::rel");
340 }
341 }
342 break;
343 case IRT_NQ:
344 {
345 NegBoolView nb(r.var());
346 if (vbd(ipl) == IPL_BND) {
347 switch (r.mode()) {
348 case RM_EQV:
349 GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,NegBoolView,RM_EQV>
350 ::post(home,x,n,nb)));
351 break;
352 case RM_IMP:
353 GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,NegBoolView,RM_PMI>
354 ::post(home,x,n,nb)));
355 break;
356 case RM_PMI:
357 GECODE_ES_FAIL((Rel::ReEqBndInt<IntView,NegBoolView,RM_IMP>
358 ::post(home,x,n,nb)));
359 break;
360 default: throw UnknownReifyMode("Int::rel");
361 }
362 } else {
363 switch (r.mode()) {
364 case RM_EQV:
365 GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,NegBoolView,RM_EQV>
366 ::post(home,x,n,nb)));
367 break;
368 case RM_IMP:
369 GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,NegBoolView,RM_PMI>
370 ::post(home,x,n,nb)));
371 break;
372 case RM_PMI:
373 GECODE_ES_FAIL((Rel::ReEqDomInt<IntView,NegBoolView,RM_IMP>
374 ::post(home,x,n,nb)));
375 break;
376 default: throw UnknownReifyMode("Int::rel");
377 }
378 }
379 }
380 break;
381 case IRT_LE:
382 n--; // Fall through
383 case IRT_LQ:
384 switch (r.mode()) {
385 case RM_EQV:
386 GECODE_ES_FAIL((Rel::ReLqInt<IntView,BoolView,RM_EQV>
387 ::post(home,x,n,r.var())));
388 break;
389 case RM_IMP:
390 GECODE_ES_FAIL((Rel::ReLqInt<IntView,BoolView,RM_IMP>
391 ::post(home,x,n,r.var())));
392 break;
393 case RM_PMI:
394 GECODE_ES_FAIL((Rel::ReLqInt<IntView,BoolView,RM_PMI>
395 ::post(home,x,n,r.var())));
396 break;
397 default: throw UnknownReifyMode("Int::rel");
398 }
399 break;
400 case IRT_GQ:
401 n--; // Fall through
402 case IRT_GR:
403 {
404 NegBoolView nb(r.var());
405 switch (r.mode()) {
406 case RM_EQV:
407 GECODE_ES_FAIL((Rel::ReLqInt<IntView,NegBoolView,RM_EQV>
408 ::post(home,x,n,nb)));
409 break;
410 case RM_IMP:
411 GECODE_ES_FAIL((Rel::ReLqInt<IntView,NegBoolView,RM_PMI>
412 ::post(home,x,n,nb)));
413 break;
414 case RM_PMI:
415 GECODE_ES_FAIL((Rel::ReLqInt<IntView,NegBoolView,RM_IMP>
416 ::post(home,x,n,nb)));
417 break;
418 default: throw UnknownReifyMode("Int::rel");
419 }
420 }
421 break;
422 default:
423 throw UnknownRelation("Int::rel");
424 }
425 }
426
427 void
428 rel(Home home, const IntVarArgs& x, IntRelType irt,
429 IntPropLevel ipl) {
430 using namespace Int;
431 GECODE_POST;
432 if ((irt != IRT_NQ) && (x.size() < 2))
433 return;
434 switch (irt) {
435 case IRT_EQ:
436 {
437 ViewArray<IntView> xv(home,x);
438 if ((vbd(ipl) == IPL_DOM) || (vbd(ipl) == IPL_DEF)) {
439 GECODE_ES_FAIL(Rel::NaryEqDom<IntView>::post(home,xv));
440 } else {
441 GECODE_ES_FAIL(Rel::NaryEqBnd<IntView>::post(home,xv));
442 }
443 }
444 break;
445 case IRT_NQ:
446 {
447 ViewArray<IntView> y(home,x);
448 GECODE_ES_FAIL((Rel::NaryNq<IntView>::post(home,y)));
449 }
450 break;
451 case IRT_LE:
452 {
453 ViewArray<IntView> y(home,x);
454 GECODE_ES_FAIL((Rel::NaryLqLe<IntView,1>::post(home,y)));
455 }
456 break;
457 case IRT_LQ:
458 {
459 ViewArray<IntView> y(home,x);
460 GECODE_ES_FAIL((Rel::NaryLqLe<IntView,0>::post(home,y)));
461 }
462 break;
463 case IRT_GR:
464 {
465 ViewArray<IntView> y(home,x.size());
466 for (int i=0; i<x.size(); i++)
467 y[i] = x[x.size()-1-i];
468 GECODE_ES_FAIL((Rel::NaryLqLe<IntView,1>::post(home,y)));
469 }
470 break;
471 case IRT_GQ:
472 {
473 ViewArray<IntView> y(home,x.size());
474 for (int i=0; i<x.size(); i++)
475 y[i] = x[x.size()-1-i];
476 GECODE_ES_FAIL((Rel::NaryLqLe<IntView,0>::post(home,y)));
477 }
478 break;
479 default:
480 throw UnknownRelation("Int::rel");
481 }
482 }
483
484 void
485 rel(Home home, const IntVarArgs& x, IntRelType irt, const IntVarArgs& y,
486 IntPropLevel ipl) {
487 using namespace Int;
488 GECODE_POST;
489
490 switch (irt) {
491 case IRT_GR:
492 {
493 ViewArray<IntView> xv(home,x), yv(home,y);
494 GECODE_ES_FAIL((Rel::LexLqLe<IntView,IntView>
495 ::post(home,yv,xv,true)));
496 }
497 break;
498 case IRT_LE:
499 {
500 ViewArray<IntView> xv(home,x), yv(home,y);
501 GECODE_ES_FAIL((Rel::LexLqLe<IntView,IntView>
502 ::post(home,xv,yv,true)));
503 }
504 break;
505 case IRT_GQ:
506 {
507 ViewArray<IntView> xv(home,x), yv(home,y);
508 GECODE_ES_FAIL((Rel::LexLqLe<IntView,IntView>
509 ::post(home,yv,xv,false)));
510 }
511 break;
512 case IRT_LQ:
513 {
514 ViewArray<IntView> xv(home,x), yv(home,y);
515 GECODE_ES_FAIL((Rel::LexLqLe<IntView,IntView>
516 ::post(home,xv,yv,false)));
517 }
518 break;
519 case IRT_EQ:
520 if (x.size() != y.size()) {
521 home.fail();
522 } else if ((vbd(ipl) == IPL_DOM) || (vbd(ipl) == IPL_DEF))
523 for (int i=0; i<x.size(); i++) {
524 GECODE_ES_FAIL((Rel::EqDom<IntView,IntView>
525 ::post(home,x[i],y[i])));
526 }
527 else
528 for (int i=0; i<x.size(); i++) {
529 GECODE_ES_FAIL((Rel::EqBnd<IntView,IntView>
530 ::post(home,x[i],y[i])));
531 }
532 break;
533 case IRT_NQ:
534 {
535 ViewArray<IntView> xv(home,x), yv(home,y);
536 GECODE_ES_FAIL((Rel::LexNq<IntView,IntView>
537 ::post(home,xv,yv)));
538 }
539 break;
540 default:
541 throw UnknownRelation("Int::rel");
542 }
543 }
544
545 namespace {
546
547 /// Return view array
548 ViewArray<Int::ConstIntView>
549 viewarray(Space& home, const IntArgs& x) {
550 ViewArray<Int::ConstIntView> xv(home, x.size());
551 for (int i=0; i<x.size(); i++) {
552 Int::Limits::check(x[i],"Int::rel");
553 xv[i] = Int::ConstIntView(x[i]);
554 }
555 return xv;
556 }
557
558 }
559
560 void
561 rel(Home home, const IntVarArgs& x, IntRelType irt, const IntArgs& y,
562 IntPropLevel) {
563 using namespace Int;
564 GECODE_POST;
565
566 switch (irt) {
567 case IRT_GR:
568 {
569 ViewArray<IntView> xv(home,x);
570 ViewArray<ConstIntView> yv(viewarray(home,y));
571 GECODE_ES_FAIL((Rel::LexLqLe<ConstIntView,IntView>
572 ::post(home,yv,xv,true)));
573 }
574 break;
575 case IRT_LE:
576 {
577 ViewArray<IntView> xv(home,x);
578 ViewArray<ConstIntView> yv(viewarray(home,y));
579 GECODE_ES_FAIL((Rel::LexLqLe<IntView,ConstIntView>
580 ::post(home,xv,yv,true)));
581 }
582 break;
583 case IRT_GQ:
584 {
585 ViewArray<IntView> xv(home,x);
586 ViewArray<ConstIntView> yv(viewarray(home,y));
587 GECODE_ES_FAIL((Rel::LexLqLe<ConstIntView,IntView>
588 ::post(home,yv,xv,false)));
589 }
590 break;
591 case IRT_LQ:
592 {
593 ViewArray<IntView> xv(home,x);
594 ViewArray<ConstIntView> yv(viewarray(home,y));
595 GECODE_ES_FAIL((Rel::LexLqLe<IntView,ConstIntView>
596 ::post(home,xv,yv,false)));
597 }
598 break;
599 case IRT_EQ:
600 if (x.size() != y.size()) {
601 home.fail();
602 } else {
603 for (int i=0; i<x.size(); i++)
604 GECODE_ME_FAIL(IntView(x[i]).eq(home,y[i]));
605 }
606 break;
607 case IRT_NQ:
608 {
609 ViewArray<IntView> xv(home,x);
610 ViewArray<ConstIntView> yv(viewarray(home,y));
611 GECODE_ES_FAIL((Rel::LexNq<IntView,ConstIntView>
612 ::post(home,xv,yv)));
613 }
614 break;
615 default:
616 throw UnknownRelation("Int::rel");
617 }
618 }
619
620 void
621 rel(Home home, const IntArgs& x, IntRelType irt, const IntVarArgs& y,
622 IntPropLevel ipl) {
623 rel(home,y,irt,x,ipl);
624 }
625
626}
627
628// STATISTICS: int-post