Generated on Tue Feb 11 2025 17:33:26 for Gecode by doxygen 1.12.0
int-expr.cpp
Go to the documentation of this file.
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, 2010
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/minimodel.hh>
35#include <gecode/int/linear.hh>
36
37namespace Gecode {
38
41 public:
43 unsigned int use;
45 int n_int;
47 int n_bool;
51 Node *l, *r;
53 union {
60 } sum;
62 int a, c;
68 Node(void);
70 void fill(Home home, const IntPropLevels& ipls,
73 long long int m, long long int& d) const;
75 int fill(Home home, const IntPropLevels& ipls,
79 bool decrement(void);
81 ~Node(void);
83 static void* operator new(size_t size);
85 static void operator delete(void* p,size_t size);
86 };
87
88 /*
89 * Operations for nodes
90 *
91 */
93 LinIntExpr::Node::Node(void) : use(1) {
94 }
95
98 switch (t) {
99 case NT_SUM_INT:
100 if (n_int > 0)
102 break;
103 case NT_SUM_BOOL:
104 if (n_bool > 0)
106 break;
107 case NT_NONLIN:
108 delete sum.ne;
109 break;
110 default: ;
111 }
112 }
113
114 forceinline void*
115 LinIntExpr::Node::operator new(size_t size) {
116 return heap.ralloc(size);
117 }
118
119 forceinline void
120 LinIntExpr::Node::operator delete(void* p, size_t) {
121 heap.rfree(p);
122 }
123 bool
125 if (--use == 0) {
126 if ((l != nullptr) && l->decrement())
127 delete l;
128 if ((r != nullptr) && r->decrement())
129 delete r;
130 return true;
131 }
132 return false;
133 }
134
135 /*
136 * Operations for expressions
137 *
138 */
139
141 : n(e.n) {
142 n->use++;
143 }
144
145 int
149 long long int d=0;
150 fill(home,ipls,ti,tb,1,d);
151 Int::Limits::check(d,"MiniModel::LinIntExpr");
152 return static_cast<int>(d);
153 }
154
155 void
157 const IntPropLevels& ipls) const {
158 if (home.failed()) return;
159 Region r;
160 if (n->n_bool == 0) {
161 // Only integer variables
162 if (n->t==NT_ADD && n->l == nullptr && n->r->t==NT_NONLIN) {
163 n->r->sum.ne->post(home,irt,-n->c,ipls);
164 } else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==nullptr) {
165 switch (irt) {
166 case IRT_LQ: irt=IRT_GQ; break;
167 case IRT_LE: irt=IRT_GR; break;
168 case IRT_GQ: irt=IRT_LQ; break;
169 case IRT_GR: irt=IRT_LE; break;
170 default: break;
171 }
172 n->r->sum.ne->post(home,irt,n->c,ipls);
173 } else if (irt==IRT_EQ &&
174 n->t==NT_SUB && n->r->t==NT_NONLIN &&
175 n->l != nullptr && n->l->t==NT_VAR_INT
176 && n->l->a==1) {
177 (void) n->r->sum.ne->post(home,&n->l->x_int,ipls);
178 } else if (irt==IRT_EQ &&
179 n->t==NT_SUB && n->r->t==NT_VAR_INT &&
180 n->l != nullptr && n->l->t==NT_NONLIN
181 && n->r->a==1) {
182 (void) n->l->sum.ne->post(home,&n->r->x_int,ipls);
183 } else {
186 int c = n->fill(home,ipls,its,nullptr);
187 Int::Linear::post(home, its, n->n_int, irt, -c,
188 (n->n_int > 2) ? ipls.linear() : ipls.linear2());
189 }
190 } else if (n->n_int == 0) {
191 // Only Boolean variables
194 int c = n->fill(home,ipls,nullptr,bts);
195 Int::Linear::post(home, bts, n->n_bool, irt, -c,
196 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
197 } else if (n->n_bool == 1) {
198 // Integer variables and only one Boolean variable
203 int c = n->fill(home,ipls,its,bts);
204 IntVar x(home,0,1);
205 channel(home,bts[0].x,x);
206 its[n->n_int].x = x;
207 its[n->n_int].a = bts[0].a;
208 Int::Linear::post(home, its, n->n_int+1, irt, -c,
209 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
210 } else {
211 // Both integer and Boolean variables
216 int c = n->fill(home,ipls,its,bts);
217 int min, max;
218 Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
219 IntVar x(home,min,max);
220 its[n->n_int].x = x; its[n->n_int].a = 1;
221 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
222 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
223 Int::Linear::post(home, its, n->n_int+1, irt, -c,
224 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
225 }
226 }
227
228 void
230 const IntPropLevels& ipls) const {
231 if (home.failed()) return;
232 Region r;
233 if (n->n_bool == 0) {
234 // Only integer variables
235 if (n->t==NT_ADD && n->l==nullptr && n->r->t==NT_NONLIN) {
236 n->r->sum.ne->post(home,irt,-n->c,b,ipls);
237 } else if (n->t==NT_SUB && n->l==nullptr && n->r->t==NT_NONLIN) {
238 switch (irt) {
239 case IRT_LQ: irt=IRT_GQ; break;
240 case IRT_LE: irt=IRT_GR; break;
241 case IRT_GQ: irt=IRT_LQ; break;
242 case IRT_GR: irt=IRT_LE; break;
243 default: break;
244 }
245 n->r->sum.ne->post(home,irt,n->c,b,ipls);
246 } else {
249 int c = n->fill(home,ipls,its,nullptr);
250 Int::Linear::post(home, its, n->n_int, irt, -c, b,
251 (n->n_int > 2) ? ipls.linear() : ipls.linear2());
252 }
253 } else if (n->n_int == 0) {
254 // Only Boolean variables
257 int c = n->fill(home,ipls,nullptr,bts);
258 Int::Linear::post(home, bts, n->n_bool, irt, -c, b,
259 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
260 } else if (n->n_bool == 1) {
261 // Integer variables and only one Boolean variable
266 int c = n->fill(home,ipls,its,bts);
267 IntVar x(home,0,1);
268 channel(home,bts[0].x,x);
269 its[n->n_int].x = x;
270 its[n->n_int].a = bts[0].a;
271 Int::Linear::post(home, its, n->n_int+1, irt, -c, b,
272 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
273 } else {
274 // Both integer and Boolean variables
279 int c = n->fill(home,ipls,its,bts);
280 int min, max;
281 Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
282 IntVar x(home,min,max);
283 its[n->n_int].x = x; its[n->n_int].a = 1;
284 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
285 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
286 Int::Linear::post(home, its, n->n_int+1, irt, -c, b,
287 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
288 }
289 }
290
291 IntVar
292 LinIntExpr::post(Home home, const IntPropLevels& ipls) const {
293 if (home.failed()) return IntVar(home,0,0);
294 Region r;
295 if (n->n_bool == 0) {
296 // Only integer variables
299 int c = n->fill(home,ipls,its,nullptr);
300 if ((n->n_int == 1) && (c == 0) && (its[0].a == 1))
301 return its[0].x;
302 int min, max;
303 Int::Linear::estimate(&its[0],n->n_int,c,min,max);
304 IntVar x(home, min, max);
305 its[n->n_int].x = x; its[n->n_int].a = -1;
306 Int::Linear::post(home, its, n->n_int+1, IRT_EQ, -c,
307 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
308 return x;
309 } else if (n->n_int == 0) {
310 // Only Boolean variables
313 int c = n->fill(home,ipls,nullptr,bts);
314 int min, max;
315 Int::Linear::estimate(&bts[0],n->n_bool,c,min,max);
316 IntVar x(home, min, max);
317 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, -c,
318 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
319 return x;
320 } else if (n->n_bool == 1) {
321 // Integer variables and single Boolean variable
326 int c = n->fill(home,ipls,its,bts);
327 IntVar x(home, 0, 1);
328 channel(home, x, bts[0].x);
329 its[n->n_int].x = x; its[n->n_int].a = bts[0].a;
330 int y_min, y_max;
331 Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
332 IntVar y(home, y_min, y_max);
333 its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
334 Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipls.linear());
335 return y;
336 } else {
337 // Both integer and Boolean variables
342 int c = n->fill(home,ipls,its,bts);
343 int x_min, x_max;
344 Int::Linear::estimate(&bts[0],n->n_bool,0,x_min,x_max);
345 IntVar x(home, x_min, x_max);
346 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
347 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
348 its[n->n_int].x = x; its[n->n_int].a = 1;
349 int y_min, y_max;
350 Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
351 IntVar y(home, y_min, y_max);
352 its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
353 Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipls.linear());
354 return y;
355 }
356 }
357
359 LinIntExpr::nle(void) const {
360 return n->t == NT_NONLIN ? n->sum.ne : nullptr;
361 }
362
364 n(new Node) {
365 n->n_int = n->n_bool = 0;
366 n->t = NT_VAR_INT;
367 n->l = n->r = nullptr;
368 n->a = 0;
369 }
370
372 n(new Node) {
373 n->n_int = n->n_bool = 0;
374 n->t = NT_CONST;
375 n->l = n->r = nullptr;
376 n->a = 0;
377 Int::Limits::check(c,"MiniModel::LinIntExpr");
378 n->c = c;
379 }
380
382 n(new Node) {
383 n->n_int = 1;
384 n->n_bool = 0;
385 n->t = NT_VAR_INT;
386 n->l = n->r = nullptr;
387 n->a = a;
388 n->x_int = x;
389 }
390
392 n(new Node) {
393 n->n_int = 0;
394 n->n_bool = 1;
395 n->t = NT_VAR_BOOL;
396 n->l = n->r = nullptr;
397 n->a = a;
398 n->x_bool = x;
399 }
400
402 n(new Node) {
403 n->n_int = x.size();
404 n->n_bool = 0;
405 n->t = NT_SUM_INT;
406 n->l = n->r = nullptr;
407 if (x.size() > 0) {
408 n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
409 for (int i=x.size(); i--; ) {
410 n->sum.ti[i].x = x[i];
411 n->sum.ti[i].a = 1;
412 }
413 }
414 }
415
416 LinIntExpr::LinIntExpr(const IntArgs& a, const IntVarArgs& x) :
417 n(new Node) {
418 if (a.size() != x.size())
419 throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
420 n->n_int = x.size();
421 n->n_bool = 0;
422 n->t = NT_SUM_INT;
423 n->l = n->r = nullptr;
424 if (x.size() > 0) {
425 n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
426 for (int i=x.size(); i--; ) {
427 n->sum.ti[i].x = x[i];
428 n->sum.ti[i].a = a[i];
429 }
430 }
431 }
432
434 n(new Node) {
435 n->n_int = 0;
436 n->n_bool = x.size();
437 n->t = NT_SUM_BOOL;
438 n->l = n->r = nullptr;
439 if (x.size() > 0) {
440 n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
441 for (int i=x.size(); i--; ) {
442 n->sum.tb[i].x = x[i];
443 n->sum.tb[i].a = 1;
444 }
445 }
446 }
447
449 n(new Node) {
450 if (a.size() != x.size())
451 throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
452 n->n_int = 0;
453 n->n_bool = x.size();
454 n->t = NT_SUM_BOOL;
455 n->l = n->r = nullptr;
456 if (x.size() > 0) {
457 n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
458 for (int i=x.size(); i--; ) {
459 n->sum.tb[i].x = x[i];
460 n->sum.tb[i].a = a[i];
461 }
462 }
463 }
464
466 n(new Node) {
467 n->n_int = e0.n->n_int + e1.n->n_int;
468 n->n_bool = e0.n->n_bool + e1.n->n_bool;
469 n->t = t;
470 n->l = e0.n; n->l->use++;
471 n->r = e1.n; n->r->use++;
472 }
473
475 n(new Node) {
476 n->n_int = e.n->n_int;
477 n->n_bool = e.n->n_bool;
478 n->t = t;
479 n->l = nullptr;
480 n->r = e.n; n->r->use++;
481 n->c = c;
482 }
483
485 n(new Node) {
486 n->n_int = e.n->n_int;
487 n->n_bool = e.n->n_bool;
488 n->t = NT_MUL;
489 n->l = e.n; n->l->use++;
490 n->r = nullptr;
491 n->a = a;
492 }
493
495 n(new Node) {
496 n->n_int = 1;
497 n->n_bool = 0;
498 n->t = NT_NONLIN;
499 n->l = n->r = nullptr;
500 n->a = 0;
501 n->sum.ne = e;
502 }
503
504 const LinIntExpr&
506 if (this != &e) {
507 if (n->decrement())
508 delete n;
509 n = e.n; n->use++;
510 }
511 return *this;
512 }
513
515 if (n->decrement())
516 delete n;
517 }
518
519
520 void
524 long long int m, long long int& d) const {
525 switch (this->t) {
526 case NT_CONST:
527 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
528 d += m*c;
529 break;
530 case NT_VAR_INT:
531 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
532 ti->a=static_cast<int>(m*a); ti->x=x_int; ti++;
533 break;
534 case NT_NONLIN:
535 ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, nullptr, ipls); ti++;
536 break;
537 case NT_VAR_BOOL:
538 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
539 tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++;
540 break;
541 case NT_SUM_INT:
542 for (int i=n_int; i--; ) {
543 Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinIntExpr");
544 ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a);
545 }
546 ti += n_int;
547 break;
548 case NT_SUM_BOOL:
549 for (int i=n_bool; i--; ) {
550 Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinIntExpr");
551 tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a);
552 }
553 tb += n_bool;
554 break;
555 case NT_ADD:
556 if (l == nullptr) {
557 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
558 d += m*c;
559 } else {
560 l->fill(home,ipls,ti,tb,m,d);
561 }
562 r->fill(home,ipls,ti,tb,m,d);
563 break;
564 case NT_SUB:
565 if (l == nullptr) {
566 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
567 d += m*c;
568 } else {
569 l->fill(home,ipls,ti,tb,m,d);
570 }
571 r->fill(home,ipls,ti,tb,-m,d);
572 break;
573 case NT_MUL:
574 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
575 l->fill(home,ipls,ti,tb,m*a,d);
576 break;
577 default:
579 }
580 }
581
582
583 /*
584 * Operators
585 *
586 */
588 operator +(int c, const IntVar& x) {
589 if (x.assigned() &&
590 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
591 return LinIntExpr(c+x.val());
592 else
594 }
596 operator +(int c, const BoolVar& x) {
597 if (x.assigned() &&
598 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
599 return LinIntExpr(c+x.val());
600 else
602 }
604 operator +(int c, const LinIntExpr& e) {
605 return LinIntExpr(e,LinIntExpr::NT_ADD,c);
606 }
608 operator +(const IntVar& x, int c) {
609 if (x.assigned() &&
610 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
611 return LinIntExpr(c+x.val());
612 else
614 }
616 operator +(const BoolVar& x, int c) {
617 if (x.assigned() &&
618 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
619 return LinIntExpr(c+x.val());
620 else
622 }
624 operator +(const LinIntExpr& e, int c) {
625 return LinIntExpr(e,LinIntExpr::NT_ADD,c);
626 }
628 operator +(const IntVar& x, const IntVar& y) {
629 if (x.assigned())
630 return x.val() + y;
631 else if (y.assigned())
632 return x + y.val();
633 else
635 }
637 operator +(const IntVar& x, const BoolVar& y) {
638 if (x.assigned())
639 return x.val() + y;
640 else if (y.assigned())
641 return x + y.val();
642 else
644 }
646 operator +(const BoolVar& x, const IntVar& y) {
647 if (x.assigned())
648 return x.val() + y;
649 else if (y.assigned())
650 return x + y.val();
651 else
653 }
655 operator +(const BoolVar& x, const BoolVar& y) {
656 if (x.assigned())
657 return x.val() + y;
658 else if (y.assigned())
659 return x + y.val();
660 else
662 }
664 operator +(const IntVar& x, const LinIntExpr& e) {
665 if (x.assigned())
666 return x.val() + e;
667 else
669 }
671 operator +(const BoolVar& x, const LinIntExpr& e) {
672 if (x.assigned())
673 return x.val() + e;
674 else
676 }
678 operator +(const LinIntExpr& e, const IntVar& x) {
679 if (x.assigned())
680 return e + x.val();
681 else
683 }
685 operator +(const LinIntExpr& e, const BoolVar& x) {
686 if (x.assigned())
687 return e + x.val();
688 else
690 }
692 operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
693 return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
694 }
695
697 operator -(int c, const IntVar& x) {
698 if (x.assigned() &&
699 Int::Limits::valid(static_cast<long long int>(c)-x.val()))
700 return LinIntExpr(c-x.val());
701 else
703 }
705 operator -(int c, const BoolVar& x) {
706 if (x.assigned() &&
707 Int::Limits::valid(static_cast<long long int>(c)-x.val()))
708 return LinIntExpr(c-x.val());
709 else
711 }
713 operator -(int c, const LinIntExpr& e) {
714 return LinIntExpr(e,LinIntExpr::NT_SUB,c);
715 }
717 operator -(const IntVar& x, int c) {
718 if (x.assigned() &&
719 Int::Limits::valid(x.val()-static_cast<long long int>(c)))
720 return LinIntExpr(x.val()-c);
721 else
723 }
725 operator -(const BoolVar& x, int c) {
726 if (x.assigned() &&
727 Int::Limits::valid(x.val()-static_cast<long long int>(c)))
728 return LinIntExpr(x.val()-c);
729 else
731 }
733 operator -(const LinIntExpr& e, int c) {
734 return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
735 }
737 operator -(const IntVar& x, const IntVar& y) {
738 if (x.assigned())
739 return x.val() - y;
740 else if (y.assigned())
741 return x - y.val();
742 else
744 }
746 operator -(const IntVar& x, const BoolVar& y) {
747 if (x.assigned())
748 return x.val() - y;
749 else if (y.assigned())
750 return x - y.val();
751 else
753 }
755 operator -(const BoolVar& x, const IntVar& y) {
756 if (x.assigned())
757 return x.val() - y;
758 else if (y.assigned())
759 return x - y.val();
760 else
762 }
764 operator -(const BoolVar& x, const BoolVar& y) {
765 if (x.assigned())
766 return x.val() - y;
767 else if (y.assigned())
768 return x - y.val();
769 else
771 }
773 operator -(const IntVar& x, const LinIntExpr& e) {
774 if (x.assigned())
775 return x.val() - e;
776 else
778 }
780 operator -(const BoolVar& x, const LinIntExpr& e) {
781 if (x.assigned())
782 return x.val() - e;
783 else
785 }
787 operator -(const LinIntExpr& e, const IntVar& x) {
788 if (x.assigned())
789 return e - x.val();
790 else
792 }
794 operator -(const LinIntExpr& e, const BoolVar& x) {
795 if (x.assigned())
796 return e - x.val();
797 else
799 }
801 operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
802 return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
803 }
804
807 if (x.assigned())
808 return LinIntExpr(-x.val());
809 else
811 }
814 if (x.assigned())
815 return LinIntExpr(-x.val());
816 else
818 }
821 return LinIntExpr(e,LinIntExpr::NT_SUB,0);
822 }
823
825 operator *(int a, const IntVar& x) {
826 if (a == 0)
827 return LinIntExpr(0);
828 else if (x.assigned() &&
829 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
830 return LinIntExpr(a*x.val());
831 else
832 return LinIntExpr(x,a);
833 }
835 operator *(int a, const BoolVar& x) {
836 if (a == 0)
837 return LinIntExpr(0);
838 else if (x.assigned() &&
839 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
840 return LinIntExpr(a*x.val());
841 else
842 return LinIntExpr(x,a);
843 }
845 operator *(const IntVar& x, int a) {
846 if (a == 0)
847 return LinIntExpr(0);
848 else if (x.assigned() &&
849 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
850 return LinIntExpr(a*x.val());
851 else
852 return LinIntExpr(x,a);
853 }
855 operator *(const BoolVar& x, int a) {
856 if (a == 0)
857 return LinIntExpr(0);
858 else if (x.assigned() &&
859 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
860 return LinIntExpr(a*x.val());
861 else
862 return LinIntExpr(x,a);
863 }
865 operator *(const LinIntExpr& e, int a) {
866 if (a == 0)
867 return LinIntExpr(0);
868 else
869 return LinIntExpr(a,e);
870 }
872 operator *(int a, const LinIntExpr& e) {
873 if (a == 0)
874 return LinIntExpr(0);
875 else
876 return LinIntExpr(a,e);
877 }
878
880 sum(const IntVarArgs& x) {
881 return LinIntExpr(x);
882 }
884 sum(const IntArgs& a, const IntVarArgs& x) {
885 return LinIntExpr(a,x);
886 }
888 sum(const BoolVarArgs& x) {
889 return LinIntExpr(x);
890 }
892 sum(const IntArgs& a, const BoolVarArgs& x) {
893 return LinIntExpr(a,x);
894 }
896 sum(const Slice<IntArgs>& slice) {
897 const Slice<IntArgs>::ArgsType & args = slice;
898 return sum(args);
899 }
901 sum(const Matrix<IntArgs>& matrix) {
902 const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
903 return sum(args);
904 }
906 sum(const IntArgs& args) {
907 int sum = 0;
908 for (int i = 0; i<args.size(); i++)
909 sum += args[i];
910 return LinIntExpr(sum);
911 }
912
913
914 IntVar
915 expr(Home home, const LinIntExpr& e, const IntPropLevels& ipls) {
916 PostInfo pi(home);
917 if (!home.failed())
918 return e.post(home,ipls);
920 return x;
921 }
922
923}
924
925// STATISTICS: minimodel-any
NNF * l
Left subtree.
struct Gecode::@603::NNF::@65::@66 b
For binary nodes (and, or, eqv)
NodeType t
Type of node.
int p
Number of positive literals for node type.
int n
Number of negative literals for node type.
struct Gecode::@603::NNF::@65::@67 a
For atomic nodes.
Node * x
Pointer to corresponding Boolean expression node.
int size(void) const
Return size of array (number of elements)
Definition array.hpp:1607
Passing Boolean variables.
Definition int.hh:712
Boolean integer variables.
Definition int.hh:512
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition heap.hpp:457
void rfree(void *p)
Free memory block starting at p.
Definition heap.hpp:371
void * ralloc(size_t s)
Allocate s bytes from heap.
Definition heap.hpp:357
Home class for posting propagators
Definition core.hpp:856
bool failed(void) const
Check whether corresponding space is failed.
Definition core.hpp:4048
Passing integer arguments.
Definition int.hh:628
Class for specifying integer propagation levels used by minimodel.
Definition minimodel.hh:101
IntPropLevel linear(void) const
Return integer propagation level for non-binary linear constraints.
Definition ipl.hpp:55
IntPropLevel linear2(void) const
Return integer propagation level for binary linear constraints.
Definition ipl.hpp:47
Passing integer variables.
Definition int.hh:656
Integer variables.
Definition int.hh:371
Exception: Arguments are of different size
Definition exception.hpp:73
Class for describing linear term .
Definition linear.hh:1336
int a
Coefficient.
Definition linear.hh:1339
Nodes for linear expressions.
Definition int-expr.cpp:40
bool decrement(void)
Decrement reference count and possibly free memory.
Definition int-expr.cpp:124
Node * l
Subexpressions.
Definition int-expr.cpp:51
Int::Linear::Term< Int::IntView > * ti
Integer views and coefficients.
Definition int-expr.cpp:55
unsigned int use
Nodes are reference counted.
Definition int-expr.cpp:43
union Gecode::LinIntExpr::Node::@69 sum
Sum of integer or Boolean variables, or non-linear expression.
int n_int
Integer variables in tree.
Definition int-expr.cpp:45
IntVar x_int
Integer variable (potentially)
Definition int-expr.cpp:64
NodeType t
Type of expression.
Definition int-expr.cpp:49
NonLinIntExpr * ne
Non-linear expression.
Definition int-expr.cpp:59
BoolVar x_bool
Boolean variable (potentially)
Definition int-expr.cpp:66
void fill(Home home, const IntPropLevels &ipls, Int::Linear::Term< Int::IntView > *&ti, Int::Linear::Term< Int::BoolView > *&tb, long long int m, long long int &d) const
Generate linear terms from expression.
Definition int-expr.cpp:521
~Node(void)
Destructor.
Definition int-expr.cpp:97
Int::Linear::Term< Int::BoolView > * tb
Bool views and coefficients.
Definition int-expr.cpp:57
int a
Coefficient and offset.
Definition int-expr.cpp:62
int n_bool
Boolean variables in tree.
Definition int-expr.cpp:47
Node(void)
Default constructor.
Definition int-expr.cpp:93
Linear expressions over integer variables.
Definition minimodel.hh:245
NodeType
Type of linear expression.
Definition minimodel.hh:255
@ NT_CONST
Integer constant.
Definition minimodel.hh:256
@ NT_SUB
Subtraction of linear terms.
Definition minimodel.hh:263
@ NT_SUM_BOOL
Sum of Boolean variables.
Definition minimodel.hh:261
@ NT_ADD
Addition of linear terms.
Definition minimodel.hh:262
@ NT_SUM_INT
Sum of integer variables.
Definition minimodel.hh:260
@ NT_VAR_BOOL
Linear term with Boolean variable.
Definition minimodel.hh:258
@ NT_MUL
Multiplication by coefficient.
Definition minimodel.hh:264
@ NT_NONLIN
Non-linear expression.
Definition minimodel.hh:259
@ NT_VAR_INT
Linear term with integer variable.
Definition minimodel.hh:257
LinIntExpr(void)
Default constructor.
Definition int-expr.cpp:363
~LinIntExpr(void)
Destructor.
Definition int-expr.cpp:514
void post(Home home, IntRelType irt, const IntPropLevels &ipls) const
Post propagator.
Definition int-expr.cpp:156
const LinIntExpr & operator=(const LinIntExpr &e)
Assignment operator.
Definition int-expr.cpp:505
NonLinIntExpr * nle(void) const
Return non-linear expression inside, or null if not non-linear.
Definition int-expr.cpp:359
Matrix-interface for arrays.
ArgsType const get_array(void) const
Return an Args-array of the contents of the matrix.
Definition matrix.hpp:149
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Base class for non-linear expressions over integer variables.
Definition minimodel.hh:215
virtual IntVar post(Home home, IntVar *ret, const IntPropLevels &ipls) const =0
Return variable constrained to be equal to the expression.
Class to set group information when a post function is executed.
Definition core.hpp:948
Handle to region.
Definition region.hpp:55
A slice of a matrix.
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
bool assigned(void) const
Test whether view is assigned.
Definition var.hpp:111
VarImp * x
Pointer to variable implementation.
Definition var.hpp:50
const int * pi[]
Definition photo.cpp:14262
void post(Home home, Term< IntView > *t, int n, IntRelType irt, int c, IntPropLevel=IPL_DEF)
Post propagator for linear constraint over integers.
Definition int-post.cpp:219
Heap heap
The single global heap.
Definition heap.cpp:44
IntRelType
Relation types for integers.
Definition int.hh:925
@ IRT_EQ
Equality ( )
Definition int.hh:926
@ IRT_GQ
Greater or equal ( )
Definition int.hh:930
@ IRT_LE
Less ( )
Definition int.hh:929
@ IRT_GR
Greater ( )
Definition int.hh:931
@ IRT_LQ
Less or equal ( )
Definition int.hh:928
void check(int n, const char *l)
Check whether n is in range, otherwise throw out of limits with information l.
Definition limits.hpp:46
const int min
Smallest allowed integer value.
Definition int.hh:118
bool valid(int n)
Return whether n is in range.
Definition limits.hpp:37
const int max
Largest allowed integer value.
Definition int.hh:116
void estimate(Term< View > *t, int n, int c, int &l, int &u)
Estimate lower and upper bounds.
Definition post.hpp:41
Gecode toplevel namespace
FloatVal operator-(const FloatVal &x)
Definition val.hpp:168
FloatVal operator+(const FloatVal &x)
Definition val.hpp:164
Post propagator for SetVar SetOpType SetVar SetRelType r
Definition set.hh:767
void channel(Home home, FloatVar x0, IntVar x1)
Post propagator for channeling a float and an integer variable .
Definition channel.cpp:41
IntVar expr(Home home, const LinIntExpr &e, const IntPropLevels &ipls=IntPropLevels::def)
Post linear expression and return its value.
Definition int-expr.cpp:915
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Post propagator for SetVar SetOpType SetVar y
Definition set.hh:767
LinIntExpr sum(const IntVarArgs &x)
Construct linear expression as sum of integer variables.
Definition int-expr.cpp:880
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition val.hpp:200
Post propagator for SetVar x
Definition set.hh:767
#define forceinline
Definition config.hpp:187
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56