Generated on Tue Jan 26 2021 00:00:00 for Gecode by doxygen 1.9.1
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 
37 namespace 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) {
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 
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) {
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) {
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) {
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:
578  GECODE_NEVER;
579  }
580  }
581 
582 
583  /*
584  * Operators
585  *
586  */
587  LinIntExpr
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  }
595  LinIntExpr
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  }
603  LinIntExpr
604  operator +(int c, const LinIntExpr& e) {
605  return LinIntExpr(e,LinIntExpr::NT_ADD,c);
606  }
607  LinIntExpr
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  }
615  LinIntExpr
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  }
623  LinIntExpr
624  operator +(const LinIntExpr& e, int c) {
625  return LinIntExpr(e,LinIntExpr::NT_ADD,c);
626  }
627  LinIntExpr
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  }
636  LinIntExpr
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  }
645  LinIntExpr
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  }
654  LinIntExpr
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  }
663  LinIntExpr
664  operator +(const IntVar& x, const LinIntExpr& e) {
665  if (x.assigned())
666  return x.val() + e;
667  else
668  return LinIntExpr(x,LinIntExpr::NT_ADD,e);
669  }
670  LinIntExpr
671  operator +(const BoolVar& x, const LinIntExpr& e) {
672  if (x.assigned())
673  return x.val() + e;
674  else
675  return LinIntExpr(x,LinIntExpr::NT_ADD,e);
676  }
677  LinIntExpr
678  operator +(const LinIntExpr& e, const IntVar& x) {
679  if (x.assigned())
680  return e + x.val();
681  else
682  return LinIntExpr(e,LinIntExpr::NT_ADD,x);
683  }
684  LinIntExpr
685  operator +(const LinIntExpr& e, const BoolVar& x) {
686  if (x.assigned())
687  return e + x.val();
688  else
689  return LinIntExpr(e,LinIntExpr::NT_ADD,x);
690  }
691  LinIntExpr
692  operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
693  return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
694  }
695 
696  LinIntExpr
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  }
704  LinIntExpr
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  }
712  LinIntExpr
713  operator -(int c, const LinIntExpr& e) {
714  return LinIntExpr(e,LinIntExpr::NT_SUB,c);
715  }
716  LinIntExpr
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
722  return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
723  }
724  LinIntExpr
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
730  return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
731  }
732  LinIntExpr
733  operator -(const LinIntExpr& e, int c) {
734  return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
735  }
736  LinIntExpr
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  }
745  LinIntExpr
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  }
754  LinIntExpr
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  }
763  LinIntExpr
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  }
772  LinIntExpr
773  operator -(const IntVar& x, const LinIntExpr& e) {
774  if (x.assigned())
775  return x.val() - e;
776  else
777  return LinIntExpr(x,LinIntExpr::NT_SUB,e);
778  }
779  LinIntExpr
780  operator -(const BoolVar& x, const LinIntExpr& e) {
781  if (x.assigned())
782  return x.val() - e;
783  else
784  return LinIntExpr(x,LinIntExpr::NT_SUB,e);
785  }
786  LinIntExpr
787  operator -(const LinIntExpr& e, const IntVar& x) {
788  if (x.assigned())
789  return e - x.val();
790  else
791  return LinIntExpr(e,LinIntExpr::NT_SUB,x);
792  }
793  LinIntExpr
794  operator -(const LinIntExpr& e, const BoolVar& x) {
795  if (x.assigned())
796  return e - x.val();
797  else
798  return LinIntExpr(e,LinIntExpr::NT_SUB,x);
799  }
800  LinIntExpr
801  operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
802  return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
803  }
804 
805  LinIntExpr
806  operator -(const IntVar& x) {
807  if (x.assigned())
808  return LinIntExpr(-x.val());
809  else
810  return LinIntExpr(x,LinIntExpr::NT_SUB,0);
811  }
812  LinIntExpr
813  operator -(const BoolVar& x) {
814  if (x.assigned())
815  return LinIntExpr(-x.val());
816  else
817  return LinIntExpr(x,LinIntExpr::NT_SUB,0);
818  }
819  LinIntExpr
820  operator -(const LinIntExpr& e) {
821  return LinIntExpr(e,LinIntExpr::NT_SUB,0);
822  }
823 
824  LinIntExpr
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  }
834  LinIntExpr
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  }
844  LinIntExpr
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  }
854  LinIntExpr
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  }
864  LinIntExpr
865  operator *(const LinIntExpr& e, int a) {
866  if (a == 0)
867  return LinIntExpr(0);
868  else
869  return LinIntExpr(a,e);
870  }
871  LinIntExpr
872  operator *(int a, const LinIntExpr& e) {
873  if (a == 0)
874  return LinIntExpr(0);
875  else
876  return LinIntExpr(a,e);
877  }
878 
879  LinIntExpr
880  sum(const IntVarArgs& x) {
881  return LinIntExpr(x);
882  }
883  LinIntExpr
884  sum(const IntArgs& a, const IntVarArgs& x) {
885  return LinIntExpr(a,x);
886  }
887  LinIntExpr
888  sum(const BoolVarArgs& x) {
889  return LinIntExpr(x);
890  }
891  LinIntExpr
892  sum(const IntArgs& a, const BoolVarArgs& x) {
893  return LinIntExpr(a,x);
894  }
895  LinIntExpr
897  const Slice<IntArgs>::ArgsType & args = slice;
898  return sum(args);
899  }
900  LinIntExpr
901  sum(const Matrix<IntArgs>& matrix) {
902  const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
903  return sum(args);
904  }
905  LinIntExpr
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
struct Gecode::@602::NNF::@65::@66 b
For binary nodes (and, or, eqv)
NNF * l
Left subtree.
Definition: bool-expr.cpp:240
NodeType t
Type of node.
Definition: bool-expr.cpp:230
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:232
BoolVar expr(Home home, const BoolExpr &e, const IntPropLevels &ipls)
Post Boolean expression and return its value.
Definition: bool-expr.cpp:629
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:234
Node * x
Pointer to corresponding Boolean expression node.
Definition: bool-expr.cpp:249
struct Gecode::@602::NNF::@65::@67 a
For atomic nodes.
NNF * r
Right subtree.
Definition: bool-expr.cpp:242
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
T * alloc(long unsigned int n)
Allocate block of n objects of type T from heap.
Definition: heap.hpp:431
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.
Definition: minimodel.hh:2161
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.
Definition: minimodel.hh:2166
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.
Definition: minimodel.hh:2097
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition: minimodel.hh:2100
bool assigned(void) const
Test whether view is assigned.
Definition: var.hpp:111
const int * pi[]
Definition: photo.cpp:14262
LinFloatExpr sum(const FloatVarArgs &x)
Construct linear float expression as sum of float variables.
Definition: float-expr.cpp:546
void channel(Home home, FloatVar x0, IntVar x1)
Post propagator for channeling a float and an integer variable .
Definition: channel.cpp:41
Post propagator for SetVar SetOpType SetVar y
Definition: set.hh:767
void post(Home home, Term< BoolView > *t, int n, IntRelType irt, IntView x, int c, IntPropLevel)
Post propagator for linear constraint over Booleans.
Definition: bool-post.cpp:589
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
const FloatNum max
Largest allowed float value.
Definition: float.hh:844
const FloatNum min
Smallest allowed float value.
Definition: float.hh:846
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
unsigned int size(I &i)
Size of all ranges of range iterator i.
const unsigned int slice
Size of a slice in a portfolio and scale factor for restarts(in number of failures)
Definition: search.hh:128
Gecode::FloatVal c(-8, 8)
Gecode::IntArgs i({1, 2, 3, 4})
Gecode::IntSet d(v, 7)
#define forceinline
Definition: config.hpp:185
#define GECODE_NEVER
Assert that this command is never executed.
Definition: macros.hpp:56