Generated on for Gecode by doxygen 1.15.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.dev>
5 *
6 * Contributing authors:
7 * Alexander Shepil <alexander.shepil@sap.com>
8 * Mikael Zayenz Lagerkvist <lagerkvist@gecode.dev>
9 *
10 * Copyright:
11 * Christian Schulte, 2010
12 * Alexander Shepil, 2024
13 * Mikael Zayenz Lagerkvist, 2026
14 *
15 * This file is part of Gecode, the generic constraint
16 * development environment:
17 * http://www.gecode.dev
18 *
19 * Permission is hereby granted, free of charge, to any person obtaining
20 * a copy of this software and associated documentation files (the
21 * "Software"), to deal in the Software without restriction, including
22 * without limitation the rights to use, copy, modify, merge, publish,
23 * distribute, sublicense, and/or sell copies of the Software, and to
24 * permit persons to whom the Software is furnished to do so, subject to
25 * the following conditions:
26 *
27 * The above copyright notice and this permission notice shall be
28 * included in all copies or substantial portions of the Software.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 *
38 */
39
40#include <gecode/minimodel.hh>
41#include <gecode/int/linear.hh>
42
43namespace Gecode {
44
47 public:
49 unsigned int use;
51 int n_int;
53 int n_bool;
57 Node *l, *r;
59 union {
66 } sum;
68 int a, c;
74 Node(void);
76 void fill(Home home, const IntPropLevels& ipls,
79 long long int m, long long int& d) const;
81 int fill(Home home, const IntPropLevels& ipls,
85 bool decrement(void);
87 ~Node(void);
89 static void* operator new(size_t size);
91 static void operator delete(void* p,size_t size);
92#ifdef GECODE_HAS_FAULT_INJECTION
94 static std::atomic<int> fault_live_nodes;
95#endif
96 };
97
98 /*
99 * Operations for nodes
100 *
101 */
104 }
105
106#ifdef GECODE_HAS_FAULT_INJECTION
107 std::atomic<int> LinIntExpr::Node::fault_live_nodes{0};
108
109 void
110 LinIntExpr::fault_reset_allocations(void) {
111 Node::fault_live_nodes.store(0, std::memory_order_relaxed);
112 }
113
114 int
115 LinIntExpr::fault_live_allocations(void) {
116 return Node::fault_live_nodes.load(std::memory_order_relaxed);
117 }
118#endif
119
122 switch (t) {
123 case NT_SUM_INT:
124 if (n_int > 0)
126 break;
127 case NT_SUM_BOOL:
128 if (n_bool > 0)
130 break;
131 case NT_NONLIN:
132 delete sum.ne;
133 break;
134 default: ;
135 }
136 }
137
138 forceinline void*
139 LinIntExpr::Node::operator new(size_t size) {
140#ifdef GECODE_HAS_FAULT_INJECTION
142#endif
143 void* p = heap.ralloc(size);
144#ifdef GECODE_HAS_FAULT_INJECTION
145 fault_live_nodes.fetch_add(1, std::memory_order_relaxed);
146#endif
147 return p;
148 }
149
150 forceinline void
151 LinIntExpr::Node::operator delete(void* p, size_t) {
152#ifdef GECODE_HAS_FAULT_INJECTION
153 fault_live_nodes.fetch_sub(1, std::memory_order_relaxed);
154#endif
155 heap.rfree(p);
156 }
157 bool
159 if (--use == 0) {
160 if ((l != nullptr) && l->decrement())
161 delete l;
162 if ((r != nullptr) && r->decrement())
163 delete r;
164 return true;
165 }
166 return false;
167 }
168
169 /*
170 * Operations for expressions
171 *
172 */
173
174 LinIntExpr::LinIntExpr(const LinIntExpr& e)
175 : n(e.n) {
176 if (n != nullptr)
177 n->use++;
178 }
179
180 int
184 long long int d=0;
185 fill(home,ipls,ti,tb,1,d);
186 Int::Limits::check(d,"MiniModel::LinIntExpr");
187 return static_cast<int>(d);
188 }
189
190 void
192 const IntPropLevels& ipls) const {
193 if (home.failed()) return;
194 Region r;
195 if (n->n_bool == 0) {
196 // Only integer variables
197 if (n->t==NT_ADD && n->l == nullptr && n->r->t==NT_NONLIN) {
198 n->r->sum.ne->post(home,irt,-n->c,ipls);
199 } else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==nullptr) {
200 switch (irt) {
201 case IRT_LQ: irt=IRT_GQ; break;
202 case IRT_LE: irt=IRT_GR; break;
203 case IRT_GQ: irt=IRT_LQ; break;
204 case IRT_GR: irt=IRT_LE; break;
205 default: break;
206 }
207 n->r->sum.ne->post(home,irt,n->c,ipls);
208 } else if (irt==IRT_EQ &&
209 n->t==NT_SUB && n->r->t==NT_NONLIN &&
210 n->l != nullptr && n->l->t==NT_VAR_INT
211 && n->l->a==1) {
212 (void) n->r->sum.ne->post(home,&n->l->x_int,ipls);
213 } else if (irt==IRT_EQ &&
214 n->t==NT_SUB && n->r->t==NT_VAR_INT &&
215 n->l != nullptr && n->l->t==NT_NONLIN
216 && n->r->a==1) {
217 (void) n->l->sum.ne->post(home,&n->r->x_int,ipls);
218 } else {
220 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int);
221 int c = n->fill(home,ipls,its,nullptr);
222 Int::Linear::post(home, its, n->n_int, irt, -c,
223 (n->n_int > 2) ? ipls.linear() : ipls.linear2());
224 }
225 } else if (n->n_int == 0) {
226 // Only Boolean variables
228 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
229 int c = n->fill(home,ipls,nullptr,bts);
230 Int::Linear::post(home, bts, n->n_bool, irt, -c,
231 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
232 } else if (n->n_bool == 1) {
233 // Integer variables and only one Boolean variable
235 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
238 int c = n->fill(home,ipls,its,bts);
239 IntVar x(home,0,1);
240 channel(home,bts[0].x,x);
241 its[n->n_int].x = x;
242 its[n->n_int].a = bts[0].a;
243 Int::Linear::post(home, its, n->n_int+1, irt, -c,
244 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
245 } else {
246 // Both integer and Boolean variables
248 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
250 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
251 int c = n->fill(home,ipls,its,bts);
252 int min, max;
253 Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
254 IntVar x(home,min,max);
255 its[n->n_int].x = x; its[n->n_int].a = 1;
256 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
257 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
258 Int::Linear::post(home, its, n->n_int+1, irt, -c,
259 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
260 }
261 }
262
263 void
265 const IntPropLevels& ipls) const {
266 if (home.failed()) return;
267 Region r;
268 if (n->n_bool == 0) {
269 // Only integer variables
270 if (n->t==NT_ADD && n->l==nullptr && n->r->t==NT_NONLIN) {
271 n->r->sum.ne->post(home,irt,-n->c,b,ipls);
272 } else if (n->t==NT_SUB && n->l==nullptr && n->r->t==NT_NONLIN) {
273 switch (irt) {
274 case IRT_LQ: irt=IRT_GQ; break;
275 case IRT_LE: irt=IRT_GR; break;
276 case IRT_GQ: irt=IRT_LQ; break;
277 case IRT_GR: irt=IRT_LE; break;
278 default: break;
279 }
280 n->r->sum.ne->post(home,irt,n->c,b,ipls);
281 } else {
283 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int);
284 int c = n->fill(home,ipls,its,nullptr);
285 Int::Linear::post(home, its, n->n_int, irt, -c, b,
286 (n->n_int > 2) ? ipls.linear() : ipls.linear2());
287 }
288 } else if (n->n_int == 0) {
289 // Only Boolean variables
291 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
292 int c = n->fill(home,ipls,nullptr,bts);
293 Int::Linear::post(home, bts, n->n_bool, irt, -c, b,
294 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
295 } else if (n->n_bool == 1) {
296 // Integer variables and only one Boolean variable
298 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
301 int c = n->fill(home,ipls,its,bts);
302 IntVar x(home,0,1);
303 channel(home,bts[0].x,x);
304 its[n->n_int].x = x;
305 its[n->n_int].a = bts[0].a;
306 Int::Linear::post(home, its, n->n_int+1, irt, -c, b,
307 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
308 } else {
309 // Both integer and Boolean variables
311 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
313 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
314 int c = n->fill(home,ipls,its,bts);
315 int min, max;
316 Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
317 IntVar x(home,min,max);
318 its[n->n_int].x = x; its[n->n_int].a = 1;
319 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
320 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
321 Int::Linear::post(home, its, n->n_int+1, irt, -c, b,
322 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
323 }
324 }
325
326 IntVar
327 LinIntExpr::post(Home home, const IntPropLevels& ipls) const {
328 if (home.failed()) return IntVar(home,0,0);
329 Region r;
330 if (n->n_bool == 0) {
331 // Only integer variables
333 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+1);
334 int c = n->fill(home,ipls,its,nullptr);
335 if ((n->n_int == 1) && (c == 0) && (its[0].a == 1))
336 return its[0].x;
337 int min, max;
338 Int::Linear::estimate(&its[0],n->n_int,c,min,max);
339 IntVar x(home, min, max);
340 its[n->n_int].x = x; its[n->n_int].a = -1;
341 Int::Linear::post(home, its, n->n_int+1, IRT_EQ, -c,
342 (n->n_int > 1) ? ipls.linear() : ipls.linear2());
343 return x;
344 } else if (n->n_int == 0) {
345 // Only Boolean variables
347 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
348 int c = n->fill(home,ipls,nullptr,bts);
349 int min, max;
350 Int::Linear::estimate(&bts[0],n->n_bool,c,min,max);
351 IntVar x(home, min, max);
352 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, -c,
353 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
354 return x;
355 } else if (n->n_bool == 1) {
356 // Integer variables and single Boolean variable
358 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+2);
361 int c = n->fill(home,ipls,its,bts);
362 IntVar x(home, 0, 1);
363 channel(home, x, bts[0].x);
364 its[n->n_int].x = x; its[n->n_int].a = bts[0].a;
365 int y_min, y_max;
366 Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
367 IntVar y(home, y_min, y_max);
368 its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
369 Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipls.linear());
370 return y;
371 } else {
372 // Both integer and Boolean variables
374 r.alloc<Int::Linear::Term<Int::IntView> >(n->n_int+2);
376 r.alloc<Int::Linear::Term<Int::BoolView> >(n->n_bool);
377 int c = n->fill(home,ipls,its,bts);
378 int x_min, x_max;
379 Int::Linear::estimate(&bts[0],n->n_bool,0,x_min,x_max);
380 IntVar x(home, x_min, x_max);
381 Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0,
382 (n->n_bool > 2) ? ipls.linear() : ipls.linear2());
383 its[n->n_int].x = x; its[n->n_int].a = 1;
384 int y_min, y_max;
385 Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
386 IntVar y(home, y_min, y_max);
387 its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
388 Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, ipls.linear());
389 return y;
390 }
391 }
392
394 LinIntExpr::nle(void) const {
395 return ((n != nullptr) && (n->t == NT_NONLIN)) ? n->sum.ne : nullptr;
396 }
397
398 LinIntExpr::LinIntExpr(NoNode) :
399 n(nullptr) {}
400
402 n(new Node) {
403 n->n_int = n->n_bool = 0;
404 n->t = NT_CONST;
405 n->l = n->r = nullptr;
406 n->a = 0;
407 n->c = 0;
408 }
409
411 n(new Node) {
412 n->n_int = n->n_bool = 0;
413 n->t = NT_CONST;
414 n->l = n->r = nullptr;
415 n->a = 0;
416 Int::Limits::check(c,"MiniModel::LinIntExpr");
417 n->c = c;
418 }
419
421 n(new Node) {
422 n->n_int = 1;
423 n->n_bool = 0;
424 n->t = NT_VAR_INT;
425 n->l = n->r = nullptr;
426 n->a = a;
427 n->x_int = x;
428 }
429
431 n(new Node) {
432 n->n_int = 0;
433 n->n_bool = 1;
434 n->t = NT_VAR_BOOL;
435 n->l = n->r = nullptr;
436 n->a = a;
437 n->x_bool = x;
438 }
439
441 n(new Node) {
442 n->n_int = 0;
443 n->n_bool = 0;
444 n->t = NT_SUM_INT;
445 n->l = n->r = nullptr;
446 try {
447 if (x.size() > 0) {
448 n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
449 n->n_int = x.size();
450 for (int i=x.size(); i--; ) {
451 n->sum.ti[i].x = x[i];
452 n->sum.ti[i].a = 1;
453 }
454 }
455 } catch (...) {
456 delete n;
457 throw;
458 }
459 }
460
462 n(nullptr) {
463 if (a.size() != x.size())
464 throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
465 n = new Node;
466 n->n_int = 0;
467 n->n_bool = 0;
468 n->t = NT_SUM_INT;
469 n->l = n->r = nullptr;
470 try {
471 if (x.size() > 0) {
472 n->sum.ti = heap.alloc<Int::Linear::Term<Int::IntView> >(x.size());
473 n->n_int = x.size();
474 for (int i=x.size(); i--; ) {
475 n->sum.ti[i].x = x[i];
476 n->sum.ti[i].a = a[i];
477 }
478 }
479 } catch (...) {
480 delete n;
481 throw;
482 }
483 }
484
485 LinIntExpr::LinIntExpr(const BoolVarArgs& x) :
486 n(new Node) {
487 n->n_int = 0;
488 n->n_bool = 0;
489 n->t = NT_SUM_BOOL;
490 n->l = n->r = nullptr;
491 try {
492 if (x.size() > 0) {
493 n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
494 n->n_bool = x.size();
495 for (int i=x.size(); i--; ) {
496 n->sum.tb[i].x = x[i];
497 n->sum.tb[i].a = 1;
498 }
499 }
500 } catch (...) {
501 delete n;
502 throw;
503 }
504 }
505
507 n(nullptr) {
508 if (a.size() != x.size())
509 throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
510 n = new Node;
511 n->n_int = 0;
512 n->n_bool = 0;
513 n->t = NT_SUM_BOOL;
514 n->l = n->r = nullptr;
515 try {
516 if (x.size() > 0) {
517 n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
518 n->n_bool = x.size();
519 for (int i=x.size(); i--; ) {
520 n->sum.tb[i].x = x[i];
521 n->sum.tb[i].a = a[i];
522 }
523 }
524 } catch (...) {
525 delete n;
526 throw;
527 }
528 }
529
530 LinIntExpr::LinIntExpr(const LinIntExpr& e0, NodeType t, const LinIntExpr& e1) :
531 n(new Node) {
532 n->n_int = e0.n->n_int + e1.n->n_int;
533 n->n_bool = e0.n->n_bool + e1.n->n_bool;
534 n->t = t;
535 n->l = e0.n; n->l->use++;
536 n->r = e1.n; n->r->use++;
537 }
538
539 LinIntExpr::LinIntExpr(const LinIntExpr& e, NodeType t, int c) :
540 n(new Node) {
541 n->n_int = e.n->n_int;
542 n->n_bool = e.n->n_bool;
543 n->t = t;
544 n->l = nullptr;
545 n->r = e.n; n->r->use++;
546 n->c = c;
547 }
548
549 LinIntExpr::LinIntExpr(int a, const LinIntExpr& e) :
550 n(new Node) {
551 n->n_int = e.n->n_int;
552 n->n_bool = e.n->n_bool;
553 n->t = NT_MUL;
554 n->l = e.n; n->l->use++;
555 n->r = nullptr;
556 n->a = a;
557 }
558
560 n(nullptr) {
561 try {
562 n = new Node;
563 } catch (...) {
564 delete e;
565 throw;
566 }
567 n->n_int = 1;
568 n->n_bool = 0;
569 n->t = NT_NONLIN;
570 n->l = n->r = nullptr;
571 n->a = 0;
572 n->sum.ne = e;
573 }
574
575 const LinIntExpr&
576 LinIntExpr::operator =(const LinIntExpr& e) {
577 if (this != &e) {
578 if ((n != nullptr) && n->decrement())
579 delete n;
580 n = e.n;
581 if (n != nullptr)
582 n->use++;
583 }
584 return *this;
585 }
586
588 if ((n != nullptr) && n->decrement())
589 delete n;
590 }
591
592
593 void
597 long long int m, long long int& d) const {
598 switch (this->t) {
599 case NT_CONST:
600 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
601 d += m*c;
602 break;
603 case NT_VAR_INT:
604 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
605 ti->a=static_cast<int>(m*a); ti->x=x_int; ti++;
606 break;
607 case NT_NONLIN:
608 ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, nullptr, ipls); ti++;
609 break;
610 case NT_VAR_BOOL:
611 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
612 tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++;
613 break;
614 case NT_SUM_INT:
615 for (int i=n_int; i--; ) {
616 Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinIntExpr");
617 ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a);
618 }
619 ti += n_int;
620 break;
621 case NT_SUM_BOOL:
622 for (int i=n_bool; i--; ) {
623 Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinIntExpr");
624 tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a);
625 }
626 tb += n_bool;
627 break;
628 case NT_ADD:
629 if (l == nullptr) {
630 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
631 d += m*c;
632 } else {
633 l->fill(home,ipls,ti,tb,m,d);
634 }
635 r->fill(home,ipls,ti,tb,m,d);
636 break;
637 case NT_SUB:
638 if (l == nullptr) {
639 Int::Limits::check(m*c,"MiniModel::LinIntExpr");
640 d += m*c;
641 } else {
642 l->fill(home,ipls,ti,tb,m,d);
643 }
644 r->fill(home,ipls,ti,tb,-m,d);
645 break;
646 case NT_MUL:
647 Int::Limits::check(m*a,"MiniModel::LinIntExpr");
648 l->fill(home,ipls,ti,tb,m*a,d);
649 break;
650 default:
652 }
653 }
654
655
656 /*
657 * Operators
658 *
659 */
660 LinIntExpr
661 operator +(int c, const IntVar& x) {
662 if (x.assigned() &&
663 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
664 return LinIntExpr(c+x.val());
665 else
666 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
667 }
669 operator +(int c, const BoolVar& x) {
670 if (x.assigned() &&
671 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
672 return LinIntExpr(c+x.val());
673 else
674 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
675 }
677 operator +(int c, const LinIntExpr& e) {
678 return LinIntExpr(e,LinIntExpr::NT_ADD,c);
679 }
681 operator +(const IntVar& x, int c) {
682 if (x.assigned() &&
683 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
684 return LinIntExpr(c+x.val());
685 else
686 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
687 }
689 operator +(const BoolVar& x, int c) {
690 if (x.assigned() &&
691 Int::Limits::valid(static_cast<long long int>(c)+x.val()))
692 return LinIntExpr(c+x.val());
693 else
694 return LinIntExpr(x,LinIntExpr::NT_ADD,c);
695 }
697 operator +(const LinIntExpr& e, int c) {
698 return LinIntExpr(e,LinIntExpr::NT_ADD,c);
699 }
701 operator +(const IntVar& x, const IntVar& y) {
702 if (x.assigned())
703 return x.val() + y;
704 else if (y.assigned())
705 return x + y.val();
706 else
707 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
708 }
710 operator +(const IntVar& x, const BoolVar& y) {
711 if (x.assigned())
712 return x.val() + y;
713 else if (y.assigned())
714 return x + y.val();
715 else
716 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
717 }
719 operator +(const BoolVar& x, const IntVar& y) {
720 if (x.assigned())
721 return x.val() + y;
722 else if (y.assigned())
723 return x + y.val();
724 else
725 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
726 }
728 operator +(const BoolVar& x, const BoolVar& y) {
729 if (x.assigned())
730 return x.val() + y;
731 else if (y.assigned())
732 return x + y.val();
733 else
734 return LinIntExpr(x,LinIntExpr::NT_ADD,y);
735 }
737 operator +(const IntVar& x, const LinIntExpr& e) {
738 if (x.assigned())
739 return x.val() + e;
740 else
741 return LinIntExpr(x,LinIntExpr::NT_ADD,e);
742 }
744 operator +(const BoolVar& x, const LinIntExpr& e) {
745 if (x.assigned())
746 return x.val() + e;
747 else
748 return LinIntExpr(x,LinIntExpr::NT_ADD,e);
749 }
751 operator +(const LinIntExpr& e, const IntVar& x) {
752 if (x.assigned())
753 return e + x.val();
754 else
755 return LinIntExpr(e,LinIntExpr::NT_ADD,x);
756 }
758 operator +(const LinIntExpr& e, const BoolVar& x) {
759 if (x.assigned())
760 return e + x.val();
761 else
762 return LinIntExpr(e,LinIntExpr::NT_ADD,x);
763 }
765 operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
766 return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
767 }
768
770 operator -(int c, const IntVar& x) {
771 if (x.assigned() &&
772 Int::Limits::valid(static_cast<long long int>(c)-x.val()))
773 return LinIntExpr(c-x.val());
774 else
775 return LinIntExpr(x,LinIntExpr::NT_SUB,c);
776 }
778 operator -(int c, const BoolVar& x) {
779 if (x.assigned() &&
780 Int::Limits::valid(static_cast<long long int>(c)-x.val()))
781 return LinIntExpr(c-x.val());
782 else
783 return LinIntExpr(x,LinIntExpr::NT_SUB,c);
784 }
786 operator -(int c, const LinIntExpr& e) {
787 return LinIntExpr(e,LinIntExpr::NT_SUB,c);
788 }
790 operator -(const IntVar& x, int c) {
791 if (x.assigned() &&
792 Int::Limits::valid(x.val()-static_cast<long long int>(c)))
793 return LinIntExpr(x.val()-c);
794 else
795 return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
796 }
798 operator -(const BoolVar& x, int c) {
799 if (x.assigned() &&
800 Int::Limits::valid(x.val()-static_cast<long long int>(c)))
801 return LinIntExpr(x.val()-c);
802 else
803 return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
804 }
806 operator -(const LinIntExpr& e, int c) {
807 return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
808 }
810 operator -(const IntVar& x, const IntVar& y) {
811 if (x.assigned())
812 return x.val() - y;
813 else if (y.assigned())
814 return x - y.val();
815 else
816 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
817 }
819 operator -(const IntVar& x, const BoolVar& y) {
820 if (x.assigned())
821 return x.val() - y;
822 else if (y.assigned())
823 return x - y.val();
824 else
825 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
826 }
828 operator -(const BoolVar& x, const IntVar& y) {
829 if (x.assigned())
830 return x.val() - y;
831 else if (y.assigned())
832 return x - y.val();
833 else
834 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
835 }
837 operator -(const BoolVar& x, const BoolVar& y) {
838 if (x.assigned())
839 return x.val() - y;
840 else if (y.assigned())
841 return x - y.val();
842 else
843 return LinIntExpr(x,LinIntExpr::NT_SUB,y);
844 }
846 operator -(const IntVar& x, const LinIntExpr& e) {
847 if (x.assigned())
848 return x.val() - e;
849 else
850 return LinIntExpr(x,LinIntExpr::NT_SUB,e);
851 }
853 operator -(const BoolVar& x, const LinIntExpr& e) {
854 if (x.assigned())
855 return x.val() - e;
856 else
857 return LinIntExpr(x,LinIntExpr::NT_SUB,e);
858 }
860 operator -(const LinIntExpr& e, const IntVar& x) {
861 if (x.assigned())
862 return e - x.val();
863 else
864 return LinIntExpr(e,LinIntExpr::NT_SUB,x);
865 }
867 operator -(const LinIntExpr& e, const BoolVar& x) {
868 if (x.assigned())
869 return e - x.val();
870 else
871 return LinIntExpr(e,LinIntExpr::NT_SUB,x);
872 }
874 operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
875 return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
876 }
877
879 operator -(const IntVar& x) {
880 if (x.assigned())
881 return LinIntExpr(-x.val());
882 else
883 return LinIntExpr(x,LinIntExpr::NT_SUB,0);
884 }
886 operator -(const BoolVar& x) {
887 if (x.assigned())
888 return LinIntExpr(-x.val());
889 else
890 return LinIntExpr(x,LinIntExpr::NT_SUB,0);
891 }
894 return LinIntExpr(e,LinIntExpr::NT_SUB,0);
895 }
896
898 operator *(int a, const IntVar& x) {
899 if (a == 0)
900 return LinIntExpr(0);
901 else if (x.assigned() &&
902 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
903 return LinIntExpr(a*x.val());
904 else
905 return LinIntExpr(x,a);
906 }
908 operator *(int a, const BoolVar& x) {
909 if (a == 0)
910 return LinIntExpr(0);
911 else if (x.assigned() &&
912 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
913 return LinIntExpr(a*x.val());
914 else
915 return LinIntExpr(x,a);
916 }
918 operator *(const IntVar& x, int a) {
919 if (a == 0)
920 return LinIntExpr(0);
921 else if (x.assigned() &&
922 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
923 return LinIntExpr(a*x.val());
924 else
925 return LinIntExpr(x,a);
926 }
928 operator *(const BoolVar& x, int a) {
929 if (a == 0)
930 return LinIntExpr(0);
931 else if (x.assigned() &&
932 Int::Limits::valid(static_cast<long long int>(a)*x.val()))
933 return LinIntExpr(a*x.val());
934 else
935 return LinIntExpr(x,a);
936 }
938 operator *(const LinIntExpr& e, int a) {
939 if (a == 0)
940 return LinIntExpr(0);
941 else
942 return LinIntExpr(a,e);
943 }
945 operator *(int a, const LinIntExpr& e) {
946 if (a == 0)
947 return LinIntExpr(0);
948 else
949 return LinIntExpr(a,e);
950 }
951
953 sum(const IntVarArgs& x) {
954 return LinIntExpr(x);
955 }
957 sum(const IntArgs& a, const IntVarArgs& x) {
958 return LinIntExpr(a,x);
959 }
961 sum(const BoolVarArgs& x) {
962 return LinIntExpr(x);
963 }
965 sum(const IntArgs& a, const BoolVarArgs& x) {
966 return LinIntExpr(a,x);
967 }
969 sum(const Slice<IntArgs>& slice) {
970 const Slice<IntArgs>::ArgsType & args = slice;
971 return sum(args);
972 }
974 sum(const Matrix<IntArgs>& matrix) {
975 const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
976 return sum(args);
977 }
979 sum(const IntArgs& args) {
980 int sum = 0;
981 for (int i = 0; i<args.size(); i++)
982 sum += args[i];
983 return LinIntExpr(sum);
984 }
985
986
987 IntVar
988 expr(Home home, const LinIntExpr& e, const IntPropLevels& ipls) {
989 PostInfo pi(home);
990 if (!home.failed())
991 return e.post(home,ipls);
993 return x;
994 }
995
996}
997
998// STATISTICS: minimodel-any
T * a
Element array.
Definition array.hpp:548
int size(void) const
Return size of array (number of elements).
Definition array.hpp:1597
Passing Boolean variables.
Definition int.hh:738
Boolean integer variables.
Definition int.hh:533
int val(void) const
Return assigned value.
Definition bool.hpp:57
FloatNum size(void) const
Return size of float value (distance between maximum and minimum).
Definition val.hpp:78
Home class for posting propagators
Definition core.hpp:863
bool failed(void) const
Check whether corresponding space is failed.
Definition core.hpp:4185
Passing integer arguments.
Definition int.hh:652
Class for specifying integer propagation levels used by minimodel.
Definition minimodel.hh:109
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:680
Integer variables.
Definition int.hh:389
int val(void) const
Return assigned value.
Definition int.hpp:56
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:46
bool decrement(void)
Decrement reference count and possibly free memory.
Definition int-expr.cpp:158
Node * l
Subexpressions.
Definition int-expr.cpp:57
union Gecode::LinIntExpr::Node::@261231010026300320017355123073322333035126115356 sum
Sum of integer or Boolean variables, or non-linear expression.
Int::Linear::Term< Int::IntView > * ti
Integer views and coefficients.
Definition int-expr.cpp:61
unsigned int use
Nodes are reference counted.
Definition int-expr.cpp:49
int n_int
Integer variables in tree.
Definition int-expr.cpp:51
IntVar x_int
Integer variable (potentially).
Definition int-expr.cpp:70
NodeType t
Type of expression.
Definition int-expr.cpp:55
NonLinIntExpr * ne
Non-linear expression.
Definition int-expr.cpp:65
BoolVar x_bool
Boolean variable (potentially).
Definition int-expr.cpp:72
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:594
~Node(void)
Destructor.
Definition int-expr.cpp:121
Int::Linear::Term< Int::BoolView > * tb
Bool views and coefficients.
Definition int-expr.cpp:63
int a
Coefficient and offset.
Definition int-expr.cpp:68
int n_bool
Boolean variables in tree.
Definition int-expr.cpp:53
Node(void)
Default constructor.
Definition int-expr.cpp:103
Linear expressions over integer variables.
Definition minimodel.hh:257
NodeType
Type of linear expression.
Definition minimodel.hh:268
@ NT_CONST
Integer constant.
Definition minimodel.hh:269
@ NT_SUB
Subtraction of linear terms.
Definition minimodel.hh:276
@ NT_SUM_BOOL
Sum of Boolean variables.
Definition minimodel.hh:274
@ NT_ADD
Addition of linear terms.
Definition minimodel.hh:275
@ NT_SUM_INT
Sum of integer variables.
Definition minimodel.hh:273
@ NT_VAR_BOOL
Linear term with Boolean variable.
Definition minimodel.hh:271
@ NT_MUL
Multiplication by coefficient.
Definition minimodel.hh:277
@ NT_NONLIN
Non-linear expression.
Definition minimodel.hh:272
@ NT_VAR_INT
Linear term with integer variable.
Definition minimodel.hh:270
LinIntExpr(void)
Default constructor.
Definition int-expr.cpp:401
~LinIntExpr(void)
Destructor.
Definition int-expr.cpp:587
void post(Home home, IntRelType irt, const IntPropLevels &ipls) const
Post propagator.
Definition int-expr.cpp:191
const LinIntExpr & operator=(const LinIntExpr &e)
Assignment operator.
Definition int-expr.cpp:576
NonLinIntExpr * nle(void) const
Return non-linear expression inside, or null if not non-linear.
Definition int-expr.cpp:394
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:223
Class to set group information when a post function is executed.
Definition core.hpp:957
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
const int * pi[]
Definition photo.cpp:14262
void post(Home home, Term< IntView > *t, int n, IntRelType irt, int c, IntPropLevel ipl=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:959
@ IRT_EQ
Equality ( ).
Definition int.hh:960
@ IRT_GQ
Greater or equal ( ).
Definition int.hh:964
@ IRT_LE
Less ( ).
Definition int.hh:963
@ IRT_GR
Greater ( ).
Definition int.hh:965
@ IRT_LQ
Less or equal ( ).
Definition int.hh:962
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:122
bool valid(int n)
Return whether n is in range.
Definition limits.hpp:37
const int max
Largest allowed integer value.
Definition int.hh:120
void estimate(Term< View > *t, int n, int c, int &l, int &u)
Estimate lower and upper bounds.
Definition post.hpp:41
void check(Phase p)
Check failpoint for phase p.
Gecode toplevel namespace
FloatVal operator-(const FloatVal &x)
Definition val.hpp:185
FloatVal operator+(const FloatVal &x)
Definition val.hpp:181
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:988
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
LinIntExpr sum(const IntVarArgs &x)
Construct linear expression as sum of integer variables.
Definition int-expr.cpp:953
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition val.hpp:217
#define forceinline
Definition config.hpp:141
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56