Generated on Sat Feb 7 2015 02:01:28 for Gecode by doxygen 1.8.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  * Last modified:
10  * $Date: 2013-08-19 14:00:39 +0200 (Mon, 19 Aug 2013) $ by $Author: schulte $
11  * $Revision: 13982 $
12  *
13  * This file is part of Gecode, the generic constraint
14  * development environment:
15  * http://www.gecode.org
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining
18  * a copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, including
20  * without limitation the rights to use, copy, modify, merge, publish,
21  * distribute, sublicense, and/or sell copies of the Software, and to
22  * permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be
26  * included in all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  *
36  */
37 
38 #include <gecode/minimodel.hh>
39 #include <gecode/int/linear.hh>
40 
41 namespace Gecode {
42 
45  public:
47  unsigned int use;
49  int n_int;
51  int n_bool;
55  Node *l, *r;
57  union {
64  } sum;
66  int a, c;
72  Node(void);
74  void fill(Home home, IntConLevel icl,
77  long long int m, long long int& d) const;
79  int fill(Home home, IntConLevel icl,
83  bool decrement(void);
85  ~Node(void);
87  static void* operator new(size_t size);
89  static void operator delete(void* p,size_t size);
90  };
91 
92  /*
93  * Operations for nodes
94  *
95  */
97  LinIntExpr::Node::Node(void) : use(1) {
98  }
99 
102  switch (t) {
103  case NT_SUM_INT:
104  if (n_int > 0)
106  break;
107  case NT_SUM_BOOL:
108  if (n_bool > 0)
110  break;
111  case NT_NONLIN:
112  delete sum.ne;
113  break;
114  default: ;
115  }
116  }
117 
118  forceinline void*
119  LinIntExpr::Node::operator new(size_t size) {
120  return heap.ralloc(size);
121  }
122 
123  forceinline void
124  LinIntExpr::Node::operator delete(void* p, size_t) {
125  heap.rfree(p);
126  }
127  bool
129  if (--use == 0) {
130  if ((l != NULL) && l->decrement())
131  delete l;
132  if ((r != NULL) && r->decrement())
133  delete r;
134  return true;
135  }
136  return false;
137  }
138 
139  /*
140  * Operations for expressions
141  *
142  */
143 
145  : n(e.n) {
146  n->use++;
147  }
148 
149  int
153  long long int d=0;
154  fill(home,icl,ti,tb,1,d);
155  Int::Limits::check(d,"MiniModel::LinIntExpr");
156  return static_cast<int>(d);
157  }
158 
159  void
160  LinIntExpr::post(Home home, IntRelType irt, IntConLevel icl) const {
161  if (home.failed()) return;
162  Region r(home);
163  if (n->n_bool == 0) {
164  // Only integer variables
165  if (n->t==NT_ADD && n->l == NULL && n->r->t==NT_NONLIN) {
166  n->r->sum.ne->post(home,irt,-n->c,icl);
167  } else if (n->t==NT_SUB && n->r->t==NT_NONLIN && n->l==NULL) {
168  switch (irt) {
169  case IRT_LQ: irt=IRT_GQ; break;
170  case IRT_LE: irt=IRT_GR; break;
171  case IRT_GQ: irt=IRT_LQ; break;
172  case IRT_GR: irt=IRT_LE; break;
173  default: break;
174  }
175  n->r->sum.ne->post(home,irt,n->c,icl);
176  } else if (irt==IRT_EQ &&
177  n->t==NT_SUB && n->r->t==NT_NONLIN &&
178  n->l != NULL && n->l->t==NT_VAR_INT
179  && n->l->a==1) {
180  (void) n->r->sum.ne->post(home,&n->l->x_int,icl);
181  } else if (irt==IRT_EQ &&
182  n->t==NT_SUB && n->r->t==NT_VAR_INT &&
183  n->l != NULL && n->l->t==NT_NONLIN
184  && n->r->a==1) {
185  (void) n->l->sum.ne->post(home,&n->r->x_int,icl);
186  } else {
189  int c = n->fill(home,icl,its,NULL);
190  Int::Linear::post(home, its, n->n_int, irt, -c, icl);
191  }
192  } else if (n->n_int == 0) {
193  // Only Boolean variables
196  int c = n->fill(home,icl,NULL,bts);
197  Int::Linear::post(home, bts, n->n_bool, irt, -c, icl);
198  } else if (n->n_bool == 1) {
199  // Integer variables and only one Boolean variable
204  int c = n->fill(home,icl,its,bts);
205  IntVar x(home,0,1);
206  channel(home,bts[0].x,x);
207  its[n->n_int].x = x;
208  its[n->n_int].a = bts[0].a;
209  Int::Linear::post(home, its, n->n_int+1, irt, -c, icl);
210  } else {
211  // Both integer and Boolean variables
216  int c = n->fill(home,icl,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, icl);
222  Int::Linear::post(home, its, n->n_int+1, irt, -c, icl);
223  }
224  }
225 
226  void
228  IntConLevel icl) const {
229  if (home.failed()) return;
230  Region r(home);
231  if (n->n_bool == 0) {
232  // Only integer variables
233  if (n->t==NT_ADD && n->l==NULL && n->r->t==NT_NONLIN) {
234  n->r->sum.ne->post(home,irt,-n->c,b,icl);
235  } else if (n->t==NT_SUB && n->l==NULL && n->r->t==NT_NONLIN) {
236  switch (irt) {
237  case IRT_LQ: irt=IRT_GQ; break;
238  case IRT_LE: irt=IRT_GR; break;
239  case IRT_GQ: irt=IRT_LQ; break;
240  case IRT_GR: irt=IRT_LE; break;
241  default: break;
242  }
243  n->r->sum.ne->post(home,irt,n->c,b,icl);
244  } else {
247  int c = n->fill(home,icl,its,NULL);
248  Int::Linear::post(home, its, n->n_int, irt, -c, b, icl);
249  }
250  } else if (n->n_int == 0) {
251  // Only Boolean variables
254  int c = n->fill(home,icl,NULL,bts);
255  Int::Linear::post(home, bts, n->n_bool, irt, -c, b, icl);
256  } else if (n->n_bool == 1) {
257  // Integer variables and only one Boolean variable
262  int c = n->fill(home,icl,its,bts);
263  IntVar x(home,0,1);
264  channel(home,bts[0].x,x);
265  its[n->n_int].x = x;
266  its[n->n_int].a = bts[0].a;
267  Int::Linear::post(home, its, n->n_int+1, irt, -c, b, icl);
268  } else {
269  // Both integer and Boolean variables
274  int c = n->fill(home,icl,its,bts);
275  int min, max;
276  Int::Linear::estimate(&bts[0],n->n_bool,0,min,max);
277  IntVar x(home,min,max);
278  its[n->n_int].x = x; its[n->n_int].a = 1;
279  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, icl);
280  Int::Linear::post(home, its, n->n_int+1, irt, -c, b, icl);
281  }
282  }
283 
284  IntVar
285  LinIntExpr::post(Home home, IntConLevel icl) const {
286  if (home.failed()) return IntVar(home,0,0);
287  Region r(home);
288  if (n->n_bool == 0) {
289  // Only integer variables
292  int c = n->fill(home,icl,its,NULL);
293  if ((n->n_int == 1) && (c == 0) && (its[0].a == 1))
294  return its[0].x;
295  int min, max;
296  Int::Linear::estimate(&its[0],n->n_int,c,min,max);
297  IntVar x(home, min, max);
298  its[n->n_int].x = x; its[n->n_int].a = -1;
299  Int::Linear::post(home, its, n->n_int+1, IRT_EQ, -c, icl);
300  return x;
301  } else if (n->n_int == 0) {
302  // Only Boolean variables
305  int c = n->fill(home,icl,NULL,bts);
306  int min, max;
307  Int::Linear::estimate(&bts[0],n->n_bool,c,min,max);
308  IntVar x(home, min, max);
309  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, -c, icl);
310  return x;
311  } else if (n->n_bool == 1) {
312  // Integer variables and single Boolean variable
317  int c = n->fill(home,icl,its,bts);
318  IntVar x(home, 0, 1);
319  channel(home, x, bts[0].x);
320  its[n->n_int].x = x; its[n->n_int].a = bts[0].a;
321  int y_min, y_max;
322  Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
323  IntVar y(home, y_min, y_max);
324  its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
325  Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, icl);
326  return y;
327  } else {
328  // Both integer and Boolean variables
333  int c = n->fill(home,icl,its,bts);
334  int x_min, x_max;
335  Int::Linear::estimate(&bts[0],n->n_bool,0,x_min,x_max);
336  IntVar x(home, x_min, x_max);
337  Int::Linear::post(home, bts, n->n_bool, IRT_EQ, x, 0, icl);
338  its[n->n_int].x = x; its[n->n_int].a = 1;
339  int y_min, y_max;
340  Int::Linear::estimate(&its[0],n->n_int+1,c,y_min,y_max);
341  IntVar y(home, y_min, y_max);
342  its[n->n_int+1].x = y; its[n->n_int+1].a = -1;
343  Int::Linear::post(home, its, n->n_int+2, IRT_EQ, -c, icl);
344  return y;
345  }
346  }
347 
349  LinIntExpr::nle(void) const {
350  return n->t == NT_NONLIN ? n->sum.ne : NULL;
351  }
352 
354  n(new Node) {
355  n->n_int = n->n_bool = 0;
356  n->t = NT_VAR_INT;
357  n->l = n->r = NULL;
358  n->a = 0;
359  }
360 
362  n(new Node) {
363  n->n_int = n->n_bool = 0;
364  n->t = NT_CONST;
365  n->l = n->r = NULL;
366  n->a = 0;
367  Int::Limits::check(c,"MiniModel::LinIntExpr");
368  n->c = c;
369  }
370 
372  n(new Node) {
373  n->n_int = 1;
374  n->n_bool = 0;
375  n->t = NT_VAR_INT;
376  n->l = n->r = NULL;
377  n->a = a;
378  n->x_int = x;
379  }
380 
382  n(new Node) {
383  n->n_int = 0;
384  n->n_bool = 1;
385  n->t = NT_VAR_BOOL;
386  n->l = n->r = NULL;
387  n->a = a;
388  n->x_bool = x;
389  }
390 
392  n(new Node) {
393  n->n_int = x.size();
394  n->n_bool = 0;
395  n->t = NT_SUM_INT;
396  n->l = n->r = NULL;
397  if (x.size() > 0) {
399  for (int i=x.size(); i--; ) {
400  n->sum.ti[i].x = x[i];
401  n->sum.ti[i].a = 1;
402  }
403  }
404  }
405 
407  n(new Node) {
408  if (a.size() != x.size())
409  throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
410  n->n_int = x.size();
411  n->n_bool = 0;
412  n->t = NT_SUM_INT;
413  n->l = n->r = NULL;
414  if (x.size() > 0) {
416  for (int i=x.size(); i--; ) {
417  n->sum.ti[i].x = x[i];
418  n->sum.ti[i].a = a[i];
419  }
420  }
421  }
422 
424  n(new Node) {
425  n->n_int = 0;
426  n->n_bool = x.size();
427  n->t = NT_SUM_BOOL;
428  n->l = n->r = NULL;
429  if (x.size() > 0) {
431  for (int i=x.size(); i--; ) {
432  n->sum.tb[i].x = x[i];
433  n->sum.tb[i].a = 1;
434  }
435  }
436  }
437 
439  n(new Node) {
440  if (a.size() != x.size())
441  throw Int::ArgumentSizeMismatch("MiniModel::LinIntExpr");
442  n->n_int = 0;
443  n->n_bool = x.size();
444  n->t = NT_SUM_BOOL;
445  n->l = n->r = NULL;
446  if (x.size() > 0) {
448  for (int i=x.size(); i--; ) {
449  n->sum.tb[i].x = x[i];
450  n->sum.tb[i].a = a[i];
451  }
452  }
453  }
454 
456  n(new Node) {
457  n->n_int = e0.n->n_int + e1.n->n_int;
458  n->n_bool = e0.n->n_bool + e1.n->n_bool;
459  n->t = t;
460  n->l = e0.n; n->l->use++;
461  n->r = e1.n; n->r->use++;
462  }
463 
465  n(new Node) {
466  n->n_int = e.n->n_int;
467  n->n_bool = e.n->n_bool;
468  n->t = t;
469  n->l = NULL;
470  n->r = e.n; n->r->use++;
471  n->c = c;
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 = NT_MUL;
479  n->l = e.n; n->l->use++;
480  n->r = NULL;
481  n->a = a;
482  }
483 
485  n(new Node) {
486  n->n_int = 1;
487  n->n_bool = 0;
488  n->t = NT_NONLIN;
489  n->l = n->r = NULL;
490  n->a = 0;
491  n->sum.ne = e;
492  }
493 
494  const LinIntExpr&
496  if (this != &e) {
497  if (n->decrement())
498  delete n;
499  n = e.n; n->use++;
500  }
501  return *this;
502  }
503 
505  if (n->decrement())
506  delete n;
507  }
508 
509 
510  void
514  long long int m, long long int& d) const {
515  switch (this->t) {
516  case NT_CONST:
517  Int::Limits::check(m*c,"MiniModel::LinIntExpr");
518  d += m*c;
519  break;
520  case NT_VAR_INT:
521  Int::Limits::check(m*a,"MiniModel::LinIntExpr");
522  ti->a=static_cast<int>(m*a); ti->x=x_int; ti++;
523  break;
524  case NT_NONLIN:
525  ti->a=static_cast<int>(m); ti->x=sum.ne->post(home, NULL, icl); ti++;
526  break;
527  case NT_VAR_BOOL:
528  Int::Limits::check(m*a,"MiniModel::LinIntExpr");
529  tb->a=static_cast<int>(m*a); tb->x=x_bool; tb++;
530  break;
531  case NT_SUM_INT:
532  for (int i=n_int; i--; ) {
533  Int::Limits::check(m*sum.ti[i].a,"MiniModel::LinIntExpr");
534  ti[i].x = sum.ti[i].x; ti[i].a = static_cast<int>(m*sum.ti[i].a);
535  }
536  ti += n_int;
537  break;
538  case NT_SUM_BOOL:
539  for (int i=n_bool; i--; ) {
540  Int::Limits::check(m*sum.tb[i].a,"MiniModel::LinIntExpr");
541  tb[i].x = sum.tb[i].x; tb[i].a = static_cast<int>(m*sum.tb[i].a);
542  }
543  tb += n_bool;
544  break;
545  case NT_ADD:
546  if (l == NULL) {
547  Int::Limits::check(m*c,"MiniModel::LinIntExpr");
548  d += m*c;
549  } else {
550  l->fill(home,icl,ti,tb,m,d);
551  }
552  r->fill(home,icl,ti,tb,m,d);
553  break;
554  case NT_SUB:
555  if (l == NULL) {
556  Int::Limits::check(m*c,"MiniModel::LinIntExpr");
557  d += m*c;
558  } else {
559  l->fill(home,icl,ti,tb,m,d);
560  }
561  r->fill(home,icl,ti,tb,-m,d);
562  break;
563  case NT_MUL:
564  Int::Limits::check(m*a,"MiniModel::LinIntExpr");
565  l->fill(home,icl,ti,tb,m*a,d);
566  break;
567  default:
568  GECODE_NEVER;
569  }
570  }
571 
572 
573  /*
574  * Operators
575  *
576  */
577  LinIntExpr
578  operator +(int c, const IntVar& x) {
579  if (x.assigned() &&
580  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
581  return LinIntExpr(c+x.val());
582  else
583  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
584  }
585  LinIntExpr
586  operator +(int c, const BoolVar& x) {
587  if (x.assigned() &&
588  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
589  return LinIntExpr(c+x.val());
590  else
591  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
592  }
593  LinIntExpr
594  operator +(int c, const LinIntExpr& e) {
595  return LinIntExpr(e,LinIntExpr::NT_ADD,c);
596  }
597  LinIntExpr
598  operator +(const IntVar& x, int c) {
599  if (x.assigned() &&
600  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
601  return LinIntExpr(c+x.val());
602  else
603  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
604  }
605  LinIntExpr
606  operator +(const BoolVar& x, int c) {
607  if (x.assigned() &&
608  Int::Limits::valid(static_cast<long long int>(c)+x.val()))
609  return LinIntExpr(c+x.val());
610  else
611  return LinIntExpr(x,LinIntExpr::NT_ADD,c);
612  }
613  LinIntExpr
614  operator +(const LinIntExpr& e, int c) {
615  return LinIntExpr(e,LinIntExpr::NT_ADD,c);
616  }
617  LinIntExpr
618  operator +(const IntVar& x, const IntVar& y) {
619  if (x.assigned())
620  return x.val() + y;
621  else if (y.assigned())
622  return x + y.val();
623  else
624  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
625  }
626  LinIntExpr
627  operator +(const IntVar& x, const BoolVar& y) {
628  if (x.assigned())
629  return x.val() + y;
630  else if (y.assigned())
631  return x + y.val();
632  else
633  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
634  }
635  LinIntExpr
636  operator +(const BoolVar& x, const IntVar& y) {
637  if (x.assigned())
638  return x.val() + y;
639  else if (y.assigned())
640  return x + y.val();
641  else
642  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
643  }
644  LinIntExpr
645  operator +(const BoolVar& x, const BoolVar& y) {
646  if (x.assigned())
647  return x.val() + y;
648  else if (y.assigned())
649  return x + y.val();
650  else
651  return LinIntExpr(x,LinIntExpr::NT_ADD,y);
652  }
653  LinIntExpr
654  operator +(const IntVar& x, const LinIntExpr& e) {
655  if (x.assigned())
656  return x.val() + e;
657  else
658  return LinIntExpr(x,LinIntExpr::NT_ADD,e);
659  }
660  LinIntExpr
661  operator +(const BoolVar& x, const LinIntExpr& e) {
662  if (x.assigned())
663  return x.val() + e;
664  else
665  return LinIntExpr(x,LinIntExpr::NT_ADD,e);
666  }
667  LinIntExpr
668  operator +(const LinIntExpr& e, const IntVar& x) {
669  if (x.assigned())
670  return e + x.val();
671  else
672  return LinIntExpr(e,LinIntExpr::NT_ADD,x);
673  }
674  LinIntExpr
675  operator +(const LinIntExpr& e, const BoolVar& x) {
676  if (x.assigned())
677  return e + x.val();
678  else
679  return LinIntExpr(e,LinIntExpr::NT_ADD,x);
680  }
681  LinIntExpr
682  operator +(const LinIntExpr& e1, const LinIntExpr& e2) {
683  return LinIntExpr(e1,LinIntExpr::NT_ADD,e2);
684  }
685 
686  LinIntExpr
687  operator -(int c, const IntVar& x) {
688  if (x.assigned() &&
689  Int::Limits::valid(static_cast<long long int>(c)-x.val()))
690  return LinIntExpr(c-x.val());
691  else
692  return LinIntExpr(x,LinIntExpr::NT_SUB,c);
693  }
694  LinIntExpr
695  operator -(int c, const BoolVar& x) {
696  if (x.assigned() &&
697  Int::Limits::valid(static_cast<long long int>(c)-x.val()))
698  return LinIntExpr(c-x.val());
699  else
700  return LinIntExpr(x,LinIntExpr::NT_SUB,c);
701  }
702  LinIntExpr
703  operator -(int c, const LinIntExpr& e) {
704  return LinIntExpr(e,LinIntExpr::NT_SUB,c);
705  }
706  LinIntExpr
707  operator -(const IntVar& x, int c) {
708  if (x.assigned() &&
709  Int::Limits::valid(x.val()-static_cast<long long int>(c)))
710  return LinIntExpr(x.val()-c);
711  else
712  return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
713  }
714  LinIntExpr
715  operator -(const BoolVar& x, int c) {
716  if (x.assigned() &&
717  Int::Limits::valid(x.val()-static_cast<long long int>(c)))
718  return LinIntExpr(x.val()-c);
719  else
720  return LinIntExpr(x,LinIntExpr::NT_ADD,-c);
721  }
722  LinIntExpr
723  operator -(const LinIntExpr& e, int c) {
724  return LinIntExpr(e,LinIntExpr::NT_ADD,-c);
725  }
726  LinIntExpr
727  operator -(const IntVar& x, const IntVar& y) {
728  if (x.assigned())
729  return x.val() - y;
730  else if (y.assigned())
731  return x - y.val();
732  else
733  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
734  }
735  LinIntExpr
736  operator -(const IntVar& x, const BoolVar& y) {
737  if (x.assigned())
738  return x.val() - y;
739  else if (y.assigned())
740  return x - y.val();
741  else
742  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
743  }
744  LinIntExpr
745  operator -(const BoolVar& x, const IntVar& y) {
746  if (x.assigned())
747  return x.val() - y;
748  else if (y.assigned())
749  return x - y.val();
750  else
751  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
752  }
753  LinIntExpr
754  operator -(const BoolVar& x, const BoolVar& y) {
755  if (x.assigned())
756  return x.val() - y;
757  else if (y.assigned())
758  return x - y.val();
759  else
760  return LinIntExpr(x,LinIntExpr::NT_SUB,y);
761  }
762  LinIntExpr
763  operator -(const IntVar& x, const LinIntExpr& e) {
764  if (x.assigned())
765  return x.val() - e;
766  else
767  return LinIntExpr(x,LinIntExpr::NT_SUB,e);
768  }
769  LinIntExpr
770  operator -(const BoolVar& x, const LinIntExpr& e) {
771  if (x.assigned())
772  return x.val() - e;
773  else
774  return LinIntExpr(x,LinIntExpr::NT_SUB,e);
775  }
776  LinIntExpr
777  operator -(const LinIntExpr& e, const IntVar& x) {
778  if (x.assigned())
779  return e - x.val();
780  else
781  return LinIntExpr(e,LinIntExpr::NT_SUB,x);
782  }
783  LinIntExpr
784  operator -(const LinIntExpr& e, const BoolVar& x) {
785  if (x.assigned())
786  return e - x.val();
787  else
788  return LinIntExpr(e,LinIntExpr::NT_SUB,x);
789  }
790  LinIntExpr
791  operator -(const LinIntExpr& e1, const LinIntExpr& e2) {
792  return LinIntExpr(e1,LinIntExpr::NT_SUB,e2);
793  }
794 
795  LinIntExpr
796  operator -(const IntVar& x) {
797  if (x.assigned())
798  return LinIntExpr(-x.val());
799  else
800  return LinIntExpr(x,LinIntExpr::NT_SUB,0);
801  }
802  LinIntExpr
803  operator -(const BoolVar& x) {
804  if (x.assigned())
805  return LinIntExpr(-x.val());
806  else
807  return LinIntExpr(x,LinIntExpr::NT_SUB,0);
808  }
809  LinIntExpr
810  operator -(const LinIntExpr& e) {
811  return LinIntExpr(e,LinIntExpr::NT_SUB,0);
812  }
813 
814  LinIntExpr
815  operator *(int a, const IntVar& x) {
816  if (a == 0)
817  return LinIntExpr(0.0);
818  else if (x.assigned() &&
819  Int::Limits::valid(static_cast<long long int>(a)*x.val()))
820  return LinIntExpr(a*x.val());
821  else
822  return LinIntExpr(x,a);
823  }
824  LinIntExpr
825  operator *(int a, const BoolVar& x) {
826  if (a == 0)
827  return LinIntExpr(0.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 *(const IntVar& x, int a) {
836  if (a == 0)
837  return LinIntExpr(0.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 BoolVar& x, int a) {
846  if (a == 0)
847  return LinIntExpr(0.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 LinIntExpr& e, int a) {
856  if (a == 0)
857  return LinIntExpr(0.0);
858  else
859  return LinIntExpr(a,e);
860  }
861  LinIntExpr
862  operator *(int a, const LinIntExpr& e) {
863  if (a == 0)
864  return LinIntExpr(0.0);
865  else
866  return LinIntExpr(a,e);
867  }
868 
869  LinIntExpr
870  sum(const IntVarArgs& x) {
871  return LinIntExpr(x);
872  }
873  LinIntExpr
874  sum(const IntArgs& a, const IntVarArgs& x) {
875  return LinIntExpr(a,x);
876  }
877  LinIntExpr
878  sum(const BoolVarArgs& x) {
879  return LinIntExpr(x);
880  }
881  LinIntExpr
882  sum(const IntArgs& a, const BoolVarArgs& x) {
883  return LinIntExpr(a,x);
884  }
885  LinIntExpr
886  sum(const Slice<IntArgs>& slice) {
887  const Slice<IntArgs>::ArgsType & args = slice;
888  return sum(args);
889  }
890  LinIntExpr
891  sum(const Matrix<IntArgs>& matrix) {
892  const Matrix<IntArgs>::ArgsType & args = matrix.get_array();
893  return sum(args);
894  }
895  LinIntExpr
896  sum(const IntArgs& args) {
897  int i, sum = 0;
898  const int size = args.size();
899 
900  for (i = 0 ; i < size ; ++i)
901  {
902  sum += args[i];
903  }
904 
905  return LinIntExpr(sum);
906  }
907 
908 
909  IntVar
910  expr(Home home, const LinIntExpr& e, IntConLevel icl) {
911  if (!home.failed())
912  return e.post(home,icl);
914  return x;
915  }
916 
917 }
918 
919 // STATISTICS: minimodel-any
bool failed(void) const
Check whether corresponding space is failed.
Definition: core.hpp:3446
FloatVal operator-(const FloatVal &x)
Definition: val.hpp:172
IntVar x_int
Integer variable (potentially)
Definition: int-expr.cpp:68
NodeType t
Type of node.
Definition: bool-expr.cpp:234
IntConLevel
Consistency levels for integer propagators.
Definition: int.hh:937
NNF * l
Left subtree.
Definition: bool-expr.cpp:244
NodeType t
Type of expression.
Definition: int-expr.cpp:53
void channel(Home home, FloatVar x0, IntVar x1)
Post propagator for channeling a float and an integer variable .
Definition: arithmetic.cpp:218
union Gecode::LinIntExpr::Node::@61 sum
Sum of integer or Boolean variables, or non-linear expression.
void rfree(void *p)
Free memory block starting at p.
Definition: heap.hpp:355
int size(void) const
Return size of array (number of elements)
Definition: array.hpp:1662
void post(Home home, Term< BoolView > *t, int n, IntRelType irt, IntView x, int c, IntConLevel)
Post propagator for linear constraint over Booleans.
Definition: bool-post.cpp:608
int a
Coefficient.
Definition: linear.hh:1313
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition: region.hpp:326
unsigned int use
Nodes are reference counted.
Definition: int-expr.cpp:47
Linear term with Boolean variable.
Definition: minimodel.hh:151
void max(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:57
Less or equal ( )
Definition: int.hh:906
Int::Linear::Term< Int::BoolView > * tb
Bool views and coefficients.
Definition: int-expr.cpp:61
Base class for non-linear expressions over integer variables.
Definition: minimodel.hh:107
void * ralloc(size_t s)
Allocate s bytes from heap.
Definition: heap.hpp:341
Addition of linear terms.
Definition: minimodel.hh:155
Node * l
Subexpressions.
Definition: int-expr.cpp:55
Multiplication by coefficient.
Definition: minimodel.hh:157
Handle to region.
Definition: region.hpp:61
Greater ( )
Definition: int.hh:909
Linear term with integer variable.
Definition: minimodel.hh:150
const int max
Largest allowed integer value.
Definition: int.hh:113
Greater or equal ( )
Definition: int.hh:908
const int min
Smallest allowed integer value.
Definition: int.hh:115
int val(void) const
Return assigned value.
Definition: bool.hpp:61
Heap heap
The single global heap.
Definition: heap.cpp:49
const LinIntExpr & operator=(const LinIntExpr &e)
Assignment operator.
Definition: int-expr.cpp:495
Gecode::IntSet d(v, 7)
Gecode::FloatVal c(-8, 8)
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
T * alloc(long unsigned int n)
Allocate block of n objects of type T from heap.
Definition: heap.hpp:400
A slice of a matrix.
Definition: minimodel.hh:1934
Int::Linear::Term< Int::IntView > * ti
Integer views and coefficients.
Definition: int-expr.cpp:59
Gecode::IntArgs i(4, 1, 2, 3, 4)
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
Equality ( )
Definition: int.hh:904
int n_int
Integer variables in tree.
Definition: int-expr.cpp:49
Nodes for linear expressions.
Definition: int-expr.cpp:44
IntRelType
Relation types for integers.
Definition: int.hh:903
FloatVal operator+(const FloatVal &x)
Definition: val.hpp:168
~Node(void)
Destructor.
Definition: int-expr.cpp:101
NNF * r
Right subtree.
Definition: bool-expr.cpp:246
BoolVar x_bool
Boolean variable (potentially)
Definition: int-expr.cpp:70
bool decrement(void)
Decrement reference count and possibly free memory.
Definition: int-expr.cpp:128
unsigned int size(I &i)
Size of all ranges of range iterator i.
int a
Coefficient and offset.
Definition: int-expr.cpp:66
LinIntExpr(void)
Default constructor.
Definition: int-expr.cpp:353
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition: minimodel.hh:2003
Less ( )
Definition: int.hh:907
NodeType
Type of linear expression.
Definition: minimodel.hh:148
Passing integer variables.
Definition: int.hh:636
Passing integer arguments.
Definition: int.hh:607
Passing Boolean variables.
Definition: int.hh:690
Non-linear expression.
Definition: minimodel.hh:152
Node(void)
Default constructor.
Definition: int-expr.cpp:97
Boolean integer variables.
Definition: int.hh:491
ArgsType const get_array(void) const
Return an Args-array of the contents of the matrix.
Definition: matrix.hpp:153
void min(Home home, FloatVar x0, FloatVar x1, FloatVar x2)
Post propagator for .
Definition: arithmetic.cpp:75
ArrayTraits< A >::ArgsType ArgsType
The type of the Args-array type for ValueType values.
Definition: minimodel.hh:1937
BoolVar expr(Home home, const BoolExpr &e, IntConLevel icl)
Post Boolean expression and return its value.
Definition: bool-expr.cpp:632
FloatVal operator*(const FloatVal &x, const FloatVal &y)
Definition: val.hpp:204
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition: heap.hpp:426
~LinIntExpr(void)
Destructor.
Definition: int-expr.cpp:504
Node * x
Pointer to corresponding Boolean expression node.
Definition: bool-expr.cpp:253
Sum of integer variables.
Definition: minimodel.hh:153
Linear expressions over integer variables.
Definition: minimodel.hh:138
int n_bool
Boolean variables in tree.
Definition: int-expr.cpp:51
Integer variables.
Definition: int.hh:350
void estimate(Term< View > *t, int n, int c, int &l, int &u)
Estimate lower and upper bounds.
Definition: post.hpp:45
#define forceinline
Definition: config.hpp:132
NonLinIntExpr * nle(void) const
Return non-linear expression inside, or NULL if not non-linear.
Definition: int-expr.cpp:349
Sum of Boolean variables.
Definition: minimodel.hh:154
bool valid(int n)
Return whether n is in range.
Definition: limits.hpp:41
int val(void) const
Return assigned value.
Definition: int.hpp:60
Subtraction of linear terms.
Definition: minimodel.hh:156
NonLinIntExpr * ne
Non-linear expression.
Definition: int-expr.cpp:63
virtual IntVar post(Home home, IntVar *ret, IntConLevel icl) const =0
Return variable constrained to be equal to the expression.
Matrix-interface for arrays.
Definition: minimodel.hh:1924
bool assigned(void) const
Test whether view is assigned.
Definition: var.hpp:123
Class for describing linear term .
Definition: linear.hh:1310
Integer constant.
Definition: minimodel.hh:149
struct Gecode::@518::NNF::@57::@58 b
For binary nodes (and, or, eqv)
Gecode toplevel namespace
LinFloatExpr sum(const FloatVarArgs &x)
Construct linear float expression as sum of float variables.
Definition: float-expr.cpp:548
void check(int n, const char *l)
Check whether n is in range, otherwise throw out of limits with information l.
Definition: limits.hpp:50
Home class for posting propagators
Definition: core.hpp:717
Exception: Arguments are of different size
Definition: exception.hpp:77
#define GECODE_NEVER
Assert that this command is never executed.
Definition: macros.hpp:60
struct Gecode::@518::NNF::@57::@59 a
For atomic nodes.
void fill(Home home, IntConLevel icl, 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:511
void post(Home home, IntRelType irt, IntConLevel icl) const
Post propagator.
Definition: int-expr.cpp:160